mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 17:32:19 +00:00
[PowerPC] Add asm parser support for CR expressions
This adds support for specifying condition registers and condition register fields via expressions using the symbols defined by the PowerISA, like "4*cr2+eq". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185633 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
32d15d90c4
commit
5606fcae50
@ -107,6 +107,67 @@ static unsigned CRRegs[8] = {
|
||||
PPC::CR4, PPC::CR5, PPC::CR6, PPC::CR7
|
||||
};
|
||||
|
||||
// Evaluate an expression containing condition register
|
||||
// or condition register field symbols. Returns positive
|
||||
// value on success, or -1 on error.
|
||||
static int64_t
|
||||
EvaluateCRExpr(const MCExpr *E) {
|
||||
switch (E->getKind()) {
|
||||
case MCExpr::Target:
|
||||
return -1;
|
||||
|
||||
case MCExpr::Constant: {
|
||||
int64_t Res = cast<MCConstantExpr>(E)->getValue();
|
||||
return Res < 0 ? -1 : Res;
|
||||
}
|
||||
|
||||
case MCExpr::SymbolRef: {
|
||||
const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
|
||||
StringRef Name = SRE->getSymbol().getName();
|
||||
|
||||
if (Name == "lt") return 0;
|
||||
if (Name == "gt") return 1;
|
||||
if (Name == "eq") return 2;
|
||||
if (Name == "so") return 3;
|
||||
if (Name == "un") return 3;
|
||||
|
||||
if (Name == "cr0") return 0;
|
||||
if (Name == "cr1") return 1;
|
||||
if (Name == "cr2") return 2;
|
||||
if (Name == "cr3") return 3;
|
||||
if (Name == "cr4") return 4;
|
||||
if (Name == "cr5") return 5;
|
||||
if (Name == "cr6") return 6;
|
||||
if (Name == "cr7") return 7;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
case MCExpr::Unary:
|
||||
return -1;
|
||||
|
||||
case MCExpr::Binary: {
|
||||
const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
|
||||
int64_t LHSVal = EvaluateCRExpr(BE->getLHS());
|
||||
int64_t RHSVal = EvaluateCRExpr(BE->getRHS());
|
||||
int64_t Res;
|
||||
|
||||
if (LHSVal < 0 || RHSVal < 0)
|
||||
return -1;
|
||||
|
||||
switch (BE->getOpcode()) {
|
||||
default: return -1;
|
||||
case MCBinaryExpr::Add: Res = LHSVal + RHSVal; break;
|
||||
case MCBinaryExpr::Mul: Res = LHSVal * RHSVal; break;
|
||||
}
|
||||
|
||||
return Res < 0 ? -1 : Res;
|
||||
}
|
||||
}
|
||||
|
||||
llvm_unreachable("Invalid expression kind!");
|
||||
}
|
||||
|
||||
struct PPCOperand;
|
||||
|
||||
class PPCAsmParser : public MCTargetAsmParser {
|
||||
@ -193,6 +254,7 @@ struct PPCOperand : public MCParsedAsmOperand {
|
||||
|
||||
struct ExprOp {
|
||||
const MCExpr *Val;
|
||||
int64_t CRVal; // Cached result of EvaluateCRExpr(Val)
|
||||
};
|
||||
|
||||
union {
|
||||
@ -240,6 +302,11 @@ public:
|
||||
return Expr.Val;
|
||||
}
|
||||
|
||||
int64_t getExprCRVal() const {
|
||||
assert(Kind == Expression && "Invalid access!");
|
||||
return Expr.CRVal;
|
||||
}
|
||||
|
||||
unsigned getReg() const {
|
||||
assert(isRegNumber() && "Invalid access!");
|
||||
return (unsigned) Imm.Val;
|
||||
@ -247,7 +314,12 @@ public:
|
||||
|
||||
unsigned getCCReg() const {
|
||||
assert(isCCRegNumber() && "Invalid access!");
|
||||
return (unsigned) Imm.Val;
|
||||
return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
|
||||
}
|
||||
|
||||
unsigned getCRBit() const {
|
||||
assert(isCRBitNumber() && "Invalid access!");
|
||||
return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
|
||||
}
|
||||
|
||||
unsigned getCRBitMask() const {
|
||||
@ -276,8 +348,14 @@ public:
|
||||
(Kind == Immediate && isInt<16>(getImm()) &&
|
||||
(getImm() & 3) == 0); }
|
||||
bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); }
|
||||
bool isCCRegNumber() const { return Kind == Immediate &&
|
||||
isUInt<3>(getImm()); }
|
||||
bool isCCRegNumber() const { return (Kind == Expression
|
||||
&& isUInt<3>(getExprCRVal())) ||
|
||||
(Kind == Immediate
|
||||
&& isUInt<3>(getImm())); }
|
||||
bool isCRBitNumber() const { return (Kind == Expression
|
||||
&& isUInt<5>(getExprCRVal())) ||
|
||||
(Kind == Immediate
|
||||
&& isUInt<5>(getImm())); }
|
||||
bool isCRBitMask() const { return Kind == Immediate && isUInt<8>(getImm()) &&
|
||||
isPowerOf2_32(getImm()); }
|
||||
bool isMem() const { return false; }
|
||||
@ -338,7 +416,7 @@ public:
|
||||
|
||||
void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
Inst.addOperand(MCOperand::CreateReg(CRBITRegs[getReg()]));
|
||||
Inst.addOperand(MCOperand::CreateReg(CRBITRegs[getCRBit()]));
|
||||
}
|
||||
|
||||
void addRegCRRCOperands(MCInst &Inst, unsigned N) const {
|
||||
@ -397,6 +475,7 @@ public:
|
||||
SMLoc S, SMLoc E, bool IsPPC64) {
|
||||
PPCOperand *Op = new PPCOperand(Expression);
|
||||
Op->Expr.Val = Val;
|
||||
Op->Expr.CRVal = EvaluateCRExpr(Val);
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
Op->IsPPC64 = IsPPC64;
|
||||
|
@ -392,7 +392,7 @@ def vrrc : RegisterOperand<VRRC> {
|
||||
let ParserMatchClass = PPCRegVRRCAsmOperand;
|
||||
}
|
||||
def PPCRegCRBITRCAsmOperand : AsmOperandClass {
|
||||
let Name = "RegCRBITRC"; let PredicateMethod = "isRegNumber";
|
||||
let Name = "RegCRBITRC"; let PredicateMethod = "isCRBitNumber";
|
||||
}
|
||||
def crbitrc : RegisterOperand<CRBITRC> {
|
||||
let ParserMatchClass = PPCRegCRBITRCAsmOperand;
|
||||
|
@ -1,7 +1,105 @@
|
||||
|
||||
# RUN: llvm-mc -triple powerpc64-unknown-unknown --show-encoding %s | FileCheck %s
|
||||
|
||||
# FIXME: Condition register bit symbols
|
||||
# Condition register bit symbols
|
||||
|
||||
# CHECK: beqlr 0 # encoding: [0x4d,0x82,0x00,0x20]
|
||||
beqlr cr0
|
||||
# CHECK: beqlr 1 # encoding: [0x4d,0x86,0x00,0x20]
|
||||
beqlr cr1
|
||||
# CHECK: beqlr 2 # encoding: [0x4d,0x8a,0x00,0x20]
|
||||
beqlr cr2
|
||||
# CHECK: beqlr 3 # encoding: [0x4d,0x8e,0x00,0x20]
|
||||
beqlr cr3
|
||||
# CHECK: beqlr 4 # encoding: [0x4d,0x92,0x00,0x20]
|
||||
beqlr cr4
|
||||
# CHECK: beqlr 5 # encoding: [0x4d,0x96,0x00,0x20]
|
||||
beqlr cr5
|
||||
# CHECK: beqlr 6 # encoding: [0x4d,0x9a,0x00,0x20]
|
||||
beqlr cr6
|
||||
# CHECK: beqlr 7 # encoding: [0x4d,0x9e,0x00,0x20]
|
||||
beqlr cr7
|
||||
|
||||
# CHECK: bclr 12, 0, 0 # encoding: [0x4d,0x80,0x00,0x20]
|
||||
btlr 4*cr0+lt
|
||||
# CHECK: bclr 12, 1, 0 # encoding: [0x4d,0x81,0x00,0x20]
|
||||
btlr 4*cr0+gt
|
||||
# CHECK: bclr 12, 2, 0 # encoding: [0x4d,0x82,0x00,0x20]
|
||||
btlr 4*cr0+eq
|
||||
# CHECK: bclr 12, 3, 0 # encoding: [0x4d,0x83,0x00,0x20]
|
||||
btlr 4*cr0+so
|
||||
# CHECK: bclr 12, 3, 0 # encoding: [0x4d,0x83,0x00,0x20]
|
||||
btlr 4*cr0+un
|
||||
# CHECK: bclr 12, 4, 0 # encoding: [0x4d,0x84,0x00,0x20]
|
||||
btlr 4*cr1+lt
|
||||
# CHECK: bclr 12, 5, 0 # encoding: [0x4d,0x85,0x00,0x20]
|
||||
btlr 4*cr1+gt
|
||||
# CHECK: bclr 12, 6, 0 # encoding: [0x4d,0x86,0x00,0x20]
|
||||
btlr 4*cr1+eq
|
||||
# CHECK: bclr 12, 7, 0 # encoding: [0x4d,0x87,0x00,0x20]
|
||||
btlr 4*cr1+so
|
||||
# CHECK: bclr 12, 7, 0 # encoding: [0x4d,0x87,0x00,0x20]
|
||||
btlr 4*cr1+un
|
||||
# CHECK: bclr 12, 8, 0 # encoding: [0x4d,0x88,0x00,0x20]
|
||||
btlr 4*cr2+lt
|
||||
# CHECK: bclr 12, 9, 0 # encoding: [0x4d,0x89,0x00,0x20]
|
||||
btlr 4*cr2+gt
|
||||
# CHECK: bclr 12, 10, 0 # encoding: [0x4d,0x8a,0x00,0x20]
|
||||
btlr 4*cr2+eq
|
||||
# CHECK: bclr 12, 11, 0 # encoding: [0x4d,0x8b,0x00,0x20]
|
||||
btlr 4*cr2+so
|
||||
# CHECK: bclr 12, 11, 0 # encoding: [0x4d,0x8b,0x00,0x20]
|
||||
btlr 4*cr2+un
|
||||
# CHECK: bclr 12, 12, 0 # encoding: [0x4d,0x8c,0x00,0x20]
|
||||
btlr 4*cr3+lt
|
||||
# CHECK: bclr 12, 13, 0 # encoding: [0x4d,0x8d,0x00,0x20]
|
||||
btlr 4*cr3+gt
|
||||
# CHECK: bclr 12, 14, 0 # encoding: [0x4d,0x8e,0x00,0x20]
|
||||
btlr 4*cr3+eq
|
||||
# CHECK: bclr 12, 15, 0 # encoding: [0x4d,0x8f,0x00,0x20]
|
||||
btlr 4*cr3+so
|
||||
# CHECK: bclr 12, 15, 0 # encoding: [0x4d,0x8f,0x00,0x20]
|
||||
btlr 4*cr3+un
|
||||
# CHECK: bclr 12, 16, 0 # encoding: [0x4d,0x90,0x00,0x20]
|
||||
btlr 4*cr4+lt
|
||||
# CHECK: bclr 12, 17, 0 # encoding: [0x4d,0x91,0x00,0x20]
|
||||
btlr 4*cr4+gt
|
||||
# CHECK: bclr 12, 18, 0 # encoding: [0x4d,0x92,0x00,0x20]
|
||||
btlr 4*cr4+eq
|
||||
# CHECK: bclr 12, 19, 0 # encoding: [0x4d,0x93,0x00,0x20]
|
||||
btlr 4*cr4+so
|
||||
# CHECK: bclr 12, 19, 0 # encoding: [0x4d,0x93,0x00,0x20]
|
||||
btlr 4*cr4+un
|
||||
# CHECK: bclr 12, 20, 0 # encoding: [0x4d,0x94,0x00,0x20]
|
||||
btlr 4*cr5+lt
|
||||
# CHECK: bclr 12, 21, 0 # encoding: [0x4d,0x95,0x00,0x20]
|
||||
btlr 4*cr5+gt
|
||||
# CHECK: bclr 12, 22, 0 # encoding: [0x4d,0x96,0x00,0x20]
|
||||
btlr 4*cr5+eq
|
||||
# CHECK: bclr 12, 23, 0 # encoding: [0x4d,0x97,0x00,0x20]
|
||||
btlr 4*cr5+so
|
||||
# CHECK: bclr 12, 23, 0 # encoding: [0x4d,0x97,0x00,0x20]
|
||||
btlr 4*cr5+un
|
||||
# CHECK: bclr 12, 24, 0 # encoding: [0x4d,0x98,0x00,0x20]
|
||||
btlr 4*cr6+lt
|
||||
# CHECK: bclr 12, 25, 0 # encoding: [0x4d,0x99,0x00,0x20]
|
||||
btlr 4*cr6+gt
|
||||
# CHECK: bclr 12, 26, 0 # encoding: [0x4d,0x9a,0x00,0x20]
|
||||
btlr 4*cr6+eq
|
||||
# CHECK: bclr 12, 27, 0 # encoding: [0x4d,0x9b,0x00,0x20]
|
||||
btlr 4*cr6+so
|
||||
# CHECK: bclr 12, 27, 0 # encoding: [0x4d,0x9b,0x00,0x20]
|
||||
btlr 4*cr6+un
|
||||
# CHECK: bclr 12, 28, 0 # encoding: [0x4d,0x9c,0x00,0x20]
|
||||
btlr 4*cr7+lt
|
||||
# CHECK: bclr 12, 29, 0 # encoding: [0x4d,0x9d,0x00,0x20]
|
||||
btlr 4*cr7+gt
|
||||
# CHECK: bclr 12, 30, 0 # encoding: [0x4d,0x9e,0x00,0x20]
|
||||
btlr 4*cr7+eq
|
||||
# CHECK: bclr 12, 31, 0 # encoding: [0x4d,0x9f,0x00,0x20]
|
||||
btlr 4*cr7+so
|
||||
# CHECK: bclr 12, 31, 0 # encoding: [0x4d,0x9f,0x00,0x20]
|
||||
btlr 4*cr7+un
|
||||
|
||||
# Branch mnemonics
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user