aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/bfd-in2.h1
-rw-r--r--bfd/libbfd.h1
-rw-r--r--bfd/reloc.c2
-rw-r--r--gas/ChangeLog19
-rw-r--r--gas/config/tc-arm.c124
-rw-r--r--gas/testsuite/gas/arm/archv8m_1m-cmse-main-bad.l8
-rw-r--r--gas/testsuite/gas/arm/archv8m_1m-cmse-main-bad.s10
-rw-r--r--gas/testsuite/gas/arm/archv8m_1m-cmse-main.d34
-rw-r--r--gas/testsuite/gas/arm/archv8m_1m-cmse-main.s34
-rw-r--r--opcodes/ChangeLog8
-rw-r--r--opcodes/arm-dis.c52
12 files changed, 295 insertions, 5 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 7876f51..834b84f 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2019-04-15 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
+ * reloc.c (BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM): New internal
+ relocation.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Likewise.
+
2019-04-15 Sudakshina Das <sudi.das@arm.com>
* reloc.c (BFD_RELOC_ARM_THUMB_LOOP12): New.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 540b9f7..13af0bea 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -3722,6 +3722,7 @@ pc-relative or some form of GOT-indirect relocation. */
BFD_RELOC_ARM_CP_OFF_IMM_S2,
BFD_RELOC_ARM_T32_CP_OFF_IMM,
BFD_RELOC_ARM_T32_CP_OFF_IMM_S2,
+ BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM,
BFD_RELOC_ARM_ADR_IMM,
BFD_RELOC_ARM_LDR_IMM,
BFD_RELOC_ARM_LITERAL,
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index f64a8f3..b51df73 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1634,6 +1634,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_ARM_CP_OFF_IMM_S2",
"BFD_RELOC_ARM_T32_CP_OFF_IMM",
"BFD_RELOC_ARM_T32_CP_OFF_IMM_S2",
+ "BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM",
"BFD_RELOC_ARM_ADR_IMM",
"BFD_RELOC_ARM_LDR_IMM",
"BFD_RELOC_ARM_LITERAL",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index e6ba9e2..9615279 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -3293,6 +3293,8 @@ ENUMX
ENUMX
BFD_RELOC_ARM_T32_CP_OFF_IMM_S2
ENUMX
+ BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM
+ENUMX
BFD_RELOC_ARM_ADR_IMM
ENUMX
BFD_RELOC_ARM_LDR_IMM
diff --git a/gas/ChangeLog b/gas/ChangeLog
index d669d00..7eb172c 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,24 @@
2019-04-15 Thomas Preud'homme <thomas.preudhomme@arm.com>
+ * config/tc-arm.c (parse_sys_vldr_vstr): New function.
+ (OP_VLDR): New enum operand_parse_code enumerator.
+ (parse_operands): Add logic for OP_VLDR.
+ (do_t_vldr_vstr_sysreg): New function.
+ (do_vldr_vstr): Likewise.
+ (insns): Guard VLDR and VSTR by arm_ext_v4t for Thumb mode.
+ (md_apply_fix): Add bound check for VLDR and VSTR co-processor offset.
+ Add masking logic for BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM relocation.
+ * testsuite/gas/arm/archv8m_1m-cmse-main-bad.s: Add examples of bad
+ uses of VLDR and VSTR.
+ * testsuite/gas/arm/archv8m_1m-cmse-main-bad.l: Add error messages for
+ above bad uses.
+ * testsuite/gas/arm/archv8m_1m-cmse-main.s: Add examples of VLDR and
+ VSTR valid uses.
+ * testsuite/gas/arm/archv8m_1m-cmse-main.d: Add disassembly for the
+ above examples.
+
+2019-04-15 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
* config/tc-arm.c (arm_typed_reg_parse): Fix typo in comment.
(enum reg_list_els): New REGLIST_VFP_S_VPR and REGLIST_VFP_D_VPR
enumerators.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index b5dc3eb..20a2dee 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -6128,6 +6128,39 @@ check_suffix:
return FAIL;
}
+static int
+parse_sys_vldr_vstr (char **str)
+{
+ unsigned i;
+ int val = FAIL;
+ struct {
+ const char *name;
+ int regl;
+ int regh;
+ } sysregs[] = {
+ {"FPSCR", 0x1, 0x0},
+ {"FPSCR_nzcvqc", 0x2, 0x0},
+ {"VPR", 0x4, 0x1},
+ {"P0", 0x5, 0x1},
+ {"FPCXTNS", 0x6, 0x1},
+ {"FPCXTS", 0x7, 0x1}
+ };
+ char *op_end = strchr (*str, ',');
+ size_t op_strlen = op_end - *str;
+
+ for (i = 0; i < sizeof (sysregs) / sizeof (sysregs[0]); i++)
+ {
+ if (!strncmp (*str, sysregs[i].name, op_strlen))
+ {
+ val = sysregs[i].regl | (sysregs[i].regh << 3);
+ *str = op_end;
+ break;
+ }
+ }
+
+ return val;
+}
+
/* Parse the flags argument to CPSI[ED]. Returns FAIL on error, or a
value suitable for splatting into the AIF field of the instruction. */
@@ -6652,6 +6685,7 @@ enum operand_parse_code
OP_RNDQ_Ibig, /* Neon D or Q reg, or big immediate for logic and VMVN. */
OP_RNDQ_I63b, /* Neon D or Q reg, or immediate for shift. */
OP_RIWR_I32z, /* iWMMXt wR register, or immediate 0 .. 32 for iWMMXt2. */
+ OP_VLDR, /* VLDR operand. */
OP_I0, /* immediate zero */
OP_I7, /* immediate value 0 .. 7 */
@@ -7225,6 +7259,13 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
val = parse_psr (&str, op_parse_code == OP_wPSR);
break;
+ case OP_VLDR:
+ po_reg_or_goto (REG_TYPE_VFSD, try_sysreg);
+ break;
+ try_sysreg:
+ val = parse_sys_vldr_vstr (&str);
+ break;
+
case OP_APSR_RR:
po_reg_or_goto (REG_TYPE_RN, try_apsr);
break;
@@ -7401,6 +7442,10 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
inst.error = BAD_PC;
break;
+ case OP_VLDR:
+ if (inst.operands[i].isreg)
+ break;
+ /* fall through. */
case OP_CPSF:
case OP_ENDI:
case OP_oROR:
@@ -17397,6 +17442,55 @@ do_neon_ldr_str (void)
}
}
+static void
+do_t_vldr_vstr_sysreg (void)
+{
+ int fp_vldr_bitno = 20, sysreg_vldr_bitno = 20;
+ bfd_boolean is_vldr = ((inst.instruction & (1 << fp_vldr_bitno)) != 0);
+
+ /* Use of PC is UNPREDICTABLE. */
+ if (inst.operands[1].reg == REG_PC)
+ inst.error = _("Use of PC here is UNPREDICTABLE");
+
+ if (inst.operands[1].immisreg)
+ inst.error = _("instruction does not accept register index");
+
+ if (!inst.operands[1].isreg)
+ inst.error = _("instruction does not accept PC-relative addressing");
+
+ if (abs (inst.operands[1].imm) >= (1 << 7))
+ inst.error = _("immediate value out of range");
+
+ inst.instruction = 0xec000f80;
+ if (is_vldr)
+ inst.instruction |= 1 << sysreg_vldr_bitno;
+ encode_arm_cp_address (1, TRUE, FALSE, BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM);
+ inst.instruction |= (inst.operands[0].imm & 0x7) << 13;
+ inst.instruction |= (inst.operands[0].imm & 0x8) << 19;
+}
+
+static void
+do_vldr_vstr (void)
+{
+ bfd_boolean sysreg_op = !inst.operands[0].isreg;
+
+ /* VLDR/VSTR (System Register). */
+ if (sysreg_op)
+ {
+ if (!mark_feature_used (&arm_ext_v8_1m_main))
+ as_bad (_("Instruction not permitted on this architecture"));
+
+ do_t_vldr_vstr_sysreg ();
+ }
+ /* VLDR/VSTR. */
+ else
+ {
+ if (!mark_feature_used (&fpu_vfp_ext_v1xd))
+ as_bad (_("Instruction not permitted on this architecture"));
+ do_neon_ldr_str ();
+ }
+}
+
/* "interleave" version also handles non-interleaving register VLD1/VST1
instructions. */
@@ -21284,8 +21378,6 @@ static const struct asm_opcode insns[] =
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),
nCEF(vcvt, _vcvt, 3, (RNSDQ, RNSDQ, oI32z), neon_cvt),
nCEF(vcvtr, _vcvt, 2, (RNSDQ, RNSDQ), neon_cvtr),
@@ -21297,6 +21389,15 @@ static const struct asm_opcode insns[] =
NCE(vmov, 0, 1, (VMOV), neon_mov),
NCE(vmovq, 0, 1, (VMOV), neon_mov),
+#undef THUMB_VARIANT
+/* Could be either VLDR/VSTR or VLDR/VSTR (system register) which are guarded
+ by different feature bits. Since we are setting the Thumb guard, we can
+ require Thumb-1 which makes it a nop guard and set the right feature bit in
+ do_vldr_vstr (). */
+#define THUMB_VARIANT & arm_ext_v4t
+ NCE(vldr, d100b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
+ NCE(vstr, d000b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
+
#undef ARM_VARIANT
#define ARM_VARIANT & arm_ext_fp16
#undef THUMB_VARIANT
@@ -24548,6 +24649,7 @@ md_apply_fix (fixS * fixP,
case BFD_RELOC_ARM_CP_OFF_IMM:
case BFD_RELOC_ARM_T32_CP_OFF_IMM:
+ case BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM:
if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM)
newval = md_chars_to_number (buf, INSN_SIZE);
else
@@ -24561,6 +24663,12 @@ md_apply_fix (fixS * fixP,
as_bad_where (fixP->fx_file, fixP->fx_line,
_("co-processor offset out of range"));
}
+ else if ((newval & 0xfe001f80) == 0xec000f80)
+ {
+ if (value < -511 || value > 512 || (value & 3))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("co-processor offset out of range"));
+ }
else if (value < -1023 || value > 1023 || (value & 3))
as_bad_where (fixP->fx_file, fixP->fx_line,
_("co-processor offset out of range"));
@@ -24574,10 +24682,18 @@ md_apply_fix (fixS * fixP,
else
newval = get_thumb32_insn (buf);
if (value == 0)
- newval &= 0xffffff00;
+ {
+ if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
+ newval &= 0xffffff80;
+ else
+ newval &= 0xffffff00;
+ }
else
{
- newval &= 0xff7fff00;
+ if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
+ newval &= 0xff7fff80;
+ else
+ newval &= 0xff7fff00;
if ((newval & 0x0f200f00) == 0x0d000900)
{
/* This is a fp16 vstr/vldr.
diff --git a/gas/testsuite/gas/arm/archv8m_1m-cmse-main-bad.l b/gas/testsuite/gas/arm/archv8m_1m-cmse-main-bad.l
index b64937d..979982d 100644
--- a/gas/testsuite/gas/arm/archv8m_1m-cmse-main-bad.l
+++ b/gas/testsuite/gas/arm/archv8m_1m-cmse-main-bad.l
@@ -6,3 +6,11 @@
[^:]*:11: Error: VPR expected last -- `vscclrm {s0}'
[^:]*:12: Error: VFP single precision register or VPR expected -- `vscclrm {s1,d1,VPR}'
[^:]*:13: Error: VFP single precision register expected -- `vscclrm {s1-d1,VPR}'
+[^:]*:15: Error: syntax error -- `vldr APSR,\[r2\]'
+[^:]*:20: Error: syntax error -- `vstr APSR,\[r2\]'
+[^:]*:16: Error: co-processor offset out of range
+[^:]*:17: Error: co-processor offset out of range
+[^:]*:18: Error: co-processor offset out of range
+[^:]*:21: Error: co-processor offset out of range
+[^:]*:22: Error: co-processor offset out of range
+[^:]*:23: Error: co-processor offset out of range
diff --git a/gas/testsuite/gas/arm/archv8m_1m-cmse-main-bad.s b/gas/testsuite/gas/arm/archv8m_1m-cmse-main-bad.s
index f4baefe..894e8b2 100644
--- a/gas/testsuite/gas/arm/archv8m_1m-cmse-main-bad.s
+++ b/gas/testsuite/gas/arm/archv8m_1m-cmse-main-bad.s
@@ -11,3 +11,13 @@ vscclrm {} @ Rejects empty list
vscclrm {s0} @ Rejects list without VPR
vscclrm {s1, d1, VPR} @ Reject mix of single and double-precision VFP registers
vscclrm {s1-d1, VPR} @ Likewise when using a range
+
+vldr APSR, [r2] @ Rejects incorrect system register
+vldr FPSCR, [r2, #2] @ Rejects invalid immediate for offset variant
+vldr FPSCR, [r2, #2]! @ Likewise for pre-index variant
+vldr FPSCR, [r2], #2 @ Likewise for post-index variant
+
+vstr APSR, [r2] @ Rejects incorrect system register
+vstr FPSCR, [r2, #2] @ Rejects invalid immediate for offset variant
+vstr FPSCR, [r2, #2]! @ Likewise for pre-index variant
+vstr FPSCR, [r2], #2 @ Likewise for post-index variant
diff --git a/gas/testsuite/gas/arm/archv8m_1m-cmse-main.d b/gas/testsuite/gas/arm/archv8m_1m-cmse-main.d
index 866adc9..1ed543a 100644
--- a/gas/testsuite/gas/arm/archv8m_1m-cmse-main.d
+++ b/gas/testsuite/gas/arm/archv8m_1m-cmse-main.d
@@ -20,4 +20,38 @@ Disassembly of section .text:
0+.* <[^>]*> ec9f 0b20 vscclrm {d0-d15, VPR}
0+.* <[^>]*> bf18 it ne
0+.* <[^>]*> ecdf 1a01 vscclrmne {s3, VPR}
+0+.* <[^>]*> ed92 2f80 vldr FPSCR, \[r2\]
+0+.* <[^>]*> ed92 2f82 vldr FPSCR, \[r2, #8\]
+0+.* <[^>]*> ed92 2f82 vldr FPSCR, \[r2, #8\]
+0+.* <[^>]*> ed12 2f82 vldr FPSCR, \[r2, #-8\]
+0+.* <[^>]*> edb2 2f82 vldr FPSCR, \[r2, #8\]!
+0+.* <[^>]*> edb2 2f82 vldr FPSCR, \[r2, #8\]!
+0+.* <[^>]*> ed32 2f82 vldr FPSCR, \[r2, #-8\]!
+0+.* <[^>]*> ecb2 2f82 vldr FPSCR, \[r2\], #8
+0+.* <[^>]*> ecb2 2f82 vldr FPSCR, \[r2\], #8
+0+.* <[^>]*> ec32 2f82 vldr FPSCR, \[r2\], #-8
+0+.* <[^>]*> ed93 4f80 vldr FPSCR_nzcvqc, \[r3\]
+0+.* <[^>]*> edd3 8f80 vldr VPR, \[r3\]
+0+.* <[^>]*> edd3 af80 vldr P0, \[r3\]
+0+.* <[^>]*> edd3 cf80 vldr FPCXTNS, \[r3\]
+0+.* <[^>]*> edd3 ef80 vldr FPCXTS, \[r3\]
+0+.* <[^>]*> bfa8 it ge
+0+.* <[^>]*> edd3 ef80 vldrge FPCXTS, \[r3\]
+0+.* <[^>]*> ed82 2f80 vstr FPSCR, \[r2\]
+0+.* <[^>]*> ed82 2f82 vstr FPSCR, \[r2, #8\]
+0+.* <[^>]*> ed82 2f82 vstr FPSCR, \[r2, #8\]
+0+.* <[^>]*> ed02 2f82 vstr FPSCR, \[r2, #-8\]
+0+.* <[^>]*> eda2 2f82 vstr FPSCR, \[r2, #8\]!
+0+.* <[^>]*> eda2 2f82 vstr FPSCR, \[r2, #8\]!
+0+.* <[^>]*> ed22 2f82 vstr FPSCR, \[r2, #-8\]!
+0+.* <[^>]*> eca2 2f82 vstr FPSCR, \[r2\], #8
+0+.* <[^>]*> eca2 2f82 vstr FPSCR, \[r2\], #8
+0+.* <[^>]*> ec22 2f82 vstr FPSCR, \[r2\], #-8
+0+.* <[^>]*> ed83 4f80 vstr FPSCR_nzcvqc, \[r3\]
+0+.* <[^>]*> edc3 8f80 vstr VPR, \[r3\]
+0+.* <[^>]*> edc3 af80 vstr P0, \[r3\]
+0+.* <[^>]*> edc3 cf80 vstr FPCXTNS, \[r3\]
+0+.* <[^>]*> edc3 ef80 vstr FPCXTS, \[r3\]
+0+.* <[^>]*> bfa8 it ge
+0+.* <[^>]*> edc3 ef80 vstrge FPCXTS, \[r3\]
#...
diff --git a/gas/testsuite/gas/arm/archv8m_1m-cmse-main.s b/gas/testsuite/gas/arm/archv8m_1m-cmse-main.s
index f4df2db..9a20e1e 100644
--- a/gas/testsuite/gas/arm/archv8m_1m-cmse-main.s
+++ b/gas/testsuite/gas/arm/archv8m_1m-cmse-main.s
@@ -18,3 +18,37 @@ vscclrm {s0-s31, VPR} @ Accept all single-precision VFP registers and VPR
@ together
vscclrm {d0-d15, VPR} @ Likewise for double-precision VFP registers
vscclrmne {s3, VPR} @ Accepts conditional execution
+
+vldr FPSCR, [r2] @ Accepts offset variant without immediate
+vldr FPSCR, [r2, #8] @ Likewise but with immediate without sign
+vldr FPSCR, [r2, #+8] @ Likewise but with positive sign
+vldr FPSCR, [r2, #-8] @ Likewise but with negative sign
+vldr FPSCR, [r2, #8]! @ Accepts pre-index variant with immediate without sign
+vldr FPSCR, [r2, #+8]! @ Likewise but with positive sign
+vldr FPSCR, [r2, #-8]! @ Likewise but with negative sign
+vldr FPSCR, [r2], #8 @ Accepts post-index variant with immediate without sign
+vldr FPSCR, [r2], #+8 @ Likewise but with positive sign
+vldr FPSCR, [r2], #-8 @ Likewise but with negative sign
+vldr FPSCR_nzcvqc, [r3] @ Accepts FPSCR_nzcvqc system register
+vldr VPR, [r3] @ Accepts VPR system register
+vldr P0, [r3] @ Accepts P0 system register
+vldr FPCXTNS, [r3] @ Accepts FPCXTNS system register
+vldr FPCXTS, [r3] @ Accepts FPCXTS system register
+vldrge FPCXTS, [r3] @ Accepts conditional execution
+
+vstr FPSCR, [r2] @ Accepts offset variant without immediate
+vstr FPSCR, [r2, #8] @ Likewise but with immediate without sign
+vstr FPSCR, [r2, #+8] @ Likewise but with positive sign
+vstr FPSCR, [r2, #-8] @ Likewise but with negative sign
+vstr FPSCR, [r2, #8]! @ Accepts pre-index variant with immediate without sign
+vstr FPSCR, [r2, #+8]! @ Likewise but with positive sign
+vstr FPSCR, [r2, #-8]! @ Likewise but with negative sign
+vstr FPSCR, [r2], #8 @ Accepts post-index variant with immediate without sign
+vstr FPSCR, [r2], #+8 @ Likewise but with positive sign
+vstr FPSCR, [r2], #-8 @ Likewise but with negative sign
+vstr FPSCR_nzcvqc, [r3] @ Accepts FPSCR_nzcvqc system register
+vstr VPR, [r3] @ Accepts VPR system register
+vstr P0, [r3] @ Accepts P0 system register
+vstr FPCXTNS, [r3] @ Accepts FPCXTNS system register
+vstr FPCXTS, [r3] @ Accepts FPCXTS system register
+vstrge FPCXTS, [r3] @ Accepts conditional execution
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 7b330c7..05d211b 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,13 @@
2019-04-15 Thomas Preud'homme <thomas.preudhomme@arm.com>
+ * arm-dis.c (coprocessor_opcodes): Document new %J and %K format
+ specifier. Add entries for VLDR and VSTR of system registers.
+ (print_insn_coprocessor): Forbid coprocessor numbers 8, 14 and 15 in
+ coprocessor instructions on Armv8.1-M Mainline targets. Add handling
+ of %J and %K format specifier.
+
+2019-04-15 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
* arm-dis.c (coprocessor_opcodes): Document new %C format control code.
Add new entries for VSCCLRM instruction.
(print_insn_coprocessor): Handle new %C format control code.
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index ea053a3..c2a8a5f 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -111,6 +111,8 @@ struct opcode16
%B print vstm/vldm register list
%C print vscclrm register list
%I print cirrus signed shift immediate: bits 0..3|4..6
+ %J print register for VLDR instruction
+ %K print address for VLDR instruction
%F print the COUNT field of a LFM/SFM instruction.
%P print floating point precision in arithmetic insn
%Q print floating point precision in ldf/stf insn
@@ -471,6 +473,10 @@ static const struct sopcode32 coprocessor_opcodes[] =
0x0d000a00, 0x0f300f00, "vstr%c\t%y1, %A"},
{ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
0x0d100a00, 0x0f300f00, "vldr%c\t%y1, %A"},
+ {ANY, ARM_FEATURE_COPROC (ARM_EXT2_V8_1M_MAIN),
+ 0xec100f80, 0xfe101f80, "vldr%c\t%J, %K"},
+ {ANY, ARM_FEATURE_COPROC (ARM_EXT2_V8_1M_MAIN),
+ 0xec000f80, 0xfe101f80, "vstr%c\t%J, %K"},
{ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
0x0d200b01, 0x0fb00f01, "fstmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
@@ -3462,6 +3468,8 @@ print_insn_coprocessor (bfd_vma pc,
int cp_num;
struct arm_private_data *private_data = info->private_data;
arm_feature_set allowed_arches = ARM_ARCH_NONE;
+ arm_feature_set arm_ext_v8_1m_main =
+ ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN);
allowed_arches = private_data->features;
@@ -3557,23 +3565,34 @@ print_insn_coprocessor (bfd_vma pc,
/* Floating-point instructions. */
if (cp_num == 9 || cp_num == 10 || cp_num == 11)
continue;
+
+ /* Armv8.1-M Mainline FP & MVE instructions. */
+ if (ARM_CPU_HAS_FEATURE (arm_ext_v8_1m_main, allowed_arches)
+ && !ARM_CPU_IS_ANY (allowed_arches)
+ && (cp_num == 8 || cp_num == 14 || cp_num == 15))
+ continue;
}
for (c = insn->assembler; *c; c++)
{
if (*c == '%')
{
- switch (*++c)
+ const char mod = *++c;
+ switch (mod)
{
case '%':
func (stream, "%%");
break;
case 'A':
+ case 'K':
{
int rn = (given >> 16) & 0xf;
bfd_vma offset = given & 0xff;
+ if (mod == 'K')
+ offset = given & 0x7f;
+
func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
if (PRE_BIT_SET || WRITEBACK_BIT_SET)
@@ -3705,6 +3724,37 @@ print_insn_coprocessor (bfd_vma pc,
break;
+ case 'J':
+ {
+ int regno = ((given >> 19) & 0x8) | ((given >> 13) & 0x7);
+
+ switch (regno)
+ {
+ case 0x1:
+ func (stream, "FPSCR");
+ break;
+ case 0x2:
+ func (stream, "FPSCR_nzcvqc");
+ break;
+ case 0xc:
+ func (stream, "VPR");
+ break;
+ case 0xd:
+ func (stream, "P0");
+ break;
+ case 0xe:
+ func (stream, "FPCXTNS");
+ break;
+ case 0xf:
+ func (stream, "FPCXTS");
+ break;
+ default:
+ func (stream, "<invalid reg %d>", regno);
+ break;
+ }
+ }
+ break;
+
case 'F':
switch (given & 0x00408000)
{