mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-23 21:39:10 -04:00
Modified RV32F instructions to support 64-bit register file and added RV64F ISA extension
This commit is contained in:
parent
30a0d34151
commit
e6eda67d0c
21 changed files with 459 additions and 316 deletions
|
@ -1,15 +1,14 @@
|
|||
# RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain
|
||||
RISCV_TOOLCHAIN_PATH = /nethome/ssrivatsan8/riscv32
|
||||
RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain
|
||||
# simx64
|
||||
RISCV64_TOOLCHAIN_PATH ?= /nethome/ssrivatsan8/riscv
|
||||
|
||||
|
||||
CC = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-gcc
|
||||
AR = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-gcc-ar
|
||||
DP = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-objdump
|
||||
CP = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-objcopy
|
||||
CC = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-gcc
|
||||
AR = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-gcc-ar
|
||||
DP = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-objdump
|
||||
CP = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-objcopy
|
||||
|
||||
CFLAGS += -O3 -march=rv64imfd -mabi=lp64d -Wstack-usage=1024 -fno-exceptions -fdata-sections -ffunction-sections
|
||||
CFLAGS += -O3 -march=rv32imf -mabi=ilp32f -Wstack-usage=1024 -fno-exceptions -fdata-sections -ffunction-sections
|
||||
CFLAGS += -I./include -I../hw
|
||||
|
||||
PROJECT = libvortexrt
|
||||
|
|
|
@ -23,13 +23,13 @@ _start:
|
|||
call memset
|
||||
|
||||
# Register global termination functions
|
||||
la a0, __libc_fini_array
|
||||
# la a0, __libc_fini_array
|
||||
|
||||
# to be called upon exit
|
||||
call atexit
|
||||
|
||||
# Run global initialization functions
|
||||
call __libc_init_array
|
||||
# call __libc_init_array
|
||||
|
||||
# call main program routine
|
||||
call main
|
||||
|
|
|
@ -106,6 +106,21 @@ uint32_t rv_ftou(uint32_t a, uint32_t frm, uint32_t* fflags) {
|
|||
return r;
|
||||
}
|
||||
|
||||
// simx64
|
||||
uint64_t rv_ftol(uint32_t a, uint32_t frm, uint32_t* fflags) {
|
||||
softfloat_roundingMode = frm;
|
||||
auto r = f32_to_i64(to_float32_t(a), frm, true);
|
||||
if (fflags) { *fflags = get_fflags(); }
|
||||
return r;
|
||||
}
|
||||
|
||||
uint64_t rv_ftolu(uint32_t a, uint32_t frm, uint32_t* fflags) {
|
||||
softfloat_roundingMode = frm;
|
||||
auto r = f32_to_ui64(to_float32_t(a), frm, true);
|
||||
if (fflags) { *fflags = get_fflags(); }
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32_t rv_itof(uint32_t a, uint32_t frm, uint32_t* fflags) {
|
||||
softfloat_roundingMode = frm;
|
||||
auto r = i32_to_f32(a);
|
||||
|
@ -120,6 +135,21 @@ uint32_t rv_utof(uint32_t a, uint32_t frm, uint32_t* fflags) {
|
|||
return from_float32_t(r);
|
||||
}
|
||||
|
||||
// simx64
|
||||
uint32_t rv_ltof(uint64_t a, uint32_t frm, uint32_t* fflags) {
|
||||
softfloat_roundingMode = frm;
|
||||
auto r = i64_to_f32(a);
|
||||
if (fflags) { *fflags = get_fflags(); }
|
||||
return from_float32_t(r);
|
||||
}
|
||||
|
||||
uint32_t rv_lutof(uint64_t a, uint32_t frm, uint32_t* fflags) {
|
||||
softfloat_roundingMode = frm;
|
||||
auto r = ui64_to_f32(a);
|
||||
if (fflags) { *fflags = get_fflags(); }
|
||||
return from_float32_t(r);
|
||||
}
|
||||
|
||||
uint32_t rv_flt(uint32_t a, uint32_t b, uint32_t* fflags) {
|
||||
auto r = f32_lt(to_float32_t(a), to_float32_t(b));
|
||||
if (fflags) { *fflags = get_fflags(); }
|
||||
|
|
|
@ -20,8 +20,14 @@ uint32_t rv_fsqrt(uint32_t a, uint32_t frm, uint32_t* fflags);
|
|||
|
||||
uint32_t rv_ftoi(uint32_t a, uint32_t frm, uint32_t* fflags);
|
||||
uint32_t rv_ftou(uint32_t a, uint32_t frm, uint32_t* fflags);
|
||||
// simx64
|
||||
uint64_t rv_ftol(uint32_t a, uint32_t frm, uint32_t* fflags);
|
||||
uint64_t rv_ftolu(uint32_t a, uint32_t frm, uint32_t* fflags);
|
||||
uint32_t rv_itof(uint32_t a, uint32_t frm, uint32_t* fflags);
|
||||
uint32_t rv_utof(uint32_t a, uint32_t frm, uint32_t* fflags);
|
||||
// simx64
|
||||
uint32_t rv_ltof(uint64_t a, uint32_t frm, uint32_t* fflags);
|
||||
uint32_t rv_lutof(uint64_t a, uint32_t frm, uint32_t* fflags);
|
||||
|
||||
uint32_t rv_fclss(uint32_t a);
|
||||
uint32_t rv_fsgnj(uint32_t a, uint32_t b);
|
||||
|
|
|
@ -21,15 +21,15 @@ inline uint64_t align_size(uint64_t size, uint64_t alignment) {
|
|||
return (size + alignment - 1) & ~(alignment - 1);
|
||||
}
|
||||
|
||||
// Apply integer sign extension
|
||||
// 64-bit sign extension
|
||||
inline uint64_t signExt(uint64_t w, uint64_t bit, uint64_t mask) {
|
||||
if (w >> (bit - 1))
|
||||
w |= ~mask;
|
||||
return w;
|
||||
}
|
||||
|
||||
// Apply integer sign extension
|
||||
inline uint32_t signExt32(uint32_t w, uint32_t bit, uint32_t mask) {
|
||||
// 128-bit sign extension
|
||||
inline __uint128_t signExt128(__uint128_t w, uint32_t bit, __uint128_t mask) {
|
||||
if (w >> (bit - 1))
|
||||
w |= ~mask;
|
||||
return w;
|
||||
|
|
|
@ -21,9 +21,7 @@ VPATH := $(sort $(dir $(SRCS)))
|
|||
|
||||
# Debugigng
|
||||
ifdef DEBUG
|
||||
# CXXFLAGS += -g -O0 -DDEBUG_LEVEL=$(DEBUG)
|
||||
# simx64
|
||||
CXXFLAGS += -g -O0 -DDEBUG_LEVEL=4
|
||||
CXXFLAGS += -g -O0 -DDEBUG_LEVEL=$(DEBUG)
|
||||
else
|
||||
CXXFLAGS += -O2 -DNDEBUG
|
||||
endif
|
||||
|
|
|
@ -241,7 +241,7 @@ void Core::writeback() {
|
|||
inst_in_writeback_.next(NULL);
|
||||
}
|
||||
|
||||
Word Core::get_csr(Addr addr, int tid, int wid) {
|
||||
DoubleWord Core::get_csr(Addr addr, int tid, int wid) {
|
||||
if (addr == CSR_FFLAGS) {
|
||||
return fcsrs_.at(wid) & 0x1F;
|
||||
} else if (addr == CSR_FRM) {
|
||||
|
@ -284,19 +284,19 @@ Word Core::get_csr(Addr addr, int tid, int wid) {
|
|||
return insts_;
|
||||
} else if (addr == CSR_MINSTRET_H) {
|
||||
// NumInsts
|
||||
return (Word)(insts_ >> 32);
|
||||
return (DoubleWord)(insts_ >> 32);
|
||||
} else if (addr == CSR_MCYCLE) {
|
||||
// NumCycles
|
||||
return (Word)steps_;
|
||||
return (DoubleWord)steps_;
|
||||
} else if (addr == CSR_MCYCLE_H) {
|
||||
// NumCycles
|
||||
return (Word)(steps_ >> 32);
|
||||
return (DoubleWord)(steps_ >> 32);
|
||||
} else {
|
||||
return csrs_.at(addr);
|
||||
}
|
||||
}
|
||||
|
||||
void Core::set_csr(Addr addr, Word value, int /*tid*/, int wid) {
|
||||
void Core::set_csr(Addr addr, DoubleWord value, int /*tid*/, int wid) {
|
||||
if (addr == CSR_FFLAGS) {
|
||||
fcsrs_.at(wid) = (fcsrs_.at(wid) & ~0x1F) | (value & 0x1F);
|
||||
} else if (addr == CSR_FRM) {
|
||||
|
@ -322,16 +322,16 @@ void Core::barrier(int bar_id, int count, int warp_id) {
|
|||
}
|
||||
|
||||
// simx64
|
||||
HalfWord Core::icache_fetch(Addr addr) {
|
||||
HalfWord data;
|
||||
mem_.read(&data, addr, sizeof(HalfWord), 0);
|
||||
Word Core::icache_fetch(Addr addr) {
|
||||
Word data;
|
||||
mem_.read(&data, addr, sizeof(Word), 0);
|
||||
return data;
|
||||
}
|
||||
|
||||
// simx64
|
||||
Word Core::dcache_read(Addr addr, Size size) {
|
||||
DoubleWord Core::dcache_read(Addr addr, Size size) {
|
||||
++loads_;
|
||||
Word data = 0;
|
||||
DoubleWord data = 0;
|
||||
#ifdef SM_ENABLE
|
||||
if ((addr >= (SMEM_BASE_ADDR - SMEM_SIZE))
|
||||
&& ((addr + 3) < SMEM_BASE_ADDR)) {
|
||||
|
@ -343,7 +343,7 @@ Word Core::dcache_read(Addr addr, Size size) {
|
|||
return data;
|
||||
}
|
||||
|
||||
void Core::dcache_write(Addr addr, Word data, Size size) {
|
||||
void Core::dcache_write(Addr addr, DoubleWord data, Size size) {
|
||||
++stores_;
|
||||
#ifdef SM_ENABLE
|
||||
if ((addr >= (SMEM_BASE_ADDR - SMEM_SIZE))
|
||||
|
@ -375,7 +375,7 @@ void Core::printStats() const {
|
|||
<< "Stores: " << stores_ << std::endl;
|
||||
}
|
||||
|
||||
void Core::writeToStdOut(Addr addr, Word data) {
|
||||
void Core::writeToStdOut(Addr addr, DoubleWord data) {
|
||||
uint32_t tid = (addr - IO_COUT_ADDR) & (IO_COUT_SIZE-1);
|
||||
auto& ss_buf = print_bufs_[tid];
|
||||
char c = (char)data;
|
||||
|
|
|
@ -60,18 +60,18 @@ public:
|
|||
return warps_[0]->getIRegValue(reg);
|
||||
}
|
||||
|
||||
Word get_csr(Addr addr, int tid, int wid);
|
||||
DoubleWord get_csr(Addr addr, int tid, int wid);
|
||||
|
||||
void set_csr(Addr addr, Word value, int tid, int wid);
|
||||
void set_csr(Addr addr, DoubleWord value, int tid, int wid);
|
||||
|
||||
void barrier(int bar_id, int count, int warp_id);
|
||||
|
||||
// simx64
|
||||
HalfWord icache_fetch(Addr);
|
||||
Word icache_fetch(Addr);
|
||||
// simx64
|
||||
Word dcache_read(Addr, Size);
|
||||
DoubleWord dcache_read(Addr, Size);
|
||||
// simx64
|
||||
void dcache_write(Addr, Word, Size);
|
||||
void dcache_write(Addr, DoubleWord, Size);
|
||||
|
||||
void trigger_ebreak();
|
||||
bool check_ebreak() const;
|
||||
|
@ -85,7 +85,7 @@ private:
|
|||
void execute();
|
||||
void writeback();
|
||||
|
||||
void writeToStdOut(Addr addr, Word data);
|
||||
void writeToStdOut(Addr addr, DoubleWord data);
|
||||
|
||||
std::vector<RegMask> in_use_iregs_;
|
||||
std::vector<RegMask> in_use_fregs_;
|
||||
|
@ -93,7 +93,7 @@ private:
|
|||
WarpMask stalled_warps_;
|
||||
std::vector<std::shared_ptr<Warp>> warps_;
|
||||
std::vector<WarpMask> barriers_;
|
||||
std::vector<Word> csrs_;
|
||||
std::vector<DoubleWord> csrs_;
|
||||
std::vector<Byte> fcsrs_;
|
||||
std::unordered_map<int, std::stringstream> print_bufs_;
|
||||
|
||||
|
|
|
@ -46,10 +46,10 @@ static const std::unordered_map<int, struct InstTableEntry_t> sc_instTable = {
|
|||
};
|
||||
|
||||
static const char* op_string(const Instr &instr) {
|
||||
HalfWord func3 = instr.getFunc3();
|
||||
HalfWord func7 = instr.getFunc7();
|
||||
HalfWord rs2 = instr.getRSrc(1);
|
||||
Word imm = instr.getImm();
|
||||
Word func3 = instr.getFunc3();
|
||||
Word func7 = instr.getFunc7();
|
||||
Word rs2 = instr.getRSrc(1);
|
||||
DoubleWord imm = instr.getImm();
|
||||
switch (instr.getOpcode()) {
|
||||
case Opcode::NOP: return "NOP";
|
||||
case Opcode::LUI_INST: return "LUI";
|
||||
|
@ -128,12 +128,24 @@ static const char* op_string(const Instr &instr) {
|
|||
}
|
||||
// simx64
|
||||
case Opcode::R_INST_64:
|
||||
switch (func3) {
|
||||
case 0: return func7 ? "SUBW" : "ADDW";
|
||||
case 1: return "SLLW";
|
||||
case 5: return func7 ? "SRAW" : "SRLW";
|
||||
default:
|
||||
std::abort();
|
||||
if (func7 & 0x1){
|
||||
switch (func3) {
|
||||
case 0: return func7 ? "SUBW" : "ADDW";
|
||||
case 1: return "SLLW";
|
||||
case 5: return func7 ? "SRAW" : "SRLW";
|
||||
default:
|
||||
std::abort();
|
||||
}
|
||||
} else {
|
||||
switch (func3) {
|
||||
case 0: return "MULW";
|
||||
case 4: return "DIVW";
|
||||
case 5: return "DIVUW";
|
||||
case 6: return "REMW";
|
||||
case 7: return "REMUW";
|
||||
default:
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
// simx64
|
||||
case Opcode::I_INST_64:
|
||||
|
@ -189,8 +201,25 @@ static const char* op_string(const Instr &instr) {
|
|||
default:
|
||||
std::abort();
|
||||
}
|
||||
case 0x60: return rs2 ? "FCVT.WU.S" : "FCVT.W.S";
|
||||
case 0x68: return rs2 ? "FCVT.S.WU" : "FCVT.S.W";
|
||||
// simx64
|
||||
case 0x60:
|
||||
switch (rs2) {
|
||||
case 0: return "FCVT.W.S";
|
||||
case 1: return "FCVT.WU.S";
|
||||
case 2: return "FCVT.L.S";
|
||||
case 3: return "FCVT.LU.S";
|
||||
default:
|
||||
std::abort();
|
||||
}
|
||||
case 0x68:
|
||||
switch (rs2) {
|
||||
case 0: return "FCVT.S.W";
|
||||
case 1: return "FCVT.S.WU";
|
||||
case 2: return "FCVT.S.L";
|
||||
case 3: return "FCVT.S.LU";
|
||||
default:
|
||||
std::abort();
|
||||
}
|
||||
case 0x70: return func3 ? "FLASS" : "FMV.X.W";
|
||||
case 0x78: return "FMV.W.X";
|
||||
default:
|
||||
|
@ -309,14 +338,14 @@ Decoder::Decoder(const ArchDef &arch) {
|
|||
}
|
||||
|
||||
// simx64
|
||||
std::shared_ptr<Instr> Decoder::decode(HalfWord code, HalfWord PC) {
|
||||
std::shared_ptr<Instr> Decoder::decode(Word code, Word PC) {
|
||||
auto instr = std::make_shared<Instr>();
|
||||
Opcode op = (Opcode)((code >> shift_opcode_) & opcode_mask_);
|
||||
instr->setOpcode(op);
|
||||
|
||||
HalfWord func3 = (code >> shift_func3_) & func3_mask_;
|
||||
HalfWord func6 = (code >> shift_func6_) & func6_mask_;
|
||||
HalfWord func7 = (code >> shift_func7_) & func7_mask_;
|
||||
Word func3 = (code >> shift_func3_) & func3_mask_;
|
||||
Word func6 = (code >> shift_func6_) & func6_mask_;
|
||||
Word func7 = (code >> shift_func7_) & func7_mask_;
|
||||
|
||||
// simx64
|
||||
int rd = (code >> shift_rd_) & reg_mask_;
|
||||
|
@ -394,7 +423,7 @@ std::shared_ptr<Instr> Decoder::decode(HalfWord code, HalfWord PC) {
|
|||
instr->setSrcReg(rs2);
|
||||
}
|
||||
instr->setFunc3(func3);
|
||||
Word imeed = (func7 << reg_s_) | rd;
|
||||
DoubleWord imeed = (func7 << reg_s_) | rd;
|
||||
instr->setImm(signExt(imeed, 12, s_imm_mask_));
|
||||
} break;
|
||||
|
||||
|
@ -402,11 +431,11 @@ std::shared_ptr<Instr> Decoder::decode(HalfWord code, HalfWord PC) {
|
|||
instr->setSrcReg(rs1);
|
||||
instr->setSrcReg(rs2);
|
||||
instr->setFunc3(func3);
|
||||
HalfWord bit_11 = rd & 0x1;
|
||||
HalfWord bits_4_1 = rd >> 1;
|
||||
HalfWord bit_10_5 = func7 & 0x3f;
|
||||
HalfWord bit_12 = func7 >> 6;
|
||||
Word imeed = (bits_4_1 << 1) | (bit_10_5 << 5) | (bit_11 << 11) | (bit_12 << 12);
|
||||
Word bit_11 = rd & 0x1;
|
||||
Word bits_4_1 = rd >> 1;
|
||||
Word bit_10_5 = func7 & 0x3f;
|
||||
Word bit_12 = func7 >> 6;
|
||||
DoubleWord imeed = (bits_4_1 << 1) | (bit_10_5 << 5) | (bit_11 << 11) | (bit_12 << 12);
|
||||
instr->setImm(signExt(imeed, 13, b_imm_mask_));
|
||||
} break;
|
||||
|
||||
|
@ -417,12 +446,12 @@ std::shared_ptr<Instr> Decoder::decode(HalfWord code, HalfWord PC) {
|
|||
|
||||
case InstType::J_TYPE: {
|
||||
instr->setDestReg(rd);
|
||||
HalfWord unordered = code >> shift_func3_;
|
||||
HalfWord bits_19_12 = unordered & 0xff;
|
||||
HalfWord bit_11 = (unordered >> 8) & 0x1;
|
||||
HalfWord bits_10_1 = (unordered >> 9) & 0x3ff;
|
||||
HalfWord bit_20 = (unordered >> 19) & 0x1;
|
||||
Word imeed = 0 | (bits_10_1 << 1) | (bit_11 << 11) | (bits_19_12 << 12) | (bit_20 << 20);
|
||||
Word unordered = code >> shift_func3_;
|
||||
Word bits_19_12 = unordered & 0xff;
|
||||
Word bit_11 = (unordered >> 8) & 0x1;
|
||||
Word bits_10_1 = (unordered >> 9) & 0x3ff;
|
||||
Word bit_20 = (unordered >> 19) & 0x1;
|
||||
DoubleWord imeed = 0 | (bits_10_1 << 1) | (bit_11 << 11) | (bits_19_12 << 12) | (bit_20 << 20);
|
||||
if (bit_20) {
|
||||
imeed |= ~j_imm_mask_;
|
||||
}
|
||||
|
@ -438,7 +467,7 @@ std::shared_ptr<Instr> Decoder::decode(HalfWord code, HalfWord PC) {
|
|||
if (func3 == 7) {
|
||||
instr->setImm(!(code >> shift_vset_));
|
||||
if (instr->getImm()) {
|
||||
HalfWord immed = (code >> shift_rs2_) & v_imm_mask_;
|
||||
Word immed = (code >> shift_rs2_) & v_imm_mask_;
|
||||
instr->setImm(immed);
|
||||
instr->setVlmul(immed & 0x3);
|
||||
instr->setVediv((immed >> 4) & 0x3);
|
||||
|
|
|
@ -13,49 +13,49 @@ class Decoder {
|
|||
public:
|
||||
Decoder(const ArchDef &);
|
||||
|
||||
std::shared_ptr<Instr> decode(HalfWord code, HalfWord PC);
|
||||
std::shared_ptr<Instr> decode(Word code, Word PC);
|
||||
|
||||
private:
|
||||
|
||||
HalfWord inst_s_;
|
||||
HalfWord opcode_s_;
|
||||
HalfWord reg_s_;
|
||||
HalfWord func2_s_;
|
||||
HalfWord func3_s_;
|
||||
HalfWord shift_opcode_;
|
||||
HalfWord shift_rd_;
|
||||
HalfWord shift_rs1_;
|
||||
HalfWord shift_rs2_;
|
||||
HalfWord shift_rs3_;
|
||||
HalfWord shift_func2_;
|
||||
HalfWord shift_func3_;
|
||||
HalfWord shift_func7_;
|
||||
HalfWord shift_j_u_immed_;
|
||||
HalfWord shift_s_b_immed_;
|
||||
HalfWord shift_i_immed_;
|
||||
Word inst_s_;
|
||||
Word opcode_s_;
|
||||
Word reg_s_;
|
||||
Word func2_s_;
|
||||
Word func3_s_;
|
||||
Word shift_opcode_;
|
||||
Word shift_rd_;
|
||||
Word shift_rs1_;
|
||||
Word shift_rs2_;
|
||||
Word shift_rs3_;
|
||||
Word shift_func2_;
|
||||
Word shift_func3_;
|
||||
Word shift_func7_;
|
||||
Word shift_j_u_immed_;
|
||||
Word shift_s_b_immed_;
|
||||
Word shift_i_immed_;
|
||||
|
||||
HalfWord reg_mask_;
|
||||
HalfWord func2_mask_;
|
||||
HalfWord func3_mask_;
|
||||
HalfWord func6_mask_;
|
||||
HalfWord func7_mask_;
|
||||
HalfWord opcode_mask_;
|
||||
HalfWord i_imm_mask_;
|
||||
HalfWord s_imm_mask_;
|
||||
HalfWord b_imm_mask_;
|
||||
HalfWord u_imm_mask_;
|
||||
HalfWord j_imm_mask_;
|
||||
HalfWord v_imm_mask_;
|
||||
Word reg_mask_;
|
||||
Word func2_mask_;
|
||||
Word func3_mask_;
|
||||
Word func6_mask_;
|
||||
Word func7_mask_;
|
||||
Word opcode_mask_;
|
||||
Word i_imm_mask_;
|
||||
Word s_imm_mask_;
|
||||
Word b_imm_mask_;
|
||||
Word u_imm_mask_;
|
||||
Word j_imm_mask_;
|
||||
Word v_imm_mask_;
|
||||
|
||||
//Vector
|
||||
HalfWord shift_vset_;
|
||||
HalfWord shift_vset_immed_;
|
||||
HalfWord shift_vmask_;
|
||||
HalfWord shift_vmop_;
|
||||
HalfWord shift_vnf_;
|
||||
HalfWord shift_func6_;
|
||||
HalfWord vmask_s_;
|
||||
HalfWord mop_s_;
|
||||
Word shift_vset_;
|
||||
Word shift_vset_immed_;
|
||||
Word shift_vmask_;
|
||||
Word shift_vmop_;
|
||||
Word shift_vnf_;
|
||||
Word shift_func6_;
|
||||
Word vmask_s_;
|
||||
Word mop_s_;
|
||||
};
|
||||
|
||||
}
|
|
@ -16,7 +16,7 @@
|
|||
using namespace vortex;
|
||||
|
||||
static bool HasDivergentThreads(const ThreadMask &thread_mask,
|
||||
const std::vector<std::vector<Word>> ®_file,
|
||||
const std::vector<std::vector<DoubleWord>> ®_file,
|
||||
unsigned reg) {
|
||||
bool cond;
|
||||
size_t thread_idx = 0;
|
||||
|
@ -53,19 +53,19 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
assert(tmask_.any());
|
||||
|
||||
// simx64
|
||||
Word nextPC = PC_ + 4;
|
||||
DoubleWord nextPC = PC_ + 4;
|
||||
bool runOnce = false;
|
||||
|
||||
HalfWord func3 = instr.getFunc3();
|
||||
HalfWord func6 = instr.getFunc6();
|
||||
HalfWord func7 = instr.getFunc7();
|
||||
Word func3 = instr.getFunc3();
|
||||
Word func6 = instr.getFunc6();
|
||||
Word func7 = instr.getFunc7();
|
||||
|
||||
auto opcode = instr.getOpcode();
|
||||
int rdest = instr.getRDest();
|
||||
int rsrc0 = instr.getRSrc(0);
|
||||
int rsrc1 = instr.getRSrc(1);
|
||||
Word immsrc= instr.getImm();
|
||||
Word vmask = instr.getVmask();
|
||||
DoubleWord immsrc= instr.getImm();
|
||||
DoubleWord vmask = instr.getVmask();
|
||||
|
||||
int num_threads = core_->arch().num_threads();
|
||||
for (int t = 0; t < num_threads; t++) {
|
||||
|
@ -75,8 +75,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
auto &iregs = iRegFile_.at(t);
|
||||
auto &fregs = fRegFile_.at(t);
|
||||
|
||||
Word rsdata[3];
|
||||
Word rddata;
|
||||
DoubleWord rsdata[3];
|
||||
DoubleWord rddata;
|
||||
|
||||
int num_rsrcs = instr.getNRSrc();
|
||||
if (num_rsrcs) {
|
||||
|
@ -106,65 +106,57 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
case NOP:
|
||||
break;
|
||||
case LUI_INST:
|
||||
rddata = signExt(((immsrc << 12) & 0xfffff000), 32, 0xFFFFFFFF);
|
||||
rddata = (immsrc << 12) & 0xfffffffffffff000;
|
||||
rd_write = true;
|
||||
break;
|
||||
case AUIPC_INST:
|
||||
// simx64
|
||||
rddata = signExt(((immsrc << 12) & 0xfffff000), 32, 0xFFFFFFFF) + PC_;
|
||||
rddata = ((immsrc << 12) & 0xfffffffffffff000) + PC_;
|
||||
rd_write = true;
|
||||
break;
|
||||
case R_INST: {
|
||||
if (func7 & 0x1) {
|
||||
switch (func3) {
|
||||
case 0:
|
||||
// MUL
|
||||
rddata = ((WordI)rsdata[0]) * ((WordI)rsdata[1]);
|
||||
// RV32M: MUL
|
||||
rddata = ((DoubleWordI)rsdata[0]) * ((DoubleWordI)rsdata[1]);
|
||||
break;
|
||||
case 1: {
|
||||
// MULH
|
||||
int64_t first = (int64_t)rsdata[0];
|
||||
if (rsdata[0] & 0x80000000) {
|
||||
first = first | 0xFFFFFFFF00000000;
|
||||
}
|
||||
int64_t second = (int64_t)rsdata[1];
|
||||
if (rsdata[1] & 0x80000000) {
|
||||
second = second | 0xFFFFFFFF00000000;
|
||||
}
|
||||
uint64_t result = first * second;
|
||||
rddata = (result >> 32) & 0xFFFFFFFF;
|
||||
// RV32M: MULH
|
||||
__int128_t first = signExt128((__int128_t)rsdata[0], 64, 0xFFFFFFFFFFFFFFFF);
|
||||
__int128_t second = signExt128((__int128_t)rsdata[1], 64, 0xFFFFFFFFFFFFFFFF);
|
||||
__uint128_t result = first * second;
|
||||
rddata = (result >> 64) & 0xFFFFFFFFFFFFFFFF;
|
||||
} break;
|
||||
case 2: {
|
||||
// MULHSU
|
||||
int64_t first = (int64_t)rsdata[0];
|
||||
if (rsdata[0] & 0x80000000) {
|
||||
first = first | 0xFFFFFFFF00000000;
|
||||
}
|
||||
int64_t second = (int64_t)rsdata[1];
|
||||
rddata = ((first * second) >> 32) & 0xFFFFFFFF;
|
||||
// RV32M: MULHSU
|
||||
__int128_t first = signExt128((__int128_t)rsdata[0], 64, 0xFFFFFFFFFFFFFFFF);
|
||||
__int128_t second = (__int128_t)rsdata[1];
|
||||
__uint128_t result = first * second;
|
||||
rddata = (result >> 64) & 0xFFFFFFFFFFFFFFFF;
|
||||
} break;
|
||||
case 3: {
|
||||
// MULHU
|
||||
uint64_t first = (uint64_t)rsdata[0];
|
||||
uint64_t second = (uint64_t)rsdata[1];
|
||||
rddata = ((first * second) >> 32) & 0xFFFFFFFF;
|
||||
// RV32M: MULHU
|
||||
__uint128_t first = (__uint128_t)rsdata[0];
|
||||
__uint128_t second = (__uint128_t)rsdata[1];
|
||||
rddata = ((first * second) >> 64) & 0xFFFFFFFFFFFFFFFF;
|
||||
} break;
|
||||
case 4: {
|
||||
// DIV
|
||||
WordI dividen = rsdata[0];
|
||||
WordI divisor = rsdata[1];
|
||||
// RV32M: DIV
|
||||
DoubleWordI dividen = rsdata[0];
|
||||
DoubleWordI divisor = rsdata[1];
|
||||
if (divisor == 0) {
|
||||
rddata = -1;
|
||||
} else if (dividen == WordI(0x80000000) && divisor == WordI(0xffffffff)) {
|
||||
} else if (dividen == DoubleWordI(0x8000000000000000) && divisor == DoubleWordI(0xFFFFFFFFFFFFFFFF)) {
|
||||
rddata = dividen;
|
||||
} else {
|
||||
rddata = dividen / divisor;
|
||||
}
|
||||
} break;
|
||||
case 5: {
|
||||
// DIVU
|
||||
Word dividen = rsdata[0];
|
||||
Word divisor = rsdata[1];
|
||||
// RV32M: DIVU
|
||||
DoubleWord dividen = rsdata[0];
|
||||
DoubleWord divisor = rsdata[1];
|
||||
if (divisor == 0) {
|
||||
rddata = -1;
|
||||
} else {
|
||||
|
@ -172,22 +164,22 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
}
|
||||
} break;
|
||||
case 6: {
|
||||
// REM
|
||||
WordI dividen = rsdata[0];
|
||||
WordI divisor = rsdata[1];
|
||||
if (rsdata[1] == 0) {
|
||||
// RV32M: REM
|
||||
DoubleWordI dividen = rsdata[0];
|
||||
DoubleWordI divisor = rsdata[1];
|
||||
if (divisor == 0) {
|
||||
rddata = dividen;
|
||||
} else if (dividen == WordI(0x80000000) && divisor == WordI(0xffffffff)) {
|
||||
} else if (dividen == DoubleWordI(0x8000000000000000) && divisor == DoubleWordI(0xFFFFFFFFFFFFFFFF)) {
|
||||
rddata = 0;
|
||||
} else {
|
||||
rddata = dividen % divisor;
|
||||
}
|
||||
} break;
|
||||
case 7: {
|
||||
// REMU
|
||||
Word dividen = rsdata[0];
|
||||
Word divisor = rsdata[1];
|
||||
if (rsdata[1] == 0) {
|
||||
// RV32M: REMU
|
||||
DoubleWord dividen = rsdata[0];
|
||||
DoubleWord divisor = rsdata[1];
|
||||
if (divisor == 0) {
|
||||
rddata = dividen;
|
||||
} else {
|
||||
rddata = dividen % divisor;
|
||||
|
@ -205,22 +197,20 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
rddata = rsdata[0] - rsdata[1];
|
||||
} else {
|
||||
// RV32I: ADD
|
||||
rddata = WordI(rsdata[0]) + WordI(rsdata[1]);//(WordI(rsdata[0]) > 0) && (WordI(rsdata[1]) > 0)? ((rsdata[0] + rsdata[1]) & 0xFFFFFFFF) :
|
||||
rddata = rsdata[0] + rsdata[1];
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// simx64
|
||||
// In RV64I, only the low 6 bits of rs2 are considered for the shift amount.
|
||||
// In RV32I, the value in register rs1 is shifted by the amount held in the lower 5 bits of register rs2.
|
||||
// RV32I: SLL
|
||||
rddata = rsdata[0] << rsdata[1];
|
||||
break;
|
||||
case 2:
|
||||
// RV32I: SLT (signed)
|
||||
rddata = (WordI(rsdata[0]) < WordI(rsdata[1]));
|
||||
rddata = (DoubleWordI(rsdata[0]) < DoubleWordI(rsdata[1]));
|
||||
break;
|
||||
case 3:
|
||||
// RV32I: SLTU (unsigned)
|
||||
rddata = (Word(rsdata[0]) < Word(rsdata[1]));
|
||||
rddata = (DoubleWord(rsdata[0]) < DoubleWord(rsdata[1]));
|
||||
break;
|
||||
case 4:
|
||||
// RV32I: XOR
|
||||
|
@ -229,10 +219,10 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
case 5:
|
||||
if (func7) {
|
||||
// RV32I: SRA
|
||||
rddata = WordI(rsdata[0]) >> WordI(rsdata[1]);
|
||||
rddata = DoubleWordI(rsdata[0]) >> DoubleWordI(rsdata[1]);
|
||||
} else {
|
||||
// RV32I: SRL
|
||||
rddata = Word(rsdata[0]) >> Word(rsdata[1]);
|
||||
rddata = DoubleWord(rsdata[0]) >> DoubleWord(rsdata[1]);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
|
@ -253,7 +243,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
switch (func3) {
|
||||
case 0:
|
||||
// RV32I: ADDI
|
||||
rddata = WordI(rsdata[0]) + WordI(immsrc);
|
||||
rddata = rsdata[0] + immsrc;
|
||||
break;
|
||||
case 1:
|
||||
// RV64I: SLLI
|
||||
|
@ -261,11 +251,11 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
break;
|
||||
case 2:
|
||||
// RV32I: SLTI
|
||||
rddata = (WordI(rsdata[0]) < WordI(immsrc));
|
||||
rddata = (DoubleWordI(rsdata[0]) < DoubleWordI(immsrc));
|
||||
break;
|
||||
case 3: {
|
||||
// RV32I: SLTIU
|
||||
rddata = (Word(rsdata[0]) < Word(immsrc));
|
||||
rddata = (DoubleWord(rsdata[0]) < DoubleWord(immsrc));
|
||||
} break;
|
||||
case 4:
|
||||
// RV32I: XORI
|
||||
|
@ -274,11 +264,13 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
case 5:
|
||||
if (func7) {
|
||||
// RV64I: SRAI
|
||||
Word result = WordI(rsdata[0]) >> immsrc;
|
||||
// rs1 shifted by lower 6 bits of immsrc
|
||||
DoubleWord result = DoubleWordI(rsdata[0]) >> immsrc;
|
||||
rddata = result;
|
||||
} else {
|
||||
// RV64I: SRLI
|
||||
Word result = Word(rsdata[0]) >> immsrc;
|
||||
// rs1 shifted by lower 6 bits of immsrc
|
||||
DoubleWord result = DoubleWord(rsdata[0]) >> immsrc;
|
||||
rddata = result;
|
||||
}
|
||||
break;
|
||||
|
@ -311,25 +303,25 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
break;
|
||||
case 4:
|
||||
// RV32I: BLT
|
||||
if (WordI(rsdata[0]) < WordI(rsdata[1])) {
|
||||
if (DoubleWordI(rsdata[0]) < DoubleWordI(rsdata[1])) {
|
||||
nextPC = PC_ + immsrc;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
// RV32I: BGE
|
||||
if (WordI(rsdata[0]) >= WordI(rsdata[1])) {
|
||||
if (DoubleWordI(rsdata[0]) >= DoubleWordI(rsdata[1])) {
|
||||
nextPC = PC_ + immsrc;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
// RV32I: BLTU
|
||||
if (Word(rsdata[0]) < Word(rsdata[1])) {
|
||||
if (DoubleWord(rsdata[0]) < DoubleWord(rsdata[1])) {
|
||||
nextPC = PC_ + immsrc;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
// RV32I: BGEU
|
||||
if (Word(rsdata[0]) >= Word(rsdata[1])) {
|
||||
if (DoubleWord(rsdata[0]) >= DoubleWord(rsdata[1])) {
|
||||
nextPC = PC_ + immsrc;
|
||||
}
|
||||
break;
|
||||
|
@ -348,15 +340,15 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
// RV32I: JALR
|
||||
case JALR_INST:
|
||||
rddata = nextPC;
|
||||
nextPC = HalfWord(rsdata[0]) + HalfWord(immsrc);
|
||||
nextPC = DoubleWord(rsdata[0]) + DoubleWord(immsrc);
|
||||
pipeline->stall_warp = true;
|
||||
runOnce = true;
|
||||
rd_write = true;
|
||||
break;
|
||||
case L_INST: {
|
||||
Word memAddr = ((rsdata[0] + immsrc) & 0xFFFFFFFC); // word aligned
|
||||
Word shift_by = ((rsdata[0] + immsrc) & 0x00000003) * 8;
|
||||
Word data_read = core_->dcache_read(memAddr, 8);
|
||||
DoubleWord memAddr = ((rsdata[0] + immsrc) & 0xFFFFFFFC); // DoubleWord aligned
|
||||
DoubleWord shift_by = ((rsdata[0] + immsrc) & 0x00000003) * 8;
|
||||
DoubleWord data_read = core_->dcache_read(memAddr, 8);
|
||||
D(3, "LOAD MEM: ADDRESS=0x" << std::hex << memAddr << ", DATA=0x" << data_read);
|
||||
switch (func3) {
|
||||
case 0:
|
||||
|
@ -373,19 +365,19 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
break;
|
||||
case 3:
|
||||
// RV64I: LD
|
||||
rddata = data_read;
|
||||
rddata = DoubleWord(data_read);
|
||||
break;
|
||||
case 4:
|
||||
// RV32I: LBU
|
||||
rddata = Word((data_read >> shift_by) & 0xFF);
|
||||
rddata = DoubleWord((data_read >> shift_by) & 0xFF);
|
||||
break;
|
||||
case 5:
|
||||
// RV32I: LHU
|
||||
rddata = Word((data_read >> shift_by) & 0xFFFF);
|
||||
rddata = DoubleWord((data_read >> shift_by) & 0xFFFF);
|
||||
break;
|
||||
case 6:
|
||||
// RV64I: LWU
|
||||
rddata = Word((data_read >> shift_by) & 0xFFFFFFFF);
|
||||
rddata = DoubleWord((data_read >> shift_by) & 0xFFFFFFFF);
|
||||
break;
|
||||
default:
|
||||
std::abort();
|
||||
|
@ -393,7 +385,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
rd_write = true;
|
||||
} break;
|
||||
case S_INST: {
|
||||
Word memAddr = rsdata[0] + immsrc;
|
||||
DoubleWord memAddr = rsdata[0] + immsrc;
|
||||
D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr);
|
||||
switch (func3) {
|
||||
case 0:
|
||||
|
@ -418,63 +410,110 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
} break;
|
||||
// simx64
|
||||
case R_INST_64: {
|
||||
switch (func3) {
|
||||
if (func7 & 0x1){
|
||||
switch (func3) {
|
||||
case 0:
|
||||
// RV64M: MULW
|
||||
rddata = signExt((WordI)rsdata[0] * (WordI)rsdata[1], 32, 0xFFFFFFFF);
|
||||
break;
|
||||
case 4: {
|
||||
// RV64M: DIVW
|
||||
int32_t dividen = (WordI) rsdata[0];
|
||||
int32_t divisor = (WordI) rsdata[1];
|
||||
if (divisor == 0){
|
||||
rddata = -1;
|
||||
} else if (dividen == WordI(0x80000000) && divisor == WordI(0xFFFFFFFF)) {
|
||||
rddata = signExt(dividen, 32, 0xFFFFFFFF);
|
||||
} else {
|
||||
rddata = signExt(dividen / divisor, 32, 0xFFFFFFFF);
|
||||
}
|
||||
} break;
|
||||
case 5: {
|
||||
// RV64M: DIVUW
|
||||
uint32_t dividen = (Word) rsdata[0];
|
||||
uint32_t divisor = (Word) rsdata[1];
|
||||
if (divisor == 0){
|
||||
rddata = -1;
|
||||
} else {
|
||||
rddata = signExt(dividen / divisor, 32, 0xFFFFFFFF);
|
||||
}
|
||||
} break;
|
||||
case 6: {
|
||||
// RV64M: REMW
|
||||
int32_t dividen = (WordI) rsdata[0];
|
||||
int32_t divisor = (WordI) rsdata[1];
|
||||
if (divisor == 0){
|
||||
rddata = signExt(dividen, 32, 0xFFFFFFFF);
|
||||
} else if (dividen == WordI(0x80000000) && divisor == WordI(0xFFFFFFFF)) {
|
||||
rddata = 0;
|
||||
} else {
|
||||
rddata = signExt(dividen % divisor, 32, 0xFFFFFFFF);
|
||||
}
|
||||
} break;
|
||||
case 7: {
|
||||
// RV64M: REMUW
|
||||
uint32_t dividen = (Word) rsdata[0];
|
||||
uint32_t divisor = (Word) rsdata[1];
|
||||
if (divisor == 0){
|
||||
rddata = signExt(dividen, 32, 0xFFFFFFFF);
|
||||
} else {
|
||||
rddata = signExt(dividen % divisor, 32, 0xFFFFFFFF);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
std::abort();
|
||||
}
|
||||
} else {
|
||||
switch (func3) {
|
||||
case 0:
|
||||
if (func7){
|
||||
// RV64I: SUBW
|
||||
rddata = signExt((HalfWord)rsdata[0] - (HalfWord)rsdata[1], 32, 0xFFFFFFFF);
|
||||
rddata = signExt((Word)rsdata[0] - (Word)rsdata[1], 32, 0xFFFFFFFF);
|
||||
}
|
||||
else{
|
||||
// RV64I: ADDW
|
||||
rddata = signExt((HalfWord)rsdata[0] + (HalfWord)rsdata[1], 32, 0xFFFFFFFF);
|
||||
rddata = signExt((Word)rsdata[0] + (Word)rsdata[1], 32, 0xFFFFFFFF);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// RV64I: SLLW
|
||||
// shift amount given by rs2[4:0]
|
||||
rddata = signExt((HalfWord)rsdata[0] << (HalfWord)rsdata[1], 32, 0xFFFFFFFF);
|
||||
rddata = signExt((Word)rsdata[0] << (Word)rsdata[1], 32, 0xFFFFFFFF);
|
||||
break;
|
||||
case 5:
|
||||
if (func7) {
|
||||
// RV64I: SRAW
|
||||
// shift amount given by rs2[4:0]
|
||||
rddata = signExt((HalfWordI)rsdata[0] >> (HalfWordI)rsdata[1], 32, 0xFFFFFFFF);
|
||||
rddata = signExt((WordI)rsdata[0] >> (WordI)rsdata[1], 32, 0xFFFFFFFF);
|
||||
} else {
|
||||
// RV64I: SRLW
|
||||
// shift amount given by rs2[4:0]
|
||||
rddata = signExt((HalfWord)rsdata[0] >> (HalfWord)rsdata[1], 32, 0xFFFFFFFF);
|
||||
rddata = signExt((Word)rsdata[0] >> (Word)rsdata[1], 32, 0xFFFFFFFF);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
rd_write = true;
|
||||
} break;
|
||||
|
||||
// simx64
|
||||
case I_INST_64: {
|
||||
switch (func3) {
|
||||
case 0:
|
||||
// RV64I: ADDIW
|
||||
rddata = signExt((HalfWord)rsdata[0] + (HalfWord)immsrc, 32, 0xFFFFFFFF);
|
||||
rddata = signExt((Word)rsdata[0] + (Word)immsrc, 32, 0xFFFFFFFF);
|
||||
break;
|
||||
case 1:
|
||||
// RV64I: SLLIW
|
||||
// rs1 shifted by lower 5 bits of imm
|
||||
// Illegal exception if imm[5] != 0
|
||||
rddata = signExt((HalfWord)rsdata[0] << (HalfWord)immsrc, 32, 0xFFFFFFFF);
|
||||
rddata = signExt((Word)rsdata[0] << (Word)immsrc, 32, 0xFFFFFFFF);
|
||||
break;
|
||||
case 5:
|
||||
if (func7) {
|
||||
// RV64I: SRAI
|
||||
// rs1 shifted by lower 5 bits of imm
|
||||
// Illegal exception if imm[5] != 0
|
||||
Word result = signExt((HalfWordI)rsdata[0] >> (HalfWordI)immsrc, 32, 0xFFFFFFFF);
|
||||
// RV64I: SRAIW
|
||||
DoubleWord result = signExt((WordI)rsdata[0] >> (WordI)immsrc, 32, 0xFFFFFFFF);
|
||||
rddata = result;
|
||||
} else {
|
||||
// RV64I: SRLI
|
||||
// rs1 shifted by lower 5 bits of imm
|
||||
// Illegal exception if imm[5] != 0
|
||||
Word result = signExt((HalfWord)rsdata[0] >> (HalfWord)immsrc, 32, 0xFFFFFFFF);
|
||||
// RV64I: SRLIW
|
||||
DoubleWord result = signExt((Word)rsdata[0] >> (Word)immsrc, 32, 0xFFFFFFFF);
|
||||
rddata = result;
|
||||
}
|
||||
break;
|
||||
|
@ -484,8 +523,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
rd_write = true;
|
||||
} break;
|
||||
case SYS_INST: {
|
||||
Word csr_addr = immsrc & 0x00000FFF;
|
||||
Word csr_value = core_->get_csr(csr_addr, t, id_);
|
||||
DoubleWord csr_addr = immsrc & 0x00000FFF;
|
||||
DoubleWord csr_value = core_->get_csr(csr_addr, t, id_);
|
||||
switch (func3) {
|
||||
case 0:
|
||||
if (csr_addr < 2) {
|
||||
|
@ -540,10 +579,12 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
break;
|
||||
case (FL | VL):
|
||||
if (func3 == 0x2) {
|
||||
Word memAddr = rsdata[0] + immsrc;
|
||||
Word data_read = core_->dcache_read(memAddr, 4);
|
||||
// RV32F: FLW
|
||||
DoubleWord memAddr = rsdata[0] + immsrc;
|
||||
DoubleWord data_read = core_->dcache_read(memAddr, 4);
|
||||
D(3, "LOAD MEM: ADDRESS=0x" << std::hex << memAddr << ", DATA=0x" << data_read);
|
||||
rddata = data_read;
|
||||
// simx64
|
||||
rddata = data_read | 0xFFFFFFFF00000000;
|
||||
} else {
|
||||
D(3, "Executing vector load");
|
||||
D(3, "lmul: " << vtype_.vlmul << " VLEN:" << (core_->arch().vsize() * 8) << "sew: " << vtype_.vsew);
|
||||
|
@ -555,11 +596,11 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
|
||||
switch (instr.getVlsWidth()) {
|
||||
case 6: {
|
||||
//load word and unit strided (not checking for unit stride)
|
||||
//load DoubleWord and unit strided (not checking for unit stride)
|
||||
for (int i = 0; i < vl_; i++) {
|
||||
Word memAddr = ((rsdata[0]) & 0xFFFFFFFC) + (i * vtype_.vsew / 8);
|
||||
DoubleWord memAddr = ((rsdata[0]) & 0xFFFFFFFC) + (i * vtype_.vsew / 8);
|
||||
D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr);
|
||||
Word data_read = core_->dcache_read(memAddr, 4);
|
||||
DoubleWord data_read = core_->dcache_read(memAddr, 4);
|
||||
D(3, "Mem addr: " << std::hex << memAddr << " Data read " << data_read);
|
||||
int *result_ptr = (int *)(vd.data() + i);
|
||||
*result_ptr = data_read;
|
||||
|
@ -574,16 +615,16 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
break;
|
||||
case (FS | VS):
|
||||
if (func3 == 0x2) {
|
||||
Word memAddr = rsdata[0] + immsrc;
|
||||
DoubleWord memAddr = rsdata[0] + immsrc;
|
||||
core_->dcache_write(memAddr, rsdata[1], 4);
|
||||
D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr);
|
||||
} else {
|
||||
for (int i = 0; i < vl_; i++) {
|
||||
Word memAddr = rsdata[0] + (i * vtype_.vsew / 8);
|
||||
DoubleWord memAddr = rsdata[0] + (i * vtype_.vsew / 8);
|
||||
D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr);
|
||||
switch (instr.getVlsWidth()) {
|
||||
case 6: {
|
||||
//store word and unit strided (not checking for unit stride)
|
||||
//store DoubleWord and unit strided (not checking for unit stride)
|
||||
uint32_t value = *(uint32_t *)(vRegFile_[instr.getVs3()].data() + i);
|
||||
core_->dcache_write(memAddr, value, 4);
|
||||
D(3, "store: " << memAddr << " value:" << value);
|
||||
|
@ -598,87 +639,109 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
uint32_t frm = get_fpu_rm(func3, core_, t, id_);
|
||||
uint32_t fflags = 0;
|
||||
switch (func7) {
|
||||
case 0x00: //FADD
|
||||
case 0x00: // RV32F: FADD
|
||||
rddata = rv_fadd(rsdata[0], rsdata[1], frm, &fflags);
|
||||
break;
|
||||
case 0x04: //FSUB
|
||||
case 0x04: // RV32F: FSUB
|
||||
rddata = rv_fsub(rsdata[0], rsdata[1], frm, &fflags);
|
||||
break;
|
||||
case 0x08: //FMUL
|
||||
case 0x08: // RV32F: FMUL
|
||||
rddata = rv_fmul(rsdata[0], rsdata[1], frm, &fflags);
|
||||
break;
|
||||
case 0x0c: //FDIV
|
||||
case 0x0c: // RV32F: FDIV
|
||||
rddata = rv_fdiv(rsdata[0], rsdata[1], frm, &fflags);
|
||||
break;
|
||||
case 0x2c: //FSQRT
|
||||
case 0x2c: // RV32F: FSQRT
|
||||
rddata = rv_fsqrt(rsdata[0], frm, &fflags);
|
||||
break;
|
||||
case 0x10:
|
||||
switch (func3) {
|
||||
case 0: // FSGNJ.S
|
||||
case 0: // RV32F: FSGNJ.S
|
||||
rddata = rv_fsgnj(rsdata[0], rsdata[1]);
|
||||
break;
|
||||
case 1: // FSGNJN.S
|
||||
case 1: // RV32F: FSGNJN.S
|
||||
rddata = rv_fsgnjn(rsdata[0], rsdata[1]);
|
||||
break;
|
||||
case 2: // FSGNJX.S
|
||||
case 2: // RV32F: FSGNJX.S
|
||||
rddata = rv_fsgnjx(rsdata[0], rsdata[1]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x14:
|
||||
if (func3) {
|
||||
// FMAX.S
|
||||
// RV32F: FMAX.S
|
||||
rddata = rv_fmax(rsdata[0], rsdata[1], &fflags);
|
||||
} else {
|
||||
// FMIN.S
|
||||
// RV32F: FMIN.S
|
||||
rddata = rv_fmin(rsdata[0], rsdata[1], &fflags);
|
||||
}
|
||||
break;
|
||||
case 0x60:
|
||||
if (rsrc1 == 0) {
|
||||
// FCVT.W.S
|
||||
rddata = rv_ftoi(rsdata[0], frm, &fflags);
|
||||
} else {
|
||||
// FCVT.WU.S
|
||||
rddata = rv_ftou(rsdata[0], frm, &fflags);
|
||||
switch(rsrc1) {
|
||||
case 0:
|
||||
// RV32F: FCVT.W.S
|
||||
rddata = signExt(rv_ftoi(rsdata[0], frm, &fflags), 32, 0xFFFFFFFF);
|
||||
break;
|
||||
case 1:
|
||||
// RV32F: FCVT.WU.S
|
||||
rddata = signExt(rv_ftou(rsdata[0], frm, &fflags), 32, 0xFFFFFFFF);
|
||||
break;
|
||||
case 2:
|
||||
// RV64F: FCVT.L.S
|
||||
rddata = rv_ftol(rsdata[0], frm, &fflags);
|
||||
break;
|
||||
case 3:
|
||||
// RV64F: FCVT.LU.S
|
||||
rddata = rv_ftolu(rsdata[0], frm, &fflags);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x70:
|
||||
if (func3) {
|
||||
// FCLASS.S
|
||||
// RV32F: FCLASS.S
|
||||
rddata = rv_fclss(rsdata[0]);
|
||||
} else {
|
||||
// FMV.X.W
|
||||
rddata = rsdata[0];
|
||||
// RV32F: FMV.X.W
|
||||
rddata = signExt((Word)rsdata[0], 32, 0xFFFFFFFF);
|
||||
}
|
||||
break;
|
||||
case 0x50:
|
||||
switch(func3) {
|
||||
case 0:
|
||||
// FLE.S
|
||||
// RV32F: FLE.S
|
||||
rddata = rv_fle(rsdata[0], rsdata[1], &fflags);
|
||||
break;
|
||||
case 1:
|
||||
// FLT.S
|
||||
// RV32F: FLT.S
|
||||
rddata = rv_flt(rsdata[0], rsdata[1], &fflags);
|
||||
break;
|
||||
case 2:
|
||||
// FEQ.S
|
||||
// RV32F: FEQ.S
|
||||
rddata = rv_feq(rsdata[0], rsdata[1], &fflags);
|
||||
break;
|
||||
} break;
|
||||
case 0x68:
|
||||
if (rsrc1) {
|
||||
// FCVT.S.WU:
|
||||
rddata = rv_utof(rsdata[0], frm, &fflags);
|
||||
} else {
|
||||
// FCVT.S.W:
|
||||
rddata = rv_itof(rsdata[0], frm, &fflags);
|
||||
switch(rsrc1) {
|
||||
case 0:
|
||||
// RV32F: FCVT.S.W
|
||||
rddata = rv_itof(rsdata[0], frm, &fflags);
|
||||
break;
|
||||
case 1:
|
||||
// RV32F: FCVT.S.WU
|
||||
rddata = rv_utof(rsdata[0], frm, &fflags);
|
||||
break;
|
||||
case 2:
|
||||
// RV64F: FCVT.S.L
|
||||
rddata = rv_ltof(rsdata[0], frm, &fflags);
|
||||
break;
|
||||
case 3:
|
||||
// RV64F: FCVT.S.LU
|
||||
rddata = rv_lutof(rsdata[0], frm, &fflags);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x78:
|
||||
// FMV.W.X
|
||||
// RV32F: FMV.W.X
|
||||
rddata = rsdata[0];
|
||||
break;
|
||||
}
|
||||
|
@ -689,21 +752,25 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
case FMSUB:
|
||||
case FMNMADD:
|
||||
case FMNMSUB: {
|
||||
// int frm = get_fpu_rm(func3, core_, t, id_);
|
||||
int frm = get_fpu_rm(func3, core_, t, id_);
|
||||
// simx64
|
||||
Word fflags = 0;
|
||||
switch (opcode) {
|
||||
case FMADD:
|
||||
// rddata = rv_fmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
||||
// RV32F: FMADD
|
||||
rddata = rv_fmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
||||
break;
|
||||
case FMSUB:
|
||||
// rddata = rv_fmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
||||
// RV32F: FMSUB
|
||||
rddata = rv_fmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
||||
break;
|
||||
case FMNMADD:
|
||||
// rddata = rv_fnmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
||||
// RV32F: FNMADD
|
||||
rddata = rv_fnmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
||||
break;
|
||||
case FMNMSUB:
|
||||
// rddata = rv_fnmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
||||
// RV32F: FNMSUB
|
||||
rddata = rv_fnmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -34,7 +34,7 @@ enum Opcode {
|
|||
// GPGPU Extension
|
||||
GPGPU = 0x6b,
|
||||
// simx64
|
||||
// RV64I Extension
|
||||
// RV64 Standard Extensions
|
||||
R_INST_64 = 0x3b,
|
||||
I_INST_64 = 0x1b,
|
||||
};
|
||||
|
@ -73,39 +73,39 @@ public:
|
|||
void setSrcFReg(int srcReg) { rsrc_type_[num_rsrcs_] = 2; rsrc_[num_rsrcs_++] = srcReg; }
|
||||
void setDestVReg(int destReg) { rdest_type_ = 3; rdest_ = destReg; }
|
||||
void setSrcVReg(int srcReg) { rsrc_type_[num_rsrcs_] = 3; rsrc_[num_rsrcs_++] = srcReg; }
|
||||
void setFunc3(HalfWord func3) { func3_ = func3; }
|
||||
void setFunc7(HalfWord func7) { func7_ = func7; }
|
||||
void setImm(Word imm) { has_imm_ = true; imm_ = imm; }
|
||||
void setVlsWidth(HalfWord width) { vlsWidth_ = width; }
|
||||
void setVmop(HalfWord mop) { vMop_ = mop; }
|
||||
void setVnf(HalfWord nf) { vNf_ = nf; }
|
||||
void setVmask(HalfWord mask) { vmask_ = mask; }
|
||||
void setVs3(HalfWord vs) { vs3_ = vs; }
|
||||
void setVlmul(HalfWord lmul) { vlmul_ = 1 << lmul; }
|
||||
void setVsew(HalfWord sew) { vsew_ = 1 << (3+sew); }
|
||||
void setVediv(HalfWord ediv) { vediv_ = 1 << ediv; }
|
||||
void setFunc6(HalfWord func6) { func6_ = func6; }
|
||||
void setFunc3(Word func3) { func3_ = func3; }
|
||||
void setFunc7(Word func7) { func7_ = func7; }
|
||||
void setImm(DoubleWord imm) { has_imm_ = true; imm_ = imm; }
|
||||
void setVlsWidth(Word width) { vlsWidth_ = width; }
|
||||
void setVmop(Word mop) { vMop_ = mop; }
|
||||
void setVnf(Word nf) { vNf_ = nf; }
|
||||
void setVmask(Word mask) { vmask_ = mask; }
|
||||
void setVs3(Word vs) { vs3_ = vs; }
|
||||
void setVlmul(Word lmul) { vlmul_ = 1 << lmul; }
|
||||
void setVsew(Word sew) { vsew_ = 1 << (3+sew); }
|
||||
void setVediv(Word ediv) { vediv_ = 1 << ediv; }
|
||||
void setFunc6(Word func6) { func6_ = func6; }
|
||||
|
||||
/* Getters used by encoders. */
|
||||
Opcode getOpcode() const { return opcode_; }
|
||||
HalfWord getFunc3() const { return func3_; }
|
||||
HalfWord getFunc6() const { return func6_; }
|
||||
HalfWord getFunc7() const { return func7_; }
|
||||
Word getFunc3() const { return func3_; }
|
||||
Word getFunc6() const { return func6_; }
|
||||
Word getFunc7() const { return func7_; }
|
||||
int getNRSrc() const { return num_rsrcs_; }
|
||||
int getRSrc(int i) const { return rsrc_[i]; }
|
||||
int getRSType(int i) const { return rsrc_type_[i]; }
|
||||
int getRDest() const { return rdest_; }
|
||||
int getRDType() const { return rdest_type_; }
|
||||
bool hasImm() const { return has_imm_; }
|
||||
Word getImm() const { return imm_; }
|
||||
HalfWord getVlsWidth() const { return vlsWidth_; }
|
||||
HalfWord getVmop() const { return vMop_; }
|
||||
HalfWord getvNf() const { return vNf_; }
|
||||
HalfWord getVmask() const { return vmask_; }
|
||||
HalfWord getVs3() const { return vs3_; }
|
||||
HalfWord getVlmul() const { return vlmul_; }
|
||||
HalfWord getVsew() const { return vsew_; }
|
||||
HalfWord getVediv() const { return vediv_; }
|
||||
DoubleWord getImm() const { return imm_; }
|
||||
Word getVlsWidth() const { return vlsWidth_; }
|
||||
Word getVmop() const { return vMop_; }
|
||||
Word getvNf() const { return vNf_; }
|
||||
Word getVmask() const { return vmask_; }
|
||||
Word getVs3() const { return vs3_; }
|
||||
Word getVlmul() const { return vlmul_; }
|
||||
Word getVsew() const { return vsew_; }
|
||||
Word getVediv() const { return vediv_; }
|
||||
|
||||
private:
|
||||
|
||||
|
@ -120,23 +120,23 @@ private:
|
|||
int isrc_mask_;
|
||||
int fsrc_mask_;
|
||||
int vsrc_mask_;
|
||||
Word imm_;
|
||||
DoubleWord imm_;
|
||||
int rsrc_type_[MAX_REG_SOURCES];
|
||||
int rsrc_[MAX_REG_SOURCES];
|
||||
int rdest_;
|
||||
HalfWord func3_;
|
||||
HalfWord func7_;
|
||||
Word func3_;
|
||||
Word func7_;
|
||||
|
||||
//Vector
|
||||
HalfWord vmask_;
|
||||
HalfWord vlsWidth_;
|
||||
HalfWord vMop_;
|
||||
HalfWord vNf_;
|
||||
HalfWord vs3_;
|
||||
HalfWord vlmul_;
|
||||
HalfWord vsew_;
|
||||
HalfWord vediv_;
|
||||
HalfWord func6_;
|
||||
Word vmask_;
|
||||
Word vlsWidth_;
|
||||
Word vMop_;
|
||||
Word vNf_;
|
||||
Word vs3_;
|
||||
Word vlmul_;
|
||||
Word vsew_;
|
||||
Word vediv_;
|
||||
Word func6_;
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &, const Instr&);
|
||||
};
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
|
||||
//--
|
||||
int wid;
|
||||
Word PC;
|
||||
DoubleWord PC;
|
||||
|
||||
//--
|
||||
int rdest_type;
|
||||
|
|
|
@ -7,13 +7,12 @@
|
|||
namespace vortex {
|
||||
|
||||
typedef uint8_t Byte;
|
||||
// simx64
|
||||
typedef uint64_t Word;
|
||||
typedef int64_t WordI;
|
||||
typedef uint32_t Word;
|
||||
typedef int32_t WordI;
|
||||
|
||||
// simx64
|
||||
typedef uint32_t HalfWord;
|
||||
typedef int32_t HalfWordI;
|
||||
typedef uint64_t DoubleWord;
|
||||
typedef int64_t DoubleWordI;
|
||||
|
||||
// simx64
|
||||
typedef uint64_t Addr;
|
||||
|
|
|
@ -14,8 +14,8 @@ Warp::Warp(Core *core, Word id)
|
|||
: id_(id)
|
||||
, core_(core) {
|
||||
// simx64
|
||||
iRegFile_.resize(core_->arch().num_threads(), std::vector<Word>(core_->arch().num_regs(), 0));
|
||||
fRegFile_.resize(core_->arch().num_threads(), std::vector<Word>(core_->arch().num_regs(), 0));
|
||||
iRegFile_.resize(core_->arch().num_threads(), std::vector<DoubleWord>(core_->arch().num_regs(), 0));
|
||||
fRegFile_.resize(core_->arch().num_threads(), std::vector<DoubleWord>(core_->arch().num_regs(), 0));
|
||||
vRegFile_.resize(core_->arch().num_regs(), std::vector<Byte>(core_->arch().vsize(), 0));
|
||||
this->clear();
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ void Warp::step(Pipeline *pipeline) {
|
|||
|
||||
/* Fetch and decode. */
|
||||
|
||||
HalfWord fetched = core_->icache_fetch(PC_);
|
||||
Word fetched = core_->icache_fetch(PC_);
|
||||
auto instr = core_->decoder().decode(fetched, PC_);
|
||||
|
||||
// Update pipeline
|
||||
|
@ -86,10 +86,12 @@ void Warp::step(Pipeline *pipeline) {
|
|||
D(4, "Register state:");
|
||||
for (int i = 0; i < core_->arch().num_regs(); ++i) {
|
||||
DPN(4, " %r" << std::setfill('0') << std::setw(2) << std::dec << i << ':');
|
||||
for (int j = 0; j < core_->arch().num_threads(); ++j) {
|
||||
// simx64
|
||||
DPN(4, ' ' << std::setfill('0') << std::setw(16) << std::hex << iRegFile_[j][i] << std::setfill(' ') << ' ');
|
||||
}
|
||||
// for (int j = 0; j < core_->arch().num_threads(); ++j) {
|
||||
// // simx64
|
||||
// DPN(4, ' ' << std::setfill('0') << std::setw(16) << std::hex << iRegFile_[j][i] << std::setfill(' ') << ' ');
|
||||
// }
|
||||
DPN(4, ' ' << std::setfill('0') << std::setw(16) << std::hex << iRegFile_[0][i] << std::setfill(' ') << ' ');
|
||||
DPN(4, ' ' << std::setfill('0') << std::setw(16) << std::hex << fRegFile_[0][i] << std::setfill(' ') << ' ');
|
||||
DPN(4, std::endl);
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ class Core;
|
|||
class Instr;
|
||||
class Pipeline;
|
||||
struct DomStackEntry {
|
||||
DomStackEntry(const ThreadMask &tmask, Word PC)
|
||||
DomStackEntry(const ThreadMask &tmask, DoubleWord PC)
|
||||
: tmask(tmask)
|
||||
, PC(PC)
|
||||
, fallThrough(false)
|
||||
|
@ -26,7 +26,7 @@ struct DomStackEntry {
|
|||
{}
|
||||
|
||||
ThreadMask tmask;
|
||||
Word PC;
|
||||
DoubleWord PC;
|
||||
bool fallThrough;
|
||||
bool unanimous;
|
||||
};
|
||||
|
@ -62,11 +62,11 @@ public:
|
|||
return id_;
|
||||
}
|
||||
|
||||
Word getPC() const {
|
||||
DoubleWord getPC() const {
|
||||
return PC_;
|
||||
}
|
||||
|
||||
void setPC(Word PC) {
|
||||
void setPC(DoubleWord PC) {
|
||||
PC_ = PC;
|
||||
}
|
||||
|
||||
|
@ -95,12 +95,12 @@ private:
|
|||
bool active_;
|
||||
Core *core_;
|
||||
|
||||
Word PC_;
|
||||
DoubleWord PC_;
|
||||
ThreadMask tmask_;
|
||||
|
||||
// simx64
|
||||
std::vector<std::vector<Word>> iRegFile_;
|
||||
std::vector<std::vector<Word>> fRegFile_;
|
||||
std::vector<std::vector<DoubleWord>> iRegFile_;
|
||||
std::vector<std::vector<DoubleWord>> fRegFile_;
|
||||
std::vector<std::vector<Byte>> vRegFile_;
|
||||
std::stack<DomStackEntry> domStack_;
|
||||
|
||||
|
|
|
@ -1,16 +1,30 @@
|
|||
ALL_TESTS := $(wildcard *.hex)
|
||||
# ALL_TESTS := $(wildcard *.hex)
|
||||
|
||||
D_TESTS := $(wildcard *ud-p-*.hex)
|
||||
V_TESTS := $(wildcard *-v-*.hex)
|
||||
M_TESTS := $(wildcard *um-*.hex)
|
||||
A_TESTS := $(wildcard *ua-*.hex)
|
||||
# D_TESTS := $(wildcard *ud-p-*.hex)
|
||||
# V_TESTS := $(wildcard *-v-*.hex)
|
||||
# M_TESTS := $(wildcard *um-*.hex)
|
||||
# A_TESTS := $(wildcard *ua-*.hex)
|
||||
|
||||
EXCLUDED_TESTS := $(V_TESTS) $(D_TESTS) $(M_TESTS) $(A_TESTS) rv32si-p-scall.hex rv32si-p-sbreak.hex rv32mi-p-breakpoint.hex rv32ua-p-amomax_w.hex rv32ua-p-amoxor_w.hex rv32ua-p-amoor_w.hex rv32mi-p-ma_addr.hex rv32mi-p-mcsr.hex rv32ua-p-amoswap_w.hex rv32mi-p-ma_fetch.hex rv32mi-p-csr.hex rv32ua-p-amoadd_w.hex rv32si-p-dirty.hex rv32ui-p-fence_i.hex rv32si-p-csr.hex rv32mi-p-shamt.hex rv32ua-p-amomin_w.hex rv32ua-p-lrsc.hex rv32si-p-wfi.hex rv32ua-p-amomaxu_w.hex rv32si-p-ma_fetch.hex rv32mi-p-illegal.hex rv32uc-p-rvc.hex rv32mi-p-sbreak.hex rv32ua-p-amominu_w.hex rv32ua-p-amoand_w.hex
|
||||
# EXCLUDED_TESTS := $(V_TESTS) $(D_TESTS) $(M_TESTS) $(A_TESTS) rv32si-p-scall.hex rv32si-p-sbreak.hex rv32mi-p-breakpoint.hex rv32ua-p-amomax_w.hex rv32ua-p-amoxor_w.hex rv32ua-p-amoor_w.hex rv32mi-p-ma_addr.hex rv32mi-p-mcsr.hex rv32ua-p-amoswap_w.hex rv32mi-p-ma_fetch.hex rv32mi-p-csr.hex rv32ua-p-amoadd_w.hex rv32si-p-dirty.hex rv32ui-p-fence_i.hex rv32si-p-csr.hex rv32mi-p-shamt.hex rv32ua-p-amomin_w.hex rv32ua-p-lrsc.hex rv32si-p-wfi.hex rv32ua-p-amomaxu_w.hex rv32si-p-ma_fetch.hex rv32mi-p-illegal.hex rv32uc-p-rvc.hex rv32mi-p-sbreak.hex rv32ua-p-amominu_w.hex rv32ua-p-amoand_w.hex
|
||||
|
||||
TESTS := $(filter-out $(EXCLUDED_TESTS), $(ALL_TESTS))
|
||||
# TESTS := $(filter-out $(EXCLUDED_TESTS), $(ALL_TESTS))
|
||||
|
||||
I_TESTS := $(wildcard *ui-p-*.hex)
|
||||
M_TESTS := $(wildcard *um-p-*.hex)
|
||||
F_TESTS := $(wildcard *uf-p-*.hex)
|
||||
TESTS := $(I_TESTS) $(M_TESTS) $(F_TESTS)
|
||||
|
||||
all:
|
||||
|
||||
run-simx-i:
|
||||
$(foreach test, $(I_TESTS), ../../../sim/simX/simX -r -a rv64i -c 1 -i $(test) || exit;)
|
||||
|
||||
run-simx-m:
|
||||
$(foreach test, $(M_TESTS), ../../../sim/simX/simX -r -a rv64i -c 1 -i $(test) || exit;)
|
||||
|
||||
run-simx-f:
|
||||
$(foreach test, $(F_TESTS), ../../../sim/simX/simX -r -a rv64i -c 1 -i $(test) || exit;)
|
||||
|
||||
run-simx:
|
||||
$(foreach test, $(TESTS), ../../../sim/simX/simX -r -a rv64i -c 1 -i $(test) || exit;)
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain
|
||||
RISCV_TOOLCHAIN_PATH = /nethome/ssrivatsan8/riscv32
|
||||
RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain
|
||||
VORTEX_RT_PATH ?= $(realpath ../../../runtime)
|
||||
|
||||
CC = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-gcc
|
||||
|
@ -10,7 +9,7 @@ CP = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-objcopy
|
|||
CFLAGS += -march=rv32imf -mabi=ilp32f -O3 -Wstack-usage=1024 -ffreestanding -nostartfiles -fdata-sections -ffunction-sections
|
||||
CFLAGS += -I$(VORTEX_RT_PATH)/include -I$(VORTEX_RT_PATH)/../hw
|
||||
|
||||
LDFLAGS += -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link.ld -Wl,--noinhibit-exec,--gc-sections $(VORTEX_RT_PATH)/libvortexrt.a
|
||||
LDFLAGS += -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link.ld -Wl,--gc-sections $(VORTEX_RT_PATH)/libvortexrt.a
|
||||
|
||||
PROJECT = hello
|
||||
|
||||
|
|
|
@ -7,14 +7,16 @@ AR = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-gcc-ar
|
|||
DP = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-objdump
|
||||
CP = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-objcopy
|
||||
|
||||
CFLAGS += -march=rv64i -mabi=lp64 -O3 -Wstack-usage=1024 -ffreestanding -nostartfiles -fdata-sections -ffunction-sections
|
||||
CFLAGS += -march=rv64imfd -mabi=lp64d -O3 -Wstack-usage=1024 -ffreestanding -nostartfiles -fdata-sections -ffunction-sections
|
||||
CFLAGS += -I$(VORTEX_RT_PATH)/include -I$(VORTEX_RT_PATH)/../hw
|
||||
|
||||
LDFLAGS += -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link64.ld -Wl,--noinhibit-exec,--gc-sections $(VORTEX_RT_PATH)/libvortexrt.a
|
||||
LDFLAGS += -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link64.ld -Wl,--gc-sections
|
||||
|
||||
# $(VORTEX_RT_PATH)/libvortexrt.a
|
||||
|
||||
PROJECT = hello64
|
||||
|
||||
SRCS = main.cpp
|
||||
SRCS = main.cpp $(VORTEX_RT_PATH)/src/vx_start.S $(VORTEX_RT_PATH)/src/vx_syscalls.c
|
||||
|
||||
all: $(PROJECT).elf $(PROJECT).bin $(PROJECT).dump
|
||||
|
||||
|
|
|
@ -2,7 +2,5 @@
|
|||
|
||||
int main()
|
||||
{
|
||||
printf("Hello World!\n");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -10,7 +10,7 @@ CP = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-objcopy
|
|||
CFLAGS += -march=rv64imfd -mabi=lp64d -O3 -Wstack-usage=1024 -ffreestanding -nostartfiles -fdata-sections -ffunction-sections
|
||||
CFLAGS += -I$(VORTEX_RT_PATH)/include -I$(VORTEX_RT_PATH)/../hw
|
||||
|
||||
LDFLAGS += -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link64.ld -Wl,--noinhibit-exec,--gc-sections $(VORTEX_RT_PATH)/libvortexrt.a
|
||||
LDFLAGS += -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link64.ld -Wl,--gc-sections $(VORTEX_RT_PATH)/libvortexrt.a
|
||||
|
||||
PROJECT = simple64
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue