diff options
-rw-r--r-- | gas/ChangeLog | 4 | ||||
-rw-r--r-- | gas/config/tc-sh.c | 83 | ||||
-rw-r--r-- | gas/config/tc-sh.h | 56 |
3 files changed, 100 insertions, 43 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 8dd9dbe..8a9061f 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,9 @@ Wed Feb 7 14:12:03 1996 Ian Lance Taylor <ian@cygnus.com> + * config/tc-sh.h (sh_do_align): Declare. + (md_do_align): Define. + * config/tc-sh.c (sh_do_align): New function. + * ecoff.c (ecoff_build_lineno): Don't try to store the address difference if the next address is before the current one. diff --git a/gas/config/tc-sh.c b/gas/config/tc-sh.c index 2766423..a64f818 100644 --- a/gas/config/tc-sh.c +++ b/gas/config/tc-sh.c @@ -211,9 +211,14 @@ parse_reg (src, mode, reg) int *mode; int *reg; { - if (src[0] == 'r') + /* We use !isalnum for the next character after the register name, to + make sure that we won't accidentally recognize a symbol name such as + 'sram' as being a reference to the register 'sr'. */ + + if (src[0] == 'r') { - if (src[1] >= '0' && src[1] <= '7' && strncmp(&src[2], "_bank", 5) == 0) + if (src[1] >= '0' && src[1] <= '7' && strncmp(&src[2], "_bank", 5) == 0 + && ! isalnum (src[7])) { *mode = A_REG_B; *reg = (src[1] - '0'); @@ -225,14 +230,14 @@ parse_reg (src, mode, reg) { if (src[1] == '1') { - if (src[2] >= '0' && src[2] <= '5') + if (src[2] >= '0' && src[2] <= '5' && ! isalnum (src[3])) { *mode = A_REG_N; *reg = 10 + src[2] - '0'; return 3; } } - if (src[1] >= '0' && src[1] <= '9') + if (src[1] >= '0' && src[1] <= '9' && ! isalnum (src[2])) { *mode = A_REG_N; *reg = (src[1] - '0'); @@ -240,53 +245,53 @@ parse_reg (src, mode, reg) } } - if (src[0] == 's' && src[1] == 's' && src[2] == 'r') + if (src[0] == 's' && src[1] == 's' && src[2] == 'r' && ! isalnum (src[3])) { *mode = A_SSR; return 3; } - if (src[0] == 's' && src[1] == 'p' && src[2] == 'c') + if (src[0] == 's' && src[1] == 'p' && src[2] == 'c' && ! isalnum (src[3])) { *mode = A_SPC; return 3; } - if (src[0] == 's' && src[1] == 'r') + if (src[0] == 's' && src[1] == 'r' && ! isalnum (src[2])) { *mode = A_SR; return 2; } - if (src[0] == 's' && src[1] == 'p') + if (src[0] == 's' && src[1] == 'p' && ! isalnum (src[2])) { *mode = A_REG_N; *reg = 15; return 2; } - if (src[0] == 'p' && src[1] == 'r') + if (src[0] == 'p' && src[1] == 'r' && ! isalnum (src[2])) { *mode = A_PR; return 2; } - if (src[0] == 'p' && src[1] == 'c') + if (src[0] == 'p' && src[1] == 'c' && ! isalnum (src[2])) { *mode = A_DISP_PC; return 2; } - if (src[0] == 'g' && src[1] == 'b' && src[2] == 'r') + if (src[0] == 'g' && src[1] == 'b' && src[2] == 'r' && ! isalnum (src[3])) { *mode = A_GBR; return 3; } - if (src[0] == 'v' && src[1] == 'b' && src[2] == 'r') + if (src[0] == 'v' && src[1] == 'b' && src[2] == 'r' && ! isalnum (src[3])) { *mode = A_VBR; return 3; } - if (src[0] == 'm' && src[1] == 'a' && src[2] == 'c') + if (src[0] == 'm' && src[1] == 'a' && src[2] == 'c' && ! isalnum (src[4])) { if (src[3] == 'l') { @@ -299,38 +304,37 @@ parse_reg (src, mode, reg) return 4; } } -/* start-sanitize-sh3e */ if (src[0] == 'f' && src[1] == 'r') { if (src[2] == '1') { - if (src[3] >= '0' && src[3] <= '5') + if (src[3] >= '0' && src[3] <= '5' && ! isalnum (src[4])) { *mode = F_REG_N; *reg = 10 + src[3] - '0'; return 4; } } - if (src[2] >= '0' && src[2] <= '9') + if (src[2] >= '0' && src[2] <= '9' && ! isalnum (src[3])) { *mode = F_REG_N; *reg = (src[2] - '0'); return 3; } } - if (src[0] == 'f' && src[1] == 'p' && src[2] == 'u' && src[3] == 'l') + if (src[0] == 'f' && src[1] == 'p' && src[2] == 'u' && src[3] == 'l' + && ! isalnum (src[4])) { *mode = FPUL_N; return 4; } - if (src[0] == 'f' && src[1] == 'p' - && src[2] == 's' && src[3] == 'c' && src[4] == 'r') + if (src[0] == 'f' && src[1] == 'p' && src[2] == 's' && src[3] == 'c' + && src[4] == 'r' && ! isalnum (src[5])) { *mode = FPSCR_N; return 5; } -/* end-sanitize-sh3e */ return 0; } @@ -562,7 +566,6 @@ get_operands (info, args, operand) ptr++; } get_operand (&ptr, operand + 1); -/* start-sanitize-sh3e */ if (info->arg[2]) { if (*ptr == ',') @@ -575,23 +578,18 @@ get_operands (info, args, operand) { operand[2].type = 0; } -/* end-sanitize-sh3e */ } else { operand[1].type = 0; -/* start-sanitize-sh3e */ operand[2].type = 0; -/* end-sanitize-sh3e */ } } else { operand[0].type = 0; operand[1].type = 0; -/* start-sanitize-sh3e */ operand[2].type = 0; -/* end-sanitize-sh3e */ } return ptr; } @@ -650,12 +648,10 @@ get_specific (opcode, operands) if (user->type != A_R0_GBR || user->reg != 0) goto fail; break; -/* start-sanitize-sh3e */ case F_FR0: if (user->type != F_REG_N || user->reg != 0) goto fail; break; -/* end-sanitize-sh3e */ case A_REG_N: case A_INC_N: @@ -663,11 +659,9 @@ get_specific (opcode, operands) case A_IND_N: case A_IND_R0_REG_N: case A_DISP_REG_N: -/* start-sanitize-sh3e */ case F_REG_N: case FPUL_N: case FPSCR_N: -/* end-sanitize-sh3e */ /* Opcode needs rn */ if (user->type != arg) goto fail; @@ -700,7 +694,6 @@ get_specific (opcode, operands) reg_m = user->reg; break; -/* start-sanitize-sh3e */ case F_REG_M: case FPUL_M: case FPSCR_M: @@ -709,7 +702,6 @@ get_specific (opcode, operands) goto fail; reg_m = user->reg; break; -/* end-sanitize-sh3e */ default: printf ("unhandled %d\n", arg); @@ -1702,6 +1694,33 @@ tc_coff_sizemachdep (frag) return md_relax_table[frag->fr_subtype].rlx_length; } +/* When we align the .text section, insert the correct NOP pattern. */ + +int +sh_do_align (n, fill) + int n; + const char *fill; +{ + if ((fill == NULL || *fill == 0) + && (now_seg == text_section +#ifdef BFD_ASSEMBLER + || (now_seg->flags & SEC_CODE) != 0 +#endif + || strcmp (obj_segment_name (now_seg), ".init") == 0)) + { + static const unsigned char big_nop_pattern[] = { 0x00, 0x09 }; + static const unsigned char little_nop_pattern[] = { 0x09, 0x00 }; + + if (target_big_endian) + frag_align_pattern (n, big_nop_pattern, sizeof big_nop_pattern); + else + frag_align_pattern (n, little_nop_pattern, sizeof little_nop_pattern); + return 1; + } + + return 0; +} + #ifdef OBJ_COFF /* Adjust a reloc for the SH. This is similar to the generic code, diff --git a/gas/config/tc-sh.h b/gas/config/tc-sh.h index 5fe4072..2452444 100644 --- a/gas/config/tc-sh.h +++ b/gas/config/tc-sh.h @@ -1,6 +1,6 @@ /* This file is tc-sh.h - Copyright (C) 1993 Free Software Foundation, Inc. + Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -16,31 +16,65 @@ You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ #define TC_SH /* This macro translates between an internal fix and an coff reloc type */ -#define TC_COFF_FIX2RTYPE(fixP) tc_coff_fix2rtype(fixP) +#define TC_COFF_FIX2RTYPE(fix) ((fix)->fx_r_type) #define BFD_ARCH bfd_arch_sh -#define COFF_MAGIC 0x0500 -/* Write out relocs which haven't been done by gas */ -#define TC_COUNT_RELOC(x) (((x)->fx_addsy)) -#define IGNORE_NONSTANDARD_ESCAPES -#define TC_RELOC_MANGLE(a,b,c) tc_reloc_mangle(a,b,c) +extern int shl; + +#define COFF_MAGIC (shl ? SH_ARCH_MAGIC_LITTLE : SH_ARCH_MAGIC_BIG) + +/* Whether -relax was used. */ +extern int sh_relax; + +/* When relaxing, we need to generate relocations for alignment + directives. */ +#define HANDLE_ALIGN(frag) sh_handle_align (frag) +extern void sh_handle_align PARAMS ((fragS *)); + +/* We need to force out some relocations when relaxing. */ +#define TC_FORCE_RELOCATION(fix) sh_force_relocation (fix) +extern int sh_force_relocation (); + +/* We need to write out relocs which have not been completed. */ +#define TC_COUNT_RELOC(fix) ((fix)->fx_addsy != NULL) + +#define TC_RELOC_MANGLE(seg, fix, int, paddr) \ + sh_coff_reloc_mangle ((seg), (fix), (int), (paddr)) +extern void sh_coff_reloc_mangle (); + +#define IGNORE_NONSTANDARD_ESCAPES #define tc_coff_symbol_emit_hook(a) ; /* not used */ #define DO_NOT_STRIP 0 #define DO_STRIP 0 -#define LISTING_HEADER "Hitachi Super-H GAS " +#define LISTING_HEADER (shl ? "Hitachi Super-H GAS Little Endian" : "Hitachi Super-H GAS Big Endian") #define NEED_FX_R_TYPE 1 #define RELOC_32 1234 -#define COFF_FLAGS 1 + +#define TC_KEEP_FX_OFFSET 1 #define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep(frag) +extern int tc_coff_sizemachdep PARAMS ((fragS *)); + +#define md_operand(x) + +extern const struct relax_type md_relax_table[]; +#define TC_GENERIC_RELAX_TABLE md_relax_table + +#define tc_frob_file sh_coff_frob_file +extern void sh_coff_frob_file PARAMS (()); + +/* We use a special alignment function to insert the correct nop + pattern. */ +extern int sh_do_align PARAMS ((int, const char *)); +#define md_do_align(n,fill,l) if (sh_do_align (n,fill)) goto l /* end of tc-sh.h */ |