[clang] 67422e4 - [MSP430] Align the _Complex ABI with current msp430-gcc
Anatoly Trosinenko via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 9 08:32:07 PDT 2020
Author: Anatoly Trosinenko
Date: 2020-07-09T18:28:48+03:00
New Revision: 67422e4294754e08f277b1ba22820487eb76b918
URL: https://github.com/llvm/llvm-project/commit/67422e4294754e08f277b1ba22820487eb76b918
DIFF: https://github.com/llvm/llvm-project/commit/67422e4294754e08f277b1ba22820487eb76b918.diff
LOG: [MSP430] Align the _Complex ABI with current msp430-gcc
Assembler output is checked against msp430-gcc 9.2.0.50 from TI.
Reviewed By: asl
Differential Revision: https://reviews.llvm.org/D82646
Added:
clang/test/CodeGen/msp430-abi-complex.c
Modified:
clang/lib/CodeGen/TargetInfo.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 801adc29acd1..b83267dec6f0 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -7475,10 +7475,49 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
namespace {
+class MSP430ABIInfo : public DefaultABIInfo {
+ static ABIArgInfo complexArgInfo() {
+ ABIArgInfo Info = ABIArgInfo::getDirect();
+ Info.setCanBeFlattened(false);
+ return Info;
+ }
+
+public:
+ MSP430ABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
+
+ ABIArgInfo classifyReturnType(QualType RetTy) const {
+ if (RetTy->isAnyComplexType())
+ return complexArgInfo();
+
+ return DefaultABIInfo::classifyReturnType(RetTy);
+ }
+
+ ABIArgInfo classifyArgumentType(QualType RetTy) const {
+ if (RetTy->isAnyComplexType())
+ return complexArgInfo();
+
+ return DefaultABIInfo::classifyArgumentType(RetTy);
+ }
+
+ // Just copy the original implementations because
+ // DefaultABIInfo::classify{Return,Argument}Type() are not virtual
+ void computeInfo(CGFunctionInfo &FI) const override {
+ if (!getCXXABI().classifyReturnType(FI))
+ FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+ for (auto &I : FI.arguments())
+ I.info = classifyArgumentType(I.type);
+ }
+
+ Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+ QualType Ty) const override {
+ return EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty));
+ }
+};
+
class MSP430TargetCodeGenInfo : public TargetCodeGenInfo {
public:
MSP430TargetCodeGenInfo(CodeGenTypes &CGT)
- : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {}
+ : TargetCodeGenInfo(std::make_unique<MSP430ABIInfo>(CGT)) {}
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
CodeGen::CodeGenModule &M) const override;
};
diff --git a/clang/test/CodeGen/msp430-abi-complex.c b/clang/test/CodeGen/msp430-abi-complex.c
new file mode 100644
index 000000000000..faafcd2cde3f
--- /dev/null
+++ b/clang/test/CodeGen/msp430-abi-complex.c
@@ -0,0 +1,226 @@
+// REQUIRES: msp430-registered-target
+// RUN: %clang -target msp430 -Os -S -o- %s | FileCheck %s
+
+volatile int N;
+volatile int i16_1, i16_2;
+volatile long i32_1, i32_2;
+volatile long long i64_1, i64_2;
+volatile float f1, f2;
+volatile double d1, d2;
+
+_Static_assert(sizeof(int) == 2, "Assumption failed");
+_Static_assert(sizeof(long) == 4, "Assumption failed");
+_Static_assert(sizeof(long long) == 8, "Assumption failed");
+
+void complex_i16_arg_first(int _Complex x, int n) {
+// CHECK-LABEL: @complex_i16_arg_first
+ i16_1 = __real__ x;
+// CHECK-DAG: mov r12, &i16_1
+ i16_2 = __imag__ x;
+// CHECK-DAG: mov r13, &i16_2
+ N = n;
+// CHECK-DAG: mov r14, &N
+// CHECK: ret
+}
+
+void complex_i16_arg_second(int n, int _Complex x) {
+// CHECK-LABEL: @complex_i16_arg_second
+ N = n;
+// CHECK-DAG: mov r12, &N
+ i16_1 = __real__ x;
+// CHECK-DAG: mov r13, &i16_1
+ i16_2 = __imag__ x;
+// CHECK-DAG: mov r14, &i16_2
+// CHECK: ret
+}
+
+void complex_i32_arg_first(long _Complex x, int n) {
+// CHECK-LABEL: @complex_i32_arg_first
+ i32_1 = __real__ x;
+// CHECK-DAG: mov r12, &i32_1
+// CHECK-DAG: mov r13, &i32_1+2
+ i32_2 = __imag__ x;
+// CHECK-DAG: mov r14, &i32_2
+// CHECK-DAG: mov r15, &i32_2+2
+ N = n;
+// CHECK-DAG: mov 2(r1), &N
+// CHECK: ret
+}
+
+void complex_i32_arg_second(int n, long _Complex x) {
+// CHECK-LABEL: @complex_i32_arg_second
+ N = n;
+// CHECK-DAG: mov r12, &N
+ i32_1 = __real__ x;
+// CHECK-DAG: mov 2(r1), &i32_1
+// CHECK-DAG: mov 4(r1), &i32_1+2
+ i32_2 = __imag__ x;
+// CHECK-DAG: mov 6(r1), &i32_2
+// CHECK-DAG: mov 8(r1), &i32_2+2
+// CHECK: ret
+}
+
+void complex_i64_arg_first(long long _Complex x, int n) {
+// CHECK-LABEL: @complex_i64_arg_first
+ i64_1 = __real__ x;
+// CHECK-DAG: mov 2(r1), &i64_1
+// CHECK-DAG: mov 4(r1), &i64_1+2
+// CHECK-DAG: mov 6(r1), &i64_1+4
+// CHECK-DAG: mov 8(r1), &i64_1+6
+ i64_2 = __imag__ x;
+// CHECK-DAG: mov 10(r1), &i64_2
+// CHECK-DAG: mov 12(r1), &i64_2+2
+// CHECK-DAG: mov 14(r1), &i64_2+4
+// CHECK-DAG: mov 16(r1), &i64_2+6
+ N = n;
+// CHECK-DAG: mov r12, &N
+// CHECK: ret
+}
+
+void complex_i64_arg_second(int n, long long _Complex x) {
+// CHECK-LABEL: @complex_i64_arg_second
+ N = n;
+// CHECK-DAG: mov r12, &N
+ i64_1 = __real__ x;
+// CHECK-DAG: mov 2(r1), &i64_1
+// CHECK-DAG: mov 4(r1), &i64_1+2
+// CHECK-DAG: mov 6(r1), &i64_1+4
+// CHECK-DAG: mov 8(r1), &i64_1+6
+ i64_2 = __imag__ x;
+// CHECK-DAG: mov 10(r1), &i64_2
+// CHECK-DAG: mov 12(r1), &i64_2+2
+// CHECK-DAG: mov 14(r1), &i64_2+4
+// CHECK-DAG: mov 16(r1), &i64_2+6
+// CHECK: ret
+}
+
+void complex_float_arg_first(float _Complex x, int n) {
+// CHECK-LABEL: @complex_float_arg_first
+ f1 = __real__ x;
+// CHECK-DAG: mov r12, &f1
+// CHECK-DAG: mov r13, &f1+2
+ f2 = __imag__ x;
+// CHECK-DAG: mov r14, &f2
+// CHECK-DAG: mov r15, &f2+2
+ N = n;
+// CHECK-DAG: mov 2(r1), &N
+// CHECK: ret
+}
+
+void complex_float_arg_second(int n, float _Complex x) {
+// CHECK-LABEL: @complex_float_arg_second
+ N = n;
+// CHECK-DAG: mov r12, &N
+ f1 = __real__ x;
+// CHECK-DAG: mov 2(r1), &f1
+// CHECK-DAG: mov 4(r1), &f1+2
+ f2 = __imag__ x;
+// CHECK-DAG: mov 6(r1), &f2
+// CHECK-DAG: mov 8(r1), &f2+2
+// CHECK: ret
+}
+
+void complex_double_arg_first(double _Complex x, int n) {
+// CHECK-LABEL: @complex_double_arg_first
+ d1 = __real__ x;
+// CHECK-DAG: mov 2(r1), &d1
+// CHECK-DAG: mov 4(r1), &d1+2
+// CHECK-DAG: mov 6(r1), &d1+4
+// CHECK-DAG: mov 8(r1), &d1+6
+ d2 = __imag__ x;
+// CHECK-DAG: mov 10(r1), &d2
+// CHECK-DAG: mov 12(r1), &d2+2
+// CHECK-DAG: mov 14(r1), &d2+4
+// CHECK-DAG: mov 16(r1), &d2+6
+ N = n;
+// CHECK-DAG: mov r12, &N
+// CHECK: ret
+}
+
+void complex_double_arg_second(int n, double _Complex x) {
+// CHECK-LABEL: @complex_double_arg_second
+ d1 = __real__ x;
+// CHECK-DAG: mov 2(r1), &d1
+// CHECK-DAG: mov 4(r1), &d1+2
+// CHECK-DAG: mov 6(r1), &d1+4
+// CHECK-DAG: mov 8(r1), &d1+6
+ d2 = __imag__ x;
+// CHECK-DAG: mov 10(r1), &d2
+// CHECK-DAG: mov 12(r1), &d2+2
+// CHECK-DAG: mov 14(r1), &d2+4
+// CHECK-DAG: mov 16(r1), &d2+6
+ N = n;
+// CHECK-DAG: mov r12, &N
+// CHECK: ret
+}
+
+int _Complex complex_i16_res(void) {
+// CHECK-LABEL: @complex_i16_res
+ int _Complex res;
+ __real__ res = 0x1122;
+// CHECK-DAG: mov #4386, r12
+ __imag__ res = 0x3344;
+// CHECK-DAG: mov #13124, r13
+ return res;
+// CHECK: ret
+}
+
+long _Complex complex_i32_res(void) {
+// CHECK-LABEL: @complex_i32_res
+ long _Complex res;
+ __real__ res = 0x11223344;
+// CHECK-DAG: mov #13124, r12
+// CHECK-DAG: mov #4386, r13
+ __imag__ res = 0x55667788;
+// CHECK-DAG: mov #30600, r14
+// CHECK-DAG: mov #21862, r15
+ return res;
+// CHECK: ret
+}
+
+long long _Complex complex_i64_res(void) {
+// CHECK-LABEL: @complex_i64_res
+ long long _Complex res;
+ __real__ res = 0x1122334455667788;
+// CHECK-DAG: mov #30600, 0(r12)
+// CHECK-DAG: mov #21862, 2(r12)
+// CHECK-DAG: mov #13124, 4(r12)
+// CHECK-DAG: mov #4386, 6(r12)
+ __imag__ res = 0x99aabbccddeeff00;
+// CHECK-DAG: mov #-256, 8(r12)
+// CHECK-DAG: mov #-8722, 10(r12)
+// CHECK-DAG: mov #-17460, 12(r12)
+// CHECK-DAG: mov #-26198, 14(r12)
+ return res;
+// CHECK: ret
+}
+
+float _Complex complex_float_res(void) {
+// CHECK-LABEL: @complex_float_res
+ float _Complex res;
+ __real__ res = 1;
+// CHECK-DAG: clr r12
+// CHECK-DAG: mov #16256, r13
+ __imag__ res = -1;
+// CHECK-DAG: clr r14
+// CHECK-DAG: mov #-16512, r15
+ return res;
+// CHECK: ret
+}
+
+double _Complex complex_double_res(void) {
+// CHECK-LABEL: @complex_double_res
+ double _Complex res;
+ __real__ res = 1;
+// CHECK-DAG: clr 0(r12)
+// CHECK-DAG: clr 2(r12)
+// CHECK-DAG: clr 4(r12)
+// CHECK-DAG: mov #16368, 6(r12)
+ __imag__ res = -1;
+// CHECK-DAG: clr 8(r12)
+// CHECK-DAG: clr 10(r12)
+// CHECK-DAG: clr 12(r12)
+// CHECK-DAG: mov #-16400, 14(r12)
+ return res;
+// CHECK: ret
+}
More information about the cfe-commits
mailing list