emit.c (7892B)
1 #include <assert.h> 2 #include <ctype.h> 3 #include <float.h> 4 #include <inttypes.h> 5 #include <stdlib.h> 6 #include <stdio.h> 7 #include "emit.h" 8 #include "qbe.h" 9 #include "typedef.h" 10 #include "types.h" 11 12 static void 13 emit_qtype(const struct qbe_type *type, bool aggr, FILE *out) 14 { 15 assert(type); 16 switch (type->stype) { 17 case Q_BYTE: 18 case Q_HALF: 19 case Q_WORD: 20 case Q_LONG: 21 case Q_SINGLE: 22 case Q_DOUBLE: 23 fprintf(out, "%c", (char)type->stype); 24 break; 25 case Q__AGGREGATE: 26 if (aggr) { 27 fprintf(out, ":%s", type->name); 28 } else { 29 fprintf(out, "l"); 30 } 31 break; 32 case Q__VOID: 33 break; // no-op 34 } 35 } 36 37 static char * 38 gen_typename(const struct type *type) 39 { 40 size_t sz = 0; 41 char *ptr = NULL; 42 FILE *f = open_memstream(&ptr, &sz); 43 emit_type(type, f); 44 fclose(f); 45 return ptr; 46 } 47 48 static void 49 qemit_type(const struct qbe_def *def, FILE *out) 50 { 51 assert(def->kind == Q_TYPE); 52 const struct type *base = def->type.base; 53 if (base) { 54 char *tn = gen_typename(base); 55 fprintf(out, "# %s [id: %u; size: %zu]\n", tn, base->id, base->size); 56 free(tn); 57 fprintf(out, "type :%s =", def->name); 58 if (base->align != (size_t)-1) { 59 fprintf(out, " align %zu", base->align); 60 } 61 } else { 62 fprintf(out, "type :%s =", def->name); 63 } 64 fprintf(out, " {"); 65 66 bool is_union = base == NULL || type_dealias(base)->storage == STORAGE_UNION; 67 const struct qbe_field *field = &def->type.fields; 68 while (field) { 69 if (is_union) { 70 fprintf(out, " {"); 71 } 72 if (field->type) { 73 fprintf(out, " "); 74 emit_qtype(field->type, true, out); 75 } 76 if (field->count) { 77 fprintf(out, " %zu", field->count); 78 } 79 if (is_union) { 80 fprintf(out, " }"); 81 } else if (field->next) { 82 fprintf(out, ","); 83 } 84 field = field->next; 85 } 86 87 fprintf(out, " }\n\n"); 88 } 89 90 static void 91 emit_const(struct qbe_value *val, FILE *out) 92 { 93 switch (val->type->stype) { 94 case Q_BYTE: 95 case Q_HALF: 96 case Q_WORD: 97 fprintf(out, "%u", val->wval); 98 break; 99 case Q_LONG: 100 fprintf(out, "%" PRIu64, val->lval); 101 break; 102 case Q_SINGLE: 103 fprintf(out, "s_%.*g", DECIMAL_DIG, val->sval); 104 break; 105 case Q_DOUBLE: 106 fprintf(out, "d_%.*g", DECIMAL_DIG, val->dval); 107 break; 108 case Q__VOID: 109 case Q__AGGREGATE: 110 assert(0); // Invariant 111 } 112 } 113 114 static void 115 emit_value(struct qbe_value *val, FILE *out) 116 { 117 switch (val->kind) { 118 case QV_CONST: 119 emit_const(val, out); 120 break; 121 case QV_GLOBAL: 122 if (val->threadlocal) { 123 fprintf(out, "thread "); 124 } 125 fprintf(out, "$%s", val->name); 126 break; 127 case QV_LABEL: 128 fprintf(out, "@%s", val->name); 129 break; 130 case QV_TEMPORARY: 131 fprintf(out, "%%%s", val->name); 132 break; 133 case QV_VARIADIC: 134 fprintf(out, "..."); 135 break; 136 } 137 } 138 139 static void 140 emit_call(struct qbe_statement *stmt, FILE *out) 141 { 142 fprintf(out, "%s ", qbe_instr[stmt->instr]); 143 144 struct qbe_arguments *arg = stmt->args; 145 assert(arg); 146 emit_value(&arg->value, out); 147 fprintf(out, "("); 148 arg = arg->next; 149 150 bool comma = false; 151 while (arg) { 152 fprintf(out, "%s", comma ? ", " : ""); 153 if (arg->value.kind != QV_VARIADIC) { 154 emit_qtype(arg->value.type, true, out); 155 fprintf(out, " "); 156 } 157 emit_value(&arg->value, out); 158 arg = arg->next; 159 comma = true; 160 } 161 162 fprintf(out, ")\n"); 163 } 164 165 static void 166 emit_stmt(struct qbe_statement *stmt, FILE *out) 167 { 168 switch (stmt->type) { 169 case Q_COMMENT: 170 fprintf(out, "\t# %s\n", stmt->comment); 171 break; 172 case Q_INSTR: 173 fprintf(out, "\t"); 174 if (stmt->instr == Q_CALL) { 175 if (stmt->out != NULL) { 176 emit_value(stmt->out, out); 177 fprintf(out, " ="); 178 emit_qtype(stmt->out->type, true, out); 179 fprintf(out, " "); 180 } 181 emit_call(stmt, out); 182 break; 183 } 184 if (stmt->out != NULL) { 185 emit_value(stmt->out, out); 186 fprintf(out, " ="); 187 emit_qtype(stmt->out->type, false, out); 188 fprintf(out, " "); 189 } 190 fprintf(out, "%s%s", qbe_instr[stmt->instr], 191 stmt->args ? " " : ""); 192 struct qbe_arguments *arg = stmt->args; 193 while (arg) { 194 fprintf(out, "%s", arg == stmt->args ? "" : ", "); 195 emit_value(&arg->value, out); 196 arg = arg->next; 197 } 198 fprintf(out, "\n"); 199 break; 200 case Q_LABEL: 201 fprintf(out, "@%s\n", stmt->label); 202 break; 203 } 204 } 205 206 static void 207 emit_func(struct qbe_def *def, FILE *out) 208 { 209 assert(def->kind == Q_FUNC); 210 fprintf(out, "section \".text.%s\" \"ax\"%s\nfunction", 211 def->name, 212 def->exported ? " export" : ""); 213 if (def->func.returns->stype != Q__VOID) { 214 fprintf(out, " "); 215 emit_qtype(def->func.returns, true, out); 216 } 217 fprintf(out, " $%s(", def->name); 218 struct qbe_func_param *param = def->func.params; 219 while (param) { 220 emit_qtype(param->type, true, out); 221 fprintf(out, " %%%s", param->name); 222 if (param->next) { 223 fprintf(out, ", "); 224 } 225 param = param->next; 226 } 227 if (def->func.variadic) { 228 fprintf(out, ", ..."); 229 } 230 fprintf(out, ") {\n"); 231 232 for (size_t i = 0; i < def->func.prelude.ln; ++i) { 233 struct qbe_statement *stmt = &def->func.prelude.stmts[i]; 234 emit_stmt(stmt, out); 235 } 236 237 for (size_t i = 0; i < def->func.body.ln; ++i) { 238 struct qbe_statement *stmt = &def->func.body.stmts[i]; 239 emit_stmt(stmt, out); 240 } 241 242 fprintf(out, "}\n\n"); 243 } 244 245 static void 246 emit_data_string(const char *str, size_t sz, FILE *out) 247 { 248 bool q = false; 249 for (size_t i = 0; i < sz; ++i) { 250 /* XXX: We could stand to emit less conservatively */ 251 if (!isprint((unsigned char)(str[i])) || str[i] == '"' 252 || str[i] == '\\') { 253 if (q) { 254 q = false; 255 fprintf(out, "\", "); 256 } 257 fprintf(out, "b %d%s", str[i], i + 1 < sz ? ", " : ""); 258 } else { 259 if (!q) { 260 q = true; 261 fprintf(out, "b \""); 262 } 263 fprintf(out, "%c", str[i]); 264 } 265 } 266 if (q) { 267 fprintf(out, "\""); 268 } 269 } 270 271 static bool 272 is_zeroes(struct qbe_data_item *data) 273 { 274 for (struct qbe_data_item *cur = data; cur; cur = cur->next) { 275 switch (cur->type) { 276 case QD_ZEROED: 277 break; 278 case QD_VALUE: 279 switch (cur->value.kind) { 280 case QV_CONST: 281 if (cur->value.lval != 0) { 282 return false; 283 } 284 break; 285 case QV_GLOBAL: 286 case QV_LABEL: 287 case QV_TEMPORARY: 288 return false; 289 case QV_VARIADIC: 290 abort(); 291 } 292 break; 293 case QD_STRING: 294 for (size_t i = 0; i < cur->sz; ++i) { 295 if (cur->str[i] != 0) { 296 return false; 297 } 298 } 299 break; 300 case QD_SYMOFFS: 301 return false; 302 } 303 } 304 return true; 305 } 306 307 static void 308 emit_data(struct qbe_def *def, FILE *out) 309 { 310 assert(def->kind == Q_DATA); 311 if (def->data.section && def->data.secflags) { 312 fprintf(out, "section \"%s\" \"%s\"", 313 def->data.section, def->data.secflags); 314 } else if (def->data.section) { 315 fprintf(out, "section \"%s\"", def->data.section); 316 } else if (def->data.threadlocal) { 317 if (is_zeroes(&def->data.items)) { 318 fprintf(out, "section \".tbss\" \"awT\""); 319 } else { 320 fprintf(out, "section \".tdata\" \"awT\""); 321 } 322 } else if (is_zeroes(&def->data.items)) { 323 fprintf(out, "section \".bss.%s\"", def->name); 324 } else { 325 fprintf(out, "section \".data.%s\"", def->name); 326 } 327 fprintf(out, "%s\ndata $%s = ", def->exported ? " export" : "", 328 def->name); 329 if (def->data.align != ALIGN_UNDEFINED) { 330 fprintf(out, "align %zu ", def->data.align); 331 } 332 fprintf(out, "{ "); 333 334 struct qbe_data_item *item = &def->data.items; 335 while (item) { 336 switch (item->type) { 337 case QD_VALUE: 338 emit_qtype(item->value.type, true, out); 339 fprintf(out, " "); 340 emit_value(&item->value, out); 341 break; 342 case QD_ZEROED: 343 fprintf(out, "z %zu", item->zeroed); 344 break; 345 case QD_STRING: 346 emit_data_string(item->str, item->sz, out); 347 break; 348 case QD_SYMOFFS: 349 // XXX: ARCH 350 fprintf(out, "l $%s + %ld", item->sym, item->offset); 351 break; 352 } 353 354 fprintf(out, item->next ? ", " : " "); 355 item = item->next; 356 } 357 358 fprintf(out, "}\n\n"); 359 } 360 361 static void 362 emit_def(struct qbe_def *def, FILE *out) 363 { 364 switch (def->kind) { 365 case Q_TYPE: 366 qemit_type(def, out); 367 break; 368 case Q_FUNC: 369 emit_func(def, out); 370 break; 371 case Q_DATA: 372 emit_data(def, out); 373 break; 374 } 375 } 376 377 void 378 emit(struct qbe_program *program, FILE *out) 379 { 380 struct qbe_def *def = program->defs; 381 while (def) { 382 emit_def(def, out); 383 def = def->next; 384 } 385 }