gen.c (116934B)
1 #include <assert.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include "check.h" 5 #include "expr.h" 6 #include "gen.h" 7 #include "scope.h" 8 #include "typedef.h" 9 #include "types.h" 10 #include "util.h" 11 12 #define EXPR_GEN_VALUE -1 13 14 static const struct gen_value gv_void = { 15 .kind = GV_CONST, 16 .type = &builtin_type_void, 17 }; 18 19 static struct gen_value gen_expr(struct gen_context *ctx, 20 const struct expression *expr); 21 static void gen_expr_at(struct gen_context *ctx, 22 const struct expression *expr, 23 struct gen_value out); 24 static struct gen_value gen_expr_with(struct gen_context *ctx, 25 const struct expression *expr, 26 struct gen_value *out); 27 static void gen_global_decl(struct gen_context *ctx, 28 const struct declaration *decl); 29 30 static void 31 gen_defers(struct gen_context *ctx, struct gen_scope *scope) 32 { 33 if (ctx->deferring || !scope) { 34 return; 35 } 36 ctx->deferring = true; 37 if (scope->defers) { 38 pushc(ctx->current, "gen defers"); 39 } 40 for (struct gen_defer *defer = scope->defers; defer; 41 defer = defer->next) { 42 gen_expr(ctx, defer->expr); 43 } 44 ctx->deferring = false; 45 } 46 47 static struct gen_scope * 48 gen_scope_lookup(struct gen_context *ctx, const struct scope *which) 49 { 50 for (struct gen_scope *scope = ctx->scope; 51 scope; scope = scope->parent) { 52 if (scope->scope == which) { 53 return scope; 54 } 55 } 56 abort(); 57 } 58 59 static struct gen_scope * 60 push_scope(struct gen_context *ctx, const struct scope *scope) 61 { 62 struct gen_scope *new = xcalloc(1, sizeof(struct gen_scope)); 63 new->parent = ctx->scope; 64 new->scope = scope; 65 ctx->scope = new; 66 return new; 67 } 68 69 static void 70 pop_scope(struct gen_context *ctx, bool gendefers) 71 { 72 if (gendefers) { 73 gen_defers(ctx, ctx->scope); 74 } 75 struct gen_scope *scope = ctx->scope; 76 ctx->scope = scope->parent; 77 for (struct gen_defer *defer = scope->defers; defer; /* n/a */) { 78 struct gen_defer *next = defer->next; 79 free(defer); 80 defer = next; 81 } 82 free(scope); 83 } 84 85 static void 86 gen_copy_memcpy(struct gen_context *ctx, 87 struct gen_value dest, struct gen_value src) 88 { 89 struct qbe_value rtfunc = mkrtfunc(ctx, "rt.memcpy"); 90 struct qbe_value dtemp = mklval(ctx, &dest); 91 struct qbe_value stemp = mklval(ctx, &src); 92 struct qbe_value sz = constl(dest.type->size); 93 pushi(ctx->current, NULL, Q_CALL, &rtfunc, &dtemp, &stemp, &sz, NULL); 94 } 95 96 static void 97 gen_copy_aligned(struct gen_context *ctx, 98 struct gen_value dest, struct gen_value src) 99 { 100 if (dest.type->size > 128) { 101 gen_copy_memcpy(ctx, dest, src); 102 return; 103 } 104 struct qbe_value srcv = mkqval(ctx, &src); 105 struct qbe_value destv = mkqval(ctx, &dest); 106 struct qbe_value size = constl(dest.type->size); 107 pushi(ctx->current, NULL, Q_BLIT, &srcv, &destv, &size, NULL); 108 } 109 110 static void 111 gen_store(struct gen_context *ctx, 112 struct gen_value object, 113 struct gen_value value) 114 { 115 const struct type *ty = type_dealias(object.type); 116 switch (ty->storage) { 117 case STORAGE_ARRAY: 118 case STORAGE_SLICE: 119 case STORAGE_STRING: 120 case STORAGE_STRUCT: 121 case STORAGE_UNION: 122 case STORAGE_TAGGED: 123 case STORAGE_TUPLE: 124 case STORAGE_VALIST: 125 gen_copy_aligned(ctx, object, value); 126 return; 127 case STORAGE_ENUM: 128 object.type = ty->alias.type; 129 break; 130 default: 131 break; // no-op 132 } 133 134 struct qbe_value qobj = mkqval(ctx, &object), 135 qval = mkqval(ctx, &value); 136 enum qbe_instr qi = store_for_type(ctx, object.type); 137 pushi(ctx->current, NULL, qi, &qval, &qobj, NULL); 138 } 139 140 static struct gen_value 141 gen_load(struct gen_context *ctx, struct gen_value object) 142 { 143 const struct type *ty = type_dealias(object.type); 144 switch (ty->storage) { 145 case STORAGE_ARRAY: 146 case STORAGE_FUNCTION: 147 case STORAGE_SLICE: 148 case STORAGE_STRING: 149 case STORAGE_STRUCT: 150 case STORAGE_TAGGED: 151 case STORAGE_TUPLE: 152 case STORAGE_UNION: 153 case STORAGE_VALIST: 154 return object; 155 case STORAGE_ENUM: 156 object.type = ty->alias.type; 157 break; 158 default: 159 break; // no-op 160 } 161 162 struct gen_value value = { 163 .kind = GV_TEMP, 164 .type = object.type, 165 .name = gen_name(&ctx->id, "load.%d"), 166 }; 167 struct qbe_value qobj = mkqval(ctx, &object), 168 qval = mkqval(ctx, &value); 169 enum qbe_instr qi = load_for_type(ctx, object.type); 170 pushi(ctx->current, &qval, qi, &qobj, NULL); 171 return value; 172 } 173 174 static void 175 gen_fixed_abort(struct gen_context *ctx, 176 struct location loc, enum fixed_aborts reason) 177 { 178 int n = snprintf(NULL, 0, "%s:%d:%d", 179 sources[loc.file], loc.lineno, loc.colno); 180 char *s = xcalloc(1, n + 1); 181 snprintf(s, n, "%s:%d:%d", 182 sources[loc.file], loc.lineno, loc.colno); 183 struct expression eloc = {0}; 184 eloc.type = EXPR_CONSTANT; 185 eloc.result = &builtin_type_const_str; 186 eloc.constant.string.value = s; 187 eloc.constant.string.len = n - 1; 188 struct gen_value msg = gen_expr(ctx, &eloc); 189 struct qbe_value qmsg = mkqval(ctx, &msg); 190 struct qbe_value rtabort = mkrtfunc(ctx, "rt.abort_fixed"); 191 struct qbe_value tmp = constl(reason); 192 pushi(ctx->current, NULL, Q_CALL, &rtabort, &qmsg, &tmp, NULL); 193 } 194 195 static struct gen_value 196 gen_autoderef(struct gen_context *ctx, struct gen_value val) 197 { 198 while (type_dealias(val.type)->storage == STORAGE_POINTER) { 199 val.type = type_dealias(val.type)->pointer.referent; 200 val = gen_load(ctx, val); 201 } 202 return val; 203 } 204 205 static struct gen_value 206 gen_access_ident(struct gen_context *ctx, const struct scope_object *obj) 207 { 208 switch (obj->otype) { 209 case O_BIND: 210 for (const struct gen_binding *gb = ctx->bindings; 211 gb; gb = gb->next) { 212 if (gb->object == obj) { 213 return gb->value; 214 } 215 } 216 break; 217 case O_DECL: 218 return (struct gen_value){ 219 .kind = GV_GLOBAL, 220 .type = obj->type, 221 .name = ident_to_sym(&obj->ident), 222 .threadlocal = obj->threadlocal, 223 }; 224 case O_CONST: 225 case O_TYPE: 226 case O_SCAN: 227 abort(); // Invariant 228 } 229 abort(); // Invariant 230 } 231 232 static struct gen_value 233 gen_access_index(struct gen_context *ctx, const struct expression *expr) 234 { 235 struct gen_value glval = gen_expr(ctx, expr->access.array); 236 glval = gen_autoderef(ctx, glval); 237 struct qbe_value qlval = mkqval(ctx, &glval); 238 struct qbe_value qival = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 239 bool checkbounds = !expr->access.bounds_checked; 240 struct qbe_value length; 241 const struct type *ty = type_dealias(glval.type); 242 switch (ty->storage) { 243 case STORAGE_SLICE:; 244 enum qbe_instr load = load_for_type(ctx, &builtin_type_size); 245 struct qbe_value base = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 246 pushi(ctx->current, &base, load, &qlval, NULL); 247 248 struct qbe_value temp = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 249 length = mkqtmp(ctx, ctx->arch.sz, "len.%d"); 250 struct qbe_value offset = constl(builtin_type_size.size); 251 pushi(ctx->current, &temp, Q_ADD, &qlval, &offset, NULL); 252 pushi(ctx->current, &length, load, &temp, NULL); 253 254 qlval = base; 255 break; 256 case STORAGE_ARRAY: 257 if (ty->array.length != SIZE_UNDEFINED) { 258 length = constl(ty->array.length); 259 } else { 260 checkbounds = false; 261 } 262 break; 263 default: 264 assert(0); // Unreachable 265 } 266 267 struct gen_value index = gen_expr(ctx, expr->access.index); 268 struct qbe_value qindex = mkqval(ctx, &index); 269 struct qbe_value itemsz = constl(expr->result->size); 270 pushi(ctx->current, &qival, Q_MUL, &qindex, &itemsz, NULL); 271 pushi(ctx->current, &qival, Q_ADD, &qlval, &qival, NULL); 272 273 if (checkbounds) { 274 struct qbe_value valid = mkqtmp(ctx, &qbe_word, ".%d"); 275 pushi(ctx->current, &valid, Q_CULTL, &qindex, &length, NULL); 276 277 struct qbe_statement linvalid, lvalid; 278 struct qbe_value binvalid = mklabel(ctx, &linvalid, ".%d"); 279 struct qbe_value bvalid = mklabel(ctx, &lvalid, ".%d"); 280 281 pushi(ctx->current, NULL, Q_JNZ, &valid, &bvalid, &binvalid, NULL); 282 push(&ctx->current->body, &linvalid); 283 gen_fixed_abort(ctx, expr->loc, ABORT_OOB); 284 push(&ctx->current->body, &lvalid); 285 } 286 287 return (struct gen_value){ 288 .kind = GV_TEMP, 289 .type = expr->result, 290 .name = qival.name, 291 }; 292 } 293 294 static struct gen_value 295 gen_access_field(struct gen_context *ctx, const struct expression *expr) 296 { 297 const struct struct_field *field = expr->access.field; 298 struct gen_value glval = gen_expr(ctx, expr->access._struct); 299 glval = gen_autoderef(ctx, glval); 300 struct qbe_value qlval = mkqval(ctx, &glval); 301 struct qbe_value qfval = mkqtmp(ctx, ctx->arch.ptr, "field.%d"); 302 struct qbe_value offs = constl(field->offset); 303 pushi(ctx->current, &qfval, Q_ADD, &qlval, &offs, NULL); 304 return (struct gen_value){ 305 .kind = GV_TEMP, 306 .type = field->type, 307 .name = qfval.name, 308 }; 309 } 310 311 static struct gen_value 312 gen_access_value(struct gen_context *ctx, const struct expression *expr) 313 { 314 const struct type_tuple *tuple = expr->access.tvalue; 315 struct gen_value glval = gen_expr(ctx, expr->access.tuple); 316 glval = gen_autoderef(ctx, glval); 317 struct qbe_value qlval = mkqval(ctx, &glval); 318 struct qbe_value qfval = mkqtmp(ctx, ctx->arch.ptr, "value.%d"); 319 struct qbe_value offs = constl(tuple->offset); 320 pushi(ctx->current, &qfval, Q_ADD, &qlval, &offs, NULL); 321 return (struct gen_value){ 322 .kind = GV_TEMP, 323 .type = tuple->type, 324 .name = qfval.name, 325 }; 326 } 327 328 static struct gen_value 329 gen_expr_access_addr(struct gen_context *ctx, const struct expression *expr) 330 { 331 struct gen_value addr; 332 switch (expr->access.type) { 333 case ACCESS_IDENTIFIER: 334 addr = gen_access_ident(ctx, expr->access.object); 335 break; 336 case ACCESS_INDEX: 337 addr = gen_access_index(ctx, expr); 338 break; 339 case ACCESS_FIELD: 340 addr = gen_access_field(ctx, expr); 341 break; 342 case ACCESS_TUPLE: 343 addr = gen_access_value(ctx, expr); 344 break; 345 } 346 return addr; 347 } 348 349 static struct gen_value 350 gen_expr_access(struct gen_context *ctx, const struct expression *expr) 351 { 352 struct gen_value addr = gen_expr_access_addr(ctx, expr); 353 return gen_load(ctx, addr); 354 } 355 356 static void 357 gen_alloc_slice_at(struct gen_context *ctx, 358 const struct expression *expr, 359 struct gen_value out, 360 bool expand) 361 { 362 struct qbe_value qcap; 363 if (expr->alloc.cap) { 364 struct gen_value cap = gen_expr(ctx, expr->alloc.cap); 365 qcap = mkqval(ctx, &cap); 366 } 367 368 struct gen_value init; 369 struct qbe_value qinit; 370 struct qbe_value length, initdata; 371 const struct type *inittype = type_dealias(expr->alloc.init->result); 372 switch (inittype->storage) { 373 case STORAGE_ARRAY: 374 assert(inittype->array.length != SIZE_UNDEFINED); 375 length = constl(inittype->array.length); 376 break; 377 case STORAGE_SLICE: 378 init = gen_expr(ctx, expr->alloc.init); 379 qinit = mkqval(ctx, &init); 380 enum qbe_instr load = load_for_type(ctx, &builtin_type_size); 381 initdata = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 382 pushi(ctx->current, &initdata, load, &qinit, NULL); 383 struct qbe_value offset = constl(builtin_type_size.size); 384 struct qbe_value ptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 385 pushi(ctx->current, &ptr, Q_ADD, &qinit, &offset, NULL); 386 length = mkqtmp(ctx, ctx->arch.sz, ".%d"); 387 pushi(ctx->current, &length, load, &ptr, NULL); 388 break; 389 default: abort(); // Invariant 390 } 391 392 if (!expr->alloc.cap) { 393 qcap = length; 394 } 395 396 const struct type *sltype = type_dealias(expr->result); 397 struct qbe_value isize = constl(sltype->array.members->size); 398 struct qbe_value size = mkqtmp(ctx, ctx->arch.sz, ".%d"); 399 pushi(ctx->current, &size, Q_MUL, &qcap, &isize, NULL); 400 401 struct qbe_statement lzero, lnonzero; 402 struct qbe_value bzero = mklabel(ctx, &lzero, ".%d"); 403 struct qbe_value bnonzero = mklabel(ctx, &lnonzero, ".%d"); 404 405 struct qbe_value rtfunc = mkrtfunc(ctx, "rt.malloc"); 406 struct qbe_value data = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 407 struct qbe_value cmpres = mkqtmp(ctx, &qbe_word, ".%d"); 408 struct qbe_value zero = constl(0); 409 pushi(ctx->current, &data, Q_COPY, &zero, NULL); 410 pushi(ctx->current, &cmpres, Q_CNEL, &size, &zero, NULL); 411 pushi(ctx->current, NULL, Q_JNZ, &cmpres, &bnonzero, &bzero, NULL); 412 push(&ctx->current->body, &lnonzero); 413 pushi(ctx->current, &data, Q_CALL, &rtfunc, &size, NULL); 414 415 struct qbe_statement linvalid; 416 struct qbe_value binvalid = mklabel(ctx, &linvalid, ".%d"); 417 pushi(ctx->current, &cmpres, Q_CNEL, &data, &zero, NULL); 418 pushi(ctx->current, NULL, Q_JNZ, &cmpres, &bzero, &binvalid, NULL); 419 push(&ctx->current->body, &linvalid); 420 gen_fixed_abort(ctx, expr->loc, ABORT_ALLOC_FAILURE); 421 push(&ctx->current->body, &lzero); 422 423 struct qbe_value base = mklval(ctx, &out); 424 struct qbe_value ptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 425 struct qbe_value offset = constl(builtin_type_size.size); 426 enum qbe_instr store = store_for_type(ctx, &builtin_type_size); 427 pushi(ctx->current, NULL, store, &data, &base, NULL); 428 pushi(ctx->current, &ptr, Q_ADD, &base, &offset, NULL); 429 430 if (expand) { 431 pushi(ctx->current, NULL, store, &qcap, &ptr, NULL); 432 } else { 433 pushi(ctx->current, NULL, store, &length, &ptr, NULL); 434 } 435 436 offset = constl(builtin_type_size.size * 2); 437 pushi(ctx->current, &ptr, Q_ADD, &base, &offset, NULL); 438 pushi(ctx->current, NULL, store, &qcap, &ptr, NULL); 439 440 if (inittype->storage == STORAGE_ARRAY) { 441 struct gen_value storage = (struct gen_value){ 442 .kind = GV_TEMP, 443 .type = inittype, 444 .name = data.name, 445 }; 446 gen_expr_at(ctx, expr->alloc.init, storage); 447 } else { 448 struct qbe_value copysize = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 449 pushi(ctx->current, ©size, Q_MUL, &length, &isize, NULL); 450 struct qbe_value rtmemcpy = mkrtfunc(ctx, "rt.memcpy"); 451 pushi(ctx->current, NULL, Q_CALL, &rtmemcpy, 452 &data, &initdata, ©size, NULL); 453 } 454 455 if (!expand) { 456 return; 457 } 458 459 struct qbe_value last = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 460 struct qbe_value next = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 461 pushi(ctx->current, &next, Q_MUL, &length, &isize, NULL); 462 pushi(ctx->current, &next, Q_ADD, &next, &data, NULL); 463 pushi(ctx->current, &last, Q_SUB, &next, &isize, NULL); 464 struct qbe_value remain = mkqtmp(ctx, ctx->arch.sz, ".%d"); 465 pushi(ctx->current, &remain, Q_SUB, &qcap, &length, NULL); 466 pushi(ctx->current, &remain, Q_MUL, &remain, &isize, NULL); 467 struct qbe_value rtmemcpy = mkrtfunc(ctx, "rt.memcpy"); 468 pushi(ctx->current, NULL, Q_CALL, &rtmemcpy, &next, &last, &remain, NULL); 469 } 470 471 static struct gen_value 472 gen_expr_alloc_init_with(struct gen_context *ctx, 473 const struct expression *expr, struct gen_value *out) 474 { 475 // alloc(init) case 476 assert(expr->alloc.cap == NULL); 477 478 const struct type *objtype = type_dealias(expr->result); 479 assert(objtype->storage == STORAGE_POINTER); 480 objtype = objtype->pointer.referent; 481 482 struct qbe_value sz = constl(objtype->size); 483 struct gen_value result = mkgtemp(ctx, expr->result, ".%d"); 484 struct qbe_value qresult = mkqval(ctx, &result); 485 struct qbe_value rtfunc = mkrtfunc(ctx, "rt.malloc"); 486 pushi(ctx->current, &qresult, Q_CALL, &rtfunc, &sz, NULL); 487 488 if (!(type_dealias(expr->result)->pointer.flags & PTR_NULLABLE)) { 489 struct qbe_statement linvalid, lvalid; 490 struct qbe_value cmpres = mkqtmp(ctx, &qbe_word, ".%d"); 491 struct qbe_value zero = constl(0); 492 struct qbe_value binvalid = mklabel(ctx, &linvalid, ".%d"); 493 struct qbe_value bvalid = mklabel(ctx, &lvalid, ".%d"); 494 495 pushi(ctx->current, &cmpres, Q_CNEL, &qresult, &zero, NULL); 496 pushi(ctx->current, NULL, Q_JNZ, &cmpres, &bvalid, &binvalid, NULL); 497 push(&ctx->current->body, &linvalid); 498 gen_fixed_abort(ctx, expr->loc, ABORT_ALLOC_FAILURE); 499 push(&ctx->current->body, &lvalid); 500 } 501 502 struct gen_value object = { 503 .kind = GV_TEMP, 504 .type = objtype, 505 .name = result.name, 506 }; 507 gen_expr_at(ctx, expr->alloc.init, object); 508 if (out) { 509 gen_store(ctx, *out, result); 510 } 511 return result; 512 } 513 514 static struct gen_value 515 gen_expr_alloc_slice_with(struct gen_context *ctx, 516 const struct expression *expr, struct gen_value *out) 517 { 518 // alloc(init, cap | len) case 519 bool expand = expr->alloc.kind == ALLOC_WITH_LEN; 520 if (out) { 521 gen_alloc_slice_at(ctx, expr, *out, expand); 522 return gv_void; 523 } 524 struct gen_value temp = mkgtemp(ctx, expr->result, "object.%d"); 525 struct qbe_value base = mkqval(ctx, &temp); 526 struct qbe_value sz = constl(expr->result->size); 527 enum qbe_instr alloc = alloc_for_align(expr->result->align); 528 pushprei(ctx->current, &base, alloc, &sz, NULL); 529 gen_alloc_slice_at(ctx, expr, temp, expand); 530 return temp; 531 } 532 533 static struct gen_value 534 gen_expr_alloc_copy_with(struct gen_context *ctx, 535 const struct expression *expr, struct gen_value *out) 536 { 537 // alloc(init...) case 538 assert(expr->alloc.cap == NULL); 539 540 struct gen_value ret = gv_void; 541 if (out == NULL) { 542 ret = mkgtemp(ctx, expr->result, "object.%d"); 543 out = &ret; 544 545 struct qbe_value base = mkqval(ctx, out); 546 struct qbe_value sz = constl(expr->result->size); 547 enum qbe_instr alloc = alloc_for_align(expr->result->align); 548 pushprei(ctx->current, &base, alloc, &sz, NULL); 549 } 550 551 enum qbe_instr load = load_for_type(ctx, &builtin_type_size); 552 enum qbe_instr store = store_for_type(ctx, &builtin_type_size); 553 554 struct gen_value src = gen_expr(ctx, expr->alloc.init); 555 struct qbe_value dbase = mkcopy(ctx, out, ".%d"); 556 struct qbe_value offs = constl(builtin_type_size.size); 557 558 const struct type *initres = type_dealias(expr->alloc.init->result); 559 struct qbe_value srcdata; 560 struct qbe_value length; 561 if (initres->storage == STORAGE_SLICE) { 562 assert(initres->array.length == SIZE_UNDEFINED); 563 srcdata = mkqtmp(ctx, ctx->arch.sz, ".%d"); 564 struct qbe_value sbase = mkcopy(ctx, &src, ".%d"); 565 pushi(ctx->current, &srcdata, load, &sbase, NULL); 566 pushi(ctx->current, &sbase, Q_ADD, &sbase, &offs, NULL); 567 length = mkqtmp(ctx, ctx->arch.sz, ".%d"); 568 pushi(ctx->current, &length, load, &sbase, NULL); 569 } else if (initres->storage == STORAGE_ARRAY) { 570 assert(initres->array.length != SIZE_UNDEFINED); 571 srcdata = mkcopy(ctx, &src, ".%d"); // TODO: object.%d 572 length = constl(initres->array.length); 573 } else { 574 abort(); 575 } 576 577 struct qbe_statement linvalid, lvalid, lalloc, lcopy; 578 struct qbe_value balloc = mklabel(ctx, &lalloc, ".%d"); 579 struct qbe_value binvalid = mklabel(ctx, &linvalid, ".%d"); 580 struct qbe_value bvalid = mklabel(ctx, &lvalid, ".%d"); 581 struct qbe_value bcopy = mklabel(ctx, &lcopy, ".%d"); 582 583 struct qbe_value cmpres = mkqtmp(ctx, &qbe_word, ".%d"); 584 struct qbe_value newdata = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 585 struct qbe_value zero = constl(0); 586 pushi(ctx->current, &newdata, Q_COPY, &zero, NULL); 587 pushi(ctx->current, &cmpres, Q_CNEL, &length, &zero, NULL); 588 pushi(ctx->current, NULL, Q_JNZ, &cmpres, &balloc, &bvalid, NULL); 589 push(&ctx->current->body, &lalloc); 590 591 const struct type *result = type_dealias(expr->result); 592 assert(result->storage == STORAGE_SLICE); 593 struct qbe_value sz = mkqtmp(ctx, ctx->arch.sz, ".%d"); 594 struct qbe_value membsz = constl(result->array.members->size); 595 pushi(ctx->current, &sz, Q_MUL, &membsz, &length, NULL); 596 597 struct qbe_value rtfunc = mkrtfunc(ctx, "rt.malloc"); 598 pushi(ctx->current, &newdata, Q_CALL, &rtfunc, &sz, NULL); 599 pushi(ctx->current, &cmpres, Q_CNEL, &newdata, &zero, NULL); 600 pushi(ctx->current, NULL, Q_JNZ, &cmpres, &bcopy, &binvalid, NULL); 601 602 push(&ctx->current->body, &linvalid); 603 gen_fixed_abort(ctx, expr->loc, ABORT_ALLOC_FAILURE); 604 605 push(&ctx->current->body, &lcopy); 606 struct qbe_value rtmemcpy = mkrtfunc(ctx, "rt.memcpy"); 607 pushi(ctx->current, NULL, Q_CALL, &rtmemcpy, &newdata, &srcdata, &sz, NULL); 608 609 push(&ctx->current->body, &lvalid); 610 pushi(ctx->current, NULL, store, &newdata, &dbase, NULL); 611 pushi(ctx->current, &dbase, Q_ADD, &dbase, &offs, NULL); 612 pushi(ctx->current, NULL, store, &length, &dbase, NULL); 613 pushi(ctx->current, &dbase, Q_ADD, &dbase, &offs, NULL); 614 pushi(ctx->current, NULL, store, &length, &dbase, NULL); 615 616 return ret; 617 } 618 619 static struct gen_value 620 gen_expr_alloc_with(struct gen_context *ctx, 621 const struct expression *expr, struct gen_value *out) 622 { 623 switch (expr->alloc.kind) { 624 case ALLOC_OBJECT: 625 return gen_expr_alloc_init_with(ctx, expr, out); 626 case ALLOC_WITH_CAP: 627 case ALLOC_WITH_LEN: 628 return gen_expr_alloc_slice_with(ctx, expr, out); 629 case ALLOC_COPY: 630 return gen_expr_alloc_copy_with(ctx, expr, out); 631 } 632 abort(); // Unreachable 633 } 634 635 static struct gen_value 636 gen_expr_append(struct gen_context *ctx, const struct expression *expr) 637 { 638 struct gen_value slice = gen_expr(ctx, expr->append.object); 639 slice = gen_autoderef(ctx, slice); 640 struct qbe_value qslice = mkqval(ctx, &slice); 641 642 struct qbe_value lenptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 643 struct qbe_value prevlen = mkqtmp(ctx, ctx->arch.sz, ".%d"); 644 struct qbe_value offs = constl(builtin_type_size.size); 645 pushi(ctx->current, &lenptr, Q_ADD, &qslice, &offs, NULL); 646 enum qbe_instr load = load_for_type(ctx, &builtin_type_size); 647 pushi(ctx->current, &prevlen, load, &lenptr, NULL); 648 649 struct qbe_value appendlen; 650 const struct type *valtype = type_dealias(expr->append.value->result); 651 if (expr->append.length != NULL) { 652 struct gen_value length = gen_expr(ctx, expr->append.length); 653 appendlen = mkqval(ctx, &length); 654 assert(valtype->storage == STORAGE_ARRAY && valtype->array.expandable); 655 } else if (!expr->append.is_multi) { 656 appendlen = constl(1); 657 } 658 659 struct gen_value value; 660 struct qbe_value qvalue; 661 if (!expr->append.is_multi || valtype->storage != STORAGE_ARRAY) { 662 // We use gen_expr_at for the array case to avoid a copy 663 value = gen_expr(ctx, expr->append.value); 664 qvalue = mkqval(ctx, &value); 665 } 666 667 if (expr->append.is_multi) { 668 if (valtype->storage == STORAGE_ARRAY) { 669 assert(valtype->array.length != SIZE_UNDEFINED); 670 appendlen = constl(valtype->array.length); 671 } else { 672 appendlen = mkqtmp(ctx, ctx->arch.sz, ".%d"); 673 struct qbe_value ptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 674 offs = constl(builtin_type_size.size); 675 pushi(ctx->current, &ptr, Q_ADD, &qvalue, &offs, NULL); 676 pushi(ctx->current, &appendlen, load, &ptr, NULL); 677 } 678 } 679 680 struct qbe_value newlen = mkqtmp(ctx, ctx->arch.sz, ".%d"); 681 pushi(ctx->current, &newlen, Q_ADD, &prevlen, &appendlen, NULL); 682 enum qbe_instr store = store_for_type(ctx, &builtin_type_size); 683 pushi(ctx->current, NULL, store, &newlen, &lenptr, NULL); 684 685 struct qbe_value ptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 686 const struct type *mtype = type_dealias(slice.type)->array.members; 687 struct qbe_value membsz = constl(mtype->size); 688 if (!expr->append.is_static) { 689 struct qbe_value rtfunc = mkrtfunc(ctx, "rt.ensure"); 690 struct qbe_value lval = mklval(ctx, &slice); 691 pushi(ctx->current, NULL, Q_CALL, &rtfunc, &lval, &membsz, NULL); 692 } else { 693 offs = constl(builtin_type_size.size * 2); 694 pushi(ctx->current, &ptr, Q_ADD, &qslice, &offs, NULL); 695 struct qbe_value cap = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 696 pushi(ctx->current, &cap, load, &ptr, NULL); 697 698 struct qbe_statement lvalid, linvalid; 699 struct qbe_value bvalid = mklabel(ctx, &lvalid, ".%d"); 700 struct qbe_value binvalid = mklabel(ctx, &linvalid, ".%d"); 701 struct qbe_value valid = mkqtmp(ctx, &qbe_word, ".%d"); 702 pushi(ctx->current, &valid, Q_CULEL, &newlen, &cap, NULL); 703 pushi(ctx->current, NULL, Q_JNZ, &valid, &bvalid, &binvalid, NULL); 704 705 push(&ctx->current->body, &linvalid); 706 gen_fixed_abort(ctx, expr->loc, ABORT_OOB); 707 push(&ctx->current->body, &lvalid); 708 } 709 710 offs = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 711 pushi(ctx->current, &ptr, load, &qslice, NULL); 712 pushi(ctx->current, &offs, Q_MUL, &prevlen, &membsz, NULL); 713 pushi(ctx->current, &ptr, Q_ADD, &ptr, &offs, NULL); 714 715 struct gen_value item = { 716 .kind = GV_TEMP, 717 .type = mtype, 718 .name = ptr.name, 719 }; 720 if (expr->append.is_multi && valtype->storage == STORAGE_ARRAY) { 721 item.type = valtype; 722 gen_expr_at(ctx, expr->append.value, item); 723 } else if (expr->append.is_multi && valtype->storage == STORAGE_SLICE) { 724 struct qbe_value qsrc = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 725 struct qbe_value rtfunc = mkrtfunc(ctx, "rt.memmove"); 726 struct qbe_value sz = mkqtmp(ctx, ctx->arch.sz, ".%d"); 727 pushi(ctx->current, &sz, Q_MUL, &appendlen, &membsz, NULL); 728 pushi(ctx->current, &qsrc, load, &qvalue, NULL); 729 pushi(ctx->current, NULL, Q_CALL, &rtfunc, &ptr, &qsrc, &sz, NULL); 730 } else if (expr->append.length != NULL) { 731 // XXX: This could be made more efficient for some cases if 732 // check could determine the length at compile time and lower it 733 // to a fixed-length array type 734 assert(valtype->storage == STORAGE_ARRAY); 735 item.type = valtype; 736 gen_expr_at(ctx, expr->append.value, item); 737 738 assert(valtype->array.length != SIZE_UNDEFINED); 739 struct qbe_value next = mkqtmp(ctx, ctx->arch.ptr, "next.%d"); 740 struct qbe_value last = mkqtmp(ctx, ctx->arch.ptr, "last.%d"); 741 struct qbe_value arlen = constl(valtype->array.length * mtype->size); 742 pushi(ctx->current, &next, Q_ADD, &ptr, &arlen, NULL); 743 arlen = constl((valtype->array.length - 1) * mtype->size); 744 pushi(ctx->current, &last, Q_ADD, &ptr, &arlen, NULL); 745 746 struct qbe_value rtfunc = mkrtfunc(ctx, "rt.memcpy"); 747 struct qbe_value remain = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 748 struct qbe_value one = constl(1); 749 pushi(ctx->current, &remain, Q_SUB, &appendlen, &one, NULL); 750 pushi(ctx->current, &remain, Q_MUL, &remain, &membsz, NULL); 751 pushi(ctx->current, NULL, Q_CALL, &rtfunc, &next, &last, &remain, NULL); 752 } else { 753 gen_store(ctx, item, value); 754 } 755 756 return gv_void; 757 } 758 759 static struct gen_value 760 gen_expr_assert(struct gen_context *ctx, const struct expression *expr) 761 { 762 assert(expr->assert.message); // Invariant 763 if (expr->assert.is_static) { 764 return gv_void; 765 } 766 767 struct gen_value msg; 768 struct qbe_statement failedl, passedl; 769 struct qbe_value rtfunc = mkrtfunc(ctx, "rt.abort"); 770 if (expr->assert.cond) { 771 struct qbe_value bfailed = mklabel(ctx, &failedl, "failed.%d"); 772 struct qbe_value bpassed = mklabel(ctx, &passedl, "passed.%d"); 773 struct gen_value cond = gen_expr(ctx, expr->assert.cond); 774 struct qbe_value qcond = mkqval(ctx, &cond); 775 pushi(ctx->current, NULL, Q_JNZ, &qcond, &bpassed, &bfailed, NULL); 776 push(&ctx->current->body, &failedl); 777 msg = gen_expr(ctx, expr->assert.message); 778 } else { 779 msg = gen_expr(ctx, expr->assert.message); 780 } 781 782 for (struct gen_scope *scope = ctx->scope; scope; scope = scope->parent) { 783 gen_defers(ctx, scope); 784 } 785 786 struct qbe_value qmsg = mkqval(ctx, &msg); 787 pushi(ctx->current, NULL, Q_CALL, &rtfunc, &qmsg, NULL); 788 789 if (expr->assert.cond) { 790 push(&ctx->current->body, &passedl); 791 } 792 793 return gv_void; 794 } 795 796 static struct gen_value 797 gen_expr_assign_slice_expandable(struct gen_context *ctx, const struct expression *expr) 798 { 799 struct gen_value obj = gen_expr(ctx, expr->assign.object); 800 struct qbe_value qobj = mkqval(ctx, &obj); 801 802 // get the length of the copy 803 struct qbe_value step = constl(ctx->arch.ptr->size); 804 struct qbe_value ptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 805 struct qbe_value olen = mkqtmp(ctx, ctx->arch.sz, ".%d"); 806 pushi(ctx->current, &ptr, Q_ADD, &qobj, &step, NULL); 807 pushi(ctx->current, &olen, Q_LOADL, &ptr, NULL); 808 809 // check if there is anything to do 810 struct qbe_statement lzero, lnonzero; 811 struct qbe_value bzero = mklabel(ctx, &lzero, ".%d"); 812 struct qbe_value bnonzero = mklabel(ctx, &lnonzero, ".%d"); 813 814 struct qbe_value cmpres = mkqtmp(ctx, &qbe_word, ".%d"); 815 struct qbe_value zero = constl(0); 816 pushi(ctx->current, &cmpres, Q_CNEL, &olen, &zero, NULL); 817 pushi(ctx->current, NULL, Q_JNZ, &cmpres, &bnonzero, &bzero, NULL); 818 push(&ctx->current->body, &lnonzero); 819 820 // get the destination 821 struct qbe_value odata = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 822 pushi(ctx->current, &odata, Q_LOADL, &qobj, NULL); 823 824 // get the source 825 struct gen_value val = gen_expr(ctx, expr->assign.value); 826 struct qbe_value qval = mkqval(ctx, &val); 827 struct qbe_value vdata = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 828 pushi(ctx->current, &vdata, Q_LOADL, &qval, NULL); 829 830 // copy the first item 831 const struct type *sltype = expr->assign.object->result->array.members; 832 enum qbe_instr store = store_for_type(ctx, sltype); 833 pushi(ctx->current, NULL, store, &vdata, &odata, NULL); 834 835 // perform the copy minus the first element 836 struct qbe_value isize = constl(sltype->size); 837 struct qbe_value next = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 838 pushi(ctx->current, &next, Q_ADD, &odata, &isize, NULL); 839 struct qbe_value rtmemcpy = mkrtfunc(ctx, "rt.memcpy"); 840 struct qbe_value one = constl(1); 841 pushi(ctx->current, &olen, Q_SUB, &olen, &one, NULL); 842 pushi(ctx->current, &olen, Q_MUL, &olen, &isize, NULL); 843 pushi(ctx->current, NULL, Q_CALL, &rtmemcpy, &next, &odata, &olen, NULL); 844 845 push(&ctx->current->body, &lzero); 846 847 return gv_void; 848 } 849 850 static struct gen_value 851 gen_expr_assign_slice(struct gen_context *ctx, const struct expression *expr) 852 { 853 const struct type *vtype = type_dealias(expr->assign.value->result); 854 if (vtype->storage == STORAGE_ARRAY && vtype->array.expandable) { 855 return gen_expr_assign_slice_expandable(ctx, expr); 856 } 857 858 struct gen_value obj = gen_expr(ctx, expr->assign.object); 859 struct gen_value val = gen_expr(ctx, expr->assign.value); 860 struct qbe_value qobj = mkqval(ctx, &obj); 861 struct qbe_value qval = mkqval(ctx, &val); 862 struct qbe_value step = constl(ctx->arch.ptr->size); 863 864 struct qbe_value ptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 865 struct qbe_value olen = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 866 struct qbe_value vlen = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 867 868 pushi(ctx->current, &ptr, Q_ADD, &qobj, &step, NULL); 869 pushi(ctx->current, &olen, Q_LOADL, &ptr, NULL); 870 pushi(ctx->current, &ptr, Q_ADD, &qval, &step, NULL); 871 pushi(ctx->current, &vlen, Q_LOADL, &ptr, NULL); 872 873 struct qbe_statement linvalid, lvalid; 874 struct qbe_value binvalid = mklabel(ctx, &linvalid, ".%d"); 875 struct qbe_value bvalid = mklabel(ctx, &lvalid, ".%d"); 876 struct qbe_value tmp = mkqtmp(ctx, &qbe_long, ".%d"); 877 pushi(ctx->current, &tmp, Q_CEQL, &olen, &vlen, NULL); 878 pushi(ctx->current, NULL, Q_JNZ, &tmp, &bvalid, &binvalid, NULL); 879 push(&ctx->current->body, &linvalid); 880 gen_fixed_abort(ctx, expr->loc, ABORT_OOB); 881 push(&ctx->current->body, &lvalid); 882 883 struct qbe_value rtmemmove = mkrtfunc(ctx, "rt.memmove"); 884 struct qbe_value optr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 885 struct qbe_value vptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 886 pushi(ctx->current, &optr, Q_LOADL, &qobj, NULL); 887 pushi(ctx->current, &vptr, Q_LOADL, &qval, NULL); 888 tmp = constl(expr->assign.object->result->array.members->size); 889 pushi(ctx->current, &olen, Q_MUL, &olen, &tmp, NULL); 890 pushi(ctx->current, NULL, Q_CALL, &rtmemmove, &optr, &vptr, &olen, NULL); 891 892 return gv_void; 893 } 894 895 static struct gen_value 896 gen_expr_assign(struct gen_context *ctx, const struct expression *expr) 897 { 898 struct expression *object = expr->assign.object; 899 struct expression *value = expr->assign.value; 900 if (object->type == EXPR_SLICE) { 901 return gen_expr_assign_slice(ctx, expr); 902 } 903 904 struct gen_value obj; 905 switch (object->type) { 906 case EXPR_ACCESS: 907 obj = gen_expr_access_addr(ctx, object); 908 break; 909 case EXPR_UNARITHM: 910 assert(object->unarithm.op == UN_DEREF); // Invariant 911 obj = gen_expr(ctx, object->unarithm.operand); 912 assert(type_dealias(obj.type)->storage == STORAGE_POINTER); 913 obj.type = type_dealias(obj.type)->pointer.referent; 914 break; 915 default: 916 abort(); // Invariant 917 } 918 if (expr->assign.op == BIN_LEQUAL) { 919 gen_store(ctx, obj, gen_expr(ctx, value)); 920 } else if (expr->assign.op == BIN_LAND || expr->assign.op == BIN_LOR) { 921 struct qbe_statement lrval, lshort; 922 struct qbe_value brval = mklabel(ctx, &lrval, ".%d"); 923 struct qbe_value bshort = mklabel(ctx, &lshort, ".%d"); 924 struct gen_value load = gen_load(ctx, obj); 925 struct qbe_value qload = mkqval(ctx, &load); 926 if (expr->binarithm.op == BIN_LAND) { 927 pushi(ctx->current, NULL, Q_JNZ, &qload, &brval, 928 &bshort, NULL); 929 } else { 930 pushi(ctx->current, NULL, Q_JNZ, &qload, &bshort, 931 &brval, NULL); 932 } 933 push(&ctx->current->body, &lrval); 934 gen_expr_at(ctx, value, obj); 935 if (!expr->binarithm.rvalue->terminates) { 936 pushi(ctx->current, NULL, Q_JMP, &bshort, NULL); 937 } 938 push(&ctx->current->body, &lshort); 939 } else { 940 struct gen_value lvalue = gen_load(ctx, obj); 941 struct gen_value rvalue = gen_expr(ctx, value); 942 struct qbe_value qlval = mkqval(ctx, &lvalue); 943 struct qbe_value qrval = mkqval(ctx, &rvalue); 944 enum qbe_instr instr = binarithm_for_op(ctx, 945 expr->assign.op, lvalue.type); 946 pushi(ctx->current, &qlval, instr, &qlval, &qrval, NULL); 947 gen_store(ctx, obj, lvalue); 948 } 949 950 return gv_void; 951 } 952 953 static struct qbe_value 954 extend(struct gen_context *ctx, struct qbe_value v, const struct type *type) 955 { 956 enum qbe_instr op; 957 switch (type->size) { 958 case 1: 959 op = type_is_signed(type) ? Q_EXTSB : Q_EXTUB; 960 break; 961 case 2: 962 op = type_is_signed(type) ? Q_EXTSH : Q_EXTUH; 963 break; 964 default: 965 return v; 966 } 967 968 struct qbe_value temp = mkqtmp(ctx, &qbe_word, "ext.%d"); 969 pushi(ctx->current, &temp, op, &v, NULL); 970 return temp; 971 } 972 973 static struct gen_value 974 gen_expr_binarithm(struct gen_context *ctx, const struct expression *expr) 975 { 976 const struct type *ltype = type_dealias(expr->binarithm.lvalue->result); 977 const struct type *rtype = type_dealias(expr->binarithm.rvalue->result); 978 struct gen_value result = mkgtemp(ctx, expr->result, ".%d"); 979 struct qbe_value qresult = mkqval(ctx, &result); 980 981 if (expr->binarithm.op == BIN_LAND || expr->binarithm.op == BIN_LOR) { 982 struct qbe_statement lrval, lshort; 983 struct qbe_value brval = mklabel(ctx, &lrval, ".%d"); 984 struct qbe_value bshort = mklabel(ctx, &lshort, ".%d"); 985 struct gen_value lval = gen_expr(ctx, expr->binarithm.lvalue); 986 struct qbe_value qlval = mkqval(ctx, &lval); 987 pushi(ctx->current, &qresult, Q_COPY, &qlval, NULL); 988 if (expr->binarithm.op == BIN_LAND) { 989 pushi(ctx->current, NULL, Q_JNZ, &qresult, &brval, 990 &bshort, NULL); 991 } else { 992 pushi(ctx->current, NULL, Q_JNZ, &qresult, &bshort, 993 &brval, NULL); 994 } 995 push(&ctx->current->body, &lrval); 996 struct gen_value rval = gen_expr(ctx, expr->binarithm.rvalue); 997 struct qbe_value qrval = mkqval(ctx, &rval); 998 pushi(ctx->current, &qresult, Q_COPY, &qrval, NULL); 999 if (!expr->binarithm.rvalue->terminates) { 1000 pushi(ctx->current, NULL, Q_JMP, &bshort, NULL); 1001 } 1002 push(&ctx->current->body, &lshort); 1003 return result; 1004 } 1005 1006 struct gen_value lvalue = gen_expr(ctx, expr->binarithm.lvalue); 1007 struct gen_value rvalue = gen_expr(ctx, expr->binarithm.rvalue); 1008 struct qbe_value qlval = mkqval(ctx, &lvalue); 1009 struct qbe_value qrval = mkqval(ctx, &rvalue); 1010 1011 switch (expr->binarithm.op) { 1012 case BIN_GREATER: 1013 case BIN_GREATEREQ: 1014 case BIN_LEQUAL: 1015 case BIN_LESS: 1016 case BIN_LESSEQ: 1017 case BIN_NEQUAL: 1018 qlval = extend(ctx, qlval, ltype); 1019 qrval = extend(ctx, qrval, rtype); 1020 break; 1021 default: 1022 break; 1023 } 1024 1025 assert((ltype->storage == STORAGE_STRING) == (rtype->storage == STORAGE_STRING)); 1026 if (ltype->storage == STORAGE_STRING) { 1027 struct qbe_value rtfunc = mkrtfunc(ctx, "rt.strcmp"); 1028 pushi(ctx->current, &qresult, Q_CALL, 1029 &rtfunc, &qlval, &qrval, NULL); 1030 if (expr->binarithm.op == BIN_NEQUAL) { 1031 struct qbe_value one = constl(1); 1032 pushi(ctx->current, &qresult, Q_XOR, &qresult, &one, NULL); 1033 } else { 1034 assert(expr->binarithm.op == BIN_LEQUAL); 1035 } 1036 return result; 1037 } 1038 enum qbe_instr instr = binarithm_for_op(ctx, expr->binarithm.op, 1039 expr->binarithm.lvalue->result); 1040 pushi(ctx->current, &qresult, instr, &qlval, &qrval, NULL); 1041 return result; 1042 } 1043 1044 static void 1045 gen_expr_binding_unpack_static(struct gen_context *ctx, 1046 const struct expression_binding *binding) 1047 { 1048 assert(binding->object == NULL); 1049 1050 struct tuple_constant *tupleconst = 1051 binding->initializer->constant.tuple; 1052 1053 for (const struct binding_unpack *unpack = binding->unpack; 1054 unpack; unpack = unpack->next) { 1055 if (unpack->object == NULL) { 1056 goto done; 1057 } 1058 assert(unpack->object->otype == O_DECL); 1059 1060 struct declaration decl = { 1061 .type = DECL_GLOBAL, 1062 .ident = unpack->object->ident, 1063 .global = { 1064 .type = unpack->object->type, 1065 .value = tupleconst->value, 1066 }, 1067 }; 1068 gen_global_decl(ctx, &decl); 1069 1070 done: 1071 tupleconst = tupleconst->next; 1072 } 1073 } 1074 1075 static void 1076 gen_expr_binding_unpack(struct gen_context *ctx, 1077 const struct expression_binding *binding) 1078 { 1079 assert(binding->object == NULL); 1080 1081 const struct type *type = binding->initializer->result; 1082 char *tuple_name = gen_name(&ctx->id, "tupleunpack.%d"); 1083 struct gen_value tuple_gv = { 1084 .kind = GV_TEMP, 1085 .type = type, 1086 .name = tuple_name, 1087 }; 1088 struct qbe_value tuple_qv = mklval(ctx, &tuple_gv); 1089 struct qbe_value sz = constl(type->size); 1090 enum qbe_instr alloc = alloc_for_align(type->align); 1091 pushprei(ctx->current, &tuple_qv, alloc, &sz, NULL); 1092 1093 gen_expr_at(ctx, binding->initializer, tuple_gv); 1094 1095 for (const struct binding_unpack *unpack = binding->unpack; 1096 unpack; unpack = unpack->next) { 1097 if (unpack->object == NULL) { 1098 continue; 1099 } 1100 assert(unpack->object->otype != O_DECL); 1101 1102 const struct type *type = unpack->object->type; 1103 struct gen_value item_gv = { 1104 .kind = GV_TEMP, 1105 .type = type, 1106 .name = gen_name(&ctx->id, "binding.%d"), 1107 }; 1108 struct gen_binding *gb = xcalloc(1, sizeof(struct gen_binding)); 1109 gb->value = item_gv; 1110 gb->object = unpack->object; 1111 gb->next = ctx->bindings; 1112 ctx->bindings = gb; 1113 struct qbe_value item_qv = mklval(ctx, &gb->value); 1114 struct qbe_value offs = constl(unpack->offset); 1115 pushprei(ctx->current, &item_qv, Q_ADD, &tuple_qv, &offs, NULL); 1116 } 1117 } 1118 1119 static struct gen_value 1120 gen_expr_binding(struct gen_context *ctx, const struct expression *expr) 1121 { 1122 for (const struct expression_binding *binding = &expr->binding; 1123 binding; binding = binding->next) { 1124 if (binding->unpack) { 1125 if (binding->unpack->object->otype == O_DECL) { 1126 gen_expr_binding_unpack_static(ctx, binding); 1127 } else { 1128 gen_expr_binding_unpack(ctx, binding); 1129 } 1130 continue; 1131 } 1132 1133 if (binding->object->otype == O_DECL) { 1134 // static binding 1135 struct declaration decl = { 1136 .type = DECL_GLOBAL, 1137 .ident = binding->object->ident, 1138 .global = { 1139 .type = binding->object->type, 1140 .value = binding->initializer, 1141 }, 1142 }; 1143 gen_global_decl(ctx, &decl); 1144 continue; 1145 } 1146 1147 const struct type *type = binding->object->type; 1148 struct gen_binding *gb = xcalloc(1, sizeof(struct gen_binding)); 1149 gb->value.kind = GV_TEMP; 1150 gb->value.type = type; 1151 gb->value.name = gen_name(&ctx->id, "binding.%d"); 1152 gb->object = binding->object; 1153 gb->next = ctx->bindings; 1154 ctx->bindings = gb; 1155 1156 struct qbe_value qv = mklval(ctx, &gb->value); 1157 struct qbe_value sz = constl(type->size); 1158 enum qbe_instr alloc = alloc_for_align(type->align); 1159 pushprei(ctx->current, &qv, alloc, &sz, NULL); 1160 gen_expr_at(ctx, binding->initializer, gb->value); 1161 } 1162 return gv_void; 1163 } 1164 1165 static struct gen_value 1166 gen_expr_control(struct gen_context *ctx, const struct expression *expr) 1167 { 1168 struct gen_scope *scope = gen_scope_lookup(ctx, expr->control.scope); 1169 1170 if (expr->control.value) { 1171 struct gen_value result = gen_expr_with(ctx, 1172 expr->control.value, scope->out); 1173 branch_copyresult(ctx, result, 1174 scope->result, scope->out); 1175 } 1176 1177 struct gen_scope *deferred = ctx->scope; 1178 while (deferred != NULL) { 1179 gen_defers(ctx, deferred); 1180 if (deferred == scope) { 1181 break; 1182 } 1183 deferred = deferred->parent; 1184 } 1185 1186 switch (expr->type) { 1187 case EXPR_BREAK: 1188 assert(scope->scope->class == SCOPE_LOOP); 1189 pushi(ctx->current, NULL, Q_JMP, scope->end, NULL); 1190 break; 1191 case EXPR_CONTINUE: 1192 assert(scope->scope->class == SCOPE_LOOP); 1193 pushi(ctx->current, NULL, Q_JMP, scope->after, NULL); 1194 break; 1195 case EXPR_YIELD: 1196 assert(scope->scope->class == SCOPE_COMPOUND); 1197 pushi(ctx->current, NULL, Q_JMP, scope->end, NULL); 1198 break; 1199 default: abort(); // Invariant 1200 } 1201 return gv_void; 1202 } 1203 1204 static struct gen_value 1205 gen_expr_call(struct gen_context *ctx, const struct expression *expr) 1206 { 1207 struct gen_value lvalue = gen_expr(ctx, expr->call.lvalue); 1208 lvalue = gen_autoderef(ctx, lvalue); 1209 1210 const struct type *rtype = type_dealias(lvalue.type); 1211 assert(rtype->storage == STORAGE_FUNCTION); 1212 1213 if (rtype->func.flags & FN_NORETURN) { 1214 for (struct gen_scope *scope = ctx->scope; scope; 1215 scope = scope->parent) { 1216 gen_defers(ctx, scope); 1217 } 1218 } 1219 1220 struct qbe_statement call = { 1221 .type = Q_INSTR, 1222 .instr = Q_CALL, 1223 }; 1224 struct gen_value rval = gv_void; 1225 if (type_dealias(rtype->func.result)->storage != STORAGE_VOID) { 1226 rval = mkgtemp(ctx, rtype->func.result, "returns.%d"); 1227 call.out = xcalloc(1, sizeof(struct qbe_value)); 1228 *call.out = mkqval(ctx, &rval); 1229 call.out->type = qtype_lookup(ctx, rtype->func.result, false); 1230 } 1231 1232 bool cvar = false; 1233 struct type_func_param *param = rtype->func.params; 1234 struct qbe_arguments *args, **next = &call.args; 1235 args = *next = xcalloc(1, sizeof(struct qbe_arguments)); 1236 args->value = mkqval(ctx, &lvalue); 1237 next = &args->next; 1238 for (struct call_argument *carg = expr->call.args; 1239 carg; carg = carg->next) { 1240 args = *next = xcalloc(1, sizeof(struct qbe_arguments)); 1241 struct gen_value arg = gen_expr(ctx, carg->value); 1242 args->value = mkqval(ctx, &arg); 1243 args->value.type = qtype_lookup(ctx, carg->value->result, false); 1244 next = &args->next; 1245 if (param) { 1246 param = param->next; 1247 } 1248 if (!param && !cvar && rtype->func.variadism == VARIADISM_C) { 1249 cvar = true; 1250 args = *next = xcalloc(1, sizeof(struct qbe_arguments)); 1251 args->value.kind = QV_VARIADIC; 1252 next = &args->next; 1253 } 1254 } 1255 push(&ctx->current->body, &call); 1256 1257 return rval; 1258 } 1259 1260 static struct gen_value gen_expr_cast(struct gen_context *ctx, 1261 const struct expression *expr); 1262 1263 static struct gen_value gen_subset_match_tests(struct gen_context *ctx, 1264 struct qbe_value bmatch, struct qbe_value bnext, 1265 struct qbe_value tag, const struct type *type); 1266 1267 static struct gen_value gen_nested_match_tests(struct gen_context *ctx, 1268 struct gen_value object, struct qbe_value bmatch, 1269 struct qbe_value bnext, struct qbe_value tag, 1270 const struct type *type); 1271 1272 static struct gen_value 1273 gen_type_assertion_or_test(struct gen_context *ctx, const struct expression *expr, 1274 struct gen_value base) 1275 { 1276 assert(expr->cast.kind == C_TEST || expr->cast.kind == C_ASSERTION); 1277 const struct type *want = expr->cast.secondary; 1278 struct qbe_value tag = mkqtmp(ctx, 1279 qtype_lookup(ctx, &builtin_type_uint, false), ".%d"); 1280 enum qbe_instr load = load_for_type(ctx, &builtin_type_uint); 1281 struct qbe_value qbase = mkqval(ctx, &base); 1282 pushi(ctx->current, &tag, load, &qbase, NULL); 1283 1284 struct qbe_statement failedl, passedl; 1285 struct qbe_value bfailed, bpassed = mklabel(ctx, &passedl, "passed.%d"); 1286 if (expr->cast.kind == C_ASSERTION) { 1287 bfailed = mklabel(ctx, &failedl, "failed.%d"); 1288 } else { 1289 bfailed = bpassed; 1290 } 1291 struct gen_value result = {0}; 1292 if (tagged_select_subtype(expr->cast.value->result, want, true)) { 1293 result = gen_nested_match_tests(ctx, base, bpassed, 1294 bfailed, tag, want); 1295 } else if (tagged_subset_compat(expr->cast.value->result, want)) { 1296 result = gen_subset_match_tests(ctx, bpassed, bfailed, tag, 1297 type_dealias(want)); 1298 } else { 1299 abort(); 1300 } 1301 1302 if (expr->cast.kind == C_ASSERTION) { 1303 push(&ctx->current->body, &failedl); 1304 gen_fixed_abort(ctx, expr->loc, ABORT_TYPE_ASSERTION); 1305 } 1306 push(&ctx->current->body, &passedl); 1307 return result; 1308 } 1309 1310 static void 1311 gen_expr_cast_slice_at(struct gen_context *ctx, 1312 const struct expression *expr, struct gen_value out) 1313 { 1314 const struct type *to = expr->result, 1315 *from = type_dealias(expr->cast.value->result); 1316 if (from->storage == STORAGE_POINTER) { 1317 from = type_dealias(from->pointer.referent); 1318 } 1319 assert(from->storage == STORAGE_ARRAY); 1320 assert(from->array.length != SIZE_UNDEFINED); 1321 1322 enum qbe_instr store = store_for_type(ctx, &builtin_type_size); 1323 struct qbe_value base = mklval(ctx, &out); 1324 struct qbe_value sz = constl(to->size); 1325 if (from->array.length == 0) { 1326 struct qbe_value tmp = constl(0); 1327 pushi(ctx->current, NULL, store, &tmp, &base, NULL); 1328 } else { 1329 struct gen_value value = gen_expr(ctx, expr->cast.value); 1330 struct qbe_value qvalue = mkqval(ctx, &value); 1331 pushi(ctx->current, NULL, store, &qvalue, &base, NULL); 1332 } 1333 struct qbe_value qptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 1334 sz = constl(builtin_type_size.size); 1335 struct qbe_value ln = constl(from->array.length); 1336 pushi(ctx->current, &qptr, Q_ADD, &base, &sz, NULL); 1337 pushi(ctx->current, NULL, store, &ln, &qptr, NULL); 1338 pushi(ctx->current, &qptr, Q_ADD, &qptr, &sz, NULL); 1339 pushi(ctx->current, NULL, store, &ln, &qptr, NULL); 1340 } 1341 1342 // Returns true if object's storage can be interpreted as want. 1343 static bool 1344 tagged_align_compat(const struct type *object, const struct type *want) 1345 { 1346 assert(type_dealias(object)->storage == STORAGE_TAGGED); 1347 assert(type_dealias(want)->storage == STORAGE_TAGGED); 1348 return object->align == want->align 1349 || want->size == builtin_type_uint.size; 1350 } 1351 1352 static void 1353 gen_expr_cast_tagged_at(struct gen_context *ctx, 1354 const struct expression *expr, struct gen_value out) 1355 { 1356 assert(expr->type == EXPR_CAST); 1357 const struct type *to = expr->result, *from = expr->cast.value->result; 1358 const struct type *subtype = tagged_select_subtype(to, from, true); 1359 1360 if (!subtype && tagged_align_compat(from, to)) { 1361 // Case 1: from is a union whose members are a subset or 1362 // superset of to, and the alignment matches, so we can just 1363 // interpret values of type 'from' as if it were of type 'to' 1364 struct gen_value out2 = out; 1365 out2.type = from; 1366 gen_expr_at(ctx, expr->cast.value, out2); 1367 if (expr->cast.kind == C_ASSERTION) { 1368 gen_type_assertion_or_test(ctx, expr, out2); 1369 } 1370 } else if (!subtype) { 1371 // Case 2: like case 1, but with an alignment mismatch; more 1372 // work is required. 1373 struct gen_value value = gen_expr(ctx, expr->cast.value); 1374 struct qbe_value qval = mkqval(ctx, &value); 1375 if (expr->cast.kind == C_ASSERTION) { 1376 gen_type_assertion_or_test(ctx, expr, value); 1377 } 1378 struct qbe_value qout = mkqval(ctx, &out); 1379 struct qbe_value tag = mkqtmp(ctx, 1380 qtype_lookup(ctx, &builtin_type_uint, false), "tag.%d"); 1381 enum qbe_instr load = load_for_type(ctx, &builtin_type_uint); 1382 enum qbe_instr store = store_for_type(ctx, &builtin_type_uint); 1383 pushi(ctx->current, &tag, load, &qval, NULL); 1384 pushi(ctx->current, NULL, store, &tag, &qout, NULL); 1385 if (to->size == builtin_type_uint.size || 1386 from->size == builtin_type_uint.size) { 1387 // No data area to copy 1388 return; 1389 } 1390 1391 subtype = tagged_subset_compat(to, from) ? from : to; 1392 const struct type *innertype = type_store_tagged_to_union( 1393 ctx->store, type_dealias(subtype)); 1394 struct gen_value iout = mkgtemp(ctx, innertype, ".%d"); 1395 struct gen_value ival = mkgtemp(ctx, innertype, ".%d"); 1396 struct qbe_value qiout = mkqval(ctx, &iout); 1397 struct qbe_value qival = mkqval(ctx, &ival); 1398 struct qbe_value offs = constl(to->align); 1399 pushi(ctx->current, &qiout, Q_ADD, &qout, &offs, NULL); 1400 offs = constl(from->align); 1401 pushi(ctx->current, &qival, Q_ADD, &qval, &offs, NULL); 1402 gen_copy_aligned(ctx, iout, ival); 1403 } else { 1404 // Case 3: from is a member of to 1405 assert(subtype == from); // Lowered by check 1406 struct qbe_value qout = mkqval(ctx, &out); 1407 struct qbe_value id = constw(subtype->id); 1408 enum qbe_instr store = store_for_type(ctx, &builtin_type_uint); 1409 pushi(ctx->current, NULL, store, &id, &qout, NULL); 1410 if (subtype->size == 0) { 1411 gen_expr(ctx, expr->cast.value); // side-effects 1412 return; 1413 } 1414 1415 struct gen_value storage = mkgtemp(ctx, subtype, ".%d"); 1416 struct qbe_value qstor = mklval(ctx, &storage); 1417 struct qbe_value offs = constl(to->align); 1418 pushi(ctx->current, &qstor, Q_ADD, &qout, &offs, NULL); 1419 gen_expr_at(ctx, expr->cast.value, storage); 1420 } 1421 } 1422 1423 static bool 1424 cast_prefers_at(const struct expression *expr) 1425 { 1426 const struct type *to = expr->result, *from = expr->cast.value->result; 1427 if (expr->cast.kind == C_TEST) { 1428 return false; 1429 } 1430 // tagged => *; subtype compatible 1431 if (type_dealias(from)->storage == STORAGE_TAGGED 1432 && tagged_select_subtype(from, to, true)) { 1433 return false; 1434 } 1435 // * => tagged 1436 if (type_dealias(to)->storage == STORAGE_TAGGED) { 1437 return true; 1438 } 1439 // array => array 1440 if (type_dealias(to)->storage == STORAGE_ARRAY 1441 && type_dealias(from)->storage == STORAGE_ARRAY) { 1442 return true; 1443 } 1444 // array => slice 1445 if (type_dealias(to)->storage == STORAGE_SLICE) { 1446 switch (type_dealias(from)->storage) { 1447 case STORAGE_ARRAY: 1448 return true; 1449 case STORAGE_POINTER: 1450 from = type_dealias(from)->pointer.referent; 1451 return type_dealias(from)->storage == STORAGE_ARRAY; 1452 default: 1453 return false; 1454 } 1455 } 1456 return false; 1457 } 1458 1459 static void 1460 gen_expr_cast_array_at(struct gen_context *ctx, 1461 const struct expression *expr, struct gen_value out) 1462 { 1463 const struct type *typeout = type_dealias(expr->result); 1464 const struct type *typein = type_dealias(expr->cast.value->result); 1465 gen_expr_at(ctx, expr->cast.value, out); 1466 if (!typein->array.expandable) { 1467 return; 1468 } 1469 1470 assert(typein->array.length != SIZE_UNDEFINED 1471 && typeout->array.length != SIZE_UNDEFINED); 1472 assert(typeout->array.length >= typein->array.length); 1473 1474 const struct type *membtype = typein->array.members; 1475 size_t remain = typeout->array.length - typein->array.length; 1476 1477 struct qbe_value base = mkqval(ctx, &out); 1478 struct qbe_value offs = constl((typein->array.length - 1) * membtype->size); 1479 struct gen_value next = mkgtemp(ctx, membtype, ".%d"); 1480 struct qbe_value ptr = mklval(ctx, &next); 1481 struct gen_value item = mkgtemp(ctx, membtype, "item.%d"); 1482 struct qbe_value qitem = mklval(ctx, &item); 1483 pushi(ctx->current, &qitem, Q_ADD, &base, &offs, NULL); 1484 1485 if (remain * membtype->size <= 128) { 1486 struct gen_value last = gen_load(ctx, item); 1487 for (size_t n = typein->array.length; n < typeout->array.length; ++n) { 1488 struct qbe_value offs = constl(n * membtype->size); 1489 pushi(ctx->current, &ptr, Q_ADD, &base, &offs, NULL); 1490 gen_store(ctx, next, last); 1491 } 1492 return; 1493 } 1494 1495 offs = constl(typein->array.length * membtype->size); 1496 pushi(ctx->current, &ptr, Q_ADD, &base, &offs, NULL); 1497 1498 struct qbe_value rtfunc = mkrtfunc(ctx, "rt.memcpy"); 1499 struct qbe_value dtemp = mklval(ctx, &next); 1500 struct qbe_value stemp = mklval(ctx, &item); 1501 struct qbe_value sz = constl(remain * membtype->size); 1502 pushi(ctx->current, NULL, Q_CALL, &rtfunc, &dtemp, &stemp, &sz, NULL); 1503 } 1504 1505 static void 1506 gen_expr_cast_at(struct gen_context *ctx, 1507 const struct expression *expr, struct gen_value out) 1508 { 1509 if (!cast_prefers_at(expr)) { 1510 struct gen_value result = gen_expr_cast(ctx, expr); 1511 if (!expr->terminates) { 1512 gen_store(ctx, out, result); 1513 } 1514 return; 1515 } 1516 1517 if (expr->cast.lowered) { 1518 pushc(ctx->current, "gen lowered cast"); 1519 } 1520 1521 const struct type *to = expr->result; 1522 switch (type_dealias(to)->storage) { 1523 case STORAGE_SLICE: 1524 gen_expr_cast_slice_at(ctx, expr, out); 1525 break; 1526 case STORAGE_TAGGED: 1527 gen_expr_cast_tagged_at(ctx, expr, out); 1528 break; 1529 case STORAGE_ARRAY: 1530 gen_expr_cast_array_at(ctx, expr, out); 1531 break; 1532 default: abort(); // Invariant 1533 } 1534 } 1535 1536 static struct qbe_value nested_tagged_offset(const struct type *tu, 1537 const struct type *targed); 1538 1539 static struct gen_value 1540 gen_expr_cast(struct gen_context *ctx, const struct expression *expr) 1541 { 1542 const struct type *to = expr->cast.secondary, 1543 *from = expr->cast.value->result; 1544 if (expr->cast.kind != C_CAST) { 1545 bool is_valid_tagged, is_valid_pointer; 1546 is_valid_tagged = type_dealias(from)->storage == STORAGE_TAGGED 1547 && (tagged_select_subtype(from, to, true) 1548 || tagged_subset_compat(from, to)); 1549 is_valid_pointer = type_dealias(from)->storage == STORAGE_POINTER 1550 && (type_dealias(to)->storage == STORAGE_POINTER 1551 || type_dealias(to)->storage == STORAGE_NULL); 1552 assert(is_valid_tagged || is_valid_pointer); 1553 if (expr->cast.kind == C_TEST && is_valid_tagged) { 1554 return gen_type_assertion_or_test(ctx, expr, 1555 gen_expr(ctx, expr->cast.value)); 1556 } 1557 } 1558 1559 if (cast_prefers_at(expr)) { 1560 struct gen_value out = mkgtemp(ctx, expr->result, "object.%d"); 1561 struct qbe_value base = mkqval(ctx, &out); 1562 struct qbe_value sz = constl(expr->result->size); 1563 enum qbe_instr alloc = alloc_for_align(expr->result->align); 1564 pushprei(ctx->current, &base, alloc, &sz, NULL); 1565 gen_expr_cast_at(ctx, expr, out); 1566 return out; 1567 } 1568 1569 if (expr->cast.lowered) { 1570 pushc(ctx->current, "gen lowered cast"); 1571 } 1572 1573 // Special cases 1574 bool want_null = false; 1575 switch (type_dealias(to)->storage) { 1576 case STORAGE_NULL: 1577 want_null = true; 1578 // fallthrough 1579 case STORAGE_POINTER: 1580 if (type_dealias(from)->storage == STORAGE_SLICE) { 1581 struct gen_value value = gen_expr(ctx, expr->cast.value); 1582 value.type = to; 1583 return gen_load(ctx, value); 1584 } 1585 if (type_dealias(from)->storage != STORAGE_POINTER) { 1586 break; 1587 } 1588 1589 struct gen_value val = gen_expr(ctx, expr->cast.value); 1590 struct qbe_value qval = mkqval(ctx, &val); 1591 struct qbe_value zero = constl(0); 1592 enum qbe_instr compare = want_null ? Q_CEQL : Q_CNEL; 1593 if (expr->cast.kind == C_TEST) { 1594 struct gen_value out = 1595 mkgtemp(ctx, &builtin_type_bool, ".%d"); 1596 struct qbe_value qout = mkqval(ctx, &out); 1597 1598 pushi(ctx->current, &qout, compare, &qval, &zero, NULL); 1599 return out; 1600 } else if (expr->cast.kind == C_ASSERTION) { 1601 struct qbe_statement failedl, passedl; 1602 struct qbe_value bfailed = 1603 mklabel(ctx, &failedl, "failed.%d"); 1604 struct qbe_value bpassed = 1605 mklabel(ctx, &passedl, "passed.%d"); 1606 1607 struct qbe_value cmpres = mkqtmp(ctx, &qbe_word, ".%d"); 1608 pushi(ctx->current, &cmpres, compare, &qval, &zero, NULL); 1609 pushi(ctx->current, NULL, Q_JNZ, &cmpres, 1610 &bpassed, &bfailed, NULL); 1611 push(&ctx->current->body, &failedl); 1612 gen_fixed_abort(ctx, expr->loc, ABORT_TYPE_ASSERTION); 1613 1614 push(&ctx->current->body, &passedl); 1615 if (want_null) { 1616 return (struct gen_value){ 1617 .kind = GV_CONST, 1618 .type = &builtin_type_null, 1619 .lval = 0, 1620 }; 1621 } 1622 } 1623 val.type = to; 1624 return val; 1625 case STORAGE_VOID: 1626 gen_expr(ctx, expr->cast.value); // Side-effects 1627 return gv_void; 1628 default: break; 1629 } 1630 1631 // Special case: tagged => non-tagged 1632 if (type_dealias(from)->storage == STORAGE_TAGGED) { 1633 struct gen_value value = gen_expr(ctx, expr->cast.value); 1634 struct qbe_value base = mkcopy(ctx, &value, ".%d"); 1635 if (expr->cast.kind == C_ASSERTION) { 1636 gen_type_assertion_or_test(ctx, expr, value); 1637 } 1638 1639 struct qbe_value align = nested_tagged_offset( 1640 expr->cast.value->result, expr->cast.secondary); 1641 pushi(ctx->current, &base, Q_ADD, &base, &align, NULL); 1642 struct gen_value storage = (struct gen_value){ 1643 .kind = GV_TEMP, 1644 .type = to, 1645 .name = base.name, 1646 }; 1647 return gen_load(ctx, storage); 1648 } 1649 1650 // Special case: no conversion required 1651 if (type_dealias(to)->storage == type_dealias(from)->storage 1652 && to->size == from->size) { 1653 struct gen_value value = gen_expr(ctx, expr->cast.value); 1654 value.type = to; 1655 return value; 1656 } 1657 1658 struct gen_value value = gen_expr(ctx, expr->cast.value); 1659 struct qbe_value qvalue = mkqval(ctx, &value); 1660 struct gen_value result = mkgtemp(ctx, expr->result, "cast.%d"); 1661 struct qbe_value qresult = mkqval(ctx, &result); 1662 struct gen_value intermediate; 1663 struct qbe_value qintermediate; 1664 1665 from = lower_const(from, NULL); 1666 1667 enum qbe_instr op; 1668 bool is_signed = type_is_signed(from); 1669 enum type_storage fstor = type_dealias(from)->storage, 1670 tstor = type_dealias(to)->storage; 1671 switch (tstor) { 1672 case STORAGE_CHAR: 1673 case STORAGE_ENUM: 1674 case STORAGE_U8: 1675 case STORAGE_I8: 1676 case STORAGE_I16: 1677 case STORAGE_U16: 1678 case STORAGE_I32: 1679 case STORAGE_U32: 1680 case STORAGE_INT: 1681 case STORAGE_UINT: 1682 case STORAGE_I64: 1683 case STORAGE_U64: 1684 case STORAGE_UINTPTR: 1685 case STORAGE_RUNE: 1686 case STORAGE_SIZE: 1687 if (type_is_integer(from) && to->size <= from->size) { 1688 op = Q_COPY; 1689 } else if (type_is_integer(from) && to->size > from->size) { 1690 switch (from->size) { 1691 case 4: op = is_signed ? Q_EXTSW : Q_EXTUW; break; 1692 case 2: op = is_signed ? Q_EXTSH : Q_EXTUH; break; 1693 case 1: op = is_signed ? Q_EXTSB : Q_EXTUB; break; 1694 default: abort(); // Invariant 1695 } 1696 } else if (fstor == STORAGE_POINTER || fstor == STORAGE_NULL) { 1697 assert(tstor == STORAGE_UINTPTR); 1698 op = Q_COPY; 1699 } else if (fstor == STORAGE_RUNE) { 1700 op = Q_COPY; 1701 } else if (type_is_float(from)) { 1702 if (type_is_signed(to)) { 1703 switch (fstor) { 1704 case STORAGE_F32: op = Q_STOSI; break; 1705 case STORAGE_F64: op = Q_DTOSI; break; 1706 default: abort(); // Invariant 1707 } 1708 } else { 1709 switch (fstor) { 1710 case STORAGE_F32: op = Q_STOUI; break; 1711 case STORAGE_F64: op = Q_DTOUI; break; 1712 default: abort(); // Invariant 1713 } 1714 } 1715 } else { 1716 abort(); // Invariant 1717 } 1718 pushi(ctx->current, &qresult, op, &qvalue, NULL); 1719 break; 1720 case STORAGE_F32: 1721 case STORAGE_F64: 1722 if (type_is_float(from) && from->size == to->size) { 1723 op = Q_COPY; 1724 } else if (type_is_float(from) && to->size < from->size) { 1725 op = Q_TRUNCD; 1726 } else if (type_is_float(from) && to->size > from->size) { 1727 op = Q_EXTS; 1728 } else if (type_is_integer(from)) { 1729 if (type_is_signed(from)) { 1730 switch (from->size) { 1731 case 1: 1732 case 2: 1733 intermediate = mkgtemp(ctx, 1734 &builtin_type_i32, "cast.%d"); 1735 qintermediate = mkqval(ctx, &intermediate); 1736 pushi(ctx->current, &qintermediate, 1737 from->size == 1? Q_EXTSB : Q_EXTSH, 1738 &qvalue, NULL); 1739 qvalue = qintermediate; 1740 /* fallthrough */ 1741 case 4: 1742 op = Q_SWTOF; 1743 break; 1744 case 8: 1745 op = Q_SLTOF; 1746 break; 1747 default: abort(); // Invariant 1748 } 1749 } else { 1750 switch (from->size) { 1751 case 1: 1752 case 2: 1753 intermediate = mkgtemp(ctx, 1754 &builtin_type_i32, "cast.%d"); 1755 qintermediate = mkqval(ctx, &intermediate); 1756 pushi(ctx->current, &qintermediate, 1757 from->size == 1? Q_EXTUB : Q_EXTUH, 1758 &qvalue, NULL); 1759 qvalue = qintermediate; 1760 /* fallthrough */ 1761 case 4: 1762 op = Q_UWTOF; 1763 break; 1764 case 8: 1765 op = Q_ULTOF; 1766 break; 1767 default: abort(); // Invariant 1768 } 1769 } 1770 } else { 1771 abort(); // Invariant 1772 } 1773 pushi(ctx->current, &qresult, op, &qvalue, NULL); 1774 break; 1775 case STORAGE_NULL: 1776 case STORAGE_POINTER: 1777 pushi(ctx->current, &qresult, Q_COPY, &qvalue, NULL); 1778 break; 1779 case STORAGE_ARRAY: 1780 assert(from->storage == STORAGE_ARRAY); 1781 pushi(ctx->current, &qresult, Q_COPY, &qvalue, NULL); 1782 break; 1783 case STORAGE_SLICE: 1784 assert(from->storage == STORAGE_SLICE); 1785 pushi(ctx->current, &qresult, Q_COPY, &qvalue, NULL); 1786 break; 1787 case STORAGE_ALIAS: 1788 case STORAGE_BOOL: 1789 case STORAGE_ERROR: 1790 case STORAGE_FCONST: 1791 case STORAGE_FUNCTION: 1792 case STORAGE_ICONST: 1793 case STORAGE_RCONST: 1794 case STORAGE_STRING: 1795 case STORAGE_STRUCT: 1796 case STORAGE_TAGGED: 1797 case STORAGE_TUPLE: 1798 case STORAGE_UNION: 1799 case STORAGE_VALIST: 1800 case STORAGE_VOID: 1801 abort(); // Invariant 1802 } 1803 1804 return result; 1805 } 1806 1807 static struct gen_value 1808 gen_expr_compound_with(struct gen_context *ctx, 1809 const struct expression *expr, 1810 struct gen_value *out) 1811 { 1812 struct qbe_statement lend; 1813 struct qbe_value bend = mklabel(ctx, &lend, ".%d"); 1814 struct gen_scope *scope = push_scope(ctx, expr->compound.scope); 1815 scope->end = &bend; 1816 1817 struct gen_value gvout = gv_void; 1818 if (!out) { 1819 gvout = mkgtemp(ctx, expr->result, ".%d"); 1820 } 1821 scope->out = out; 1822 scope->result = gvout; 1823 1824 const struct expressions *exprs; 1825 for (exprs = &expr->compound.exprs; exprs->next; exprs = exprs->next) { 1826 gen_expr(ctx, exprs->expr); 1827 } 1828 1829 struct gen_value last = gen_expr_with(ctx, exprs->expr, out); 1830 branch_copyresult(ctx, last, gvout, out); 1831 pop_scope(ctx, !exprs->expr->terminates); 1832 push(&ctx->current->body, &lend); 1833 return gvout; 1834 } 1835 1836 static void 1837 gen_const_array_at(struct gen_context *ctx, 1838 const struct expression *expr, 1839 struct gen_value out) 1840 { 1841 struct array_constant *aexpr = expr->constant.array; 1842 struct qbe_value base = mkqval(ctx, &out); 1843 1844 size_t n = 0; 1845 const struct type *atype = type_dealias(expr->result); 1846 size_t msize = atype->array.members->size; 1847 struct gen_value item = mkgtemp(ctx, atype->array.members, "item.%d"); 1848 for (const struct array_constant *ac = aexpr; ac; ac = ac->next) { 1849 struct qbe_value offs = constl(n * msize); 1850 struct qbe_value ptr = mklval(ctx, &item); 1851 pushi(ctx->current, &ptr, Q_ADD, &base, &offs, NULL); 1852 gen_expr_at(ctx, ac->value, item); 1853 ++n; 1854 } 1855 assert(n == atype->array.length); 1856 if (!atype->array.expandable || n == 0) { 1857 return; 1858 } 1859 assert(out.type); 1860 const struct type_array arr = type_dealias(out.type)->array; 1861 if (arr.length <= n) { 1862 return; 1863 } 1864 1865 // last copied element 1866 struct qbe_value lsize = constl((n - 1) * msize); 1867 struct qbe_value last = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 1868 pushi(ctx->current, &last, Q_ADD, &base, &lsize, NULL); 1869 // start from the elements already copied 1870 struct qbe_value nsize = constl(n * msize); 1871 struct qbe_value next = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 1872 pushi(ctx->current, &next, Q_ADD, &base, &nsize, NULL); 1873 1874 struct qbe_value rtmemcpy = mkrtfunc(ctx, "rt.memcpy"); 1875 struct qbe_value qlen = constl((arr.length - n) * msize); 1876 pushi(ctx->current, NULL, Q_CALL, &rtmemcpy, &next, &last, &qlen, NULL); 1877 } 1878 1879 static void 1880 gen_const_string_at(struct gen_context *ctx, 1881 const struct expression *expr, struct gen_value out) 1882 { 1883 const struct expression_constant *constant = &expr->constant; 1884 const char *val = constant->string.value; 1885 size_t len = constant->string.len; 1886 1887 // TODO: Generate string data structure as global also? 1888 struct qbe_value global = mkqtmp(ctx, ctx->arch.ptr, "strdata.%d"); 1889 global.kind = QV_GLOBAL; 1890 1891 struct qbe_def *def = xcalloc(1, sizeof(struct qbe_def)); 1892 def->name = global.name; 1893 def->kind = Q_DATA; 1894 def->data.align = ALIGN_UNDEFINED; 1895 def->data.items.type = QD_STRING; 1896 def->data.items.str = xcalloc(1, len); 1897 memcpy(def->data.items.str, val, len); 1898 def->data.items.sz = len; 1899 1900 if (len != 0) { 1901 qbe_append_def(ctx->out, def); 1902 } else { 1903 free(def); 1904 global = constl(0); 1905 } 1906 1907 enum qbe_instr store = store_for_type(ctx, &builtin_type_size); 1908 struct qbe_value strp = mkcopy(ctx, &out, ".%d"); 1909 struct qbe_value qlen = constl(len); 1910 struct qbe_value offs = constl(builtin_type_size.size); 1911 pushi(ctx->current, NULL, store, &global, &strp, NULL); 1912 pushi(ctx->current, &strp, Q_ADD, &strp, &offs, NULL); 1913 pushi(ctx->current, NULL, store, &qlen, &strp, NULL); 1914 pushi(ctx->current, &strp, Q_ADD, &strp, &offs, NULL); 1915 pushi(ctx->current, NULL, store, &qlen, &strp, NULL); 1916 } 1917 1918 static void 1919 gen_const_struct_at(struct gen_context *ctx, 1920 const struct expression *expr, struct gen_value out) 1921 { 1922 // TODO: Merge me into constant expressions 1923 struct qbe_value base = mkqval(ctx, &out); 1924 1925 struct gen_value ftemp = mkgtemp(ctx, &builtin_type_void, "field.%d"); 1926 for (const struct struct_constant *field = expr->constant._struct; 1927 field; field = field->next) { 1928 assert(field->value); 1929 1930 struct qbe_value offs = constl(field->field->offset); 1931 ftemp.type = field->value->result; 1932 struct qbe_value ptr = mklval(ctx, &ftemp); 1933 pushi(ctx->current, &ptr, Q_ADD, &base, &offs, NULL); 1934 gen_expr_at(ctx, field->value, ftemp); 1935 } 1936 } 1937 1938 static void 1939 gen_const_tagged_at(struct gen_context *ctx, 1940 const struct expression *expr, struct gen_value out) 1941 { 1942 struct qbe_value qout = mklval(ctx, &out); 1943 const struct type *subtype = expr->constant.tagged.tag; 1944 struct qbe_value id = constw(subtype->id); 1945 enum qbe_instr store = store_for_type(ctx, &builtin_type_uint); 1946 pushi(ctx->current, NULL, store, &id, &qout, NULL); 1947 if (subtype->size == 0) { 1948 return; 1949 } 1950 1951 struct gen_value storage = mkgtemp(ctx, subtype, ".%d"); 1952 struct qbe_value qstor = mklval(ctx, &storage); 1953 struct qbe_value offs = constl(expr->result->align); 1954 pushi(ctx->current, &qstor, Q_ADD, &qout, &offs, NULL); 1955 gen_expr_at(ctx, expr->constant.tagged.value, storage); 1956 } 1957 1958 static void 1959 gen_const_tuple_at(struct gen_context *ctx, 1960 const struct expression *expr, struct gen_value out) 1961 { 1962 // TODO: Merge me into constant expressions 1963 struct qbe_value base = mkqval(ctx, &out); 1964 1965 struct gen_value ftemp = mkgtemp(ctx, &builtin_type_void, "field.%d"); 1966 for (const struct tuple_constant *field = expr->constant.tuple; field; 1967 field = field->next) { 1968 assert(field->value); 1969 1970 struct qbe_value offs = constl(field->field->offset); 1971 ftemp.type = field->value->result; 1972 struct qbe_value ptr = mklval(ctx, &ftemp); 1973 pushi(ctx->current, &ptr, Q_ADD, &base, &offs, NULL); 1974 gen_expr_at(ctx, field->value, ftemp); 1975 } 1976 } 1977 1978 static void 1979 gen_expr_const_at(struct gen_context *ctx, 1980 const struct expression *expr, struct gen_value out) 1981 { 1982 if (!type_is_aggregate(type_dealias(expr->result))) { 1983 gen_store(ctx, out, gen_expr(ctx, expr)); 1984 return; 1985 } 1986 1987 switch (type_dealias(expr->result)->storage) { 1988 case STORAGE_ARRAY: 1989 gen_const_array_at(ctx, expr, out); 1990 break; 1991 case STORAGE_STRING: 1992 gen_const_string_at(ctx, expr, out); 1993 break; 1994 case STORAGE_STRUCT: 1995 gen_const_struct_at(ctx, expr, out); 1996 break; 1997 case STORAGE_TAGGED: 1998 gen_const_tagged_at(ctx, expr, out); 1999 break; 2000 case STORAGE_TUPLE: 2001 gen_const_tuple_at(ctx, expr, out); 2002 break; 2003 default: 2004 abort(); // Invariant 2005 } 2006 } 2007 2008 static struct gen_value 2009 gen_expr_const(struct gen_context *ctx, const struct expression *expr) 2010 { 2011 if (type_is_aggregate(type_dealias(expr->result))) { 2012 struct gen_value out = mkgtemp(ctx, expr->result, "object.%d"); 2013 struct qbe_value base = mkqval(ctx, &out); 2014 struct qbe_value sz = constl(expr->result->size); 2015 enum qbe_instr alloc = alloc_for_align(expr->result->align); 2016 pushprei(ctx->current, &base, alloc, &sz, NULL); 2017 gen_expr_at(ctx, expr, out); 2018 return out; 2019 } 2020 2021 struct gen_value val = { 2022 .kind = GV_CONST, 2023 .type = expr->result, 2024 }; 2025 2026 // Special cases 2027 switch (type_dealias(expr->result)->storage) { 2028 case STORAGE_BOOL: 2029 val.wval = expr->constant.bval ? 1 : 0; 2030 return val; 2031 case STORAGE_VOID: 2032 return val; 2033 case STORAGE_NULL: 2034 val.lval = 0; 2035 return val; 2036 default: 2037 // Moving right along 2038 break; 2039 } 2040 2041 if (expr->constant.object != NULL) { 2042 assert(expr->constant.ival == 0); 2043 val = gen_access_ident(ctx, expr->constant.object); 2044 val.type = expr->result; 2045 return val; 2046 } 2047 2048 const struct qbe_type *qtype = qtype_lookup(ctx, expr->result, false); 2049 switch (qtype->stype) { 2050 case Q_BYTE: 2051 case Q_HALF: 2052 case Q_WORD: 2053 val.wval = (uint32_t)expr->constant.uval; 2054 return val; 2055 case Q_LONG: 2056 val.lval = expr->constant.uval; 2057 return val; 2058 case Q_SINGLE: 2059 val.sval = (float)expr->constant.fval; 2060 return val; 2061 case Q_DOUBLE: 2062 val.dval = expr->constant.fval; 2063 return val; 2064 case Q__VOID: 2065 return val; 2066 case Q__AGGREGATE: 2067 assert(0); // Invariant 2068 } 2069 2070 abort(); // Invariant 2071 } 2072 2073 static struct gen_value 2074 gen_expr_defer(struct gen_context *ctx, const struct expression *expr) 2075 { 2076 struct gen_defer *defer = xcalloc(1, sizeof(struct gen_defer)); 2077 defer->expr = expr->defer.deferred; 2078 defer->next = ctx->scope->defers; 2079 ctx->scope->defers = defer; 2080 return gv_void; 2081 } 2082 2083 static struct gen_value 2084 gen_expr_delete(struct gen_context *ctx, const struct expression *expr) 2085 { 2086 struct gen_value object, start; 2087 const struct expression *dexpr = expr->delete.expr; 2088 if (dexpr->type == EXPR_SLICE) { 2089 object = gen_expr(ctx, dexpr->slice.object); 2090 if (dexpr->slice.start) { 2091 start = gen_expr(ctx, dexpr->slice.start); 2092 } else { 2093 start.kind = GV_CONST; 2094 start.type = &builtin_type_size; 2095 start.lval = 0; 2096 } 2097 } else { 2098 assert(dexpr->type == EXPR_ACCESS 2099 && dexpr->access.type == ACCESS_INDEX); 2100 object = gen_expr(ctx, dexpr->access.array); 2101 start = gen_expr(ctx, dexpr->access.index); 2102 } 2103 object = gen_autoderef(ctx, object); 2104 assert(type_dealias(object.type)->storage == STORAGE_SLICE); 2105 2106 struct qbe_value qobj = mkqval(ctx, &object); 2107 struct qbe_value qlenptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2108 struct qbe_value qlen = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2109 struct qbe_value offset = constl(builtin_type_size.size); 2110 enum qbe_instr load = load_for_type(ctx, &builtin_type_size); 2111 pushi(ctx->current, &qlenptr, Q_ADD, &qobj, &offset, NULL); 2112 pushi(ctx->current, &qlen, load, &qlenptr, NULL); 2113 2114 struct qbe_value qstart = mkqval(ctx, &start); 2115 struct qbe_value qend = {0}; 2116 if (dexpr->type == EXPR_SLICE) { 2117 if (dexpr->slice.end) { 2118 struct gen_value end = gen_expr(ctx, dexpr->slice.end); 2119 qend = mkqval(ctx, &end); 2120 } else { 2121 qend = qlen; 2122 } 2123 } else { 2124 struct qbe_value tmp = constl(1); 2125 qend = mkqtmp(ctx, qstart.type, ".%d"); 2126 pushi(ctx->current, &qend, Q_ADD, &qstart, &tmp, NULL); 2127 } 2128 2129 struct qbe_value start_oob = mkqtmp(ctx, &qbe_word, ".%d"); 2130 struct qbe_value end_oob = mkqtmp(ctx, &qbe_word, ".%d"); 2131 struct qbe_value startend_oob = mkqtmp(ctx, &qbe_word, ".%d"); 2132 struct qbe_value valid = mkqtmp(ctx, &qbe_word, ".%d"); 2133 pushi(ctx->current, &start_oob, Q_CULEL, &qstart, &qlen, NULL); 2134 pushi(ctx->current, &end_oob, Q_CULEL, &qend, &qlen, NULL); 2135 pushi(ctx->current, &valid, Q_AND, &start_oob, &end_oob, NULL); 2136 pushi(ctx->current, &startend_oob, Q_CULEL, &qstart, &qend, NULL); 2137 pushi(ctx->current, &valid, Q_AND, &valid, &startend_oob, NULL); 2138 2139 struct qbe_statement linvalid, lvalid; 2140 struct qbe_value binvalid = mklabel(ctx, &linvalid, ".%d"); 2141 struct qbe_value bvalid = mklabel(ctx, &lvalid, ".%d"); 2142 2143 pushi(ctx->current, NULL, Q_JNZ, &valid, &bvalid, &binvalid, NULL); 2144 push(&ctx->current->body, &linvalid); 2145 gen_fixed_abort(ctx, expr->loc, ABORT_OOB); 2146 push(&ctx->current->body, &lvalid); 2147 2148 struct qbe_value data = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2149 struct qbe_value startptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2150 struct qbe_value endptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2151 struct qbe_value mlen = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2152 pushi(ctx->current, &data, load, &qobj, NULL); 2153 struct qbe_value membsz = 2154 constl(type_dealias(object.type)->array.members->size); 2155 pushi(ctx->current, &startptr, Q_MUL, &qstart, &membsz, NULL); 2156 pushi(ctx->current, &startptr, Q_ADD, &startptr, &data, NULL); 2157 pushi(ctx->current, &endptr, Q_MUL, &qend, &membsz, NULL); 2158 pushi(ctx->current, &endptr, Q_ADD, &endptr, &data, NULL); 2159 pushi(ctx->current, &qlen, Q_SUB, &qlen, &qend, NULL); 2160 pushi(ctx->current, &mlen, Q_MUL, &qlen, &membsz, NULL); 2161 2162 struct qbe_value rtmemmove = mkrtfunc(ctx, "rt.memmove"); 2163 pushi(ctx->current, NULL, Q_CALL, &rtmemmove, &startptr, &endptr, &mlen, 2164 NULL); 2165 2166 pushi(ctx->current, &qlen, Q_ADD, &qlen, &qstart, NULL); 2167 enum qbe_instr store = store_for_type(ctx, &builtin_type_size); 2168 pushi(ctx->current, NULL, store, &qlen, &qlenptr, NULL); 2169 2170 if (!expr->delete.is_static) { 2171 struct qbe_value rtunensure = mkrtfunc(ctx, "rt.unensure"); 2172 qobj = mklval(ctx, &object); 2173 pushi(ctx->current, NULL, Q_CALL, &rtunensure, &qobj, &membsz, 2174 NULL); 2175 } 2176 2177 return gv_void; 2178 } 2179 2180 static struct gen_value 2181 gen_expr_for(struct gen_context *ctx, const struct expression *expr) 2182 { 2183 struct qbe_statement lloop, lbody, lafter, lend; 2184 struct qbe_value bloop = mklabel(ctx, &lloop, "loop.%d"); 2185 struct qbe_value bbody = mklabel(ctx, &lbody, "body.%d"); 2186 struct qbe_value bend = mklabel(ctx, &lend, ".%d"); 2187 struct qbe_value bafter = mklabel(ctx, &lafter, "after.%d"); 2188 2189 if (expr->_for.bindings) { 2190 gen_expr_binding(ctx, expr->_for.bindings); 2191 } 2192 2193 push_scope(ctx, expr->_for.scope); 2194 ctx->scope->after = &bafter; 2195 ctx->scope->end = &bend; 2196 2197 push(&ctx->current->body, &lloop); 2198 struct gen_value cond = gen_expr(ctx, expr->_for.cond); 2199 struct qbe_value qcond = mkqval(ctx, &cond); 2200 pushi(ctx->current, NULL, Q_JNZ, &qcond, &bbody, &bend, NULL); 2201 2202 push(&ctx->current->body, &lbody); 2203 gen_expr(ctx, expr->_for.body); 2204 2205 push(&ctx->current->body, &lafter); 2206 if (expr->_for.afterthought) { 2207 gen_expr(ctx, expr->_for.afterthought); 2208 } 2209 2210 pop_scope(ctx, true); 2211 2212 pushi(ctx->current, NULL, Q_JMP, &bloop, NULL); 2213 2214 push(&ctx->current->body, &lend); 2215 return gv_void; 2216 } 2217 2218 static struct gen_value 2219 gen_expr_free(struct gen_context *ctx, const struct expression *expr) 2220 { 2221 const struct type *type = type_dealias(expr->free.expr->result); 2222 struct qbe_value rtfunc = mkrtfunc(ctx, "rt.free"); 2223 struct gen_value val = gen_expr(ctx, expr->free.expr); 2224 struct qbe_value qval = mkqval(ctx, &val); 2225 if (type->storage == STORAGE_SLICE || type->storage == STORAGE_STRING) { 2226 struct qbe_value lval = mklval(ctx, &val); 2227 qval = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2228 pushi(ctx->current, &qval, Q_LOADL, &lval, NULL); 2229 } 2230 pushi(ctx->current, NULL, Q_CALL, &rtfunc, &qval, NULL); 2231 return gv_void; 2232 } 2233 2234 static struct gen_value 2235 gen_expr_if_with(struct gen_context *ctx, 2236 const struct expression *expr, 2237 struct gen_value *out) 2238 { 2239 struct gen_value gvout = gv_void; 2240 if (!out) { 2241 gvout = mkgtemp(ctx, expr->result, ".%d"); 2242 } 2243 2244 struct qbe_statement ltrue, lfalse, lend; 2245 struct qbe_value btrue = mklabel(ctx, <rue, "true.%d"); 2246 struct qbe_value bfalse = mklabel(ctx, &lfalse, "false.%d"); 2247 struct qbe_value bend = mklabel(ctx, &lend, ".%d"); 2248 struct gen_value cond = gen_expr(ctx, expr->_if.cond); 2249 struct qbe_value qcond = mkqval(ctx, &cond); 2250 qcond = extend(ctx, qcond, &builtin_type_bool); 2251 pushi(ctx->current, NULL, Q_JNZ, &qcond, &btrue, &bfalse, NULL); 2252 2253 push(&ctx->current->body, <rue); 2254 struct gen_value vtrue = gen_expr_with(ctx, expr->_if.true_branch, out); 2255 branch_copyresult(ctx, vtrue, gvout, out); 2256 if (!expr->_if.true_branch->terminates) { 2257 pushi(ctx->current, NULL, Q_JMP, &bend, NULL); 2258 } 2259 2260 push(&ctx->current->body, &lfalse); 2261 if (expr->_if.false_branch) { 2262 struct gen_value vfalse = gen_expr_with(ctx, 2263 expr->_if.false_branch, out); 2264 branch_copyresult(ctx, vfalse, gvout, out); 2265 } 2266 2267 push(&ctx->current->body, &lend); 2268 return gvout; 2269 } 2270 2271 static struct gen_value 2272 gen_expr_insert(struct gen_context *ctx, const struct expression *expr) 2273 { 2274 // XXX: A lot of this code is identical to the corresponding append 2275 // code, maybe we can/should deduplicate it 2276 assert(expr->append.length == NULL); 2277 const struct expression *objexpr = expr->append.object; 2278 assert(objexpr->type == EXPR_ACCESS 2279 && objexpr->access.type == ACCESS_INDEX); 2280 const struct expression *arexpr = objexpr->access.array; 2281 struct gen_value slice = gen_expr(ctx, arexpr); 2282 slice = gen_autoderef(ctx, slice); 2283 struct qbe_value qslice = mkqval(ctx, &slice); 2284 struct gen_value index = gen_expr(ctx, objexpr->access.index); 2285 struct qbe_value qindex = mkqval(ctx, &index); 2286 2287 struct qbe_value lenptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2288 struct qbe_value prevlen = mkqtmp(ctx, ctx->arch.sz, ".%d"); 2289 struct qbe_value offs = constl(builtin_type_size.size); 2290 pushi(ctx->current, &lenptr, Q_ADD, &qslice, &offs, NULL); 2291 enum qbe_instr load = load_for_type(ctx, &builtin_type_size); 2292 pushi(ctx->current, &prevlen, load, &lenptr, NULL); 2293 2294 struct qbe_value appendlen = constl(1); 2295 const struct type *valtype = type_dealias(expr->append.value->result); 2296 2297 struct gen_value value; 2298 struct qbe_value qvalue; 2299 if (!expr->append.is_multi || valtype->storage != STORAGE_ARRAY) { 2300 // We use gen_expr_at for the array case to avoid a copy 2301 value = gen_expr(ctx, expr->append.value); 2302 qvalue = mkqval(ctx, &value); 2303 } 2304 2305 if (expr->append.is_multi) { 2306 if (valtype->storage == STORAGE_ARRAY) { 2307 assert(valtype->array.length != SIZE_UNDEFINED); 2308 appendlen = constl(valtype->array.length); 2309 } else { 2310 appendlen = mkqtmp(ctx, ctx->arch.sz, ".%d"); 2311 struct qbe_value ptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2312 offs = constl(builtin_type_size.size); 2313 pushi(ctx->current, &ptr, Q_ADD, &qvalue, &offs, NULL); 2314 pushi(ctx->current, &appendlen, load, &ptr, NULL); 2315 } 2316 } 2317 2318 struct qbe_value newlen = mkqtmp(ctx, ctx->arch.sz, ".%d"); 2319 pushi(ctx->current, &newlen, Q_ADD, &prevlen, &appendlen, NULL); 2320 enum qbe_instr store = store_for_type(ctx, &builtin_type_size); 2321 pushi(ctx->current, NULL, store, &newlen, &lenptr, NULL); 2322 2323 struct qbe_value ptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2324 const struct type *mtype = type_dealias(slice.type)->array.members; 2325 struct qbe_value membsz = constl(mtype->size); 2326 if (!expr->append.is_static) { 2327 struct qbe_value rtfunc = mkrtfunc(ctx, "rt.ensure"); 2328 struct qbe_value lval = mklval(ctx, &slice); 2329 pushi(ctx->current, NULL, Q_CALL, &rtfunc, &lval, &membsz, NULL); 2330 } else { 2331 offs = constl(builtin_type_size.size * 2); 2332 pushi(ctx->current, &ptr, Q_ADD, &qslice, &offs, NULL); 2333 struct qbe_value cap = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2334 pushi(ctx->current, &cap, load, &ptr, NULL); 2335 2336 struct qbe_statement lvalid, linvalid; 2337 struct qbe_value bvalid = mklabel(ctx, &lvalid, ".%d"); 2338 struct qbe_value binvalid = mklabel(ctx, &linvalid, ".%d"); 2339 struct qbe_value valid = mkqtmp(ctx, &qbe_word, ".%d"); 2340 pushi(ctx->current, &valid, Q_CULEL, &newlen, &cap, NULL); 2341 pushi(ctx->current, NULL, Q_JNZ, &valid, &bvalid, &binvalid, NULL); 2342 2343 push(&ctx->current->body, &linvalid); 2344 gen_fixed_abort(ctx, expr->loc, ABORT_OOB); 2345 push(&ctx->current->body, &lvalid); 2346 } 2347 2348 struct qbe_value base = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2349 pushi(ctx->current, &base, load, &qslice, NULL); 2350 2351 pushi(ctx->current, &ptr, Q_MUL, &qindex, &membsz, NULL); 2352 pushi(ctx->current, &ptr, Q_ADD, &base, &ptr, NULL); 2353 2354 struct qbe_value nbyte = mkqtmp(ctx, ctx->arch.sz, ".%d"); 2355 struct qbe_value dest = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2356 struct qbe_value ncopy = mkqtmp(ctx, ctx->arch.sz, ".%d"); 2357 pushi(ctx->current, &nbyte, Q_MUL, &appendlen, &membsz, NULL); 2358 pushi(ctx->current, &ncopy, Q_SUB, &prevlen, &qindex, NULL); 2359 pushi(ctx->current, &ncopy, Q_MUL, &ncopy, &membsz, NULL); 2360 pushi(ctx->current, &dest, Q_ADD, &ptr, &nbyte, NULL); 2361 2362 struct qbe_value rtfunc = mkrtfunc(ctx, "rt.memmove"); 2363 pushi(ctx->current, NULL, Q_CALL, &rtfunc, &dest, &ptr, &ncopy, NULL); 2364 2365 struct gen_value item = { 2366 .kind = GV_TEMP, 2367 .type = mtype, 2368 .name = ptr.name, 2369 }; 2370 if (expr->append.is_multi && valtype->storage == STORAGE_ARRAY) { 2371 item.type = valtype; 2372 gen_expr_at(ctx, expr->append.value, item); 2373 } else if (expr->append.is_multi && valtype->storage == STORAGE_SLICE) { 2374 struct qbe_value qsrc = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2375 struct qbe_value rtfunc = mkrtfunc(ctx, "rt.memmove"); 2376 pushi(ctx->current, &qsrc, load, &qvalue, NULL); 2377 pushi(ctx->current, NULL, Q_CALL, &rtfunc, &ptr, &qsrc, &nbyte, NULL); 2378 } else { 2379 gen_store(ctx, item, value); 2380 } 2381 2382 return gv_void; 2383 } 2384 2385 enum match_compat { 2386 // The case type is a member of the match object type and can be used 2387 // directly from the match object's tagged union storage area. 2388 COMPAT_SUBTYPE, 2389 // The case type is a tagged union which is a subset of the object type, 2390 // and alignment-compatible. In this case we can use the match object 2391 // directly. 2392 COMPAT_ALIGNED, 2393 // The case type is a tagged union which is a subset of the object type, 2394 // but with a different alignment. In this case we must convert the 2395 // match object before using it. 2396 COMPAT_MISALIGNED, 2397 }; 2398 2399 static struct qbe_value 2400 nested_tagged_offset(const struct type *tu, const struct type *target) 2401 { 2402 // This function calculates the offset of a member in a nested tagged union 2403 // 2404 // type foo = (int | void); 2405 // type bar = (size | foo); 2406 // 2407 // Offset of the foo field from the start of bar is 8 and offset of int 2408 // inside foo is 4, so the offset of the int from the start of bar is 12 2409 const struct type *test = tu; 2410 struct qbe_value offset = constl(tu->align); 2411 do { 2412 test = tagged_select_subtype(tu, target, false); 2413 if (!test) { 2414 break; 2415 } 2416 if (test->id != target->id && type_dealias(test)->id != target->id) { 2417 offset.lval += test->align; 2418 } 2419 tu = test; 2420 } while (test->id != target->id && type_dealias(test)->id != target->id); 2421 return offset; 2422 } 2423 2424 static struct gen_value 2425 gen_nested_match_tests(struct gen_context *ctx, struct gen_value object, 2426 struct qbe_value bmatch, struct qbe_value bnext, 2427 struct qbe_value tag, const struct type *type) 2428 { 2429 // This function handles the case where we're matching against a type 2430 // which is a member of the tagged union, or an inner tagged union. 2431 // 2432 // type foo = (int | void); 2433 // type bar = (size | foo); 2434 // 2435 // let x: bar = 10i; 2436 // match (x) { 2437 // case let z: size => ... 2438 // case let i: int => ... 2439 // case void => ... 2440 // }; 2441 // 2442 // In the first case, we can simply test the object's tag. In the second 2443 // case, we have to test if the selected tag is 'foo', then check the 2444 // tag of the foo object for int. 2445 struct qbe_value *subtag = &tag; 2446 struct qbe_value subval = mkcopy(ctx, &object, "subval.%d"); 2447 struct gen_value match = mkgtemp(ctx, &builtin_type_bool, ".%d"); 2448 struct qbe_value qmatch = mkqval(ctx, &match); 2449 struct qbe_value temp = mkqtmp(ctx, &qbe_word, ".%d"); 2450 const struct type *subtype = object.type; 2451 const struct type *test = type; 2452 do { 2453 struct qbe_statement lsubtype; 2454 struct qbe_value bsubtype = mklabel(ctx, &lsubtype, "subtype.%d"); 2455 2456 if (type_dealias(subtype)->storage != STORAGE_TAGGED) { 2457 break; 2458 } 2459 test = tagged_select_subtype(subtype, type, false); 2460 if (!test) { 2461 break; 2462 } 2463 2464 struct qbe_value id = constw(test->id); 2465 pushi(ctx->current, &qmatch, Q_CEQW, subtag, &id, NULL); 2466 pushi(ctx->current, NULL, Q_JNZ, &qmatch, &bsubtype, &bnext, NULL); 2467 push(&ctx->current->body, &lsubtype); 2468 2469 if (test->id != type->id && type_dealias(test)->id != type->id) { 2470 struct qbe_value offs = constl(subtype->align); 2471 pushi(ctx->current, &subval, Q_ADD, &subval, &offs, NULL); 2472 pushi(ctx->current, &temp, Q_LOADUW, &subval, NULL); 2473 subtag = &temp; 2474 } 2475 2476 subtype = test; 2477 } while (test->id != type->id && type_dealias(test)->id != type->id); 2478 2479 pushi(ctx->current, NULL, Q_JMP, &bmatch, NULL); 2480 return match; 2481 } 2482 2483 static struct gen_value 2484 gen_subset_match_tests(struct gen_context *ctx, 2485 struct qbe_value bmatch, struct qbe_value bnext, 2486 struct qbe_value tag, const struct type *type) 2487 { 2488 // In this case, we're testing a case which is itself a tagged union, 2489 // and is a subset of the match object. 2490 // 2491 // type foo = (size | int | void); 2492 // 2493 // let x: foo = 10i; 2494 // match (x) { 2495 // case let n: (size | int) => ... 2496 // case void => ... 2497 // }; 2498 // 2499 // In this situation, we test the match object's tag against each type 2500 // ID of the case type. 2501 struct gen_value match = mkgtemp(ctx, &builtin_type_bool, ".%d"); 2502 for (const struct type_tagged_union *tu = &type->tagged; tu; tu = tu->next) { 2503 struct qbe_statement lnexttag; 2504 struct qbe_value bnexttag = mklabel(ctx, &lnexttag, ".%d"); 2505 struct qbe_value id = constl(tu->type->id); 2506 struct qbe_value qmatch = mkqval(ctx, &match); 2507 pushi(ctx->current, &qmatch, Q_CEQW, &tag, &id, NULL); 2508 pushi(ctx->current, NULL, Q_JNZ, &qmatch, &bmatch, &bnexttag, NULL); 2509 push(&ctx->current->body, &lnexttag); 2510 } 2511 pushi(ctx->current, NULL, Q_JMP, &bnext, NULL); 2512 return match; 2513 } 2514 2515 static struct gen_value 2516 gen_match_with_tagged(struct gen_context *ctx, 2517 const struct expression *expr, 2518 struct gen_value *out) 2519 { 2520 struct gen_value gvout = gv_void; 2521 if (!out) { 2522 gvout = mkgtemp(ctx, expr->result, ".%d"); 2523 } 2524 2525 const struct type *objtype = expr->match.value->result; 2526 struct gen_value object = gen_expr(ctx, expr->match.value); 2527 struct qbe_value qobject = mkqval(ctx, &object); 2528 struct qbe_value tag = mkqtmp(ctx, ctx->arch.sz, "tag.%d"); 2529 enum qbe_instr load = load_for_type(ctx, &builtin_type_uint); 2530 pushi(ctx->current, &tag, load, &qobject, NULL); 2531 2532 struct qbe_statement lout; 2533 struct qbe_value bout = mklabel(ctx, &lout, ".%d"); 2534 2535 struct gen_value bval; 2536 const struct match_case *_default = NULL; 2537 for (const struct match_case *_case = expr->match.cases; 2538 _case; _case = _case->next) { 2539 if (!_case->type) { 2540 _default = _case; 2541 continue; 2542 } 2543 2544 struct qbe_statement lmatch, lnext; 2545 struct qbe_value bmatch = mklabel(ctx, &lmatch, "matches.%d"); 2546 struct qbe_value bnext = mklabel(ctx, &lnext, "next.%d"); 2547 const struct type *subtype = 2548 tagged_select_subtype(objtype, _case->type, false); 2549 enum match_compat compat = COMPAT_SUBTYPE; 2550 if (subtype) { 2551 gen_nested_match_tests(ctx, object, 2552 bmatch, bnext, tag, _case->type); 2553 } else { 2554 assert(type_dealias(_case->type)->storage == STORAGE_TAGGED); 2555 assert(tagged_subset_compat(objtype, _case->type)); 2556 if (tagged_align_compat(objtype, _case->type)) { 2557 compat = COMPAT_ALIGNED; 2558 } else { 2559 compat = COMPAT_MISALIGNED; 2560 } 2561 const struct type *casetype = type_dealias(_case->type); 2562 gen_subset_match_tests(ctx, bmatch, bnext, tag, casetype); 2563 } 2564 2565 push(&ctx->current->body, &lmatch); 2566 2567 if (!_case->object) { 2568 goto next; 2569 } 2570 2571 struct gen_binding *gb = xcalloc(1, sizeof(struct gen_binding)); 2572 gb->value.kind = GV_TEMP; 2573 gb->value.type = _case->type; 2574 gb->value.name = gen_name(&ctx->id, "binding.%d"); 2575 gb->object = _case->object; 2576 gb->next = ctx->bindings; 2577 ctx->bindings = gb; 2578 2579 struct qbe_value qv = mklval(ctx, &gb->value); 2580 enum qbe_instr alloc = alloc_for_align(_case->type->align); 2581 struct qbe_value sz = constl(_case->type->size); 2582 pushprei(ctx->current, &qv, alloc, &sz, NULL); 2583 2584 struct qbe_value ptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2585 struct gen_value src = { 2586 .kind = GV_TEMP, 2587 .type = _case->type, 2588 .name = ptr.name, 2589 }; 2590 struct gen_value load; 2591 struct qbe_value offset; 2592 switch (compat) { 2593 case COMPAT_SUBTYPE: 2594 offset = nested_tagged_offset(object.type, _case->type); 2595 pushi(ctx->current, &ptr, Q_ADD, &qobject, &offset, NULL); 2596 load = gen_load(ctx, src); 2597 gen_store(ctx, gb->value, load); 2598 break; 2599 case COMPAT_ALIGNED: 2600 pushi(ctx->current, &ptr, Q_COPY, &qobject, NULL); 2601 load = gen_load(ctx, src); 2602 gen_store(ctx, gb->value, load); 2603 break; 2604 case COMPAT_MISALIGNED: 2605 ; 2606 struct expression value = { 2607 .type = EXPR_GEN_VALUE, 2608 .result = objtype, 2609 .user = &object, 2610 }; 2611 struct expression cast = { 2612 .type = EXPR_CAST, 2613 .result = _case->type, 2614 .cast = { 2615 .kind = C_CAST, 2616 .secondary = _case->type, 2617 .value = &value, 2618 }, 2619 }; 2620 gen_expr_at(ctx, &cast, gb->value); 2621 break; 2622 } 2623 2624 next: 2625 bval = gen_expr_with(ctx, _case->value, out); 2626 branch_copyresult(ctx, bval, gvout, out); 2627 if (!_case->value->terminates) { 2628 pushi(ctx->current, NULL, Q_JMP, &bout, NULL); 2629 } 2630 push(&ctx->current->body, &lnext); 2631 } 2632 2633 if (_default) { 2634 bval = gen_expr_with(ctx, _default->value, out); 2635 branch_copyresult(ctx, bval, gvout, out); 2636 } else { 2637 struct qbe_statement labort; 2638 mklabel(ctx, &labort, ".%d"); 2639 push(&ctx->current->body, &labort); 2640 gen_fixed_abort(ctx, expr->loc, ABORT_UNREACHABLE); 2641 } 2642 2643 push(&ctx->current->body, &lout); 2644 return gvout; 2645 } 2646 2647 static struct gen_value 2648 gen_match_with_nullable(struct gen_context *ctx, 2649 const struct expression *expr, 2650 struct gen_value *out) 2651 { 2652 struct gen_value gvout = gv_void; 2653 if (!out) { 2654 gvout = mkgtemp(ctx, expr->result, ".%d"); 2655 } 2656 2657 struct qbe_statement lout; 2658 struct qbe_value bout = mklabel(ctx, &lout, ".%d"); 2659 struct gen_value object = gen_expr(ctx, expr->match.value); 2660 struct qbe_value qobject = mkqval(ctx, &object); 2661 struct qbe_value zero = constl(0); 2662 2663 struct gen_value bval; 2664 const struct match_case *_default = NULL; 2665 for (const struct match_case *_case = expr->match.cases; 2666 _case; _case = _case->next) { 2667 if (!_case->type) { 2668 _default = _case; 2669 continue; 2670 } 2671 2672 struct qbe_statement lmatch, lnext; 2673 struct qbe_value cmpres = mkqtmp(ctx, &qbe_word, ".%d"); 2674 struct qbe_value bmatch = mklabel(ctx, &lmatch, "matches.%d"); 2675 struct qbe_value bnext = mklabel(ctx, &lnext, "next.%d"); 2676 2677 enum qbe_instr compare; 2678 if (_case->type->storage == STORAGE_NULL) { 2679 compare = Q_CEQL; 2680 } else { 2681 compare = Q_CNEL; 2682 } 2683 pushi(ctx->current, &cmpres, compare, &qobject, &zero, NULL); 2684 pushi(ctx->current, NULL, Q_JNZ, &cmpres, &bmatch, &bnext, NULL); 2685 2686 push(&ctx->current->body, &lmatch); 2687 2688 if (!_case->object) { 2689 goto next; 2690 } 2691 2692 struct gen_binding *gb = xcalloc(1, sizeof(struct gen_binding)); 2693 gb->value = mkgtemp(ctx, _case->type, "binding.%d"); 2694 gb->object = _case->object; 2695 gb->next = ctx->bindings; 2696 ctx->bindings = gb; 2697 2698 enum qbe_instr store = store_for_type(ctx, _case->type); 2699 enum qbe_instr alloc = alloc_for_align(_case->type->align); 2700 struct qbe_value qv = mkqval(ctx, &gb->value); 2701 struct qbe_value sz = constl(_case->type->size); 2702 pushprei(ctx->current, &qv, alloc, &sz, NULL); 2703 pushi(ctx->current, NULL, store, &qobject, &qv, NULL); 2704 2705 next: 2706 bval = gen_expr_with(ctx, _case->value, out); 2707 branch_copyresult(ctx, bval, gvout, out); 2708 if (!_case->value->terminates) { 2709 pushi(ctx->current, NULL, Q_JMP, &bout, NULL); 2710 } 2711 push(&ctx->current->body, &lnext); 2712 } 2713 2714 if (_default) { 2715 bval = gen_expr_with(ctx, _default->value, out); 2716 branch_copyresult(ctx, bval, gvout, out); 2717 if (!_default->value->terminates) { 2718 pushi(ctx->current, NULL, Q_JMP, &bout, NULL); 2719 } 2720 } 2721 2722 struct qbe_statement labort; 2723 mklabel(ctx, &labort, ".%d"); 2724 push(&ctx->current->body, &labort); 2725 gen_fixed_abort(ctx, expr->loc, ABORT_UNREACHABLE); 2726 2727 push(&ctx->current->body, &lout); 2728 return gvout; 2729 } 2730 2731 static struct gen_value 2732 gen_expr_match_with(struct gen_context *ctx, 2733 const struct expression *expr, 2734 struct gen_value *out) 2735 { 2736 const struct type *objtype = expr->match.value->result; 2737 switch (type_dealias(objtype)->storage) { 2738 case STORAGE_POINTER: 2739 return gen_match_with_nullable(ctx, expr, out); 2740 case STORAGE_TAGGED: 2741 return gen_match_with_tagged(ctx, expr, out); 2742 default: abort(); // Invariant 2743 } 2744 } 2745 2746 static struct gen_value 2747 gen_expr_measure(struct gen_context *ctx, const struct expression *expr) 2748 { 2749 size_t len; 2750 struct gen_value gv, temp; 2751 const struct type *type; 2752 const struct expression *value = expr->measure.value; 2753 switch (expr->measure.op) { 2754 case M_LEN: 2755 type = type_dealias(type_dereference(value->result)); 2756 switch (type->storage) { 2757 case STORAGE_ARRAY: 2758 len = type->array.length; 2759 assert(len != SIZE_UNDEFINED); 2760 return (struct gen_value){ 2761 .kind = GV_CONST, 2762 .type = &builtin_type_size, 2763 .lval = len, 2764 }; 2765 case STORAGE_SLICE: 2766 case STORAGE_STRING: 2767 gv = gen_expr(ctx, value); 2768 gv = gen_autoderef(ctx, gv); 2769 temp = mkgtemp(ctx, &builtin_type_size, ".%d"); 2770 struct qbe_value qv = mkqval(ctx, &gv), 2771 qtemp = mkqval(ctx, &temp), 2772 offs = constl(builtin_type_size.size); 2773 enum qbe_instr load = load_for_type(ctx, 2774 &builtin_type_size); 2775 pushi(ctx->current, &qtemp, Q_ADD, &qv, &offs, NULL); 2776 pushi(ctx->current, &qtemp, load, &qtemp, NULL); 2777 return temp; 2778 default: 2779 abort(); // Invariant 2780 } 2781 break; 2782 case M_ALIGN: 2783 return (struct gen_value){ 2784 .kind = GV_CONST, 2785 .type = &builtin_type_size, 2786 .lval = expr->measure.dimensions.align, 2787 }; 2788 case M_SIZE: 2789 return (struct gen_value){ 2790 .kind = GV_CONST, 2791 .type = &builtin_type_size, 2792 .lval = expr->measure.dimensions.size, 2793 }; 2794 case M_OFFSET: 2795 if (expr->measure.value->access.type == ACCESS_FIELD) { 2796 return (struct gen_value){ 2797 .kind = GV_CONST, 2798 .type = &builtin_type_size, 2799 .lval = expr->measure.value->access.field->offset, 2800 }; 2801 } else { 2802 assert(expr->measure.value->access.type == ACCESS_TUPLE); 2803 return (struct gen_value){ 2804 .kind = GV_CONST, 2805 .type = &builtin_type_size, 2806 .lval = expr->measure.value->access.tvalue->offset, 2807 }; 2808 } 2809 } 2810 abort(); // Invariant 2811 } 2812 2813 static struct gen_value 2814 gen_expr_return(struct gen_context *ctx, const struct expression *expr) 2815 { 2816 struct gen_value ret = gen_expr(ctx, expr->_return.value); 2817 for (struct gen_scope *scope = ctx->scope; scope; scope = scope->parent) { 2818 gen_defers(ctx, scope); 2819 } 2820 if (type_dealias(ret.type)->storage == STORAGE_VOID) { 2821 pushi(ctx->current, NULL, Q_RET, NULL); 2822 } else { 2823 struct qbe_value qret = mkqval(ctx, &ret); 2824 pushi(ctx->current, NULL, Q_RET, &qret, NULL); 2825 } 2826 return gv_void; 2827 } 2828 2829 static void 2830 gen_expr_struct_at(struct gen_context *ctx, 2831 const struct expression *expr, 2832 struct gen_value out) 2833 { 2834 // TODO: Merge me into constant expressions 2835 struct qbe_value base = mkqval(ctx, &out); 2836 2837 if (expr->_struct.autofill) { 2838 struct qbe_value rtfunc = mkrtfunc(ctx, "rt.memset"); 2839 struct qbe_value size = 2840 constl(expr->result->size), zero = constl(0); 2841 struct qbe_value base = mklval(ctx, &out); 2842 pushi(ctx->current, NULL, Q_CALL, &rtfunc, 2843 &base, &zero, &size, NULL); 2844 } 2845 2846 struct gen_value ftemp = mkgtemp(ctx, &builtin_type_void, "field.%d"); 2847 for (const struct expr_struct_field *field = expr->_struct.fields; 2848 field; field = field->next) { 2849 if (!field->value) { 2850 assert(expr->_struct.autofill); 2851 continue; 2852 } 2853 2854 struct qbe_value offs = constl(field->field->offset); 2855 ftemp.type = field->value->result; 2856 struct qbe_value ptr = mklval(ctx, &ftemp); 2857 pushi(ctx->current, &ptr, Q_ADD, &base, &offs, NULL); 2858 gen_expr_at(ctx, field->value, ftemp); 2859 } 2860 } 2861 2862 static struct gen_value 2863 gen_expr_switch_with(struct gen_context *ctx, 2864 const struct expression *expr, 2865 struct gen_value *out) 2866 { 2867 struct gen_value gvout = gv_void; 2868 if (!out) { 2869 gvout = mkgtemp(ctx, expr->result, ".%d"); 2870 } 2871 2872 struct qbe_statement lout; 2873 struct qbe_value bout = mklabel(ctx, &lout, ".%d"); 2874 struct gen_value value = gen_expr(ctx, expr->_switch.value); 2875 2876 struct gen_value bval; 2877 const struct switch_case *_default = NULL; 2878 for (const struct switch_case *_case = expr->_switch.cases; 2879 _case; _case = _case->next) { 2880 if (!_case->options) { 2881 _default = _case; 2882 continue; 2883 } 2884 2885 struct qbe_statement lmatch, lnextcase; 2886 struct qbe_value bmatch = mklabel(ctx, &lmatch, "matches.%d"); 2887 struct qbe_value bnextcase = mklabel(ctx, &lnextcase, "next.%d"); 2888 2889 for (struct case_option *opt = _case->options; 2890 opt; opt = opt->next) { 2891 struct qbe_statement lnextopt; 2892 struct qbe_value bnextopt = mklabel(ctx, &lnextopt, ".%d"); 2893 struct gen_value test = gen_expr_const(ctx, opt->value); 2894 struct expression lvalue = { 2895 .type = EXPR_GEN_VALUE, 2896 .result = value.type, 2897 .user = &value, 2898 }, rvalue = { 2899 .type = EXPR_GEN_VALUE, 2900 .result = test.type, 2901 .user = &test, 2902 }, compare = { 2903 .type = EXPR_BINARITHM, 2904 .result = &builtin_type_bool, 2905 .binarithm = { 2906 .op = BIN_LEQUAL, 2907 .lvalue = &lvalue, 2908 .rvalue = &rvalue, 2909 }, 2910 }; 2911 struct gen_value match = gen_expr(ctx, &compare); 2912 struct qbe_value cond = mkqval(ctx, &match); 2913 pushi(ctx->current, NULL, Q_JNZ, 2914 &cond, &bmatch, &bnextopt, NULL); 2915 push(&ctx->current->body, &lnextopt); 2916 } 2917 2918 pushi(ctx->current, NULL, Q_JMP, &bnextcase, NULL); 2919 push(&ctx->current->body, &lmatch); 2920 bval = gen_expr_with(ctx, _case->value, out); 2921 branch_copyresult(ctx, bval, gvout, out); 2922 if (!_case->value->terminates) { 2923 pushi(ctx->current, NULL, Q_JMP, &bout, NULL); 2924 } 2925 push(&ctx->current->body, &lnextcase); 2926 } 2927 2928 if (_default) { 2929 bval = gen_expr_with(ctx, _default->value, out); 2930 branch_copyresult(ctx, bval, gvout, out); 2931 if (!_default->value->terminates) { 2932 pushi(ctx->current, NULL, Q_JMP, &bout, NULL); 2933 } 2934 } 2935 2936 struct qbe_statement labort; 2937 mklabel(ctx, &labort, ".%d"); 2938 push(&ctx->current->body, &labort); 2939 gen_fixed_abort(ctx, expr->loc, ABORT_UNREACHABLE); 2940 2941 push(&ctx->current->body, &lout); 2942 return gvout; 2943 } 2944 2945 static void 2946 gen_expr_slice_at(struct gen_context *ctx, 2947 const struct expression *expr, 2948 struct gen_value out) 2949 { 2950 struct gen_value object = gen_expr(ctx, expr->slice.object); 2951 object = gen_autoderef(ctx, object); 2952 const struct type *srctype = type_dealias(object.type); 2953 2954 bool check_bounds = !expr->slice.bounds_checked; 2955 struct gen_value length; 2956 struct qbe_value qlength; 2957 struct qbe_value qbase; 2958 struct qbe_value qobject = mkqval(ctx, &object); 2959 struct qbe_value offset = constl(builtin_type_size.size); 2960 struct qbe_value qptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); 2961 switch (srctype->storage) { 2962 case STORAGE_ARRAY: 2963 if (srctype->array.length != SIZE_UNDEFINED) { 2964 length = (struct gen_value){ 2965 .kind = GV_CONST, 2966 .type = &builtin_type_size, 2967 .lval = srctype->array.length, 2968 }; 2969 qlength = mkqval(ctx, &length); 2970 } else { 2971 assert(expr->slice.end); 2972 check_bounds = false; 2973 } 2974 qbase = mkqval(ctx, &object); 2975 break; 2976 case STORAGE_SLICE: 2977 qbase = mkqtmp(ctx, ctx->arch.sz, "base.%d"); 2978 enum qbe_instr load = load_for_type(ctx, &builtin_type_size); 2979 pushi(ctx->current, &qbase, load, &qobject, NULL); 2980 length = mkgtemp(ctx, &builtin_type_size, "len.%d"); 2981 qlength = mkqval(ctx, &length); 2982 pushi(ctx->current, &qptr, Q_ADD, &qobject, &offset, NULL); 2983 pushi(ctx->current, &qlength, load, &qptr, NULL); 2984 break; 2985 default: abort(); // Invariant 2986 } 2987 2988 struct gen_value start; 2989 if (expr->slice.start) { 2990 start = gen_expr(ctx, expr->slice.start); 2991 } else { 2992 start = (struct gen_value){ 2993 .kind = GV_CONST, 2994 .type = &builtin_type_size, 2995 .lval = 0, 2996 }; 2997 } 2998 2999 struct gen_value end; 3000 if (expr->slice.end) { 3001 end = gen_expr(ctx, expr->slice.end); 3002 } else { 3003 end = length; 3004 } 3005 3006 struct qbe_value qstart = mkqval(ctx, &start); 3007 struct qbe_value qend = mkqval(ctx, &end); 3008 3009 if (check_bounds) { 3010 struct qbe_value start_oob = mkqtmp(ctx, &qbe_word, ".%d"); 3011 struct qbe_value end_oob = mkqtmp(ctx, &qbe_word, ".%d"); 3012 struct qbe_value startend_oob = mkqtmp(ctx, &qbe_word, ".%d"); 3013 struct qbe_value valid = mkqtmp(ctx, &qbe_word, ".%d"); 3014 pushi(ctx->current, &start_oob, Q_CULEL, &qstart, &qlength, NULL); 3015 pushi(ctx->current, &end_oob, Q_CULEL, &qend, &qlength, NULL); 3016 pushi(ctx->current, &valid, Q_AND, &start_oob, &end_oob, NULL); 3017 pushi(ctx->current, &startend_oob, Q_CULEL, &qstart, &qend, NULL); 3018 pushi(ctx->current, &valid, Q_AND, &valid, &startend_oob, NULL); 3019 3020 struct qbe_statement linvalid, lvalid; 3021 struct qbe_value binvalid = mklabel(ctx, &linvalid, ".%d"); 3022 struct qbe_value bvalid = mklabel(ctx, &lvalid, ".%d"); 3023 3024 pushi(ctx->current, NULL, Q_JNZ, &valid, &bvalid, &binvalid, NULL); 3025 push(&ctx->current->body, &linvalid); 3026 gen_fixed_abort(ctx, expr->loc, ABORT_OOB); 3027 push(&ctx->current->body, &lvalid); 3028 } 3029 3030 struct qbe_value isz = constl(srctype->array.members->size); 3031 3032 struct qbe_value qout = mkqval(ctx, &out); 3033 struct qbe_value data = mkqtmp(ctx, ctx->arch.ptr, "data.%d"); 3034 pushi(ctx->current, &data, Q_MUL, &qstart, &isz, NULL); 3035 pushi(ctx->current, &data, Q_ADD, &qbase, &data, NULL); 3036 3037 struct qbe_value newlen = mkqtmp(ctx, ctx->arch.sz, "newlen.%d"); 3038 pushi(ctx->current, &newlen, Q_SUB, &qend, &qstart, NULL); 3039 struct qbe_value newcap = mkqtmp(ctx, ctx->arch.sz, "newcap.%d"); 3040 if (check_bounds) { 3041 pushi(ctx->current, &newcap, Q_SUB, &qlength, &qstart, NULL); 3042 } else { 3043 pushi(ctx->current, &newcap, Q_COPY, &newlen, NULL); 3044 } 3045 3046 enum qbe_instr store = store_for_type(ctx, &builtin_type_size); 3047 pushi(ctx->current, NULL, store, &data, &qout, NULL); 3048 pushi(ctx->current, &qptr, Q_ADD, &qout, &offset, NULL); 3049 pushi(ctx->current, NULL, store, &newlen, &qptr, NULL); 3050 offset = constl(builtin_type_size.size * 2); 3051 pushi(ctx->current, &qptr, Q_ADD, &qout, &offset, NULL); 3052 pushi(ctx->current, NULL, store, &newcap, &qptr, NULL); 3053 } 3054 3055 static void 3056 gen_expr_tuple_at(struct gen_context *ctx, 3057 const struct expression *expr, 3058 struct gen_value out) 3059 { 3060 // TODO: Merge me into constant expressions 3061 struct qbe_value base = mkqval(ctx, &out); 3062 3063 const struct type *type = type_dealias(expr->result); 3064 struct gen_value vtemp = mkgtemp(ctx, &builtin_type_void, "value.%d"); 3065 const struct expression_tuple *value = &expr->tuple; 3066 for (const struct type_tuple *tuple = &type->tuple; 3067 tuple; tuple = tuple->next) { 3068 struct qbe_value offs = constl(tuple->offset); 3069 vtemp.type = value->value->result; 3070 struct qbe_value ptr = mklval(ctx, &vtemp); 3071 pushi(ctx->current, &ptr, Q_ADD, &base, &offs, NULL); 3072 gen_expr_at(ctx, value->value, vtemp); 3073 value = value->next; 3074 } 3075 } 3076 3077 static struct gen_value 3078 gen_expr_unarithm(struct gen_context *ctx, 3079 const struct expression *expr) 3080 { 3081 struct gen_value val, temp; 3082 struct qbe_value qval, qtmp; 3083 const struct expression *operand = expr->unarithm.operand; 3084 switch (expr->unarithm.op) { 3085 case UN_ADDRESS: 3086 if (operand->type == EXPR_ACCESS) { 3087 val = gen_expr_access_addr(ctx, operand); 3088 val.type = expr->result; 3089 return val; 3090 } 3091 struct gen_value val = mkgtemp(ctx, operand->result, ".%d"); 3092 struct qbe_value qv = mklval(ctx, &val); 3093 struct qbe_value sz = constl(val.type->size); 3094 enum qbe_instr alloc = alloc_for_align(val.type->align); 3095 pushprei(ctx->current, &qv, alloc, &sz, NULL); 3096 gen_expr_at(ctx, operand, val); 3097 val.type = expr->result; 3098 return val; 3099 case UN_DEREF: 3100 val = gen_expr(ctx, operand); 3101 assert(type_dealias(val.type)->storage == STORAGE_POINTER); 3102 val.type = type_dealias(val.type)->pointer.referent; 3103 return gen_load(ctx, val); 3104 case UN_BNOT: 3105 val = gen_expr(ctx, operand); 3106 temp = mkgtemp(ctx, operand->result, ".%d"); 3107 qval = mkqval(ctx, &val), qtmp = mkqval(ctx, &temp); 3108 struct qbe_value ones = constl((uint64_t)-1); 3109 pushi(ctx->current, &qtmp, Q_XOR, &qval, &ones, NULL); 3110 return temp; 3111 case UN_LNOT: 3112 val = gen_expr(ctx, operand); 3113 temp = mkgtemp(ctx, operand->result, ".%d"); 3114 qval = mkqval(ctx, &val), qtmp = mkqval(ctx, &temp); 3115 struct qbe_value zerow = constw(0); 3116 pushi(ctx->current, &qtmp, Q_CEQW, &qval, &zerow, NULL); 3117 return temp; 3118 case UN_MINUS: 3119 val = gen_expr(ctx, operand); 3120 temp = mkgtemp(ctx, operand->result, ".%d"); 3121 qval = mkqval(ctx, &val), qtmp = mkqval(ctx, &temp); 3122 pushi(ctx->current, &qtmp, Q_NEG, &qval, NULL); 3123 return temp; 3124 case UN_PLUS: 3125 return gen_expr(ctx, operand); 3126 } 3127 abort(); // Invariant 3128 } 3129 3130 static struct gen_value 3131 gen_expr_vaarg(struct gen_context *ctx, 3132 const struct expression *expr) 3133 { 3134 // XXX: qbe only supports variadic base types, should check for this 3135 struct gen_value result = mkgtemp(ctx, expr->result, ".%d"); 3136 struct qbe_value qresult = mkqval(ctx, &result); 3137 struct gen_value ap = gen_expr(ctx, expr->vaarg.ap); 3138 struct qbe_value qap = mkqval(ctx, &ap); 3139 pushi(ctx->current, &qresult, Q_VAARG, &qap, NULL); 3140 return result; 3141 } 3142 3143 static void 3144 gen_expr_vastart_at(struct gen_context *ctx, 3145 const struct expression *expr, 3146 struct gen_value out) 3147 { 3148 struct qbe_value base = mklval(ctx, &out); 3149 pushi(ctx->current, NULL, Q_VASTART, &base, NULL); 3150 } 3151 3152 static struct gen_value 3153 gen_expr(struct gen_context *ctx, const struct expression *expr) 3154 { 3155 switch ((int)expr->type) { 3156 case EXPR_ACCESS: 3157 return gen_expr_access(ctx, expr); 3158 case EXPR_ALLOC: 3159 return gen_expr_alloc_with(ctx, expr, NULL); 3160 case EXPR_APPEND: 3161 return gen_expr_append(ctx, expr); 3162 case EXPR_ASSERT: 3163 return gen_expr_assert(ctx, expr); 3164 case EXPR_ASSIGN: 3165 return gen_expr_assign(ctx, expr); 3166 case EXPR_BINARITHM: 3167 return gen_expr_binarithm(ctx, expr); 3168 case EXPR_BINDING: 3169 return gen_expr_binding(ctx, expr); 3170 case EXPR_BREAK: 3171 case EXPR_CONTINUE: 3172 case EXPR_YIELD: 3173 return gen_expr_control(ctx, expr); 3174 case EXPR_CALL: 3175 return gen_expr_call(ctx, expr); 3176 case EXPR_CAST: 3177 return gen_expr_cast(ctx, expr); 3178 case EXPR_COMPOUND: 3179 return gen_expr_compound_with(ctx, expr, NULL); 3180 case EXPR_CONSTANT: 3181 return gen_expr_const(ctx, expr); 3182 case EXPR_DEFER: 3183 return gen_expr_defer(ctx, expr); 3184 case EXPR_DELETE: 3185 return gen_expr_delete(ctx, expr); 3186 case EXPR_FOR: 3187 return gen_expr_for(ctx, expr); 3188 case EXPR_FREE: 3189 return gen_expr_free(ctx, expr); 3190 case EXPR_IF: 3191 return gen_expr_if_with(ctx, expr, NULL); 3192 case EXPR_INSERT: 3193 return gen_expr_insert(ctx, expr); 3194 case EXPR_MATCH: 3195 return gen_expr_match_with(ctx, expr, NULL); 3196 case EXPR_MEASURE: 3197 return gen_expr_measure(ctx, expr); 3198 case EXPR_PROPAGATE: 3199 assert(0); // Lowered in check (for now?) 3200 case EXPR_RETURN: 3201 return gen_expr_return(ctx, expr); 3202 case EXPR_SWITCH: 3203 return gen_expr_switch_with(ctx, expr, NULL); 3204 case EXPR_UNARITHM: 3205 return gen_expr_unarithm(ctx, expr); 3206 case EXPR_VAARG: 3207 return gen_expr_vaarg(ctx, expr); 3208 case EXPR_VAEND: 3209 return gv_void; // no-op 3210 case EXPR_SLICE: 3211 case EXPR_STRUCT: 3212 case EXPR_TUPLE: 3213 case EXPR_VASTART: 3214 break; // Prefers -at style 3215 // gen-specific psuedo-expressions 3216 case EXPR_GEN_VALUE: 3217 return *(struct gen_value *)expr->user; 3218 } 3219 3220 struct gen_value out = mkgtemp(ctx, expr->result, "object.%d"); 3221 struct qbe_value base = mkqval(ctx, &out); 3222 struct qbe_value sz = constl(expr->result->size); 3223 enum qbe_instr alloc = alloc_for_align(expr->result->align); 3224 pushprei(ctx->current, &base, alloc, &sz, NULL); 3225 gen_expr_at(ctx, expr, out); 3226 return out; 3227 } 3228 3229 static void 3230 gen_expr_at(struct gen_context *ctx, 3231 const struct expression *expr, 3232 struct gen_value out) 3233 { 3234 assert(out.kind != GV_CONST); 3235 3236 switch (expr->type) { 3237 case EXPR_ALLOC: 3238 gen_expr_alloc_with(ctx, expr, &out); 3239 return; 3240 case EXPR_CAST: 3241 gen_expr_cast_at(ctx, expr, out); 3242 return; 3243 case EXPR_COMPOUND: 3244 gen_expr_compound_with(ctx, expr, &out); 3245 return; 3246 case EXPR_CONSTANT: 3247 gen_expr_const_at(ctx, expr, out); 3248 return; 3249 case EXPR_IF: 3250 gen_expr_if_with(ctx, expr, &out); 3251 return; 3252 case EXPR_MATCH: 3253 gen_expr_match_with(ctx, expr, &out); 3254 return; 3255 case EXPR_SLICE: 3256 gen_expr_slice_at(ctx, expr, out); 3257 return; 3258 case EXPR_STRUCT: 3259 gen_expr_struct_at(ctx, expr, out); 3260 return; 3261 case EXPR_SWITCH: 3262 gen_expr_switch_with(ctx, expr, &out); 3263 return; 3264 case EXPR_TUPLE: 3265 gen_expr_tuple_at(ctx, expr, out); 3266 return; 3267 case EXPR_VASTART: 3268 gen_expr_vastart_at(ctx, expr, out); 3269 return; 3270 default: 3271 break; // Prefers non-at style 3272 } 3273 3274 struct gen_value result = gen_expr(ctx, expr); 3275 if (!expr->terminates) { 3276 gen_store(ctx, out, result); 3277 } 3278 } 3279 3280 static struct gen_value 3281 gen_expr_with(struct gen_context *ctx, 3282 const struct expression *expr, 3283 struct gen_value *out) 3284 { 3285 if (out) { 3286 gen_expr_at(ctx, expr, *out); 3287 return *out; 3288 } 3289 return gen_expr(ctx, expr); 3290 } 3291 3292 static struct qbe_data_item *gen_data_item(struct gen_context *, 3293 struct expression *, struct qbe_data_item *); 3294 3295 static void 3296 gen_function_decl(struct gen_context *ctx, const struct declaration *decl) 3297 { 3298 const struct function_decl *func = &decl->func; 3299 const struct type *fntype = func->type; 3300 if (func->body == NULL) { 3301 return; // Prototype 3302 } 3303 3304 struct qbe_def *qdef = xcalloc(1, sizeof(struct qbe_def)); 3305 qdef->kind = Q_FUNC; 3306 qdef->exported = decl->exported; 3307 ctx->current = &qdef->func; 3308 3309 qdef->name = decl->symbol ? xstrdup(decl->symbol) 3310 : ident_to_sym(&decl->ident); 3311 3312 struct qbe_statement start_label = {0}; 3313 mklabel(ctx, &start_label, "start.%d"); 3314 push(&qdef->func.prelude, &start_label); 3315 3316 if (type_dealias(fntype->func.result)->storage != STORAGE_VOID) { 3317 qdef->func.returns = qtype_lookup( 3318 ctx, fntype->func.result, false); 3319 } else { 3320 qdef->func.returns = &qbe_void; 3321 } 3322 if (fntype->func.variadism == VARIADISM_C) { 3323 qdef->func.variadic = true; 3324 } 3325 3326 struct qbe_func_param *param, **next = &qdef->func.params; 3327 for (struct scope_object *obj = decl->func.scope->objects; 3328 obj; obj = obj->lnext) { 3329 const struct type *type = obj->type; 3330 param = *next = xcalloc(1, sizeof(struct qbe_func_param)); 3331 assert(!obj->ident.ns); // Invariant 3332 param->name = xstrdup(obj->ident.name); 3333 param->type = qtype_lookup(ctx, type, false); 3334 3335 struct gen_binding *gb = 3336 xcalloc(1, sizeof(struct gen_binding)); 3337 gb->value.kind = GV_TEMP; 3338 gb->value.type = type; 3339 gb->object = obj; 3340 if (type_is_aggregate(type)) { 3341 // No need to copy to stack 3342 gb->value.name = xstrdup(param->name); 3343 } else { 3344 gb->value.name = gen_name(&ctx->id, "param.%d"); 3345 3346 struct qbe_value qv = mklval(ctx, &gb->value); 3347 struct qbe_value sz = constl(type->size); 3348 enum qbe_instr alloc = alloc_for_align(type->align); 3349 pushprei(ctx->current, &qv, alloc, &sz, NULL); 3350 struct gen_value src = { 3351 .kind = GV_TEMP, 3352 .type = type, 3353 .name = param->name, 3354 }; 3355 gen_store(ctx, gb->value, src); 3356 } 3357 3358 gb->next = ctx->bindings; 3359 ctx->bindings = gb; 3360 next = ¶m->next; 3361 } 3362 3363 pushl(&qdef->func, &ctx->id, "body.%d"); 3364 struct gen_value ret = gen_expr(ctx, decl->func.body); 3365 3366 if (decl->func.body->terminates) { 3367 // XXX: This is a bit hacky, to appease qbe 3368 size_t ln = ctx->current->body.ln; 3369 struct qbe_statement *last = &ctx->current->body.stmts[ln - 1]; 3370 if (last->type != Q_INSTR || last->instr != Q_RET) { 3371 pushi(ctx->current, NULL, Q_RET, NULL); 3372 } 3373 } else if (type_dealias(fntype->func.result)->storage != STORAGE_VOID) { 3374 struct qbe_value qret = mkqval(ctx, &ret); 3375 pushi(ctx->current, NULL, Q_RET, &qret, NULL); 3376 } else { 3377 pushi(ctx->current, NULL, Q_RET, NULL); 3378 } 3379 3380 qbe_append_def(ctx->out, qdef); 3381 3382 if (func->flags & FN_INIT) { 3383 struct qbe_def *init = xcalloc(1, sizeof *init); 3384 init->kind = Q_DATA; 3385 init->exported = false; 3386 init->data.align = 8; 3387 init->data.section = ".init_array"; 3388 init->data.secflags = NULL; 3389 3390 size_t n = snprintf(NULL, 0, ".init.%s", qdef->name); 3391 init->name = xcalloc(n + 1, 1); 3392 snprintf(init->name, n + 1, ".init.%s", qdef->name); 3393 3394 struct qbe_data_item dataitem = { 3395 .type = QD_VALUE, 3396 .value = { 3397 .kind = QV_GLOBAL, 3398 .type = &qbe_long, 3399 .name = xstrdup(qdef->name), 3400 }, 3401 .next = NULL, 3402 }; 3403 init->data.items = dataitem; 3404 3405 qbe_append_def(ctx->out, init); 3406 } 3407 3408 if (func->flags & FN_FINI) { 3409 struct qbe_def *fini = xcalloc(1, sizeof *fini); 3410 fini->kind = Q_DATA; 3411 fini->exported = false; 3412 fini->data.align = 8; 3413 fini->data.section = ".fini_array"; 3414 fini->data.secflags = NULL; 3415 3416 size_t n = snprintf(NULL, 0, ".fini.%s", qdef->name); 3417 fini->name = xcalloc(n + 1, 1); 3418 snprintf(fini->name, n + 1, ".fini.%s", qdef->name); 3419 3420 struct qbe_data_item dataitem = { 3421 .type = QD_VALUE, 3422 .value = { 3423 .kind = QV_GLOBAL, 3424 .type = &qbe_long, 3425 .name = xstrdup(qdef->name), 3426 }, 3427 .next = NULL, 3428 }; 3429 fini->data.items = dataitem; 3430 3431 qbe_append_def(ctx->out, fini); 3432 } 3433 3434 if (func->flags & FN_TEST) { 3435 struct qbe_def *test = xcalloc(1, sizeof *test); 3436 test->kind = Q_DATA; 3437 test->exported = false; 3438 test->data.align = 8; 3439 test->data.section = ".test_array"; 3440 test->data.secflags = "aw"; 3441 3442 size_t n = snprintf(NULL, 0, ".test.%s", qdef->name); 3443 test->name = xcalloc(n + 1, 1); 3444 snprintf(test->name, n + 1, ".test.%s", qdef->name); 3445 3446 char *ident = identifier_unparse(&decl->ident); 3447 3448 struct qbe_data_item *dataitem = &test->data.items; 3449 struct expression expr = { 3450 .type = EXPR_CONSTANT, 3451 .result = &builtin_type_str, 3452 .constant = { 3453 .object = NULL, 3454 .string = { 3455 .value = ident, 3456 .len = strlen(ident), 3457 }, 3458 }, 3459 }; 3460 dataitem = gen_data_item(ctx, &expr, dataitem); 3461 3462 struct qbe_data_item *next = xcalloc(1, sizeof *next); 3463 next->type = QD_VALUE; 3464 next->value.kind = QV_GLOBAL; 3465 next->value.type = &qbe_long; 3466 next->value.name = xstrdup(qdef->name); 3467 next->next = NULL; 3468 dataitem->next = next; 3469 3470 qbe_append_def(ctx->out, test); 3471 } 3472 3473 ctx->current = NULL; 3474 } 3475 3476 static struct qbe_data_item * 3477 gen_data_item(struct gen_context *ctx, struct expression *expr, 3478 struct qbe_data_item *item) 3479 { 3480 assert(expr->type == EXPR_CONSTANT); 3481 3482 struct qbe_def *def; 3483 const struct expression_constant *constant = &expr->constant; 3484 const struct type *type = type_dealias(expr->result); 3485 if (type->storage == STORAGE_ENUM) { 3486 type = type->alias.type; 3487 } 3488 type = lower_const(type, NULL); 3489 if (constant->object) { 3490 item->type = QD_SYMOFFS; 3491 item->sym = ident_to_sym(&constant->object->ident); 3492 item->offset = constant->ival; 3493 return item; 3494 } 3495 3496 switch (type->storage) { 3497 case STORAGE_I8: 3498 case STORAGE_U8: 3499 case STORAGE_CHAR: 3500 item->type = QD_VALUE; 3501 item->value = constw((uint8_t)constant->uval); 3502 item->value.type = &qbe_byte; 3503 break; 3504 case STORAGE_BOOL: 3505 item->type = QD_VALUE; 3506 item->value = constw(constant->bval ? 1 : 0); 3507 item->value.type = &qbe_byte; 3508 break; 3509 case STORAGE_I16: 3510 case STORAGE_U16: 3511 item->type = QD_VALUE; 3512 item->value = constw((uint16_t)constant->uval); 3513 item->value.type = &qbe_half; 3514 break; 3515 case STORAGE_I32: 3516 case STORAGE_U32: 3517 case STORAGE_INT: 3518 case STORAGE_UINT: 3519 case STORAGE_RUNE: 3520 item->type = QD_VALUE; 3521 item->value = constw((uint32_t)constant->uval); 3522 break; 3523 case STORAGE_U64: 3524 case STORAGE_I64: 3525 case STORAGE_SIZE: 3526 item->type = QD_VALUE; 3527 item->value = constl((uint64_t)constant->uval); 3528 break; 3529 case STORAGE_F32: 3530 item->type = QD_VALUE; 3531 item->value = consts((float)constant->fval); 3532 break; 3533 case STORAGE_F64: 3534 item->type = QD_VALUE; 3535 item->value = constd((double)constant->fval); 3536 break; 3537 case STORAGE_UINTPTR: 3538 case STORAGE_POINTER: 3539 item->type = QD_VALUE; 3540 switch (ctx->arch.ptr->stype) { 3541 case Q_LONG: 3542 item->value = constl((uint64_t)constant->uval); 3543 break; 3544 default: assert(0); 3545 } 3546 break; 3547 case STORAGE_ARRAY: 3548 assert(type->array.length != SIZE_UNDEFINED); 3549 size_t n = type->array.length; 3550 for (struct array_constant *c = constant->array; 3551 c && n; c = c->next ? c->next : c, --n) { 3552 item = gen_data_item(ctx, c->value, item); 3553 if (n > 1 || c->next) { 3554 item->next = xcalloc(1, 3555 sizeof(struct qbe_data_item)); 3556 item = item->next; 3557 } 3558 } 3559 break; 3560 case STORAGE_STRING: 3561 def = xcalloc(1, sizeof(struct qbe_def)); 3562 def->name = gen_name(&ctx->id, "strdata.%d"); 3563 def->kind = Q_DATA; 3564 def->data.align = ALIGN_UNDEFINED; 3565 def->data.items.type = QD_STRING; 3566 def->data.items.str = xcalloc(1, expr->constant.string.len); 3567 def->data.items.sz = expr->constant.string.len; 3568 memcpy(def->data.items.str, expr->constant.string.value, 3569 expr->constant.string.len); 3570 3571 item->type = QD_VALUE; 3572 if (expr->constant.string.len != 0) { 3573 qbe_append_def(ctx->out, def); 3574 item->value.kind = QV_GLOBAL; 3575 item->value.type = &qbe_long; 3576 item->value.name = xstrdup(def->name); 3577 } else { 3578 free(def); 3579 item->value = constl(0); 3580 } 3581 3582 item->next = xcalloc(1, sizeof(struct qbe_data_item)); 3583 item = item->next; 3584 item->type = QD_VALUE; 3585 item->value = constl(expr->constant.string.len); 3586 item->next = xcalloc(1, sizeof(struct qbe_data_item)); 3587 item = item->next; 3588 item->type = QD_VALUE; 3589 item->value = constl(expr->constant.string.len); 3590 break; 3591 case STORAGE_SLICE: 3592 def = xcalloc(1, sizeof(struct qbe_def)); 3593 def->name = gen_name(&ctx->id, "sldata.%d"); 3594 def->kind = Q_DATA; 3595 def->data.align = ALIGN_UNDEFINED; 3596 3597 size_t len = 0; 3598 struct qbe_data_item *subitem = &def->data.items; 3599 for (struct array_constant *c = constant->array; 3600 c; c = c->next) { 3601 subitem = gen_data_item(ctx, c->value, subitem); 3602 if (c->next) { 3603 subitem->next = xcalloc(1, 3604 sizeof(struct qbe_data_item)); 3605 subitem = subitem->next; 3606 } 3607 ++len; 3608 } 3609 3610 item->type = QD_VALUE; 3611 if (len != 0) { 3612 qbe_append_def(ctx->out, def); 3613 item->value.kind = QV_GLOBAL; 3614 item->value.type = &qbe_long; 3615 item->value.name = xstrdup(def->name); 3616 } else { 3617 free(def); 3618 item->value = constl(0); 3619 } 3620 3621 item->next = xcalloc(1, sizeof(struct qbe_data_item)); 3622 item = item->next; 3623 item->type = QD_VALUE; 3624 item->value = constl(len); 3625 item->next = xcalloc(1, sizeof(struct qbe_data_item)); 3626 item = item->next; 3627 item->type = QD_VALUE; 3628 item->value = constl(len); 3629 break; 3630 case STORAGE_STRUCT: 3631 for (struct struct_constant *f = constant->_struct; 3632 f; f = f->next) { 3633 item = gen_data_item(ctx, f->value, item); 3634 if (f->next) { 3635 const struct struct_field *f1 = f->field; 3636 const struct struct_field *f2 = f->next->field; 3637 if (f2->offset != f1->offset + f1->type->size) { 3638 item->next = xcalloc(1, 3639 sizeof(struct qbe_data_item)); 3640 item = item->next; 3641 item->type = QD_ZEROED; 3642 item->zeroed = f2->offset - 3643 (f1->offset + f1->type->size); 3644 } 3645 3646 item->next = xcalloc(1, 3647 sizeof(struct qbe_data_item)); 3648 item = item->next; 3649 } else { 3650 const struct struct_field *fi = f->field; 3651 if (fi->offset + fi->type->size 3652 != expr->result->size) { 3653 item->next = xcalloc(1, 3654 sizeof(struct qbe_data_item)); 3655 item = item->next; 3656 item->type = QD_ZEROED; 3657 item->zeroed = expr->result->size 3658 - (fi->offset + fi->type->size); 3659 } 3660 } 3661 } 3662 break; 3663 case STORAGE_TUPLE: 3664 for (const struct tuple_constant *tuple = constant->tuple; 3665 tuple; tuple = tuple->next) { 3666 item = gen_data_item(ctx, tuple->value, item); 3667 if (tuple->next) { 3668 const struct type_tuple *f1 = tuple->field; 3669 const struct type_tuple *f2 = tuple->next->field; 3670 if (f2->offset != f1->offset + f1->type->size) { 3671 item->next = xcalloc(1, 3672 sizeof(struct qbe_data_item)); 3673 item = item->next; 3674 item->type = QD_ZEROED; 3675 item->zeroed = f2->offset - 3676 (f1->offset + f1->type->size); 3677 } 3678 3679 3680 item->next = xcalloc(1, 3681 sizeof(struct qbe_data_item)); 3682 item = item->next; 3683 } else { 3684 const struct type_tuple *fi = tuple->field; 3685 if (fi->offset + fi->type->size 3686 != expr->result->size) { 3687 item->next = xcalloc(1, 3688 sizeof(struct qbe_data_item)); 3689 item = item->next; 3690 item->type = QD_ZEROED; 3691 item->zeroed = expr->result->size 3692 - (fi->offset + fi->type->size); 3693 } 3694 } 3695 } 3696 break; 3697 case STORAGE_TAGGED: 3698 item->type = QD_VALUE; 3699 item->value = constw((uint32_t)constant->tagged.tag->id); 3700 if (type->align != builtin_type_uint.align) { 3701 item->next = xcalloc(1, sizeof(struct qbe_data_item)); 3702 item = item->next; 3703 item->type = QD_ZEROED; 3704 item->zeroed = type->align - builtin_type_uint.align; 3705 } 3706 if (constant->tagged.tag->size != 0) { 3707 item->next = xcalloc(1, sizeof(struct qbe_data_item)); 3708 item = item->next; 3709 item = gen_data_item(ctx, constant->tagged.value, item); 3710 } 3711 if (constant->tagged.tag->size < type->size - type->align) { 3712 item->next = xcalloc(1, sizeof(struct qbe_data_item)); 3713 item = item->next; 3714 item->type = QD_ZEROED; 3715 item->zeroed = type->size - type->align - constant->tagged.tag->size; 3716 } 3717 break; 3718 case STORAGE_ENUM: 3719 case STORAGE_UNION: 3720 case STORAGE_ALIAS: 3721 case STORAGE_ERROR: 3722 case STORAGE_FCONST: 3723 case STORAGE_FUNCTION: 3724 case STORAGE_ICONST: 3725 case STORAGE_RCONST: 3726 case STORAGE_NULL: 3727 case STORAGE_VALIST: 3728 case STORAGE_VOID: 3729 assert(0); // Invariant 3730 } 3731 3732 assert(item->type != QD_VALUE || item->value.type); 3733 return item; 3734 } 3735 3736 static void 3737 gen_global_decl(struct gen_context *ctx, const struct declaration *decl) 3738 { 3739 assert(decl->type == DECL_GLOBAL); 3740 const struct global_decl *global = &decl->global; 3741 if (!global->value) { 3742 return; // Forward declaration 3743 } 3744 struct qbe_def *qdef = xcalloc(1, sizeof(struct qbe_def)); 3745 qdef->kind = Q_DATA; 3746 qdef->data.align = ALIGN_UNDEFINED; 3747 qdef->data.threadlocal = global->threadlocal; 3748 qdef->exported = decl->exported; 3749 qdef->name = ident_to_sym(&decl->ident); 3750 gen_data_item(ctx, global->value, &qdef->data.items); 3751 qbe_append_def(ctx->out, qdef); 3752 } 3753 3754 static void 3755 gen_decl(struct gen_context *ctx, const struct declaration *decl) 3756 { 3757 switch (decl->type) { 3758 case DECL_FUNC: 3759 gen_function_decl(ctx, decl); 3760 break; 3761 case DECL_GLOBAL: 3762 gen_global_decl(ctx, decl); 3763 break; 3764 case DECL_TYPE: 3765 case DECL_CONST: 3766 break; // no-op 3767 } 3768 } 3769 3770 void 3771 gen(const struct unit *unit, struct type_store *store, struct qbe_program *out) 3772 { 3773 struct gen_context ctx = { 3774 .out = out, 3775 .store = store, 3776 .ns = unit->ns, 3777 .arch = { 3778 .ptr = &qbe_long, 3779 .sz = &qbe_long, 3780 }, 3781 }; 3782 ctx.out->next = &ctx.out->defs; 3783 const struct declarations *decls = unit->declarations; 3784 while (decls) { 3785 gen_decl(&ctx, decls->decl); 3786 decls = decls->next; 3787 } 3788 }