| Jia Liu | 9f61011 | 2012-02-17 08:55:11 +0000 | [diff] [blame] | 1 | //===-- MipsMachineFunctionInfo.cpp - Private data used for Mips ----------===// |
| David Blaikie | a379b181 | 2011-12-20 02:50:00 +0000 | [diff] [blame] | 2 | // |
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| David Blaikie | a379b181 | 2011-12-20 02:50:00 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| Chandler Carruth | 71f308a | 2015-02-13 09:09:03 +0000 | [diff] [blame] | 9 | #include "MipsMachineFunction.h" |
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 10 | #include "MCTargetDesc/MipsABIInfo.h" |
| Akira Hatanaka | b049aef | 2012-02-24 22:34:47 +0000 | [diff] [blame] | 11 | #include "MipsSubtarget.h" |
| Eric Christopher | 96e72c6 | 2015-01-29 23:27:36 +0000 | [diff] [blame] | 12 | #include "MipsTargetMachine.h" |
| Eugene Zelenko | dde94e4 | 2017-01-30 23:21:32 +0000 | [diff] [blame] | 13 | #include "llvm/CodeGen/MachineFrameInfo.h" |
| Akira Hatanaka | b049aef | 2012-02-24 22:34:47 +0000 | [diff] [blame] | 14 | #include "llvm/CodeGen/MachineRegisterInfo.h" |
| Eugene Zelenko | dde94e4 | 2017-01-30 23:21:32 +0000 | [diff] [blame] | 15 | #include "llvm/CodeGen/PseudoSourceValue.h" |
| David Blaikie | b3bde2e | 2017-11-17 01:07:10 +0000 | [diff] [blame] | 16 | #include "llvm/CodeGen/TargetRegisterInfo.h" |
| Akira Hatanaka | b049aef | 2012-02-24 22:34:47 +0000 | [diff] [blame] | 17 | #include "llvm/Support/CommandLine.h" |
| David Blaikie | a379b181 | 2011-12-20 02:50:00 +0000 | [diff] [blame] | 18 | |
| 19 | using namespace llvm; |
| 20 | |
| Akira Hatanaka | b049aef | 2012-02-24 22:34:47 +0000 | [diff] [blame] | 21 | static cl::opt<bool> |
| 22 | FixGlobalBaseReg("mips-fix-global-base-reg", cl::Hidden, cl::init(true), |
| 23 | cl::desc("Always use $gp as the global base register.")); |
| 24 | |
| Eugene Zelenko | dde94e4 | 2017-01-30 23:21:32 +0000 | [diff] [blame] | 25 | MipsFunctionInfo::~MipsFunctionInfo() = default; |
| Akira Hatanaka | e0657b2 | 2013-09-27 22:30:36 +0000 | [diff] [blame] | 26 | |
| Akira Hatanaka | b049aef | 2012-02-24 22:34:47 +0000 | [diff] [blame] | 27 | bool MipsFunctionInfo::globalBaseRegSet() const { |
| 28 | return GlobalBaseReg; |
| 29 | } |
| 30 | |
| Simon Atanasyan | 2c5b18f | 2018-07-21 16:16:08 +0000 | [diff] [blame] | 31 | static const TargetRegisterClass &getGlobalBaseRegClass(MachineFunction &MF) { |
| 32 | auto &STI = static_cast<const MipsSubtarget &>(MF.getSubtarget()); |
| 33 | auto &TM = static_cast<const MipsTargetMachine &>(MF.getTarget()); |
| 34 | |
| 35 | if (STI.inMips16Mode()) |
| 36 | return Mips::CPU16RegsRegClass; |
| 37 | |
| 38 | if (STI.inMicroMipsMode()) |
| 39 | return Mips::GPRMM16RegClass; |
| 40 | |
| 41 | if (TM.getABI().IsN64()) |
| 42 | return Mips::GPR64RegClass; |
| 43 | |
| 44 | return Mips::GPR32RegClass; |
| 45 | } |
| 46 | |
| Matt Arsenault | faeaedf | 2019-06-24 16:16:12 +0000 | [diff] [blame] | 47 | Register MipsFunctionInfo::getGlobalBaseReg() { |
| Simon Atanasyan | 2c5b18f | 2018-07-21 16:16:08 +0000 | [diff] [blame] | 48 | if (!GlobalBaseReg) |
| 49 | GlobalBaseReg = |
| 50 | MF.getRegInfo().createVirtualRegister(&getGlobalBaseRegClass(MF)); |
| 51 | return GlobalBaseReg; |
| Akira Hatanaka | b049aef | 2012-02-24 22:34:47 +0000 | [diff] [blame] | 52 | } |
| 53 | |
| Matt Arsenault | faeaedf | 2019-06-24 16:16:12 +0000 | [diff] [blame] | 54 | Register MipsFunctionInfo::getGlobalBaseRegForGlobalISel() { |
| Petar Avramovic | efcd3c0 | 2019-05-31 08:27:06 +0000 | [diff] [blame] | 55 | if (!GlobalBaseReg) { |
| 56 | getGlobalBaseReg(); |
| 57 | initGlobalBaseReg(); |
| 58 | } |
| 59 | return GlobalBaseReg; |
| 60 | } |
| 61 | |
| Petar Avramovic | 9058b50 | 2019-05-31 08:15:28 +0000 | [diff] [blame] | 62 | void MipsFunctionInfo::initGlobalBaseReg() { |
| 63 | if (!GlobalBaseReg) |
| 64 | return; |
| 65 | |
| 66 | MachineBasicBlock &MBB = MF.front(); |
| 67 | MachineBasicBlock::iterator I = MBB.begin(); |
| 68 | MachineRegisterInfo &RegInfo = MF.getRegInfo(); |
| 69 | const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); |
| 70 | DebugLoc DL; |
| 71 | unsigned V0, V1; |
| 72 | const TargetRegisterClass *RC; |
| 73 | const MipsABIInfo &ABI = |
| 74 | static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI(); |
| 75 | RC = (ABI.IsN64()) ? &Mips::GPR64RegClass : &Mips::GPR32RegClass; |
| 76 | |
| 77 | V0 = RegInfo.createVirtualRegister(RC); |
| 78 | V1 = RegInfo.createVirtualRegister(RC); |
| 79 | |
| 80 | if (ABI.IsN64()) { |
| 81 | MF.getRegInfo().addLiveIn(Mips::T9_64); |
| 82 | MBB.addLiveIn(Mips::T9_64); |
| 83 | |
| 84 | // lui $v0, %hi(%neg(%gp_rel(fname))) |
| 85 | // daddu $v1, $v0, $t9 |
| 86 | // daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname))) |
| 87 | const GlobalValue *FName = &MF.getFunction(); |
| 88 | BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0) |
| 89 | .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI); |
| 90 | BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0) |
| 91 | .addReg(Mips::T9_64); |
| 92 | BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1) |
| 93 | .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO); |
| 94 | return; |
| 95 | } |
| 96 | |
| 97 | if (!MF.getTarget().isPositionIndependent()) { |
| 98 | // Set global register to __gnu_local_gp. |
| 99 | // |
| 100 | // lui $v0, %hi(__gnu_local_gp) |
| 101 | // addiu $globalbasereg, $v0, %lo(__gnu_local_gp) |
| 102 | BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0) |
| 103 | .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI); |
| 104 | BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0) |
| 105 | .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO); |
| 106 | return; |
| 107 | } |
| 108 | |
| 109 | MF.getRegInfo().addLiveIn(Mips::T9); |
| 110 | MBB.addLiveIn(Mips::T9); |
| 111 | |
| 112 | if (ABI.IsN32()) { |
| 113 | // lui $v0, %hi(%neg(%gp_rel(fname))) |
| 114 | // addu $v1, $v0, $t9 |
| 115 | // addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname))) |
| 116 | const GlobalValue *FName = &MF.getFunction(); |
| 117 | BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0) |
| 118 | .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI); |
| 119 | BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9); |
| 120 | BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1) |
| 121 | .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO); |
| 122 | return; |
| 123 | } |
| 124 | |
| 125 | assert(ABI.IsO32()); |
| 126 | |
| 127 | // For O32 ABI, the following instruction sequence is emitted to initialize |
| 128 | // the global base register: |
| 129 | // |
| 130 | // 0. lui $2, %hi(_gp_disp) |
| 131 | // 1. addiu $2, $2, %lo(_gp_disp) |
| 132 | // 2. addu $globalbasereg, $2, $t9 |
| 133 | // |
| 134 | // We emit only the last instruction here. |
| 135 | // |
| 136 | // GNU linker requires that the first two instructions appear at the beginning |
| 137 | // of a function and no instructions be inserted before or between them. |
| 138 | // The two instructions are emitted during lowering to MC layer in order to |
| 139 | // avoid any reordering. |
| 140 | // |
| 141 | // Register $2 (Mips::V0) is added to the list of live-in registers to ensure |
| 142 | // the value instruction 1 (addiu) defines is valid when instruction 2 (addu) |
| 143 | // reads it. |
| 144 | MF.getRegInfo().addLiveIn(Mips::V0); |
| 145 | MBB.addLiveIn(Mips::V0); |
| 146 | BuildMI(MBB, I, DL, TII.get(Mips::ADDu), GlobalBaseReg) |
| 147 | .addReg(Mips::V0).addReg(Mips::T9); |
| 148 | } |
| 149 | |
| Akira Hatanaka | c0b0206 | 2013-01-30 00:26:49 +0000 | [diff] [blame] | 150 | void MipsFunctionInfo::createEhDataRegsFI() { |
| Krzysztof Parzyszek | 44e25f3 | 2017-04-24 18:55:33 +0000 | [diff] [blame] | 151 | const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); |
| Akira Hatanaka | c0b0206 | 2013-01-30 00:26:49 +0000 | [diff] [blame] | 152 | for (int I = 0; I < 4; ++I) { |
| Krzysztof Parzyszek | 44e25f3 | 2017-04-24 18:55:33 +0000 | [diff] [blame] | 153 | const TargetRegisterClass &RC = |
| Eric Christopher | 96e72c6 | 2015-01-29 23:27:36 +0000 | [diff] [blame] | 154 | static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI().IsN64() |
| Krzysztof Parzyszek | 44e25f3 | 2017-04-24 18:55:33 +0000 | [diff] [blame] | 155 | ? Mips::GPR64RegClass |
| 156 | : Mips::GPR32RegClass; |
| Akira Hatanaka | c0b0206 | 2013-01-30 00:26:49 +0000 | [diff] [blame] | 157 | |
| Krzysztof Parzyszek | 44e25f3 | 2017-04-24 18:55:33 +0000 | [diff] [blame] | 158 | EhDataRegFI[I] = MF.getFrameInfo().CreateStackObject(TRI.getSpillSize(RC), |
| 159 | TRI.getSpillAlignment(RC), false); |
| Akira Hatanaka | c0b0206 | 2013-01-30 00:26:49 +0000 | [diff] [blame] | 160 | } |
| 161 | } |
| 162 | |
| Vasileios Kalintiris | 43dff0c | 2015-10-26 12:38:43 +0000 | [diff] [blame] | 163 | void MipsFunctionInfo::createISRRegFI() { |
| 164 | // ISRs require spill slots for Status & ErrorPC Coprocessor 0 registers. |
| 165 | // The current implementation only supports Mips32r2+ not Mips64rX. Status |
| Simon Pilgrim | dcd8433 | 2016-11-18 11:53:36 +0000 | [diff] [blame] | 166 | // is always 32 bits, ErrorPC is 32 or 64 bits dependent on architecture, |
| Vasileios Kalintiris | 43dff0c | 2015-10-26 12:38:43 +0000 | [diff] [blame] | 167 | // however Mips32r2+ is the supported architecture. |
| Krzysztof Parzyszek | 44e25f3 | 2017-04-24 18:55:33 +0000 | [diff] [blame] | 168 | const TargetRegisterClass &RC = Mips::GPR32RegClass; |
| 169 | const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); |
| Vasileios Kalintiris | 43dff0c | 2015-10-26 12:38:43 +0000 | [diff] [blame] | 170 | |
| 171 | for (int I = 0; I < 2; ++I) |
| Matthias Braun | 941a705 | 2016-07-28 18:40:00 +0000 | [diff] [blame] | 172 | ISRDataRegFI[I] = MF.getFrameInfo().CreateStackObject( |
| Krzysztof Parzyszek | 44e25f3 | 2017-04-24 18:55:33 +0000 | [diff] [blame] | 173 | TRI.getSpillSize(RC), TRI.getSpillAlignment(RC), false); |
| Vasileios Kalintiris | 43dff0c | 2015-10-26 12:38:43 +0000 | [diff] [blame] | 174 | } |
| 175 | |
| Akira Hatanaka | c0b0206 | 2013-01-30 00:26:49 +0000 | [diff] [blame] | 176 | bool MipsFunctionInfo::isEhDataRegFI(int FI) const { |
| 177 | return CallsEhReturn && (FI == EhDataRegFI[0] || FI == EhDataRegFI[1] |
| 178 | || FI == EhDataRegFI[2] || FI == EhDataRegFI[3]); |
| 179 | } |
| 180 | |
| Vasileios Kalintiris | 43dff0c | 2015-10-26 12:38:43 +0000 | [diff] [blame] | 181 | bool MipsFunctionInfo::isISRRegFI(int FI) const { |
| 182 | return IsISR && (FI == ISRDataRegFI[0] || FI == ISRDataRegFI[1]); |
| 183 | } |
| Alex Lorenz | 5659a2f | 2015-08-11 23:23:17 +0000 | [diff] [blame] | 184 | MachinePointerInfo MipsFunctionInfo::callPtrInfo(const char *ES) { |
| 185 | return MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES)); |
| Akira Hatanaka | e0657b2 | 2013-09-27 22:30:36 +0000 | [diff] [blame] | 186 | } |
| 187 | |
| Alex Lorenz | 5659a2f | 2015-08-11 23:23:17 +0000 | [diff] [blame] | 188 | MachinePointerInfo MipsFunctionInfo::callPtrInfo(const GlobalValue *GV) { |
| 189 | return MachinePointerInfo(MF.getPSVManager().getGlobalValueCallEntry(GV)); |
| Akira Hatanaka | e0657b2 | 2013-09-27 22:30:36 +0000 | [diff] [blame] | 190 | } |
| 191 | |
| Daniel Sanders | 7ddb0ab | 2014-07-14 13:08:14 +0000 | [diff] [blame] | 192 | int MipsFunctionInfo::getMoveF64ViaSpillFI(const TargetRegisterClass *RC) { |
| Krzysztof Parzyszek | 44e25f3 | 2017-04-24 18:55:33 +0000 | [diff] [blame] | 193 | const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); |
| Daniel Sanders | 7ddb0ab | 2014-07-14 13:08:14 +0000 | [diff] [blame] | 194 | if (MoveF64ViaSpillFI == -1) { |
| Matthias Braun | 941a705 | 2016-07-28 18:40:00 +0000 | [diff] [blame] | 195 | MoveF64ViaSpillFI = MF.getFrameInfo().CreateStackObject( |
| Krzysztof Parzyszek | 44e25f3 | 2017-04-24 18:55:33 +0000 | [diff] [blame] | 196 | TRI.getSpillSize(*RC), TRI.getSpillAlignment(*RC), false); |
| Sasa Stankovic | b976fee | 2014-07-14 09:40:29 +0000 | [diff] [blame] | 197 | } |
| Daniel Sanders | 7ddb0ab | 2014-07-14 13:08:14 +0000 | [diff] [blame] | 198 | return MoveF64ViaSpillFI; |
| Sasa Stankovic | b976fee | 2014-07-14 09:40:29 +0000 | [diff] [blame] | 199 | } |
| 200 | |
| Eugene Zelenko | dde94e4 | 2017-01-30 23:21:32 +0000 | [diff] [blame] | 201 | void MipsFunctionInfo::anchor() {} |