AArch64/ARM64: remove AArch64 from tree prior to renaming ARM64.
[oota-llvm.git] / lib / Target / ARM64 / ARM64CallingConv.h
1 //=== ARM64CallingConv.h - Custom Calling Convention Routines -*- 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 contains the custom routines for the ARM64 Calling Convention that
11 // aren't done by tablegen.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef ARM64CALLINGCONV_H
16 #define ARM64CALLINGCONV_H
17
18 #include "ARM64InstrInfo.h"
19 #include "llvm/IR/CallingConv.h"
20 #include "llvm/CodeGen/CallingConvLower.h"
21 #include "llvm/Target/TargetInstrInfo.h"
22
23 namespace llvm {
24
25 /// CC_ARM64_Custom_i1i8i16_Reg - customized handling of passing i1/i8/i16 via
26 /// register. Here, ValVT can be i1/i8/i16 or i32 depending on whether the
27 /// argument is already promoted and LocVT is i1/i8/i16. We only promote the
28 /// argument to i32 if we are sure this argument will be passed in register.
29 static bool CC_ARM64_Custom_i1i8i16_Reg(unsigned ValNo, MVT ValVT, MVT LocVT,
30                                         CCValAssign::LocInfo LocInfo,
31                                         ISD::ArgFlagsTy ArgFlags,
32                                         CCState &State,
33                                         bool IsWebKitJS = false) {
34   static const MCPhysReg RegList1[] = { ARM64::W0, ARM64::W1, ARM64::W2,
35                                         ARM64::W3, ARM64::W4, ARM64::W5,
36                                         ARM64::W6, ARM64::W7 };
37   static const MCPhysReg RegList2[] = { ARM64::X0, ARM64::X1, ARM64::X2,
38                                         ARM64::X3, ARM64::X4, ARM64::X5,
39                                         ARM64::X6, ARM64::X7 };
40   static const MCPhysReg WebKitRegList1[] = { ARM64::W0 };
41   static const MCPhysReg WebKitRegList2[] = { ARM64::X0 };
42
43   const MCPhysReg *List1 = IsWebKitJS ? WebKitRegList1 : RegList1;
44   const MCPhysReg *List2 = IsWebKitJS ? WebKitRegList2 : RegList2;
45
46   if (unsigned Reg = State.AllocateReg(List1, List2, 8)) {
47     // Customized extra section for handling i1/i8/i16:
48     // We need to promote the argument to i32 if it is not done already.
49     if (ValVT != MVT::i32) {
50       if (ArgFlags.isSExt())
51         LocInfo = CCValAssign::SExt;
52       else if (ArgFlags.isZExt())
53         LocInfo = CCValAssign::ZExt;
54       else
55         LocInfo = CCValAssign::AExt;
56       ValVT = MVT::i32;
57     }
58     // Set LocVT to i32 as well if passing via register.
59     LocVT = MVT::i32;
60     State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
61     return true;
62   }
63   return false;
64 }
65
66 /// CC_ARM64_WebKit_JS_i1i8i16_Reg - customized handling of passing i1/i8/i16
67 /// via register. This behaves the same as CC_ARM64_Custom_i1i8i16_Reg, but only
68 /// uses the first register.
69 static bool CC_ARM64_WebKit_JS_i1i8i16_Reg(unsigned ValNo, MVT ValVT, MVT LocVT,
70                                            CCValAssign::LocInfo LocInfo,
71                                            ISD::ArgFlagsTy ArgFlags,
72                                            CCState &State) {
73   return CC_ARM64_Custom_i1i8i16_Reg(ValNo, ValVT, LocVT, LocInfo, ArgFlags,
74                                      State, true);
75 }
76
77 /// CC_ARM64_Custom_i1i8i16_Stack: customized handling of passing i1/i8/i16 on
78 /// stack. Here, ValVT can be i1/i8/i16 or i32 depending on whether the argument
79 /// is already promoted and LocVT is i1/i8/i16. If ValVT is already promoted,
80 /// it will be truncated back to i1/i8/i16.
81 static bool CC_ARM64_Custom_i1i8i16_Stack(unsigned ValNo, MVT ValVT, MVT LocVT,
82                                           CCValAssign::LocInfo LocInfo,
83                                           ISD::ArgFlagsTy ArgFlags,
84                                           CCState &State) {
85   unsigned Space = ((LocVT == MVT::i1 || LocVT == MVT::i8) ? 1 : 2);
86   unsigned Offset12 = State.AllocateStack(Space, Space);
87   ValVT = LocVT;
88   State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset12, LocVT, LocInfo));
89   return true;
90 }
91
92 } // End llvm namespace
93
94 #endif