update generated code with correct sign extension
This commit is contained in:
		| @@ -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 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 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);} |     inline void writeSpace8(typename super::mem_type_e space, uint64_t addr, uint64_t data){super::write_mem(space, addr, data);} | ||||||
|  |     template<unsigned W, typename T> | ||||||
|  |     inline T sext(T from) { | ||||||
|  |         auto mask = (1ULL<<W) - 1; | ||||||
|  |         auto sign_mask = 1ULL<<(W-1); | ||||||
|  |         return (from & mask) | ((from & sign_mask) ? ~mask : 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     /**************************************************************************** |     /**************************************************************************** | ||||||
|   | |||||||
| @@ -36,7 +36,9 @@ | |||||||
| #include <boost/lexical_cast.hpp> | #include <boost/lexical_cast.hpp> | ||||||
| #include <boost/program_options.hpp> | #include <boost/program_options.hpp> | ||||||
| #include <iss/arch/riscv_hart_m_p.h> | #include <iss/arch/riscv_hart_m_p.h> | ||||||
|  | #ifdef WITH_TGF_B | ||||||
| #include <iss/arch/tgf_b.h> | #include <iss/arch/tgf_b.h> | ||||||
|  | #endif | ||||||
| #include <iss/arch/tgf_c.h> | #include <iss/arch/tgf_c.h> | ||||||
| #ifdef WITH_LLVM | #ifdef WITH_LLVM | ||||||
| #include <iss/llvm/jit_helper.h> | #include <iss/llvm/jit_helper.h> | ||||||
| @@ -129,10 +131,13 @@ int main(int argc, char *argv[]) { | |||||||
|         vm_ptr vm{nullptr}; |         vm_ptr vm{nullptr}; | ||||||
|         cpu_ptr cpu{nullptr}; |         cpu_ptr cpu{nullptr}; | ||||||
|         std::string isa_opt(clim["isa"].as<std::string>()); |         std::string isa_opt(clim["isa"].as<std::string>()); | ||||||
|  | #ifdef WITH_TGF_B | ||||||
|         if (isa_opt == "tgf_b") { |         if (isa_opt == "tgf_b") { | ||||||
|             std::tie(cpu, vm) = |             std::tie(cpu, vm) = | ||||||
|                 create_cpu<iss::arch::tgf_b>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); |                 create_cpu<iss::arch::tgf_b>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); | ||||||
|         } else if (isa_opt == "tgf_c") { |         } else | ||||||
|  | #endif | ||||||
|  |             if (isa_opt == "tgf_c") { | ||||||
|             std::tie(cpu, vm) = |             std::tie(cpu, vm) = | ||||||
|                 create_cpu<iss::arch::tgf_c>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); |                 create_cpu<iss::arch::tgf_c>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); | ||||||
|         } else { |         } else { | ||||||
| @@ -174,7 +179,7 @@ int main(int argc, char *argv[]) { | |||||||
|         } |         } | ||||||
|         uint64_t start_address = 0; |         uint64_t start_address = 0; | ||||||
|         if (clim.count("mem")) |         if (clim.count("mem")) | ||||||
|             vm->get_arch()->load_file(clim["mem"].as<std::string>(), iss::arch::traits<iss::arch::tgf_b>::MEM); |             vm->get_arch()->load_file(clim["mem"].as<std::string>(), iss::arch::traits<iss::arch::tgf_c>::MEM); | ||||||
|         if (clim.count("elf")) |         if (clim.count("elf")) | ||||||
|             for (std::string input : clim["elf"].as<std::vector<std::string>>()) { |             for (std::string input : clim["elf"].as<std::vector<std::string>>()) { | ||||||
|                 auto start_addr = vm->get_arch()->load_file(input); |                 auto start_addr = vm->get_arch()->load_file(input); | ||||||
|   | |||||||
| @@ -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 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 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);} |     inline void writeSpace8(typename super::mem_type_e space, uint64_t addr, uint64_t data){super::write_mem(space, addr, data);} | ||||||
|  |     template<unsigned W, typename T> | ||||||
|  |     inline T sext(T from) { | ||||||
|  |         auto mask = (1ULL<<W) - 1; | ||||||
|  |         auto sign_mask = 1ULL<<(W-1); | ||||||
|  |         return (from & mask) | ((from & sign_mask) ? ~mask : 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     /**************************************************************************** |     /**************************************************************************** | ||||||
| @@ -444,7 +450,7 @@ private: | |||||||
|         // execute instruction |         // execute instruction | ||||||
|         { |         { | ||||||
|         	if(rd != 0) *(X+rd) = *PC + 4;  |         	if(rd != 0) *(X+rd) = *PC + 4;  | ||||||
|         	pc_assign(*NEXT_PC) = *PC + (int32_t)imm; |         	pc_assign(*NEXT_PC) = *PC + (int32_t)sext<21>(imm); | ||||||
|         } |         } | ||||||
|         // post execution stuff |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 2); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 2); | ||||||
| @@ -479,7 +485,7 @@ private: | |||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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;  |         	if(rd != 0) *(X+rd) = *PC + 4;  | ||||||
|         	pc_assign(*NEXT_PC) = new_pc & ~ 0x1; |         	pc_assign(*NEXT_PC) = new_pc & ~ 0x1; | ||||||
|         } |         } | ||||||
| @@ -515,7 +521,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 4); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 4); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
| @@ -548,7 +554,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 5); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 5); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
| @@ -581,7 +587,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 6); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 6); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
| @@ -614,7 +620,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 7); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 7); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
| @@ -647,7 +653,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 8); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 8); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
| @@ -680,7 +686,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 9); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 9); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
| @@ -714,7 +720,7 @@ private: | |||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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;  |         	if(rd != 0) *(X+rd) = res;  | ||||||
|         } |         } | ||||||
|         // post execution stuff |         // post execution stuff | ||||||
| @@ -750,10 +756,10 @@ private: | |||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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);  |         	if(traits::eei_aligned_addresses && (load_address & 0x1)) raise(0,  4);  | ||||||
|         	else { |         	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;  |         		if(rd != 0) *(X+rd) = res;  | ||||||
|         	} |         	} | ||||||
|         } |         } | ||||||
| @@ -790,10 +796,10 @@ private: | |||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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);  |         	if(traits::eei_aligned_addresses && (load_address & 0x3)) raise(0,  4);  | ||||||
|         	else { |         	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;  |         		if(rd != 0) *(X+rd) = (uint32_t)res;  | ||||||
|         	} |         	} | ||||||
|         } |         } | ||||||
| @@ -830,7 +836,7 @@ private: | |||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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;  |         	if(rd != 0) *(X+rd) = res;  | ||||||
|         } |         } | ||||||
|         // post execution stuff |         // post execution stuff | ||||||
| @@ -866,10 +872,10 @@ private: | |||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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);  |         	if(traits::eei_aligned_addresses && (load_address & 0x1)) raise(0,  4);  | ||||||
|         	else { |         	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;  |         		if(rd != 0) *(X+rd) = res;  | ||||||
|         	} |         	} | ||||||
|         } |         } | ||||||
| @@ -905,7 +911,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 15); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 15); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
| @@ -939,7 +945,7 @@ private: | |||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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);  |         	if(traits::eei_aligned_addresses && (store_address & 0x1)) raise(0,  6);  | ||||||
|         	else writeSpace2(traits::MEM, store_address, (int16_t)*(X+rs2)); |         	else writeSpace2(traits::MEM, store_address, (int16_t)*(X+rs2)); | ||||||
|         } |         } | ||||||
| @@ -976,7 +982,7 @@ private: | |||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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);  |         	if(traits::eei_aligned_addresses && (store_address & 0x3)) raise(0,  6);  | ||||||
|         	else writeSpace4(traits::MEM, store_address, *(X+rs2)); |         	else writeSpace4(traits::MEM, store_address, *(X+rs2)); | ||||||
|         } |         } | ||||||
| @@ -1012,7 +1018,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 18); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 18); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
| @@ -1045,7 +1051,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 19); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 19); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
| @@ -1111,7 +1117,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 21); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 21); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
| @@ -1144,7 +1150,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 22); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 22); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
| @@ -1177,7 +1183,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 4; |         *NEXT_PC = *PC + 4; | ||||||
|         // execute instruction |         // 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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 23); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 23); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
| @@ -2567,7 +2573,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 2; |         *NEXT_PC = *PC + 2; | ||||||
|         // execute instruction |         // execute instruction | ||||||
|         *(X+rs1) = *(X+rs1) + (int8_t)imm; |         *(X+rs1) = *(X+rs1) + (int8_t)sext<6>(imm); | ||||||
|         // post execution stuff |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 63); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 63); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
| @@ -2629,7 +2635,7 @@ private: | |||||||
|         // execute instruction |         // execute instruction | ||||||
|         { |         { | ||||||
|         	*(X+1) = *PC + 2; |         	*(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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65); | ||||||
| @@ -2663,7 +2669,7 @@ private: | |||||||
|         *NEXT_PC = *PC + 2; |         *NEXT_PC = *PC + 2; | ||||||
|         // execute instruction |         // execute instruction | ||||||
|         { |         { | ||||||
|         	if(rd ==  0) *(X+rd) = (int8_t)imm;  |         	if(rd ==  0) *(X+rd) = (int8_t)sext<6>(imm);  | ||||||
|         } |         } | ||||||
|         // post execution stuff |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66); | ||||||
| @@ -2699,7 +2705,7 @@ private: | |||||||
|         { |         { | ||||||
|         	if(rd ==  0) raise(0,  2);  |         	if(rd ==  0) raise(0,  2);  | ||||||
|         	if(imm ==  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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 67); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 67); | ||||||
| @@ -2732,7 +2738,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 2; |         *NEXT_PC = *PC + 2; | ||||||
|         // execute instruction |         // 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); |         else raise(0,  2); | ||||||
|         // post execution stuff |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 68); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 68); | ||||||
| @@ -2841,7 +2847,7 @@ private: | |||||||
|         // execute instruction |         // execute instruction | ||||||
|         { |         { | ||||||
|         	uint8_t rs1_idx = rs1 +  8; |         	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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 71); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 71); | ||||||
| @@ -3013,7 +3019,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 2; |         *NEXT_PC = *PC + 2; | ||||||
|         // execute instruction |         // execute instruction | ||||||
|         pc_assign(*NEXT_PC) = *PC + (int16_t)imm; |         pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); | ||||||
|         // post execution stuff |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 76); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 76); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
| @@ -3045,7 +3051,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 2; |         *NEXT_PC = *PC + 2; | ||||||
|         // execute instruction |         // 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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 77); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 77); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
| @@ -3077,7 +3083,7 @@ private: | |||||||
|         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); |         uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]); | ||||||
|         *NEXT_PC = *PC + 2; |         *NEXT_PC = *PC + 2; | ||||||
|         // execute instruction |         // 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 |         // post execution stuff | ||||||
|         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 78); |         if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 78); | ||||||
|         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); |         auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user