|
19 | 19 | #include "CodeGenFunction.h" |
20 | 20 | #include "clang/AST/Attr.h" |
21 | 21 | #include "clang/AST/RecordLayout.h" |
| 22 | +#include "clang/Basic/Builtins.h" |
22 | 23 | #include "clang/Basic/CodeGenOptions.h" |
23 | 24 | #include "clang/Basic/DiagnosticFrontend.h" |
24 | | -#include "clang/Basic/Builtins.h" |
25 | 25 | #include "clang/CodeGen/CGFunctionInfo.h" |
26 | 26 | #include "clang/CodeGen/SwiftCallingConv.h" |
27 | 27 | #include "llvm/ADT/SmallBitVector.h" |
|
33 | 33 | #include "llvm/IR/IntrinsicsNVPTX.h" |
34 | 34 | #include "llvm/IR/IntrinsicsS390.h" |
35 | 35 | #include "llvm/IR/Type.h" |
| 36 | +#include "llvm/Support/MathExtras.h" |
36 | 37 | #include "llvm/Support/raw_ostream.h" |
37 | 38 | #include <algorithm> // std::sort |
38 | 39 |
|
@@ -8278,32 +8279,93 @@ void M68kTargetCodeGenInfo::setTargetAttributes( |
8278 | 8279 |
|
8279 | 8280 | namespace { |
8280 | 8281 | class AVRABIInfo : public DefaultABIInfo { |
| 8282 | +private: |
| 8283 | + // The total amount of registers can be used to pass parameters. It is 18 on |
| 8284 | + // AVR, or 6 on AVRTiny. |
| 8285 | + const unsigned ParamRegs; |
| 8286 | + // The total amount of registers can be used to pass return value. It is 8 on |
| 8287 | + // AVR, or 4 on AVRTiny. |
| 8288 | + const unsigned RetRegs; |
| 8289 | + |
8281 | 8290 | public: |
8282 | | - AVRABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} |
| 8291 | + AVRABIInfo(CodeGenTypes &CGT, unsigned NPR, unsigned NRR) |
| 8292 | + : DefaultABIInfo(CGT), ParamRegs(NPR), RetRegs(NRR) {} |
| 8293 | + |
| 8294 | + ABIArgInfo classifyReturnType(QualType Ty, bool &LargeRet) const { |
| 8295 | + if (isAggregateTypeForABI(Ty)) { |
| 8296 | + // On AVR, a return struct with size less than or equals to 8 bytes is |
| 8297 | + // returned directly via registers R18-R25. On AVRTiny, a return struct |
| 8298 | + // with size less than or equals to 4 bytes is returned directly via |
| 8299 | + // registers R22-R25. |
| 8300 | + if (getContext().getTypeSize(Ty) <= RetRegs * 8) |
| 8301 | + return ABIArgInfo::getDirect(); |
| 8302 | + // A return struct with larger size is returned via a stack |
| 8303 | + // slot, along with a pointer to it as the function's implicit argument. |
| 8304 | + LargeRet = true; |
| 8305 | + return getNaturalAlignIndirect(Ty); |
| 8306 | + } |
| 8307 | + // Otherwise we follow the default way which is compatible. |
| 8308 | + return DefaultABIInfo::classifyReturnType(Ty); |
| 8309 | + } |
8283 | 8310 |
|
8284 | | - ABIArgInfo classifyReturnType(QualType Ty) const { |
8285 | | - // A return struct with size less than or equal to 8 bytes is returned |
8286 | | - // directly via registers R18-R25. |
8287 | | - if (isAggregateTypeForABI(Ty) && getContext().getTypeSize(Ty) <= 64) |
| 8311 | + ABIArgInfo classifyArgumentType(QualType Ty, unsigned &NumRegs) const { |
| 8312 | + unsigned TySize = getContext().getTypeSize(Ty); |
| 8313 | + |
| 8314 | + // An int8 type argument always costs two registers like an int16. |
| 8315 | + if (TySize == 8 && NumRegs >= 2) { |
| 8316 | + NumRegs -= 2; |
| 8317 | + return ABIArgInfo::getExtend(Ty); |
| 8318 | + } |
| 8319 | + |
| 8320 | + // If the argument size is an odd number of bytes, round up the size |
| 8321 | + // to the next even number. |
| 8322 | + TySize = llvm::alignTo(TySize, 16); |
| 8323 | + |
| 8324 | + // Any type including an array/struct type can be passed in rgisters, |
| 8325 | + // if there are enough registers left. |
| 8326 | + if (TySize <= NumRegs * 8) { |
| 8327 | + NumRegs -= TySize / 8; |
8288 | 8328 | return ABIArgInfo::getDirect(); |
8289 | | - else |
8290 | | - return DefaultABIInfo::classifyReturnType(Ty); |
| 8329 | + } |
| 8330 | + |
| 8331 | + // An argument is passed either completely in registers or completely in |
| 8332 | + // memory. Since there are not enough registers left, current argument |
| 8333 | + // and all other unprocessed arguments should be passed in memory. |
| 8334 | + // However we still need to return `ABIArgInfo::getDirect()` other than |
| 8335 | + // `ABIInfo::getNaturalAlignIndirect(Ty)`, otherwise an extra stack slot |
| 8336 | + // will be allocated, so the stack frame layout will be incompatible with |
| 8337 | + // avr-gcc. |
| 8338 | + NumRegs = 0; |
| 8339 | + return ABIArgInfo::getDirect(); |
8291 | 8340 | } |
8292 | 8341 |
|
8293 | | - // Just copy the original implementation of DefaultABIInfo::computeInfo(), |
8294 | | - // since DefaultABIInfo::classify{Return,Argument}Type() are not virtual. |
8295 | 8342 | void computeInfo(CGFunctionInfo &FI) const override { |
| 8343 | + // Decide the return type. |
| 8344 | + bool LargeRet = false; |
8296 | 8345 | if (!getCXXABI().classifyReturnType(FI)) |
8297 | | - FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); |
| 8346 | + FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), LargeRet); |
| 8347 | + |
| 8348 | + // Decide each argument type. The total number of registers can be used for |
| 8349 | + // arguments depends on several factors: |
| 8350 | + // 1. Arguments of varargs functions are passed on the stack. This applies |
| 8351 | + // even to the named arguments. So no register can be used. |
| 8352 | + // 2. Total 18 registers can be used on avr and 6 ones on avrtiny. |
| 8353 | + // 3. If the return type is a struct with too large size, two registers |
| 8354 | + // (out of 18/6) will be cost as an implicit pointer argument. |
| 8355 | + unsigned NumRegs = ParamRegs; |
| 8356 | + if (FI.isVariadic()) |
| 8357 | + NumRegs = 0; |
| 8358 | + else if (LargeRet) |
| 8359 | + NumRegs -= 2; |
8298 | 8360 | for (auto &I : FI.arguments()) |
8299 | | - I.info = classifyArgumentType(I.type); |
| 8361 | + I.info = classifyArgumentType(I.type, NumRegs); |
8300 | 8362 | } |
8301 | 8363 | }; |
8302 | 8364 |
|
8303 | 8365 | class AVRTargetCodeGenInfo : public TargetCodeGenInfo { |
8304 | 8366 | public: |
8305 | | - AVRTargetCodeGenInfo(CodeGenTypes &CGT) |
8306 | | - : TargetCodeGenInfo(std::make_unique<AVRABIInfo>(CGT)) {} |
| 8367 | + AVRTargetCodeGenInfo(CodeGenTypes &CGT, unsigned NPR, unsigned NRR) |
| 8368 | + : TargetCodeGenInfo(std::make_unique<AVRABIInfo>(CGT, NPR, NRR)) {} |
8307 | 8369 |
|
8308 | 8370 | LangAS getGlobalVarAddressSpace(CodeGenModule &CGM, |
8309 | 8371 | const VarDecl *D) const override { |
@@ -11280,8 +11342,14 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { |
11280 | 11342 | case llvm::Triple::mips64el: |
11281 | 11343 | return SetCGInfo(new MIPSTargetCodeGenInfo(Types, false)); |
11282 | 11344 |
|
11283 | | - case llvm::Triple::avr: |
11284 | | - return SetCGInfo(new AVRTargetCodeGenInfo(Types)); |
| 11345 | + case llvm::Triple::avr: { |
| 11346 | + // For passing parameters, R8~R25 are used on avr, and R18~R25 are used |
| 11347 | + // on avrtiny. For passing return value, R18~R25 are used on avr, and |
| 11348 | + // R22~R25 are used on avrtiny. |
| 11349 | + unsigned NPR = getTarget().getABI() == "avrtiny" ? 6 : 18; |
| 11350 | + unsigned NRR = getTarget().getABI() == "avrtiny" ? 4 : 8; |
| 11351 | + return SetCGInfo(new AVRTargetCodeGenInfo(Types, NPR, NRR)); |
| 11352 | + } |
11285 | 11353 |
|
11286 | 11354 | case llvm::Triple::aarch64: |
11287 | 11355 | case llvm::Triple::aarch64_32: |
|
0 commit comments