aboutsummaryrefslogtreecommitdiff
path: root/compiler.c
diff options
context:
space:
mode:
Diffstat (limited to 'compiler.c')
-rw-r--r--compiler.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/compiler.c b/compiler.c
index adcca46..bdbbb8b 100644
--- a/compiler.c
+++ b/compiler.c
@@ -226,6 +226,7 @@ static struct ref compile_expr(struct ir *ir, struct symtab *symtab, struct info
r1 = ref_mem(r1.reg, 0, REFREL_ZERO); break;
break;
}
+ case REF_VARNAME: assert(false);
}
struct ref r0 = ref_next_register();
ir_append(ir, irins_make_01(INS_MOV, r0, r1));
@@ -430,6 +431,30 @@ static void compile_node(struct ir *ir, struct symtab *symtab, struct info info,
break;
}
+ case N_IRINS: {
+ bool haveref[3];
+ irins_which_refs(node->irins, haveref);
+ for (int i = 0; i < 3; i++) {
+ if (!haveref[i]) continue;
+ struct ref *ref = &node->irins->three_refs[i];
+ if (ref->type == REF_VARNAME) {
+ struct symbol *sym = symtab_find(symtab, ref->name);
+ if (!sym) {
+ fprintf(stderr, "Use of undeclared variable '%s' in asm block\n", node->name);
+ exit(1);
+ }
+ if (sym->stype != ST_VAR) {
+ fprintf(stderr, "Variable reference in asm block should be variable\n");
+ exit(1);
+ }
+ *ref = sym->ref;
+ }
+ }
+ ir_append(ir, node->irins);
+ node->irins = NULL;
+ break;
+ }
+
default: // hmm, maybe it's an expression statement?
compile_expr(ir, symtab, info, node);
break;