diff options
Diffstat (limited to 'gas/config/tc-sh.c')
-rw-r--r-- | gas/config/tc-sh.c | 111 |
1 files changed, 80 insertions, 31 deletions
diff --git a/gas/config/tc-sh.c b/gas/config/tc-sh.c index 555842b..0b294e0 100644 --- a/gas/config/tc-sh.c +++ b/gas/config/tc-sh.c @@ -134,7 +134,11 @@ int sh_small; static int dont_adjust_reloc_32; -/* preset architecture set, if given; zero otherwise. */ +/* Flag to indicate that '$' is allowed as a register prefix. */ + +static int allow_dollar_register_prefix; + +/* Preset architecture set, if given; zero otherwise. */ static unsigned int preset_target_arch; @@ -869,8 +873,8 @@ static int reg_b; /* Try to parse a reg name. Return the number of chars consumed. */ -static int -parse_reg (char *src, int *mode, int *reg) +static unsigned int +parse_reg_without_prefix (char *src, int *mode, int *reg) { char l0 = TOLOWER (src[0]); char l1 = l0 ? TOLOWER (src[1]) : 0; @@ -1225,6 +1229,36 @@ parse_reg (char *src, int *mode, int *reg) return 0; } +/* Like parse_reg_without_prefix, but this version supports + $-prefixed register names if enabled by the user. */ + +static unsigned int +parse_reg (char *src, int *mode, int *reg) +{ + unsigned int prefix; + unsigned int consumed; + + if (src[0] == '$') + { + if (allow_dollar_register_prefix) + { + src ++; + prefix = 1; + } + else + return 0; + } + else + prefix = 0; + + consumed = parse_reg_without_prefix (src, mode, reg); + + if (consumed == 0) + return 0; + + return consumed + prefix; +} + static char * parse_exp (char *s, sh_operand_info *op) { @@ -3005,31 +3039,39 @@ s_uses (int ignore ATTRIBUTE_UNUSED) demand_empty_rest_of_line (); } +enum options +{ + OPTION_RELAX = OPTION_MD_BASE, + OPTION_BIG, + OPTION_LITTLE, + OPTION_SMALL, + OPTION_DSP, + OPTION_ISA, + OPTION_RENESAS, + OPTION_ALLOW_REG_PREFIX, +#ifdef HAVE_SH64 + OPTION_ABI, + OPTION_NO_MIX, + OPTION_SHCOMPACT_CONST_CRANGE, + OPTION_NO_EXPAND, + OPTION_PT32, +#endif + OPTION_DUMMY /* Not used. This is just here to make it easy to add and subtract options from this enum. */ +}; + const char *md_shortopts = ""; struct option md_longopts[] = { -#define OPTION_RELAX (OPTION_MD_BASE) -#define OPTION_BIG (OPTION_MD_BASE + 1) -#define OPTION_LITTLE (OPTION_BIG + 1) -#define OPTION_SMALL (OPTION_LITTLE + 1) -#define OPTION_DSP (OPTION_SMALL + 1) -#define OPTION_ISA (OPTION_DSP + 1) -#define OPTION_RENESAS (OPTION_ISA + 1) - {"relax", no_argument, NULL, OPTION_RELAX}, {"big", no_argument, NULL, OPTION_BIG}, {"little", no_argument, NULL, OPTION_LITTLE}, {"small", no_argument, NULL, OPTION_SMALL}, {"dsp", no_argument, NULL, OPTION_DSP}, - {"isa", required_argument, NULL, OPTION_ISA}, + {"isa", required_argument, NULL, OPTION_ISA}, {"renesas", no_argument, NULL, OPTION_RENESAS}, + {"allow-reg-prefix", no_argument, NULL, OPTION_ALLOW_REG_PREFIX}, #ifdef HAVE_SH64 -#define OPTION_ABI (OPTION_RENESAS + 1) -#define OPTION_NO_MIX (OPTION_ABI + 1) -#define OPTION_SHCOMPACT_CONST_CRANGE (OPTION_NO_MIX + 1) -#define OPTION_NO_EXPAND (OPTION_SHCOMPACT_CONST_CRANGE + 1) -#define OPTION_PT32 (OPTION_NO_EXPAND + 1) {"abi", required_argument, NULL, OPTION_ABI}, {"no-mix", no_argument, NULL, OPTION_NO_MIX}, {"shcompact-const-crange", no_argument, NULL, OPTION_SHCOMPACT_CONST_CRANGE}, @@ -3070,6 +3112,10 @@ md_parse_option (int c, char *arg ATTRIBUTE_UNUSED) dont_adjust_reloc_32 = 1; break; + case OPTION_ALLOW_REG_PREFIX: + allow_dollar_register_prefix = 1; + break; + case OPTION_ISA: if (strcasecmp (arg, "dsp") == 0) preset_target_arch = arch_sh_up & ~(arch_sh_sp_fpu|arch_sh_dp_fpu); @@ -3097,6 +3143,7 @@ md_parse_option (int c, char *arg ATTRIBUTE_UNUSED) { extern const bfd_arch_info_type bfd_sh_arch; bfd_arch_info_type const *bfd_arch = &bfd_sh_arch; + preset_target_arch = 0; for (; bfd_arch; bfd_arch=bfd_arch->next) { @@ -3173,19 +3220,21 @@ md_show_usage (FILE *stream) { fprintf (stream, _("\ SH options:\n\ --little generate little endian code\n\ --big generate big endian code\n\ --relax alter jump instructions for long displacements\n\ --renesas disable optimization with section symbol for\n\ +--little generate little endian code\n\ +--big generate big endian code\n\ +--relax alter jump instructions for long displacements\n\ +--renesas disable optimization with section symbol for\n\ compatibility with Renesas assembler.\n\ --small align sections to 4 byte boundaries, not 16\n\ --dsp enable sh-dsp insns, and disable floating-point ISAs.\n\ --isa=[any use most appropriate isa\n\ +--small align sections to 4 byte boundaries, not 16\n\ +--dsp enable sh-dsp insns, and disable floating-point ISAs.\n\ +--allow-reg-prefix allow '$' as a register name prefix.\n\ +--isa=[any use most appropriate isa\n\ | dsp same as '-dsp'\n\ | fp")); { extern const bfd_arch_info_type bfd_sh_arch; bfd_arch_info_type const *bfd_arch = &bfd_sh_arch; + for (; bfd_arch; bfd_arch=bfd_arch->next) if (bfd_arch->mach != bfd_mach_sh5) { @@ -3196,19 +3245,19 @@ SH options:\n\ fprintf (stream, "]\n"); #ifdef HAVE_SH64 fprintf (stream, _("\ --isa=[shmedia set as the default instruction set for SH64\n\ +--isa=[shmedia set as the default instruction set for SH64\n\ | SHmedia\n\ | shcompact\n\ | SHcompact]\n")); fprintf (stream, _("\ --abi=[32|64] set size of expanded SHmedia operands and object\n\ +--abi=[32|64] set size of expanded SHmedia operands and object\n\ file type\n\ --shcompact-const-crange emit code-range descriptors for constants in\n\ +--shcompact-const-crange emit code-range descriptors for constants in\n\ SHcompact code sections\n\ --no-mix disallow SHmedia code in the same section as\n\ +--no-mix disallow SHmedia code in the same section as\n\ constants and SHcompact code\n\ --no-expand do not expand MOVI, PT, PTA or PTB instructions\n\ --expand-pt32 with -abi=64, expand PT, PTA and PTB instructions\n\ +--no-expand do not expand MOVI, PT, PTA or PTB instructions\n\ +--expand-pt32 with -abi=64, expand PT, PTA and PTB instructions\n\ to 32 bits only\n")); #endif /* HAVE_SH64 */ } @@ -4263,7 +4312,7 @@ sh_parse_name (char const *name, expressionS *exprP, char *nextcharP) exprP->X_add_symbol = GOT_symbol; no_suffix: /* If we have an absolute symbol or a reg, then we know its - value now. */ + value now. */ segment = S_GET_SEGMENT (exprP->X_add_symbol); if (segment == absolute_section) { |