Skip to content

Commit 1a3f307

Browse files
committed
[Mips] Support "$sp" named register
Fix #47656.
1 parent 5d8e8e8 commit 1a3f307

File tree

5 files changed

+247
-28
lines changed

5 files changed

+247
-28
lines changed

llvm/lib/Target/Mips/MipsISelLowering.cpp

Lines changed: 101 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@
7272
#include <cstdint>
7373
#include <deque>
7474
#include <iterator>
75+
#include <regex>
76+
#include <string>
7577
#include <utility>
7678
#include <vector>
7779

@@ -4888,28 +4890,111 @@ MipsTargetLowering::emitPseudoD_SELECT(MachineInstr &MI,
48884890
return BB;
48894891
}
48904892

4893+
// Copies the function MipsAsmParser::matchCPURegisterName.
4894+
int MipsTargetLowering::getCPURegisterIndex(StringRef Name) const {
4895+
int CC;
4896+
4897+
CC = StringSwitch<unsigned>(Name)
4898+
.Case("zero", 0)
4899+
.Cases("at", "AT", 1)
4900+
.Case("a0", 4)
4901+
.Case("a1", 5)
4902+
.Case("a2", 6)
4903+
.Case("a3", 7)
4904+
.Case("v0", 2)
4905+
.Case("v1", 3)
4906+
.Case("s0", 16)
4907+
.Case("s1", 17)
4908+
.Case("s2", 18)
4909+
.Case("s3", 19)
4910+
.Case("s4", 20)
4911+
.Case("s5", 21)
4912+
.Case("s6", 22)
4913+
.Case("s7", 23)
4914+
.Case("k0", 26)
4915+
.Case("k1", 27)
4916+
.Case("gp", 28)
4917+
.Case("sp", 29)
4918+
.Case("fp", 30)
4919+
.Case("s8", 30)
4920+
.Case("ra", 31)
4921+
.Case("t0", 8)
4922+
.Case("t1", 9)
4923+
.Case("t2", 10)
4924+
.Case("t3", 11)
4925+
.Case("t4", 12)
4926+
.Case("t5", 13)
4927+
.Case("t6", 14)
4928+
.Case("t7", 15)
4929+
.Case("t8", 24)
4930+
.Case("t9", 25)
4931+
.Default(-1);
4932+
4933+
if (!(ABI.IsN32() || ABI.IsN64()))
4934+
return CC;
4935+
4936+
// Although SGI documentation just cuts out t0-t3 for n32/n64,
4937+
// GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
4938+
// We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
4939+
if (8 <= CC && CC <= 11)
4940+
CC += 4;
4941+
4942+
if (CC == -1)
4943+
CC = StringSwitch<unsigned>(Name)
4944+
.Case("a4", 8)
4945+
.Case("a5", 9)
4946+
.Case("a6", 10)
4947+
.Case("a7", 11)
4948+
.Case("kt0", 26)
4949+
.Case("kt1", 27)
4950+
.Default(-1);
4951+
4952+
return CC;
4953+
}
4954+
48914955
// FIXME? Maybe this could be a TableGen attribute on some registers and
48924956
// this table could be generated automatically from RegInfo.
48934957
Register
48944958
MipsTargetLowering::getRegisterByName(const char *RegName, LLT VT,
48954959
const MachineFunction &MF) const {
4896-
// The Linux kernel uses $28 and sp.
4897-
if (Subtarget.isGP64bit()) {
4898-
Register Reg = StringSwitch<Register>(RegName)
4899-
.Case("$28", Mips::GP_64)
4900-
.Case("sp", Mips::SP_64)
4901-
.Default(Register());
4902-
if (Reg)
4903-
return Reg;
4904-
} else {
4905-
Register Reg = StringSwitch<Register>(RegName)
4906-
.Case("$28", Mips::GP)
4907-
.Case("sp", Mips::SP)
4908-
.Default(Register());
4909-
if (Reg)
4910-
return Reg;
4960+
// 1. Delete symbol '$'.
4961+
std::string newRegName = RegName;
4962+
if (StringRef(RegName).starts_with("$"))
4963+
newRegName = StringRef(RegName).substr(1);
4964+
4965+
// 2. Check if number [0-31], then transform to int.
4966+
std::smatch matchResult;
4967+
static const std::regex matchStr("^[0-9]*$");
4968+
if (std::regex_match(newRegName, matchResult, matchStr)) {
4969+
int regIdx = std::stoi(newRegName);
4970+
if (regIdx >= 0 && regIdx < 32) {
4971+
return Subtarget.isGP64bit() ? MF.getContext()
4972+
.getRegisterInfo()
4973+
->getRegClass(Mips::GPR64RegClassID)
4974+
.getRegister(regIdx)
4975+
: MF.getContext()
4976+
.getRegisterInfo()
4977+
->getRegClass(Mips::GPR32RegClassID)
4978+
.getRegister(regIdx);
4979+
}
4980+
}
4981+
4982+
// 3. Use function `getCPURegisterIndex` to get register index value
4983+
newRegName = StringRef(newRegName).lower();
4984+
int regNo = getCPURegisterIndex(StringRef(newRegName));
4985+
if (regNo >= 0 && regNo < 32) {
4986+
return Subtarget.isGP64bit() ? MF.getContext()
4987+
.getRegisterInfo()
4988+
->getRegClass(Mips::GPR64RegClassID)
4989+
.getRegister(regNo)
4990+
: MF.getContext()
4991+
.getRegisterInfo()
4992+
->getRegClass(Mips::GPR32RegClassID)
4993+
.getRegister(regNo);
49114994
}
4912-
report_fatal_error("Invalid register name global variable");
4995+
4996+
report_fatal_error(
4997+
Twine("Invalid register name \"" + StringRef(RegName) + "\"."));
49134998
}
49144999

49155000
MachineBasicBlock *MipsTargetLowering::emitLDR_W(MachineInstr &MI,

llvm/lib/Target/Mips/MipsISelLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,8 @@ class TargetRegisterClass;
715715
return true;
716716
}
717717

718+
int getCPURegisterIndex(StringRef Name) const;
719+
718720
/// Emit a sign-extension using sll/sra, seb, or seh appropriately.
719721
MachineBasicBlock *emitSignExtendToI32InReg(MachineInstr &MI,
720722
MachineBasicBlock *BB,

llvm/test/CodeGen/Mips/named-register-n32.ll

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,39 @@
44

55
declare i64 @llvm.read_register.i64(metadata)
66

7+
define i64 @get_$28() {
8+
; CHECK-LABEL: get_$28:
9+
; CHECK: # %bb.0:
10+
; CHECK-NEXT: jr $ra
11+
; CHECK-NEXT: move $2, $gp
12+
%1 = call i64 @llvm.read_register.i64(metadata !0)
13+
ret i64 %1
14+
}
15+
716
define i64 @get_gp() {
817
; CHECK-LABEL: get_gp:
918
; CHECK: # %bb.0:
1019
; CHECK-NEXT: jr $ra
1120
; CHECK-NEXT: move $2, $gp
12-
%1 = call i64 @llvm.read_register.i64(metadata !0)
21+
%1 = call i64 @llvm.read_register.i64(metadata !1)
22+
ret i64 %1
23+
}
24+
25+
define i64 @get_$gp() {
26+
; CHECK-LABEL: get_$gp:
27+
; CHECK: # %bb.0:
28+
; CHECK-NEXT: jr $ra
29+
; CHECK-NEXT: move $2, $gp
30+
%1 = call i64 @llvm.read_register.i64(metadata !2)
31+
ret i64 %1
32+
}
33+
34+
define i64 @get_$29() {
35+
; CHECK-LABEL: get_$29:
36+
; CHECK: # %bb.0:
37+
; CHECK-NEXT: jr $ra
38+
; CHECK-NEXT: move $2, $sp
39+
%1 = call i64 @llvm.read_register.i64(metadata !3)
1340
ret i64 %1
1441
}
1542

@@ -18,12 +45,29 @@ define i64 @get_sp() {
1845
; CHECK: # %bb.0:
1946
; CHECK-NEXT: jr $ra
2047
; CHECK-NEXT: move $2, $sp
21-
%1 = call i64 @llvm.read_register.i64(metadata !1)
48+
%1 = call i64 @llvm.read_register.i64(metadata !4)
49+
ret i64 %1
50+
}
51+
52+
define i64 @get_$sp() {
53+
; CHECK-LABEL: get_$sp:
54+
; CHECK: # %bb.0:
55+
; CHECK-NEXT: jr $ra
56+
; CHECK-NEXT: move $2, $sp
57+
%1 = call i64 @llvm.read_register.i64(metadata !5)
2258
ret i64 %1
2359
}
2460

2561
!llvm.named.register.$28 = !{!0}
26-
!llvm.named.register.sp = !{!1}
62+
!llvm.named.register.gp = !{!1}
63+
!llvm.named.register.$gp = !{!2}
64+
!llvm.named.register.$29 = !{!3}
65+
!llvm.named.register.sp = !{!4}
66+
!llvm.named.register.$sp = !{!5}
2767

2868
!0 = !{!"$28"}
29-
!1 = !{!"sp"}
69+
!1 = !{!"gp"}
70+
!2 = !{!"$gp"}
71+
!3 = !{!"$29"}
72+
!4 = !{!"sp"}
73+
!5 = !{!"$sp"}

llvm/test/CodeGen/Mips/named-register-n64.ll

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,39 @@
44

55
declare i64 @llvm.read_register.i64(metadata)
66

7+
define i64 @get_$28() {
8+
; CHECK-LABEL: get_$28:
9+
; CHECK: # %bb.0:
10+
; CHECK-NEXT: jr $ra
11+
; CHECK-NEXT: move $2, $gp
12+
%1 = call i64 @llvm.read_register.i64(metadata !0)
13+
ret i64 %1
14+
}
15+
716
define i64 @get_gp() {
817
; CHECK-LABEL: get_gp:
918
; CHECK: # %bb.0:
1019
; CHECK-NEXT: jr $ra
1120
; CHECK-NEXT: move $2, $gp
12-
%1 = call i64 @llvm.read_register.i64(metadata !0)
21+
%1 = call i64 @llvm.read_register.i64(metadata !1)
22+
ret i64 %1
23+
}
24+
25+
define i64 @get_$gp() {
26+
; CHECK-LABEL: get_$gp:
27+
; CHECK: # %bb.0:
28+
; CHECK-NEXT: jr $ra
29+
; CHECK-NEXT: move $2, $gp
30+
%1 = call i64 @llvm.read_register.i64(metadata !2)
31+
ret i64 %1
32+
}
33+
34+
define i64 @get_$29() {
35+
; CHECK-LABEL: get_$29:
36+
; CHECK: # %bb.0:
37+
; CHECK-NEXT: jr $ra
38+
; CHECK-NEXT: move $2, $sp
39+
%1 = call i64 @llvm.read_register.i64(metadata !3)
1340
ret i64 %1
1441
}
1542

@@ -18,12 +45,29 @@ define i64 @get_sp() {
1845
; CHECK: # %bb.0:
1946
; CHECK-NEXT: jr $ra
2047
; CHECK-NEXT: move $2, $sp
21-
%1 = call i64 @llvm.read_register.i64(metadata !1)
48+
%1 = call i64 @llvm.read_register.i64(metadata !4)
49+
ret i64 %1
50+
}
51+
52+
define i64 @get_$sp() {
53+
; CHECK-LABEL: get_$sp:
54+
; CHECK: # %bb.0:
55+
; CHECK-NEXT: jr $ra
56+
; CHECK-NEXT: move $2, $sp
57+
%1 = call i64 @llvm.read_register.i64(metadata !5)
2258
ret i64 %1
2359
}
2460

2561
!llvm.named.register.$28 = !{!0}
26-
!llvm.named.register.sp = !{!1}
62+
!llvm.named.register.gp = !{!1}
63+
!llvm.named.register.$gp = !{!2}
64+
!llvm.named.register.$29 = !{!3}
65+
!llvm.named.register.sp = !{!4}
66+
!llvm.named.register.$sp = !{!5}
2767

2868
!0 = !{!"$28"}
29-
!1 = !{!"sp"}
69+
!1 = !{!"gp"}
70+
!2 = !{!"$gp"}
71+
!3 = !{!"$29"}
72+
!4 = !{!"sp"}
73+
!5 = !{!"$sp"}

llvm/test/CodeGen/Mips/named-register-o32.ll

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,39 @@
44

55
declare i32 @llvm.read_register.i32(metadata)
66

7+
define i32 @get_$28() {
8+
; CHECK-LABEL: get_$28:
9+
; CHECK: # %bb.0:
10+
; CHECK-NEXT: jr $ra
11+
; CHECK-NEXT: move $2, $gp
12+
%1 = call i32 @llvm.read_register.i32(metadata !0)
13+
ret i32 %1
14+
}
15+
716
define i32 @get_gp() {
817
; CHECK-LABEL: get_gp:
918
; CHECK: # %bb.0:
1019
; CHECK-NEXT: jr $ra
1120
; CHECK-NEXT: move $2, $gp
12-
%1 = call i32 @llvm.read_register.i32(metadata !0)
21+
%1 = call i32 @llvm.read_register.i32(metadata !1)
22+
ret i32 %1
23+
}
24+
25+
define i32 @get_$gp() {
26+
; CHECK-LABEL: get_$gp:
27+
; CHECK: # %bb.0:
28+
; CHECK-NEXT: jr $ra
29+
; CHECK-NEXT: move $2, $gp
30+
%1 = call i32 @llvm.read_register.i32(metadata !2)
31+
ret i32 %1
32+
}
33+
34+
define i32 @get_$29() {
35+
; CHECK-LABEL: get_$29:
36+
; CHECK: # %bb.0:
37+
; CHECK-NEXT: jr $ra
38+
; CHECK-NEXT: move $2, $sp
39+
%1 = call i32 @llvm.read_register.i32(metadata !3)
1340
ret i32 %1
1441
}
1542

@@ -18,12 +45,29 @@ define i32 @get_sp() {
1845
; CHECK: # %bb.0:
1946
; CHECK-NEXT: jr $ra
2047
; CHECK-NEXT: move $2, $sp
21-
%1 = call i32 @llvm.read_register.i32(metadata !1)
48+
%1 = call i32 @llvm.read_register.i32(metadata !4)
49+
ret i32 %1
50+
}
51+
52+
define i32 @get_$sp() {
53+
; CHECK-LABEL: get_$sp:
54+
; CHECK: # %bb.0:
55+
; CHECK-NEXT: jr $ra
56+
; CHECK-NEXT: move $2, $sp
57+
%1 = call i32 @llvm.read_register.i32(metadata !5)
2258
ret i32 %1
2359
}
2460

2561
!llvm.named.register.$28 = !{!0}
26-
!llvm.named.register.sp = !{!1}
62+
!llvm.named.register.gp = !{!1}
63+
!llvm.named.register.$gp = !{!2}
64+
!llvm.named.register.$29 = !{!3}
65+
!llvm.named.register.sp = !{!4}
66+
!llvm.named.register.$sp = !{!5}
2767

2868
!0 = !{!"$28"}
29-
!1 = !{!"sp"}
69+
!1 = !{!"gp"}
70+
!2 = !{!"$gp"}
71+
!3 = !{!"$29"}
72+
!4 = !{!"sp"}
73+
!5 = !{!"$sp"}

0 commit comments

Comments
 (0)