brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.4 KiB · 01f588f Raw
205 lines · cpp
1//===-- Thumb1InstrInfo.cpp - Thumb-1 Instruction Information -------------===//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// This file contains the Thumb-1 implementation of the TargetInstrInfo class.10//11//===----------------------------------------------------------------------===//12 13#include "Thumb1InstrInfo.h"14#include "ARMSubtarget.h"15#include "llvm/ADT/BitVector.h"16#include "llvm/CodeGen/LiveRegUnits.h"17#include "llvm/CodeGen/MachineFrameInfo.h"18#include "llvm/CodeGen/MachineInstrBuilder.h"19#include "llvm/CodeGen/MachineMemOperand.h"20#include "llvm/IR/Module.h"21#include "llvm/MC/MCInst.h"22#include "llvm/MC/MCInstBuilder.h"23 24using namespace llvm;25 26Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI)27    : ARMBaseInstrInfo(STI, RI), RI(STI) {}28 29/// Return the noop instruction to use for a noop.30MCInst Thumb1InstrInfo::getNop() const {31  return MCInstBuilder(ARM::tMOVr)32      .addReg(ARM::R8)33      .addReg(ARM::R8)34      .addImm(ARMCC::AL)35      .addReg(0);36}37 38unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc) const {39  return 0;40}41 42void Thumb1InstrInfo::copyPhysReg(MachineBasicBlock &MBB,43                                  MachineBasicBlock::iterator I,44                                  const DebugLoc &DL, Register DestReg,45                                  Register SrcReg, bool KillSrc,46                                  bool RenamableDest, bool RenamableSrc) const {47  // Need to check the arch.48  MachineFunction &MF = *MBB.getParent();49  const ARMSubtarget &st = MF.getSubtarget<ARMSubtarget>();50 51  assert(ARM::GPRRegClass.contains(DestReg, SrcReg) &&52         "Thumb1 can only copy GPR registers");53 54  if (st.hasV6Ops() || ARM::hGPRRegClass.contains(SrcReg) ||55      !ARM::tGPRRegClass.contains(DestReg))56    BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg)57        .addReg(SrcReg, getKillRegState(KillSrc))58        .add(predOps(ARMCC::AL));59  else {60    const TargetRegisterInfo *RegInfo = st.getRegisterInfo();61    LiveRegUnits UsedRegs(*RegInfo);62    UsedRegs.addLiveOuts(MBB);63 64    auto InstUpToI = MBB.end();65    while (InstUpToI != I)66      // The pre-decrement is on purpose here.67      // We want to have the liveness right before I.68      UsedRegs.stepBackward(*--InstUpToI);69 70    if (UsedRegs.available(ARM::CPSR)) {71      BuildMI(MBB, I, DL, get(ARM::tMOVSr), DestReg)72          .addReg(SrcReg, getKillRegState(KillSrc))73          ->addRegisterDead(ARM::CPSR, RegInfo);74      return;75    }76 77    // Use high register to move source to destination78    // if movs is not an option.79    BitVector Allocatable = RegInfo->getAllocatableSet(80        MF, RegInfo->getRegClass(ARM::hGPRRegClassID));81 82    Register TmpReg = ARM::NoRegister;83    // Prefer R12 as it is known to not be preserved anyway84    if (UsedRegs.available(ARM::R12) && Allocatable.test(ARM::R12)) {85      TmpReg = ARM::R12;86    } else {87      for (Register Reg : Allocatable.set_bits()) {88        if (UsedRegs.available(Reg)) {89          TmpReg = Reg;90          break;91        }92      }93    }94 95    if (TmpReg) {96      BuildMI(MBB, I, DL, get(ARM::tMOVr), TmpReg)97          .addReg(SrcReg, getKillRegState(KillSrc))98          .add(predOps(ARMCC::AL));99      BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg)100          .addReg(TmpReg, getKillRegState(true))101          .add(predOps(ARMCC::AL));102      return;103    }104 105    // 'MOV lo, lo' is unpredictable on < v6, so use the stack to do it106    BuildMI(MBB, I, DL, get(ARM::tPUSH))107        .add(predOps(ARMCC::AL))108        .addReg(SrcReg, getKillRegState(KillSrc));109    BuildMI(MBB, I, DL, get(ARM::tPOP))110        .add(predOps(ARMCC::AL))111        .addReg(DestReg, getDefRegState(true));112  }113}114 115void Thumb1InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,116                                          MachineBasicBlock::iterator I,117                                          Register SrcReg, bool isKill, int FI,118                                          const TargetRegisterClass *RC,119                                          Register VReg,120                                          MachineInstr::MIFlag Flags) const {121  assert((RC == &ARM::tGPRRegClass ||122          (SrcReg.isPhysical() && isARMLowRegister(SrcReg))) &&123         "Unknown regclass!");124 125  if (RC == &ARM::tGPRRegClass ||126      (SrcReg.isPhysical() && isARMLowRegister(SrcReg))) {127    DebugLoc DL;128    if (I != MBB.end()) DL = I->getDebugLoc();129 130    MachineFunction &MF = *MBB.getParent();131    MachineFrameInfo &MFI = MF.getFrameInfo();132    MachineMemOperand *MMO = MF.getMachineMemOperand(133        MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,134        MFI.getObjectSize(FI), MFI.getObjectAlign(FI));135    BuildMI(MBB, I, DL, get(ARM::tSTRspi))136        .addReg(SrcReg, getKillRegState(isKill))137        .addFrameIndex(FI)138        .addImm(0)139        .addMemOperand(MMO)140        .add(predOps(ARMCC::AL));141  }142}143 144void Thumb1InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,145                                           MachineBasicBlock::iterator I,146                                           Register DestReg, int FI,147                                           const TargetRegisterClass *RC,148                                           Register VReg,149                                           MachineInstr::MIFlag Flags) const {150  assert((RC->hasSuperClassEq(&ARM::tGPRRegClass) ||151          (DestReg.isPhysical() && isARMLowRegister(DestReg))) &&152         "Unknown regclass!");153 154  if (RC->hasSuperClassEq(&ARM::tGPRRegClass) ||155      (DestReg.isPhysical() && isARMLowRegister(DestReg))) {156    DebugLoc DL;157    if (I != MBB.end()) DL = I->getDebugLoc();158 159    MachineFunction &MF = *MBB.getParent();160    MachineFrameInfo &MFI = MF.getFrameInfo();161    MachineMemOperand *MMO = MF.getMachineMemOperand(162        MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,163        MFI.getObjectSize(FI), MFI.getObjectAlign(FI));164    BuildMI(MBB, I, DL, get(ARM::tLDRspi), DestReg)165        .addFrameIndex(FI)166        .addImm(0)167        .addMemOperand(MMO)168        .add(predOps(ARMCC::AL));169  }170}171 172void Thumb1InstrInfo::expandLoadStackGuard(173    MachineBasicBlock::iterator MI) const {174  MachineFunction &MF = *MI->getParent()->getParent();175  const ARMSubtarget &ST = MF.getSubtarget<ARMSubtarget>();176  const auto *GV = cast<GlobalValue>((*MI->memoperands_begin())->getValue());177 178  assert(MF.getFunction().getParent()->getStackProtectorGuard() != "tls" &&179         "TLS stack protector not supported for Thumb1 targets");180 181  unsigned Instr;182  if (!GV->isDSOLocal())183    Instr = ARM::tLDRLIT_ga_pcrel;184  else if (ST.genExecuteOnly() && ST.hasV8MBaselineOps())185    Instr = ARM::t2MOVi32imm;186  else if (ST.genExecuteOnly())187    Instr = ARM::tMOVi32imm;188  else189    Instr = ARM::tLDRLIT_ga_abs;190  expandLoadStackGuardBase(MI, Instr, ARM::tLDRi);191}192 193bool Thumb1InstrInfo::canCopyGluedNodeDuringSchedule(SDNode *N) const {194  // In Thumb1 the scheduler may need to schedule a cross-copy between GPRS and CPSR195  // but this is not always possible there, so allow the Scheduler to clone tADCS and tSBCS196  // even if they have glue.197  // FIXME. Actually implement the cross-copy where it is possible (post v6)198  // because these copies entail more spilling.199  unsigned Opcode = N->getMachineOpcode();200  if (Opcode == ARM::tADCS || Opcode == ARM::tSBCS)201    return true;202 203  return false;204}205