Home | History | Annotate | Download | only in s390x
      1 #include <stdio.h>
      2 #include <stdint.h>
      3 #include "dfp_utils.h"
      4 
      5 /* Test various DFP ops:
      6    - extract biased exponent 64/128 bit
      7    - extract significance 64/128 bit
      8    - insert biased exponent 64/128 bit
      9    - load and test 64/128 bit
     10    - shift left/right 64/128 bit
     11    - reround 64/128 bit
     12 */
     13 
     14 void eedtr(_Decimal64 in)
     15 {
     16   long out;
     17   asm volatile(".insn rre, 0xb3e50000, %[out], %[in]\n\t"
     18                :[out] "=d" (out) :[in] "f" (in));
     19   printf("EEDTR ");
     20   DFP_VAL_PRINT(in, _Decimal64);
     21   printf(" -> %ld\n", out);
     22 }
     23 
     24 void eextr(_Decimal128 in)
     25 {
     26   long out;
     27   asm volatile(".insn rre, 0xb3ed0000, %[out], %[in]\n\t"
     28                :[out] "=d" (out) :[in] "f" (in));
     29   printf("EEXTR ");
     30   DFP_VAL_PRINT(in, _Decimal128);
     31   printf(" -> %ld\n", out);
     32 }
     33 
     34 void esdtr(_Decimal64 in)
     35 {
     36   long out;
     37   asm volatile(".insn rre, 0xb3e70000, %[out], %[in]\n\t"
     38                :[out] "=d" (out) :[in] "f" (in));
     39   printf("ESDTR ");
     40   DFP_VAL_PRINT(in, _Decimal64);
     41   printf(" -> %ld\n", out);
     42 }
     43 
     44 void esxtr(_Decimal128 in)
     45 {
     46   long out;
     47   asm volatile(".insn rre, 0xb3ef0000, %[out], %[in]\n\t"
     48                :[out] "=d" (out) :[in] "f" (in));
     49   printf("ESXTR ");
     50   DFP_VAL_PRINT(in, _Decimal128);
     51   printf(" -> %ld\n", out);
     52 }
     53 
     54 void iedtr(_Decimal64 in, long amount)
     55 {
     56   _Decimal64 out;
     57 
     58   asm volatile (".insn rrf, 0xb3f60000, %[out], %[amount], %[in], 0\n\t"
     59                 :[out]"=f"(out)
     60                 :[in]"f"(in), [amount]"d"(amount));
     61 
     62   printf("IEDTR ");
     63   DFP_VAL_PRINT(in, _Decimal64);
     64   printf(", %ld -> ", amount);
     65   DFP_VAL_PRINT(out, _Decimal64);
     66   printf("\n");
     67 }
     68 
     69 void iextr(_Decimal128 in, long amount)
     70 {
     71   _Decimal128 out;
     72 
     73   asm volatile (".insn rrf, 0xb3fe0000, %[out], %[amount], %[in], 0\n\t"
     74                 :[out]"=f"(out)
     75                 :[in]"f"(in), [amount]"d"(amount));
     76 
     77   printf("IEXTR ");
     78   DFP_VAL_PRINT(in, _Decimal128);
     79   printf(", %ld -> ", amount);
     80   DFP_VAL_PRINT(out, _Decimal128);
     81   printf("\n");
     82 }
     83 
     84 void ltdtr(_Decimal64 in)
     85 {
     86   _Decimal64 out;
     87   int cc;
     88   asm volatile(".insn rre, 0xb3d60000, %[out], %[in]\n\t"
     89                "ipm %1\n\t"
     90                "srl %1,28\n\t"
     91                :[out] "=d" (out), "=d" (cc)
     92                :[in] "f" (in));
     93   printf("LTDTR ");
     94   DFP_VAL_PRINT(in, _Decimal64);
     95   printf(" -> %d\n", cc);
     96 }
     97 
     98 void ltxtr(_Decimal128 in)
     99 {
    100   _Decimal128 out;
    101   int cc;
    102   asm volatile(".insn rre, 0xb3de0000, %[out], %[in]\n\t"
    103                "ipm %1\n\t"
    104                "srl %1,28\n\t"
    105                :[out] "=f" (out), "=d" (cc)
    106                :[in] "f" (in));
    107   printf("LTXTR ");
    108   DFP_VAL_PRINT(in, _Decimal128);
    109   printf(" -> %d\n", cc);
    110 }
    111 
    112 void qadtr(_Decimal64 op, _Decimal64 quan, uint8_t rm)
    113 {
    114   _Decimal64 out;
    115 
    116   asm volatile (
    117                 ".insn rrf, 0xb3f50000, %[out], %[quan], %[op], %[rm]\n\t"
    118                 :[out]"=f"(out)
    119                 :[op]"f"(op), [quan]"f"(quan), [rm]"d"(rm)
    120                 );
    121   printf("QADTR ");
    122   DFP_VAL_PRINT(op, _Decimal64);
    123   printf(", ");
    124   DFP_VAL_PRINT(quan, _Decimal64);
    125   printf(", %x -> ", rm);
    126   DFP_VAL_PRINT(out, _Decimal64);
    127   printf("\n");
    128 }
    129 
    130 void quantize64(_Decimal64 op, _Decimal64 quan)
    131 {
    132   uint8_t i;
    133 
    134   for (i = 0; i < 16; i++)
    135     qadtr(op, quan, i);
    136 }
    137 
    138 void qaxtr(_Decimal128 op, _Decimal128 quan, uint8_t rm)
    139 {
    140   _Decimal128 out;
    141 
    142   asm volatile (
    143                 ".insn rrf, 0xb3fd0000, %[out], %[quan], %[op], %[rm]\n\t"
    144                 :[out]"=f"(out)
    145                 :[op]"f"(op), [quan]"f"(quan), [rm]"d"(rm)
    146                 );
    147   printf("QAXTR ");
    148   DFP_VAL_PRINT(op, _Decimal128);
    149   printf(", ");
    150   DFP_VAL_PRINT(quan, _Decimal128);
    151   printf(", %x -> ", rm);
    152   DFP_VAL_PRINT(out, _Decimal128);
    153   printf("\n");
    154 }
    155 
    156 void quantize128(_Decimal128 op, _Decimal128 quan)
    157 {
    158   uint8_t i;
    159 
    160   for (i = 0; i < 16; i++)
    161     qaxtr(op, quan, i);
    162 }
    163 
    164 void rrdtr(_Decimal64 op, uint8_t sig, uint8_t rm)
    165 {
    166   _Decimal64 out;
    167 
    168   asm volatile (
    169                 ".insn rrf, 0xb3f70000, %[out], %[sig], %[op], %[rm]\n\t"
    170                 :[out]"=f"(out)
    171                 :[op]"f"(op), [sig]"d"(sig), [rm]"d"(rm)
    172                 );
    173   printf("RRDTR ");
    174   DFP_VAL_PRINT(op, _Decimal64);
    175   printf(", %d, %x -> ", sig, rm);
    176   DFP_VAL_PRINT(out, _Decimal64);
    177   printf("\n");
    178 }
    179 
    180 void reround64(_Decimal64 op, uint8_t sig)
    181 {
    182   uint8_t i;
    183 
    184   for (i = 0; i < 16; i++)
    185     rrdtr(op, sig, i);
    186 }
    187 
    188 void rrxtr(_Decimal128 op, uint8_t sig, uint8_t rm)
    189 {
    190   _Decimal128 out;
    191 
    192   asm volatile (
    193                 ".insn rrf, 0xb3ff0000, %[out], %[sig], %[op], %[rm]\n\t"
    194                 :[out]"=f"(out)
    195                 :[op]"f"(op), [sig]"d"(sig), [rm]"d"(rm)
    196                 );
    197   printf("RRXTR ");
    198   DFP_VAL_PRINT(op, _Decimal128);
    199   printf(", %d, %x -> ", sig, rm);
    200   DFP_VAL_PRINT(out, _Decimal128);
    201   printf("\n");
    202 }
    203 
    204 void reround128(_Decimal128 op, uint8_t sig)
    205 {
    206   uint8_t i;
    207 
    208   for (i = 0; i < 16; i++)
    209     rrxtr(op, sig, i);
    210 }
    211 
    212 void sldt(_Decimal64 in, unsigned long amount)
    213 {
    214   _Decimal64 out;
    215   int *shift = (int *) amount;
    216 
    217   asm volatile (".insn rxf, 0xed0000000040, %[out], %[in], 0(%[amount])\n\t"
    218                 :[out]"=f"(out)
    219                 :[in]"f"(in),[amount]"a"(shift));
    220 
    221   printf("SLDT ");
    222   DFP_VAL_PRINT(in, _Decimal64);
    223   printf(" -> ");
    224   DFP_VAL_PRINT(out, _Decimal64);
    225   printf("\n");
    226 }
    227 
    228 void slxt(_Decimal128 in, unsigned long amount)
    229 {
    230   _Decimal128 out;
    231   int *shift = (int *) amount;
    232 
    233   asm volatile (".insn rxf, 0xed0000000048, %[out], %[in], 0(%[amount])\n\t"
    234                 :[out]"=f"(out)
    235                 :[in]"f"(in),[amount]"a"(shift));
    236 
    237   printf("SLXT ");
    238   DFP_VAL_PRINT(in, _Decimal128);
    239   printf(" -> ");
    240   DFP_VAL_PRINT(out, _Decimal128);
    241   printf("\n");
    242 }
    243 
    244 void srdt(_Decimal64 in, unsigned long amount)
    245 {
    246   _Decimal64 out;
    247   int *shift = (int *) amount;
    248 
    249   asm volatile (".insn rxf, 0xed0000000041, %[out], %[in], 0(%[amount])\n\t"
    250                 :[out]"=f"(out)
    251                 :[in]"f"(in),[amount]"a"(shift));
    252 
    253   printf("SRDT ");
    254   DFP_VAL_PRINT(in, _Decimal64);
    255   printf(" -> ");
    256   DFP_VAL_PRINT(out, _Decimal64);
    257   printf("\n");
    258 }
    259 
    260 void srxt(_Decimal128 in, unsigned long amount)
    261 {
    262   _Decimal128 out;
    263   int *shift = (int *) amount;
    264 
    265   asm volatile (".insn rxf, 0xed0000000049, %[out], %[in], 0(%[amount])\n\t"
    266                 :[out]"=f"(out)
    267                 :[in]"f"(in),[amount]"a"(shift));
    268 
    269   printf("SRXT ");
    270   DFP_VAL_PRINT(in, _Decimal128);
    271   printf(" -> ");
    272   DFP_VAL_PRINT(out, _Decimal128);
    273   printf("\n");
    274 }
    275 
    276 int main() {
    277   _Decimal64 d64 = 50.0005DD;
    278   _Decimal128 d128 = 50.0005DL;
    279 
    280   eedtr(d64);
    281   eedtr(-d64);
    282   eedtr(0.DD);
    283   eextr(d128);
    284   eextr(-d128);
    285   eextr(0.DL);
    286 
    287   esdtr(d64);
    288   esdtr(-d64);
    289   esdtr(0.DD);
    290   esxtr(d128);
    291   esxtr(-d128);
    292   esxtr(0.DL);
    293 
    294   ltdtr(d64);
    295   ltdtr(-d64);
    296   ltdtr(0.0DD);
    297   ltxtr(d128);
    298   ltxtr(-d128);
    299   ltxtr(0.0DL);
    300 
    301   d64 = 12345678.54321DD;
    302   sldt(d64, 10);
    303   sldt(-d64, 2);
    304   sldt(0.DD, 2);
    305   sldt(-0.DD, 2);
    306 
    307   srdt(d64, 5);
    308   srdt(-d64, 2);
    309   srdt(0.DD, 2);
    310   srdt(-0.DD, 2);
    311 
    312   d128 = 12345678.54321DL;
    313   slxt(d128, 10);
    314   slxt(-d128, 2);
    315   slxt(0.DL, 2);
    316   slxt(-0.DL, 2);
    317 
    318   srxt(d128, 10);
    319   srxt(-d128, 2);
    320   srxt(0.DL, 2);
    321   srxt(-0.DL, 2);
    322 
    323   d64 = 5.000005DD;
    324   iedtr(d64, 391);
    325   iedtr(d64, 392);
    326   iedtr(d64, 393);
    327   iedtr(-d64, 391);
    328   iedtr(-d64, 392);
    329   iedtr(-d64, 393);
    330   iedtr(0.DD, 393);
    331   iedtr(-0.DD, 393);
    332   iedtr(1.DD, 393);
    333 
    334   d128 = 5.000005DL;
    335   iextr(d128, 6169);
    336   iextr(d128, 6170);
    337   iextr(d128, 6171);
    338   iextr(-d128, 6169);
    339   iextr(-d128, 6170);
    340   iextr(-d128, 6171);
    341   iextr(0.DL, 6171);
    342   iextr(-0.DL, 6171);
    343   iextr(1.DL, 6171);
    344 
    345   d64 = 2.171234DD;
    346   quantize64(d64, 0.001DD);
    347   quantize64(-d64, 0.001DD);
    348   quantize64(-d64, 0.DD);
    349   quantize64(0.DD, 0.001DD);
    350 
    351   d128 = 26365343648.171234DL;
    352   quantize128(d128, 230.01DL);
    353   quantize128(-d128, 230.01DL);
    354   quantize128(d128, 0.DL);
    355   quantize128(-0.DL, 230.01DL);
    356 
    357   d64 = 2.174598DD;
    358   reround64(d64, 3);
    359   reround64(d64, 4);
    360   reround64(d64, 5);
    361   reround64(-d64, 3);
    362   reround64(-d64, 4);
    363   reround64(-d64, 5);
    364   reround64(0.DD, 0);
    365 
    366   d128 = 2.174598DL;
    367   reround128(d128, 3);
    368   reround128(d128, 4);
    369   reround128(d128, 5);
    370   reround128(-d128, 3);
    371   reround128(-d128, 4);
    372   reround128(-d128, 5);
    373   reround128(0.DL, 0);
    374 
    375   return 0;
    376 }
    377