update generated code with correct sign extension

This commit is contained in:
Eyck Jentzsch 2021-03-09 10:21:36 +00:00
parent 40db74ce02
commit a6691bcd3c
3 changed files with 52 additions and 35 deletions

View File

@ -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<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:
/****************************************************************************

View File

@ -36,7 +36,9 @@
#include <boost/lexical_cast.hpp>
#include <boost/program_options.hpp>
#include <iss/arch/riscv_hart_m_p.h>
#ifdef WITH_TGF_B
#include <iss/arch/tgf_b.h>
#endif
#include <iss/arch/tgf_c.h>
#ifdef WITH_LLVM
#include <iss/llvm/jit_helper.h>
@ -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<std::string>());
#ifdef WITH_TGF_B
if (isa_opt == "tgf_b") {
std::tie(cpu, vm) =
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) =
create_cpu<iss::arch::tgf_c>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
} 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<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"))
for (std::string input : clim["elf"].as<std::vector<std::string>>()) {
auto start_addr = vm->get_arch()->load_file(input);

View File

@ -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<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:
/****************************************************************************
@ -444,7 +450,7 @@ private:
// execute instruction
{
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
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<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::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<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]);
*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<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]);
*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<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]);
*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<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]);
*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<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]);
*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<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;
// 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<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::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<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;
// 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<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::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<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]);
*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<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]);
*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<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]);
*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<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]);
*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<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]);
*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<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::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<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::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<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::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<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]);
*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<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]);
*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<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]);