X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-m32c.c;h=cae3302132e928f28274f83d7b653a628a40d4c4;hb=c32fa91d70ea20b38f90e5a88911f796b9a6418c;hp=930342294a7dda2589389e2569d5f1616be12fc2;hpb=7bc4c13c6114fe7f1b243fbe37001452d51f054c;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-m32c.c b/gas/config/tc-m32c.c index 930342294a..cae3302132 100644 --- a/gas/config/tc-m32c.c +++ b/gas/config/tc-m32c.c @@ -1,12 +1,12 @@ /* tc-m32c.c -- Assembler for the Renesas M32C. - Copyright (C) 2005, 2006 Free Software Foundation. + Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation. Contributed by RedHat. This file is part of GAS, the GNU Assembler. GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. GAS is distributed in the hope that it will be useful, @@ -52,8 +52,8 @@ typedef struct } m32c_insn; -#define rl_for(insn) (CGEN_ATTR_CGEN_INSN_RL_TYPE_VALUE (&(insn.insn->base->attrs))) -#define relaxable(insn) (CGEN_ATTR_CGEN_INSN_RELAXABLE_VALUE (&(insn.insn->base->attrs))) +#define rl_for(_insn) (CGEN_ATTR_CGEN_INSN_RL_TYPE_VALUE (&((_insn).insn->base->attrs))) +#define relaxable(_insn) (CGEN_ATTR_CGEN_INSN_RELAXABLE_VALUE (&((_insn).insn->base->attrs))) const char comment_chars[] = ";"; const char line_comment_chars[] = "#"; @@ -68,12 +68,14 @@ const char * md_shortopts = M32C_SHORTOPTS; #define OPTION_CPU_M16C (OPTION_MD_BASE) #define OPTION_CPU_M32C (OPTION_MD_BASE + 1) #define OPTION_LINKRELAX (OPTION_MD_BASE + 2) +#define OPTION_H_TICK_HEX (OPTION_MD_BASE + 3) struct option md_longopts[] = { { "m16c", no_argument, NULL, OPTION_CPU_M16C }, { "m32c", no_argument, NULL, OPTION_CPU_M32C }, { "relax", no_argument, NULL, OPTION_LINKRELAX }, + { "h-tick-hex", no_argument, NULL, OPTION_H_TICK_HEX }, {NULL, no_argument, NULL, 0} }; size_t md_longopts_size = sizeof (md_longopts); @@ -125,6 +127,10 @@ md_parse_option (int c, char * arg ATTRIBUTE_UNUSED) m32c_relax = 1; break; + case OPTION_H_TICK_HEX: + enable_h_tick_hex = 1; + break; + default: return 0; } @@ -448,7 +454,12 @@ const relax_typeS md_relax_table[] = /* 19 */ { 32767, -32768, 3, 20 }, /* jsr16.w */ /* 20 */ { 0, 0, 4, 0 }, /* jsr16.a */ /* 21 */ { 32767, -32768, 3, 11 }, /* jsr32.w */ - /* 22 */ { 0, 0, 4, 0 } /* jsr32.a */ + /* 22 */ { 0, 0, 4, 0 }, /* jsr32.a */ + + /* 23 */ { 0, 0, 3, 0 }, /* adjnz pc8 */ + /* 24 */ { 0, 0, 4, 0 }, /* adjnz disp8 pc8 */ + /* 25 */ { 0, 0, 5, 0 }, /* adjnz disp16 pc8 */ + /* 26 */ { 0, 0, 6, 0 } /* adjnz disp24 pc8 */ }; enum { @@ -458,6 +469,11 @@ enum { M32C_MACRO_JCND16_A, M32C_MACRO_JCND32_W, M32C_MACRO_JCND32_A, + /* the digit is the array index of the pcrel byte */ + M32C_MACRO_ADJNZ_2, + M32C_MACRO_ADJNZ_3, + M32C_MACRO_ADJNZ_4, + M32C_MACRO_ADJNZ_5, } M32C_Macros; static struct { @@ -494,7 +510,12 @@ static struct { /* 19 */ { M32C_INSN_JSR16_W, 3, M32C_INSN_JSR16_A, 2 }, /* 20 */ { M32C_INSN_JSR16_A, 4, M32C_INSN_JSR16_A, 0 }, /* 21 */ { M32C_INSN_JSR32_W, 3, M32C_INSN_JSR32_A, 2 }, - /* 22 */ { M32C_INSN_JSR32_A, 4, M32C_INSN_JSR32_A, 0 } + /* 22 */ { M32C_INSN_JSR32_A, 4, M32C_INSN_JSR32_A, 0 }, + + /* 23 */ { -M32C_MACRO_ADJNZ_2, 3, -M32C_MACRO_ADJNZ_2, 0 }, + /* 24 */ { -M32C_MACRO_ADJNZ_3, 4, -M32C_MACRO_ADJNZ_3, 0 }, + /* 25 */ { -M32C_MACRO_ADJNZ_4, 5, -M32C_MACRO_ADJNZ_4, 0 }, + /* 26 */ { -M32C_MACRO_ADJNZ_5, 6, -M32C_MACRO_ADJNZ_5, 0 } }; #define NUM_MAPPINGS (sizeof (subtype_mappings) / sizeof (subtype_mappings[0])) @@ -509,11 +530,21 @@ m32c_prepare_relax_scan (fragS *fragP, offsetT *aim, relax_substateT this_state) } static int -insn_to_subtype (int insn) +insn_to_subtype (int inum, const CGEN_INSN *insn) { unsigned int i; + + if (insn + && (strncmp (insn->base->mnemonic, "adjnz", 5) == 0 + || strncmp (insn->base->mnemonic, "sbjnz", 5) == 0)) + { + i = 23 + insn->base->bitsize/8 - 3; + /*printf("mapping %d used for %s\n", i, insn->base->mnemonic);*/ + return i; + } + for (i=0; ifr_opcode - fragP->fr_literal; if (fragP->fr_subtype == 1) - fragP->fr_subtype = insn_to_subtype (fragP->fr_cgen.insn->base->num); + fragP->fr_subtype = insn_to_subtype (fragP->fr_cgen.insn->base->num, fragP->fr_cgen.insn); if (S_GET_SEGMENT (fragP->fr_symbol) != segment) { int new_insn; new_insn = subtype_mappings[fragP->fr_subtype].insn_for_extern; - fragP->fr_subtype = insn_to_subtype (new_insn); + fragP->fr_subtype = insn_to_subtype (new_insn, 0); } if (fragP->fr_cgen.insn->base @@ -833,6 +864,26 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, rl_addend = 0x41; break; + case -M32C_MACRO_ADJNZ_2: + rl_addend = 0x31; + op[2] = addend - 2; + operand = M32C_OPERAND_LAB_16_8; + break; + case -M32C_MACRO_ADJNZ_3: + rl_addend = 0x41; + op[3] = addend - 2; + operand = M32C_OPERAND_LAB_24_8; + break; + case -M32C_MACRO_ADJNZ_4: + rl_addend = 0x51; + op[4] = addend - 2; + operand = M32C_OPERAND_LAB_32_8; + break; + case -M32C_MACRO_ADJNZ_5: + rl_addend = 0x61; + op[5] = addend - 2; + operand = M32C_OPERAND_LAB_40_8; + break; default: @@ -858,15 +909,16 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, || (m32c_relax && (operand != M32C_OPERAND_LAB_5_3 && operand != M32C_OPERAND_LAB32_JMP_S))) { - assert (fragP->fr_cgen.insn != 0); - gas_cgen_record_fixup (fragP, - where, - fragP->fr_cgen.insn, - (fragP->fr_fix - where) * 8, - cgen_operand_lookup_by_num (gas_cgen_cpu_desc, - operand), - fragP->fr_cgen.opinfo, - fragP->fr_symbol, fragP->fr_offset); + fixS *fixP; + gas_assert (fragP->fr_cgen.insn != 0); + fixP = gas_cgen_record_fixup (fragP, + where, + fragP->fr_cgen.insn, + (fragP->fr_fix - where) * 8, + cgen_operand_lookup_by_num (gas_cgen_cpu_desc, + operand), + fragP->fr_cgen.opinfo, + fragP->fr_symbol, fragP->fr_offset); } } @@ -1018,6 +1070,37 @@ md_cgen_lookup_reloc (const CGEN_INSN * insn ATTRIBUTE_UNUSED, return BFD_RELOC_NONE; } +void +m32c_cons_fix_new (fragS * frag, + int where, + int size, + expressionS *exp) +{ + bfd_reloc_code_real_type type; + + switch (size) + { + case 1: + type = BFD_RELOC_8; + break; + case 2: + type = BFD_RELOC_16; + break; + case 3: + type = BFD_RELOC_24; + break; + case 4: + default: + type = BFD_RELOC_32; + break; + case 8: + type = BFD_RELOC_64; + break; + } + + fix_new_exp (frag, where, (int) size, exp, 0, type); +} + void m32c_apply_fix (struct fix *f, valueT *t, segT s) { @@ -1131,47 +1214,7 @@ md_number_to_chars (char * buf, valueT val, int n) char * md_atof (int type, char * litP, int * sizeP) { - int i; - int prec; - LITTLENUM_TYPE words [MAX_LITTLENUMS]; - char * t; - - switch (type) - { - case 'f': - case 'F': - case 's': - case 'S': - prec = 2; - break; - - case 'd': - case 'D': - case 'r': - case 'R': - prec = 4; - break; - - /* FIXME: Some targets allow other format chars for bigger sizes here. */ - - default: - * sizeP = 0; - return _("Bad call to md_atof()"); - } - - t = atof_ieee (input_line_pointer, type, words); - if (t) - input_line_pointer = t; - * sizeP = prec * sizeof (LITTLENUM_TYPE); - - for (i = 0; i < prec; i++) - { - md_number_to_chars (litP, (valueT) words[i], - sizeof (LITTLENUM_TYPE)); - litP += sizeof (LITTLENUM_TYPE); - } - - return 0; + return ieee_md_atof (type, litP, sizeP, TRUE); } bfd_boolean @@ -1260,8 +1303,6 @@ m32c_fix_adjustable (fixS * fixP) } /* Worker function for m32c_is_colon_insn(). */ -static char restore_colon PARAMS ((int)); - static char restore_colon (int advance_i_l_p_by) {