Skip to content

Commit 67422e4

Browse files
committed
[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
1 parent 28cd3cb commit 67422e4

File tree

2 files changed

+266
-1
lines changed

2 files changed

+266
-1
lines changed

clang/lib/CodeGen/TargetInfo.cpp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7475,10 +7475,49 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
74757475

74767476
namespace {
74777477

7478+
class MSP430ABIInfo : public DefaultABIInfo {
7479+
static ABIArgInfo complexArgInfo() {
7480+
ABIArgInfo Info = ABIArgInfo::getDirect();
7481+
Info.setCanBeFlattened(false);
7482+
return Info;
7483+
}
7484+
7485+
public:
7486+
MSP430ABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
7487+
7488+
ABIArgInfo classifyReturnType(QualType RetTy) const {
7489+
if (RetTy->isAnyComplexType())
7490+
return complexArgInfo();
7491+
7492+
return DefaultABIInfo::classifyReturnType(RetTy);
7493+
}
7494+
7495+
ABIArgInfo classifyArgumentType(QualType RetTy) const {
7496+
if (RetTy->isAnyComplexType())
7497+
return complexArgInfo();
7498+
7499+
return DefaultABIInfo::classifyArgumentType(RetTy);
7500+
}
7501+
7502+
// Just copy the original implementations because
7503+
// DefaultABIInfo::classify{Return,Argument}Type() are not virtual
7504+
void computeInfo(CGFunctionInfo &FI) const override {
7505+
if (!getCXXABI().classifyReturnType(FI))
7506+
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
7507+
for (auto &I : FI.arguments())
7508+
I.info = classifyArgumentType(I.type);
7509+
}
7510+
7511+
Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
7512+
QualType Ty) const override {
7513+
return EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty));
7514+
}
7515+
};
7516+
74787517
class MSP430TargetCodeGenInfo : public TargetCodeGenInfo {
74797518
public:
74807519
MSP430TargetCodeGenInfo(CodeGenTypes &CGT)
7481-
: TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {}
7520+
: TargetCodeGenInfo(std::make_unique<MSP430ABIInfo>(CGT)) {}
74827521
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
74837522
CodeGen::CodeGenModule &M) const override;
74847523
};
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
// REQUIRES: msp430-registered-target
2+
// RUN: %clang -target msp430 -Os -S -o- %s | FileCheck %s
3+
4+
volatile int N;
5+
volatile int i16_1, i16_2;
6+
volatile long i32_1, i32_2;
7+
volatile long long i64_1, i64_2;
8+
volatile float f1, f2;
9+
volatile double d1, d2;
10+
11+
_Static_assert(sizeof(int) == 2, "Assumption failed");
12+
_Static_assert(sizeof(long) == 4, "Assumption failed");
13+
_Static_assert(sizeof(long long) == 8, "Assumption failed");
14+
15+
void complex_i16_arg_first(int _Complex x, int n) {
16+
// CHECK-LABEL: @complex_i16_arg_first
17+
i16_1 = __real__ x;
18+
// CHECK-DAG: mov r12, &i16_1
19+
i16_2 = __imag__ x;
20+
// CHECK-DAG: mov r13, &i16_2
21+
N = n;
22+
// CHECK-DAG: mov r14, &N
23+
// CHECK: ret
24+
}
25+
26+
void complex_i16_arg_second(int n, int _Complex x) {
27+
// CHECK-LABEL: @complex_i16_arg_second
28+
N = n;
29+
// CHECK-DAG: mov r12, &N
30+
i16_1 = __real__ x;
31+
// CHECK-DAG: mov r13, &i16_1
32+
i16_2 = __imag__ x;
33+
// CHECK-DAG: mov r14, &i16_2
34+
// CHECK: ret
35+
}
36+
37+
void complex_i32_arg_first(long _Complex x, int n) {
38+
// CHECK-LABEL: @complex_i32_arg_first
39+
i32_1 = __real__ x;
40+
// CHECK-DAG: mov r12, &i32_1
41+
// CHECK-DAG: mov r13, &i32_1+2
42+
i32_2 = __imag__ x;
43+
// CHECK-DAG: mov r14, &i32_2
44+
// CHECK-DAG: mov r15, &i32_2+2
45+
N = n;
46+
// CHECK-DAG: mov 2(r1), &N
47+
// CHECK: ret
48+
}
49+
50+
void complex_i32_arg_second(int n, long _Complex x) {
51+
// CHECK-LABEL: @complex_i32_arg_second
52+
N = n;
53+
// CHECK-DAG: mov r12, &N
54+
i32_1 = __real__ x;
55+
// CHECK-DAG: mov 2(r1), &i32_1
56+
// CHECK-DAG: mov 4(r1), &i32_1+2
57+
i32_2 = __imag__ x;
58+
// CHECK-DAG: mov 6(r1), &i32_2
59+
// CHECK-DAG: mov 8(r1), &i32_2+2
60+
// CHECK: ret
61+
}
62+
63+
void complex_i64_arg_first(long long _Complex x, int n) {
64+
// CHECK-LABEL: @complex_i64_arg_first
65+
i64_1 = __real__ x;
66+
// CHECK-DAG: mov 2(r1), &i64_1
67+
// CHECK-DAG: mov 4(r1), &i64_1+2
68+
// CHECK-DAG: mov 6(r1), &i64_1+4
69+
// CHECK-DAG: mov 8(r1), &i64_1+6
70+
i64_2 = __imag__ x;
71+
// CHECK-DAG: mov 10(r1), &i64_2
72+
// CHECK-DAG: mov 12(r1), &i64_2+2
73+
// CHECK-DAG: mov 14(r1), &i64_2+4
74+
// CHECK-DAG: mov 16(r1), &i64_2+6
75+
N = n;
76+
// CHECK-DAG: mov r12, &N
77+
// CHECK: ret
78+
}
79+
80+
void complex_i64_arg_second(int n, long long _Complex x) {
81+
// CHECK-LABEL: @complex_i64_arg_second
82+
N = n;
83+
// CHECK-DAG: mov r12, &N
84+
i64_1 = __real__ x;
85+
// CHECK-DAG: mov 2(r1), &i64_1
86+
// CHECK-DAG: mov 4(r1), &i64_1+2
87+
// CHECK-DAG: mov 6(r1), &i64_1+4
88+
// CHECK-DAG: mov 8(r1), &i64_1+6
89+
i64_2 = __imag__ x;
90+
// CHECK-DAG: mov 10(r1), &i64_2
91+
// CHECK-DAG: mov 12(r1), &i64_2+2
92+
// CHECK-DAG: mov 14(r1), &i64_2+4
93+
// CHECK-DAG: mov 16(r1), &i64_2+6
94+
// CHECK: ret
95+
}
96+
97+
void complex_float_arg_first(float _Complex x, int n) {
98+
// CHECK-LABEL: @complex_float_arg_first
99+
f1 = __real__ x;
100+
// CHECK-DAG: mov r12, &f1
101+
// CHECK-DAG: mov r13, &f1+2
102+
f2 = __imag__ x;
103+
// CHECK-DAG: mov r14, &f2
104+
// CHECK-DAG: mov r15, &f2+2
105+
N = n;
106+
// CHECK-DAG: mov 2(r1), &N
107+
// CHECK: ret
108+
}
109+
110+
void complex_float_arg_second(int n, float _Complex x) {
111+
// CHECK-LABEL: @complex_float_arg_second
112+
N = n;
113+
// CHECK-DAG: mov r12, &N
114+
f1 = __real__ x;
115+
// CHECK-DAG: mov 2(r1), &f1
116+
// CHECK-DAG: mov 4(r1), &f1+2
117+
f2 = __imag__ x;
118+
// CHECK-DAG: mov 6(r1), &f2
119+
// CHECK-DAG: mov 8(r1), &f2+2
120+
// CHECK: ret
121+
}
122+
123+
void complex_double_arg_first(double _Complex x, int n) {
124+
// CHECK-LABEL: @complex_double_arg_first
125+
d1 = __real__ x;
126+
// CHECK-DAG: mov 2(r1), &d1
127+
// CHECK-DAG: mov 4(r1), &d1+2
128+
// CHECK-DAG: mov 6(r1), &d1+4
129+
// CHECK-DAG: mov 8(r1), &d1+6
130+
d2 = __imag__ x;
131+
// CHECK-DAG: mov 10(r1), &d2
132+
// CHECK-DAG: mov 12(r1), &d2+2
133+
// CHECK-DAG: mov 14(r1), &d2+4
134+
// CHECK-DAG: mov 16(r1), &d2+6
135+
N = n;
136+
// CHECK-DAG: mov r12, &N
137+
// CHECK: ret
138+
}
139+
140+
void complex_double_arg_second(int n, double _Complex x) {
141+
// CHECK-LABEL: @complex_double_arg_second
142+
d1 = __real__ x;
143+
// CHECK-DAG: mov 2(r1), &d1
144+
// CHECK-DAG: mov 4(r1), &d1+2
145+
// CHECK-DAG: mov 6(r1), &d1+4
146+
// CHECK-DAG: mov 8(r1), &d1+6
147+
d2 = __imag__ x;
148+
// CHECK-DAG: mov 10(r1), &d2
149+
// CHECK-DAG: mov 12(r1), &d2+2
150+
// CHECK-DAG: mov 14(r1), &d2+4
151+
// CHECK-DAG: mov 16(r1), &d2+6
152+
N = n;
153+
// CHECK-DAG: mov r12, &N
154+
// CHECK: ret
155+
}
156+
157+
int _Complex complex_i16_res(void) {
158+
// CHECK-LABEL: @complex_i16_res
159+
int _Complex res;
160+
__real__ res = 0x1122;
161+
// CHECK-DAG: mov #4386, r12
162+
__imag__ res = 0x3344;
163+
// CHECK-DAG: mov #13124, r13
164+
return res;
165+
// CHECK: ret
166+
}
167+
168+
long _Complex complex_i32_res(void) {
169+
// CHECK-LABEL: @complex_i32_res
170+
long _Complex res;
171+
__real__ res = 0x11223344;
172+
// CHECK-DAG: mov #13124, r12
173+
// CHECK-DAG: mov #4386, r13
174+
__imag__ res = 0x55667788;
175+
// CHECK-DAG: mov #30600, r14
176+
// CHECK-DAG: mov #21862, r15
177+
return res;
178+
// CHECK: ret
179+
}
180+
181+
long long _Complex complex_i64_res(void) {
182+
// CHECK-LABEL: @complex_i64_res
183+
long long _Complex res;
184+
__real__ res = 0x1122334455667788;
185+
// CHECK-DAG: mov #30600, 0(r12)
186+
// CHECK-DAG: mov #21862, 2(r12)
187+
// CHECK-DAG: mov #13124, 4(r12)
188+
// CHECK-DAG: mov #4386, 6(r12)
189+
__imag__ res = 0x99aabbccddeeff00;
190+
// CHECK-DAG: mov #-256, 8(r12)
191+
// CHECK-DAG: mov #-8722, 10(r12)
192+
// CHECK-DAG: mov #-17460, 12(r12)
193+
// CHECK-DAG: mov #-26198, 14(r12)
194+
return res;
195+
// CHECK: ret
196+
}
197+
198+
float _Complex complex_float_res(void) {
199+
// CHECK-LABEL: @complex_float_res
200+
float _Complex res;
201+
__real__ res = 1;
202+
// CHECK-DAG: clr r12
203+
// CHECK-DAG: mov #16256, r13
204+
__imag__ res = -1;
205+
// CHECK-DAG: clr r14
206+
// CHECK-DAG: mov #-16512, r15
207+
return res;
208+
// CHECK: ret
209+
}
210+
211+
double _Complex complex_double_res(void) {
212+
// CHECK-LABEL: @complex_double_res
213+
double _Complex res;
214+
__real__ res = 1;
215+
// CHECK-DAG: clr 0(r12)
216+
// CHECK-DAG: clr 2(r12)
217+
// CHECK-DAG: clr 4(r12)
218+
// CHECK-DAG: mov #16368, 6(r12)
219+
__imag__ res = -1;
220+
// CHECK-DAG: clr 8(r12)
221+
// CHECK-DAG: clr 10(r12)
222+
// CHECK-DAG: clr 12(r12)
223+
// CHECK-DAG: mov #-16400, 14(r12)
224+
return res;
225+
// CHECK: ret
226+
}

0 commit comments

Comments
 (0)