@@ -26,7 +26,7 @@ T va_arg(T)(va_list ap)
26
26
{
27
27
static if (is (T U == __argTypes))
28
28
{
29
- static if (U.length == 0 || U[0 ].sizeof > 8 || is (T1 == __vector ))
29
+ static if (U.length == 0 || U[0 ].sizeof > 8 || is (U[ 0 ] == __vector ))
30
30
{
31
31
// Always passed in memory (varying vectors are passed in parameter area)
32
32
auto p = * cast (T* ) ap.__overflow_arg_area;
@@ -45,7 +45,7 @@ T va_arg(T)(va_list ap)
45
45
// Passed in $fr registers (FPR region starts at +0x80)
46
46
auto p = cast (T* ) ap.__reg_save_area + 128 + ap.__fpr * 8 ;
47
47
ap.__fpr++ ;
48
- return p;
48
+ return * p;
49
49
}
50
50
else
51
51
{
@@ -54,7 +54,7 @@ T va_arg(T)(va_list ap)
54
54
// no matter the actual size of the fp variable
55
55
// parameter slot is always 8-byte-wide (f32 is extended to f64)
56
56
ap.__overflow_arg_area += 8 ;
57
- return p;
57
+ return * p;
58
58
}
59
59
}
60
60
else
@@ -65,7 +65,7 @@ T va_arg(T)(va_list ap)
65
65
// Passed in $gpr registers (GPR region starts at +0x10)
66
66
auto p = cast (T* ) ap.__reg_save_area + 16 + ap.__gpr * 8 ;
67
67
ap.__gpr++ ;
68
- return p;
68
+ return * p;
69
69
}
70
70
else
71
71
{
@@ -74,7 +74,7 @@ T va_arg(T)(va_list ap)
74
74
// no matter the actual size of the gpr variable
75
75
// parameter slot is always 8-byte-wide (after ABI adjustments)
76
76
ap.__overflow_arg_area += 8 ;
77
- return p;
77
+ return * p;
78
78
}
79
79
}
80
80
}
@@ -93,6 +93,23 @@ T va_arg(T)(va_list ap)
93
93
void va_arg ()(va_list ap, TypeInfo ti, void * parmn)
94
94
{
95
95
TypeInfo arg1, arg2;
96
+ if (TypeInfo_Struct ti_struct = cast (TypeInfo_Struct ) ti)
97
+ {
98
+ // handle single-float element struct
99
+ const rtFields = ti_struct.offTi();
100
+ if (rtFields && rtFields.length == 1 )
101
+ {
102
+ TypeInfo field1TypeInfo = rtFields[0 ].ti;
103
+ if (field1TypeInfo is typeid (float ) || field1TypeInfo is typeid (double ))
104
+ {
105
+ auto tsize = field1TypeInfo.tsize;
106
+ auto toffset = rtFields[0 ].offset;
107
+ parmn[0 .. tsize] = p[toffset.. tsize];
108
+ return ;
109
+ }
110
+ }
111
+ }
112
+
96
113
if (! ti.argTypes(arg1, arg2))
97
114
{
98
115
TypeInfo_Vector v1 = arg1 ? cast (TypeInfo_Vector) arg1 : null ;
@@ -117,6 +134,30 @@ void va_arg()(va_list ap, TypeInfo ti, void* parmn)
117
134
parmn[0 .. tsize] = p[0 .. tsize];
118
135
}
119
136
}
137
+ else if (arg1 && (arg1 is typeid (float ) || arg1 is typeid (double )))
138
+ {
139
+ // Maybe passed in $fr registers
140
+ if (ap.__fpr <= 4 )
141
+ {
142
+ // Passed in $fr registers (FPR region starts at +0x80)
143
+ auto p = cast (T* ) ap.__reg_save_area + 128 + ap.__fpr * 8 ;
144
+ ap.__fpr++ ;
145
+ parmn[0 .. tsize] = p[0 .. tsize];
146
+ }
147
+ else
148
+ {
149
+ // overflow arguments
150
+ auto p = cast (T* ) ap.__overflow_arg_area;
151
+ // no matter the actual size of the fp variable
152
+ // parameter slot is always 8-byte-wide (f32 is extended to f64)
153
+ ap.__overflow_arg_area += 8 ;
154
+ parmn[0 .. tsize] = p[0 .. tsize];
155
+ }
156
+ }
157
+ else
158
+ {
159
+ assert (false , " unhandled va_arg type!" );
160
+ }
120
161
assert (! arg2);
121
162
}
122
163
else
0 commit comments