diff options
author | Jim Grosbach <grosbach@apple.com> | 2011-07-22 23:16:18 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2011-07-22 23:16:18 +0000 |
commit | 801e0a3fdebc6c2d22706967874a572846f3e5d8 (patch) | |
tree | 67276c24f7b34d10d94cb0c5cf299359aa310f06 /llvm/lib | |
parent | c8eab671cf3f9d3fe19f87d0ede9451072ff9866 (diff) | |
download | bcm5719-llvm-801e0a3fdebc6c2d22706967874a572846f3e5d8.tar.gz bcm5719-llvm-801e0a3fdebc6c2d22706967874a572846f3e5d8.zip |
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.
llvm-svn: 135823
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.td | 22 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb2.td | 4 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h | 2 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h | 1 |
8 files changed, 37 insertions, 23 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index 009f7add00e..ec6052dfd75 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/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/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index 287c2d94d28..33a246f2ed3 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/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/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp b/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp index 43eb5e32b3d..d7bd62443b2 100644 --- a/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/llvm/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/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 4491c5099a7..da07ea08507 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/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/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp index 40e48129a8a..38c77d479db 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp +++ b/llvm/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/llvm/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h b/llvm/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h index 85d62be60c1..7ad958f51a7 100644 --- a/llvm/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h +++ b/llvm/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/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index e50f3b20875..1bd92b52f1e 100644 --- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/llvm/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/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h index bb225f2e2a2..208a3a71f14 100644 --- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h +++ b/llvm/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); }; |