changes to make correct oversighst for XLEN=64 in Vector functions
This commit is contained in:
parent
ece6f7290f
commit
7b35f45a48
@ -654,7 +654,7 @@ if(vector != null) {%>
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
}
|
||||
}
|
||||
void vector_slide1up(uint8_t* V, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, unsigned vd, unsigned vs2, int64_t imm, uint8_t sew_val) {
|
||||
void vector_slide1up(uint8_t* V, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, unsigned vd, unsigned vs2, uint64_t imm, uint8_t sew_val) {
|
||||
switch(sew_val){
|
||||
case 0b000:
|
||||
return softvector::vector_slide1up<${vlen}, uint8_t>(V, vl, vstart, vtype, vm, vd, vs2, imm);
|
||||
@ -668,7 +668,7 @@ if(vector != null) {%>
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
}
|
||||
}
|
||||
void vector_slide1down(uint8_t* V, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, unsigned vd, unsigned vs2, int64_t imm, uint8_t sew_val) {
|
||||
void vector_slide1down(uint8_t* V, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, unsigned vd, unsigned vs2, uint64_t imm, uint8_t sew_val) {
|
||||
switch(sew_val){
|
||||
case 0b000:
|
||||
return softvector::vector_slide1down<${vlen}, uint8_t>(V, vl, vstart, vtype, vm, vd, vs2, imm);
|
||||
@ -791,7 +791,7 @@ if(vector != null) {%>
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
}
|
||||
}
|
||||
void fp_vector_imm_op(uint8_t* V, uint8_t funct6, uint8_t funct3, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, uint8_t vd, uint8_t vs2, int64_t imm, uint8_t rm, uint8_t sew_val){
|
||||
void fp_vector_imm_op(uint8_t* V, uint8_t funct6, uint8_t funct3, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, uint8_t vd, uint8_t vs2, uint64_t imm, uint8_t rm, uint8_t sew_val){
|
||||
switch(sew_val){
|
||||
case 0b000:
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
@ -818,14 +818,14 @@ if(vector != null) {%>
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
}
|
||||
}
|
||||
void fp_vector_imm_wv(uint8_t* V, uint8_t funct6, uint8_t funct3, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, uint8_t vd, uint8_t vs2, int64_t imm, uint8_t rm, uint8_t sew_val){
|
||||
void fp_vector_imm_wv(uint8_t* V, uint8_t funct6, uint8_t funct3, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, uint8_t vd, uint8_t vs2, uint64_t imm, uint8_t rm, uint8_t sew_val){
|
||||
switch(sew_val){
|
||||
case 0b000:
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
case 0b001:
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
case 0b010:
|
||||
return softvector::fp_vector_imm_op<${vlen}, uint64_t, uint32_t>(V, funct6, funct3, vl, vstart, vtype, vm, vd, vs2, imm, rm);
|
||||
return softvector::fp_vector_imm_op<${vlen}, uint64_t, uint32_t, uint32_t>(V, funct6, funct3, vl, vstart, vtype, vm, vd, vs2, imm, rm);
|
||||
case 0b011: // would widen to 128 bits
|
||||
default:
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
@ -844,7 +844,7 @@ if(vector != null) {%>
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
}
|
||||
}
|
||||
void fp_vector_imm_ww(uint8_t* V, uint8_t funct6, uint8_t funct3, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, uint8_t vd, uint8_t vs2, int64_t imm, uint8_t rm, uint8_t sew_val){
|
||||
void fp_vector_imm_ww(uint8_t* V, uint8_t funct6, uint8_t funct3, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, uint8_t vd, uint8_t vs2, uint64_t imm, uint8_t rm, uint8_t sew_val){
|
||||
switch(sew_val){
|
||||
case 0b000:
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
@ -885,7 +885,7 @@ if(vector != null) {%>
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
}
|
||||
}
|
||||
void mask_fp_vector_imm_op(uint8_t* V, uint8_t funct6, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, uint8_t vd, uint8_t vs2, int64_t imm, uint8_t rm, uint8_t sew_val){
|
||||
void mask_fp_vector_imm_op(uint8_t* V, uint8_t funct6, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, uint8_t vd, uint8_t vs2, uint64_t imm, uint8_t rm, uint8_t sew_val){
|
||||
switch(sew_val){
|
||||
case 0b000:
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
@ -899,7 +899,7 @@ if(vector != null) {%>
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
}
|
||||
}
|
||||
void fp_vector_imm_merge(uint8_t* V, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, uint8_t vd, uint8_t vs2, int64_t imm, uint8_t sew_val){
|
||||
void fp_vector_imm_merge(uint8_t* V, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, uint8_t vd, uint8_t vs2, uint64_t imm, uint8_t sew_val){
|
||||
vector_imm_merge(V, vl, vstart, vtype, vm, vd, vs2, imm, sew_val);
|
||||
}
|
||||
void fp_vector_unary_w(uint8_t* V, uint8_t encoding_space, uint8_t unary_op, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, uint8_t vd, uint8_t vs2, uint8_t rm, uint8_t sew_val){
|
||||
@ -907,7 +907,7 @@ if(vector != null) {%>
|
||||
case 0b000:
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
case 0b001:
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
return softvector::fp_vector_unary_op<${vlen}, uint32_t, uint16_t>(V, encoding_space, unary_op, vl, vstart, vtype, vm, vd, vs2, rm);
|
||||
case 0b010:
|
||||
return softvector::fp_vector_unary_op<${vlen}, uint64_t, uint32_t>(V, encoding_space, unary_op, vl, vstart, vtype, vm, vd, vs2, rm);
|
||||
case 0b011: // would widen to 128 bits
|
||||
@ -920,11 +920,10 @@ if(vector != null) {%>
|
||||
case 0b000:
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
case 0b001:
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
return softvector::fp_vector_unary_op<${vlen}, uint16_t, uint32_t>(V, encoding_space, unary_op, vl, vstart, vtype, vm, vd, vs2, rm);
|
||||
case 0b010:
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
case 0b011:
|
||||
return softvector::fp_vector_unary_op<${vlen}, uint32_t, uint64_t>(V, encoding_space, unary_op, vl, vstart, vtype, vm, vd, vs2, rm);
|
||||
case 0b011: // would require 128 bit value to narrow
|
||||
default:
|
||||
throw new std::runtime_error("Unsupported sew bit value");
|
||||
}
|
||||
|
@ -141,10 +141,10 @@ template <unsigned VLEN> void vector_whole_move(uint8_t* V, unsigned vd, unsigne
|
||||
template <unsigned VLEN, typename dest_elem_t, typename src_elem_t = dest_elem_t>
|
||||
void fp_vector_red_op(uint8_t* V, unsigned funct6, unsigned funct3, uint64_t vl, uint64_t vstart, vtype_t vtype, bool vm, unsigned vd,
|
||||
unsigned vs2, unsigned vs1, uint8_t rm);
|
||||
template <unsigned VLEN, typename dest_elem_t, typename src2_elem_t = dest_elem_t, typename src1_elem_t = dest_elem_t>
|
||||
template <unsigned VLEN, typename dest_elem_t, typename src2_elem_t = dest_elem_t, typename src1_elem_t = src2_elem_t>
|
||||
void fp_vector_vector_op(uint8_t* V, unsigned funct6, unsigned funct3, uint64_t vl, uint64_t vstart, vtype_t vtype, bool vm, unsigned vd,
|
||||
unsigned vs2, unsigned vs1, uint8_t rm);
|
||||
template <unsigned VLEN, typename dest_elem_t, typename src2_elem_t = dest_elem_t, typename src1_elem_t = dest_elem_t>
|
||||
template <unsigned VLEN, typename dest_elem_t, typename src2_elem_t = dest_elem_t, typename src1_elem_t = src2_elem_t>
|
||||
void fp_vector_imm_op(uint8_t* V, unsigned funct6, unsigned funct3, uint64_t vl, uint64_t vstart, vtype_t vtype, bool vm, unsigned vd,
|
||||
unsigned vs2, src1_elem_t imm, uint8_t rm);
|
||||
template <unsigned VLEN, typename dest_elem_t, typename src_elem_t = dest_elem_t>
|
||||
|
@ -1007,9 +1007,8 @@ template <> inline uint32_t fp_min<uint32_t>(uint32_t v2, uint32_t v1) {
|
||||
return v2;
|
||||
}
|
||||
template <> inline uint64_t fp_min<uint64_t>(uint64_t v2, uint64_t v1) {
|
||||
bool v1_lt_v2 = fcmp_d(v1, v2, 2);
|
||||
if(isNaN(v1) && isNaN(v2))
|
||||
return defaultNaNF32UI;
|
||||
return defaultNaNF64UI;
|
||||
else if(isNaN(v1))
|
||||
return v2;
|
||||
else if(isNaN(v2))
|
||||
@ -1018,14 +1017,13 @@ template <> inline uint64_t fp_min<uint64_t>(uint64_t v2, uint64_t v1) {
|
||||
return v1;
|
||||
else if(isNegZero(v2) && isNegZero(v1))
|
||||
return v2;
|
||||
else if(v1_lt_v2)
|
||||
else if(fcmp_d(v1, v2, 2))
|
||||
return v1;
|
||||
else
|
||||
return v2;
|
||||
}
|
||||
template <typename elem_size_t> elem_size_t fp_max(elem_size_t, elem_size_t);
|
||||
template <> inline uint32_t fp_max<uint32_t>(uint32_t v2, uint32_t v1) {
|
||||
bool v1_lt_v2 = fcmp_s(v1, v2, 2);
|
||||
if(isNaN(v1) && isNaN(v2))
|
||||
return defaultNaNF32UI;
|
||||
else if(isNaN(v1))
|
||||
@ -1036,15 +1034,14 @@ template <> inline uint32_t fp_max<uint32_t>(uint32_t v2, uint32_t v1) {
|
||||
return v2;
|
||||
else if(isNegZero(v2) && isNegZero(v1))
|
||||
return v1;
|
||||
else if(v1_lt_v2)
|
||||
else if(fcmp_s(v1, v2, 2))
|
||||
return v2;
|
||||
else
|
||||
return v1;
|
||||
}
|
||||
template <> inline uint64_t fp_max<uint64_t>(uint64_t v2, uint64_t v1) {
|
||||
bool v1_lt_v2 = fcmp_d(v1, v2, 2);
|
||||
if(isNaN(v1) && isNaN(v2))
|
||||
return defaultNaNF32UI;
|
||||
return defaultNaNF64UI;
|
||||
else if(isNaN(v1))
|
||||
return v2;
|
||||
else if(isNaN(v2))
|
||||
@ -1053,7 +1050,7 @@ template <> inline uint64_t fp_max<uint64_t>(uint64_t v2, uint64_t v1) {
|
||||
return v2;
|
||||
else if(isNegZero(v2) && isNegZero(v1))
|
||||
return v1;
|
||||
else if(v1_lt_v2)
|
||||
else if(fcmp_d(v1, v2, 2))
|
||||
return v2;
|
||||
else
|
||||
return v1;
|
||||
@ -1065,23 +1062,23 @@ std::function<dest_elem_t(uint8_t, uint8_t&, dest_elem_t, src2_elem_t, src1_elem
|
||||
switch(funct6) {
|
||||
case 0b000000: // VFADD
|
||||
return [](uint8_t rm, uint8_t& accrued_flags, dest_elem_t vd, src2_elem_t vs2, src1_elem_t vs1) {
|
||||
dest_elem_t val = fp_add<dest_elem_t>(rm, vs2, vs1);
|
||||
dest_elem_t val = fp_add<src2_elem_t>(rm, vs2, vs1);
|
||||
accrued_flags |= softfloat_exceptionFlags;
|
||||
return val;
|
||||
};
|
||||
case 0b000010: // VFSUB
|
||||
return [](uint8_t rm, uint8_t& accrued_flags, dest_elem_t vd, src2_elem_t vs2, src1_elem_t vs1) {
|
||||
dest_elem_t val = fp_sub<dest_elem_t>(rm, vs2, vs1);
|
||||
dest_elem_t val = fp_sub<src2_elem_t>(rm, vs2, vs1);
|
||||
accrued_flags |= softfloat_exceptionFlags;
|
||||
return val;
|
||||
};
|
||||
case 0b000100: // VFMIN
|
||||
return [](uint8_t rm, uint8_t& accrued_flags, dest_elem_t vd, src2_elem_t vs2, src1_elem_t vs1) {
|
||||
return fp_min<dest_elem_t>(vs2, vs1);
|
||||
return fp_min<src2_elem_t>(vs2, vs1);
|
||||
};
|
||||
case 0b000110: // VFMAX
|
||||
return [](uint8_t rm, uint8_t& accrued_flags, dest_elem_t vd, src2_elem_t vs2, src1_elem_t vs1) {
|
||||
return fp_max<dest_elem_t>(vs2, vs1);
|
||||
return fp_max<src2_elem_t>(vs2, vs1);
|
||||
};
|
||||
case 0b100000: // VFDIV
|
||||
return [](uint8_t rm, uint8_t& accrued_flags, dest_elem_t vd, src2_elem_t vs2, src1_elem_t vs1) {
|
||||
@ -1097,7 +1094,7 @@ std::function<dest_elem_t(uint8_t, uint8_t&, dest_elem_t, src2_elem_t, src1_elem
|
||||
};
|
||||
case 0b100100: // VFMUL
|
||||
return [](uint8_t rm, uint8_t& accrued_flags, dest_elem_t vd, src2_elem_t vs2, src1_elem_t vs1) {
|
||||
dest_elem_t val = fp_mul<dest_elem_t>(rm, vs2, vs1);
|
||||
dest_elem_t val = fp_mul<src2_elem_t>(rm, vs2, vs1);
|
||||
accrued_flags |= softfloat_exceptionFlags;
|
||||
return val;
|
||||
};
|
||||
@ -1181,7 +1178,7 @@ std::function<dest_elem_t(uint8_t, uint8_t&, dest_elem_t, src2_elem_t, src1_elem
|
||||
};
|
||||
case 0b111000: // VFWMUL
|
||||
return [](uint8_t rm, uint8_t& accrued_flags, dest_elem_t vd, src2_elem_t vs2, src1_elem_t vs1) {
|
||||
dest_elem_t val = fp_mul<dest_elem_t>(rm, widen_float<dest_elem_t>(vs2), vs1);
|
||||
dest_elem_t val = fp_mul<dest_elem_t>(rm, widen_float<dest_elem_t>(vs2), widen_float<dest_elem_t>(vs1));
|
||||
accrued_flags |= softfloat_exceptionFlags;
|
||||
return val;
|
||||
};
|
||||
@ -1356,90 +1353,162 @@ void fp_vector_red_op(uint8_t* V, unsigned funct6, unsigned funct3, uint64_t vl,
|
||||
return;
|
||||
}
|
||||
template <typename elem_size_t> elem_size_t fp_sqrt(uint8_t, elem_size_t);
|
||||
template <> inline uint16_t fp_sqrt<uint16_t>(uint8_t mode, uint16_t v2) { return fsqrt_h(v2, mode); }
|
||||
template <> inline uint32_t fp_sqrt<uint32_t>(uint8_t mode, uint32_t v2) { return fsqrt_s(v2, mode); }
|
||||
template <> inline uint64_t fp_sqrt<uint64_t>(uint8_t mode, uint64_t v2) { return fsqrt_d(v2, mode); }
|
||||
template <typename elem_size_t> elem_size_t fp_rsqrt7(elem_size_t);
|
||||
template <> inline uint16_t fp_rsqrt7<uint16_t>(uint16_t v2) { return frsqrt7_h(v2); }
|
||||
template <> inline uint32_t fp_rsqrt7<uint32_t>(uint32_t v2) { return frsqrt7_s(v2); }
|
||||
template <> inline uint64_t fp_rsqrt7<uint64_t>(uint64_t v2) { return frsqrt7_d(v2); }
|
||||
template <typename elem_size_t> elem_size_t fp_rec7(uint8_t, elem_size_t);
|
||||
template <> inline uint16_t fp_rec7<uint16_t>(uint8_t mode, uint16_t v2) { return frec7_h(v2, mode); }
|
||||
template <> inline uint32_t fp_rec7<uint32_t>(uint8_t mode, uint32_t v2) { return frec7_s(v2, mode); }
|
||||
template <> inline uint64_t fp_rec7<uint64_t>(uint8_t mode, uint64_t v2) { return frec7_d(v2, mode); }
|
||||
template <typename elem_size_t> elem_size_t fp_fclass(elem_size_t);
|
||||
template <> inline uint16_t fp_fclass<uint16_t>(uint16_t v2) { return fclass_h(v2); }
|
||||
template <> inline uint32_t fp_fclass<uint32_t>(uint32_t v2) { return fclass_s(v2); }
|
||||
template <> inline uint64_t fp_fclass<uint64_t>(uint64_t v2) { return fclass_d(v2); }
|
||||
template <typename dest_elem_size_t, typename src_elem_size_t> dest_elem_size_t fp_f_to_ui(uint8_t, src_elem_size_t);
|
||||
template <> inline uint32_t fp_f_to_ui<uint32_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return f32_to_ui32(float32_t{v2}, rm, true);
|
||||
}
|
||||
template <> inline uint64_t fp_f_to_ui<uint64_t, uint64_t>(uint8_t rm, uint64_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return f64_to_ui64(float64_t{v2}, rm, true);
|
||||
}
|
||||
template <> inline uint32_t fp_f_to_ui<uint32_t, uint16_t>(uint8_t rm, uint16_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return f16_to_ui32(float16_t{v2}, rm, true);
|
||||
}
|
||||
template <> inline uint64_t fp_f_to_ui<uint64_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return f32_to_ui64(float32_t{v2}, rm, true);
|
||||
}
|
||||
template <> inline uint16_t fp_f_to_ui<uint16_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
// return f32_to_ui16(float32_t{v2}, rm, true);
|
||||
throw new std::runtime_error("No conversion from f32 to ui16 implemented");
|
||||
}
|
||||
template <> inline uint32_t fp_f_to_ui<uint32_t, uint64_t>(uint8_t rm, uint64_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return f64_to_ui32(float64_t{v2}, rm, true);
|
||||
}
|
||||
template <typename dest_elem_size_t, typename src_elem_size_t> dest_elem_size_t fp_f_to_i(uint8_t, src_elem_size_t);
|
||||
template <> inline uint32_t fp_f_to_i<uint32_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return f32_to_i32(float32_t{v2}, rm, true);
|
||||
}
|
||||
template <> inline uint64_t fp_f_to_i<uint64_t, uint64_t>(uint8_t rm, uint64_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return f64_to_i64(float64_t{v2}, rm, true);
|
||||
}
|
||||
template <> inline uint32_t fp_f_to_i<uint32_t, uint16_t>(uint8_t rm, uint16_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return f16_to_i32(float16_t{v2}, rm, true);
|
||||
}
|
||||
template <> inline uint16_t fp_f_to_i<uint16_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
// return f32_to_i16(float32_t{v2}, rm, true);
|
||||
throw new std::runtime_error("No conversion from f32 to i16 implemented");
|
||||
}
|
||||
template <> inline uint64_t fp_f_to_i<uint64_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return f32_to_i64(float32_t{v2}, rm, true);
|
||||
}
|
||||
template <> inline uint32_t fp_f_to_i<uint32_t, uint64_t>(uint8_t rm, uint64_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return f64_to_i32(float64_t{v2}, rm, true);
|
||||
}
|
||||
template <typename dest_elem_size_t, typename src_elem_size_t> dest_elem_size_t fp_ui_to_f(src_elem_size_t);
|
||||
template <> inline uint32_t fp_ui_to_f<uint32_t, uint32_t>(uint32_t v2) {
|
||||
template <typename dest_elem_size_t, typename src_elem_size_t> dest_elem_size_t fp_ui_to_f(uint8_t, src_elem_size_t);
|
||||
template <> inline uint32_t fp_ui_to_f<uint32_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return ui32_to_f32(v2).v;
|
||||
}
|
||||
template <> inline uint64_t fp_ui_to_f<uint64_t, uint64_t>(uint64_t v2) {
|
||||
template <> inline uint64_t fp_ui_to_f<uint64_t, uint64_t>(uint8_t rm, uint64_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return ui64_to_f64(v2).v;
|
||||
}
|
||||
template <> inline uint64_t fp_ui_to_f<uint64_t, uint32_t>(uint32_t v2) {
|
||||
template <> inline uint32_t fp_ui_to_f<uint32_t, uint16_t>(uint8_t rm, uint16_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
// return ui16_to_f32(v2).v;
|
||||
throw new std::runtime_error("No conversion from ui16 to f32 implemented");
|
||||
}
|
||||
template <> inline uint64_t fp_ui_to_f<uint64_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return ui32_to_f64(v2).v;
|
||||
}
|
||||
template <> inline uint32_t fp_ui_to_f<uint32_t, uint64_t>(uint64_t v2) {
|
||||
template <> inline uint16_t fp_ui_to_f<uint16_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return ui32_to_f16(v2).v;
|
||||
}
|
||||
template <> inline uint32_t fp_ui_to_f<uint32_t, uint64_t>(uint8_t rm, uint64_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return ui64_to_f32(v2).v;
|
||||
}
|
||||
template <typename dest_elem_size_t, typename src_elem_size_t> dest_elem_size_t fp_i_to_f(src_elem_size_t);
|
||||
template <> inline uint32_t fp_i_to_f<uint32_t, uint32_t>(uint32_t v2) {
|
||||
template <typename dest_elem_size_t, typename src_elem_size_t> dest_elem_size_t fp_i_to_f(uint8_t, src_elem_size_t);
|
||||
template <> inline uint32_t fp_i_to_f<uint32_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return i32_to_f32(v2).v;
|
||||
}
|
||||
template <> inline uint64_t fp_i_to_f<uint64_t, uint64_t>(uint64_t v2) {
|
||||
template <> inline uint64_t fp_i_to_f<uint64_t, uint64_t>(uint8_t rm, uint64_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return i64_to_f64(v2).v;
|
||||
}
|
||||
template <> inline uint64_t fp_i_to_f<uint64_t, uint32_t>(uint32_t v2) {
|
||||
template <> inline uint32_t fp_i_to_f<uint32_t, uint16_t>(uint8_t rm, uint16_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
// return i16_to_f32(v2).v;
|
||||
throw new std::runtime_error("No conversion from i16 to f32 implemented");
|
||||
}
|
||||
template <> inline uint64_t fp_i_to_f<uint64_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return i32_to_f64(v2).v;
|
||||
}
|
||||
template <> inline uint32_t fp_i_to_f<uint32_t, uint64_t>(uint64_t v2) {
|
||||
template <> inline uint16_t fp_i_to_f<uint16_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return i32_to_f16(v2).v;
|
||||
}
|
||||
template <> inline uint32_t fp_i_to_f<uint32_t, uint64_t>(uint8_t rm, uint64_t v2) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return i64_to_f32(v2).v;
|
||||
}
|
||||
template <typename dest_elem_t, typename src_elem_t> dest_elem_t fp_f_to_f(uint8_t mode, src_elem_t val) {
|
||||
template <typename dest_elem_t, typename src_elem_t> dest_elem_t fp_f_to_f(uint8_t rm, src_elem_t val) {
|
||||
throw new std::runtime_error("Conversion not explicitly specialized");
|
||||
}
|
||||
template <> inline uint64_t fp_f_to_f<uint64_t, uint32_t>(uint8_t mode, uint32_t val) { return fconv_f2d(val, mode); }
|
||||
template <> inline uint32_t fp_f_to_f<uint32_t, uint64_t>(uint8_t mode, uint64_t val) { return fconv_d2f(val, mode); }
|
||||
template <> inline uint64_t fp_f_to_f<uint64_t, uint32_t>(uint8_t rm, uint32_t val) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return f32_to_f64(float32_t{val}).v;
|
||||
}
|
||||
template <> inline uint32_t fp_f_to_f<uint32_t, uint64_t>(uint8_t rm, uint64_t val) {
|
||||
softfloat_exceptionFlags = 0;
|
||||
softfloat_roundingMode = rm;
|
||||
return f64_to_f32(float64_t{val}).v;
|
||||
}
|
||||
|
||||
template <typename dest_elem_t, typename src_elem_t = dest_elem_t>
|
||||
std::function<dest_elem_t(uint8_t, uint8_t&, src_elem_t)> get_fp_unary_fn(unsigned encoding_space, unsigned unary_op) {
|
||||
@ -1499,7 +1568,7 @@ std::function<dest_elem_t(uint8_t, uint8_t&, src_elem_t)> get_fp_unary_fn(unsign
|
||||
case 0b01010: // VFWCVT.F.XU.V
|
||||
case 0b10010: // VFNCVT.F.XU.W
|
||||
return [](uint8_t rm, uint8_t& accrued_flags, src_elem_t vs2) {
|
||||
dest_elem_t val = fp_ui_to_f<dest_elem_t, src_elem_t>(vs2);
|
||||
dest_elem_t val = fp_ui_to_f<dest_elem_t, src_elem_t>(rm, vs2);
|
||||
accrued_flags |= softfloat_exceptionFlags;
|
||||
return val;
|
||||
};
|
||||
@ -1507,7 +1576,7 @@ std::function<dest_elem_t(uint8_t, uint8_t&, src_elem_t)> get_fp_unary_fn(unsign
|
||||
case 0b01011: // VFWCVT.F.X.V
|
||||
case 0b10011: // VFNCVT.F.X.W
|
||||
return [](uint8_t rm, uint8_t& accrued_flags, src_elem_t vs2) {
|
||||
dest_elem_t val = fp_i_to_f<dest_elem_t, src_elem_t>(vs2);
|
||||
dest_elem_t val = fp_i_to_f<dest_elem_t, src_elem_t>(rm, vs2);
|
||||
accrued_flags |= softfloat_exceptionFlags;
|
||||
return val;
|
||||
};
|
||||
@ -1534,7 +1603,7 @@ void fp_vector_unary_op(uint8_t* V, unsigned encoding_space, unsigned unary_op,
|
||||
auto vd_view = get_vreg<VLEN, dest_elem_t>(V, vd, elem_count);
|
||||
auto fn = get_fp_unary_fn<dest_elem_t, src_elem_t>(encoding_space, unary_op);
|
||||
uint8_t accrued_flags = 0;
|
||||
for(size_t idx = vstart; idx < std::min(elem_count, vl); idx++) {
|
||||
for(size_t idx = vstart; idx < vl; idx++) {
|
||||
bool mask_active = vm ? 1 : mask_reg[idx];
|
||||
if(mask_active) {
|
||||
vd_view[idx] = fn(rm, accrued_flags, vs2_view[idx]);
|
||||
@ -1543,11 +1612,9 @@ void fp_vector_unary_op(uint8_t* V, unsigned encoding_space, unsigned unary_op,
|
||||
}
|
||||
}
|
||||
softfloat_exceptionFlags = accrued_flags;
|
||||
unsigned maximum_elems = VLEN * vtype.lmul() / (sizeof(dest_elem_t) * 8);
|
||||
for(size_t idx = std::min(elem_count, vl); idx < maximum_elems; idx++) {
|
||||
for(size_t idx = vl; idx < elem_count; idx++) {
|
||||
vd_view[idx] = vtype.vta() ? vd_view[idx] : vd_view[idx];
|
||||
}
|
||||
return;
|
||||
}
|
||||
template <typename elem_size_t> bool fp_eq(elem_size_t, elem_size_t);
|
||||
template <> inline bool fp_eq<uint32_t>(uint32_t v2, uint32_t v1) { return fcmp_s(v2, v1, 0); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user