Polishing. Alcune implementazioni

This commit is contained in:
Giulio De Pasquale 2017-05-18 15:41:05 +02:00
parent 8eab267645
commit 020a5062a2
8 changed files with 259 additions and 99 deletions

View File

@ -59,7 +59,7 @@ class VMAssembler:
self.define_ops(key) self.define_ops(key)
def parse(self, instruction): def parse(self, instruction):
action = getattr(self, "op_{}".format(instruction.opcode.name)) action = getattr(self, "{}".format(instruction.opcode.method))
action(instruction) action(instruction)
def process_code_line(self, line): def process_code_line(self, line):
@ -125,36 +125,66 @@ class VMAssembler:
self.assembled_code += opcode.uint8() + imm.uint16() + reg.uint8() self.assembled_code += opcode.uint8() + imm.uint16() + reg.uint8()
return return
def imm(self, instruction): def byt2reg(self, instruction):
"""
Intel syntax -> REG, [BYTE]IMM
"""
opcode = instruction.opcode
reg = instruction.args[0]
imm = instruction.args[1]
if reg.name == "ip":
raise IPOverwrite(instruction)
if not imm.isimm():
raise ExpectedImmediate(imm)
if not reg.isreg():
raise ExpectedRegister(reg)
if not opcode.uint8() or not reg.uint8() or not imm.uint8():
raise InvalidValue(instruction)
self.assembled_code += opcode.uint8() + reg.uint8() + imm.uint8()
return return
def op_movi(self, instruction): def regonly(self, instruction):
self.imm2reg(instruction) """
Instruction with only an argument: a register
"""
opcode = instruction.opcode
reg = instruction.args[0]
if reg.name == "ip":
raise IPOverwrite(instruction)
if not reg.isreg():
raise ExpectedRegister(reg)
if not opcode.uint8() or not reg.uint8():
raise InvalidValue(instruction)
self.assembled_code += opcode.uint8() + reg.uint8()
return
def op_movr(self, instruction): def immonly(self, instruction):
self.reg2reg(instruction) """
Instruction with only an argument: an immediate
"""
opcode = instruction.opcode
imm = instruction.args[0]
if not imm.isimm():
raise ExpectedImmediate(imm)
if not opcode.uint8() or not imm.uint16():
raise InvalidValue(instruction)
self.assembled_code += opcode.uint8() + imm.uint16()
return
def op_load(self, instruction): def single(self, instruction):
self.imm2reg(instruction) """
Instruction with no arguments
def op_stor(self, instruction): """
self.reg2imm(instruction) opcode = instruction.opcode
self.assembled_code += opcode.uint8()
def op_addi(self, instruction): return
self.imm2reg(instruction)
def op_addr(self, instruction):
self.reg2reg(instruction)
def define_ops(self, key): def define_ops(self, key):
key_ba = bytearray(key, 'utf-8') key_ba = bytearray(key, 'utf-8')
olds = copy.deepcopy(ops) olds = copy.deepcopy(ops)
for b in key_ba: for b in key_ba:
for op_com in ops: for op_com in ops:
if b % 2:
op_com.set_value(rol(b ^ op_com.value, b % 8, 8)) op_com.set_value(rol(b ^ op_com.value, b % 8, 8))
else:
op_com.set_value(rol(b ^ op_com.value, (b + 1) % 8, 8))
for i in ops: for i in ops:
for j in ops: for j in ops:
j.set_value(rol(j.value, i.value % 8, 8)) j.set_value(rol(j.value, i.value % 8, 8))
@ -167,9 +197,10 @@ class VMComponent:
Represents a register, operation or an immediate the VM recognizes Represents a register, operation or an immediate the VM recognizes
""" """
def __init__(self, name, value): def __init__(self, name, value, method=None):
self.name = name.casefold() self.name = name.casefold()
self.value = value self.value = value
self.method = method
def __repr__(self): def __repr__(self):
return "{}".format(self.name) return "{}".format(self.name)
@ -206,7 +237,7 @@ class VMComponent:
return True return True
def isop(self): def isop(self):
if self.name not in [x.casefold() for x in op_names]: if self.name not in [x[0].casefold() for x in op_names]:
return False return False
return True return True
@ -240,38 +271,42 @@ class VMInstruction:
def __repr__(self): def __repr__(self):
return "{} {}".format(self.opcode.name, ", ".join([x.name for x in self.args])) return "{} {}".format(self.opcode.name, ", ".join([x.name for x in self.args]))
op_names = ["MOVI", op_names = [["MOVI", "imm2reg"],
"MOVR", ["MOVR", "reg2reg"],
"LOAD", ["LOAD", "imm2reg"],
"STOR", ["STOR", "reg2imm"],
"ADDI", ["ADDI", "imm2reg"],
"ADDR", ["ADDR", "reg2reg"],
"SUBI", ["SUBI", "imm2reg"],
"SUBR", ["SUBR", "reg2reg"],
"XORB", ["XORB", "byt2reg"],
"XORW", ["XORW", "imm2reg"],
"XORR", ["XORR", "reg2reg"],
"NOTR", ["NOTR", "regonly"],
"MULI", ["MULI", "imm2reg"],
"MULR", ["MULR", "reg2reg"],
"DIVI", ["DIVI", "imm2reg"],
"DIVR", ["DIVR", "reg2reg"],
"PUSH", ["PUSH", "regonly"],
"POOP", ["POOP", "regonly"],
"CMPI", ["CMPI", "imm2reg"],
"CMPR", ["CMPR", "reg2reg"],
"JUMP", ["JMPI", "immonly"],
"JMPA", ["JMPR", "regonly"],
"JMPB", ["JPAI", "immonly"],
"JMPE", ["JPAR", "regonly"],
"SHIT", ["JPBI", "immonly"],
"NOPE", ["JPBR", "regonly"],
"GRMN"] ["JPEI", "immonly"],
["JPER", "regonly"],
["SHIT", "single"],
["NOPE", "single"],
["GRMN", "single"]]
reg_names = ["R0", "R1", "R2", "R3", "S0", "S1", "S2", "S3", "IP", "BP", "SP"] reg_names = ["R0", "R1", "R2", "R3", "S0", "S1", "S2", "S3", "IP", "BP", "SP"]
section_names = ["DATA:", "CODE:", "STACK:"] section_names = ["DATA:", "CODE:", "STACK:"]
section_flags = {s.casefold(): i + 1 for i, s in enumerate(section_names)} section_flags = {s.casefold(): i + 1 for i, s in enumerate(section_names)}
ops = [VMComponent(s.casefold(), i) for i, s in enumerate(op_names)] ops = [VMComponent(le[0], i, le[1]) for i, le in enumerate(op_names)]
regs = [VMComponent(s.casefold(), i) for i, s in enumerate(reg_names)] regs = [VMComponent(s.casefold(), i) for i, s in enumerate(reg_names)]

