aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-arm.c
diff options
context:
space:
mode:
authorAndre Vieira <andre.simoesdiasvieira@arm.com>2019-05-16 13:44:14 +0100
committerAndre Vieira <andre.simoesdiasvieira@arm.com>2019-05-16 16:36:50 +0100
commitacca5630749e83ce4ec893e650afa015a086cc0f (patch)
tree6f8328feef0c4abe0c8285fd89a556e1e2d2435c /gas/config/tc-arm.c
parent5150f0d83e7525e75d900c6859163db8797507c3 (diff)
downloadgdb-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.c61
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),