aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-sh.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/config/tc-sh.c')
-rw-r--r--gas/config/tc-sh.c111
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)
{