ir_builder* ir_builder_new(const char *modulename)
{
ir_builder* self;
+ size_t i;
self = (ir_builder*)mem_a(sizeof(*self));
if (!self)
self->nil = ir_value_var("nil", store_value, TYPE_NIL);
self->nil->cvq = CV_CONST;
+ for (i = 0; i != IR_MAX_VINSTR_TEMPS; ++i) {
+ /* we write to them, but they're not supposed to be used outside the IR, so
+ * let's not allow the generation of ir_instrs which use these.
+ * So it's a constant noexpr.
+ */
+ self->vinstr_temp[i] = ir_value_var("vinstr_temp", store_value, TYPE_NOEXPR);
+ self->vinstr_temp[i]->cvq = CV_CONST;
+ }
+
self->reserved_va_count = NULL;
self->code = code_init();
ir_value_delete(self->fields[i]);
}
ir_value_delete(self->nil);
+ for (i = 0; i != IR_MAX_VINSTR_TEMPS; ++i) {
+ ir_value_delete(self->vinstr_temp[i]);
+ }
vec_free(self->fields);
vec_free(self->filenames);
vec_free(self->filestrings);
vec_push(self->code->globals, 0);
vec_push(self->code->globals, 0);
+ /* generate virtual-instruction temps */
+ for (i = 0; i < IR_MAX_VINSTR_TEMPS; ++i) {
+ ir_value_code_setaddr(self->vinstr_temp[i], vec_size(self->code->globals));
+ vec_push(self->code->globals, 0);
+ vec_push(self->code->globals, 0);
+ vec_push(self->code->globals, 0);
+ }
+
/* generate global temps */
self->first_common_globaltemp = vec_size(self->code->globals);
for (i = 0; i < self->max_globaltemps; ++i) {
/* builder */
#define IR_HT_SIZE 1024
+#define IR_MAX_VINSTR_TEMPS 1
typedef struct ir_builder_s
{
char *name;
uint32_t first_common_globaltemp;
const char **filenames;
- qcint_t *filestrings;
+ qcint_t *filestrings;
/* we cache the #IMMEDIATE string here */
- qcint_t str_immediate;
+ qcint_t str_immediate;
/* there should just be this one nil */
ir_value *nil;
ir_value *reserved_va_count;
+ /* some virtual instructions require temps, and their code is isolated
+ * so that we don't need to keep track of their liveness.
+ */
+ ir_value *vinstr_temp[IR_MAX_VINSTR_TEMPS];
/* code generator */
code_t *code;