Subversion Repositories Kolibri OS

Rev

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 "util/ralloc.h"
  28. #include "brw_context.h"
  29. #include "brw_eu.h"
  30.  
  31. static bool
  32. test_compact_instruction(struct brw_codegen *p, brw_inst src)
  33. {
  34.    brw_compact_inst dst;
  35.    memset(&dst, 0xd0, sizeof(dst));
  36.  
  37.    if (brw_try_compact_instruction(p->devinfo, &dst, &src)) {
  38.       brw_inst uncompacted;
  39.  
  40.       brw_uncompact_instruction(p->devinfo, &uncompacted, &dst);
  41.       if (memcmp(&uncompacted, &src, sizeof(src))) {
  42.          brw_debug_compact_uncompact(p->devinfo, &src, &uncompacted);
  43.          return false;
  44.       }
  45.    } else {
  46.       brw_compact_inst unchanged;
  47.       memset(&unchanged, 0xd0, sizeof(unchanged));
  48.       /* It's not supposed to change dst unless it compacted. */
  49.       if (memcmp(&unchanged, &dst, sizeof(dst))) {
  50.          fprintf(stderr, "Failed to compact, but dst changed\n");
  51.          fprintf(stderr, "  Instruction: ");
  52.          brw_disassemble_inst(stderr, p->devinfo, &src, false);
  53.          return false;
  54.       }
  55.    }
  56.  
  57.    return true;
  58. }
  59.  
  60. /**
  61.  * When doing fuzz testing, pad bits won't round-trip.
  62.  *
  63.  * This sort of a superset of skip_bit, which is testing for changing bits that
  64.  * aren't worth testing for fuzzing.  We also just want to clear bits that
  65.  * become meaningless once fuzzing twiddles a related bit.
  66.  */
  67. static void
  68. clear_pad_bits(const struct brw_device_info *devinfo, brw_inst *inst)
  69. {
  70.    if (brw_inst_opcode(devinfo, inst) != BRW_OPCODE_SEND &&
  71.        brw_inst_opcode(devinfo, inst) != BRW_OPCODE_SENDC &&
  72.        brw_inst_opcode(devinfo, inst) != BRW_OPCODE_BREAK &&
  73.        brw_inst_opcode(devinfo, inst) != BRW_OPCODE_CONTINUE &&
  74.        brw_inst_src0_reg_file(devinfo, inst) != BRW_IMMEDIATE_VALUE &&
  75.        brw_inst_src1_reg_file(devinfo, inst) != BRW_IMMEDIATE_VALUE) {
  76.       brw_inst_set_bits(inst, 127, 111, 0);
  77.    }
  78. }
  79.  
  80. static bool
  81. skip_bit(const struct brw_device_info *devinfo, brw_inst *src, int bit)
  82. {
  83.    /* pad bit */
  84.    if (bit == 7)
  85.       return true;
  86.  
  87.    /* The compact bit -- uncompacted can't have it set. */
  88.    if (bit == 29)
  89.       return true;
  90.  
  91.    /* pad bit */
  92.    if (bit == 47)
  93.       return true;
  94.  
  95.    /* pad bits */
  96.    if (bit >= 90 && bit <= 95)
  97.       return true;
  98.  
  99.    /* sometimes these are pad bits. */
  100.    if (brw_inst_opcode(devinfo, src) != BRW_OPCODE_SEND &&
  101.        brw_inst_opcode(devinfo, src) != BRW_OPCODE_SENDC &&
  102.        brw_inst_opcode(devinfo, src) != BRW_OPCODE_BREAK &&
  103.        brw_inst_opcode(devinfo, src) != BRW_OPCODE_CONTINUE &&
  104.        brw_inst_src0_reg_file(devinfo, src) != BRW_IMMEDIATE_VALUE &&
  105.        brw_inst_src1_reg_file(devinfo, src) != BRW_IMMEDIATE_VALUE &&
  106.        bit >= 121) {
  107.       return true;
  108.    }
  109.  
  110.    return false;
  111. }
  112.  
  113. static bool
  114. test_fuzz_compact_instruction(struct brw_codegen *p, brw_inst src)
  115. {
  116.    for (int bit0 = 0; bit0 < 128; bit0++) {
  117.       if (skip_bit(p->devinfo, &src, bit0))
  118.          continue;
  119.  
  120.       for (int bit1 = 0; bit1 < 128; bit1++) {
  121.          brw_inst instr = src;
  122.          uint32_t *bits = (uint32_t *)&instr;
  123.  
  124.          if (skip_bit(p->devinfo, &src, bit1))
  125.             continue;
  126.  
  127.          bits[bit0 / 32] ^= (1 << (bit0 & 31));
  128.          bits[bit1 / 32] ^= (1 << (bit1 & 31));
  129.  
  130.          clear_pad_bits(p->devinfo, &instr);
  131.  
  132.          if (!test_compact_instruction(p, instr)) {
  133.             printf("  twiddled bits for fuzzing %d, %d\n", bit0, bit1);
  134.             return false;
  135.          }
  136.       }
  137.    }
  138.  
  139.    return true;
  140. }
  141.  
  142. static void
  143. gen_ADD_GRF_GRF_GRF(struct brw_codegen *p)
  144. {
  145.    struct brw_reg g0 = brw_vec8_grf(0, 0);
  146.    struct brw_reg g2 = brw_vec8_grf(2, 0);
  147.    struct brw_reg g4 = brw_vec8_grf(4, 0);
  148.  
  149.    brw_ADD(p, g0, g2, g4);
  150. }
  151.  
  152. static void
  153. gen_ADD_GRF_GRF_IMM(struct brw_codegen *p)
  154. {
  155.    struct brw_reg g0 = brw_vec8_grf(0, 0);
  156.    struct brw_reg g2 = brw_vec8_grf(2, 0);
  157.  
  158.    brw_ADD(p, g0, g2, brw_imm_f(1.0));
  159. }
  160.  
  161. static void
  162. gen_ADD_GRF_GRF_IMM_d(struct brw_codegen *p)
  163. {
  164.    struct brw_reg g0 = retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_D);
  165.    struct brw_reg g2 = retype(brw_vec8_grf(2, 0), BRW_REGISTER_TYPE_D);
  166.  
  167.    brw_ADD(p, g0, g2, brw_imm_d(1));
  168. }
  169.  
  170. static void
  171. gen_MOV_GRF_GRF(struct brw_codegen *p)
  172. {
  173.    struct brw_reg g0 = brw_vec8_grf(0, 0);
  174.    struct brw_reg g2 = brw_vec8_grf(2, 0);
  175.  
  176.    brw_MOV(p, g0, g2);
  177. }
  178.  
  179. static void
  180. gen_ADD_MRF_GRF_GRF(struct brw_codegen *p)
  181. {
  182.    struct brw_reg m6 = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 6, 0);
  183.    struct brw_reg g2 = brw_vec8_grf(2, 0);
  184.    struct brw_reg g4 = brw_vec8_grf(4, 0);
  185.  
  186.    brw_ADD(p, m6, g2, g4);
  187. }
  188.  
  189. static void
  190. gen_ADD_vec1_GRF_GRF_GRF(struct brw_codegen *p)
  191. {
  192.    struct brw_reg g0 = brw_vec1_grf(0, 0);
  193.    struct brw_reg g2 = brw_vec1_grf(2, 0);
  194.    struct brw_reg g4 = brw_vec1_grf(4, 0);
  195.  
  196.    brw_ADD(p, g0, g2, g4);
  197. }
  198.  
  199. static void
  200. gen_PLN_MRF_GRF_GRF(struct brw_codegen *p)
  201. {
  202.    struct brw_reg m6 = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 6, 0);
  203.    struct brw_reg interp = brw_vec1_grf(2, 0);
  204.    struct brw_reg g4 = brw_vec8_grf(4, 0);
  205.  
  206.    brw_PLN(p, m6, interp, g4);
  207. }
  208.  
  209. static void
  210. gen_f0_0_MOV_GRF_GRF(struct brw_codegen *p)
  211. {
  212.    struct brw_reg g0 = brw_vec8_grf(0, 0);
  213.    struct brw_reg g2 = brw_vec8_grf(2, 0);
  214.  
  215.    brw_push_insn_state(p);
  216.    brw_set_default_predicate_control(p, true);
  217.    brw_MOV(p, g0, g2);
  218.    brw_pop_insn_state(p);
  219. }
  220.  
  221. /* The handling of f0.1 vs f0.0 changes between gen6 and gen7.  Explicitly test
  222.  * it, so that we run the fuzzing can run over all the other bits that might
  223.  * interact with it.
  224.  */
  225. static void
  226. gen_f0_1_MOV_GRF_GRF(struct brw_codegen *p)
  227. {
  228.    struct brw_reg g0 = brw_vec8_grf(0, 0);
  229.    struct brw_reg g2 = brw_vec8_grf(2, 0);
  230.  
  231.    brw_push_insn_state(p);
  232.    brw_set_default_predicate_control(p, true);
  233.    brw_inst *mov = brw_MOV(p, g0, g2);
  234.    brw_inst_set_flag_subreg_nr(p->devinfo, mov, 1);
  235.    brw_pop_insn_state(p);
  236. }
  237.  
  238. struct {
  239.    void (*func)(struct brw_codegen *p);
  240. } tests[] = {
  241.    { gen_MOV_GRF_GRF },
  242.    { gen_ADD_GRF_GRF_GRF },
  243.    { gen_ADD_GRF_GRF_IMM },
  244.    { gen_ADD_GRF_GRF_IMM_d },
  245.    { gen_ADD_MRF_GRF_GRF },
  246.    { gen_ADD_vec1_GRF_GRF_GRF },
  247.    { gen_PLN_MRF_GRF_GRF },
  248.    { gen_f0_0_MOV_GRF_GRF },
  249.    { gen_f0_1_MOV_GRF_GRF },
  250. };
  251.  
  252. static bool
  253. run_tests(const struct brw_device_info *devinfo)
  254. {
  255.    bool fail = false;
  256.  
  257.    for (int i = 0; i < ARRAY_SIZE(tests); i++) {
  258.       for (int align_16 = 0; align_16 <= 1; align_16++) {
  259.          struct brw_codegen *p = rzalloc(NULL, struct brw_codegen);
  260.          brw_init_codegen(devinfo, p, p);
  261.  
  262.          brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
  263.          if (align_16)
  264.             brw_set_default_access_mode(p, BRW_ALIGN_16);
  265.          else
  266.             brw_set_default_access_mode(p, BRW_ALIGN_1);
  267.  
  268.          tests[i].func(p);
  269.          assert(p->nr_insn == 1);
  270.  
  271.          if (!test_compact_instruction(p, p->store[0])) {
  272.             fail = true;
  273.             continue;
  274.          }
  275.  
  276.          if (!test_fuzz_compact_instruction(p, p->store[0])) {
  277.             fail = true;
  278.             continue;
  279.          }
  280.  
  281.          ralloc_free(p);
  282.       }
  283.    }
  284.  
  285.    return fail;
  286. }
  287.  
  288. int
  289. main(int argc, char **argv)
  290. {
  291.    struct brw_device_info *devinfo = calloc(1, sizeof(*devinfo));
  292.    devinfo->gen = 6;
  293.    bool fail = false;
  294.  
  295.    for (devinfo->gen = 6; devinfo->gen <= 7; devinfo->gen++) {
  296.       fail |= run_tests(devinfo);
  297.    }
  298.  
  299.    return fail;
  300. }
  301.