Home | History | Annotate | Download | only in ppc32
      1 /*  Copyright (C) 2012 IBM
      2 
      3  Author: Maynard Johnson <maynardj (at) us.ibm.com>
      4 
      5  This program is free software; you can redistribute it and/or
      6  modify it under the terms of the GNU General Public License as
      7  published by the Free Software Foundation; either version 2 of the
      8  License, or (at your option) any later version.
      9 
     10  This program is distributed in the hope that it will be useful, but
     11  WITHOUT ANY WARRANTY; without even the implied warranty of
     12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  General Public License for more details.
     14 
     15  You should have received a copy of the GNU General Public License
     16  along with this program; if not, write to the Free Software
     17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     18  02111-1307, USA.
     19 
     20  The GNU General Public License is contained in the file COPYING.
     21  */
     22 
     23 #include <stdio.h>
     24 #include <stdlib.h>
     25 #include <stdint.h>
     26 #include <string.h>
     27 
     28 #if defined(HAS_DFP)
     29 
     30 register double f14 __asm__ ("fr14");
     31 register double f15 __asm__ ("fr15");
     32 register double f16 __asm__ ("fr16");
     33 register double f17 __asm__ ("fr17");
     34 register double f18 __asm__ ("fr18");
     35 register double f19 __asm__ ("fr19");
     36 
     37 
     38 typedef unsigned char Bool;
     39 #define True 1
     40 #define False 0
     41 
     42 
     43 #define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7"
     44 
     45 #define SET_CR(_arg) \
     46       __asm__ __volatile__ ("mtcr  %0" : : "b"(_arg) : ALLCR );
     47 
     48 #define SET_XER(_arg) \
     49       __asm__ __volatile__ ("mtxer %0" : : "b"(_arg) : "xer" );
     50 
     51 #define GET_CR(_lval) \
     52       __asm__ __volatile__ ("mfcr %0"  : "=b"(_lval) )
     53 
     54 #define GET_XER(_lval) \
     55       __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) )
     56 
     57 #define GET_CR_XER(_lval_cr,_lval_xer) \
     58    do { GET_CR(_lval_cr); GET_XER(_lval_xer); } while (0)
     59 
     60 #define SET_CR_ZERO \
     61       SET_CR(0)
     62 
     63 #define SET_XER_ZERO \
     64       SET_XER(0)
     65 
     66 #define SET_CR_XER_ZERO \
     67    do { SET_CR_ZERO; SET_XER_ZERO; } while (0)
     68 
     69 #define SET_FPSCR_ZERO \
     70    do { double _d = 0.0; \
     71         __asm__ __volatile__ ("mtfsf 0xFF, %0" : : "f"(_d) ); \
     72    } while (0)
     73 
     74 #define GET_FPSCR(_arg) \
     75     __asm__ __volatile__ ("mffs %0"  : "=f"(_arg) )
     76 
     77 #define SET_FPSCR_DRN \
     78     __asm__ __volatile__ ("mtfsf  1, %0, 0, 1" :  : "f"(f14) )
     79 
     80 
     81 // The assembly-level instructions being tested
     82 static void _test_drintx(int R, int RMC)
     83 {
     84    if (RMC < 0 || RMC > 3 || R < 0 || R > 1) {
     85       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", R, RMC);
     86       return;
     87    }
     88    switch (RMC) {
     89       case 0:
     90          if (R)
     91             __asm__ __volatile__ ("drintx 1, %0, %1, 0" : "=f" (f18) : "f" (f16));
     92          else
     93             __asm__ __volatile__ ("drintx 0, %0, %1, 0" : "=f" (f18) : "f" (f16));
     94          break;
     95       case 1:
     96          if (R)
     97             __asm__ __volatile__ ("drintx 1, %0, %1, 1" : "=f" (f18) : "f" (f16));
     98          else
     99             __asm__ __volatile__ ("drintx 0, %0, %1, 1" : "=f" (f18) : "f" (f16));
    100          break;
    101       case 2:
    102          if (R)
    103             __asm__ __volatile__ ("drintx 1, %0, %1, 2" : "=f" (f18) : "f" (f16));
    104          else
    105             __asm__ __volatile__ ("drintx 0, %0, %1, 2" : "=f" (f18) : "f" (f16));
    106          break;
    107       case 3:
    108          if (R)
    109             __asm__ __volatile__ ("drintx 1, %0, %1, 3" : "=f" (f18) : "f" (f16));
    110          else
    111             __asm__ __volatile__ ("drintx 0, %0, %1, 3" : "=f" (f18) : "f" (f16));
    112          break;
    113       default:
    114          break;
    115    }
    116 }
    117 
    118 static void _test_drintn(int R, int RMC)
    119 {
    120    if (RMC < 0 || RMC > 3 || R < 0 || R > 1) {
    121       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", R, RMC);
    122       return;
    123    }
    124    switch (RMC) {
    125       case 0:
    126          if (R)
    127             __asm__ __volatile__ ("drintn 1, %0, %1, 0" : "=f" (f18) : "f" (f16));
    128          else
    129             __asm__ __volatile__ ("drintn 0, %0, %1, 0" : "=f" (f18) : "f" (f16));
    130          break;
    131       case 1:
    132          if (R)
    133             __asm__ __volatile__ ("drintn 1, %0, %1, 1" : "=f" (f18) : "f" (f16));
    134          else
    135             __asm__ __volatile__ ("drintn 0, %0, %1, 1" : "=f" (f18) : "f" (f16));
    136          break;
    137       case 2:
    138          if (R)
    139             __asm__ __volatile__ ("drintn 1, %0, %1, 2" : "=f" (f18) : "f" (f16));
    140          else
    141             __asm__ __volatile__ ("drintn 0, %0, %1, 2" : "=f" (f18) : "f" (f16));
    142          break;
    143       case 3:
    144          if (R)
    145             __asm__ __volatile__ ("drintn 1, %0, %1, 3" : "=f" (f18) : "f" (f16));
    146          else
    147             __asm__ __volatile__ ("drintn 0, %0, %1, 3" : "=f" (f18) : "f" (f16));
    148          break;
    149       default:
    150          break;
    151    }
    152 }
    153 
    154 
    155 static void _test_diex(int a __attribute__((unused)), int b __attribute__((unused)))
    156 {
    157    __asm__ __volatile__ ("diex  %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
    158 }
    159 
    160 static void _test_dxex(int a __attribute__((unused)), int b __attribute__((unused)))
    161 {
    162    __asm__ __volatile__ ("dxex  %0, %1" : "=f" (f18) : "f" (f16));
    163 }
    164 
    165 static void _test_dcmpo(int BF, int x __attribute__((unused)))
    166 {
    167    if (BF < 0 || BF > 7) {
    168       fprintf(stderr, "Invalid input to asm test: a=%d\n", BF);
    169       return;
    170    }
    171    switch (BF) {
    172       case 0:
    173          __asm__ __volatile__ ("dcmpo  0, %0, %1" :  : "f" (f14),"f" (f16));
    174          break;
    175       case 1:
    176          __asm__ __volatile__ ("dcmpo  1, %0, %1" :  : "f" (f14),"f" (f16));
    177          break;
    178       case 2:
    179          __asm__ __volatile__ ("dcmpo  2, %0, %1" :  : "f" (f14),"f" (f16));
    180          break;
    181       case 3:
    182          __asm__ __volatile__ ("dcmpo  3, %0, %1" :  : "f" (f14),"f" (f16));
    183          break;
    184       case 4:
    185          __asm__ __volatile__ ("dcmpo  4, %0, %1" :  : "f" (f14),"f" (f16));
    186          break;
    187       case 5:
    188          __asm__ __volatile__ ("dcmpo  5, %0, %1" :  : "f" (f14),"f" (f16));
    189          break;
    190       case 6:
    191          __asm__ __volatile__ ("dcmpo  6, %0, %1" :  : "f" (f14),"f" (f16));
    192          break;
    193       case 7:
    194          __asm__ __volatile__ ("dcmpo  7, %0, %1" :  : "f" (f14),"f" (f16));
    195          break;
    196       default:
    197          break;
    198    }
    199 }
    200 
    201 static void _test_dcmpu(int BF, int x __attribute__((unused)))
    202 {
    203    if (BF < 0 || BF > 7) {
    204       fprintf(stderr, "Invalid input to asm test: a=%d\n", BF);
    205       return;
    206    }
    207    switch (BF) {
    208       case 0:
    209          __asm__ __volatile__ ("dcmpu  0, %0, %1" :  : "f" (f14),"f" (f16));
    210          break;
    211       case 1:
    212          __asm__ __volatile__ ("dcmpu  1, %0, %1" :  : "f" (f14),"f" (f16));
    213          break;
    214       case 2:
    215          __asm__ __volatile__ ("dcmpu  2, %0, %1" :  : "f" (f14),"f" (f16));
    216          break;
    217       case 3:
    218          __asm__ __volatile__ ("dcmpu  3, %0, %1" :  : "f" (f14),"f" (f16));
    219          break;
    220       case 4:
    221          __asm__ __volatile__ ("dcmpu  4, %0, %1" :  : "f" (f14),"f" (f16));
    222          break;
    223       case 5:
    224          __asm__ __volatile__ ("dcmpu  5, %0, %1" :  : "f" (f14),"f" (f16));
    225          break;
    226       case 6:
    227          __asm__ __volatile__ ("dcmpu  6, %0, %1" :  : "f" (f14),"f" (f16));
    228          break;
    229       case 7:
    230          __asm__ __volatile__ ("dcmpu  7, %0, %1" :  : "f" (f14),"f" (f16));
    231          break;
    232       default:
    233          break;
    234    }
    235 }
    236 
    237 // Quad instruction testing
    238 static void _test_drintxq(int R, int RMC)
    239 {
    240    if (RMC < 0 || RMC > 3 || R < 0 || R > 1) {
    241       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", R, RMC);
    242       return;
    243    }
    244    switch (RMC) {
    245       case 0:
    246          if (R)
    247             __asm__ __volatile__ ("drintxq 1, %0, %1, 0" : "=f" (f18) : "f" (f16));
    248          else
    249             __asm__ __volatile__ ("drintxq 0, %0, %1, 0" : "=f" (f18) : "f" (f16));
    250          break;
    251       case 1:
    252          if (R)
    253             __asm__ __volatile__ ("drintxq 1, %0, %1, 1" : "=f" (f18) : "f" (f16));
    254          else
    255             __asm__ __volatile__ ("drintxq 0, %0, %1, 1" : "=f" (f18) : "f" (f16));
    256          break;
    257       case 2:
    258          if (R)
    259             __asm__ __volatile__ ("drintxq 1, %0, %1, 2" : "=f" (f18) : "f" (f16));
    260          else
    261             __asm__ __volatile__ ("drintxq 0, %0, %1, 2" : "=f" (f18) : "f" (f16));
    262          break;
    263       case 3:
    264          if (R)
    265             __asm__ __volatile__ ("drintxq 1, %0, %1, 3" : "=f" (f18) : "f" (f16));
    266          else
    267             __asm__ __volatile__ ("drintxq 0, %0, %1, 3" : "=f" (f18) : "f" (f16));
    268          break;
    269       default:
    270          break;
    271    }
    272 }
    273 
    274 static void _test_drintnq(int R, int RMC)
    275 {
    276    if (RMC < 0 || RMC > 3 || R < 0 || R > 1) {
    277       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", R, RMC);
    278       return;
    279    }
    280    switch (RMC) {
    281       case 0:
    282          if (R)
    283             __asm__ __volatile__ ("drintnq 1, %0, %1, 0" : "=f" (f18) : "f" (f16));
    284          else
    285             __asm__ __volatile__ ("drintnq 0, %0, %1, 0" : "=f" (f18) : "f" (f16));
    286          break;
    287       case 1:
    288          if (R)
    289             __asm__ __volatile__ ("drintnq 1, %0, %1, 1" : "=f" (f18) : "f" (f16));
    290          else
    291             __asm__ __volatile__ ("drintnq 0, %0, %1, 1" : "=f" (f18) : "f" (f16));
    292          break;
    293       case 2:
    294          if (R)
    295             __asm__ __volatile__ ("drintnq 1, %0, %1, 2" : "=f" (f18) : "f" (f16));
    296          else
    297             __asm__ __volatile__ ("drintnq 0, %0, %1, 2" : "=f" (f18) : "f" (f16));
    298          break;
    299       case 3:
    300          if (R)
    301             __asm__ __volatile__ ("drintnq 1, %0, %1, 3" : "=f" (f18) : "f" (f16));
    302          else
    303             __asm__ __volatile__ ("drintnq 0, %0, %1, 3" : "=f" (f18) : "f" (f16));
    304          break;
    305       default:
    306          break;
    307    }
    308 }
    309 
    310 static void _test_diexq(int a __attribute__((unused)), int b __attribute__((unused)))
    311 {
    312    __asm__ __volatile__ ("diexq  %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
    313 }
    314 
    315 static void _test_dxexq(int a __attribute__((unused)), int b __attribute__((unused)))
    316 {
    317    __asm__ __volatile__ ("dxexq  %0, %1" : "=f" (f18) : "f" (f16));
    318 }
    319 
    320 static void _test_dcmpoq(int BF, int x __attribute__((unused)))
    321 {
    322    if (BF < 0 || BF > 7) {
    323       fprintf(stderr, "Invalid input to asm test: a=%d\n", BF );
    324       return;
    325    }
    326    switch (BF) {
    327       case 0:
    328          __asm__ __volatile__ ("dcmpoq  0, %0, %1" :  : "f" (f14),"f" (f16));
    329          break;
    330       case 1:
    331          __asm__ __volatile__ ("dcmpoq  1, %0, %1" :  : "f" (f14),"f" (f16));
    332          break;
    333       case 2:
    334          __asm__ __volatile__ ("dcmpoq  2, %0, %1" :  : "f" (f14),"f" (f16));
    335          break;
    336       case 3:
    337          __asm__ __volatile__ ("dcmpoq  3, %0, %1" :  : "f" (f14),"f" (f16));
    338          break;
    339       case 4:
    340          __asm__ __volatile__ ("dcmpoq  4, %0, %1" :  : "f" (f14),"f" (f16));
    341          break;
    342       case 5:
    343          __asm__ __volatile__ ("dcmpoq  5, %0, %1" :  : "f" (f14),"f" (f16));
    344          break;
    345       case 6:
    346          __asm__ __volatile__ ("dcmpoq  6, %0, %1" :  : "f" (f14),"f" (f16));
    347          break;
    348       case 7:
    349          __asm__ __volatile__ ("dcmpoq  7, %0, %1" :  : "f" (f14),"f" (f16));
    350          break;
    351       default:
    352          break;
    353    }
    354 }
    355 
    356 static void _test_dcmpuq(int BF, int x __attribute__((unused)))
    357 {
    358    if (BF < 0 || BF > 7) {
    359       fprintf(stderr, "Invalid input to asm test: a=%d\n", BF);
    360       return;
    361    }
    362    switch (BF) {
    363       case 0:
    364          __asm__ __volatile__ ("dcmpuq  0, %0, %1" :  : "f" (f14),"f" (f16));
    365          break;
    366       case 1:
    367          __asm__ __volatile__ ("dcmpuq  1, %0, %1" :  : "f" (f14),"f" (f16));
    368          break;
    369       case 2:
    370          __asm__ __volatile__ ("dcmpuq  2, %0, %1" :  : "f" (f14),"f" (f16));
    371          break;
    372       case 3:
    373          __asm__ __volatile__ ("dcmpuq  3, %0, %1" :  : "f" (f14),"f" (f16));
    374          break;
    375       case 4:
    376          __asm__ __volatile__ ("dcmpuq  4, %0, %1" :  : "f" (f14),"f" (f16));
    377          break;
    378       case 5:
    379          __asm__ __volatile__ ("dcmpuq  5, %0, %1" :  : "f" (f14),"f" (f16));
    380          break;
    381       case 6:
    382          __asm__ __volatile__ ("dcmpuq  6, %0, %1" :  : "f" (f14),"f" (f16));
    383          break;
    384       case 7:
    385          __asm__ __volatile__ ("dcmpuq  7, %0, %1" :  : "f" (f14),"f" (f16));
    386          break;
    387       default:
    388          break;
    389    }
    390 }
    391 
    392 static void _test_drrnd(int x __attribute__((unused)), int RMC)
    393 {
    394    if (RMC < 0 || RMC > 31) {
    395       fprintf(stderr, "Invalid input to asm test: a=%d\n", RMC);
    396       return;
    397    }
    398    switch (RMC) {
    399       case 0:
    400          __asm__ __volatile__ ("drrnd %0, %1, %2, 0" : "=f" (f18) : "f" (f14), "f" (f16));
    401          break;
    402       case 1:
    403          __asm__ __volatile__ ("drrnd %0, %1, %2, 1" : "=f" (f18) : "f" (f14), "f" (f16));
    404          break;
    405       case 2:
    406          __asm__ __volatile__ ("drrnd %0, %1, %2, 2" : "=f" (f18) : "f" (f14), "f" (f16));
    407          break;
    408       case 3:
    409          __asm__ __volatile__ ("drrnd %0, %1, %2, 3" : "=f" (f18) : "f" (f14), "f" (f16));
    410          break;
    411       default:
    412          break;
    413    }
    414 }
    415 
    416 static void _test_drrndq(int x __attribute__((unused)), int RMC)
    417 {
    418    if (RMC < 0 || RMC > 3) {
    419       fprintf(stderr, "Invalid input to asm test: a=%dn", RMC);
    420       return;
    421    }
    422    switch (RMC) {
    423       case 0:
    424          __asm__ __volatile__ ("drrndq %0, %1, %2, 0" : "=f" (f18) : "f" (f14), "f" (f16));
    425          break;
    426       case 1:
    427          __asm__ __volatile__ ("drrndq %0, %1, %2, 1" : "=f" (f18) : "f" (f14), "f" (f16));
    428          break;
    429       case 2:
    430          __asm__ __volatile__ ("drrndq %0, %1, %2, 2" : "=f" (f18) : "f" (f14), "f" (f16));
    431          break;
    432       case 3:
    433          __asm__ __volatile__ ("drrndq %0, %1, %2, 3" : "=f" (f18) : "f" (f14), "f" (f16));
    434          break;
    435       default:
    436          break;
    437    }
    438 }
    439 
    440 static void _test_dqua(int x __attribute__((unused)), int RMC)
    441 {
    442    if (RMC < 0 || RMC > 3) {
    443       fprintf(stderr, "Invalid input to asm test: a=%d\n", RMC);
    444       return;
    445    }
    446    switch (RMC) {
    447       case 0:
    448          __asm__ __volatile__ ("dqua %0, %1, %2, 0" : "=f" (f18) : "f" (f14), "f" (f16));
    449          break;
    450       case 1:
    451          __asm__ __volatile__ ("dqua %0, %1, %2, 1" : "=f" (f18) : "f" (f14), "f" (f16));
    452          break;
    453       case 2:
    454          __asm__ __volatile__ ("dqua %0, %1, %2, 2" : "=f" (f18) : "f" (f14), "f" (f16));
    455          break;
    456       case 3:
    457          __asm__ __volatile__ ("dqua %0, %1, %2, 3" : "=f" (f18) : "f" (f14), "f" (f16));
    458          break;
    459       default:
    460          break;
    461    }
    462 }
    463 
    464 static void _test_dquaq(int x __attribute__((unused)), int RMC)
    465 {
    466    if (RMC < 0 || RMC > 3) {
    467       fprintf(stderr, "Invalid input to asm test: a=%d\n", RMC);
    468       return;
    469    }
    470    switch (RMC) {
    471       case 0:
    472          __asm__ __volatile__ ("dquaq %0, %1, %2, 0" : "=f" (f18) : "f" (f14), "f" (f16));
    473          break;
    474       case 1:
    475          __asm__ __volatile__ ("dquaq %0, %1, %2, 1" : "=f" (f18) : "f" (f14), "f" (f16));
    476          break;
    477       case 2:
    478          __asm__ __volatile__ ("dquaq %0, %1, %2, 2" : "=f" (f18) : "f" (f14), "f" (f16));
    479          break;
    480       case 3:
    481          __asm__ __volatile__ ("dquaq %0, %1, %2, 3" : "=f" (f18) : "f" (f14), "f" (f16));
    482          break;
    483       default:
    484          break;
    485    }
    486 }
    487 
    488 static int TE_vals[] = { -16, -2, 0, 5};
    489 #define TE_VAL_LEN sizeof(TE_vals)/sizeof(int)
    490 static Bool __is_TE_val(int x)
    491 {
    492    int i;
    493    for (i = 0; i < TE_VAL_LEN; i++) {
    494       if (x==TE_vals[i])
    495          return True;
    496    }
    497    return False;
    498 }
    499 
    500 static void _test_dquai(int TE, int RMC)
    501 {
    502    if (RMC < 0 || RMC > 3 || !__is_TE_val(TE)) {
    503       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", TE, RMC);
    504       return;
    505    }
    506    switch (RMC) {
    507       case 0:
    508          switch (TE) {
    509             case -16:
    510                __asm__ __volatile__ ("dquai -16, %0, %1, 0" : "=f" (f18) : "f" (f16));
    511                break;
    512             case -2:
    513                __asm__ __volatile__ ("dquai  -2, %0, %1, 0" : "=f" (f18) : "f" (f16));
    514                break;
    515             case 0:
    516                __asm__ __volatile__ ("dquai   0, %0, %1, 0" : "=f" (f18) : "f" (f16));
    517                break;
    518             case 5:
    519                __asm__ __volatile__ ("dquai   5, %0, %1, 0" : "=f" (f18) : "f" (f16));
    520                break;
    521             default:
    522                break;
    523          }
    524          break;
    525       case 1:
    526          switch (TE) {
    527             case -16:
    528                __asm__ __volatile__ ("dquai -16, %0, %1, 1" : "=f" (f18) : "f" (f16));
    529                break;
    530             case -2:
    531                __asm__ __volatile__ ("dquai  -2, %0, %1, 1" : "=f" (f18) : "f" (f16));
    532                break;
    533             case 0:
    534                __asm__ __volatile__ ("dquai   0, %0, %1, 1" : "=f" (f18) : "f" (f16));
    535                break;
    536             case 5:
    537                __asm__ __volatile__ ("dquai   5, %0, %1, 1" : "=f" (f18) : "f" (f16));
    538                break;
    539             default:
    540                break;
    541          }
    542          break;
    543       case 2:
    544          switch (TE) {
    545             case -16:
    546                __asm__ __volatile__ ("dquai -16, %0, %1, 2" : "=f" (f18) : "f" (f16));
    547                break;
    548             case -2:
    549                __asm__ __volatile__ ("dquai  -2, %0, %1, 2" : "=f" (f18) : "f" (f16));
    550                break;
    551             case 0:
    552                __asm__ __volatile__ ("dquai   0, %0, %1, 2" : "=f" (f18) : "f" (f16));
    553                break;
    554             case 5:
    555                __asm__ __volatile__ ("dquai   5, %0, %1, 2" : "=f" (f18) : "f" (f16));
    556                break;
    557             default:
    558                break;
    559          }
    560          break;
    561       case 3:
    562          switch (TE) {
    563             case -16:
    564                __asm__ __volatile__ ("dquai -16, %0, %1, 3" : "=f" (f18) : "f" (f16));
    565                break;
    566             case -2:
    567                __asm__ __volatile__ ("dquai  -2, %0, %1, 3" : "=f" (f18) : "f" (f16));
    568                break;
    569             case 0:
    570                __asm__ __volatile__ ("dquai   0, %0, %1, 3" : "=f" (f18) : "f" (f16));
    571                break;
    572             case 5:
    573                __asm__ __volatile__ ("dquai   5, %0, %1, 3" : "=f" (f18) : "f" (f16));
    574                break;
    575             default:
    576                break;
    577          }
    578          break;
    579       default:
    580          break;
    581    }
    582 }
    583 
    584 static void _test_dquaiq(int TE, int RMC)
    585 {
    586    if (RMC < 0 || RMC > 3 || !__is_TE_val(TE)) {
    587       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", TE, RMC);
    588       return;
    589    }
    590    switch (RMC) {
    591       case 0:
    592          switch (TE) {
    593             case -16:
    594                __asm__ __volatile__ ("dquaiq -16, %0, %1, 0" : "=f" (f18) : "f" (f16));
    595                break;
    596             case -2:
    597                __asm__ __volatile__ ("dquaiq  -2, %0, %1, 0" : "=f" (f18) : "f" (f16));
    598                break;
    599             case 0:
    600                __asm__ __volatile__ ("dquaiq   0, %0, %1, 0" : "=f" (f18) : "f" (f16));
    601                break;
    602             case 5:
    603                __asm__ __volatile__ ("dquaiq   5, %0, %1, 0" : "=f" (f18) : "f" (f16));
    604                break;
    605             default:
    606                break;
    607          }
    608          break;
    609       case 1:
    610          switch (TE) {
    611             case -16:
    612                __asm__ __volatile__ ("dquaiq -16, %0, %1, 1" : "=f" (f18) : "f" (f16));
    613                break;
    614             case -2:
    615                __asm__ __volatile__ ("dquaiq  -2, %0, %1, 1" : "=f" (f18) : "f" (f16));
    616                break;
    617             case 0:
    618                __asm__ __volatile__ ("dquaiq   0, %0, %1, 1" : "=f" (f18) : "f" (f16));
    619                break;
    620             case 5:
    621                __asm__ __volatile__ ("dquaiq   5, %0, %1, 1" : "=f" (f18) : "f" (f16));
    622                break;
    623             default:
    624                break;
    625          }
    626          break;
    627       case 2:
    628          switch (TE) {
    629             case -16:
    630                __asm__ __volatile__ ("dquaiq -16, %0, %1, 2" : "=f" (f18) : "f" (f16));
    631                break;
    632             case -2:
    633                __asm__ __volatile__ ("dquaiq  -2, %0, %1, 2" : "=f" (f18) : "f" (f16));
    634                break;
    635             case 0:
    636                __asm__ __volatile__ ("dquaiq   0, %0, %1, 2" : "=f" (f18) : "f" (f16));
    637                break;
    638             case 5:
    639                __asm__ __volatile__ ("dquaiq   5, %0, %1, 2" : "=f" (f18) : "f" (f16));
    640                break;
    641             default:
    642                break;
    643          }
    644          break;
    645       case 3:
    646          switch (TE) {
    647             case -16:
    648                __asm__ __volatile__ ("dquaiq -16, %0, %1, 3" : "=f" (f18) : "f" (f16));
    649                break;
    650             case -2:
    651                __asm__ __volatile__ ("dquaiq  -2, %0, %1, 3" : "=f" (f18) : "f" (f16));
    652                break;
    653             case 0:
    654                __asm__ __volatile__ ("dquaiq   0, %0, %1, 3" : "=f" (f18) : "f" (f16));
    655                break;
    656             case 5:
    657                __asm__ __volatile__ ("dquaiq   5, %0, %1, 3" : "=f" (f18) : "f" (f16));
    658                break;
    659             default:
    660                break;
    661          }
    662          break;
    663       default:
    664          break;
    665    }
    666 }
    667 
    668 
    669 typedef void (*test_func_t)(int a, int b);
    670 typedef void (*test_driver_func_t)(void);
    671 typedef struct test_table
    672 {
    673    test_driver_func_t test_category;
    674    char * name;
    675 } test_table_t;
    676 
    677 /*
    678  *  345.0DD (0x2207c00000000000 0xe50)
    679  *  1.2300e+5DD (0x2207c00000000000 0x14c000)
    680  *  -16.0DD (0xa207c00000000000 0xe0)
    681  *  0.00189DD (0x2206c00000000000 0xcf)
    682  *  -4.1235DD (0xa205c00000000000 0x10a395bcf)
    683  *  9.8399e+20DD (0x2209400000000000 0x253f1f534acdd4)
    684  *  0DD (0x2208000000000000 0x0)
    685  *  0DD (0x2208000000000000 0x0)
    686  *  infDD (0x7800000000000000 0x0)
    687  *  nanDD (0x7c00000000000000 0x0
    688  */
    689 static unsigned long long dfp128_vals[] = {
    690                                     // Some finite numbers
    691                                     0x2207c00000000000ULL, 0x0000000000000e50ULL,
    692                                     0x2207c00000000000ULL, 0x000000000014c000ULL,
    693                                     0xa207c00000000000ULL, 0x00000000000000e0ULL,
    694                                     0x2206c00000000000ULL, 0x00000000000000cfULL,
    695                                     0xa205c00000000000ULL, 0x000000010a395bcfULL,
    696                                     0x6209400000fd0000ULL, 0x00253f1f534acdd4ULL, // huge number
    697                                     0x000400000089b000ULL, 0x0a6000d000000049ULL, // very small number
    698                                     // flavors of zero
    699                                     0x2208000000000000ULL, 0x0000000000000000ULL,
    700                                     0xa208000000000000ULL, 0x0000000000000000ULL, // negative
    701                                     0xa248000000000000ULL, 0x0000000000000000ULL,
    702                                     // flavors of NAN
    703                                     0x7c00000000000000ULL, 0x0000000000000000ULL, // quiet
    704                                     0xfc00000000000000ULL, 0xc00100035b007700ULL,
    705                                     0x7e00000000000000ULL, 0xfe000000d0e0a0d0ULL, // signaling
    706                                     // flavors of Infinity
    707                                     0x7800000000000000ULL, 0x0000000000000000ULL,
    708                                     0xf800000000000000ULL, 0x0000000000000000ULL, // negative
    709                                     0xf900000000000000ULL, 0x0000000000000000ULL
    710 };
    711 
    712 static unsigned long long dfp64_vals[] = {
    713                                  // various finite numbers
    714                                  0x2234000000000e50ULL,
    715                                  0x223400000014c000ULL,
    716                                  0xa2340000000000e0ULL,// negative
    717                                  0x22240000000000cfULL,
    718                                  0xa21400010a395bcfULL,// negative
    719                                  0x6e4d3f1f534acdd4ULL,// huge number
    720                                  0x000400000089b000ULL,// very small number
    721                                  // flavors of zero
    722                                  0x2238000000000000ULL,
    723                                  0xa238000000000000ULL,
    724                                  0x4248000000000000ULL,
    725                                  // flavors of NAN
    726                                  0x7e34000000000111ULL,
    727                                  0xfe000000d0e0a0d0ULL,//signaling
    728                                  0xfc00000000000000ULL,//quiet
    729                                  // flavors of Infinity
    730                                  0x7800000000000000ULL,
    731                                  0xf800000000000000ULL,//negative
    732                                  0x7a34000000000000ULL,
    733 };
    734 
    735 // Both Long and Quad arrays of DFP values should have the same length.
    736 // If that length is changed, t
    737 #define NUM_DFP_VALS (sizeof(dfp64_vals)/8)
    738 
    739 typedef struct dfp_test_args {
    740    int fra_idx;
    741    int frb_idx;
    742 } dfp_test_args_t;
    743 
    744 
    745 // Index pairs from dfp64_vals array to be used with dfp_two_arg_tests
    746 static dfp_test_args_t dfp_2args_x1[] = {
    747                                     {0, 1},
    748                                     {2, 1},
    749                                     {3, 4},
    750                                     {0, 6},
    751                                     {2, 4},
    752                                     {5, 1},
    753                                     {5, 2},
    754                                     {7, 1},
    755                                     {7, 2},
    756                                     {8, 0},
    757                                     {8, 1},
    758                                     {8, 2},
    759                                     {7, 8},
    760                                     {12, 14},
    761                                     {12, 1},
    762                                     {12, 13},
    763                                     {12, 12},
    764                                     {12, 11},
    765                                     {11, 14},
    766                                     {11, 0},
    767                                     {11, 13},
    768                                     {11, 11},
    769                                     {14, 14},
    770                                     {14, 3},
    771                                     {14, 15},
    772 };
    773 
    774 typedef enum {
    775    LONG_TEST,
    776    QUAD_TEST
    777 } precision_type_t;
    778 
    779 typedef struct dfp_test
    780 {
    781    test_func_t test_func;
    782    const char * name;
    783    dfp_test_args_t * targs;
    784    int num_tests;
    785    precision_type_t precision;
    786    const char * op;
    787 } dfp_test_t;
    788 
    789 typedef struct dfp_one_arg_test
    790 {
    791    test_func_t test_func;
    792    const char * name;
    793    precision_type_t precision;
    794    const char * op;
    795 } dfp_one_arg_test_t;
    796 
    797 
    798 static dfp_one_arg_test_t
    799 dfp_quai_tests[] = {
    800                     { &_test_dquai, "dquai", LONG_TEST, "[QI]"},
    801                     { &_test_dquaiq, "dquaiq", QUAD_TEST, "[QI]"},
    802                     { NULL, NULL, 0, NULL}
    803 };
    804 
    805 static void test_dfp_quai_ops(void)
    806 {
    807    test_func_t func;
    808    unsigned long long u0, u0x;
    809    double res, d0, *d0p, d0x, *d0xp;
    810 
    811    int k = 0;
    812    u0 = u0x = 0;
    813    d0p = &d0;
    814    d0xp = &d0x;
    815 
    816    while ((func = dfp_quai_tests[k].test_func)) {
    817       int i;
    818       dfp_one_arg_test_t test_def = dfp_quai_tests[k];
    819 
    820       for (i = 0; i < NUM_DFP_VALS; i++) {
    821          int TE, RMC;
    822 
    823          if (test_def.precision == LONG_TEST) {
    824             u0 = dfp64_vals[i];
    825          } else {
    826             u0 = dfp128_vals[i * 2];
    827             u0x = dfp128_vals[(i * 2) + 1];
    828          }
    829          *(unsigned long long *)d0p = u0;
    830          f16 = d0;
    831          if (test_def.precision == QUAD_TEST) {
    832             *(unsigned long long *)d0xp = u0x;
    833             f17 = d0x;
    834          }
    835 
    836          for (TE = 0; TE < TE_VAL_LEN; TE++) {
    837             for (RMC = 0; RMC < 4; RMC++) {
    838                (*func)(TE_vals[TE], RMC);
    839                res = f18;
    840                printf("%s (RMC=%2d, TE=%3d) %s %016llx", test_def.name, RMC,
    841                       TE_vals[TE], test_def.op, u0);
    842                if (test_def.precision == LONG_TEST) {
    843                   printf(" => %016llx\n",
    844                          *((unsigned long long *)(&res)));
    845                } else {
    846                   double resx = f19;
    847                   printf(" %016llx ==> %016llx %016llx\n",
    848                          u0x, *((unsigned long long *)(&res)), *((unsigned long long *)(&resx)));
    849                }
    850             }
    851          }
    852       }
    853       k++;
    854       printf( "\n" );
    855    }
    856 }
    857 
    858 
    859 static dfp_test_t
    860 dfp_qua_tests[] = {
    861                    { &_test_dqua, "dqua", dfp_2args_x1, 25, LONG_TEST, "[Q]"},
    862                    { &_test_dquaq, "dquaq", dfp_2args_x1, 25, QUAD_TEST, "[Q]"},
    863                    { NULL, NULL, NULL, 0, 0, NULL}
    864 };
    865 
    866 static void test_dfp_qua_ops(void)
    867 {
    868    test_func_t func;
    869    unsigned long long u0, u0x, u1, u1x;
    870    double res, d0, d1, *d0p, *d1p;
    871    double d0x, d1x, *d0xp, *d1xp;
    872    int k = 0;
    873    u0x = u1x = 0;
    874    d0p = &d0;
    875    d0xp = &d0x;
    876    d1p = &d1;
    877    d1xp = &d1x;
    878 
    879    while ((func = dfp_qua_tests[k].test_func)) {
    880       int i, RMC;
    881       dfp_test_t test_def = dfp_qua_tests[k];
    882 
    883       for (i = 0; i < test_def.num_tests; i++) {
    884          if (test_def.precision == LONG_TEST) {
    885             u0 = dfp64_vals[test_def.targs[i].fra_idx];
    886             u1 = dfp64_vals[test_def.targs[i].frb_idx];
    887          } else {
    888             u0 = dfp128_vals[test_def.targs[i].fra_idx * 2];
    889             u0x = dfp128_vals[(test_def.targs[i].fra_idx * 2) + 1];
    890             u1 = dfp128_vals[test_def.targs[i].frb_idx * 2];
    891             u1x = dfp128_vals[(test_def.targs[i].frb_idx * 2) + 1];
    892          }
    893          *(unsigned long long *)d0p = u0;
    894          *(unsigned long long *)d1p = u1;
    895          f14 = d0;
    896          f16 = d1;
    897          if (test_def.precision == QUAD_TEST) {
    898             *(unsigned long long *)d0xp = u0x;
    899             *(unsigned long long *)d1xp = u1x;
    900             f15 = d0x;
    901             f17 = d1x;
    902          }
    903          for (RMC = 0; RMC < 4; RMC++) {
    904             (*func)(-1, RMC);
    905             res = f18;
    906             printf("%s (RMC=%2d) %s %016llx", test_def.name, RMC, test_def.op, u0);
    907             if (test_def.precision == LONG_TEST) {
    908                printf(", %016llx => %016llx\n", u1, *((unsigned long long *)(&res)));
    909             } else {
    910                double resx = f19;
    911                printf(" %016llx, %016llx %016llx ==> %016llx %016llx\n",u0x, u1, u1x,
    912                       *((unsigned long long *)(&res)), *((unsigned long long *)(&resx)));
    913             }
    914          }
    915       }
    916       k++;
    917       printf( "\n" );
    918    }
    919 }
    920 
    921 
    922 static dfp_one_arg_test_t
    923 dfp_rrnd_tests[] = {
    924                     { &_test_drrnd, "drrnd", LONG_TEST, "[RR]"},
    925                     { &_test_drrndq, "drrndq", QUAD_TEST, "[RR]"},
    926                     { NULL, NULL, 0, NULL}
    927 };
    928 
    929 static void test_dfp_rrnd_ops(void)
    930 {
    931    test_func_t func;
    932    unsigned long long u0, u0x;
    933    double res, d0, *d0p, d0x, *d0xp, reference_sig, *reference_sig_p;
    934    long long reference_sig_vals[] = {0ULL, 2ULL, 6ULL, 63ULL};
    935    int num_reference_sig_vals = sizeof(reference_sig_vals)/sizeof(long long);
    936 
    937    int k = 0;
    938    u0 = u0x = 0;
    939    d0p = &d0;
    940    d0xp = &d0x;
    941    reference_sig_p = &reference_sig;
    942 
    943    while ((func = dfp_rrnd_tests[k].test_func)) {
    944       int i, j;
    945       dfp_one_arg_test_t test_def = dfp_rrnd_tests[k];
    946 
    947       for (i = 0; i < NUM_DFP_VALS; i++) {
    948          int RMC;
    949 
    950          if (test_def.precision == LONG_TEST) {
    951             u0 = dfp64_vals[i];
    952          } else {
    953             u0 = dfp128_vals[i * 2];
    954             u0x = dfp128_vals[(i * 2) + 1];
    955          }
    956          *(unsigned long long *)d0p = u0;
    957          f16 = d0;
    958          if (test_def.precision == QUAD_TEST) {
    959             *(unsigned long long *)d0xp = u0x;
    960             f17 = d0x;
    961          }
    962 
    963          for (j = 0; j < num_reference_sig_vals; j++) {
    964             *(long long *)reference_sig_p = reference_sig_vals[j];
    965             f14 = reference_sig;
    966             for (RMC = 0; RMC < 4; RMC++) {
    967                (*func)(-1, RMC);
    968                res = f18;
    969                printf("%s (RMC=%d, ref sig=%d) %s%016llx", test_def.name, RMC,
    970                       (int)reference_sig_vals[j], test_def.op, u0);
    971                if (test_def.precision == LONG_TEST) {
    972                   printf(" => %016llx\n",
    973                          *((unsigned long long *)(&res)));
    974                } else {
    975                   double resx = f19;
    976                   printf(" %016llx ==> %016llx %016llx\n",
    977                          u0x, *((unsigned long long *)(&res)), *((unsigned long long *)(&resx)));
    978                }
    979             }
    980          }
    981       }
    982       k++;
    983       printf( "\n" );
    984    }
    985 }
    986 
    987 
    988 static dfp_one_arg_test_t
    989 dfp_xiex_tests[] = {
    990                        { &_test_diex, "diex", LONG_TEST, ">>"},
    991                        { &_test_diexq, "diexq", QUAD_TEST, ">>"},
    992                        { &_test_dxex, "dxex", LONG_TEST, "<<"},
    993                        { &_test_dxexq, "dxexq", QUAD_TEST, "<<"},
    994                        { NULL, NULL, 0, NULL}
    995 };
    996 
    997 static void test_dfp_xiex_ops(void)
    998 {
    999    test_func_t func;
   1000    unsigned long long u0, u0x;
   1001    double res, d0, *d0p, d0x, *d0xp, target_exp, *target_exp_p;
   1002    /* The first two positions are placeholders and will be filled in later,
   1003     * based on the precision of the DFP argument.
   1004     */
   1005    long long target_exp_vals[] = {0ULL, 0ULL, 0ULL, -1ULL, -2ULL, -3ULL, -4ULL, -5ULL};
   1006    int num_exp_vals = sizeof(target_exp_vals)/sizeof(long long);
   1007    int k = 0;
   1008    u0 = u0x = 0;
   1009    d0p = &d0;
   1010    d0xp = &d0x;
   1011    target_exp_p = &target_exp;
   1012 
   1013    while ((func = dfp_xiex_tests[k].test_func)) {
   1014       int i;
   1015       Bool insert_insn = False;
   1016       dfp_one_arg_test_t test_def = dfp_xiex_tests[k];
   1017 
   1018       if (!strncmp(test_def.name, "di", 2))
   1019          insert_insn = True;
   1020 
   1021       if (test_def.precision == QUAD_TEST) {
   1022          target_exp_vals[0] = 12288ULL; // > max biased exponent
   1023          target_exp_vals[1] = 5235ULL;
   1024       } else {
   1025          target_exp_vals[0] = 768ULL; // > max biased exponent
   1026          target_exp_vals[1] = 355ULL;
   1027       }
   1028 
   1029       for (i = 0; i < NUM_DFP_VALS; i++) {
   1030          unsigned int j;
   1031 
   1032          if (test_def.precision == QUAD_TEST) {
   1033             u0 = dfp128_vals[i * 2];
   1034             u0x = dfp128_vals[(i * 2) + 1];
   1035          } else {
   1036             u0 = dfp64_vals[i];
   1037          }
   1038          *(unsigned long long *)d0p = u0;
   1039          f16 = d0;
   1040          if (test_def.precision == QUAD_TEST) {
   1041             *(unsigned long long *)d0xp = u0x;
   1042             f17 = d0x;
   1043          }
   1044 
   1045          if (!insert_insn) {
   1046             // This is just for extract insns (dexex[q])
   1047             (*func)(0, 0);
   1048             res = f18;
   1049             printf("%s %s ", test_def.name, test_def.op);
   1050             if (test_def.precision == LONG_TEST) {
   1051                printf("%016llx => %016llx\n", u0,
   1052                       *((unsigned long long *)(&res)));
   1053             } else {
   1054                double resx = f19;
   1055                printf("%016llx %016llx ==> %016llx %016llx\n", u0, u0x,
   1056                       *((unsigned long long *)(&res)), *((unsigned long long *)(&resx)));
   1057             }
   1058             continue;
   1059          }
   1060          // The following for-loop is just for insert insns (diex[q])
   1061          for (j = 0; j < num_exp_vals; j++) {
   1062             *(long long *)target_exp_p = target_exp_vals[j];
   1063             f14 = target_exp;
   1064             (*func)(0, 0);
   1065             res = f18;
   1066             printf("%s %s %5d, ", test_def.name, test_def.op, (int)target_exp_vals[j]);
   1067 
   1068             if (test_def.precision == LONG_TEST) {
   1069                printf("%016llx => %016llx\n", u0,
   1070                       *((unsigned long long *)(&res)));
   1071             } else {
   1072                double resx = f19;
   1073                printf("%016llx %016llx ==> %016llx %016llx\n", u0, u0x,
   1074                       *((unsigned long long *)(&res)), *((unsigned long long *)(&resx)));
   1075             }
   1076          }
   1077       }
   1078       k++;
   1079       printf( "\n" );
   1080    }
   1081 }
   1082 
   1083 static dfp_one_arg_test_t
   1084 dfp_rint_tests[] = {
   1085                     { &_test_drintn, "drintn", LONG_TEST, "~"},
   1086                     { &_test_drintnq, "drintnq", QUAD_TEST, "~"},
   1087                     { &_test_drintx, "drintx", LONG_TEST, "~"},
   1088                     { &_test_drintxq, "drintxq", QUAD_TEST, "~"},
   1089                     { NULL, NULL, 0, NULL}
   1090 };
   1091 
   1092 static void test_dfp_rint_ops(void)
   1093 {
   1094    test_func_t func;
   1095    unsigned long long u0, u0x;
   1096    double res, d0, *d0p, d0x, *d0xp;
   1097    int k = 0;
   1098    u0 = u0x = 0;
   1099    d0p = &d0;
   1100    d0xp = &d0x;
   1101 
   1102    while ((func = dfp_rint_tests[k].test_func)) {
   1103       int i;
   1104       dfp_one_arg_test_t test_def = dfp_rint_tests[k];
   1105 
   1106       for (i = 0; i < NUM_DFP_VALS; i++) {
   1107          int R, RMC;
   1108 
   1109          if (test_def.precision == LONG_TEST) {
   1110             u0 = dfp64_vals[i];
   1111          } else {
   1112             u0 = dfp128_vals[i * 2];
   1113             u0x = dfp128_vals[(i * 2) + 1];
   1114          }
   1115          *(unsigned long long *)d0p = u0;
   1116          f16 = d0;
   1117          if (test_def.precision == QUAD_TEST) {
   1118             *(unsigned long long *)d0xp = u0x;
   1119             f17 = d0x;
   1120          }
   1121 
   1122          for (R = 0; R < 2; R++) {
   1123             for (RMC = 0; RMC < 4; RMC++) {
   1124                (*func)(R, RMC);
   1125                res = f18;
   1126                printf("%s (RM=%d) %s%016llx", test_def.name, (RMC + (R << 2)), test_def.op, u0);
   1127                if (test_def.precision == LONG_TEST) {
   1128                   printf(" => %016llx\n",
   1129                          *((unsigned long long *)(&res)));
   1130                } else {
   1131                   double resx = f19;
   1132                   printf(" %016llx ==> %016llx %016llx\n",
   1133                          u0x, *((unsigned long long *)(&res)), *((unsigned long long *)(&resx)));
   1134                }
   1135             }
   1136          }
   1137       }
   1138       k++;
   1139       printf( "\n" );
   1140    }
   1141 }
   1142 
   1143 static dfp_test_t
   1144 dfp_cmp_tests[] = {
   1145                      { &_test_dcmpo, "dcmpo", dfp_2args_x1, 25, LONG_TEST, "<>"},
   1146                      { &_test_dcmpoq, "dcmpoq", dfp_2args_x1, 25, QUAD_TEST, "<>"},
   1147                      { &_test_dcmpu, "dcmpu", dfp_2args_x1, 25, LONG_TEST, "<>"},
   1148                      { &_test_dcmpuq, "dcmpuq", dfp_2args_x1, 25, QUAD_TEST, "<>"},
   1149                      { NULL, NULL, NULL, 0, 0, NULL}
   1150 };
   1151 
   1152 static void test_dfp_cmp_ops(void)
   1153 {
   1154    test_func_t func;
   1155    unsigned long long u0, u0x, u1, u1x;
   1156    double d0, d1, *d0p, *d1p;
   1157    double d0x, d1x, *d0xp, *d1xp;
   1158    /* BF is a 3-bit instruction field that indicates the CR field in which the
   1159     * result of the compare should be placed.  We won't iterate through all
   1160     * 8 possible BF values since storing compare results to a given field is
   1161     * a well-tested mechanism in VEX.  But we will test two BF values, just as
   1162     * a sniff-test.
   1163     */
   1164    int k = 0, BF;
   1165    u0x = u1x = 0;
   1166    d0p = &d0;
   1167    d0xp = &d0x;
   1168    d1p = &d1;
   1169    d1xp = &d1x;
   1170 
   1171    while ((func = dfp_cmp_tests[k].test_func)) {
   1172       int i, repeat = 1;
   1173       dfp_test_t test_def = dfp_cmp_tests[k];
   1174       BF = 0;
   1175 
   1176 again:
   1177       for (i = 0; i < test_def.num_tests; i++) {
   1178          unsigned int condreg;
   1179          unsigned int flags;
   1180 
   1181          if (test_def.precision == LONG_TEST) {
   1182             u0 = dfp64_vals[test_def.targs[i].fra_idx];
   1183             u1 = dfp64_vals[test_def.targs[i].frb_idx];
   1184          } else {
   1185             u0 = dfp128_vals[test_def.targs[i].fra_idx * 2];
   1186             u0x = dfp128_vals[(test_def.targs[i].fra_idx * 2) + 1];
   1187             u1 = dfp128_vals[test_def.targs[i].frb_idx * 2];
   1188             u1x = dfp128_vals[(test_def.targs[i].frb_idx * 2) + 1];
   1189          }
   1190          *(unsigned long long *)d0p = u0;
   1191          *(unsigned long long *)d1p = u1;
   1192          f14 = d0;
   1193          f16 = d1;
   1194          if (test_def.precision == QUAD_TEST) {
   1195             *(unsigned long long *)d0xp = u0x;
   1196             *(unsigned long long *)d1xp = u1x;
   1197             f15 = d0x;
   1198             f17 = d1x;
   1199          }
   1200 
   1201          SET_FPSCR_ZERO;
   1202          SET_CR_XER_ZERO;
   1203          (*func)(BF, 0);
   1204          GET_CR(flags);
   1205 
   1206          condreg = ((flags >> (4 * (7-BF)))) & 0xf;
   1207          printf("%s %016llx", test_def.name, u0);
   1208          if (test_def.precision == LONG_TEST) {
   1209             printf(" %s %016llx => %x (BF=%d)\n",
   1210                    test_def.op, u1, condreg, BF);
   1211          } else {
   1212             printf(" %016llx %s %016llx %016llx ==> %x (BF=%d)\n",
   1213                    u0x, test_def.op, u1, u1x,
   1214                    condreg, BF);
   1215          }
   1216       }
   1217       if (repeat) {
   1218          repeat = 0;
   1219          BF = 5;
   1220          goto again;
   1221       }
   1222       k++;
   1223       printf( "\n" );
   1224    }
   1225 }
   1226 
   1227 
   1228 static test_table_t
   1229          all_tests[] =
   1230 {
   1231                     { &test_dfp_cmp_ops,
   1232                       "Test DFP compare instructions"},
   1233                     { &test_dfp_rint_ops,
   1234                       "Test DFP round instructions"},
   1235                     { &test_dfp_xiex_ops,
   1236                       "Test DFP insert/extract instructions"},
   1237                     { &test_dfp_rrnd_ops,
   1238                       "Test DFP reround instructions"},
   1239                     { &test_dfp_qua_ops,
   1240                       "Test DFP quantize instructions"},
   1241                     { &test_dfp_quai_ops,
   1242                       "Test DFP quantize immediate instructions"},
   1243                     { NULL, NULL }
   1244 };
   1245 #endif // HAS_DFP
   1246 
   1247 int main() {
   1248 #if defined(HAS_DFP)
   1249 
   1250    test_table_t aTest;
   1251    test_driver_func_t func;
   1252    int i = 0;
   1253 
   1254    while ((func = all_tests[i].test_category)) {
   1255       aTest = all_tests[i];
   1256       printf( "%s\n", aTest.name );
   1257       (*func)();
   1258       i++;
   1259    }
   1260 
   1261 #endif // HAS_DFP
   1262    return 0;
   1263 }
   1264