qbe.h (4138B)
1 #ifndef HAREC_QBE_H 2 #define HAREC_QBE_H 3 #include <stdarg.h> 4 #include <stdbool.h> 5 #include <stddef.h> 6 #include <stdint.h> 7 8 enum qbe_stype { 9 Q__VOID = 'V', 10 Q_BYTE = 'b', 11 Q_HALF = 'h', 12 Q_WORD = 'w', 13 Q_LONG = 'l', 14 Q_SINGLE = 's', 15 Q_DOUBLE = 'd', 16 Q__AGGREGATE = 'A', 17 }; 18 19 struct qbe_type; 20 21 struct qbe_field { 22 const struct qbe_type *type; 23 size_t count; 24 struct qbe_field *next; 25 }; 26 27 struct qbe_type { 28 enum qbe_stype stype; 29 size_t size; 30 31 // Aggregate types only: 32 char *name; 33 struct qbe_field fields; 34 const struct type *base; 35 }; 36 37 // Simple type singletons 38 extern const struct qbe_type 39 qbe_byte, 40 qbe_half, 41 qbe_word, 42 qbe_long, 43 qbe_single, 44 qbe_double, 45 qbe_void, 46 qbe_aggregate; 47 48 enum qbe_value_kind { 49 QV_CONST, 50 QV_GLOBAL, 51 QV_LABEL, 52 QV_TEMPORARY, 53 QV_VARIADIC, 54 }; 55 56 struct qbe_value { 57 enum qbe_value_kind kind; 58 bool threadlocal; 59 const struct qbe_type *type; 60 union { 61 char *name; 62 uint32_t wval; 63 uint64_t lval; 64 float sval; 65 double dval; 66 }; 67 }; 68 69 enum qbe_instr { 70 Q_ADD, 71 Q_ALLOC16, 72 Q_ALLOC4, 73 Q_ALLOC8, 74 Q_AND, 75 Q_BLIT, 76 Q_CALL, 77 Q_CAST, 78 Q_CEQD, 79 Q_CEQL, 80 Q_CEQS, 81 Q_CEQW, 82 Q_CGED, 83 Q_CGES, 84 Q_CGTD, 85 Q_CGTS, 86 Q_CLED, 87 Q_CLES, 88 Q_CLTD, 89 Q_CLTS, 90 Q_CNED, 91 Q_CNEL, 92 Q_CNES, 93 Q_CNEW, 94 Q_COD, 95 Q_COPY, 96 Q_COS, 97 Q_CSGEL, 98 Q_CSGEW, 99 Q_CSGTL, 100 Q_CSGTW, 101 Q_CSLEL, 102 Q_CSLEW, 103 Q_CSLTL, 104 Q_CSLTW, 105 Q_CUGEL, 106 Q_CUGEW, 107 Q_CUGTL, 108 Q_CUGTW, 109 Q_CULEL, 110 Q_CULEW, 111 Q_CULTL, 112 Q_CULTW, 113 Q_CUOD, 114 Q_CUOS, 115 Q_DIV, 116 Q_DTOSI, 117 Q_DTOUI, 118 Q_EXTS, 119 Q_EXTSB, 120 Q_EXTSH, 121 Q_EXTSW, 122 Q_EXTUB, 123 Q_EXTUH, 124 Q_EXTUW, 125 Q_JMP, 126 Q_JNZ, 127 Q_LOADD, 128 Q_LOADL, 129 Q_LOADS, 130 Q_LOADSB, 131 Q_LOADSH, 132 Q_LOADSW, 133 Q_LOADUB, 134 Q_LOADUH, 135 Q_LOADUW, 136 Q_MUL, 137 Q_OR, 138 Q_REM, 139 Q_RET, 140 Q_NEG, 141 Q_SAR, 142 Q_SHL, 143 Q_SHR, 144 Q_SLTOF, 145 Q_STOREB, 146 Q_STORED, 147 Q_STOREH, 148 Q_STOREL, 149 Q_STORES, 150 Q_STOREW, 151 Q_STOSI, 152 Q_STOUI, 153 Q_SUB, 154 Q_SWTOF, 155 Q_TRUNCD, 156 Q_UDIV, 157 Q_ULTOF, 158 Q_UREM, 159 Q_UWTOF, 160 Q_VAARG, 161 Q_VASTART, 162 Q_XOR, 163 164 Q_LAST_INSTR, 165 }; 166 167 extern const char *qbe_instr[Q_LAST_INSTR]; 168 169 enum qbe_statement_type { 170 Q_COMMENT, 171 Q_INSTR, 172 Q_LABEL, 173 }; 174 175 struct qbe_arguments { 176 struct qbe_value value; 177 struct qbe_arguments *next; 178 }; 179 180 struct qbe_statement { 181 enum qbe_statement_type type; 182 union { 183 struct { 184 enum qbe_instr instr; 185 struct qbe_value *out; 186 struct qbe_arguments *args; 187 }; 188 char *label; 189 char *comment; 190 }; 191 }; 192 193 struct qbe_func_param { 194 char *name; 195 const struct qbe_type *type; 196 struct qbe_func_param *next; 197 }; 198 199 struct qbe_statements { 200 size_t ln, sz; 201 struct qbe_statement *stmts; 202 }; 203 204 struct qbe_func { 205 const struct qbe_type *returns; 206 struct qbe_func_param *params; 207 bool variadic; 208 struct qbe_statements prelude, body; 209 }; 210 211 enum qbe_datatype { 212 QD_VALUE, 213 QD_ZEROED, 214 QD_STRING, 215 QD_SYMOFFS, 216 }; 217 218 struct qbe_data_item { 219 enum qbe_datatype type; 220 union { 221 struct qbe_value value; 222 size_t zeroed; 223 struct { 224 char *str; 225 size_t sz; 226 }; 227 struct { 228 char *sym; 229 long offset; 230 }; 231 }; 232 struct qbe_data_item *next; 233 }; 234 235 struct qbe_data { 236 size_t align; 237 char *section, *secflags; 238 bool threadlocal; 239 struct qbe_data_item items; 240 }; 241 242 enum qbe_defkind { 243 Q_TYPE, 244 Q_FUNC, 245 Q_DATA, 246 }; 247 248 struct qbe_def { 249 char *name; 250 enum qbe_defkind kind; 251 bool exported; 252 union { 253 struct qbe_func func; 254 struct qbe_type type; 255 struct qbe_data data; 256 }; 257 struct qbe_def *next; 258 }; 259 260 struct qbe_program { 261 struct qbe_def *defs; 262 struct qbe_def **next; 263 }; 264 265 void qbe_append_def(struct qbe_program *prog, struct qbe_def *def); 266 267 void geni(struct qbe_statement *stmt, const struct qbe_value *out, enum qbe_instr instr, ...); 268 const char *genl(struct qbe_statement *stmt, int *id, const char *fmt); 269 void pushi(struct qbe_func *func, const struct qbe_value *out, enum qbe_instr instr, ...); 270 void pushprei(struct qbe_func *func, const struct qbe_value *out, enum qbe_instr instr, ...); 271 const char *pushl(struct qbe_func *func, int *id, const char *fmt); 272 void pushc(struct qbe_func *func, const char *fmt, ...); 273 void push(struct qbe_statements *stmts, struct qbe_statement *stmt); 274 275 struct qbe_value *qval_dup(const struct qbe_value *val); 276 277 struct qbe_value constl(uint64_t l); 278 struct qbe_value constw(uint32_t w); 279 struct qbe_value consts(float s); 280 struct qbe_value constd(double d); 281 282 #endif