commit b5e6f0bf3c6c1c0cd060f5a2439ba1ec0060682f
parent 14c0158d7c84182c913e860efd011991109a9d52
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 28 Dec 2020 10:28:48 -0500
gen: add better docs and tracing around values
Diffstat:
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/include/qbe.h b/include/qbe.h
@@ -5,14 +5,14 @@
#include <stdint.h>
enum qbe_stype {
- Q__VOID = 0,
+ Q__VOID = 'V',
Q_BYTE = 'b',
Q_HALF = 'h',
Q_WORD = 'w',
Q_LONG = 'l',
Q_SINGLE = 's',
Q_DOUBLE = 'd',
- Q__AGGREGATE,
+ Q__AGGREGATE = 'A',
};
struct qbe_type {
@@ -41,10 +41,22 @@ enum qbe_value_kind {
};
// Represents a value which can be an argument to a QBE instruction.
+//
+// If the value is a non-aggregate type, indirect determines if it is a pointer
+// to the value, or the value itself.
//
-// If indirect, this value is a pointer to the actual value, which is allocated
-// elsewhere (e.g. the stack). This is usually true unless we have temporarily
-// loaded a value as an input into an instruction.
+// let x = 10; // %x =l alloc4 4; storew 10, %x
+// // qbe_value{QV_TEMPORARY, =l, true, %x}
+// x; // %temp =w loadw %x
+// // qbe_value{QV_TEMPORARY, =w, false, %temp}
+//
+// Aggregate types cannot be directly stored in temporaries, so if direct is
+// set, the value is still a pointer to an aggregate type.
+//
+// let x = [1, 2, 3]; // %x =l alloc4 12; storew 1, %x; ...
+// // qbe_value{QV_TEMPORARY, :aggregate, true, %x }
+// let y = &x; // %y =l alloc8 8; storel %x, %y
+// // qbe_value{QV_TEMPORARY, =l, true, %y }
struct qbe_value {
enum qbe_value_kind kind;
const struct qbe_type *type;
diff --git a/src/gen.c b/src/gen.c
@@ -70,6 +70,9 @@ binding_alloc(struct gen_context *ctx, const struct scope_object *obj,
binding->object = obj;
binding->next = ctx->bindings;
ctx->bindings = binding;
+ pushc(ctx->current, "alloc binding: %s -> %%%s, =%c, indirect: %d",
+ obj->ident.name, binding->name,
+ (char)val->type->stype, val->indirect);
return binding;
}