3 * Copyright(c) 2019-2023 rev.ng Labs Srl. All Rights Reserved.
5 * This program is distributed in the hope that it will be useful,
6 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8 * GNU General Public License for more details.
10 * You should have received a copy of the GNU General Public License
11 * along with this program; if not, see <http://www.gnu.org/licenses/>.
14 #include "idef-parser.h"
15 #include "parser-helpers.h"
16 #include "idef-parser.tab.h"
17 #include "idef-parser.yy.h"
19 /* Uncomment this to disable yyasserts */
22 #define ERR_LINE_CONTEXT 40
26 %lex
-param
{void *scanner
}
27 %parse
-param
{void *scanner
}
28 %parse
-param
{Context
*c
}
30 %define parse.
error verbose
31 %define parse.lac full
43 HexSignedness signedness
;
53 %token ABS CROUND ROUND CIRCADD COUNTONES INC DEC ANDA ORA XORA PLUSPLUS ASL
54 %token ASR LSR EQ NEQ LTE GTE MIN MAX ANDL FOR ICIRC IF MUN FSCR FCHK SXT
55 %token ZXT CONSTEXT LOCNT BREV SIGN LOAD STORE PC LPCFG
56 %token LOAD_CANCEL STORE_CANCEL CANCEL IDENTITY ROTL INSBITS SETBITS EXTRANGE
57 %token CAST4_8U FAIL CARRY_FROM_ADD ADDSAT64 LSBNEW
58 %token TYPE_SIZE_T TYPE_INT TYPE_SIGNED TYPE_UNSIGNED TYPE_LONG
60 %token
<rvalue
> REG IMM PRED
64 %token
<cast
> CAST DEPOSIT SETHALF
65 %token
<extract
> EXTRACT
67 %type
<rvalue
> rvalue lvalue VAR assign_statement var var_decl var_type
69 %type
<rvalue
> TYPE_SIGNED TYPE_UNSIGNED TYPE_INT TYPE_LONG TYPE_SIZE_T
70 %type
<index
> if_stmt IF
71 %type
<signedness
> SIGN
73 /* Operator Precedences */
79 %right INC DEC ANDA ORA XORA
99 /* Input file containing the description of each hexagon instruction */
102 /* Suppress warning about unused yynerrs */
108 instructions
: instruction instructions
123 gen_inst_code
(c
, &@
1);
125 |
error /* Recover gracefully after instruction compilation error */
132 |
'(' argument_list
')';
134 argument_list
: argument_decl
',' argument_list
140 track_string
(c
, $1.var.name
);
146 * Here the integer types are defined from valid combinations of
147 * `signed`, `unsigned`, `int`, and `long` tokens. The `signed`
148 * and `unsigned` tokens are here assumed to always be placed
149 * first in the type declaration, which is not the case in
150 * normal C. Similarly, `int` is assumed to always be placed
155 | TYPE_SIGNED TYPE_INT
;
156 type_uint
: TYPE_UNSIGNED
157 | TYPE_UNSIGNED TYPE_INT
;
158 type_ulonglong
: TYPE_UNSIGNED TYPE_LONG TYPE_LONG
159 | TYPE_UNSIGNED TYPE_LONG TYPE_LONG TYPE_INT
;
162 * Here the various valid int types defined above specify
163 * their `signedness` and `bit_width`. The LP64 convention
164 * is assumed where longs are 64-bit, long longs are then
165 * assumed to also be 64-bit.
167 var_type
: TYPE_SIZE_T
169 yyassert
(c
, &@
1, $1.bit_width
<= 64,
170 "Variables with size > 64-bit are not supported!");
175 $$.signedness
= SIGNED
;
180 $$.signedness
= UNSIGNED
;
185 $$.signedness
= UNSIGNED
;
190 /* Rule to capture declarations of VARs */
191 var_decl
: var_type IMM
194 * Rule to capture "int i;" declarations since "i" is special
195 * and assumed to be always be IMM. Moreover, "i" is only
196 * assumed to be used in for-loops.
198 * Therefore we want to NOP these declarations.
200 yyassert
(c
, &@
2, $2.imm.type
== I
,
201 "Variable declaration with immedaties only allowed"
202 " for the loop induction variable \"i\"");
208 * Allocate new variable, this checks that it hasn't already
211 gen_varid_allocate
(c
, &@
1, &$2, $1.bit_width
, $1.signedness
);
212 /* Copy var for variable name */
214 /* Copy type info from var_type */
215 $$.signedness
= $1.signedness
;
216 $$.bit_width
= $1.bit_width
;
220 /* Return the modified registers list */
221 code
: '{' statements
'}'
223 c
->inst.code_begin
= c
->input_buffer
+ @
2.first_column
- 1;
224 c
->inst.code_end
= c
->input_buffer
+ @
2.last_column
- 1;
235 emit_arg
(c
, &@
1, &$1);
236 /* Enqueue register into initialization list */
237 g_array_append_val
(c
->inst.init_list
, $1);
241 emit_arg
(c
, &@
1, &$1);
242 /* Enqueue predicate into initialization list */
243 g_array_append_val
(c
->inst.init_list
, $1);
247 emit_arg
(c
, &@
2, &$2);
251 emit_arg
(c
, &@
2, &$2);
255 EMIT_SIG
(c
, ", int %ciV", $1.imm.id
);
259 code_block
: '{' statements
'}'
263 /* A list of one or more statements */
264 statements
: statements statement
268 /* Statements can be assignment (rvalue ';'), control or memory statements */
269 statement
: control_statement
276 assign_statement
: lvalue
'=' rvalue
278 @
1.last_column
= @
3.last_column
;
279 gen_assign
(c
, &@
1, &$1, &$3);
282 | var_decl
'=' rvalue
284 @
1.last_column
= @
3.last_column
;
285 gen_assign
(c
, &@
1, &$1, &$3);
290 @
1.last_column
= @
3.last_column
;
291 HexValue tmp
= gen_bin_op
(c
, &@
1, ADD_OP
, &$1, &$3);
292 gen_assign
(c
, &@
1, &$1, &tmp
);
297 @
1.last_column
= @
3.last_column
;
298 HexValue tmp
= gen_bin_op
(c
, &@
1, SUB_OP
, &$1, &$3);
299 gen_assign
(c
, &@
1, &$1, &tmp
);
304 @
1.last_column
= @
3.last_column
;
305 HexValue tmp
= gen_bin_op
(c
, &@
1, ANDB_OP
, &$1, &$3);
306 gen_assign
(c
, &@
1, &$1, &tmp
);
311 @
1.last_column
= @
3.last_column
;
312 HexValue tmp
= gen_bin_op
(c
, &@
1, ORB_OP
, &$1, &$3);
313 gen_assign
(c
, &@
1, &$1, &tmp
);
318 @
1.last_column
= @
3.last_column
;
319 HexValue tmp
= gen_bin_op
(c
, &@
1, XORB_OP
, &$1, &$3);
320 gen_assign
(c
, &@
1, &$1, &tmp
);
325 @
1.last_column
= @
3.last_column
;
326 gen_pred_assign
(c
, &@
1, &$1, &$3);
330 @
1.last_column
= @
3.last_column
;
331 yyassert
(c
, &@
1, $3.type
== IMMEDIATE
,
332 "Cannot assign non-immediate to immediate!");
333 yyassert
(c
, &@
1, $1.imm.type
== VARIABLE
,
334 "Cannot assign to non-variable!");
335 /* Assign to the function argument */
336 OUT
(c
, &@
1, &$1, " = ", &$3, ";\n");
339 | LOAD
'(' IMM
',' IMM
',' SIGN
',' var
',' lvalue
')'
341 @
1.last_column
= @
12.last_column
;
342 yyassert
(c
, &@
1, !is_inside_ternary
(c
),
343 "Assignment side-effect not modeled!");
344 yyassert
(c
, &@
1, $3.imm.value
== 1,
345 "LOAD of arrays not supported!");
346 gen_load
(c
, &@
1, &$5, $7, &$9, &$11);
348 | STORE
'(' IMM
',' IMM
',' var
',' rvalue
')'
349 /* Store primitive */
351 @
1.last_column
= @
10.last_column
;
352 yyassert
(c
, &@
1, !is_inside_ternary
(c
),
353 "Assignment side-effect not modeled!");
354 yyassert
(c
, &@
1, $3.imm.value
== 1,
355 "STORE of arrays not supported!");
356 gen_store
(c
, &@
1, &$5, &$7, &$9);
360 @
1.last_column
= @
3.last_column
;
361 yyassert
(c
, &@
1, !is_inside_ternary
(c
),
362 "Assignment side-effect not modeled!");
363 $3 = gen_rvalue_truncate
(c
, &@
1, &$3);
364 $3 = rvalue_materialize
(c
, &@
1, &$3);
365 OUT
(c
, &@
1, "gen_set_usr_field(ctx, USR_LPCFG, ", &$3, ");\n");
367 | DEPOSIT
'(' rvalue
',' rvalue
',' rvalue
')'
369 @
1.last_column
= @
8.last_column
;
370 yyassert
(c
, &@
1, !is_inside_ternary
(c
),
371 "Assignment side-effect not modeled!");
372 gen_deposit_op
(c
, &@
1, &$5, &$7, &$3, &$1);
374 | SETHALF
'(' rvalue
',' lvalue
',' rvalue
')'
376 @
1.last_column
= @
8.last_column
;
377 yyassert
(c
, &@
1, !is_inside_ternary
(c
),
378 "Assignment side-effect not modeled!");
379 gen_sethalf
(c
, &@
1, &$1, &$3, &$5, &$7);
381 | SETBITS
'(' rvalue
',' rvalue
',' rvalue
',' rvalue
')'
383 @
1.last_column
= @
10.last_column
;
384 yyassert
(c
, &@
1, !is_inside_ternary
(c
),
385 "Assignment side-effect not modeled!");
386 gen_setbits
(c
, &@
1, &$3, &$5, &$7, &$9);
388 | INSBITS
'(' lvalue
',' rvalue
',' rvalue
',' rvalue
')'
390 @
1.last_column
= @
10.last_column
;
391 yyassert
(c
, &@
1, !is_inside_ternary
(c
),
392 "Assignment side-effect not modeled!");
393 gen_rdeposit_op
(c
, &@
1, &$3, &$9, &$7, &$5);
395 | IDENTITY
'(' rvalue
')'
397 @
1.last_column
= @
4.last_column
;
402 control_statement
: frame_check
408 frame_check
: FCHK
'(' rvalue
',' rvalue
')' ';'
411 cancel_statement
: LOAD_CANCEL
413 gen_load_cancel
(c
, &@
1);
422 if_statement
: if_stmt
425 OUT
(c
, &@
1, "gen_set_label(if_label_", &$1, ");\n");
429 @
1.last_column
= @
2.last_column
;
430 $2 = gen_if_else
(c
, &@
1, $1);
434 OUT
(c
, &@
1, "gen_set_label(if_label_", &$2, ");\n");
438 for_statement
: FOR
'(' IMM
'=' IMM
';' IMM
'<' IMM
';' IMM PLUSPLUS
')'
444 "Loop induction variable must be \"i\"");
445 @
1.last_column
= @
13.last_column
;
446 OUT
(c
, &@
1, "for (int ", &$3, " = ", &$5, "; ",
448 OUT
(c
, &@
1, "; ", &$11, "++) {\n");
456 if_stmt
: IF
'(' rvalue
')'
458 @
1.last_column
= @
3.last_column
;
459 $1 = gen_if_cond
(c
, &@
1, &$3);
469 yyassert
(c
, &@
1, false
, "Encountered a FAIL token as rvalue.\n");
482 $$
= gen_rvalue_pred
(c
, &@
1, &$1);
486 /* Read PC from the CR */
488 memset
(&rvalue
, 0, sizeof
(HexValue
));
489 rvalue.type
= IMMEDIATE
;
490 rvalue.imm.type
= IMM_PC
;
491 rvalue.bit_width
= 32;
492 rvalue.signedness
= UNSIGNED
;
498 memset
(&rvalue
, 0, sizeof
(HexValue
));
499 rvalue.type
= IMMEDIATE
;
500 rvalue.imm.type
= IMM_CONSTEXT
;
501 rvalue.signedness
= UNSIGNED
;
502 rvalue.is_dotnew
= false
;
507 $$
= gen_rvalue_var
(c
, &@
1, &$1);
509 | MPY
'(' rvalue
',' rvalue
')'
511 @
1.last_column
= @
6.last_column
;
512 $$
= gen_rvalue_mpy
(c
, &@
1, &$1, &$3, &$5);
516 @
1.last_column
= @
3.last_column
;
517 $$
= gen_bin_op
(c
, &@
1, ADD_OP
, &$1, &$3);
521 @
1.last_column
= @
3.last_column
;
522 $$
= gen_bin_op
(c
, &@
1, SUB_OP
, &$1, &$3);
526 @
1.last_column
= @
3.last_column
;
527 $$
= gen_bin_op
(c
, &@
1, MUL_OP
, &$1, &$3);
531 @
1.last_column
= @
3.last_column
;
532 $$
= gen_bin_op
(c
, &@
1, ASL_OP
, &$1, &$3);
536 @
1.last_column
= @
3.last_column
;
537 assert_signedness
(c
, &@
1, $1.signedness
);
538 if
($1.signedness
== UNSIGNED
) {
539 $$
= gen_bin_op
(c
, &@
1, LSR_OP
, &$1, &$3);
540 } else if
($1.signedness
== SIGNED
) {
541 $$
= gen_bin_op
(c
, &@
1, ASR_OP
, &$1, &$3);
546 @
1.last_column
= @
3.last_column
;
547 $$
= gen_bin_op
(c
, &@
1, LSR_OP
, &$1, &$3);
551 @
1.last_column
= @
3.last_column
;
552 $$
= gen_bin_op
(c
, &@
1, ANDB_OP
, &$1, &$3);
556 @
1.last_column
= @
3.last_column
;
557 $$
= gen_bin_op
(c
, &@
1, ORB_OP
, &$1, &$3);
561 @
1.last_column
= @
3.last_column
;
562 $$
= gen_bin_op
(c
, &@
1, XORB_OP
, &$1, &$3);
566 @
1.last_column
= @
3.last_column
;
567 $$
= gen_bin_op
(c
, &@
1, ANDL_OP
, &$1, &$3);
569 | MIN
'(' rvalue
',' rvalue
')'
571 @
1.last_column
= @
3.last_column
;
572 $$
= gen_bin_op
(c
, &@
1, MINI_OP
, &$3, &$5);
574 | MAX
'(' rvalue
',' rvalue
')'
576 @
1.last_column
= @
3.last_column
;
577 $$
= gen_bin_op
(c
, &@
1, MAXI_OP
, &$3, &$5);
581 @
1.last_column
= @
2.last_column
;
582 $$
= gen_rvalue_not
(c
, &@
1, &$2);
586 @
1.last_column
= @
2.last_column
;
587 $$
= gen_rvalue_notl
(c
, &@
1, &$2);
589 | SAT
'(' IMM
',' rvalue
')'
591 @
1.last_column
= @
6.last_column
;
592 $$
= gen_rvalue_sat
(c
, &@
1, &$1, &$3, &$5);
596 @
1.last_column
= @
2.last_column
;
597 /* Assign target signedness */
598 $2.signedness
= $1.signedness
;
599 $$
= gen_cast_op
(c
, &@
1, &$2, $1.bit_width
, $1.signedness
);
603 @
1.last_column
= @
3.last_column
;
604 $$
= gen_bin_cmp
(c
, &@
1, TCG_COND_EQ
, &$1, &$3);
608 @
1.last_column
= @
3.last_column
;
609 $$
= gen_bin_cmp
(c
, &@
1, TCG_COND_NE
, &$1, &$3);
613 @
1.last_column
= @
3.last_column
;
615 assert_signedness
(c
, &@
1, $1.signedness
);
616 assert_signedness
(c
, &@
1, $3.signedness
);
617 if
($1.signedness
== UNSIGNED ||
$3.signedness
== UNSIGNED
) {
618 $$
= gen_bin_cmp
(c
, &@
1, TCG_COND_LTU
, &$1, &$3);
620 $$
= gen_bin_cmp
(c
, &@
1, TCG_COND_LT
, &$1, &$3);
625 @
1.last_column
= @
3.last_column
;
627 assert_signedness
(c
, &@
1, $1.signedness
);
628 assert_signedness
(c
, &@
1, $3.signedness
);
629 if
($1.signedness
== UNSIGNED ||
$3.signedness
== UNSIGNED
) {
630 $$
= gen_bin_cmp
(c
, &@
1, TCG_COND_GTU
, &$1, &$3);
632 $$
= gen_bin_cmp
(c
, &@
1, TCG_COND_GT
, &$1, &$3);
637 @
1.last_column
= @
3.last_column
;
639 assert_signedness
(c
, &@
1, $1.signedness
);
640 assert_signedness
(c
, &@
1, $3.signedness
);
641 if
($1.signedness
== UNSIGNED ||
$3.signedness
== UNSIGNED
) {
642 $$
= gen_bin_cmp
(c
, &@
1, TCG_COND_LEU
, &$1, &$3);
644 $$
= gen_bin_cmp
(c
, &@
1, TCG_COND_LE
, &$1, &$3);
649 @
1.last_column
= @
3.last_column
;
651 assert_signedness
(c
, &@
1, $1.signedness
);
652 assert_signedness
(c
, &@
1, $3.signedness
);
653 if
($1.signedness
== UNSIGNED ||
$3.signedness
== UNSIGNED
) {
654 $$
= gen_bin_cmp
(c
, &@
1, TCG_COND_GEU
, &$1, &$3);
656 $$
= gen_bin_cmp
(c
, &@
1, TCG_COND_GE
, &$1, &$3);
664 g_array_append_val
(c
->ternary
, t
);
668 Ternary
*t
= &g_array_index
(c
->ternary
, Ternary
,
669 c
->ternary
->len
- 1);
674 @
1.last_column
= @
5.last_column
;
675 $$
= gen_rvalue_ternary
(c
, &@
1, &$1, &$4, &$7);
677 | FSCR
'(' rvalue
')'
679 @
1.last_column
= @
4.last_column
;
680 $$
= gen_rvalue_fscr
(c
, &@
1, &$3);
682 | SXT
'(' rvalue
',' IMM
',' rvalue
')'
684 @
1.last_column
= @
8.last_column
;
685 yyassert
(c
, &@
1, $5.type
== IMMEDIATE
&&
686 $5.imm.type
== VALUE
,
687 "SXT expects immediate values\n");
688 $$
= gen_extend_op
(c
, &@
1, &$3, $5.imm.value
, &$7, SIGNED
);
690 | ZXT
'(' rvalue
',' IMM
',' rvalue
')'
692 @
1.last_column
= @
8.last_column
;
693 yyassert
(c
, &@
1, $5.type
== IMMEDIATE
&&
694 $5.imm.type
== VALUE
,
695 "ZXT expects immediate values\n");
696 $$
= gen_extend_op
(c
, &@
1, &$3, $5.imm.value
, &$7, UNSIGNED
);
704 @
1.last_column
= @
2.last_column
;
705 $$
= gen_rvalue_abs
(c
, &@
1, &$2);
707 | CROUND
'(' rvalue
',' rvalue
')'
709 @
1.last_column
= @
6.last_column
;
710 $$
= gen_convround_n
(c
, &@
1, &$3, &$5);
712 | CROUND
'(' rvalue
')'
714 @
1.last_column
= @
4.last_column
;
715 $$
= gen_convround
(c
, &@
1, &$3);
717 | ROUND
'(' rvalue
',' rvalue
')'
719 @
1.last_column
= @
6.last_column
;
720 $$
= gen_round
(c
, &@
1, &$3, &$5);
724 @
1.last_column
= @
2.last_column
;
725 $$
= gen_rvalue_neg
(c
, &@
1, &$2);
727 | ICIRC
'(' rvalue
')' ASL IMM
729 @
1.last_column
= @
6.last_column
;
730 $$
= gen_tmp
(c
, &@
1, 32, UNSIGNED
);
731 OUT
(c
, &@
1, "gen_read_ireg(", &$$
, ", ", &$3, ", ", &$6, ");\n");
733 | CIRCADD
'(' rvalue
',' rvalue
',' rvalue
')'
735 @
1.last_column
= @
8.last_column
;
736 gen_circ_op
(c
, &@
1, &$3, &$5, &$7);
738 | LOCNT
'(' rvalue
')'
740 @
1.last_column
= @
4.last_column
;
741 /* Leading ones count */
742 $$
= gen_locnt_op
(c
, &@
1, &$3);
744 | COUNTONES
'(' rvalue
')'
746 @
1.last_column
= @
4.last_column
;
748 $$
= gen_ctpop_op
(c
, &@
1, &$3);
750 | EXTRACT
'(' rvalue
',' rvalue
')'
752 @
1.last_column
= @
6.last_column
;
753 $$
= gen_extract_op
(c
, &@
1, &$5, &$3, &$1);
755 | EXTRANGE
'(' rvalue
',' rvalue
',' rvalue
')'
757 @
1.last_column
= @
8.last_column
;
758 yyassert
(c
, &@
1, $5.type
== IMMEDIATE
&&
759 $5.imm.type
== VALUE
&&
760 $7.type
== IMMEDIATE
&&
761 $7.imm.type
== VALUE
,
762 "Range extract needs immediate values!\n");
763 $$
= gen_rextract_op
(c
,
767 $5.imm.value
- $7.imm.value
+ 1);
769 | CAST4_8U
'(' rvalue
')'
771 @
1.last_column
= @
4.last_column
;
772 $$
= gen_rvalue_truncate
(c
, &@
1, &$3);
773 $$.signedness
= UNSIGNED
;
774 $$
= rvalue_materialize
(c
, &@
1, &$$
);
775 $$
= gen_rvalue_extend
(c
, &@
1, &$$
);
777 | BREV
'(' rvalue
')'
779 @
1.last_column
= @
4.last_column
;
780 $$
= gen_rvalue_brev
(c
, &@
1, &$3);
782 | ROTL
'(' rvalue
',' rvalue
')'
784 @
1.last_column
= @
6.last_column
;
785 $$
= gen_rotl
(c
, &@
1, &$3, &$5);
787 | ADDSAT64
'(' rvalue
',' rvalue
',' rvalue
')'
789 @
1.last_column
= @
8.last_column
;
790 gen_addsat64
(c
, &@
1, &$3, &$5, &$7);
792 | CARRY_FROM_ADD
'(' rvalue
',' rvalue
',' rvalue
')'
794 @
1.last_column
= @
8.last_column
;
795 $$
= gen_carry_from_add
(c
, &@
1, &$3, &$5, &$7);
797 | LSBNEW
'(' rvalue
')'
799 @
1.last_column
= @
4.last_column
;
800 HexValue one
= gen_imm_value
(c
, &@
1, 1, 32, UNSIGNED
);
801 $$
= gen_bin_op
(c
, &@
1, ANDB_OP
, &$3, &one
);
807 @
1.last_column
= @
1.last_column
;
808 yyassert
(c
, &@
1, false
, "Encountered a FAIL token as lvalue.\n");
822 int main
(int argc
, char **argv
)
826 "Semantics: Hexagon ISA to tinycode generator compiler\n\n");
828 "Usage: ./semantics IDEFS EMITTER_C EMITTER_H "
829 "ENABLED_INSTRUCTIONS_LIST\n");
838 ARG_INDEX_ENABLED_INSTRUCTIONS_LIST
841 FILE *enabled_file
= fopen
(argv
[ARG_INDEX_ENABLED_INSTRUCTIONS_LIST
], "w");
843 FILE *output_file
= fopen
(argv
[ARG_INDEX_EMITTER_C
], "w");
844 fputs
("#include \"qemu/osdep.h\"\n", output_file
);
845 fputs
("#include \"qemu/log.h\"\n", output_file
);
846 fputs
("#include \"cpu.h\"\n", output_file
);
847 fputs
("#include \"internal.h\"\n", output_file
);
848 fputs
("#include \"tcg/tcg-op.h\"\n", output_file
);
849 fputs
("#include \"insn.h\"\n", output_file
);
850 fputs
("#include \"opcodes.h\"\n", output_file
);
851 fputs
("#include \"translate.h\"\n", output_file
);
852 fputs
("#define QEMU_GENERATE\n", output_file
);
853 fputs
("#include \"genptr.h\"\n", output_file
);
854 fputs
("#include \"tcg/tcg.h\"\n", output_file
);
855 fputs
("#include \"macros.h\"\n", output_file
);
856 fprintf
(output_file
, "#include \"%s\"\n", argv
[ARG_INDEX_EMITTER_H
]);
858 FILE *defines_file
= fopen
(argv
[ARG_INDEX_EMITTER_H
], "w");
859 assert
(defines_file
!= NULL
);
860 fputs
("#ifndef HEX_EMITTER_H\n", defines_file
);
861 fputs
("#define HEX_EMITTER_H\n", defines_file
);
862 fputs
("\n", defines_file
);
863 fputs
("#include \"insn.h\"\n\n", defines_file
);
865 /* Parser input file */
866 Context context
= { 0 };
867 context.defines_file
= defines_file
;
868 context.output_file
= output_file
;
869 context.enabled_file
= enabled_file
;
870 /* Initialize buffers */
871 context.out_str
= g_string_new
(NULL
);
872 context.signature_str
= g_string_new
(NULL
);
873 context.header_str
= g_string_new
(NULL
);
874 context.ternary
= g_array_new
(FALSE
, TRUE
, sizeof
(Ternary
));
875 /* Read input file */
876 FILE *input_file
= fopen
(argv
[ARG_INDEX_IDEFS
], "r");
877 fseek
(input_file
, 0L, SEEK_END
);
878 long input_size
= ftell
(input_file
);
879 context.input_buffer
= (char *) calloc
(input_size
+ 1, sizeof
(char));
880 fseek
(input_file
, 0L, SEEK_SET
);
881 size_t read_chars
= fread
(context.input_buffer
,
885 if
(read_chars
!= (size_t) input_size
) {
886 fprintf
(stderr
, "Error: an error occurred while reading input file!\n");
889 yylex_init
(&context.scanner
);
890 YY_BUFFER_STATE buffer
;
891 buffer
= yy_scan_string
(context.input_buffer
, context.scanner
);
892 /* Start the parsing procedure */
893 yyparse(context.scanner
, &context
);
894 if
(context.implemented_insn
!= context.total_insn
) {
896 "Warning: %d/%d meta instructions have been implemented!\n",
897 context.implemented_insn
,
900 fputs
("#endif " START_COMMENT
" HEX_EMITTER_h " END_COMMENT
"\n",
903 yy_delete_buffer
(buffer
, context.scanner
);
904 yylex_destroy
(context.scanner
);
905 free
(context.input_buffer
);
906 g_string_free
(context.out_str
, TRUE
);
907 g_string_free
(context.signature_str
, TRUE
);
908 g_string_free
(context.header_str
, TRUE
);
909 g_array_free
(context.ternary
, TRUE
);
912 fclose
(defines_file
);
913 fclose
(enabled_file
);