This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 36/57][Arm][GAS] Add support for MVE instructions: wlstp, dlstp, letp and lctp
- From: "Andre Vieira (lists)" <andre dot simoesdiasvieira at arm dot com>
- To: binutils at sourceware dot org
- Date: Wed, 1 May 2019 18:36:53 +0100
- Subject: [PATCH 36/57][Arm][GAS] Add support for MVE instructions: wlstp, dlstp, letp and lctp
- References: <19569550-4d2e-0bb3-592a-d91050d490f6@arm.com>
Hi,
This patch adds support for MVE instructions WLSTP, DLSTP, LETP, and LCTP.
gas/ChangeLog:
2019-05-01 Andre Vieira <andre.simoesdiasvieira@arm.com>
* config/tc-arm.c (T16_32_TAB): Add new instructions.
(do_t_loloop): Changed to handle tail predication variants.
(md_apply_fix): Likewise.
(insns): Add entries for MVE mnemonics.
* testsuite/gas/arm/mve-tailpredloop-bad.d: New test.
* testsuite/gas/arm/mve-tailpredloop-bad.l: New test.
* testsuite/gas/arm/mve-tailpredloop-bad.s: New test.
* testsuite/gas/arm/mve-tailpredloop.d: New test.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index b3e4228d62f6dd9f3f672dad8f407ef4aed2bf1f..6ace0adc5041d5333ed57c87db7ea6b00d8319ac 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -11137,9 +11137,11 @@ encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
X(_cpy, 4600, ea4f0000), \
X(_dec_sp,80dd, f1ad0d00), \
X(_dls, 0000, f040e001), \
+ X(_dlstp, 0000, f000e001), \
X(_eor, 4040, ea800000), \
X(_eors, 4040, ea900000), \
X(_inc_sp,00dd, f10d0d00), \
+ X(_lctp, 0000, f00fe001), \
X(_ldmia, c800, e8900000), \
X(_ldr, 6800, f8500000), \
X(_ldrb, 7800, f8100000), \
@@ -11150,6 +11152,7 @@ encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
X(_ldr_pc2,4800, f85f0000), \
X(_ldr_sp,9800, f85d0000), \
X(_le, 0000, f00fc001), \
+ X(_letp, 0000, f01fc001), \
X(_lsl, 0000, fa00f000), \
X(_lsls, 0000, fa10f000), \
X(_lsr, 0800, fa20f000), \
@@ -11192,6 +11195,7 @@ encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
X(_wfe, bf20, f3af8002), \
X(_wfi, bf30, f3af8003), \
X(_wls, 0000, f040c001), \
+ X(_wlstp, 0000, f000c001), \
X(_sev, bf40, f3af8004), \
X(_sevl, bf50, f3af8005), \
X(_udf, de00, f7f0a000)
@@ -14117,38 +14121,6 @@ v8_1_loop_reloc (int is_le)
}
}
-/* To handle the Scalar Low Overhead Loop instructions
- in Armv8.1-M Mainline. */
-static void
-do_t_loloop (void)
-{
- unsigned long insn = inst.instruction;
-
- set_pred_insn_type (OUTSIDE_PRED_INSN);
- inst.instruction = THUMB_OP32 (inst.instruction);
-
- switch (insn)
- {
- case T_MNEM_le:
- /* le <label>. */
- if (!inst.operands[0].present)
- inst.instruction |= 1 << 21;
-
- v8_1_loop_reloc (TRUE);
- break;
-
- case T_MNEM_wls:
- v8_1_loop_reloc (FALSE);
- /* Fall through. */
- case T_MNEM_dls:
- constraint (inst.operands[1].isreg != 1, BAD_ARGS);
- inst.instruction |= (inst.operands[1].reg << 16);
- break;
-
- default: abort();
- }
-}
-
/* MVE instruction encoder helpers. */
#define M_MNEM_vabav 0xee800f01
#define M_MNEM_vmladav 0xeef00e00
@@ -14447,6 +14419,8 @@ NEON_ENC_TAB
X(2, (R, S), SINGLE), \
X(2, (F, R), SINGLE), \
X(2, (R, F), SINGLE), \
+/* Used for MVE tail predicated loop instructions. */\
+ X(2, (R, R), QUAD), \
/* Half float shape supported so far. */\
X (2, (H, D), MIXED), \
X (2, (D, H), MIXED), \
@@ -15988,6 +15962,66 @@ do_mve_vcmul (void)
inst.is_neon = 1;
}
+/* To handle the Low Overhead Loop instructions
+ in Armv8.1-M Mainline and MVE. */
+static void
+do_t_loloop (void)
+{
+ unsigned long insn = inst.instruction;
+
+ inst.instruction = THUMB_OP32 (inst.instruction);
+
+ if (insn == T_MNEM_lctp)
+ return;
+
+ set_pred_insn_type (MVE_OUTSIDE_PRED_INSN);
+
+ if (insn == T_MNEM_wlstp || insn == T_MNEM_dlstp)
+ {
+ struct neon_type_el et
+ = neon_check_type (2, NS_RR, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
+ inst.instruction |= neon_logbits (et.size) << 20;
+ inst.is_neon = 1;
+ }
+
+ switch (insn)
+ {
+ case T_MNEM_letp:
+ constraint (!inst.operands[0].present,
+ _("expected LR"));
+ /* fall through. */
+ case T_MNEM_le:
+ /* le <label>. */
+ if (!inst.operands[0].present)
+ inst.instruction |= 1 << 21;
+
+ v8_1_loop_reloc (TRUE);
+ break;
+
+ case T_MNEM_wls:
+ case T_MNEM_wlstp:
+ v8_1_loop_reloc (FALSE);
+ /* fall through. */
+ case T_MNEM_dlstp:
+ case T_MNEM_dls:
+ constraint (inst.operands[1].isreg != 1, BAD_ARGS);
+
+ if (insn == T_MNEM_wlstp || insn == T_MNEM_dlstp)
+ constraint (inst.operands[1].reg == REG_PC, BAD_PC);
+ else if (inst.operands[1].reg == REG_PC)
+ as_tsktsk (MVE_BAD_PC);
+ if (inst.operands[1].reg == REG_SP)
+ as_tsktsk (MVE_BAD_SP);
+
+ inst.instruction |= (inst.operands[1].reg << 16);
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+
static void
do_vfp_nsyn_cmp (void)
{
@@ -25243,6 +25277,11 @@ static const struct asm_opcode insns[] =
mToC("vshllt", ee201e00, 3, (RMQ, RMQ, I32), mve_vshll),
mToC("vshllb", ee200e00, 3, (RMQ, RMQ, I32), mve_vshll),
+ toU("dlstp", _dlstp, 2, (LR, RR), t_loloop),
+ toU("wlstp", _wlstp, 3, (LR, RR, EXP), t_loloop),
+ toU("letp", _letp, 2, (LR, EXP), t_loloop),
+ toU("lctp", _lctp, 0, (), t_loloop),
+
#undef THUMB_VARIANT
#define THUMB_VARIANT & mve_fp_ext
mToC("vcmul", ee300e00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vcmul),
@@ -28644,9 +28683,10 @@ md_apply_fix (fixS * fixP,
}
bfd_vma insn = md_chars_to_number (buf, INSN_SIZE);
- /* le lr, <label> or le <label> */
+ /* le lr, <label>, le <label> or letp lr, <label> */
if (((insn & 0xffffffff) == 0xc001f00f)
- || ((insn & 0xffffffff) == 0xc001f02f))
+ || ((insn & 0xffffffff) == 0xc001f02f)
+ || ((insn & 0xffffffff) == 0xc001f01f))
value = -value;
if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
diff --git a/gas/testsuite/gas/arm/mve-tailpredloop-bad.d b/gas/testsuite/gas/arm/mve-tailpredloop-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..53c0abcba591bcd685d36d37161d6646348f055f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-tailpredloop-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE WLSTP, DLSTP and LETP instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-tailpredloop-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-tailpredloop-bad.l b/gas/testsuite/gas/arm/mve-tailpredloop-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..5e9209ff3e3669b840dd3b7097a07d30f39206be
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-tailpredloop-bad.l
@@ -0,0 +1,26 @@
+[^:]*: Assembler messages:
+[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:28: Error: r15 not allowed here -- `wlstp.8 lr,pc,.label'
+[^:]*:29: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:30: Error: r15 not allowed here -- `dlstp.16 lr,pc'
+[^:]*:31: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:33: Error: ARM register expected -- `letp .label_back'
+[^:]*:34: Error: branch out of range or not a multiple of 2
+[^:]*:35: Error: branch out of range or not a multiple of 2
diff --git a/gas/testsuite/gas/arm/mve-tailpredloop-bad.s b/gas/testsuite/gas/arm/mve-tailpredloop-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..929722a99c2fae207344f0a5f8b0935efac8f814
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-tailpredloop-bad.s
@@ -0,0 +1,36 @@
+.macro cond1
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+wlstp.8 lr, r0, .label
+.endr
+.endm
+
+.macro cond2
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+dlstp.8 lr, r0
+.endr
+.endm
+
+.macro cond3
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+letp lr, .label_back
+.endr
+.endm
+
+.label_back:
+.syntax unified
+.thumb
+cond1
+cond2
+cond3
+wlstp.8 lr, pc, .label
+wlstp.8 lr, sp, .label
+dlstp.16 lr, pc
+dlstp.16 lr, sp
+.label:
+letp .label_back
+wlstp.8 lr, r0, .label
+letp lr, .label2
+.label2: