PPCCallingConv.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. //===-- PPCCallingConv.h - --------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "PPCRegisterInfo.h"
  9. #include "PPCCallingConv.h"
  10. #include "PPCSubtarget.h"
  11. #include "PPCCCState.h"
  12. using namespace llvm;
  13. inline bool CC_PPC_AnyReg_Error(unsigned &, MVT &, MVT &,
  14. CCValAssign::LocInfo &, ISD::ArgFlagsTy &,
  15. CCState &) {
  16. llvm_unreachable("The AnyReg calling convention is only supported by the " \
  17. "stackmap and patchpoint intrinsics.");
  18. // gracefully fallback to PPC C calling convention on Release builds.
  19. return false;
  20. }
  21. static bool CC_PPC32_SVR4_Custom_Dummy(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
  22. CCValAssign::LocInfo &LocInfo,
  23. ISD::ArgFlagsTy &ArgFlags,
  24. CCState &State) {
  25. return true;
  26. }
  27. static bool CC_PPC32_SVR4_Custom_AlignArgRegs(unsigned &ValNo, MVT &ValVT,
  28. MVT &LocVT,
  29. CCValAssign::LocInfo &LocInfo,
  30. ISD::ArgFlagsTy &ArgFlags,
  31. CCState &State) {
  32. static const MCPhysReg ArgRegs[] = {
  33. PPC::R3, PPC::R4, PPC::R5, PPC::R6,
  34. PPC::R7, PPC::R8, PPC::R9, PPC::R10,
  35. };
  36. const unsigned NumArgRegs = array_lengthof(ArgRegs);
  37. unsigned RegNum = State.getFirstUnallocated(ArgRegs);
  38. // Skip one register if the first unallocated register has an even register
  39. // number and there are still argument registers available which have not been
  40. // allocated yet. RegNum is actually an index into ArgRegs, which means we
  41. // need to skip a register if RegNum is odd.
  42. if (RegNum != NumArgRegs && RegNum % 2 == 1) {
  43. State.AllocateReg(ArgRegs[RegNum]);
  44. }
  45. // Always return false here, as this function only makes sure that the first
  46. // unallocated register has an odd register number and does not actually
  47. // allocate a register for the current argument.
  48. return false;
  49. }
  50. static bool CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128(
  51. unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo,
  52. ISD::ArgFlagsTy &ArgFlags, CCState &State) {
  53. static const MCPhysReg ArgRegs[] = {
  54. PPC::R3, PPC::R4, PPC::R5, PPC::R6,
  55. PPC::R7, PPC::R8, PPC::R9, PPC::R10,
  56. };
  57. const unsigned NumArgRegs = array_lengthof(ArgRegs);
  58. unsigned RegNum = State.getFirstUnallocated(ArgRegs);
  59. int RegsLeft = NumArgRegs - RegNum;
  60. // Skip if there is not enough registers left for long double type (4 gpr regs
  61. // in soft float mode) and put long double argument on the stack.
  62. if (RegNum != NumArgRegs && RegsLeft < 4) {
  63. for (int i = 0; i < RegsLeft; i++) {
  64. State.AllocateReg(ArgRegs[RegNum + i]);
  65. }
  66. }
  67. return false;
  68. }
  69. static bool CC_PPC32_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT,
  70. MVT &LocVT,
  71. CCValAssign::LocInfo &LocInfo,
  72. ISD::ArgFlagsTy &ArgFlags,
  73. CCState &State) {
  74. static const MCPhysReg ArgRegs[] = {
  75. PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
  76. PPC::F8
  77. };
  78. const unsigned NumArgRegs = array_lengthof(ArgRegs);
  79. unsigned RegNum = State.getFirstUnallocated(ArgRegs);
  80. // If there is only one Floating-point register left we need to put both f64
  81. // values of a split ppc_fp128 value on the stack.
  82. if (RegNum != NumArgRegs && ArgRegs[RegNum] == PPC::F8) {
  83. State.AllocateReg(ArgRegs[RegNum]);
  84. }
  85. // Always return false here, as this function only makes sure that the two f64
  86. // values a ppc_fp128 value is split into are both passed in registers or both
  87. // passed on the stack and does not actually allocate a register for the
  88. // current argument.
  89. return false;
  90. }
  91. // Split F64 arguments into two 32-bit consecutive registers.
  92. static bool CC_PPC32_SPE_CustomSplitFP64(unsigned &ValNo, MVT &ValVT,
  93. MVT &LocVT,
  94. CCValAssign::LocInfo &LocInfo,
  95. ISD::ArgFlagsTy &ArgFlags,
  96. CCState &State) {
  97. static const MCPhysReg HiRegList[] = { PPC::R3, PPC::R5, PPC::R7, PPC::R9 };
  98. static const MCPhysReg LoRegList[] = { PPC::R4, PPC::R6, PPC::R8, PPC::R10 };
  99. // Try to get the first register.
  100. unsigned Reg = State.AllocateReg(HiRegList);
  101. if (!Reg)
  102. return false;
  103. unsigned i;
  104. for (i = 0; i < sizeof(HiRegList) / sizeof(HiRegList[0]); ++i)
  105. if (HiRegList[i] == Reg)
  106. break;
  107. unsigned T = State.AllocateReg(LoRegList[i]);
  108. (void)T;
  109. assert(T == LoRegList[i] && "Could not allocate register");
  110. State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
  111. State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
  112. LocVT, LocInfo));
  113. return true;
  114. }
  115. // Same as above, but for return values, so only allocate for R3 and R4
  116. static bool CC_PPC32_SPE_RetF64(unsigned &ValNo, MVT &ValVT,
  117. MVT &LocVT,
  118. CCValAssign::LocInfo &LocInfo,
  119. ISD::ArgFlagsTy &ArgFlags,
  120. CCState &State) {
  121. static const MCPhysReg HiRegList[] = { PPC::R3 };
  122. static const MCPhysReg LoRegList[] = { PPC::R4 };
  123. // Try to get the first register.
  124. unsigned Reg = State.AllocateReg(HiRegList, LoRegList);
  125. if (!Reg)
  126. return false;
  127. unsigned i;
  128. for (i = 0; i < sizeof(HiRegList) / sizeof(HiRegList[0]); ++i)
  129. if (HiRegList[i] == Reg)
  130. break;
  131. State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
  132. State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
  133. LocVT, LocInfo));
  134. return true;
  135. }
  136. #include "PPCGenCallingConv.inc"