Edit

IABSD.fr/xenocara/lib/mesa/src/intel/compiler/brw_asm_tool.c

Branch :

  • Show log

    Commit

  • Author : jsg
    Date : 2025-06-05 11:23:11
    Hash : 67d6f117
    Message : Import Mesa 25.0.7

  • lib/mesa/src/intel/compiler/brw_asm_tool.c
  • /*
     * Copyright © 2018 Intel Corporation
     *
     * Permission is hereby granted, free of charge, to any person obtaining a
     * copy of this software and associated documentation files (the "Software"),
     * to deal in the Software without restriction, including without limitation
     * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     * and/or sell copies of the Software, and to permit persons to whom the
     * Software is furnished to do so, subject to the following conditions:
     *
     * The above copyright notice and this permission notice (including the next
     * paragraph) shall be included in all copies or substantial portions of the
     * Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     * SOFTWARE.
     *
     */
    
    #include <stdio.h>
    #include <string.h>
    #include <getopt.h>
    
    #include "util/ralloc.h"
    #include "compiler/brw_eu_inst.h"
    #include "dev/intel_device_info.h"
    
    #include "brw_asm.h"
    
    enum opt_output_type {
       OPT_OUTPUT_HEX,
       OPT_OUTPUT_C_LITERAL,
       OPT_OUTPUT_BIN,
    };
    
    static enum opt_output_type output_type = OPT_OUTPUT_BIN;
    
    static void
    print_help(const char *progname, FILE *file)
    {
       fprintf(file,
               "Usage: %s [OPTION] inputfile\n"
               "Assemble i965 instructions from input file.\n\n"
               "    -h, --help             display this help and exit\n"
               "    -t, --type=OUTPUT_TYPE OUTPUT_TYPE can be 'bin' (default if omitted),\n"
               "                           'c_literal', or 'hex'\n"
               "    -o, --output           specify output file\n"
               "        --compact          print compacted instructions\n"
               "    -g, --gen=platform     assemble instructions for given \n"
               "                           platform (3 letter platform name)\n"
               "Example:\n"
               "    i965_asm -g kbl input.asm -t hex -o output\n",
               progname);
    }
    
    static uint32_t
    get_dword(const brw_eu_inst *inst, int idx)
    {
       uint32_t dword;
       memcpy(&dword, (char *)inst + 4 * idx, sizeof(dword));
       return dword;
    }
    
    static void
    print_instruction(FILE *output, bool compact, const brw_eu_inst *instruction)
    {
       int byte_limit;
    
       byte_limit = (compact == true) ? 8 : 16;
    
       switch (output_type) {
       case OPT_OUTPUT_HEX: {
          fprintf(output, "%02x", ((unsigned char *)instruction)[0]);
    
          for (unsigned i = 1; i < byte_limit; i++) {
             fprintf(output, " %02x", ((unsigned char *)instruction)[i]);
          }
          break;
       }
       case OPT_OUTPUT_C_LITERAL: {
          fprintf(output, "\t0x%08x,", get_dword(instruction, 0));
    
          for (unsigned i = 1; i < byte_limit / 4; i++)
             fprintf(output, " 0x%08x,", get_dword(instruction, i));
    
          break;
       }
       case OPT_OUTPUT_BIN:
          fwrite(instruction, 1, byte_limit, output);
          break;
       }
    
       if (output_type != OPT_OUTPUT_BIN) {
          fprintf(output, "\n");
       }
    }
    
    static struct intel_device_info *
    i965_asm_init(uint16_t pci_id)
    {
       struct intel_device_info *devinfo;
    
       devinfo = malloc(sizeof *devinfo);
       if (devinfo == NULL)
          return NULL;
    
       if (!intel_get_device_info_from_pci_id(pci_id, devinfo)) {
          fprintf(stderr, "can't find device information: pci_id=0x%x\n",
                  pci_id);
          free(devinfo);
          return NULL;
       }
    
       if (devinfo->ver < 9) {
          fprintf(stderr, "device has gfx version %d but must be >= 9, try elk_asm instead",
                  devinfo->ver);
          exit(EXIT_FAILURE);
       }
    
       return devinfo;
    }
    
    
    
    int main(int argc, char **argv)
    {
       void *mem_ctx = ralloc_context(NULL);
       FILE *input_file = NULL;
       char *output_file = NULL;
       char c;
       FILE *output = stdout;
       bool help = false, compact = false;
       uint64_t pci_id = 0;
       struct intel_device_info *devinfo = NULL;
       int result = EXIT_FAILURE;
    
       const struct option i965_asm_opts[] = {
          { "help",          no_argument,       (int *) &help,      true },
          { "type",          required_argument, NULL,               't' },
          { "gen",           required_argument, NULL,               'g' },
          { "output",        required_argument, NULL,               'o' },
          { "compact",       no_argument,       (int *) &compact,   true },
          { NULL,            0,                 NULL,               0 }
       };
    
       while ((c = getopt_long(argc, argv, ":t:g:o:h", i965_asm_opts, NULL)) != -1) {
          switch (c) {
          case 'g': {
             const int id = intel_device_name_to_pci_device_id(optarg);
             if (id < 0) {
                fprintf(stderr, "can't parse gen: '%s', expected 3 letter "
                                "platform name\n", optarg);
                goto end;
             } else {
                pci_id = id;
             }
             break;
          }
          case 'h':
             help = true;
             print_help(argv[0], stderr);
             goto end;
          case 't': {
             if (strcmp(optarg, "hex") == 0) {
                output_type = OPT_OUTPUT_HEX;
             } else if (strcmp(optarg, "c_literal") == 0) {
                output_type = OPT_OUTPUT_C_LITERAL;
             } else if (strcmp(optarg, "bin") == 0) {
                output_type = OPT_OUTPUT_BIN;
             } else {
                fprintf(stderr, "invalid value for --type: %s\n", optarg);
                goto end;
             }
             break;
          }
          case 'o':
             output_file = strdup(optarg);
             break;
          case 0:
             break;
          case ':':
             fprintf(stderr, "%s: option `-%c' requires an argument\n",
                     argv[0], optopt);
             goto end;
          case '?':
          default:
             fprintf(stderr, "%s: option `-%c' is invalid: ignored\n",
                     argv[0], optopt);
             goto end;
          }
       }
    
       if (help || !pci_id) {
          print_help(argv[0], stderr);
          goto end;
       }
    
       if (!argv[optind]) {
          fprintf(stderr, "Please specify input file\n");
          goto end;
       }
    
       const char *filename = argv[optind];
       input_file = fopen(filename, "r");
       if (!input_file) {
          fprintf(stderr, "Unable to read input file : %s\n",
                  filename);
          goto end;
       }
    
       if (output_file) {
          output = fopen(output_file, "w");
          if (!output) {
             fprintf(stderr, "Couldn't open output file\n");
             goto end;
          }
       }
    
       devinfo = i965_asm_init(pci_id);
       if (!devinfo) {
          fprintf(stderr, "Unable to allocate memory for "
                          "intel_device_info struct instance.\n");
          goto end;
       }
    
       brw_assemble_result r = brw_assemble(mem_ctx, devinfo, input_file, filename,
                                            compact ? BRW_ASSEMBLE_COMPACT : 0);
       if (!r.bin)
          goto end;
    
       if (output_type == OPT_OUTPUT_C_LITERAL)
          fprintf(output, "{\n");
    
       for (int offset = 0; offset < r.bin_size;) {
          const brw_eu_inst *insn = r.bin + offset;
          bool compacted = false;
    
          if (compact && brw_eu_inst_cmpt_control(devinfo, insn)) {
                offset += 8;
                compacted = true;
          } else {
                offset += 16;
          }
    
          print_instruction(output, compacted, insn);
       }
    
       if (output_type == OPT_OUTPUT_C_LITERAL)
          fprintf(output, "}");
    
       result = EXIT_SUCCESS;
       goto end;
    
    end:
       free(output_file);
    
       if (input_file)
          fclose(input_file);
    
       if (output)
          fclose(output);
    
       ralloc_free(mem_ctx);
    
       if (devinfo)
          free(devinfo);
    
       exit(result);
    }