This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[RFA] ARM: VLDM/VSTM pc, {} is predictable in ARM state
- From: Matthew Gretton-Dann <matthew dot gretton-dann at arm dot com>
- To: binutils at sourceware dot org
- Date: Mon, 07 Jun 2010 17:24:03 +0100
- Subject: [RFA] ARM: VLDM/VSTM pc, {} is predictable in ARM state
All,
Please can someone review and approve the attached patch?
The patch is to fix gas so that it accepts vldm pc, {...}, vstm pc,
{...}, and the divided syntax equivalents, in ARM state.
(These instructions with writeback, or in Thumb-state are
unpredictable).
Thanks,
Matt
Proposed ChangeLogs:
gas/ChangeLog:
2010-06-07 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
* config/tc-arm.c (operand_parse_code): Add OP_RRnpctw enum
value.
(parse_operands): Add support for OP_RRnpctw.
(insns): Update floating-point load/store multiples so the
first register is of type OP_RRnpctw.
gas/testsuite/ChangeLog:
2010-06-07 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
* gas/arm/vldm-arm.d: New test.
* gas/arm/vldm-thumb-bad.d: Likewise.
* gas/arm/vldm-thumb-bad.l: Likewise.
* gas/arm/vldm.s: Likewise.
* gas/arm/vldmw-arm-bad.d: Likewise.
* gas/arm/vldmw-bad.l: Likewise.
* gad/arm-vldmw-bad.s: Likewise.
* gas/arm/vldmw-thumb-bad.d: Likewise.
--
Matthew Gretton-Dann
Principal Engineer - PDSW Tools
ARM Ltd
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 6cf37b1..2e4880a 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -5759,6 +5759,8 @@ enum operand_parse_code
OP_RRnpc, /* ARM register, not r15 */
OP_RRnpcsp, /* ARM register, neither r15 nor r13 (a.k.a. 'BadReg') */
OP_RRnpcb, /* ARM register, not r15, in square brackets */
+ OP_RRnpctw, /* ARM register, not r15 in Thumb-state or with writeback,
+ optional trailing ! */
OP_RRw, /* ARM register, not r15, optional trailing ! */
OP_RCP, /* Coprocessor number */
OP_RCN, /* Coprocessor register */
@@ -6128,6 +6130,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
po_char_or_fail (']');
break;
+ case OP_RRnpctw:
case OP_RRw:
case OP_oRRw:
po_reg_or_fail (REG_TYPE_RN);
@@ -6436,6 +6439,13 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
}
break;
+ case OP_RRnpctw:
+ if (inst.operands[i].isreg
+ && inst.operands[i].reg == REG_PC
+ && (inst.operands[i].writeback || thumb))
+ inst.error = BAD_PC;
+ break;
+
case OP_CPSF:
case OP_ENDI:
case OP_oROR:
@@ -17426,22 +17436,22 @@ static const struct asm_opcode insns[] =
/* Memory operations. */
cCE("flds", d100a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
cCE("fsts", d000a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
- cCE("fldmias", c900a00, 2, (RRw, VRSLST), vfp_sp_ldstmia),
- cCE("fldmfds", c900a00, 2, (RRw, VRSLST), vfp_sp_ldstmia),
- cCE("fldmdbs", d300a00, 2, (RRw, VRSLST), vfp_sp_ldstmdb),
- cCE("fldmeas", d300a00, 2, (RRw, VRSLST), vfp_sp_ldstmdb),
- cCE("fldmiax", c900b00, 2, (RRw, VRDLST), vfp_xp_ldstmia),
- cCE("fldmfdx", c900b00, 2, (RRw, VRDLST), vfp_xp_ldstmia),
- cCE("fldmdbx", d300b00, 2, (RRw, VRDLST), vfp_xp_ldstmdb),
- cCE("fldmeax", d300b00, 2, (RRw, VRDLST), vfp_xp_ldstmdb),
- cCE("fstmias", c800a00, 2, (RRw, VRSLST), vfp_sp_ldstmia),
- cCE("fstmeas", c800a00, 2, (RRw, VRSLST), vfp_sp_ldstmia),
- cCE("fstmdbs", d200a00, 2, (RRw, VRSLST), vfp_sp_ldstmdb),
- cCE("fstmfds", d200a00, 2, (RRw, VRSLST), vfp_sp_ldstmdb),
- cCE("fstmiax", c800b00, 2, (RRw, VRDLST), vfp_xp_ldstmia),
- cCE("fstmeax", c800b00, 2, (RRw, VRDLST), vfp_xp_ldstmia),
- cCE("fstmdbx", d200b00, 2, (RRw, VRDLST), vfp_xp_ldstmdb),
- cCE("fstmfdx", d200b00, 2, (RRw, VRDLST), vfp_xp_ldstmdb),
+ cCE("fldmias", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
+ cCE("fldmfds", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
+ cCE("fldmdbs", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
+ cCE("fldmeas", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
+ cCE("fldmiax", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
+ cCE("fldmfdx", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
+ cCE("fldmdbx", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
+ cCE("fldmeax", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
+ cCE("fstmias", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
+ cCE("fstmeas", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
+ cCE("fstmdbs", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
+ cCE("fstmfds", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
+ cCE("fstmiax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
+ cCE("fstmeax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
+ cCE("fstmdbx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
+ cCE("fstmfdx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
/* Monadic operations. */
cCE("fabss", eb00ac0, 2, (RVS, RVS), vfp_sp_monadic),
@@ -17469,14 +17479,14 @@ static const struct asm_opcode insns[] =
implementations. */
cCE("fldd", d100b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
cCE("fstd", d000b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
- cCE("fldmiad", c900b00, 2, (RRw, VRDLST), vfp_dp_ldstmia),
- cCE("fldmfdd", c900b00, 2, (RRw, VRDLST), vfp_dp_ldstmia),
- cCE("fldmdbd", d300b00, 2, (RRw, VRDLST), vfp_dp_ldstmdb),
- cCE("fldmead", d300b00, 2, (RRw, VRDLST), vfp_dp_ldstmdb),
- cCE("fstmiad", c800b00, 2, (RRw, VRDLST), vfp_dp_ldstmia),
- cCE("fstmead", c800b00, 2, (RRw, VRDLST), vfp_dp_ldstmia),
- cCE("fstmdbd", d200b00, 2, (RRw, VRDLST), vfp_dp_ldstmdb),
- cCE("fstmfdd", d200b00, 2, (RRw, VRDLST), vfp_dp_ldstmdb),
+ cCE("fldmiad", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
+ cCE("fldmfdd", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
+ cCE("fldmdbd", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
+ cCE("fldmead", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
+ cCE("fstmiad", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
+ cCE("fstmead", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
+ cCE("fstmdbd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
+ cCE("fstmfdd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
#undef ARM_VARIANT
#define ARM_VARIANT & fpu_vfp_ext_v1 /* VFP V1 (Double precision). */
@@ -17556,12 +17566,12 @@ static const struct asm_opcode insns[] =
NCEF(vabs, 1b10300, 2, (RNSDQ, RNSDQ), neon_abs_neg),
NCEF(vneg, 1b10380, 2, (RNSDQ, RNSDQ), neon_abs_neg),
- NCE(vldm, c900b00, 2, (RRw, VRSDLST), neon_ldm_stm),
- NCE(vldmia, c900b00, 2, (RRw, VRSDLST), neon_ldm_stm),
- NCE(vldmdb, d100b00, 2, (RRw, VRSDLST), neon_ldm_stm),
- NCE(vstm, c800b00, 2, (RRw, VRSDLST), neon_ldm_stm),
- NCE(vstmia, c800b00, 2, (RRw, VRSDLST), neon_ldm_stm),
- NCE(vstmdb, d000b00, 2, (RRw, VRSDLST), neon_ldm_stm),
+ NCE(vldm, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
+ NCE(vldmia, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
+ NCE(vldmdb, d100b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
+ NCE(vstm, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
+ NCE(vstmia, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
+ NCE(vstmdb, d000b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
NCE(vldr, d100b00, 2, (RVSD, ADDRGLDC), neon_ldr_str),
NCE(vstr, d000b00, 2, (RVSD, ADDRGLDC), neon_ldr_str),
diff --git a/gas/testsuite/gas/arm/vldm-arm.d b/gas/testsuite/gas/arm/vldm-arm.d
new file mode 100644
index 0000000..1e65e5e
--- /dev/null
+++ b/gas/testsuite/gas/arm/vldm-arm.d
@@ -0,0 +1,22 @@
+# name: VFP VLDM and VSTM, ARM mode
+# as: -mfpu=vfp3
+# source: vldm.s
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> ec9f0b04 vldmia pc, {d0-d1}
+0[0-9a-f]+ <[^>]+> ea000003 b 00000018 <bar>
+0[0-9a-f]+ <[^>]+> 00000000 .word 0x00000000
+0[0-9a-f]+ <[^>]+> 3ff00000 .word 0x3ff00000
+0[0-9a-f]+ <[^>]+> 9999999a .word 0x9999999a
+0[0-9a-f]+ <[^>]+> 3ff19999 .word 0x3ff19999
+0[0-9a-f]+ <[^>]+> ec8f0b04 vstmia pc, {d0-d1}
+0[0-9a-f]+ <[^>]+> ea000003 b 00000030 <foo2>
+0[0-9a-f]+ <[^>]+> 9999999a .word 0x9999999a
+0[0-9a-f]+ <[^>]+> 40019999 .word 0x40019999
+0[0-9a-f]+ <[^>]+> 66666666 .word 0x66666666
+0[0-9a-f]+ <[^>]+> 400a6666 .word 0x400a6666
+0[0-9a-f]+ <[^>]+> e1a00000 nop.*
+0[0-9a-f]+ <[^>]+> e1a00000 nop.*
diff --git a/gas/testsuite/gas/arm/vldm-thumb-bad.d b/gas/testsuite/gas/arm/vldm-thumb-bad.d
new file mode 100644
index 0000000..2e2b8c3
--- /dev/null
+++ b/gas/testsuite/gas/arm/vldm-thumb-bad.d
@@ -0,0 +1,4 @@
+# name: VFP VLDM and VSTM, Thumb mode
+# as: -mfpu=vfp3 -mthumb
+# source: vldm.s
+# error-output: vldm-thumb-bad.l
diff --git a/gas/testsuite/gas/arm/vldm-thumb-bad.l b/gas/testsuite/gas/arm/vldm-thumb-bad.l
new file mode 100644
index 0000000..9ef9c84
--- /dev/null
+++ b/gas/testsuite/gas/arm/vldm-thumb-bad.l
@@ -0,0 +1,3 @@
+[^:]*: Assembler messages:
+[^:]*:4: Error: r15 not allowed here -- `vldmia pc,{d0-d1}'
+[^:]*:9: Error: r15 not allowed here -- `vstmia pc,{d0-d1}'
diff --git a/gas/testsuite/gas/arm/vldm.s b/gas/testsuite/gas/arm/vldm.s
new file mode 100644
index 0000000..4592096
--- /dev/null
+++ b/gas/testsuite/gas/arm/vldm.s
@@ -0,0 +1,16 @@
+ .syntax unified
+
+foo:
+ vldmia pc, {d0-d1}
+ b bar
+baz:
+ .double 1.0, 1.1
+bar:
+ vstmia pc, {d0-d1}
+ b foo2
+baz2:
+ .double 2.2, 3.3
+foo2:
+ nop
+ nop
+
diff --git a/gas/testsuite/gas/arm/vldmw-arm-bad.d b/gas/testsuite/gas/arm/vldmw-arm-bad.d
new file mode 100644
index 0000000..1cbcf45
--- /dev/null
+++ b/gas/testsuite/gas/arm/vldmw-arm-bad.d
@@ -0,0 +1,4 @@
+# name: VFP VLDM and VSTM with writeback, ARM mode
+# as: -mfpu=vfp3
+# source: vldmw-bad.s
+# error-output: vldmw-bad.l
diff --git a/gas/testsuite/gas/arm/vldmw-bad.l b/gas/testsuite/gas/arm/vldmw-bad.l
new file mode 100644
index 0000000..ba0f66f
--- /dev/null
+++ b/gas/testsuite/gas/arm/vldmw-bad.l
@@ -0,0 +1,3 @@
+[^:]*: Assembler messages:
+[^:]*:4: Error: r15 not allowed here -- `vldmia pc!,{d0-d1}'
+[^:]*:9: Error: r15 not allowed here -- `vstmia pc!,{d0-d1}'
diff --git a/gas/testsuite/gas/arm/vldmw-bad.s b/gas/testsuite/gas/arm/vldmw-bad.s
new file mode 100644
index 0000000..4527a20
--- /dev/null
+++ b/gas/testsuite/gas/arm/vldmw-bad.s
@@ -0,0 +1,16 @@
+ .syntax unified
+
+foo:
+ vldmia pc!, {d0-d1}
+ b bar
+baz:
+ .double 1.0, 1.1
+bar:
+ vstmia pc!, {d0-d1}
+ b foo2
+baz2:
+ .double 2.2, 3.3
+foo2:
+ nop
+ nop
+
diff --git a/gas/testsuite/gas/arm/vldmw-thumb-bad.d b/gas/testsuite/gas/arm/vldmw-thumb-bad.d
new file mode 100644
index 0000000..aca1209
--- /dev/null
+++ b/gas/testsuite/gas/arm/vldmw-thumb-bad.d
@@ -0,0 +1,4 @@
+# name: VFP VLDM and VSTM with writeback, Thumb mode
+# as: -mfpu=vfp3 -mthumb
+# source: vldmw-bad.s
+# error-output: vldmw-bad.l