forked from OSchip/llvm-project
ARM assembly parsing and encoding for SSAT16 instruction.
llvm-svn: 136006
This commit is contained in:
parent
9212bf275d
commit
475c6dbef6
|
@ -543,10 +543,20 @@ def imm1_32_XFORM: SDNodeXForm<imm, [{
|
||||||
def Imm1_32AsmOperand: AsmOperandClass { let Name = "Imm1_32"; }
|
def Imm1_32AsmOperand: AsmOperandClass { let Name = "Imm1_32"; }
|
||||||
def imm1_32 : Operand<i32>, PatLeaf<(imm), [{ return Imm > 0 && Imm <= 32; }],
|
def imm1_32 : Operand<i32>, PatLeaf<(imm), [{ return Imm > 0 && Imm <= 32; }],
|
||||||
imm1_32_XFORM> {
|
imm1_32_XFORM> {
|
||||||
let PrintMethod = "printImm1_32Operand";
|
let PrintMethod = "printImmPlusOneOperand";
|
||||||
let ParserMatchClass = Imm1_32AsmOperand;
|
let ParserMatchClass = Imm1_32AsmOperand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def imm1_16_XFORM: SDNodeXForm<imm, [{
|
||||||
|
return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, MVT::i32);
|
||||||
|
}]>;
|
||||||
|
def Imm1_16AsmOperand: AsmOperandClass { let Name = "Imm1_16"; }
|
||||||
|
def imm1_16 : Operand<i32>, PatLeaf<(imm), [{ return Imm > 0 && Imm <= 16; }],
|
||||||
|
imm1_16_XFORM> {
|
||||||
|
let PrintMethod = "printImmPlusOneOperand";
|
||||||
|
let ParserMatchClass = Imm1_16AsmOperand;
|
||||||
|
}
|
||||||
|
|
||||||
// Define ARM specific addressing modes.
|
// Define ARM specific addressing modes.
|
||||||
// addrmode_imm12 := reg +/- imm12
|
// addrmode_imm12 := reg +/- imm12
|
||||||
//
|
//
|
||||||
|
@ -2709,7 +2719,7 @@ def SSAT : AI<(outs GPR:$Rd), (ins imm1_32:$sat_imm, GPR:$Rn, shift_imm:$sh),
|
||||||
let Inst{3-0} = Rn;
|
let Inst{3-0} = Rn;
|
||||||
}
|
}
|
||||||
|
|
||||||
def SSAT16 : AI<(outs GPR:$Rd), (ins imm1_32:$sat_imm, GPR:$Rn), SatFrm,
|
def SSAT16 : AI<(outs GPR:$Rd), (ins imm1_16:$sat_imm, GPR:$Rn), SatFrm,
|
||||||
NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", []> {
|
NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", []> {
|
||||||
bits<4> Rd;
|
bits<4> Rd;
|
||||||
bits<4> sat_imm;
|
bits<4> sat_imm;
|
||||||
|
|
|
@ -1935,7 +1935,7 @@ def t2SSAT: T2SatI<
|
||||||
}
|
}
|
||||||
|
|
||||||
def t2SSAT16: T2SatI<
|
def t2SSAT16: T2SatI<
|
||||||
(outs rGPR:$Rd), (ins imm1_32:$sat_imm, rGPR:$Rn), NoItinerary,
|
(outs rGPR:$Rd), (ins imm1_16:$sat_imm, rGPR:$Rn), NoItinerary,
|
||||||
"ssat16", "\t$Rd, $sat_imm, $Rn",
|
"ssat16", "\t$Rd, $sat_imm, $Rn",
|
||||||
[/* For disassembly only; pattern left blank */]>,
|
[/* For disassembly only; pattern left blank */]>,
|
||||||
Requires<[IsThumb2, HasThumb2DSP]> {
|
Requires<[IsThumb2, HasThumb2DSP]> {
|
||||||
|
|
|
@ -433,6 +433,14 @@ public:
|
||||||
int64_t Value = CE->getValue();
|
int64_t Value = CE->getValue();
|
||||||
return Value >= 0 && Value < 32;
|
return Value >= 0 && Value < 32;
|
||||||
}
|
}
|
||||||
|
bool isImm1_16() 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 < 17;
|
||||||
|
}
|
||||||
bool isImm1_32() const {
|
bool isImm1_32() const {
|
||||||
if (Kind != Immediate)
|
if (Kind != Immediate)
|
||||||
return false;
|
return false;
|
||||||
|
@ -704,6 +712,14 @@ public:
|
||||||
addExpr(Inst, getImm());
|
addExpr(Inst, getImm());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addImm1_16Operands(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 addImm1_32Operands(MCInst &Inst, unsigned N) const {
|
void addImm1_32Operands(MCInst &Inst, unsigned N) const {
|
||||||
assert(N == 1 && "Invalid number of operands!");
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
// The constant encodes as the immediate-1, and we store in the instruction
|
// The constant encodes as the immediate-1, and we store in the instruction
|
||||||
|
|
|
@ -830,8 +830,8 @@ void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum,
|
||||||
O << "#0x" << utohexstr(Val);
|
O << "#0x" << utohexstr(Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMInstPrinter::printImm1_32Operand(const MCInst *MI, unsigned OpNum,
|
void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum,
|
||||||
raw_ostream &O) {
|
raw_ostream &O) {
|
||||||
unsigned Imm = MI->getOperand(OpNum).getImm();
|
unsigned Imm = MI->getOperand(OpNum).getImm();
|
||||||
O << "#" << Imm + 1;
|
O << "#" << Imm + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ public:
|
||||||
void printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
void printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||||
void printVFPf64ImmOperand(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 printNEONModImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||||
void printImm1_32Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
void printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||||
|
|
||||||
void printPCLabel(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
void printPCLabel(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1631,6 +1631,17 @@ _func:
|
||||||
@ CHECK: ssat r8, #1, r10, asr #32 @ encoding: [0x5a,0x80,0xa0,0xe6]
|
@ CHECK: ssat r8, #1, r10, asr #32 @ encoding: [0x5a,0x80,0xa0,0xe6]
|
||||||
@ CHECK: ssat r8, #1, r10, asr #1 @ encoding: [0xda,0x80,0xa0,0xe6]
|
@ CHECK: ssat r8, #1, r10, asr #1 @ encoding: [0xda,0x80,0xa0,0xe6]
|
||||||
|
|
||||||
|
|
||||||
|
@------------------------------------------------------------------------------
|
||||||
|
@ SSAT16
|
||||||
|
@------------------------------------------------------------------------------
|
||||||
|
ssat16 r2, #1, r7
|
||||||
|
ssat16 r3, #16, r5
|
||||||
|
|
||||||
|
@ CHECK: ssat16 r2, #1, r7 @ encoding: [0x37,0x2f,0xa0,0xe6]
|
||||||
|
@ CHECK: ssat16 r3, #16, r5 @ encoding: [0x35,0x3f,0xaf,0xe6]
|
||||||
|
|
||||||
|
|
||||||
@------------------------------------------------------------------------------
|
@------------------------------------------------------------------------------
|
||||||
@ STM*
|
@ STM*
|
||||||
@------------------------------------------------------------------------------
|
@------------------------------------------------------------------------------
|
||||||
|
|
|
@ -200,3 +200,14 @@
|
||||||
@ CHECK: error: shift amount must be an immediate
|
@ CHECK: error: shift amount must be an immediate
|
||||||
@ CHECK: ssat r8, #1, r10, lsl #fred
|
@ CHECK: ssat r8, #1, r10, lsl #fred
|
||||||
@ CHECK: ^
|
@ CHECK: ^
|
||||||
|
|
||||||
|
@ Out of range immediates for SSAT16
|
||||||
|
ssat16 r2, #0, r7
|
||||||
|
ssat16 r3, #17, r5
|
||||||
|
|
||||||
|
@ CHECK: error: invalid operand for instruction
|
||||||
|
@ CHECK: ssat16 r2, #0, r7
|
||||||
|
@ CHECK: ^
|
||||||
|
@ CHECK: error: invalid operand for instruction
|
||||||
|
@ CHECK: ssat16 r3, #17, r5
|
||||||
|
@ CHECK: ^
|
||||||
|
|
|
@ -587,6 +587,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
|
||||||
IMM("neg_zero");
|
IMM("neg_zero");
|
||||||
IMM("imm0_31");
|
IMM("imm0_31");
|
||||||
IMM("imm0_31_m1");
|
IMM("imm0_31_m1");
|
||||||
|
IMM("imm1_16");
|
||||||
IMM("imm1_32");
|
IMM("imm1_32");
|
||||||
IMM("nModImm");
|
IMM("nModImm");
|
||||||
IMM("imm0_7");
|
IMM("imm0_7");
|
||||||
|
|
Loading…
Reference in New Issue