36
36
static bool canRewriteAsInt (Type* t)
37
37
{
38
38
unsigned size = t->size ();
39
- return size <= 8 &&
40
- (size == 1 || size == 2 || size == 4 || size == 8 ) &&
41
- (t->ty == Tstruct || t->ty == Tsarray);
39
+ return size == 1 || size == 2 || size == 4 || size == 8 ;
40
+ }
41
+
42
+ // Returns true if the D type is a composite (struct or static array).
43
+ static bool isComposite (const Type* t)
44
+ {
45
+ return t->ty == Tstruct || t->ty == Tsarray;
46
+ }
42
47
48
+ // Returns true if the D type is passed byval (the callee getting a pointer
49
+ // to a dedicated hidden copy).
50
+ static bool isPassedWithByvalSemantics (Type* t)
51
+ {
52
+ return
53
+ // * structs and static arrays which can NOT be rewritten as integers
54
+ (isComposite (t) && !canRewriteAsInt (t)) ||
55
+ // * 80-bit real and ireal
56
+ (t->ty == Tfloat80 || t->ty == Timaginary80) ||
57
+ // * cdouble and creal
58
+ (t->ty == Tcomplex64 || t->ty == Tcomplex80);
43
59
}
44
60
45
61
// FIXME: This should actually be handled by LLVM and the ByVal arg attribute.
@@ -71,8 +87,21 @@ struct Win64_byval_rewrite : ABIRewrite
71
87
*/
72
88
73
89
LLValue* original = v->getRVal ();
74
- LLValue* copy = DtoRawAlloca (original->getType (), 16 , " copy_for_callee" );
75
- DtoStore (original, copy); // *copy = *original
90
+ LLValue* copy;
91
+
92
+ llvm::Type* type = original->getType ();
93
+ if (type->isPointerTy ())
94
+ {
95
+ type = type->getPointerElementType ();
96
+ copy = DtoRawAlloca (type, 16 , " copy_for_callee" );
97
+ DtoStore (DtoLoad (original), copy); // *copy = *original
98
+ }
99
+ else
100
+ {
101
+ copy = DtoRawAlloca (type, 16 , " copy_for_callee" );
102
+ DtoStore (original, copy); // *copy = original
103
+ }
104
+
76
105
return copy;
77
106
}
78
107
@@ -134,22 +163,20 @@ bool Win64TargetABI::returnInArg(TypeFunction* tf)
134
163
// everything <= 64 bits and of a size that is a power of 2
135
164
// is returned in a register (RAX, or XMM0 for single float/
136
165
// double) - except for cfloat
137
- // real/ireal is returned on top of the x87 stack: ST(0)
166
+ // 80-bit real/ireal is returned on top of the x87 stack: ST(0)
138
167
// complex numbers are returned in XMM0 & XMM1 (cfloat, cdouble)
139
168
// or ST(1) & ST(0) (creal)
140
169
// all other structs and static arrays are returned by struct-return (sret)
141
- return (rt->ty == Tstruct
142
- || rt->ty == Tsarray
143
- ) && !canRewriteAsInt (rt);
170
+ return isComposite (rt) && !canRewriteAsInt (rt);
144
171
}
145
172
146
173
bool Win64TargetABI::passByVal (Type* t)
147
174
{
148
175
t = t->toBasetype ();
149
176
150
- // structs and static arrays are passed byval unless they can be
151
- // rewritten as integers
152
- return (t-> ty == Tstruct || t-> ty == Tsarray) && ! canRewriteAsInt (t) ;
177
+ // FIXME: LLVM doesn't seem to support ByVal on Win64 yet
178
+ // return isPassedWithByvalSemantics(t);
179
+ return false ;
153
180
}
154
181
155
182
void Win64TargetABI::rewriteFunctionType (TypeFunction* tf, IrFuncTy &fty)
@@ -168,7 +195,7 @@ void Win64TargetABI::rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty)
168
195
// the other complex number types are returned via XMM0 = re and XMM1 = im
169
196
fty.ret ->rewrite = &swapComplex;
170
197
}
171
- else if (canRewriteAsInt (rt))
198
+ else if (isComposite (rt) && canRewriteAsInt (rt))
172
199
{
173
200
fty.ret ->rewrite = &compositeToInt;
174
201
fty.ret ->ltype = compositeToInt.type (fty.ret ->type , fty.ret ->ltype );
@@ -195,12 +222,13 @@ void Win64TargetABI::rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty)
195
222
arg.rewrite = &cfloatToInt;
196
223
arg.ltype = cfloatToInt.type (arg.type , arg.ltype );
197
224
}
198
- else if (canRewriteAsInt (ty))
225
+ else if (isComposite (ty) && canRewriteAsInt (ty))
199
226
{
200
227
arg.rewrite = &compositeToInt;
201
228
arg.ltype = compositeToInt.type (arg.type , arg.ltype );
202
229
}
203
- else if (ty->iscomplex () || ty->ty == Tfloat80 || ty->ty == Timaginary80)
230
+ // FIXME: this should actually be handled by LLVM and the ByVal arg attribute
231
+ else if (isPassedWithByvalSemantics (ty))
204
232
{
205
233
// these types are passed byval:
206
234
// the caller allocates a copy and then passes a pointer to the copy
0 commit comments