@@ -173,6 +173,26 @@ static bool interp__builtin_fmin(InterpState &S, CodePtr OpPC,
173
173
return true ;
174
174
}
175
175
176
+ static bool interp__builtin_fmax (InterpState &S, CodePtr OpPC,
177
+ const InterpFrame *Frame,
178
+ const Function *Func) {
179
+ const Floating &LHS = getParam<Floating>(Frame, 0 );
180
+ const Floating &RHS = getParam<Floating>(Frame, 1 );
181
+
182
+ Floating Result;
183
+
184
+ // When comparing zeroes, return +0.0 if one of the zeroes is positive.
185
+ if (LHS.isZero () && RHS.isZero () && LHS.isNegative ())
186
+ Result = RHS;
187
+ else if (LHS.isNan () || RHS > LHS)
188
+ Result = RHS;
189
+ else
190
+ Result = LHS;
191
+
192
+ S.Stk .push <Floating>(Result);
193
+ return true ;
194
+ }
195
+
176
196
// / Defined as __builtin_isnan(...), to accommodate the fact that it can
177
197
// / take a float, double, long double, etc.
178
198
// / But for us, that's all a Floating anyway.
@@ -341,6 +361,15 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F) {
341
361
return Ret<PT_Float>(S, OpPC, Dummy);
342
362
break ;
343
363
364
+ case Builtin::BI__builtin_fmax:
365
+ case Builtin::BI__builtin_fmaxf:
366
+ case Builtin::BI__builtin_fmaxl:
367
+ case Builtin::BI__builtin_fmaxf16:
368
+ case Builtin::BI__builtin_fmaxf128:
369
+ if (interp__builtin_fmax (S, OpPC, Frame, F))
370
+ return Ret<PT_Float>(S, OpPC, Dummy);
371
+ break ;
372
+
344
373
case Builtin::BI__builtin_isnan:
345
374
if (interp__builtin_isnan (S, OpPC, Frame, F))
346
375
return Ret<PT_Sint32>(S, OpPC, Dummy);
0 commit comments