Home | History | Annotate | Download | only in Hexagon
      1 //===-- HexagonVarargsCallingConvention.h - Calling Conventions -*- C++ -*-===//
      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 declares the functions that assign locations to outgoing function
     11 // arguments. Adapted from the target independent version but this handles
     12 // calls to varargs functions
     13 //
     14 //===----------------------------------------------------------------------===//
     15 //
     16 
     17 
     18 
     19 
     20 static bool RetCC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
     21                                     EVT LocVT, CCValAssign::LocInfo LocInfo,
     22                                     ISD::ArgFlagsTy ArgFlags,
     23                                     Hexagon_CCState &State,
     24                                     int NonVarArgsParams,
     25                                     int CurrentParam,
     26                                     bool ForceMem);
     27 
     28 
     29 static bool CC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
     30                                  EVT LocVT, CCValAssign::LocInfo LocInfo,
     31                                  ISD::ArgFlagsTy ArgFlags,
     32                                  Hexagon_CCState &State,
     33                                  int NonVarArgsParams,
     34                                  int CurrentParam,
     35                                  bool ForceMem) {
     36   unsigned ByValSize = 0;
     37   if (ArgFlags.isByVal() &&
     38       ((ByValSize = ArgFlags.getByValSize()) >
     39        (MVT(MVT::i64).getSizeInBits() / 8))) {
     40     ForceMem = true;
     41   }
     42 
     43 
     44   // Only assign registers for named (non-varargs) arguments
     45   if ( !ForceMem && ((NonVarArgsParams == -1) || (CurrentParam <=
     46                                                   NonVarArgsParams))) {
     47 
     48     if (LocVT == MVT::i32 ||
     49         LocVT == MVT::i16 ||
     50         LocVT == MVT::i8 ||
     51         LocVT == MVT::f32) {
     52       static const unsigned RegList1[] = {
     53         Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
     54         Hexagon::R5
     55       };
     56       if (unsigned Reg = State.AllocateReg(RegList1, 6)) {
     57         State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
     58                                          LocVT.getSimpleVT(), LocInfo));
     59         return false;
     60       }
     61     }
     62 
     63     if (LocVT == MVT::i64 ||
     64         LocVT == MVT::f64) {
     65       static const unsigned RegList2[] = {
     66         Hexagon::D0, Hexagon::D1, Hexagon::D2
     67       };
     68       if (unsigned Reg = State.AllocateReg(RegList2, 3)) {
     69         State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
     70                                          LocVT.getSimpleVT(), LocInfo));
     71         return false;
     72       }
     73     }
     74   }
     75 
     76   const Type* ArgTy = LocVT.getTypeForEVT(State.getContext());
     77   unsigned Alignment =
     78     State.getTarget().getDataLayout()->getABITypeAlignment(ArgTy);
     79   unsigned Size =
     80     State.getTarget().getDataLayout()->getTypeSizeInBits(ArgTy) / 8;
     81 
     82   // If it's passed by value, then we need the size of the aggregate not of
     83   // the pointer.
     84   if (ArgFlags.isByVal()) {
     85     Size = ByValSize;
     86 
     87     // Hexagon_TODO: Get the alignment of the contained type here.
     88     Alignment = 8;
     89   }
     90 
     91   unsigned Offset3 = State.AllocateStack(Size, Alignment);
     92   State.addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset3,
     93                                    LocVT.getSimpleVT(), LocInfo));
     94   return false;
     95 }
     96 
     97 
     98 static bool RetCC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
     99                                     EVT LocVT, CCValAssign::LocInfo LocInfo,
    100                                     ISD::ArgFlagsTy ArgFlags,
    101                                     Hexagon_CCState &State,
    102                                     int NonVarArgsParams,
    103                                     int CurrentParam,
    104                                     bool ForceMem) {
    105 
    106   if (LocVT == MVT::i32 ||
    107       LocVT == MVT::f32) {
    108     static const unsigned RegList1[] = {
    109       Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
    110       Hexagon::R5
    111     };
    112     if (unsigned Reg = State.AllocateReg(RegList1, 6)) {
    113       State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
    114                                        LocVT.getSimpleVT(), LocInfo));
    115       return false;
    116     }
    117   }
    118 
    119   if (LocVT == MVT::i64 ||
    120       LocVT == MVT::f64) {
    121     static const unsigned RegList2[] = {
    122       Hexagon::D0, Hexagon::D1, Hexagon::D2
    123     };
    124     if (unsigned Reg = State.AllocateReg(RegList2, 3)) {
    125       State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
    126                                        LocVT.getSimpleVT(), LocInfo));
    127       return false;
    128     }
    129   }
    130 
    131   const Type* ArgTy = LocVT.getTypeForEVT(State.getContext());
    132   unsigned Alignment =
    133     State.getTarget().getDataLayout()->getABITypeAlignment(ArgTy);
    134   unsigned Size =
    135     State.getTarget().getDataLayout()->getTypeSizeInBits(ArgTy) / 8;
    136 
    137   unsigned Offset3 = State.AllocateStack(Size, Alignment);
    138   State.addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset3,
    139                                    LocVT.getSimpleVT(), LocInfo));
    140   return false;
    141 }
    142