SHLI, SHLR, SHRI, SHRL, DIVR
This commit is contained in:
		
							parent
							
								
									3c453485b1
								
							
						
					
					
						commit
						0dfd9bdb57
					
				@ -49,6 +49,7 @@ class InvalidValue(AssemblerException):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VMAssembler:
 | 
					class VMAssembler:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, key, data):
 | 
					    def __init__(self, key, data):
 | 
				
			||||||
        self.data = data
 | 
					        self.data = data
 | 
				
			||||||
        self.assembled_code = bytearray()
 | 
					        self.assembled_code = bytearray()
 | 
				
			||||||
@ -80,12 +81,14 @@ class VMAssembler:
 | 
				
			|||||||
        # putting main in first position in order to assemble it first
 | 
					        # putting main in first position in order to assemble it first
 | 
				
			||||||
        for i, f in enumerate(self.functions):
 | 
					        for i, f in enumerate(self.functions):
 | 
				
			||||||
            if f.name == "main" and i is not 0:
 | 
					            if f.name == "main" and i is not 0:
 | 
				
			||||||
                 self.functions[0], self.functions[i] = self.functions[i], self.functions[0]
 | 
					                self.functions[0], self.functions[
 | 
				
			||||||
 | 
					                    i] = self.functions[i], self.functions[0]
 | 
				
			||||||
                break
 | 
					                break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # calculating functions offsets
 | 
					        # calculating functions offsets
 | 
				
			||||||
        for i in range(1, len(self.functions)):
 | 
					        for i in range(1, len(self.functions)):
 | 
				
			||||||
            prev_fun_tot_size = self.functions[i-1].size + self.functions[i-1].offset
 | 
					            prev_fun_tot_size = self.functions[
 | 
				
			||||||
 | 
					                i - 1].size + self.functions[i - 1].offset
 | 
				
			||||||
            cur_fun_size = self.functions[i].size
 | 
					            cur_fun_size = self.functions[i].size
 | 
				
			||||||
            self.functions[i].set_offset(prev_fun_tot_size)
 | 
					            self.functions[i].set_offset(prev_fun_tot_size)
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
@ -209,7 +212,8 @@ class VMAssembler:
 | 
				
			|||||||
            # the symbal has not been resolved
 | 
					            # the symbal has not been resolved
 | 
				
			||||||
            if dst.name == dst.value:
 | 
					            if dst.name == dst.value:
 | 
				
			||||||
                # check whether it is a function
 | 
					                # check whether it is a function
 | 
				
			||||||
                val = next((x.offset for x in self.functions if x.name == dst.name), None)
 | 
					                val = next(
 | 
				
			||||||
 | 
					                    (x.offset for x in self.functions if x.name == dst.name), None)
 | 
				
			||||||
                # check whether it is a label
 | 
					                # check whether it is a label
 | 
				
			||||||
                if val == None:
 | 
					                if val == None:
 | 
				
			||||||
                    for f in self.functions:
 | 
					                    for f in self.functions:
 | 
				
			||||||
