ducky.cpu.coprocessor.math_copro module

Stack-based coprocessor, providing several arithmetic operations with “long” numbers.

Coprocessor’s instructions operates on a stack of (by default) 8 slots. Operations to move values between math stack and registers/data stack are also available.

In the following documentation several different data types are used:

  • int - standard word, 32-bit wide integer
  • long - long integer, 64-bit wide

Unless said otherwise, instruction takes its arguments from the stack, removing the values in the process, and pushes the result - if any - back on the stack.

class ducky.cpu.coprocessor.math_copro.ADDL(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

static execute(core, inst)[source]
mnemonic = 'addl'
opcode = <MathCoprocessorOpcodes.ADDL: 32>
class ducky.cpu.coprocessor.math_copro.DECL(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

Decrement top of the stack by one.

static execute(core, inst)[source]
mnemonic = 'decl'
opcode = <MathCoprocessorOpcodes.DECL: 31>
class ducky.cpu.coprocessor.math_copro.DIVL(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

Divide the value below the top of the math stack by the topmost value.

static execute(core, inst)[source]
mnemonic = 'divl'
opcode = <MathCoprocessorOpcodes.DIVL: 11>
class ducky.cpu.coprocessor.math_copro.DROP(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

static execute(core, inst)[source]
mnemonic = 'drop'
opcode = <MathCoprocessorOpcodes.DROP: 23>
class ducky.cpu.coprocessor.math_copro.DUP(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

static execute(core, inst)[source]
mnemonic = 'dup'
opcode = <MathCoprocessorOpcodes.DUP: 20>
class ducky.cpu.coprocessor.math_copro.DUP2(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

static execute(core, inst)[source]
mnemonic = 'dup2'
opcode = <MathCoprocessorOpcodes.DUP2: 21>
class ducky.cpu.coprocessor.math_copro.Descriptor_MATH(instruction_set)[source]

Bases: ducky.cpu.instructions.Descriptor_R_R

static assemble_operands(logger, buffer, inst, operands)[source]
static disassemble_operands(logger, inst)[source]
operands = ''
exception ducky.cpu.coprocessor.math_copro.EmptyMathStackError(*args, **kwargs)[source]

Bases: ducky.cpu.CPUException

Raised when operation expects at least one value on math stack but stack is empty.

exception ducky.cpu.coprocessor.math_copro.FullMathStackError(*args, **kwargs)[source]

Bases: ducky.cpu.CPUException

Raised when operation tries to put value on math stack but there is no empty spot available.

class ducky.cpu.coprocessor.math_copro.INCL(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

Increment top of the stack by one.

static execute(core, inst)[source]
mnemonic = 'incl'
opcode = <MathCoprocessorOpcodes.INCL: 30>
class ducky.cpu.coprocessor.math_copro.LOAD(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

Merge two registers together, and make the result new TOS.

static assemble_operands(logger, buffer, inst, operands)[source]
static disassemble_operands(logger, inst)[source]
static execute(core, inst)[source]
mnemonic = 'load'
opcode = <MathCoprocessorOpcodes.LOAD: 9>
operands = 'r,r'
class ducky.cpu.coprocessor.math_copro.LOADUW(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

Take a value from register, extend it to long, and make the result TOS.

static assemble_operands(logger, buffer, inst, operands)[source]
static disassemble_operands(logger, inst)[source]
static execute(core, inst)[source]
mnemonic = 'loaduw'
opcode = <MathCoprocessorOpcodes.LOADUW: 5>
operands = 'r'
class ducky.cpu.coprocessor.math_copro.LOADW(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

Take a value from register, extend it to long, and make the result TOS.

static assemble_operands(logger, buffer, inst, operands)[source]
static disassemble_operands(logger, inst)[source]
static execute(core, inst)[source]
mnemonic = 'loadw'
opcode = <MathCoprocessorOpcodes.LOADW: 4>
operands = 'r'
class ducky.cpu.coprocessor.math_copro.MODL(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

static execute(core, inst)[source]
mnemonic = 'modl'
opcode = <MathCoprocessorOpcodes.MODL: 12>
class ducky.cpu.coprocessor.math_copro.MULL(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

Multiply two top-most numbers on the stack.

static execute(core, inst)[source]
mnemonic = 'mull'
opcode = <MathCoprocessorOpcodes.MULL: 10>
class ducky.cpu.coprocessor.math_copro.MathCoprocessor(core, *args, **kwargs)[source]

Bases: ducky.interfaces.ISnapshotable, ducky.cpu.coprocessor.Coprocessor

Coprocessor itself, includes its register set (“math stack”).

Parameters:core (ducky.cpu.CPUCore) – CPU core coprocessor belongs to.
dump_stack()[source]

Log content of the stack using parent’s DEBUG method.

extend_with_push(u32)[source]
load_state(state)[source]
save_state(parent)[source]
sign_extend_with_push(i32)[source]
class ducky.cpu.coprocessor.math_copro.MathCoprocessorInstructionSet[source]

Bases: ducky.cpu.instructions.InstructionSet

Math coprocessor’s instruction set.

instruction_set_id = 1
instructions = [<ducky.cpu.coprocessor.math_copro.ADDL object at 0x7f16cbad27d0>, <ducky.cpu.coprocessor.math_copro.INCL object at 0x7f16cbad2090>, <ducky.cpu.coprocessor.math_copro.DECL object at 0x7f16cbad2e50>, <ducky.cpu.coprocessor.math_copro.MULL object at 0x7f16cbad2fd0>, <ducky.cpu.coprocessor.math_copro.DIVL object at 0x7f16cbad2750>, <ducky.cpu.coprocessor.math_copro.MODL object at 0x7f16cbad2a10>, <ducky.cpu.coprocessor.math_copro.UDIVL object at 0x7f16cbad2a90>, <ducky.cpu.coprocessor.math_copro.UMODL object at 0x7f16cbad2810>, <ducky.cpu.coprocessor.math_copro.SYMDIVL object at 0x7f16cbad2210>, <ducky.cpu.coprocessor.math_copro.SYMMODL object at 0x7f16cbad2990>, <ducky.cpu.coprocessor.math_copro.DUP object at 0x7f16cbad2b50>, <ducky.cpu.coprocessor.math_copro.DUP2 object at 0x7f16cbad2890>, <ducky.cpu.coprocessor.math_copro.SWP object at 0x7f16cbad2d10>, <ducky.cpu.coprocessor.math_copro.DROP object at 0x7f16cbad2650>, <ducky.cpu.coprocessor.math_copro.PUSHW object at 0x7f16cbad2310>, <ducky.cpu.coprocessor.math_copro.SAVEW object at 0x7f16cbad2ed0>, <ducky.cpu.coprocessor.math_copro.POPW object at 0x7f16cbad2bd0>, <ducky.cpu.coprocessor.math_copro.LOADW object at 0x7f16cbad2910>, <ducky.cpu.coprocessor.math_copro.POPUW object at 0x7f16cbad2f10>, <ducky.cpu.coprocessor.math_copro.LOADUW object at 0x7f16cbad2550>, <ducky.cpu.coprocessor.math_copro.PUSH object at 0x7f16cbad2250>, <ducky.cpu.coprocessor.math_copro.SAVE object at 0x7f16cba1bcd0>, <ducky.cpu.coprocessor.math_copro.POP object at 0x7f16cba1b9d0>, <ducky.cpu.coprocessor.math_copro.LOAD object at 0x7f16cba1b150>, <ducky.cpu.instructions.SIS object at 0x7f16cba1bc10>]
opcode_desc_map = {<MathCoprocessorOpcodes.POPW: 0>: <ducky.cpu.coprocessor.math_copro.POPW object at 0x7f16cbad2bd0>, <MathCoprocessorOpcodes.POPUW: 1>: <ducky.cpu.coprocessor.math_copro.POPUW object at 0x7f16cbad2f10>, <MathCoprocessorOpcodes.PUSHW: 2>: <ducky.cpu.coprocessor.math_copro.PUSHW object at 0x7f16cbad2310>, <MathCoprocessorOpcodes.SAVEW: 3>: <ducky.cpu.coprocessor.math_copro.SAVEW object at 0x7f16cbad2ed0>, <MathCoprocessorOpcodes.LOADW: 4>: <ducky.cpu.coprocessor.math_copro.LOADW object at 0x7f16cbad2910>, <MathCoprocessorOpcodes.LOADUW: 5>: <ducky.cpu.coprocessor.math_copro.LOADUW object at 0x7f16cbad2550>, <MathCoprocessorOpcodes.POP: 6>: <ducky.cpu.coprocessor.math_copro.POP object at 0x7f16cba1b9d0>, <MathCoprocessorOpcodes.SAVE: 7>: <ducky.cpu.coprocessor.math_copro.SAVE object at 0x7f16cba1bcd0>, <MathCoprocessorOpcodes.PUSH: 8>: <ducky.cpu.coprocessor.math_copro.PUSH object at 0x7f16cbad2250>, <MathCoprocessorOpcodes.LOAD: 9>: <ducky.cpu.coprocessor.math_copro.LOAD object at 0x7f16cba1b150>, <MathCoprocessorOpcodes.MULL: 10>: <ducky.cpu.coprocessor.math_copro.MULL object at 0x7f16cbad2fd0>, <MathCoprocessorOpcodes.DIVL: 11>: <ducky.cpu.coprocessor.math_copro.DIVL object at 0x7f16cbad2750>, <MathCoprocessorOpcodes.MODL: 12>: <ducky.cpu.coprocessor.math_copro.MODL object at 0x7f16cbad2a10>, <MathCoprocessorOpcodes.SYMDIVL: 13>: <ducky.cpu.coprocessor.math_copro.SYMDIVL object at 0x7f16cbad2210>, <MathCoprocessorOpcodes.SYMMODL: 14>: <ducky.cpu.coprocessor.math_copro.SYMMODL object at 0x7f16cbad2990>, <MathCoprocessorOpcodes.UDIVL: 15>: <ducky.cpu.coprocessor.math_copro.UDIVL object at 0x7f16cbad2a90>, <MathCoprocessorOpcodes.UMODL: 16>: <ducky.cpu.coprocessor.math_copro.UMODL object at 0x7f16cbad2810>, <MathCoprocessorOpcodes.DUP: 20>: <ducky.cpu.coprocessor.math_copro.DUP object at 0x7f16cbad2b50>, <MathCoprocessorOpcodes.DUP2: 21>: <ducky.cpu.coprocessor.math_copro.DUP2 object at 0x7f16cbad2890>, <MathCoprocessorOpcodes.SWP: 22>: <ducky.cpu.coprocessor.math_copro.SWP object at 0x7f16cbad2d10>, <MathCoprocessorOpcodes.DROP: 23>: <ducky.cpu.coprocessor.math_copro.DROP object at 0x7f16cbad2650>, <MathCoprocessorOpcodes.INCL: 30>: <ducky.cpu.coprocessor.math_copro.INCL object at 0x7f16cbad2090>, <MathCoprocessorOpcodes.DECL: 31>: <ducky.cpu.coprocessor.math_copro.DECL object at 0x7f16cbad2e50>, <MathCoprocessorOpcodes.ADDL: 32>: <ducky.cpu.coprocessor.math_copro.ADDL object at 0x7f16cbad27d0>, <DuckyOpcodes.SIS: 63>: <ducky.cpu.instructions.SIS object at 0x7f16cba1bc10>}
opcode_encoding_map = {<MathCoprocessorOpcodes.POPW: 0>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.POPUW: 1>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.PUSHW: 2>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.SAVEW: 3>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.LOADW: 4>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.LOADUW: 5>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.POP: 6>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.SAVE: 7>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.PUSH: 8>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.LOAD: 9>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.MULL: 10>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.DIVL: 11>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.MODL: 12>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.SYMDIVL: 13>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.SYMMODL: 14>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.UDIVL: 15>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.UMODL: 16>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.DUP: 20>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.DUP2: 21>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.SWP: 22>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.DROP: 23>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.INCL: 30>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.DECL: 31>: <class 'ducky.cpu.instructions.EncodingR'>, <MathCoprocessorOpcodes.ADDL: 32>: <class 'ducky.cpu.instructions.EncodingR'>, <DuckyOpcodes.SIS: 63>: <class 'ducky.cpu.instructions.EncodingI'>}
opcodes

alias of MathCoprocessorOpcodes

class ducky.cpu.coprocessor.math_copro.MathCoprocessorOpcodes[source]

Bases: enum.IntEnum

Math coprocessor’s instruction opcodes.

ADDL = <MathCoprocessorOpcodes.ADDL: 32>
DECL = <MathCoprocessorOpcodes.DECL: 31>
DIVL = <MathCoprocessorOpcodes.DIVL: 11>
DROP = <MathCoprocessorOpcodes.DROP: 23>
DUP = <MathCoprocessorOpcodes.DUP: 20>
DUP2 = <MathCoprocessorOpcodes.DUP2: 21>
INCL = <MathCoprocessorOpcodes.INCL: 30>
LOAD = <MathCoprocessorOpcodes.LOAD: 9>
LOADUW = <MathCoprocessorOpcodes.LOADUW: 5>
LOADW = <MathCoprocessorOpcodes.LOADW: 4>
MODL = <MathCoprocessorOpcodes.MODL: 12>
MULL = <MathCoprocessorOpcodes.MULL: 10>
POP = <MathCoprocessorOpcodes.POP: 6>
POPUW = <MathCoprocessorOpcodes.POPUW: 1>
POPW = <MathCoprocessorOpcodes.POPW: 0>
PUSH = <MathCoprocessorOpcodes.PUSH: 8>
PUSHW = <MathCoprocessorOpcodes.PUSHW: 2>
SAVE = <MathCoprocessorOpcodes.SAVE: 7>
SAVEW = <MathCoprocessorOpcodes.SAVEW: 3>
SIS = <MathCoprocessorOpcodes.SIS: 63>
SWP = <MathCoprocessorOpcodes.SWP: 22>
SYMDIVL = <MathCoprocessorOpcodes.SYMDIVL: 13>
SYMMODL = <MathCoprocessorOpcodes.SYMMODL: 14>
UDIVL = <MathCoprocessorOpcodes.UDIVL: 15>
UMODL = <MathCoprocessorOpcodes.UMODL: 16>
class ducky.cpu.coprocessor.math_copro.MathCoprocessorState[source]

Bases: ducky.snapshot.SnapshotNode

Snapshot node holding the state of math coprocessor.

class ducky.cpu.coprocessor.math_copro.POP(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

Pop the long from data stack, and make it new TOS.

static execute(core, inst)[source]
mnemonic = 'pop'
opcode = <MathCoprocessorOpcodes.POP: 6>
class ducky.cpu.coprocessor.math_copro.POPUW(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

Pop the int``from data stack, extend it to ``long, and make the result TOS.

static execute(core, inst)[source]
mnemonic = 'popuw'
opcode = <MathCoprocessorOpcodes.POPUW: 1>
class ducky.cpu.coprocessor.math_copro.POPW(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

Pop the int from data stack, extend it to long, and make the result TOS.

static execute(core, inst)[source]
mnemonic = 'popw'
opcode = <MathCoprocessorOpcodes.POPW: 0>
class ducky.cpu.coprocessor.math_copro.PUSH(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

Push the TOS on the data stack.

static execute(core, inst)[source]
mnemonic = 'push'
opcode = <MathCoprocessorOpcodes.PUSH: 8>
class ducky.cpu.coprocessor.math_copro.PUSHW(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

Downsize TOS to int, and push the result on the data stack.

static execute(core, inst)[source]
mnemonic = 'pushw'
opcode = <MathCoprocessorOpcodes.PUSHW: 2>
class ducky.cpu.coprocessor.math_copro.RegisterSet(core)[source]

Bases: ducky.interfaces.ISnapshotable

Math stack wrapping class. Provides basic push/pop access, and direct access to a top of the stack.

Parameters:core (ducky.cpu.CPUCore) – CPU core registers belong to.
load_state(state)[source]
pop()[source]

Pop the top value from stack and return it.

Raises:ducky.cpu.coprocessor.math_copro.EmptyMathStackError – if there are no values on the stack.
push(v)[source]

Push new value on top of the stack.

Raises:ducky.cpu.coprocessor.math_copro.FullMathStackError – if there is no space available on the stack.
save_state(parent)[source]
tos()[source]

Return the top of the stack, without removing it from a stack.

Raises:ducky.cpu.coprocessor.math_copro.EmptyMathStackError – if there are no values on the stack.
tos1()[source]

Return the item below the top of the stack, without removing it from a stack.

Raises:ducky.cpu.coprocessor.math_copro.EmptyMathStackError – if there are no values on the stack.
class ducky.cpu.coprocessor.math_copro.SAVE(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

Store TOS in two registers.

static assemble_operands(logger, buffer, inst, operands)[source]
static disassemble_operands(logger, inst)[source]
static execute(core, inst)[source]
mnemonic = 'save'
opcode = <MathCoprocessorOpcodes.SAVE: 7>
operands = 'r,r'
class ducky.cpu.coprocessor.math_copro.SAVEW(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

Downsize TOS to int, and store the result in register.

static assemble_operands(logger, buffer, inst, operands)[source]
static disassemble_operands(logger, inst)[source]
static execute(core, inst)[source]
mnemonic = 'savew'
opcode = <MathCoprocessorOpcodes.SAVEW: 3>
operands = 'r'
ducky.cpu.coprocessor.math_copro.STACK_DEPTH = 8

Number of available spots on the math stack.

class ducky.cpu.coprocessor.math_copro.SWP(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

static execute(core, inst)[source]
mnemonic = 'swp'
opcode = <MathCoprocessorOpcodes.SWP: 22>
class ducky.cpu.coprocessor.math_copro.SYMDIVL(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

The same operation like DIVL but provides symmetric results.

static execute(core, inst)[source]
mnemonic = 'symdivl'
opcode = <MathCoprocessorOpcodes.SYMDIVL: 13>
class ducky.cpu.coprocessor.math_copro.SYMMODL(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

static execute(core, inst)[source]
mnemonic = 'symmodl'
opcode = <MathCoprocessorOpcodes.SYMMODL: 14>
class ducky.cpu.coprocessor.math_copro.UDIVL(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

Divide the value below the top of the math stack by the topmost value.

static execute(core, inst)[source]
mnemonic = 'udivl'
opcode = <MathCoprocessorOpcodes.UDIVL: 15>
class ducky.cpu.coprocessor.math_copro.UMODL(instruction_set)[source]

Bases: ducky.cpu.coprocessor.math_copro.Descriptor_MATH

static execute(core, inst)[source]
mnemonic = 'umodl'
opcode = <MathCoprocessorOpcodes.UMODL: 16>