This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Thumb32 assembler (22/69)
- From: Zack Weinberg <zack at codesourcery dot com>
- To: binutils <binutils at sourceware dot org>
- Date: Tue, 26 Apr 2005 02:54:27 -0700
- Subject: Thumb32 assembler (22/69)
Here I change my mind again about how to handle the "invalid use of
r15" diagnostic.
zw
Go back to checking for invalid use of PC during parsing.
* config/tc-arm.c (OP_bRR): Replace with OP_bRRnpc.
(OP_RRnpc): New operand parse code.
(parse_operands): Handle new codes.
(reject_pc): Delete.
(do_bfc, do_clz, do_ldrex, do_mlas, do_mov16, do_mul, do_mull)
(do_qadd, do_qadd16, do_rev, do_ssat16, do_usat16, do_smla)
(do_smlal, do_strex, do_swap, do_xsc_mia, do_xsc_mar, do_xsc_mra):
Use new operand parse codes, not reject_pc.
===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c (revision 23)
+++ gas/config/tc-arm.c (revision 24)
@@ -4321,33 +4321,34 @@
#define OP_stop 000 /* end of line */
#define OP_RR 001 /* ARM register */
-#define OP_bRR 002 /* ARM register in square brackets */
-#define OP_RCP 003 /* Coprocessor number */
-#define OP_RCN 004 /* Coprocessor register */
-#define OP_RF 005 /* FPA register */
-#define OP_RVS 006 /* VFP single precision register */
-#define OP_RVD 007 /* VFP double precision register */
-#define OP_RVC 010 /* VFP control register */
-#define OP_RMF 011 /* Maverick F register */
-#define OP_RMD 012 /* Maverick D register */
-#define OP_RMFX 013 /* Maverick FX register */
-#define OP_RMDX 014 /* Maverick DX register */
-#define OP_RMAX 015 /* Maverick AX register */
-#define OP_RMDS 016 /* Maverick DSPSC register */
-#define OP_RIWR 017 /* iWMMXt wR register */
-#define OP_RIWC 020 /* iWMMXt wC register */
-#define OP_RIWG 021 /* iWMMXt wCG register */
-#define OP_RXA 022 /* XScale accumulator register */
-#define OP_EXP 023 /* arbitrary expression */
-#define OP_iEXP 024 /* same, with optional immediate prefix */
-#define OP_I0 025 /* immediate value 0 */
-#define OP_I4 026 /* 1 .. 4 */
-#define OP_I15 027 /* 0 .. 15 */
-#define OP_I16 030 /* 1 .. 16 */
-#define OP_I31 031 /* 0 .. 31 */
-#define OP_I32 032 /* 1 .. 32 */
-#define OP_I255 033 /* 0 .. 255 */
-#define OP_Iffff 034 /* 0 .. 65535 */
+#define OP_RRnpc 002 /* ARM register, not r15 */
+#define OP_bRRnpc 003 /* ARM register, not r15, in square brackets */
+#define OP_RCP 004 /* Coprocessor number */
+#define OP_RCN 005 /* Coprocessor register */
+#define OP_RF 006 /* FPA register */
+#define OP_RVS 007 /* VFP single precision register */
+#define OP_RVD 010 /* VFP double precision register */
+#define OP_RVC 011 /* VFP control register */
+#define OP_RMF 012 /* Maverick F register */
+#define OP_RMD 013 /* Maverick D register */
+#define OP_RMFX 014 /* Maverick FX register */
+#define OP_RMDX 015 /* Maverick DX register */
+#define OP_RMAX 016 /* Maverick AX register */
+#define OP_RMDS 017 /* Maverick DSPSC register */
+#define OP_RIWR 020 /* iWMMXt wR register */
+#define OP_RIWC 021 /* iWMMXt wC register */
+#define OP_RIWG 022 /* iWMMXt wCG register */
+#define OP_RXA 023 /* XScale accumulator register */
+#define OP_EXP 024 /* arbitrary expression */
+#define OP_iEXP 025 /* same, with optional immediate prefix */
+#define OP_I0 026 /* immediate value 0 */
+#define OP_I4 027 /* 1 .. 4 */
+#define OP_I15 030 /* 0 .. 15 */
+#define OP_I16 031 /* 1 .. 16 */
+#define OP_I31 032 /* 0 .. 31 */
+#define OP_I32 033 /* 1 .. 32 */
+#define OP_I255 034 /* 0 .. 255 */
+#define OP_Iffff 035 /* 0 .. 65535 */
/* Macro for referring to one of the above constants as a number.
Should appear solely in parse_operands(). */
@@ -4422,11 +4423,22 @@
case OP_(RIWG): po_reg_or_fail (REG_TYPE_MMXWCG); break;
case OP_(RXA): po_reg_or_fail (REG_TYPE_XSCALE); break;
- /* Decorated registers */
- case OP_(bRR):
+ /* Register variants */
+ case OP_(RRnpc):
+ po_reg_or_fail (REG_TYPE_RN);
+ if (inst.operands[i].reg == REG_PC)
+ inst.error = BAD_PC;
+ /* We do not signal an immediate failure for the PC; this
+ allows a syntax error to take precedence. The error will
+ be caught by output_inst. */
+ break;
+
+ case OP_(bRRnpc):
po_char_or_fail ('[');
po_reg_or_fail (REG_TYPE_RN);
po_char_or_fail (']');
+ if (inst.operands[i].reg == REG_PC)
+ inst.error = BAD_PC;
break;
/* Immediates */
@@ -4485,26 +4497,6 @@
/* Operand validation functions. */
-/* Set inst.error to BAD_PC and return FAIL if any of the specified register
- operands are REG_PC. N is the number of operands. */
-static int
-reject_pc (int n, ...)
-{
- va_list ap;
- va_start (ap, n);
- while (n--)
- {
- int op = va_arg (ap, int);
- if (inst.operands[op].reg == REG_PC)
- {
- inst.error = BAD_PC;
- return FAIL;
- }
- }
- va_end (ap);
- return SUCCESS;
-}
-
/* Set inst.error to BAD_OVERLAP and return FAIL if any of the
specified pairs of register operands are the same. N is the number
of pairs. */
@@ -4605,10 +4597,8 @@
do_bfc (char *str)
{
unsigned int msb;
- if (parse_operands (str, OPERANDS3(RR,I31,I32)))
+ if (parse_operands (str, OPERANDS3(RRnpc,I31,I32)))
return;
- if (reject_pc (1,0))
- return;
msb = inst.operands[1].imm + inst.operands[2].imm;
if (msb > 32)
@@ -4910,10 +4900,9 @@
static void
do_clz (char * str)
{
- if (parse_operands (str, OPERANDS2 (RR, RR)) == FAIL)
+ if (parse_operands (str, OPERANDS2 (RRnpc,RRnpc)) == FAIL)
return;
- if (reject_pc (2, 0,1))
- return;
+
inst.instruction |= (inst.operands[0].reg << 12);
inst.instruction |= (inst.operands[1].reg << 0);
}
@@ -5148,10 +5137,9 @@
static void
do_ldrex (char * str)
{
- if (parse_operands (str, OPERANDS2(RR, bRR)))
+ if (parse_operands (str, OPERANDS2(RRnpc, bRRnpc)))
return;
- if (reject_pc (2, 0,1))
- return;
+
inst.instruction |= (inst.operands[0].reg << 12);
inst.instruction |= (inst.operands[1].reg << 16);
}
@@ -5626,10 +5614,8 @@
static void
do_mlas (char * str, bfd_boolean is_mls)
{
- if (parse_operands (str, OPERANDS4(RR,RR,RR,RR)))
+ if (parse_operands (str, OPERANDS4(RRnpc,RRnpc,RRnpc,RRnpc)))
return;
- if (reject_pc (4, 0,1,2,3))
- return;
inst.instruction |= (inst.operands[0].reg << 16);
inst.instruction |= (inst.operands[1].reg << 0);
@@ -5675,13 +5661,10 @@
static void
do_mov16 (char *str)
{
- if (parse_operands (str, OPERANDS2(RR,Iffff)))
+ if (parse_operands (str, OPERANDS2(RRnpc,Iffff)))
return;
- if (reject_pc (1,0))
- return;
inst.instruction |= (inst.operands[0].reg << 12);
-
/* The value is in two pieces: 0:11, 16:19. */
inst.instruction |= (inst.operands[1].imm & 0x00000fff);
inst.instruction |= (inst.operands[1].imm & 0x0000f000) << 4;
@@ -5783,10 +5766,8 @@
static void
do_mul (char * str)
{
- if (parse_operands (str, OPERANDS3(RR,RR,RR)))
+ if (parse_operands (str, OPERANDS3(RRnpc,RRnpc,RR)))
return;
- if (reject_pc (2, 0,1))
- return;
inst.instruction |= (inst.operands[0].reg << 16);
inst.instruction |= (inst.operands[1].reg << 0);
@@ -5805,10 +5786,8 @@
static void
do_mull (char * str)
{
- if (parse_operands (str, OPERANDS4(RR,RR,RR,RR)))
+ if (parse_operands (str, OPERANDS4(RRnpc,RRnpc,RRnpc,RRnpc)))
return;
- if (reject_pc (4, 0,1,2,3))
- return;
inst.instruction |= (inst.operands[0].reg << 12);
inst.instruction |= (inst.operands[1].reg << 16);
@@ -5978,10 +5957,8 @@
static void
do_qadd (char * str)
{
- if (parse_operands (str, OPERANDS3(RR,RR,RR)))
+ if (parse_operands (str, OPERANDS3(RRnpc,RRnpc,RRnpc)))
return;
- if (reject_pc (3, 0,1,2))
- return;
inst.instruction |= (inst.operands[0].reg << 12);
inst.instruction |= (inst.operands[1].reg << 0);
@@ -5996,10 +5973,8 @@
static void
do_qadd16 (char * str)
{
- if (parse_operands (str, OPERANDS3(RR,RR,RR)))
+ if (parse_operands (str, OPERANDS3(RRnpc,RRnpc,RRnpc)))
return;
- if (reject_pc (3, 0,1,2))
- return;
inst.instruction |= (inst.operands[0].reg << 12);
inst.instruction |= (inst.operands[1].reg << 16);
@@ -6025,10 +6000,8 @@
static void
do_rev (char * str)
{
- if (parse_operands (str, OPERANDS2(RR,RR)))
+ if (parse_operands (str, OPERANDS2(RRnpc,RRnpc)))
return;
- if (reject_pc (2, 0,1))
- return;
inst.instruction |= (inst.operands[0].reg << 12);
inst.instruction |= (inst.operands[1].reg << 0);
@@ -6097,10 +6070,8 @@
static void
do_ssat16 (char * str)
{
- if (parse_operands (str, OPERANDS3(RR,I16,RR)))
+ if (parse_operands (str, OPERANDS3(RRnpc,I16,RRnpc)))
return;
- if (reject_pc (2, 0,2))
- return;
inst.instruction |= (inst.operands[0].reg << 12);
inst.instruction |= ((inst.operands[1].imm - 1) << 16);
@@ -6110,10 +6081,8 @@
static void
do_usat16 (char * str)
{
- if (parse_operands (str, OPERANDS3(RR,I15,RR)))
+ if (parse_operands (str, OPERANDS3(RRnpc,I15,RRnpc)))
return;
- if (reject_pc (2, 0,2))
- return;
inst.instruction |= (inst.operands[0].reg << 12);
inst.instruction |= (inst.operands[1].imm << 16);
@@ -6161,10 +6130,8 @@
static void
do_smla (char * str)
{
- if (parse_operands (str, OPERANDS4(RR,RR,RR,RR)))
+ if (parse_operands (str, OPERANDS4(RRnpc,RRnpc,RRnpc,RRnpc)))
return;
- if (reject_pc (4, 0,1,2,3))
- return;
inst.instruction |= (inst.operands[0].reg << 16);
inst.instruction |= (inst.operands[1].reg << 0);
@@ -6180,10 +6147,8 @@
static void
do_smlal (char * str)
{
- if (parse_operands (str, OPERANDS4(RR,RR,RR,RR)))
+ if (parse_operands (str, OPERANDS4(RRnpc,RRnpc,RRnpc,RRnpc)))
return;
- if (reject_pc (4, 0,1,2,3))
- return;
inst.instruction |= (inst.operands[0].reg << 12);
inst.instruction |= (inst.operands[1].reg << 16);
@@ -6201,10 +6166,8 @@
static void
do_smul (char * str)
{
- if (parse_operands (str, OPERANDS3(RR,RR,RR)))
+ if (parse_operands (str, OPERANDS3(RRnpc,RRnpc,RRnpc)))
return;
- if (reject_pc (3, 0,1,2))
- return;
inst.instruction |= (inst.operands[0].reg << 16);
inst.instruction |= (inst.operands[1].reg << 0);
@@ -6237,9 +6200,9 @@
static void
do_strex (char * str)
{
- if (parse_operands (str, OPERANDS3(RR,RR,bRR)))
+ if (parse_operands (str, OPERANDS3(RRnpc,RRnpc,bRRnpc)))
return;
- if (reject_pc (3, 0,1,2) || reject_overlap (2, 0,1, 0,2))
+ if (reject_overlap (2, 0,1, 0,2))
return;
inst.instruction |= (inst.operands[0].reg << 12);
@@ -6250,10 +6213,8 @@
static void
do_swap (char * str)
{
- if (parse_operands (str, OPERANDS3(RR,RR,bRR)))
+ if (parse_operands (str, OPERANDS3(RRnpc,RRnpc,bRRnpc)))
return;
- if (reject_pc (3, 0,1,2))
- return;
inst.instruction |= (inst.operands[0].reg << 12);
inst.instruction |= (inst.operands[1].reg << 0);
@@ -8632,10 +8593,8 @@
static void
do_xsc_mia (char * str)
{
- if (parse_operands (str, OPERANDS3(RXA,RR,RR)))
+ if (parse_operands (str, OPERANDS3(RXA,RRnpc,RRnpc)))
return;
- if (reject_pc (2, 1,2))
- return;
inst.instruction |= (inst.operands[1].reg << 0);
inst.instruction |= (inst.operands[2].reg << 12);
@@ -8648,10 +8607,8 @@
static void
do_xsc_mar (char * str)
{
- if (parse_operands (str, OPERANDS3(RXA,RR,RR)))
+ if (parse_operands (str, OPERANDS3(RXA,RRnpc,RRnpc)))
return;
- if (reject_pc (2, 1,2))
- return;
inst.instruction |= (inst.operands[1].reg << 12);
inst.instruction |= (inst.operands[2].reg << 16);
@@ -8664,9 +8621,9 @@
static void
do_xsc_mra (char * str)
{
- if (parse_operands (str, OPERANDS3(RR,RR,RXA)))
+ if (parse_operands (str, OPERANDS3(RRnpc,RRnpc,RXA)))
return;
- if (reject_pc (2, 0,1) || reject_overlap (1, 0,1))
+ if (reject_overlap (1, 0,1))
return;
inst.instruction |= (inst.operands[0].reg << 12);