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");
|
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){
|
switch(sew_val){
|
||||||
case 0b000:
|
case 0b000:
|
||||||
return softvector::vector_slide1up<${vlen}, uint8_t>(V, vl, vstart, vtype, vm, vd, vs2, imm);
|
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");
|
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){
|
switch(sew_val){
|
||||||
case 0b000:
|
case 0b000:
|
||||||
return softvector::vector_slide1down<${vlen}, uint8_t>(V, vl, vstart, vtype, vm, vd, vs2, imm);
|
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");
|
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){
|
switch(sew_val){
|
||||||
case 0b000:
|
case 0b000:
|
||||||
throw new std::runtime_error("Unsupported sew bit value");
|
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");
|
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){
|
switch(sew_val){
|
||||||
case 0b000:
|
case 0b000:
|
||||||
throw new std::runtime_error("Unsupported sew bit value");
|
throw new std::runtime_error("Unsupported sew bit value");
|
||||||
case 0b001:
|
case 0b001:
|
||||||
throw new std::runtime_error("Unsupported sew bit value");
|
throw new std::runtime_error("Unsupported sew bit value");
|
||||||
case 0b010:
|
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
|
case 0b011: // would widen to 128 bits
|
||||||
default:
|
default:
|
||||||
throw new std::runtime_error("Unsupported sew bit value");
|
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");
|
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){
|
switch(sew_val){
|
||||||
case 0b000:
|
case 0b000:
|
||||||
throw new std::runtime_error("Unsupported sew bit value");
|
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");
|
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){
|
switch(sew_val){
|
||||||
case 0b000:
|
case 0b000:
|
||||||
throw new std::runtime_error("Unsupported sew bit value");
|
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");
|
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);
|
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){
|
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:
|
case 0b000:
|
||||||
throw new std::runtime_error("Unsupported sew bit value");
|
throw new std::runtime_error("Unsupported sew bit value");
|
||||||
case 0b001:
|
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:
|
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);
|
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
|
case 0b011: // would widen to 128 bits
|
||||||
@ -920,11 +920,10 @@ if(vector != null) {%>
|
|||||||
case 0b000:
|
case 0b000:
|
||||||
throw new std::runtime_error("Unsupported sew bit value");
|
throw new std::runtime_error("Unsupported sew bit value");
|
||||||
case 0b001:
|
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:
|
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);
|
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:
|
default:
|
||||||
throw new std::runtime_error("Unsupported sew bit value");
|
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>
|
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,
|
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);
|
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,
|
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);
|
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,
|
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);
|
unsigned vs2, src1_elem_t imm, uint8_t rm);
|
||||||
template <unsigned VLEN, typename dest_elem_t, typename src_elem_t = dest_elem_t>
|
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;
|
return v2;
|
||||||
}
|
}
|
||||||
template <> inline uint64_t fp_min<uint64_t>(uint64_t v2, uint64_t v1) {
|
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))
|
if(isNaN(v1) && isNaN(v2))
|
||||||
return defaultNaNF32UI;
|
return defaultNaNF64UI;
|
||||||
else if(isNaN(v1))
|
else if(isNaN(v1))
|
||||||
return v2;
|
return v2;
|
||||||
else if(isNaN(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;
|
return v1;
|
||||||
else if(isNegZero(v2) && isNegZero(v1))
|
else if(isNegZero(v2) && isNegZero(v1))
|
||||||
return v2;
|
return v2;
|
||||||
else if(v1_lt_v2)
|
else if(fcmp_d(v1, v2, 2))
|
||||||
return v1;
|
return v1;
|
||||||
else
|
else
|
||||||
return v2;
|
return v2;
|
||||||
}
|
}
|
||||||
template <typename elem_size_t> elem_size_t fp_max(elem_size_t, elem_size_t);
|
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) {
|
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))
|
if(isNaN(v1) && isNaN(v2))
|
||||||
return defaultNaNF32UI;
|
return defaultNaNF32UI;
|
||||||
else if(isNaN(v1))
|
else if(isNaN(v1))
|
||||||
@ -1036,15 +1034,14 @@ template <> inline uint32_t fp_max<uint32_t>(uint32_t v2, uint32_t v1) {
|
|||||||
return v2;
|
return v2;
|
||||||
else if(isNegZero(v2) && isNegZero(v1))
|
else if(isNegZero(v2) && isNegZero(v1))
|
||||||
return v1;
|
return v1;
|
||||||
else if(v1_lt_v2)
|
else if(fcmp_s(v1, v2, 2))
|
||||||
return v2;
|
return v2;
|
||||||
else
|
else
|
||||||
return v1;
|
return v1;
|
||||||
}
|
}
|
||||||
template <> inline uint64_t fp_max<uint64_t>(uint64_t v2, uint64_t 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))
|
if(isNaN(v1) && isNaN(v2))
|
||||||
return defaultNaNF32UI;
|
return defaultNaNF64UI;
|
||||||
else if(isNaN(v1))
|
else if(isNaN(v1))
|
||||||
return v2;
|
return v2;
|
||||||
else if(isNaN(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;
|
return v2;
|
||||||
else if(isNegZero(v2) && isNegZero(v1))
|
else if(isNegZero(v2) && isNegZero(v1))
|
||||||
return v1;
|
return v1;
|
||||||
else if(v1_lt_v2)
|
else if(fcmp_d(v1, v2, 2))
|
||||||
return v2;
|
return v2;
|
||||||
else
|
else
|
||||||
return v1;
|
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) {
|
switch(funct6) {
|
||||||
case 0b000000: // VFADD
|
case 0b000000: // VFADD
|
||||||
return [](uint8_t rm, uint8_t& accrued_flags, dest_elem_t vd, src2_elem_t vs2, src1_elem_t vs1) {
|
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;
|
accrued_flags |= softfloat_exceptionFlags;
|
||||||
return val;
|
return val;
|
||||||
};
|
};
|
||||||
case 0b000010: // VFSUB
|
case 0b000010: // VFSUB
|
||||||
return [](uint8_t rm, uint8_t& accrued_flags, dest_elem_t vd, src2_elem_t vs2, src1_elem_t vs1) {
|
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;
|
accrued_flags |= softfloat_exceptionFlags;
|
||||||
return val;
|
return val;
|
||||||
};
|
};
|
||||||
case 0b000100: // VFMIN
|
case 0b000100: // VFMIN
|
||||||
return [](uint8_t rm, uint8_t& accrued_flags, dest_elem_t vd, src2_elem_t vs2, src1_elem_t vs1) {
|
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
|
case 0b000110: // VFMAX
|
||||||
return [](uint8_t rm, uint8_t& accrued_flags, dest_elem_t vd, src2_elem_t vs2, src1_elem_t vs1) {
|
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
|
case 0b100000: // VFDIV
|
||||||
return [](uint8_t rm, uint8_t& accrued_flags, dest_elem_t vd, src2_elem_t vs2, src1_elem_t vs1) {
|
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
|
case 0b100100: // VFMUL
|
||||||
return [](uint8_t rm, uint8_t& accrued_flags, dest_elem_t vd, src2_elem_t vs2, src1_elem_t vs1) {
|
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;
|
accrued_flags |= softfloat_exceptionFlags;
|
||||||
return val;
|
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
|
case 0b111000: // VFWMUL
|
||||||
return [](uint8_t rm, uint8_t& accrued_flags, dest_elem_t vd, src2_elem_t vs2, src1_elem_t vs1) {
|
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;
|
accrued_flags |= softfloat_exceptionFlags;
|
||||||
return val;
|
return val;
|
||||||
};
|
};
|
||||||
@ -1356,90 +1353,162 @@ void fp_vector_red_op(uint8_t* V, unsigned funct6, unsigned funct3, uint64_t vl,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
template <typename elem_size_t> elem_size_t fp_sqrt(uint8_t, elem_size_t);
|
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 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 <> 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 <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 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 <> 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 <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 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 <> 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 <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 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 <> 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 <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) {
|
template <> inline uint32_t fp_f_to_ui<uint32_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||||
softfloat_exceptionFlags = 0;
|
softfloat_exceptionFlags = 0;
|
||||||
|
softfloat_roundingMode = rm;
|
||||||
return f32_to_ui32(float32_t{v2}, rm, true);
|
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) {
|
template <> inline uint64_t fp_f_to_ui<uint64_t, uint64_t>(uint8_t rm, uint64_t v2) {
|
||||||
softfloat_exceptionFlags = 0;
|
softfloat_exceptionFlags = 0;
|
||||||
|
softfloat_roundingMode = rm;
|
||||||
return f64_to_ui64(float64_t{v2}, rm, true);
|
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) {
|
template <> inline uint64_t fp_f_to_ui<uint64_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||||
softfloat_exceptionFlags = 0;
|
softfloat_exceptionFlags = 0;
|
||||||
|
softfloat_roundingMode = rm;
|
||||||
return f32_to_ui64(float32_t{v2}, rm, true);
|
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) {
|
template <> inline uint32_t fp_f_to_ui<uint32_t, uint64_t>(uint8_t rm, uint64_t v2) {
|
||||||
softfloat_exceptionFlags = 0;
|
softfloat_exceptionFlags = 0;
|
||||||
|
softfloat_roundingMode = rm;
|
||||||
return f64_to_ui32(float64_t{v2}, rm, true);
|
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 <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) {
|
template <> inline uint32_t fp_f_to_i<uint32_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||||
softfloat_exceptionFlags = 0;
|
softfloat_exceptionFlags = 0;
|
||||||
|
softfloat_roundingMode = rm;
|
||||||
return f32_to_i32(float32_t{v2}, rm, true);
|
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) {
|
template <> inline uint64_t fp_f_to_i<uint64_t, uint64_t>(uint8_t rm, uint64_t v2) {
|
||||||
softfloat_exceptionFlags = 0;
|
softfloat_exceptionFlags = 0;
|
||||||
|
softfloat_roundingMode = rm;
|
||||||
return f64_to_i64(float64_t{v2}, rm, true);
|
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) {
|
template <> inline uint64_t fp_f_to_i<uint64_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||||
softfloat_exceptionFlags = 0;
|
softfloat_exceptionFlags = 0;
|
||||||
|
softfloat_roundingMode = rm;
|
||||||
return f32_to_i64(float32_t{v2}, rm, true);
|
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) {
|
template <> inline uint32_t fp_f_to_i<uint32_t, uint64_t>(uint8_t rm, uint64_t v2) {
|
||||||
softfloat_exceptionFlags = 0;
|
softfloat_exceptionFlags = 0;
|
||||||
|
softfloat_roundingMode = rm;
|
||||||
return f64_to_i32(float64_t{v2}, rm, true);
|
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 <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>(uint32_t v2) {
|
template <> inline uint32_t fp_ui_to_f<uint32_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||||
softfloat_exceptionFlags = 0;
|
softfloat_exceptionFlags = 0;
|
||||||
|
softfloat_roundingMode = rm;
|
||||||
return ui32_to_f32(v2).v;
|
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_exceptionFlags = 0;
|
||||||
|
softfloat_roundingMode = rm;
|
||||||
return ui64_to_f64(v2).v;
|
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_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;
|
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_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;
|
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 <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>(uint32_t v2) {
|
template <> inline uint32_t fp_i_to_f<uint32_t, uint32_t>(uint8_t rm, uint32_t v2) {
|
||||||
softfloat_exceptionFlags = 0;
|
softfloat_exceptionFlags = 0;
|
||||||
|
softfloat_roundingMode = rm;
|
||||||
return i32_to_f32(v2).v;
|
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_exceptionFlags = 0;
|
||||||
|
softfloat_roundingMode = rm;
|
||||||
return i64_to_f64(v2).v;
|
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_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;
|
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_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;
|
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");
|
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 uint64_t fp_f_to_f<uint64_t, uint32_t>(uint8_t rm, uint32_t val) {
|
||||||
template <> inline uint32_t fp_f_to_f<uint32_t, uint64_t>(uint8_t mode, uint64_t val) { return fconv_d2f(val, mode); }
|
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>
|
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) {
|
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 0b01010: // VFWCVT.F.XU.V
|
||||||
case 0b10010: // VFNCVT.F.XU.W
|
case 0b10010: // VFNCVT.F.XU.W
|
||||||
return [](uint8_t rm, uint8_t& accrued_flags, src_elem_t vs2) {
|
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;
|
accrued_flags |= softfloat_exceptionFlags;
|
||||||
return val;
|
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 0b01011: // VFWCVT.F.X.V
|
||||||
case 0b10011: // VFNCVT.F.X.W
|
case 0b10011: // VFNCVT.F.X.W
|
||||||
return [](uint8_t rm, uint8_t& accrued_flags, src_elem_t vs2) {
|
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;
|
accrued_flags |= softfloat_exceptionFlags;
|
||||||
return val;
|
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 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);
|
auto fn = get_fp_unary_fn<dest_elem_t, src_elem_t>(encoding_space, unary_op);
|
||||||
uint8_t accrued_flags = 0;
|
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];
|
bool mask_active = vm ? 1 : mask_reg[idx];
|
||||||
if(mask_active) {
|
if(mask_active) {
|
||||||
vd_view[idx] = fn(rm, accrued_flags, vs2_view[idx]);
|
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;
|
softfloat_exceptionFlags = accrued_flags;
|
||||||
unsigned maximum_elems = VLEN * vtype.lmul() / (sizeof(dest_elem_t) * 8);
|
for(size_t idx = vl; idx < elem_count; idx++) {
|
||||||
for(size_t idx = std::min(elem_count, vl); idx < maximum_elems; idx++) {
|
|
||||||
vd_view[idx] = vtype.vta() ? vd_view[idx] : vd_view[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 <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); }
|
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