/* tc-h8300.c -- Assemble code for the Hitachi H8/300
- Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 2000
- Free Software Foundation.
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001
+ Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-/*
- Written By Steve Chamberlain
- sac@cygnus.com
- */
+/* Written By Steve Chamberlain <sac@cygnus.com>. */
#include <stdio.h>
#include "as.h"
#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"
+#endif
const char comment_chars[] = ";";
const char line_comment_chars[] = "#";
{
Hmode = 1;
Smode = 0;
+#ifdef BFD_ASSEMBLER
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300h))
+ as_warn (_("could not set architecture and machine"));
+#endif
}
void
{
Smode = 1;
Hmode = 1;
+#ifdef BFD_ASSEMBLER
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300s))
+ as_warn (_("could not set architecture and machine"));
+#endif
}
void
char prev_buffer[100];
int idx = 0;
+#ifdef BFD_ASSEMBLER
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300))
+ as_warn (_("could not set architecture and machine"));
+#endif
+
opcode_hash_control = hash_new ();
prev_buffer[0] = 0;
ccr
*/
-/* Try and parse a reg name, returns number of chars consumed. */
+/* Try to parse a reg name. Return the number of chars consumed. */
+
static int
parse_reg (src, mode, reg, direction)
char *src;
{
*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;
if (c & MACREG)
{
- nib = 2 + operand[d].reg;
+ if (operand[0].mode == MACREG)
+ /* stmac has mac[hl] as the first operand. */
+ nib = 2 + operand[0].reg;
+ else
+ /* ldmac has mac[hl] as the second operand. */
+ nib = 2 + operand[1].reg;
}
}
nibble_count++;
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,
build_bytes (opcode, operand);
}
+#ifndef BFD_ASSEMBLER
void
tc_crawl_symbol_chain (headers)
object_headers *headers ATTRIBUTE_UNUSED;
{
printf (_("call to tc_crawl_symbol_chain \n"));
}
+#endif
symbolS *
md_undefined_symbol (name)
return 0;
}
+#ifndef BFD_ASSEMBLER
void
tc_headers_hook (headers)
object_headers *headers ATTRIBUTE_UNUSED;
{
printf (_("call to tc_headers_hook \n"));
}
+#endif
/* Various routines to kill one day */
/* Equal to MAX_PRECISION in atof-ieee.c */
/* Turn a string in input_line_pointer into a floating point constant
of type TYPE, and store the appropriate bytes in *LITP. The number
- of LITTLENUMS emitted is stored in *SIZEP . An error message is
+ of LITTLENUMS emitted is stored in *SIZEP. An error message is
returned, or NULL on OK. */
+
char *
md_atof (type, litP, sizeP)
char type;
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
+
+#ifdef BFD_ASSEMBLER
+int
+md_apply_fix (fixP, valp)
+ fixS *fixP;
+ valueT *valp;
+#else
void
md_apply_fix (fixP, val)
fixS *fixP;
long val;
+#endif
{
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+#ifdef BFD_ASSEMBLER
+ long val = *valp;
+#endif
switch (fixP->fx_size)
{
abort ();
}
+#ifndef BFD_ASSEMBLER
void
tc_reloc_mangle (fix_ptr, intr, base)
fixS *fix_ptr;
else
intr->r_symndx = -1;
}
+#else /* BFD_ASSEMBLER */
+arelent *
+tc_gen_reloc (section, fixp)
+ asection *section ATTRIBUTE_UNUSED;
+ fixS *fixp;
+{
+ 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);
+ rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ rel->addend = fixp->fx_offset;
+
+ r_type = fixp->fx_r_type;
+
+#define DEBUG 0
+#if DEBUG
+ fprintf (stderr, "%s\n", bfd_get_reloc_code_name (r_type));
+ fflush(stderr);
+#endif
+ rel->howto = bfd_reloc_type_lookup (stdoutput, r_type);
+ if (rel->howto == NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Cannot represent relocation type %s"),
+ bfd_get_reloc_code_name (r_type));
+ return NULL;
+ }
+
+ return rel;
+}
+#endif