VirtualBox

Changeset 96659 in vbox


Ignore:
Timestamp:
Sep 8, 2022 1:17:16 PM (2 years ago)
Author:
vboxsync
Message:

VMM/IEM: Calculation of constants for fsin, fcos, fl2x instructions, ​bugref:9898

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/tools/IEMGenFpuConstants.c

    r96655 r96659  
    142142    printf("};\n");
    143143
     144    mpfr_init2(Val, 112 + 1);
     145    mpfr_const_pi(Val, MPFR_RNDN);
     146    PrintF128(Val, "g_r128pi", "The pi constant as 128-bit floating point value.");
     147    mpfr_div_ui(Val, Val, 2, MPFR_RNDD);
     148    PrintF128(Val, "g_r128pi2", "The pi/2 constant as 128-bit floating point value.");
     149
     150    printf("\n"
     151           "/** CORDIC constants for fsin and fcos, defined by c(i)=atan(2^(-i)) */\n"
     152           "const RTFLOAT128U g_ar128FsincosCORDICConsts[] =\n"
     153           "{\n");
     154    mpfr_init2(Val, 112 + 1);
     155    signed kmax = 68;
     156
     157    for (signed k = 0; k < kmax; k++)
     158    {
     159        // mpfr_mul_2si ?
     160        mpfr_set_si_2exp(Val, 1, -k, MPFR_RNDD);
     161        mpfr_atan(Val, Val, MPFR_RNDD);
     162        PrintF128(Val, NULL, "c%u", k);
     163    }
     164
     165    printf("};\n");
     166
     167    printf("\n"
     168           "/** CORDIC multipliers for fsin and fcos, defined by K(i)=1/sqrt(1+2^(-2i)) */\n"
     169           "const RTFLOAT128U g_ar128FsincosCORDICConsts2[] =\n"
     170           "{\n");
     171
     172    mpfr_init2(Val, 112 + 1);
     173    mpfr_init2(Val2, 112 + 1);
     174
     175    mpfr_set_ui(Val, 2, MPFR_RNDD);
     176    mpfr_sqrt(Val, Val, MPFR_RNDD);
     177    mpfr_ui_div(Val2, 1, Val, MPFR_RNDD);
     178    PrintF128(Val2, NULL, "K_%u", 0);
     179
     180    for (signed k = 1; k < kmax; k++)
     181    {
     182        mpfr_set_si_2exp(Val, 1, -2 * k, MPFR_RNDD);
     183        mpfr_add_ui(Val, Val, 1, MPFR_RNDD);
     184        mpfr_sqrt(Val, Val, MPFR_RNDD);
     185        mpfr_div(Val2, Val2, Val, MPFR_RNDD);
     186        PrintF128(Val2, NULL, "K_%u", k);
     187    }
     188
     189    printf("};\n");
     190
     191    printf("\n"
     192           "/** Chebyshev coeffs for log2 function in [1, 2] interval */\n"
     193           "const RTFLOAT128U g_ar128ChebLog2Consts[] =\n"
     194           "{\n");
     195    signed j, d, dmax = 22;
     196    mpfr_t ValX, ValXX, ValA, ValB, ValBmA, ValCos, ValSum;
     197    mpfr_init2(Val, 112 + 1);
     198    mpfr_init2(Val2, 112 + 1);
     199    mpfr_init2(ValX, 112 + 1);
     200    mpfr_init2(ValXX, 112 + 1);
     201    mpfr_init2(ValA, 112 + 1);
     202    mpfr_init2(ValB, 112 + 1);
     203    mpfr_init2(ValBmA, 112 + 1);
     204    mpfr_init2(ValCos, 112 + 1);
     205    mpfr_init2(ValSum, 112 + 1);
     206
     207    /* Setting the desired interpolation range [1.0, 2.0] */
     208    mpfr_set_d(ValA, 1.0, MPFR_RNDD);
     209    mpfr_set_d(ValB, 2.0, MPFR_RNDD);
     210    mpfr_sub(ValBmA, ValB, ValA, MPFR_RNDD);
     211
     212    for (signed d = 0; d < dmax; d++)
     213    {
     214        mpfr_set_si(ValSum, 0, MPFR_RNDD);
     215
     216        for(j = 0; j < dmax; j++)
     217        {
     218            mpfr_set_si_2exp(Val, 1, -1, MPFR_RNDD);
     219            mpfr_add_ui(Val, Val, j, MPFR_RNDD);
     220            mpfr_const_pi(Val2, MPFR_RNDN);
     221            mpfr_mul(Val, Val2, Val, MPFR_RNDN);
     222            mpfr_div_si(Val, Val, dmax, MPFR_RNDN);
     223            /* Val = M_PIq * (j + 0.5Q) / N */
     224
     225            mpfr_cos(ValX, Val, MPFR_RNDN);
     226            /* ValX = cos(M_PIq * (j + 0.5Q) / N) */
     227
     228            mpfr_mul_si(Val, Val, d, MPFR_RNDN);
     229            mpfr_cos(ValCos, Val, MPFR_RNDN);
     230            /* ValCos = cos(M_PIq * d * (j + 0.5Q) / N) */
     231
     232            mpfr_add_si(Val, ValX, 1, MPFR_RNDN);
     233            mpfr_div_si(Val, Val, 2, MPFR_RNDN);
     234            mpfr_mul(Val, ValBmA, Val, MPFR_RNDN);
     235            mpfr_add(ValXX, ValA, Val, MPFR_RNDN);
     236            /* ValXX = a + (b - a) * (x + 1.0Q) / 2.0Q */
     237
     238            mpfr_sub_si(Val, ValXX, 1, MPFR_RNDN);
     239            mpfr_log2(Val2, ValXX, MPFR_RNDN);
     240            mpfr_div(Val, Val2, Val, MPFR_RNDN);
     241            mpfr_mul(Val, Val, ValCos, MPFR_RNDN);
     242            mpfr_add(ValSum, ValSum, Val, MPFR_RNDN);
     243        }
     244
     245        mpfr_div_si(ValSum, ValSum, dmax, MPFR_RNDN);
     246
     247        if (d != 0)
     248            mpfr_mul_si(ValSum, ValSum, 2, MPFR_RNDN);
     249
     250        PrintF128(ValSum, NULL, "c%u", d);
     251    }
     252
     253    printf("};\n");
     254
     255    mpfr_clear(ValXX);
     256    mpfr_clear(ValX);
    144257    mpfr_clear(Val);
    145258    mpfr_clear(Val2);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette