|
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 |
|
@@ -4865,25 +4867,101 @@ MipsTargetLowering::emitPseudoD_SELECT(MachineInstr &MI, |
4865 | 4867 | return BB; |
4866 | 4868 | } |
4867 | 4869 |
|
| 4870 | +// Copies the function MipsAsmParser::matchCPURegisterName. |
| 4871 | +int MipsTargetLowering::getCPURegisterIndex(StringRef Name) const { |
| 4872 | + int CC; |
| 4873 | + |
| 4874 | + CC = StringSwitch<unsigned>(Name) |
| 4875 | + .Case("zero", 0) |
| 4876 | + .Case("at", 1) |
| 4877 | + .Case("AT", 1) |
| 4878 | + .Case("a0", 4) |
| 4879 | + .Case("a1", 5) |
| 4880 | + .Case("a2", 6) |
| 4881 | + .Case("a3", 7) |
| 4882 | + .Case("v0", 2) |
| 4883 | + .Case("v1", 3) |
| 4884 | + .Case("s0", 16) |
| 4885 | + .Case("s1", 17) |
| 4886 | + .Case("s2", 18) |
| 4887 | + .Case("s3", 19) |
| 4888 | + .Case("s4", 20) |
| 4889 | + .Case("s5", 21) |
| 4890 | + .Case("s6", 22) |
| 4891 | + .Case("s7", 23) |
| 4892 | + .Case("k0", 26) |
| 4893 | + .Case("k1", 27) |
| 4894 | + .Case("gp", 28) |
| 4895 | + .Case("sp", 29) |
| 4896 | + .Case("fp", 30) |
| 4897 | + .Case("s8", 30) |
| 4898 | + .Case("ra", 31) |
| 4899 | + .Case("t0", 8) |
| 4900 | + .Case("t1", 9) |
| 4901 | + .Case("t2", 10) |
| 4902 | + .Case("t3", 11) |
| 4903 | + .Case("t4", 12) |
| 4904 | + .Case("t5", 13) |
| 4905 | + .Case("t6", 14) |
| 4906 | + .Case("t7", 15) |
| 4907 | + .Case("t8", 24) |
| 4908 | + .Case("t9", 25) |
| 4909 | + .Default(-1); |
| 4910 | + |
| 4911 | + if (!(ABI.IsN32() || ABI.IsN64())) |
| 4912 | + return CC; |
| 4913 | + |
| 4914 | + // Although SGI documentation just cuts out t0-t3 for n32/n64, |
| 4915 | + // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 |
| 4916 | + // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. |
| 4917 | + if (8 <= CC && CC <= 11) |
| 4918 | + CC += 4; |
| 4919 | + |
| 4920 | + if (CC == -1) |
| 4921 | + CC = StringSwitch<unsigned>(Name) |
| 4922 | + .Case("a4", 8) |
| 4923 | + .Case("a5", 9) |
| 4924 | + .Case("a6", 10) |
| 4925 | + .Case("a7", 11) |
| 4926 | + .Case("kt0", 26) |
| 4927 | + .Case("kt1", 27) |
| 4928 | + .Default(-1); |
| 4929 | + |
| 4930 | + return CC; |
| 4931 | +} |
| 4932 | + |
4868 | 4933 | // FIXME? Maybe this could be a TableGen attribute on some registers and |
4869 | 4934 | // this table could be generated automatically from RegInfo. |
4870 | 4935 | Register |
4871 | 4936 | MipsTargetLowering::getRegisterByName(const char *RegName, LLT VT, |
4872 | 4937 | const MachineFunction &MF) const { |
4873 | | - // The Linux kernel uses $28 and sp. |
4874 | | - if (Subtarget.isGP64bit()) { |
4875 | | - Register Reg = StringSwitch<Register>(RegName) |
4876 | | - .Case("$28", Mips::GP_64) |
4877 | | - .Case("sp", Mips::SP_64) |
4878 | | - .Default(Register()); |
4879 | | - return Reg; |
| 4938 | + // 1. Delete symbol '$'. |
| 4939 | + std::string newRegName = RegName; |
| 4940 | + if (StringRef(RegName).starts_with("$")) |
| 4941 | + newRegName = StringRef(RegName).substr(1); |
| 4942 | + |
| 4943 | + // 2. Get register index value. |
| 4944 | + std::smatch matchResult; |
| 4945 | + int regIdx; |
| 4946 | + static const std::regex matchStr("^[0-9]*$"); |
| 4947 | + if (std::regex_match(newRegName, matchResult, matchStr)) |
| 4948 | + regIdx = std::stoi(newRegName); |
| 4949 | + else { |
| 4950 | + newRegName = StringRef(newRegName).lower(); |
| 4951 | + regIdx = getCPURegisterIndex(StringRef(newRegName)); |
| 4952 | + } |
| 4953 | + |
| 4954 | + // 3. Get register. |
| 4955 | + if (regIdx >= 0 && regIdx < 32) { |
| 4956 | + const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo(); |
| 4957 | + const MCRegisterClass &RC = Subtarget.isGP64bit() |
| 4958 | + ? MRI->getRegClass(Mips::GPR64RegClassID) |
| 4959 | + : MRI->getRegClass(Mips::GPR32RegClassID); |
| 4960 | + return RC.getRegister(regIdx); |
4880 | 4961 | } |
4881 | 4962 |
|
4882 | | - Register Reg = StringSwitch<Register>(RegName) |
4883 | | - .Case("$28", Mips::GP) |
4884 | | - .Case("sp", Mips::SP) |
4885 | | - .Default(Register()); |
4886 | | - return Reg; |
| 4963 | + report_fatal_error( |
| 4964 | + Twine("Invalid register name \"" + StringRef(RegName) + "\".")); |
4887 | 4965 | } |
4888 | 4966 |
|
4889 | 4967 | MachineBasicBlock *MipsTargetLowering::emitLDR_W(MachineInstr &MI, |
|
0 commit comments