Skip to content

Commit e493f17

Browse files
author
Tom Coxon
committed
[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. llvm-svn: 218753
1 parent 815f286 commit e493f17

File tree

8 files changed

+44
-70
lines changed

8 files changed

+44
-70
lines changed

llvm/lib/Target/AArch64/AArch64InstrFormats.td

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ def MRSSystemRegisterOperand : AsmOperandClass {
843843
let ParserMethod = "tryParseSysReg";
844844
let DiagnosticType = "MRS";
845845
}
846-
// concatenation of 1, op0, op1, CRn, CRm, op2. 16-bit immediate.
846+
// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
847847
def mrs_sysreg_op : Operand<i32> {
848848
let ParserMatchClass = MRSSystemRegisterOperand;
849849
let DecoderMethod = "DecodeMRSSystemRegister";
@@ -863,19 +863,17 @@ def msr_sysreg_op : Operand<i32> {
863863

864864
class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
865865
"mrs", "\t$Rt, $systemreg"> {
866-
bits<15> systemreg;
867-
let Inst{20} = 1;
868-
let Inst{19-5} = systemreg;
866+
bits<16> systemreg;
867+
let Inst{20-5} = systemreg;
869868
}
870869

871870
// FIXME: Some of these def NZCV, others don't. Best way to model that?
872871
// Explicitly modeling each of the system register as a register class
873872
// would do it, but feels like overkill at this point.
874873
class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
875874
"msr", "\t$systemreg, $Rt"> {
876-
bits<15> systemreg;
877-
let Inst{20} = 1;
878-
let Inst{19-5} = systemreg;
875+
bits<16> systemreg;
876+
let Inst{20-5} = systemreg;
879877
}
880878

881879
def SystemPStateFieldOperand : AsmOperandClass {

llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -626,35 +626,19 @@ static DecodeStatus DecodeMemExtend(llvm::MCInst &Inst, unsigned Imm,
626626
static DecodeStatus DecodeMRSSystemRegister(llvm::MCInst &Inst, unsigned Imm,
627627
uint64_t Address,
628628
const void *Decoder) {
629-
const AArch64Disassembler *Dis =
630-
static_cast<const AArch64Disassembler *>(Decoder);
631-
const MCSubtargetInfo &STI = Dis->getSubtargetInfo();
632-
633-
Imm |= 0x8000;
634629
Inst.addOperand(MCOperand::CreateImm(Imm));
635630

636-
bool ValidNamed;
637-
(void)AArch64SysReg::MRSMapper(STI.getFeatureBits())
638-
.toString(Imm, ValidNamed);
639-
640-
return ValidNamed ? Success : Fail;
631+
// Every system register in the encoding space is valid with the syntax
632+
// S<op0>_<op1>_<Cn>_<Cm>_<op2>, so decoding system registers always succeeds.
633+
return Success;
641634
}
642635

643636
static DecodeStatus DecodeMSRSystemRegister(llvm::MCInst &Inst, unsigned Imm,
644637
uint64_t Address,
645638
const void *Decoder) {
646-
const AArch64Disassembler *Dis =
647-
static_cast<const AArch64Disassembler *>(Decoder);
648-
const MCSubtargetInfo &STI = Dis->getSubtargetInfo();
649-
650-
Imm |= 0x8000;
651639
Inst.addOperand(MCOperand::CreateImm(Imm));
652640

653-
bool ValidNamed;
654-
(void)AArch64SysReg::MSRMapper(STI.getFeatureBits())
655-
.toString(Imm, ValidNamed);
656-
657-
return ValidNamed ? Success : Fail;
641+
return Success;
658642
}
659643

660644
static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,

llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,24 +1276,20 @@ void AArch64InstPrinter::printMRSSystemRegister(const MCInst *MI, unsigned OpNo,
12761276
raw_ostream &O) {
12771277
unsigned Val = MI->getOperand(OpNo).getImm();
12781278

1279-
bool Valid;
12801279
auto Mapper = AArch64SysReg::MRSMapper(getAvailableFeatures());
1281-
std::string Name = Mapper.toString(Val, Valid);
1280+
std::string Name = Mapper.toString(Val);
12821281

1283-
if (Valid)
1284-
O << StringRef(Name).upper();
1282+
O << StringRef(Name).upper();
12851283
}
12861284

12871285
void AArch64InstPrinter::printMSRSystemRegister(const MCInst *MI, unsigned OpNo,
12881286
raw_ostream &O) {
12891287
unsigned Val = MI->getOperand(OpNo).getImm();
12901288

1291-
bool Valid;
12921289
auto Mapper = AArch64SysReg::MSRMapper(getAvailableFeatures());
1293-
std::string Name = Mapper.toString(Val, Valid);
1290+
std::string Name = Mapper.toString(Val);
12941291

1295-
if (Valid)
1296-
O << StringRef(Name).upper();
1292+
O << StringRef(Name).upper();
12971293
}
12981294

12991295
void AArch64InstPrinter::printSystemPStateField(const MCInst *MI, unsigned OpNo,

llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -791,34 +791,33 @@ AArch64SysReg::SysRegMapper::fromString(StringRef Name, bool &Valid) const {
791791
}
792792
}
793793

794-
// Try to parse an S<op0>_<op1>_<Cn>_<Cm>_<op2> register name, where the bits
795-
// are: 11 xxx 1x11 xxxx xxx
796-
Regex GenericRegPattern("^s3_([0-7])_c(1[15])_c([0-9]|1[0-5])_([0-7])$");
794+
// Try to parse an S<op0>_<op1>_<Cn>_<Cm>_<op2> register name
795+
Regex GenericRegPattern("^s([0-3])_([0-7])_c([0-9]|1[0-5])_c([0-9]|1[0-5])_([0-7])$");
797796

798-
SmallVector<StringRef, 4> Ops;
797+
SmallVector<StringRef, 5> Ops;
799798
if (!GenericRegPattern.match(NameLower, &Ops)) {
800799
Valid = false;
801800
return -1;
802801
}
803802

804-
uint32_t Op0 = 3, Op1 = 0, CRn = 0, CRm = 0, Op2 = 0;
803+
uint32_t Op0 = 0, Op1 = 0, CRn = 0, CRm = 0, Op2 = 0;
805804
uint32_t Bits;
806-
Ops[1].getAsInteger(10, Op1);
807-
Ops[2].getAsInteger(10, CRn);
808-
Ops[3].getAsInteger(10, CRm);
809-
Ops[4].getAsInteger(10, Op2);
805+
Ops[1].getAsInteger(10, Op0);
806+
Ops[2].getAsInteger(10, Op1);
807+
Ops[3].getAsInteger(10, CRn);
808+
Ops[4].getAsInteger(10, CRm);
809+
Ops[5].getAsInteger(10, Op2);
810810
Bits = (Op0 << 14) | (Op1 << 11) | (CRn << 7) | (CRm << 3) | Op2;
811811

812812
Valid = true;
813813
return Bits;
814814
}
815815

816816
std::string
817-
AArch64SysReg::SysRegMapper::toString(uint32_t Bits, bool &Valid) const {
817+
AArch64SysReg::SysRegMapper::toString(uint32_t Bits) const {
818818
// First search the registers shared by all
819819
for (unsigned i = 0; i < array_lengthof(SysRegPairs); ++i) {
820820
if (SysRegPairs[i].Value == Bits) {
821-
Valid = true;
822821
return SysRegPairs[i].Name;
823822
}
824823
}
@@ -827,7 +826,6 @@ AArch64SysReg::SysRegMapper::toString(uint32_t Bits, bool &Valid) const {
827826
if (FeatureBits & AArch64::ProcCyclone) {
828827
for (unsigned i = 0; i < array_lengthof(CycloneSysRegPairs); ++i) {
829828
if (CycloneSysRegPairs[i].Value == Bits) {
830-
Valid = true;
831829
return CycloneSysRegPairs[i].Name;
832830
}
833831
}
@@ -837,28 +835,18 @@ AArch64SysReg::SysRegMapper::toString(uint32_t Bits, bool &Valid) const {
837835
// write-only).
838836
for (unsigned i = 0; i < NumInstPairs; ++i) {
839837
if (InstPairs[i].Value == Bits) {
840-
Valid = true;
841838
return InstPairs[i].Name;
842839
}
843840
}
844841

842+
assert(Bits < 0x10000);
845843
uint32_t Op0 = (Bits >> 14) & 0x3;
846844
uint32_t Op1 = (Bits >> 11) & 0x7;
847845
uint32_t CRn = (Bits >> 7) & 0xf;
848846
uint32_t CRm = (Bits >> 3) & 0xf;
849847
uint32_t Op2 = Bits & 0x7;
850848

851-
// Only combinations matching: 11 xxx 1x11 xxxx xxx are valid for a generic
852-
// name.
853-
if (Op0 != 3 || (CRn != 11 && CRn != 15)) {
854-
Valid = false;
855-
return "";
856-
}
857-
858-
assert(Op0 == 3 && (CRn == 11 || CRn == 15) && "Invalid generic sysreg");
859-
860-
Valid = true;
861-
return "s3_" + utostr(Op1) + "_c" + utostr(CRn)
849+
return "s" + utostr(Op0)+ "_" + utostr(Op1) + "_c" + utostr(CRn)
862850
+ "_c" + utostr(CRm) + "_" + utostr(Op2);
863851
}
864852

llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1143,7 +1143,7 @@ namespace AArch64SysReg {
11431143

11441144
SysRegMapper(uint64_t FeatureBits) : FeatureBits(FeatureBits) { }
11451145
uint32_t fromString(StringRef Name, bool &Valid) const;
1146-
std::string toString(uint32_t Bits, bool &Valid) const;
1146+
std::string toString(uint32_t Bits) const;
11471147
};
11481148

11491149
struct MSRMapper : SysRegMapper {

llvm/test/MC/AArch64/arm64-system-encoding.s

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ foo:
135135
msr VTTBR_EL2, x3
136136
msr SPSel, x3
137137
msr S3_2_C11_C6_4, x1
138+
msr S0_0_C0_C0_0, x0
139+
msr S1_2_C3_C4_5, x2
138140
; CHECK: msr ACTLR_EL1, x3 ; encoding: [0x23,0x10,0x18,0xd5]
139141
; CHECK: msr ACTLR_EL2, x3 ; encoding: [0x23,0x10,0x1c,0xd5]
140142
; CHECK: msr ACTLR_EL3, x3 ; encoding: [0x23,0x10,0x1e,0xd5]
@@ -213,6 +215,8 @@ foo:
213215
; CHECK: msr VTTBR_EL2, x3 ; encoding: [0x03,0x21,0x1c,0xd5]
214216
; CHECK: msr SPSEL, x3 ; encoding: [0x03,0x42,0x18,0xd5]
215217
; CHECK: msr S3_2_C11_C6_4, x1 ; encoding: [0x81,0xb6,0x1a,0xd5]
218+
; CHECK: msr S0_0_C0_C0_0, x0 ; encoding: [0x00,0x00,0x00,0xd5]
219+
; CHECK: msr S1_2_C3_C4_5, x2 ; encoding: [0xa2,0x34,0x0a,0xd5]
216220

217221
mrs x3, ACTLR_EL1
218222
mrs x3, ACTLR_EL2

llvm/test/MC/AArch64/basic-a64-diagnostics.s

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3679,26 +3679,26 @@
36793679
// CHECK-ERROR-NEXT: ^
36803680

36813681
// Now check some invalid generic names
3682-
mrs xzr, s2_5_c11_c13_2
36833682
mrs x12, s3_8_c11_c13_2
3684-
mrs x13, s3_3_c12_c13_2
36853683
mrs x19, s3_2_c15_c16_2
36863684
mrs x30, s3_2_c15_c1_8
3687-
// CHECK-ERROR-NEXT: error: expected readable system register
3688-
// CHECK-ERROR-NEXT: mrs xzr, s2_5_c11_c13_2
3689-
// CHECK-ERROR-NEXT: ^
3685+
mrs x4, s4_7_c15_c15_7
3686+
mrs x14, s3_7_c16_c15_7
36903687
// CHECK-ERROR-NEXT: error: expected readable system register
36913688
// CHECK-ERROR-NEXT: mrs x12, s3_8_c11_c13_2
36923689
// CHECK-ERROR-NEXT: ^
36933690
// CHECK-ERROR-NEXT: error: expected readable system register
3694-
// CHECK-ERROR-NEXT: mrs x13, s3_3_c12_c13_2
3695-
// CHECK-ERROR-NEXT: ^
3696-
// CHECK-ERROR-NEXT: error: expected readable system register
36973691
// CHECK-ERROR-NEXT: mrs x19, s3_2_c15_c16_2
36983692
// CHECK-ERROR-NEXT: ^
36993693
// CHECK-ERROR-NEXT: error: expected readable system register
37003694
// CHECK-ERROR-NEXT: mrs x30, s3_2_c15_c1_8
37013695
// CHECK-ERROR-NEXT: ^
3696+
// CHECK-ERROR-NEXT: error: expected readable system register
3697+
// CHECK-ERROR-NEXT: mrs x4, s4_7_c15_c15_7
3698+
// CHECK-ERROR-NEXT: ^
3699+
// CHECK-ERROR-NEXT: error: expected readable system register
3700+
// CHECK-ERROR-NEXT: mrs x14, s3_7_c16_c15_7
3701+
// CHECK-ERROR-NEXT: ^
37023702

37033703
//------------------------------------------------------------------------------
37043704
// Test and branch (immediate)

llvm/test/MC/AArch64/basic-a64-instructions.s

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4798,12 +4798,16 @@ _func:
47984798

47994799
mrs x12, s3_7_c15_c1_5
48004800
mrs x13, s3_2_c11_c15_7
4801+
mrs x14, s1_3_c9_c2_1
48014802
msr s3_0_c15_c0_0, x12
48024803
msr s3_7_c11_c13_7, x5
4804+
msr s1_3_c9_c2_1, x4
48034805
// CHECK: mrs x12, {{s3_7_c15_c1_5|S3_7_C15_C1_5}} // encoding: [0xac,0xf1,0x3f,0xd5]
4804-
// CHECK: mrs x13, {{s3_2_c11_c15_7|S3_2_C11_C15_7}} // encoding: [0xed,0xbf,0x3a,0xd5]
4806+
// CHECK: mrs x13, {{s3_2_c11_c15_7|S3_2_C11_C15_7}} // encoding: [0xed,0xbf,0x3a,0xd5]
4807+
// CHECK: mrs x14, {{s1_3_c9_c2_1|S1_3_C9_C2_1}} // encoding: [0x2e,0x92,0x2b,0xd5]
48054808
// CHECK: msr {{s3_0_c15_c0_0|S3_0_C15_C0_0}}, x12 // encoding: [0x0c,0xf0,0x18,0xd5]
4806-
// CHECK: msr {{s3_7_c11_c13_7|S3_7_C11_C13_7}}, x5 // encoding: [0xe5,0xbd,0x1f,0xd5]
4809+
// CHECK: msr {{s3_7_c11_c13_7|S3_7_C11_C13_7}}, x5 // encoding: [0xe5,0xbd,0x1f,0xd5]
4810+
// CHECK: msr {{s1_3_c9_c2_1|S1_3_C9_C2_1}}, x4 // encoding: [0x24,0x92,0x0b,0xd5]
48074811

48084812
//------------------------------------------------------------------------------
48094813
// Unconditional branch (immediate)

0 commit comments

Comments
 (0)