Skip to content

Commit

Permalink
rv64v: fix some exception checks with bugs or missing
Browse files Browse the repository at this point in the history
* add exception check for vector load/store, remove alignment check when access vector registers
* move vector load/store instructions info generation from decode stage to execute stage
* fix illegal vtype check
* when vstart is not zero and is a arithmetic vector instruction, raise illegal instruction exception
* support sew check for zext and sext instructions
  • Loading branch information
Ziyue-Zhang authored and huxuan0307 committed Jul 9, 2024
1 parent 0b2e23f commit 24be240
Show file tree
Hide file tree
Showing 10 changed files with 226 additions and 97 deletions.
16 changes: 0 additions & 16 deletions src/isa/riscv64/instr/rvf/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,6 @@ def_THelper(vstore_mmu) {
def_THelper(fload) {
print_Dop(id_src1->str, OP_STR_SIZE, "%ld(%s)", id_src2->imm, reg_name(s->isa.instr.i.rs1, 4));

#ifdef CONFIG_RVV
const int table [8] = {1, 0, 0, 0, 0, 2, 4, 8};
s->vm = s->isa.instr.v_opv.v_vm; //1 for without mask; 0 for with mask
s->v_width = table[s->isa.instr.vldfp.v_width];
s->v_nf = s->isa.instr.vldfp.v_nf;
s->v_lsumop = s->isa.instr.vldfp.v_lsumop;
#endif // CONFIG_RVV

int mmu_mode = isa_mmu_state();
if (mmu_mode == MMU_DIRECT) {
if (fp_enable()) {
Expand Down Expand Up @@ -163,14 +155,6 @@ def_THelper(fload) {
def_THelper(fstore) {
print_Dop(id_src1->str, OP_STR_SIZE, "%ld(%s)", id_src2->imm, reg_name(s->isa.instr.i.rs1, 4));

#ifdef CONFIG_RVV
const int table [8] = {1, 0, 0, 0, 0, 2, 4, 8};
s->vm = s->isa.instr.v_opv.v_vm; //1 for without mask; 0 for with mask
s->v_width = table[s->isa.instr.vldfp.v_width];
s->v_nf = s->isa.instr.vldfp.v_nf;
s->v_lsumop = s->isa.instr.vldfp.v_lsumop;
#endif // CONFIG_RVV

int mmu_mode = isa_mmu_state();
if (mmu_mode == MMU_DIRECT) {
#ifndef CONFIG_FPU_NONE
Expand Down
14 changes: 6 additions & 8 deletions src/isa/riscv64/instr/rvv/vcfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,18 @@ void set_vtype_vl(Decode *s, int mode) {

if(vl_num == (uint64_t)-1 || check_vlmul_sew_illegal(id_src2->val)) {
vtype->val = error;

// if vtype illegal, set vl = 0, vd = 0
vl->val = 0;
rtl_sr(s, id_dest->reg, &vl->val, 8);
return;
}
else {
vtype->val = id_src2->val;
}
// if vtype illegal,set vl = 0 ,vd = 0
if(check_vlmul_sew_illegal(id_src2->val)){
vl->val = 0;

rtl_sr(s, id_dest->reg, &vl->val, 8/*4*/);
return;
}
vl->val = vl_num;

rtl_sr(s, id_dest->reg, &vl_num, 8/*4*/);
rtl_sr(s, id_dest->reg, &vl_num, 8);

vstart->val = 0;
}
Expand Down
27 changes: 22 additions & 5 deletions src/isa/riscv64/instr/rvv/vcommon.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include <math.h>
#include "vcommon.h"
#include <cpu/cpu.h>

uint8_t check_vstart_ignore(Decode *s) {
if(vstart->val >= vl->val) {
if(vstart->val > 0) {
Expand All @@ -15,13 +17,28 @@ uint8_t check_vstart_ignore(Decode *s) {
return 0;
}

bool check_vlmul_sew_illegal(rtlreg_t vtype_req){
vtype_t vt = (vtype_t )vtype_req;
uint8_t check_vstart_exception(Decode *s) {
if(vstart->val > 0) {
longjmp_exception(EX_II);
}
if (vl->val == 0) {
return 1;
}
return 0;
}

bool check_vlmul_sew_illegal(rtlreg_t vtype_req) {
vtype_t vt = (vtype_t) vtype_req;
int vlmul = vt.vlmul;
int vsew = vt.vsew;
if (vlmul > 4) vlmul -= 8;
if((vlmul < vsew + 3 - log2(MAXELEN)) || vlmul == 4) return true; // vmul < sew/ELEN || vlmul == 100
return false;
int vsew = 8 << vt.vsew;
float vflmul = vlmul >= 0 ? 1 << vlmul : 1.0 / (1 << -vlmul);
float min_vflmul = vflmul < 1.0f ? vflmul : 1.0f;
int vill = !(vflmul >= 0.125 && vflmul <= 8)
|| vsew > min_vflmul * 64
|| (vtype_req >> 8) != 0
|| vsew > 64;
return vill == 1;
}

void set_NAN(rtlreg_t* fpreg, uint64_t vsew){
Expand Down
1 change: 1 addition & 0 deletions src/isa/riscv64/instr/rvv/vcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "../local-include/rtl.h"

uint8_t check_vstart_ignore(Decode *s);
uint8_t check_vstart_exception(Decode *s);
bool check_vlmul_sew_illegal(rtlreg_t vtype_req);
void set_NAN(rtlreg_t* fpreg, uint64_t vsew);
bool check_isFpCanonicalNAN(rtlreg_t* fpreg, uint64_t vsew);
Expand Down
12 changes: 5 additions & 7 deletions src/isa/riscv64/instr/rvv/vcompute.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,11 @@ def_EHelper(vadd) {
def_EHelper(vsub) {
Assert(s->src_vmode != SRC_VI, "vsub.vi not supported\n");
ARTHI(SUB, SIGNED)
// print_asm_template3(vsub);
}

def_EHelper(vrsub) {
Assert(s->src_vmode != SRC_VV, "vrsub.vv not supported\n");
ARTHI(RSUB, SIGNED)
// print_asm_template3(vrsub);
}

def_EHelper(vminu) {
Expand Down Expand Up @@ -378,7 +376,7 @@ def_EHelper(vmvnr) {
def_EHelper(vpopc) {
require_vector(true);
if(vstart->val != 0)
check_vstart_ignore(s);
check_vstart_exception(s);

rtl_li(s, s1, 0);
for(int idx = vstart->val; idx < vl->val; idx ++) {
Expand All @@ -400,7 +398,7 @@ def_EHelper(vpopc) {
def_EHelper(vfirst) {
require_vector(true);
if(vstart->val != 0)
check_vstart_ignore(s);
check_vstart_exception(s);

int pos = -1;
for(int idx = vstart->val; idx < vl->val; idx ++) {
Expand Down Expand Up @@ -571,7 +569,7 @@ def_EHelper(viota) {
require_aligned(id_dest->reg, vflmul);
require_noover(id_dest->reg, vflmul, id_src2->reg, 1);

if(!check_vstart_ignore(s)) {
if(!check_vstart_exception(s)) {
rtl_li(s, s1, 0);
for(int idx = vstart->val; idx < vl->val; idx ++) {
rtlreg_t mask = get_mask(0, idx, vtype->vsew, vtype->vlmul);
Expand Down Expand Up @@ -617,7 +615,7 @@ def_EHelper(vid) {
double vflmul = compute_vflmul();
require_aligned(id_dest->reg, vflmul);

if(!check_vstart_ignore(s)) {
if(!check_vstart_exception(s)) {
for(int idx = 0; idx < vl->val; idx ++) {
// mask
rtlreg_t mask = get_mask(0, idx, vtype->vsew, vtype->vlmul);
Expand Down Expand Up @@ -787,7 +785,7 @@ def_EHelper(vcompress) {
longjmp_exception(EX_II);
}
require_noover(id_dest->reg, vflmul, id_src->reg, 1);
if(!check_vstart_ignore(s)) {
if(!check_vstart_exception(s)) {

rtl_li(s, s1, 0);
for(int idx = vstart->val; idx < vl->val; idx ++) {
Expand Down
28 changes: 13 additions & 15 deletions src/isa/riscv64/instr/rvv/vcompute_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,6 @@ void vector_slide_check(Decode *s, bool is_over) {
}

void arthimetic_instr(int opcode, int is_signed, int widening, int narrow, int dest_mask, Decode *s) {
if(check_vstart_ignore(s)) return;
require_vector(true);
int vlmax = get_vlmax(vtype->vsew, vtype->vlmul);
int idx;
Expand Down Expand Up @@ -369,7 +368,12 @@ void arthimetic_instr(int opcode, int is_signed, int widening, int narrow, int d
} else {
vector_vwv_check(s, false);
}
} else if (narrow < 0) {
if (vtype->vsew + narrow < 0) {
longjmp_exception(EX_II);
}
}
if(check_vstart_exception(s)) return;
for(idx = vstart->val; idx < vl->val; idx ++) {
// mask
rtlreg_t mask = get_mask(0, idx, vtype->vsew, vtype->vlmul);
Expand Down Expand Up @@ -417,7 +421,7 @@ void arthimetic_instr(int opcode, int is_signed, int widening, int narrow, int d
switch (opcode) {
case VEXT:
eew = vtype->vsew + narrow;
emul = vtype->vlmul - ((vtype->vsew) - (vtype->vsew + narrow));
emul = vtype->vlmul + narrow;
break;
default:
eew = vtype->vsew + narrow;
Expand Down Expand Up @@ -833,8 +837,7 @@ void arthimetic_instr(int opcode, int is_signed, int widening, int narrow, int d
* because the illegal instruction exception is handled in vcompute.h for vrgather and vslide instruction
*/
void permutaion_instr(int opcode, Decode *s) {
if(check_vstart_ignore(s)) return;
require_vector(true);
if(check_vstart_exception(s)) return;
int vlmax = get_vlmax(vtype->vsew, vtype->vlmul);
int idx;
for(idx = vstart->val; idx < vl->val; idx ++) {
Expand Down Expand Up @@ -978,7 +981,6 @@ void permutaion_instr(int opcode, Decode *s) {
}

void floating_arthimetic_instr(int opcode, int is_signed, int widening, int dest_mask, Decode *s) {
if(check_vstart_ignore(s)) return;
require_vector(true);
if (dest_mask) {
if (s->src_vmode == SRC_VV) {
Expand Down Expand Up @@ -1013,17 +1015,13 @@ void floating_arthimetic_instr(int opcode, int is_signed, int widening, int dest
vector_wwv_check(s, false);
}
}
if(check_vstart_exception(s)) return;
int idx;
word_t FPCALL_TYPE = FPCALL_W64;
// fpcall type
switch (vtype->vsew) {
case 0 :
switch (widening) {
case vdNarrow : FPCALL_TYPE = FPCALL_W16; break;
case vdWidening : FPCALL_TYPE = FPCALL_W8; break;
default : Loge("f8 not supported"); longjmp_exception(EX_II); break;
}
break;
Loge("f8 not supported"); longjmp_exception(EX_II); break;
case 1 :
switch (widening) {
case vsdWidening : FPCALL_TYPE = FPCALL_W16_to_32; break;
Expand Down Expand Up @@ -1215,7 +1213,7 @@ void mask_instr(int opcode, Decode *s) {
if (s->vm == 0) {
longjmp_exception(EX_II);
}
if(check_vstart_ignore(s)) return;
if(check_vstart_exception(s)) return;
int idx;
for(idx = vstart->val; idx < vl->val; idx++) {
// operand - vs2
Expand Down Expand Up @@ -1268,8 +1266,8 @@ vector register, not a vector register group, so any vector register can be the
scalar source or destination of a vector reduction regardless of LMUL setting.
*/
void reduction_instr(int opcode, int is_signed, int wide, Decode *s) {
if(check_vstart_ignore(s)) return;
vector_reduction_check(s, wide);
if(check_vstart_exception(s)) return;
// operand - vs1
get_vreg(id_src->reg, 0, s1, vtype->vsew+wide, vtype->vlmul, is_signed, 0);
if(is_signed) rtl_sext(s, s1, s1, 1 << (vtype->vsew+wide));
Expand Down Expand Up @@ -1311,8 +1309,8 @@ void reduction_instr(int opcode, int is_signed, int wide, Decode *s) {
}

void float_reduction_instr(int opcode, int widening, Decode *s) {
if(check_vstart_ignore(s)) return;
vector_reduction_check(s, widening);
if(check_vstart_exception(s)) return;
if (widening)
get_vreg(id_src->reg, 0, s1, vtype->vsew+1, vtype->vlmul, 0, 1);
else
Expand Down Expand Up @@ -1448,8 +1446,8 @@ void float_reduction_step1(uint64_t src1, uint64_t src2, Decode *s) {
}

void float_reduction_computing(Decode *s) {
if(check_vstart_ignore(s)) return;
vector_reduction_check(s, false);
if(check_vstart_exception(s)) return;
word_t FPCALL_TYPE = FPCALL_W64;
int idx;

Expand Down
Loading

0 comments on commit 24be240

Please sign in to comment.