1a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes/* Copyright (C) 2012 IBM 2a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 3a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes Author: Maynard Johnson <maynardj@us.ibm.com> 4a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 5a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes This program is free software; you can redistribute it and/or 6a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes modify it under the terms of the GNU General Public License as 7a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes published by the Free Software Foundation; either version 2 of the 8a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes License, or (at your option) any later version. 9a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 10a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes This program is distributed in the hope that it will be useful, but 11a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes WITHOUT ANY WARRANTY; without even the implied warranty of 12a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes General Public License for more details. 14a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 15a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes You should have received a copy of the GNU General Public License 16a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes along with this program; if not, write to the Free Software 17a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 02111-1307, USA. 19a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 20a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes The GNU General Public License is contained in the file COPYING. 21a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes */ 22a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 23a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#include <stdio.h> 24a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#include <stdlib.h> 25a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#include <stdint.h> 26a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 27a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#if defined(HAS_DFP) 28a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 29a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef union stuff { 30a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes _Decimal64 dec_val; 31a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes _Decimal128 dec_val128; 32a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes unsigned long long u64_val; 33a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes struct { 34a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#if defined(VGP_ppc64le_linux) 35a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes unsigned long long vall; 36a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes unsigned long long valu; 37a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#else 38a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes unsigned long long valu; 39a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes unsigned long long vall; 40a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#endif 41a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } u128; 42a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} dfp_val_t; 43a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 44a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 45a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef unsigned char Bool; 46a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define True 1 47a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define False 0 48a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 49a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 50a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7" 51a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 52a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define SET_CR(_arg) \ 53a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("mtcr %0" : : "b"(_arg) : ALLCR ); 54a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 55a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define SET_XER(_arg) \ 56a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("mtxer %0" : : "b"(_arg) : "xer" ); 57a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 58a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define GET_CR(_lval) \ 59a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("mfcr %0" : "=b"(_lval) ) 60a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 61a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define GET_XER(_lval) \ 62a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) ) 63a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 64a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define GET_CR_XER(_lval_cr,_lval_xer) \ 65a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes do { GET_CR(_lval_cr); GET_XER(_lval_xer); } while (0) 66a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 67a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define SET_CR_ZERO \ 68a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes SET_CR(0) 69a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 70a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define SET_XER_ZERO \ 71a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes SET_XER(0) 72a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 73a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define SET_CR_XER_ZERO \ 74a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes do { SET_CR_ZERO; SET_XER_ZERO; } while (0) 75a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 76a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define SET_FPSCR_ZERO \ 77a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes do { double _d = 0.0; \ 78a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("mtfsf 0xFF, %0" : : "f"(_d) ); \ 79a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } while (0) 80a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 81a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define GET_FPSCR(_arg) \ 82a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("mffs %0" : "=f"(_arg) ) 83a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 84a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define SET_FPSCR_DRN \ 85a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("mtfsf 1, %0, 0, 1" : : "f"(f14) ) 86a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 87a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#ifndef __powerpc64__ 88a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef uint32_t HWord_t; 89a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#else 90a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef uint64_t HWord_t; 91a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#endif /* __powerpc64__ */ 92a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 93a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesenum BF_vals { BF_val1 = 0, BF_val2 = 1, BF_val3 =6}; 94a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 95a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// The assembly-level instructions being tested 96a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic void _test_dtstsf(unsigned int BF, unsigned int ref_sig, dfp_val_t *valB) 97a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 98a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes _Decimal64 f16 = valB->dec_val; 99a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes register HWord_t r14 __asm__ ("r14"); 100a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes double f14; 101a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes r14 = (HWord_t)&ref_sig; 102a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 103a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm __volatile__ ("lfiwax %0, 0, %1" : "=f" (f14): "r" (r14)); 104a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes switch (BF) { 105a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case BF_val1: 106a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("dtstsf %0, %1, %2" : : "i" (BF_val1), "f" (f14), "f" (f16)); 107a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 108a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case BF_val2: 109a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("dtstsf %0, %1, %2" : : "i" (BF_val2), "f" (f14), "f" (f16)); 110a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 111a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case BF_val3: 112a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("dtstsf %0, %1, %2" : : "i" (BF_val3), "f" (f14), "f" (f16)); 113a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 114a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes default: 115a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes fprintf(stderr, "Invalid value %d for BF\n", BF); 116a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 117a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 118a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} 119a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 120a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic void _test_dtstsfq(unsigned int BF, unsigned int ref_sig, dfp_val_t *valB) 121a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 122a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes _Decimal128 f16 = valB->dec_val128; 123a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes register HWord_t r14 __asm__ ("r14"); 124a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes double f14; 125a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes r14 = (HWord_t)&ref_sig; 126a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 127a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm __volatile__ ("lfiwax %0, 0, %1" : "=f" (f14): "r" (r14)); 128a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes switch (BF) { 129a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case BF_val1: 130a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("dtstsfq %0, %1, %2" : : "i" (BF_val1), "f" (f14), "f" (f16)); 131a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 132a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case BF_val2: 133a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("dtstsfq %0, %1, %2" : : "i" (BF_val2), "f" (f14), "f" (f16)); 134a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 135a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case BF_val3: 136a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("dtstsfq %0, %1, %2" : : "i" (BF_val3), "f" (f14), "f" (f16)); 137a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 138a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes default: 139a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes fprintf(stderr, "Invalid value %d for BF\n", BF); 140a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 141a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 142a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} 143a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 144a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic dfp_val_t _test_ddedpd(unsigned int SP, dfp_val_t *valB) 145a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 146a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes _Decimal64 ret = 0; 147a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes dfp_val_t result; 148a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes _Decimal64 f16 = valB->dec_val; 149a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes switch (SP) { 150a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case 0: 151a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("ddedpd. 0, %0, %1" : "=f" (ret) : "f" (f16)); 152a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 153a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case 1: 154a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("ddedpd. 1, %0, %1" : "=f" (ret) : "f" (f16)); 155a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 156a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case 2: 157a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("ddedpd. 2, %0, %1" : "=f" (ret) : "f" (f16)); 158a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 159a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case 3: 160a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("ddedpd. 3, %0, %1" : "=f" (ret) : "f" (f16)); 161a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 162a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes default: 163a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes fprintf(stderr, "Invalid value %d for SP\n", SP); 164a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 165a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 166a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes result.dec_val = ret; 167a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes return result; 168a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} 169a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 170a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 171a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic dfp_val_t _test_ddedpdq(unsigned int SP, dfp_val_t *valB) 172a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 173a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes _Decimal128 ret = 0; 174a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes dfp_val_t result; 175a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes _Decimal128 f16 = valB->dec_val128; 176a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes switch (SP) { 177a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case 0: 178a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("ddedpdq 0, %0, %1" : "=f" (ret) : "f" (f16)); 179a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 180a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case 1: 181a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("ddedpdq 1, %0, %1" : "=f" (ret) : "f" (f16)); 182a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 183a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case 2: 184a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("ddedpdq 2, %0, %1" : "=f" (ret) : "f" (f16)); 185a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 186a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case 3: 187a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("ddedpdq 3, %0, %1" : "=f" (ret) : "f" (f16)); 188a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 189a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes default: 190a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes fprintf(stderr, "Invalid value %d for SP\n", SP); 191a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 192a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 193a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes result.dec_val128 = ret; 194a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes return result; 195a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} 196a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 197a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic dfp_val_t _test_denbcd(unsigned int S, dfp_val_t *valB) 198a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 199a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes _Decimal64 ret = 0; 200a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes dfp_val_t result; 201a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes _Decimal64 f16 = valB->dec_val; 202a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes switch (S) { 203a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case 0: 204a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("denbcd. 0, %0, %1" : "=f" (ret) : "f" (f16)); 205a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 206a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case 1: 207a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("denbcd. 1, %0, %1" : "=f" (ret) : "f" (f16)); 208a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 209a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes default: 210a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes fprintf(stderr, "Invalid value %d for S\n", S); 211a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 212a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 213a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes result.dec_val = ret; 214a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes return result; 215a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} 216a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 217a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 218a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic dfp_val_t _test_denbcdq(unsigned int S, dfp_val_t *valB) 219a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 220a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes _Decimal128 ret = 0; 221a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes dfp_val_t result; 222a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes _Decimal128 f16 = valB->dec_val128; 223a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes switch (S) { 224a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case 0: 225a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("denbcdq 0, %0, %1" : "=f" (ret) : "f" (f16)); 226a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 227a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case 1: 228a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__ ("denbcdq 1, %0, %1" : "=f" (ret) : "f" (f16)); 229a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 230a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes default: 231a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes fprintf(stderr, "Invalid value %d for S\n", S); 232a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes break; 233a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 234a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes result.dec_val128 = ret; 235a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes return result; 236a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} 237a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 238a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 239a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef void (*test_funcp_t)(unsigned int imm, unsigned int imm2, dfp_val_t *valB); 240a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef dfp_val_t (*test_func_bcdp_t)(unsigned int imm, dfp_val_t *valB); 241a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef void (*test_driver_func_t)(void); 242a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef struct test_table 243a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 244a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_driver_func_t test_category; 245a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes char * name; 246a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} test_table_t; 247a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 248a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes/* 249a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * 345.0DD (0x2207c00000000000 0xe50) 250a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * 1.2300e+5DD (0x2207c00000000000 0x14c000) 251a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * -16.0DD (0xa207c00000000000 0xe0) 252a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * 0.00189DD (0x2206c00000000000 0xcf) 253a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * -4.1235DD (0xa205c00000000000 0x10a395bcf) 254a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * 9.8399e+20DD (0x2209400000000000 0x253f1f534acdd4) 255a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * 0DD (0x2208000000000000 0x0) 256a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * 0DD (0x2208000000000000 0x0) 257a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * infDD (0x7800000000000000 0x0) 258a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * nanDD (0x7c00000000000000 0x0 259a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes */ 260a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic unsigned long long dfp128_vals[] = { 261a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes // Some finite numbers 262a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x2207c00000000000ULL, 0x0000000000000e50ULL, 263a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x2207c00000000000ULL, 0x000000000014c000ULL, 264a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0xa207c00000000000ULL, 0x00000000000000e0ULL, 265a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x2206c00000000000ULL, 0x00000000000000cfULL, 266a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0xa205c00000000000ULL, 0x000000010a395bcfULL, 267a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x6209400000fd0000ULL, 0x00253f1f534acdd4ULL, // huge number 268a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000400000089b000ULL, 0x0a6000d000000049ULL, // very small number 269a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes // flavors of zero 270a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x2208000000000000ULL, 0x0000000000000000ULL, 271a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0xa208000000000000ULL, 0x0000000000000000ULL, // negative 272a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0xa248000000000000ULL, 0x0000000000000000ULL, 273a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes // flavors of NAN 274a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x7c00000000000000ULL, 0x0000000000000000ULL, // quiet 275a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0xfc00000000000000ULL, 0xc00100035b007700ULL, 276a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x7e00000000000000ULL, 0xfe000000d0e0a0d0ULL, // signaling 277a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes // flavors of Infinity 278a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x7800000000000000ULL, 0x0000000000000000ULL, 279a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0xf800000000000000ULL, 0x0000000000000000ULL, // negative 280a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0xf900000000000000ULL, 0x0000000000000000ULL 281a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes}; 282a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 283a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic unsigned long long dfp64_vals[] = { 284a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes // various finite numbers 285a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x2234000000000e50ULL, 286a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x223400000014c000ULL, 287a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0xa2340000000000e0ULL,// negative 288a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x22240000000000cfULL, 289a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0xa21400010a395bcfULL,// negative 290a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x6e4d3f1f534acdd4ULL,// huge number 291a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000400000089b000ULL,// very small number 292a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes // flavors of zero 293a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x2238000000000000ULL, 294a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0xa238000000000000ULL, 295a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x4248000000000000ULL, 296a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes // flavors of NAN 297a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x7e34000000000111ULL, 298a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0xfe000000d0e0a0d0ULL,//signaling 299a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0xfc00000000000000ULL,//quiet 300a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes // flavors of Infinity 301a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x7800000000000000ULL, 302a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0xf800000000000000ULL,//negative 303a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x7a34000000000000ULL, 304a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes}; 305a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 306a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes/* The bcd64_vals and bdc128_vals hold the unique results of executing 307a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * the ddedpd instruction on the basic dfp64 and dfp128 array values. 308a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * Executing the inverse operation (denbcd) on these values with the 309a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * appropriate S (signed) value should yield values approximating the 310a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * original dfp values (except being 2^4 in magnitude since the decoding 311a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * operation shifted the value one hex digit to the left to make room 312a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * for signedness info). 313a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes */ 314a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic unsigned long long bcd64_vals[] = { 315a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000003450ULL, 316a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000000000003450cULL, 317a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000000000003450fULL, 318a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000001230000ULL, 319a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000000001230000cULL, 320a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000000001230000fULL, 321a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000160ULL, 322a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000000000000160dULL, 323a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000189ULL, 324a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000000000000189cULL, 325a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000000000000189fULL, 326a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000004123456789ULL, 327a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000004123456789dULL, 328a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x9839871234533354ULL, 329a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x839871234533354cULL, 330a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x839871234533354fULL, 331a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000008864000ULL, 332a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000000008864000cULL, 333a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000000008864000fULL, 334a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 335a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000000000000000cULL, 336a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000000000000000fULL, 337a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000000000000000dULL, 338a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000211ULL, 339a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000000000000211cULL, 340a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000000000000211fULL, 341a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000003882028150ULL, 342a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x000003882028150dULL 343a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes }; 344a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 345a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic unsigned long long bcd128_vals[] = { 346a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x0000000000003450ULL, 347a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x000000000003450cULL, 348a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x000000000003450fULL, 349a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x0000000001230000ULL, 350a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x000000001230000cULL, 351a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x000000001230000fULL, 352a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x0000000000000160ULL, 353a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x000000000000160dULL, 354a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x0000000000000189ULL, 355a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x000000000000189cULL, 356a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x000000000000189fULL, 357a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x0000004123456789ULL, 358a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x000004123456789dULL, 359a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000097100000000ULL, 0x9839871234533354ULL, 360a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000971000000009ULL, 0x839871234533354cULL, 361a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000971000000009ULL, 0x839871234533354fULL, 362a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000010954000051ULL, 0x8000640000000049ULL, 363a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000109540000518ULL, 0x000640000000049cULL, 364a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000109540000518ULL, 0x000640000000049fULL, 365a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x0000000000000000ULL, 366a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x000000000000000cULL, 367a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x000000000000000fULL, 368a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000000000ULL, 0x000000000000000dULL, 369a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000080000ULL, 0x0200801330811600ULL, 370a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000800000ULL, 0x200801330811600dULL, 371a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000088170ULL, 0x0000003882028150ULL, 372a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000881700ULL, 0x000003882028150cULL, 373a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 0x0000000000881700ULL, 0x000003882028150fULL 374a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes}; 375a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 376a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// Both Long and Quad arrays of DFP values should have the same length, so it 377a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// doesn't matter which array I use for calculating the following #define. 378a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define NUM_DFP_VALS (sizeof(dfp64_vals)/8) 379a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 380a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef enum { 381a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes LONG_TEST, 382a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes QUAD_TEST 383a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} precision_type_t; 384a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 385a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef struct dfp_one_arg_test 386a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 387a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_funcp_t test_func; 388a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes const char * name; 389a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes precision_type_t precision; 390a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes const char * op; 391a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} dfp_one_arg_test_t; 392a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 393a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef struct dfp_one_arg_bcd_test 394a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 395a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_func_bcdp_t test_func; 396a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes const char * name; 397a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes precision_type_t precision; 398a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes const char * op; 399a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} dfp_one_arg_bcd_test_t; 400a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 401a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic dfp_one_arg_bcd_test_t 402a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesdfp_test_dfp_ddedpd_tests[] = { 403a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes { &_test_ddedpd, "ddedpd", LONG_TEST, "[D->B]"}, 404a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes { &_test_ddedpdq, "ddedpdq", QUAD_TEST, "[D->B]"}, 405a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes { NULL, NULL, 0, NULL} 406a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes}; 407a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 408a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic void test_dfp_ddedpd_ops(void) 409a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 410a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_func_bcdp_t func; 411a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes dfp_val_t test_val; 412a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 413a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes int k = 0; 414a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 415a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes while ((func = dfp_test_dfp_ddedpd_tests[k].test_func)) { 416a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes int i; 417a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes dfp_one_arg_bcd_test_t test_def = dfp_test_dfp_ddedpd_tests[k]; 418a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 419a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes for (i = 0; i < NUM_DFP_VALS; i++) { 420a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes unsigned int SP; 421a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 422a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (test_def.precision == LONG_TEST) { 423a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_val.u64_val = dfp64_vals[i]; 424a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } else { 425a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_val.u128.valu = dfp128_vals[i * 2]; 426a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_val.u128.vall = dfp128_vals[(i * 2) + 1]; 427a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 428a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 429a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes for (SP = 0; SP < 4; SP++) { 430a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes dfp_val_t result; 431a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 432a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /* There is an ABI change in how 128 bit arguments are aligned 433a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * with GCC 5.0. The compiler generates a "note" about this 434a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * starting with GCC 4.8. To avoid generating the "note", pass 435a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * the address of the 128-bit arguments rather then the value. 436a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes */ 437a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes result = (*func)(SP, &test_val); 438a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("%s (SP=%d) %s", test_def.name, SP, test_def.op); 439a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (test_def.precision == LONG_TEST) { 440a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("%016llx ==> %016llx\n", test_val.u64_val, result.u64_val); 441a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } else { 442a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("%016llx %016llx ==> %016llx %016llx\n", 443a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_val.u128.valu, test_val.u128.vall, 444a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes result.u128.valu, result.u128.vall); 445a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 446a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 447a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 448a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes k++; 449a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf( "\n" ); 450a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 451a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} 452a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 453a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic dfp_one_arg_bcd_test_t 454a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesdfp_test_dfp_denbcd_tests[] = { 455a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes { &_test_denbcd, "denbcd", LONG_TEST, "[B->D]"}, 456a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes { &_test_denbcdq, "denbcdq", QUAD_TEST, "[B->D]"}, 457a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes { NULL, NULL, 0, NULL} 458a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes}; 459a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 460a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic void test_dfp_denbcd_ops(void) 461a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 462a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_func_bcdp_t func; 463a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes dfp_val_t test_val; 464a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes int num_test_vals; 465a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 466a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes int k = 0; 467a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 468a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes while ((func = dfp_test_dfp_denbcd_tests[k].test_func)) { 469a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes int i; 470a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes dfp_one_arg_bcd_test_t test_def = dfp_test_dfp_denbcd_tests[k]; 471a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (test_def.precision == LONG_TEST) 472a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes num_test_vals = sizeof(bcd64_vals)/sizeof(unsigned long long); 473a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes else 474a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes num_test_vals = sizeof(bcd128_vals)/(2 * sizeof(unsigned long long)); 475a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 476a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes for (i = 0; i < num_test_vals; i++) { 477a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes unsigned int S; 478a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes dfp_val_t result; 479a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /* The DPD-to-BCD decodings may contain up to 3 decodings for each normal DFP 480a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * value: the first is an unsigned decoding, and the other two are 481a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * signed decodings, with SP[1] set to '0' and '1' respectively at decode 482a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * time. But some of the results of decodings were duplicates, so they were 483a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * not included in the bcd64_vals and bcd128_vals arrays. 484a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * 485a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * When doing the encoding operation (denbcd), we'll attempt both S=0 and 486a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * S=1; one or the other should encode the BCD value to something close to 487a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * its original DFP value (except being 2^4 in magnitude since the decoding 488a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * operation shifted the value one hex digit to the left to make room 489a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * for signedness info). 490a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes */ 491a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes for (S = 0; S < 2; S++) { 492a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (test_def.precision == LONG_TEST) { 493a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_val.u64_val = bcd64_vals[i]; 494a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } else { 495a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_val.u128.valu = bcd128_vals[i * 2]; 496a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_val.u128.vall = bcd128_vals[(i * 2) + 1]; 497a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 498a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 499a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /* There is an API change in how 128 bit arguments are aligned 500a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * with GCC 5.0. The compiler generates a "note" about this 501a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * starting with GCC 4.8. To avoid generating the "note", pass 502a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * the address of the 128-bit arguments rather then the value. 503a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes */ 504a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes result = (*func)(S, &test_val); 505a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("%s (S=%d) %s", test_def.name, S, test_def.op); 506a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (test_def.precision == LONG_TEST) { 507a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("%016llx ==> %016llx\n", test_val.u64_val, result.u64_val); 508a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } else { 509a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("%016llx %016llx ==> %016llx %016llx\n", 510a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_val.u128.valu, test_val.u128.vall, 511a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes result.u128.valu, result.u128.vall); 512a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 513a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 514a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 515a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes k++; 516a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf( "\n" ); 517a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 518a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} 519a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 520a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 521a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic dfp_one_arg_test_t 522a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesdfp_test_significance_tests[] = { 523a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes { &_test_dtstsf, "dtstsf", LONG_TEST, "[tSig]"}, 524a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes { &_test_dtstsfq, "dtstsfq", QUAD_TEST, "[tSig]"}, 525a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes { NULL, NULL, 0, NULL} 526a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes}; 527a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 528a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic void test_dfp_test_significance_ops(void) 529a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 530a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_funcp_t func; 531a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes dfp_val_t test_valB; 532a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes int k = 0; 533a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes unsigned int BF_vals[] = {BF_val1, BF_val2, BF_val3}; 534a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes unsigned int reference_sig, reference_sig_vals[] = {0U, 1U, 2U, 4U, 6U, 63U}; 535a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes int num_reference_sig_vals = sizeof(reference_sig_vals)/sizeof(unsigned int); 536a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 537a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes while ((func = dfp_test_significance_tests[k].test_func)) { 538a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes int i; 539a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes dfp_one_arg_test_t test_def = dfp_test_significance_tests[k]; 540a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 541a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes for (i = 0; i < NUM_DFP_VALS; i++) { 542a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes int j; 543a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (test_def.precision == LONG_TEST) { 544a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_valB.u64_val = dfp64_vals[i]; 545a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } else { 546a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_valB.u128.valu = dfp128_vals[i * 2]; 547a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_valB.u128.vall = dfp128_vals[(i * 2) + 1]; 548a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 549a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 550a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes for (j = 0; j < num_reference_sig_vals; j++) { 551a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes int bf_idx, BF; 552a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes reference_sig = reference_sig_vals[j]; 553a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes for (bf_idx = 0; bf_idx < sizeof(BF_vals)/sizeof(unsigned int); bf_idx++) { 554a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes unsigned int condreg; 555a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes unsigned int flags; 556a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes BF = BF_vals[bf_idx]; 557a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes SET_FPSCR_ZERO; 558a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes SET_CR_XER_ZERO; 559a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /* There is an ABI change in how 128 bit arguments are aligned 560a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * with GCC 5.0. The compiler generates a "note" about this 561a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * starting with GCC 4.9. To avoid generating the "note", pass 562a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes * the address of the 128-bit arguments rather then the value. 563a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes */ 564a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes (*func)(BF, reference_sig, &test_valB); 565a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes GET_CR(flags); 566a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 567a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes condreg = ((flags >> (4 * (7-BF)))) & 0xf; 568a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("%s (ref_sig=%d) %s", test_def.name, reference_sig, test_def.op); 569a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (test_def.precision == LONG_TEST) { 570a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("%016llx", test_valB.u64_val); 571a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } else { 572a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("%016llx %016llx", test_valB.u128.valu, test_valB.u128.vall); 573a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 574a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf(" => %x (BF=%d)\n", condreg, BF); 575a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 576a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 577a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf( "\n" ); 578a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 579a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes k++; 580a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 581a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} 582a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 583a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic test_table_t 584a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes all_tests[] = 585a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 586a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes { &test_dfp_test_significance_ops, 587a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "Test DFP test significance instructions"}, 588a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes { &test_dfp_ddedpd_ops, 589a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "Test DFP DPD-to-BCD instructions"}, 590a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes { &test_dfp_denbcd_ops, 591a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "Test DFP BCD-to-DPD instructions"}, 592a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes { NULL, NULL } 593a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes}; 594a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#endif // HAS_DFP 595a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 596a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesint main() { 597a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#if defined(HAS_DFP) 598a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 599a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_table_t aTest; 600a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes test_driver_func_t func; 601a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes int i = 0; 602a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 603a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes while ((func = all_tests[i].test_category)) { 604a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes aTest = all_tests[i]; 605a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf( "%s\n", aTest.name ); 606a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes (*func)(); 607a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes i++; 608a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 609a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 610a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#endif // HAS_DFP 611a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes return 0; 612a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} 613