package nebula.vm;
/***
* Excerpted from "Language Implementation Patterns", published by The Pragmatic
* Bookshelf. Copyrights apply to this code. It may not be used to create
* training material, courses, books, articles, and the like. Contact us if you
* are in doubt. We make no guarantees that this code is fit for any purpose.
* Visit http://www.pragmaticprogrammer.com/titles/tpdsl for more book
* information.
***/
public class BytecodeDefinition {
// operand types
public static final int REG = AssemblerParser.REG;
public static final int FUNC = AssemblerParser.FUNC;
public static final int INT = AssemblerParser.INT;
public static final int POOL = 1000; // unique imaginary token
public static final int OFFSET_X_ = 9;
public static final int OFFSET_OP = OFFSET_X_ * 3;
public static final int OFFSET_A_ = OFFSET_X_ * 2;
public static final int OFFSET_AX = OFFSET_X_ * 1;
public static final int OFFSET_B_ = OFFSET_X_ * 1;
public static final int OFFSET_BX = OFFSET_X_ * 0;
public static final int OFFSET_C_ = OFFSET_X_ * 0;
public static byte TRUE = 1;
public static byte FALSE = 0;
public static final int MASK_X_ = 0x000001FF;
public static final int MASK_XX = (MASK_X_ << OFFSET_X_) | MASK_X_;
public static class Instruction {
String name; // E.g., "iadd", "call"
int[] type = new int[3];
int n = 0;
public Instruction(String name) {
this(name, 0, 0, 0);
n = 0;
}
public Instruction(String name, int a) {
this(name, a, 0, 0);
n = 1;
}
public Instruction(String name, int a, int b) {
this(name, a, b, 0);
n = 2;
}
public Instruction(String name, int a, int b, int c) {
this.name = name;
type[0] = a;
type[1] = b;
type[2] = c;
n = 3;
}
}
// INSTRUCTION BYTECODES (byte is signed; use a short to keep 0..255)
public static final short INSTR_IADD = 1; // int add
public static final short INSTR_ISUB = 2;
public static final short INSTR_IMUL = 3;
public static final short INSTR_ILT = 4; // int less than
public static final short INSTR_IEQ = 5; // int equal
public static final short INSTR_FADD = 6; // float add
public static final short INSTR_FSUB = 7;
public static final short INSTR_FMUL = 8;
public static final short INSTR_FLT = 9; // float less than
public static final short INSTR_FEQ = 10;
public static final short INSTR_ITOF = 11; // int to float
public static final short INSTR_CALL = 12;
public static final short INSTR_RET = 13; // return with/without value
public static final short INSTR_BR = 14; // branch
public static final short INSTR_BRT = 15; // branch if true
public static final short INSTR_BRF = 16; // branch if false
public static final short INSTR_CCONST = 17; // load constant char
public static final short INSTR_ICONST = 18; // load constant integer
public static final short INSTR_FCONST = 19; // load constant float
public static final short INSTR_SCONST = 20; // load constant string
public static final short INSTR_GLOAD = 21; // load from global memory
public static final short INSTR_GSTORE = 22; // store in global memory
public static final short INSTR_FLOAD = 23; // field load
public static final short INSTR_FSTORE = 24; // store field
public static final short INSTR_MOVE = 25; // reg to reg move
public static final short INSTR_PRINT = 26; // print reg
public static final short INSTR_STRUCT = 27; // create new struct
public static final short INSTR_FORPREP = 28; // load null into register
public static final short INSTR_FORLOOP = 29; // load null into register
public static final short INSTR_NULL = 30; // load null into register
public static final short INSTR_HALT = 31;
//@formatter:off
public static Instruction[] instructions = new Instruction[] {
null, // <INVALID>
new Instruction("iadd", REG, REG, REG), // index is the opcode
new Instruction("isub", REG, REG, REG),
new Instruction("imul", REG, REG, REG),
new Instruction("ilt", REG, REG, REG),
new Instruction("ieq", REG, REG, REG),
new Instruction("fadd", REG, REG, REG),
new Instruction("fsub", REG, REG, REG),
new Instruction("fmul", REG, REG, REG),
new Instruction("flt", REG, REG, REG),
new Instruction("feq", REG, REG, REG),
new Instruction("itof", REG, REG),
new Instruction("call", REG,FUNC, REG),
new Instruction("ret",REG,INT),
new Instruction("br", REG, INT),
new Instruction("brt", REG, INT),
new Instruction("brf", REG, INT),
new Instruction("cconst", REG, INT),
new Instruction("iconst", REG, INT),
new Instruction("fconst", REG, POOL),
new Instruction("sconst", REG, POOL),
new Instruction("gload", REG, INT),
new Instruction("gstore", REG, INT),
new Instruction("fload", REG, REG, POOL),
new Instruction("fstore", REG, POOL, REG),
new Instruction("move", REG, REG),
new Instruction("print", REG),
new Instruction("struct", REG, INT),
new Instruction("forprep", REG, INT), // goto done
new Instruction("forloop", REG, INT), // goto for
new Instruction("null", REG),
new Instruction("halt")
};
//@formatter:on
}