|
72 | 72 | #include <cstdint> |
73 | 73 | #include <deque> |
74 | 74 | #include <iterator> |
| 75 | +#include <regex> |
| 76 | +#include <string> |
75 | 77 | #include <utility> |
76 | 78 | #include <vector> |
77 | 79 |
|
@@ -4888,28 +4890,111 @@ MipsTargetLowering::emitPseudoD_SELECT(MachineInstr &MI, |
4888 | 4890 | return BB; |
4889 | 4891 | } |
4890 | 4892 |
|
| 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 | + |
4891 | 4955 | // FIXME? Maybe this could be a TableGen attribute on some registers and |
4892 | 4956 | // this table could be generated automatically from RegInfo. |
4893 | 4957 | Register |
4894 | 4958 | MipsTargetLowering::getRegisterByName(const char *RegName, LLT VT, |
4895 | 4959 | 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); |
4911 | 4994 | } |
4912 | | - report_fatal_error("Invalid register name global variable"); |
| 4995 | + |
| 4996 | + report_fatal_error( |
| 4997 | + Twine("Invalid register name \"" + StringRef(RegName) + "\".")); |
4913 | 4998 | } |
4914 | 4999 |
|
4915 | 5000 | MachineBasicBlock *MipsTargetLowering::emitLDR_W(MachineInstr &MI, |
|
0 commit comments