1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2009 VMware, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci/** 30bf215546Sopenharmony_ci * @file 31bf215546Sopenharmony_ci * Unit tests for type conversion. 32bf215546Sopenharmony_ci * 33bf215546Sopenharmony_ci * @author Jose Fonseca <jfonseca@vmware.com> 34bf215546Sopenharmony_ci */ 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "util/u_pointer.h" 38bf215546Sopenharmony_ci#include "gallivm/lp_bld_init.h" 39bf215546Sopenharmony_ci#include "gallivm/lp_bld_type.h" 40bf215546Sopenharmony_ci#include "gallivm/lp_bld_const.h" 41bf215546Sopenharmony_ci#include "gallivm/lp_bld_conv.h" 42bf215546Sopenharmony_ci#include "gallivm/lp_bld_debug.h" 43bf215546Sopenharmony_ci#include "lp_test.h" 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_citypedef void (*conv_test_ptr_t)(const void *src, const void *dst); 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_civoid 50bf215546Sopenharmony_ciwrite_tsv_header(FILE *fp) 51bf215546Sopenharmony_ci{ 52bf215546Sopenharmony_ci fprintf(fp, 53bf215546Sopenharmony_ci "result\t" 54bf215546Sopenharmony_ci "cycles_per_channel\t" 55bf215546Sopenharmony_ci "src_type\t" 56bf215546Sopenharmony_ci "dst_type\n"); 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci fflush(fp); 59bf215546Sopenharmony_ci} 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_cistatic void 63bf215546Sopenharmony_ciwrite_tsv_row(FILE *fp, 64bf215546Sopenharmony_ci struct lp_type src_type, 65bf215546Sopenharmony_ci struct lp_type dst_type, 66bf215546Sopenharmony_ci double cycles, 67bf215546Sopenharmony_ci boolean success) 68bf215546Sopenharmony_ci{ 69bf215546Sopenharmony_ci fprintf(fp, "%s\t", success ? "pass" : "fail"); 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci fprintf(fp, "%.1f\t", cycles / MAX2(src_type.length, dst_type.length)); 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci dump_type(fp, src_type); 74bf215546Sopenharmony_ci fprintf(fp, "\t"); 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci dump_type(fp, dst_type); 77bf215546Sopenharmony_ci fprintf(fp, "\n"); 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci fflush(fp); 80bf215546Sopenharmony_ci} 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_cistatic void 84bf215546Sopenharmony_cidump_conv_types(FILE *fp, 85bf215546Sopenharmony_ci struct lp_type src_type, 86bf215546Sopenharmony_ci struct lp_type dst_type) 87bf215546Sopenharmony_ci{ 88bf215546Sopenharmony_ci fprintf(fp, "src_type="); 89bf215546Sopenharmony_ci dump_type(fp, src_type); 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci fprintf(fp, " dst_type="); 92bf215546Sopenharmony_ci dump_type(fp, dst_type); 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci fprintf(fp, " ...\n"); 95bf215546Sopenharmony_ci fflush(fp); 96bf215546Sopenharmony_ci} 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_cistatic LLVMValueRef 100bf215546Sopenharmony_ciadd_conv_test(struct gallivm_state *gallivm, 101bf215546Sopenharmony_ci struct lp_type src_type, unsigned num_srcs, 102bf215546Sopenharmony_ci struct lp_type dst_type, unsigned num_dsts) 103bf215546Sopenharmony_ci{ 104bf215546Sopenharmony_ci LLVMModuleRef module = gallivm->module; 105bf215546Sopenharmony_ci LLVMContextRef context = gallivm->context; 106bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 107bf215546Sopenharmony_ci LLVMTypeRef args[2]; 108bf215546Sopenharmony_ci LLVMValueRef func; 109bf215546Sopenharmony_ci LLVMValueRef src_ptr; 110bf215546Sopenharmony_ci LLVMValueRef dst_ptr; 111bf215546Sopenharmony_ci LLVMBasicBlockRef block; 112bf215546Sopenharmony_ci LLVMValueRef src[LP_MAX_VECTOR_LENGTH]; 113bf215546Sopenharmony_ci LLVMValueRef dst[LP_MAX_VECTOR_LENGTH]; 114bf215546Sopenharmony_ci unsigned i; 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci args[0] = LLVMPointerType(lp_build_vec_type(gallivm, src_type), 0); 117bf215546Sopenharmony_ci args[1] = LLVMPointerType(lp_build_vec_type(gallivm, dst_type), 0); 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci func = LLVMAddFunction(module, "test", 120bf215546Sopenharmony_ci LLVMFunctionType(LLVMVoidTypeInContext(context), 121bf215546Sopenharmony_ci args, 2, 0)); 122bf215546Sopenharmony_ci LLVMSetFunctionCallConv(func, LLVMCCallConv); 123bf215546Sopenharmony_ci src_ptr = LLVMGetParam(func, 0); 124bf215546Sopenharmony_ci dst_ptr = LLVMGetParam(func, 1); 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci block = LLVMAppendBasicBlockInContext(context, func, "entry"); 127bf215546Sopenharmony_ci LLVMPositionBuilderAtEnd(builder, block); 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci for(i = 0; i < num_srcs; ++i) { 130bf215546Sopenharmony_ci LLVMValueRef index = LLVMConstInt(LLVMInt32TypeInContext(context), i, 0); 131bf215546Sopenharmony_ci LLVMValueRef ptr = LLVMBuildGEP(builder, src_ptr, &index, 1, ""); 132bf215546Sopenharmony_ci src[i] = LLVMBuildLoad(builder, ptr, ""); 133bf215546Sopenharmony_ci } 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci lp_build_conv(gallivm, src_type, dst_type, src, num_srcs, dst, num_dsts); 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci for(i = 0; i < num_dsts; ++i) { 138bf215546Sopenharmony_ci LLVMValueRef index = LLVMConstInt(LLVMInt32TypeInContext(context), i, 0); 139bf215546Sopenharmony_ci LLVMValueRef ptr = LLVMBuildGEP(builder, dst_ptr, &index, 1, ""); 140bf215546Sopenharmony_ci LLVMBuildStore(builder, dst[i], ptr); 141bf215546Sopenharmony_ci } 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci LLVMBuildRetVoid(builder); 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci gallivm_verify_function(gallivm, func); 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci return func; 148bf215546Sopenharmony_ci} 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ciPIPE_ALIGN_STACK 152bf215546Sopenharmony_cistatic boolean 153bf215546Sopenharmony_citest_one(unsigned verbose, 154bf215546Sopenharmony_ci FILE *fp, 155bf215546Sopenharmony_ci struct lp_type src_type, 156bf215546Sopenharmony_ci struct lp_type dst_type) 157bf215546Sopenharmony_ci{ 158bf215546Sopenharmony_ci LLVMContextRef context; 159bf215546Sopenharmony_ci struct gallivm_state *gallivm; 160bf215546Sopenharmony_ci LLVMValueRef func = NULL; 161bf215546Sopenharmony_ci conv_test_ptr_t conv_test_ptr; 162bf215546Sopenharmony_ci boolean success; 163bf215546Sopenharmony_ci const unsigned n = LP_TEST_NUM_SAMPLES; 164bf215546Sopenharmony_ci int64_t cycles[LP_TEST_NUM_SAMPLES]; 165bf215546Sopenharmony_ci double cycles_avg = 0.0; 166bf215546Sopenharmony_ci unsigned num_srcs; 167bf215546Sopenharmony_ci unsigned num_dsts; 168bf215546Sopenharmony_ci double eps; 169bf215546Sopenharmony_ci unsigned i, j; 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci if ((src_type.width >= dst_type.width && src_type.length > dst_type.length) || 172bf215546Sopenharmony_ci (src_type.width <= dst_type.width && src_type.length < dst_type.length)) { 173bf215546Sopenharmony_ci return TRUE; 174bf215546Sopenharmony_ci } 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci /* Known failures 177bf215546Sopenharmony_ci * - fixed point 32 -> float 32 178bf215546Sopenharmony_ci * - float 32 -> signed normalized integer 32 179bf215546Sopenharmony_ci */ 180bf215546Sopenharmony_ci if ((src_type.floating && !dst_type.floating && dst_type.sign && dst_type.norm && src_type.width == dst_type.width) || 181bf215546Sopenharmony_ci (!src_type.floating && dst_type.floating && src_type.fixed && src_type.width == dst_type.width)) { 182bf215546Sopenharmony_ci return TRUE; 183bf215546Sopenharmony_ci } 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci /* Known failures 186bf215546Sopenharmony_ci * - fixed point 32 -> float 32 187bf215546Sopenharmony_ci * - float 32 -> signed normalized integer 32 188bf215546Sopenharmony_ci */ 189bf215546Sopenharmony_ci if ((src_type.floating && !dst_type.floating && dst_type.sign && dst_type.norm && src_type.width == dst_type.width) || 190bf215546Sopenharmony_ci (!src_type.floating && dst_type.floating && src_type.fixed && src_type.width == dst_type.width)) { 191bf215546Sopenharmony_ci return TRUE; 192bf215546Sopenharmony_ci } 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci if(verbose >= 1) 195bf215546Sopenharmony_ci dump_conv_types(stderr, src_type, dst_type); 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci if (src_type.length > dst_type.length) { 198bf215546Sopenharmony_ci num_srcs = 1; 199bf215546Sopenharmony_ci num_dsts = src_type.length/dst_type.length; 200bf215546Sopenharmony_ci } 201bf215546Sopenharmony_ci else if (src_type.length < dst_type.length) { 202bf215546Sopenharmony_ci num_dsts = 1; 203bf215546Sopenharmony_ci num_srcs = dst_type.length/src_type.length; 204bf215546Sopenharmony_ci } 205bf215546Sopenharmony_ci else { 206bf215546Sopenharmony_ci num_dsts = 1; 207bf215546Sopenharmony_ci num_srcs = 1; 208bf215546Sopenharmony_ci } 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci /* We must not loose or gain channels. Only precision */ 211bf215546Sopenharmony_ci assert(src_type.length * num_srcs == dst_type.length * num_dsts); 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci eps = MAX2(lp_const_eps(src_type), lp_const_eps(dst_type)); 214bf215546Sopenharmony_ci if (dst_type.norm && dst_type.sign && src_type.sign && !src_type.floating) { 215bf215546Sopenharmony_ci /* 216bf215546Sopenharmony_ci * This is quite inaccurate due to shift being used. 217bf215546Sopenharmony_ci * I don't think it's possible to hit such conversions with 218bf215546Sopenharmony_ci * llvmpipe though. 219bf215546Sopenharmony_ci */ 220bf215546Sopenharmony_ci eps *= 2; 221bf215546Sopenharmony_ci } 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci context = LLVMContextCreate(); 224bf215546Sopenharmony_ci#if LLVM_VERSION_MAJOR >= 15 225bf215546Sopenharmony_ci LLVMContextSetOpaquePointers(context, false); 226bf215546Sopenharmony_ci#endif 227bf215546Sopenharmony_ci gallivm = gallivm_create("test_module", context, NULL); 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci func = add_conv_test(gallivm, src_type, num_srcs, dst_type, num_dsts); 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci gallivm_compile_module(gallivm); 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci conv_test_ptr = (conv_test_ptr_t)gallivm_jit_function(gallivm, func); 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci gallivm_free_ir(gallivm); 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci success = TRUE; 238bf215546Sopenharmony_ci for(i = 0; i < n && success; ++i) { 239bf215546Sopenharmony_ci unsigned src_stride = src_type.length*src_type.width/8; 240bf215546Sopenharmony_ci unsigned dst_stride = dst_type.length*dst_type.width/8; 241bf215546Sopenharmony_ci alignas(LP_MIN_VECTOR_ALIGN) uint8_t src[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH]; 242bf215546Sopenharmony_ci alignas(LP_MIN_VECTOR_ALIGN) uint8_t dst[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH]; 243bf215546Sopenharmony_ci double fref[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH]; 244bf215546Sopenharmony_ci uint8_t ref[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH]; 245bf215546Sopenharmony_ci int64_t start_counter = 0; 246bf215546Sopenharmony_ci int64_t end_counter = 0; 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci for(j = 0; j < num_srcs; ++j) { 249bf215546Sopenharmony_ci random_vec(src_type, src + j*src_stride); 250bf215546Sopenharmony_ci read_vec(src_type, src + j*src_stride, fref + j*src_type.length); 251bf215546Sopenharmony_ci } 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci for(j = 0; j < num_dsts; ++j) { 254bf215546Sopenharmony_ci write_vec(dst_type, ref + j*dst_stride, fref + j*dst_type.length); 255bf215546Sopenharmony_ci } 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci start_counter = rdtsc(); 258bf215546Sopenharmony_ci conv_test_ptr(src, dst); 259bf215546Sopenharmony_ci end_counter = rdtsc(); 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_ci cycles[i] = end_counter - start_counter; 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci for(j = 0; j < num_dsts; ++j) { 264bf215546Sopenharmony_ci if(!compare_vec_with_eps(dst_type, dst + j*dst_stride, ref + j*dst_stride, eps)) 265bf215546Sopenharmony_ci success = FALSE; 266bf215546Sopenharmony_ci } 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci if (!success || verbose >= 3) { 269bf215546Sopenharmony_ci if(verbose < 1) 270bf215546Sopenharmony_ci dump_conv_types(stderr, src_type, dst_type); 271bf215546Sopenharmony_ci if (success) { 272bf215546Sopenharmony_ci fprintf(stderr, "PASS\n"); 273bf215546Sopenharmony_ci } 274bf215546Sopenharmony_ci else { 275bf215546Sopenharmony_ci fprintf(stderr, "MISMATCH\n"); 276bf215546Sopenharmony_ci } 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci for(j = 0; j < num_srcs; ++j) { 279bf215546Sopenharmony_ci fprintf(stderr, " Src%u: ", j); 280bf215546Sopenharmony_ci dump_vec(stderr, src_type, src + j*src_stride); 281bf215546Sopenharmony_ci fprintf(stderr, "\n"); 282bf215546Sopenharmony_ci } 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci#if 1 285bf215546Sopenharmony_ci fprintf(stderr, " Ref: "); 286bf215546Sopenharmony_ci for(j = 0; j < src_type.length*num_srcs; ++j) 287bf215546Sopenharmony_ci fprintf(stderr, " %f", fref[j]); 288bf215546Sopenharmony_ci fprintf(stderr, "\n"); 289bf215546Sopenharmony_ci#endif 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci for(j = 0; j < num_dsts; ++j) { 292bf215546Sopenharmony_ci fprintf(stderr, " Dst%u: ", j); 293bf215546Sopenharmony_ci dump_vec(stderr, dst_type, dst + j*dst_stride); 294bf215546Sopenharmony_ci fprintf(stderr, "\n"); 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci fprintf(stderr, " Ref%u: ", j); 297bf215546Sopenharmony_ci dump_vec(stderr, dst_type, ref + j*dst_stride); 298bf215546Sopenharmony_ci fprintf(stderr, "\n"); 299bf215546Sopenharmony_ci } 300bf215546Sopenharmony_ci } 301bf215546Sopenharmony_ci } 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci /* 304bf215546Sopenharmony_ci * Unfortunately the output of cycle counter is not very reliable as it comes 305bf215546Sopenharmony_ci * -- sometimes we get outliers (due IRQs perhaps?) which are 306bf215546Sopenharmony_ci * better removed to avoid random or biased data. 307bf215546Sopenharmony_ci */ 308bf215546Sopenharmony_ci { 309bf215546Sopenharmony_ci double sum = 0.0, sum2 = 0.0; 310bf215546Sopenharmony_ci double avg, std; 311bf215546Sopenharmony_ci unsigned m; 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci for(i = 0; i < n; ++i) { 314bf215546Sopenharmony_ci sum += cycles[i]; 315bf215546Sopenharmony_ci sum2 += cycles[i]*cycles[i]; 316bf215546Sopenharmony_ci } 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci avg = sum/n; 319bf215546Sopenharmony_ci std = sqrtf((sum2 - n*avg*avg)/n); 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci m = 0; 322bf215546Sopenharmony_ci sum = 0.0; 323bf215546Sopenharmony_ci for(i = 0; i < n; ++i) { 324bf215546Sopenharmony_ci if(fabs(cycles[i] - avg) <= 4.0*std) { 325bf215546Sopenharmony_ci sum += cycles[i]; 326bf215546Sopenharmony_ci ++m; 327bf215546Sopenharmony_ci } 328bf215546Sopenharmony_ci } 329bf215546Sopenharmony_ci 330bf215546Sopenharmony_ci cycles_avg = sum/m; 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci } 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci if(fp) 335bf215546Sopenharmony_ci write_tsv_row(fp, src_type, dst_type, cycles_avg, success); 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci gallivm_destroy(gallivm); 338bf215546Sopenharmony_ci LLVMContextDispose(context); 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci return success; 341bf215546Sopenharmony_ci} 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci 344bf215546Sopenharmony_ciconst struct lp_type conv_types[] = { 345bf215546Sopenharmony_ci /* float, fixed, sign, norm, width, len */ 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci /* Float */ 348bf215546Sopenharmony_ci { TRUE, FALSE, TRUE, TRUE, 32, 4 }, 349bf215546Sopenharmony_ci { TRUE, FALSE, TRUE, FALSE, 32, 4 }, 350bf215546Sopenharmony_ci { TRUE, FALSE, FALSE, TRUE, 32, 4 }, 351bf215546Sopenharmony_ci { TRUE, FALSE, FALSE, FALSE, 32, 4 }, 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci { TRUE, FALSE, TRUE, TRUE, 32, 8 }, 354bf215546Sopenharmony_ci { TRUE, FALSE, TRUE, FALSE, 32, 8 }, 355bf215546Sopenharmony_ci { TRUE, FALSE, FALSE, TRUE, 32, 8 }, 356bf215546Sopenharmony_ci { TRUE, FALSE, FALSE, FALSE, 32, 8 }, 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci /* Fixed */ 359bf215546Sopenharmony_ci { FALSE, TRUE, TRUE, TRUE, 32, 4 }, 360bf215546Sopenharmony_ci { FALSE, TRUE, TRUE, FALSE, 32, 4 }, 361bf215546Sopenharmony_ci { FALSE, TRUE, FALSE, TRUE, 32, 4 }, 362bf215546Sopenharmony_ci { FALSE, TRUE, FALSE, FALSE, 32, 4 }, 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci { FALSE, TRUE, TRUE, TRUE, 32, 8 }, 365bf215546Sopenharmony_ci { FALSE, TRUE, TRUE, FALSE, 32, 8 }, 366bf215546Sopenharmony_ci { FALSE, TRUE, FALSE, TRUE, 32, 8 }, 367bf215546Sopenharmony_ci { FALSE, TRUE, FALSE, FALSE, 32, 8 }, 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci /* Integer */ 370bf215546Sopenharmony_ci { FALSE, FALSE, TRUE, TRUE, 32, 4 }, 371bf215546Sopenharmony_ci { FALSE, FALSE, TRUE, FALSE, 32, 4 }, 372bf215546Sopenharmony_ci { FALSE, FALSE, FALSE, TRUE, 32, 4 }, 373bf215546Sopenharmony_ci { FALSE, FALSE, FALSE, FALSE, 32, 4 }, 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ci { FALSE, FALSE, TRUE, TRUE, 32, 8 }, 376bf215546Sopenharmony_ci { FALSE, FALSE, TRUE, FALSE, 32, 8 }, 377bf215546Sopenharmony_ci { FALSE, FALSE, FALSE, TRUE, 32, 8 }, 378bf215546Sopenharmony_ci { FALSE, FALSE, FALSE, FALSE, 32, 8 }, 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci { FALSE, FALSE, TRUE, TRUE, 16, 8 }, 381bf215546Sopenharmony_ci { FALSE, FALSE, TRUE, FALSE, 16, 8 }, 382bf215546Sopenharmony_ci { FALSE, FALSE, FALSE, TRUE, 16, 8 }, 383bf215546Sopenharmony_ci { FALSE, FALSE, FALSE, FALSE, 16, 8 }, 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci { FALSE, FALSE, TRUE, TRUE, 8, 16 }, 386bf215546Sopenharmony_ci { FALSE, FALSE, TRUE, FALSE, 8, 16 }, 387bf215546Sopenharmony_ci { FALSE, FALSE, FALSE, TRUE, 8, 16 }, 388bf215546Sopenharmony_ci { FALSE, FALSE, FALSE, FALSE, 8, 16 }, 389bf215546Sopenharmony_ci 390bf215546Sopenharmony_ci { FALSE, FALSE, TRUE, TRUE, 8, 4 }, 391bf215546Sopenharmony_ci { FALSE, FALSE, TRUE, FALSE, 8, 4 }, 392bf215546Sopenharmony_ci { FALSE, FALSE, FALSE, TRUE, 8, 4 }, 393bf215546Sopenharmony_ci { FALSE, FALSE, FALSE, FALSE, 8, 4 }, 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci { FALSE, FALSE, FALSE, TRUE, 8, 8 }, 396bf215546Sopenharmony_ci}; 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_ci 399bf215546Sopenharmony_ciconst unsigned num_types = ARRAY_SIZE(conv_types); 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ciboolean 403bf215546Sopenharmony_citest_all(unsigned verbose, FILE *fp) 404bf215546Sopenharmony_ci{ 405bf215546Sopenharmony_ci const struct lp_type *src_type; 406bf215546Sopenharmony_ci const struct lp_type *dst_type; 407bf215546Sopenharmony_ci boolean success = TRUE; 408bf215546Sopenharmony_ci int error_count = 0; 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci for(src_type = conv_types; src_type < &conv_types[num_types]; ++src_type) { 411bf215546Sopenharmony_ci for(dst_type = conv_types; dst_type < &conv_types[num_types]; ++dst_type) { 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci if(src_type == dst_type) 414bf215546Sopenharmony_ci continue; 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ci if(!test_one(verbose, fp, *src_type, *dst_type)){ 417bf215546Sopenharmony_ci success = FALSE; 418bf215546Sopenharmony_ci ++error_count; 419bf215546Sopenharmony_ci } 420bf215546Sopenharmony_ci } 421bf215546Sopenharmony_ci } 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci fprintf(stderr, "%d failures\n", error_count); 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci return success; 426bf215546Sopenharmony_ci} 427bf215546Sopenharmony_ci 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ciboolean 430bf215546Sopenharmony_citest_some(unsigned verbose, FILE *fp, 431bf215546Sopenharmony_ci unsigned long n) 432bf215546Sopenharmony_ci{ 433bf215546Sopenharmony_ci const struct lp_type *src_type; 434bf215546Sopenharmony_ci const struct lp_type *dst_type; 435bf215546Sopenharmony_ci unsigned long i; 436bf215546Sopenharmony_ci boolean success = TRUE; 437bf215546Sopenharmony_ci 438bf215546Sopenharmony_ci for(i = 0; i < n; ++i) { 439bf215546Sopenharmony_ci src_type = &conv_types[rand() % num_types]; 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_ci do { 442bf215546Sopenharmony_ci dst_type = &conv_types[rand() % num_types]; 443bf215546Sopenharmony_ci } while (src_type == dst_type || src_type->norm != dst_type->norm); 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_ci if(!test_one(verbose, fp, *src_type, *dst_type)) 446bf215546Sopenharmony_ci success = FALSE; 447bf215546Sopenharmony_ci } 448bf215546Sopenharmony_ci 449bf215546Sopenharmony_ci return success; 450bf215546Sopenharmony_ci} 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci 453bf215546Sopenharmony_ciboolean 454bf215546Sopenharmony_citest_single(unsigned verbose, FILE *fp) 455bf215546Sopenharmony_ci{ 456bf215546Sopenharmony_ci /* float, fixed, sign, norm, width, len */ 457bf215546Sopenharmony_ci struct lp_type f32x4_type = 458bf215546Sopenharmony_ci { TRUE, FALSE, TRUE, TRUE, 32, 4 }; 459bf215546Sopenharmony_ci struct lp_type ub8x4_type = 460bf215546Sopenharmony_ci { FALSE, FALSE, FALSE, TRUE, 8, 16 }; 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_ci boolean success; 463bf215546Sopenharmony_ci 464bf215546Sopenharmony_ci success = test_one(verbose, fp, f32x4_type, ub8x4_type); 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_ci return success; 467bf215546Sopenharmony_ci} 468