/* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
- Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Written by Stephane Carrez (stcarrez@nerim.fr)
This file is part of GAS, the GNU Assembler.
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <stdio.h>
#include "as.h"
#include "safe-ctype.h"
#include "subsegs.h"
#define STATE_CONDITIONAL_BRANCH (1)
#define STATE_PC_RELATIVE (2)
#define STATE_INDEXED_OFFSET (3)
-#define STATE_XBCC_BRANCH (4)
-#define STATE_CONDITIONAL_BRANCH_6812 (5)
+#define STATE_INDEXED_PCREL (4)
+#define STATE_XBCC_BRANCH (5)
+#define STATE_CONDITIONAL_BRANCH_6812 (6)
#define STATE_BYTE (0)
#define STATE_BITS5 (0)
{0, 0, 2, 0},
{1, 1, 0, 0},
+ /* Relax for PC relative offset: 5-bits, 9-bits, 16-bits.
+ For the 9-bit case, there will be a -1 correction to take into
+ account the new byte that's why the range is -255..256. */
+ {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9)},
+ {(256), (-255), 1, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16)},
+ {0, 0, 2, 0},
+ {1, 1, 0, 0},
+
/* Relax for dbeq/ibeq/tbeq r,<L>:
These insns are translated into db!cc +3 jmp L. */
{(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD)},
static struct m68hc11_opcode *m68hc11_sorted_opcodes;
/* ELF flags to set in the output file header. */
-static int elf_flags = 0;
+static int elf_flags = E_M68HC11_F64;
/* These are the machine dependent pseudo-ops. These are included so
the assembler can work on the output from the SUN C compiler, which
{"fcc", stringer, 1},
{"rmb", s_space, 0},
- /* Dwarf2 support for Gcc. */
- {"file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0},
- {"loc", dwarf2_directive_loc, 0},
-
/* Motorola ALIS. */
{"xrefb", s_ignore, 0}, /* Same as xref */
#define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
{"generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE},
+#define OPTION_MSHORT (OPTION_MD_BASE + 6)
+ {"mshort", no_argument, NULL, OPTION_MSHORT},
+
+#define OPTION_MLONG (OPTION_MD_BASE + 7)
+ {"mlong", no_argument, NULL, OPTION_MLONG},
+
+#define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 8)
+ {"mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE},
+
+#define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 9)
+ {"mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE},
+
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof (md_longopts);
{
get_default_target ();
fprintf (stream, _("\
-Motorola 68HC11/68HC12 options:\n\
- -m68hc11 | -m68hc12 specify the processor [default %s]\n\
+Motorola 68HC11/68HC12/68HCS12 options:\n\
+ -m68hc11 | -m68hc12 |\n\
+ -m68hcs12 specify the processor [default %s]\n\
+ -mshort use 16-bit int ABI (default)\n\
+ -mlong use 32-bit int ABI\n\
+ -mshort-double use 32-bit double ABI\n\
+ -mlong-double use 64-bit double ABI (default)\n\
--force-long-branchs always turn relative branchs into absolute ones\n\
-S,--short-branchs do not turn relative branchs into absolute ones\n\
when the offset is out of range\n\
flag_print_opcodes = 2;
break;
+ case OPTION_MSHORT:
+ elf_flags &= ~E_M68HC11_I32;
+ break;
+
+ case OPTION_MLONG:
+ elf_flags |= E_M68HC11_I32;
+ break;
+
+ case OPTION_MSHORT_DOUBLE:
+ elf_flags &= ~E_M68HC11_F64;
+ break;
+
+ case OPTION_MLONG_DOUBLE:
+ elf_flags |= E_M68HC11_F64;
+ break;
+
case 'm':
if (strcasecmp (arg, "68hc11") == 0)
current_architecture = cpu6811;
else if (strcasecmp (arg, "68hc12") == 0)
current_architecture = cpu6812;
+ else if (strcasecmp (arg, "68hcs12") == 0)
+ current_architecture = cpu6812 | cpu6812s;
else
as_bad (_("Option `%s' is not recognized."), arg);
break;
}
}
}
- qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode), cmp_opcode);
+ qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode),
+ (int (*) PARAMS ((const PTR, const PTR))) cmp_opcode);
opc = (struct m68hc11_opcode_def *)
xmalloc (num_opcodes * sizeof (struct m68hc11_opcode_def));
return reg_number;
}
+#define M6811_OP_CALL_ADDR 0x00800000
+#define M6811_OP_PAGE_ADDR 0x04000000
/* Parse a string of operands and return an array of expressions.
p += 3;
mode |= M6811_OP_LOW_ADDR;
}
+ /* %page modifier is used to obtain only the page number
+ of the address of a function. */
+ else if (strncmp (p, "%page", 5) == 0)
+ {
+ p += 5;
+ mode |= M6811_OP_PAGE_ADDR;
+ }
+
+ /* %addr modifier is used to obtain the physical address part
+ of the function (16-bit). For 68HC12 the function will be
+ mapped in the 16K window at 0x8000 and the value will be
+ within that window (although the function address may not fit
+ in 16-bit). See bfd/elf32-m68hc12.c for the translation. */
+ else if (strncmp (p, "%addr", 5) == 0)
+ {
+ p += 5;
+ mode |= M6811_OP_CALL_ADDR;
+ }
}
else if (*p == '.' && (p[1] == '+' || p[1] == '-'))
{
as_bad (_("Spurious `,' or bad indirect register addressing mode."));
return -1;
}
+ /* Handle 68HC12 page specification in 'call foo,%page(bar)'. */
+ else if ((opmode & M6812_OP_PAGE) && strncmp (p, "%page", 5) == 0)
+ {
+ p += 5;
+ mode = M6811_OP_PAGE_ADDR | M6812_OP_PAGE | M6811_OP_IND16;
+ }
input_line_pointer = p;
if (mode == M6811_OP_NONE || mode == M6812_OP_D_IDX)
fixS *fixp;
fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
- oper, true, BFD_RELOC_8_PCREL);
+ oper, TRUE, BFD_RELOC_8_PCREL);
fixp->fx_pcrel_adjust = 1;
}
else
{
- /* Now create an 8-bit fixup. If there was some %hi or %lo
- modifier, generate the reloc accordingly. */
- fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
- oper, false,
- ((opmode & M6811_OP_HIGH_ADDR)
- ? BFD_RELOC_M68HC11_HI8
- : ((opmode & M6811_OP_LOW_ADDR)
- ? BFD_RELOC_M68HC11_LO8
- : ((mode & M6812_OP_PAGE)
- ? BFD_RELOC_M68HC11_PAGE : BFD_RELOC_8))));
+ fixS *fixp;
+ int reloc;
+
+ /* Now create an 8-bit fixup. If there was some %hi, %lo
+ or %page modifier, generate the reloc accordingly. */
+ if (opmode & M6811_OP_HIGH_ADDR)
+ reloc = BFD_RELOC_M68HC11_HI8;
+ else if (opmode & M6811_OP_LOW_ADDR)
+ reloc = BFD_RELOC_M68HC11_LO8;
+ else if (opmode & M6811_OP_PAGE_ADDR)
+ reloc = BFD_RELOC_M68HC11_PAGE;
+ else
+ reloc = BFD_RELOC_8;
+
+ fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
+ oper, FALSE, reloc);
+ if (reloc != BFD_RELOC_8)
+ fixp->fx_no_overflow = 1;
}
number_to_chars_bigendian (f, 0, 1);
}
else if (oper->X_op != O_register)
{
fixS *fixp;
+ int reloc;
+
+ if ((opmode & M6811_OP_CALL_ADDR) && (mode & M6811_OP_IMM16))
+ reloc = BFD_RELOC_M68HC11_LO16;
+ else if (mode & M6812_OP_JUMP_REL16)
+ reloc = BFD_RELOC_16_PCREL;
+ else if (mode & M6812_OP_PAGE)
+ reloc = BFD_RELOC_M68HC11_LO16;
+ else
+ reloc = BFD_RELOC_16;
/* Now create a 16-bit fixup. */
fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
oper,
- (mode & M6812_OP_JUMP_REL16 ? true : false),
- (mode & M6812_OP_JUMP_REL16
- ? BFD_RELOC_16_PCREL
- : (mode & M6812_OP_PAGE)
- ? BFD_RELOC_M68HC11_LO16 : BFD_RELOC_16));
+ reloc == BFD_RELOC_16_PCREL,
+ reloc);
number_to_chars_bigendian (f, 0, 2);
- if (mode & M6812_OP_JUMP_REL16)
+ if (reloc == BFD_RELOC_16_PCREL)
fixp->fx_pcrel_adjust = 2;
+ if (reloc == BFD_RELOC_M68HC11_LO16)
+ fixp->fx_no_overflow = 1;
}
else
{
/* Now create a 24-bit fixup. */
fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
- oper, false, BFD_RELOC_M68HC11_24);
+ oper, FALSE, BFD_RELOC_M68HC11_24);
number_to_chars_bigendian (f, 0, 3);
}
else
}
else if (op->reg1 != REG_PC)
{
- byte = (byte << 3) | 0xe2;
+ symbolS *sym;
+ offsetT off;
+
f = frag_more (1);
number_to_chars_bigendian (f, byte, 1);
-
- f = frag_more (2);
- fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
- &op->exp, false, BFD_RELOC_16);
- number_to_chars_bigendian (f, 0, 2);
+ sym = op->exp.X_add_symbol;
+ off = op->exp.X_add_number;
+ if (op->exp.X_op != O_symbol)
+ {
+ sym = make_expr_symbol (&op->exp);
+ off = 0;
+ }
+ frag_var (rs_machine_dependent, 2, 2,
+ ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
+ sym, off, f);
}
else
{
f = frag_more (1);
number_to_chars_bigendian (f, byte, 1);
frag_var (rs_machine_dependent, 2, 2,
- ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
+ ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_UNDF),
op->exp.X_add_symbol,
op->exp.X_add_number, f);
}
char *f;
long format;
int move_insn = 0;
- fragS *frag;
- int where;
/* Put the page code instruction if there is one. */
format = opcode->format;
- frag = frag_now;
- where = frag_now_fix ();
-
if (format & M6811_OP_BRANCH)
- fix_new (frag, where, 1,
+ fix_new (frag_now, frag_now_fix (), 1,
&abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
if (format & OP_EXTENDED)
if (i >= opc->min_operands)
{
opcode = find (opc, operands, i);
+
+ /* Another special case for 'call foo,page' instructions.
+ Since we support 'call foo' and 'call foo,page' we must look
+ if the optional page specification is present otherwise we will
+ assemble immediately and treat the page spec as garbage. */
if (opcode && !(opcode->format & M6812_OP_PAGE))
return opcode;
return;
}
- fix_new_exp (frag_now, frag_now_fix (), 1, &ex, 1,
+ fix_new_exp (frag_now, frag_now_fix (), 2, &ex, 1,
BFD_RELOC_M68HC11_RL_GROUP);
demand_empty_rest_of_line ();
then it is done here. */
arelent *
tc_gen_reloc (section, fixp)
- asection *section;
+ asection *section ATTRIBUTE_UNUSED;
fixS *fixp;
{
arelent *reloc;
return NULL;
}
- if (!fixp->fx_pcrel)
- reloc->addend = fixp->fx_addnumber;
- else
- reloc->addend = (section->vma
- /*+ (fixp->fx_pcrel_adjust == 64
- ? -1 : fixp->fx_pcrel_adjust)*/
- + fixp->fx_addnumber
- + md_pcrel_from (fixp));
+ /* Since we use Rel instead of Rela, encode the vtable entry to be
+ used in the relocation's section offset. */
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ reloc->address = fixp->fx_offset;
+
+ reloc->addend = 0;
return reloc;
}
+/* We need a port-specific relaxation function to cope with sym2 - sym1
+ relative expressions with both symbols in the same segment (but not
+ necessarily in the same frag as this insn), for example:
+ ldab sym2-(sym1-2),pc
+ sym1:
+ The offset can be 5, 9 or 16 bits long. */
+
+long
+m68hc11_relax_frag (seg, fragP, stretch)
+ segT seg ATTRIBUTE_UNUSED;
+ fragS *fragP;
+ long stretch ATTRIBUTE_UNUSED;
+{
+ long growth;
+ offsetT aim = 0;
+ symbolS *symbolP;
+ const relax_typeS *this_type;
+ const relax_typeS *start_type;
+ relax_substateT next_state;
+ relax_substateT this_state;
+ const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
+
+ /* We only have to cope with frags as prepared by
+ md_estimate_size_before_relax. The STATE_BITS16 case may geet here
+ because of the different reasons that it's not relaxable. */
+ switch (fragP->fr_subtype)
+ {
+ case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
+ case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
+ /* When we get to this state, the frag won't grow any more. */
+ return 0;
+
+ case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
+ case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
+ case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
+ case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
+ if (fragP->fr_symbol == NULL
+ || S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
+ as_fatal (_("internal inconsistency problem in %s: fr_symbol %lx"),
+ __FUNCTION__, (long) fragP->fr_symbol);
+ symbolP = fragP->fr_symbol;
+ if (symbol_resolved_p (symbolP))
+ as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
+ __FUNCTION__);
+ aim = S_GET_VALUE (symbolP);
+ break;
+
+ default:
+ as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"),
+ __FUNCTION__, fragP->fr_subtype);
+ }
+
+ /* The rest is stolen from relax_frag. There's no obvious way to
+ share the code, but fortunately no requirement to keep in sync as
+ long as fragP->fr_symbol does not have its segment changed. */
+
+ this_state = fragP->fr_subtype;
+ start_type = this_type = table + this_state;
+
+ if (aim < 0)
+ {
+ /* Look backwards. */
+ for (next_state = this_type->rlx_more; next_state;)
+ if (aim >= this_type->rlx_backward)
+ next_state = 0;
+ else
+ {
+ /* Grow to next state. */
+ this_state = next_state;
+ this_type = table + this_state;
+ next_state = this_type->rlx_more;
+ }
+ }
+ else
+ {
+ /* Look forwards. */
+ for (next_state = this_type->rlx_more; next_state;)
+ if (aim <= this_type->rlx_forward)
+ next_state = 0;
+ else
+ {
+ /* Grow to next state. */
+ this_state = next_state;
+ this_type = table + this_state;
+ next_state = this_type->rlx_more;
+ }
+ }
+
+ growth = this_type->rlx_length - start_type->rlx_length;
+ if (growth != 0)
+ fragP->fr_subtype = this_state;
+ return growth;
+}
+
void
md_convert_frag (abfd, sec, fragP)
bfd *abfd ATTRIBUTE_UNUSED;
fragP->fr_fix += 2;
break;
+ case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
+ if (fragP->fr_symbol != 0
+ && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
+ value = disp;
+ /* fall through */
+
case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
- if ((fragP->fr_opcode[0] & 0x0ff) == 0x0c0)
- fragP->fr_opcode[0] |= disp & 0x1f;
- else
- fragP->fr_opcode[0] |= value & 0x1f;
+ fragP->fr_opcode[0] |= value & 0x1f;
break;
+ case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
+ /* For a PC-relative offset, use the displacement with a -1 correction
+ to take into account the additional byte of the insn. */
+ if (fragP->fr_symbol != 0
+ && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
+ value = disp - 1;
+ /* fall through */
+
case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
fragP->fr_opcode[0] |= 0xE0;
- fix_new (fragP, fragP->fr_fix, 1,
- fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_8);
+ fragP->fr_opcode[0] |= (value >> 8) & 1;
+ fragP->fr_opcode[1] = value;
fragP->fr_fix += 1;
break;
+ case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
fragP->fr_opcode[0] |= 0xe2;
- if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa)
+ if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa
+ && fragP->fr_symbol != 0
+ && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
{
fixp = fix_new (fragP, fragP->fr_fix, 2,
fragP->fr_symbol, fragP->fr_offset,
1, BFD_RELOC_16_PCREL);
- fixp->fx_pcrel_adjust = 2;
}
else
{
if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
{
if (S_GET_SEGMENT (fragP->fr_symbol) != segment
- || !relaxable_symbol (fragP->fr_symbol))
+ || !relaxable_symbol (fragP->fr_symbol)
+ || (segment != absolute_section
+ && RELAX_STATE (fragP->fr_subtype) == STATE_INDEXED_OFFSET))
{
/* Non-relaxable cases. */
int old_fr_fix;
case STATE_INDEXED_OFFSET:
assert (current_architecture & cpu6812);
- /* Switch the indexed operation to 16-bit mode. */
- fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
- fragP->fr_opcode[0] |= 0xe2;
- fragP->fr_fix++;
- fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
- fragP->fr_offset, 0, BFD_RELOC_16);
- fragP->fr_fix++;
+ if (fragP->fr_symbol
+ && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
+ {
+ fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
+ STATE_BITS5);
+ /* Return the size of the variable part of the frag. */
+ return md_relax_table[fragP->fr_subtype].rlx_length;
+ }
+ else
+ {
+ /* Switch the indexed operation to 16-bit mode. */
+ fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
+ fragP->fr_opcode[0] |= 0xe2;
+ fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
+ fragP->fr_offset, 0, BFD_RELOC_16);
+ fragP->fr_fix += 2;
+ }
+ break;
+
+ case STATE_INDEXED_PCREL:
+ assert (current_architecture & cpu6812);
+
+ if (fragP->fr_symbol
+ && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
+ {
+ fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
+ STATE_BITS5);
+ /* Return the size of the variable part of the frag. */
+ return md_relax_table[fragP->fr_subtype].rlx_length;
+ }
+ else
+ {
+ fixS* fixp;
+
+ fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
+ fragP->fr_opcode[0] |= 0xe2;
+ fixp = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
+ fragP->fr_fix += 2;
+ }
break;
case STATE_XBCC_BRANCH:
STATE_BITS5);
break;
+ case STATE_INDEXED_PCREL:
+ assert (current_architecture & cpu6812);
+
+ fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
+ STATE_BITS5);
+ break;
+
case STATE_XBCC_BRANCH:
assert (current_architecture & cpu6812);
tc_m68hc11_force_relocation (fixP)
fixS * fixP;
{
- switch (fixP->fx_r_type)
- {
- case BFD_RELOC_VTABLE_INHERIT:
- case BFD_RELOC_VTABLE_ENTRY:
- case BFD_RELOC_M68HC11_RL_GROUP:
- return 1;
+ if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_GROUP)
+ return 1;
- default:
- return 0;
- }
+ return generic_force_reloc (fixP);
}
/* Here we decide which fixups can be adjusted to make them relative
tc_m68hc11_fix_adjustable (fixP)
fixS *fixP;
{
- /* Prevent all adjustments to global symbols. */
- if (! relaxable_symbol (fixP->fx_addsy))
- return 0;
-
switch (fixP->fx_r_type)
{
/* For the linker relaxation to work correctly, these relocs
need to be on the symbol itself. */
case BFD_RELOC_16:
- case BFD_RELOC_LO16:
case BFD_RELOC_M68HC11_RL_JUMP:
case BFD_RELOC_M68HC11_RL_GROUP:
case BFD_RELOC_VTABLE_INHERIT:
case BFD_RELOC_VTABLE_ENTRY:
+ case BFD_RELOC_32:
+
+ /* The memory bank addressing translation also needs the original
+ symbol. */
+ case BFD_RELOC_M68HC11_LO16:
+ case BFD_RELOC_M68HC11_PAGE:
+ case BFD_RELOC_M68HC11_24:
return 0;
- case BFD_RELOC_32:
default:
return 1;
}
if (fixP->fx_addsy == (symbolS *) NULL)
fixP->fx_done = 1;
- else if (fixP->fx_pcrel)
- ;
-
- else
- {
- value = fixP->fx_offset;
-
- if (fixP->fx_subsy != (symbolS *) NULL)
- {
- if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
- value -= S_GET_VALUE (fixP->fx_subsy);
- else
- /* We don't actually support subtracting a symbol. */
- as_bad_where (fixP->fx_file, fixP->fx_line,
- _("Expression too complex."));
- }
- }
+ /* We don't actually support subtracting a symbol. */
+ if (fixP->fx_subsy != (symbolS *) NULL)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
op_type = fixP->fx_r_type;
as_fatal (_("Line %d: unknown relocation type: 0x%x."),
fixP->fx_line, fixP->fx_r_type);
}
-
- /* Are we finished with this relocation now? */
- if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
- fixP->fx_done = 1;
}
/* Set the ELF specific flags. */
void
m68hc11_elf_final_processing ()
{
+ if (current_architecture & cpu6812s)
+ elf_flags |= EF_M68HCS12_MACH;
elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI;
elf_elfheader (stdoutput)->e_flags |= elf_flags;
}