|
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 |
|
@@ -4938,25 +4940,101 @@ MipsTargetLowering::emitPseudoD_SELECT(MachineInstr &MI, |
4938 | 4940 | return BB; |
4939 | 4941 | } |
4940 | 4942 |
|
| 4943 | +// Copies the function MipsAsmParser::matchCPURegisterName. |
| 4944 | +int MipsTargetLowering::getCPURegisterIndex(StringRef Name) const { |
| 4945 | + int CC; |
| 4946 | + |
| 4947 | + CC = StringSwitch<unsigned>(Name) |
| 4948 | + .Case("zero", 0) |
| 4949 | + .Case("at", 1) |
| 4950 | + .Case("AT", 1) |
| 4951 | + .Case("a0", 4) |
| 4952 | + .Case("a1", 5) |
| 4953 | + .Case("a2", 6) |
| 4954 | + .Case("a3", 7) |
| 4955 | + .Case("v0", 2) |
| 4956 | + .Case("v1", 3) |
| 4957 | + .Case("s0", 16) |
| 4958 | + .Case("s1", 17) |
| 4959 | + .Case("s2", 18) |
| 4960 | + .Case("s3", 19) |
| 4961 | + .Case("s4", 20) |
| 4962 | + .Case("s5", 21) |
| 4963 | + .Case("s6", 22) |
| 4964 | + .Case("s7", 23) |
| 4965 | + .Case("k0", 26) |
| 4966 | + .Case("k1", 27) |
| 4967 | + .Case("gp", 28) |
| 4968 | + .Case("sp", 29) |
| 4969 | + .Case("fp", 30) |
| 4970 | + .Case("s8", 30) |
| 4971 | + .Case("ra", 31) |
| 4972 | + .Case("t0", 8) |
| 4973 | + .Case("t1", 9) |
| 4974 | + .Case("t2", 10) |
| 4975 | + .Case("t3", 11) |
| 4976 | + .Case("t4", 12) |
| 4977 | + .Case("t5", 13) |
| 4978 | + .Case("t6", 14) |
| 4979 | + .Case("t7", 15) |
| 4980 | + .Case("t8", 24) |
| 4981 | + .Case("t9", 25) |
| 4982 | + .Default(-1); |
| 4983 | + |
| 4984 | + if (!(ABI.IsN32() || ABI.IsN64())) |
| 4985 | + return CC; |
| 4986 | + |
| 4987 | + // Although SGI documentation just cuts out t0-t3 for n32/n64, |
| 4988 | + // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 |
| 4989 | + // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. |
| 4990 | + if (8 <= CC && CC <= 11) |
| 4991 | + CC += 4; |
| 4992 | + |
| 4993 | + if (CC == -1) |
| 4994 | + CC = StringSwitch<unsigned>(Name) |
| 4995 | + .Case("a4", 8) |
| 4996 | + .Case("a5", 9) |
| 4997 | + .Case("a6", 10) |
| 4998 | + .Case("a7", 11) |
| 4999 | + .Case("kt0", 26) |
| 5000 | + .Case("kt1", 27) |
| 5001 | + .Default(-1); |
| 5002 | + |
| 5003 | + return CC; |
| 5004 | +} |
| 5005 | + |
4941 | 5006 | // FIXME? Maybe this could be a TableGen attribute on some registers and |
4942 | 5007 | // this table could be generated automatically from RegInfo. |
4943 | 5008 | Register |
4944 | 5009 | MipsTargetLowering::getRegisterByName(const char *RegName, LLT VT, |
4945 | 5010 | const MachineFunction &MF) const { |
4946 | | - // The Linux kernel uses $28 and sp. |
4947 | | - if (Subtarget.isGP64bit()) { |
4948 | | - Register Reg = StringSwitch<Register>(RegName) |
4949 | | - .Case("$28", Mips::GP_64) |
4950 | | - .Case("sp", Mips::SP_64) |
4951 | | - .Default(Register()); |
4952 | | - return Reg; |
| 5011 | + // 1. Delete symbol '$'. |
| 5012 | + std::string newRegName = RegName; |
| 5013 | + if (StringRef(RegName).starts_with("$")) |
| 5014 | + newRegName = StringRef(RegName).substr(1); |
| 5015 | + |
| 5016 | + // 2. Get register index value. |
| 5017 | + std::smatch matchResult; |
| 5018 | + int regIdx; |
| 5019 | + static const std::regex matchStr("^[0-9]*$"); |
| 5020 | + if (std::regex_match(newRegName, matchResult, matchStr)) |
| 5021 | + regIdx = std::stoi(newRegName); |
| 5022 | + else { |
| 5023 | + newRegName = StringRef(newRegName).lower(); |
| 5024 | + regIdx = getCPURegisterIndex(StringRef(newRegName)); |
| 5025 | + } |
| 5026 | + |
| 5027 | + // 3. Get register. |
| 5028 | + if (regIdx >= 0 && regIdx < 32) { |
| 5029 | + const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo(); |
| 5030 | + const MCRegisterClass &RC = Subtarget.isGP64bit() |
| 5031 | + ? MRI->getRegClass(Mips::GPR64RegClassID) |
| 5032 | + : MRI->getRegClass(Mips::GPR32RegClassID); |
| 5033 | + return RC.getRegister(regIdx); |
4953 | 5034 | } |
4954 | 5035 |
|
4955 | | - Register Reg = StringSwitch<Register>(RegName) |
4956 | | - .Case("$28", Mips::GP) |
4957 | | - .Case("sp", Mips::SP) |
4958 | | - .Default(Register()); |
4959 | | - return Reg; |
| 5036 | + report_fatal_error( |
| 5037 | + Twine("Invalid register name \"" + StringRef(RegName) + "\".")); |
4960 | 5038 | } |
4961 | 5039 |
|
4962 | 5040 | MachineBasicBlock *MipsTargetLowering::emitLDR_W(MachineInstr &MI, |
|
0 commit comments