/* tc-d30v.c -- Assembler code for the Mitsubishi D30V
-
- Copyright (C) 1997, 1998 Free Software Foundation.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation.
This file is part of GAS, the GNU Assembler.
const char EXP_CHARS[] = "eE";
const char FLT_CHARS[] = "dD";
+#if HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
#define NOP_MULTIPLY 1
#define NOP_ALL 2
static int warn_nops = 0;
static Fixups FixUps[2];
static Fixups *fixups;
-/* Whether current and previous instruction is a word multiply. */
+/* Whether current and previous instruction are word multiply insns. */
static int cur_mul32_p = 0;
static int prev_mul32_p = 0;
static symbolS *d30v_last_label;
/* Two nops */
-#define NOP_LEFT ((long long)NOP << 32)
-#define NOP_RIGHT ((long long)NOP)
+#define NOP_LEFT ((long long) NOP << 32)
+#define NOP_RIGHT ((long long) NOP)
#define NOP2 (FM00 | NOP_LEFT | NOP_RIGHT)
/* local functions */
low = 0;
high = reg_name_cnt () - 1;
- if (symbol_find (name) != NULL)
- {
- if (warn_register_name_conflicts)
- as_warn ("Register name %s conflicts with symbol of the same name",
- name);
- }
-
do
{
middle = (low + high) / 2;
high = middle - 1;
else if (cmp > 0)
low = middle + 1;
- else
- return pre_defined_registers[middle].value;
+ else
+ {
+ if (symbol_find (name) != NULL)
+ {
+ if (warn_register_name_conflicts)
+ as_warn (_("Register name %s conflicts with symbol of the same name"),
+ name);
+ }
+
+ return pre_defined_registers[middle].value;
+ }
}
while (low <= high);
}
/* register_name() checks the string at input_line_pointer
- to see if it is a valid register name */
+ to see if it is a valid register name. */
static int
register_name (expressionP)
{
expressionP->X_op = O_register;
/* temporarily store a pointer to the string here */
- expressionP->X_op_symbol = (struct symbol *)input_line_pointer;
+ expressionP->X_op_symbol = (symbolS *)input_line_pointer;
expressionP->X_add_number = reg_number;
input_line_pointer = p;
return 1;
int retval=0;
/* don't bother checking 32-bit values */
- if (bits == 32)
+ if (bits == 32 && sizeof(unsigned long) * CHAR_BIT == 32)
return 0;
+ /* Sign extend signed values to unsigned long */
+ if ((flags & OPERAND_SIGNED) && (num & ((unsigned long)1 << (bits - 1))))
+ num |= ((long)-1 << (bits - 1));
+
if (flags & OPERAND_SHIFT)
{
/* We know that all shifts are right by three bits.... */
if (flags & OPERAND_SIGNED)
- num = (unsigned long) (((/*signed*/ long) num) >> 3);
+ num = (unsigned long) ( (long) num >= 0)
+ ? ( ((long) num) >> 3 )
+ : ( (num >> 3) | ((unsigned long)-1 << (32 - 3)) );
else
num >>= 3;
}
if (flags & OPERAND_SIGNED)
{
- max = (1 << (bits - 1))-1;
- min = - (1 << (bits - 1));
+ max = ((unsigned long)1 << (bits - 1)) - 1;
+ min = - ((unsigned long)1 << (bits - 1));
if (((long)num > max) || ((long)num < min))
retval = 1;
}
else
{
- max = (1 << bits) - 1;
+ max = ((unsigned long)1 << bits) - 1;
min = 0;
if ((num > max) || (num < min))
retval = 1;
}
+
return retval;
}
void
md_begin ()
{
- struct d30v_opcode *opcode;
+ struct d30v_opcode * opcode;
d30v_hash = hash_new ();
/* Insert opcode names into a hash table. */
/* According to 4.3.1: for FM=00, sub-instructions performed
only by IU cannot be encoded in L-container. */
- if (opcode->op->unit == IU)
- insn |= FM00 | NOP_LEFT; /* right container */
- else
- insn = FM00 | (insn << 32) | NOP_RIGHT; /* left container */
+ if (opcode->op->unit == IU)
+ insn |= FM00 | NOP_LEFT; /* right container */
+ else
+ insn = FM00 | (insn << 32) | NOP_RIGHT; /* left container */
}
d30v_number_to_chars (f, insn, 8);
fx->fc = 0;
}
-/* write out a short form instruction if possible */
-/* return number of instructions not written out */
+/* Write out a short form instruction if possible.
+ Return number of instructions not written out. */
static int
write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
struct d30v_insn *opcode1, *opcode2;
char *f;
int i,j, where;
- if (exec_type != EXEC_PARALLEL &&
- ((opcode1->op->flags_used & (FLAG_JSR | FLAG_DELAY)) == FLAG_JSR))
+ if (exec_type == EXEC_SEQ
+ && (opcode1->op->flags_used & (FLAG_JMP | FLAG_JSR))
+ && ((opcode1->op->flags_used & FLAG_DELAY) == 0)
+ && ((opcode1->ecc == ECC_AL) || ! Optimizing))
{
- /* subroutines must be called from 32-bit boundaries */
- /* so the return address will be correct */
+ /* Unconditional, non-delayed branches kill instructions in
+ the right bin. Conditional branches don't always but if
+ we are not optimizing, then we have been asked to produce
+ an error about such constructs. For the purposes of this
+ test, subroutine calls are considered to be branches. */
write_1_short (opcode1, insn1, fx->next, false);
return 1;
}
-
+
+ /* Note: we do not have to worry about subroutine calls occuring
+ in the right hand container. The return address is always
+ aligned to the next 64 bit boundary, be that 64 or 32 bit away. */
+
switch (exec_type)
{
- case EXEC_UNKNOWN: /* order not specified */
- if (Optimizing && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
+ case EXEC_UNKNOWN: /* Order not specified. */
+ if (Optimizing
+ && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type)
+ && ! ( (opcode1->op->unit == EITHER_BUT_PREFER_MU
+ || opcode1->op->unit == MU)
+ &&
+ ( opcode2->op->unit == EITHER_BUT_PREFER_MU
+ || opcode2->op->unit == MU)))
{
/* parallel */
exec_type = EXEC_PARALLEL;
- if (opcode1->op->unit == IU)
- insn = FM00 | (insn2 << 32) | insn1;
- else if (opcode2->op->unit == MU)
+
+ if (opcode1->op->unit == IU
+ || opcode2->op->unit == MU
+ || opcode2->op->unit == EITHER_BUT_PREFER_MU)
insn = FM00 | (insn2 << 32) | insn1;
else
{
fx = fx->next;
}
}
- else if (opcode1->op->unit == IU)
+ else if ((opcode1->op->flags_used & (FLAG_JMP | FLAG_JSR)
+ && ((opcode1->op->flags_used & FLAG_DELAY) == 0)
+ && ((opcode1->ecc == ECC_AL) || ! Optimizing))
+ || opcode1->op->flags_used & FLAG_RP)
+ {
+ /* We must emit (non-delayed) branch type instructions
+ on their own with nothing in the right container. */
+ /* We must treat repeat instructions likewise, since the
+ following instruction has to be separate from the repeat
+ in order to be repeated. */
+ write_1_short (opcode1, insn1, fx->next, false);
+ return 1;
+ }
+ else if (prev_left_kills_right_p)
+ {
+ /* The left instruction kils the right slot, so we
+ must leave it empty. */
+ write_1_short (opcode1, insn1, fx->next, false);
+ return 1;
+ }
+ else if (opcode1->op->unit == IU
+ || (opcode1->op->unit == EITHER
+ && opcode2->op->unit == EITHER_BUT_PREFER_MU))
{
/* reverse sequential */
insn = FM10 | (insn2 << 32) | insn1;
case EXEC_PARALLEL: /* parallel */
flag_explicitly_parallel = flag_xp_state;
if (! parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
- as_fatal (_("Instructions may not be executed in parallel"));
+ as_bad (_("Instructions may not be executed in parallel"));
else if (opcode1->op->unit == IU)
{
if (opcode2->op->unit == IU)
- as_fatal (_("Two IU instructions may not be executed in parallel"));
+ as_bad (_("Two IU instructions may not be executed in parallel"));
as_warn (_("Swapping instruction order"));
insn = FM00 | (insn2 << 32) | insn1;
}
else if (opcode2->op->unit == MU)
{
if (opcode1->op->unit == MU)
- as_fatal (_("Two MU instructions may not be executed in parallel"));
+ as_bad (_("Two MU instructions may not be executed in parallel"));
+ else if (opcode1->op->unit == EITHER_BUT_PREFER_MU)
+ as_warn (_("Executing %s in IU may not work"), opcode1->op->name);
as_warn (_("Swapping instruction order"));
insn = FM00 | (insn2 << 32) | insn1;
}
else
{
+ if (opcode2->op->unit == EITHER_BUT_PREFER_MU)
+ as_warn (_("Executing %s in IU may not work"), opcode2->op->name);
+
insn = FM00 | (insn1 << 32) | insn2;
fx = fx->next;
}
case EXEC_SEQ: /* sequential */
if (opcode1->op->unit == IU)
- as_fatal (_("IU instruction may not be in the left container"));
+ as_bad (_("IU instruction may not be in the left container"));
if (prev_left_kills_right_p)
- as_warn (_("special left instruction `%s' kills instruction "
+ as_bad (_("special left instruction `%s' kills instruction "
"`%s' in right container"),
opcode1->op->name, opcode2->op->name);
+ if (opcode2->op->unit == EITHER_BUT_PREFER_MU)
+ as_warn (_("Executing %s in IU may not work"), opcode2->op->name);
insn = FM01 | (insn1 << 32) | insn2;
fx = fx->next;
break;
case EXEC_REVSEQ: /* reverse sequential */
if (opcode2->op->unit == MU)
- as_fatal (_("MU instruction may not be in the right container"));
+ as_bad (_("MU instruction may not be in the right container"));
+ if (opcode2->op->unit == EITHER_BUT_PREFER_MU)
+ as_warn (_("Executing %s in IU may not work"), opcode2->op->name);
insn = FM10 | (insn1 << 32) | insn2;
fx = fx->next;
break;
as_fatal (_("unknown execution type passed to write_2_short()"));
}
- /* printf("writing out %llx\n",insn); */
+ /* printf ("writing out %llx\n",insn); */
f = frag_more (8);
d30v_number_to_chars (f, insn, 8);
fx->fix[i].reloc);
}
}
+
fx->fc = 0;
fx = fx->next;
}
- return (0);
+
+ return 0;
}
}
flag_reg[j] = 0;
mod_reg[j][0] = mod_reg[j][1] = 0;
- mod_reg[j][2] = (op->flags_set & FLAG_ALL);
used_reg[j][0] = used_reg[j][1] = 0;
- used_reg[j][2] = (op->flags_used & FLAG_ALL);
+ if (flag_explicitly_parallel)
+ {
+ /* For human specified parallel instructions we have been asked
+ to ignore the possibility that both instructions could modify
+ bits in the PSW, so we initialise the mod & used arrays to 0.
+ We have been asked, however, to refuse to allow parallel
+ instructions which explicitly set the same flag register,
+ eg "cmpne f0,r1,0x10 || cmpeq f0, r5, 0x2", so further on we test
+ for the use of a flag register and set a bit in the mod or used
+ array appropriately. */
+
+ mod_reg[j][2] = 0;
+ used_reg[j][2] = 0;
+ }
+ else
+ {
+ mod_reg[j][2] = (op->flags_set & FLAG_ALL);
+ used_reg[j][2] = (op->flags_used & FLAG_ALL);
+ }
+
/* BSR/JSR always sets R62 */
if (op->flags_used & FLAG_JSR)
mod_reg[j][1] = (1L << (62-32));
}
}
}
-
+
flags_set1 = op1->op->flags_set;
flags_set2 = op2->op->flags_set;
flags_used1 = op1->op->flags_used;
don't trust the human if both instructions modify the same
register but we do trust the human if they modify the same
flags. */
+ /* We have now been requested not to trust the human if the
+ instructions modify the same flag registers either. */
if (flag_explicitly_parallel)
{
- if ((j < 2) && (mod_reg[0][j] & mod_reg[1][j]) != 0)
+ if ((mod_reg[0][j] & mod_reg[1][j]) != 0)
return 0;
}
else
}
-
/* This is the main entry point for the machine-dependent assembler. str points to a
machine-dependent instruction. This function is supposed to emit the frags/bytes
it assembles to. For the D30V, it mostly handles the special VLIW parsing and packing
then first write it out */
d30v_cleanup (false);
- /* assemble first instruction and save it */
+ /* Assemble first instruction and save it. */
prev_insn = do_assemble (str, &prev_opcode, 1, 0);
if (prev_insn == -1)
- as_fatal (_("Cannot assemble instruction"));
- if (prev_opcode.form->form >= LONG)
- as_fatal (_("First opcode is long. Unable to mix instructions as specified."));
+ as_bad (_("Cannot assemble instruction"));
+ if (prev_opcode.form != NULL && prev_opcode.form->form >= LONG)
+ as_bad (_("First opcode is long. Unable to mix instructions as specified."));
fixups = fixups->next;
str = str2 + 2;
prev_seg = now_seg;
if (insn == -1)
{
if (extype != EXEC_UNKNOWN)
- {
- etype = extype;
- return;
- }
- as_fatal (_("Cannot assemble instruction"));
+ etype = extype;
+ as_bad (_("Cannot assemble instruction"));
+ return;
}
if (etype != EXEC_UNKNOWN)
if (opcode.form->form >= LONG)
{
if (extype != EXEC_UNKNOWN)
- as_fatal (_("Unable to mix instructions as specified"));
+ as_bad (_("Instruction uses long version, so it cannot be mixed as specified"));
d30v_cleanup (false);
- write_long (&opcode, insn, fixups);
+ write_long (& opcode, insn, fixups);
prev_insn = -1;
}
- else if ((prev_insn != -1) &&
- (write_2_short (&prev_opcode, (long)prev_insn, &opcode, (long)insn, extype, fixups) == 0))
+ else if ((prev_insn != -1)
+ && (write_2_short
+ (& prev_opcode, (long) prev_insn, & opcode,
+ (long) insn, extype, fixups) == 0))
{
/* No instructions saved. */
prev_insn = -1;
else
{
if (extype != EXEC_UNKNOWN)
- as_fatal (_("Unable to mix instructions as specified"));
+ as_bad (_("Unable to mix instructions as specified"));
/* Save off last instruction so it may be packed on next pass. */
memcpy (&prev_opcode, &opcode, sizeof (prev_opcode));
prev_seg = now_seg;
prev_subseg = now_subseg;
fixups = fixups->next;
+ prev_mul32_p = cur_mul32_p;
}
}
/* do_assemble assembles a single instruction and returns an opcode */
/* it returns -1 (an invalid opcode) on error */
+#define NAME_BUF_LEN 20
+
static long long
do_assemble (str, opcode, shortp, is_parallel)
char *str;
int shortp;
int is_parallel;
{
- unsigned char *op_start, *save;
- unsigned char *op_end;
- char name[20];
- int cmp_hack, nlen = 0, fsize = (shortp ? FORCE_SHORT : 0);
- expressionS myops[6];
- long long insn;
+ unsigned char * op_start;
+ unsigned char * save;
+ unsigned char * op_end;
+ char name [NAME_BUF_LEN];
+ int cmp_hack;
+ int nlen = 0;
+ int fsize = (shortp ? FORCE_SHORT : 0);
+ expressionS myops [6];
+ long long insn;
/* Drop leading whitespace */
- while (*str == ' ')
- str++;
+ while (* str == ' ')
+ str ++;
/* find the opcode end */
for (op_start = op_end = (unsigned char *) (str);
- *op_end
- && nlen < 20
- && *op_end != '/'
+ * op_end
+ && nlen < (NAME_BUF_LEN - 1)
+ && * op_end != '/'
&& !is_end_of_line[*op_end] && *op_end != ' ';
op_end++)
{
}
if (nlen == 0)
- return (-1);
+ return -1;
name[nlen] = 0;
if (*op_end == '/')
{
int i = 0;
- while ( (i < ECC_MAX) && strncasecmp (d30v_ecc_names[i],op_end+1,2))
+ while ( (i < ECC_MAX) && strncasecmp (d30v_ecc_names[i], op_end + 1, 2))
i++;
if (i == ECC_MAX)
{
char tmp[4];
- strncpy (tmp,op_end+1,2);
+ strncpy (tmp, op_end + 1, 2);
tmp[2] = 0;
- as_fatal (_("unknown condition code: %s"),tmp);
+ as_bad (_("unknown condition code: %s"),tmp);
return -1;
}
- /* printf("condition code=%d\n",i); */
+ /* printf ("condition code=%d\n",i); */
opcode->ecc = i;
op_end += 3;
}
/* CMP and CMPU change their name based on condition codes */
- if (!strncmp (name,"cmp",3))
+ if (!strncmp (name, "cmp", 3))
{
int p,i;
char **str = (char **)d30v_cc_names;
else
p = 3;
- for (i=1; *str && strncmp (*str,&name[p],2); i++, str++)
+ for (i=1; *str && strncmp (*str, & name[p], 2); i++, str++)
;
/* cmpu only supports some condition codes */
if (i < 3 || i > 6)
{
name[p+2]=0;
- as_fatal (_("cmpu doesn't support condition code %s"),&name[p]);
+ as_bad (_("cmpu doesn't support condition code %s"),&name[p]);
}
}
if (!*str)
{
name[p+2]=0;
- as_fatal (_("unknown condition code: %s"),&name[p]);
+ as_bad (_("unknown condition code: %s"),&name[p]);
}
cmp_hack = i;
/* find the first opcode with the proper name */
opcode->op = (struct d30v_opcode *)hash_find (d30v_hash, name);
if (opcode->op == NULL)
- as_fatal (_("unknown opcode: %s"),name);
+ {
+ as_bad (_("unknown opcode: %s"),name);
+ return -1;
+ }
save = input_line_pointer;
input_line_pointer = op_end;
while (!(opcode->form = find_format (opcode->op, myops, fsize, cmp_hack)))
{
opcode->op++;
- if (strcmp (opcode->op->name,name))
- as_fatal (_("operands for opcode `%s' do not match any valid format"), name);
+ if (opcode->op->name == NULL || strcmp (opcode->op->name, name))
+ {
+ as_bad (_("operands for opcode `%s' do not match any valid format"), name);
+ return -1;
+ }
}
input_line_pointer = save;
cur_left_kills_right_p = 0;
}
-
- return (insn);
+ return insn;
}
int numops, match, index, i=0, j, k;
struct d30v_format *fm;
+ if (opcode == NULL)
+ return NULL;
+
/* Get all the operands and save them as expressions. */
numops = get_operands (myops, cmp_hack);
|| ((flags & OPERAND_ACC) && !(num & OPERAND_ACC))
|| (!(flags & OPERAND_ACC) && (num & OPERAND_ACC))
|| ((flags & OPERAND_FLAG) && !(num & OPERAND_FLAG))
- || (!(flags & OPERAND_FLAG) && (num & OPERAND_FLAG))
+ || (!(flags & (OPERAND_FLAG | OPERAND_CONTROL)) && (num & OPERAND_FLAG))
|| ((flags & OPERAND_CONTROL)
&& !(num & (OPERAND_CONTROL | OPERAND_FLAG))))
{
/* printf("through the loop: match=%d\n",match); */
/* We're only done if the operands matched so far AND there
are no more to check. */
- if (match && myops[j].X_op == 0)
- return fm;
+ if (match && myops[j].X_op == 0)
+ {
+ /* Final check - issue a warning if an odd numbered register
+ is used as the first register in an instruction that reads
+ or writes 2 registers. */
+
+ for (j = 0; fm->operands[j]; j++)
+ if (myops[j].X_op == O_register
+ && (myops[j].X_add_number & 1)
+ && (d30v_operand_table[fm->operands[j]].flags & OPERAND_2REG))
+ as_warn (\
+_("Odd numbered register used as target of multi-register instruction"));
+
+ return fm;
+ }
fm = (struct d30v_format *)&d30v_format_table[++k];
}
/* printf("trying another format: i=%d\n",i); */
{
arelent *reloc;
reloc = (arelent *) xmalloc (sizeof (arelent));
- reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
if (reloc->howto == (reloc_howto_type *) NULL)
int
md_apply_fix3 (fixp, valuep, seg)
- fixS *fixp;
- valueT *valuep;
+ fixS * fixp;
+ valueT * valuep;
segT seg;
{
- char *where;
+ char * where;
unsigned long insn, insn2;
long value;
-
+
if (fixp->fx_addsy == (symbolS *) NULL)
{
- value = *valuep;
+ value = * valuep;
fixp->fx_done = 1;
}
else if (fixp->fx_pcrel)
- {
- value = *valuep;
- }
+ value = * valuep;
else
{
value = fixp->fx_offset;
+
if (fixp->fx_subsy != (symbolS *) NULL)
{
if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
switch (fixp->fx_r_type)
{
- case BFD_RELOC_8:
- /* Caused by a bad .byte directive. */
- as_fatal (_("line %d: unable to place address of symbol '%s' into a byte"),
+ case BFD_RELOC_8: /* Check for a bad .byte directive. */
+ if (fixp->fx_addsy != NULL)
+ as_bad (_("line %d: unable to place address of symbol '%s' into a byte"),
fixp->fx_line, S_GET_NAME (fixp->fx_addsy));
+ else if (((unsigned)value) > 0xff)
+ as_bad (_("line %d: unable to place value %x into a byte"),
+ fixp->fx_line, value);
+ else
+ * (unsigned char *) where = value;
break;
- case BFD_RELOC_16:
- /* Caused by a bad .short directive. */
- as_fatal (_("line %d: unable to place address of symbol '%s' into a short"),
+ case BFD_RELOC_16: /* Check for a bad .short directive. */
+ if (fixp->fx_addsy != NULL)
+ as_bad (_("line %d: unable to place address of symbol '%s' into a short"),
fixp->fx_line, S_GET_NAME (fixp->fx_addsy));
+ else if (((unsigned)value) > 0xffff)
+ as_bad (_("line %d: unable to place value %x into a short"),
+ fixp->fx_line, value);
+ else
+ bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
break;
- case BFD_RELOC_64:
- /* Caused by a bad .quad directive. */
- as_fatal (_("line %d: unable to place address of symbol '%s' into a .quad"),
+ case BFD_RELOC_64: /* Check for a bad .quad directive. */
+ if (fixp->fx_addsy != NULL)
+ as_bad (_("line %d: unable to place address of symbol '%s' into a quad"),
fixp->fx_line, S_GET_NAME (fixp->fx_addsy));
+ else
+ {
+ bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
+ bfd_putb32 (0, ((unsigned char *) where) + 4);
+ }
break;
case BFD_RELOC_D30V_6:
break;
default:
- as_fatal (_("line %d: unknown relocation type: 0x%x"),fixp->fx_line,fixp->fx_r_type);
+ as_bad (_("line %d: unknown relocation type: 0x%x"),
+ fixp->fx_line,fixp->fx_r_type);
}
+
return 0;
}
d30v_cleanup (false);
/* Update the label's address with the current output pointer. */
- lab->sy_frag = frag_now;
+ symbol_set_frag (lab, frag_now);
S_SET_VALUE (lab, (valueT) frag_now_fix ());
/* Record this label for future adjustment after we find out what
this alignement request. The alignment of the current frag
can be changed under our feet, for example by a .ascii
directive in the source code. cf testsuite/gas/d30v/reloc.s */
-
+
d30v_cleanup (false);
if (pfill == NULL)
assert (S_GET_SEGMENT (label) == now_seg);
- old_frag = label->sy_frag;
+ old_frag = symbol_get_frag (label);
old_value = S_GET_VALUE (label);
new_value = (valueT) frag_now_fix ();
in the target fragment. Note, this search is guaranteed to
find at least one match when sym == label, so no special case
code is necessary. */
- for (sym = symbol_lastP; sym != NULL; sym = sym->sy_previous)
+ for (sym = symbol_lastP; sym != NULL; sym = symbol_previous (sym))
{
- if (sym->sy_frag == old_frag && S_GET_VALUE (sym) == old_value)
+ if (symbol_get_frag (sym) == old_frag
+ && S_GET_VALUE (sym) == old_value)
{
label_seen = true;
- sym->sy_frag = frag_now;
+ symbol_set_frag (sym, frag_now);
S_SET_VALUE (sym, new_value);
}
- else if (label_seen && sym->sy_frag != old_frag)
+ else if (label_seen && symbol_get_frag (sym) != old_frag)
break;
}
}