Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2012 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21.  * IN THE SOFTWARE.
  22.  */
  23.  
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <stdbool.h>
  27. #include "glsl/ralloc.h"
  28. #include "brw_context.h"
  29. #include "brw_eu.h"
  30.  
  31. static bool
  32. test_compact_instruction(struct brw_compile *p, struct brw_instruction src)
  33. {
  34.    struct brw_context *brw = p->brw;
  35.  
  36.    struct brw_compact_instruction dst;
  37.    memset(&dst, 0xd0, sizeof(dst));
  38.  
  39.    if (brw_try_compact_instruction(p, &dst, &src)) {
  40.       struct brw_instruction uncompacted;
  41.  
  42.       brw_uncompact_instruction(brw, &uncompacted, &dst);
  43.       if (memcmp(&uncompacted, &src, sizeof(src))) {
  44.          brw_debug_compact_uncompact(brw, &src, &uncompacted);
  45.          return false;
  46.       }
  47.    } else {
  48.       struct brw_compact_instruction unchanged;
  49.       memset(&unchanged, 0xd0, sizeof(unchanged));
  50.       /* It's not supposed to change dst unless it compacted. */
  51.       if (memcmp(&unchanged, &dst, sizeof(dst))) {
  52.          fprintf(stderr, "Failed to compact, but dst changed\n");
  53.          fprintf(stderr, "  Instruction: ");
  54.          brw_disasm(stderr, &src, brw->gen);
  55.          return false;
  56.       }
  57.    }
  58.  
  59.    return true;
  60. }
  61.  
  62. /**
  63.  * When doing fuzz testing, pad bits won't round-trip.
  64.  *
  65.  * This sort of a superset of skip_bit, which is testing for changing bits that
  66.  * aren't worth testing for fuzzing.  We also just want to clear bits that
  67.  * become meaningless once fuzzing twiddles a related bit.
  68.  */
  69. static void
  70. clear_pad_bits(struct brw_instruction *inst)
  71. {
  72.    if (inst->header.opcode != BRW_OPCODE_SEND &&
  73.        inst->header.opcode != BRW_OPCODE_SENDC &&
  74.        inst->header.opcode != BRW_OPCODE_BREAK &&
  75.        inst->header.opcode != BRW_OPCODE_CONTINUE &&
  76.        inst->bits1.da1.src0_reg_file != BRW_IMMEDIATE_VALUE &&
  77.        inst->bits1.da1.src1_reg_file != BRW_IMMEDIATE_VALUE) {
  78.       if (inst->bits3.da1.src1_address_mode)
  79.          inst->bits3.ia1.pad1 = 0;
  80.       else
  81.          inst->bits3.da1.pad0 = 0;
  82.    }
  83. }
  84.  
  85. static bool
  86. skip_bit(struct brw_instruction *src, int bit)
  87. {
  88.    /* pad bit */
  89.    if (bit == 7)
  90.       return true;
  91.  
  92.    /* The compact bit -- uncompacted can't have it set. */
  93.    if (bit == 29)
  94.       return true;
  95.  
  96.    /* pad bit */
  97.    if (bit == 47)
  98.       return true;
  99.  
  100.    /* pad bits */
  101.    if (bit >= 90 && bit <= 95)
  102.       return true;
  103.  
  104.    /* sometimes these are pad bits. */
  105.    if (src->header.opcode != BRW_OPCODE_SEND &&
  106.        src->header.opcode != BRW_OPCODE_SENDC &&
  107.        src->header.opcode != BRW_OPCODE_BREAK &&
  108.        src->header.opcode != BRW_OPCODE_CONTINUE &&
  109.        src->bits1.da1.src0_reg_file != BRW_IMMEDIATE_VALUE &&
  110.        src->bits1.da1.src1_reg_file != BRW_IMMEDIATE_VALUE &&
  111.        bit >= 121) {
  112.       return true;
  113.    }
  114.  
  115.    return false;
  116. }
  117.  
  118. static bool
  119. test_fuzz_compact_instruction(struct brw_compile *p,
  120.                               struct brw_instruction src)
  121. {
  122.    for (int bit0 = 0; bit0 < 128; bit0++) {
  123.       if (skip_bit(&src, bit0))
  124.          continue;
  125.  
  126.       for (int bit1 = 0; bit1 < 128; bit1++) {
  127.          struct brw_instruction instr = src;
  128.          uint32_t *bits = (uint32_t *)&instr;
  129.  
  130.          if (skip_bit(&src, bit1))
  131.             continue;
  132.  
  133.          bits[bit0 / 32] ^= (1 << (bit0 & 31));
  134.          bits[bit1 / 32] ^= (1 << (bit1 & 31));
  135.  
  136.          clear_pad_bits(&instr);
  137.  
  138.          if (!test_compact_instruction(p, instr)) {
  139.             printf("  twiddled bits for fuzzing %d, %d\n", bit0, bit1);
  140.             return false;
  141.          }
  142.       }
  143.    }
  144.  
  145.    return true;
  146. }
  147.  
  148. static void
  149. gen_ADD_GRF_GRF_GRF(struct brw_compile *p)
  150. {
  151.    struct brw_reg g0 = brw_vec8_grf(0, 0);
  152.    struct brw_reg g2 = brw_vec8_grf(2, 0);
  153.    struct brw_reg g4 = brw_vec8_grf(4, 0);
  154.  
  155.    brw_ADD(p, g0, g2, g4);
  156. }
  157.  
  158. static void
  159. gen_ADD_GRF_GRF_IMM(struct brw_compile *p)
  160. {
  161.    struct brw_reg g0 = brw_vec8_grf(0, 0);
  162.    struct brw_reg g2 = brw_vec8_grf(2, 0);
  163.  
  164.    brw_ADD(p, g0, g2, brw_imm_f(1.0));
  165. }
  166.  
  167. static void
  168. gen_ADD_GRF_GRF_IMM_d(struct brw_compile *p)
  169. {
  170.    struct brw_reg g0 = retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_D);
  171.    struct brw_reg g2 = retype(brw_vec8_grf(2, 0), BRW_REGISTER_TYPE_D);
  172.  
  173.    brw_ADD(p, g0, g2, brw_imm_d(1));
  174. }
  175.  
  176. static void
  177. gen_MOV_GRF_GRF(struct brw_compile *p)
  178. {
  179.    struct brw_reg g0 = brw_vec8_grf(0, 0);
  180.    struct brw_reg g2 = brw_vec8_grf(2, 0);
  181.  
  182.    brw_MOV(p, g0, g2);
  183. }
  184.  
  185. static void
  186. gen_ADD_MRF_GRF_GRF(struct brw_compile *p)
  187. {
  188.    struct brw_reg m6 = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 6, 0);
  189.    struct brw_reg g2 = brw_vec8_grf(2, 0);
  190.    struct brw_reg g4 = brw_vec8_grf(4, 0);
  191.  
  192.    brw_ADD(p, m6, g2, g4);
  193. }
  194.  
  195. static void
  196. gen_ADD_vec1_GRF_GRF_GRF(struct brw_compile *p)
  197. {
  198.    struct brw_reg g0 = brw_vec1_grf(0, 0);
  199.    struct brw_reg g2 = brw_vec1_grf(2, 0);
  200.    struct brw_reg g4 = brw_vec1_grf(4, 0);
  201.  
  202.    brw_ADD(p, g0, g2, g4);
  203. }
  204.  
  205. static void
  206. gen_PLN_MRF_GRF_GRF(struct brw_compile *p)
  207. {
  208.    struct brw_reg m6 = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 6, 0);
  209.    struct brw_reg interp = brw_vec1_grf(2, 0);
  210.    struct brw_reg g4 = brw_vec8_grf(4, 0);
  211.  
  212.    brw_PLN(p, m6, interp, g4);
  213. }
  214.  
  215. static void
  216. gen_f0_0_MOV_GRF_GRF(struct brw_compile *p)
  217. {
  218.    struct brw_reg g0 = brw_vec8_grf(0, 0);
  219.    struct brw_reg g2 = brw_vec8_grf(2, 0);
  220.  
  221.    brw_push_insn_state(p);
  222.    brw_set_predicate_control(p, true);
  223.    brw_MOV(p, g0, g2);
  224.    brw_pop_insn_state(p);
  225. }
  226.  
  227. /* The handling of f0.1 vs f0.0 changes between gen6 and gen7.  Explicitly test
  228.  * it, so that we run the fuzzing can run over all the other bits that might
  229.  * interact with it.
  230.  */
  231. static void
  232. gen_f0_1_MOV_GRF_GRF(struct brw_compile *p)
  233. {
  234.    struct brw_reg g0 = brw_vec8_grf(0, 0);
  235.    struct brw_reg g2 = brw_vec8_grf(2, 0);
  236.  
  237.    brw_push_insn_state(p);
  238.    brw_set_predicate_control(p, true);
  239.    current_insn(p)->bits2.da1.flag_subreg_nr = 1;
  240.    brw_MOV(p, g0, g2);
  241.    brw_pop_insn_state(p);
  242. }
  243.  
  244. struct {
  245.    void (*func)(struct brw_compile *p);
  246. } tests[] = {
  247.    { gen_MOV_GRF_GRF },
  248.    { gen_ADD_GRF_GRF_GRF },
  249.    { gen_ADD_GRF_GRF_IMM },
  250.    { gen_ADD_GRF_GRF_IMM_d },
  251.    { gen_ADD_MRF_GRF_GRF },
  252.    { gen_ADD_vec1_GRF_GRF_GRF },
  253.    { gen_PLN_MRF_GRF_GRF },
  254.    { gen_f0_0_MOV_GRF_GRF },
  255.    { gen_f0_1_MOV_GRF_GRF },
  256. };
  257.  
  258. static bool
  259. run_tests(struct brw_context *brw)
  260. {
  261.    bool fail = false;
  262.  
  263.    for (int i = 0; i < ARRAY_SIZE(tests); i++) {
  264.       for (int align_16 = 0; align_16 <= 1; align_16++) {
  265.          struct brw_compile *p = rzalloc(NULL, struct brw_compile);
  266.          brw_init_compile(brw, p, p);
  267.  
  268.          brw_set_predicate_control(p, BRW_PREDICATE_NONE);
  269.          if (align_16)
  270.             brw_set_access_mode(p, BRW_ALIGN_16);
  271.          else
  272.             brw_set_access_mode(p, BRW_ALIGN_1);
  273.  
  274.          tests[i].func(p);
  275.          assert(p->nr_insn == 1);
  276.  
  277.          if (!test_compact_instruction(p, p->store[0])) {
  278.             fail = true;
  279.             continue;
  280.          }
  281.  
  282.          if (!test_fuzz_compact_instruction(p, p->store[0])) {
  283.             fail = true;
  284.             continue;
  285.          }
  286.  
  287.          ralloc_free(p);
  288.       }
  289.    }
  290.  
  291.    return fail;
  292. }
  293.  
  294. int
  295. main(int argc, char **argv)
  296. {
  297.    struct brw_context *brw = calloc(1, sizeof(*brw));
  298.    brw->gen = 6;
  299.    bool fail = false;
  300.  
  301.    for (brw->gen = 6; brw->gen <= 7; brw->gen++) {
  302.       fail |= run_tests(brw);
  303.    }
  304.  
  305.    return fail;
  306. }
  307.