X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-sh.c;h=55966e0376cdd0423e8b6d5a21d1dbc610bf06c3;hb=feb4bea70a297eb6316d1b0685bbbb8095b7fb29;hp=67bec05c315608a3b740fc09eb59b97f49b64a79;hpb=6d0cb78c78e090501eced0284e413137aeb50875;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-sh.c b/gas/config/tc-sh.c index 67bec05c31..55966e0376 100644 --- a/gas/config/tc-sh.c +++ b/gas/config/tc-sh.c @@ -1,7 +1,5 @@ /* tc-sh.c -- Assemble code for the Renesas / SuperH SH - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. + Copyright (C) 1993-2016 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -145,8 +143,10 @@ static unsigned int preset_target_arch; accommodate the insns seen so far. */ static unsigned int valid_arch; +#ifdef OBJ_ELF /* Whether --fdpic was given. */ static int sh_fdpic; +#endif const char EXP_CHARS[] = "eE"; @@ -281,15 +281,15 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP"; #if BFD_HOST_64BIT_LONG /* The "reach" type is long, so we can only do this for a 64-bit-long host. */ -#define SH64PCREL32_M (((long) -1 << 30) * 2 - 4) +#define SH64PCREL32_M ((-((long) 1 << 30)) * 2 - 4) #define SH64PCREL48_F ((((long) 1 << 47) - 1) - 4) -#define SH64PCREL48_M (((long) -1 << 47) - 4) +#define SH64PCREL48_M ((-((long) 1 << 47)) - 4) #define SH64PCREL48_LENGTH (3 * 4) #else /* If the host does not have 64-bit longs, just make this state identical in reach to the 32-bit state. Note that we have a slightly incorrect reach, but the correct one above will overflow a 32-bit number. */ -#define SH64PCREL32_M (((long) -1 << 30) * 2) +#define SH64PCREL32_M ((-((long) 1 << 30)) * 2) #define SH64PCREL48_F SH64PCREL32_F #define SH64PCREL48_M SH64PCREL32_M #define SH64PCREL48_LENGTH (3 * 4) @@ -313,14 +313,14 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP"; #if BFD_HOST_64BIT_LONG /* The "reach" type is long, so we can only do this for a 64-bit-long host. */ -#define MOVI_32_M (((long) -1 << 30) * 2 - 4) +#define MOVI_32_M ((-((long) 1 << 30)) * 2 - 4) #define MOVI_48_F ((((long) 1 << 47) - 1) - 4) -#define MOVI_48_M (((long) -1 << 47) - 4) +#define MOVI_48_M ((-((long) 1 << 47)) - 4) #else /* If the host does not have 64-bit longs, just make this state identical in reach to the 32-bit state. Note that we have a slightly incorrect reach, but the correct one above will overflow a 32-bit number. */ -#define MOVI_32_M (((long) -1 << 30) * 2) +#define MOVI_32_M ((-((long) 1 << 30)) * 2) #define MOVI_48_F MOVI_32_F #define MOVI_48_M MOVI_32_M #endif /* BFD_HOST_64BIT_LONG */ @@ -765,9 +765,10 @@ sh_check_fixup (expressionS *main_exp, bfd_reloc_code_real_type *r_type_p) /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */ void -sh_cons_fix_new (fragS *frag, int off, int size, expressionS *exp) +sh_cons_fix_new (fragS *frag, int off, int size, expressionS *exp, + bfd_reloc_code_real_type r_type) { - bfd_reloc_code_real_type r_type = BFD_RELOC_UNUSED; + r_type = BFD_RELOC_UNUSED; if (sh_check_fixup (exp, &r_type)) as_bad (_("Invalid PIC expression.")); @@ -787,11 +788,9 @@ sh_cons_fix_new (fragS *frag, int off, int size, expressionS *exp) r_type = BFD_RELOC_32; break; -#ifdef HAVE_SH64 case 8: r_type = BFD_RELOC_64; break; -#endif default: goto error; @@ -812,7 +811,7 @@ sh_cons_fix_new (fragS *frag, int off, int size, expressionS *exp) /* Clobbers input_line_pointer, checks end-of-line. */ /* NBYTES 1=.byte, 2=.word, 4=.long */ static void -sh_elf_cons (register int nbytes) +sh_elf_cons (int nbytes) { expressionS exp; @@ -931,10 +930,11 @@ sh_optimize_expr (expressionS *l, operatorT op, expressionS *r) symbol_get_frag (r->X_add_symbol), &frag_off)) { - l->X_add_number -= r->X_add_number; - l->X_add_number -= frag_off / OCTETS_PER_BYTE; - l->X_add_number += (S_GET_VALUE (l->X_add_symbol) - - S_GET_VALUE (r->X_add_symbol)); + offsetT symval_diff = S_GET_VALUE (l->X_add_symbol) + - S_GET_VALUE (r->X_add_symbol); + subtract_from_result (l, r->X_add_number, r->X_extrabit); + subtract_from_result (l, frag_off / OCTETS_PER_BYTE, 0); + add_to_result (l, symval_diff, symval_diff < 0); l->X_op = O_constant; l->X_add_symbol = 0; return 1; @@ -950,7 +950,7 @@ void md_begin (void) { const sh_opcode_info *opcode; - char *prev_name = ""; + const char *prev_name = ""; unsigned int target_arch; target_arch @@ -987,7 +987,7 @@ static int reg_b; /* Try to parse a reg name. Return the number of chars consumed. */ static unsigned int -parse_reg_without_prefix (char *src, int *mode, int *reg) +parse_reg_without_prefix (char *src, sh_arg_type *mode, int *reg) { char l0 = TOLOWER (src[0]); char l1 = l0 ? TOLOWER (src[1]) : 0; @@ -1346,7 +1346,7 @@ parse_reg_without_prefix (char *src, int *mode, int *reg) $-prefixed register names if enabled by the user. */ static unsigned int -parse_reg (char *src, int *mode, int *reg) +parse_reg (char *src, sh_arg_type *mode, int *reg) { unsigned int prefix; unsigned int consumed; @@ -1363,7 +1363,7 @@ parse_reg (char *src, int *mode, int *reg) } else prefix = 0; - + consumed = parse_reg_without_prefix (src, mode, reg); if (consumed == 0) @@ -1411,7 +1411,7 @@ static char * parse_at (char *src, sh_operand_info *op) { int len; - int mode; + sh_arg_type mode; src++; if (src[0] == '@') { @@ -1583,7 +1583,7 @@ static void get_operand (char **ptr, sh_operand_info *op) { char *src = *ptr; - int mode = -1; + sh_arg_type mode = (sh_arg_type) -1; unsigned int len; if (src[0] == '#') @@ -1677,7 +1677,7 @@ static sh_opcode_info * get_specific (sh_opcode_info *opcode, sh_operand_info *operands) { sh_opcode_info *this_try = opcode; - char *name = opcode->name; + const char *name = opcode->name; int n = 0; while (opcode->name) @@ -2235,7 +2235,8 @@ get_specific (sh_opcode_info *opcode, sh_operand_info *operands) } static void -insert (char *where, int how, int pcrel, sh_operand_info *op) +insert (char *where, bfd_reloc_code_real_type how, int pcrel, + sh_operand_info *op) { fix_new_exp (frag_now, where - frag_now->fr_literal, @@ -2246,7 +2247,8 @@ insert (char *where, int how, int pcrel, sh_operand_info *op) } static void -insert4 (char * where, int how, int pcrel, sh_operand_info * op) +insert4 (char * where, bfd_reloc_code_real_type how, int pcrel, + sh_operand_info * op) { fix_new_exp (frag_now, where - frag_now->fr_literal, @@ -2292,7 +2294,6 @@ build_relax (sh_opcode_info *opcode, sh_operand_info *op) static char * insert_loop_bounds (char *output, sh_operand_info *operand) { - char *name; symbolS *end_sym; /* Since the low byte of the opcode will be overwritten by the reloc, we @@ -2305,6 +2306,7 @@ insert_loop_bounds (char *output, sh_operand_info *operand) if (sh_relax) { static int count = 0; + char name[11]; /* If the last loop insn is a two-byte-insn, it is in danger of being swapped with the insn after it. To prevent this, create a new @@ -2313,7 +2315,6 @@ insert_loop_bounds (char *output, sh_operand_info *operand) right in the middle, but four byte insns are not swapped anyways. */ /* A REPEAT takes 6 bytes. The SH has a 32 bit address space. Hence a 9 digit number should be enough to count all REPEATs. */ - name = alloca (11); sprintf (name, "_R%x", count++ & 0x3fffffff); end_sym = symbol_new (name, undefined_section, 0, &zero_address_frag); /* Make this a local symbol. */ @@ -2347,7 +2348,9 @@ build_Mytes (sh_opcode_info *opcode, sh_operand_info *operand) int low_byte = target_big_endian ? 1 : 0; int max_index = 4; bfd_reloc_code_real_type r_type; +#ifdef OBJ_ELF int unhandled_pic = 0; +#endif nbuf[0] = 0; nbuf[1] = 0; @@ -2358,6 +2361,7 @@ build_Mytes (sh_opcode_info *opcode, sh_operand_info *operand) nbuf[6] = 0; nbuf[7] = 0; +#ifdef OBJ_ELF for (indx = 0; indx < 3; indx++) if (opcode->arg[indx] == A_IMM && operand[indx].type == A_IMM @@ -2365,6 +2369,7 @@ build_Mytes (sh_opcode_info *opcode, sh_operand_info *operand) || sh_PIC_related_p (operand[indx].immediate.X_add_symbol) || sh_PIC_related_p (operand[indx].immediate.X_op_symbol))) unhandled_pic = 1; +#endif if (SH_MERGE_ARCH_SET (opcode->arch, arch_op32)) { @@ -2409,11 +2414,13 @@ build_Mytes (sh_opcode_info *opcode, sh_operand_info *operand) break; case IMM0_3s: nbuf[indx] |= 0x08; + /* Fall through. */ case IMM0_3c: insert (output + low_byte, BFD_RELOC_SH_IMM3, 0, operand); break; case IMM0_3Us: nbuf[indx] |= 0x80; + /* Fall through. */ case IMM0_3Uc: insert (output + low_byte, BFD_RELOC_SH_IMM3U, 0, operand); break; @@ -2445,9 +2452,11 @@ build_Mytes (sh_opcode_info *opcode, sh_operand_info *operand) break; case IMM0_20: r_type = BFD_RELOC_SH_DISP20; +#ifdef OBJ_ELF if (sh_check_fixup (&operand->immediate, &r_type)) as_bad (_("Invalid PIC expression.")); unhandled_pic = 0; +#endif insert4 (output, r_type, 0, operand); break; case IMM0_20BY8: @@ -2507,8 +2516,10 @@ build_Mytes (sh_opcode_info *opcode, sh_operand_info *operand) } } } +#ifdef OBJ_ELF if (unhandled_pic) as_bad (_("misplaced PIC operand")); +#endif if (!target_big_endian) { output[1] = (nbuf[0] << 4) | (nbuf[1]); @@ -3082,7 +3093,7 @@ md_undefined_symbol (char *name ATTRIBUTE_UNUSED) /* Various routines to kill one day. */ -char * +const char * md_atof (int type, char *litP, int *sizeP) { return ieee_md_atof (type, litP, sizeP, target_big_endian); @@ -3173,7 +3184,7 @@ struct option md_longopts[] = size_t md_longopts_size = sizeof (md_longopts); int -md_parse_option (int c, char *arg ATTRIBUTE_UNUSED) +md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED) { switch (c) { @@ -3237,10 +3248,10 @@ md_parse_option (int c, char *arg ATTRIBUTE_UNUSED) for (; bfd_arch; bfd_arch=bfd_arch->next) { int len = strlen(bfd_arch->printable_name); - + if (bfd_arch->mach == bfd_mach_sh5) continue; - + if (strncasecmp (bfd_arch->printable_name, arg, len) != 0) continue; @@ -3254,7 +3265,7 @@ md_parse_option (int c, char *arg ATTRIBUTE_UNUSED) continue; break; } - + if (!preset_target_arch) as_bad (_("Invalid argument to --isa option: %s"), arg); } @@ -3684,7 +3695,7 @@ md_section_align (segT seg ATTRIBUTE_UNUSED, valueT size) return size; #else /* ! OBJ_ELF */ return ((size + (1 << bfd_get_section_alignment (stdoutput, seg)) - 1) - & (-1 << bfd_get_section_alignment (stdoutput, seg))); + & -(1 << bfd_get_section_alignment (stdoutput, seg))); #endif /* ! OBJ_ELF */ } @@ -3715,7 +3726,6 @@ void sh_cons_align (int nbytes) { int nalign; - char *p; if (sh_no_align_cons) { @@ -3741,8 +3751,8 @@ sh_cons_align (int nbytes) return; } - p = frag_var (rs_align_test, 1, 1, (relax_substateT) 0, - (symbolS *) NULL, (offsetT) nalign, (char *) NULL); + frag_var (rs_align_test, 1, 1, (relax_substateT) 0, + (symbolS *) NULL, (offsetT) nalign, (char *) NULL); record_alignment (now_seg, nalign); } @@ -3959,6 +3969,11 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) the other symbol. We have to adjust the relocation type here. */ if (fixP->fx_pcrel) { +#ifndef HAVE_SH64 + /* Safeguard; this must not occur for non-sh64 configurations. */ + gas_assert (fixP->fx_r_type != BFD_RELOC_64); +#endif + switch (fixP->fx_r_type) { default: @@ -4157,6 +4172,12 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) buf[highbyte] |= (val >> 8) & 0xf; break; +#ifndef HAVE_SH64 + case BFD_RELOC_64: + apply_full_field_fix (fixP, buf, *valP, 8); + break; +#endif + case BFD_RELOC_32: case BFD_RELOC_32_PCREL: apply_full_field_fix (fixP, buf, val, 4); @@ -4407,8 +4428,8 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) arelent *rel; bfd_reloc_code_real_type r_type; - rel = (arelent *) xmalloc (sizeof (arelent)); - rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + rel = XNEW (arelent); + rel->sym_ptr_ptr = XNEW (asymbol *); *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); rel->address = fixp->fx_frag->fr_address + fixp->fx_where; @@ -4417,7 +4438,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) if (SWITCH_TABLE (fixp)) { *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy); - rel->addend = 0; + rel->addend = rel->address - S_GET_VALUE(fixp->fx_subsy); if (r_type == BFD_RELOC_16) r_type = BFD_RELOC_SH_SWITCH16; else if (r_type == BFD_RELOC_8) @@ -4472,7 +4493,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) #ifdef OBJ_ELF inline static char * -sh_end_of_match (char *cont, char *what) +sh_end_of_match (char *cont, const char *what) { int len = strlen (what); @@ -4585,7 +4606,7 @@ sh_regname_to_dw2regnum (char *regname) unsigned int i; const char *p; char *q; - static struct { char *name; int dw2regnum; } regnames[] = + static struct { const char *name; int dw2regnum; } regnames[] = { { "pr", 17 }, { "t", 18 }, { "gbr", 19 }, { "mach", 20 }, { "macl", 21 }, { "fpul", 23 }