This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Thumb32 assembler (8/69)
- From: Zack Weinberg <zack at codesourcery dot com>
- To: binutils <binutils at sourceware dot org>
- Date: Tue, 26 Apr 2005 02:53:12 -0700
- Subject: Thumb32 assembler (8/69)
The previous patch pays dividends, allowing us to get rid of some
redundant constants and simplify some of the coprocessor parsers.
* config/tc-arm.c (enum wreg_type): Delete.
(IWMMXT_REG_WR, IWMMXT_REG_WC, IWMMXT_REG_WCG): All occurrences
replaced with REG_TYPE_MMXWR, REG_TYPE_MMXWC, REG_TYPE_MMXWCG
respectively.
(arm_reg_parse_multi): New function.
(arm_reg_parse, wreg_required_here, mav_reg_required_here)
(s_arm_unwind_save): Rewrite in terms of arm_reg_parse_multi.
===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c (revision 9)
+++ gas/config/tc-arm.c (revision 10)
@@ -481,13 +481,6 @@
{"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
};
-enum wreg_type
- {
- IWMMXT_REG_WR = 0,
- IWMMXT_REG_WC = 1,
- IWMMXT_REG_WCG
- };
-
enum iwmmxt_insn_type
{
check_rd,
@@ -1275,11 +1268,11 @@
/* Generic register parser. CCP points to what should be the
beginning of a register name. If it is indeed a valid register
- name, of type TYPE, return the associated register number. If it
- is not, return FAIL. Does not issue diagnostics. */
+ name, advance CCP over it and return the reg_entry structure;
+ otherwise return NULL. Does not issue diagnostics. */
-static int
-arm_reg_parse (char **ccp, enum arm_reg_type type)
+static struct reg_entry *
+arm_reg_parse_multi (char **ccp)
{
char *start = *ccp;
char *p;
@@ -1297,7 +1290,7 @@
p = start;
if (!ISALPHA (*p) || !is_name_beginner (*p))
- return FAIL;
+ return NULL;
do
p++;
@@ -1305,13 +1298,29 @@
reg = (struct reg_entry *) hash_find_n (arm_reg_hsh, start, p - start);
- if (!reg || reg->type != type)
- return FAIL;
+ if (!reg)
+ return NULL;
*ccp = p;
- return reg->number;
+ return reg;
}
+/* As above, but the register must be of type TYPE, and the return
+ value is the register number or NULL. */
+
+static int
+arm_reg_parse (char **ccp, enum arm_reg_type type)
+{
+ char *start = *ccp;
+ struct reg_entry *reg = arm_reg_parse_multi (ccp);
+
+ if (reg && reg->type == type)
+ return reg->number;
+
+ *ccp = start;
+ return FAIL;
+}
+
/* A standard register must be given at this point. SHIFT is the
place to put it in inst.instruction. Restores input start point on
error. Returns the reg#, or FAIL. */
@@ -1512,44 +1521,21 @@
Returns the reg#, or FAIL. */
static int
-wreg_required_here (char **str, int shift, enum wreg_type reg_type)
+wreg_required_here (char **str, int shift, enum arm_reg_type regtype)
{
int reg;
- switch (reg_type)
+ if ((reg = arm_reg_parse (str, regtype)) == FAIL)
{
- case IWMMXT_REG_WR:
- if ((reg = arm_reg_parse (str, REG_TYPE_MMXWR)) == FAIL)
- {
- inst.error = gettext (reg_expected_msgs[REG_TYPE_MMXWR]);
- return FAIL;
- }
- break;
-
- case IWMMXT_REG_WC:
- if ((reg = arm_reg_parse (str, REG_TYPE_MMXWC)) == FAIL)
- {
- inst.error = gettext (reg_expected_msgs[REG_TYPE_MMXWC]);
- return FAIL;
- }
- break;
-
- case IWMMXT_REG_WCG:
- if ((reg = arm_reg_parse (str, REG_TYPE_MMXWCG)) == FAIL)
- {
- inst.error = gettext (reg_expected_msgs[REG_TYPE_MMXWCG]);
- return FAIL;
- }
- break;
-
- default:
- abort ();
+ inst.error = gettext (reg_expected_msgs[regtype]);
+ return FAIL;
}
-
- if (shift >= 0)
- inst.instruction |= reg << shift;
-
- return reg;
+ else
+ {
+ if (shift >= 0)
+ inst.instruction |= reg << shift;
+ return reg;
+ }
}
/* A register must be given at this point.
@@ -1562,43 +1548,27 @@
static int
mav_reg_required_here (char ** str, int shift, enum arm_reg_type regtype)
{
- int reg;
+ struct reg_entry *reg;
char *start = *str;
- if ((reg = arm_reg_parse (str, regtype)) != FAIL)
+ reg = arm_reg_parse_multi (str);
+ if (!reg
+ || (reg->type != regtype
+ /* Accept generic coprocessor register if applicable. */
+ && (reg->type != REG_TYPE_CN || (regtype != REG_TYPE_MVF
+ && regtype != REG_TYPE_MVD
+ && regtype != REG_TYPE_MVFX
+ && regtype != REG_TYPE_MVDX))))
{
- if (shift >= 0)
- inst.instruction |= reg << shift;
-
- return reg;
- }
-
- /* Restore the start point. */
- *str = start;
-
- /* Try generic coprocessor name if applicable. */
- if (regtype == REG_TYPE_MVF ||
- regtype == REG_TYPE_MVD ||
- regtype == REG_TYPE_MVFX ||
- regtype == REG_TYPE_MVDX)
- {
- if ((reg = arm_reg_parse (str, REG_TYPE_CN)) != FAIL)
- {
- if (shift >= 0)
- inst.instruction |= reg << shift;
-
- return reg;
- }
-
- /* Restore the start point. */
+ inst.error = gettext (reg_expected_msgs[regtype]);
*str = start;
+ return FAIL;
}
- /* In the few cases where we might be able to accept something else
- this error can be overridden. */
- inst.error = gettext (reg_expected_msgs[regtype]);
+ if (shift >= 0)
+ inst.instruction |= reg->number << shift;
- return FAIL;
+ return reg->number;
}
/* Expects *str -> the characters "acc0", possibly with leading blanks.
@@ -4522,59 +4492,50 @@
static void
s_arm_unwind_save (int ignored ATTRIBUTE_UNUSED)
{
- char *saved_ptr;
- int reg;
+ char *peek;
+ struct reg_entry *reg;
+ bfd_boolean had_brace = FALSE;
/* Figure out what sort of save we have. */
- SKIP_WHITESPACE ();
- saved_ptr = input_line_pointer;
+ peek = input_line_pointer;
+ skip_whitespace (peek);
- reg = arm_reg_parse (&input_line_pointer, REG_TYPE_FN);
- if (reg != FAIL)
+ if (*peek == '{')
{
- s_arm_unwind_save_fpa (reg);
- return;
+ had_brace = TRUE;
+ peek++;
}
- if (*input_line_pointer == '{')
- input_line_pointer++;
+ reg = arm_reg_parse_multi (&peek);
- SKIP_WHITESPACE ();
-
- reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
- if (reg != FAIL)
+ if (!reg)
{
- input_line_pointer = saved_ptr;
- s_arm_unwind_save_core ();
+ as_bad (_("register expected"));
+ ignore_rest_of_line ();
return;
}
- reg = arm_reg_parse (&input_line_pointer, REG_TYPE_DN);
- if (reg != FAIL)
+ switch (reg->type)
{
- input_line_pointer = saved_ptr;
- s_arm_unwind_save_vfp ();
+ case REG_TYPE_FN:
+ if (had_brace)
+ {
+ as_bad (_("FPA .unwind_save does not take a register list"));
+ ignore_rest_of_line ();
+ return;
+ }
+ s_arm_unwind_save_fpa (reg->number);
return;
- }
- reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
- if (reg != FAIL)
- {
- input_line_pointer = saved_ptr;
- s_arm_unwind_save_mmxwr ();
- return;
- }
+ case REG_TYPE_RN: s_arm_unwind_save_core (); return;
+ case REG_TYPE_DN: s_arm_unwind_save_vfp (); return;
+ case REG_TYPE_MMXWR: s_arm_unwind_save_mmxwr (); return;
+ case REG_TYPE_MMXWCG: s_arm_unwind_save_mmxwcg (); return;
- reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
- if (reg != FAIL)
- {
- input_line_pointer = saved_ptr;
- s_arm_unwind_save_mmxwcg ();
- return;
+ default:
+ as_bad (_(".unwind_save does not support this kind of register"));
+ ignore_rest_of_line ();
}
-
- /* TODO: Maverick registers. */
- as_bad (_("unrecognised register"));
}
@@ -8741,37 +8702,37 @@
break;
case check_wr:
- if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
+ if ((wreg_required_here (&str, 0, REG_TYPE_MMXWR)) == FAIL)
return FAIL;
break;
case check_wrwr:
- if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
+ if ((wreg_required_here (&str, 12, REG_TYPE_MMXWR) == FAIL
|| skip_past_comma (&str) == FAIL
- || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
+ || wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL))
return FAIL;
break;
case check_wrwrwr:
- if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
+ if ((wreg_required_here (&str, 12, REG_TYPE_MMXWR) == FAIL
|| skip_past_comma (&str) == FAIL
- || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL
|| skip_past_comma (&str) == FAIL
- || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
+ || wreg_required_here (&str, 0, REG_TYPE_MMXWR) == FAIL))
return FAIL;
break;
case check_wrwrwcg:
- if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
+ if ((wreg_required_here (&str, 12, REG_TYPE_MMXWR) == FAIL
|| skip_past_comma (&str) == FAIL
- || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL
|| skip_past_comma (&str) == FAIL
- || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
+ || wreg_required_here (&str, 0, REG_TYPE_MMXWCG) == FAIL))
return FAIL;
break;
case check_tbcst:
- if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ if ((wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL
|| skip_past_comma (&str) == FAIL
|| reg_required_here (&str, 12, FALSE) == FAIL))
return FAIL;
@@ -8780,12 +8741,12 @@
case check_tmovmsk:
if ((reg_required_here (&str, 12, FALSE) == FAIL
|| skip_past_comma (&str) == FAIL
- || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
+ || wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL))
return FAIL;
break;
case check_tmia:
- if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
+ if ((wreg_required_here (&str, 5, REG_TYPE_MMXWR) == FAIL
|| skip_past_comma (&str) == FAIL
|| reg_required_here (&str, 0, FALSE) == FAIL
|| skip_past_comma (&str) == FAIL
@@ -8794,7 +8755,7 @@
break;
case check_tmcrr:
- if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
+ if ((wreg_required_here (&str, 0, REG_TYPE_MMXWR) == FAIL
|| skip_past_comma (&str) == FAIL
|| reg_required_here (&str, 12, FALSE) == FAIL
|| skip_past_comma (&str) == FAIL
@@ -8807,12 +8768,12 @@
|| skip_past_comma (&str) == FAIL
|| reg_required_here (&str, 16, FALSE) == FAIL
|| skip_past_comma (&str) == FAIL
- || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
+ || wreg_required_here (&str, 0, REG_TYPE_MMXWR) == FAIL))
return FAIL;
break;
case check_tmcr:
- if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
+ if ((wreg_required_here (&str, 16, REG_TYPE_MMXWC) == FAIL
|| skip_past_comma (&str) == FAIL
|| reg_required_here (&str, 12, FALSE) == FAIL))
return FAIL;
@@ -8821,12 +8782,12 @@
case check_tmrc:
if ((reg_required_here (&str, 12, FALSE) == FAIL
|| skip_past_comma (&str) == FAIL
- || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
+ || wreg_required_here (&str, 16, REG_TYPE_MMXWC) == FAIL))
return FAIL;
break;
case check_tinsr:
- if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ if ((wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL
|| skip_past_comma (&str) == FAIL
|| reg_required_here (&str, 12, FALSE) == FAIL
|| skip_past_comma (&str) == FAIL))
@@ -8840,11 +8801,11 @@
break;
case check_waligni:
- if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
+ if ((wreg_required_here (&str, 12, REG_TYPE_MMXWR) == FAIL
|| skip_past_comma (&str) == FAIL
- || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL
|| skip_past_comma (&str) == FAIL
- || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
+ || wreg_required_here (&str, 0, REG_TYPE_MMXWR) == FAIL
|| skip_past_comma (&str) == FAIL))
return FAIL;
break;
@@ -8852,15 +8813,15 @@
case check_textrm:
if ((reg_required_here (&str, 12, FALSE) == FAIL
|| skip_past_comma (&str) == FAIL
- || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL
|| skip_past_comma (&str) == FAIL))
return FAIL;
break;
case check_wshufh:
- if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
+ if ((wreg_required_here (&str, 12, REG_TYPE_MMXWR) == FAIL
|| skip_past_comma (&str) == FAIL
- || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL
|| skip_past_comma (&str) == FAIL))
return FAIL;
break;
@@ -8894,7 +8855,7 @@
skip_whitespace (str);
- if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR)) == FAIL
+ if ((reg = wreg_required_here (&str, 12, REG_TYPE_MMXWR)) == FAIL
|| skip_past_comma (& str) == FAIL
|| cp_byte_address_required_here (&str) == FAIL)
{
@@ -9028,10 +8989,10 @@
skip_whitespace (str);
- if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR)) == FAIL)
+ if ((reg = wreg_required_here (&str, 12, REG_TYPE_MMXWR)) == FAIL)
{
inst.error = 0;
- if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WC)) == FAIL)
+ if ((reg = wreg_required_here (&str, 12, REG_TYPE_MMXWC)) == FAIL)
return;
if ((inst.instruction & COND_MASK) != COND_ALWAYS)