#define DEFINE_TABLE
#define h8_opcodes ops
#include "opcode/h8300.h"
-#include <ctype.h>
+#include "safe-ctype.h"
#ifdef OBJ_ELF
#include "elf/h8.h"
-
-#define R_MOV24B1 BFD_RELOC_H8_DIR24A8
-#define R_MOVL1 BFD_RELOC_H8_DIR32A16
-#define R_MOV24B1 BFD_RELOC_H8_DIR24A8
-#define R_MOVL1 BFD_RELOC_H8_DIR32A16
-#define R_RELLONG BFD_RELOC_32
-#define R_MOV16B1 BFD_RELOC_H8_DIR16A8
-#define R_RELWORD BFD_RELOC_16
-#define R_RELBYTE BFD_RELOC_8
-#define R_PCRWORD BFD_RELOC_16_PCREL
-#define R_PCRBYTE BFD_RELOC_8_PCREL
-#define R_JMPL1 BFD_RELOC_H8_DIR24R8
#endif
const char comment_chars[] = ";";
{
*mode |= L_16;
}
- while (isdigit (*ptr))
+ while (ISDIGIT (*ptr))
ptr++;
}
}
/* Gross. Gross. ldm and stm have a format not easily handled
by get_operand. We deal with it explicitly here. */
- if (src[0] == 'e' && src[1] == 'r' && isdigit (src[2])
- && src[3] == '-' && src[4] == 'e' && src[5] == 'r' && isdigit (src[6]))
+ if (src[0] == 'e' && src[1] == 'r' && ISDIGIT (src[2])
+ && src[3] == '-' && src[4] == 'e' && src[5] == 'r' && ISDIGIT (src[6]))
{
int low, high;
fit a 16 bit address truncated into an 8 bit address
of something like bset. */
}
+ else if (strcmp (string, "@") == 0
+ && width == 0xffff
+ && (operand->exp.X_add_number & 0xff8000) == 0xff8000)
+ {
+ /* Just ignore this one - which happens when trying to
+ fit a 24 bit address truncated into a 16 bit address
+ of something like mov.w. */
+ }
else
{
as_warn (_("operand %s0x%lx out of range."), string,
int where = size16 ? 2 : 1;
int size = size16 ? 2 : 1;
int type = size16 ? R_PCRWORD : R_PCRBYTE;
+ fixS *fixP;
check_operand (operand + i, size16 ? 0x7fff : 0x7f, "@");
(unsigned long) operand->exp.X_add_number);
}
+#ifndef OBJ_ELF
+ /* The COFF port has always been off by one, changing it
+ now would be an incompatible change, so we leave it as-is.
+
+ We don't want to do this for ELF as we want to be
+ compatible with the proposed ELF format from Hitachi. */
operand[i].exp.X_add_number -= 1;
+#endif
+
operand[i].exp.X_add_number =
((operand[i].exp.X_add_number & 0xff) ^ 0x80) - 0x80;
- fix_new_exp (frag_now,
- output - frag_now->fr_literal + where,
- size,
- &operand[i].exp,
- 1,
- type);
+ fixP = fix_new_exp (frag_now,
+ output - frag_now->fr_literal + where,
+ size,
+ &operand[i].exp,
+ 1,
+ type);
+ fixP->fx_signed = 1;
}
else if (x & MEMIND)
{
}
else if (x & ABSJMP)
{
+ int where = 0;
+
+#ifdef OBJ_ELF
+ /* To be compatible with the proposed H8 ELF format, we
+ want the relocation's offset to point to the first byte
+ that will be modified, not to the start of the instruction. */
+ where += 1;
+#endif
+
/* This jmp may be a jump or a branch. */
check_operand (operand + i, Hmode ? 0xffffff : 0xffff, "@");
operand[i].exp.X_add_number =
((operand[i].exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
fix_new_exp (frag_now,
- output - frag_now->fr_literal,
+ output - frag_now->fr_literal + where,
4,
&operand[i].exp,
0,
void
md_convert_frag (headers, seg, fragP)
+#ifdef BFD_ASSEMBLER
+ bfd *headers ATTRIBUTE_UNUSED;
+#else
object_headers *headers ATTRIBUTE_UNUSED;
+#endif
segT seg ATTRIBUTE_UNUSED;
fragS *fragP ATTRIBUTE_UNUSED;
{
abort ();
}
+#ifdef BFD_ASSEMBLER
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+ int align = bfd_get_section_alignment (stdoutput, segment);
+ return ((size + (1 << align) - 1) & (-1 << align));
+}
+#else
valueT
md_section_align (seg, size)
segT seg;
valueT size;
{
return ((size + (1 << section_alignment[(int) seg]) - 1)
- & (-1 << section_alignment[(int) seg]));
+ & (-1 << section_alignment[(int) seg]));
}
+#endif
+
void
-md_apply_fix (fixP, val)
+md_apply_fix3 (fixP, valP, seg)
fixS *fixP;
- long val;
+ valueT *valP;
+ segT seg ATTRIBUTE_UNUSED;
{
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+ long val = * (long *) valP;
switch (fixP->fx_size)
{
default:
abort ();
}
+
+ if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
+ fixP->fx_done = 1;
}
int
arelent *rel;
bfd_reloc_code_real_type r_type;
+ if (fixp->fx_addsy && fixp->fx_subsy)
+ {
+ if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
+ || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ "Difference of symbols in different sections is not supported");
+ return NULL;
+ }
+ }
+
rel = (arelent *) xmalloc (sizeof (arelent));
rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
*rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);