X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-cr16.c;h=b7fffa7878030277ea74508b746357bafc7f6364;hb=9dfa3e63479d3c3106c7e5e86764a0ed8e22aa7f;hp=a6185f99af817bb06cd0553cec107307ecb22b5c;hpb=d75d1c9fe1b42014a16a3a23972d6e8683a7a4f3;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-cr16.c b/gas/config/tc-cr16.c index a6185f99af..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 @@ -335,7 +335,7 @@ get_register_pair (char *reg_name) 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); @@ -349,7 +349,7 @@ get_register_pair (char *reg_name) return rreg->value.reg_val; return nullregister; -} +} /* Get the index register 'reg_name'. */ @@ -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); @@ -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); @@ -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. @@ -1663,13 +1656,13 @@ 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 *rreg; char *reg_name; /* Check whether the register is in registers table. */ - if (r < MAX_REG) + if (r >= MAX_REG && r < MAX_PREG) rreg = &cr16_pregtab[r - MAX_REG]; /* Register not found. */ else @@ -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 *rreg; char *reg_name; int pregptab_disp = 0; /* Check whether the register is in registers table. */ - if (r < MAX_REG) + if (r >= MAX_REG && r < MAX_PREG) { r = r - MAX_REG; switch (r) @@ -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); }