1663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Copyright (C) 2012 IBM 2663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Author: Maynard Johnson <maynardj@us.ibm.com> 4663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 5663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng This program is free software; you can redistribute it and/or 6663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng modify it under the terms of the GNU General Public License as 7663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng published by the Free Software Foundation; either version 2 of the 8663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng License, or (at your option) any later version. 9663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 10663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng This program is distributed in the hope that it will be useful, but 11663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng WITHOUT ANY WARRANTY; without even the implied warranty of 12663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng General Public License for more details. 14663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 15663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng You should have received a copy of the GNU General Public License 16663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng along with this program; if not, write to the Free Software 17663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 02111-1307, USA. 19663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 20663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng The GNU General Public License is contained in the file COPYING. 21663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 22663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 23663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <stdio.h> 24663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <stdlib.h> 25663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <stdint.h> 26663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 27663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(HAS_DFP) 28663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 29663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengregister double f14 __asm__ ("fr14"); 30663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengregister double f15 __asm__ ("fr15"); 31663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengregister double f16 __asm__ ("fr16"); 32663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengregister double f17 __asm__ ("fr17"); 33663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengregister double f18 __asm__ ("fr18"); 34663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengregister double f19 __asm__ ("fr19"); 35663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 36663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 37663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef unsigned char Bool; 38663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define True 1 39663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define False 0 40663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 41663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 42663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7" 43663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 44663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SET_CR(_arg) \ 45663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("mtcr %0" : : "b"(_arg) : ALLCR ); 46663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 47663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SET_XER(_arg) \ 48663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("mtxer %0" : : "b"(_arg) : "xer" ); 49663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 50663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define GET_CR(_lval) \ 51663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("mfcr %0" : "=b"(_lval) ) 52663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 53663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define GET_XER(_lval) \ 54663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) ) 55663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 56663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define GET_CR_XER(_lval_cr,_lval_xer) \ 57663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { GET_CR(_lval_cr); GET_XER(_lval_xer); } while (0) 58663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 59663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SET_CR_ZERO \ 60663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_CR(0) 61663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 62663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SET_XER_ZERO \ 63663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_XER(0) 64663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 65663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SET_CR_XER_ZERO \ 66663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { SET_CR_ZERO; SET_XER_ZERO; } while (0) 67663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 68663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SET_FPSCR_ZERO \ 69663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do { double _d = 0.0; \ 70663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("mtfsf 0xFF, %0" : : "f"(_d) ); \ 71663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } while (0) 72663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 73663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define GET_FPSCR(_arg) \ 74663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("mffs %0" : "=f"(_arg) ) 75663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 76663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SET_FPSCR_DRN \ 77663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("mtfsf 1, %0, 0, 1" : : "f"(f14) ) 78663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 79663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 80663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// The assembly-level instructions being tested 81663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool do_dot; 82663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_dadd (void) 83663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 84663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (do_dot) 85663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("dadd. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 86663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 87663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("dadd %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 88663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 89663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 90663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_dsub (void) 91663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 92663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (do_dot) 93663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("dsub. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 94663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 95663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("dsub %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 96663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 97663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 98663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_dmul (void) 99663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (do_dot) 101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("dmul. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("dmul %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_ddiv (void) 107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (do_dot) 109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("ddiv. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("ddiv %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// Quad DFP arith instructions 115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_daddq (void) 116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (do_dot) 118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("daddq. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("daddq %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_dsubq (void) 124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (do_dot) 126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("dsubq. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("dsubq %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_dmulq (void) 132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (do_dot) 134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("dmulq. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("dmulq %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_ddivq (void) 140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 141663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (do_dot) 142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("ddivq. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 143663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 144663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("ddivq %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16)); 145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_mffs (void) 148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("mffs %0" : "=f"(f14)); 150663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 151663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_mtfsf (int upper) 153663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 154663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (upper) 155663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("mtfsf 1, %0, 0, 1" : : "f"(f14) ); 156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 157663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("mtfsf 1, %0, 0, 0" : : "f"(f14) ); 158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 159663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef void (*test_func_t)(void); 161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef struct test_table 162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng test_func_t test_category; 164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng char * name; 165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} test_table_t; 166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* 168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * 345.0DD (0x2207c00000000000 0xe50) 169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * 1.2300e+5DD (0x2207c00000000000 0x14c000) 170663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * -16.0DD (0xa207c00000000000 0xe0) 171663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * 0.00189DD (0x2206c00000000000 0xcf) 172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * -4.1235DD (0xa205c00000000000 0x10a395bcf) 173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * 9.8399e+20DD (0x2209400000000000 0x253f1f534acdd4) 174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * 0DD (0x2208000000000000 0x0) 175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * 0DD (0x2208000000000000 0x0) 176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * infDD (0x7800000000000000 0x0) 177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * nanDD (0x7c00000000000000 0x0 178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic unsigned long long dfp128_vals[] = { 180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // Some finite numbers 181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x2207c00000000000ULL, 0x0000000000000e50ULL, 182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x2207c00000000000ULL, 0x000000000014c000ULL, 183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xa207c00000000000ULL, 0x00000000000000e0ULL, 184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x2206c00000000000ULL, 0x00000000000000cfULL, 185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xa205c00000000000ULL, 0x000000010a395bcfULL, 186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x6209400000fd0000ULL, 0x00253f1f534acdd4ULL, // huge number 187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x000400000089b000ULL, 0x0a6000d000000049ULL, // very small number 188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // flavors of zero 189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x2208000000000000ULL, 0x0000000000000000ULL, 190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xa208000000000000ULL, 0x0000000000000000ULL, // negative 191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xa248000000000000ULL, 0x0000000000000000ULL, 192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // flavors of NAN 193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x7c00000000000000ULL, 0x0000000000000000ULL, // quiet 194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xfc00000000000000ULL, 0xc00100035b007700ULL, 195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x7e00000000000000ULL, 0xfe000000d0e0a0d0ULL, // signaling 196663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // flavors of Infinity 197663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x7800000000000000ULL, 0x0000000000000000ULL, 198663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xf800000000000000ULL, 0x0000000000000000ULL, // negative 199663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xf900000000000000ULL, 0x0000000000000000ULL 200663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}; 201663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 202663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic unsigned long long dfp64_vals[] = { 203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // various finite numbers 204663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x2234000000000e50ULL, 205663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x223400000014c000ULL, 206663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xa2340000000000e0ULL,// negative 207663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x22240000000000cfULL, 208663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xa21400010a395bcfULL,// negative 209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x6e4d3f1f534acdd4ULL,// huge number 210663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x000400000089b000ULL,// very small number 211663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // flavors of zero 212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x2238000000000000ULL, 213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xa238000000000000ULL, 214663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x4248000000000000ULL, 215663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // flavors of NAN 216663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x7e34000000000111ULL, 217663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xfe000000d0e0a0d0ULL,//signaling 218663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xfc00000000000000ULL,//quiet 219663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // flavors of Infinity 220663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x7800000000000000ULL, 221663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0xf800000000000000ULL,//negative 222663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 0x7a34000000000000ULL, 223663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}; 224663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 225663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 226663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef struct dfp_test_args { 227663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int fra_idx; 228663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int frb_idx; 229663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} dfp_test_args_t; 230663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 231663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// Index pairs from dfp64_vals or dfp128_vals array to be used with dfp_two_arg_tests 233663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic dfp_test_args_t dfp_2args_x2[] = { 234663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {0, 1}, 235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {2, 1}, 236663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {3, 4}, 237663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {0, 6}, 238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {2, 4}, 239663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {5, 1}, 240663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {5, 2}, 241663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {7, 8}, 242663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {7, 1}, 243663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {9, 15}, 244663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {8, 12}, 245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {7, 11}, 246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {13, 2}, 247663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {13, 14}, 248663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {15, 12}, 249663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {14, 11}, 250663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {12, 12}, 251663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {12, 11}, 252663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {11, 11} 253663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}; 254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 255663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// Index pairs from dfp64_vals array to be used with dfp_two_arg_tests 256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic dfp_test_args_t dfp_2args_x1[] = { 257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {0, 1}, 258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {2, 1}, 259663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {3, 4}, 260663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {0, 6}, 261663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {2, 4}, 262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {5, 1}, 263663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {5, 2}, 264663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {7, 1}, 265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {7, 2}, 266663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {8, 0}, 267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {8, 1}, 268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {8, 2}, 269663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {7, 8}, 270663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {12, 14}, 271663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {12, 1}, 272663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {12, 13}, 273663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {12, 12}, 274663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {12, 11}, 275663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {11, 14}, 276663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {11, 0}, 277663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {11, 13}, 278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {11, 11}, 279663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {14, 14}, 280663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {14, 3}, 281663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng {14, 15}, 282663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}; 283663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 284663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef enum { 285663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng LONG_TEST, 286663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng QUAD_TEST 287663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} precision_type_t; 288663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 289663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef struct dfp_test 290663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 291663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng test_func_t test_func; 292663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng const char * name; 293663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dfp_test_args_t * targs; 294663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int num_tests; 295663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng precision_type_t precision; 296663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng const char * op; 297663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool cr_supported; 298663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} dfp_test_t; 299663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 301663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic dfp_test_t 302663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengdfp_two_arg_tests[] = { 303663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { &_test_dadd, "dadd", dfp_2args_x1, 25, LONG_TEST, "+", False}, 304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { &_test_dsub, "dsub", dfp_2args_x1, 25, LONG_TEST, "-", False}, 305663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { &_test_dmul, "dmul", dfp_2args_x2, 19, LONG_TEST, "*", False}, 306663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { &_test_ddiv, "ddiv", dfp_2args_x2, 19, LONG_TEST, "/", False}, 307663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { &_test_daddq, "daddq", dfp_2args_x1, 25, QUAD_TEST, "+", False}, 308663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { &_test_dsubq, "dsubq", dfp_2args_x1, 25, QUAD_TEST, "-", False}, 309663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { &_test_dmulq, "dmulq", dfp_2args_x2, 19, QUAD_TEST, "*", False}, 310663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { &_test_ddivq, "ddivq", dfp_2args_x2, 19, QUAD_TEST, "/", False}, 311663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { NULL, NULL, NULL, 0, 0, NULL} 312663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}; 313663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 314663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void test_dfp_two_arg_ops(void) 315663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 316663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng test_func_t func; 317663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng unsigned long long u0, u0x, u1, u1x; 318663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng double res, d0, d1, *d0p, *d1p; 319663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng double d0x, d1x, *d0xp, *d1xp; 320663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int k = 0; 321663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng u0x = u1x = 0; 322663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng d0p = &d0; 323663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng d0xp = &d0x; 324663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng d1p = &d1; 325663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng d1xp = &d1x; 326663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 327663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng while ((func = dfp_two_arg_tests[k].test_func)) { 328663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int i, repeat = 1; 329663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dfp_test_t test_group = dfp_two_arg_tests[k]; 330663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do_dot = False; 331663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 332663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengagain: 333663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < test_group.num_tests; i++) { 334663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng unsigned int condreg; 335663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng unsigned int flags; 336663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 337663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (test_group.precision == LONG_TEST) { 338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng u0 = dfp64_vals[test_group.targs[i].fra_idx]; 339663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng u1 = dfp64_vals[test_group.targs[i].frb_idx]; 340663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 341663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng u0 = dfp128_vals[test_group.targs[i].fra_idx * 2]; 342663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng u0x = dfp128_vals[(test_group.targs[i].fra_idx * 2) + 1]; 343663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng u1 = dfp128_vals[test_group.targs[i].frb_idx * 2]; 344663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng u1x = dfp128_vals[(test_group.targs[i].frb_idx * 2) + 1]; 345663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 346663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *(unsigned long long *)d0p = u0; 347663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *(unsigned long long *)d1p = u1; 348663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng f14 = d0; 349663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng f16 = d1; 350663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (test_group.precision == QUAD_TEST) { 351663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *(unsigned long long *)d0xp = u0x; 352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *(unsigned long long *)d1xp = u1x; 353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng f15 = d0x; 354663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng f17 = d1x; 355663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 356663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 357663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_FPSCR_ZERO; 358663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_CR_XER_ZERO; 359663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (*func)(); 360663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng GET_CR(flags); 361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng res = f18; 362663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 363663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng condreg = (flags & 0x000000f0) >> 4; 364663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("%s%s %016llx", test_group.name, do_dot? "." : "", u0); 365663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (test_group.precision == LONG_TEST) { 366663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf(" %s %016llx => %016llx", 367663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng test_group.op, u1, *((unsigned long long *)(&res))); 368663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 369663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng double resx = f19; 370663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf(" %016llx %s %016llx %016llx ==> %016llx %016llx", 371663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng u0x, test_group.op, u1, u1x, 372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *((unsigned long long *)(&res)), *((unsigned long long *)(&resx))); 373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 374663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (test_group.cr_supported) 375663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf(" (cr = %08x)\n", condreg); 376663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 377663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("\n"); 378663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 379663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 380663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("\n"); 381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (repeat) { 382663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng repeat = 0; 383663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do_dot = True; 384663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto again; 385663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 386663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng k++; 387663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf( "\n" ); 388663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 390663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 391663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid test_move_toFrom_fpscr(void) 392663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 393663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define BFP_MAX_RM 3 394663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int shift = 0; 395663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng unsigned long long i, max_rm, expected_val; 396663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng double fpscr_in, fpscr_out; 397663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng unsigned long long * hex_fpscr_in = (unsigned long long *)&fpscr_in; 398663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng unsigned long long * hex_fpscr_out = (unsigned long long *)&fpscr_out; 399663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 400663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 401663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng max_rm = 4; 402663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengagain: 403663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* NOTE: The first time through this loop is for setting the binary 404663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * floating point rounding mode (bits 62:63 of FPSCR). The second time 405663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * through is for setting the decimal floating point rounding mode 406663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * (bits 29:31 of FPSCR). In the second time through this loop, the value 407663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * returned should include the final binary FP rounding mode, along with 408663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * the decimal FP rounding modes. 409663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 410663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < max_rm; i++) { 411663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *hex_fpscr_in = (i << shift); 412663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng f14 = fpscr_in; 413663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _test_mtfsf(max_rm/8); 414663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *hex_fpscr_in = 0ULL; 415663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng f14= fpscr_in; 416663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _test_mffs(); 417663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fpscr_out = f14; 418663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (max_rm == 4) { 419663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *hex_fpscr_out &= (max_rm - 1) << shift; 420663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng expected_val = i << shift; 421663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 422663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *hex_fpscr_out &= BFP_MAX_RM | ((max_rm - 1) << shift); 423663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng expected_val = (i << shift) | BFP_MAX_RM; 424663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 425663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 426663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("FPSCR %s floating point rounding mode %016llx == %016llx? %s\n", 427663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (max_rm == 8) ? "decimal" : "binary", 428663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *hex_fpscr_out, expected_val, 429663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (expected_val == *hex_fpscr_out) ? "yes" : "no"); 430663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (max_rm == 4) { 432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng max_rm = 8; 433663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng shift = 32; 434663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto again; 435663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 436663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid test_rounding_modes(void) 439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 440663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int j; 441663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng unsigned long long u0, u1, rm_idx; 442663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng double res, d0, d1, *d0p, *d1p, fpscr; 443663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng unsigned long long * hex_fpscr = (unsigned long long *)&fpscr; 444663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng u0 = 0x26cc3f1f534acdd4ULL; 445663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng u1 = 0x27feff197a42ba06ULL; 446663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng d0p = &d0; 447663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng d1p = &d1; 448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (j = 0; j < 12; j++) { 450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (rm_idx = 0; rm_idx < 8; rm_idx++) { 451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *hex_fpscr = 0ULL; 452663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__ ("mffs %0" : "=f"(f14)); 453663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fpscr = f14; 454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *hex_fpscr &= 0xFFFFFFF0FFFFFFFFULL; 455663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *hex_fpscr |= (rm_idx << 32); 456663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng f14 = fpscr; 457663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SET_FPSCR_DRN; 458663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *(unsigned long long *)d0p = u0; 459663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *(unsigned long long *)d1p = u1; 460663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng f14 = d0; 461663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng f16 = d1; 462663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _test_dmul(); 463663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng res = f18; 464663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("test #%d: dmul with rounding mode %d: %016llx * %016llx => %016llx\n", 465663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng j, (int)rm_idx, u0, u1, *((unsigned long long *)(&res))); 466663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("\n"); 467663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 468663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // Changing the least significant bit of one of the dmul arguments give us more 469663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // opportunities for different rounding modes to yield different results which 470663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // can then be validated. 471663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng u0++; 472663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 473663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 474663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 475663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic test_table_t 476663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng all_tests[] = 477663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 478663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { &test_dfp_two_arg_ops, 479663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "Test DFP arithmetic instructions"}, 480663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { &test_rounding_modes, 481663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "Test DFP rounding modes"}, 482663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { &test_move_toFrom_fpscr, 483663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "Test move to/from FPSCR"}, 484663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { NULL, NULL } 485663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}; 486663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif // HAS_DFP 487663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 488663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint main() { 489663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(HAS_DFP) 490663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 491663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng test_table_t aTest; 492663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng test_func_t func; 493663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int i = 0; 494663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 495663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng while ((func = all_tests[i].test_category)) { 496663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aTest = all_tests[i]; 497663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf( "%s\n", aTest.name ); 498663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (*func)(); 499663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng i++; 500663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 501663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 502663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif // HAS_DFP 503663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return 0; 504663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 505