xref: /freebsd/contrib/llvm-project/llvm/lib/Target/ARC/ARCExpandPseudos.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===- ARCExpandPseudosPass - ARC expand pseudo loads -----------*- C++ -*-===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // This pass expands stores with large offsets into an appropriate sequence.
10*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11*0b57cec5SDimitry Andric 
12*0b57cec5SDimitry Andric #include "ARC.h"
13*0b57cec5SDimitry Andric #include "ARCInstrInfo.h"
14*0b57cec5SDimitry Andric #include "ARCRegisterInfo.h"
15*0b57cec5SDimitry Andric #include "ARCSubtarget.h"
16*0b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
17*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
18*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
19*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
20*0b57cec5SDimitry Andric 
21*0b57cec5SDimitry Andric using namespace llvm;
22*0b57cec5SDimitry Andric 
23*0b57cec5SDimitry Andric #define DEBUG_TYPE "arc-expand-pseudos"
24*0b57cec5SDimitry Andric 
25*0b57cec5SDimitry Andric namespace {
26*0b57cec5SDimitry Andric 
27*0b57cec5SDimitry Andric class ARCExpandPseudos : public MachineFunctionPass {
28*0b57cec5SDimitry Andric public:
29*0b57cec5SDimitry Andric   static char ID;
30*0b57cec5SDimitry Andric   ARCExpandPseudos() : MachineFunctionPass(ID) {}
31*0b57cec5SDimitry Andric 
32*0b57cec5SDimitry Andric   bool runOnMachineFunction(MachineFunction &Fn) override;
33*0b57cec5SDimitry Andric 
34*0b57cec5SDimitry Andric   StringRef getPassName() const override { return "ARC Expand Pseudos"; }
35*0b57cec5SDimitry Andric 
36*0b57cec5SDimitry Andric private:
37*0b57cec5SDimitry Andric   void ExpandStore(MachineFunction &, MachineBasicBlock::iterator);
38*0b57cec5SDimitry Andric 
39*0b57cec5SDimitry Andric   const ARCInstrInfo *TII;
40*0b57cec5SDimitry Andric };
41*0b57cec5SDimitry Andric 
42*0b57cec5SDimitry Andric char ARCExpandPseudos::ID = 0;
43*0b57cec5SDimitry Andric 
44*0b57cec5SDimitry Andric } // end anonymous namespace
45*0b57cec5SDimitry Andric 
46*0b57cec5SDimitry Andric static unsigned getMappedOp(unsigned PseudoOp) {
47*0b57cec5SDimitry Andric   switch (PseudoOp) {
48*0b57cec5SDimitry Andric   case ARC::ST_FAR:
49*0b57cec5SDimitry Andric     return ARC::ST_rs9;
50*0b57cec5SDimitry Andric   case ARC::STH_FAR:
51*0b57cec5SDimitry Andric     return ARC::STH_rs9;
52*0b57cec5SDimitry Andric   case ARC::STB_FAR:
53*0b57cec5SDimitry Andric     return ARC::STB_rs9;
54*0b57cec5SDimitry Andric   default:
55*0b57cec5SDimitry Andric     llvm_unreachable("Unhandled pseudo op.");
56*0b57cec5SDimitry Andric   }
57*0b57cec5SDimitry Andric }
58*0b57cec5SDimitry Andric 
59*0b57cec5SDimitry Andric void ARCExpandPseudos::ExpandStore(MachineFunction &MF,
60*0b57cec5SDimitry Andric                                    MachineBasicBlock::iterator SII) {
61*0b57cec5SDimitry Andric   MachineInstr &SI = *SII;
62*0b57cec5SDimitry Andric   unsigned AddrReg = MF.getRegInfo().createVirtualRegister(&ARC::GPR32RegClass);
63*0b57cec5SDimitry Andric   unsigned AddOpc =
64*0b57cec5SDimitry Andric       isUInt<6>(SI.getOperand(2).getImm()) ? ARC::ADD_rru6 : ARC::ADD_rrlimm;
65*0b57cec5SDimitry Andric   BuildMI(*SI.getParent(), SI, SI.getDebugLoc(), TII->get(AddOpc), AddrReg)
66*0b57cec5SDimitry Andric       .addReg(SI.getOperand(1).getReg())
67*0b57cec5SDimitry Andric       .addImm(SI.getOperand(2).getImm());
68*0b57cec5SDimitry Andric   BuildMI(*SI.getParent(), SI, SI.getDebugLoc(),
69*0b57cec5SDimitry Andric           TII->get(getMappedOp(SI.getOpcode())))
70*0b57cec5SDimitry Andric       .addReg(SI.getOperand(0).getReg())
71*0b57cec5SDimitry Andric       .addReg(AddrReg)
72*0b57cec5SDimitry Andric       .addImm(0);
73*0b57cec5SDimitry Andric   SI.eraseFromParent();
74*0b57cec5SDimitry Andric }
75*0b57cec5SDimitry Andric 
76*0b57cec5SDimitry Andric bool ARCExpandPseudos::runOnMachineFunction(MachineFunction &MF) {
77*0b57cec5SDimitry Andric   const ARCSubtarget *STI = &MF.getSubtarget<ARCSubtarget>();
78*0b57cec5SDimitry Andric   TII = STI->getInstrInfo();
79*0b57cec5SDimitry Andric   bool ExpandedStore = false;
80*0b57cec5SDimitry Andric   for (auto &MBB : MF) {
81*0b57cec5SDimitry Andric     MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
82*0b57cec5SDimitry Andric     while (MBBI != E) {
83*0b57cec5SDimitry Andric       MachineBasicBlock::iterator NMBBI = std::next(MBBI);
84*0b57cec5SDimitry Andric       switch (MBBI->getOpcode()) {
85*0b57cec5SDimitry Andric       case ARC::ST_FAR:
86*0b57cec5SDimitry Andric       case ARC::STH_FAR:
87*0b57cec5SDimitry Andric       case ARC::STB_FAR:
88*0b57cec5SDimitry Andric         ExpandStore(MF, MBBI);
89*0b57cec5SDimitry Andric         ExpandedStore = true;
90*0b57cec5SDimitry Andric         break;
91*0b57cec5SDimitry Andric       default:
92*0b57cec5SDimitry Andric         break;
93*0b57cec5SDimitry Andric       }
94*0b57cec5SDimitry Andric       MBBI = NMBBI;
95*0b57cec5SDimitry Andric     }
96*0b57cec5SDimitry Andric   }
97*0b57cec5SDimitry Andric   return ExpandedStore;
98*0b57cec5SDimitry Andric }
99*0b57cec5SDimitry Andric 
100*0b57cec5SDimitry Andric FunctionPass *llvm::createARCExpandPseudosPass() {
101*0b57cec5SDimitry Andric   return new ARCExpandPseudos();
102*0b57cec5SDimitry Andric }
103