ANEW ANN Value new_value(MemPool p, const Type type, const m_str name);
ANN void valuefrom(const Env, struct ValueFrom_*, const loc_t loc);
+
+ANN static inline void defined_here(const Value v) {
+ gwerr_secondary(_("defined here"), v->from->filename, v->from->loc);
+}
#endif
eStructMemberOther,
eStructMemberAddr,
eMemSetImm,
+ eMemAddImm,
+ eRepeatIdx,
+ eRepeat,
eRegPushMe,
eRegPushMaybe,
eFuncReturn,
#define StructMemberOther (f_instr)eStructMemberOther
#define StructMemberAddr (f_instr)eStructMemberAddr
#define MemSetImm (f_instr)eMemSetImm
+#define MemAddImm (f_instr)eMemAddImm
+#define RepeatIdx (f_instr)eRepeatIdx
+#define Repeat (f_instr)eRepeat
#define RegPushMe (f_instr)eRegPushMe
#define RegPushMaybe (f_instr)eRegPushMaybe
#define FuncReturn (f_instr)eFuncReturn
StructMemberOther
StructMemberAddr
MemSetImm
+MemAddImm
+RepeatIdx
+Repeat
RegPushMe
RegPushMaybe
FuncReturn
struct Looper;
+typedef Instr (*f_looper_init)(const Emitter, const struct Looper *);
typedef void (*f_looper)(const Emitter, const struct Looper *);
struct Looper {
const Stmt stmt;
/*const */m_uint offset;
const m_uint n;
- const f_looper roll;
+ const f_looper_init roll;
const f_looper unroll;
};
ANN static inline m_bool roll(const Emitter emit, const struct Looper *loop) {
- if(loop->roll)
- loop->roll(emit, loop);
- const Instr instr = emit_add_instr(emit, BranchEqInt);
+ const Instr instr = loop->roll(emit, loop);
CHECK_BB(scoped_stmt(emit, loop->stmt, 1));
instr->m_val = emit_code_size(emit) + 1; // pass after goto
return GW_OK;
}
-ANN static void stmt_each_roll(const Emitter emit, const struct Looper *loop) {
+ANN static Instr stmt_each_roll(const Emitter emit, const struct Looper *loop) {
const Instr instr = emit_add_instr(emit, AutoLoop);
- instr->m_val = loop->offset + SZ_INT;
- regpush(emit, SZ_INT);
+ instr->m_val2 = loop->offset + SZ_INT;
+ return instr;
}
ANN static inline void unroll_init(const Emitter emit, const m_uint n) {
return ret;
}
-ANN static void stmt_loop_roll(const Emitter emit, const struct Looper *loop) {
- const Instr counter = emit_add_instr(emit, RegPushMem4);
- counter->m_val = loop->offset;
- emit_add_instr(emit, int_post_dec);
+ANN static Instr stmt_loop_roll(const Emitter emit, const struct Looper *loop) {
+ const Instr eq = emit_add_instr(emit, Repeat);
+ eq->m_val2 = loop->offset;
+ return eq;
}
-ANN static void stmt_loop_roll_idx(const Emitter emit, const struct Looper *loop) {
- const Instr target = emit_add_instr(emit, RegPushMem);
- target->m_val = loop->offset + SZ_INT;
- const Instr counter = emit_add_instr(emit, RegPushMem4);
- counter->m_val = loop->offset;
- emit_add_instr(emit, int_post_inc);
- emit_add_instr(emit, int_minus);
+ANN static Instr stmt_loop_roll_idx(const Emitter emit, const struct Looper *loop) {
+ const Instr instr = emit_add_instr(emit, RepeatIdx);
+ instr->m_val2 = loop->offset;
+ return instr;
}
-ANN static m_bool _emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt, m_uint *index) {
+ANN static m_bool _emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt,
+ m_uint *index) {
const uint n = emit->info->unroll;
if(n)
unroll_init(emit, n);
const m_uint offset = emit_local(emit, emit->gwion->type[et_int]);
- if(stmt->idx)
- emit_local(emit, emit->gwion->type[et_int]);
+ if(stmt->idx) {
+ const Instr instr = emit_add_instr(emit, MemSetImm);
+ instr->m_val = stmt->idx->v->from->offset = emit_local(emit, emit->gwion->type[et_int]);
+ }
CHECK_BB(emit_exp_pop_next(emit, stmt->cond));
regpop(emit, SZ_INT);
const Instr tomem = emit_add_instr(emit, Reg2Mem);
if(value) {
env_err(env, var->pos,
_("Value defined in parent class"));
- gwerr_secondary(_("defined here"), value->from->filename, value->from->loc);
+ defined_here(value);
return GW_ERROR;
}
return GW_OK;
ANN static inline m_bool shadow_err(const Env env, const Value v, const loc_t loc) {
gwerr_basic(_("shadowing a previously defined variable"), NULL, NULL, env->name, loc, 0);
- gwerr_secondary(_("defined here"), v->from->filename, v->from->loc);
+ defined_here(v);
env->context->error = true;
return GW_ERROR;
}
&&baseint, &&basefloat, &&baseother, &&baseaddr,
&®toreg, &®toregother, &®toregaddr, &®toregderef,
&&structmember, &&structmemberfloat, &&structmemberother, &&structmemberaddr,
- &&memsetimm,
+ &&memsetimm, &&memaddimm, &&repeatidx, &&repeat,
&®pushme, &®pushmaybe,
&&funcreturn,
&&_goto,
memsetimm:
*(m_uint*)(mem+VAL) = VAL2;
DISPATCH();
+memaddimm:
+ *(m_int*)(mem+VAL) += (m_int)VAL2;
+// (*(m_int*)(mem+VAL))--;
+ DISPATCH();
+repeatidx:
+ BRANCH_DISPATCH(*(m_int*)(mem+VAL2+SZ_INT) == ++(*(m_int*)(mem+VAL2)));
+repeat:
+ BRANCH_DISPATCH(!--*(m_uint*)(mem+VAL2));
regpushme:
*(M_Object*)reg = shred->info->me;
reg += SZ_INT;
*(m_uint*)(mem + VAL) = m_vector_size(ARRAY(*(M_Object*)(mem+VAL+SZ_INT)));
DISPATCH()
autoloop:
- *(m_bit**)(mem + VAL + SZ_INT) = m_vector_addr(ARRAY(*(M_Object*)(mem+VAL-SZ_INT)), *(m_uint*)(mem + VAL) + 1);
- *(m_uint*)reg = m_vector_size(ARRAY(*(M_Object*)(mem+VAL-SZ_INT))) - (*(m_uint*)(mem + VAL))++ -1;
- DISPATCH()
+ *(m_bit**)(mem + VAL2 + SZ_INT) = m_vector_addr(ARRAY(*(M_Object*)(mem+VAL2-SZ_INT)), *(m_uint*)(mem + VAL2) + 1);
+ BRANCH_DISPATCH(m_vector_size(ARRAY(*(M_Object*)(mem+VAL2-SZ_INT))) == ++*(m_uint*)(mem + VAL2));
arraytop:
if(*(m_uint*)(reg - SZ_INT * 2) < *(m_uint*)(reg-SZ_INT))
goto newobj;
}
static inline uint isgoto(const unsigned opcode) {
- return opcode == eGoto || opcode == eArrayTop ||
- opcode == eBranchEqInt || opcode == eBranchNeqInt ||
+ return opcode == eGoto || opcode == eArrayTop ||
+ opcode == eBranchEqInt || opcode == eBranchNeqInt ||
opcode == eBranchEqFloat || opcode == eBranchNeqFloat ||
- opcode == eHandleEffect;
+ opcode == eHandleEffect || opcode == eRepeat ||
+ opcode == eRepeatIdx || opcode == eAutoLoop;
}
ANN static inline void setpc(const m_bit *data, const m_uint i) {
-Subproject commit 7f657c4d12c8a4362d26b1976ddca5de2324d60a
+Subproject commit 4e08843bd4c85578e1965ffd81c41fc36f42358d