#include <stdlib.h>

#include "coduo_x87emu.h" /* defines EMULATE_X87; x87 shim when it is 1 */

#include "core_math_private.h"

void gunrandom(float *x, float *y)
{
    float angleDegrees;
    float radius;
    float sinValue;
    float cosValue;

    /* No explicit (float) cast on rand(): the stock binary feeds the fild
     * result straight into the divide (0x806603c/0x806605c, no float spill),
     * and under -std=c11 (-fexcess-precision=standard) a cast would round the
     * integer to float first, diverging for rand() >= 2^24. The implicit
     * conversion stays in extended precision like the original. */
#if EMULATE_X87
    /* fild(rand)/2^31 in 80-bit (no float spill of the integer), * 360 for the
     * angle; the sincos arg is (angleDegrees*pi)/180 in 80-bit; the radius scale
     * products round to float. */
    angleDegrees = x87f_store_f32(
        x87f_mul(x87f_div(x87f_load_i32(rand()), x87f_load_f32(2147483648.0f)),
                 x87f_load_f32(360.0f)));
    radius = x87f_store_f32(
        x87f_div(x87f_load_i32(rand()), x87f_load_f32(2147483648.0f)));
    SinCosFloat(
        x87f_store_f32(x87f_div(x87f_mul(x87f_load_f32(angleDegrees),
                                         x87f_load_f64(3.141592653589793)),
                                x87f_load_f64(180.0))),
        &sinValue, &cosValue);
    *x = x87f_store_f32(x87f_mul(x87f_load_f32(radius), x87f_load_f32(cosValue)));
    *y = x87f_store_f32(x87f_mul(x87f_load_f32(radius), x87f_load_f32(sinValue)));
#else
    angleDegrees = (rand() / 2147483648.0f) * 360.0f;
    radius = rand() / 2147483648.0f;
    SinCosFloat((float)(((double)angleDegrees * 3.141592653589793) / 180.0),
                 &sinValue, &cosValue);
    *x = radius * cosValue;
    *y = radius * sinValue;
#endif
}
