*/
struct etna_compile_frame {
enum etna_compile_frame_type type;
- struct etna_compile_label *lbl_else;
- struct etna_compile_label *lbl_endif;
- struct etna_compile_label *lbl_loop_bgn;
- struct etna_compile_label *lbl_loop_end;
+ int lbl_else_idx;
+ int lbl_endif_idx;
+ int lbl_loop_bgn_idx;
+ int lbl_loop_end_idx;
};
struct etna_compile_file {
/* Fields for handling nested conditionals */
struct etna_compile_frame frame_stack[ETNA_MAX_DEPTH];
int frame_sp;
- struct etna_compile_label *lbl_usage[ETNA_MAX_INSTRUCTIONS];
+ int lbl_usage[ETNA_MAX_INSTRUCTIONS];
unsigned labels_count, labels_sz;
struct etna_compile_label *labels;
}
/* create a new label */
-static struct etna_compile_label *
+static unsigned int
alloc_new_label(struct etna_compile *c)
{
struct etna_compile_label label = {
array_insert(c->labels, label);
- return &c->labels[c->labels_count - 1];
+ return c->labels_count - 1;
}
/* place label at current instruction pointer */
* as the value becomes known.
*/
static void
-label_mark_use(struct etna_compile *c, struct etna_compile_label *label)
+label_mark_use(struct etna_compile *c, int lbl_idx)
{
assert(c->inst_ptr < ETNA_MAX_INSTRUCTIONS);
- c->lbl_usage[c->inst_ptr] = label;
+ c->lbl_usage[c->inst_ptr] = lbl_idx;
}
/* walk the frame stack and return first frame with matching type */
/* push IF to stack */
f->type = ETNA_COMPILE_FRAME_IF;
/* create "else" label */
- f->lbl_else = alloc_new_label(c);
- f->lbl_endif = NULL;
+ f->lbl_else_idx = alloc_new_label(c);
+ f->lbl_endif_idx = -1;
/* We need to avoid the emit_inst() below becoming two instructions */
if (etna_src_uniforms_conflict(src[0], imm_0))
/* mark position in instruction stream of label reference so that it can be
* filled in in next pass */
- label_mark_use(c, f->lbl_else);
+ label_mark_use(c, f->lbl_else_idx);
/* create conditional branch to label if src0 EQ 0 */
emit_inst(c, &(struct etna_inst){
assert(f->type == ETNA_COMPILE_FRAME_IF);
/* create "endif" label, and branch to endif label */
- f->lbl_endif = alloc_new_label(c);
- label_mark_use(c, f->lbl_endif);
+ f->lbl_endif_idx = alloc_new_label(c);
+ label_mark_use(c, f->lbl_endif_idx);
emit_inst(c, &(struct etna_inst) {
.opcode = INST_OPCODE_BRANCH,
.cond = INST_CONDITION_TRUE,
});
/* mark "else" label at this position in instruction stream */
- label_place(c, f->lbl_else);
+ label_place(c, &c->labels[f->lbl_else_idx]);
}
static void
/* assign "endif" or "else" (if no ELSE) label to current position in
* instruction stream, pop IF */
- if (f->lbl_endif != NULL)
- label_place(c, f->lbl_endif);
+ if (f->lbl_endif_idx != -1)
+ label_place(c, &c->labels[f->lbl_endif_idx]);
else
- label_place(c, f->lbl_else);
+ label_place(c, &c->labels[f->lbl_else_idx]);
}
static void
/* push LOOP to stack */
f->type = ETNA_COMPILE_FRAME_LOOP;
- f->lbl_loop_bgn = alloc_new_label(c);
- f->lbl_loop_end = alloc_new_label(c);
+ f->lbl_loop_bgn_idx = alloc_new_label(c);
+ f->lbl_loop_end_idx = alloc_new_label(c);
- label_place(c, f->lbl_loop_bgn);
+ label_place(c, &c->labels[f->lbl_loop_bgn_idx]);
c->num_loops++;
}
/* mark position in instruction stream of label reference so that it can be
* filled in in next pass */
- label_mark_use(c, f->lbl_loop_bgn);
+ label_mark_use(c, f->lbl_loop_bgn_idx);
/* create branch to loop_bgn label */
emit_inst(c, &(struct etna_inst) {
/* imm is filled in later */
});
- label_place(c, f->lbl_loop_end);
+ label_place(c, &c->labels[f->lbl_loop_end_idx]);
}
static void
/* mark position in instruction stream of label reference so that it can be
* filled in in next pass */
- label_mark_use(c, f->lbl_loop_end);
+ label_mark_use(c, f->lbl_loop_end_idx);
/* create branch to loop_end label */
emit_inst(c, &(struct etna_inst) {
/* mark position in instruction stream of label reference so that it can be
* filled in in next pass */
- label_mark_use(c, f->lbl_loop_bgn);
+ label_mark_use(c, f->lbl_loop_bgn_idx);
/* create branch to loop_end label */
emit_inst(c, &(struct etna_inst) {
etna_compile_fill_in_labels(struct etna_compile *c)
{
for (int idx = 0; idx < c->inst_ptr; ++idx) {
- if (c->lbl_usage[idx])
- etna_assemble_set_imm(&c->code[idx * 4], c->lbl_usage[idx]->inst_idx);
+ if (c->lbl_usage[idx] != -1)
+ etna_assemble_set_imm(&c->code[idx * 4],
+ c->labels[c->lbl_usage[idx]].inst_idx);
}
}
if (!c)
return false;
+ memset(&c->lbl_usage, -1, ARRAY_SIZE(c->lbl_usage));
+
const struct tgsi_token *tokens = v->shader->tokens;
c->specs = specs;
etna_compile_add_z_div_if_needed(c);
etna_compile_frag_rb_swap(c);
etna_compile_add_nop_if_needed(c);
- etna_compile_fill_in_labels(c);
ret = etna_compile_check_limits(c);
if (!ret)
goto out;
+ etna_compile_fill_in_labels(c);
+
/* fill in output structure */
v->processor = c->info.processor;
v->code_size = c->inst_ptr * 4;