|
|
|
@ -133,7 +133,7 @@ enum fh_error w_user_word(struct fh_thread_s *fh, const struct fh_word_s *w0) |
|
|
|
|
|
|
|
|
|
uint32_t strl; |
|
|
|
|
uint32_t val; |
|
|
|
|
uint32_t limit, index, index0; |
|
|
|
|
uint32_t limit, index; |
|
|
|
|
|
|
|
|
|
LOG("0x%08x: Instr %s, 0x%08x", fh->execptr, instr_name(instr->kind), instr->data); |
|
|
|
|
|
|
|
|
@ -271,20 +271,28 @@ enum fh_error w_user_word(struct fh_thread_s *fh, const struct fh_word_s *w0) |
|
|
|
|
TRY(rs_peek(fh, &limit)); |
|
|
|
|
|
|
|
|
|
LOG("+LOOP, i=%d, step %d, limit %d", fh->loop_i, val, limit); |
|
|
|
|
|
|
|
|
|
index0 = fh->loop_i; |
|
|
|
|
fh->loop_i += val; |
|
|
|
|
|
|
|
|
|
LOG("after add: %d", fh->loop_i); |
|
|
|
|
|
|
|
|
|
// FIXME this is probably wrong
|
|
|
|
|
// FIXME yes it actually is wrong
|
|
|
|
|
if (((int32_t)index0 < (int32_t)limit) == ((int32_t)fh->loop_i < (int32_t)limit) && fh->loop_i != limit) { // boundary not crossed, continue
|
|
|
|
|
fh->execptr = instr->data; // go to beginning
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
const int32_t vi = (int32_t)val; |
|
|
|
|
const int32_t bdr = (int32_t)limit - (int32_t)1; |
|
|
|
|
const int32_t i0 = (int32_t)fh->loop_i;
|
|
|
|
|
fh->loop_i += val; // this can overflow
|
|
|
|
|
const int32_t i1 = (int32_t)fh->loop_i; |
|
|
|
|
|
|
|
|
|
// TODO this can probably be optimized
|
|
|
|
|
if ( |
|
|
|
|
(vi > 0 && i0 <= bdr && i1 > bdr)
|
|
|
|
|
|| (vi > 0 && i0 > 0 && i1 < 0 && (bdr >= i0 || bdr <= i1)) |
|
|
|
|
|| (vi < 0 && i0 > bdr && i1 <= bdr) |
|
|
|
|
|| (vi < 0 && i0 < 0 && i1 > 0 && (bdr <= i0 || bdr >= i1)) |
|
|
|
|
) {
|
|
|
|
|
//LOGE("end of loop");
|
|
|
|
|
// end of loop
|
|
|
|
|
TRY(rs_pop(fh, &limit)); |
|
|
|
|
TRY(fh_loop_unnest(fh)); |
|
|
|
|
} else { |
|
|
|
|
//LOGE("continue loop");
|
|
|
|
|
// continue the loop
|
|
|
|
|
fh->execptr = instr->data; |
|
|
|
|
} |
|
|
|
|
goto instr; |
|
|
|
|
|
|
|
|
|