brintos

brintos / llvm-project-archived public Read only

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