mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 16:33:28 +00:00
ARM LDRD(register) assembly parsing and encoding.
Add support for literal encoding of #-0 along the way. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137254 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b549bcfe6c
commit
251bf25e7e
@ -722,7 +722,10 @@ def addrmode3 : Operand<i32>,
|
||||
|
||||
// FIXME: split into imm vs. reg versions.
|
||||
// FIXME: parser method to handle +/- register.
|
||||
def AM3OffsetAsmOperand : AsmOperandClass { let Name = "AM3Offset"; }
|
||||
def AM3OffsetAsmOperand : AsmOperandClass {
|
||||
let Name = "AM3Offset";
|
||||
let ParserMethod = "parseAM3Offset";
|
||||
}
|
||||
def am3offset : Operand<i32>,
|
||||
ComplexPattern<i32, 2, "SelectAddrMode3Offset",
|
||||
[], [SDNPWantRoot]> {
|
||||
|
@ -114,6 +114,7 @@ class ARMAsmParser : public MCTargetAsmParser {
|
||||
OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
|
||||
OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
|
||||
OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
|
||||
OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
|
||||
|
||||
// Asm Match Converter Methods
|
||||
bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
|
||||
@ -557,7 +558,8 @@ public:
|
||||
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
|
||||
if (!CE) return false;
|
||||
int64_t Val = CE->getValue();
|
||||
return Val > -256 && Val < 256;
|
||||
// Special case, #-0 is INT32_MIN.
|
||||
return (Val > -256 && Val < 256) || Val == INT32_MIN;
|
||||
}
|
||||
bool isAddrMode5() const {
|
||||
if (Kind != Memory)
|
||||
@ -865,6 +867,7 @@ public:
|
||||
ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
|
||||
Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
|
||||
Inst.addOperand(MCOperand::CreateImm(Val));
|
||||
return;
|
||||
}
|
||||
|
||||
// Constant offset.
|
||||
@ -874,7 +877,7 @@ public:
|
||||
// Special case for #-0
|
||||
if (Val == INT32_MIN) Val = 0;
|
||||
if (Val < 0) Val = -Val;
|
||||
Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
|
||||
Val = ARM_AM::getAM3Opc(AddSub, Val);
|
||||
Inst.addOperand(MCOperand::CreateReg(0));
|
||||
Inst.addOperand(MCOperand::CreateImm(Val));
|
||||
}
|
||||
@ -2007,6 +2010,76 @@ parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
ARMAsmParser::OperandMatchResultTy ARMAsmParser::
|
||||
parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
// Check for a post-index addressing register operand. Specifically:
|
||||
// am3offset := '+' register
|
||||
// | '-' register
|
||||
// | register
|
||||
// | # imm
|
||||
// | # + imm
|
||||
// | # - imm
|
||||
|
||||
// This method must return MatchOperand_NoMatch without consuming any tokens
|
||||
// in the case where there is no match, as other alternatives take other
|
||||
// parse methods.
|
||||
AsmToken Tok = Parser.getTok();
|
||||
SMLoc S = Tok.getLoc();
|
||||
|
||||
// Do immediates first, as we always parse those if we have a '#'.
|
||||
if (Parser.getTok().is(AsmToken::Hash)) {
|
||||
Parser.Lex(); // Eat the '#'.
|
||||
// Explicitly look for a '-', as we need to encode negative zero
|
||||
// differently.
|
||||
bool isNegative = Parser.getTok().is(AsmToken::Minus);
|
||||
const MCExpr *Offset;
|
||||
if (getParser().ParseExpression(Offset))
|
||||
return MatchOperand_ParseFail;
|
||||
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
|
||||
if (!CE) {
|
||||
Error(S, "constant expression expected");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
SMLoc E = Tok.getLoc();
|
||||
// Negative zero is encoded as the flag value INT32_MIN.
|
||||
int32_t Val = CE->getValue();
|
||||
if (isNegative && Val == 0)
|
||||
Val = INT32_MIN;
|
||||
|
||||
Operands.push_back(
|
||||
ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
|
||||
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
|
||||
bool haveEaten = false;
|
||||
bool isAdd = true;
|
||||
int Reg = -1;
|
||||
if (Tok.is(AsmToken::Plus)) {
|
||||
Parser.Lex(); // Eat the '+' token.
|
||||
haveEaten = true;
|
||||
} else if (Tok.is(AsmToken::Minus)) {
|
||||
Parser.Lex(); // Eat the '-' token.
|
||||
isAdd = false;
|
||||
haveEaten = true;
|
||||
}
|
||||
if (Parser.getTok().is(AsmToken::Identifier))
|
||||
Reg = tryParseRegister();
|
||||
if (Reg == -1) {
|
||||
if (!haveEaten)
|
||||
return MatchOperand_NoMatch;
|
||||
Error(Parser.getTok().getLoc(), "register expected");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
SMLoc E = Parser.getTok().getLoc();
|
||||
|
||||
Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
|
||||
0, 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.
|
||||
|
@ -114,8 +114,28 @@ _func:
|
||||
ldrd r7, r8, [r2, #15]
|
||||
ldrd r1, r2, [r9, #32]!
|
||||
ldrd r6, r7, [r1], #8
|
||||
ldrd r1, r2, [r8], #0
|
||||
ldrd r1, r2, [r8], #+0
|
||||
ldrd r1, r2, [r8], #-0
|
||||
|
||||
@ CHECK: ldrd r3, r4, [r5] @ encoding: [0xd0,0x30,0xc5,0xe1]
|
||||
@ CHECK: ldrd r7, r8, [r2, #15] @ encoding: [0xdf,0x70,0xc2,0xe1]
|
||||
@ CHECK: ldrd r1, r2, [r9, #32]! @ encoding: [0xd0,0x12,0xe9,0xe1]
|
||||
@ CHECK: ldrd r6, r7, [r1], #8 @ encoding: [0xd8,0x60,0xc1,0xe0]
|
||||
@ CHECK: ldrd r1, r2, [r8], #0 @ encoding: [0xd0,0x10,0xc8,0xe0]
|
||||
@ CHECK: ldrd r1, r2, [r8], #0 @ encoding: [0xd0,0x10,0xc8,0xe0]
|
||||
@ CHECK: ldrd r1, r2, [r8], #-0 @ encoding: [0xd0,0x10,0x48,0xe0]
|
||||
|
||||
|
||||
@------------------------------------------------------------------------------
|
||||
@ LDRD (register)
|
||||
@------------------------------------------------------------------------------
|
||||
ldrd r3, r4, [r1, r3]
|
||||
ldrd r4, r5, [r7, r2]!
|
||||
ldrd r1, r2, [r8], r12
|
||||
ldrd r1, r2, [r8], -r12
|
||||
|
||||
ldrd r3, r4, [r1, r3] @ encoding: [0xd3,0x30,0x81,0xe1]
|
||||
ldrd r4, r5, [r7, r2]! @ encoding: [0xd2,0x40,0xa7,0xe1]
|
||||
ldrd r1, r2, [r8], r12 @ encoding: [0xdc,0x10,0x88,0xe0]
|
||||
ldrd r1, r2, [r8], -r12 @ encoding: [0xdc,0x10,0x08,0xe0]
|
||||
|
Loading…
x
Reference in New Issue
Block a user