Added support for RV64I instructions
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain
|
RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain
|
||||||
# simx64
|
# simx64
|
||||||
RISCV64_TOOLCHAIN_PATH ?= /nethome/ssrivatsan8/riscv64-unknown-elf-toolchain
|
RISCV64_TOOLCHAIN_PATH ?= /nethome/ssrivatsan8/riscv
|
||||||
|
|
||||||
|
|
||||||
CC = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-gcc
|
CC = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-gcc
|
||||||
@@ -8,7 +8,7 @@ AR = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-gcc-ar
|
|||||||
DP = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-objdump
|
DP = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-objdump
|
||||||
CP = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-objcopy
|
CP = $(RISCV64_TOOLCHAIN_PATH)/bin/riscv64-unknown-elf-objcopy
|
||||||
|
|
||||||
CFLAGS += -O3 -march=rv64imfd -mabi=lp64d -Wstack-usage=1024 -fno-exceptions -fdata-sections -ffunction-sections
|
CFLAGS += -O3 -march=rv64i -mabi=lp64 -Wstack-usage=1024 -fno-exceptions -fdata-sections -ffunction-sections
|
||||||
CFLAGS += -I./include -I../hw
|
CFLAGS += -I./include -I../hw
|
||||||
|
|
||||||
PROJECT = libvortexrt
|
PROJECT = libvortexrt
|
||||||
|
|||||||
@@ -22,7 +22,14 @@ inline uint64_t align_size(uint64_t size, uint64_t alignment) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply integer sign extension
|
// Apply integer sign extension
|
||||||
inline uint32_t signExt(uint32_t w, uint32_t bit, uint32_t mask) {
|
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) {
|
||||||
if (w >> (bit - 1))
|
if (w >> (bit - 1))
|
||||||
w |= ~mask;
|
w |= ~mask;
|
||||||
return w;
|
return w;
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ public:
|
|||||||
int num_cores,
|
int num_cores,
|
||||||
int num_warps,
|
int num_warps,
|
||||||
int num_threads) {
|
int num_threads) {
|
||||||
wsize_ = 4;
|
// simx64
|
||||||
|
wsize_ = 8;
|
||||||
vsize_ = 16;
|
vsize_ = 16;
|
||||||
num_regs_ = 32;
|
num_regs_ = 32;
|
||||||
num_csrs_ = 4096;
|
num_csrs_ = 4096;
|
||||||
|
|||||||
@@ -107,8 +107,12 @@ static const char* op_string(const Instr &instr) {
|
|||||||
case 0: return "LBI";
|
case 0: return "LBI";
|
||||||
case 1: return "LHI";
|
case 1: return "LHI";
|
||||||
case 2: return "LW";
|
case 2: return "LW";
|
||||||
|
// simx64
|
||||||
|
case 3: return "LD";
|
||||||
case 4: return "LBU";
|
case 4: return "LBU";
|
||||||
case 5: return "LHU";
|
case 5: return "LHU";
|
||||||
|
// simx64
|
||||||
|
case 6: return "LWU";
|
||||||
default:
|
default:
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
@@ -117,6 +121,8 @@ static const char* op_string(const Instr &instr) {
|
|||||||
case 0: return "SB";
|
case 0: return "SB";
|
||||||
case 1: return "SH";
|
case 1: return "SH";
|
||||||
case 2: return "SW";
|
case 2: return "SW";
|
||||||
|
// simx64
|
||||||
|
case 3: return "SD";
|
||||||
default:
|
default:
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
@@ -301,7 +307,7 @@ Decoder::Decoder(const ArchDef &arch) {
|
|||||||
v_imm_mask_ = 0x7ff;
|
v_imm_mask_ = 0x7ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Instr> Decoder::decode(Word code, Word PC) {
|
std::shared_ptr<Instr> Decoder::decode(uint32_t code, uint32_t PC) {
|
||||||
auto instr = std::make_shared<Instr>();
|
auto instr = std::make_shared<Instr>();
|
||||||
Opcode op = (Opcode)((code >> shift_opcode_) & opcode_mask_);
|
Opcode op = (Opcode)((code >> shift_opcode_) & opcode_mask_);
|
||||||
instr->setOpcode(op);
|
instr->setOpcode(op);
|
||||||
@@ -310,10 +316,11 @@ std::shared_ptr<Instr> Decoder::decode(Word code, Word PC) {
|
|||||||
Word func6 = (code >> shift_func6_) & func6_mask_;
|
Word func6 = (code >> shift_func6_) & func6_mask_;
|
||||||
Word func7 = (code >> shift_func7_) & func7_mask_;
|
Word func7 = (code >> shift_func7_) & func7_mask_;
|
||||||
|
|
||||||
int rd = (code >> shift_rd_) & reg_mask_;
|
// simx64
|
||||||
int rs1 = (code >> shift_rs1_) & reg_mask_;
|
long rd = (code >> shift_rd_) & reg_mask_;
|
||||||
int rs2 = (code >> shift_rs2_) & reg_mask_;
|
long rs1 = (code >> shift_rs1_) & reg_mask_;
|
||||||
int rs3 = (code >> shift_rs3_) & reg_mask_;
|
long rs2 = (code >> shift_rs2_) & reg_mask_;
|
||||||
|
long rs3 = (code >> shift_rs3_) & reg_mask_;
|
||||||
|
|
||||||
auto op_it = sc_instTable.find(op);
|
auto op_it = sc_instTable.find(op);
|
||||||
if (op_it == sc_instTable.end()) {
|
if (op_it == sc_instTable.end()) {
|
||||||
@@ -371,7 +378,7 @@ std::shared_ptr<Instr> Decoder::decode(Word code, Word PC) {
|
|||||||
instr->setFunc3(func3);
|
instr->setFunc3(func3);
|
||||||
instr->setFunc7(func7);
|
instr->setFunc7(func7);
|
||||||
if ((func3 == 5) && (op != L_INST) && (op != Opcode::FL)) {
|
if ((func3 == 5) && (op != L_INST) && (op != Opcode::FL)) {
|
||||||
instr->setImm(signExt(rs2, 5, reg_mask_));
|
instr->setImm(signExt(rs2, 6, 0x3F));
|
||||||
} else {
|
} else {
|
||||||
instr->setImm(signExt(code >> shift_rs2_, 12, i_imm_mask_));
|
instr->setImm(signExt(code >> shift_rs2_, 12, i_imm_mask_));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class Decoder {
|
|||||||
public:
|
public:
|
||||||
Decoder(const ArchDef &);
|
Decoder(const ArchDef &);
|
||||||
|
|
||||||
std::shared_ptr<Instr> decode(Word code, Word PC);
|
std::shared_ptr<Instr> decode(uint32_t code, uint32_t PC);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
using namespace vortex;
|
using namespace vortex;
|
||||||
|
|
||||||
static bool HasDivergentThreads(const ThreadMask &thread_mask,
|
static bool HasDivergentThreads(const ThreadMask &thread_mask,
|
||||||
const std::vector<std::vector<DoubleWord>> ®_file,
|
const std::vector<std::vector<Word>> ®_file,
|
||||||
unsigned reg) {
|
unsigned reg) {
|
||||||
bool cond;
|
bool cond;
|
||||||
size_t thread_idx = 0;
|
size_t thread_idx = 0;
|
||||||
@@ -109,7 +109,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
rd_write = true;
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case AUIPC_INST:
|
case AUIPC_INST:
|
||||||
rddata = ((immsrc << 12) & 0xfffff000) + PC_;
|
// simx64
|
||||||
|
rddata = signExt(((immsrc << 12) & 0xfffff000), 32, 0xFFFFFFFF) + PC_;
|
||||||
rd_write = true;
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case R_INST: {
|
case R_INST: {
|
||||||
@@ -199,8 +200,10 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
switch (func3) {
|
switch (func3) {
|
||||||
case 0:
|
case 0:
|
||||||
if (func7) {
|
if (func7) {
|
||||||
|
// RV32I: SUB
|
||||||
rddata = rsdata[0] - rsdata[1];
|
rddata = rsdata[0] - rsdata[1];
|
||||||
} else {
|
} else {
|
||||||
|
// RV32I: ADD
|
||||||
rddata = rsdata[0] + rsdata[1];
|
rddata = rsdata[0] + rsdata[1];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -211,25 +214,32 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
rddata = rsdata[0] << rsdata[1];
|
rddata = rsdata[0] << rsdata[1];
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
// RV32I: SLT (signed)
|
||||||
rddata = (WordI(rsdata[0]) < WordI(rsdata[1]));
|
rddata = (WordI(rsdata[0]) < WordI(rsdata[1]));
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
// RV32I: SLTU (unsigned)
|
||||||
rddata = (Word(rsdata[0]) < Word(rsdata[1]));
|
rddata = (Word(rsdata[0]) < Word(rsdata[1]));
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
|
// RV32I: XOR
|
||||||
rddata = rsdata[0] ^ rsdata[1];
|
rddata = rsdata[0] ^ rsdata[1];
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if (func7) {
|
if (func7) {
|
||||||
|
// RV32I: SRA
|
||||||
rddata = WordI(rsdata[0]) >> WordI(rsdata[1]);
|
rddata = WordI(rsdata[0]) >> WordI(rsdata[1]);
|
||||||
} else {
|
} else {
|
||||||
|
// RV32I: SRL
|
||||||
rddata = Word(rsdata[0]) >> Word(rsdata[1]);
|
rddata = Word(rsdata[0]) >> Word(rsdata[1]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
|
// RV32I: OR
|
||||||
rddata = rsdata[0] | rsdata[1];
|
rddata = rsdata[0] | rsdata[1];
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
|
// RV32I: AND
|
||||||
rddata = rsdata[0] & rsdata[1];
|
rddata = rsdata[0] & rsdata[1];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -241,42 +251,42 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
case I_INST:
|
case I_INST:
|
||||||
switch (func3) {
|
switch (func3) {
|
||||||
case 0:
|
case 0:
|
||||||
// ADDI
|
// RV32I: ADDI
|
||||||
rddata = rsdata[0] + immsrc;
|
rddata = rsdata[0] + immsrc;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// SLLI
|
// RV64I: SLLI
|
||||||
rddata = rsdata[0] << immsrc;
|
rddata = rsdata[0] << immsrc;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
// SLTI
|
// RV32I: SLTI
|
||||||
rddata = (WordI(rsdata[0]) < WordI(immsrc));
|
rddata = (WordI(rsdata[0]) < WordI(immsrc));
|
||||||
break;
|
break;
|
||||||
case 3: {
|
case 3: {
|
||||||
// SLTIU
|
// RV32I: SLTIU
|
||||||
rddata = (Word(rsdata[0]) < Word(immsrc));
|
rddata = (Word(rsdata[0]) < Word(immsrc));
|
||||||
} break;
|
} break;
|
||||||
case 4:
|
case 4:
|
||||||
// XORI
|
// RV32I: XORI
|
||||||
rddata = rsdata[0] ^ immsrc;
|
rddata = rsdata[0] ^ immsrc;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if (func7) {
|
if (func7) {
|
||||||
// SRAI
|
// RV64I: SRAI
|
||||||
Word result = WordI(rsdata[0]) >> immsrc;
|
Word result = WordI(rsdata[0]) >> immsrc;
|
||||||
rddata = result;
|
rddata = result;
|
||||||
} else {
|
} else {
|
||||||
// SRLI
|
// RV64I: SRLI
|
||||||
Word result = Word(rsdata[0]) >> immsrc;
|
Word result = Word(rsdata[0]) >> immsrc;
|
||||||
rddata = result;
|
rddata = result;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
// ORI
|
// RV32I: ORI
|
||||||
rddata = rsdata[0] | immsrc;
|
rddata = rsdata[0] | immsrc;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
// ANDI
|
// RV32I: ANDI
|
||||||
rddata = rsdata[0] & immsrc;
|
rddata = rsdata[0] & immsrc;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -287,37 +297,37 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
case B_INST:
|
case B_INST:
|
||||||
switch (func3) {
|
switch (func3) {
|
||||||
case 0:
|
case 0:
|
||||||
// BEQ
|
// RV32I: BEQ
|
||||||
if (rsdata[0] == rsdata[1]) {
|
if (rsdata[0] == rsdata[1]) {
|
||||||
nextPC = PC_ + immsrc;
|
nextPC = PC_ + immsrc;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// BNE
|
// RV32I: BNE
|
||||||
if (rsdata[0] != rsdata[1]) {
|
if (rsdata[0] != rsdata[1]) {
|
||||||
nextPC = PC_ + immsrc;
|
nextPC = PC_ + immsrc;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
// BLT
|
// RV32I: BLT
|
||||||
if (WordI(rsdata[0]) < WordI(rsdata[1])) {
|
if (WordI(rsdata[0]) < WordI(rsdata[1])) {
|
||||||
nextPC = PC_ + immsrc;
|
nextPC = PC_ + immsrc;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
// BGE
|
// RV32I: BGE
|
||||||
if (WordI(rsdata[0]) >= WordI(rsdata[1])) {
|
if (WordI(rsdata[0]) >= WordI(rsdata[1])) {
|
||||||
nextPC = PC_ + immsrc;
|
nextPC = PC_ + immsrc;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
// BLTU
|
// RV32I: BLTU
|
||||||
if (Word(rsdata[0]) < Word(rsdata[1])) {
|
if (Word(rsdata[0]) < Word(rsdata[1])) {
|
||||||
nextPC = PC_ + immsrc;
|
nextPC = PC_ + immsrc;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
// BGEU
|
// RV32I: BGEU
|
||||||
if (Word(rsdata[0]) >= Word(rsdata[1])) {
|
if (Word(rsdata[0]) >= Word(rsdata[1])) {
|
||||||
nextPC = PC_ + immsrc;
|
nextPC = PC_ + immsrc;
|
||||||
}
|
}
|
||||||
@@ -326,6 +336,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
pipeline->stall_warp = true;
|
pipeline->stall_warp = true;
|
||||||
runOnce = true;
|
runOnce = true;
|
||||||
break;
|
break;
|
||||||
|
// RV32I: JAL
|
||||||
case JAL_INST:
|
case JAL_INST:
|
||||||
rddata = nextPC;
|
rddata = nextPC;
|
||||||
nextPC = PC_ + immsrc;
|
nextPC = PC_ + immsrc;
|
||||||
@@ -333,9 +344,10 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
runOnce = true;
|
runOnce = true;
|
||||||
rd_write = true;
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
|
// RV32I: JALR
|
||||||
case JALR_INST:
|
case JALR_INST:
|
||||||
rddata = nextPC;
|
rddata = nextPC;
|
||||||
nextPC = rsdata[0] + immsrc;
|
nextPC = HalfWord(rsdata[0]) + HalfWord(immsrc);
|
||||||
pipeline->stall_warp = true;
|
pipeline->stall_warp = true;
|
||||||
runOnce = true;
|
runOnce = true;
|
||||||
rd_write = true;
|
rd_write = true;
|
||||||
@@ -343,29 +355,37 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
case L_INST: {
|
case L_INST: {
|
||||||
Word memAddr = ((rsdata[0] + immsrc) & 0xFFFFFFFC); // word aligned
|
Word memAddr = ((rsdata[0] + immsrc) & 0xFFFFFFFC); // word aligned
|
||||||
Word shift_by = ((rsdata[0] + immsrc) & 0x00000003) * 8;
|
Word shift_by = ((rsdata[0] + immsrc) & 0x00000003) * 8;
|
||||||
Word data_read = core_->dcache_read(memAddr, 4);
|
Word data_read = core_->dcache_read(memAddr, 8);
|
||||||
D(3, "LOAD MEM: ADDRESS=0x" << std::hex << memAddr << ", DATA=0x" << data_read);
|
D(3, "LOAD MEM: ADDRESS=0x" << std::hex << memAddr << ", DATA=0x" << data_read);
|
||||||
switch (func3) {
|
switch (func3) {
|
||||||
case 0:
|
case 0:
|
||||||
// LBI
|
// RV32I: LBI
|
||||||
rddata = signExt((data_read >> shift_by) & 0xFF, 8, 0xFF);
|
rddata = signExt((data_read >> shift_by) & 0xFF, 8, 0xFF);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// LHI
|
// RV32I: LHI
|
||||||
rddata = signExt((data_read >> shift_by) & 0xFFFF, 16, 0xFFFF);
|
rddata = signExt((data_read >> shift_by) & 0xFFFF, 16, 0xFFFF);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
// LW
|
// RV32I: LW
|
||||||
|
rddata = signExt((data_read >> shift_by) & 0xFFFFFFFF, 32, 0xFFFFFFFF);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
// RV64I: LD
|
||||||
rddata = data_read;
|
rddata = data_read;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
// LBU
|
// RV32I: LBU
|
||||||
rddata = Word((data_read >> shift_by) & 0xFF);
|
rddata = Word((data_read >> shift_by) & 0xFF);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
// LHU
|
// RV32I: LHU
|
||||||
rddata = Word((data_read >> shift_by) & 0xFFFF);
|
rddata = Word((data_read >> shift_by) & 0xFFFF);
|
||||||
break;
|
break;
|
||||||
|
case 6:
|
||||||
|
// RV64I: LWU
|
||||||
|
rddata = Word((data_read >> shift_by) & 0xFFFFFFFF);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
@@ -376,16 +396,20 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr);
|
D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr);
|
||||||
switch (func3) {
|
switch (func3) {
|
||||||
case 0:
|
case 0:
|
||||||
// SB
|
// RV32I: SB
|
||||||
core_->dcache_write(memAddr, rsdata[1] & 0x000000FF, 1);
|
core_->dcache_write(memAddr, rsdata[1] & 0x000000FF, 1);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// SH
|
// RV32I: SH
|
||||||
core_->dcache_write(memAddr, rsdata[1], 2);
|
core_->dcache_write(memAddr, rsdata[1] & 0x0000FFFF, 2);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
// SW
|
// RV32I: SW
|
||||||
core_->dcache_write(memAddr, rsdata[1], 4);
|
core_->dcache_write(memAddr, rsdata[1] & 0xFFFFFFFF, 4);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
// RV64I: SD
|
||||||
|
core_ ->dcache_write(memAddr, rsdata[1], 8);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
std::abort();
|
std::abort();
|
||||||
@@ -396,65 +420,68 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
switch (func3) {
|
switch (func3) {
|
||||||
case 0:
|
case 0:
|
||||||
if (func7){
|
if (func7){
|
||||||
// SUBW
|
// RV64I: SUBW
|
||||||
rddata = DoubleWord(rsdata[0] - rsdata[1]);
|
rddata = signExt((HalfWord)rsdata[0] - (HalfWord)rsdata[1], 32, 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// ADDW
|
// RV64I: ADDW
|
||||||
rddata = DoubleWord(rsdata[0] + rsdata[1]);
|
rddata = signExt((HalfWord)rsdata[0] + (HalfWord)rsdata[1], 32, 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// SLLW
|
// RV64I: SLLW
|
||||||
// shift amount given by rs2[4:0]
|
// shift amount given by rs2[4:0]
|
||||||
rddata = DoubleWord(rsdata[0] << rsdata[1]);
|
rddata = signExt((HalfWord)rsdata[0] << (HalfWord)rsdata[1], 32, 0xFFFFFFFF);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if (func7) {
|
if (func7) {
|
||||||
// SRAW
|
// RV64I: SRAW
|
||||||
// shift amount given by rs2[4:0]
|
// shift amount given by rs2[4:0]
|
||||||
rddata = DoubleWord(WordI(rsdata[0]) >> WordI(rsdata[1]));
|
rddata = signExt((HalfWordI)rsdata[0] >> (HalfWordI)rsdata[1], 32, 0xFFFFFFFF);
|
||||||
} else {
|
} else {
|
||||||
// SRLW
|
// RV64I: SRLW
|
||||||
// shift amount given by rs2[4:0]
|
// shift amount given by rs2[4:0]
|
||||||
rddata = DoubleWord(Word(rsdata[0]) >> Word(rsdata[1]));
|
rddata = signExt((HalfWord)rsdata[0] >> (HalfWord)rsdata[1], 32, 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
rd_write = true;
|
||||||
} break;
|
} break;
|
||||||
// simx64
|
// simx64
|
||||||
case I_INST_64: {
|
case I_INST_64: {
|
||||||
switch (func3) {
|
switch (func3) {
|
||||||
case 0:
|
case 0:
|
||||||
// ADDIW
|
// RV64I: ADDIW
|
||||||
rddata = DoubleWord(rsdata[0] + immsrc);
|
rddata = signExt((HalfWord)rsdata[0] + (HalfWord)immsrc, 32, 0xFFFFFFFF);
|
||||||
|
printf("rddata\n");
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// SLLIW
|
// RV64I: SLLIW
|
||||||
// rs1 shifted by lower 5 bits of imm
|
// rs1 shifted by lower 5 bits of imm
|
||||||
// Illegal exception if imm[5] != 0
|
// Illegal exception if imm[5] != 0
|
||||||
rddata = DoubleWord(rsdata[0] << immsrc);
|
rddata = signExt((HalfWord)rsdata[0] << (HalfWord)immsrc, 32, 0xFFFFFFFF);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if (func7) {
|
if (func7) {
|
||||||
// SRAI
|
// RV64I: SRAI
|
||||||
// rs1 shifted by lower 5 bits of imm
|
// rs1 shifted by lower 5 bits of imm
|
||||||
// Illegal exception if imm[5] != 0
|
// Illegal exception if imm[5] != 0
|
||||||
Word result = DoubleWord(WordI(rsdata[0]) >> immsrc);
|
Word result = signExt((HalfWordI)rsdata[0] >> (HalfWordI)immsrc, 32, 0xFFFFFFFF);
|
||||||
rddata = result;
|
rddata = result;
|
||||||
} else {
|
} else {
|
||||||
// SRLI
|
// RV64I: SRLI
|
||||||
// rs1 shifted by lower 5 bits of imm
|
// rs1 shifted by lower 5 bits of imm
|
||||||
// Illegal exception if imm[5] != 0
|
// Illegal exception if imm[5] != 0
|
||||||
Word result = DoubleWord(Word(rsdata[0]) >> immsrc);
|
Word result = signExt((HalfWord)rsdata[0] >> (HalfWord)immsrc, 32, 0xFFFFFFFF);
|
||||||
rddata = result;
|
rddata = result;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
rd_write = true;
|
||||||
} break;
|
} break;
|
||||||
case SYS_INST: {
|
case SYS_INST: {
|
||||||
Word csr_addr = immsrc & 0x00000FFF;
|
Word csr_addr = immsrc & 0x00000FFF;
|
||||||
@@ -467,37 +494,37 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// CSRRW
|
// RV32I: CSRRW
|
||||||
rddata = csr_value;
|
rddata = csr_value;
|
||||||
core_->set_csr(csr_addr, rsdata[0], t, id_);
|
core_->set_csr(csr_addr, rsdata[0], t, id_);
|
||||||
rd_write = true;
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
// CSRRS
|
// RV32I: CSRRS
|
||||||
rddata = csr_value;
|
rddata = csr_value;
|
||||||
core_->set_csr(csr_addr, csr_value | rsdata[0], t, id_);
|
core_->set_csr(csr_addr, csr_value | rsdata[0], t, id_);
|
||||||
rd_write = true;
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
// CSRRC
|
// RV32I: CSRRC
|
||||||
rddata = csr_value;
|
rddata = csr_value;
|
||||||
core_->set_csr(csr_addr, csr_value & ~rsdata[0], t, id_);
|
core_->set_csr(csr_addr, csr_value & ~rsdata[0], t, id_);
|
||||||
rd_write = true;
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
// CSRRWI
|
// RV32I: CSRRWI
|
||||||
rddata = csr_value;
|
rddata = csr_value;
|
||||||
core_->set_csr(csr_addr, rsrc0, t, id_);
|
core_->set_csr(csr_addr, rsrc0, t, id_);
|
||||||
rd_write = true;
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
// CSRRSI
|
// RV32I: CSRRSI
|
||||||
rddata = csr_value;
|
rddata = csr_value;
|
||||||
core_->set_csr(csr_addr, csr_value | rsrc0, t, id_);
|
core_->set_csr(csr_addr, csr_value | rsrc0, t, id_);
|
||||||
rd_write = true;
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
// CSRRCI
|
// RV32I: CSRRCI
|
||||||
rddata = csr_value;
|
rddata = csr_value;
|
||||||
core_->set_csr(csr_addr, csr_value & ~rsrc0, t, id_);
|
core_->set_csr(csr_addr, csr_value & ~rsrc0, t, id_);
|
||||||
rd_write = true;
|
rd_write = true;
|
||||||
@@ -506,6 +533,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
// RV32I: FENCE
|
||||||
case FENCE:
|
case FENCE:
|
||||||
pipeline->stall_warp = true;
|
pipeline->stall_warp = true;
|
||||||
runOnce = true;
|
runOnce = true;
|
||||||
@@ -661,20 +689,21 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
case FMSUB:
|
case FMSUB:
|
||||||
case FMNMADD:
|
case FMNMADD:
|
||||||
case FMNMSUB: {
|
case FMNMSUB: {
|
||||||
int frm = get_fpu_rm(func3, core_, t, id_);
|
// int frm = get_fpu_rm(func3, core_, t, id_);
|
||||||
|
// simx64
|
||||||
Word fflags = 0;
|
Word fflags = 0;
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case FMADD:
|
case FMADD:
|
||||||
rddata = rv_fmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
// rddata = rv_fmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
||||||
break;
|
break;
|
||||||
case FMSUB:
|
case FMSUB:
|
||||||
rddata = rv_fmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
// rddata = rv_fmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
||||||
break;
|
break;
|
||||||
case FMNMADD:
|
case FMNMADD:
|
||||||
rddata = rv_fnmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
// rddata = rv_fnmadd(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
||||||
break;
|
break;
|
||||||
case FMNMSUB:
|
case FMNMSUB:
|
||||||
rddata = rv_fnmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
// rddata = rv_fnmsub(rsdata[0], rsdata[1], rsdata[2], frm, &fflags);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -7,13 +7,15 @@
|
|||||||
namespace vortex {
|
namespace vortex {
|
||||||
|
|
||||||
typedef uint8_t Byte;
|
typedef uint8_t Byte;
|
||||||
typedef uint32_t Word;
|
typedef uint64_t Word;
|
||||||
typedef int32_t WordI;
|
typedef int64_t WordI;
|
||||||
// simx64
|
|
||||||
typedef uint64_t DoubleWord;
|
|
||||||
|
|
||||||
// simx64
|
// simx64
|
||||||
typedef uint64_t Addr;
|
typedef uint32_t HalfWord;
|
||||||
|
typedef int32_t HalfWordI;
|
||||||
|
|
||||||
|
// simx64
|
||||||
|
typedef uint32_t Addr;
|
||||||
typedef uint32_t Size;
|
typedef uint32_t Size;
|
||||||
|
|
||||||
typedef std::bitset<32> RegMask;
|
typedef std::bitset<32> RegMask;
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ Warp::Warp(Core *core, Word id)
|
|||||||
: id_(id)
|
: id_(id)
|
||||||
, core_(core) {
|
, core_(core) {
|
||||||
// simx64
|
// simx64
|
||||||
iRegFile_.resize(core_->arch().num_threads(), std::vector<DoubleWord>(core_->arch().num_regs(), 0));
|
iRegFile_.resize(core_->arch().num_threads(), std::vector<Word>(core_->arch().num_regs(), 0));
|
||||||
fRegFile_.resize(core_->arch().num_threads(), std::vector<DoubleWord>(core_->arch().num_regs(), 0));
|
fRegFile_.resize(core_->arch().num_threads(), std::vector<Word>(core_->arch().num_regs(), 0));
|
||||||
vRegFile_.resize(core_->arch().num_regs(), std::vector<Byte>(core_->arch().vsize(), 0));
|
vRegFile_.resize(core_->arch().num_regs(), std::vector<Byte>(core_->arch().vsize(), 0));
|
||||||
this->clear();
|
this->clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,8 +99,8 @@ private:
|
|||||||
ThreadMask tmask_;
|
ThreadMask tmask_;
|
||||||
|
|
||||||
// simx64
|
// simx64
|
||||||
std::vector<std::vector<DoubleWord>> iRegFile_;
|
std::vector<std::vector<Word>> iRegFile_;
|
||||||
std::vector<std::vector<DoubleWord>> fRegFile_;
|
std::vector<std::vector<Word>> fRegFile_;
|
||||||
std::vector<std::vector<Byte>> vRegFile_;
|
std::vector<std::vector<Byte>> vRegFile_;
|
||||||
std::stack<DomStackEntry> domStack_;
|
std::stack<DomStackEntry> domStack_;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user