View File

@ -22,10 +22,14 @@ enum OPS_STARTING_VALUES {
POOP, POOP,
CMPI, CMPI,
CMPR, CMPR,
JUMP, JMPI,
JMPA, JMPR,
JMPB, JPAI,
JMPE, JPAR,
JPBI,
JPBR,
JPEI,
JPER,
SHIT, SHIT,
NOPE, NOPE,
GRMN, GRMN,
@ -41,7 +45,8 @@ INSTRUCTION SIZE TYPES
#define IMM2REG 4 #define IMM2REG 4
#define REG2IMM 4 #define REG2IMM 4
#define BYT2REG 3 #define BYT2REG 3
#define UNARY 2 #define REGONLY 2
#define IMMONLY 3
#define SINGLE 1 #define SINGLE 1
/* /*
@ -58,19 +63,23 @@ INSTRUCTION SIZES
#define XORB_SIZE BYT2REG #define XORB_SIZE BYT2REG
#define XORW_SIZE IMM2REG #define XORW_SIZE IMM2REG
#define XORR_SIZE REG2REG #define XORR_SIZE REG2REG
#define NOTR_SIZE UNARY #define NOTR_SIZE REGONLY
#define MULI_SIZE IMM2REG #define MULI_SIZE IMM2REG
#define MULR_SIZE REG2REG #define MULR_SIZE REG2REG
#define DIVI_SIZE IMM2REG #define DIVI_SIZE IMM2REG
#define DIVR_SIZE REG2REG #define DIVR_SIZE REG2REG
#define PUSH_SIZE UNARY #define PUSH_SIZE REGONLY
#define POOP_SIZE UNARY #define POOP_SIZE REGONLY
#define CMPI_SIZE IMM2REG #define CMPI_SIZE IMM2REG
#define CMPR_SIZE REG2REG #define CMPR_SIZE REG2REG
#define JUMP_SIZE UNARY #define JMPI_SIZE IMMONLY
#define JMPA_SIZE UNARY #define JMPR_SIZE REGONLY
#define JMPB_SIZE UNARY #define JPAI_SIZE IMMONLY
#define JMPE_SIZE UNARY #define JPAR_SIZE REGONLY
#define JPBI_SIZE IMMONLY
#define JPBR_SIZE REGONLY
#define JPEI_SIZE IMMONLY
#define JPER_SIZE REGONLY
#define SHIT_SIZE SINGLE #define SHIT_SIZE SINGLE
#define NOPE_SIZE SINGLE #define NOPE_SIZE SINGLE
#define GRMN_SIZE SINGLE #define GRMN_SIZE SINGLE

View File

@ -14,11 +14,7 @@ void VM::defineOpcodes(uint8_t *key) {
keysize = strlen((char *)key); keysize = strlen((char *)key);
for (i = 0; i < keysize; i++) { for (i = 0; i < keysize; i++) {
for (j = 0; j < NUM_OPS; j++) { for (j = 0; j < NUM_OPS; j++) {
if (key[i] % 2) {
OPS[j] = rol(key[i] ^ OPS[j], key[i] % 8, 8); OPS[j] = rol(key[i] ^ OPS[j], key[i] % 8, 8);
} else {
OPS[j] = rol(key[i] ^ OPS[j], (key[i] + 1) % 8, 8);
}
} }
} }
for (i = 0; i < NUM_OPS; i++) { for (i = 0; i < NUM_OPS; i++) {
@ -185,7 +181,7 @@ bool VM::execMOVI(void) {
bool VM::execMOVR(void) { bool VM::execMOVR(void) {
/* /*
MOVR R1, R0 | R1 = R0 MOVR R1, R0 -> R1 = R0
--------------------- ---------------------
R1, R0 = 0x10 <- DST / SRC are nibbles! R1, R0 = 0x10 <- DST / SRC are nibbles!
*/ */
@ -203,7 +199,7 @@ bool VM::execMOVR(void) {
bool VM::execLOAD(void) { bool VM::execLOAD(void) {
/* /*
LOAD R0, 0x1000 | R0 = data[0x1000] LOAD R0, 0x1000 -> R0 = data[0x1000]
*/ */
uint8_t dst; uint8_t dst;
uint16_t src; uint16_t src;
@ -216,7 +212,7 @@ bool VM::execLOAD(void) {
bool VM::execSTOR(void) { bool VM::execSTOR(void) {
/* /*
STOR 0x1000, R0 | data[0x1000] = R0 STOR 0x1000, R0 -> data[0x1000] = R0
*/ */
uint16_t dst; uint16_t dst;
uint8_t src; uint8_t src;
@ -229,7 +225,7 @@ bool VM::execSTOR(void) {
bool VM::execADDI(void) { bool VM::execADDI(void) {
/* /*
ADDI R0, 0x2 | R0 += 2 ADDI R0, 0x2 -> R0 += 2
*/ */
uint8_t dst; uint8_t dst;
uint16_t src; uint16_t src;
@ -242,6 +238,9 @@ bool VM::execADDI(void) {
} }
bool VM::execADDR(void) { bool VM::execADDR(void) {
/*
ADDR R0, R1 -> R0 += R1
*/
uint8_t dst; uint8_t dst;
uint8_t src; uint8_t src;
@ -252,24 +251,124 @@ bool VM::execADDR(void) {
return true; return true;
} }
bool VM::execSUBI(void) { return true; } bool VM::execSUBI(void) {
bool VM::execSUBR(void) { return true; } /*
bool VM::execXORB(void) { return true; } SUBI R0, 0x2 -> R0 -= 2
bool VM::execXORW(void) { return true; } */
bool VM::execXORR(void) { return true; } uint8_t dst;
bool VM::execNOTR(void) { return true; } uint16_t src;
bool VM::execMULI(void) { return true; }
dst = as.code[regs[IP] + 1];
src = *((uint16_t *)&as.code[regs[IP] + 2]);
DBG_INFO(("SUBI %s, 0x%x\n", getRegName(dst), src));
regs[dst] -= src;
return true;
}
bool VM::execSUBR(void) {
/*
SUBR R0, R1 -> R0 -= R1
*/
uint8_t dst;
uint8_t src;
dst = as.code[regs[IP] + 1] >> 4;
src = as.code[regs[IP] + 1] & 0b00001111;
DBG_INFO(("SUBR %s, 0x%x\n", getRegName(dst), src));
regs[dst] -= regs[src];
return true;
}
bool VM::execXORB(void) {
/*
XORB R0, 0x2 -> R0 ^= 0x02 or R0 ^= [BYTE] 0x02 (low byte)
*/
uint8_t dst;
uint8_t src;
dst = as.code[regs[IP] + 1];
src = as.code[regs[IP] + 2];
DBG_INFO(("XORB %s, 0x%x\n", getRegName(dst), src));
regs[dst] ^= src;
return true;
}
bool VM::execXORW(void) {
/*
XORW R0, 0x2 -> R0 ^= 0x0002 or R0, ^= [WORD] 0x2
*/
uint8_t dst;
uint16_t src;
dst = as.code[regs[IP] + 1];
src = *((uint16_t *)&as.code[regs[IP] + 2]);
DBG_INFO(("XORW %s, 0x%x\n", getRegName(dst), src));
regs[dst] ^= src;
return true;
}
bool VM::execXORR(void) {
/*
XORR R0, R1 -> R0 ^= R1
*/
uint8_t dst;
uint8_t src;
dst = as.code[regs[IP] + 1] >> 4;
src = as.code[regs[IP] + 1] & 0b00001111;
DBG_INFO(("XORR %s, 0x%x\n", getRegName(dst), src));
regs[dst] ^= regs[src];
return true;
}
bool VM::execNOTR(void) {
/*
NOTR R0, R1 -> R0 = ~R1
*/
uint8_t dst;
uint8_t src;
dst = as.code[regs[IP] + 1] >> 4;
src = as.code[regs[IP] + 1] & 0b00001111;
DBG_INFO(("NOTR %s, 0x%x\n", getRegName(dst), src));
regs[dst] = ~regs[src];
return true;
}
bool VM::execMULI(void) {
/*
MULI R0, 0x2 | R0 *= 2
*/
uint8_t dst;
uint16_t src;
dst = as.code[regs[IP] + 1];
src = *((uint16_t *)&as.code[regs[IP] + 2]);
DBG_INFO(("SUBI %s, 0x%x\n", getRegName(dst), src));
regs[dst] *= src;
return true;
}
bool VM::execMULR(void) { return true; } bool VM::execMULR(void) { return true; }
bool VM::execDIVI(void) { return true; } bool VM::execDIVI(void) {
/*
DIVI R0, 0x2 | R0 /= 2
*/
uint8_t dst;
uint16_t src;
dst = as.code[regs[IP] + 1];
src = *((uint16_t *)&as.code[regs[IP] + 2]);
DBG_INFO(("DIVI %s, 0x%x\n", getRegName(dst), src));
regs[dst] /= src;
return true;
}
bool VM::execDIVR(void) { return true; } bool VM::execDIVR(void) { return true; }
bool VM::execPUSH(void) { return true; } bool VM::execPUSH(void) { return true; }
bool VM::execPOOP(void) { return true; } bool VM::execPOOP(void) { return true; }
bool VM::execCMPI(void) { return true; } bool VM::execCMPI(void) { return true; }
bool VM::execCMPR(void) { return true; } bool VM::execCMPR(void) { return true; }
bool VM::execJUMP(void) { return true; } bool VM::execJMPI(void) { return true; }
bool VM::execJMPA(void) { return true; } bool VM::execJMPR(void) { return true; }
bool VM::execJMPB(void) { return true; } bool VM::execJPAI(void) { return true; }
bool VM::execJMPE(void) { return true; } bool VM::execJPAR(void) { return true; }
bool VM::execJPBI(void) { return true; }
bool VM::execJPBR(void) { return true; }
bool VM::execJPEI(void) { return true; }
bool VM::execJPER(void) { return true; }
bool VM::execGRMN(void) { return true; } bool VM::execGRMN(void) { return true; }
void VM::run(void) { void VM::run(void) {
uint8_t opcode; uint8_t opcode;
@ -333,22 +432,35 @@ void VM::run(void) {
} else if (opcode == OPS[CMPR]) { } else if (opcode == OPS[CMPR]) {
execCMPR(); execCMPR();
regs[IP] += CMPR_SIZE; regs[IP] += CMPR_SIZE;
} else if (opcode == OPS[JUMP]) { } else if (opcode == OPS[JMPI]) {
execJUMP(); execJMPI();
regs[IP] += JUMP_SIZE; regs[IP] += JMPI_SIZE;
} else if (opcode == OPS[JMPA]) { } else if (opcode == OPS[JMPR]) {
execJMPA(); execJMPR();
regs[IP] += JMPA_SIZE; regs[IP] += JMPR_SIZE;
} else if (opcode == OPS[JMPB]) { }else if (opcode == OPS[JPAI]) {
execJMPB(); execJPAI();
regs[IP] += JMPB_SIZE; regs[IP] += JPAI_SIZE;
} else if (opcode == OPS[JMPE]) { }else if (opcode == OPS[JPAR]) {
execJMPE(); execJPAR();
regs[IP] += JMPE_SIZE; regs[IP] += JPAR_SIZE;
}else if (opcode == OPS[JPBI]) {
execJPBI();
regs[IP] += JPBI_SIZE;
}else if (opcode == OPS[JPBR]) {
execJPBR();
regs[IP] += JPBR_SIZE;
}else if (opcode == OPS[JPEI]) {
execJPEI();
regs[IP] += JPEI_SIZE;
}else if (opcode == OPS[JPER]) {
execJPER();
regs[IP] += JPER_SIZE;
} else if (opcode == OPS[GRMN]) { } else if (opcode == OPS[GRMN]) {
execGRMN(); execGRMN();
regs[IP] += GRMN_SIZE; regs[IP] += GRMN_SIZE;
} else if (opcode == OPS[SHIT]) { } else if (opcode == OPS[SHIT]) {
DBG_INFO(("Halting.\n"));
finished = true; finished = true;
} else if (opcode == OPS[NOPE]) { } else if (opcode == OPS[NOPE]) {
regs[IP] += NOPE_SIZE; regs[IP] += NOPE_SIZE;

View File

@ -51,10 +51,14 @@ private:
bool execPOOP(void); bool execPOOP(void);
bool execCMPI(void); bool execCMPI(void);
bool execCMPR(void); bool execCMPR(void);
bool execJUMP(void); bool execJMPI(void);
bool execJMPA(void); bool execJMPR(void);
bool execJMPB(void); bool execJPAI(void);
bool execJMPE(void); bool execJPAR(void);
bool execJPBI(void);
bool execJPBR(void);
bool execJPEI(void);
bool execJPER(void);
bool execGRMN(void); bool execGRMN(void);
public: public: