add signed division IDIV
This commit is contained in:
parent
18ad8f03c6
commit
5f3275cf2d
|
@ -11,6 +11,11 @@ def word_2c(w):
|
||||||
def ti(w):
|
def ti(w):
|
||||||
""" Explicitly transform integer into two's compliment representation. """
|
""" Explicitly transform integer into two's compliment representation. """
|
||||||
return w if w >= 0 else word_wc(-w)
|
return w if w >= 0 else word_wc(-w)
|
||||||
|
def from_2c(w):
|
||||||
|
""" Turn two's compliment word into Python integer. """
|
||||||
|
if (w >> 31) & 1 == 0:
|
||||||
|
return w
|
||||||
|
return -word_2c(w)
|
||||||
|
|
||||||
class ArgType(Enum):
|
class ArgType(Enum):
|
||||||
""" Class denoting the type of an argument to an instruction. """
|
""" Class denoting the type of an argument to an instruction. """
|
||||||
|
@ -86,9 +91,10 @@ class Instruction(Enum):
|
||||||
ADD = 3, ArgType.REG, ArgType.VAL, ArgType.VAL
|
ADD = 3, ArgType.REG, ArgType.VAL, ArgType.VAL
|
||||||
MUL = 4, ArgType.REG, ArgType.VAL, ArgType.VAL
|
MUL = 4, ArgType.REG, ArgType.VAL, ArgType.VAL
|
||||||
DIV = 5, ArgType.REG, ArgType.VAL, ArgType.VAL
|
DIV = 5, ArgType.REG, ArgType.VAL, ArgType.VAL
|
||||||
JL = 6, ArgType.LAB, ArgType.VAL, ArgType.VAL
|
IDIV = 6, ArgType.REG, ArgType.VAL, ArgType.VAL
|
||||||
CLB = 7, ArgType.LAB
|
JL = 7, ArgType.LAB, ArgType.VAL, ArgType.VAL
|
||||||
SYS = 8, ArgType.VAL
|
CLB = 8, ArgType.LAB
|
||||||
|
SYS = 9, ArgType.VAL
|
||||||
|
|
||||||
def __init__(self, opcode, *args):
|
def __init__(self, opcode, *args):
|
||||||
if opcode > 0x7F or opcode < 0:
|
if opcode > 0x7F or opcode < 0:
|
||||||
|
|
32
asm/ffi.py
32
asm/ffi.py
|
@ -1,4 +1,5 @@
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
|
import creole
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
dll = CDLL("./libcreole.so")
|
dll = CDLL("./libcreole.so")
|
||||||
|
|
||||||
|
@ -24,6 +25,7 @@ class RunRet(Enum):
|
||||||
RUN_LABEL_OVERFLOW = 5
|
RUN_LABEL_OVERFLOW = 5
|
||||||
REGISTER_OVERFLOW = 6
|
REGISTER_OVERFLOW = 6
|
||||||
UNKNOWN_OPCODE = 7
|
UNKNOWN_OPCODE = 7
|
||||||
|
DIVIDE_BY_ZERO = 8
|
||||||
|
|
||||||
def is_halt(self):
|
def is_halt(self):
|
||||||
return not (self == RunRet.CONTINUE or self == RunRet.SYSCALL)
|
return not (self == RunRet.CONTINUE or self == RunRet.SYSCALL)
|
||||||
|
@ -59,8 +61,30 @@ class CEnv(Structure):
|
||||||
("prglen", c_size_t)
|
("prglen", c_size_t)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
class RegisterOverflowError(Exception):
|
||||||
|
def __init__(self, reg):
|
||||||
|
self.reg = reg
|
||||||
|
class StackOverflowError(Exception):
|
||||||
|
def __init__(self, pos):
|
||||||
|
self.pos = pos
|
||||||
|
class InvalidSyscallError(Exception):
|
||||||
|
def __init__(self, sc):
|
||||||
|
self.sc = sc
|
||||||
|
class CompileError(Exception):
|
||||||
|
def __init__(self, r):
|
||||||
|
self.r = r
|
||||||
|
|
||||||
class Environment:
|
class Environment:
|
||||||
def __init__(self, reglen=32, lablen=32, stklen=4096, prglen=4096):
|
def getreg(self, reg):
|
||||||
|
if reg >= self.cenv.reglen or reg < 0:
|
||||||
|
raise RegisterOverflowError(r)
|
||||||
|
return creole.from_2c(self.cenv.reg[reg])
|
||||||
|
def getstk(self, stk):
|
||||||
|
if stk >= self.cenv.stklen or stk < 0:
|
||||||
|
raise StackOverflowError(r)
|
||||||
|
return creole.from_2c(self.cenv.stk[stk])
|
||||||
|
|
||||||
|
def __init__(self, prog=None, reglen=32, lablen=32, stklen=4096, prglen=4096):
|
||||||
cenv = CEnv()
|
cenv = CEnv()
|
||||||
cenv.reglen = reglen
|
cenv.reglen = reglen
|
||||||
cenv.reg = (c_uint * reglen)()
|
cenv.reg = (c_uint * reglen)()
|
||||||
|
@ -78,6 +102,10 @@ class Environment:
|
||||||
cenv.prgend = 0
|
cenv.prgend = 0
|
||||||
|
|
||||||
self.cenv = cenv
|
self.cenv = cenv
|
||||||
|
if prog is not None:
|
||||||
|
r = self.load(prog)
|
||||||
|
if r is not CompileRet.OK:
|
||||||
|
raise CompileError(r)
|
||||||
|
|
||||||
def restart(self):
|
def restart(self):
|
||||||
self.cenv.stkptr = 0
|
self.cenv.stkptr = 0
|
||||||
|
@ -91,7 +119,7 @@ class Environment:
|
||||||
return CompileRet(ret)
|
return CompileRet(ret)
|
||||||
|
|
||||||
def syscall(self, sc):
|
def syscall(self, sc):
|
||||||
pass
|
raise InvalidSyscallError(sc)
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
sc = c_size_t()
|
sc = c_size_t()
|
||||||
ret = RunRet.CONTINUE
|
ret = RunRet.CONTINUE
|
||||||
|
|
109
asm/test.py
109
asm/test.py
|
@ -56,10 +56,8 @@ class PushTest(unittest.TestCase):
|
||||||
p = Program()
|
p = Program()
|
||||||
p.parse_asm_line("PUSH r0")
|
p.parse_asm_line("PUSH r0")
|
||||||
p.parse_asm_line("PUSH 6")
|
p.parse_asm_line("PUSH 6")
|
||||||
b = p()
|
|
||||||
|
|
||||||
ex = ffi.Environment()
|
ex = ffi.Environment(p())
|
||||||
self.assertEqual(ex.load(b), ffi.CompileRet.OK)
|
|
||||||
self.assertEqual(ex.cenv.prgend, 2)
|
self.assertEqual(ex.cenv.prgend, 2)
|
||||||
|
|
||||||
self.assertEqual(ex.cenv.prg[0].opcode, 1)
|
self.assertEqual(ex.cenv.prg[0].opcode, 1)
|
||||||
|
@ -83,19 +81,17 @@ class PushTest(unittest.TestCase):
|
||||||
stklen = 40
|
stklen = 40
|
||||||
for n in range(0,stklen):
|
for n in range(0,stklen):
|
||||||
p.parse_asm_line("PUSH 5")
|
p.parse_asm_line("PUSH 5")
|
||||||
ex = ffi.Environment(stklen=stklen)
|
ex = ffi.Environment(p(), stklen=stklen)
|
||||||
self.assertEqual(ex.load(p()), ffi.CompileRet.OK)
|
|
||||||
self.assertEqual(ex(), ffi.RunRet.STOP)
|
self.assertEqual(ex(), ffi.RunRet.STOP)
|
||||||
for n in range(0,stklen):
|
for n in range(0,stklen):
|
||||||
self.assertEqual(ex.cenv.stk[n], 5)
|
self.assertEqual(ex.getstk(n), 5)
|
||||||
|
|
||||||
def test_push_overflow(self):
|
def test_push_overflow(self):
|
||||||
p = Program()
|
p = Program()
|
||||||
stklen = 40
|
stklen = 40
|
||||||
for n in range(0, stklen + 1):
|
for n in range(0, stklen + 1):
|
||||||
p.parse_asm_line("PUSH 5")
|
p.parse_asm_line("PUSH 5")
|
||||||
ex = ffi.Environment(stklen=stklen)
|
ex = ffi.Environment(p(), stklen=stklen)
|
||||||
self.assertEqual(ex.load(p()), ffi.CompileRet.OK)
|
|
||||||
self.assertEqual(ex(), ffi.RunRet.STACK_OVERFLOW)
|
self.assertEqual(ex(), ffi.RunRet.STACK_OVERFLOW)
|
||||||
|
|
||||||
class PopTest(unittest.TestCase):
|
class PopTest(unittest.TestCase):
|
||||||
|
@ -104,8 +100,7 @@ class PopTest(unittest.TestCase):
|
||||||
p.parse_asm_line("pop r9")
|
p.parse_asm_line("pop r9")
|
||||||
b = p()
|
b = p()
|
||||||
self.assertEqual(b, b'\x02\xC2\x89\x00')
|
self.assertEqual(b, b'\x02\xC2\x89\x00')
|
||||||
ex = ffi.Environment()
|
ex = ffi.Environment(b)
|
||||||
self.assertEqual(ex.load(b), ffi.CompileRet.OK)
|
|
||||||
self.assertEqual(ex.cenv.prgend, 1)
|
self.assertEqual(ex.cenv.prgend, 1)
|
||||||
|
|
||||||
self.assertEqual(ex.cenv.prg[0].opcode, 2)
|
self.assertEqual(ex.cenv.prg[0].opcode, 2)
|
||||||
|
@ -152,8 +147,7 @@ class PopTest(unittest.TestCase):
|
||||||
def test_pop_underflow(self):
|
def test_pop_underflow(self):
|
||||||
p = Program()
|
p = Program()
|
||||||
p.parse_asm_line("pop r0")
|
p.parse_asm_line("pop r0")
|
||||||
ex = ffi.Environment()
|
ex = ffi.Environment(p())
|
||||||
self.assertEqual(ex.load(p()), ffi.CompileRet.OK)
|
|
||||||
self.assertEqual(ex(), ffi.RunRet.STACK_UNDERFLOW)
|
self.assertEqual(ex(), ffi.RunRet.STACK_UNDERFLOW)
|
||||||
|
|
||||||
def test_pop_underflow_2(self):
|
def test_pop_underflow_2(self):
|
||||||
|
@ -161,16 +155,14 @@ class PopTest(unittest.TestCase):
|
||||||
p.parse_asm_line("push 5")
|
p.parse_asm_line("push 5")
|
||||||
p.parse_asm_line("pop r0")
|
p.parse_asm_line("pop r0")
|
||||||
p.parse_asm_line("pop r1")
|
p.parse_asm_line("pop r1")
|
||||||
ex = ffi.Environment()
|
ex = ffi.Environment(p())
|
||||||
self.assertEqual(ex.load(p()), ffi.CompileRet.OK)
|
|
||||||
self.assertEqual(ex(), ffi.RunRet.STACK_UNDERFLOW)
|
self.assertEqual(ex(), ffi.RunRet.STACK_UNDERFLOW)
|
||||||
|
|
||||||
class AddTest(unittest.TestCase):
|
class AddTest(unittest.TestCase):
|
||||||
def test_exec_add(self):
|
def test_exec_add(self):
|
||||||
p = Program()
|
p = Program()
|
||||||
p.parse_asm_line("add r0 1 1")
|
p.parse_asm_line("add r0 1 1")
|
||||||
ex = ffi.Environment()
|
ex = ffi.Environment(p())
|
||||||
self.assertEqual(ex.load(p()), ffi.CompileRet.OK)
|
|
||||||
self.assertEqual(ex(), ffi.RunRet.STOP)
|
self.assertEqual(ex(), ffi.RunRet.STOP)
|
||||||
self.assertEqual(ex.cenv.reg[0], 2)
|
self.assertEqual(ex.cenv.reg[0], 2)
|
||||||
|
|
||||||
|
@ -179,11 +171,10 @@ class AddTest(unittest.TestCase):
|
||||||
p.parse_asm_line("add r0 10 20")
|
p.parse_asm_line("add r0 10 20")
|
||||||
p.parse_asm_line("add r1 5 0")
|
p.parse_asm_line("add r1 5 0")
|
||||||
p.parse_asm_line("add r1 r0 -40")
|
p.parse_asm_line("add r1 r0 -40")
|
||||||
ex = ffi.Environment()
|
ex = ffi.Environment(p())
|
||||||
self.assertEqual(ex.load(p()), ffi.CompileRet.OK)
|
|
||||||
self.assertEqual(ex(), ffi.RunRet.STOP)
|
self.assertEqual(ex(), ffi.RunRet.STOP)
|
||||||
self.assertEqual(ex.cenv.reg[0], 30)
|
self.assertEqual(ex.getreg(0), 30)
|
||||||
self.assertEqual(ex.cenv.reg[1], word_2c(10))
|
self.assertEqual(ex.getreg(1), -10)
|
||||||
|
|
||||||
def test_exec_add_throw_imm(self):
|
def test_exec_add_throw_imm(self):
|
||||||
p = Program()
|
p = Program()
|
||||||
|
@ -216,20 +207,18 @@ class MulTest(unittest.TestCase):
|
||||||
def test_exec_mul_imm_imm(self):
|
def test_exec_mul_imm_imm(self):
|
||||||
p = Program()
|
p = Program()
|
||||||
p.parse_asm_line("mul r0 2 2")
|
p.parse_asm_line("mul r0 2 2")
|
||||||
ex = ffi.Environment()
|
ex = ffi.Environment(p())
|
||||||
self.assertEqual(ex.load(p()), ffi.CompileRet.OK)
|
|
||||||
self.assertEqual(ex(), ffi.RunRet.STOP)
|
self.assertEqual(ex(), ffi.RunRet.STOP)
|
||||||
self.assertEqual(ex.cenv.reg[0], 4)
|
self.assertEqual(ex.getreg(0), 4)
|
||||||
|
|
||||||
def test_exec_mul_imm_neg_imm(self):
|
def test_exec_mul_imm_neg_imm(self):
|
||||||
p = Program()
|
p = Program()
|
||||||
p.parse_asm_line("mul r0 -5 5")
|
p.parse_asm_line("mul r0 -5 5")
|
||||||
p.parse_asm_line("mul r1 r0 -5")
|
p.parse_asm_line("mul r1 r0 -5")
|
||||||
ex = ffi.Environment()
|
ex = ffi.Environment(p())
|
||||||
self.assertEqual(ex.load(p()), ffi.CompileRet.OK)
|
|
||||||
self.assertEqual(ex(), ffi.RunRet.STOP)
|
self.assertEqual(ex(), ffi.RunRet.STOP)
|
||||||
self.assertEqual(ex.cenv.reg[0], word_2c(25))
|
self.assertEqual(ex.getreg(0), -25)
|
||||||
self.assertEqual(ex.cenv.reg[1], 125)
|
self.assertEqual(ex.getreg(1), 125)
|
||||||
|
|
||||||
def test_exec_mul_throw_imm(self):
|
def test_exec_mul_throw_imm(self):
|
||||||
p = Program()
|
p = Program()
|
||||||
|
@ -258,6 +247,68 @@ class MulTest(unittest.TestCase):
|
||||||
self.assertEqual(cm.exception.i, 2)
|
self.assertEqual(cm.exception.i, 2)
|
||||||
self.assertEqual(cm.exception.opcode, 4)
|
self.assertEqual(cm.exception.opcode, 4)
|
||||||
|
|
||||||
|
class DivTest(unittest.TestCase):
|
||||||
|
def test_div(self):
|
||||||
|
p = Program()
|
||||||
|
p.parse_asm_line("div r0 8 4")
|
||||||
|
ex = ffi.Environment(p())
|
||||||
|
self.assertEqual(ex(), ffi.RunRet.STOP)
|
||||||
|
self.assertEqual(ex.getreg(0), 2)
|
||||||
|
|
||||||
|
def test_div_round_down(self):
|
||||||
|
p = Program()
|
||||||
|
p.parse_asm_line("div r0 8 10")
|
||||||
|
ex = ffi.Environment(p())
|
||||||
|
self.assertEqual(ex(), ffi.RunRet.STOP)
|
||||||
|
|
||||||
|
def test_div_by_zero(self):
|
||||||
|
p = Program()
|
||||||
|
p.parse_asm_line("div r0 8 0")
|
||||||
|
ex = ffi.Environment(p())
|
||||||
|
self.assertEqual(ex(), ffi.RunRet.DIVIDE_BY_ZERO)
|
||||||
|
|
||||||
|
def test_idiv_by_zero(self):
|
||||||
|
p = Program()
|
||||||
|
p.parse_asm_line("idiv r0 8 0")
|
||||||
|
ex = ffi.Environment(p())
|
||||||
|
self.assertEqual(ex(), ffi.RunRet.DIVIDE_BY_ZERO)
|
||||||
|
|
||||||
|
def test_div_neg(self):
|
||||||
|
p = Program()
|
||||||
|
p.parse_asm_line("idiv r0 16 -4")
|
||||||
|
p.parse_asm_line("idiv r1 r0 -4")
|
||||||
|
ex = ffi.Environment(p())
|
||||||
|
self.assertEqual(ex(), ffi.RunRet.STOP)
|
||||||
|
self.assertEqual(ex.getreg(0), -4)
|
||||||
|
self.assertEqual(ex.getreg(1), 1)
|
||||||
|
|
||||||
|
def test_exec_div_throw_imm(self):
|
||||||
|
p = Program()
|
||||||
|
with self.assertRaises(TypecheckException) as cm:
|
||||||
|
p.parse_asm_line("div 5 1 2")
|
||||||
|
self.assertEqual(cm.exception.argtype, ArgType.REG)
|
||||||
|
self.assertEqual(cm.exception.sarg, '5')
|
||||||
|
self.assertEqual(cm.exception.i, 0)
|
||||||
|
self.assertEqual(cm.exception.opcode, 5)
|
||||||
|
|
||||||
|
def test_exec_div_throw_lab_1(self):
|
||||||
|
p = Program()
|
||||||
|
with self.assertRaises(TypecheckException) as cm:
|
||||||
|
p.parse_asm_line("div r0 l123 456")
|
||||||
|
self.assertEqual(cm.exception.argtype, ArgType.VAL)
|
||||||
|
self.assertEqual(cm.exception.sarg, 'l123')
|
||||||
|
self.assertEqual(cm.exception.i, 1)
|
||||||
|
self.assertEqual(cm.exception.opcode, 5)
|
||||||
|
|
||||||
|
def test_exec_div_throw_lab_2(self):
|
||||||
|
p = Program()
|
||||||
|
with self.assertRaises(TypecheckException) as cm:
|
||||||
|
p.parse_asm_line("div r5 1919 l24")
|
||||||
|
self.assertEqual(cm.exception.argtype, ArgType.VAL)
|
||||||
|
self.assertEqual(cm.exception.sarg, 'l24')
|
||||||
|
self.assertEqual(cm.exception.i, 2)
|
||||||
|
self.assertEqual(cm.exception.opcode, 5)
|
||||||
|
|
||||||
class ProgramTest(unittest.TestCase):
|
class ProgramTest(unittest.TestCase):
|
||||||
def test_exec_simple_reg(self):
|
def test_exec_simple_reg(self):
|
||||||
p = Program()
|
p = Program()
|
||||||
|
@ -268,8 +319,8 @@ class ProgramTest(unittest.TestCase):
|
||||||
ex = ffi.Environment()
|
ex = ffi.Environment()
|
||||||
self.assertEqual(ex.load(p()), ffi.CompileRet.OK)
|
self.assertEqual(ex.load(p()), ffi.CompileRet.OK)
|
||||||
self.assertEqual(ex(), ffi.RunRet.STOP)
|
self.assertEqual(ex(), ffi.RunRet.STOP)
|
||||||
self.assertEqual(ex.cenv.reg[0], 6)
|
self.assertEqual(ex.getreg(0), 6)
|
||||||
self.assertEqual(ex.cenv.reg[1], 5)
|
self.assertEqual(ex.getreg(1), 5)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
14
creole.c
14
creole.c
|
@ -35,6 +35,7 @@ static const struct {
|
||||||
defop(ADD, 3, TYPE_REG, TYPE_VAL, TYPE_VAL),
|
defop(ADD, 3, TYPE_REG, TYPE_VAL, TYPE_VAL),
|
||||||
defop(MUL, 3, TYPE_REG, TYPE_VAL, TYPE_VAL),
|
defop(MUL, 3, TYPE_REG, TYPE_VAL, TYPE_VAL),
|
||||||
defop(DIV, 3, TYPE_REG, TYPE_VAL, TYPE_VAL),
|
defop(DIV, 3, TYPE_REG, TYPE_VAL, TYPE_VAL),
|
||||||
|
defop(IDIV, 3, TYPE_REG, TYPE_VAL, TYPE_VAL),
|
||||||
defop(JL, 3, TYPE_LAB, TYPE_VAL, TYPE_VAL),
|
defop(JL, 3, TYPE_LAB, TYPE_VAL, TYPE_VAL),
|
||||||
defop(CLB, 1, TYPE_LAB, TYPE_NONE, TYPE_NONE),
|
defop(CLB, 1, TYPE_LAB, TYPE_NONE, TYPE_NONE),
|
||||||
defop(SYS, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE)
|
defop(SYS, 1, TYPE_VAL, TYPE_NONE, TYPE_NONE)
|
||||||
|
@ -323,8 +324,9 @@ creole_parse_line(struct creole_ins *ins, struct creole_reader *r)
|
||||||
return CREOLE_OPCODE_READ_ERROR;
|
return CREOLE_OPCODE_READ_ERROR;
|
||||||
|
|
||||||
ins->opcode = w.word;
|
ins->opcode = w.word;
|
||||||
if (w.word >= CREOLE_ARG_TYPE_LEN || w.len != 1)
|
if (w.word >= CREOLE_OPCODE_LEN || w.len != 1) {
|
||||||
return CREOLE_OPCODE_MALFORMED;
|
return CREOLE_OPCODE_MALFORMED;
|
||||||
|
}
|
||||||
|
|
||||||
for (arg = 0; arg < opcode_info[ins->opcode].arglen; arg++) {
|
for (arg = 0; arg < opcode_info[ins->opcode].arglen; arg++) {
|
||||||
if (!decode_seq(r, &w))
|
if (!decode_seq(r, &w))
|
||||||
|
@ -542,8 +544,18 @@ enum creole_run_ret creole_step(struct creole_env *env, creole_word *sc)
|
||||||
case CREOLE_DIV:
|
case CREOLE_DIV:
|
||||||
check(read_val(env, ins, 1, &a1));
|
check(read_val(env, ins, 1, &a1));
|
||||||
check(read_val(env, ins, 2, &a2));
|
check(read_val(env, ins, 2, &a2));
|
||||||
|
if (a2 == 0)
|
||||||
|
return CREOLE_DIV_BY_ZERO;
|
||||||
check(creole_reg_write(env, ins->w[0], a1 / a2));
|
check(creole_reg_write(env, ins->w[0], a1 / a2));
|
||||||
break;
|
break;
|
||||||
|
case CREOLE_IDIV:
|
||||||
|
check(read_val(env, ins, 1, &a1));
|
||||||
|
check(read_val(env, ins, 2, &a2));
|
||||||
|
if (a2 == 0)
|
||||||
|
return CREOLE_DIV_BY_ZERO;
|
||||||
|
check(creole_reg_write(env, ins->w[0],
|
||||||
|
(creole_signed)a1 / (creole_signed)a2));
|
||||||
|
break;
|
||||||
case CREOLE_JL:
|
case CREOLE_JL:
|
||||||
check(read_val(env, ins, 1, &a1));
|
check(read_val(env, ins, 1, &a1));
|
||||||
check(read_val(env, ins, 2, &a2));
|
check(read_val(env, ins, 2, &a2));
|
||||||
|
|
11
creole.h
11
creole.h
|
@ -7,11 +7,14 @@
|
||||||
#ifndef CREOLE_WORD
|
#ifndef CREOLE_WORD
|
||||||
# define CREOLE_WORD unsigned int
|
# define CREOLE_WORD unsigned int
|
||||||
# define CREOLE_WORD_MAX UINT_MAX
|
# define CREOLE_WORD_MAX UINT_MAX
|
||||||
|
# define CREOLE_SIGNED_WORD int
|
||||||
|
# define CREOLE_SIGNED_MAX INT_MAX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CREOLE_MAX_ARG 3
|
#define CREOLE_MAX_ARG 3
|
||||||
|
|
||||||
typedef CREOLE_WORD creole_word;
|
typedef CREOLE_WORD creole_word;
|
||||||
|
typedef CREOLE_SIGNED_WORD creole_signed;
|
||||||
|
|
||||||
enum creole_opcode {
|
enum creole_opcode {
|
||||||
CREOLE_NOOP = 0,
|
CREOLE_NOOP = 0,
|
||||||
|
@ -20,9 +23,10 @@ enum creole_opcode {
|
||||||
CREOLE_ADD = 3,
|
CREOLE_ADD = 3,
|
||||||
CREOLE_MUL = 4,
|
CREOLE_MUL = 4,
|
||||||
CREOLE_DIV = 5,
|
CREOLE_DIV = 5,
|
||||||
CREOLE_JL = 6,
|
CREOLE_IDIV = 6,
|
||||||
CREOLE_CLB = 7,
|
CREOLE_JL = 7,
|
||||||
CREOLE_SYS = 8,
|
CREOLE_CLB = 8,
|
||||||
|
CREOLE_SYS = 9,
|
||||||
CREOLE_OPCODE_LEN
|
CREOLE_OPCODE_LEN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,6 +60,7 @@ enum creole_run_ret {
|
||||||
CREOLE_RUN_LABEL_OVERFLOW,
|
CREOLE_RUN_LABEL_OVERFLOW,
|
||||||
CREOLE_REGISTER_OVERFLOW,
|
CREOLE_REGISTER_OVERFLOW,
|
||||||
CREOLE_STEP_UNKNOWN_OPCODE,
|
CREOLE_STEP_UNKNOWN_OPCODE,
|
||||||
|
CREOLE_DIV_BY_ZERO,
|
||||||
CREOLE_RUN_RET_LEN
|
CREOLE_RUN_RET_LEN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue