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