17ec681f3Smrg/*
27ec681f3Smrg * Copyright (C) 2021 Collabora, Ltd.
37ec681f3Smrg *
47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
67ec681f3Smrg * to deal in the Software without restriction, including without limitation
77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the
97ec681f3Smrg * Software is furnished to do so, subject to the following conditions:
107ec681f3Smrg *
117ec681f3Smrg * The above copyright notice and this permission notice (including the next
127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
137ec681f3Smrg * Software.
147ec681f3Smrg *
157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
207ec681f3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
217ec681f3Smrg * SOFTWARE.
227ec681f3Smrg */
237ec681f3Smrg
247ec681f3Smrg#include "compiler.h"
257ec681f3Smrg#include "bi_test.h"
267ec681f3Smrg#include "bi_builder.h"
277ec681f3Smrg
287ec681f3Smrg#define CASE(instr, expected) do { \
297ec681f3Smrg   bool _unsupported = false; \
307ec681f3Smrg   uint32_t _value = bi_fold_constant(instr, &_unsupported); \
317ec681f3Smrg   if (_unsupported) { \
327ec681f3Smrg      fprintf(stderr, "Constant folding failed:\n"); \
337ec681f3Smrg      bi_print_instr(instr, stderr); \
347ec681f3Smrg      fprintf(stderr, "\n"); \
357ec681f3Smrg   } else if (_value == (expected)) { \
367ec681f3Smrg      nr_pass++; \
377ec681f3Smrg   } else { \
387ec681f3Smrg      fprintf(stderr, "Got %" PRIx32 ", expected %" PRIx32 "\n", _value, expected); \
397ec681f3Smrg      bi_print_instr(instr, stderr); \
407ec681f3Smrg      fprintf(stderr, "\n"); \
417ec681f3Smrg      nr_fail++; \
427ec681f3Smrg   } \
437ec681f3Smrg} while(0)
447ec681f3Smrg
457ec681f3Smrg#define NEGCASE(instr) do { \
467ec681f3Smrg   bool _unsupported = false; \
477ec681f3Smrg   bi_fold_constant(instr, &_unsupported); \
487ec681f3Smrg   if (_unsupported) { \
497ec681f3Smrg      nr_pass++; \
507ec681f3Smrg   } else { \
517ec681f3Smrg      fprintf(stderr, "Should not have constant folded:\n"); \
527ec681f3Smrg      bi_print_instr(instr, stderr); \
537ec681f3Smrg      fprintf(stderr, "\n"); \
547ec681f3Smrg      nr_fail++; \
557ec681f3Smrg   } \
567ec681f3Smrg} while(0)
577ec681f3Smrg
587ec681f3Smrgint
597ec681f3Smrgmain(int argc, const char **argv)
607ec681f3Smrg{
617ec681f3Smrg   unsigned nr_fail = 0, nr_pass = 0;
627ec681f3Smrg   void *ralloc_ctx = ralloc_context(NULL);
637ec681f3Smrg   bi_builder *b = bit_builder(ralloc_ctx);
647ec681f3Smrg   bi_index zero = bi_fau(BIR_FAU_IMMEDIATE | 0, false);
657ec681f3Smrg   bi_index reg = bi_register(0);
667ec681f3Smrg
677ec681f3Smrg   /* Swizzles should be constant folded */
687ec681f3Smrg   CASE(bi_swz_v2i16_to(b, reg, bi_imm_u32(0xCAFEBABE)), 0xCAFEBABE);
697ec681f3Smrg   CASE(bi_swz_v2i16_to(b, reg, bi_swz_16(bi_imm_u32(0xCAFEBABE), false, false)),
707ec681f3Smrg        0xBABEBABE);
717ec681f3Smrg   CASE(bi_swz_v2i16_to(b, reg, bi_swz_16(bi_imm_u32(0xCAFEBABE), true, false)),
727ec681f3Smrg        0xBABECAFE);
737ec681f3Smrg   CASE(bi_swz_v2i16_to(b, reg, bi_swz_16(bi_imm_u32(0xCAFEBABE), true, true)),
747ec681f3Smrg        0xCAFECAFE);
757ec681f3Smrg
767ec681f3Smrg   /* Vector constructions should be constant folded */
777ec681f3Smrg   CASE(bi_mkvec_v2i16_to(b, reg, bi_imm_u16(0xCAFE), bi_imm_u16(0xBABE)), 0xBABECAFE);
787ec681f3Smrg   CASE(bi_mkvec_v2i16_to(b, reg, bi_swz_16(bi_imm_u32(0xCAFEBABE), true, true),
797ec681f3Smrg         bi_imm_u16(0xBABE)), 0xBABECAFE);
807ec681f3Smrg   CASE(bi_mkvec_v2i16_to(b, reg, bi_swz_16(bi_imm_u32(0xCAFEBABE), true, true),
817ec681f3Smrg         bi_swz_16(bi_imm_u32(0xCAFEBABE), false, false)), 0xBABECAFE);
827ec681f3Smrg
837ec681f3Smrg   {
847ec681f3Smrg      bi_index u32 = bi_imm_u32(0xCAFEBABE);
857ec681f3Smrg
867ec681f3Smrg      bi_index a = bi_byte(u32, 0); /* 0xBE */
877ec681f3Smrg      bi_index c = bi_byte(u32, 2); /* 0xFE */
887ec681f3Smrg
897ec681f3Smrg      CASE(bi_mkvec_v4i8_to(b, reg, a, a, a, a), 0xBEBEBEBE);
907ec681f3Smrg      CASE(bi_mkvec_v4i8_to(b, reg, a, c, a, c), 0xFEBEFEBE);
917ec681f3Smrg      CASE(bi_mkvec_v4i8_to(b, reg, c, a, c, a), 0xBEFEBEFE);
927ec681f3Smrg      CASE(bi_mkvec_v4i8_to(b, reg, c, c, c, c), 0xFEFEFEFE);
937ec681f3Smrg   }
947ec681f3Smrg
957ec681f3Smrg   /* Limited shifts required for texturing */
967ec681f3Smrg   CASE(bi_lshift_or_i32_to(b, reg, bi_imm_u32(0xCAFE), bi_imm_u32(0xA0000), bi_imm_u8(4)), (0xCAFE << 4) | 0xA0000);
977ec681f3Smrg   NEGCASE(bi_lshift_or_i32_to(b, reg, bi_imm_u32(0xCAFE), bi_not(bi_imm_u32(0xA0000)), bi_imm_u8(4)));
987ec681f3Smrg   NEGCASE(bi_lshift_or_i32_to(b, reg, bi_not(bi_imm_u32(0xCAFE)), bi_imm_u32(0xA0000), bi_imm_u8(4)));
997ec681f3Smrg   {
1007ec681f3Smrg      bi_instr *I = bi_lshift_or_i32_to(b, reg, bi_imm_u32(0xCAFE), bi_imm_u32(0xA0000), bi_imm_u8(4));
1017ec681f3Smrg      I->not_result = true;
1027ec681f3Smrg      NEGCASE(I);
1037ec681f3Smrg   }
1047ec681f3Smrg
1057ec681f3Smrg   /* Limited rounding needed for texturing */
1067ec681f3Smrg   CASE(bi_f32_to_u32_to(b, reg, bi_imm_f32(15.0), BI_ROUND_NONE), 15);
1077ec681f3Smrg   CASE(bi_f32_to_u32_to(b, reg, bi_imm_f32(15.9), BI_ROUND_NONE), 15);
1087ec681f3Smrg   CASE(bi_f32_to_u32_to(b, reg, bi_imm_f32(-20.4), BI_ROUND_NONE), 0);
1097ec681f3Smrg   NEGCASE(bi_f32_to_u32_to(b, reg, bi_imm_f32(-20.4), BI_ROUND_RTP));
1107ec681f3Smrg   NEGCASE(bi_f32_to_u32_to(b, reg, bi_imm_f32(-20.4), BI_ROUND_RTZ));
1117ec681f3Smrg
1127ec681f3Smrg   /* Instructions with non-constant sources cannot be constant folded */
1137ec681f3Smrg   NEGCASE(bi_swz_v2i16_to(b, reg, bi_temp(b->shader)));
1147ec681f3Smrg   NEGCASE(bi_mkvec_v2i16_to(b, reg, bi_temp(b->shader), bi_temp(b->shader)));
1157ec681f3Smrg   NEGCASE(bi_mkvec_v2i16_to(b, reg, bi_temp(b->shader), bi_imm_u32(0xDEADBEEF)));
1167ec681f3Smrg   NEGCASE(bi_mkvec_v2i16_to(b, reg, bi_imm_u32(0xDEADBEEF), bi_temp(b->shader)));
1177ec681f3Smrg
1187ec681f3Smrg   /* Other operations should not be constant folded */
1197ec681f3Smrg   NEGCASE(bi_fma_f32_to(b, reg, zero, zero, zero, BI_ROUND_NONE));
1207ec681f3Smrg   NEGCASE(bi_fadd_f32_to(b, reg, zero, zero, BI_ROUND_NONE));
1217ec681f3Smrg
1227ec681f3Smrg   ralloc_free(ralloc_ctx);
1237ec681f3Smrg   TEST_END(nr_pass, nr_fail);
1247ec681f3Smrg}
125