[llvm] r218753 - [AArch64] Allow access to all system registers with MRS/MSR instructions.
Tom Coxon
tom.coxon at arm.com
Wed Oct 1 03:14:00 PDT 2014
Author: tomc
Date: Wed Oct 1 05:13:59 2014
New Revision: 218753
URL: http://llvm.org/viewvc/llvm-project?rev=218753&view=rev
Log:
[AArch64] Allow access to all system registers with MRS/MSR instructions.
The A64 instruction set includes a generic register syntax for accessing
implementation-defined system registers. The syntax for these registers is:
S<op0>_<op1>_<CRn>_<CRm>_<op2>
The encoding space permitted for implementation-defined system registers
is:
op0 op1 CRn CRm op2
11 xxx 1x11 xxxx xxx
The full encoding space can now be accessed:
op0 op1 CRn CRm op2
xx xxx xxxx xxxx xxx
This is useful to anyone needing to write assembly code supporting new
system registers before the assembler has learned the official names for
them.
Modified:
llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td
llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h
llvm/trunk/test/MC/AArch64/arm64-system-encoding.s
llvm/trunk/test/MC/AArch64/basic-a64-diagnostics.s
llvm/trunk/test/MC/AArch64/basic-a64-instructions.s
Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td?rev=218753&r1=218752&r2=218753&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td Wed Oct 1 05:13:59 2014
@@ -843,7 +843,7 @@ def MRSSystemRegisterOperand : AsmOperan
let ParserMethod = "tryParseSysReg";
let DiagnosticType = "MRS";
}
-// concatenation of 1, op0, op1, CRn, CRm, op2. 16-bit immediate.
+// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
def mrs_sysreg_op : Operand<i32> {
let ParserMatchClass = MRSSystemRegisterOperand;
let DecoderMethod = "DecodeMRSSystemRegister";
@@ -863,9 +863,8 @@ def msr_sysreg_op : Operand<i32> {
class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
"mrs", "\t$Rt, $systemreg"> {
- bits<15> systemreg;
- let Inst{20} = 1;
- let Inst{19-5} = systemreg;
+ bits<16> systemreg;
+ let Inst{20-5} = systemreg;
}
// FIXME: Some of these def NZCV, others don't. Best way to model that?
@@ -873,9 +872,8 @@ class MRSI : RtSystemI<1, (outs GPR64:$R
// would do it, but feels like overkill at this point.
class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
"msr", "\t$systemreg, $Rt"> {
- bits<15> systemreg;
- let Inst{20} = 1;
- let Inst{19-5} = systemreg;
+ bits<16> systemreg;
+ let Inst{20-5} = systemreg;
}
def SystemPStateFieldOperand : AsmOperandClass {
Modified: llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp?rev=218753&r1=218752&r2=218753&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp Wed Oct 1 05:13:59 2014
@@ -626,35 +626,19 @@ static DecodeStatus DecodeMemExtend(llvm
static DecodeStatus DecodeMRSSystemRegister(llvm::MCInst &Inst, unsigned Imm,
uint64_t Address,
const void *Decoder) {
- const AArch64Disassembler *Dis =
- static_cast<const AArch64Disassembler *>(Decoder);
- const MCSubtargetInfo &STI = Dis->getSubtargetInfo();
-
- Imm |= 0x8000;
Inst.addOperand(MCOperand::CreateImm(Imm));
- bool ValidNamed;
- (void)AArch64SysReg::MRSMapper(STI.getFeatureBits())
- .toString(Imm, ValidNamed);
-
- return ValidNamed ? Success : Fail;
+ // Every system register in the encoding space is valid with the syntax
+ // S<op0>_<op1>_<Cn>_<Cm>_<op2>, so decoding system registers always succeeds.
+ return Success;
}
static DecodeStatus DecodeMSRSystemRegister(llvm::MCInst &Inst, unsigned Imm,
uint64_t Address,
const void *Decoder) {
- const AArch64Disassembler *Dis =
- static_cast<const AArch64Disassembler *>(Decoder);
- const MCSubtargetInfo &STI = Dis->getSubtargetInfo();
-
- Imm |= 0x8000;
Inst.addOperand(MCOperand::CreateImm(Imm));
- bool ValidNamed;
- (void)AArch64SysReg::MSRMapper(STI.getFeatureBits())
- .toString(Imm, ValidNamed);
-
- return ValidNamed ? Success : Fail;
+ return Success;
}
static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,
Modified: llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp?rev=218753&r1=218752&r2=218753&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp Wed Oct 1 05:13:59 2014
@@ -1276,24 +1276,20 @@ void AArch64InstPrinter::printMRSSystemR
raw_ostream &O) {
unsigned Val = MI->getOperand(OpNo).getImm();
- bool Valid;
auto Mapper = AArch64SysReg::MRSMapper(getAvailableFeatures());
- std::string Name = Mapper.toString(Val, Valid);
+ std::string Name = Mapper.toString(Val);
- if (Valid)
- O << StringRef(Name).upper();
+ O << StringRef(Name).upper();
}
void AArch64InstPrinter::printMSRSystemRegister(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
unsigned Val = MI->getOperand(OpNo).getImm();
- bool Valid;
auto Mapper = AArch64SysReg::MSRMapper(getAvailableFeatures());
- std::string Name = Mapper.toString(Val, Valid);
+ std::string Name = Mapper.toString(Val);
- if (Valid)
- O << StringRef(Name).upper();
+ O << StringRef(Name).upper();
}
void AArch64InstPrinter::printSystemPStateField(const MCInst *MI, unsigned OpNo,
Modified: llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp?rev=218753&r1=218752&r2=218753&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp Wed Oct 1 05:13:59 2014
@@ -791,22 +791,22 @@ AArch64SysReg::SysRegMapper::fromString(
}
}
- // Try to parse an S<op0>_<op1>_<Cn>_<Cm>_<op2> register name, where the bits
- // are: 11 xxx 1x11 xxxx xxx
- Regex GenericRegPattern("^s3_([0-7])_c(1[15])_c([0-9]|1[0-5])_([0-7])$");
+ // Try to parse an S<op0>_<op1>_<Cn>_<Cm>_<op2> register name
+ Regex GenericRegPattern("^s([0-3])_([0-7])_c([0-9]|1[0-5])_c([0-9]|1[0-5])_([0-7])$");
- SmallVector<StringRef, 4> Ops;
+ SmallVector<StringRef, 5> Ops;
if (!GenericRegPattern.match(NameLower, &Ops)) {
Valid = false;
return -1;
}
- uint32_t Op0 = 3, Op1 = 0, CRn = 0, CRm = 0, Op2 = 0;
+ uint32_t Op0 = 0, Op1 = 0, CRn = 0, CRm = 0, Op2 = 0;
uint32_t Bits;
- Ops[1].getAsInteger(10, Op1);
- Ops[2].getAsInteger(10, CRn);
- Ops[3].getAsInteger(10, CRm);
- Ops[4].getAsInteger(10, Op2);
+ Ops[1].getAsInteger(10, Op0);
+ Ops[2].getAsInteger(10, Op1);
+ Ops[3].getAsInteger(10, CRn);
+ Ops[4].getAsInteger(10, CRm);
+ Ops[5].getAsInteger(10, Op2);
Bits = (Op0 << 14) | (Op1 << 11) | (CRn << 7) | (CRm << 3) | Op2;
Valid = true;
@@ -814,11 +814,10 @@ AArch64SysReg::SysRegMapper::fromString(
}
std::string
-AArch64SysReg::SysRegMapper::toString(uint32_t Bits, bool &Valid) const {
+AArch64SysReg::SysRegMapper::toString(uint32_t Bits) const {
// First search the registers shared by all
for (unsigned i = 0; i < array_lengthof(SysRegPairs); ++i) {
if (SysRegPairs[i].Value == Bits) {
- Valid = true;
return SysRegPairs[i].Name;
}
}
@@ -827,7 +826,6 @@ AArch64SysReg::SysRegMapper::toString(ui
if (FeatureBits & AArch64::ProcCyclone) {
for (unsigned i = 0; i < array_lengthof(CycloneSysRegPairs); ++i) {
if (CycloneSysRegPairs[i].Value == Bits) {
- Valid = true;
return CycloneSysRegPairs[i].Name;
}
}
@@ -837,28 +835,18 @@ AArch64SysReg::SysRegMapper::toString(ui
// write-only).
for (unsigned i = 0; i < NumInstPairs; ++i) {
if (InstPairs[i].Value == Bits) {
- Valid = true;
return InstPairs[i].Name;
}
}
+ assert(Bits < 0x10000);
uint32_t Op0 = (Bits >> 14) & 0x3;
uint32_t Op1 = (Bits >> 11) & 0x7;
uint32_t CRn = (Bits >> 7) & 0xf;
uint32_t CRm = (Bits >> 3) & 0xf;
uint32_t Op2 = Bits & 0x7;
- // Only combinations matching: 11 xxx 1x11 xxxx xxx are valid for a generic
- // name.
- if (Op0 != 3 || (CRn != 11 && CRn != 15)) {
- Valid = false;
- return "";
- }
-
- assert(Op0 == 3 && (CRn == 11 || CRn == 15) && "Invalid generic sysreg");
-
- Valid = true;
- return "s3_" + utostr(Op1) + "_c" + utostr(CRn)
+ return "s" + utostr(Op0)+ "_" + utostr(Op1) + "_c" + utostr(CRn)
+ "_c" + utostr(CRm) + "_" + utostr(Op2);
}
Modified: llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h?rev=218753&r1=218752&r2=218753&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h (original)
+++ llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h Wed Oct 1 05:13:59 2014
@@ -1143,7 +1143,7 @@ namespace AArch64SysReg {
SysRegMapper(uint64_t FeatureBits) : FeatureBits(FeatureBits) { }
uint32_t fromString(StringRef Name, bool &Valid) const;
- std::string toString(uint32_t Bits, bool &Valid) const;
+ std::string toString(uint32_t Bits) const;
};
struct MSRMapper : SysRegMapper {
Modified: llvm/trunk/test/MC/AArch64/arm64-system-encoding.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/arm64-system-encoding.s?rev=218753&r1=218752&r2=218753&view=diff
==============================================================================
--- llvm/trunk/test/MC/AArch64/arm64-system-encoding.s (original)
+++ llvm/trunk/test/MC/AArch64/arm64-system-encoding.s Wed Oct 1 05:13:59 2014
@@ -135,6 +135,8 @@ foo:
msr VTTBR_EL2, x3
msr SPSel, x3
msr S3_2_C11_C6_4, x1
+ msr S0_0_C0_C0_0, x0
+ msr S1_2_C3_C4_5, x2
; CHECK: msr ACTLR_EL1, x3 ; encoding: [0x23,0x10,0x18,0xd5]
; CHECK: msr ACTLR_EL2, x3 ; encoding: [0x23,0x10,0x1c,0xd5]
; CHECK: msr ACTLR_EL3, x3 ; encoding: [0x23,0x10,0x1e,0xd5]
@@ -213,6 +215,8 @@ foo:
; CHECK: msr VTTBR_EL2, x3 ; encoding: [0x03,0x21,0x1c,0xd5]
; CHECK: msr SPSEL, x3 ; encoding: [0x03,0x42,0x18,0xd5]
; CHECK: msr S3_2_C11_C6_4, x1 ; encoding: [0x81,0xb6,0x1a,0xd5]
+; CHECK: msr S0_0_C0_C0_0, x0 ; encoding: [0x00,0x00,0x00,0xd5]
+; CHECK: msr S1_2_C3_C4_5, x2 ; encoding: [0xa2,0x34,0x0a,0xd5]
mrs x3, ACTLR_EL1
mrs x3, ACTLR_EL2
Modified: llvm/trunk/test/MC/AArch64/basic-a64-diagnostics.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/basic-a64-diagnostics.s?rev=218753&r1=218752&r2=218753&view=diff
==============================================================================
--- llvm/trunk/test/MC/AArch64/basic-a64-diagnostics.s (original)
+++ llvm/trunk/test/MC/AArch64/basic-a64-diagnostics.s Wed Oct 1 05:13:59 2014
@@ -3679,26 +3679,26 @@
// CHECK-ERROR-NEXT: ^
// Now check some invalid generic names
- mrs xzr, s2_5_c11_c13_2
mrs x12, s3_8_c11_c13_2
- mrs x13, s3_3_c12_c13_2
mrs x19, s3_2_c15_c16_2
mrs x30, s3_2_c15_c1_8
-// CHECK-ERROR-NEXT: error: expected readable system register
-// CHECK-ERROR-NEXT: mrs xzr, s2_5_c11_c13_2
-// CHECK-ERROR-NEXT: ^
+ mrs x4, s4_7_c15_c15_7
+ mrs x14, s3_7_c16_c15_7
// CHECK-ERROR-NEXT: error: expected readable system register
// CHECK-ERROR-NEXT: mrs x12, s3_8_c11_c13_2
// CHECK-ERROR-NEXT: ^
// CHECK-ERROR-NEXT: error: expected readable system register
-// CHECK-ERROR-NEXT: mrs x13, s3_3_c12_c13_2
-// CHECK-ERROR-NEXT: ^
-// CHECK-ERROR-NEXT: error: expected readable system register
// CHECK-ERROR-NEXT: mrs x19, s3_2_c15_c16_2
// CHECK-ERROR-NEXT: ^
// CHECK-ERROR-NEXT: error: expected readable system register
// CHECK-ERROR-NEXT: mrs x30, s3_2_c15_c1_8
// CHECK-ERROR-NEXT: ^
+// CHECK-ERROR-NEXT: error: expected readable system register
+// CHECK-ERROR-NEXT: mrs x4, s4_7_c15_c15_7
+// CHECK-ERROR-NEXT: ^
+// CHECK-ERROR-NEXT: error: expected readable system register
+// CHECK-ERROR-NEXT: mrs x14, s3_7_c16_c15_7
+// CHECK-ERROR-NEXT: ^
//------------------------------------------------------------------------------
// Test and branch (immediate)
Modified: llvm/trunk/test/MC/AArch64/basic-a64-instructions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/basic-a64-instructions.s?rev=218753&r1=218752&r2=218753&view=diff
==============================================================================
--- llvm/trunk/test/MC/AArch64/basic-a64-instructions.s (original)
+++ llvm/trunk/test/MC/AArch64/basic-a64-instructions.s Wed Oct 1 05:13:59 2014
@@ -4798,12 +4798,16 @@ _func:
mrs x12, s3_7_c15_c1_5
mrs x13, s3_2_c11_c15_7
+ mrs x14, s1_3_c9_c2_1
msr s3_0_c15_c0_0, x12
msr s3_7_c11_c13_7, x5
+ msr s1_3_c9_c2_1, x4
// CHECK: mrs x12, {{s3_7_c15_c1_5|S3_7_C15_C1_5}} // encoding: [0xac,0xf1,0x3f,0xd5]
-// CHECK: mrs x13, {{s3_2_c11_c15_7|S3_2_C11_C15_7}} // encoding: [0xed,0xbf,0x3a,0xd5]
+// CHECK: mrs x13, {{s3_2_c11_c15_7|S3_2_C11_C15_7}} // encoding: [0xed,0xbf,0x3a,0xd5]
+// CHECK: mrs x14, {{s1_3_c9_c2_1|S1_3_C9_C2_1}} // encoding: [0x2e,0x92,0x2b,0xd5]
// CHECK: msr {{s3_0_c15_c0_0|S3_0_C15_C0_0}}, x12 // encoding: [0x0c,0xf0,0x18,0xd5]
-// CHECK: msr {{s3_7_c11_c13_7|S3_7_C11_C13_7}}, x5 // encoding: [0xe5,0xbd,0x1f,0xd5]
+// CHECK: msr {{s3_7_c11_c13_7|S3_7_C11_C13_7}}, x5 // encoding: [0xe5,0xbd,0x1f,0xd5]
+// CHECK: msr {{s1_3_c9_c2_1|S1_3_C9_C2_1}}, x4 // encoding: [0x24,0x92,0x0b,0xd5]
//------------------------------------------------------------------------------
// Unconditional branch (immediate)
More information about the llvm-commits
mailing list