diff options
author | Andre Vieira <andre.simoesdiasvieira@arm.com> | 2019-05-16 13:52:51 +0100 |
---|---|---|
committer | Andre Vieira <andre.simoesdiasvieira@arm.com> | 2019-05-16 16:36:53 +0100 |
commit | 1f6234a335eab15c3ad878338b5256b5bdc190ab (patch) | |
tree | 10bdc36cff6d05a4ba667b227089cb58f8232a6f /gas | |
parent | acca5630749e83ce4ec893e650afa015a086cc0f (diff) | |
download | gdb-1f6234a335eab15c3ad878338b5256b5bdc190ab.zip gdb-1f6234a335eab15c3ad878338b5256b5bdc190ab.tar.gz gdb-1f6234a335eab15c3ad878338b5256b5bdc190ab.tar.bz2 |
[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.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 11 | ||||
-rw-r--r-- | gas/config/tc-arm.c | 108 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/mve-tailpredloop-bad.d | 5 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/mve-tailpredloop-bad.l | 26 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/mve-tailpredloop-bad.s | 36 |
5 files changed, 152 insertions, 34 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index f7883ed..e2cab99 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,16 @@ 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. (do_mve_vshlc): Likewise. (insns): Add entries for MVE mnemonics. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index ab672c1..1bc15df 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -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) 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 0000000..53c0abc --- /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 0000000..5e9209f --- /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 0000000..929722a --- /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: |