diff options
| author | 2023-02-11 21:24:48 +0000 | |
|---|---|---|
| committer | 2023-02-11 21:24:48 +0000 | |
| commit | b425e26ea3ff2df3f6b98b475ae870900efaf2e6 (patch) | |
| tree | d134435547ee287f23b237b4be0c14bd353d87a7 /creole.c | |
| parent | rename idiv to sdiv (diff) | |
jump tests
Diffstat (limited to 'creole.c')
| -rw-r--r-- | creole.c | 68 |
1 files changed, 61 insertions, 7 deletions
@@ -36,9 +36,14 @@ static const struct { defop(MUL, 3, TYPE_REG, TYPE_VAL, TYPE_VAL), defop(DIV, 3, TYPE_REG, TYPE_VAL, TYPE_VAL), defop(SDIV, 3, TYPE_REG, TYPE_VAL, TYPE_VAL), - defop(JL, 3, TYPE_LAB, TYPE_VAL, TYPE_VAL), + defop(SYS, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE), defop(CLB, 1, TYPE_LAB, TYPE_NONE, TYPE_NONE), - defop(SYS, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE) + defop(JL, 3, TYPE_LAB, TYPE_VAL, TYPE_VAL), + defop(JLE, 3, TYPE_LAB, TYPE_VAL, TYPE_VAL), + defop(JG, 3, TYPE_LAB, TYPE_VAL, TYPE_VAL), + defop(JGE, 3, TYPE_LAB, TYPE_VAL, TYPE_VAL), + defop(JE, 3, TYPE_LAB, TYPE_VAL, TYPE_VAL), + defop(JNE, 3, TYPE_LAB, TYPE_VAL, TYPE_VAL) }; /************************************************************************* @@ -518,6 +523,7 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc) struct creole_ins *ins = env->prg + env->prgptr; creole_word a1, a2; int rcode = CREOLE_STEP_CONTINUE; + int increase_pointer = 1; if (env->prgptr == env->prgend) return CREOLE_STEP_STOP; @@ -556,22 +562,70 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc) check(creole_reg_write(env, ins->w[0], (creole_signed)a1 / (creole_signed)a2)); break; + case CREOLE_SYS: + check(read_val(env, ins, 0, sc)); + rcode = CREOLE_STEP_SYSCALL; + break; case CREOLE_JL: check(read_val(env, ins, 1, &a1)); check(read_val(env, ins, 2, &a2)); check(check_label(env, ins->w[0])); - if (a1 < a2) + if (a1 < a2) { env->prgptr = env->lab[ins->w[0]]; + increase_pointer = 0; + } break; - case CREOLE_SYS: - check(read_val(env, ins, 0, sc)); - rcode = CREOLE_STEP_SYSCALL; + case CREOLE_JLE: + check(read_val(env, ins, 1, &a1)); + check(read_val(env, ins, 2, &a2)); + check(check_label(env, ins->w[0])); + if (a1 <= a2) { + env->prgptr = env->lab[ins->w[0]]; + increase_pointer = 0; + } + break; + case CREOLE_JG: + check(read_val(env, ins, 1, &a1)); + check(read_val(env, ins, 2, &a2)); + check(check_label(env, ins->w[0])); + if (a1 > a2) { + env->prgptr = env->lab[ins->w[0]]; + increase_pointer = 0; + } + break; + case CREOLE_JGE: + check(read_val(env, ins, 1, &a1)); + check(read_val(env, ins, 2, &a2)); + check(check_label(env, ins->w[0])); + if (a1 >= a2) { + env->prgptr = env->lab[ins->w[0]]; + increase_pointer = 0; + } + break; + case CREOLE_JE: + check(read_val(env, ins, 1, &a1)); + check(read_val(env, ins, 2, &a2)); + check(check_label(env, ins->w[0])); + if (a1 == a2) { + env->prgptr = env->lab[ins->w[0]]; + increase_pointer = 0; + } + break; + case CREOLE_JNE: + check(read_val(env, ins, 1, &a1)); + check(read_val(env, ins, 2, &a2)); + check(check_label(env, ins->w[0])); + if (a1 != a2) { + env->prgptr = env->lab[ins->w[0]]; + increase_pointer = 0; + } break; default: rcode = CREOLE_STEP_UNKNOWN_OPCODE; } - env->prgptr++; + if (increase_pointer) + env->prgptr++; return rcode; } |
