eBranchNeqInt,
eBranchEqFloat,
eBranchNeqFloat,
+ eUnroll,
eArrayAppend,
eAutoLoop,
eArrayTop,
eGack,
eNoOp,
eEOC,
+ eUnroll2,
eOP_MAX,
eDotTmplVal,
};
#define BranchNeqInt (f_instr)eBranchNeqInt
#define BranchEqFloat (f_instr)eBranchEqFloat
#define BranchNeqFloat (f_instr)eBranchNeqFloat
+#define Unroll (f_instr)eUnroll
#define ArrayAppend (f_instr)eArrayAppend
#define AutoLoop (f_instr)eAutoLoop
#define ArrayTop (f_instr)eArrayTop
#define Gack (f_instr)eGack
#define NoOp (f_instr)eNoOp
#define EOC (f_instr)eEOC
+#define Unroll2 (f_instr)eUnroll2
#define OP_MAX (f_instr)eOP_MAX
#define DotTmplVal (f_instr)eDotTmplVal
#endif
BranchNeqInt
BranchEqFloat
BranchNeqFloat
+Unroll
ArrayAppend
AutoLoop
ArrayTop
Gack
NoOp
EOC
+Unroll2
OP_MAX
DotTmplVal
return ret;
}
-static INSTR(Unroll) {
- const m_uint n = *(m_uint*)MEM(instr->m_val -SZ_INT);
- const m_uint idx = *(m_uint*)MEM(instr->m_val);
- if(idx) {
- if(idx >= n)
- *(m_uint*)MEM(instr->m_val) -= n;
- else {
- *(m_uint*)MEM(instr->m_val) = 0;
- shred->pc += instr->m_val2*(idx+1);
- }
- } else
- shred->pc += instr->m_val2 *n + 1;
-}
-
-INSTR(Unroll2) {
- exit(4);
-}
-
ANN static m_bool stmt_loop_roll(const Emitter emit, const Stmt stmt, const m_uint offset) {
const Instr cpy = emit_add_instr(emit, RegPushMem4);
cpy->m_val = offset;
&&setcode,
&®move, &®tomem, &®tomemother, &&overflow, &&funcusrend, &&funcmemberend,
&&sporkini, &&forkini, &&sporkfunc, &&sporkmemberfptr, &&sporkexp, &&sporkend,
- &&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat,
+ &&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat, &&unroll,
&&arrayappend, &&autoloop, &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&arrayvalid,
&&newobj, &&addref, &&addrefaddr, &&structaddref, &&structaddrefaddr, &&objassign, &&assign, &&remref,
&&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr,
&&upvalueint, &&upvaluefloat, &&upvalueother, &&upvalueaddr,
&&dotfunc,
&&gcini, &&gcadd, &&gcend,
- &&gacktype, &&gackend, &&gack, &&noop, &&eoc, &&other, &®pushimm
+ &&gacktype, &&gackend, &&gack, &&noop, &&eoc, &&unroll2, &&other, &®pushimm
};
const Shreduler s = vm->shreduler;
register VM_Shred shred;
branchnefloat:
reg -= SZ_FLOAT;
BRANCH_DISPATCH(*(m_float*)reg);
+unroll:
+{
+ const m_uint n = *(m_uint*)(mem + VAL - SZ_INT);
+ const m_uint idx = *(m_uint*)(mem + VAL);
+ if(idx) {
+ if(idx >= n) {
+ *(m_uint*)(mem + VAL) -= n;
+ DISPATCH()
+ }
+ *(m_uint*)(mem + VAL) = 0;
+ PC_DISPATCH(PC + VAL2*(idx));
+ }
+ PC_DISPATCH(PC + VAL2 *n + 1);
+}
arrayappend:
m_vector_add(ARRAY(*(M_Object*)(reg-SZ_INT)), reg);
DISPATCH()
other:
VM_OUT
((f_instr)VAL2)(shred, (Instr)VAL);
+unroll2:
in:
if(!s->curr)
break;
*(unsigned*)(data+1) = i + 1;
}
-INSTR(Unroll2);
ANN static m_bit* tobytecode(MemPool p, const VM_Code code) {
- const Vector v = code->instr;
+ const Vector v = code->instr;
const m_uint sz = vector_size(v);
m_bit *ptr = _mp_malloc(p, sz * BYTECODE_SZ);
struct Vector_ nop;
}
i += j;
continue;
- }
- if(instr->opcode != eNoOp)
- memcpy(data, instr, BYTECODE_SZ);
- else
- vector_add(&nop, i);
- } else {
- if(instr->execute == Unroll2) {
+ } else if(instr->opcode == eUnroll2) {
const Instr unroll = (Instr)instr->m_val;
- const m_uint pc = vector_find(v, unroll);
- m_uint reduce = 0;
+ const m_uint pc = vector_find(v, (m_uint)unroll);
+ m_uint reduce_pre = 0, reduce = 0;
for(m_uint j = 0; j < vector_size(&nop); ++j) {
const m_uint at = vector_at(&nop, j);
+ if(at < pc)
+ ++reduce_pre;
if(at >= pc) {
if(at >= (pc + unroll->m_val2))
break;
++reduce;
}
}
+ m_bit *const unroll_data = ptr + (pc-reduce_pre)*BYTECODE_SZ;
unroll->m_val2 -= reduce;
+ *(m_uint*)(unroll_data + SZ_INT *2) -= reduce;
instr->opcode = eNoOp;
vector_add(&nop, i);
continue;
}
+ if(instr->opcode != eNoOp)
+ memcpy(data, instr, BYTECODE_SZ);
+ else
+ vector_add(&nop, i);
+ } else {
*(m_bit*)(data) = instr->opcode;
*(Instr*)(data + SZ_INT) = instr;
*(f_instr*)(data + SZ_INT*2) = instr->execute;