|
13 | 13 |
|
14 | 14 | #include "AVRISelLowering.h"
|
15 | 15 |
|
| 16 | +#include "llvm/ADT/ArrayRef.h" |
16 | 17 | #include "llvm/ADT/STLExtras.h"
|
17 | 18 | #include "llvm/ADT/StringSwitch.h"
|
18 | 19 | #include "llvm/CodeGen/CallingConvLower.h"
|
@@ -1023,28 +1024,47 @@ bool AVRTargetLowering::isOffsetFoldingLegal(
|
1023 | 1024 |
|
1024 | 1025 | /// Registers for calling conventions, ordered in reverse as required by ABI.
|
1025 | 1026 | /// Both arrays must be of the same length.
|
1026 |
| -static const MCPhysReg RegList8[] = { |
| 1027 | +static const MCPhysReg RegList8AVR[] = { |
1027 | 1028 | AVR::R25, AVR::R24, AVR::R23, AVR::R22, AVR::R21, AVR::R20,
|
1028 | 1029 | AVR::R19, AVR::R18, AVR::R17, AVR::R16, AVR::R15, AVR::R14,
|
1029 | 1030 | AVR::R13, AVR::R12, AVR::R11, AVR::R10, AVR::R9, AVR::R8};
|
1030 |
| -static const MCPhysReg RegList16[] = { |
| 1031 | +static const MCPhysReg RegList8Tiny[] = {AVR::R25, AVR::R24, AVR::R23, |
| 1032 | + AVR::R22, AVR::R21, AVR::R20}; |
| 1033 | +static const MCPhysReg RegList16AVR[] = { |
1031 | 1034 | AVR::R26R25, AVR::R25R24, AVR::R24R23, AVR::R23R22, AVR::R22R21,
|
1032 | 1035 | AVR::R21R20, AVR::R20R19, AVR::R19R18, AVR::R18R17, AVR::R17R16,
|
1033 | 1036 | AVR::R16R15, AVR::R15R14, AVR::R14R13, AVR::R13R12, AVR::R12R11,
|
1034 | 1037 | AVR::R11R10, AVR::R10R9, AVR::R9R8};
|
| 1038 | +static const MCPhysReg RegList16Tiny[] = {AVR::R26R25, AVR::R25R24, |
| 1039 | + AVR::R24R23, AVR::R23R22, |
| 1040 | + AVR::R22R21, AVR::R21R20}; |
1035 | 1041 |
|
1036 |
| -static_assert(array_lengthof(RegList8) == array_lengthof(RegList16), |
| 1042 | +static_assert(array_lengthof(RegList8AVR) == array_lengthof(RegList16AVR), |
| 1043 | + "8-bit and 16-bit register arrays must be of equal length"); |
| 1044 | +static_assert(array_lengthof(RegList8Tiny) == array_lengthof(RegList16Tiny), |
1037 | 1045 | "8-bit and 16-bit register arrays must be of equal length");
|
1038 | 1046 |
|
1039 | 1047 | /// Analyze incoming and outgoing function arguments. We need custom C++ code
|
1040 | 1048 | /// to handle special constraints in the ABI.
|
1041 | 1049 | /// In addition, all pieces of a certain argument have to be passed either
|
1042 | 1050 | /// using registers or the stack but never mixing both.
|
1043 | 1051 | template <typename ArgT>
|
1044 |
| -static void |
1045 |
| -analyzeArguments(TargetLowering::CallLoweringInfo *CLI, const Function *F, |
1046 |
| - const DataLayout *TD, const SmallVectorImpl<ArgT> &Args, |
1047 |
| - SmallVectorImpl<CCValAssign> &ArgLocs, CCState &CCInfo) { |
| 1052 | +static void analyzeArguments(TargetLowering::CallLoweringInfo *CLI, |
| 1053 | + const Function *F, const DataLayout *TD, |
| 1054 | + const SmallVectorImpl<ArgT> &Args, |
| 1055 | + SmallVectorImpl<CCValAssign> &ArgLocs, |
| 1056 | + CCState &CCInfo, bool Tiny) { |
| 1057 | + // Choose the proper register list for argument passing according to the ABI. |
| 1058 | + ArrayRef<MCPhysReg> RegList8; |
| 1059 | + ArrayRef<MCPhysReg> RegList16; |
| 1060 | + if (Tiny) { |
| 1061 | + RegList8 = makeArrayRef(RegList8Tiny, array_lengthof(RegList8Tiny)); |
| 1062 | + RegList16 = makeArrayRef(RegList16Tiny, array_lengthof(RegList16Tiny)); |
| 1063 | + } else { |
| 1064 | + RegList8 = makeArrayRef(RegList8AVR, array_lengthof(RegList8AVR)); |
| 1065 | + RegList16 = makeArrayRef(RegList16AVR, array_lengthof(RegList16AVR)); |
| 1066 | + } |
| 1067 | + |
1048 | 1068 | unsigned NumArgs = Args.size();
|
1049 | 1069 | // This is the index of the last used register, in RegList*.
|
1050 | 1070 | // -1 means R26 (R26 is never actually used in CC).
|
@@ -1074,7 +1094,7 @@ analyzeArguments(TargetLowering::CallLoweringInfo *CLI, const Function *F,
|
1074 | 1094 | unsigned RegIdx = RegLastIdx + TotalBytes;
|
1075 | 1095 | RegLastIdx = RegIdx;
|
1076 | 1096 | // If there are not enough registers, use the stack
|
1077 |
| - if (RegIdx >= array_lengthof(RegList8)) { |
| 1097 | + if (RegIdx >= RegList8.size()) { |
1078 | 1098 | UseStack = true;
|
1079 | 1099 | }
|
1080 | 1100 | for (; i != j; ++i) {
|
@@ -1123,13 +1143,24 @@ getTotalArgumentsSizeInBytes(const SmallVectorImpl<ArgT> &Args) {
|
1123 | 1143 | /// one value, possibly an aggregate, and it is limited to 8 bytes.
|
1124 | 1144 | template <typename ArgT>
|
1125 | 1145 | static void analyzeReturnValues(const SmallVectorImpl<ArgT> &Args,
|
1126 |
| - CCState &CCInfo) { |
| 1146 | + CCState &CCInfo, bool Tiny) { |
1127 | 1147 | unsigned NumArgs = Args.size();
|
1128 | 1148 | unsigned TotalBytes = getTotalArgumentsSizeInBytes(Args);
|
1129 | 1149 | // CanLowerReturn() guarantees this assertion.
|
1130 | 1150 | assert(TotalBytes <= 8 &&
|
1131 | 1151 | "return values greater than 8 bytes cannot be lowered");
|
1132 | 1152 |
|
| 1153 | + // Choose the proper register list for argument passing according to the ABI. |
| 1154 | + ArrayRef<MCPhysReg> RegList8; |
| 1155 | + ArrayRef<MCPhysReg> RegList16; |
| 1156 | + if (Tiny) { |
| 1157 | + RegList8 = makeArrayRef(RegList8Tiny, array_lengthof(RegList8Tiny)); |
| 1158 | + RegList16 = makeArrayRef(RegList16Tiny, array_lengthof(RegList16Tiny)); |
| 1159 | + } else { |
| 1160 | + RegList8 = makeArrayRef(RegList8AVR, array_lengthof(RegList8AVR)); |
| 1161 | + RegList16 = makeArrayRef(RegList16AVR, array_lengthof(RegList16AVR)); |
| 1162 | + } |
| 1163 | + |
1133 | 1164 | // GCC-ABI says that the size is rounded up to the next even number,
|
1134 | 1165 | // but actually once it is more than 4 it will always round up to 8.
|
1135 | 1166 | if (TotalBytes > 4) {
|
@@ -1174,7 +1205,8 @@ SDValue AVRTargetLowering::LowerFormalArguments(
|
1174 | 1205 | if (isVarArg) {
|
1175 | 1206 | CCInfo.AnalyzeFormalArguments(Ins, ArgCC_AVR_Vararg);
|
1176 | 1207 | } else {
|
1177 |
| - analyzeArguments(nullptr, &MF.getFunction(), &DL, Ins, ArgLocs, CCInfo); |
| 1208 | + analyzeArguments(nullptr, &MF.getFunction(), &DL, Ins, ArgLocs, CCInfo, |
| 1209 | + Subtarget.hasTinyEncoding()); |
1178 | 1210 | }
|
1179 | 1211 |
|
1180 | 1212 | SDValue ArgValue;
|
@@ -1299,7 +1331,8 @@ SDValue AVRTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
1299 | 1331 | if (isVarArg) {
|
1300 | 1332 | CCInfo.AnalyzeCallOperands(Outs, ArgCC_AVR_Vararg);
|
1301 | 1333 | } else {
|
1302 |
| - analyzeArguments(&CLI, F, &DAG.getDataLayout(), Outs, ArgLocs, CCInfo); |
| 1334 | + analyzeArguments(&CLI, F, &DAG.getDataLayout(), Outs, ArgLocs, CCInfo, |
| 1335 | + Subtarget.hasTinyEncoding()); |
1303 | 1336 | }
|
1304 | 1337 |
|
1305 | 1338 | // Get a count of how many bytes are to be pushed on the stack.
|
@@ -1444,7 +1477,7 @@ SDValue AVRTargetLowering::LowerCallResult(
|
1444 | 1477 | if (CallConv == CallingConv::AVR_BUILTIN) {
|
1445 | 1478 | CCInfo.AnalyzeCallResult(Ins, RetCC_AVR_BUILTIN);
|
1446 | 1479 | } else {
|
1447 |
| - analyzeReturnValues(Ins, CCInfo); |
| 1480 | + analyzeReturnValues(Ins, CCInfo, Subtarget.hasTinyEncoding()); |
1448 | 1481 | }
|
1449 | 1482 |
|
1450 | 1483 | // Copy all of the result registers out of their specified physreg.
|
@@ -1495,7 +1528,7 @@ AVRTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
|
1495 | 1528 | if (CallConv == CallingConv::AVR_BUILTIN) {
|
1496 | 1529 | CCInfo.AnalyzeReturn(Outs, RetCC_AVR_BUILTIN);
|
1497 | 1530 | } else {
|
1498 |
| - analyzeReturnValues(Outs, CCInfo); |
| 1531 | + analyzeReturnValues(Outs, CCInfo, Subtarget.hasTinyEncoding()); |
1499 | 1532 | }
|
1500 | 1533 |
|
1501 | 1534 | SDValue Flag;
|
|
0 commit comments