X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-m68hc11.c;h=2f80e0adb23f3a437d7c0bd3a2946e65612daeca;hb=e18382406ce321517210e0fdb6a8a0d417078fef;hp=6211f9dcab2b88a475aa8d7e5b466d322cf8a04b;hpb=6927f98292aaa6f7fcb3152d5d902758538e626c;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-m68hc11.c b/gas/config/tc-m68hc11.c index 6211f9dcab..2f80e0adb2 100644 --- a/gas/config/tc-m68hc11.c +++ b/gas/config/tc-m68hc11.c @@ -1,7 +1,5 @@ /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12. - Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, - 2011, 2012 - Free Software Foundation, Inc. + Copyright (C) 1999-2016 Free Software Foundation, Inc. Written by Stephane Carrez (stcarrez@nerim.fr) XGATE and S12X added by James Murray (jsm@jsm-net.demon.co.uk) @@ -225,6 +223,9 @@ static void s_m68hc11_relax (int); /* Pseudo op to control the ELF flags. */ static void s_m68hc11_mode (int); +/* Process directives specified via pseudo ops. */ +static void s_m68hc11_parse_pseudo_instruction (int); + /* Mark the symbols with STO_M68HC12_FAR to indicate the functions are using 'rtc' for returning. It is necessary to use 'call' to invoke them. This is also used by the debugger to correctly @@ -314,6 +315,9 @@ const pseudo_typeS md_pseudo_table[] = /* .interrupt instruction. */ {"interrupt", s_m68hc11_mark_symbol, STO_M68HC12_INTERRUPT}, + /* .nobankwarning instruction. */ + {"nobankwarning", s_m68hc11_parse_pseudo_instruction, E_M68HC11_NO_BANK_WARNING}, + {0, 0, 0} }; @@ -486,7 +490,7 @@ m68hc11_print_statistics (FILE *file) } int -md_parse_option (int c, char *arg) +md_parse_option (int c, const char *arg) { get_default_target (); switch (c) @@ -570,7 +574,7 @@ md_undefined_symbol (char *name ATTRIBUTE_UNUSED) return 0; } -char * +const char * md_atof (int type, char *litP, int *sizeP) { return ieee_md_atof (type, litP, sizeP, TRUE); @@ -580,7 +584,7 @@ valueT md_section_align (asection *seg, valueT addr) { int align = bfd_get_section_alignment (stdoutput, seg); - return ((addr + (1 << align) - 1) & (-1 << align)); + return ((addr + (1 << align) - 1) & -(1 << align)); } static int @@ -599,7 +603,7 @@ cmp_opcode (struct m68hc11_opcode *op1, struct m68hc11_opcode *op2) void md_begin (void) { - char *prev_name = ""; + const char *prev_name = ""; struct m68hc11_opcode *opcodes; struct m68hc11_opcode_def *opc = 0; int i, j; @@ -609,9 +613,7 @@ md_begin (void) m68hc11_hash = hash_new (); /* Get a writable copy of the opcode table and sort it on the names. */ - opcodes = (struct m68hc11_opcode *) xmalloc (m68hc11_num_opcodes * - sizeof (struct - m68hc11_opcode)); + opcodes = XNEWVEC (struct m68hc11_opcode, m68hc11_num_opcodes); m68hc11_sorted_opcodes = opcodes; num_opcodes = 0; for (i = 0; i < m68hc11_num_opcodes; i++) @@ -640,8 +642,7 @@ md_begin (void) qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode), (int (*) (const void*, const void*)) cmp_opcode); - opc = (struct m68hc11_opcode_def *) - xmalloc (num_opcodes * sizeof (struct m68hc11_opcode_def)); + opc = XNEWVEC (struct m68hc11_opcode_def, num_opcodes); m68hc11_opcode_defs = opc--; /* Insert unique names into hash table. The M6811 instruction set @@ -960,7 +961,7 @@ static void print_opcode_list (void) { int i; - char *prev_name = ""; + const char *prev_name = ""; struct m68hc11_opcode *opcodes; int example = flag_print_opcodes == 2; @@ -1597,16 +1598,13 @@ fixup8 (expressionS *oper, int mode, int opmode) if (mode == M6811_OP_JUMP_REL) { - fixS *fixp; - - fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1, - oper, TRUE, BFD_RELOC_8_PCREL); - fixp->fx_pcrel_adjust = 1; + fix_new_exp (frag_now, f - frag_now->fr_literal, 1, + oper, TRUE, BFD_RELOC_8_PCREL); } else { fixS *fixp; - int reloc; + bfd_reloc_code_real_type reloc; /* Now create an 8-bit fixup. If there was some %hi, %lo or %page modifier, generate the reloc accordingly. */ @@ -1653,7 +1651,7 @@ fixup16 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED) else if (oper->X_op != O_register) { fixS *fixp; - int reloc; + bfd_reloc_code_real_type reloc; if ((opmode & M6811_OP_CALL_ADDR) && (mode & M6811_OP_IMM16)) reloc = BFD_RELOC_M68HC11_LO16; @@ -1670,8 +1668,7 @@ fixup16 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED) reloc == BFD_RELOC_16_PCREL, reloc); number_to_chars_bigendian (f, 0, 2); - if (reloc == BFD_RELOC_16_PCREL) - fixp->fx_pcrel_adjust = 2; + if (reloc == BFD_RELOC_M68HC11_LO16) fixp->fx_no_overflow = 1; } @@ -1724,7 +1721,7 @@ fixup8_xg (expressionS *oper, int mode, int opmode) if (oper->X_op == O_constant) { fixS *fixp; - int reloc; + bfd_reloc_code_real_type reloc; if ((opmode & M6811_OP_HIGH_ADDR) || (opmode & M6811_OP_LOW_ADDR)) { @@ -1750,28 +1747,22 @@ fixup8_xg (expressionS *oper, int mode, int opmode) { if (mode == M68XG_OP_REL9) { - fixS *fixp; - /* Future improvement: This fixup/reloc isn't adding on constants to symbols. */ - fixp = fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2, - oper, TRUE, BFD_RELOC_M68HC12_9_PCREL); - fixp->fx_pcrel_adjust = 1; + fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2, + oper, TRUE, BFD_RELOC_M68HC12_9_PCREL); } else if (mode == M68XG_OP_REL10) { - fixS *fixp; - /* Future improvement: This fixup/reloc isn't adding on constants to symbols. */ - fixp = fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2, - oper, TRUE, BFD_RELOC_M68HC12_10_PCREL); - fixp->fx_pcrel_adjust = 1; + fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2, + oper, TRUE, BFD_RELOC_M68HC12_10_PCREL); } else { fixS *fixp; - int reloc; + bfd_reloc_code_real_type reloc; /* Now create an 8-bit fixup. If there was some %hi, %lo modifier, generate the reloc accordingly. */ @@ -2147,8 +2138,8 @@ build_indexed_byte (operand *op, int format ATTRIBUTE_UNUSED, int move_insn) if (!check_range (val, M6812_OP_IDX)) as_bad (_("Offset out of 16-bit range: %ld."), val); - if (move_insn && !(val >= -16 && val <= 15) - && ((!(mode & M6812_OP_IDX) && !(mode & M6812_OP_D_IDX_2)) + if (move_insn && !(val >= -16 && val <= 15) + && ((!(mode & M6812_OP_IDX) && !(mode & M6812_OP_D_IDX_2)) || !(current_architecture & cpu9s12x))) { as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."), @@ -2221,11 +2212,11 @@ build_indexed_byte (operand *op, int format ATTRIBUTE_UNUSED, int move_insn) /* Must treat as a 16bit relocate as size of final result is unknown. */ byte <<= 3; - byte |= 0b11100010; + byte |= 0xe2; number_to_chars_bigendian (f, byte, 1); + f = frag_more (2); fix_new (frag_now, f - frag_now->fr_literal, 2, sym, off, 0, BFD_RELOC_M68HC12_16B); - f = frag_more (2); return 1; } else @@ -2426,7 +2417,7 @@ build_insn_xg (struct m68hc11_opcode *opcode, f = m68hc11_new_insn (1); number_to_chars_bigendian (f, opcode->opcode >> 8, 1); /* High byte. */ fixup8_xg (&operands[0].exp, format, M68XG_OP_REL9); - } + } else if (format & M68XG_OP_REL10) { f = m68hc11_new_insn (1); @@ -2955,7 +2946,7 @@ md_assemble (char *str) } else as_bad ("No opcode found\n"); - + return; } else @@ -2979,7 +2970,7 @@ md_assemble (char *str) { opcode_local.opcode |= (operands[0].exp.X_add_number); operands[0].mode = M68XG_OP_IMM3; - + opcode = find (opc, operands, 1); if (opcode) { @@ -3073,7 +3064,7 @@ md_assemble (char *str) if (opc->format & (M68XG_OP_REL9 | M68XG_OP_REL10)) { - opcode_local.format = opc->format; + opcode_local.format = opc->format; input_line_pointer = skip_whites (input_line_pointer); expression (&operands[0].exp); if (operands[0].exp.X_op == O_illegal) @@ -3099,12 +3090,12 @@ md_assemble (char *str) if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r') || (*input_line_pointer == '\0')) return; /* nothing left */ - + if (*input_line_pointer == '#') { as_bad ("No register specified before hash\n"); return; - } + } /* first operand is expected to be a register */ if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r')) @@ -3171,12 +3162,12 @@ md_assemble (char *str) if (opcode) opcode_local.opcode = opcode->opcode | (operands[0].reg1 << 8); - + if (operands[0].exp.X_op != O_constant) as_bad ("Only constants supported at for IMM4 mode\n"); else { - if (check_range + if (check_range (operands[0].exp.X_add_number,M68XG_OP_R_IMM4)) opcode_local.opcode |= (operands[0].exp.X_add_number << 4); @@ -3232,7 +3223,7 @@ md_assemble (char *str) com RD, RS alias for xnor RD,R0,RS mov RD, RS alias for or RD, R0, RS neg RD, RS alias for sub RD, R0, RS */ - opcode_local.opcode = opcode->opcode + opcode_local.opcode = opcode->opcode | (operands[0].reg1 << 8) | (operands[1].reg1 << 2); } else if ((strncmp (opc->opcode->name, "cmp",3) == 0) @@ -3241,7 +3232,7 @@ md_assemble (char *str) /* special cases for: cmp RS1, RS2 alias for sub R0, RS1, RS2 cpc RS1, RS2 alias for sbc R0, RS1, RS2 */ - opcode_local.opcode = opcode->opcode + opcode_local.opcode = opcode->opcode | (operands[0].reg1 << 5) | (operands[1].reg1 << 2); } else @@ -3283,7 +3274,7 @@ md_assemble (char *str) opcode = find (opc, operands, 1); if (opcode) { - opcode_local.opcode = opcode->opcode + opcode_local.opcode = opcode->opcode | (operands[0].reg1 << 8) | (operands[1].reg1 << 5) | (operands[2].reg1 << 2); opcode_local.format = M68XG_OP_NONE; @@ -3320,7 +3311,7 @@ md_assemble (char *str) } input_line_pointer = skip_whites (input_line_pointer); - + if (*input_line_pointer != ',') { as_bad (_("Missing operand.")); @@ -3355,7 +3346,7 @@ md_assemble (char *str) { input_line_pointer++; } - + /* Ok so far, can only be one mode. */ opcode_local.format = M68XG_OP_R_R_OFFS5; operands[0].mode = M68XG_OP_R_R_OFFS5; @@ -3766,10 +3757,9 @@ s_m68hc11_mark_symbol (int mark) do { - name = input_line_pointer; - c = get_symbol_end (); + c = get_symbol_name (&name); symbolP = symbol_find_or_make (name); - *input_line_pointer = c; + (void) restore_line_pointer (c); SKIP_WHITESPACE (); @@ -3838,8 +3828,8 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) { arelent *reloc; - reloc = (arelent *) xmalloc (sizeof (arelent)); - reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + reloc = XNEW (arelent); + reloc->sym_ptr_ptr = XNEW (asymbol *); *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; if (fixp->fx_r_type == 0) @@ -3959,13 +3949,12 @@ void md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED, fragS *fragP) { - fixS *fixp; long value; long disp; char *buffer_address = fragP->fr_literal; /* Address in object code of the displacement. */ - register int object_address = fragP->fr_fix + fragP->fr_address; + int object_address = fragP->fr_fix + fragP->fr_address; buffer_address += fragP->fr_fix; @@ -4012,10 +4001,9 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED, fragP->fr_opcode[1] = fragP->fr_opcode[0]; fragP->fr_opcode[0] = M6811_OPCODE_PAGE2; - fixp = fix_new (fragP, fragP->fr_fix, 2, - fragP->fr_symbol, fragP->fr_offset, 1, + fix_new (fragP, fragP->fr_fix, 2, + fragP->fr_symbol, fragP->fr_offset, 1, BFD_RELOC_16_PCREL); - fixp->fx_pcrel_adjust = 2; fragP->fr_fix += 2; break; @@ -4054,9 +4042,9 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED, && 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); + fix_new (fragP, fragP->fr_fix, 2, + fragP->fr_symbol, fragP->fr_offset, + 1, BFD_RELOC_16_PCREL); } else { @@ -4441,7 +4429,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) value); if (value >= 0) where[0] |= value; - else + else where[0] |= (0x10 | (16 + value)); break; @@ -4453,7 +4441,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) /* sign bit already in xb postbyte */ if (value >= 0) where[1] = value; - else + else where[1] = (256 + value); break; @@ -4465,8 +4453,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) if (value < 0) value += 65536; - where[1] = (value >> 8); - where[2] = (value & 0xff); + where[0] = (value >> 8); + where[1] = (value & 0xff); break; case BFD_RELOC_M68HC11_RL_JUMP: @@ -4491,3 +4479,17 @@ m68hc11_elf_final_processing (void) elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI; elf_elfheader (stdoutput)->e_flags |= elf_flags; } + +/* Process directives specified via pseudo ops */ +static void +s_m68hc11_parse_pseudo_instruction (int pseudo_insn) +{ + switch (pseudo_insn) + { + case E_M68HC11_NO_BANK_WARNING: + elf_flags |= E_M68HC11_NO_BANK_WARNING; + break; + default: + as_bad (_("Invalid directive")); + } +}