1
0
infernal-interpreter/opcodes.py
Jon Michael Aanes 8b146efe68 Added Junk value, for which all operations are
defined to produce junk.
Any comparison involving junk triggers the i status register.
Any conditional jump triggered when the i register is true,
triggers a python level exception.
2015-12-19 16:55:14 +01:00

89 lines
1.9 KiB
Python

OPCODES = {}
def add_opcode (*opcode_names):
def wrapped (func):
for name in opcode_names:
OPCODES[name] = func
return wrapped
################################################################################
# Stack
@add_opcode("push","pushq")
def push(emu, value):
emu.pushToStack(emu.getVal(value))
@add_opcode("pop","popq")
def pop(emu, target_reg):
emu.registers[target_reg] = emu.popFromStack()
emu.changedRegisters((target_reg,"change"))
# Arithmetic
@add_opcode("mov","movq")
def mov(emu, from_reg, target_reg):
emu.registers[target_reg] = emu.getVal(from_reg)
emu.changedRegisters((target_reg,"change"))
@add_opcode("add","addq")
def add(emu, add_val, target_reg):
emu.registers[target_reg] += emu.getVal(add_val)
emu.changedRegisters((target_reg,"change"))
@add_opcode("sub","subq")
def sub(emu, sub_val, target_reg):
emu.registers[target_reg] -= emu.getVal(sub_val)
emu.changedRegisters((target_reg,"change"))
# Comparison and conditional jumping
@add_opcode("cmp","cmpq")
def comp(emu, val1, val2):
emu.compareVal(val1, val2)
@add_opcode("jg")
def jg(emu, label):
emu.jump(label, g=True)
@add_opcode("jl")
def jl(emu, label):
emu.jump(label, l=True)
@add_opcode("je")
def je(emu, label):
emu.jump(label, e=True)
@add_opcode("jge")
def jge(emu, label):
emu.jump(label, "or", g=True, e=True)
@add_opcode("jle")
def jle(emu, label):
emu.jump(label, "or", l=True, e=True)
@add_opcode("jne")
def jne(emu, label):
emu.jump(label, e=False)
# Unconditional Jumping
@add_opcode("jmp")
def jmp(emu, label):
emu.registers['%rip'] = emu.labels[label]
@add_opcode("call")
def call(emu, label):
emu.pushToStack(emu.registers['%rip']+1)
emu.registers['%rip'] = emu.labels[label]
@add_opcode("leave")
def leave(emu):
emu.registers["%rsp"] = emu.registers["%rbp"]
emu.registers["%rbp"] = emu.popFromStack()
@add_opcode("ret")
def ret(emu):
emu.registers['%rip'] = emu.popFromStack()