aboutsummaryrefslogtreecommitdiffstats
path: root/creole.c
diff options
context:
space:
mode:
authorGravatar Peter McGoron 2023-02-11 21:24:48 +0000
committerGravatar Peter McGoron 2023-02-11 21:24:48 +0000
commitb425e26ea3ff2df3f6b98b475ae870900efaf2e6 (patch)
treed134435547ee287f23b237b4be0c14bd353d87a7 /creole.c
parentrename idiv to sdiv (diff)
jump tests
Diffstat (limited to 'creole.c')
-rw-r--r--creole.c68
1 files changed, 61 insertions, 7 deletions
diff --git a/creole.c b/creole.c
index 135576f..6a1daa8 100644
--- a/creole.c
+++ b/creole.c
@@ -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;
}