LLVM API Documentation

IA64InstrInfo.cpp

Go to the documentation of this file.
00001 //===- IA64InstrInfo.cpp - IA64 Instruction Information -----------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the IA64 implementation of the TargetInstrInfo class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "IA64InstrInfo.h"
00015 #include "IA64.h"
00016 #include "IA64InstrBuilder.h"
00017 #include "llvm/CodeGen/MachineInstrBuilder.h"
00018 #include "llvm/ADT/SmallVector.h"
00019 #include "IA64GenInstrInfo.inc"
00020 using namespace llvm;
00021 
00022 IA64InstrInfo::IA64InstrInfo()
00023   : TargetInstrInfoImpl(IA64Insts, sizeof(IA64Insts)/sizeof(IA64Insts[0])),
00024     RI(*this) {
00025 }
00026 
00027 
00028 bool IA64InstrInfo::isMoveInstr(const MachineInstr& MI,
00029                                 unsigned& sourceReg,
00030                                 unsigned& destReg,
00031                                 unsigned& SrcSR, unsigned& DstSR) const {
00032   SrcSR = DstSR = 0;  // No sub-registers.
00033 
00034   unsigned oc = MI.getOpcode();
00035   if (oc == IA64::MOV || oc == IA64::FMOV) {
00036   // TODO: this doesn't detect predicate moves
00037      assert(MI.getNumOperands() >= 2 &&
00038              /* MI.getOperand(0).isReg() &&
00039              MI.getOperand(1).isReg() && */
00040              "invalid register-register move instruction");
00041      if (MI.getOperand(0).isReg() &&
00042          MI.getOperand(1).isReg()) {
00043        // if both operands of the MOV/FMOV are registers, then
00044        // yes, this is a move instruction
00045        sourceReg = MI.getOperand(1).getReg();
00046        destReg = MI.getOperand(0).getReg();
00047        return true;
00048      }
00049   }
00050   return false; // we don't consider e.g. %regN = MOV <FrameIndex #x> a
00051                 // move instruction
00052 }
00053 
00054 unsigned
00055 IA64InstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
00056                             MachineBasicBlock *FBB,
00057                             const SmallVectorImpl<MachineOperand> &Cond)const {
00058   // Can only insert uncond branches so far.
00059   assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!");
00060   BuildMI(&MBB, get(IA64::BRL_NOTCALL)).addMBB(TBB);
00061   return 1;
00062 }
00063 
00064 bool IA64InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
00065                                    MachineBasicBlock::iterator MI,
00066                                    unsigned DestReg, unsigned SrcReg,
00067                                    const TargetRegisterClass *DestRC,
00068                                    const TargetRegisterClass *SrcRC) const {
00069   if (DestRC != SrcRC) {
00070     // Not yet supported!
00071     return false;
00072   }
00073 
00074   if(DestRC == IA64::PRRegisterClass ) // if a bool, we use pseudocode
00075     // (SrcReg) DestReg = cmp.eq.unc(r0, r0)
00076     BuildMI(MBB, MI, get(IA64::PCMPEQUNC), DestReg)
00077       .addReg(IA64::r0).addReg(IA64::r0).addReg(SrcReg);
00078   else // otherwise, MOV works (for both gen. regs and FP regs)
00079     BuildMI(MBB, MI, get(IA64::MOV), DestReg).addReg(SrcReg);
00080   
00081   return true;
00082 }
00083 
00084 void IA64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
00085                                            MachineBasicBlock::iterator MI,
00086                                            unsigned SrcReg, bool isKill,
00087                                            int FrameIdx,
00088                                            const TargetRegisterClass *RC) const{
00089 
00090   if (RC == IA64::FPRegisterClass) {
00091     BuildMI(MBB, MI, get(IA64::STF_SPILL)).addFrameIndex(FrameIdx)
00092       .addReg(SrcReg, false, false, isKill);
00093   } else if (RC == IA64::GRRegisterClass) {
00094     BuildMI(MBB, MI, get(IA64::ST8)).addFrameIndex(FrameIdx)
00095       .addReg(SrcReg, false, false, isKill);
00096   } else if (RC == IA64::PRRegisterClass) {
00097     /* we use IA64::r2 as a temporary register for doing this hackery. */
00098     // first we load 0:
00099     BuildMI(MBB, MI, get(IA64::MOV), IA64::r2).addReg(IA64::r0);
00100     // then conditionally add 1:
00101     BuildMI(MBB, MI, get(IA64::CADDIMM22), IA64::r2).addReg(IA64::r2)
00102       .addImm(1).addReg(SrcReg, false, false, isKill);
00103     // and then store it to the stack
00104     BuildMI(MBB, MI, get(IA64::ST8)).addFrameIndex(FrameIdx).addReg(IA64::r2);
00105   } else assert(0 &&
00106       "sorry, I don't know how to store this sort of reg in the stack\n");
00107 }
00108 
00109 void IA64InstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
00110                                       bool isKill,
00111                                       SmallVectorImpl<MachineOperand> &Addr,
00112                                       const TargetRegisterClass *RC,
00113                                  SmallVectorImpl<MachineInstr*> &NewMIs) const {
00114   unsigned Opc = 0;
00115   if (RC == IA64::FPRegisterClass) {
00116     Opc = IA64::STF8;
00117   } else if (RC == IA64::GRRegisterClass) {
00118     Opc = IA64::ST8;
00119   } else if (RC == IA64::PRRegisterClass) {
00120     Opc = IA64::ST1;
00121   } else {
00122     assert(0 &&
00123       "sorry, I don't know how to store this sort of reg\n");
00124   }
00125 
00126   MachineInstrBuilder MIB = BuildMI(MF, get(Opc));
00127   for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
00128     MachineOperand &MO = Addr[i];
00129     if (MO.isReg())
00130       MIB.addReg(MO.getReg());
00131     else if (MO.isImm())
00132       MIB.addImm(MO.getImm());
00133     else
00134       MIB.addFrameIndex(MO.getIndex());
00135   }
00136   MIB.addReg(SrcReg, false, false, isKill);
00137   NewMIs.push_back(MIB);
00138   return;
00139 
00140 }
00141 
00142 void IA64InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
00143                                             MachineBasicBlock::iterator MI,
00144                                             unsigned DestReg, int FrameIdx,
00145                                             const TargetRegisterClass *RC)const{
00146 
00147   if (RC == IA64::FPRegisterClass) {
00148     BuildMI(MBB, MI, get(IA64::LDF_FILL), DestReg).addFrameIndex(FrameIdx);
00149   } else if (RC == IA64::GRRegisterClass) {
00150     BuildMI(MBB, MI, get(IA64::LD8), DestReg).addFrameIndex(FrameIdx);
00151  } else if (RC == IA64::PRRegisterClass) {
00152    // first we load a byte from the stack into r2, our 'predicate hackery'
00153    // scratch reg
00154    BuildMI(MBB, MI, get(IA64::LD8), IA64::r2).addFrameIndex(FrameIdx);
00155    // then we compare it to zero. If it _is_ zero, compare-not-equal to
00156    // r0 gives us 0, which is what we want, so that's nice.
00157    BuildMI(MBB, MI, get(IA64::CMPNE), DestReg).addReg(IA64::r2).addReg(IA64::r0);
00158  } else assert(0 &&
00159      "sorry, I don't know how to load this sort of reg from the stack\n");
00160 }
00161 
00162 void IA64InstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
00163                                        SmallVectorImpl<MachineOperand> &Addr,
00164                                        const TargetRegisterClass *RC,
00165                                  SmallVectorImpl<MachineInstr*> &NewMIs) const {
00166   unsigned Opc = 0;
00167   if (RC == IA64::FPRegisterClass) {
00168     Opc = IA64::LDF8;
00169   } else if (RC == IA64::GRRegisterClass) {
00170     Opc = IA64::LD8;
00171   } else if (RC == IA64::PRRegisterClass) {
00172     Opc = IA64::LD1;
00173   } else {
00174     assert(0 &&
00175       "sorry, I don't know how to store this sort of reg\n");
00176   }
00177 
00178   MachineInstrBuilder MIB = BuildMI(MF, get(Opc), DestReg);
00179   for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
00180     MachineOperand &MO = Addr[i];
00181     if (MO.isReg())
00182       MIB.addReg(MO.getReg());
00183     else if (MO.isImm())
00184       MIB.addImm(MO.getImm());
00185     else
00186       MIB.addFrameIndex(MO.getIndex());
00187   }
00188   NewMIs.push_back(MIB);
00189   return;
00190 }