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.llvm.org/pipermail/llvm-dev/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 = MF.getMachineMemOperand(
     88         MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
     89         MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
     90     AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tSTRspi))
     91                    .addReg(SrcReg, getKillRegState(isKill))
     92                    .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
     93   }
     94 }
     95 
     96 void Thumb1InstrInfo::
     97 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
     98                      unsigned DestReg, int FI,
     99                      const TargetRegisterClass *RC,
    100                      const TargetRegisterInfo *TRI) const {
    101   assert((RC == &ARM::tGPRRegClass ||
    102           (TargetRegisterInfo::isPhysicalRegister(DestReg) &&
    103            isARMLowRegister(DestReg))) && "Unknown regclass!");
    104 
    105   if (RC == &ARM::tGPRRegClass ||
    106       (TargetRegisterInfo::isPhysicalRegister(DestReg) &&
    107        isARMLowRegister(DestReg))) {
    108     DebugLoc DL;
    109     if (I != MBB.end()) DL = I->getDebugLoc();
    110 
    111     MachineFunction &MF = *MBB.getParent();
    112     MachineFrameInfo &MFI = *MF.getFrameInfo();
    113     MachineMemOperand *MMO = MF.getMachineMemOperand(
    114         MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
    115         MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
    116     AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tLDRspi), DestReg)
    117                    .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
    118   }
    119 }
    120 
    121 void
    122 Thumb1InstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI,
    123                                       Reloc::Model RM) const {
    124   if (RM == Reloc::PIC_)
    125     expandLoadStackGuardBase(MI, ARM::tLDRLIT_ga_pcrel, ARM::tLDRi, RM);
    126   else
    127     expandLoadStackGuardBase(MI, ARM::tLDRLIT_ga_abs, ARM::tLDRi, RM);
    128 }
    129