diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index 688437d..bced679 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -165,6 +165,12 @@ protected: inline void writeSpace2(typename super::mem_type_e space, uint64_t addr, uint16_t data){super::write_mem(space, addr, data);} inline void writeSpace4(typename super::mem_type_e space, uint64_t addr, uint32_t data){super::write_mem(space, addr, data);} inline void writeSpace8(typename super::mem_type_e space, uint64_t addr, uint64_t data){super::write_mem(space, addr, data);} + template + inline T sext(T from) { + auto mask = (1ULL< #include #include +#ifdef WITH_TGF_B #include +#endif #include #ifdef WITH_LLVM #include @@ -129,10 +131,13 @@ int main(int argc, char *argv[]) { vm_ptr vm{nullptr}; cpu_ptr cpu{nullptr}; std::string isa_opt(clim["isa"].as()); +#ifdef WITH_TGF_B if (isa_opt == "tgf_b") { std::tie(cpu, vm) = create_cpu(clim["backend"].as(), clim["gdb-port"].as()); - } else if (isa_opt == "tgf_c") { + } else +#endif + if (isa_opt == "tgf_c") { std::tie(cpu, vm) = create_cpu(clim["backend"].as(), clim["gdb-port"].as()); } else { @@ -174,7 +179,7 @@ int main(int argc, char *argv[]) { } uint64_t start_address = 0; if (clim.count("mem")) - vm->get_arch()->load_file(clim["mem"].as(), iss::arch::traits::MEM); + vm->get_arch()->load_file(clim["mem"].as(), iss::arch::traits::MEM); if (clim.count("elf")) for (std::string input : clim["elf"].as>()) { auto start_addr = vm->get_arch()->load_file(input); diff --git a/src/vm/interp/vm_tgf_c.cpp b/src/vm/interp/vm_tgf_c.cpp index 1954fe5..940ed02 100644 --- a/src/vm/interp/vm_tgf_c.cpp +++ b/src/vm/interp/vm_tgf_c.cpp @@ -165,6 +165,12 @@ protected: inline void writeSpace2(typename super::mem_type_e space, uint64_t addr, uint16_t data){super::write_mem(space, addr, data);} inline void writeSpace4(typename super::mem_type_e space, uint64_t addr, uint32_t data){super::write_mem(space, addr, data);} inline void writeSpace8(typename super::mem_type_e space, uint64_t addr, uint64_t data){super::write_mem(space, addr, data);} + template + inline T sext(T from) { + auto mask = (1ULL<(imm); } // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 2); @@ -479,7 +485,7 @@ private: *NEXT_PC = *PC + 4; // execute instruction { - int32_t new_pc = *(X+rs1) + (int16_t)imm; + int32_t new_pc = *(X+rs1) + (int16_t)sext<12>(imm); if(rd != 0) *(X+rd) = *PC + 4; pc_assign(*NEXT_PC) = new_pc & ~ 0x1; } @@ -515,7 +521,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 4; // execute instruction - if(*(X+rs1) == *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)imm; + if(*(X+rs1) == *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 4); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); @@ -548,7 +554,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 4; // execute instruction - if(*(X+rs1) != *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)imm; + if(*(X+rs1) != *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 5); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); @@ -581,7 +587,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 4; // execute instruction - if(*(X+rs1) < *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)imm; + if(*(X+rs1) < *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 6); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); @@ -614,7 +620,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 4; // execute instruction - if(*(X+rs1) >= *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)imm; + if(*(X+rs1) >= *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 7); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); @@ -647,7 +653,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 4; // execute instruction - if(*(X+rs1) < *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)imm; + if(*(X+rs1) < *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 8); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); @@ -680,7 +686,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 4; // execute instruction - if(*(X+rs1) >= *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)imm; + if(*(X+rs1) >= *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 9); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); @@ -714,7 +720,7 @@ private: *NEXT_PC = *PC + 4; // execute instruction { - int8_t res = (int8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)imm); + int8_t res = (int8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); if(rd != 0) *(X+rd) = res; } // post execution stuff @@ -750,10 +756,10 @@ private: *NEXT_PC = *PC + 4; // execute instruction { - uint32_t load_address = *(X+rs1) + (int16_t)imm; + uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); if(traits::eei_aligned_addresses && (load_address & 0x1)) raise(0, 4); else { - int16_t res = (int16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)imm); + int16_t res = (int16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); if(rd != 0) *(X+rd) = res; } } @@ -790,10 +796,10 @@ private: *NEXT_PC = *PC + 4; // execute instruction { - uint32_t load_address = *(X+rs1) + (int16_t)imm; + uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); if(traits::eei_aligned_addresses && (load_address & 0x3)) raise(0, 4); else { - int32_t res = (int32_t)readSpace4(traits::MEM, *(X+rs1) + (int16_t)imm); + int32_t res = (int32_t)readSpace4(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); if(rd != 0) *(X+rd) = (uint32_t)res; } } @@ -830,7 +836,7 @@ private: *NEXT_PC = *PC + 4; // execute instruction { - uint8_t res = (uint8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)imm); + uint8_t res = (uint8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); if(rd != 0) *(X+rd) = res; } // post execution stuff @@ -866,10 +872,10 @@ private: *NEXT_PC = *PC + 4; // execute instruction { - uint32_t load_address = *(X+rs1) + (int16_t)imm; + uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); if(traits::eei_aligned_addresses && (load_address & 0x1)) raise(0, 4); else { - uint16_t res = (uint16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)imm); + uint16_t res = (uint16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); if(rd != 0) *(X+rd) = res; } } @@ -905,7 +911,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 4; // execute instruction - writeSpace1(traits::MEM, *(X+rs1) + (int16_t)imm, (int8_t)*(X+rs2)); + writeSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm), (int8_t)*(X+rs2)); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 15); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); @@ -939,7 +945,7 @@ private: *NEXT_PC = *PC + 4; // execute instruction { - uint32_t store_address = *(X+rs1) + (int16_t)imm; + uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); if(traits::eei_aligned_addresses && (store_address & 0x1)) raise(0, 6); else writeSpace2(traits::MEM, store_address, (int16_t)*(X+rs2)); } @@ -976,7 +982,7 @@ private: *NEXT_PC = *PC + 4; // execute instruction { - uint32_t store_address = *(X+rs1) + (int16_t)imm; + uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); if(traits::eei_aligned_addresses && (store_address & 0x3)) raise(0, 6); else writeSpace4(traits::MEM, store_address, *(X+rs2)); } @@ -1012,7 +1018,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 4; // execute instruction - if(rd != 0) *(X+rd) = *(X+rs1) + (int16_t)imm; + if(rd != 0) *(X+rd) = *(X+rs1) + (int16_t)sext<12>(imm); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 18); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); @@ -1045,7 +1051,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 4; // execute instruction - if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int16_t)imm? 1 : 0; + if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int16_t)sext<12>(imm)? 1 : 0; // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 19); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); @@ -1111,7 +1117,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 4; // execute instruction - if(rd != 0) *(X+rd) = *(X+rs1) ^ (int16_t)imm; + if(rd != 0) *(X+rd) = *(X+rs1) ^ (int16_t)sext<12>(imm); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 21); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); @@ -1144,7 +1150,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 4; // execute instruction - if(rd != 0) *(X+rd) = *(X+rs1) | (int16_t)imm; + if(rd != 0) *(X+rd) = *(X+rs1) | (int16_t)sext<12>(imm); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 22); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); @@ -1177,7 +1183,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 4; // execute instruction - if(rd != 0) *(X+rd) = *(X+rs1) & (int16_t)imm; + if(rd != 0) *(X+rd) = *(X+rs1) & (int16_t)sext<12>(imm); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 23); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); @@ -2567,7 +2573,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 2; // execute instruction - *(X+rs1) = *(X+rs1) + (int8_t)imm; + *(X+rs1) = *(X+rs1) + (int8_t)sext<6>(imm); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 63); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); @@ -2629,7 +2635,7 @@ private: // execute instruction { *(X+1) = *PC + 2; - pc_assign(*NEXT_PC) = *PC + (int16_t)imm; + pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); } // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65); @@ -2663,7 +2669,7 @@ private: *NEXT_PC = *PC + 2; // execute instruction { - if(rd == 0) *(X+rd) = (int8_t)imm; + if(rd == 0) *(X+rd) = (int8_t)sext<6>(imm); } // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66); @@ -2699,7 +2705,7 @@ private: { if(rd == 0) raise(0, 2); if(imm == 0) raise(0, 2); - *(X+rd) = (int32_t)imm; + *(X+rd) = (int32_t)sext<18>(imm); } // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 67); @@ -2732,7 +2738,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 2; // execute instruction - if(nzimm) *(X+2) = *(X+2) + (int16_t)nzimm; + if(nzimm) *(X+2) = *(X+2) + (int16_t)sext<10>(nzimm); else raise(0, 2); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 68); @@ -2841,7 +2847,7 @@ private: // execute instruction { uint8_t rs1_idx = rs1 + 8; - *(X+rs1_idx) = *(X+rs1_idx) & (int8_t)imm; + *(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm); } // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 71); @@ -3013,7 +3019,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 2; // execute instruction - pc_assign(*NEXT_PC) = *PC + (int16_t)imm; + pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 76); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); @@ -3045,7 +3051,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 2; // execute instruction - if(*(X+(rs1 + 8)) == 0) pc_assign(*NEXT_PC) = *PC + (int16_t)imm; + if(*(X+(rs1 + 8)) == 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 77); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); @@ -3077,7 +3083,7 @@ private: uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); *NEXT_PC = *PC + 2; // execute instruction - if(*(X+(rs1 + 8)) != 0) pc_assign(*NEXT_PC) = *PC + (int16_t)imm; + if(*(X+(rs1 + 8)) != 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 78); auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]);