131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//=== ARMCallingConv.h - ARM Custom Calling Convention Routines -*- C++ -*-===// 26f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher// 36f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher// The LLVM Compiler Infrastructure 46f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher// 56f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher// This file is distributed under the University of Illinois Open Source 66f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher// License. See LICENSE.TXT for details. 76f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher// 86f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher//===----------------------------------------------------------------------===// 96f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher// 106f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher// This file contains the custom routines for the ARM Calling Convention that 116f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher// aren't done by tablegen. 126f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher// 136f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher//===----------------------------------------------------------------------===// 146f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 156f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher#ifndef ARMCALLINGCONV_H 166f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher#define ARMCALLINGCONV_H 176f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 18c1f6f42049696e7357fb4837e1b25dabbaed3fe6Craig Topper#include "ARM.h" 196f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher#include "ARMBaseInstrInfo.h" 206f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher#include "ARMSubtarget.h" 21c1f6f42049696e7357fb4837e1b25dabbaed3fe6Craig Topper#include "llvm/CallingConv.h" 22c1f6f42049696e7357fb4837e1b25dabbaed3fe6Craig Topper#include "llvm/CodeGen/CallingConvLower.h" 23c1f6f42049696e7357fb4837e1b25dabbaed3fe6Craig Topper#include "llvm/Target/TargetInstrInfo.h" 246f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 256f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christophernamespace llvm { 266f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 276f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher// APCS f64 is in register pairs, possibly split to stack 281e96bab329eb23e4ce8a0dc3cc6b33a3f03d15bfDuncan Sandsstatic bool f64AssignAPCS(unsigned &ValNo, MVT &ValVT, MVT &LocVT, 296f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher CCValAssign::LocInfo &LocInfo, 306f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher CCState &State, bool CanFail) { 31c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper static const uint16_t RegList[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 }; 326f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 336f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher // Try to get the first register. 346f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher if (unsigned Reg = State.AllocateReg(RegList, 4)) 356f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 366f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher else { 376f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher // For the 2nd half of a v2f64, do not fail. 386f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher if (CanFail) 396f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return false; 406f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 416f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher // Put the whole thing on the stack. 426f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT, 436f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher State.AllocateStack(8, 4), 446f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher LocVT, LocInfo)); 456f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return true; 466f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher } 476f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 486f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher // Try to get the second register. 496f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher if (unsigned Reg = State.AllocateReg(RegList, 4)) 506f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 516f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher else 526f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT, 536f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher State.AllocateStack(4, 4), 546f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher LocVT, LocInfo)); 556f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return true; 566f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher} 576f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 581e96bab329eb23e4ce8a0dc3cc6b33a3f03d15bfDuncan Sandsstatic bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT, 596f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher CCValAssign::LocInfo &LocInfo, 606f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher ISD::ArgFlagsTy &ArgFlags, 616f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher CCState &State) { 626f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher if (!f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, true)) 636f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return false; 646f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher if (LocVT == MVT::v2f64 && 656f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher !f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, false)) 666f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return false; 676f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return true; // we handled it 686f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher} 696f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 706f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher// AAPCS f64 is in aligned register pairs 711e96bab329eb23e4ce8a0dc3cc6b33a3f03d15bfDuncan Sandsstatic bool f64AssignAAPCS(unsigned &ValNo, MVT &ValVT, MVT &LocVT, 726f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher CCValAssign::LocInfo &LocInfo, 736f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher CCState &State, bool CanFail) { 74c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper static const uint16_t HiRegList[] = { ARM::R0, ARM::R2 }; 75c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper static const uint16_t LoRegList[] = { ARM::R1, ARM::R3 }; 76c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper static const uint16_t ShadowRegList[] = { ARM::R0, ARM::R1 }; 776f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 786f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher unsigned Reg = State.AllocateReg(HiRegList, ShadowRegList, 2); 796f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher if (Reg == 0) { 806f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher // For the 2nd half of a v2f64, do not just fail. 816f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher if (CanFail) 826f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return false; 836f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 846f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher // Put the whole thing on the stack. 856f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT, 866f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher State.AllocateStack(8, 8), 876f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher LocVT, LocInfo)); 886f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return true; 896f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher } 906f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 916f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher unsigned i; 926f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher for (i = 0; i < 2; ++i) 936f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher if (HiRegList[i] == Reg) 946f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher break; 956f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 966f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher unsigned T = State.AllocateReg(LoRegList[i]); 976f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher (void)T; 986f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher assert(T == LoRegList[i] && "Could not allocate register"); 996f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 1006f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 1016f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i], 1026f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher LocVT, LocInfo)); 1036f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return true; 1046f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher} 1056f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 1061e96bab329eb23e4ce8a0dc3cc6b33a3f03d15bfDuncan Sandsstatic bool CC_ARM_AAPCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT, 1076f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher CCValAssign::LocInfo &LocInfo, 1086f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher ISD::ArgFlagsTy &ArgFlags, 1096f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher CCState &State) { 1106f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher if (!f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, true)) 1116f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return false; 1126f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher if (LocVT == MVT::v2f64 && 1136f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher !f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, false)) 1146f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return false; 1156f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return true; // we handled it 1166f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher} 1176f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 1181e96bab329eb23e4ce8a0dc3cc6b33a3f03d15bfDuncan Sandsstatic bool f64RetAssign(unsigned &ValNo, MVT &ValVT, MVT &LocVT, 1196f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher CCValAssign::LocInfo &LocInfo, CCState &State) { 120c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper static const uint16_t HiRegList[] = { ARM::R0, ARM::R2 }; 121c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper static const uint16_t LoRegList[] = { ARM::R1, ARM::R3 }; 1226f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 1236f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher unsigned Reg = State.AllocateReg(HiRegList, LoRegList, 2); 1246f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher if (Reg == 0) 1256f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return false; // we didn't handle it 1266f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 1276f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher unsigned i; 1286f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher for (i = 0; i < 2; ++i) 1296f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher if (HiRegList[i] == Reg) 1306f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher break; 1316f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 1326f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 1336f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i], 1346f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher LocVT, LocInfo)); 1356f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return true; 1366f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher} 1376f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 1381e96bab329eb23e4ce8a0dc3cc6b33a3f03d15bfDuncan Sandsstatic bool RetCC_ARM_APCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT, 1396f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher CCValAssign::LocInfo &LocInfo, 1406f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher ISD::ArgFlagsTy &ArgFlags, 1416f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher CCState &State) { 1426f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher if (!f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State)) 1436f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return false; 1446f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher if (LocVT == MVT::v2f64 && !f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State)) 1456f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return false; 1466f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return true; // we handled it 1476f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher} 1486f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 1491e96bab329eb23e4ce8a0dc3cc6b33a3f03d15bfDuncan Sandsstatic bool RetCC_ARM_AAPCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT, 1506f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher CCValAssign::LocInfo &LocInfo, 1516f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher ISD::ArgFlagsTy &ArgFlags, 1526f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher CCState &State) { 1536f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher return RetCC_ARM_APCS_Custom_f64(ValNo, ValVT, LocVT, LocInfo, ArgFlags, 1546f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher State); 1556f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher} 1566f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 1576f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher} // End llvm namespace 1586f2ccefdc069b6bd2e8f8b110fc3205b821a17a7Eric Christopher 15909b2171d7e78de240c4b510dd9808010a5e2efddEric Christopher#endif 160