summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
diff options
context:
space:
mode:
authorOliver Stannard <oliver.stannard@arm.com>2015-12-16 12:37:39 +0000
committerOliver Stannard <oliver.stannard@arm.com>2015-12-16 12:37:39 +0000
commit2de8c1691304420d2f1050f31c9f25e043ab7874 (patch)
tree64bfdc49f345b7df8a2890fd573b528bcb58db67 /llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
parent25e241b006559ec6cb188ac32fb7fba0f358bc1b (diff)
downloadbcm5719-llvm-2de8c1691304420d2f1050f31c9f25e043ab7874.tar.gz
bcm5719-llvm-2de8c1691304420d2f1050f31c9f25e043ab7874.zip
[ARM] Add ARMv8.2-A FP16 vector instructions
ARMv8.2-A adds 16-bit floating point versions of all existing SIMD floating-point instructions. This is an optional extension, so all of these instructions require the FeatureFullFP16 subtarget feature. Note that VFP without SIMD is not a valid combination for any version of ARMv8-A, but I have ensured that these instructions all depend on both FeatureNEON and FeatureFullFP16 for consistency. Differential Revision: http://reviews.llvm.org/D15039 llvm-svn: 255764
Diffstat (limited to 'llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp')
-rw-r--r--llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp74
1 files changed, 66 insertions, 8 deletions
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index a05111e4ceb..bc63c26b328 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -5073,6 +5073,10 @@ static DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder) {
+ const FeatureBitset &featureBits =
+ ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
+ bool hasFullFP16 = featureBits[ARM::FeatureFullFP16];
+
unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
@@ -5083,10 +5087,35 @@ static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
DecodeStatus S = MCDisassembler::Success;
- // VMOVv2f32 is ambiguous with these decodings.
- if (!(imm & 0x38) && cmode == 0xF) {
- if (op == 1) return MCDisassembler::Fail;
- Inst.setOpcode(ARM::VMOVv2f32);
+ // If the top 3 bits of imm are clear, this is a VMOV (immediate)
+ if (!(imm & 0x38)) {
+ if (cmode == 0xF) {
+ if (op == 1) return MCDisassembler::Fail;
+ Inst.setOpcode(ARM::VMOVv2f32);
+ }
+ if (hasFullFP16) {
+ if (cmode == 0xE) {
+ if (op == 1) {
+ Inst.setOpcode(ARM::VMOVv1i64);
+ } else {
+ Inst.setOpcode(ARM::VMOVv8i8);
+ }
+ }
+ if (cmode == 0xD) {
+ if (op == 1) {
+ Inst.setOpcode(ARM::VMVNv2i32);
+ } else {
+ Inst.setOpcode(ARM::VMOVv2i32);
+ }
+ }
+ if (cmode == 0xC) {
+ if (op == 1) {
+ Inst.setOpcode(ARM::VMVNv2i32);
+ } else {
+ Inst.setOpcode(ARM::VMOVv2i32);
+ }
+ }
+ }
return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
}
@@ -5103,6 +5132,10 @@ static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder) {
+ const FeatureBitset &featureBits =
+ ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
+ bool hasFullFP16 = featureBits[ARM::FeatureFullFP16];
+
unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
@@ -5113,10 +5146,35 @@ static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
DecodeStatus S = MCDisassembler::Success;
- // VMOVv4f32 is ambiguous with these decodings.
- if (!(imm & 0x38) && cmode == 0xF) {
- if (op == 1) return MCDisassembler::Fail;
- Inst.setOpcode(ARM::VMOVv4f32);
+ // If the top 3 bits of imm are clear, this is a VMOV (immediate)
+ if (!(imm & 0x38)) {
+ if (cmode == 0xF) {
+ if (op == 1) return MCDisassembler::Fail;
+ Inst.setOpcode(ARM::VMOVv4f32);
+ }
+ if (hasFullFP16) {
+ if (cmode == 0xE) {
+ if (op == 1) {
+ Inst.setOpcode(ARM::VMOVv2i64);
+ } else {
+ Inst.setOpcode(ARM::VMOVv16i8);
+ }
+ }
+ if (cmode == 0xD) {
+ if (op == 1) {
+ Inst.setOpcode(ARM::VMVNv4i32);
+ } else {
+ Inst.setOpcode(ARM::VMOVv4i32);
+ }
+ }
+ if (cmode == 0xC) {
+ if (op == 1) {
+ Inst.setOpcode(ARM::VMVNv4i32);
+ } else {
+ Inst.setOpcode(ARM::VMOVv4i32);
+ }
+ }
+ }
return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
}
OpenPOWER on IntegriCloud