diff --git a/sources/zweic/RISC.java b/sources/zweic/RISC.java new file mode 100644 index 0000000..d1b1758 --- /dev/null +++ b/sources/zweic/RISC.java @@ -0,0 +1,633 @@ +package zweic; + +public interface RISC { + + //######################################################################## + // Word size + + /** The word size */ + public static final int WORD_SIZE = 4; + + //######################################################################## + // Opcodes - instructions with registers + + /** + *

Opcode: integer addition.

+ * ADD a b c
+ * R.a = R.b + R.c + */ + public static final int ADD = 0; + + /** + *

Opcode: integer subtraction.

+ * SUB a b c
+ * R.a = R.b - R.c + */ + public static final int SUB = 1; + + /** + *

Opcode: integer multiplication.

+ * MUL a b c
+ * R.a = R.b * R.c + */ + public static final int MUL = 2; + + /** + *

Opcode: integer division.

+ * DIV a b c
+ * R.a = R.b / R.c + */ + public static final int DIV = 3; + + /** + *

Opcode: integer modulo.

+ * MOD a b c
+ * R.a = R.b % R.c + */ + public static final int MOD = 4; + + /** + *

Opcode: integer comparison.

+ * CMP a b c
+ * R.a = <a value with the same sign as (R.b - R.c) + * but with a possibly different magnitude> + */ + public static final int CMP = 5; + + /** + *

Opcode: logical or.

+ * OR a b c
+ * R.a = R.b | R.c + */ + public static final int OR = 8; + + /** + *

Opcode: logical and.

+ * AND a b c
+ * R.a = R.b & R.c + */ + public static final int AND = 9; + + /** + *

Opcode: logical bic.

+ * BIC a b c
+ * R.a = R.b & ~R.c + */ + public static final int BIC = 10; + + /** + *

Opcode: logical xor.

+ * XOR a b c
+ * R.a = R.b ^ R.c + */ + public static final int XOR = 11; + + /** + *

Opcode: logical shift.

+ * LSH a b c
+ * R.a = (R.c > 0) ? + * (R.b << R.c) : (R.b >>> -R.c) + */ + public static final int LSH = 12; + + /** + *

Opcode: arithmetic shift.

+ * ASH a b c
+ * R.a = (R.c > 0) ? + * (R.b << R.c) : (R.b >> -R.c) + */ + public static final int ASH = 13; + + /** + *

Opcode: bound check.

+ * CHK a c
+ * raise an error if not (0 <= R.a < R.c) + */ + public static final int CHK = 14; + + //######################################################################## + // Opcodes - instructions with register and signed immediate + + /** + *

Opcode: integer addition with signed immediate.

+ * ADDI a b ic
+ * R.a = R.b + ic + */ + public static final int ADDI = 16; + + /** + *

Opcode: integer subtraction with signed immediate.

+ * SUBI a b ic
+ * R.a = R.b - ic + */ + public static final int SUBI = 17; + + /** + *

Opcode: integer multiplication with signed immediate.

+ * MULI a b ic
+ * R.a = R.b * ic + */ + public static final int MULI = 18; + + /** + *

Opcode: integer division with signed immediate.

+ * DIVI a b ic
+ * R.a = R.b / ic + */ + public static final int DIVI = 19; + + /** + *

Opcode: integer modulo with signed immediate.

+ * MODI a b ic
+ * R.a = R.b % ic + */ + public static final int MODI = 20; + + /** + *

Opcode: integer comparison with signed immediate.

+ * CMPI a b ic
+ * R.a = <a value with the same sign as (R.b - ic) + * but with a possibly different magnitude> + */ + public static final int CMPI = 21; + + /** + *

Opcode: logical or with signed immediate.

+ * ORI a b ic
+ * R.a = R.b | ic + */ + public static final int ORI = 24; + + /** + *

Opcode: logical and with signed immediate.

+ * ANDI a b ic
+ * R.a = R.b & ic + */ + public static final int ANDI = 25; + + /** + *

Opcode: logical bic with signed immediate.

+ * BICI a b ic
+ * R.a = R.b & ~ic + */ + public static final int BICI = 26; + + /** + *

Opcode: logical xor with signed immediate.

+ * XORI a b ic
+ * R.a = R.b ^ ic + */ + public static final int XORI = 27; + + /** + *

Opcode: logical shift with signed immediate.

+ * LSHI a b ic
+ * R.a = (ic > 0) ? + * (R.b << ic) : (R.b >>> -ic) + */ + public static final int LSHI = 28; + + /** + *

Opcode: arithmetic shift with signed immediate.

+ * ASHI a b ic
+ * R.a = (ic > 0) ? + * (R.b << ic) : (R.b >> -ic) + */ + public static final int ASHI = 29; + + /** + *

Opcode: bound check with signed immediate.

+ * CHKI a ic
+ * raise an error if not (0 <= R.a < ic) + */ + public static final int CHKI = 30; + + //######################################################################## + // Opcodes - instructions with register and unsigned immediate + + /** + *

Opcode: integer addition with unsigned immediate.

+ * ADDIU a b uc
+ * R.a = R.b + uc + */ + public static final int ADDIU = 54; + + /** + *

Opcode: integer subtraction with unsigned immediate.

+ * SUBIU a b uc
+ * R.a = R.b - uc + */ + public static final int SUBIU = 55; + + /** + *

Opcode: integer multiplication with unsigned immediate.

+ * MULIU a b uc
+ * R.a = R.b * uc + */ + public static final int MULIU = 56; + + /** + *

Opcode: integer division with unsigned immediate.

+ * DIVIU a b uc
+ * R.a = R.b / uc + */ + public static final int DIVIU = 57; + + /** + *

Opcode: integer modulo with unsigned immediate.

+ * MODIU a b uc
+ * R.a = R.b % uc + */ + public static final int MODIU = 58; + + /** + *

Opcode: integer comparison with unsigned immediate.

+ * CMPIU a b uc
+ * R.a = <a value with the same sign as (R.b - uc) + * but with a possibly different magnitude> + */ + public static final int CMPIU = 59; + + /** + *

Opcode: logical or with unsigned immediate.

+ * ORIU a b uc
+ * R.a = R.b | uc + */ + public static final int ORIU = 60; + + /** + *

Opcode: logical and with unsigned immediate.

+ * ANDIU a b uc
+ * R.a = R.b & uc + */ + public static final int ANDIU = 61; + + /** + *

Opcode: logical bic with unsigned immediate.

+ * BICIU a b uc
+ * R.a = R.b & ~uc + */ + public static final int BICIU = 62; + + /** + *

Opcode: logical xor with unsigned immediate.

+ * XORIU a b uc
+ * R.a = R.b ^ uc + */ + public static final int XORIU = 63; + + /** + *

Opcode: bound check with unsigned immediate.

+ * CHKIU a uc
+ * raise an error if not (0 <= R.a < uc) + */ + public static final int CHKIU = 39; + + //######################################################################## + // Opcodes - load/store instructions + + /** + *

Opcode: load word from memory. The address R.b + * must be aligned on a word boundary.

+ * + * LDW a b ic
+ * R.a = <word at address R.b + ic> + */ + public static final int LDW = 32; + + /** + *

Opcode: load byte from memory.

+ * + * LDB a b ic
+ * R.a = <byte at address R.b + ic> + */ + public static final int LDB = 33; + + /** + *

Opcode: pop word from stack. The address R.b must + * be aligned on a word boundary.

+ * + * POP a b ic
+ * R.a = <word at address R.b>
+ * R.b = R.b + ic + */ + public static final int POP = 34; + + /** + *

Opcode: store word into memory. The address R.b + * must be aligned on a word boundary.

+ * + * STW a b ic
+ * <word at address R.b + ic> = R.a + */ + public static final int STW = 36; + + /** + *

Opcode: store byte into memory.

+ * + * STB a b ic
+ * <byte at address R.b + ic> = (byte)R.a + */ + public static final int STB = 37; + + /** + *

Opcode: push word on stack. The address R.b must + * be aligned on a word boundary.

+ * + * PSH a b ic
+ * R.b = R.b - ic
+ * <word at address R.b> = R.a + */ + public static final int PSH = 38; + + //######################################################################## + // Opcodes - control instructions + + /** + *

Opcode: branch if equal.

+ * BEQ a oc
+ * branch to (PC + 4*oc) if (R.a == 0) + */ + public static final int BEQ = 40; + + /** + *

Opcode: branch if not equal.

+ * BNE a oc
+ * branch to (PC + 4*oc) if (R.a != 0) + */ + public static final int BNE = 41; + + /** + *

Opcode: branch if less than.

+ * BLT a oc
+ * branch to (PC + 4*oc) if (R.a < 0) + */ + public static final int BLT = 42; + + /** + *

Opcode: branch if greater or equal.

+ * BGE a oc
+ * branch to (PC + 4*oc) if (R.a >= 0) + */ + public static final int BGE = 43; + + /** + *

Opcode: branch if equal less or equal.

+ * BLE a oc
+ * branch to (PC + 4*oc) if (R.a <= 0) + */ + public static final int BLE = 44; + + /** + *

Opcode: branch if greater than.

+ * BGT a oc
+ * branch to (PC + 4*oc) if (R.a > 0) + */ + public static final int BGT = 45; + + /** + *

Opcode: branch to subroutine.

+ * BSR oc
+ * R.31 = PC + 4
+ * branch to (PC + 4*oc) + */ + public static final int BSR = 46; + + /** + *

Opcode: jump to subroutine.

+ * JSR lc
+ * R.31 = PC + 4
+ * branch to (4*lc) + */ + public static final int JSR = 48; + + /** + *

Opcode: jump to return address.

+ * RET c
+ * jump to R.c + */ + public static final int RET = 49; + + //######################################################################## + // Opcodes - miscellaneous instructions + + /** + *

Opcode: stop execution and return to debugger.

+ * BREAK
+ * stop execution and return to debugger + */ + public static final int BREAK = 6; + + /** + *

Opcode: invoke a system function.

+ * SYSCALL a b uc
+ * invoke system function uc with registers + * R.a and R.b + */ + public static final int SYSCALL = 7; + + //######################################################################## + // System calls - IO read + + /** + *

System call: read one character.

+ * SYSCALL a 0 SYS_IO_RD_CHR
+ * R.a = <Unicode of read character or -1 if EOF> + */ + public static final int SYS_IO_RD_CHR = 1; + + /** + *

System call: read an integer.

+ * SYSCALL a 0 SYS_IO_RD_INT
+ * R.a = <value of read integer> + */ + public static final int SYS_IO_RD_INT = 2; + + //######################################################################## + // System calls - IO write + + /** + *

System call: write one character.

+ * SYSCALL a 0 SYS_IO_WR_CHR
+ * <write character with Unicode R.a> + */ + public static final int SYS_IO_WR_CHR = 6; + + /** + *

System call: write an integer.

+ * SYSCALL a b SYS_IO_WR_INT
+ * <write signed value R.a in decimal format and + * space padded to width R.b> + */ + public static final int SYS_IO_WR_INT = 7; + + //######################################################################## + // System calls - garbage collector + + /** + *

System call: initialize the garbage collector.

+ * + *

The garbage collector is initialized with an empty heap that + * starts at address R.a and with a maximum size of + * sz = R.b & 0x07FFFFFF words. If sz is + * zero then the heap extends to the end of the memory.

+ * + *

The value sp = R.b >>> 27 determines + * whether there is a stack and which register is the stack + * pointer: if sp is non-zero, the garbage collector + * assumes that there is a stack and that R.sp is the + * stack pointer register. It is assumed that the stack starts at + * the end of the memory and grows downwards.

+ * + *

During a garbage collection, the garbage collector frees all + * the memory blocks which are not referenced by any live + * pointer. A live pointer (resp. value) is either a root pointer + * (resp. value) or a pointer (resp. value) contained in a block + * referenced by a live pointer. Note that as there is no way to + * distinguish between pointers and non-pointer values, all values + * are regarded as pointers. A root value is one that is contained + * in a register, in the memory below the heap or in the stack. If + * there is no stack, all the values contained in the memory above + * the heap are also root values.

+ * + * SYSCALL a b SYS_GC_INIT
+ * <initialize the garbage collector> + */ + public static final int SYS_GC_INIT = 11; + + /** + *

System call: allocate a memory block from the heap.

+ * + *

Allocates a memory block of, at least, R.b + * bytes from the heap and returns its address in + * R.a. The allocated memory is zero-initialized and + * its address is guaranteed to be aligned on a word boundary. If + * there is not enough free memory, a garbage collection is + * triggered and if this doesn't free enough memory, an error is + * raised and the execution stopped.

+ * + * SYSCALL a b SYS_GC_ALLOC
+ * R.a = <address of the newly allocated and + * zero-initialized memory block of R.b bytes> + */ + public static final int SYS_GC_ALLOC = 12; + + //######################################################################## + // System calls - miscellaneous + + /** + *

System call: get memory size.

+ * SYSCALL a 0 SYS_GET_TOTAL_MEM_SIZE
+ * R.a = <memory size in bytes> + */ + public static final int SYS_GET_TOTAL_MEM_SIZE = 13; + + /** + *

System call: flush the output stream.

+ * SYSCALL 0 0 SYS_IO_FLUSH
+ * <flush the output stream> + */ + public static final int SYS_IO_FLUSH = 15; + + /** + *

System call: terminate the emulation.

+ * SYSCALL a 0 SYS_EXIT
+ * <terminates the emulation with status code R.a> + */ + public static final int SYS_EXIT = 19; + + //######################################################################## + // Registers + + /** Register: zero */ + public static final int ZERO = 0; + + /** Register: function result */ + public static final int RES = 1; + + /** Register: stack pointer */ + public static final int SP = 30; + + /** Register: return address */ + public static final int LNK = 31; + + //######################################################################## + // Data structures + + /** String representation of instructions */ + public static final String[] mnemonics = Helper.getMnemonics(); + + //######################################################################## + // class Helper + + public class Helper { + + public static String[] getMnemonics() { + String[] mnemonics = new String[64]; + + mnemonics[ADD ] = "add"; + mnemonics[SUB ] = "sub"; + mnemonics[MUL ] = "mul"; + mnemonics[DIV ] = "div"; + mnemonics[MOD ] = "mod"; + mnemonics[CMP ] = "cmp"; + mnemonics[OR ] = "or"; + mnemonics[AND ] = "and"; + mnemonics[BIC ] = "bic"; + mnemonics[XOR ] = "xor"; + mnemonics[LSH ] = "lsh"; + mnemonics[ASH ] = "ash"; + mnemonics[CHK ] = "chk"; + + mnemonics[ADDI ] = "addi"; + mnemonics[SUBI ] = "subi"; + mnemonics[MULI ] = "muli"; + mnemonics[DIVI ] = "divi"; + mnemonics[MODI ] = "modi"; + mnemonics[CMPI ] = "cmpi"; + mnemonics[ORI ] = "ori"; + mnemonics[ANDI ] = "andi"; + mnemonics[BICI ] = "bici"; + mnemonics[XORI ] = "xori"; + mnemonics[LSHI ] = "lshi"; + mnemonics[ASHI ] = "ashi"; + mnemonics[CHKI ] = "chki"; + + mnemonics[ADDIU ] = "addiu"; + mnemonics[SUBIU ] = "subiu"; + mnemonics[MULIU ] = "muliu"; + mnemonics[DIVIU ] = "diviu"; + mnemonics[MODIU ] = "modiu"; + mnemonics[CMPIU ] = "cmpiu"; + mnemonics[ORIU ] = "oriu"; + mnemonics[ANDIU ] = "andiu"; + mnemonics[BICIU ] = "biciu"; + mnemonics[XORIU ] = "xoriu"; + mnemonics[CHKIU ] = "chkiu"; + + mnemonics[LDW ] = "ldw"; + mnemonics[LDB ] = "ldb"; + mnemonics[POP ] = "pop"; + mnemonics[STW ] = "stw"; + mnemonics[STB ] = "stb"; + mnemonics[PSH ] = "psh"; + + mnemonics[BEQ ] = "beq"; + mnemonics[BNE ] = "bne"; + mnemonics[BLT ] = "blt"; + mnemonics[BGE ] = "bge"; + mnemonics[BLE ] = "ble"; + mnemonics[BGT ] = "bgt"; + mnemonics[BSR ] = "bsr"; + mnemonics[JSR ] = "jsr"; + mnemonics[RET ] = "ret"; + + mnemonics[BREAK ] = "break"; + mnemonics[SYSCALL] = "syscall"; + + return mnemonics; + } + } + + //######################################################################## +}