-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[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. |
| if (StringRef(RegName).starts_with("$")) | ||
| newRegName = StringRef(RegName).substr(1); | ||
|
|
||
| // 2. Check if number [0-31], then transform to int. |
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.
here the code is duplicated.
In fact we can get the register index first for any case, and then getRegister(regIdx).
| if (std::regex_match(newRegName, matchResult, matchStr)) { | ||
| int regIdx = std::stoi(newRegName); | ||
| if (regIdx >= 0 && regIdx < 32) { | ||
| return Subtarget.isGP64bit() ? MF.getContext() |
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.
Use something like
RegClass = Subtarget.isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID;
so that we can reduce code duplication.
| !llvm.named.register.$gp = !{!2} | ||
| !llvm.named.register.$29 = !{!3} | ||
| !llvm.named.register.sp = !{!4} | ||
| !llvm.named.register.$sp = !{!5} |
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.
we need tests to cover all of these register 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.
Hi, I have appended tests with all regs, could you help review again?
50264fb to
4bf9d38
Compare
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
d8527f7 to
23dfa8c
Compare
23dfa8c to
c6357cc
Compare
|
cc @wzssyqa |
Fix #47656.