@ -254,7 +258,9 @@ class VMAssembler:
 | 
				
			|||||||
        for o, n in zip(olds, ops):
 | 
					        for o, n in zip(olds, ops):
 | 
				
			||||||
            print("{} : {}->{}".format(o.name, hex(o.value), hex(n.value)))
 | 
					            print("{} : {}->{}".format(o.name, hex(o.value), hex(n.value)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VMFunction:
 | 
					class VMFunction:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, name, code):
 | 
					    def __init__(self, name, code):
 | 
				
			||||||
        self.name = name
 | 
					        self.name = name
 | 
				
			||||||
        self.size = 0
 | 
					        self.size = 0
 | 
				
			||||||
@ -269,7 +275,8 @@ class VMFunction:
 | 
				
			|||||||
            label = label_re.match(line)
 | 
					            label = label_re.match(line)
 | 
				
			||||||
            if label:
 | 
					            if label:
 | 
				
			||||||
                label_name = label.group(1)
 | 
					                label_name = label.group(1)
 | 
				
			||||||
                self.instructions.append(VMInstruction(code[i+1], label_name))
 | 
					                self.instructions.append(
 | 
				
			||||||
 | 
					                    VMInstruction(code[i + 1], label_name))
 | 
				
			||||||
                i += 2
 | 
					                i += 2
 | 
				
			||||||
            elif ins:
 | 
					            elif ins:
 | 
				
			||||||
                self.instructions.append(VMInstruction(line))
 | 
					                self.instructions.append(VMInstruction(line))
 | 
				
			||||||
@ -297,6 +304,7 @@ class VMFunction:
 | 
				
			|||||||
    def __repr__(self):
 | 
					    def __repr__(self):
 | 
				
			||||||
        return "{}: size {}, offset {}".format(self.name, hex(self.size), hex(self.offset))
 | 
					        return "{}: size {}, offset {}".format(self.name, hex(self.size), hex(self.offset))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VMInstruction:
 | 
					class VMInstruction:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Represents an instruction the VM recognizes.
 | 
					    Represents an instruction the VM recognizes.
 | 
				
			||||||
@ -420,6 +428,10 @@ op_names = [["MOVI", "imm2reg"],
 | 
				
			|||||||
            ["MULR", "reg2reg"],
 | 
					            ["MULR", "reg2reg"],
 | 
				
			||||||
            ["DIVI", "imm2reg"],
 | 
					            ["DIVI", "imm2reg"],
 | 
				
			||||||
            ["DIVR", "reg2reg"],
 | 
					            ["DIVR", "reg2reg"],
 | 
				
			||||||
 | 
					            ["SHLI", "imm2reg"],
 | 
				
			||||||
 | 
					            ["SHLR", "reg2reg"],
 | 
				
			||||||
 | 
					            ["SHRI", "imm2reg"],
 | 
				
			||||||
 | 
					            ["SHRR", "reg2reg"],
 | 
				
			||||||
            ["PUSH", "regonly"],
 | 
					            ["PUSH", "regonly"],
 | 
				
			||||||
            ["POOP", "regonly"],
 | 
					            ["POOP", "regonly"],
 | 
				
			||||||
            ["CMPI", "imm2reg"],
 | 
					            ["CMPI", "imm2reg"],
 | 
				
			||||||
@ -442,7 +454,8 @@ op_names = [["MOVI", "imm2reg"],
 | 
				
			|||||||
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"]
 | 
				
			||||||
ops = [VMComponent(le[0], i, le[1]) for i, le 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)]
 | 
				
			||||||
instruction_re = re.compile("^([\w]{4})(?:\ +(?:([\w]+)\ *(?:,[\ ]*([\w]+))*))?$") # 1: opcode 2+: args
 | 
					instruction_re = re.compile(
 | 
				
			||||||
 | 
					    "^([\w]{4})(?:\ +(?:([\w]+)\ *(?:,[\ ]*([\w]+))*))?$")  # 1: opcode 2+: args
 | 
				
			||||||
function_re = re.compile("(?:def\ )([a-zA-Z]*)\:")
 | 
					function_re = re.compile("(?:def\ )([a-zA-Z]*)\:")
 | 
				
			||||||
immediate_re = re.compile("(?:0x)?[0-9a-fA-F]+$")
 | 
					immediate_re = re.compile("(?:0x)?[0-9a-fA-F]+$")
 | 
				
			||||||
alpha_re = re.compile("^[a-zA-Z]*$")
 | 
					alpha_re = re.compile("^[a-zA-Z]*$")
 | 
				
			||||||
@ -450,6 +463,7 @@ register_re = re.compile("(^[rRsS][0-4]$)|([iIrRsS][pP]$)")
 | 
				
			|||||||
label_re = re.compile("^([a-zA-Z]+)\:$")
 | 
					label_re = re.compile("^([a-zA-Z]+)\:$")
 | 
				
			||||||
symcall_re = re.compile("^([jJ][pPmM][pPaAbBeEnN][iIrR])\ +([\w]*)$")
 | 
					symcall_re = re.compile("^([jJ][pPmM][pPaAbBeEnN][iIrR])\ +([\w]*)$")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def main():
 | 
					def main():
 | 
				
			||||||
    if len(sys.argv) < 4:
 | 
					    if len(sys.argv) < 4:
 | 
				
			||||||
        print("Usage: {} opcodes_key file_to_assemble output".format(
 | 
					        print("Usage: {} opcodes_key file_to_assemble output".format(
 | 
				
			||||||
 | 
				
			|||||||
@ -24,6 +24,10 @@ enum OPS_STARTING_VALUES {
 | 
				
			|||||||
  MULR,
 | 
					  MULR,
 | 
				
			||||||
  DIVI,
 | 
					  DIVI,
 | 
				
			||||||
  DIVR,
 | 
					  DIVR,
 | 
				
			||||||
 | 
					  SHLI,
 | 
				
			||||||
 | 
					  SHLR,
 | 
				
			||||||
 | 
					  SHRI,
 | 
				
			||||||
 | 
					  SHRR,
 | 
				
			||||||
  PUSH,
 | 
					  PUSH,
 | 
				
			||||||
  POOP,
 | 
					  POOP,
 | 
				
			||||||
  CMPI,
 | 
					  CMPI,
 | 
				
			||||||
@ -83,6 +87,10 @@ INSTRUCTION SIZES
 | 
				
			|||||||
#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 SHLI_SIZE IMM2REG
 | 
				
			||||||
 | 
					#define SHLR_SIZE REG2REG
 | 
				
			||||||
 | 
					#define SHRI_SIZE IMM2REG
 | 
				
			||||||
 | 
					#define SHRR_SIZE REG2REG
 | 
				
			||||||
#define PUSH_SIZE REGONLY
 | 
					#define PUSH_SIZE REGONLY
 | 
				
			||||||
#define POOP_SIZE REGONLY
 | 
					#define POOP_SIZE REGONLY
 | 
				
			||||||
#define CMPI_SIZE IMM2REG
 | 
					#define CMPI_SIZE IMM2REG
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										69
									
								
								vm/vm.cpp
									
									
									
									
									
								
							
							
						
						
									
										69
									
								
								vm/vm.cpp
									
									
									
									
									
								
							@ -459,10 +459,62 @@ bool VM::execDIVR(void) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  dst = as.code[regs[IP] + 1] >> 4;
 | 
					  dst = as.code[regs[IP] + 1] >> 4;
 | 
				
			||||||
  src = as.code[regs[IP] + 1] & 0b00001111;
 | 
					  src = as.code[regs[IP] + 1] & 0b00001111;
 | 
				
			||||||
  DBG_INFO(("ADDR %s, 0x%x\n", getRegName(dst), src));
 | 
					  DBG_INFO(("DIVR %s, 0x%x\n", getRegName(dst), src));
 | 
				
			||||||
  regs[dst] /= regs[src];
 | 
					  regs[dst] /= regs[src];
 | 
				
			||||||
  return true;
 | 
					  return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					bool VM::execSHLI(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(("SHLI %s, 0x%x\n", getRegName(dst), src));
 | 
				
			||||||
 | 
					  regs[dst] = regs[dst] << src;
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool VM::execSHLR(void) {
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					  SHLR 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(("SHLR %s, 0x%x\n", getRegName(dst), src));
 | 
				
			||||||
 | 
					  regs[dst] = regs[dst] << regs[src];
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool VM::execSHRI(void) {
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					  SHRI 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(("SHRI %s, 0x%x\n", getRegName(dst), src));
 | 
				
			||||||
 | 
					  regs[dst] = regs[dst] >> src;
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool VM::execSHRR(void) {
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					  SHRR 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(("SHRR %s, 0x%x\n", getRegName(dst), src));
 | 
				
			||||||
 | 
					  regs[dst] = regs[dst] >> regs[src];
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
bool VM::execPUSH(void) {
 | 
					bool VM::execPUSH(void) {
 | 
				
			||||||
  // TODO: STACK < 0
 | 
					  // TODO: STACK < 0
 | 
				
			||||||
  uint8_t src;
 | 
					  uint8_t src;
 | 
				
			||||||
@ -755,6 +807,21 @@ void VM::run(void) {
 | 
				
			|||||||
    } else if (opcode == OPS[DIVI]) {
 | 
					    } else if (opcode == OPS[DIVI]) {
 | 
				
			||||||
      execDIVI();
 | 
					      execDIVI();
 | 
				
			||||||
      regs[IP] += DIVI_SIZE;
 | 
					      regs[IP] += DIVI_SIZE;
 | 
				
			||||||
 | 
					    } else if (opcode == OPS[DIVR]) {
 | 
				
			||||||
 | 
					      execDIVR();
 | 
				
			||||||
 | 
					      regs[IP] += DIVR_SIZE;
 | 
				
			||||||
 | 
					    } else if (opcode == OPS[SHLI]) {
 | 
				
			||||||
 | 
					      execSHLI();
 | 
				
			||||||
 | 
					      regs[IP] += SHLI_SIZE;
 | 
				
			||||||
 | 
					    } else if (opcode == OPS[SHLR]) {
 | 
				
			||||||
 | 
					      execSHLR();
 | 
				
			||||||
 | 
					      regs[IP] += SHLR_SIZE;
 | 
				
			||||||
 | 
					    } else if (opcode == OPS[SHRI]) {
 | 
				
			||||||
 | 
					      execSHRI();
 | 
				
			||||||
 | 
					      regs[IP] += SHRI_SIZE;
 | 
				
			||||||
 | 
					    } else if (opcode == OPS[SHRR]) {
 | 
				
			||||||
 | 
					      execSHRR();
 | 
				
			||||||
 | 
					      regs[IP] += SHRR_SIZE;
 | 
				
			||||||
    } else if (opcode == OPS[PUSH]) {
 | 
					    } else if (opcode == OPS[PUSH]) {
 | 
				
			||||||
      execPUSH();
 | 
					      execPUSH();
 | 
				
			||||||
      regs[IP] += PUSH_SIZE;
 | 
					      regs[IP] += PUSH_SIZE;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										4
									
								
								vm/vm.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								vm/vm.h
									
									
									
									
									
								
							@ -54,6 +54,10 @@ private:
 | 
				
			|||||||
  bool execMULR(void);
 | 
					  bool execMULR(void);
 | 
				
			||||||
  bool execDIVI(void);
 | 
					  bool execDIVI(void);
 | 
				
			||||||
  bool execDIVR(void);
 | 
					  bool execDIVR(void);
 | 
				
			||||||
 | 
					  bool execSHLI(void);
 | 
				
			||||||
 | 
					  bool execSHLR(void);
 | 
				
			||||||
 | 
					  bool execSHRI(void);
 | 
				
			||||||
 | 
					  bool execSHRR(void);
 | 
				
			||||||
  bool execPUSH(void);
 | 
					  bool execPUSH(void);
 | 
				
			||||||
  bool execPOOP(void);
 | 
					  bool execPOOP(void);
 | 
				
			||||||
  bool execCMPI(void);
 | 
					  bool execCMPI(void);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user