1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2018 Intel Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21bf215546Sopenharmony_ci * SOFTWARE.
22bf215546Sopenharmony_ci *
23bf215546Sopenharmony_ci */
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_ci#include <stdio.h>
26bf215546Sopenharmony_ci#include <getopt.h>
27bf215546Sopenharmony_ci#include "i965_asm.h"
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_cienum opt_output_type {
30bf215546Sopenharmony_ci   OPT_OUTPUT_HEX,
31bf215546Sopenharmony_ci   OPT_OUTPUT_C_LITERAL,
32bf215546Sopenharmony_ci   OPT_OUTPUT_BIN,
33bf215546Sopenharmony_ci};
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_ciextern FILE *yyin;
36bf215546Sopenharmony_cistruct brw_codegen *p;
37bf215546Sopenharmony_cistatic enum opt_output_type output_type = OPT_OUTPUT_BIN;
38bf215546Sopenharmony_cichar *input_filename = NULL;
39bf215546Sopenharmony_ciint errors;
40bf215546Sopenharmony_ci
41bf215546Sopenharmony_cistruct list_head instr_labels;
42bf215546Sopenharmony_cistruct list_head target_labels;
43bf215546Sopenharmony_ci
44bf215546Sopenharmony_cistatic void
45bf215546Sopenharmony_ciprint_help(const char *progname, FILE *file)
46bf215546Sopenharmony_ci{
47bf215546Sopenharmony_ci   fprintf(file,
48bf215546Sopenharmony_ci           "Usage: %s [OPTION] inputfile\n"
49bf215546Sopenharmony_ci           "Assemble i965 instructions from input file.\n\n"
50bf215546Sopenharmony_ci           "    -h, --help             display this help and exit\n"
51bf215546Sopenharmony_ci           "    -t, --type=OUTPUT_TYPE OUTPUT_TYPE can be 'bin' (default if omitted),\n"
52bf215546Sopenharmony_ci           "                           'c_literal', or 'hex'\n"
53bf215546Sopenharmony_ci           "    -o, --output           specify output file\n"
54bf215546Sopenharmony_ci           "        --compact          print compacted instructions\n"
55bf215546Sopenharmony_ci           "    -g, --gen=platform     assemble instructions for given \n"
56bf215546Sopenharmony_ci           "                           platform (3 letter platform name)\n"
57bf215546Sopenharmony_ci           "Example:\n"
58bf215546Sopenharmony_ci           "    i965_asm -g kbl input.asm -t hex -o output\n",
59bf215546Sopenharmony_ci           progname);
60bf215546Sopenharmony_ci}
61bf215546Sopenharmony_ci
62bf215546Sopenharmony_cistatic uint32_t
63bf215546Sopenharmony_ciget_dword(const brw_inst *inst, int idx)
64bf215546Sopenharmony_ci{
65bf215546Sopenharmony_ci   uint32_t dword;
66bf215546Sopenharmony_ci   memcpy(&dword, (char *)inst + 4 * idx, sizeof(dword));
67bf215546Sopenharmony_ci   return dword;
68bf215546Sopenharmony_ci}
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_cistatic void
71bf215546Sopenharmony_ciprint_instruction(FILE *output, bool compact, const brw_inst *instruction)
72bf215546Sopenharmony_ci{
73bf215546Sopenharmony_ci   int byte_limit;
74bf215546Sopenharmony_ci
75bf215546Sopenharmony_ci   byte_limit = (compact == true) ? 8 : 16;
76bf215546Sopenharmony_ci
77bf215546Sopenharmony_ci   switch (output_type) {
78bf215546Sopenharmony_ci   case OPT_OUTPUT_HEX: {
79bf215546Sopenharmony_ci      fprintf(output, "%02x", ((unsigned char *)instruction)[0]);
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_ci      for (unsigned i = 1; i < byte_limit; i++) {
82bf215546Sopenharmony_ci         fprintf(output, " %02x", ((unsigned char *)instruction)[i]);
83bf215546Sopenharmony_ci      }
84bf215546Sopenharmony_ci      break;
85bf215546Sopenharmony_ci   }
86bf215546Sopenharmony_ci   case OPT_OUTPUT_C_LITERAL: {
87bf215546Sopenharmony_ci      fprintf(output, "\t0x%08x,", get_dword(instruction, 0));
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ci      for (unsigned i = 1; i < byte_limit / 4; i++)
90bf215546Sopenharmony_ci         fprintf(output, " 0x%08x,", get_dword(instruction, i));
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci      break;
93bf215546Sopenharmony_ci   }
94bf215546Sopenharmony_ci   case OPT_OUTPUT_BIN:
95bf215546Sopenharmony_ci      fwrite(instruction, 1, byte_limit, output);
96bf215546Sopenharmony_ci      break;
97bf215546Sopenharmony_ci   }
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci   if (output_type != OPT_OUTPUT_BIN) {
100bf215546Sopenharmony_ci      fprintf(output, "\n");
101bf215546Sopenharmony_ci   }
102bf215546Sopenharmony_ci}
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_cistatic struct intel_device_info *
105bf215546Sopenharmony_cii965_disasm_init(uint16_t pci_id)
106bf215546Sopenharmony_ci{
107bf215546Sopenharmony_ci   struct intel_device_info *devinfo;
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ci   devinfo = malloc(sizeof *devinfo);
110bf215546Sopenharmony_ci   if (devinfo == NULL)
111bf215546Sopenharmony_ci      return NULL;
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci   if (!intel_get_device_info_from_pci_id(pci_id, devinfo)) {
114bf215546Sopenharmony_ci      fprintf(stderr, "can't find device information: pci_id=0x%x\n",
115bf215546Sopenharmony_ci              pci_id);
116bf215546Sopenharmony_ci      free(devinfo);
117bf215546Sopenharmony_ci      return NULL;
118bf215546Sopenharmony_ci   }
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_ci   return devinfo;
121bf215546Sopenharmony_ci}
122bf215546Sopenharmony_ci
123bf215546Sopenharmony_cistatic bool
124bf215546Sopenharmony_cii965_postprocess_labels()
125bf215546Sopenharmony_ci{
126bf215546Sopenharmony_ci   if (p->devinfo->ver < 6) {
127bf215546Sopenharmony_ci      return true;
128bf215546Sopenharmony_ci   }
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_ci   void *store = p->store;
131bf215546Sopenharmony_ci
132bf215546Sopenharmony_ci   struct target_label *tlabel;
133bf215546Sopenharmony_ci   struct instr_label *ilabel, *s;
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_ci   const unsigned to_bytes_scale = brw_jump_scale(p->devinfo);
136bf215546Sopenharmony_ci
137bf215546Sopenharmony_ci   LIST_FOR_EACH_ENTRY(tlabel, &target_labels, link) {
138bf215546Sopenharmony_ci      LIST_FOR_EACH_ENTRY_SAFE(ilabel, s, &instr_labels, link) {
139bf215546Sopenharmony_ci         if (!strcmp(tlabel->name, ilabel->name)) {
140bf215546Sopenharmony_ci            brw_inst *inst = store + ilabel->offset;
141bf215546Sopenharmony_ci
142bf215546Sopenharmony_ci            int relative_offset = (tlabel->offset - ilabel->offset) / sizeof(brw_inst);
143bf215546Sopenharmony_ci            relative_offset *= to_bytes_scale;
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_ci            unsigned opcode = brw_inst_opcode(p->isa, inst);
146bf215546Sopenharmony_ci
147bf215546Sopenharmony_ci            if (ilabel->type == INSTR_LABEL_JIP) {
148bf215546Sopenharmony_ci               switch (opcode) {
149bf215546Sopenharmony_ci               case BRW_OPCODE_IF:
150bf215546Sopenharmony_ci               case BRW_OPCODE_ELSE:
151bf215546Sopenharmony_ci               case BRW_OPCODE_ENDIF:
152bf215546Sopenharmony_ci               case BRW_OPCODE_WHILE:
153bf215546Sopenharmony_ci                  if (p->devinfo->ver >= 7) {
154bf215546Sopenharmony_ci                     brw_inst_set_jip(p->devinfo, inst, relative_offset);
155bf215546Sopenharmony_ci                  } else if (p->devinfo->ver == 6) {
156bf215546Sopenharmony_ci                     brw_inst_set_gfx6_jump_count(p->devinfo, inst, relative_offset);
157bf215546Sopenharmony_ci                  }
158bf215546Sopenharmony_ci                  break;
159bf215546Sopenharmony_ci               case BRW_OPCODE_BREAK:
160bf215546Sopenharmony_ci               case BRW_OPCODE_HALT:
161bf215546Sopenharmony_ci               case BRW_OPCODE_CONTINUE:
162bf215546Sopenharmony_ci                  brw_inst_set_jip(p->devinfo, inst, relative_offset);
163bf215546Sopenharmony_ci                  break;
164bf215546Sopenharmony_ci               default:
165bf215546Sopenharmony_ci                  fprintf(stderr, "Unknown opcode %d with JIP label\n", opcode);
166bf215546Sopenharmony_ci                  return false;
167bf215546Sopenharmony_ci               }
168bf215546Sopenharmony_ci            } else {
169bf215546Sopenharmony_ci               switch (opcode) {
170bf215546Sopenharmony_ci               case BRW_OPCODE_IF:
171bf215546Sopenharmony_ci               case BRW_OPCODE_ELSE:
172bf215546Sopenharmony_ci                  if (p->devinfo->ver > 7) {
173bf215546Sopenharmony_ci                     brw_inst_set_uip(p->devinfo, inst, relative_offset);
174bf215546Sopenharmony_ci                  } else if (p->devinfo->ver == 7) {
175bf215546Sopenharmony_ci                     brw_inst_set_uip(p->devinfo, inst, relative_offset);
176bf215546Sopenharmony_ci                  } else if (p->devinfo->ver == 6) {
177bf215546Sopenharmony_ci                     // Nothing
178bf215546Sopenharmony_ci                  }
179bf215546Sopenharmony_ci                  break;
180bf215546Sopenharmony_ci               case BRW_OPCODE_WHILE:
181bf215546Sopenharmony_ci               case BRW_OPCODE_ENDIF:
182bf215546Sopenharmony_ci                  fprintf(stderr, "WHILE/ENDIF cannot have UIP offset\n");
183bf215546Sopenharmony_ci                  return false;
184bf215546Sopenharmony_ci               case BRW_OPCODE_BREAK:
185bf215546Sopenharmony_ci               case BRW_OPCODE_CONTINUE:
186bf215546Sopenharmony_ci               case BRW_OPCODE_HALT:
187bf215546Sopenharmony_ci                  brw_inst_set_uip(p->devinfo, inst, relative_offset);
188bf215546Sopenharmony_ci                  break;
189bf215546Sopenharmony_ci               default:
190bf215546Sopenharmony_ci                  fprintf(stderr, "Unknown opcode %d with UIP label\n", opcode);
191bf215546Sopenharmony_ci                  return false;
192bf215546Sopenharmony_ci               }
193bf215546Sopenharmony_ci            }
194bf215546Sopenharmony_ci
195bf215546Sopenharmony_ci            list_del(&ilabel->link);
196bf215546Sopenharmony_ci         }
197bf215546Sopenharmony_ci      }
198bf215546Sopenharmony_ci   }
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_ci   LIST_FOR_EACH_ENTRY(ilabel, &instr_labels, link) {
201bf215546Sopenharmony_ci      fprintf(stderr, "Unknown label '%s'\n", ilabel->name);
202bf215546Sopenharmony_ci   }
203bf215546Sopenharmony_ci
204bf215546Sopenharmony_ci   return list_is_empty(&instr_labels);
205bf215546Sopenharmony_ci}
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_ciint main(int argc, char **argv)
208bf215546Sopenharmony_ci{
209bf215546Sopenharmony_ci   char *output_file = NULL;
210bf215546Sopenharmony_ci   char c;
211bf215546Sopenharmony_ci   FILE *output = stdout;
212bf215546Sopenharmony_ci   bool help = false, compact = false;
213bf215546Sopenharmony_ci   void *store;
214bf215546Sopenharmony_ci   uint64_t pci_id = 0;
215bf215546Sopenharmony_ci   int offset = 0, err;
216bf215546Sopenharmony_ci   int start_offset = 0;
217bf215546Sopenharmony_ci   struct disasm_info *disasm_info;
218bf215546Sopenharmony_ci   struct intel_device_info *devinfo = NULL;
219bf215546Sopenharmony_ci   int result = EXIT_FAILURE;
220bf215546Sopenharmony_ci   list_inithead(&instr_labels);
221bf215546Sopenharmony_ci   list_inithead(&target_labels);
222bf215546Sopenharmony_ci
223bf215546Sopenharmony_ci   const struct option i965_asm_opts[] = {
224bf215546Sopenharmony_ci      { "help",          no_argument,       (int *) &help,      true },
225bf215546Sopenharmony_ci      { "type",          required_argument, NULL,               't' },
226bf215546Sopenharmony_ci      { "gen",           required_argument, NULL,               'g' },
227bf215546Sopenharmony_ci      { "output",        required_argument, NULL,               'o' },
228bf215546Sopenharmony_ci      { "compact",       no_argument,       (int *) &compact,   true },
229bf215546Sopenharmony_ci      { NULL,            0,                 NULL,               0 }
230bf215546Sopenharmony_ci   };
231bf215546Sopenharmony_ci
232bf215546Sopenharmony_ci   while ((c = getopt_long(argc, argv, ":t:g:o:h", i965_asm_opts, NULL)) != -1) {
233bf215546Sopenharmony_ci      switch (c) {
234bf215546Sopenharmony_ci      case 'g': {
235bf215546Sopenharmony_ci         const int id = intel_device_name_to_pci_device_id(optarg);
236bf215546Sopenharmony_ci         if (id < 0) {
237bf215546Sopenharmony_ci            fprintf(stderr, "can't parse gen: '%s', expected 3 letter "
238bf215546Sopenharmony_ci                            "platform name\n", optarg);
239bf215546Sopenharmony_ci            goto end;
240bf215546Sopenharmony_ci         } else {
241bf215546Sopenharmony_ci            pci_id = id;
242bf215546Sopenharmony_ci         }
243bf215546Sopenharmony_ci         break;
244bf215546Sopenharmony_ci      }
245bf215546Sopenharmony_ci      case 'h':
246bf215546Sopenharmony_ci         help = true;
247bf215546Sopenharmony_ci         print_help(argv[0], stderr);
248bf215546Sopenharmony_ci         goto end;
249bf215546Sopenharmony_ci      case 't': {
250bf215546Sopenharmony_ci         if (strcmp(optarg, "hex") == 0) {
251bf215546Sopenharmony_ci            output_type = OPT_OUTPUT_HEX;
252bf215546Sopenharmony_ci         } else if (strcmp(optarg, "c_literal") == 0) {
253bf215546Sopenharmony_ci            output_type = OPT_OUTPUT_C_LITERAL;
254bf215546Sopenharmony_ci         } else if (strcmp(optarg, "bin") == 0) {
255bf215546Sopenharmony_ci            output_type = OPT_OUTPUT_BIN;
256bf215546Sopenharmony_ci         } else {
257bf215546Sopenharmony_ci            fprintf(stderr, "invalid value for --type: %s\n", optarg);
258bf215546Sopenharmony_ci            goto end;
259bf215546Sopenharmony_ci         }
260bf215546Sopenharmony_ci         break;
261bf215546Sopenharmony_ci      }
262bf215546Sopenharmony_ci      case 'o':
263bf215546Sopenharmony_ci         output_file = strdup(optarg);
264bf215546Sopenharmony_ci         break;
265bf215546Sopenharmony_ci      case 0:
266bf215546Sopenharmony_ci         break;
267bf215546Sopenharmony_ci      case ':':
268bf215546Sopenharmony_ci         fprintf(stderr, "%s: option `-%c' requires an argument\n",
269bf215546Sopenharmony_ci                 argv[0], optopt);
270bf215546Sopenharmony_ci         goto end;
271bf215546Sopenharmony_ci      case '?':
272bf215546Sopenharmony_ci      default:
273bf215546Sopenharmony_ci         fprintf(stderr, "%s: option `-%c' is invalid: ignored\n",
274bf215546Sopenharmony_ci                 argv[0], optopt);
275bf215546Sopenharmony_ci         goto end;
276bf215546Sopenharmony_ci      }
277bf215546Sopenharmony_ci   }
278bf215546Sopenharmony_ci
279bf215546Sopenharmony_ci   if (help || !pci_id) {
280bf215546Sopenharmony_ci      print_help(argv[0], stderr);
281bf215546Sopenharmony_ci      goto end;
282bf215546Sopenharmony_ci   }
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_ci   if (!argv[optind]) {
285bf215546Sopenharmony_ci      fprintf(stderr, "Please specify input file\n");
286bf215546Sopenharmony_ci      goto end;
287bf215546Sopenharmony_ci   }
288bf215546Sopenharmony_ci
289bf215546Sopenharmony_ci   input_filename = strdup(argv[optind]);
290bf215546Sopenharmony_ci   yyin = fopen(input_filename, "r");
291bf215546Sopenharmony_ci   if (!yyin) {
292bf215546Sopenharmony_ci      fprintf(stderr, "Unable to read input file : %s\n",
293bf215546Sopenharmony_ci              input_filename);
294bf215546Sopenharmony_ci      goto end;
295bf215546Sopenharmony_ci   }
296bf215546Sopenharmony_ci
297bf215546Sopenharmony_ci   if (output_file) {
298bf215546Sopenharmony_ci      output = fopen(output_file, "w");
299bf215546Sopenharmony_ci      if (!output) {
300bf215546Sopenharmony_ci         fprintf(stderr, "Couldn't open output file\n");
301bf215546Sopenharmony_ci         goto end;
302bf215546Sopenharmony_ci      }
303bf215546Sopenharmony_ci   }
304bf215546Sopenharmony_ci
305bf215546Sopenharmony_ci   devinfo = i965_disasm_init(pci_id);
306bf215546Sopenharmony_ci   if (!devinfo) {
307bf215546Sopenharmony_ci      fprintf(stderr, "Unable to allocate memory for "
308bf215546Sopenharmony_ci                      "intel_device_info struct instance.\n");
309bf215546Sopenharmony_ci      goto end;
310bf215546Sopenharmony_ci   }
311bf215546Sopenharmony_ci
312bf215546Sopenharmony_ci   struct brw_isa_info isa;
313bf215546Sopenharmony_ci   brw_init_isa_info(&isa, devinfo);
314bf215546Sopenharmony_ci
315bf215546Sopenharmony_ci   p = rzalloc(NULL, struct brw_codegen);
316bf215546Sopenharmony_ci   brw_init_codegen(&isa, p, p);
317bf215546Sopenharmony_ci   p->automatic_exec_sizes = false;
318bf215546Sopenharmony_ci
319bf215546Sopenharmony_ci   err = yyparse();
320bf215546Sopenharmony_ci   if (err || errors)
321bf215546Sopenharmony_ci      goto end;
322bf215546Sopenharmony_ci
323bf215546Sopenharmony_ci   if (!i965_postprocess_labels())
324bf215546Sopenharmony_ci      goto end;
325bf215546Sopenharmony_ci
326bf215546Sopenharmony_ci   store = p->store;
327bf215546Sopenharmony_ci
328bf215546Sopenharmony_ci   disasm_info = disasm_initialize(p->isa, NULL);
329bf215546Sopenharmony_ci   if (!disasm_info) {
330bf215546Sopenharmony_ci      fprintf(stderr, "Unable to initialize disasm_info struct instance\n");
331bf215546Sopenharmony_ci      goto end;
332bf215546Sopenharmony_ci   }
333bf215546Sopenharmony_ci
334bf215546Sopenharmony_ci   if (output_type == OPT_OUTPUT_C_LITERAL)
335bf215546Sopenharmony_ci      fprintf(output, "{\n");
336bf215546Sopenharmony_ci
337bf215546Sopenharmony_ci   brw_validate_instructions(p->isa, p->store, 0,
338bf215546Sopenharmony_ci                             p->next_insn_offset, disasm_info);
339bf215546Sopenharmony_ci
340bf215546Sopenharmony_ci   const int nr_insn = (p->next_insn_offset - start_offset) / 16;
341bf215546Sopenharmony_ci
342bf215546Sopenharmony_ci   if (compact)
343bf215546Sopenharmony_ci      brw_compact_instructions(p, start_offset, disasm_info);
344bf215546Sopenharmony_ci
345bf215546Sopenharmony_ci   for (int i = 0; i < nr_insn; i++) {
346bf215546Sopenharmony_ci      const brw_inst *insn = store + offset;
347bf215546Sopenharmony_ci      bool compacted = false;
348bf215546Sopenharmony_ci
349bf215546Sopenharmony_ci      if (compact && brw_inst_cmpt_control(p->devinfo, insn)) {
350bf215546Sopenharmony_ci            offset += 8;
351bf215546Sopenharmony_ci            compacted = true;
352bf215546Sopenharmony_ci      } else {
353bf215546Sopenharmony_ci            offset += 16;
354bf215546Sopenharmony_ci      }
355bf215546Sopenharmony_ci
356bf215546Sopenharmony_ci      print_instruction(output, compacted, insn);
357bf215546Sopenharmony_ci   }
358bf215546Sopenharmony_ci
359bf215546Sopenharmony_ci   ralloc_free(disasm_info);
360bf215546Sopenharmony_ci
361bf215546Sopenharmony_ci   if (output_type == OPT_OUTPUT_C_LITERAL)
362bf215546Sopenharmony_ci      fprintf(output, "}");
363bf215546Sopenharmony_ci
364bf215546Sopenharmony_ci   result = EXIT_SUCCESS;
365bf215546Sopenharmony_ci   goto end;
366bf215546Sopenharmony_ci
367bf215546Sopenharmony_ciend:
368bf215546Sopenharmony_ci   free(input_filename);
369bf215546Sopenharmony_ci   free(output_file);
370bf215546Sopenharmony_ci
371bf215546Sopenharmony_ci   if (yyin)
372bf215546Sopenharmony_ci      fclose(yyin);
373bf215546Sopenharmony_ci
374bf215546Sopenharmony_ci   if (output)
375bf215546Sopenharmony_ci      fclose(output);
376bf215546Sopenharmony_ci
377bf215546Sopenharmony_ci   if (p)
378bf215546Sopenharmony_ci      ralloc_free(p);
379bf215546Sopenharmony_ci
380bf215546Sopenharmony_ci   if (devinfo)
381bf215546Sopenharmony_ci      free(devinfo);
382bf215546Sopenharmony_ci
383bf215546Sopenharmony_ci   exit(result);
384bf215546Sopenharmony_ci}
385