/* 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;
{
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;
fx = fx->next;
}
}
- else if (opcode1->op->flags_used & (FLAG_JMP | FLAG_JSR)
- && ((opcode1->op->flags_used & FLAG_DELAY) == 0)
- && ((opcode1->ecc == ECC_AL) || ! Optimizing))
+ 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;
}
{
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)
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
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;
}
}