summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBradley Smith <bradley.smith@arm.com>2014-04-09 14:43:35 +0000
committerBradley Smith <bradley.smith@arm.com>2014-04-09 14:43:35 +0000
commiteb4ca04db2b8b57d593a5f768cfbba37d370949e (patch)
tree08603b070781839129af0036892f9af3c05f1f78
parentdb7b9b17ebba5e0c7ba1307f53e45d86645ad165 (diff)
downloadbcm5719-llvm-eb4ca04db2b8b57d593a5f768cfbba37d370949e.tar.gz
bcm5719-llvm-eb4ca04db2b8b57d593a5f768cfbba37d370949e.zip
[ARM64] SCVTF and FCVTZS/U are undefined if scale<5> == 0.
llvm-svn: 205882
-rw-r--r--llvm/lib/Target/ARM64/ARM64InstrFormats.td8
-rw-r--r--llvm/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp24
-rw-r--r--llvm/test/MC/Disassembler/ARM64/basic-a64-undefined.txt5
3 files changed, 29 insertions, 8 deletions
diff --git a/llvm/lib/Target/ARM64/ARM64InstrFormats.td b/llvm/lib/Target/ARM64/ARM64InstrFormats.td
index aeb71a20fb5..83a64dc43d7 100644
--- a/llvm/lib/Target/ARM64/ARM64InstrFormats.td
+++ b/llvm/lib/Target/ARM64/ARM64InstrFormats.td
@@ -304,12 +304,12 @@ def movk_symbol_g0 : Operand<i32> {
def fixedpoint32 : Operand<i32> {
let EncoderMethod = "getFixedPointScaleOpValue";
- let DecoderMethod = "DecodeFixedPointScaleImm";
+ let DecoderMethod = "DecodeFixedPointScaleImm32";
let ParserMatchClass = Imm1_32Operand;
}
def fixedpoint64 : Operand<i64> {
let EncoderMethod = "getFixedPointScaleOpValue";
- let DecoderMethod = "DecodeFixedPointScaleImm";
+ let DecoderMethod = "DecodeFixedPointScaleImm64";
let ParserMatchClass = Imm1_64Operand;
}
@@ -3117,6 +3117,7 @@ multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
fixedpoint32, asm> {
let Inst{31} = 0; // 32-bit GPR flag
+ let scale{5} = 1;
}
// Scaled single-precision to 64-bit
@@ -3129,6 +3130,7 @@ multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
fixedpoint32, asm> {
let Inst{31} = 0; // 32-bit GPR flag
+ let scale{5} = 1;
}
// Scaled double-precision to 64-bit
@@ -3203,11 +3205,13 @@ multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint32, asm> {
let Inst{31} = 0; // 32-bit GPR flag
let Inst{22} = 0; // 32-bit FPR flag
+ let scale{5} = 1;
}
def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint32, asm> {
let Inst{31} = 0; // 32-bit GPR flag
let Inst{22} = 1; // 64-bit FPR flag
+ let scale{5} = 1;
}
def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint64, asm> {
diff --git a/llvm/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp b/llvm/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp
index 667603ca0c3..6eb7367bf31 100644
--- a/llvm/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp
+++ b/llvm/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp
@@ -82,9 +82,12 @@ static DecodeStatus DecodeDDDDRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
-static DecodeStatus DecodeFixedPointScaleImm(llvm::MCInst &Inst, unsigned Imm,
- uint64_t Address,
- const void *Decoder);
+static DecodeStatus DecodeFixedPointScaleImm32(llvm::MCInst &Inst, unsigned Imm,
+ uint64_t Address,
+ const void *Decoder);
+static DecodeStatus DecodeFixedPointScaleImm64(llvm::MCInst &Inst, unsigned Imm,
+ uint64_t Address,
+ const void *Decoder);
static DecodeStatus DecodeCondBranchTarget(llvm::MCInst &Inst, unsigned Imm,
uint64_t Address,
const void *Decoder);
@@ -744,9 +747,18 @@ static DecodeStatus DecodeDDDDRegisterClass(MCInst &Inst, unsigned RegNo,
return Success;
}
-static DecodeStatus DecodeFixedPointScaleImm(llvm::MCInst &Inst, unsigned Imm,
- uint64_t Addr,
- const void *Decoder) {
+static DecodeStatus DecodeFixedPointScaleImm32(llvm::MCInst &Inst, unsigned Imm,
+ uint64_t Addr,
+ const void *Decoder) {
+ // scale{5} is asserted as 1 in tblgen.
+ Imm |= 0x20;
+ Inst.addOperand(MCOperand::CreateImm(64 - Imm));
+ return Success;
+}
+
+static DecodeStatus DecodeFixedPointScaleImm64(llvm::MCInst &Inst, unsigned Imm,
+ uint64_t Addr,
+ const void *Decoder) {
Inst.addOperand(MCOperand::CreateImm(64 - Imm));
return Success;
}
diff --git a/llvm/test/MC/Disassembler/ARM64/basic-a64-undefined.txt b/llvm/test/MC/Disassembler/ARM64/basic-a64-undefined.txt
index c2e3841bb94..0e15af63e68 100644
--- a/llvm/test/MC/Disassembler/ARM64/basic-a64-undefined.txt
+++ b/llvm/test/MC/Disassembler/ARM64/basic-a64-undefined.txt
@@ -23,4 +23,9 @@
# EXT on vectors of i8 must have imm<3> = 0.
# RUN: echo "0x00 0x40 0x00 0x2e" | llvm-mc -triple=arm64 -disassemble 2>&1 | FileCheck %s
+# SCVTF on fixed point W-registers is undefined if scale<5> == 0.
+# Same with FCVTZS and FCVTZU.
+# RUN: echo "0x00 0x00 0x02 0x1e" | llvm-mc -triple=arm64 -disassemble 2>&1 | FileCheck %s
+# RUN: echo "0x00 0x00 0x18 0x1e" | llvm-mc -triple=arm64 -disassemble 2>&1 | FileCheck %s
+
# CHECK: invalid instruction encoding
OpenPOWER on IntegriCloud