summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorDiogo N. Sampaio <diogo.sampaio@arm.com>2019-03-08 17:11:20 +0000
committerDiogo N. Sampaio <diogo.sampaio@arm.com>2019-03-08 17:11:20 +0000
commitc20c37ba7f546e0898e09953f03ca2c28ddc7035 (patch)
treed5a1dde3c2e00799460167457e57d5212ae8c280 /llvm/lib/Target
parent7f3c16c0f3178efd2883ceac441aa162728f1726 (diff)
downloadbcm5719-llvm-c20c37ba7f546e0898e09953f03ca2c28ddc7035.tar.gz
bcm5719-llvm-c20c37ba7f546e0898e09953f03ca2c28ddc7035.zip
[ARM][FIX] Fix vfmal.f16 and vfmsl.f16 operand
The indexed variant of vfmal.f16 and vfmsl.f16 instructions use the uppser bits of the indexed operand to store the index (1 bit for the double variant, 2 bits for the quad). This limits the usable registers to d0 - d7 or s0 - s15. This patch enforces this limitation. Differential Revision: https://reviews.llvm.org/D59021 llvm-svn: 355707
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/ARM/ARMInstrNEON.td22
-rw-r--r--llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp9
2 files changed, 21 insertions, 10 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrNEON.td b/llvm/lib/Target/ARM/ARMInstrNEON.td
index 90aa574cbde..2c996b571d6 100644
--- a/llvm/lib/Target/ARM/ARMInstrNEON.td
+++ b/llvm/lib/Target/ARM/ARMInstrNEON.td
@@ -5121,10 +5121,11 @@ class N3VCP8F16Q0<string asm, RegisterClass Td, RegisterClass Tn,
: N3VCP8Q0<op1, op2, 0, op3, (outs Td:$Vd), (ins Tn:$Vn, Tm:$Vm), NoItinerary,
asm, "f16", "$Vd, $Vn, $Vm", "", []>;
-class VFMQ0<string opc, bits<2> S>
+// Vd, Vs, Vs[0-15], Idx[0-1]
+class VFMD<string opc, string type, bits<2> S>
: N3VLaneCP8<0, S, 0, 1, (outs DPR:$Vd),
- (ins SPR:$Vn, SPR:$Vm, VectorIndex32:$idx),
- IIC_VMACD, opc, "f16", "$Vd, $Vn, $Vm$idx", "", []> {
+ (ins SPR:$Vn, SPR_8:$Vm, VectorIndex32:$idx),
+ IIC_VMACD, opc, type, "$Vd, $Vn, $Vm$idx", "", []> {
bit idx;
let Inst{3} = idx;
let Inst{19-16} = Vn{4-1};
@@ -5133,10 +5134,11 @@ class VFMQ0<string opc, bits<2> S>
let Inst{2-0} = Vm{3-1};
}
-class VFMQ1<string opc, bits<2> S>
+// Vq, Vd, Vd[0-7], Idx[0-3]
+class VFMQ<string opc, string type, bits<2> S>
: N3VLaneCP8<0, S, 1, 1, (outs QPR:$Vd),
- (ins DPR:$Vn, DPR:$Vm, VectorIndex16:$idx),
- IIC_VMACD, opc, "f16", "$Vd, $Vn, $Vm$idx", "", []> {
+ (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$idx),
+ IIC_VMACD, opc, type, "$Vd, $Vn, $Vm$idx", "", []> {
bits<2> idx;
let Inst{5} = idx{1};
let Inst{3} = idx{0};
@@ -5148,10 +5150,10 @@ def VFMALD : N3VCP8F16Q0<"vfmal", DPR, SPR, SPR, 0b00, 0b10, 1>;
def VFMSLD : N3VCP8F16Q0<"vfmsl", DPR, SPR, SPR, 0b01, 0b10, 1>;
def VFMALQ : N3VCP8F16Q1<"vfmal", QPR, DPR, DPR, 0b00, 0b10, 1>;
def VFMSLQ : N3VCP8F16Q1<"vfmsl", QPR, DPR, DPR, 0b01, 0b10, 1>;
-def VFMALDI : VFMQ0<"vfmal", 0b00>;
-def VFMSLDI : VFMQ0<"vfmsl", 0b01>;
-def VFMALQI : VFMQ1<"vfmal", 0b00>;
-def VFMSLQI : VFMQ1<"vfmsl", 0b01>;
+def VFMALDI : VFMD<"vfmal", "f16", 0b00>;
+def VFMSLDI : VFMD<"vfmsl", "f16", 0b01>;
+def VFMALQI : VFMQ<"vfmal", "f16", 0b00>;
+def VFMSLQI : VFMQ<"vfmsl", "f16", 0b01>;
}
} // HasNEON, HasFP16FML
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index b65a0753de0..e92bcc5ba51 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -165,6 +165,8 @@ static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
+ uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
@@ -1045,6 +1047,13 @@ static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
}
+static DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
+ uint64_t Address, const void *Decoder) {
+ if (RegNo > 15)
+ return MCDisassembler::Fail;
+ return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);
+}
+
static DecodeStatus
DecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address, const void *Decoder) {
OpenPOWER on IntegriCloud