109467b48Spatrick //===-- RISCVExpandPseudoInsts.cpp - Expand pseudo instructions -----------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file contains a pass that expands pseudo instructions into target
1009467b48Spatrick // instructions. This pass should be run after register allocation but before
1109467b48Spatrick // the post-regalloc scheduling pass.
1209467b48Spatrick //
1309467b48Spatrick //===----------------------------------------------------------------------===//
1409467b48Spatrick
1509467b48Spatrick #include "RISCV.h"
1609467b48Spatrick #include "RISCVInstrInfo.h"
1709467b48Spatrick #include "RISCVTargetMachine.h"
1809467b48Spatrick
1909467b48Spatrick #include "llvm/CodeGen/LivePhysRegs.h"
2009467b48Spatrick #include "llvm/CodeGen/MachineFunctionPass.h"
2109467b48Spatrick #include "llvm/CodeGen/MachineInstrBuilder.h"
22*d415bd75Srobert #include "llvm/MC/MCContext.h"
2309467b48Spatrick
2409467b48Spatrick using namespace llvm;
2509467b48Spatrick
2609467b48Spatrick #define RISCV_EXPAND_PSEUDO_NAME "RISCV pseudo instruction expansion pass"
27*d415bd75Srobert #define RISCV_PRERA_EXPAND_PSEUDO_NAME "RISCV Pre-RA pseudo instruction expansion pass"
2809467b48Spatrick
2909467b48Spatrick namespace {
3009467b48Spatrick
3109467b48Spatrick class RISCVExpandPseudo : public MachineFunctionPass {
3209467b48Spatrick public:
3309467b48Spatrick const RISCVInstrInfo *TII;
3409467b48Spatrick static char ID;
3509467b48Spatrick
RISCVExpandPseudo()3609467b48Spatrick RISCVExpandPseudo() : MachineFunctionPass(ID) {
3709467b48Spatrick initializeRISCVExpandPseudoPass(*PassRegistry::getPassRegistry());
3809467b48Spatrick }
3909467b48Spatrick
4009467b48Spatrick bool runOnMachineFunction(MachineFunction &MF) override;
4109467b48Spatrick
getPassName() const4209467b48Spatrick StringRef getPassName() const override { return RISCV_EXPAND_PSEUDO_NAME; }
4309467b48Spatrick
4409467b48Spatrick private:
4509467b48Spatrick bool expandMBB(MachineBasicBlock &MBB);
4609467b48Spatrick bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
4709467b48Spatrick MachineBasicBlock::iterator &NextMBBI);
48*d415bd75Srobert bool expandCCOp(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
4909467b48Spatrick MachineBasicBlock::iterator &NextMBBI);
5073471bf0Spatrick bool expandVSetVL(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI);
5173471bf0Spatrick bool expandVMSET_VMCLR(MachineBasicBlock &MBB,
5273471bf0Spatrick MachineBasicBlock::iterator MBBI, unsigned Opcode);
5309467b48Spatrick };
5409467b48Spatrick
5509467b48Spatrick char RISCVExpandPseudo::ID = 0;
5609467b48Spatrick
runOnMachineFunction(MachineFunction & MF)5709467b48Spatrick bool RISCVExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
5809467b48Spatrick TII = static_cast<const RISCVInstrInfo *>(MF.getSubtarget().getInstrInfo());
5909467b48Spatrick bool Modified = false;
6009467b48Spatrick for (auto &MBB : MF)
6109467b48Spatrick Modified |= expandMBB(MBB);
6209467b48Spatrick return Modified;
6309467b48Spatrick }
6409467b48Spatrick
expandMBB(MachineBasicBlock & MBB)6509467b48Spatrick bool RISCVExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
6609467b48Spatrick bool Modified = false;
6709467b48Spatrick
6809467b48Spatrick MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
6909467b48Spatrick while (MBBI != E) {
7009467b48Spatrick MachineBasicBlock::iterator NMBBI = std::next(MBBI);
7109467b48Spatrick Modified |= expandMI(MBB, MBBI, NMBBI);
7209467b48Spatrick MBBI = NMBBI;
7309467b48Spatrick }
7409467b48Spatrick
7509467b48Spatrick return Modified;
7609467b48Spatrick }
7709467b48Spatrick
expandMI(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,MachineBasicBlock::iterator & NextMBBI)7809467b48Spatrick bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB,
7909467b48Spatrick MachineBasicBlock::iterator MBBI,
8009467b48Spatrick MachineBasicBlock::iterator &NextMBBI) {
81*d415bd75Srobert // RISCVInstrInfo::getInstSizeInBytes expects that the total size of the
82*d415bd75Srobert // expanded instructions for each pseudo is correct in the Size field of the
83*d415bd75Srobert // tablegen definition for the pseudo.
8409467b48Spatrick switch (MBBI->getOpcode()) {
85*d415bd75Srobert case RISCV::PseudoCCMOVGPR:
86*d415bd75Srobert case RISCV::PseudoCCADD:
87*d415bd75Srobert case RISCV::PseudoCCSUB:
88*d415bd75Srobert case RISCV::PseudoCCAND:
89*d415bd75Srobert case RISCV::PseudoCCOR:
90*d415bd75Srobert case RISCV::PseudoCCXOR:
91*d415bd75Srobert case RISCV::PseudoCCADDW:
92*d415bd75Srobert case RISCV::PseudoCCSUBW:
93*d415bd75Srobert return expandCCOp(MBB, MBBI, NextMBBI);
9473471bf0Spatrick case RISCV::PseudoVSETVLI:
95*d415bd75Srobert case RISCV::PseudoVSETVLIX0:
9673471bf0Spatrick case RISCV::PseudoVSETIVLI:
9773471bf0Spatrick return expandVSetVL(MBB, MBBI);
9873471bf0Spatrick case RISCV::PseudoVMCLR_M_B1:
9973471bf0Spatrick case RISCV::PseudoVMCLR_M_B2:
10073471bf0Spatrick case RISCV::PseudoVMCLR_M_B4:
10173471bf0Spatrick case RISCV::PseudoVMCLR_M_B8:
10273471bf0Spatrick case RISCV::PseudoVMCLR_M_B16:
10373471bf0Spatrick case RISCV::PseudoVMCLR_M_B32:
10473471bf0Spatrick case RISCV::PseudoVMCLR_M_B64:
10573471bf0Spatrick // vmclr.m vd => vmxor.mm vd, vd, vd
10673471bf0Spatrick return expandVMSET_VMCLR(MBB, MBBI, RISCV::VMXOR_MM);
10773471bf0Spatrick case RISCV::PseudoVMSET_M_B1:
10873471bf0Spatrick case RISCV::PseudoVMSET_M_B2:
10973471bf0Spatrick case RISCV::PseudoVMSET_M_B4:
11073471bf0Spatrick case RISCV::PseudoVMSET_M_B8:
11173471bf0Spatrick case RISCV::PseudoVMSET_M_B16:
11273471bf0Spatrick case RISCV::PseudoVMSET_M_B32:
11373471bf0Spatrick case RISCV::PseudoVMSET_M_B64:
11473471bf0Spatrick // vmset.m vd => vmxnor.mm vd, vd, vd
11573471bf0Spatrick return expandVMSET_VMCLR(MBB, MBBI, RISCV::VMXNOR_MM);
11609467b48Spatrick }
11709467b48Spatrick
11809467b48Spatrick return false;
11909467b48Spatrick }
12009467b48Spatrick
expandCCOp(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,MachineBasicBlock::iterator & NextMBBI)121*d415bd75Srobert bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
122*d415bd75Srobert MachineBasicBlock::iterator MBBI,
123*d415bd75Srobert MachineBasicBlock::iterator &NextMBBI) {
124*d415bd75Srobert
12509467b48Spatrick MachineFunction *MF = MBB.getParent();
12609467b48Spatrick MachineInstr &MI = *MBBI;
12709467b48Spatrick DebugLoc DL = MI.getDebugLoc();
12809467b48Spatrick
129*d415bd75Srobert MachineBasicBlock *TrueBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
130*d415bd75Srobert MachineBasicBlock *MergeBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
131*d415bd75Srobert
132*d415bd75Srobert MF->insert(++MBB.getIterator(), TrueBB);
133*d415bd75Srobert MF->insert(++TrueBB->getIterator(), MergeBB);
134*d415bd75Srobert
135*d415bd75Srobert // We want to copy the "true" value when the condition is true which means
136*d415bd75Srobert // we need to invert the branch condition to jump over TrueBB when the
137*d415bd75Srobert // condition is false.
138*d415bd75Srobert auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
139*d415bd75Srobert CC = RISCVCC::getOppositeBranchCondition(CC);
140*d415bd75Srobert
141*d415bd75Srobert // Insert branch instruction.
142*d415bd75Srobert BuildMI(MBB, MBBI, DL, TII->getBrCond(CC))
143*d415bd75Srobert .addReg(MI.getOperand(1).getReg())
144*d415bd75Srobert .addReg(MI.getOperand(2).getReg())
145*d415bd75Srobert .addMBB(MergeBB);
146*d415bd75Srobert
14709467b48Spatrick Register DestReg = MI.getOperand(0).getReg();
148*d415bd75Srobert assert(MI.getOperand(4).getReg() == DestReg);
14909467b48Spatrick
150*d415bd75Srobert if (MI.getOpcode() == RISCV::PseudoCCMOVGPR) {
151*d415bd75Srobert // Add MV.
152*d415bd75Srobert BuildMI(TrueBB, DL, TII->get(RISCV::ADDI), DestReg)
153*d415bd75Srobert .add(MI.getOperand(5))
154*d415bd75Srobert .addImm(0);
155*d415bd75Srobert } else {
156*d415bd75Srobert unsigned NewOpc;
157*d415bd75Srobert switch (MI.getOpcode()) {
158*d415bd75Srobert default:
159*d415bd75Srobert llvm_unreachable("Unexpected opcode!");
160*d415bd75Srobert case RISCV::PseudoCCADD: NewOpc = RISCV::ADD; break;
161*d415bd75Srobert case RISCV::PseudoCCSUB: NewOpc = RISCV::SUB; break;
162*d415bd75Srobert case RISCV::PseudoCCAND: NewOpc = RISCV::AND; break;
163*d415bd75Srobert case RISCV::PseudoCCOR: NewOpc = RISCV::OR; break;
164*d415bd75Srobert case RISCV::PseudoCCXOR: NewOpc = RISCV::XOR; break;
165*d415bd75Srobert case RISCV::PseudoCCADDW: NewOpc = RISCV::ADDW; break;
166*d415bd75Srobert case RISCV::PseudoCCSUBW: NewOpc = RISCV::SUBW; break;
167*d415bd75Srobert }
168*d415bd75Srobert BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg)
169*d415bd75Srobert .add(MI.getOperand(5))
170*d415bd75Srobert .add(MI.getOperand(6));
171*d415bd75Srobert }
17209467b48Spatrick
173*d415bd75Srobert TrueBB->addSuccessor(MergeBB);
17409467b48Spatrick
175*d415bd75Srobert MergeBB->splice(MergeBB->end(), &MBB, MI, MBB.end());
176*d415bd75Srobert MergeBB->transferSuccessors(&MBB);
17709467b48Spatrick
178*d415bd75Srobert MBB.addSuccessor(TrueBB);
179*d415bd75Srobert MBB.addSuccessor(MergeBB);
18009467b48Spatrick
18109467b48Spatrick NextMBBI = MBB.end();
18209467b48Spatrick MI.eraseFromParent();
183*d415bd75Srobert
184*d415bd75Srobert // Make sure live-ins are correctly attached to this new basic block.
185*d415bd75Srobert LivePhysRegs LiveRegs;
186*d415bd75Srobert computeAndAddLiveIns(LiveRegs, *TrueBB);
187*d415bd75Srobert computeAndAddLiveIns(LiveRegs, *MergeBB);
188*d415bd75Srobert
18909467b48Spatrick return true;
19009467b48Spatrick }
19109467b48Spatrick
expandVSetVL(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI)19273471bf0Spatrick bool RISCVExpandPseudo::expandVSetVL(MachineBasicBlock &MBB,
19373471bf0Spatrick MachineBasicBlock::iterator MBBI) {
19473471bf0Spatrick assert(MBBI->getNumExplicitOperands() == 3 && MBBI->getNumOperands() >= 5 &&
19573471bf0Spatrick "Unexpected instruction format");
19673471bf0Spatrick
19773471bf0Spatrick DebugLoc DL = MBBI->getDebugLoc();
19873471bf0Spatrick
19973471bf0Spatrick assert((MBBI->getOpcode() == RISCV::PseudoVSETVLI ||
200*d415bd75Srobert MBBI->getOpcode() == RISCV::PseudoVSETVLIX0 ||
20173471bf0Spatrick MBBI->getOpcode() == RISCV::PseudoVSETIVLI) &&
20273471bf0Spatrick "Unexpected pseudo instruction");
20373471bf0Spatrick unsigned Opcode;
204*d415bd75Srobert if (MBBI->getOpcode() == RISCV::PseudoVSETIVLI)
20573471bf0Spatrick Opcode = RISCV::VSETIVLI;
206*d415bd75Srobert else
207*d415bd75Srobert Opcode = RISCV::VSETVLI;
20873471bf0Spatrick const MCInstrDesc &Desc = TII->get(Opcode);
20973471bf0Spatrick assert(Desc.getNumOperands() == 3 && "Unexpected instruction format");
21073471bf0Spatrick
21173471bf0Spatrick Register DstReg = MBBI->getOperand(0).getReg();
21273471bf0Spatrick bool DstIsDead = MBBI->getOperand(0).isDead();
21373471bf0Spatrick BuildMI(MBB, MBBI, DL, Desc)
21473471bf0Spatrick .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
21573471bf0Spatrick .add(MBBI->getOperand(1)) // VL
21673471bf0Spatrick .add(MBBI->getOperand(2)); // VType
21773471bf0Spatrick
21873471bf0Spatrick MBBI->eraseFromParent(); // The pseudo instruction is gone now.
21973471bf0Spatrick return true;
22073471bf0Spatrick }
22173471bf0Spatrick
expandVMSET_VMCLR(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,unsigned Opcode)22273471bf0Spatrick bool RISCVExpandPseudo::expandVMSET_VMCLR(MachineBasicBlock &MBB,
22373471bf0Spatrick MachineBasicBlock::iterator MBBI,
22473471bf0Spatrick unsigned Opcode) {
22573471bf0Spatrick DebugLoc DL = MBBI->getDebugLoc();
22673471bf0Spatrick Register DstReg = MBBI->getOperand(0).getReg();
22773471bf0Spatrick const MCInstrDesc &Desc = TII->get(Opcode);
22873471bf0Spatrick BuildMI(MBB, MBBI, DL, Desc, DstReg)
22973471bf0Spatrick .addReg(DstReg, RegState::Undef)
23073471bf0Spatrick .addReg(DstReg, RegState::Undef);
23173471bf0Spatrick MBBI->eraseFromParent(); // The pseudo instruction is gone now.
23273471bf0Spatrick return true;
23373471bf0Spatrick }
23473471bf0Spatrick
235*d415bd75Srobert class RISCVPreRAExpandPseudo : public MachineFunctionPass {
236*d415bd75Srobert public:
237*d415bd75Srobert const RISCVInstrInfo *TII;
238*d415bd75Srobert static char ID;
23973471bf0Spatrick
RISCVPreRAExpandPseudo()240*d415bd75Srobert RISCVPreRAExpandPseudo() : MachineFunctionPass(ID) {
241*d415bd75Srobert initializeRISCVPreRAExpandPseudoPass(*PassRegistry::getPassRegistry());
24273471bf0Spatrick }
243*d415bd75Srobert
244*d415bd75Srobert bool runOnMachineFunction(MachineFunction &MF) override;
245*d415bd75Srobert
getAnalysisUsage(AnalysisUsage & AU) const246*d415bd75Srobert void getAnalysisUsage(AnalysisUsage &AU) const override {
247*d415bd75Srobert AU.setPreservesCFG();
248*d415bd75Srobert MachineFunctionPass::getAnalysisUsage(AU);
249*d415bd75Srobert }
getPassName() const250*d415bd75Srobert StringRef getPassName() const override {
251*d415bd75Srobert return RISCV_PRERA_EXPAND_PSEUDO_NAME;
252*d415bd75Srobert }
253*d415bd75Srobert
254*d415bd75Srobert private:
255*d415bd75Srobert bool expandMBB(MachineBasicBlock &MBB);
256*d415bd75Srobert bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
257*d415bd75Srobert MachineBasicBlock::iterator &NextMBBI);
258*d415bd75Srobert bool expandAuipcInstPair(MachineBasicBlock &MBB,
259*d415bd75Srobert MachineBasicBlock::iterator MBBI,
260*d415bd75Srobert MachineBasicBlock::iterator &NextMBBI,
261*d415bd75Srobert unsigned FlagsHi, unsigned SecondOpcode);
262*d415bd75Srobert bool expandLoadLocalAddress(MachineBasicBlock &MBB,
263*d415bd75Srobert MachineBasicBlock::iterator MBBI,
264*d415bd75Srobert MachineBasicBlock::iterator &NextMBBI);
265*d415bd75Srobert bool expandLoadAddress(MachineBasicBlock &MBB,
266*d415bd75Srobert MachineBasicBlock::iterator MBBI,
267*d415bd75Srobert MachineBasicBlock::iterator &NextMBBI);
268*d415bd75Srobert bool expandLoadTLSIEAddress(MachineBasicBlock &MBB,
269*d415bd75Srobert MachineBasicBlock::iterator MBBI,
270*d415bd75Srobert MachineBasicBlock::iterator &NextMBBI);
271*d415bd75Srobert bool expandLoadTLSGDAddress(MachineBasicBlock &MBB,
272*d415bd75Srobert MachineBasicBlock::iterator MBBI,
273*d415bd75Srobert MachineBasicBlock::iterator &NextMBBI);
274*d415bd75Srobert };
275*d415bd75Srobert
276*d415bd75Srobert char RISCVPreRAExpandPseudo::ID = 0;
277*d415bd75Srobert
runOnMachineFunction(MachineFunction & MF)278*d415bd75Srobert bool RISCVPreRAExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
279*d415bd75Srobert TII = static_cast<const RISCVInstrInfo *>(MF.getSubtarget().getInstrInfo());
280*d415bd75Srobert bool Modified = false;
281*d415bd75Srobert for (auto &MBB : MF)
282*d415bd75Srobert Modified |= expandMBB(MBB);
283*d415bd75Srobert return Modified;
284*d415bd75Srobert }
285*d415bd75Srobert
expandMBB(MachineBasicBlock & MBB)286*d415bd75Srobert bool RISCVPreRAExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
287*d415bd75Srobert bool Modified = false;
288*d415bd75Srobert
289*d415bd75Srobert MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
290*d415bd75Srobert while (MBBI != E) {
291*d415bd75Srobert MachineBasicBlock::iterator NMBBI = std::next(MBBI);
292*d415bd75Srobert Modified |= expandMI(MBB, MBBI, NMBBI);
293*d415bd75Srobert MBBI = NMBBI;
294*d415bd75Srobert }
295*d415bd75Srobert
296*d415bd75Srobert return Modified;
297*d415bd75Srobert }
298*d415bd75Srobert
expandMI(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,MachineBasicBlock::iterator & NextMBBI)299*d415bd75Srobert bool RISCVPreRAExpandPseudo::expandMI(MachineBasicBlock &MBB,
300*d415bd75Srobert MachineBasicBlock::iterator MBBI,
301*d415bd75Srobert MachineBasicBlock::iterator &NextMBBI) {
302*d415bd75Srobert
303*d415bd75Srobert switch (MBBI->getOpcode()) {
304*d415bd75Srobert case RISCV::PseudoLLA:
305*d415bd75Srobert return expandLoadLocalAddress(MBB, MBBI, NextMBBI);
306*d415bd75Srobert case RISCV::PseudoLA:
307*d415bd75Srobert return expandLoadAddress(MBB, MBBI, NextMBBI);
308*d415bd75Srobert case RISCV::PseudoLA_TLS_IE:
309*d415bd75Srobert return expandLoadTLSIEAddress(MBB, MBBI, NextMBBI);
310*d415bd75Srobert case RISCV::PseudoLA_TLS_GD:
311*d415bd75Srobert return expandLoadTLSGDAddress(MBB, MBBI, NextMBBI);
312*d415bd75Srobert }
313*d415bd75Srobert return false;
314*d415bd75Srobert }
315*d415bd75Srobert
expandAuipcInstPair(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,MachineBasicBlock::iterator & NextMBBI,unsigned FlagsHi,unsigned SecondOpcode)316*d415bd75Srobert bool RISCVPreRAExpandPseudo::expandAuipcInstPair(
317*d415bd75Srobert MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
318*d415bd75Srobert MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi,
319*d415bd75Srobert unsigned SecondOpcode) {
320*d415bd75Srobert MachineFunction *MF = MBB.getParent();
321*d415bd75Srobert MachineInstr &MI = *MBBI;
322*d415bd75Srobert DebugLoc DL = MI.getDebugLoc();
323*d415bd75Srobert
324*d415bd75Srobert Register DestReg = MI.getOperand(0).getReg();
325*d415bd75Srobert Register ScratchReg =
326*d415bd75Srobert MF->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass);
327*d415bd75Srobert
328*d415bd75Srobert MachineOperand &Symbol = MI.getOperand(1);
329*d415bd75Srobert Symbol.setTargetFlags(FlagsHi);
330*d415bd75Srobert MCSymbol *AUIPCSymbol = MF->getContext().createNamedTempSymbol("pcrel_hi");
331*d415bd75Srobert
332*d415bd75Srobert MachineInstr *MIAUIPC =
333*d415bd75Srobert BuildMI(MBB, MBBI, DL, TII->get(RISCV::AUIPC), ScratchReg).add(Symbol);
334*d415bd75Srobert MIAUIPC->setPreInstrSymbol(*MF, AUIPCSymbol);
335*d415bd75Srobert
336*d415bd75Srobert MachineInstr *SecondMI =
337*d415bd75Srobert BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg)
338*d415bd75Srobert .addReg(ScratchReg)
339*d415bd75Srobert .addSym(AUIPCSymbol, RISCVII::MO_PCREL_LO);
340*d415bd75Srobert
341*d415bd75Srobert if (MI.hasOneMemOperand())
342*d415bd75Srobert SecondMI->addMemOperand(*MF, *MI.memoperands_begin());
343*d415bd75Srobert
344*d415bd75Srobert MI.eraseFromParent();
34573471bf0Spatrick return true;
34673471bf0Spatrick }
34773471bf0Spatrick
expandLoadLocalAddress(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,MachineBasicBlock::iterator & NextMBBI)348*d415bd75Srobert bool RISCVPreRAExpandPseudo::expandLoadLocalAddress(
349*d415bd75Srobert MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
350*d415bd75Srobert MachineBasicBlock::iterator &NextMBBI) {
351*d415bd75Srobert return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_PCREL_HI,
352*d415bd75Srobert RISCV::ADDI);
35373471bf0Spatrick }
354*d415bd75Srobert
expandLoadAddress(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,MachineBasicBlock::iterator & NextMBBI)355*d415bd75Srobert bool RISCVPreRAExpandPseudo::expandLoadAddress(
356*d415bd75Srobert MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
357*d415bd75Srobert MachineBasicBlock::iterator &NextMBBI) {
358*d415bd75Srobert MachineFunction *MF = MBB.getParent();
359*d415bd75Srobert
360*d415bd75Srobert const auto &STI = MF->getSubtarget<RISCVSubtarget>();
361*d415bd75Srobert // When HWASAN is used and tagging of global variables is enabled
362*d415bd75Srobert // they should be accessed via the GOT, since the tagged address of a global
363*d415bd75Srobert // is incompatible with existing code models. This also applies to non-pic
364*d415bd75Srobert // mode.
365*d415bd75Srobert assert(MF->getTarget().isPositionIndependent() || STI.allowTaggedGlobals());
366*d415bd75Srobert unsigned SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW;
367*d415bd75Srobert return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_GOT_HI,
368*d415bd75Srobert SecondOpcode);
369*d415bd75Srobert }
370*d415bd75Srobert
expandLoadTLSIEAddress(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,MachineBasicBlock::iterator & NextMBBI)371*d415bd75Srobert bool RISCVPreRAExpandPseudo::expandLoadTLSIEAddress(
372*d415bd75Srobert MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
373*d415bd75Srobert MachineBasicBlock::iterator &NextMBBI) {
374*d415bd75Srobert MachineFunction *MF = MBB.getParent();
375*d415bd75Srobert
376*d415bd75Srobert const auto &STI = MF->getSubtarget<RISCVSubtarget>();
377*d415bd75Srobert unsigned SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW;
378*d415bd75Srobert return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GOT_HI,
379*d415bd75Srobert SecondOpcode);
380*d415bd75Srobert }
381*d415bd75Srobert
expandLoadTLSGDAddress(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,MachineBasicBlock::iterator & NextMBBI)382*d415bd75Srobert bool RISCVPreRAExpandPseudo::expandLoadTLSGDAddress(
383*d415bd75Srobert MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
384*d415bd75Srobert MachineBasicBlock::iterator &NextMBBI) {
385*d415bd75Srobert return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GD_HI,
386*d415bd75Srobert RISCV::ADDI);
38773471bf0Spatrick }
38873471bf0Spatrick
38909467b48Spatrick } // end of anonymous namespace
39009467b48Spatrick
39109467b48Spatrick INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo",
39209467b48Spatrick RISCV_EXPAND_PSEUDO_NAME, false, false)
393*d415bd75Srobert
394*d415bd75Srobert INITIALIZE_PASS(RISCVPreRAExpandPseudo, "riscv-prera-expand-pseudo",
395*d415bd75Srobert RISCV_PRERA_EXPAND_PSEUDO_NAME, false, false)
396*d415bd75Srobert
39709467b48Spatrick namespace llvm {
39809467b48Spatrick
createRISCVExpandPseudoPass()39909467b48Spatrick FunctionPass *createRISCVExpandPseudoPass() { return new RISCVExpandPseudo(); }
createRISCVPreRAExpandPseudoPass()400*d415bd75Srobert FunctionPass *createRISCVPreRAExpandPseudoPass() { return new RISCVPreRAExpandPseudo(); }
40109467b48Spatrick
40209467b48Spatrick } // end of namespace llvm
403