forked from OSchip/llvm-project
ARM assembly parsing and encoding for extend instructions.
Assembly parser handling for extend instruction rotate operands. Add tests for the sign extend instructions. llvm-svn: 136252
This commit is contained in:
parent
9d155aa061
commit
833b9d3353
|
@ -397,11 +397,16 @@ def rot_imm_XFORM: SDNodeXForm<imm, [{
|
|||
case 24: return CurDAG->getTargetConstant(3, MVT::i32);
|
||||
}
|
||||
}]>;
|
||||
def RotImmAsmOperand : AsmOperandClass {
|
||||
let Name = "RotImm";
|
||||
let ParserMethod = "parseRotImm";
|
||||
}
|
||||
def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
|
||||
int32_t v = N->getZExtValue();
|
||||
return v == 8 || v == 16 || v == 24; }],
|
||||
rot_imm_XFORM> {
|
||||
let PrintMethod = "printRotImmOperand";
|
||||
let ParserMatchClass = RotImmAsmOperand;
|
||||
}
|
||||
|
||||
// shift_imm: An integer that encodes a shift amount and the type of shift
|
||||
|
|
|
@ -124,6 +124,7 @@ class ARMAsmParser : public MCTargetAsmParser {
|
|||
}
|
||||
OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
|
||||
OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
|
||||
OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
|
||||
|
||||
// Asm Match Converter Methods
|
||||
bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
|
||||
|
@ -187,6 +188,7 @@ class ARMOperand : public MCParsedAsmOperand {
|
|||
ShiftedRegister,
|
||||
ShiftedImmediate,
|
||||
ShifterImmediate,
|
||||
RotateImmediate,
|
||||
Token
|
||||
} Kind;
|
||||
|
||||
|
@ -260,6 +262,9 @@ class ARMOperand : public MCParsedAsmOperand {
|
|||
unsigned SrcReg;
|
||||
unsigned ShiftImm;
|
||||
} RegShiftedImm;
|
||||
struct {
|
||||
unsigned Imm;
|
||||
} RotImm;
|
||||
};
|
||||
|
||||
ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
|
||||
|
@ -312,6 +317,9 @@ public:
|
|||
case ShiftedImmediate:
|
||||
RegShiftedImm = o.RegShiftedImm;
|
||||
break;
|
||||
case RotateImmediate:
|
||||
RotImm = o.RotImm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -531,6 +539,7 @@ public:
|
|||
bool isShifterImm() const { return Kind == ShifterImmediate; }
|
||||
bool isRegShiftedReg() const { return Kind == ShiftedRegister; }
|
||||
bool isRegShiftedImm() const { return Kind == ShiftedImmediate; }
|
||||
bool isRotImm() const { return Kind == RotateImmediate; }
|
||||
bool isMemMode2() const {
|
||||
if (getMemAddrMode() != ARMII::AddrMode2)
|
||||
return false;
|
||||
|
@ -701,6 +710,12 @@ public:
|
|||
addRegListOperands(Inst, N);
|
||||
}
|
||||
|
||||
void addRotImmOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
// Encoded as val>>3. The printer handles display as 8, 16, 24.
|
||||
Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
|
||||
}
|
||||
|
||||
void addImmOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
addExpr(Inst, getImm());
|
||||
|
@ -1008,6 +1023,14 @@ public:
|
|||
return Op;
|
||||
}
|
||||
|
||||
static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
|
||||
ARMOperand *Op = new ARMOperand(RotateImmediate);
|
||||
Op->RotImm.Imm = Imm;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
return Op;
|
||||
}
|
||||
|
||||
static ARMOperand *
|
||||
CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
|
||||
SMLoc StartLoc, SMLoc EndLoc) {
|
||||
|
@ -1183,6 +1206,9 @@ void ARMOperand::print(raw_ostream &OS) const {
|
|||
<< ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm)
|
||||
<< ">";
|
||||
break;
|
||||
case RotateImmediate:
|
||||
OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
|
||||
break;
|
||||
case RegisterList:
|
||||
case DPRRegisterList:
|
||||
case SPRRegisterList: {
|
||||
|
@ -1810,6 +1836,58 @@ parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
|||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
|
||||
/// of instructions. Legal values are:
|
||||
/// ror #n 'n' in {0, 8, 16, 24}
|
||||
ARMAsmParser::OperandMatchResultTy ARMAsmParser::
|
||||
parseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
SMLoc S = Tok.getLoc();
|
||||
if (Tok.isNot(AsmToken::Identifier)) {
|
||||
Error(S, "rotate operator 'ror' expected");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
StringRef ShiftName = Tok.getString();
|
||||
if (ShiftName != "ror" && ShiftName != "ROR") {
|
||||
Error(S, "rotate operator 'ror' expected");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
Parser.Lex(); // Eat the operator.
|
||||
|
||||
// A '#' and a rotate amount.
|
||||
if (Parser.getTok().isNot(AsmToken::Hash)) {
|
||||
Error(Parser.getTok().getLoc(), "'#' expected");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
Parser.Lex(); // Eat hash token.
|
||||
|
||||
const MCExpr *ShiftAmount;
|
||||
SMLoc E = Parser.getTok().getLoc();
|
||||
if (getParser().ParseExpression(ShiftAmount)) {
|
||||
Error(E, "malformed rotate expression");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
|
||||
if (!CE) {
|
||||
Error(E, "rotate amount must be an immediate");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
|
||||
int64_t Val = CE->getValue();
|
||||
// Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
|
||||
// normally, zero is represented in asm by omitting the rotate operand
|
||||
// entirely.
|
||||
if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
|
||||
Error(E, "'ror' rotate amount must be 8, 16, or 24");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
|
||||
E = Parser.getTok().getLoc();
|
||||
Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
|
||||
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
|
||||
/// Needed here because the Asm Gen Matcher can't handle properly tied operands
|
||||
/// when they refer multiple MIOperands inside a single one.
|
||||
|
|
|
@ -1802,3 +1802,115 @@ _func:
|
|||
@ CHECK: swp r1, r2, [r3] @ encoding: [0x92,0x10,0x03,0xe1]
|
||||
@ CHECK: swp r4, r4, [r6] @ encoding: [0x94,0x40,0x06,0xe1]
|
||||
@ CHECK: swpb r5, r1, [r9] @ encoding: [0x91,0x50,0x49,0xe1]
|
||||
|
||||
|
||||
@------------------------------------------------------------------------------
|
||||
@ SXTAB
|
||||
@------------------------------------------------------------------------------
|
||||
sxtab r2, r3, r4
|
||||
sxtab r4, r5, r6, ror #0
|
||||
sxtablt r6, r2, r9, ror #8
|
||||
sxtab r5, r1, r4, ror #16
|
||||
sxtab r7, r8, r3, ror #24
|
||||
|
||||
@ CHECK: sxtab r2, r3, r4 @ encoding: [0x74,0x20,0xa3,0xe6]
|
||||
@ CHECK: sxtab r4, r5, r6 @ encoding: [0x76,0x40,0xa5,0xe6]
|
||||
@ CHECK: sxtablt r6, r2, r9, ror #8
|
||||
@ encoding: [0x79,0x64,0xa2,0xb6]
|
||||
@ CHECK: sxtab r5, r1, r4, ror #16
|
||||
@ encoding: [0x74,0x58,0xa1,0xe6]
|
||||
@ CHECK: sxtab r7, r8, r3, ror #24
|
||||
@ encoding: [0x73,0x7c,0xa8,0xe6]
|
||||
|
||||
|
||||
@------------------------------------------------------------------------------
|
||||
@ SXTAB16
|
||||
@------------------------------------------------------------------------------
|
||||
sxtab16ge r0, r1, r4
|
||||
sxtab16 r6, r2, r7, ror #0
|
||||
sxtab16 r3, r5, r8, ror #8
|
||||
sxtab16 r3, r2, r1, ror #16
|
||||
sxtab16eq r1, r2, r3, ror #24
|
||||
|
||||
@ CHECK: sxtab16ge r0, r1, r4 @ encoding: [0x74,0x00,0x81,0xa6]
|
||||
@ CHECK: sxtab16 r6, r2, r7 @ encoding: [0x77,0x60,0x82,0xe6]
|
||||
@ CHECK: sxtab16 r3, r5, r8, ror #8
|
||||
@ encoding: [0x78,0x34,0x85,0xe6]
|
||||
@ CHECK: sxtab16 r3, r2, r1, ror #16
|
||||
@ encoding: [0x71,0x38,0x82,0xe6]
|
||||
@ CHECK: sxtab16eq r1, r2, r3, ror #24
|
||||
@ encoding: [0x73,0x1c,0x82,0x06]
|
||||
|
||||
@------------------------------------------------------------------------------
|
||||
@ SXTAH
|
||||
@------------------------------------------------------------------------------
|
||||
sxtah r1, r3, r9
|
||||
sxtahhi r6, r1, r6, ror #0
|
||||
sxtah r3, r8, r3, ror #8
|
||||
sxtahlo r2, r2, r4, ror #16
|
||||
sxtah r9, r3, r3, ror #24
|
||||
|
||||
@ CHECK: sxtah r1, r3, r9 @ encoding: [0x79,0x10,0xb3,0xe6]
|
||||
@ CHECK: sxtahhi r6, r1, r6 @ encoding: [0x76,0x60,0xb1,0x86]
|
||||
@ CHECK: sxtah r3, r8, r3, ror #8
|
||||
@ encoding: [0x73,0x34,0xb8,0xe6]
|
||||
@ CHECK: sxtahlo r2, r2, r4, ror #16
|
||||
@ encoding: [0x74,0x28,0xb2,0x36]
|
||||
@ CHECK: sxtah r9, r3, r3, ror #24
|
||||
@ encoding: [0x73,0x9c,0xb3,0xe6]
|
||||
|
||||
@------------------------------------------------------------------------------
|
||||
@ SXTB
|
||||
@------------------------------------------------------------------------------
|
||||
sxtbge r2, r4
|
||||
sxtb r5, r6, ror #0
|
||||
sxtb r6, r9, ror #8
|
||||
sxtbcc r5, r1, ror #16
|
||||
sxtb r8, r3, ror #24
|
||||
|
||||
@ CHECK: sxtbge r2, r4 @ encoding: [0x74,0x20,0xaf,0xa6]
|
||||
@ CHECK: sxtb r5, r6 @ encoding: [0x76,0x50,0xaf,0xe6]
|
||||
@ CHECK: sxtb r6, r9, ror #8
|
||||
@ encoding: [0x79,0x64,0xaf,0xe6]
|
||||
@ CHECK: sxtblo r5, r1, ror #16
|
||||
@ encoding: [0x71,0x58,0xaf,0x36]
|
||||
@ CHECK: sxtb r8, r3, ror #24
|
||||
@ encoding: [0x73,0x8c,0xaf,0xe6]
|
||||
|
||||
|
||||
@------------------------------------------------------------------------------
|
||||
@ SXTB16
|
||||
@------------------------------------------------------------------------------
|
||||
sxtb16 r1, r4
|
||||
sxtb16 r6, r7, ror #0
|
||||
sxtb16cs r3, r5, ror #8
|
||||
sxtb16 r3, r1, ror #16
|
||||
sxtb16ge r2, r3, ror #24
|
||||
|
||||
@ CHECK: sxtb16 r1, r4 @ encoding: [0x74,0x10,0x8f,0xe6]
|
||||
@ CHECK: sxtb16 r6, r7 @ encoding: [0x77,0x60,0x8f,0xe6]
|
||||
@ CHECK: sxtb16hs r3, r5, ror #8
|
||||
@ encoding: [0x75,0x34,0x8f,0x26]
|
||||
@ CHECK: sxtb16 r3, r1, ror #16
|
||||
@ encoding: [0x71,0x38,0x8f,0xe6]
|
||||
@ CHECK: sxtb16ge r2, r3, ror #24
|
||||
@ encoding: [0x73,0x2c,0x8f,0xa6]
|
||||
|
||||
|
||||
@------------------------------------------------------------------------------
|
||||
@ SXTH
|
||||
@------------------------------------------------------------------------------
|
||||
sxthne r3, r9
|
||||
sxth r1, r6, ror #0
|
||||
sxth r3, r8, ror #8
|
||||
sxthle r2, r2, ror #16
|
||||
sxth r9, r3, ror #24
|
||||
|
||||
@ CHECK: sxthne r3, r9 @ encoding: [0x79,0x30,0xbf,0x16]
|
||||
@ CHECK: sxth r1, r6 @ encoding: [0x76,0x10,0xbf,0xe6]
|
||||
@ CHECK: sxth r3, r8, ror #8
|
||||
@ encoding: [0x78,0x34,0xbf,0xe6]
|
||||
@ CHECK: sxthle r2, r2, ror #16
|
||||
@ encoding: [0x72,0x28,0xbf,0xd6]
|
||||
@ CHECK: sxth r9, r3, ror #24
|
||||
@ encoding: [0x73,0x9c,0xbf,0xe6]
|
||||
|
|
|
@ -238,3 +238,37 @@
|
|||
@ CHECK-ERRORS: error: source operands must be sequential
|
||||
@ CHECK-ERRORS: strexd r6, r5, r3, [r8]
|
||||
@ CHECK-ERRORS: ^
|
||||
|
||||
@ Illegal rotate operators for extend instructions
|
||||
sxtb r8, r3, #8
|
||||
sxtb r8, r3, ror 24
|
||||
sxtb r8, r3, ror #8 -
|
||||
sxtab r3, r8, r3, ror #(fred - wilma)
|
||||
sxtab r7, r8, r3, ror #25
|
||||
sxtah r9, r3, r3, ror #-8
|
||||
sxtb16ge r2, r3, lsr #24
|
||||
|
||||
@ CHECK-ERRORS: error: rotate operator 'ror' expected
|
||||
@ CHECK-ERRORS: sxtb r8, r3, #8
|
||||
@ CHECK-ERRORS: ^
|
||||
@ CHECK-ERRORS: error: '#' expected
|
||||
@ CHECK-ERRORS: sxtb r8, r3, ror 24
|
||||
@ CHECK-ERRORS: ^
|
||||
@ CHECK-ERRORS: error: unknown token in expression
|
||||
@ CHECK-ERRORS: sxtb r8, r3, ror #8 -
|
||||
@ CHECK-ERRORS: ^
|
||||
@ CHECK-ERRORS: error: malformed rotate expression
|
||||
@ CHECK-ERRORS: sxtb r8, r3, ror #8 -
|
||||
@ CHECK-ERRORS: ^
|
||||
@ CHECK-ERRORS: error: rotate amount must be an immediate
|
||||
@ CHECK-ERRORS: sxtab r3, r8, r3, ror #(fred - wilma)
|
||||
@ CHECK-ERRORS: ^
|
||||
@ CHECK-ERRORS: error: 'ror' rotate amount must be 8, 16, or 24
|
||||
@ CHECK-ERRORS: sxtab r7, r8, r3, ror #25
|
||||
@ CHECK-ERRORS: ^
|
||||
@ CHECK-ERRORS: error: 'ror' rotate amount must be 8, 16, or 24
|
||||
@ CHECK-ERRORS: sxtah r9, r3, r3, ror #-8
|
||||
@ CHECK-ERRORS: ^
|
||||
@ CHECK-ERRORS: error: rotate operator 'ror' expected
|
||||
@ CHECK-ERRORS: sxtb16ge r2, r3, lsr #24
|
||||
@ CHECK-ERRORS: ^
|
||||
|
|
Loading…
Reference in New Issue