-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[Mips] Support "$sp" named register #136821
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Looks good for adding support for |
We can see the code comments |
I think that we need something to support something like $0-$31 and something like $gp, $t1 etc. |
You mean we need to process all registers? |
yes. |
9a585ca
to
5233436
Compare
@wzssyqa Could you help review again? Thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More test cases with other reg names?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have appended test with other reg, can you help review again?
5233436
to
1a3f307
Compare
ping @wzssyqa |
Ping |
ping |
@wzssyqa Can you help review again, thanks! |
You need to resolve the conflicts. |
@llvm/pr-subscribers-backend-mips Author: None (yingopq) ChangesFix #47656. Full diff: https://github.com/llvm/llvm-project/pull/136821.diff 5 Files Affected:
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index b05de49d8332a..020a8325a32fd 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -72,6 +72,8 @@
#include <cstdint>
#include <deque>
#include <iterator>
+#include <regex>
+#include <string>
#include <utility>
#include <vector>
@@ -4937,25 +4939,111 @@ MipsTargetLowering::emitPseudoD_SELECT(MachineInstr &MI,
return BB;
}
+// Copies the function MipsAsmParser::matchCPURegisterName.
+int MipsTargetLowering::getCPURegisterIndex(StringRef Name) const {
+ int CC;
+
+ CC = StringSwitch<unsigned>(Name)
+ .Case("zero", 0)
+ .Cases("at", "AT", 1)
+ .Case("a0", 4)
+ .Case("a1", 5)
+ .Case("a2", 6)
+ .Case("a3", 7)
+ .Case("v0", 2)
+ .Case("v1", 3)
+ .Case("s0", 16)
+ .Case("s1", 17)
+ .Case("s2", 18)
+ .Case("s3", 19)
+ .Case("s4", 20)
+ .Case("s5", 21)
+ .Case("s6", 22)
+ .Case("s7", 23)
+ .Case("k0", 26)
+ .Case("k1", 27)
+ .Case("gp", 28)
+ .Case("sp", 29)
+ .Case("fp", 30)
+ .Case("s8", 30)
+ .Case("ra", 31)
+ .Case("t0", 8)
+ .Case("t1", 9)
+ .Case("t2", 10)
+ .Case("t3", 11)
+ .Case("t4", 12)
+ .Case("t5", 13)
+ .Case("t6", 14)
+ .Case("t7", 15)
+ .Case("t8", 24)
+ .Case("t9", 25)
+ .Default(-1);
+
+ if (!(ABI.IsN32() || ABI.IsN64()))
+ return CC;
+
+ // Although SGI documentation just cuts out t0-t3 for n32/n64,
+ // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
+ // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
+ if (8 <= CC && CC <= 11)
+ CC += 4;
+
+ if (CC == -1)
+ CC = StringSwitch<unsigned>(Name)
+ .Case("a4", 8)
+ .Case("a5", 9)
+ .Case("a6", 10)
+ .Case("a7", 11)
+ .Case("kt0", 26)
+ .Case("kt1", 27)
+ .Default(-1);
+
+ return CC;
+}
+
// FIXME? Maybe this could be a TableGen attribute on some registers and
// this table could be generated automatically from RegInfo.
Register
MipsTargetLowering::getRegisterByName(const char *RegName, LLT VT,
const MachineFunction &MF) const {
- // The Linux kernel uses $28 and sp.
- if (Subtarget.isGP64bit()) {
- Register Reg = StringSwitch<Register>(RegName)
- .Case("$28", Mips::GP_64)
- .Case("sp", Mips::SP_64)
- .Default(Register());
- return Reg;
+ // 1. Delete symbol '$'.
+ std::string newRegName = RegName;
+ if (StringRef(RegName).starts_with("$"))
+ newRegName = StringRef(RegName).substr(1);
+
+ // 2. Check if number [0-31], then transform to int.
+ std::smatch matchResult;
+ static const std::regex matchStr("^[0-9]*$");
+ if (std::regex_match(newRegName, matchResult, matchStr)) {
+ int regIdx = std::stoi(newRegName);
+ if (regIdx >= 0 && regIdx < 32) {
+ return Subtarget.isGP64bit() ? MF.getContext()
+ .getRegisterInfo()
+ ->getRegClass(Mips::GPR64RegClassID)
+ .getRegister(regIdx)
+ : MF.getContext()
+ .getRegisterInfo()
+ ->getRegClass(Mips::GPR32RegClassID)
+ .getRegister(regIdx);
+ }
+ }
+
+ // 3. Use function `getCPURegisterIndex` to get register index value
+ newRegName = StringRef(newRegName).lower();
+ int regNo = getCPURegisterIndex(StringRef(newRegName));
+ if (regNo >= 0 && regNo < 32) {
+ return Subtarget.isGP64bit() ? MF.getContext()
+ .getRegisterInfo()
+ ->getRegClass(Mips::GPR64RegClassID)
+ .getRegister(regNo)
+ : MF.getContext()
+ .getRegisterInfo()
+ ->getRegClass(Mips::GPR32RegClassID)
+ .getRegister(regNo);
}
- Register Reg = StringSwitch<Register>(RegName)
- .Case("$28", Mips::GP)
- .Case("sp", Mips::SP)
- .Default(Register());
- return Reg;
+ report_fatal_error(
+ Twine("Invalid register name \"" + StringRef(RegName) + "\"."));
}
MachineBasicBlock *MipsTargetLowering::emitLDR_W(MachineInstr &MI,
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index c65c76ccffc75..09a59905c8c25 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -718,6 +718,8 @@ class TargetRegisterClass;
return true;
}
+ int getCPURegisterIndex(StringRef Name) const;
+
/// Emit a sign-extension using sll/sra, seb, or seh appropriately.
MachineBasicBlock *emitSignExtendToI32InReg(MachineInstr &MI,
MachineBasicBlock *BB,
diff --git a/llvm/test/CodeGen/Mips/named-register-n32.ll b/llvm/test/CodeGen/Mips/named-register-n32.ll
index 112e04e14b2ac..617e03f95b050 100644
--- a/llvm/test/CodeGen/Mips/named-register-n32.ll
+++ b/llvm/test/CodeGen/Mips/named-register-n32.ll
@@ -4,12 +4,39 @@
declare i64 @llvm.read_register.i64(metadata)
+define i64 @get_$28() {
+; CHECK-LABEL: get_$28:
+; CHECK: # %bb.0:
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: move $2, $gp
+ %1 = call i64 @llvm.read_register.i64(metadata !0)
+ ret i64 %1
+}
+
define i64 @get_gp() {
; CHECK-LABEL: get_gp:
; CHECK: # %bb.0:
; CHECK-NEXT: jr $ra
; CHECK-NEXT: move $2, $gp
- %1 = call i64 @llvm.read_register.i64(metadata !0)
+ %1 = call i64 @llvm.read_register.i64(metadata !1)
+ ret i64 %1
+}
+
+define i64 @get_$gp() {
+; CHECK-LABEL: get_$gp:
+; CHECK: # %bb.0:
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: move $2, $gp
+ %1 = call i64 @llvm.read_register.i64(metadata !2)
+ ret i64 %1
+}
+
+define i64 @get_$29() {
+; CHECK-LABEL: get_$29:
+; CHECK: # %bb.0:
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: move $2, $sp
+ %1 = call i64 @llvm.read_register.i64(metadata !3)
ret i64 %1
}
@@ -18,12 +45,29 @@ define i64 @get_sp() {
; CHECK: # %bb.0:
; CHECK-NEXT: jr $ra
; CHECK-NEXT: move $2, $sp
- %1 = call i64 @llvm.read_register.i64(metadata !1)
+ %1 = call i64 @llvm.read_register.i64(metadata !4)
+ ret i64 %1
+}
+
+define i64 @get_$sp() {
+; CHECK-LABEL: get_$sp:
+; CHECK: # %bb.0:
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: move $2, $sp
+ %1 = call i64 @llvm.read_register.i64(metadata !5)
ret i64 %1
}
!llvm.named.register.$28 = !{!0}
-!llvm.named.register.sp = !{!1}
+!llvm.named.register.gp = !{!1}
+!llvm.named.register.$gp = !{!2}
+!llvm.named.register.$29 = !{!3}
+!llvm.named.register.sp = !{!4}
+!llvm.named.register.$sp = !{!5}
!0 = !{!"$28"}
-!1 = !{!"sp"}
+!1 = !{!"gp"}
+!2 = !{!"$gp"}
+!3 = !{!"$29"}
+!4 = !{!"sp"}
+!5 = !{!"$sp"}
diff --git a/llvm/test/CodeGen/Mips/named-register-n64.ll b/llvm/test/CodeGen/Mips/named-register-n64.ll
index 42d9ba1e1f15c..bee8643fabfee 100644
--- a/llvm/test/CodeGen/Mips/named-register-n64.ll
+++ b/llvm/test/CodeGen/Mips/named-register-n64.ll
@@ -4,12 +4,39 @@
declare i64 @llvm.read_register.i64(metadata)
+define i64 @get_$28() {
+; CHECK-LABEL: get_$28:
+; CHECK: # %bb.0:
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: move $2, $gp
+ %1 = call i64 @llvm.read_register.i64(metadata !0)
+ ret i64 %1
+}
+
define i64 @get_gp() {
; CHECK-LABEL: get_gp:
; CHECK: # %bb.0:
; CHECK-NEXT: jr $ra
; CHECK-NEXT: move $2, $gp
- %1 = call i64 @llvm.read_register.i64(metadata !0)
+ %1 = call i64 @llvm.read_register.i64(metadata !1)
+ ret i64 %1
+}
+
+define i64 @get_$gp() {
+; CHECK-LABEL: get_$gp:
+; CHECK: # %bb.0:
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: move $2, $gp
+ %1 = call i64 @llvm.read_register.i64(metadata !2)
+ ret i64 %1
+}
+
+define i64 @get_$29() {
+; CHECK-LABEL: get_$29:
+; CHECK: # %bb.0:
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: move $2, $sp
+ %1 = call i64 @llvm.read_register.i64(metadata !3)
ret i64 %1
}
@@ -18,12 +45,29 @@ define i64 @get_sp() {
; CHECK: # %bb.0:
; CHECK-NEXT: jr $ra
; CHECK-NEXT: move $2, $sp
- %1 = call i64 @llvm.read_register.i64(metadata !1)
+ %1 = call i64 @llvm.read_register.i64(metadata !4)
+ ret i64 %1
+}
+
+define i64 @get_$sp() {
+; CHECK-LABEL: get_$sp:
+; CHECK: # %bb.0:
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: move $2, $sp
+ %1 = call i64 @llvm.read_register.i64(metadata !5)
ret i64 %1
}
!llvm.named.register.$28 = !{!0}
-!llvm.named.register.sp = !{!1}
+!llvm.named.register.gp = !{!1}
+!llvm.named.register.$gp = !{!2}
+!llvm.named.register.$29 = !{!3}
+!llvm.named.register.sp = !{!4}
+!llvm.named.register.$sp = !{!5}
!0 = !{!"$28"}
-!1 = !{!"sp"}
+!1 = !{!"gp"}
+!2 = !{!"$gp"}
+!3 = !{!"$29"}
+!4 = !{!"sp"}
+!5 = !{!"$sp"}
diff --git a/llvm/test/CodeGen/Mips/named-register-o32.ll b/llvm/test/CodeGen/Mips/named-register-o32.ll
index 280c56e4db6a4..c01c110bcbd77 100644
--- a/llvm/test/CodeGen/Mips/named-register-o32.ll
+++ b/llvm/test/CodeGen/Mips/named-register-o32.ll
@@ -4,12 +4,39 @@
declare i32 @llvm.read_register.i32(metadata)
+define i32 @get_$28() {
+; CHECK-LABEL: get_$28:
+; CHECK: # %bb.0:
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: move $2, $gp
+ %1 = call i32 @llvm.read_register.i32(metadata !0)
+ ret i32 %1
+}
+
define i32 @get_gp() {
; CHECK-LABEL: get_gp:
; CHECK: # %bb.0:
; CHECK-NEXT: jr $ra
; CHECK-NEXT: move $2, $gp
- %1 = call i32 @llvm.read_register.i32(metadata !0)
+ %1 = call i32 @llvm.read_register.i32(metadata !1)
+ ret i32 %1
+}
+
+define i32 @get_$gp() {
+; CHECK-LABEL: get_$gp:
+; CHECK: # %bb.0:
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: move $2, $gp
+ %1 = call i32 @llvm.read_register.i32(metadata !2)
+ ret i32 %1
+}
+
+define i32 @get_$29() {
+; CHECK-LABEL: get_$29:
+; CHECK: # %bb.0:
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: move $2, $sp
+ %1 = call i32 @llvm.read_register.i32(metadata !3)
ret i32 %1
}
@@ -18,12 +45,29 @@ define i32 @get_sp() {
; CHECK: # %bb.0:
; CHECK-NEXT: jr $ra
; CHECK-NEXT: move $2, $sp
- %1 = call i32 @llvm.read_register.i32(metadata !1)
+ %1 = call i32 @llvm.read_register.i32(metadata !4)
+ ret i32 %1
+}
+
+define i32 @get_$sp() {
+; CHECK-LABEL: get_$sp:
+; CHECK: # %bb.0:
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: move $2, $sp
+ %1 = call i32 @llvm.read_register.i32(metadata !5)
ret i32 %1
}
!llvm.named.register.$28 = !{!0}
-!llvm.named.register.sp = !{!1}
+!llvm.named.register.gp = !{!1}
+!llvm.named.register.$gp = !{!2}
+!llvm.named.register.$29 = !{!3}
+!llvm.named.register.sp = !{!4}
+!llvm.named.register.$sp = !{!5}
!0 = !{!"$28"}
-!1 = !{!"sp"}
+!1 = !{!"gp"}
+!2 = !{!"$gp"}
+!3 = !{!"$29"}
+!4 = !{!"sp"}
+!5 = !{!"$sp"}
|
OK, updated. |
Fix #47656.