[PATCH 36/57][Arm][GAS] Add support for MVE instructions: wlstp, dlstp, letp and lctp

gas/ChangeLog:
2019-05-16  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.
This commit is contained in:
Andre Vieira 2019-05-16 13:52:51 +01:00
parent acca563074
commit 1f6234a335
5 changed files with 152 additions and 34 deletions

View File

@ -1,3 +1,14 @@
2019-05-16 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.
2019-05-16 Andre Vieira <andre.simoesdiasvieira@arm.com>
* config/tc-arm.c (do_mve_vshll): New encoding function.

View File

@ -11134,9 +11134,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), \
@ -11147,6 +11149,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), \
@ -11189,6 +11192,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)
@ -14114,38 +14118,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
@ -14444,6 +14416,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), \
@ -15985,6 +15959,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)
{
@ -25240,6 +25274,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),
@ -28641,9 +28680,10 @@ md_apply_fix (fixS * fixP,
}
bfd_vma insn = get_thumb32_insn (buf);
/* le lr, <label> or le <label> */
/* le lr, <label>, le <label> or letp lr, <label> */
if (((insn & 0xffffffff) == 0xf00fc001)
|| ((insn & 0xffffffff) == 0xf02fc001))
|| ((insn & 0xffffffff) == 0xf02fc001)
|| ((insn & 0xffffffff) == 0xf01fc001))
value = -value;
if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)

View File

@ -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.*

View File

@ -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

View File

@ -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: