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.
// 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;
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;
}
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;
}
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]> {
return msb;
}
-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 {
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;
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());
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,
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,
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;
+}
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);
};
IMM("neg_zero");
IMM("imm0_31");
IMM("imm0_31_m1");
+ IMM("imm1_32");
IMM("nModImm");
IMM("imm0_7");
IMM("imm0_15");
IMM("t_adrlabel");
IMM("t2adrlabel");
IMM("shift_imm");
- IMM("ssat_imm");
IMM("neon_vcvt_imm32");
IMM("shr_imm8");
IMM("shr_imm16");