typedef Instr (*f_looper_init)(const Emitter, const struct Looper *);
typedef void (*f_looper)(const Emitter, const struct Looper *);
struct Looper {
+ const Exp exp;
const Stmt stmt;
/*const */ m_uint offset;
const m_uint n;
const f_looper_init roll;
const f_looper_init unroll;
- struct Vector_ unroll_v;
+// union {
+ struct Vector_ unroll_v;
+ Instr instr;
+// };
};
ANN static inline m_bool roll(const Emitter emit, struct Looper *const loop) {
}
ANN static Instr stmt_each_roll(const Emitter emit, const struct Looper *loop) {
- const Instr instr = emit_add_instr(emit, AutoLoop);
- instr->m_val2 = loop->offset + SZ_INT;
- return instr;
+// const Instr instr = emit_add_instr(emit, AutoLoop);
+// instr->m_val2 = loop->offset + SZ_INT;
+// return instr;
+ struct Op_Import opi = {
+ .lhs = loop->exp->type,
+ .op = insert_symbol("@autoloop"),
+ .data = (m_uint)loop
+ };
+ CHECK_BO(op_emit(emit, &opi));
+ return loop->instr;
}
ANN static inline void unroll_init(const Emitter emit, const m_uint n) {
}
ANN static Instr stmt_each_unroll(const Emitter emit,
const struct Looper *loop) {
- const Instr instr = emit_add_instr(emit, AutoLoop);
- instr->m_val2 = loop->offset + SZ_INT * 2;
- return instr;
+ struct Op_Import opi = {
+ .lhs = loop->exp->type,
+ .op = insert_symbol("@autoloop"),
+ .data = (m_uint)loop
+ };
+ CHECK_BO(op_emit(emit, &opi));
+ return loop->instr;
+// const Instr instr = emit_add_instr(emit, AutoLoop);
+// instr->m_val2 = loop->offset + SZ_INT * 2;
+// return instr;
}
ANN static inline m_bool looper_run(const Emitter emit,
instr->m_val = offset - SZ_INT;
}
const m_uint ini_pc = emit_code_size(emit);
- struct Looper loop = {.stmt = stmt->body,
+ struct Looper loop = {.exp = stmt->exp,
+ .stmt = stmt->body,
.offset = offset,
.n = n,
.roll = stmt_each_roll,
const Instr tomem = emit_add_instr(emit, Reg2Mem);
tomem->m_val = offset + (!stmt->idx ? 0 : SZ_INT);
*index = emit_code_size(emit);
- struct Looper loop = {.stmt = stmt->body,
+ struct Looper loop = {.exp = stmt->cond,
+ .stmt = stmt->body,
.offset = offset,
.n = n,
.roll =
return imp->t;
}
+struct Looper;
+typedef Instr (*f_looper_init)(const Emitter, const struct Looper *);
+typedef void (*f_looper)(const Emitter, const struct Looper *);
+struct Looper {
+ const Exp exp;
+ const Stmt stmt;
+ /*const */ m_uint offset;
+ const m_uint n;
+ const f_looper_init roll;
+ const f_looper_init unroll;
+// union {
+ struct Vector_ unroll_v;
+ Instr instr;
+// };
+};
+
+static OP_EMIT(opem_array_autoloop) {
+ struct Looper *loop = (struct Looper *)data;
+ const Instr instr = emit_add_instr(emit, AutoLoop);
+ if(!loop->n) {
+ instr->m_val2 = loop->offset + SZ_INT;
+ } else {
+ instr->m_val2 = loop->offset + SZ_INT*2;
+ vector_add(&loop->unroll_v, (m_uint)instr);
+ }
+ loop->instr = instr;
+ return GW_OK;
+}
+
ANN static void prepare_run(m_bit *const byte, const f_instr ini,
const f_instr end) {
*(unsigned *)byte = eOP_MAX;
GWI_BB(gwi_oper_add(gwi, opck_array))
GWI_BB(gwi_oper_emi(gwi, opem_array_access))
GWI_BB(gwi_oper_end(gwi, "@array", NULL))
+ GWI_BB(gwi_oper_ini(gwi, "@Array", NULL, "int"))
+ GWI_BB(gwi_oper_emi(gwi, opem_array_autoloop))
+ GWI_BB(gwi_oper_end(gwi, "@autoloop", NULL))
GWI_BB(gwi_oper_ini(gwi, "@Array", NULL, NULL))
GWI_BB(gwi_oper_add(gwi, opck_array_scan))
GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
*(m_uint *)(mem + VAL) =
m_vector_size(ARRAY(*(M_Object *)(mem + VAL + SZ_INT)));
DISPATCH()
- autoloop:
+ autoloop: {
+ const M_Vector array = ARRAY(*(M_Object *)(mem + VAL2 - SZ_INT));
*(m_bit **)(mem + VAL2 + SZ_INT) =
- m_vector_addr(ARRAY(*(M_Object *)(mem + VAL2 - SZ_INT)),
- ++*(m_uint *)(mem + VAL2));
- BRANCH_DISPATCH(
- m_vector_size(ARRAY(*(M_Object *)(mem + VAL2 - SZ_INT))) ==
- *(m_uint *)(mem + VAL2));
+ m_vector_addr(array, ++*(m_uint *)(mem + VAL2));
+ BRANCH_DISPATCH(m_vector_size(array) == *(m_uint *)(mem + VAL2));
+ }
arraytop:
if (*(m_uint *)(reg - SZ_INT * 2) < *(m_uint *)(reg - SZ_INT))
goto newobj;