mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-27 14:24:40 +00:00
MIR Serialization: Serialize the null register operands.
This commit serializes the null register machine operands. It uses the '_' keyword to represent them, but the parser also allows the '%noreg' named register syntax. Reviewers: Duncan P. N. Exon Smith Differential Revision: http://reviews.llvm.org/D10580 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240558 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -64,7 +64,9 @@ static Cursor lexIdentifier(Cursor C, MIToken &Token) {
|
|||||||
auto Range = C;
|
auto Range = C;
|
||||||
while (isIdentifierChar(C.peek()))
|
while (isIdentifierChar(C.peek()))
|
||||||
C.advance();
|
C.advance();
|
||||||
Token = MIToken(MIToken::Identifier, Range.upto(C));
|
auto Identifier = Range.upto(C);
|
||||||
|
Token = MIToken(Identifier == "_" ? MIToken::underscore : MIToken::Identifier,
|
||||||
|
Identifier);
|
||||||
return C;
|
return C;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ struct MIToken {
|
|||||||
// Tokens with no info.
|
// Tokens with no info.
|
||||||
comma,
|
comma,
|
||||||
equal,
|
equal,
|
||||||
|
underscore,
|
||||||
|
|
||||||
// Identifier tokens
|
// Identifier tokens
|
||||||
Identifier,
|
Identifier,
|
||||||
@ -58,7 +59,9 @@ public:
|
|||||||
|
|
||||||
bool isError() const { return Kind == Error; }
|
bool isError() const { return Kind == Error; }
|
||||||
|
|
||||||
bool isRegister() const { return Kind == NamedRegister; }
|
bool isRegister() const {
|
||||||
|
return Kind == NamedRegister || Kind == underscore;
|
||||||
|
}
|
||||||
|
|
||||||
bool is(TokenKind K) const { return Kind == K; }
|
bool is(TokenKind K) const { return Kind == K; }
|
||||||
|
|
||||||
|
@ -174,6 +174,9 @@ bool MIParser::parseInstruction(unsigned &OpCode) {
|
|||||||
|
|
||||||
bool MIParser::parseRegister(unsigned &Reg) {
|
bool MIParser::parseRegister(unsigned &Reg) {
|
||||||
switch (Token.kind()) {
|
switch (Token.kind()) {
|
||||||
|
case MIToken::underscore:
|
||||||
|
Reg = 0;
|
||||||
|
break;
|
||||||
case MIToken::NamedRegister: {
|
case MIToken::NamedRegister: {
|
||||||
StringRef Name = Token.stringValue().drop_front(1); // Drop the '%'
|
StringRef Name = Token.stringValue().drop_front(1); // Drop the '%'
|
||||||
if (getRegisterByName(Name, Reg))
|
if (getRegisterByName(Name, Reg))
|
||||||
@ -211,6 +214,7 @@ bool MIParser::parseImmediateOperand(MachineOperand &Dest) {
|
|||||||
|
|
||||||
bool MIParser::parseMachineOperand(MachineOperand &Dest) {
|
bool MIParser::parseMachineOperand(MachineOperand &Dest) {
|
||||||
switch (Token.kind()) {
|
switch (Token.kind()) {
|
||||||
|
case MIToken::underscore:
|
||||||
case MIToken::NamedRegister:
|
case MIToken::NamedRegister:
|
||||||
return parseRegisterOperand(Dest);
|
return parseRegisterOperand(Dest);
|
||||||
case MIToken::IntegerLiteral:
|
case MIToken::IntegerLiteral:
|
||||||
@ -245,6 +249,8 @@ bool MIParser::parseInstrName(StringRef InstrName, unsigned &OpCode) {
|
|||||||
void MIParser::initNames2Regs() {
|
void MIParser::initNames2Regs() {
|
||||||
if (!Names2Regs.empty())
|
if (!Names2Regs.empty())
|
||||||
return;
|
return;
|
||||||
|
// The '%noreg' register is the register 0.
|
||||||
|
Names2Regs.insert(std::make_pair("noreg", 0));
|
||||||
const auto *TRI = MF.getSubtarget().getRegisterInfo();
|
const auto *TRI = MF.getSubtarget().getRegisterInfo();
|
||||||
assert(TRI && "Expected target register info");
|
assert(TRI && "Expected target register info");
|
||||||
for (unsigned I = 0, E = TRI->getNumRegs(); I < E; ++I) {
|
for (unsigned I = 0, E = TRI->getNumRegs(); I < E; ++I) {
|
||||||
|
@ -144,9 +144,10 @@ void MIPrinter::print(const MachineInstr &MI) {
|
|||||||
static void printReg(unsigned Reg, raw_ostream &OS,
|
static void printReg(unsigned Reg, raw_ostream &OS,
|
||||||
const TargetRegisterInfo *TRI) {
|
const TargetRegisterInfo *TRI) {
|
||||||
// TODO: Print Stack Slots.
|
// TODO: Print Stack Slots.
|
||||||
// TODO: Print no register.
|
|
||||||
// TODO: Print virtual registers.
|
// TODO: Print virtual registers.
|
||||||
if (Reg < TRI->getNumRegs())
|
if (!Reg)
|
||||||
|
OS << '_';
|
||||||
|
else if (Reg < TRI->getNumRegs())
|
||||||
OS << '%' << StringRef(TRI->getName(Reg)).lower();
|
OS << '%' << StringRef(TRI->getName(Reg)).lower();
|
||||||
else
|
else
|
||||||
llvm_unreachable("Can't print this kind of register yet");
|
llvm_unreachable("Can't print this kind of register yet");
|
||||||
|
23
test/CodeGen/MIR/X86/null-register-operands.mir
Normal file
23
test/CodeGen/MIR/X86/null-register-operands.mir
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# RUN: llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s | FileCheck %s
|
||||||
|
# This test ensures that the MIR parser parses null register operands correctly.
|
||||||
|
|
||||||
|
--- |
|
||||||
|
|
||||||
|
define i32 @deref(i32* %p) {
|
||||||
|
entry:
|
||||||
|
%a = load i32, i32* %p
|
||||||
|
ret i32 %a
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
# CHECK: name: deref
|
||||||
|
name: deref
|
||||||
|
body:
|
||||||
|
- name: entry
|
||||||
|
instructions:
|
||||||
|
# CHECK: - '%eax = MOV32rm %rdi, 1, _, 0, _'
|
||||||
|
# CHECK-NEXT: - 'RETQ %eax'
|
||||||
|
- '%eax = MOV32rm %rdi, 1, _, 0, %noreg'
|
||||||
|
- 'RETQ %eax'
|
||||||
|
...
|
Reference in New Issue
Block a user