Home | History | Annotate | Download | only in ARM
      1 //===-- Thumb1InstrInfo.cpp - Thumb-1 Instruction Information -------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file contains the Thumb-1 implementation of the TargetInstrInfo class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "ARMSubtarget.h"
     15 #include "Thumb1InstrInfo.h"
     16 #include "llvm/CodeGen/MachineFrameInfo.h"
     17 #include "llvm/CodeGen/MachineInstrBuilder.h"
     18 #include "llvm/CodeGen/MachineMemOperand.h"
     19 #include "llvm/CodeGen/MachineRegisterInfo.h"
     20 #include "llvm/MC/MCInst.h"
     21 
     22 using namespace llvm;
     23 
     24 Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI)
     25     : ARMBaseInstrInfo(STI), RI() {}
     26 
     27 /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
     28 void Thumb1InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
     29   NopInst.setOpcode(ARM::tMOVr);
     30   NopInst.addOperand(MCOperand::CreateReg(ARM::R8));
     31   NopInst.addOperand(MCOperand::CreateReg(ARM::R8));
     32   NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
     33   NopInst.addOperand(MCOperand::CreateReg(0));
     34 }
     35 
     36 unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc) const {
     37   return 0;
     38 }
     39 
     40 void Thumb1InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
     41                                   MachineBasicBlock::iterator I, DebugLoc DL,
     42                                   unsigned DestReg, unsigned SrcReg,
     43                                   bool KillSrc) const {
     44   // Need to check the arch.
     45   MachineFunction &MF = *MBB.getParent();
     46   const ARMSubtarget &st = MF.getSubtarget<ARMSubtarget>();
     47 
     48   assert(ARM::GPRRegClass.contains(DestReg, SrcReg) &&
     49          "Thumb1 can only copy GPR registers");
     50 
     51   if (st.hasV6Ops() || ARM::hGPRRegClass.contains(SrcReg)
     52       || !ARM::tGPRRegClass.contains(DestReg))
     53     AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg)
     54       .addReg(SrcReg, getKillRegState(KillSrc)));
     55   else {
     56     // FIXME: The performance consequences of this are going to be atrocious.
     57     // Some things to try that should be better:
     58     //   * 'mov hi, $src; mov $dst, hi', with hi as either r10 or r11
     59     //   * 'movs $dst, $src' if cpsr isn't live
     60     // See: http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-August/075998.html
     61 
     62     // 'MOV lo, lo' is unpredictable on < v6, so use the stack to do it
     63     AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tPUSH)))
     64       .addReg(SrcReg, getKillRegState(KillSrc));
     65     AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tPOP)))
     66       .addReg(DestReg, getDefRegState(true));
     67   }
     68 }
     69 
     70 void Thumb1InstrInfo::
     71 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
     72                     unsigned SrcReg, bool isKill, int FI,
     73                     const TargetRegisterClass *RC,
     74                     const TargetRegisterInfo *TRI) const {
     75   assert((RC == &ARM::tGPRRegClass ||
     76           (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
     77            isARMLowRegister(SrcReg))) && "Unknown regclass!");
     78 
     79   if (RC == &ARM::tGPRRegClass ||
     80       (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
     81        isARMLowRegister(SrcReg))) {
     82     DebugLoc DL;
     83     if (I != MBB.end()) DL = I->getDebugLoc();
     84 
     85     MachineFunction &MF = *MBB.getParent();
     86     MachineFrameInfo &MFI = *MF.getFrameInfo();
     87     MachineMemOperand *MMO =
     88       MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI),
     89                               MachineMemOperand::MOStore,
     90                               MFI.getObjectSize(FI),
     91                               MFI.getObjectAlignment(FI));
     92     AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tSTRspi))
     93                    .addReg(SrcReg, getKillRegState(isKill))
     94                    .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
     95   }
     96 }
     97 
     98 void Thumb1InstrInfo::
     99 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
    100                      unsigned DestReg, int FI,
    101                      const TargetRegisterClass *RC,
    102                      const TargetRegisterInfo *TRI) const {
    103   assert((RC == &ARM::tGPRRegClass ||
    104           (TargetRegisterInfo::isPhysicalRegister(DestReg) &&
    105            isARMLowRegister(DestReg))) && "Unknown regclass!");
    106 
    107   if (RC == &ARM::tGPRRegClass ||
    108       (TargetRegisterInfo::isPhysicalRegister(DestReg) &&
    109        isARMLowRegister(DestReg))) {
    110     DebugLoc DL;
    111     if (I != MBB.end()) DL = I->getDebugLoc();
    112 
    113     MachineFunction &MF = *MBB.getParent();
    114     MachineFrameInfo &MFI = *MF.getFrameInfo();
    115     MachineMemOperand *MMO =
    116       MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI),
    117                               MachineMemOperand::MOLoad,
    118                               MFI.getObjectSize(FI),
    119                               MFI.getObjectAlignment(FI));
    120     AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tLDRspi), DestReg)
    121                    .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
    122   }
    123 }
    124 
    125 void
    126 Thumb1InstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI,
    127                                       Reloc::Model RM) const {
    128   if (RM == Reloc::PIC_)
    129     expandLoadStackGuardBase(MI, ARM::tLDRLIT_ga_pcrel, ARM::tLDRi, RM);
    130   else
    131     expandLoadStackGuardBase(MI, ARM::tLDRLIT_ga_abs, ARM::tLDRi, RM);
    132 }
    133