Home | History | Annotate | Download | only in Hexagon
      1 //===-- llvm/CallingConvLower.cpp - Calling Convention lowering -----------===//
      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 implements the Hexagon_CCState class, used for lowering and
     11 // implementing calling conventions. Adapted from the machine independent
     12 // version of the class (CCState) but this handles calls to varargs functions
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #include "HexagonCallingConvLower.h"
     17 #include "Hexagon.h"
     18 #include "llvm/IR/DataLayout.h"
     19 #include "llvm/Support/Debug.h"
     20 #include "llvm/Support/ErrorHandling.h"
     21 #include "llvm/Support/raw_ostream.h"
     22 #include "llvm/Target/TargetMachine.h"
     23 #include "llvm/Target/TargetRegisterInfo.h"
     24 using namespace llvm;
     25 
     26 Hexagon_CCState::Hexagon_CCState(CallingConv::ID CC, bool isVarArg,
     27                                  const TargetMachine &tm,
     28                                  SmallVectorImpl<CCValAssign> &locs,
     29                                  LLVMContext &c)
     30   : CallingConv(CC), IsVarArg(isVarArg), TM(tm), Locs(locs), Context(c) {
     31   // No stack is used.
     32   StackOffset = 0;
     33 
     34   UsedRegs.resize((TM.getRegisterInfo()->getNumRegs()+31)/32);
     35 }
     36 
     37 // HandleByVal - Allocate a stack slot large enough to pass an argument by
     38 // value. The size and alignment information of the argument is encoded in its
     39 // parameter attribute.
     40 void Hexagon_CCState::HandleByVal(unsigned ValNo, EVT ValVT,
     41                                 EVT LocVT, CCValAssign::LocInfo LocInfo,
     42                                 int MinSize, int MinAlign,
     43                                 ISD::ArgFlagsTy ArgFlags) {
     44   unsigned Align = ArgFlags.getByValAlign();
     45   unsigned Size  = ArgFlags.getByValSize();
     46   if (MinSize > (int)Size)
     47     Size = MinSize;
     48   if (MinAlign > (int)Align)
     49     Align = MinAlign;
     50   unsigned Offset = AllocateStack(Size, Align);
     51 
     52   addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset,
     53                              LocVT.getSimpleVT(), LocInfo));
     54 }
     55 
     56 /// MarkAllocated - Mark a register and all of its aliases as allocated.
     57 void Hexagon_CCState::MarkAllocated(unsigned Reg) {
     58   const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
     59   for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)
     60     UsedRegs[*AI/32] |= 1 << (*AI&31);
     61 }
     62 
     63 /// AnalyzeFormalArguments - Analyze an ISD::FORMAL_ARGUMENTS node,
     64 /// incorporating info about the formals into this state.
     65 void
     66 Hexagon_CCState::AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg>
     67                                         &Ins,
     68                                         Hexagon_CCAssignFn Fn,
     69                                         unsigned SretValueInRegs) {
     70   unsigned NumArgs = Ins.size();
     71   unsigned i = 0;
     72 
     73   // If the function returns a small struct in registers, skip
     74   // over the first (dummy) argument.
     75   if (SretValueInRegs != 0) {
     76     ++i;
     77   }
     78 
     79 
     80   for (; i != NumArgs; ++i) {
     81     EVT ArgVT = Ins[i].VT;
     82     ISD::ArgFlagsTy ArgFlags = Ins[i].Flags;
     83     if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this, 0, 0, false)) {
     84       dbgs() << "Formal argument #" << i << " has unhandled type "
     85              << ArgVT.getEVTString() << "\n";
     86       abort();
     87     }
     88   }
     89 }
     90 
     91 /// AnalyzeReturn - Analyze the returned values of an ISD::RET node,
     92 /// incorporating info about the result values into this state.
     93 void
     94 Hexagon_CCState::AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
     95                                Hexagon_CCAssignFn Fn,
     96                                unsigned SretValueInRegs) {
     97 
     98   // For Hexagon, Return small structures in registers.
     99   if (SretValueInRegs != 0) {
    100     if (SretValueInRegs <= 32) {
    101       unsigned Reg = Hexagon::R0;
    102       addLoc(CCValAssign::getReg(0, MVT::i32, Reg, MVT::i32,
    103                                  CCValAssign::Full));
    104       return;
    105     }
    106     if (SretValueInRegs <= 64) {
    107       unsigned Reg = Hexagon::D0;
    108       addLoc(CCValAssign::getReg(0, MVT::i64, Reg, MVT::i64,
    109                                  CCValAssign::Full));
    110       return;
    111     }
    112   }
    113 
    114 
    115   // Determine which register each value should be copied into.
    116   for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
    117     EVT VT = Outs[i].VT;
    118     ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
    119     if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this, -1, -1, false)){
    120       dbgs() << "Return operand #" << i << " has unhandled type "
    121            << VT.getEVTString() << "\n";
    122       abort();
    123     }
    124   }
    125 }
    126 
    127 
    128 /// AnalyzeCallOperands - Analyze an ISD::CALL node, incorporating info
    129 /// about the passed values into this state.
    130 void
    131 Hexagon_CCState::AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg>
    132                                      &Outs,
    133                                      Hexagon_CCAssignFn Fn,
    134                                      int NonVarArgsParams,
    135                                      unsigned SretValueSize) {
    136   unsigned NumOps = Outs.size();
    137 
    138   unsigned i = 0;
    139   // If the called function returns a small struct in registers, skip
    140   // the first actual parameter. We do not want to pass a pointer to
    141   // the stack location.
    142   if (SretValueSize != 0) {
    143     ++i;
    144   }
    145 
    146   for (; i != NumOps; ++i) {
    147     EVT ArgVT = Outs[i].VT;
    148     ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
    149     if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this,
    150            NonVarArgsParams, i+1, false)) {
    151       dbgs() << "Call operand #" << i << " has unhandled type "
    152            << ArgVT.getEVTString() << "\n";
    153       abort();
    154     }
    155   }
    156 }
    157 
    158 /// AnalyzeCallOperands - Same as above except it takes vectors of types
    159 /// and argument flags.
    160 void
    161 Hexagon_CCState::AnalyzeCallOperands(SmallVectorImpl<EVT> &ArgVTs,
    162                                      SmallVectorImpl<ISD::ArgFlagsTy> &Flags,
    163                                      Hexagon_CCAssignFn Fn) {
    164   unsigned NumOps = ArgVTs.size();
    165   for (unsigned i = 0; i != NumOps; ++i) {
    166     EVT ArgVT = ArgVTs[i];
    167     ISD::ArgFlagsTy ArgFlags = Flags[i];
    168     if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this, -1, -1,
    169            false)) {
    170       dbgs() << "Call operand #" << i << " has unhandled type "
    171            << ArgVT.getEVTString() << "\n";
    172       abort();
    173     }
    174   }
    175 }
    176 
    177 /// AnalyzeCallResult - Analyze the return values of an ISD::CALL node,
    178 /// incorporating info about the passed values into this state.
    179 void
    180 Hexagon_CCState::AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins,
    181                                    Hexagon_CCAssignFn Fn,
    182                                    unsigned SretValueInRegs) {
    183 
    184   for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
    185     EVT VT = Ins[i].VT;
    186     ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy();
    187       if (Fn(i, VT, VT, CCValAssign::Full, Flags, *this, -1, -1, false)) {
    188         dbgs() << "Call result #" << i << " has unhandled type "
    189                << VT.getEVTString() << "\n";
    190       abort();
    191     }
    192   }
    193 }
    194 
    195 /// AnalyzeCallResult - Same as above except it's specialized for calls which
    196 /// produce a single value.
    197 void Hexagon_CCState::AnalyzeCallResult(EVT VT, Hexagon_CCAssignFn Fn) {
    198   if (Fn(0, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this, -1, -1,
    199          false)) {
    200     dbgs() << "Call result has unhandled type "
    201          << VT.getEVTString() << "\n";
    202     abort();
    203   }
    204 }
    205