104eeddc0SDimitry Andric //===-- M68kExpandPseudo.cpp - Expand pseudo instructions -------*- C++ -*-===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric /// 9fe6060f1SDimitry Andric /// \file 10fe6060f1SDimitry Andric /// This file contains a pass that expands pseudo instructions into target 11fe6060f1SDimitry Andric /// instructions to allow proper scheduling, if-conversion, other late 12fe6060f1SDimitry Andric /// optimizations, or simply the encoding of the instructions. 13fe6060f1SDimitry Andric /// 14fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 15fe6060f1SDimitry Andric 16fe6060f1SDimitry Andric #include "M68k.h" 17fe6060f1SDimitry Andric #include "M68kFrameLowering.h" 18fe6060f1SDimitry Andric #include "M68kInstrInfo.h" 19fe6060f1SDimitry Andric #include "M68kMachineFunction.h" 20fe6060f1SDimitry Andric #include "M68kSubtarget.h" 21fe6060f1SDimitry Andric 22fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 23fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 24fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 25fe6060f1SDimitry Andric #include "llvm/CodeGen/Passes.h" // For IDs of passes that are preserved. 2606c3fb27SDimitry Andric #include "llvm/IR/EHPersonalities.h" 27fe6060f1SDimitry Andric #include "llvm/IR/GlobalValue.h" 28fe6060f1SDimitry Andric 29fe6060f1SDimitry Andric using namespace llvm; 30fe6060f1SDimitry Andric 3106c3fb27SDimitry Andric #define DEBUG_TYPE "m68k-expand-pseudo" 3206c3fb27SDimitry Andric #define PASS_NAME "M68k pseudo instruction expansion pass" 33fe6060f1SDimitry Andric 34fe6060f1SDimitry Andric namespace { 35fe6060f1SDimitry Andric class M68kExpandPseudo : public MachineFunctionPass { 36fe6060f1SDimitry Andric public: 37fe6060f1SDimitry Andric static char ID; 38fe6060f1SDimitry Andric M68kExpandPseudo() : MachineFunctionPass(ID) {} 39fe6060f1SDimitry Andric 40fe6060f1SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 41fe6060f1SDimitry Andric AU.setPreservesCFG(); 42fe6060f1SDimitry Andric AU.addPreservedID(MachineLoopInfoID); 43fe6060f1SDimitry Andric AU.addPreservedID(MachineDominatorsID); 44fe6060f1SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 45fe6060f1SDimitry Andric } 46fe6060f1SDimitry Andric 47fe6060f1SDimitry Andric const M68kSubtarget *STI; 48fe6060f1SDimitry Andric const M68kInstrInfo *TII; 49fe6060f1SDimitry Andric const M68kRegisterInfo *TRI; 50fe6060f1SDimitry Andric const M68kMachineFunctionInfo *MFI; 51fe6060f1SDimitry Andric const M68kFrameLowering *FL; 52fe6060f1SDimitry Andric 53fe6060f1SDimitry Andric bool runOnMachineFunction(MachineFunction &Fn) override; 54fe6060f1SDimitry Andric 55fe6060f1SDimitry Andric MachineFunctionProperties getRequiredProperties() const override { 56fe6060f1SDimitry Andric return MachineFunctionProperties().set( 57fe6060f1SDimitry Andric MachineFunctionProperties::Property::NoVRegs); 58fe6060f1SDimitry Andric } 59fe6060f1SDimitry Andric 60fe6060f1SDimitry Andric private: 61fe6060f1SDimitry Andric bool ExpandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI); 62fe6060f1SDimitry Andric bool ExpandMBB(MachineBasicBlock &MBB); 63fe6060f1SDimitry Andric }; 64fe6060f1SDimitry Andric char M68kExpandPseudo::ID = 0; 65fe6060f1SDimitry Andric } // End anonymous namespace. 66fe6060f1SDimitry Andric 6706c3fb27SDimitry Andric INITIALIZE_PASS(M68kExpandPseudo, DEBUG_TYPE, PASS_NAME, false, false) 6806c3fb27SDimitry Andric 69fe6060f1SDimitry Andric /// If \p MBBI is a pseudo instruction, this method expands 70fe6060f1SDimitry Andric /// it to the corresponding (sequence of) actual instruction(s). 71fe6060f1SDimitry Andric /// \returns true if \p MBBI has been expanded. 72fe6060f1SDimitry Andric bool M68kExpandPseudo::ExpandMI(MachineBasicBlock &MBB, 73fe6060f1SDimitry Andric MachineBasicBlock::iterator MBBI) { 74fe6060f1SDimitry Andric MachineInstr &MI = *MBBI; 75fe6060f1SDimitry Andric MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI); 76fe6060f1SDimitry Andric unsigned Opcode = MI.getOpcode(); 77fe6060f1SDimitry Andric DebugLoc DL = MBBI->getDebugLoc(); 78fe6060f1SDimitry Andric /// TODO infer argument size to create less switch cases 79fe6060f1SDimitry Andric switch (Opcode) { 80fe6060f1SDimitry Andric default: 81fe6060f1SDimitry Andric return false; 82fe6060f1SDimitry Andric 83*0fca6ea1SDimitry Andric case M68k::MOVI8di: 84*0fca6ea1SDimitry Andric return TII->ExpandMOVI(MIB, MVT::i8); 85*0fca6ea1SDimitry Andric case M68k::MOVI16ri: 86*0fca6ea1SDimitry Andric return TII->ExpandMOVI(MIB, MVT::i16); 87*0fca6ea1SDimitry Andric case M68k::MOVI32ri: 88*0fca6ea1SDimitry Andric return TII->ExpandMOVI(MIB, MVT::i32); 89*0fca6ea1SDimitry Andric 90fe6060f1SDimitry Andric case M68k::MOVXd16d8: 91fe6060f1SDimitry Andric return TII->ExpandMOVX_RR(MIB, MVT::i16, MVT::i8); 92fe6060f1SDimitry Andric case M68k::MOVXd32d8: 93fe6060f1SDimitry Andric return TII->ExpandMOVX_RR(MIB, MVT::i32, MVT::i8); 94fe6060f1SDimitry Andric case M68k::MOVXd32d16: 95fe6060f1SDimitry Andric return TII->ExpandMOVX_RR(MIB, MVT::i32, MVT::i16); 96fe6060f1SDimitry Andric 97fe6060f1SDimitry Andric case M68k::MOVSXd16d8: 98fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RR(MIB, true, MVT::i16, MVT::i8); 99fe6060f1SDimitry Andric case M68k::MOVSXd32d8: 100fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RR(MIB, true, MVT::i32, MVT::i8); 101fe6060f1SDimitry Andric case M68k::MOVSXd32d16: 102fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RR(MIB, true, MVT::i32, MVT::i16); 103fe6060f1SDimitry Andric 104fe6060f1SDimitry Andric case M68k::MOVZXd16d8: 105fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RR(MIB, false, MVT::i16, MVT::i8); 106fe6060f1SDimitry Andric case M68k::MOVZXd32d8: 107fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RR(MIB, false, MVT::i32, MVT::i8); 108fe6060f1SDimitry Andric case M68k::MOVZXd32d16: 109fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RR(MIB, false, MVT::i32, MVT::i16); 110fe6060f1SDimitry Andric 111fe6060f1SDimitry Andric case M68k::MOVSXd16j8: 112fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8dj), MVT::i16, 113fe6060f1SDimitry Andric MVT::i8); 114fe6060f1SDimitry Andric case M68k::MOVSXd32j8: 115fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8dj), MVT::i32, 116fe6060f1SDimitry Andric MVT::i8); 117fe6060f1SDimitry Andric case M68k::MOVSXd32j16: 118fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV16rj), MVT::i32, 119fe6060f1SDimitry Andric MVT::i16); 120fe6060f1SDimitry Andric 121fe6060f1SDimitry Andric case M68k::MOVZXd16j8: 122fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8dj), MVT::i16, 123fe6060f1SDimitry Andric MVT::i8); 124fe6060f1SDimitry Andric case M68k::MOVZXd32j8: 125fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8dj), MVT::i32, 126fe6060f1SDimitry Andric MVT::i8); 127fe6060f1SDimitry Andric case M68k::MOVZXd32j16: 128fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV16rj), MVT::i32, 129fe6060f1SDimitry Andric MVT::i16); 130fe6060f1SDimitry Andric 131fe6060f1SDimitry Andric case M68k::MOVSXd16p8: 132fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8dp), MVT::i16, 133fe6060f1SDimitry Andric MVT::i8); 134fe6060f1SDimitry Andric case M68k::MOVSXd32p8: 135fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8dp), MVT::i32, 136fe6060f1SDimitry Andric MVT::i8); 137fe6060f1SDimitry Andric case M68k::MOVSXd32p16: 138fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV16rp), MVT::i32, 139fe6060f1SDimitry Andric MVT::i16); 140fe6060f1SDimitry Andric 141fe6060f1SDimitry Andric case M68k::MOVZXd16p8: 142fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8dp), MVT::i16, 143fe6060f1SDimitry Andric MVT::i8); 144fe6060f1SDimitry Andric case M68k::MOVZXd32p8: 145fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8dp), MVT::i32, 146fe6060f1SDimitry Andric MVT::i8); 147fe6060f1SDimitry Andric case M68k::MOVZXd32p16: 148fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV16rp), MVT::i32, 149fe6060f1SDimitry Andric MVT::i16); 150fe6060f1SDimitry Andric 151fe6060f1SDimitry Andric case M68k::MOVSXd16f8: 152fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8df), MVT::i16, 153fe6060f1SDimitry Andric MVT::i8); 154fe6060f1SDimitry Andric case M68k::MOVSXd32f8: 155fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8df), MVT::i32, 156fe6060f1SDimitry Andric MVT::i8); 157fe6060f1SDimitry Andric case M68k::MOVSXd32f16: 158fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV16rf), MVT::i32, 159fe6060f1SDimitry Andric MVT::i16); 160fe6060f1SDimitry Andric 161fe6060f1SDimitry Andric case M68k::MOVZXd16f8: 162fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8df), MVT::i16, 163fe6060f1SDimitry Andric MVT::i8); 164fe6060f1SDimitry Andric case M68k::MOVZXd32f8: 165fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8df), MVT::i32, 166fe6060f1SDimitry Andric MVT::i8); 167fe6060f1SDimitry Andric case M68k::MOVZXd32f16: 168fe6060f1SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV16rf), MVT::i32, 169fe6060f1SDimitry Andric MVT::i16); 170fe6060f1SDimitry Andric 171647cbc5dSDimitry Andric case M68k::MOVSXd16q8: 172647cbc5dSDimitry Andric return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8dq), MVT::i16, 173647cbc5dSDimitry Andric MVT::i8); 174647cbc5dSDimitry Andric case M68k::MOVSXd32q8: 175647cbc5dSDimitry Andric return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV8dq), MVT::i32, 176647cbc5dSDimitry Andric MVT::i8); 177647cbc5dSDimitry Andric case M68k::MOVSXd32q16: 178647cbc5dSDimitry Andric return TII->ExpandMOVSZX_RM(MIB, true, TII->get(M68k::MOV16dq), MVT::i32, 179647cbc5dSDimitry Andric MVT::i16); 180647cbc5dSDimitry Andric 18106c3fb27SDimitry Andric case M68k::MOVZXd16q8: 18206c3fb27SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8dq), MVT::i16, 18306c3fb27SDimitry Andric MVT::i8); 18406c3fb27SDimitry Andric case M68k::MOVZXd32q8: 18506c3fb27SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8dq), MVT::i32, 18606c3fb27SDimitry Andric MVT::i8); 18706c3fb27SDimitry Andric case M68k::MOVZXd32q16: 18806c3fb27SDimitry Andric return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV16dq), MVT::i32, 18906c3fb27SDimitry Andric MVT::i16); 19006c3fb27SDimitry Andric 191fe6060f1SDimitry Andric case M68k::MOV8cd: 192fe6060f1SDimitry Andric return TII->ExpandCCR(MIB, /*IsToCCR=*/true); 193fe6060f1SDimitry Andric case M68k::MOV8dc: 194fe6060f1SDimitry Andric return TII->ExpandCCR(MIB, /*IsToCCR=*/false); 195fe6060f1SDimitry Andric 196fe6060f1SDimitry Andric case M68k::MOVM8jm_P: 197fe6060f1SDimitry Andric return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32jm), /*IsRM=*/false); 198fe6060f1SDimitry Andric case M68k::MOVM16jm_P: 199fe6060f1SDimitry Andric return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32jm), /*IsRM=*/false); 200fe6060f1SDimitry Andric case M68k::MOVM32jm_P: 201fe6060f1SDimitry Andric return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32jm), /*IsRM=*/false); 202fe6060f1SDimitry Andric 203fe6060f1SDimitry Andric case M68k::MOVM8pm_P: 204fe6060f1SDimitry Andric return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32pm), /*IsRM=*/false); 205fe6060f1SDimitry Andric case M68k::MOVM16pm_P: 206fe6060f1SDimitry Andric return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32pm), /*IsRM=*/false); 207fe6060f1SDimitry Andric case M68k::MOVM32pm_P: 208fe6060f1SDimitry Andric return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32pm), /*IsRM=*/false); 209fe6060f1SDimitry Andric 210fe6060f1SDimitry Andric case M68k::MOVM8mj_P: 211fe6060f1SDimitry Andric return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32mj), /*IsRM=*/true); 212fe6060f1SDimitry Andric case M68k::MOVM16mj_P: 213fe6060f1SDimitry Andric return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32mj), /*IsRM=*/true); 214fe6060f1SDimitry Andric case M68k::MOVM32mj_P: 215fe6060f1SDimitry Andric return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32mj), /*IsRM=*/true); 216fe6060f1SDimitry Andric 217fe6060f1SDimitry Andric case M68k::MOVM8mp_P: 218fe6060f1SDimitry Andric return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32mp), /*IsRM=*/true); 219fe6060f1SDimitry Andric case M68k::MOVM16mp_P: 220fe6060f1SDimitry Andric return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32mp), /*IsRM=*/true); 221fe6060f1SDimitry Andric case M68k::MOVM32mp_P: 222fe6060f1SDimitry Andric return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32mp), /*IsRM=*/true); 223fe6060f1SDimitry Andric 224fe6060f1SDimitry Andric case M68k::TCRETURNq: 225fe6060f1SDimitry Andric case M68k::TCRETURNj: { 226fe6060f1SDimitry Andric MachineOperand &JumpTarget = MI.getOperand(0); 227fe6060f1SDimitry Andric MachineOperand &StackAdjust = MI.getOperand(1); 228fe6060f1SDimitry Andric assert(StackAdjust.isImm() && "Expecting immediate value."); 229fe6060f1SDimitry Andric 230fe6060f1SDimitry Andric // Adjust stack pointer. 231fe6060f1SDimitry Andric int StackAdj = StackAdjust.getImm(); 232fe6060f1SDimitry Andric int MaxTCDelta = MFI->getTCReturnAddrDelta(); 233fe6060f1SDimitry Andric int Offset = 0; 234fe6060f1SDimitry Andric assert(MaxTCDelta <= 0 && "MaxTCDelta should never be positive"); 235fe6060f1SDimitry Andric 236fe6060f1SDimitry Andric // Incoporate the retaddr area. 237fe6060f1SDimitry Andric Offset = StackAdj - MaxTCDelta; 238fe6060f1SDimitry Andric assert(Offset >= 0 && "Offset should never be negative"); 239fe6060f1SDimitry Andric 240fe6060f1SDimitry Andric if (Offset) { 241fe6060f1SDimitry Andric // Check for possible merge with preceding ADD instruction. 242fe6060f1SDimitry Andric Offset += FL->mergeSPUpdates(MBB, MBBI, true); 243fe6060f1SDimitry Andric FL->emitSPUpdate(MBB, MBBI, Offset, /*InEpilogue=*/true); 244fe6060f1SDimitry Andric } 245fe6060f1SDimitry Andric 246fe6060f1SDimitry Andric // Jump to label or value in register. 247fe6060f1SDimitry Andric if (Opcode == M68k::TCRETURNq) { 248fe6060f1SDimitry Andric MachineInstrBuilder MIB = 249fe6060f1SDimitry Andric BuildMI(MBB, MBBI, DL, TII->get(M68k::TAILJMPq)); 250fe6060f1SDimitry Andric if (JumpTarget.isGlobal()) { 251fe6060f1SDimitry Andric MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(), 252fe6060f1SDimitry Andric JumpTarget.getTargetFlags()); 253fe6060f1SDimitry Andric } else { 254fe6060f1SDimitry Andric assert(JumpTarget.isSymbol()); 255fe6060f1SDimitry Andric MIB.addExternalSymbol(JumpTarget.getSymbolName(), 256fe6060f1SDimitry Andric JumpTarget.getTargetFlags()); 257fe6060f1SDimitry Andric } 258fe6060f1SDimitry Andric } else { 259fe6060f1SDimitry Andric BuildMI(MBB, MBBI, DL, TII->get(M68k::TAILJMPj)) 260fe6060f1SDimitry Andric .addReg(JumpTarget.getReg(), RegState::Kill); 261fe6060f1SDimitry Andric } 262fe6060f1SDimitry Andric 263fe6060f1SDimitry Andric MachineInstr &NewMI = *std::prev(MBBI); 264fe6060f1SDimitry Andric NewMI.copyImplicitOps(*MBBI->getParent()->getParent(), *MBBI); 265fe6060f1SDimitry Andric 266fe6060f1SDimitry Andric // Delete the pseudo instruction TCRETURN. 267fe6060f1SDimitry Andric MBB.erase(MBBI); 268fe6060f1SDimitry Andric 269fe6060f1SDimitry Andric return true; 270fe6060f1SDimitry Andric } 271fe6060f1SDimitry Andric case M68k::RET: { 2725f757f3fSDimitry Andric if (MBB.getParent()->getFunction().getCallingConv() == 2735f757f3fSDimitry Andric CallingConv::M68k_INTR) { 2745f757f3fSDimitry Andric BuildMI(MBB, MBBI, DL, TII->get(M68k::RTE)); 2755f757f3fSDimitry Andric } else if (int64_t StackAdj = MBBI->getOperand(0).getImm(); StackAdj == 0) { 2765f757f3fSDimitry Andric BuildMI(MBB, MBBI, DL, TII->get(M68k::RTS)); 277fe6060f1SDimitry Andric } else { 2785f757f3fSDimitry Andric // Copy return address from stack to a free address(A0 or A1) register 279fe6060f1SDimitry Andric // TODO check if pseudo expand uses free address register 280fe6060f1SDimitry Andric BuildMI(MBB, MBBI, DL, TII->get(M68k::MOV32aj), M68k::A1) 281fe6060f1SDimitry Andric .addReg(M68k::SP); 282fe6060f1SDimitry Andric 283fe6060f1SDimitry Andric // Adjust SP 284fe6060f1SDimitry Andric FL->emitSPUpdate(MBB, MBBI, StackAdj, /*InEpilogue=*/true); 285fe6060f1SDimitry Andric 286fe6060f1SDimitry Andric // Put the return address on stack 287fe6060f1SDimitry Andric BuildMI(MBB, MBBI, DL, TII->get(M68k::MOV32ja)) 288fe6060f1SDimitry Andric .addReg(M68k::SP) 289fe6060f1SDimitry Andric .addReg(M68k::A1); 290fe6060f1SDimitry Andric 291fe6060f1SDimitry Andric // RTS 292fe6060f1SDimitry Andric BuildMI(MBB, MBBI, DL, TII->get(M68k::RTS)); 293fe6060f1SDimitry Andric } 294fe6060f1SDimitry Andric 295fe6060f1SDimitry Andric // FIXME: Can rest of the operands be ignored, if there is any? 296fe6060f1SDimitry Andric MBB.erase(MBBI); 297fe6060f1SDimitry Andric return true; 298fe6060f1SDimitry Andric } 299fe6060f1SDimitry Andric } 300fe6060f1SDimitry Andric llvm_unreachable("Previous switch has a fallthrough?"); 301fe6060f1SDimitry Andric } 302fe6060f1SDimitry Andric 303fe6060f1SDimitry Andric /// Expand all pseudo instructions contained in \p MBB. 304fe6060f1SDimitry Andric /// \returns true if any expansion occurred for \p MBB. 305fe6060f1SDimitry Andric bool M68kExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) { 306fe6060f1SDimitry Andric bool Modified = false; 307fe6060f1SDimitry Andric 308fe6060f1SDimitry Andric // MBBI may be invalidated by the expansion. 309fe6060f1SDimitry Andric MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 310fe6060f1SDimitry Andric while (MBBI != E) { 311fe6060f1SDimitry Andric MachineBasicBlock::iterator NMBBI = std::next(MBBI); 312fe6060f1SDimitry Andric Modified |= ExpandMI(MBB, MBBI); 313fe6060f1SDimitry Andric MBBI = NMBBI; 314fe6060f1SDimitry Andric } 315fe6060f1SDimitry Andric 316fe6060f1SDimitry Andric return Modified; 317fe6060f1SDimitry Andric } 318fe6060f1SDimitry Andric 319fe6060f1SDimitry Andric bool M68kExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 32081ad6265SDimitry Andric STI = &MF.getSubtarget<M68kSubtarget>(); 321fe6060f1SDimitry Andric TII = STI->getInstrInfo(); 322fe6060f1SDimitry Andric TRI = STI->getRegisterInfo(); 323fe6060f1SDimitry Andric MFI = MF.getInfo<M68kMachineFunctionInfo>(); 324fe6060f1SDimitry Andric FL = STI->getFrameLowering(); 325fe6060f1SDimitry Andric 326fe6060f1SDimitry Andric bool Modified = false; 327fe6060f1SDimitry Andric for (MachineBasicBlock &MBB : MF) 328fe6060f1SDimitry Andric Modified |= ExpandMBB(MBB); 329fe6060f1SDimitry Andric return Modified; 330fe6060f1SDimitry Andric } 331fe6060f1SDimitry Andric 332fe6060f1SDimitry Andric /// Returns an instance of the pseudo instruction expansion pass. 333fe6060f1SDimitry Andric FunctionPass *llvm::createM68kExpandPseudoPass() { 334fe6060f1SDimitry Andric return new M68kExpandPseudo(); 335fe6060f1SDimitry Andric } 336