This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Thumb32 assembler (34/69)
- From: Zack Weinberg <zack at codesourcery dot com>
- To: binutils <binutils at sourceware dot org>
- Date: Tue, 26 Apr 2005 02:55:00 -0700
- Subject: Thumb32 assembler (34/69)
parse_operands conversion for some of the FPA instructions; also a
certain amount of whitespace tweaking.
zw
* config/tc-arm.c (my_get_float_expression): Rename fpa_immediate.
Fold in exact-string-match logic from fp_op2. Return the
pseudo-register number, not the index into the table.
(fp_op2): Delete.
(OP_RF_IF): New operand parse code.
(parse_operand): Implement it.
(do_fpa_cmp, do_fpa_monadic, do_fpa_dyadic): Use parse_operands.
===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c (revision 35)
+++ gas/config/tc-arm.c (revision 37)
@@ -877,11 +877,11 @@
return 0;
}
-/* Returns the index into fp_values of a floating point number,
- or -1 if not in the table. */
+/* Returns the pseudo-register number of an FPA immediate constant,
+ or FAIL if there isn't a valid constant here. */
static int
-my_get_float_expression (char ** str)
+fpa_immediate (char ** str)
{
LITTLENUM_TYPE words[MAX_LITTLENUMS];
char * save_in;
@@ -889,6 +889,27 @@
int i;
int j;
+ /* First try and match exact strings, this is to guarantee
+ that some formats will work even for cross assembly. */
+
+ for (i = 0; fp_const[i]; i++)
+ {
+ if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
+ {
+ char *start = *str;
+
+ *str += strlen (fp_const[i]);
+ if (is_end_of_line[(unsigned char) **str])
+ return i + 8;
+ *str = start;
+ }
+ }
+
+ /* Just because we didn't get a match doesn't mean that the constant
+ isn't valid, just that it is in a format that we don't
+ automatically recognize. Try parsing it with the standard
+ expression routines. */
+
memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
/* Look for a raw floating point number. */
@@ -906,7 +927,7 @@
if (j == MAX_LITTLENUMS)
{
*str = save_in;
- return i;
+ return i + 8;
}
}
}
@@ -935,7 +956,7 @@
{
*str = input_line_pointer;
input_line_pointer = save_in;
- return i;
+ return i + 8;
}
}
}
@@ -943,7 +964,8 @@
*str = input_line_pointer;
input_line_pointer = save_in;
- return -1;
+ inst.error = _("invalid FPA immediate expression");
+ return FAIL;
}
/* We handle all bad expressions here, so that we can report the faulty
@@ -989,7 +1011,7 @@
inst.error = _("immediate value out of range");
return FAIL;
}
-
+
*val = exp.X_add_number;
return SUCCESS;
}
@@ -1125,7 +1147,7 @@
if (!reg)
return NULL;
-
+
*ccp = p;
return reg;
}
@@ -1825,59 +1847,6 @@
}
}
-
-static int
-fp_op2 (char ** str)
-{
- if (reg_required_here (str, 0, REG_TYPE_FN) != FAIL)
- return SUCCESS;
- else
- {
- /* Immediate expression. */
- if (*((*str)++) == '#')
- {
- int i;
-
- inst.error = NULL;
-
- /* First try and match exact strings, this is to guarantee
- that some formats will work even for cross assembly. */
-
- for (i = 0; fp_const[i]; i++)
- {
- if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
- {
- char *start = *str;
-
- *str += strlen (fp_const[i]);
- if (is_end_of_line[(unsigned char) **str])
- {
- inst.instruction |= i + 8;
- return SUCCESS;
- }
- *str = start;
- }
- }
-
- /* Just because we didn't get a match doesn't mean that the
- constant isn't valid, just that it is in a format that we
- don't automatically recognize. Try parsing it with
- the standard expression routines. */
- if ((i = my_get_float_expression (str)) >= 0)
- {
- inst.instruction |= i + 8;
- return SUCCESS;
- }
-
- inst.error = _("invalid floating point immediate expression");
- return FAIL;
- }
- inst.error =
- _("floating point register or immediate expression expected");
- return FAIL;
- }
-}
-
/* Parse an explicit relocation suffix on an expression. This is
either nothing, or a word in parentheses. Note that if !OBJ_ELF,
arm_reloc_hsh contains no entries, so this function can only
@@ -1888,7 +1857,7 @@
{
struct reloc_entry *r;
char *p, *q;
-
+
if (**str != '(')
return BFD_RELOC_UNUSED;
@@ -2624,7 +2593,7 @@
{
if (new->builtin)
as_warn (_("ignoring attempt to redefine built-in register '%s'"), str);
-
+
/* Only warn about a redefinition if it's not defined as the
same register. */
else if (new->number != number || new->type != type)
@@ -4287,64 +4256,65 @@
the macros below. Never refer to these constants except via the
macros below. */
-#define OP_stop 000 /* end of line */
+#define OP_stop 000 /* end of line */
-#define OP_RR 001 /* ARM register */
-#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_RR 001 /* ARM register */
+#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_EXPr 026 /* same, with optional relocation suffix */
+#define OP_EXP 024 /* arbitrary expression */
+#define OP_iEXP 025 /* same, with optional immediate prefix */
+#define OP_EXPr 026 /* same, with optional relocation suffix */
-#define OP_I0 027 /* immediate value 0 */
+#define OP_I0 027 /* immediate value 0 */
#define OP_I4 030 /* 1 .. 4 */
-#define OP_I7 031 /* 0 .. 7 */
-#define OP_I15 032 /* 0 .. 15 */
-#define OP_I16 033 /* 1 .. 16 */
-#define OP_I31 034 /* 0 .. 31 */
-#define OP_I32 035 /* 1 .. 32 */
-#define OP_Is63 036 /* -64 .. 63 */
-#define OP_I255 037 /* 0 .. 255 */
+#define OP_I7 031 /* 0 .. 7 */
+#define OP_I15 032 /* 0 .. 15 */
+#define OP_I16 033 /* 1 .. 16 */
+#define OP_I31 034 /* 0 .. 31 */
+#define OP_I32 035 /* 1 .. 32 */
+#define OP_Is63 036 /* -64 .. 63 */
+#define OP_I255 037 /* 0 .. 255 */
#define OP_Iffff 040 /* 0 .. 65535 */
-#define OP_bI7 041 /* immediate, prefix optional, 0 .. 7 */
+#define OP_bI7 041 /* immediate, prefix optional, 0 .. 7 */
#define OP_bI15 042 /* 0 .. 15 */
#define OP_bI31 043 /* 0 .. 31 */
-#define OP_I31w 050 /* 0 .. 31, optional trailing ! */
-#define OP_RRw 051 /* ARM register, not the PC, optional trailing ! */
+#define OP_I31w 050 /* 0 .. 31, optional trailing ! */
+#define OP_RRw 051 /* ARM register, not the PC, optional trailing ! */
-#define OP_RL 052 /* Thumb low register */
-#define OP_RLlb 053 /* Thumb low register, leading [ */
-#define OP_RLtb 054 /* Thumb low register. trailing ] */
+#define OP_RL 052 /* Thumb low register */
+#define OP_RLlb 053 /* Thumb low register, leading [ */
+#define OP_RLtb 054 /* Thumb low register. trailing ] */
-#define OP_CPSF 060 /* CPS flags */
-#define OP_ENDI 061 /* Endianness specifier */
+#define OP_CPSF 060 /* CPS flags */
+#define OP_ENDI 061 /* Endianness specifier */
#define OP_PSR 062 /* CPSR/SPSR mask for msr */
/* This-or-that operands. All have bit 7 set. */
-#define OP_RR_EX 100 /* ARM register or expression */
-#define OP_RL_iEX 101 /* Thumb low register or expression with imm prefix */
-#define OP_RRnpc_I0 102 /* ARM register or literal 0 */
+#define OP_RR_EX 100 /* ARM register or expression */
+#define OP_RL_iEX 101 /* Thumb low register or expression with imm prefix */
+#define OP_RRnpc_I0 102 /* ARM register or literal 0 */
#define OP_RR_EXr 103 /* ARM register or expression with opt. reloc suff. */
#define OP_RR_iEX 104 /* ARM register or expression with imm prefix */
+#define OP_RF_IF 105 /* FPA register or immediate */
/* Optional operands. All have the high bit set. */
#define OP_obI7 200 /* optional, prefix optional, immediate 0 .. 7 */
@@ -4353,10 +4323,10 @@
#define OP_obIffff 203 /* 0 .. 65535 */
#define OP_ocI255 204 /* optional, curly-brace enclosed, imm 0 .. 255 */
-#define OP_oROR 210 /* optional rotate right 0/8/16/24 */
-#define OP_oRL 211 /* optional Thumb low register */
+#define OP_oROR 210 /* optional rotate right 0/8/16/24 */
+#define OP_oRL 211 /* optional Thumb low register */
-#define OP_oRL_iEX 300 /* optional Thumb low reg or expression */
+#define OP_oRL_iEX 300 /* optional Thumb low reg or expression */
/* Macro for referring to one of the above constants as a number.
Should appear solely in parse_operands(). */
@@ -4484,7 +4454,7 @@
if (inst.operands[i].reg > 7)
inst.error = BAD_HIREG;
break;
-
+
case OP_(RLlb):
po_char_or_fail ('[');
po_reg_or_fail (REG_TYPE_RN);
@@ -4498,7 +4468,7 @@
if (inst.operands[i].reg > 7)
inst.error = BAD_HIREG;
break;
-
+
/* Immediates */
I0:
case OP_(I0): po_imm_or_fail ( 0, 0, FALSE); break;
@@ -4544,14 +4514,14 @@
str = s;
}
break;
-
+
/* Expressions */
case OP_(iEXP):
iEXP:
if (is_immediate_prefix (*str))
str++;
/* fall through */
-
+
case OP_(EXP):
EXP:
if (my_get_expression (&inst.reloc.exp, &str))
@@ -4597,6 +4567,23 @@
inst.error = BAD_PC;
break;
+ case OP_(RF_IF):
+ if (!is_immediate_prefix (*str))
+ po_reg_or_fail (REG_TYPE_FN);
+ else
+ {
+ int reg_;
+ str++;
+ reg_ = fpa_immediate (&str);
+ if (reg_ == FAIL)
+ return FAIL;
+ /* FPA immediates are encoded as registers 8-15.
+ fpa_immediate has already applied the offset. */
+ inst.operands[i].reg = reg_;
+ inst.operands[i].isreg = 1;
+ }
+ break;
+
/* Misc */
case OP_(CPSF):
if (parse_cps_flags (&inst.operands[i].imm, &str))
@@ -4621,7 +4608,7 @@
inst.operands[i].imm = psrmask;
}
break;
-
+
default:
as_fatal ("unhandled operand code %03o", *p);
}
@@ -4687,7 +4674,7 @@
static void
do_empty (char * str)
{
- parse_operands (str, OPERANDS0 ());
+ parse_operands (str, OPERANDS0());
}
/* ARM instructions, in alphabetical order by function name (except
@@ -4700,7 +4687,7 @@
static void
do_adr (char * str)
{
- if (parse_operands (str, OPERANDS2 (RR, EXP)) == FAIL)
+ if (parse_operands (str, OPERANDS2(RR,EXP)) == FAIL)
return;
inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
@@ -4722,7 +4709,7 @@
static void
do_adrl (char * str)
{
- if (parse_operands (str, OPERANDS2 (RR, EXP)) == FAIL)
+ if (parse_operands (str, OPERANDS2(RR,EXP)) == FAIL)
return;
inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
@@ -4911,7 +4898,7 @@
static void
do_bx (char * str)
{
- if (parse_operands (str, OPERANDS1 (RR)) == FAIL)
+ if (parse_operands (str, OPERANDS1(RR)) == FAIL)
return;
if (inst.operands[0].reg == REG_PC)
@@ -4926,7 +4913,7 @@
static void
do_bxj (char * str)
{
- if (parse_operands (str, OPERANDS1 (RR)) == FAIL)
+ if (parse_operands (str, OPERANDS1(RR)) == FAIL)
return;
if (inst.operands[0].reg == REG_PC)
@@ -4960,7 +4947,7 @@
static void
do_clz (char * str)
{
- if (parse_operands (str, OPERANDS2 (RRnpc,RRnpc)) == FAIL)
+ if (parse_operands (str, OPERANDS2(RRnpc,RRnpc)) == FAIL)
return;
inst.instruction |= (inst.operands[0].reg << 12);
@@ -5170,7 +5157,7 @@
static void
do_ldrex (char * str)
{
- if (parse_operands (str, OPERANDS2(RRnpc, bRRnpc)))
+ if (parse_operands (str, OPERANDS2(RRnpc,bRRnpc)))
return;
inst.instruction |= (inst.operands[0].reg << 12);
@@ -5650,7 +5637,7 @@
inst.instruction |= (inst.operands[1].reg << 0);
inst.instruction |= (inst.operands[2].reg << 8);
inst.instruction |= (inst.operands[3].reg << 12);
-
+
/* This restriction does not apply to mls (nor to mla in v6, but
that's hard to detect at present). */
if (inst.operands[0].reg == inst.operands[1].reg && !is_mls)
@@ -6134,7 +6121,7 @@
inst.instruction |= (inst.operands[1].reg << 16);
inst.instruction |= (inst.operands[2].reg << 0);
inst.instruction |= (inst.operands[3].reg << 8);
-
+
if (inst.operands[0].reg == inst.operands[1].reg)
as_tsktsk (_("rdhi and rdlo must be different"));
}
@@ -6742,7 +6729,7 @@
{
if (parse_operands (str, OPERANDS2(RL,EXP)))
return;
-
+
inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
inst.reloc.pc_rel = 1;
@@ -7415,40 +7402,32 @@
static void
do_fpa_cmp (char * str)
{
- reg_or_fail (&str, 16, REG_TYPE_FN);
- comma_or_fail (&str);
-
- if (fp_op2 (&str) == FAIL)
+ if (parse_operands (str, OPERANDS2(RF,RF_IF)))
return;
- end_of_line (str);
+ inst.instruction |= inst.operands[0].reg << 16;
+ inst.instruction |= inst.operands[1].reg;
}
static void
do_fpa_monadic (char * str)
{
- reg_or_fail (&str, 12, REG_TYPE_FN);
- comma_or_fail (&str);
-
- if (fp_op2 (&str) == FAIL)
+ if (parse_operands (str, OPERANDS2(RF,RF_IF)))
return;
- end_of_line (str);
+ inst.instruction |= inst.operands[0].reg << 12;
+ inst.instruction |= inst.operands[1].reg;
}
static void
do_fpa_dyadic (char * str)
{
- reg_or_fail (&str, 12, REG_TYPE_FN);
- comma_or_fail (&str);
-
- reg_or_fail (&str, 16, REG_TYPE_FN);
- comma_or_fail (&str);
-
- if (fp_op2 (&str) == FAIL)
+ if (parse_operands (str, OPERANDS3(RF,RF,RF_IF)))
return;
- end_of_line (str);
+ inst.instruction |= inst.operands[0].reg << 12;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.instruction |= inst.operands[2].reg;
}
static void
@@ -7456,7 +7435,7 @@
{
if (parse_operands (str, OPERANDS2(RF,RR)))
return;
-
+
inst.instruction |= (inst.operands[0].reg << 16);
inst.instruction |= (inst.operands[1].reg << 12);
}
@@ -7466,7 +7445,7 @@
{
if (parse_operands (str, OPERANDS2(RR,RF)))
return;
-
+
inst.instruction |= (inst.operands[0].reg << 12);
inst.instruction |= (inst.operands[1].reg << 0);
}
@@ -7599,7 +7578,7 @@
{
if (parse_operands (str, OPERANDS2(RR,RIWR)))
return;
-
+
inst.instruction |= (inst.operands[0].reg << 12);
inst.instruction |= (inst.operands[1].reg << 16);
}
@@ -7641,7 +7620,7 @@
{
if (parse_operands (str, OPERANDS2(RIWC,RR)))
return;
-
+
inst.instruction |= (inst.operands[0].reg << 16);
inst.instruction |= (inst.operands[1].reg << 12);
}
@@ -7651,7 +7630,7 @@
{
if (parse_operands (str, OPERANDS3(RIWR,RR,RR)))
return;
-
+
inst.instruction |= (inst.operands[0].reg << 0);
inst.instruction |= (inst.operands[1].reg << 12);
inst.instruction |= (inst.operands[2].reg << 16);
@@ -7662,7 +7641,7 @@
{
if (parse_operands (str, OPERANDS3(RIWR,RR,RR)))
return;
-
+
inst.instruction |= (inst.operands[0].reg << 5);
inst.instruction |= (inst.operands[1].reg << 0);
inst.instruction |= (inst.operands[2].reg << 12);
@@ -7673,7 +7652,7 @@
{
if (parse_operands (str, OPERANDS2(RR,RIWR)))
return;
-
+
inst.instruction |= (inst.operands[0].reg << 12);
inst.instruction |= (inst.operands[1].reg << 16);
@@ -7684,7 +7663,7 @@
{
if (parse_operands (str, OPERANDS2(RR,RIWC)))
return;
-
+
inst.instruction |= (inst.operands[0].reg << 12);
inst.instruction |= (inst.operands[1].reg << 16);
}
@@ -7694,7 +7673,7 @@
{
if (parse_operands (str, OPERANDS3(RR,RR,RIWR)))
return;
-
+
inst.instruction |= (inst.operands[0].reg << 12);
inst.instruction |= (inst.operands[1].reg << 16);
inst.instruction |= (inst.operands[2].reg << 0);
@@ -8586,11 +8565,11 @@
/* VFP control registers. */
REGDEF(fpsid,0,VFC), REGDEF(fpscr,1,VFC), REGDEF(fpexc,8,VFC),
REGDEF(FPSID,0,VFC), REGDEF(FPSCR,1,VFC), REGDEF(FPEXC,8,VFC),
-
+
/* Maverick DSP coprocessor registers. */
REGSET(mvf,MVF), REGSET(mvd,MVD), REGSET(mvfx,MVFX), REGSET(mvdx,MVDX),
REGSET(MVF,MVF), REGSET(MVD,MVD), REGSET(MVFX,MVFX), REGSET(MVDX,MVDX),
-
+
REGNUM(mvax,0,MVAX), REGNUM(mvax,1,MVAX),
REGNUM(mvax,2,MVAX), REGNUM(mvax,3,MVAX),
REGDEF(dspsc,0,DSPSC),
@@ -10302,7 +10281,7 @@
flags = SHF_ALLOC;
linkonce = 0;
group_name = 0;
-
+
/* Handle COMDAT group. */
if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
{
@@ -10622,7 +10601,7 @@
/* This will need to go in the object file. */
fixP->fx_done = 0;
break;
-
+
case BFD_RELOC_ARM_IMMEDIATE:
/* We claim that this fixup has been processed here,
even if in fact we generate an error because we do
@@ -11833,7 +11812,7 @@
}
else if (mfpu_opt == -1)
{
-#if !(defined (TE_LINUX) || defined (TE_NetBSD) || defined (TE_VXWORKS))
+#if !(defined (TE_LINUX) || defined (TE_NetBSD) || defined (TE_VXWORKS))
/* Some environments specify a default FPU. If they don't, infer it
from the processor. */
if (mcpu_fpu_opt != -1)