X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-cr16.c;h=b7fffa7878030277ea74508b746357bafc7f6364;hb=9dfa3e63479d3c3106c7e5e86764a0ed8e22aa7f;hp=1ed74cda44238606f4d08b95b14874fec65038ba;hpb=aa820537ead0135a7c38c619039dce8a6fc74ed1;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-cr16.c b/gas/config/tc-cr16.c index 1ed74cda44..b7fffa7878 100644 --- a/gas/config/tc-cr16.c +++ b/gas/config/tc-cr16.c @@ -1,5 +1,5 @@ /* tc-cr16.c -- Assembler code for the CR16 CPU core. - Copyright 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2007-2016 Free Software Foundation, Inc. Contributed by M R Swami Reddy @@ -206,7 +206,7 @@ l_cons (int nbytes) return; } - value |= ((~(-1 << width) & exp.X_add_number) + value |= ((~(-(1 << width)) & exp.X_add_number) << ((BITS_PER_CHAR * nbytes) - bits_available)); if ((bits_available -= width) == 0 @@ -317,12 +317,12 @@ get_cc (char *cc_name) static reg get_register (char *reg_name) { - const reg_entry *reg; + const reg_entry *rreg; - reg = (const reg_entry *) hash_find (reg_hash, reg_name); + rreg = (const reg_entry *) hash_find (reg_hash, reg_name); - if (reg != NULL) - return reg->value.reg_val; + if (rreg != NULL) + return rreg->value.reg_val; return nullregister; } @@ -331,38 +331,38 @@ get_register (char *reg_name) static reg get_register_pair (char *reg_name) { - const reg_entry *reg; + const reg_entry *rreg; char tmp_rp[16]="\0"; /* Add '(' and ')' to the reg pair, if its not present. */ - if (reg_name[0] != '(') + if (reg_name[0] != '(') { tmp_rp[0] = '('; strcat (tmp_rp, reg_name); strcat (tmp_rp,")"); - reg = (const reg_entry *) hash_find (regp_hash, tmp_rp); + rreg = (const reg_entry *) hash_find (regp_hash, tmp_rp); } else - reg = (const reg_entry *) hash_find (regp_hash, reg_name); + rreg = (const reg_entry *) hash_find (regp_hash, reg_name); - if (reg != NULL) - return reg->value.reg_val; + if (rreg != NULL) + return rreg->value.reg_val; return nullregister; -} +} /* Get the index register 'reg_name'. */ static reg get_index_register (char *reg_name) { - const reg_entry *reg; + const reg_entry *rreg; - reg = (const reg_entry *) hash_find (reg_hash, reg_name); + rreg = (const reg_entry *) hash_find (reg_hash, reg_name); - if ((reg != NULL) - && ((reg->value.reg_val == 12) || (reg->value.reg_val == 13))) - return reg->value.reg_val; + if ((rreg != NULL) + && ((rreg->value.reg_val == 12) || (rreg->value.reg_val == 13))) + return rreg->value.reg_val; return nullregister; } @@ -371,17 +371,17 @@ get_index_register (char *reg_name) static reg get_index_register_pair (char *reg_name) { - const reg_entry *reg; + const reg_entry *rreg; - reg = (const reg_entry *) hash_find (regp_hash, reg_name); + rreg = (const reg_entry *) hash_find (regp_hash, reg_name); - if (reg != NULL) + if (rreg != NULL) { - if ((reg->value.reg_val != 1) || (reg->value.reg_val != 7) - || (reg->value.reg_val != 9) || (reg->value.reg_val > 10)) - return reg->value.reg_val; + if ((rreg->value.reg_val != 1) || (rreg->value.reg_val != 7) + || (rreg->value.reg_val != 9) || (rreg->value.reg_val > 10)) + return rreg->value.reg_val; - as_bad (_("Unknown register pair - index relative mode: `%d'"), reg->value.reg_val); + as_bad (_("Unknown register pair - index relative mode: `%d'"), rreg->value.reg_val); } return nullregister; @@ -392,12 +392,12 @@ get_index_register_pair (char *reg_name) static preg get_pregister (char *preg_name) { - const reg_entry *preg; + const reg_entry *prreg; - preg = (const reg_entry *) hash_find (preg_hash, preg_name); + prreg = (const reg_entry *) hash_find (preg_hash, preg_name); - if (preg != NULL) - return preg->value.preg_val; + if (prreg != NULL) + return prreg->value.preg_val; return nullpregister; } @@ -407,12 +407,12 @@ get_pregister (char *preg_name) static preg get_pregisterp (char *preg_name) { - const reg_entry *preg; + const reg_entry *prreg; - preg = (const reg_entry *) hash_find (pregp_hash, preg_name); + prreg = (const reg_entry *) hash_find (pregp_hash, preg_name); - if (preg != NULL) - return preg->value.preg_val; + if (prreg != NULL) + return prreg->value.preg_val; return nullpregister; } @@ -492,10 +492,9 @@ cr16_force_relocation (fixS *fix) /* Record a fixup for a cons expression. */ void -cr16_cons_fix_new (fragS *frag, int offset, int len, expressionS *exp) +cr16_cons_fix_new (fragS *frag, int offset, int len, expressionS *exp, + bfd_reloc_code_real_type rtype) { - int rtype = BFD_RELOC_UNUSED; - switch (len) { default: rtype = BFD_RELOC_NONE; break; @@ -521,17 +520,16 @@ arelent * tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP) { arelent * reloc; - bfd_reloc_code_real_type code; /* If symbols are local and resolved, then no relocation needed. */ - if ( ((fixP->fx_addsy) + if ( ((fixP->fx_addsy) && (S_GET_SEGMENT (fixP->fx_addsy) == absolute_section)) - || ((fixP->fx_subsy) + || ((fixP->fx_subsy) && (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section))) return NULL; - reloc = xmalloc (sizeof (arelent)); - reloc->sym_ptr_ptr = 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; reloc->addend = fixP->fx_offset; @@ -581,14 +579,12 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP) && GOT_symbol && fixP->fx_addsy == GOT_symbol) { - code = BFD_RELOC_CR16_GOT_REGREL20; reloc->addend = fixP->fx_offset = reloc->address; } else if ((fixP->fx_r_type == BFD_RELOC_CR16_GOTC_REGREL20) && GOT_symbol && fixP->fx_addsy == GOT_symbol) { - code = BFD_RELOC_CR16_GOTC_REGREL20; reloc->addend = fixP->fx_offset = reloc->address; } #endif @@ -706,7 +702,7 @@ md_undefined_symbol (char *name) GAS does not understand. */ int -md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED) +md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED) { return 0; } @@ -719,7 +715,7 @@ md_show_usage (FILE *stream ATTRIBUTE_UNUSED) return; } -char * +const char * md_atof (int type, char *litP, int *sizeP) { return ieee_md_atof (type, litP, sizeP, target_big_endian); @@ -797,20 +793,20 @@ initialise_reg_hash_table (struct hash_control ** hash_table, const reg_entry * register_table, const unsigned int num_entries) { - const reg_entry * reg; + const reg_entry * rreg; const char *hashret; if ((* hash_table = hash_new ()) == NULL) as_fatal (_("Virtual memory exhausted")); - for (reg = register_table; - reg < (register_table + num_entries); - reg++) + for (rreg = register_table; + rreg < (register_table + num_entries); + rreg++) { - hashret = hash_insert (* hash_table, reg->name, (char *) reg); + hashret = hash_insert (* hash_table, rreg->name, (char *) rreg); if (hashret) as_fatal (_("Internal Error: Can't hash %s: %s"), - reg->name, hashret); + rreg->name, hashret); } } @@ -936,7 +932,7 @@ process_label_constant (char *str, ins * cr16_ins) else if (strneq (input_line_pointer, "@GOT", 4) || strneq (input_line_pointer, "@got", 4)) { - if ((strneq (input_line_pointer, "+", 1)) + if ((strneq (input_line_pointer, "+", 1)) || (strneq (input_line_pointer, "-", 1))) as_warn (_("GOT bad expression with %s."), input_line_pointer); @@ -1105,20 +1101,20 @@ process_label_constant (char *str, ins * cr16_ins) static int getreg_image (reg r) { - const reg_entry *reg; + const reg_entry *rreg; char *reg_name; int is_procreg = 0; /* Nonzero means argument should be processor reg. */ /* Check whether the register is in registers table. */ if (r < MAX_REG) - reg = cr16_regtab + r; + rreg = cr16_regtab + r; else /* Register not found. */ { as_bad (_("Unknown register: `%d'"), r); return 0; } - reg_name = reg->name; + reg_name = rreg->name; /* Issue a error message when register is illegal. */ #define IMAGE_ERR \ @@ -1126,16 +1122,16 @@ getreg_image (reg r) reg_name, ins_parse); \ break; - switch (reg->type) + switch (rreg->type) { case CR16_R_REGTYPE: if (! is_procreg) - return reg->image; + return rreg->image; else IMAGE_ERR; case CR16_P_REGTYPE: - return reg->image; + return rreg->image; break; default: @@ -1548,28 +1544,25 @@ is_bcc_insn (char * op) /* Cinv instruction requires special handling. */ -static int +static void check_cinv_options (char * operand) { char *p = operand; - int i_used = 0, u_used = 0, d_used = 0; while (*++p != ']') { - if (*p == ',' || *p == ' ') - continue; - - else if (*p == 'i') - i_used = 1; - else if (*p == 'u') - u_used = 1; - else if (*p == 'd') - d_used = 1; - else - as_bad (_("Illegal `cinv' parameter: `%c'"), *p); + switch (*p) + { + case ',': + case ' ': + case 'i': + case 'u': + case 'd': + break; + default: + as_bad (_("Illegal `cinv' parameter: `%c'"), *p); + } } - - return 0; } /* Retrieve the opcode image of a given register pair. @@ -1579,12 +1572,12 @@ check_cinv_options (char * operand) static int getregp_image (reg r) { - const reg_entry *reg; + const reg_entry *rreg; char *reg_name; /* Check whether the register is in registers table. */ if (r < MAX_REG) - reg = cr16_regptab + r; + rreg = cr16_regptab + r; /* Register not found. */ else { @@ -1592,7 +1585,7 @@ getregp_image (reg r) return 0; } - reg_name = reg->name; + reg_name = rreg->name; /* Issue a error message when register pair is illegal. */ #define RPAIR_IMAGE_ERR \ @@ -1600,10 +1593,10 @@ getregp_image (reg r) reg_name, ins_parse); \ break; - switch (reg->type) + switch (rreg->type) { case CR16_RP_REGTYPE: - return reg->image; + return rreg->image; default: RPAIR_IMAGE_ERR; } @@ -1618,12 +1611,12 @@ getregp_image (reg r) static int getidxregp_image (reg r) { - const reg_entry *reg; + const reg_entry *rreg; char *reg_name; /* Check whether the register is in registers table. */ if (r < MAX_REG) - reg = cr16_regptab + r; + rreg = cr16_regptab + r; /* Register not found. */ else { @@ -1631,16 +1624,16 @@ getidxregp_image (reg r) return 0; } - reg_name = reg->name; + reg_name = rreg->name; /* Issue a error message when register pair is illegal. */ #define IDX_RPAIR_IMAGE_ERR \ as_bad (_("Illegal index register pair (`%s') in Instruction: `%s'"), \ reg_name, ins_parse); \ - if (reg->type == CR16_RP_REGTYPE) + if (rreg->type == CR16_RP_REGTYPE) { - switch (reg->image) + switch (rreg->image) { case 0: return 0; break; case 2: return 1; break; @@ -1663,14 +1656,14 @@ getidxregp_image (reg r) If the register is illegal for the current instruction, issue an error. */ static int -getprocreg_image (reg r) +getprocreg_image (int r) { - const reg_entry *reg; + const reg_entry *rreg; char *reg_name; /* Check whether the register is in registers table. */ - if (r < MAX_PREG) - reg = &cr16_pregtab[r - MAX_REG]; + if (r >= MAX_REG && r < MAX_PREG) + rreg = &cr16_pregtab[r - MAX_REG]; /* Register not found. */ else { @@ -1678,7 +1671,7 @@ getprocreg_image (reg r) return 0; } - reg_name = reg->name; + reg_name = rreg->name; /* Issue a error message when register pair is illegal. */ #define PROCREG_IMAGE_ERR \ @@ -1686,10 +1679,10 @@ getprocreg_image (reg r) reg_name, ins_parse); \ break; - switch (reg->type) + switch (rreg->type) { case CR16_P_REGTYPE: - return reg->image; + return rreg->image; default: PROCREG_IMAGE_ERR; } @@ -1701,14 +1694,14 @@ getprocreg_image (reg r) If the register is illegal for the current instruction, issue an error. */ static int -getprocregp_image (reg r) +getprocregp_image (int r) { - const reg_entry *reg; + const reg_entry *rreg; char *reg_name; int pregptab_disp = 0; /* Check whether the register is in registers table. */ - if (r < MAX_PREG) + if (r >= MAX_REG && r < MAX_PREG) { r = r - MAX_REG; switch (r) @@ -1725,7 +1718,7 @@ getprocregp_image (reg r) pregptab_disp = 5; break; default: break; } - reg = &cr16_pregptab[r - pregptab_disp]; + rreg = &cr16_pregptab[r - pregptab_disp]; } /* Register not found. */ else @@ -1734,7 +1727,7 @@ getprocregp_image (reg r) return 0; } - reg_name = reg->name; + reg_name = rreg->name; /* Issue a error message when register pair is illegal. */ #define PROCREGP_IMAGE_ERR \ @@ -1742,10 +1735,10 @@ getprocregp_image (reg r) reg_name, ins_parse); \ break; - switch (reg->type) + switch (rreg->type) { case CR16_P_REGTYPE: - return reg->image; + return rreg->image; default: PROCREGP_IMAGE_ERR; } @@ -2202,7 +2195,7 @@ adjust_if_needed (ins *insn ATTRIBUTE_UNUSED) Returns 1 upon success, 0 upon failure. */ static int -assemble_insn (char *mnemonic, ins *insn) +assemble_insn (const char *mnemonic, ins *insn) { /* Type of each operand in the current template. */ argtype cur_type[MAX_OPERANDS]; @@ -2464,7 +2457,7 @@ print_insn (ins *insn) int size; reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype); - + if (!reloc_howto) abort (); @@ -2494,6 +2487,35 @@ print_insn (ins *insn) } } +/* Actually assemble an instruction. */ + +static void +cr16_assemble (const char *op, char *param) +{ + ins cr16_ins; + + /* Find the instruction. */ + instruction = (const inst *) hash_find (cr16_inst_hash, op); + if (instruction == NULL) + { + as_bad (_("Unknown opcode: `%s'"), op); + return; + } + + /* Tie dwarf2 debug info to the address at the start of the insn. */ + dwarf2_emit_insn (0); + + /* Parse the instruction's operands. */ + parse_insn (&cr16_ins, param); + + /* Assemble the instruction - return upon failure. */ + if (assemble_insn (op, &cr16_ins) == 0) + return; + + /* Print the instruction. */ + print_insn (&cr16_ins); +} + /* This is the guts of the machine-dependent assembler. OP points to a machine dependent instruction. This function is supposed to emit the frags/bytes it assembles to. */ @@ -2503,7 +2525,6 @@ md_assemble (char *op) { ins cr16_ins; char *param, param1[32]; - char c; /* Reset global variables for a new instruction. */ reset_vars (op); @@ -2511,17 +2532,17 @@ md_assemble (char *op) /* Strip the mnemonic. */ for (param = op; *param != 0 && !ISSPACE (*param); param++) ; - c = *param; *param++ = '\0'; /* bCC instuctions and adjust the mnemonic by adding extra white spaces. */ if (is_bcc_insn (op)) { strcpy (param1, get_b_cc (op)); - op = "b"; strcat (param1,","); strcat (param1, param); param = (char *) ¶m1; + cr16_assemble ("b", param); + return; } /* Checking the cinv options and adjust the mnemonic by removing the @@ -2547,32 +2568,14 @@ md_assemble (char *op) && ((&cr16_ins)->arg[0].constant >= 0)) { if (streq ("lshb", op)) - op = "ashub"; + cr16_assemble ("ashub", param); else if (streq ("lshd", op)) - op = "ashud"; + cr16_assemble ("ashud", param); else - op = "ashuw"; + cr16_assemble ("ashuw", param); + return; } } - /* Find the instruction. */ - instruction = (const inst *) hash_find (cr16_inst_hash, op); - if (instruction == NULL) - { - as_bad (_("Unknown opcode: `%s'"), op); - return; - } - - /* Tie dwarf2 debug info to the address at the start of the insn. */ - dwarf2_emit_insn (0); - - /* Parse the instruction's operands. */ - parse_insn (&cr16_ins, param); - - /* Assemble the instruction - return upon failure. */ - if (assemble_insn (op, &cr16_ins) == 0) - return; - - /* Print the instruction. */ - print_insn (&cr16_ins); + cr16_assemble (op, param); }