aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-07-22 23:16:18 +0000
committerJim Grosbach <grosbach@apple.com>2011-07-22 23:16:18 +0000
commit4a5ffb399f841783c201c599b88d576757f1922e (patch)
tree617da249fe89433aa1af7b1043521bed6c9bc7c5
parent4428069f10ac6e7efb55826437c82428d4bbe03e (diff)
ARM SSAT instruction 5-bit immediate handling.
The immediate is in the range 1-32, but is encoded as 0-31 in a 5-bit bitfield. Update the representation such that we store the operand as 0-31, allowing us to remove the encoder method and the special case handling in the disassembler. Update the assembly parser and the instruction printer accordingly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135823 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td22
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td4
-rw-r--r--lib/Target/ARM/ARMMCCodeEmitter.cpp7
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp16
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp2
-rw-r--r--lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h2
-rw-r--r--lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp6
-rw-r--r--lib/Target/ARM/InstPrinter/ARMInstPrinter.h1
-rw-r--r--utils/TableGen/EDEmitter.cpp2
9 files changed, 38 insertions, 24 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 009f7add00..ec6052dfd7 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -553,10 +553,14 @@ def width_imm : Operand<i32>, ImmLeaf<i32, [{
let EncoderMethod = "getMsbOpValue";
}
-def ssat_imm : Operand<i32>, ImmLeaf<i32, [{
- return Imm > 0 && Imm <= 32;
-}]> {
- let EncoderMethod = "getSsatBitPosValue";
+def imm1_32_XFORM: SDNodeXForm<imm, [{
+ return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, MVT::i32);
+}]>;
+def Imm1_32AsmOperand: AsmOperandClass { let Name = "Imm1_32"; }
+def imm1_32 : Operand<i32>, PatLeaf<(imm), [{ return Imm > 0 && Imm <= 32; }],
+ imm1_32_XFORM> {
+ let PrintMethod = "printImm1_32Operand";
+ let ParserMatchClass = Imm1_32AsmOperand;
}
// Define ARM specific addressing modes.
@@ -2723,9 +2727,8 @@ def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
// Signed/Unsigned saturate -- for disassembly only
-def SSAT : AI<(outs GPR:$Rd), (ins ssat_imm:$sat_imm, GPR:$a, shift_imm:$sh),
- SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh",
- [/* For disassembly only; pattern left blank */]> {
+def SSAT : AI<(outs GPR:$Rd), (ins imm1_32:$sat_imm, GPR:$a, shift_imm:$sh),
+ SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh", []> {
bits<4> Rd;
bits<5> sat_imm;
bits<4> Rn;
@@ -2739,9 +2742,8 @@ def SSAT : AI<(outs GPR:$Rd), (ins ssat_imm:$sat_imm, GPR:$a, shift_imm:$sh),
let Inst{3-0} = Rn;
}
-def SSAT16 : AI<(outs GPR:$Rd), (ins ssat_imm:$sat_imm, GPR:$Rn), SatFrm,
- NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn",
- [/* For disassembly only; pattern left blank */]> {
+def SSAT16 : AI<(outs GPR:$Rd), (ins imm1_32:$sat_imm, GPR:$Rn), SatFrm,
+ NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", []> {
bits<4> Rd;
bits<4> sat_imm;
bits<4> Rn;
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index 287c2d94d2..33a246f2ed 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -1925,7 +1925,7 @@ class T2SatI<dag oops, dag iops, InstrItinClass itin,
}
def t2SSAT: T2SatI<
- (outs rGPR:$Rd), (ins ssat_imm:$sat_imm, rGPR:$Rn, shift_imm:$sh),
+ (outs rGPR:$Rd), (ins imm1_32:$sat_imm, rGPR:$Rn, shift_imm:$sh),
NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
@@ -1935,7 +1935,7 @@ def t2SSAT: T2SatI<
}
def t2SSAT16: T2SatI<
- (outs rGPR:$Rd), (ins ssat_imm:$sat_imm, rGPR:$Rn), NoItinerary,
+ (outs rGPR:$Rd), (ins imm1_32:$sat_imm, rGPR:$Rn), NoItinerary,
"ssat16", "\t$Rd, $sat_imm, $Rn",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsThumb2, HasThumb2DSP]> {
diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp
index 43eb5e32b3..d7bd62443b 100644
--- a/lib/Target/ARM/ARMMCCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp
@@ -1171,13 +1171,6 @@ getMsbOpValue(const MCInst &MI, unsigned Op,
}
unsigned ARMMCCodeEmitter::
-getSsatBitPosValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- // For ssat instructions, the bit position should be encoded decremented by 1
- return MI.getOperand(Op).getImm()-1;
-}
-
-unsigned ARMMCCodeEmitter::
getRegisterListOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const {
// VLDM/VSTM:
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 4491c5099a..da07ea0850 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -427,6 +427,14 @@ public:
int64_t Value = CE->getValue();
return Value >= 0 && Value < 32;
}
+ bool isImm1_32() const {
+ if (Kind != Immediate)
+ return false;
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+ if (!CE) return false;
+ int64_t Value = CE->getValue();
+ return Value > 0 && Value < 33;
+ }
bool isImm0_65535() const {
if (Kind != Immediate)
return false;
@@ -690,6 +698,14 @@ public:
addExpr(Inst, getImm());
}
+ void addImm1_32Operands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ // The constant encodes as the immediate-1, and we store in the instruction
+ // the bits as encoded, so subtract off one here.
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+ Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
+ }
+
void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
addExpr(Inst, getImm());
diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
index 40e48129a8..38c77d479d 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
@@ -1726,8 +1726,6 @@ static bool DisassembleSatFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
decodeRd(insn))));
unsigned Pos = slice(insn, 20, 16);
- if (Opcode == ARM::SSAT || Opcode == ARM::SSAT16)
- Pos += 1;
MI.addOperand(MCOperand::CreateImm(Pos));
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
diff --git a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
index 85d62be60c..7ad958f51a 100644
--- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
+++ b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
@@ -1609,8 +1609,6 @@ static bool DisassembleThumb2Sat(MCInst &MI, unsigned Opcode, uint32_t insn,
decodeRs(insn))));
unsigned Pos = slice(insn, 4, 0);
- if (Opcode == ARM::t2SSAT || Opcode == ARM::t2SSAT16)
- Pos += 1;
MI.addOperand(MCOperand::CreateImm(Pos));
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
index e50f3b2087..1bd92b52f1 100644
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
@@ -837,3 +837,9 @@ void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum,
uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
O << "#0x" << utohexstr(Val);
}
+
+void ARMInstPrinter::printImm1_32Operand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ unsigned Imm = MI->getOperand(OpNum).getImm();
+ O << "#" << Imm + 1;
+}
diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
index bb225f2e2a..208a3a71f1 100644
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
@@ -114,6 +114,7 @@ public:
void printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
void printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
void printNEONModImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printImm1_32Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
void printPCLabel(const MCInst *MI, unsigned OpNum, raw_ostream &O);
};
diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp
index 7569e5576c..3001192e7f 100644
--- a/utils/TableGen/EDEmitter.cpp
+++ b/utils/TableGen/EDEmitter.cpp
@@ -587,6 +587,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
IMM("neg_zero");
IMM("imm0_31");
IMM("imm0_31_m1");
+ IMM("imm1_32");
IMM("nModImm");
IMM("imm0_7");
IMM("imm0_15");
@@ -603,7 +604,6 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
IMM("t_adrlabel");
IMM("t2adrlabel");
IMM("shift_imm");
- IMM("ssat_imm");
IMM("neon_vcvt_imm32");
IMM("shr_imm8");
IMM("shr_imm16");