reg2reg assembler
This commit is contained in:
		
							parent
							
								
									56b8a9c407
								
							
						
					
					
						commit
						ffb11f9a2e
					
				| @ -1,7 +1,7 @@ | |||||||
| /*
 | /*
 | ||||||
| MEMORY LOCATIONS AND IMMEDIATES ARE 16 BITS LONG | MEMORY LOCATIONS AND IMMEDIATES ARE 16 BITS LONG | ||||||
| */ | */ | ||||||
| enum ops_starting_values { | enum OPS_STARTING_VALUES { | ||||||
|   MOVI, |   MOVI, | ||||||
|   MOVR, |   MOVR, | ||||||
|   LOAD, |   LOAD, | ||||||
|  | |||||||
							
								
								
									
										43
									
								
								cpp/vm.cpp
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								cpp/vm.cpp
									
									
									
									
									
								
							| @ -40,7 +40,7 @@ void VM::defineOpcodes(uint8_t *key) { | |||||||
| DBG UTILS | DBG UTILS | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| uint8_t *VM::reg_name(uint8_t regvalue) { | uint8_t *VM::getRegName(uint8_t regvalue) { | ||||||
|   uint8_t *buf = new uint8_t[2]; |   uint8_t *buf = new uint8_t[2]; | ||||||
| #ifdef DBG | #ifdef DBG | ||||||
|   switch (regvalue) { |   switch (regvalue) { | ||||||
| @ -166,7 +166,7 @@ void VM::initVariables(void) { | |||||||
| INSTRUCTIONS IMPLEMENTATIONS | INSTRUCTIONS IMPLEMENTATIONS | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| bool VM::exec_movi(void) { | bool VM::execMOVI(void) { | ||||||
|   /*
 |   /*
 | ||||||
|   MOVI R0, 0x2400 | R0 = 0x2400 |   MOVI R0, 0x2400 | R0 = 0x2400 | ||||||
|   */ |   */ | ||||||
| @ -174,7 +174,7 @@ bool VM::exec_movi(void) { | |||||||
|   uint16_t imm; |   uint16_t imm; | ||||||
|   dst = as.code[regs[IP] + 1]; |   dst = as.code[regs[IP] + 1]; | ||||||
|   imm = *((uint16_t *)&as.code[regs[IP] + 2]); |   imm = *((uint16_t *)&as.code[regs[IP] + 2]); | ||||||
|   DBG_INFO(("MOVI %s, 0x%x\n", reg_name(dst), imm)); |   DBG_INFO(("MOVI %s, 0x%x\n", getRegName(dst), imm)); | ||||||
|   if (dst == IP) { |   if (dst == IP) { | ||||||
|     DBG_ERROR(("Can't MOVI to IP!\n")); |     DBG_ERROR(("Can't MOVI to IP!\n")); | ||||||
|     return false; |     return false; | ||||||
| @ -183,7 +183,7 @@ bool VM::exec_movi(void) { | |||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool VM::exec_movr(void) { | bool VM::execMOVR(void) { | ||||||
|   /*
 |   /*
 | ||||||
|   MOVR R1, R0 | R1 = R0 |   MOVR R1, R0 | R1 = R0 | ||||||
|   --------------------- |   --------------------- | ||||||
| @ -192,7 +192,7 @@ bool VM::exec_movr(void) { | |||||||
|   uint8_t dst, src; |   uint8_t dst, src; | ||||||
|   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(("MOVR %s, %s\n", reg_name(dst), reg_name(src))); |   DBG_INFO(("MOVR %s, %s\n", getRegName(dst), getRegName(src))); | ||||||
|   if (dst == IP || src == IP) { |   if (dst == IP || src == IP) { | ||||||
|     DBG_ERROR(("Can't MOVR IP!\n")); |     DBG_ERROR(("Can't MOVR IP!\n")); | ||||||
|     return false; |     return false; | ||||||
| @ -201,7 +201,7 @@ bool VM::exec_movr(void) { | |||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool VM::exec_load(void) { | bool VM::execLOAD(void) { | ||||||
|   /*
 |   /*
 | ||||||
|   LOAD R0, 0x1000 | R0 = data[0x1000] |   LOAD R0, 0x1000 | R0 = data[0x1000] | ||||||
|   */ |   */ | ||||||
| @ -209,12 +209,12 @@ bool VM::exec_load(void) { | |||||||
|   uint16_t src; |   uint16_t src; | ||||||
|   dst = as.code[regs[IP] + 1]; |   dst = as.code[regs[IP] + 1]; | ||||||
|   src = *((uint16_t *)&as.code[regs[IP] + 2]); |   src = *((uint16_t *)&as.code[regs[IP] + 2]); | ||||||
|   DBG_INFO(("LOAD %s, 0x%x\n", reg_name(dst), src)); |   DBG_INFO(("LOAD %s, 0x%x\n", getRegName(dst), src)); | ||||||
|   regs[dst] = *((uint16_t *)&as.data[src]); |   regs[dst] = *((uint16_t *)&as.data[src]); | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool VM::exec_stor(void) { | bool VM::execSTOR(void) { | ||||||
|   /*
 |   /*
 | ||||||
|   STOR 0x1000, R0 | data[0x1000] = R0 |   STOR 0x1000, R0 | data[0x1000] = R0 | ||||||
|   */ |   */ | ||||||
| @ -222,12 +222,12 @@ bool VM::exec_stor(void) { | |||||||
|   uint8_t src; |   uint8_t src; | ||||||
|   dst = *((uint16_t *)&as.code[regs[IP] + 1]); |   dst = *((uint16_t *)&as.code[regs[IP] + 1]); | ||||||
|   src = as.code[regs[IP] + 3]; |   src = as.code[regs[IP] + 3]; | ||||||
|   DBG_INFO(("STOR 0x%x, %s\n", dst, reg_name(src))); |   DBG_INFO(("STOR 0x%x, %s\n", dst, getRegName(src))); | ||||||
|   *((uint16_t *)&as.data[dst]) = regs[src]; |   *((uint16_t *)&as.data[dst]) = regs[src]; | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool VM::exec_addi(void) { | bool VM::execADDI(void) { | ||||||
|   /*
 |   /*
 | ||||||
|   ADDI R0, 0x2 | R0 += 2 |   ADDI R0, 0x2 | R0 += 2 | ||||||
|   */ |   */ | ||||||
| @ -236,30 +236,41 @@ bool VM::exec_addi(void) { | |||||||
| 
 | 
 | ||||||
|   dst = as.code[regs[IP] + 1]; |   dst = as.code[regs[IP] + 1]; | ||||||
|   src = *((uint16_t *)&as.code[regs[IP] + 2]); |   src = *((uint16_t *)&as.code[regs[IP] + 2]); | ||||||
|   DBG_INFO(("ADDI %s, 0x%x\n", reg_name(dst), src)); |   DBG_INFO(("ADDI %s, 0x%x\n", getRegName(dst), src)); | ||||||
|   regs[dst] += src; |   regs[dst] += src; | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void VM::execADDR(void) { | ||||||
|  |   uint8_t dst; | ||||||
|  |   uint8_t src; | ||||||
|  | 
 | ||||||
|  |   dst = as.code[regs[IP] + 1] >> 4; | ||||||
|  |   src = as.code[regs[IP] + 1] & 0b00001111; | ||||||
|  |   DBG_INFO(("ADDR %s, 0x%x\n", getRegName(dst), src)); | ||||||
|  |   regs[dst] += regs[src]; | ||||||
|  |   return; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void VM::run(void) { | void VM::run(void) { | ||||||
|   uint8_t opcode; |   uint8_t opcode; | ||||||
|   bool finished = false; |   bool finished = false; | ||||||
|   while (!finished) { |   while (!finished) { | ||||||
|     opcode = (uint8_t)as.code[regs[IP]]; |     opcode = (uint8_t)as.code[regs[IP]]; | ||||||
|     if (opcode == OPS[MOVI]) { |     if (opcode == OPS[MOVI]) { | ||||||
|       exec_movi(); |       execMOVI(); | ||||||
|       regs[IP] += MOVI_SIZE; |       regs[IP] += MOVI_SIZE; | ||||||
|     } else if (opcode == OPS[MOVR]) { |     } else if (opcode == OPS[MOVR]) { | ||||||
|       exec_movr(); |       execMOVR(); | ||||||
|       regs[IP] += MOVR_SIZE; |       regs[IP] += MOVR_SIZE; | ||||||
|     } else if (opcode == OPS[LOAD]) { |     } else if (opcode == OPS[LOAD]) { | ||||||
|       exec_load(); |       execLOAD(); | ||||||
|       regs[IP] += LOAD_SIZE; |       regs[IP] += LOAD_SIZE; | ||||||
|     } else if (opcode == OPS[STOR]) { |     } else if (opcode == OPS[STOR]) { | ||||||
|       exec_stor(); |       execSTOR(); | ||||||
|       regs[IP] += STOR_SIZE; |       regs[IP] += STOR_SIZE; | ||||||
|     } else if (opcode == OPS[ADDI]) { |     } else if (opcode == OPS[ADDI]) { | ||||||
|       exec_addi(); |       execADDI(); | ||||||
|       regs[IP] += ADDI_SIZE; |       regs[IP] += ADDI_SIZE; | ||||||
|     } else if (opcode == OPS[SHIT]) { |     } else if (opcode == OPS[SHIT]) { | ||||||
|       finished = true; |       finished = true; | ||||||
|  | |||||||
							
								
								
									
										16
									
								
								cpp/vm.h
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								cpp/vm.h
									
									
									
									
									
								
							| @ -3,7 +3,6 @@ | |||||||
| #include "vmas.h" | #include "vmas.h" | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| enum regs { R0, R1, R2, R3, S0, S1, S2, S3, IP, BP, SP, NUM_REGS }; | enum regs { R0, R1, R2, R3, S0, S1, S2, S3, IP, BP, SP, NUM_REGS }; | ||||||
| 
 | 
 | ||||||
| class VM { | class VM { | ||||||
| @ -27,16 +26,17 @@ private: | |||||||
|   /*
 |   /*
 | ||||||
|   DBG UTILS |   DBG UTILS | ||||||
|   */ |   */ | ||||||
|   uint8_t *reg_name(uint8_t); |   uint8_t *getRegName(uint8_t); | ||||||
|   /*
 |   /*
 | ||||||
|   IMPLEMENTATIONS |   IMPLEMENTATIONS | ||||||
|   */ |   */ | ||||||
|   bool exec_movi(void); |   bool execMOVI(void); | ||||||
|   bool exec_movr(void); |   bool execMOVR(void); | ||||||
|   bool exec_movm(void); |   bool execMOVM(void); | ||||||
|   bool exec_load(void); |   bool execLOAD(void); | ||||||
|   bool exec_stor(void); |   bool execSTOR(void); | ||||||
|   bool exec_addi(void); |   bool execADDI(void); | ||||||
|  |   void execADDR(void); | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
|   VM(uint8_t *key); |   VM(uint8_t *key); | ||||||
|  | |||||||
| @ -51,6 +51,7 @@ rol = lambda val, r_bits, max_bits: \ | |||||||
|     (val << r_bits % max_bits) & (2**max_bits - 1) | \ |     (val << r_bits % max_bits) & (2**max_bits - 1) | \ | ||||||
|     ((val & (2**max_bits - 1)) >> (max_bits - (r_bits % max_bits))) |     ((val & (2**max_bits - 1)) >> (max_bits - (r_bits % max_bits))) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| class VMAssembler: | class VMAssembler: | ||||||
| 
 | 
 | ||||||
|     def __init__(self, key): |     def __init__(self, key): | ||||||
| @ -87,6 +88,23 @@ class VMAssembler: | |||||||
|         return |         return | ||||||
| 
 | 
 | ||||||
|     def reg2reg(self, instruction): |     def reg2reg(self, instruction): | ||||||
|  |         """ | ||||||
|  |         Intel syntax -> DST_REG, SRC_REG | ||||||
|  |         """ | ||||||
|  |         opcode = instruction.opcode | ||||||
|  |         dst_reg = instruction.args[0] | ||||||
|  |         src_reg = instruction.args[1] | ||||||
|  |         if dst_reg.name == "ip" or src_reg.name == "ip": | ||||||
|  |             raise IPOverwrite(instruction) | ||||||
|  |         if not dst_reg.isreg(): | ||||||
|  |             raise ExpectedRegister(dst_reg) | ||||||
|  |         if not src_reg.isreg(): | ||||||
|  |             raise ExpectedRegister(src_reg) | ||||||
|  |         if not opcode.uint8() or not dst_reg.uint8() or not src_reg.uint8(): | ||||||
|  |             raise InvalidValue(instruction) | ||||||
|  |         byte_with_nibbles = struct.pack("<B", dst_reg.uint8()[0] << 4 ^ ( | ||||||
|  |             src_reg.uint8()[0] & 0b00001111)) | ||||||
|  |         self.assembled_code += opcode.uint8() + byte_with_nibbles | ||||||
|         return |         return | ||||||
| 
 | 
 | ||||||
|     def reg2imm(self, instruction): |     def reg2imm(self, instruction): | ||||||
| @ -125,6 +143,9 @@ class VMAssembler: | |||||||
|     def op_addi(self, instruction): |     def op_addi(self, instruction): | ||||||
|         self.imm2reg(instruction) |         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) | ||||||
| @ -281,7 +302,8 @@ def assemble_data(line): | |||||||
| 
 | 
 | ||||||
| def main(): | def main(): | ||||||
|     if len(sys.argv) < 4: |     if len(sys.argv) < 4: | ||||||
|         print("Usage: {} opcodes_key file_to_assemble output".format(sys.argv[0])) |         print("Usage: {} opcodes_key file_to_assemble output".format( | ||||||
|  |             sys.argv[0])) | ||||||
|         return |         return | ||||||
|     vma = VMAssembler(sys.argv[1]) |     vma = VMAssembler(sys.argv[1]) | ||||||
|     with open(sys.argv[2], 'r') as f: |     with open(sys.argv[2], 'r') as f: | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user