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);
|
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), [{
|
def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
|
||||||
int32_t v = N->getZExtValue();
|
int32_t v = N->getZExtValue();
|
||||||
return v == 8 || v == 16 || v == 24; }],
|
return v == 8 || v == 16 || v == 24; }],
|
||||||
rot_imm_XFORM> {
|
rot_imm_XFORM> {
|
||||||
let PrintMethod = "printRotImmOperand";
|
let PrintMethod = "printRotImmOperand";
|
||||||
|
let ParserMatchClass = RotImmAsmOperand;
|
||||||
}
|
}
|
||||||
|
|
||||||
// shift_imm: An integer that encodes a shift amount and the type of shift
|
// 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 parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
|
||||||
OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
|
OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
|
||||||
|
OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
|
||||||
|
|
||||||
// Asm Match Converter Methods
|
// Asm Match Converter Methods
|
||||||
bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
|
bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
|
||||||
|
@ -187,6 +188,7 @@ class ARMOperand : public MCParsedAsmOperand {
|
||||||
ShiftedRegister,
|
ShiftedRegister,
|
||||||
ShiftedImmediate,
|
ShiftedImmediate,
|
||||||
ShifterImmediate,
|
ShifterImmediate,
|
||||||
|
RotateImmediate,
|
||||||
Token
|
Token
|
||||||
} Kind;
|
} Kind;
|
||||||
|
|
||||||
|
@ -260,6 +262,9 @@ class ARMOperand : public MCParsedAsmOperand {
|
||||||
unsigned SrcReg;
|
unsigned SrcReg;
|
||||||
unsigned ShiftImm;
|
unsigned ShiftImm;
|
||||||
} RegShiftedImm;
|
} RegShiftedImm;
|
||||||
|
struct {
|
||||||
|
unsigned Imm;
|
||||||
|
} RotImm;
|
||||||
};
|
};
|
||||||
|
|
||||||
ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
|
ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
|
||||||
|
@ -312,6 +317,9 @@ public:
|
||||||
case ShiftedImmediate:
|
case ShiftedImmediate:
|
||||||
RegShiftedImm = o.RegShiftedImm;
|
RegShiftedImm = o.RegShiftedImm;
|
||||||
break;
|
break;
|
||||||
|
case RotateImmediate:
|
||||||
|
RotImm = o.RotImm;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,6 +539,7 @@ public:
|
||||||
bool isShifterImm() const { return Kind == ShifterImmediate; }
|
bool isShifterImm() const { return Kind == ShifterImmediate; }
|
||||||
bool isRegShiftedReg() const { return Kind == ShiftedRegister; }
|
bool isRegShiftedReg() const { return Kind == ShiftedRegister; }
|
||||||
bool isRegShiftedImm() const { return Kind == ShiftedImmediate; }
|
bool isRegShiftedImm() const { return Kind == ShiftedImmediate; }
|
||||||
|
bool isRotImm() const { return Kind == RotateImmediate; }
|
||||||
bool isMemMode2() const {
|
bool isMemMode2() const {
|
||||||
if (getMemAddrMode() != ARMII::AddrMode2)
|
if (getMemAddrMode() != ARMII::AddrMode2)
|
||||||
return false;
|
return false;
|
||||||
|
@ -701,6 +710,12 @@ public:
|
||||||
addRegListOperands(Inst, N);
|
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 {
|
void addImmOperands(MCInst &Inst, unsigned N) const {
|
||||||
assert(N == 1 && "Invalid number of operands!");
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
addExpr(Inst, getImm());
|
addExpr(Inst, getImm());
|
||||||
|
@ -1008,6 +1023,14 @@ public:
|
||||||
return Op;
|
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 *
|
static ARMOperand *
|
||||||
CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
|
CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
|
||||||
SMLoc StartLoc, SMLoc EndLoc) {
|
SMLoc StartLoc, SMLoc EndLoc) {
|
||||||
|
@ -1183,6 +1206,9 @@ void ARMOperand::print(raw_ostream &OS) const {
|
||||||
<< ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm)
|
<< ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm)
|
||||||
<< ">";
|
<< ">";
|
||||||
break;
|
break;
|
||||||
|
case RotateImmediate:
|
||||||
|
OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
|
||||||
|
break;
|
||||||
case RegisterList:
|
case RegisterList:
|
||||||
case DPRRegisterList:
|
case DPRRegisterList:
|
||||||
case SPRRegisterList: {
|
case SPRRegisterList: {
|
||||||
|
@ -1810,6 +1836,58 @@ parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
return MatchOperand_Success;
|
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.
|
/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
|
||||||
/// Needed here because the Asm Gen Matcher can't handle properly tied operands
|
/// Needed here because the Asm Gen Matcher can't handle properly tied operands
|
||||||
/// when they refer multiple MIOperands inside a single one.
|
/// 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 r1, r2, [r3] @ encoding: [0x92,0x10,0x03,0xe1]
|
||||||
@ CHECK: swp r4, r4, [r6] @ encoding: [0x94,0x40,0x06,0xe1]
|
@ CHECK: swp r4, r4, [r6] @ encoding: [0x94,0x40,0x06,0xe1]
|
||||||
@ CHECK: swpb r5, r1, [r9] @ encoding: [0x91,0x50,0x49,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: error: source operands must be sequential
|
||||||
@ CHECK-ERRORS: strexd r6, r5, r3, [r8]
|
@ CHECK-ERRORS: strexd r6, r5, r3, [r8]
|
||||||
@ CHECK-ERRORS: ^
|
@ 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