mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-11 00:39:36 +00:00
[ARM64] Conditionalize CPU specific system registers on subtarget features
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207742 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4c715625d9
commit
e29cd17aeb
@ -195,6 +195,9 @@ private:
|
||||
struct SysRegOp {
|
||||
const char *Data;
|
||||
unsigned Length;
|
||||
uint64_t FeatureBits; // We need to pass through information about which
|
||||
// core we are compiling for so that the SysReg
|
||||
// Mappers can appropriately conditionalize.
|
||||
};
|
||||
|
||||
struct SysCRImmOp {
|
||||
@ -351,6 +354,11 @@ public:
|
||||
return StringRef(SysReg.Data, SysReg.Length);
|
||||
}
|
||||
|
||||
uint64_t getSysRegFeatureBits() const {
|
||||
assert(Kind == k_SysReg && "Invalid access!");
|
||||
return SysReg.FeatureBits;
|
||||
}
|
||||
|
||||
unsigned getSysCR() const {
|
||||
assert(Kind == k_SysCR && "Invalid access!");
|
||||
return SysCRImm.Val;
|
||||
@ -668,7 +676,8 @@ public:
|
||||
if (!isSysReg()) return false;
|
||||
|
||||
bool IsKnownRegister;
|
||||
ARM64SysReg::MRSMapper().fromString(getSysReg(), IsKnownRegister);
|
||||
auto Mapper = ARM64SysReg::MRSMapper(getSysRegFeatureBits());
|
||||
Mapper.fromString(getSysReg(), IsKnownRegister);
|
||||
|
||||
return IsKnownRegister;
|
||||
}
|
||||
@ -676,7 +685,8 @@ public:
|
||||
if (!isSysReg()) return false;
|
||||
|
||||
bool IsKnownRegister;
|
||||
ARM64SysReg::MSRMapper().fromString(getSysReg(), IsKnownRegister);
|
||||
auto Mapper = ARM64SysReg::MSRMapper(getSysRegFeatureBits());
|
||||
Mapper.fromString(getSysReg(), IsKnownRegister);
|
||||
|
||||
return IsKnownRegister;
|
||||
}
|
||||
@ -1332,7 +1342,8 @@ public:
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
|
||||
bool Valid;
|
||||
uint32_t Bits = ARM64SysReg::MRSMapper().fromString(getSysReg(), Valid);
|
||||
auto Mapper = ARM64SysReg::MRSMapper(getSysRegFeatureBits());
|
||||
uint32_t Bits = Mapper.fromString(getSysReg(), Valid);
|
||||
|
||||
Inst.addOperand(MCOperand::CreateImm(Bits));
|
||||
}
|
||||
@ -1341,7 +1352,8 @@ public:
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
|
||||
bool Valid;
|
||||
uint32_t Bits = ARM64SysReg::MSRMapper().fromString(getSysReg(), Valid);
|
||||
auto Mapper = ARM64SysReg::MSRMapper(getSysRegFeatureBits());
|
||||
uint32_t Bits = Mapper.fromString(getSysReg(), Valid);
|
||||
|
||||
Inst.addOperand(MCOperand::CreateImm(Bits));
|
||||
}
|
||||
@ -1666,10 +1678,12 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static ARM64Operand *CreateSysReg(StringRef Str, SMLoc S, MCContext &Ctx) {
|
||||
static ARM64Operand *CreateSysReg(StringRef Str, SMLoc S,
|
||||
uint64_t FeatureBits, MCContext &Ctx) {
|
||||
ARM64Operand *Op = new ARM64Operand(k_SysReg, Ctx);
|
||||
Op->SysReg.Data = Str.data();
|
||||
Op->SysReg.Length = Str.size();
|
||||
Op->SysReg.FeatureBits = FeatureBits;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = S;
|
||||
return Op;
|
||||
@ -2682,7 +2696,7 @@ ARM64AsmParser::tryParseSysReg(OperandVector &Operands) {
|
||||
return MatchOperand_NoMatch;
|
||||
|
||||
Operands.push_back(ARM64Operand::CreateSysReg(Tok.getString(), getLoc(),
|
||||
getContext()));
|
||||
STI.getFeatureBits(), getContext()));
|
||||
Parser.Lex(); // Eat identifier
|
||||
|
||||
return MatchOperand_Success;
|
||||
|
@ -601,11 +601,15 @@ static DecodeStatus DecodePCRelLabel19(llvm::MCInst &Inst, unsigned Imm,
|
||||
static DecodeStatus DecodeMRSSystemRegister(llvm::MCInst &Inst, unsigned Imm,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
const ARM64Disassembler *Dis =
|
||||
static_cast<const ARM64Disassembler *>(Decoder);
|
||||
const MCSubtargetInfo &STI = Dis->getSubtargetInfo();
|
||||
|
||||
Imm |= 0x8000;
|
||||
Inst.addOperand(MCOperand::CreateImm(Imm));
|
||||
|
||||
bool ValidNamed;
|
||||
(void)ARM64SysReg::MRSMapper().toString(Imm, ValidNamed);
|
||||
(void)ARM64SysReg::MRSMapper(STI.getFeatureBits()).toString(Imm, ValidNamed);
|
||||
|
||||
return ValidNamed ? Success : Fail;
|
||||
}
|
||||
@ -613,11 +617,15 @@ static DecodeStatus DecodeMRSSystemRegister(llvm::MCInst &Inst, unsigned Imm,
|
||||
static DecodeStatus DecodeMSRSystemRegister(llvm::MCInst &Inst, unsigned Imm,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
const ARM64Disassembler *Dis =
|
||||
static_cast<const ARM64Disassembler *>(Decoder);
|
||||
const MCSubtargetInfo &STI = Dis->getSubtargetInfo();
|
||||
|
||||
Imm |= 0x8000;
|
||||
Inst.addOperand(MCOperand::CreateImm(Imm));
|
||||
|
||||
bool ValidNamed;
|
||||
(void)ARM64SysReg::MSRMapper().toString(Imm, ValidNamed);
|
||||
(void)ARM64SysReg::MSRMapper(STI.getFeatureBits()).toString(Imm, ValidNamed);
|
||||
|
||||
return ValidNamed ? Success : Fail;
|
||||
}
|
||||
|
@ -1397,7 +1397,7 @@ void ARM64InstPrinter::printMRSSystemRegister(const MCInst *MI, unsigned OpNo,
|
||||
unsigned Val = MI->getOperand(OpNo).getImm();
|
||||
|
||||
bool Valid;
|
||||
auto Mapper = ARM64SysReg::MRSMapper();
|
||||
auto Mapper = ARM64SysReg::MRSMapper(getAvailableFeatures());
|
||||
std::string Name = Mapper.toString(Val, Valid);
|
||||
|
||||
if (Valid)
|
||||
@ -1409,7 +1409,7 @@ void ARM64InstPrinter::printMSRSystemRegister(const MCInst *MI, unsigned OpNo,
|
||||
unsigned Val = MI->getOperand(OpNo).getImm();
|
||||
|
||||
bool Valid;
|
||||
auto Mapper = ARM64SysReg::MSRMapper();
|
||||
auto Mapper = ARM64SysReg::MSRMapper(getAvailableFeatures());
|
||||
std::string Name = Mapper.toString(Val, Valid);
|
||||
|
||||
if (Valid)
|
||||
|
@ -245,7 +245,8 @@ const ARM64NamedImmMapper::Mapping ARM64SysReg::MRSMapper::MRSPairs[] = {
|
||||
{"ich_elsr_el2", ICH_ELSR_EL2}
|
||||
};
|
||||
|
||||
ARM64SysReg::MRSMapper::MRSMapper() {
|
||||
ARM64SysReg::MRSMapper::MRSMapper(uint64_t FeatureBits)
|
||||
: SysRegMapper(FeatureBits) {
|
||||
InstPairs = &MRSPairs[0];
|
||||
NumInstPairs = llvm::array_lengthof(MRSPairs);
|
||||
}
|
||||
@ -268,7 +269,8 @@ const ARM64NamedImmMapper::Mapping ARM64SysReg::MSRMapper::MSRPairs[] = {
|
||||
{"icc_sgi0r_el1", ICC_SGI0R_EL1}
|
||||
};
|
||||
|
||||
ARM64SysReg::MSRMapper::MSRMapper() {
|
||||
ARM64SysReg::MSRMapper::MSRMapper(uint64_t FeatureBits)
|
||||
: SysRegMapper(FeatureBits) {
|
||||
InstPairs = &MSRPairs[0];
|
||||
NumInstPairs = llvm::array_lengthof(MSRPairs);
|
||||
}
|
||||
@ -750,14 +752,19 @@ const ARM64NamedImmMapper::Mapping ARM64SysReg::SysRegMapper::SysRegPairs[] = {
|
||||
{"ich_lr12_el2", ICH_LR12_EL2},
|
||||
{"ich_lr13_el2", ICH_LR13_EL2},
|
||||
{"ich_lr14_el2", ICH_LR14_EL2},
|
||||
{"ich_lr15_el2", ICH_LR15_EL2},
|
||||
{"ich_lr15_el2", ICH_LR15_EL2}
|
||||
};
|
||||
|
||||
const ARM64NamedImmMapper::Mapping
|
||||
ARM64SysReg::SysRegMapper::CycloneSysRegPairs[] = {
|
||||
{"cpm_ioacc_ctl_el3", CPM_IOACC_CTL_EL3}
|
||||
};
|
||||
|
||||
uint32_t
|
||||
ARM64SysReg::SysRegMapper::fromString(StringRef Name, bool &Valid) const {
|
||||
// First search the registers shared by all
|
||||
std::string NameLower = Name.lower();
|
||||
|
||||
// First search the registers shared by all
|
||||
for (unsigned i = 0; i < array_lengthof(SysRegPairs); ++i) {
|
||||
if (SysRegPairs[i].Name == NameLower) {
|
||||
Valid = true;
|
||||
@ -765,6 +772,16 @@ ARM64SysReg::SysRegMapper::fromString(StringRef Name, bool &Valid) const {
|
||||
}
|
||||
}
|
||||
|
||||
// Next search for target specific registers
|
||||
if (FeatureBits & ARM64::ProcCyclone) {
|
||||
for (unsigned i = 0; i < array_lengthof(CycloneSysRegPairs); ++i) {
|
||||
if (CycloneSysRegPairs[i].Name == NameLower) {
|
||||
Valid = true;
|
||||
return CycloneSysRegPairs[i].Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now try the instruction-specific registers (either read-only or
|
||||
// write-only).
|
||||
for (unsigned i = 0; i < NumInstPairs; ++i) {
|
||||
@ -798,6 +815,7 @@ ARM64SysReg::SysRegMapper::fromString(StringRef Name, bool &Valid) const {
|
||||
|
||||
std::string
|
||||
ARM64SysReg::SysRegMapper::toString(uint32_t Bits, bool &Valid) const {
|
||||
// First search the registers shared by all
|
||||
for (unsigned i = 0; i < array_lengthof(SysRegPairs); ++i) {
|
||||
if (SysRegPairs[i].Value == Bits) {
|
||||
Valid = true;
|
||||
@ -805,6 +823,18 @@ ARM64SysReg::SysRegMapper::toString(uint32_t Bits, bool &Valid) const {
|
||||
}
|
||||
}
|
||||
|
||||
// Next search for target specific registers
|
||||
if (FeatureBits & ARM64::ProcCyclone) {
|
||||
for (unsigned i = 0; i < array_lengthof(CycloneSysRegPairs); ++i) {
|
||||
if (CycloneSysRegPairs[i].Value == Bits) {
|
||||
Valid = true;
|
||||
return CycloneSysRegPairs[i].Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now try the instruction-specific registers (either read-only or
|
||||
// write-only).
|
||||
for (unsigned i = 0; i < NumInstPairs; ++i) {
|
||||
if (InstPairs[i].Value == Bits) {
|
||||
Valid = true;
|
||||
|
@ -1136,8 +1136,10 @@ namespace ARM64SysReg {
|
||||
ICH_LR13_EL2 = 0xe66d, // 11 100 1100 1101 101
|
||||
ICH_LR14_EL2 = 0xe66e, // 11 100 1100 1101 110
|
||||
ICH_LR15_EL2 = 0xe66f, // 11 100 1100 1101 111
|
||||
};
|
||||
|
||||
// Cyclone specific system registers
|
||||
// Cyclone specific system registers
|
||||
enum CycloneSysRegValues {
|
||||
CPM_IOACC_CTL_EL3 = 0xff90
|
||||
};
|
||||
|
||||
@ -1147,23 +1149,25 @@ namespace ARM64SysReg {
|
||||
// this one case.
|
||||
struct SysRegMapper {
|
||||
static const ARM64NamedImmMapper::Mapping SysRegPairs[];
|
||||
static const ARM64NamedImmMapper::Mapping CycloneSysRegPairs[];
|
||||
|
||||
const ARM64NamedImmMapper::Mapping *InstPairs;
|
||||
size_t NumInstPairs;
|
||||
uint64_t FeatureBits;
|
||||
|
||||
SysRegMapper() {}
|
||||
SysRegMapper(uint64_t FeatureBits) : FeatureBits(FeatureBits) { }
|
||||
uint32_t fromString(StringRef Name, bool &Valid) const;
|
||||
std::string toString(uint32_t Bits, bool &Valid) const;
|
||||
};
|
||||
|
||||
struct MSRMapper : SysRegMapper {
|
||||
static const ARM64NamedImmMapper::Mapping MSRPairs[];
|
||||
MSRMapper();
|
||||
MSRMapper(uint64_t FeatureBits);
|
||||
};
|
||||
|
||||
struct MRSMapper : SysRegMapper {
|
||||
static const ARM64NamedImmMapper::Mapping MRSPairs[];
|
||||
MRSMapper();
|
||||
MRSMapper(uint64_t FeatureBits);
|
||||
};
|
||||
|
||||
uint32_t ParseGenericRegister(StringRef Name, bool &Valid);
|
||||
|
@ -586,14 +586,12 @@ foo:
|
||||
msr RMR_EL3, x0
|
||||
msr RMR_EL2, x0
|
||||
msr RMR_EL1, x0
|
||||
msr CPM_IOACC_CTL_EL3, x0
|
||||
msr OSLAR_EL1, x3
|
||||
msr DBGDTRTX_EL0, x3
|
||||
|
||||
; CHECK: msr RMR_EL3, x0 ; encoding: [0x40,0xc0,0x1e,0xd5]
|
||||
; CHECK: msr RMR_EL2, x0 ; encoding: [0x40,0xc0,0x1c,0xd5]
|
||||
; CHECK: msr RMR_EL1, x0 ; encoding: [0x40,0xc0,0x18,0xd5]
|
||||
; CHECK: msr CPM_IOACC_CTL_EL3, x0 ; encoding: [0x00,0xf2,0x1f,0xd5]
|
||||
; CHECK: msr OSLAR_EL1, x3 ; encoding: [0x83,0x10,0x10,0xd5]
|
||||
; CHECK: msr DBGDTRTX_EL0, x3 ; encoding: [0x03,0x05,0x13,0xd5]
|
||||
|
||||
|
10
test/MC/ARM64/target-specific-sysreg.s
Normal file
10
test/MC/ARM64/target-specific-sysreg.s
Normal file
@ -0,0 +1,10 @@
|
||||
// RUN: not llvm-mc -triple arm64 -mcpu=generic -show-encoding < %s 2>&1 | \
|
||||
// RUN: FileCheck %s --check-prefix=CHECK-GENERIC
|
||||
//
|
||||
// RUN: llvm-mc -triple arm64 -mcpu=cyclone -show-encoding < %s 2>&1 | \
|
||||
// RUN: FileCheck %s --check-prefix=CHECK-CYCLONE
|
||||
|
||||
msr CPM_IOACC_CTL_EL3, x0
|
||||
|
||||
// CHECK-GENERIC: error: expected writable system register or pstate
|
||||
// CHECK-CYCLONE: msr CPM_IOACC_CTL_EL3, x0 // encoding: [0x00,0xf2,0x1f,0xd5]
|
Loading…
x
Reference in New Issue
Block a user