1 //===-- RISCVExpandPseudoInsts.cpp - Expand pseudo instructions -----------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains a pass that expands pseudo instructions into target
10 // instructions. This pass should be run after register allocation but before
11 // the post-regalloc scheduling pass.
13 //===----------------------------------------------------------------------===//
16 #include "RISCVInstrInfo.h"
17 #include "RISCVTargetMachine.h"
19 #include "llvm/CodeGen/LivePhysRegs.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/MC/MCContext.h"
26 #define RISCV_EXPAND_PSEUDO_NAME "RISC-V pseudo instruction expansion pass"
27 #define RISCV_PRERA_EXPAND_PSEUDO_NAME "RISC-V Pre-RA pseudo instruction expansion pass"
31 class RISCVExpandPseudo
: public MachineFunctionPass
{
33 const RISCVSubtarget
*STI
;
34 const RISCVInstrInfo
*TII
;
37 RISCVExpandPseudo() : MachineFunctionPass(ID
) {}
39 bool runOnMachineFunction(MachineFunction
&MF
) override
;
41 StringRef
getPassName() const override
{ return RISCV_EXPAND_PSEUDO_NAME
; }
44 bool expandMBB(MachineBasicBlock
&MBB
);
45 bool expandMI(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
46 MachineBasicBlock::iterator
&NextMBBI
);
47 bool expandCCOp(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
48 MachineBasicBlock::iterator
&NextMBBI
);
49 bool expandVMSET_VMCLR(MachineBasicBlock
&MBB
,
50 MachineBasicBlock::iterator MBBI
, unsigned Opcode
);
51 bool expandMV_FPR16INX(MachineBasicBlock
&MBB
,
52 MachineBasicBlock::iterator MBBI
);
53 bool expandMV_FPR32INX(MachineBasicBlock
&MBB
,
54 MachineBasicBlock::iterator MBBI
);
55 bool expandRV32ZdinxStore(MachineBasicBlock
&MBB
,
56 MachineBasicBlock::iterator MBBI
);
57 bool expandRV32ZdinxLoad(MachineBasicBlock
&MBB
,
58 MachineBasicBlock::iterator MBBI
);
60 unsigned getInstSizeInBytes(const MachineFunction
&MF
) const {
64 Size
+= TII
->getInstSizeInBytes(MI
);
70 char RISCVExpandPseudo::ID
= 0;
72 bool RISCVExpandPseudo::runOnMachineFunction(MachineFunction
&MF
) {
73 STI
= &MF
.getSubtarget
<RISCVSubtarget
>();
74 TII
= STI
->getInstrInfo();
77 const unsigned OldSize
= getInstSizeInBytes(MF
);
80 bool Modified
= false;
82 Modified
|= expandMBB(MBB
);
85 const unsigned NewSize
= getInstSizeInBytes(MF
);
86 assert(OldSize
>= NewSize
);
91 bool RISCVExpandPseudo::expandMBB(MachineBasicBlock
&MBB
) {
92 bool Modified
= false;
94 MachineBasicBlock::iterator MBBI
= MBB
.begin(), E
= MBB
.end();
96 MachineBasicBlock::iterator NMBBI
= std::next(MBBI
);
97 Modified
|= expandMI(MBB
, MBBI
, NMBBI
);
104 bool RISCVExpandPseudo::expandMI(MachineBasicBlock
&MBB
,
105 MachineBasicBlock::iterator MBBI
,
106 MachineBasicBlock::iterator
&NextMBBI
) {
107 // RISCVInstrInfo::getInstSizeInBytes expects that the total size of the
108 // expanded instructions for each pseudo is correct in the Size field of the
109 // tablegen definition for the pseudo.
110 switch (MBBI
->getOpcode()) {
111 case RISCV::PseudoMV_FPR16INX
:
112 return expandMV_FPR16INX(MBB
, MBBI
);
113 case RISCV::PseudoMV_FPR32INX
:
114 return expandMV_FPR32INX(MBB
, MBBI
);
115 case RISCV::PseudoRV32ZdinxSD
:
116 return expandRV32ZdinxStore(MBB
, MBBI
);
117 case RISCV::PseudoRV32ZdinxLD
:
118 return expandRV32ZdinxLoad(MBB
, MBBI
);
119 case RISCV::PseudoCCMOVGPRNoX0
:
120 case RISCV::PseudoCCMOVGPR
:
121 case RISCV::PseudoCCADD
:
122 case RISCV::PseudoCCSUB
:
123 case RISCV::PseudoCCAND
:
124 case RISCV::PseudoCCOR
:
125 case RISCV::PseudoCCXOR
:
126 case RISCV::PseudoCCADDW
:
127 case RISCV::PseudoCCSUBW
:
128 case RISCV::PseudoCCSLL
:
129 case RISCV::PseudoCCSRL
:
130 case RISCV::PseudoCCSRA
:
131 case RISCV::PseudoCCADDI
:
132 case RISCV::PseudoCCSLLI
:
133 case RISCV::PseudoCCSRLI
:
134 case RISCV::PseudoCCSRAI
:
135 case RISCV::PseudoCCANDI
:
136 case RISCV::PseudoCCORI
:
137 case RISCV::PseudoCCXORI
:
138 case RISCV::PseudoCCSLLW
:
139 case RISCV::PseudoCCSRLW
:
140 case RISCV::PseudoCCSRAW
:
141 case RISCV::PseudoCCADDIW
:
142 case RISCV::PseudoCCSLLIW
:
143 case RISCV::PseudoCCSRLIW
:
144 case RISCV::PseudoCCSRAIW
:
145 case RISCV::PseudoCCANDN
:
146 case RISCV::PseudoCCORN
:
147 case RISCV::PseudoCCXNOR
:
148 return expandCCOp(MBB
, MBBI
, NextMBBI
);
149 case RISCV::PseudoVMCLR_M_B1
:
150 case RISCV::PseudoVMCLR_M_B2
:
151 case RISCV::PseudoVMCLR_M_B4
:
152 case RISCV::PseudoVMCLR_M_B8
:
153 case RISCV::PseudoVMCLR_M_B16
:
154 case RISCV::PseudoVMCLR_M_B32
:
155 case RISCV::PseudoVMCLR_M_B64
:
156 // vmclr.m vd => vmxor.mm vd, vd, vd
157 return expandVMSET_VMCLR(MBB
, MBBI
, RISCV::VMXOR_MM
);
158 case RISCV::PseudoVMSET_M_B1
:
159 case RISCV::PseudoVMSET_M_B2
:
160 case RISCV::PseudoVMSET_M_B4
:
161 case RISCV::PseudoVMSET_M_B8
:
162 case RISCV::PseudoVMSET_M_B16
:
163 case RISCV::PseudoVMSET_M_B32
:
164 case RISCV::PseudoVMSET_M_B64
:
165 // vmset.m vd => vmxnor.mm vd, vd, vd
166 return expandVMSET_VMCLR(MBB
, MBBI
, RISCV::VMXNOR_MM
);
172 bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock
&MBB
,
173 MachineBasicBlock::iterator MBBI
,
174 MachineBasicBlock::iterator
&NextMBBI
) {
176 MachineFunction
*MF
= MBB
.getParent();
177 MachineInstr
&MI
= *MBBI
;
178 DebugLoc DL
= MI
.getDebugLoc();
180 MachineBasicBlock
*TrueBB
= MF
->CreateMachineBasicBlock(MBB
.getBasicBlock());
181 MachineBasicBlock
*MergeBB
= MF
->CreateMachineBasicBlock(MBB
.getBasicBlock());
183 MF
->insert(++MBB
.getIterator(), TrueBB
);
184 MF
->insert(++TrueBB
->getIterator(), MergeBB
);
186 // We want to copy the "true" value when the condition is true which means
187 // we need to invert the branch condition to jump over TrueBB when the
188 // condition is false.
189 auto CC
= static_cast<RISCVCC::CondCode
>(MI
.getOperand(3).getImm());
190 CC
= RISCVCC::getOppositeBranchCondition(CC
);
192 // Insert branch instruction.
193 BuildMI(MBB
, MBBI
, DL
, TII
->getBrCond(CC
))
194 .addReg(MI
.getOperand(1).getReg())
195 .addReg(MI
.getOperand(2).getReg())
198 Register DestReg
= MI
.getOperand(0).getReg();
199 assert(MI
.getOperand(4).getReg() == DestReg
);
201 if (MI
.getOpcode() == RISCV::PseudoCCMOVGPR
||
202 MI
.getOpcode() == RISCV::PseudoCCMOVGPRNoX0
) {
204 BuildMI(TrueBB
, DL
, TII
->get(RISCV::ADDI
), DestReg
)
205 .add(MI
.getOperand(5))
209 switch (MI
.getOpcode()) {
211 llvm_unreachable("Unexpected opcode!");
212 case RISCV::PseudoCCADD
: NewOpc
= RISCV::ADD
; break;
213 case RISCV::PseudoCCSUB
: NewOpc
= RISCV::SUB
; break;
214 case RISCV::PseudoCCSLL
: NewOpc
= RISCV::SLL
; break;
215 case RISCV::PseudoCCSRL
: NewOpc
= RISCV::SRL
; break;
216 case RISCV::PseudoCCSRA
: NewOpc
= RISCV::SRA
; break;
217 case RISCV::PseudoCCAND
: NewOpc
= RISCV::AND
; break;
218 case RISCV::PseudoCCOR
: NewOpc
= RISCV::OR
; break;
219 case RISCV::PseudoCCXOR
: NewOpc
= RISCV::XOR
; break;
220 case RISCV::PseudoCCADDI
: NewOpc
= RISCV::ADDI
; break;
221 case RISCV::PseudoCCSLLI
: NewOpc
= RISCV::SLLI
; break;
222 case RISCV::PseudoCCSRLI
: NewOpc
= RISCV::SRLI
; break;
223 case RISCV::PseudoCCSRAI
: NewOpc
= RISCV::SRAI
; break;
224 case RISCV::PseudoCCANDI
: NewOpc
= RISCV::ANDI
; break;
225 case RISCV::PseudoCCORI
: NewOpc
= RISCV::ORI
; break;
226 case RISCV::PseudoCCXORI
: NewOpc
= RISCV::XORI
; break;
227 case RISCV::PseudoCCADDW
: NewOpc
= RISCV::ADDW
; break;
228 case RISCV::PseudoCCSUBW
: NewOpc
= RISCV::SUBW
; break;
229 case RISCV::PseudoCCSLLW
: NewOpc
= RISCV::SLLW
; break;
230 case RISCV::PseudoCCSRLW
: NewOpc
= RISCV::SRLW
; break;
231 case RISCV::PseudoCCSRAW
: NewOpc
= RISCV::SRAW
; break;
232 case RISCV::PseudoCCADDIW
: NewOpc
= RISCV::ADDIW
; break;
233 case RISCV::PseudoCCSLLIW
: NewOpc
= RISCV::SLLIW
; break;
234 case RISCV::PseudoCCSRLIW
: NewOpc
= RISCV::SRLIW
; break;
235 case RISCV::PseudoCCSRAIW
: NewOpc
= RISCV::SRAIW
; break;
236 case RISCV::PseudoCCANDN
: NewOpc
= RISCV::ANDN
; break;
237 case RISCV::PseudoCCORN
: NewOpc
= RISCV::ORN
; break;
238 case RISCV::PseudoCCXNOR
: NewOpc
= RISCV::XNOR
; break;
240 BuildMI(TrueBB
, DL
, TII
->get(NewOpc
), DestReg
)
241 .add(MI
.getOperand(5))
242 .add(MI
.getOperand(6));
245 TrueBB
->addSuccessor(MergeBB
);
247 MergeBB
->splice(MergeBB
->end(), &MBB
, MI
, MBB
.end());
248 MergeBB
->transferSuccessors(&MBB
);
250 MBB
.addSuccessor(TrueBB
);
251 MBB
.addSuccessor(MergeBB
);
253 NextMBBI
= MBB
.end();
254 MI
.eraseFromParent();
256 // Make sure live-ins are correctly attached to this new basic block.
257 LivePhysRegs LiveRegs
;
258 computeAndAddLiveIns(LiveRegs
, *TrueBB
);
259 computeAndAddLiveIns(LiveRegs
, *MergeBB
);
264 bool RISCVExpandPseudo::expandVMSET_VMCLR(MachineBasicBlock
&MBB
,
265 MachineBasicBlock::iterator MBBI
,
267 DebugLoc DL
= MBBI
->getDebugLoc();
268 Register DstReg
= MBBI
->getOperand(0).getReg();
269 const MCInstrDesc
&Desc
= TII
->get(Opcode
);
270 BuildMI(MBB
, MBBI
, DL
, Desc
, DstReg
)
271 .addReg(DstReg
, RegState::Undef
)
272 .addReg(DstReg
, RegState::Undef
);
273 MBBI
->eraseFromParent(); // The pseudo instruction is gone now.
277 bool RISCVExpandPseudo::expandMV_FPR16INX(MachineBasicBlock
&MBB
,
278 MachineBasicBlock::iterator MBBI
) {
279 DebugLoc DL
= MBBI
->getDebugLoc();
280 const TargetRegisterInfo
*TRI
= STI
->getRegisterInfo();
281 Register DstReg
= TRI
->getMatchingSuperReg(
282 MBBI
->getOperand(0).getReg(), RISCV::sub_16
, &RISCV::GPRRegClass
);
283 Register SrcReg
= TRI
->getMatchingSuperReg(
284 MBBI
->getOperand(1).getReg(), RISCV::sub_16
, &RISCV::GPRRegClass
);
286 BuildMI(MBB
, MBBI
, DL
, TII
->get(RISCV::ADDI
), DstReg
)
287 .addReg(SrcReg
, getKillRegState(MBBI
->getOperand(1).isKill()))
290 MBBI
->eraseFromParent(); // The pseudo instruction is gone now.
294 bool RISCVExpandPseudo::expandMV_FPR32INX(MachineBasicBlock
&MBB
,
295 MachineBasicBlock::iterator MBBI
) {
296 DebugLoc DL
= MBBI
->getDebugLoc();
297 const TargetRegisterInfo
*TRI
= STI
->getRegisterInfo();
298 Register DstReg
= TRI
->getMatchingSuperReg(
299 MBBI
->getOperand(0).getReg(), RISCV::sub_32
, &RISCV::GPRRegClass
);
300 Register SrcReg
= TRI
->getMatchingSuperReg(
301 MBBI
->getOperand(1).getReg(), RISCV::sub_32
, &RISCV::GPRRegClass
);
303 BuildMI(MBB
, MBBI
, DL
, TII
->get(RISCV::ADDI
), DstReg
)
304 .addReg(SrcReg
, getKillRegState(MBBI
->getOperand(1).isKill()))
307 MBBI
->eraseFromParent(); // The pseudo instruction is gone now.
311 // This function expands the PseudoRV32ZdinxSD for storing a double-precision
312 // floating-point value into memory by generating an equivalent instruction
313 // sequence for RV32.
314 bool RISCVExpandPseudo::expandRV32ZdinxStore(MachineBasicBlock
&MBB
,
315 MachineBasicBlock::iterator MBBI
) {
316 DebugLoc DL
= MBBI
->getDebugLoc();
317 const TargetRegisterInfo
*TRI
= STI
->getRegisterInfo();
319 TRI
->getSubReg(MBBI
->getOperand(0).getReg(), RISCV::sub_gpr_even
);
321 TRI
->getSubReg(MBBI
->getOperand(0).getReg(), RISCV::sub_gpr_odd
);
323 auto MIBLo
= BuildMI(MBB
, MBBI
, DL
, TII
->get(RISCV::SW
))
324 .addReg(Lo
, getKillRegState(MBBI
->getOperand(0).isKill()))
325 .addReg(MBBI
->getOperand(1).getReg())
326 .add(MBBI
->getOperand(2));
328 MachineInstrBuilder MIBHi
;
329 if (MBBI
->getOperand(2).isGlobal() || MBBI
->getOperand(2).isCPI()) {
330 assert(MBBI
->getOperand(2).getOffset() % 8 == 0);
331 MBBI
->getOperand(2).setOffset(MBBI
->getOperand(2).getOffset() + 4);
332 MIBHi
= BuildMI(MBB
, MBBI
, DL
, TII
->get(RISCV::SW
))
333 .addReg(Hi
, getKillRegState(MBBI
->getOperand(0).isKill()))
334 .add(MBBI
->getOperand(1))
335 .add(MBBI
->getOperand(2));
337 assert(isInt
<12>(MBBI
->getOperand(2).getImm() + 4));
338 MIBHi
= BuildMI(MBB
, MBBI
, DL
, TII
->get(RISCV::SW
))
339 .addReg(Hi
, getKillRegState(MBBI
->getOperand(0).isKill()))
340 .add(MBBI
->getOperand(1))
341 .addImm(MBBI
->getOperand(2).getImm() + 4);
344 if (!MBBI
->memoperands_empty()) {
345 assert(MBBI
->hasOneMemOperand() && "Expected mem operand");
346 MachineMemOperand
*OldMMO
= MBBI
->memoperands().front();
347 MachineFunction
*MF
= MBB
.getParent();
348 MachineMemOperand
*MMOLo
= MF
->getMachineMemOperand(OldMMO
, 0, 4);
349 MachineMemOperand
*MMOHi
= MF
->getMachineMemOperand(OldMMO
, 4, 4);
350 MIBLo
.setMemRefs(MMOLo
);
351 MIBHi
.setMemRefs(MMOHi
);
354 MBBI
->eraseFromParent();
358 // This function expands PseudoRV32ZdinxLoad for loading a double-precision
359 // floating-point value from memory into an equivalent instruction sequence for
361 bool RISCVExpandPseudo::expandRV32ZdinxLoad(MachineBasicBlock
&MBB
,
362 MachineBasicBlock::iterator MBBI
) {
363 DebugLoc DL
= MBBI
->getDebugLoc();
364 const TargetRegisterInfo
*TRI
= STI
->getRegisterInfo();
366 TRI
->getSubReg(MBBI
->getOperand(0).getReg(), RISCV::sub_gpr_even
);
368 TRI
->getSubReg(MBBI
->getOperand(0).getReg(), RISCV::sub_gpr_odd
);
370 MachineInstrBuilder MIBLo
, MIBHi
;
372 // If the register of operand 1 is equal to the Lo register, then swap the
373 // order of loading the Lo and Hi statements.
374 bool IsOp1EqualToLo
= Lo
== MBBI
->getOperand(1).getReg();
376 if (!IsOp1EqualToLo
) {
377 MIBLo
= BuildMI(MBB
, MBBI
, DL
, TII
->get(RISCV::LW
), Lo
)
378 .addReg(MBBI
->getOperand(1).getReg())
379 .add(MBBI
->getOperand(2));
382 if (MBBI
->getOperand(2).isGlobal() || MBBI
->getOperand(2).isCPI()) {
383 auto Offset
= MBBI
->getOperand(2).getOffset();
384 assert(Offset
% 8 == 0);
385 MBBI
->getOperand(2).setOffset(Offset
+ 4);
386 MIBHi
= BuildMI(MBB
, MBBI
, DL
, TII
->get(RISCV::LW
), Hi
)
387 .addReg(MBBI
->getOperand(1).getReg())
388 .add(MBBI
->getOperand(2));
389 MBBI
->getOperand(2).setOffset(Offset
);
391 assert(isInt
<12>(MBBI
->getOperand(2).getImm() + 4));
392 MIBHi
= BuildMI(MBB
, MBBI
, DL
, TII
->get(RISCV::LW
), Hi
)
393 .addReg(MBBI
->getOperand(1).getReg())
394 .addImm(MBBI
->getOperand(2).getImm() + 4);
398 if (IsOp1EqualToLo
) {
399 MIBLo
= BuildMI(MBB
, MBBI
, DL
, TII
->get(RISCV::LW
), Lo
)
400 .addReg(MBBI
->getOperand(1).getReg())
401 .add(MBBI
->getOperand(2));
404 if (!MBBI
->memoperands_empty()) {
405 assert(MBBI
->hasOneMemOperand() && "Expected mem operand");
406 MachineMemOperand
*OldMMO
= MBBI
->memoperands().front();
407 MachineFunction
*MF
= MBB
.getParent();
408 MachineMemOperand
*MMOLo
= MF
->getMachineMemOperand(OldMMO
, 0, 4);
409 MachineMemOperand
*MMOHi
= MF
->getMachineMemOperand(OldMMO
, 4, 4);
410 MIBLo
.setMemRefs(MMOLo
);
411 MIBHi
.setMemRefs(MMOHi
);
414 MBBI
->eraseFromParent();
418 class RISCVPreRAExpandPseudo
: public MachineFunctionPass
{
420 const RISCVSubtarget
*STI
;
421 const RISCVInstrInfo
*TII
;
424 RISCVPreRAExpandPseudo() : MachineFunctionPass(ID
) {}
426 bool runOnMachineFunction(MachineFunction
&MF
) override
;
428 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
429 AU
.setPreservesCFG();
430 MachineFunctionPass::getAnalysisUsage(AU
);
432 StringRef
getPassName() const override
{
433 return RISCV_PRERA_EXPAND_PSEUDO_NAME
;
437 bool expandMBB(MachineBasicBlock
&MBB
);
438 bool expandMI(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
439 MachineBasicBlock::iterator
&NextMBBI
);
440 bool expandAuipcInstPair(MachineBasicBlock
&MBB
,
441 MachineBasicBlock::iterator MBBI
,
442 MachineBasicBlock::iterator
&NextMBBI
,
443 unsigned FlagsHi
, unsigned SecondOpcode
);
444 bool expandLoadLocalAddress(MachineBasicBlock
&MBB
,
445 MachineBasicBlock::iterator MBBI
,
446 MachineBasicBlock::iterator
&NextMBBI
);
447 bool expandLoadGlobalAddress(MachineBasicBlock
&MBB
,
448 MachineBasicBlock::iterator MBBI
,
449 MachineBasicBlock::iterator
&NextMBBI
);
450 bool expandLoadTLSIEAddress(MachineBasicBlock
&MBB
,
451 MachineBasicBlock::iterator MBBI
,
452 MachineBasicBlock::iterator
&NextMBBI
);
453 bool expandLoadTLSGDAddress(MachineBasicBlock
&MBB
,
454 MachineBasicBlock::iterator MBBI
,
455 MachineBasicBlock::iterator
&NextMBBI
);
456 bool expandLoadTLSDescAddress(MachineBasicBlock
&MBB
,
457 MachineBasicBlock::iterator MBBI
,
458 MachineBasicBlock::iterator
&NextMBBI
);
461 unsigned getInstSizeInBytes(const MachineFunction
&MF
) const {
465 Size
+= TII
->getInstSizeInBytes(MI
);
471 char RISCVPreRAExpandPseudo::ID
= 0;
473 bool RISCVPreRAExpandPseudo::runOnMachineFunction(MachineFunction
&MF
) {
474 STI
= &MF
.getSubtarget
<RISCVSubtarget
>();
475 TII
= STI
->getInstrInfo();
478 const unsigned OldSize
= getInstSizeInBytes(MF
);
481 bool Modified
= false;
483 Modified
|= expandMBB(MBB
);
486 const unsigned NewSize
= getInstSizeInBytes(MF
);
487 assert(OldSize
>= NewSize
);
492 bool RISCVPreRAExpandPseudo::expandMBB(MachineBasicBlock
&MBB
) {
493 bool Modified
= false;
495 MachineBasicBlock::iterator MBBI
= MBB
.begin(), E
= MBB
.end();
497 MachineBasicBlock::iterator NMBBI
= std::next(MBBI
);
498 Modified
|= expandMI(MBB
, MBBI
, NMBBI
);
505 bool RISCVPreRAExpandPseudo::expandMI(MachineBasicBlock
&MBB
,
506 MachineBasicBlock::iterator MBBI
,
507 MachineBasicBlock::iterator
&NextMBBI
) {
509 switch (MBBI
->getOpcode()) {
510 case RISCV::PseudoLLA
:
511 return expandLoadLocalAddress(MBB
, MBBI
, NextMBBI
);
512 case RISCV::PseudoLGA
:
513 return expandLoadGlobalAddress(MBB
, MBBI
, NextMBBI
);
514 case RISCV::PseudoLA_TLS_IE
:
515 return expandLoadTLSIEAddress(MBB
, MBBI
, NextMBBI
);
516 case RISCV::PseudoLA_TLS_GD
:
517 return expandLoadTLSGDAddress(MBB
, MBBI
, NextMBBI
);
518 case RISCV::PseudoLA_TLSDESC
:
519 return expandLoadTLSDescAddress(MBB
, MBBI
, NextMBBI
);
524 bool RISCVPreRAExpandPseudo::expandAuipcInstPair(
525 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
526 MachineBasicBlock::iterator
&NextMBBI
, unsigned FlagsHi
,
527 unsigned SecondOpcode
) {
528 MachineFunction
*MF
= MBB
.getParent();
529 MachineInstr
&MI
= *MBBI
;
530 DebugLoc DL
= MI
.getDebugLoc();
532 Register DestReg
= MI
.getOperand(0).getReg();
533 Register ScratchReg
=
534 MF
->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass
);
536 MachineOperand
&Symbol
= MI
.getOperand(1);
537 Symbol
.setTargetFlags(FlagsHi
);
538 MCSymbol
*AUIPCSymbol
= MF
->getContext().createNamedTempSymbol("pcrel_hi");
540 MachineInstr
*MIAUIPC
=
541 BuildMI(MBB
, MBBI
, DL
, TII
->get(RISCV::AUIPC
), ScratchReg
).add(Symbol
);
542 MIAUIPC
->setPreInstrSymbol(*MF
, AUIPCSymbol
);
544 MachineInstr
*SecondMI
=
545 BuildMI(MBB
, MBBI
, DL
, TII
->get(SecondOpcode
), DestReg
)
547 .addSym(AUIPCSymbol
, RISCVII::MO_PCREL_LO
);
549 if (MI
.hasOneMemOperand())
550 SecondMI
->addMemOperand(*MF
, *MI
.memoperands_begin());
552 MI
.eraseFromParent();
556 bool RISCVPreRAExpandPseudo::expandLoadLocalAddress(
557 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
558 MachineBasicBlock::iterator
&NextMBBI
) {
559 return expandAuipcInstPair(MBB
, MBBI
, NextMBBI
, RISCVII::MO_PCREL_HI
,
563 bool RISCVPreRAExpandPseudo::expandLoadGlobalAddress(
564 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
565 MachineBasicBlock::iterator
&NextMBBI
) {
566 unsigned SecondOpcode
= STI
->is64Bit() ? RISCV::LD
: RISCV::LW
;
567 return expandAuipcInstPair(MBB
, MBBI
, NextMBBI
, RISCVII::MO_GOT_HI
,
571 bool RISCVPreRAExpandPseudo::expandLoadTLSIEAddress(
572 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
573 MachineBasicBlock::iterator
&NextMBBI
) {
574 unsigned SecondOpcode
= STI
->is64Bit() ? RISCV::LD
: RISCV::LW
;
575 return expandAuipcInstPair(MBB
, MBBI
, NextMBBI
, RISCVII::MO_TLS_GOT_HI
,
579 bool RISCVPreRAExpandPseudo::expandLoadTLSGDAddress(
580 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
581 MachineBasicBlock::iterator
&NextMBBI
) {
582 return expandAuipcInstPair(MBB
, MBBI
, NextMBBI
, RISCVII::MO_TLS_GD_HI
,
586 bool RISCVPreRAExpandPseudo::expandLoadTLSDescAddress(
587 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
588 MachineBasicBlock::iterator
&NextMBBI
) {
589 MachineFunction
*MF
= MBB
.getParent();
590 MachineInstr
&MI
= *MBBI
;
591 DebugLoc DL
= MI
.getDebugLoc();
593 const auto &STI
= MF
->getSubtarget
<RISCVSubtarget
>();
594 unsigned SecondOpcode
= STI
.is64Bit() ? RISCV::LD
: RISCV::LW
;
596 Register FinalReg
= MI
.getOperand(0).getReg();
598 MF
->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass
);
599 Register ScratchReg
=
600 MF
->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass
);
602 MachineOperand
&Symbol
= MI
.getOperand(1);
603 Symbol
.setTargetFlags(RISCVII::MO_TLSDESC_HI
);
604 MCSymbol
*AUIPCSymbol
= MF
->getContext().createNamedTempSymbol("tlsdesc_hi");
606 MachineInstr
*MIAUIPC
=
607 BuildMI(MBB
, MBBI
, DL
, TII
->get(RISCV::AUIPC
), ScratchReg
).add(Symbol
);
608 MIAUIPC
->setPreInstrSymbol(*MF
, AUIPCSymbol
);
610 BuildMI(MBB
, MBBI
, DL
, TII
->get(SecondOpcode
), DestReg
)
612 .addSym(AUIPCSymbol
, RISCVII::MO_TLSDESC_LOAD_LO
);
614 BuildMI(MBB
, MBBI
, DL
, TII
->get(RISCV::ADDI
), RISCV::X10
)
616 .addSym(AUIPCSymbol
, RISCVII::MO_TLSDESC_ADD_LO
);
618 BuildMI(MBB
, MBBI
, DL
, TII
->get(RISCV::PseudoTLSDESCCall
), RISCV::X5
)
621 .addSym(AUIPCSymbol
, RISCVII::MO_TLSDESC_CALL
);
623 BuildMI(MBB
, MBBI
, DL
, TII
->get(RISCV::ADD
), FinalReg
)
627 MI
.eraseFromParent();
631 } // end of anonymous namespace
633 INITIALIZE_PASS(RISCVExpandPseudo
, "riscv-expand-pseudo",
634 RISCV_EXPAND_PSEUDO_NAME
, false, false)
636 INITIALIZE_PASS(RISCVPreRAExpandPseudo
, "riscv-prera-expand-pseudo",
637 RISCV_PRERA_EXPAND_PSEUDO_NAME
, false, false)
641 FunctionPass
*createRISCVExpandPseudoPass() { return new RISCVExpandPseudo(); }
642 FunctionPass
*createRISCVPreRAExpandPseudoPass() { return new RISCVPreRAExpandPseudo(); }
644 } // end of namespace llvm