This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Thumb32 assembler (45/69)
- From: Zack Weinberg <zack at codesourcery dot com>
- To: binutils <binutils at sourceware dot org>
- Date: Tue, 26 Apr 2005 02:55:35 -0700
- Subject: Thumb32 assembler (45/69)
Move the processing of (occasionally) optional immediate prefixes into
my_get_expression from its callers. This will facilitate a future
change (not in this patch series) to make all immediate prefixes
optional, as is recommended by the ARM "new assembly syntax"
supplement. I haven't done that for this patch series because it
would require lots of careful testing and it's tangential.
zw
* config/tc-arm.c (my_get_expression): Add handling of immediate
prefix, under control of third tristate argument.
(GE_NO_PREFIX, GE_IMM_PREFIX, GE_OPT_PREFIX): New macros.
(expression_or_fail): Pass down third argument.
(immediate_required_here, decode_shift, data_op2)
(cp_address_required_here, parse_thumb_address, parse_operands):
Update to match. No need to handle immediate prefix here.
(reg_list, ldst_extend, ldst_extend_v4, ld_mode_required_here)
(do_ldst, do_ldstv4): Update to match.
(cp_address_offset): Merge into cp_address_required_here.
===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c (revision 47)
+++ gas/config/tc-arm.c (revision 48)
@@ -707,12 +707,35 @@
static int in_my_get_expression = 0;
+/* Third argument to my_get_expression. */
+#define GE_NO_PREFIX 0
+#define GE_IMM_PREFIX 1
+#define GE_OPT_PREFIX 2
+
static int
-my_get_expression (expressionS * ep, char ** str)
+my_get_expression (expressionS * ep, char ** str, int prefix_mode)
{
char * save_in;
segT seg;
+ switch (prefix_mode)
+ {
+ case GE_NO_PREFIX: break;
+ case GE_IMM_PREFIX:
+ if (!is_immediate_prefix (**str))
+ {
+ inst.error = _("immediate expression requires a # prefix");
+ return FAIL;
+ }
+ (*str)++;
+ break;
+ case GE_OPT_PREFIX:
+ if (is_immediate_prefix (**str))
+ (*str)++;
+ break;
+ default: abort ();
+ }
+
memset (ep, 0, sizeof (expressionS));
save_in = input_line_pointer;
@@ -765,9 +788,9 @@
return 0;
}
-#define expression_or_fail(exp, str) \
+#define expression_or_fail(exp, str, pmode) \
do { \
- if (my_get_expression (exp, str)) \
+ if (my_get_expression (exp, str, pmode)) \
return; \
} while (0)
@@ -972,16 +995,7 @@
bfd_boolean prefix_opt)
{
expressionS exp;
-
- if (is_immediate_prefix (**str))
- (*str)++;
- else if (!prefix_opt)
- {
- inst.error = _("immediate expression requires a # prefix");
- return FAIL;
- }
-
- my_get_expression (&exp, str);
+ my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX);
if (exp.X_op != O_constant)
{
inst.error = _("constant expression required");
@@ -1332,7 +1346,7 @@
{
expressionS expr;
- if (my_get_expression (&expr, &str))
+ if (my_get_expression (&expr, &str, GE_NO_PREFIX))
return FAIL;
if (expr.X_op == O_constant)
@@ -1505,25 +1519,22 @@
/* KIND indicates what kind of shifts are accepted. */
static int
-decode_shift (char ** str, int kind)
+decode_shift (char **str, int kind)
{
- const struct asm_shift_name * shift;
- char * p;
- char c;
+ const struct asm_shift_name *shift;
+ int reg;
+ char *p;
- for (p = * str; ISALPHA (* p); p ++)
+ for (p = *str; ISALPHA (*p); p++)
;
- if (p == * str)
+ if (p == *str)
{
inst.error = _("shift expression expected");
return FAIL;
}
- c = * p;
- * p = '\0';
- shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
- * p = c;
+ shift = hash_find_n (arm_shift_hsh, *str, p - *str);
if (shift == NULL)
{
@@ -1531,7 +1542,8 @@
return FAIL;
}
- assert (shift->properties->index == shift_properties[shift->properties->index].index);
+ assert (shift->properties->index ==
+ shift_properties[shift->properties->index].index);
if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
&& shift->properties->index != SHIFT_LSL
@@ -1555,7 +1567,7 @@
if (shift->properties->index == SHIFT_RRX)
{
- * str = p;
+ *str = p;
inst.instruction |= shift->properties->bit_field;
return SUCCESS;
}
@@ -1563,25 +1575,14 @@
skip_whitespace (p);
if (kind == NO_SHIFT_RESTRICT
- && reg_required_here (& p, 8, REG_TYPE_RN) != FAIL)
+ && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
{
inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
- * str = p;
+ inst.instruction |= reg << 8;
+ *str = p;
return SUCCESS;
}
- else if (! is_immediate_prefix (* p))
- {
- inst.error = (NO_SHIFT_RESTRICT
- ? _("shift requires register or #expression")
- : _("shift requires #expression"));
- * str = p;
- return FAIL;
- }
-
- inst.error = NULL;
- p ++;
-
- if (my_get_expression (& inst.reloc.exp, & p))
+ else if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
return FAIL;
/* Validate some simple #expressions. */
@@ -1726,85 +1727,72 @@
int value;
expressionS expr;
- if (reg_required_here (str, 0, REG_TYPE_RN) != FAIL)
+ if ((value = arm_reg_parse (str, REG_TYPE_RN)) != FAIL)
{
+ inst.instruction |= value;
if (skip_past_comma (str) == SUCCESS)
/* Shift operation on register. */
return decode_shift (str, NO_SHIFT_RESTRICT);
return SUCCESS;
}
+ else if (my_get_expression (&inst.reloc.exp, str, GE_IMM_PREFIX))
+ return FAIL;
+
+ if (inst.reloc.exp.X_add_symbol)
+ {
+ inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
+ inst.reloc.pc_rel = 0;
+ }
else
{
- /* Immediate expression. */
- if (is_immediate_prefix (**str))
+ if (skip_past_comma (str) == SUCCESS)
{
- (*str)++;
- inst.error = NULL;
-
- if (my_get_expression (&inst.reloc.exp, str))
+ /* #x, y -- ie explicit rotation by Y. */
+ if (my_get_expression (&expr, str, GE_NO_PREFIX))
return FAIL;
- if (inst.reloc.exp.X_add_symbol)
+ if (expr.X_op != O_constant)
{
- inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
- inst.reloc.pc_rel = 0;
+ inst.error = _("constant expression expected");
+ return FAIL;
}
- else
- {
- if (skip_past_comma (str) == SUCCESS)
- {
- /* #x, y -- ie explicit rotation by Y. */
- if (my_get_expression (&expr, str))
- return FAIL;
- if (expr.X_op != O_constant)
- {
- inst.error = _("constant expression expected");
- return FAIL;
- }
-
- /* Rotate must be a multiple of 2. */
- if (((unsigned) expr.X_add_number) > 30
- || (expr.X_add_number & 1) != 0
- || ((unsigned) inst.reloc.exp.X_add_number) > 255)
- {
- inst.error = _("invalid constant");
- return FAIL;
- }
- inst.instruction |= INST_IMMEDIATE;
- inst.instruction |= inst.reloc.exp.X_add_number;
- inst.instruction |= expr.X_add_number << 7;
- return SUCCESS;
- }
-
- /* Implicit rotation, select a suitable one. */
- value = validate_immediate (inst.reloc.exp.X_add_number);
-
- if (value == FAIL)
- {
- /* Can't be done. Perhaps the code reads something like
- "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
- if ((value = negate_data_op (&inst.instruction,
- inst.reloc.exp.X_add_number))
- == FAIL)
- {
- inst.error = _("invalid constant");
- return FAIL;
- }
- }
-
- inst.instruction |= value;
+ /* Rotate must be a multiple of 2. */
+ if (((unsigned) expr.X_add_number) > 30
+ || (expr.X_add_number & 1) != 0
+ || ((unsigned) inst.reloc.exp.X_add_number) > 255)
+ {
+ inst.error = _("invalid constant");
+ return FAIL;
}
-
inst.instruction |= INST_IMMEDIATE;
+ inst.instruction |= inst.reloc.exp.X_add_number;
+ inst.instruction |= expr.X_add_number << 7;
return SUCCESS;
}
- (*str)++;
- inst.error = _("register or shift expression expected");
- return FAIL;
+ /* Implicit rotation, select a suitable one. */
+ value = validate_immediate (inst.reloc.exp.X_add_number);
+
+ if (value == FAIL)
+ {
+ /* Can't be done. Perhaps the code reads something like
+ "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
+ if ((value = negate_data_op (&inst.instruction,
+ inst.reloc.exp.X_add_number))
+ == FAIL)
+ {
+ inst.error = _("invalid constant");
+ return FAIL;
+ }
+ }
+
+ inst.instruction |= value;
}
+
+ inst.instruction |= INST_IMMEDIATE;
+ return SUCCESS;
}
/* Parse an explicit relocation suffix on an expression. This is
@@ -1846,7 +1834,7 @@
case '#':
case '$':
(*str)++;
- if (my_get_expression (& inst.reloc.exp, str))
+ if (my_get_expression (& inst.reloc.exp, str, GE_NO_PREFIX))
return FAIL;
if (inst.reloc.exp.X_op == O_constant)
@@ -1904,7 +1892,7 @@
case '#':
case '$':
(*str)++;
- if (my_get_expression (& inst.reloc.exp, str))
+ if (my_get_expression (& inst.reloc.exp, str, GE_NO_PREFIX))
return FAIL;
if (inst.reloc.exp.X_op == O_constant)
@@ -2028,7 +2016,7 @@
return FAIL;
else /* PC +- 8 bit immediate offset. */
{
- if (my_get_expression (& inst.reloc.exp, & str))
+ if (my_get_expression (& inst.reloc.exp, & str, GE_NO_PREFIX))
return FAIL;
inst.instruction |= HWOFFSET_IMM; /* The I bit. */
@@ -2109,23 +2097,6 @@
}
static int
-cp_address_offset (char ** str, int reloc)
-{
- if (! is_immediate_prefix (**str))
- {
- inst.error = _("immediate expression expected");
- return FAIL;
- }
- (*str)++;
- if (my_get_expression (& inst.reloc.exp, str))
- return FAIL;
-
- inst.reloc.type = reloc;
-
- return SUCCESS;
-}
-
-static int
cp_address_required_here (char ** str, int wb_ok, int reloc)
{
char * p = * str;
@@ -2175,8 +2146,9 @@
return FAIL;
}
- if (cp_address_offset (&p, reloc) == FAIL)
+ if (my_get_expression (& inst.reloc.exp, &p, GE_IMM_PREFIX))
return FAIL;
+ inst.reloc.type = reloc;
}
else
pre_inc = PRE_INDEX | INDEX_UP;
@@ -2218,11 +2190,11 @@
return FAIL;
}
+ if (my_get_expression (& inst.reloc.exp, &p, GE_IMM_PREFIX))
+ return FAIL;
+ inst.reloc.type = reloc;
pre_inc = PRE_INDEX;
- if (cp_address_offset (&p, reloc) == FAIL)
- return FAIL;
-
if (*p++ != ']')
{
inst.error = _("missing ]");
@@ -2244,7 +2216,7 @@
}
else
{
- if (my_get_expression (&inst.reloc.exp, &p))
+ if (my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX))
return FAIL;
inst.reloc.type = reloc;
@@ -2291,16 +2263,8 @@
inst.operands[i].isreg = 1;
if (skip_past_comma (&s) != FAIL)
{
- if (is_immediate_prefix (*s))
+ if ((Ro = arm_reg_parse (&s, REG_TYPE_RN)) != FAIL)
{
- s++;
- if (my_get_expression (&inst.reloc.exp, &s))
- return FAIL;
- }
- else
- {
- if ((Ro = arm_reg_parse (&s, REG_TYPE_RN)) == FAIL)
- return FAIL;
if (Ro > 7 || Rb > 7)
{
inst.error = BAD_HIREG;
@@ -2309,6 +2273,8 @@
inst.operands[i].imm = Ro;
inst.operands[i].immisreg = 1;
}
+ else if (my_get_expression (&inst.reloc.exp, &s, GE_IMM_PREFIX))
+ return FAIL;
}
else
{
@@ -2325,7 +2291,7 @@
else if (*s == '=')
{
s++;
- if (my_get_expression (&inst.reloc.exp, &s))
+ if (my_get_expression (&inst.reloc.exp, &s, GE_NO_PREFIX))
return FAIL;
if ( inst.reloc.exp.X_op != O_constant
@@ -2337,7 +2303,7 @@
}
else
{
- if (my_get_expression (&inst.reloc.exp, &s))
+ if (my_get_expression (&inst.reloc.exp, &s, GE_NO_PREFIX))
return FAIL;
inst.reloc.exp.X_add_number -= 4; /* Pipeline offset. */
@@ -4363,19 +4329,19 @@
/* Expressions */
case OP_(iEXP):
iEXP:
- if (is_immediate_prefix (*str))
- str++;
- /* fall through */
+ if (my_get_expression (&inst.reloc.exp, &str, GE_OPT_PREFIX))
+ return FAIL;
+ break;
case OP_(EXP):
EXP:
- if (my_get_expression (&inst.reloc.exp, &str))
+ if (my_get_expression (&inst.reloc.exp, &str, GE_NO_PREFIX))
return FAIL;
break;
case OP_(EXPr):
EXPr:
- if (my_get_expression (&inst.reloc.exp, &str))
+ if (my_get_expression (&inst.reloc.exp, &str, GE_NO_PREFIX))
return FAIL;
if (inst.reloc.exp.X_op == O_symbol)
{
@@ -5124,7 +5090,7 @@
/* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
str++;
- expression_or_fail (&inst.reloc.exp, &str);
+ expression_or_fail (&inst.reloc.exp, &str, GE_NO_PREFIX);
if (inst.reloc.exp.X_op != O_constant
&& inst.reloc.exp.X_op != O_symbol)
@@ -5178,7 +5144,7 @@
}
else
{
- expression_or_fail (&inst.reloc.exp, &str);
+ expression_or_fail (&inst.reloc.exp, &str, GE_NO_PREFIX);
inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
#ifndef TE_WINCE
@@ -5351,7 +5317,7 @@
/* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
str++;
- expression_or_fail (&inst.reloc.exp, &str);
+ expression_or_fail (&inst.reloc.exp, &str, GE_NO_PREFIX);
if (inst.reloc.exp.X_op != O_constant
&& inst.reloc.exp.X_op != O_symbol)
@@ -5404,7 +5370,7 @@
}
else
{
- expression_or_fail (&inst.reloc.exp, &str);
+ expression_or_fail (&inst.reloc.exp, &str, GE_NO_PREFIX);
inst.instruction |= HWOFFSET_IMM;
inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;