@@ -43,17 +43,16 @@ alias __va_list = __va_list_tag;
43
43
alias va_list = __va_list* ;
44
44
45
45
// /
46
- void va_arg (T)(va_list apx, ref T parmn )
46
+ T va_arg (T)(va_list ap )
47
47
{
48
- __va_list* ap = cast (__va_list* ) apx;
49
48
static if (is (T U == __argTypes))
50
49
{
51
50
static if (U.length == 0 || T.sizeof > 16 || (U[0 ].sizeof > 8 && ! is (U[0 ] == __vector )))
52
51
{ // Always passed in memory
53
52
// The arg may have more strict alignment than the stack
54
53
void * p = ap.stack_args.alignUp! (T.alignof);
55
54
ap.stack_args = p + T.sizeof.alignUp;
56
- parmn = * cast (T* ) p;
55
+ return * cast (T* ) p;
57
56
}
58
57
else static if (U.length == 1 )
59
58
{ // Arg is passed in one register
@@ -62,35 +61,41 @@ void va_arg(T)(va_list apx, ref T parmn)
62
61
{ // Passed in XMM register
63
62
if (ap.offset_fpregs < (6 * 8 + 16 * 8 ))
64
63
{
65
- parmn = * cast (T* ) (ap.reg_args + ap.offset_fpregs);
64
+ auto p = cast (T* ) (ap.reg_args + ap.offset_fpregs);
66
65
ap.offset_fpregs += 16 ;
66
+ return * p;
67
67
}
68
68
else
69
69
{
70
- parmn = * cast (T* ) ap.stack_args;
70
+ auto p = cast (T* ) ap.stack_args;
71
71
ap.stack_args += T1 .sizeof.alignUp;
72
+ return * p;
72
73
}
73
74
}
74
75
else
75
76
{ // Passed in regular register
76
77
if (ap.offset_regs < 6 * 8 && T.sizeof <= 8 )
77
78
{
78
- parmn = * cast (T* ) (ap.reg_args + ap.offset_regs);
79
+ auto p = cast (T* ) (ap.reg_args + ap.offset_regs);
79
80
ap.offset_regs += 8 ;
81
+ return * p;
80
82
}
81
83
else
82
84
{
83
85
void * p = ap.stack_args.alignUp! (T.alignof);
84
86
ap.stack_args = p + T.sizeof.alignUp;
85
- parmn = * cast (T* ) p;
87
+ return * cast (T* ) p;
86
88
}
87
89
}
88
90
}
89
91
else static if (U.length == 2 )
90
92
{ // Arg is passed in two registers
91
93
alias U[0 ] T1 ;
92
94
alias U[1 ] T2 ;
93
- auto p = (cast (void * ) &parmn) + 8 ;
95
+
96
+ T result = void ;
97
+ auto p1 = cast (T1 * ) &result;
98
+ auto p2 = cast (T2 * ) ((cast (void * ) &result) + 8 );
94
99
95
100
// Both must be in registers, or both on stack, hence 4 cases
96
101
@@ -99,15 +104,15 @@ void va_arg(T)(va_list apx, ref T parmn)
99
104
{
100
105
if (ap.offset_fpregs < (6 * 8 + 16 * 8 ) - 16 )
101
106
{
102
- * cast ( T1 * ) &parmn = * cast (T1 * ) (ap.reg_args + ap.offset_fpregs);
103
- * cast ( T2 * ) p = * cast (T2 * ) (ap.reg_args + ap.offset_fpregs + 16 );
107
+ * p1 = * cast (T1 * ) (ap.reg_args + ap.offset_fpregs);
108
+ * p2 = * cast (T2 * ) (ap.reg_args + ap.offset_fpregs + 16 );
104
109
ap.offset_fpregs += 32 ;
105
110
}
106
111
else
107
112
{
108
- * cast ( T1 * ) &parmn = * cast (T1 * ) ap.stack_args;
113
+ * p1 = * cast (T1 * ) ap.stack_args;
109
114
ap.stack_args += T1 .sizeof.alignUp;
110
- * cast ( T2 * ) p = * cast (T2 * ) ap.stack_args;
115
+ * p2 = * cast (T2 * ) ap.stack_args;
111
116
ap.stack_args += T2 .sizeof.alignUp;
112
117
}
113
118
}
@@ -117,37 +122,37 @@ void va_arg(T)(va_list apx, ref T parmn)
117
122
if (ap.offset_fpregs < (6 * 8 + 16 * 8 ) &&
118
123
ap.offset_regs < 6 * 8 && T2 .sizeof <= 8 )
119
124
{
120
- * cast ( T1 * ) &parmn = * cast (T1 * ) (ap.reg_args + ap.offset_fpregs);
125
+ * p1 = * cast (T1 * ) (ap.reg_args + ap.offset_fpregs);
121
126
ap.offset_fpregs += 16 ;
122
127
a = ap.reg_args + ap.offset_regs;
123
128
ap.offset_regs += 8 ;
124
129
}
125
130
else
126
131
{
127
- * cast ( T1 * ) &parmn = * cast (T1 * ) ap.stack_args;
132
+ * p1 = * cast (T1 * ) ap.stack_args;
128
133
ap.stack_args += T1 .sizeof.alignUp;
129
134
a = ap.stack_args;
130
135
ap.stack_args += 8 ;
131
136
}
132
137
// Be careful not to go past the size of the actual argument
133
138
const sz2 = T.sizeof - 8 ;
134
- p [0 .. sz2] = a[0 .. sz2];
139
+ ( cast ( void * ) p2) [0 .. sz2] = a[0 .. sz2];
135
140
}
136
141
else static if (is (T2 == double ) || is (T2 == float ))
137
142
{
138
143
if (ap.offset_regs < 6 * 8 && T1 .sizeof <= 8 &&
139
144
ap.offset_fpregs < (6 * 8 + 16 * 8 ))
140
145
{
141
- * cast ( T1 * ) &parmn = * cast (T1 * ) (ap.reg_args + ap.offset_regs);
146
+ * p1 = * cast (T1 * ) (ap.reg_args + ap.offset_regs);
142
147
ap.offset_regs += 8 ;
143
- * cast ( T2 * ) p = * cast (T2 * ) (ap.reg_args + ap.offset_fpregs);
148
+ * p2 = * cast (T2 * ) (ap.reg_args + ap.offset_fpregs);
144
149
ap.offset_fpregs += 16 ;
145
150
}
146
151
else
147
152
{
148
- * cast ( T1 * ) &parmn = * cast (T1 * ) ap.stack_args;
153
+ * p1 = * cast (T1 * ) ap.stack_args;
149
154
ap.stack_args += 8 ;
150
- * cast ( T2 * ) p = * cast (T2 * ) ap.stack_args;
155
+ * p2 = * cast (T2 * ) ap.stack_args;
151
156
ap.stack_args += T2 .sizeof.alignUp;
152
157
}
153
158
}
@@ -156,22 +161,24 @@ void va_arg(T)(va_list apx, ref T parmn)
156
161
void * a = void ;
157
162
if (ap.offset_regs < 5 * 8 && T1 .sizeof <= 8 && T2 .sizeof <= 8 )
158
163
{
159
- * cast ( T1 * ) &parmn = * cast (T1 * ) (ap.reg_args + ap.offset_regs);
164
+ * p1 = * cast (T1 * ) (ap.reg_args + ap.offset_regs);
160
165
ap.offset_regs += 8 ;
161
166
a = ap.reg_args + ap.offset_regs;
162
167
ap.offset_regs += 8 ;
163
168
}
164
169
else
165
170
{
166
- * cast ( T1 * ) &parmn = * cast (T1 * ) ap.stack_args;
171
+ * p1 = * cast (T1 * ) ap.stack_args;
167
172
ap.stack_args += 8 ;
168
173
a = ap.stack_args;
169
174
ap.stack_args += 8 ;
170
175
}
171
176
// Be careful not to go past the size of the actual argument
172
177
const sz2 = T.sizeof - 8 ;
173
- p [0 .. sz2] = a[0 .. sz2];
178
+ ( cast ( void * ) p2) [0 .. sz2] = a[0 .. sz2];
174
179
}
180
+
181
+ return result;
175
182
}
176
183
else
177
184
{
@@ -185,9 +192,8 @@ void va_arg(T)(va_list apx, ref T parmn)
185
192
}
186
193
187
194
// /
188
- void va_arg ()(va_list apx , TypeInfo ti, void * parmn)
195
+ void va_arg ()(va_list ap , TypeInfo ti, void * parmn)
189
196
{
190
- __va_list* ap = cast (__va_list* ) apx;
191
197
TypeInfo arg1, arg2;
192
198
if (! ti.argTypes(arg1, arg2))
193
199
{
0 commit comments