summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2011-09-26 21:06:22 +0000
committerOwen Anderson <resistor@mac.com>2011-09-26 21:06:22 +0000
commit0afa0094afdfe589f407feb76948f273b414b278 (patch)
treedcc693d8abcbd0897ad5600232a3ced34d1ee48e
parentad2d46d0a5a3e8593a2754b618acd6e9cfe39453 (diff)
downloadllvm-0afa0094afdfe589f407feb76948f273b414b278.tar.gz
llvm-0afa0094afdfe589f407feb76948f273b414b278.tar.bz2
llvm-0afa0094afdfe589f407feb76948f273b414b278.tar.xz
ASR #32 is not allowed on Thumb2 USAT and SSAT instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140560 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td20
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp6
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassembler.cpp14
-rw-r--r--utils/TableGen/EDEmitter.cpp1
4 files changed, 38 insertions, 3 deletions
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index 44804bdbf3..e8874c7f21 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -28,6 +28,18 @@ def it_mask : Operand<i32> {
let ParserMatchClass = it_mask_asmoperand;
}
+// t2_shift_imm: An integer that encodes a shift amount and the type of shift
+// (asr or lsl). The 6-bit immediate encodes as:
+// {5} 0 ==> lsl
+// 1 asr
+// {4-0} imm5 shift amount.
+// asr #32 not allowed
+def t2_shift_imm : Operand<i32> {
+ let PrintMethod = "printShiftImmOperand";
+ let ParserMatchClass = ShifterImmAsmOperand;
+ let DecoderMethod = "DecodeT2ShifterImmOperand";
+}
+
// Shifted operands. No register controlled shifts for Thumb2.
// Note: We do not support rrx shifted operands yet.
def t2_so_reg : Operand<i32>, // reg imm
@@ -2023,7 +2035,8 @@ class T2SatI<dag oops, dag iops, InstrItinClass itin,
}
def t2SSAT: T2SatI<
- (outs rGPR:$Rd), (ins imm1_32:$sat_imm, rGPR:$Rn, shift_imm:$sh),
+ (outs rGPR:$Rd),
+ (ins imm1_32:$sat_imm, rGPR:$Rn, t2_shift_imm:$sh),
NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []> {
let Inst{31-27} = 0b11110;
let Inst{25-22} = 0b1100;
@@ -2047,7 +2060,8 @@ def t2SSAT16: T2SatI<
}
def t2USAT: T2SatI<
- (outs rGPR:$Rd), (ins imm0_31:$sat_imm, rGPR:$Rn, shift_imm:$sh),
+ (outs rGPR:$Rd),
+ (ins imm0_31:$sat_imm, rGPR:$Rn, t2_shift_imm:$sh),
NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []> {
let Inst{31-27} = 0b11110;
let Inst{25-22} = 0b1110;
@@ -3928,6 +3942,8 @@ def : t2InstAlias<"sxtb16${p} $Rd, $Rm",
(t2SXTB16 rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>;
def : t2InstAlias<"sxth${p} $Rd, $Rm",
(t2SXTH rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>;
+def : t2InstAlias<"sxth${p} $Rd, $Rm",
+ (t2SXTH rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>;
def : t2InstAlias<"uxtab${p} $Rd, $Rn, $Rm",
(t2UXTAB rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>;
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index e62899e7b0..543340f8e4 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -2255,7 +2255,11 @@ parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Error(E, "'asr' shift amount must be in range [1,32]");
return MatchOperand_ParseFail;
}
- // asr #32 encoded as asr #0.
+ // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
+ if (isThumb() && Val == 32) {
+ Error(E, "'asr #32' shift amount not allowed in Thumb mode");
+ return MatchOperand_ParseFail;
+ }
if (Val == 32) Val = 0;
} else {
// Shift amount must be in [1,32]
diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index a775cf61b5..c8d1321351 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -307,6 +307,9 @@ static DecodeStatus DecodeT2Adr(llvm::MCInst &Inst, unsigned Val,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeT2LdStPre(llvm::MCInst &Inst, unsigned Val,
uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeT2ShifterImmOperand(llvm::MCInst &Inst, unsigned Val,
+ uint64_t Address, const void *Decoder);
+
#include "ARMGenDisassemblerTables.inc"
@@ -3876,3 +3879,14 @@ static DecodeStatus DecodeT2Adr(llvm::MCInst &Inst, uint32_t Insn,
return MCDisassembler::Success;
}
+static DecodeStatus DecodeT2ShifterImmOperand(llvm::MCInst &Inst, uint32_t Val,
+ uint64_t Address,
+ const void *Decoder) {
+ DecodeStatus S = MCDisassembler::Success;
+
+ // Shift of "asr #32" is not allowed in Thumb2 mode.
+ if (Val == 0x20) S = MCDisassembler::SoftFail;
+ Inst.addOperand(MCOperand::CreateImm(Val));
+ return S;
+}
+
diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp
index 9a0039f33b..e866487d25 100644
--- a/utils/TableGen/EDEmitter.cpp
+++ b/utils/TableGen/EDEmitter.cpp
@@ -610,6 +610,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
IMM("t_adrlabel");
IMM("t2adrlabel");
IMM("shift_imm");
+ IMM("t2_shift_imm");
IMM("neon_vcvt_imm32");
IMM("shr_imm8");
IMM("shr_imm16");