diff options
author | Andre Vieira <andre.simoesdiasvieira@arm.com> | 2019-05-16 13:44:14 +0100 |
---|---|---|
committer | Andre Vieira <andre.simoesdiasvieira@arm.com> | 2019-05-16 16:36:50 +0100 |
commit | acca5630749e83ce4ec893e650afa015a086cc0f (patch) | |
tree | 6f8328feef0c4abe0c8285fd89a556e1e2d2435c /gas/config/tc-arm.c | |
parent | 5150f0d83e7525e75d900c6859163db8797507c3 (diff) | |
download | gdb-acca5630749e83ce4ec893e650afa015a086cc0f.zip gdb-acca5630749e83ce4ec893e650afa015a086cc0f.tar.gz gdb-acca5630749e83ce4ec893e650afa015a086cc0f.tar.bz2 |
[PATCH 35/57][Arm][GAS] Add support for MVE instructions: vshlc and vshll
gas/ChangeLog:
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.
* testsuite/gas/arm/mve-vshlc-bad.d: New test.
* testsuite/gas/arm/mve-vshlc-bad.l: New test.
* testsuite/gas/arm/mve-vshlc-bad.s: New test.
* testsuite/gas/arm/mve-vshll-bad.d: New test.
* testsuite/gas/arm/mve-vshll-bad.l: New test.
* testsuite/gas/arm/mve-vshll-bad.s: New test.
Diffstat (limited to 'gas/config/tc-arm.c')
-rw-r--r-- | gas/config/tc-arm.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index e2786f5..ab672c1 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -15772,6 +15772,63 @@ do_mve_vmlas (void) } static void +do_mve_vshll (void) +{ + struct neon_type_el et + = neon_check_type (2, NS_QQI, N_EQK, N_S8 | N_U8 | N_S16 | N_U16 | N_KEY); + + if (inst.cond > COND_ALWAYS) + inst.pred_insn_type = INSIDE_VPT_INSN; + else + inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN; + + int imm = inst.operands[2].imm; + constraint (imm < 1 || (unsigned)imm > et.size, + _("immediate value out of range")); + + if ((unsigned)imm == et.size) + { + inst.instruction |= neon_logbits (et.size) << 18; + inst.instruction |= 0x110001; + } + else + { + inst.instruction |= (et.size + imm) << 16; + inst.instruction |= 0x800140; + } + + inst.instruction |= (et.type == NT_unsigned) << 28; + inst.instruction |= HI1 (inst.operands[0].reg) << 22; + inst.instruction |= LOW4 (inst.operands[0].reg) << 12; + inst.instruction |= HI1 (inst.operands[1].reg) << 5; + inst.instruction |= LOW4 (inst.operands[1].reg); + inst.is_neon = 1; +} + +static void +do_mve_vshlc (void) +{ + if (inst.cond > COND_ALWAYS) + inst.pred_insn_type = INSIDE_VPT_INSN; + else + inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN; + + if (inst.operands[1].reg == REG_PC) + as_tsktsk (MVE_BAD_PC); + else if (inst.operands[1].reg == REG_SP) + as_tsktsk (MVE_BAD_SP); + + int imm = inst.operands[2].imm; + constraint (imm < 1 || imm > 32, _("immediate value out of range")); + + inst.instruction |= HI1 (inst.operands[0].reg) << 22; + inst.instruction |= (imm & 0x1f) << 16; + inst.instruction |= LOW4 (inst.operands[0].reg) << 12; + inst.instruction |= inst.operands[1].reg; + inst.is_neon = 1; +} + +static void do_mve_vshrn (void) { unsigned types; @@ -25179,6 +25236,10 @@ static const struct asm_opcode insns[] = mCEF(vqrshrunt, _vqrshrunt, 3, (RMQ, RMQ, I32z), mve_vshrn), mCEF(vqrshrunb, _vqrshrunb, 3, (RMQ, RMQ, I32z), mve_vshrn), + mToC("vshlc", eea00fc0, 3, (RMQ, RR, I32z), mve_vshlc), + mToC("vshllt", ee201e00, 3, (RMQ, RMQ, I32), mve_vshll), + mToC("vshllb", ee200e00, 3, (RMQ, RMQ, I32), mve_vshll), + #undef THUMB_VARIANT #define THUMB_VARIANT & mve_fp_ext mToC("vcmul", ee300e00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vcmul), |