1 /*
2 * Copyright © 2022 Mary Guillemard
3 * SPDX-License-Identifier: MIT
4 */
5 #ifndef MME_BUILDER_H
6 #error "This file must only be included by mme_builder.h"
7 #endif
8
9 #include "mme_fermi.h"
10 #include "mme_value.h"
11
12 #include "util/bitscan.h"
13 #include "util/enum_operators.h"
14
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18
19 #define MME_FERMI_BUILDER_MAX_INSTS 128
20
21 enum mme_fermi_instr_parts {
22 MME_FERMI_INSTR_PART_OP = BITFIELD_BIT(0),
23 MME_FERMI_INSTR_PART_ASSIGN = BITFIELD_BIT(1)
24 };
25
26 struct mme_fermi_builder {
27 bool first_loaded;
28 uint32_t inst_count;
29 enum mme_fermi_instr_parts inst_parts;
30 struct mme_fermi_inst insts[MME_FERMI_BUILDER_MAX_INSTS];
31 uint32_t cf_depth;
32 struct mme_value loop_counter;
33 struct mme_cf cf_stack[8];
34 };
35
36 void mme_fermi_builder_init(struct mme_builder *b);
37
38 uint32_t * mme_fermi_builder_finish(struct mme_fermi_builder *b, size_t *size_out);
39
40 void mme_fermi_builder_dump(struct mme_builder *b, FILE *fp);
41
42 void mme_fermi_add_inst(struct mme_builder *b,
43 const struct mme_fermi_inst *inst);
44
45 static inline bool
mme_fermi_is_empty(struct mme_fermi_builder * b)46 mme_fermi_is_empty(struct mme_fermi_builder *b)
47 {
48 return b->inst_count == 0;
49 }
50
51 #define mme_fermi_asm(b, __inst) \
52 for (struct mme_fermi_inst __inst = { MME_FERMI_INST_DEFAULTS }; \
53 !__inst.end_next; \
54 mme_fermi_add_inst((b), &__inst), __inst.end_next = true)
55
56 void mme_fermi_mthd_arr(struct mme_builder *b,
57 uint16_t mthd,
58 struct mme_value index);
59
60 void mme_fermi_emit(struct mme_builder *b,
61 struct mme_value data);
62
63 void mme_fermi_start_loop(struct mme_builder *b,
64 struct mme_value count);
65 void mme_fermi_end_loop(struct mme_builder *b);
66
67 void mme_fermi_start_if(struct mme_builder *b,
68 enum mme_cmp_op op,
69 bool if_true,
70 struct mme_value x,
71 struct mme_value y);
72 void mme_fermi_end_if(struct mme_builder *b);
73
74 void mme_fermi_start_while(struct mme_builder *b);
75 void mme_fermi_end_while(struct mme_builder *b,
76 enum mme_cmp_op op,
77 bool if_true,
78 struct mme_value x,
79 struct mme_value y);
80
81 void mme_fermi_load_to(struct mme_builder *b,
82 struct mme_value dst);
83
84 struct mme_value mme_fermi_load(struct mme_builder *b);
85
86 void
87 mme_fermi_alu_to(struct mme_builder *b,
88 struct mme_value dst,
89 enum mme_alu_op op,
90 struct mme_value x,
91 struct mme_value y);
92
93 void
94 mme_fermi_alu64_to(struct mme_builder *b,
95 struct mme_value64 dst,
96 enum mme_alu_op op_lo,
97 enum mme_alu_op op_hi,
98 struct mme_value64 x,
99 struct mme_value64 y);
100
101 void
102 mme_fermi_bfe_to(struct mme_builder *b, struct mme_value dst,
103 struct mme_value x, struct mme_value pos, uint8_t bits);
104
105 void
106 mme_fermi_umul_32x32_32_to_free_srcs(struct mme_builder *b,
107 struct mme_value dst,
108 struct mme_value x,
109 struct mme_value y);
110
111 void
112 mme_fermi_umul_32x64_64_to_free_srcs(struct mme_builder *b,
113 struct mme_value64 dst,
114 struct mme_value x,
115 struct mme_value64 y);
116
117 void
118 mme_fermi_merge_to(struct mme_builder *b, struct mme_value dst,
119 struct mme_value x, struct mme_value y,
120 uint16_t dst_pos, uint16_t bits, uint16_t src_pos);
121
122 void mme_fermi_state_arr_to(struct mme_builder *b,
123 struct mme_value dst,
124 uint16_t state,
125 struct mme_value index);
126
127 #ifdef __cplusplus
128 }
129 #endif
130
131