/* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
- Copyright (C) 1999, 2000 Free Software Foundation.
+ Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
Written by Stephane Carrez (stcarrez@worldnet.fr)
This file is part of GAS, the GNU Assembler.
#include "opcode/m68hc11.h"
#include "dwarf2dbg.h"
-struct dwarf2_line_info debug_line;
-
const char comment_chars[] = ";!";
const char line_comment_chars[] = "#*";
const char line_separator_chars[] = "";
/* This macro has no side-effects. */
#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
+#define RELAX_STATE(s) ((s) >> 2)
+#define RELAX_LENGTH(s) ((s) & 3)
#define IS_OPCODE(C1,C2) (((C1) & 0x0FF) == ((C2) & 0x0FF))
How many bytes this mode will add to the size of the frag.
Which mode to go to if the offset won't fit in this one. */
-relax_typeS md_relax_table[] =
-{
+relax_typeS md_relax_table[] = {
{1, 1, 0, 0}, /* First entries aren't used. */
{1, 1, 0, 0}, /* For no good reason except. */
{1, 1, 0, 0}, /* that the VAX doesn't either. */
/* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
{(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
{(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
- {0, 0, 1, 0},
+ {0, 0, 2, 0},
{1, 1, 0, 0},
/* Relax for dbeq/ibeq/tbeq r,<L>:
};
/* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
-typedef enum register_id
-{
+typedef enum register_id {
REG_NONE = -1,
REG_A = 0,
REG_B = 1,
REG_PC = 8
} register_id;
-typedef struct operand
-{
+typedef struct operand {
expressionS exp;
register_id reg1;
register_id reg2;
int mode;
} operand;
-struct m68hc11_opcode_def
-{
+struct m68hc11_opcode_def {
long format;
int min_operands;
int max_operands;
static struct m68hc11_opcode_def *m68hc11_opcode_defs = 0;
static int m68hc11_nb_opcode_defs = 0;
-typedef struct alias
-{
+typedef struct alias {
const char *name;
const char *alias;
-}
-alias;
+} alias;
-static alias alias_opcodes[] =
-{
+static alias alias_opcodes[] = {
{"cpd", "cmpd"},
{"cpx", "cmpx"},
{"cpy", "cmpy"},
pseudo-op name without dot
function to call to execute this pseudo-op
Integer arg to pass to the function. */
-const pseudo_typeS md_pseudo_table[] =
-{
+const pseudo_typeS md_pseudo_table[] = {
/* The following pseudo-ops are supported for MRI compatibility. */
{"fcb", cons, 1},
{"fdb", cons, 2},
{"fcc", stringer, 1},
{"rmb", s_space, 0},
+
+ /* Dwarf2 support for Gcc. */
{"file", dwarf2_directive_file, 0},
{"loc", dwarf2_directive_loc, 0},
+ /* Motorola ALIS. */
+ {"xrefb", s_ignore, 0}, /* Same as xref */
+
{0, 0, 0}
};
\f
CONST char *md_shortopts = "Sm:";
-struct option md_longopts[] =
-{
+struct option md_longopts[] = {
#define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
{"force-long-branchs", no_argument, NULL, OPTION_FORCE_LONG_BRANCH},
return 0;
}
+/* Listing header selected according to cpu. */
+const char *
+m68hc11_listing_header ()
+{
+ if (current_architecture & cpu6811)
+ return "M68HC11 GAS ";
+ else
+ return "M68HC12 GAS ";
+}
+
void
md_show_usage (stream)
FILE *stream;
get_default_target ();
switch (c)
{
- /* -S means keep external to 2 bits offset rather than 16 bits one. */
+ /* -S means keep external to 2 bit offset rather than 16 bit one. */
case OPTION_SHORT_BRANCHS:
case 'S':
flag_fixed_branchs = 1;
if (*p == ',')
{
+ int possible_mode = M6811_OP_NONE;
+ char *old_input_line;
p++;
/* 68HC12 pre increment or decrement. */
{
if (*p == '-')
{
- mode = M6812_PRE_DEC;
+ possible_mode = M6812_PRE_DEC;
p++;
- if (current_architecture & cpu6811)
- as_bad (_("Pre-decrement mode is not valid for 68HC11"));
}
else if (*p == '+')
{
- mode = M6812_PRE_INC;
+ possible_mode = M6812_PRE_INC;
p++;
- if (current_architecture & cpu6811)
- as_bad (_("Pre-increment mode is not valid for 68HC11"));
}
p = skip_whites (p);
}
+ old_input_line = input_line_pointer;
input_line_pointer = p;
reg = register_name ();
+ /* Backtrack if we have a valid constant expression and
+ it does not correspond to the offset of the 68HC12 indexed
+ addressing mode (as in N,x). */
+ if (reg == REG_NONE && mode == M6811_OP_NONE
+ && possible_mode != M6811_OP_NONE)
+ {
+ oper->mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
+ input_line_pointer = skip_whites (old_input_line);
+ return 1;
+ }
+
+ if (possible_mode != M6811_OP_NONE)
+ mode = possible_mode;
+
+ if ((current_architecture & cpu6811)
+ && possible_mode != M6811_OP_NONE)
+ as_bad (_("Pre-increment mode is not valid for 68HC11"));
/* Backtrack. */
if (which == 0 && opmode & M6812_OP_IDX_P2
&& reg != REG_X && reg != REG_Y
if (mode & M6812_AUTO_INC_DEC)
return (num != 0 && num <= 8 && num >= -8);
- /* The 68HC12 supports 5, 9 and 16-bits offsets. */
+ /* The 68HC12 supports 5, 9 and 16-bit offsets. */
if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX))
mode = M6811_OP_IND16;
}
}
-/* Put a 2 bytes expression described by 'oper'. If this expression contains
+/* Put a 2 byte expression described by 'oper'. If this expression contains
unresolved symbols, generate a 16-bit fixup. */
static void
fixup16 (oper, mode, opmode)
f = frag_more (size);
- /* Emit line number information in dwarf2 debug sections. */
- if (debug_type == DEBUG_DWARF2)
- {
- bfd_vma addr;
+ dwarf2_emit_insn (size);
- dwarf2_where (&debug_line);
- addr = frag_now->fr_address + frag_now_fix () - size;
- dwarf2_gen_line_info (addr, &debug_line);
- }
return f;
}
int jmp_mode;
{
unsigned char code;
- int insn_size;
char *f;
unsigned long n;
assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE);
code = opcode->opcode;
- insn_size = 1;
n = operands[0].exp.X_add_number;
opcode = m68hc11_new_insn (2);
number_to_chars_bigendian (opcode, code, 1);
number_to_chars_bigendian (opcode + 1, 0, 1);
- frag_var (rs_machine_dependent, 1, 1,
+ frag_var (rs_machine_dependent, 2, 1,
ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
operands[0].exp.X_add_symbol, (offsetT) n, opcode);
}
int jmp_mode;
{
unsigned char code;
- int insn_size;
char *f;
unsigned long n;
assert (operands[0].reg1 != REG_NONE);
code = opcode->opcode & 0x0FF;
- insn_size = 1;
f = m68hc11_new_insn (1);
number_to_chars_bigendian (f, code, 1);
if (move_insn && !(val >= -16 && val <= 15))
{
- as_bad (_("Offset out of 5-bit range for movw/movb insn."));
+ as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
+ val);
return -1;
}
return 3;
}
}
- f = frag_more (1);
- number_to_chars_bigendian (f, byte, 1);
-#if 0
- fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
- &op->exp, false, BFD_RELOC_16);
-#endif
- frag_var (rs_machine_dependent, 2, 2,
- ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
- op->exp.X_add_symbol, val, f);
+ if (op->reg1 != REG_PC)
+ {
+ byte = (byte << 3) | 0xe2;
+ 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);
+ }
+ 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),
+ op->exp.X_add_symbol,
+ op->exp.X_add_number, f);
+ }
return 3;
}
{
int i;
char *f;
- int insn_size = 1;
long format;
int move_insn = 0;
number_to_chars_bigendian (f, page_code, 1);
f++;
- insn_size = 2;
}
else
f = m68hc11_new_insn (1);
move_insn = 1;
if (format & M6812_OP_IDX)
{
- insn_size += build_indexed_byte (&operands[0], format, 1);
+ build_indexed_byte (&operands[0], format, 1);
i = 1;
format &= ~M6812_OP_IDX;
}
if (format & M6812_OP_IDX_P2)
{
- insn_size += build_indexed_byte (&operands[1], format, 1);
+ build_indexed_byte (&operands[1], format, 1);
i = 0;
format &= ~M6812_OP_IDX_P2;
}
if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
{
- insn_size++;
fixup8 (&operands[i].exp,
format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
operands[i].mode);
}
else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
{
- insn_size += 2;
fixup16 (&operands[i].exp, format & (M6811_OP_IMM16 | M6811_OP_IND16),
operands[i].mode);
i++;
if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y))
as_bad (_("Invalid indexed register, expecting register Y."));
- insn_size++;
fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
i = 1;
}
else if (format &
(M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1 | M6812_OP_D_IDX))
{
- insn_size += build_indexed_byte (&operands[i], format, move_insn);
+ build_indexed_byte (&operands[i], format, move_insn);
i++;
}
else if (format & M6812_OP_REG && current_architecture & cpu6812)
{
- insn_size += build_reg_mode (&operands[i], format);
+ build_reg_mode (&operands[i], format);
i++;
}
if (format & M6811_OP_BITMASK)
{
- insn_size++;
fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
i++;
}
if (format & M6811_OP_JUMP_REL)
{
- insn_size++;
fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
- i++;
}
else if (format & M6812_OP_IND16_P2)
{
- insn_size += 2;
fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
}
}
}
if (mode & M6812_OP_REG)
{
- if (i == 0 && format & M6812_OP_REG
- && operands[i].reg2 == REG_NONE)
+ if (i == 0
+ && (format & M6812_OP_REG)
+ && (operands[i].reg2 == REG_NONE))
continue;
- if (i == 0 && format & M6812_OP_REG
- && format & M6812_OP_REG_2 && operands[i].reg2 != REG_NONE)
- {
- continue;
- }
- if (i == 0 && format & M6812_OP_D_IDX)
+ if (i == 0
+ && (format & M6812_OP_REG)
+ && (format & M6812_OP_REG_2)
+ && (operands[i].reg2 != REG_NONE))
continue;
- if (i == 0 && (format & M6812_OP_IDX)
+ if (i == 0
+ && (format & M6812_OP_IDX)
+ && (operands[i].reg2 != REG_NONE))
+ continue;
+ if (i == 0
+ && (format & M6812_OP_D_IDX))
+ continue;
+ if (i == 0
+ && (format & M6812_OP_IDX)
&& (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
continue;
- if (i == 1 && format & M6812_OP_IDX_P2)
+ if (i == 1
+ && (format & M6812_OP_IDX_P2))
continue;
break;
}
if (*input_line_pointer == ',')
input_line_pointer++;
}
-
+
return 0;
}
}
/* Identify a possible instruction alias. There are some on the
- 68HC12 to emulate a fiew 68HC11 instructions. */
+ 68HC12 to emulate a few 68HC11 instructions. */
if (opc == NULL && (current_architecture & cpu6812))
{
int i;
fragS *fragP;
{
fixS *fixp;
+ long value;
long disp;
char *buffer_address = fragP->fr_literal;
buffer_address += fragP->fr_fix;
/* The displacement of the address, from current location. */
- disp = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0;
- disp = (disp + fragP->fr_offset) - object_address;
- disp += symbol_get_frag (fragP->fr_symbol)->fr_address;
+ value = S_GET_VALUE (fragP->fr_symbol);
+ disp = (value + fragP->fr_offset) - object_address;
switch (fragP->fr_subtype)
{
break;
case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
- fragP->fr_opcode[0] = fragP->fr_opcode[0] << 5;
- fragP->fr_opcode[0] |= disp & 0x1f;
+ 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;
break;
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, 1,
+ fix_new (fragP, fragP->fr_fix, 1,
fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_8);
fragP->fr_fix += 1;
break;
case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
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 += 1;
+ fragP->fr_opcode[0] |= 0xe2;
+ if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa)
+ {
+ 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
+ {
+ fix_new (fragP, fragP->fr_fix, 2,
+ fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
+ }
+ fragP->fr_fix += 2;
break;
case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
}
}
+/* On an ELF system, we can't relax a weak symbol. The weak symbol
+ can be overridden at final link time by a non weak symbol. We can
+ relax externally visible symbol because there is no shared library
+ and such symbol can't be overridden (unless they are weak). */
+static int
+relaxable_symbol (symbol)
+ symbolS *symbol;
+{
+ return ! S_IS_WEAK (symbol);
+}
+
/* Force truly undefined symbols to their maximum size, and generally set up
the frag list to be relaxed. */
int
fragS *fragP;
asection *segment;
{
- int old_fr_fix;
- char *buffer_address = fragP->fr_fix + fragP->fr_literal;
+ if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
+ {
+ if (S_GET_SEGMENT (fragP->fr_symbol) != segment
+ || !relaxable_symbol (fragP->fr_symbol))
+ {
+ /* Non-relaxable cases. */
+ int old_fr_fix;
+ char *buffer_address;
- old_fr_fix = fragP->fr_fix;
+ old_fr_fix = fragP->fr_fix;
+ buffer_address = fragP->fr_fix + fragP->fr_literal;
- switch (fragP->fr_subtype)
- {
- case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF):
+ switch (RELAX_STATE (fragP->fr_subtype))
+ {
+ case STATE_PC_RELATIVE:
+
+ /* This relax is only for bsr and bra. */
+ assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
+ || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
+ || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
+
+ if (flag_fixed_branchs)
+ as_bad_where (fragP->fr_file, fragP->fr_line,
+ _("bra or bsr with undefined symbol."));
+
+ /* The symbol is undefined or in a separate section.
+ Turn bra into a jmp and bsr into a jsr. The insn
+ becomes 3 bytes long (instead of 2). A fixup is
+ necessary for the unresolved symbol address. */
+ fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
+
+ fix_new (fragP, fragP->fr_fix - 1, 2, fragP->fr_symbol,
+ fragP->fr_offset, 0, BFD_RELOC_16);
+ fragP->fr_fix++;
+ break;
- /* This relax is only for bsr and bra. */
- assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
- || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
- || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
+ case STATE_CONDITIONAL_BRANCH:
+ assert (current_architecture & cpu6811);
- /* A relaxable case. */
- if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
- {
- fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
- }
- else
- {
- if (flag_fixed_branchs)
- as_bad_where (fragP->fr_file, fragP->fr_line,
- _("bra or bsr with undefined symbol."));
+ fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
+ fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
- /* The symbol is undefined or in a separate section. Turn bra into a
- jmp and bsr into a jsr. The insn becomes 3 bytes long (instead of
- 2). A fixup is necessary for the unresolved symbol address. */
+ /* Don't use fr_opcode[2] because this may be
+ in a different frag. */
+ buffer_address[0] = M6811_JMP;
- fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
+ fragP->fr_fix++;
+ fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
+ fragP->fr_offset, 0, BFD_RELOC_16);
+ fragP->fr_fix += 2;
+ break;
- fragP->fr_fix++;
- fix_new (fragP, old_fr_fix - 1, 2, fragP->fr_symbol,
- fragP->fr_offset, 0, BFD_RELOC_16);
- frag_wane (fragP);
- }
- break;
+ case STATE_INDEXED_OFFSET:
+ assert (current_architecture & cpu6812);
- case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF):
- assert (current_architecture & cpu6811);
+ /* 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++;
+ break;
- if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
- {
- fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
- STATE_BYTE);
- }
- else
- {
- fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
- fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
+ case STATE_XBCC_BRANCH:
+ assert (current_architecture & cpu6812);
+
+ fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
+ fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
+
+ /* Don't use fr_opcode[2] because this may be
+ in a different frag. */
+ buffer_address[0] = M6812_JMP;
+
+ fragP->fr_fix++;
+ fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
+ fragP->fr_offset, 0, BFD_RELOC_16);
+ fragP->fr_fix += 2;
+ break;
+
+ case STATE_CONDITIONAL_BRANCH_6812:
+ assert (current_architecture & cpu6812);
- /* Don't use fr_opcode[2] because this may be
- in a different frag. */
- buffer_address[0] = M6811_JMP;
+ /* Translate into a lbcc branch. */
+ fragP->fr_opcode[1] = fragP->fr_opcode[0];
+ fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
- fragP->fr_fix++;
- fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
- fragP->fr_offset, 0, BFD_RELOC_16);
- fragP->fr_fix += 2;
+ fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
+ fragP->fr_offset, 0, BFD_RELOC_16_PCREL);
+ fragP->fr_fix += 2;
+ break;
+
+ default:
+ as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
+ }
frag_wane (fragP);
- }
- break;
- case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF):
- assert (current_architecture & cpu6812);
+ /* Return the growth in the fixed part of the frag. */
+ return fragP->fr_fix - old_fr_fix;
+ }
- if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
+ /* Relaxable cases. */
+ switch (RELAX_STATE (fragP->fr_subtype))
{
+ case STATE_PC_RELATIVE:
+ /* This relax is only for bsr and bra. */
+ assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
+ || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
+ || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
+
+ fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
+ break;
+
+ case STATE_CONDITIONAL_BRANCH:
+ assert (current_architecture & cpu6811);
+
+ fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
+ STATE_BYTE);
+ break;
+
+ case STATE_INDEXED_OFFSET:
+ assert (current_architecture & cpu6812);
+
fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
STATE_BITS5);
- }
- else
- {
- /* Switch the indexed operation to 16-bit mode. */
- if ((fragP->fr_opcode[1] & 0x21) == 0x20)
- fragP->fr_opcode[1] = (fragP->fr_opcode[1] >> 3) | 0xc0 | 0x02;
-
- fragP->fr_fix++;
- fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
- fragP->fr_offset, 0, BFD_RELOC_16);
- fragP->fr_fix += 2;
- frag_wane (fragP);
- }
- break;
+ break;
- case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF):
- assert (current_architecture & cpu6812);
+ case STATE_XBCC_BRANCH:
+ assert (current_architecture & cpu6812);
- if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
- {
fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
- }
- else
- {
- fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
- fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
-
- /* Don't use fr_opcode[2] because this may be
- in a different frag. */
- buffer_address[0] = M6812_JMP;
-
- fragP->fr_fix++;
- fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
- fragP->fr_offset, 0, BFD_RELOC_16);
- fragP->fr_fix += 2;
- frag_wane (fragP);
- }
- break;
+ break;
- case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF):
- assert (current_architecture & cpu6812);
+ case STATE_CONDITIONAL_BRANCH_6812:
+ assert (current_architecture & cpu6812);
- if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
- {
fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
STATE_BYTE);
+ break;
}
- else
- {
- /* Translate into a lbcc branch. */
- fragP->fr_opcode[1] = fragP->fr_opcode[0];
- fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
-
- fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
- fragP->fr_offset, 0, BFD_RELOC_16_PCREL);
- fragP->fr_fix += 2;
- frag_wane (fragP);
- }
- break;
-
- default:
- as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
}
- return (fragP->fr_fix - old_fr_fix);
+ if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
+ as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
+
+ /* Return the size of the variable part of the frag. */
+ return md_relax_table[fragP->fr_subtype].rlx_length;
}
int
as_fatal (_("Line %d: unknown relocation type: 0x%x."),
fixp->fx_line, fixp->fx_r_type);
}
-
- return 0;
-}
-
-int
-m68hc11_cleanup ()
-{
- return 1;
-}
-
-void
-m68hc11_end_of_source ()
-{
- segT saved_seg;
- subsegT saved_subseg;
- segT debug_info;
- char *p;
- long total_size = 0;
-
- if (debug_type != DEBUG_DWARF2)
- return;
- dwarf2_finish ();
-
- saved_seg = now_seg;
- saved_subseg = now_subseg;
-
- debug_info = subseg_new (".debug_info", 0);
- bfd_set_section_flags (stdoutput, debug_info, SEC_READONLY);
- subseg_set (debug_info, 0);
- p = frag_more (10);
- total_size = 12;
-
-# define STUFF(val,size) md_number_to_chars (p, val, size); p += size;
- STUFF (total_size, 4); /* Length of compilation unit. */
- STUFF (2, 2); /* Dwarf version */
- STUFF (0, 4);
- STUFF (2, 1); /* Pointer size */
- STUFF (1, 1); /* Compile unit */
- STUFF (0, 4);
-
- now_subseg = saved_subseg;
- now_seg = saved_seg;
+ return 0;
}