adds UserProvidedFunctions for NaNBoxing, updates generated files, adapts to new fp API

This commit is contained in:
2025-04-02 10:19:11 +02:00
parent 8f5d666b7d
commit 7e97329e78
8 changed files with 412 additions and 265 deletions

View File

@@ -139,7 +139,33 @@ if(fcsr != null) {%>
}
<%functions.each{ it.eachLine { %>
${it}<%}%>
${it}<%}
}
if(fcsr != null) {%>
value NaNBox16(tu_builder& tu, value NaNBox16_val){
if(static_cast<uint32_t>(traits::FLEN) == 16)
return tu.ext(NaNBox16_val, traits::FLEN, false);
else {
auto box = tu.assignment(tu.logical_neg((tu.ext(0, 32, false))), traits::FLEN) ;
return tu.ext((tu.bitwise_or(tu.shl(box, 16), NaNBox16_val)), traits::FLEN, false);
}
}
value NaNBox32(tu_builder& tu, value NaNBox32_val){
if(static_cast<uint32_t>(traits::FLEN) == 32)
return tu.ext(NaNBox32_val, traits::FLEN, false);
else {
auto box = tu.assignment(tu.logical_neg((tu.ext(0, 64, false))), traits::FLEN) ;
return tu.ext((tu.bitwise_or(tu.shl(box, 32), NaNBox32_val)), traits::FLEN, false);
}
}
value NaNBox64(tu_builder& tu, value NaNBox64_val){
if(static_cast<uint32_t>(traits::FLEN) == 32)
return tu.ext(NaNBox64_val, traits::FLEN, false);
else {
auto box = tu.assignment(tu.logical_neg((tu.ext(0, 128, false))), traits::FLEN) ;
return tu.ext((tu.bitwise_or(tu.shl(box, 64), NaNBox64_val)), traits::FLEN, false);
}
}
<%}%>
private:
/****************************************************************************
@@ -181,6 +207,8 @@ private:
this->gen_set_tval(tu, instr);
<%instr.behavior.eachLine{%>${it}
<%}%>
tu("(*icount)++;");
tu("(*instret)++;");
tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,${idx});
gen_trap_check(tu);
@@ -232,8 +260,6 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, tu_builder& tu) {
enum {TRAP_ID=1<<16};
code_word_t instr = 0;
phys_addr_t paddr(pc);
if(this->core.has_mmu())
paddr = this->core.virt2phys(pc);
auto res = this->core.read(paddr, 4, reinterpret_cast<uint8_t*>(&instr));
if (res != iss::Ok)
return ILLEGAL_FETCH;
@@ -278,34 +304,74 @@ template <typename ARCH> void vm_impl<ARCH>::add_prologue(tu_builder& tu){
os << tu.add_reg_ptr("trap_state", arch::traits<ARCH>::TRAP_STATE, this->regs_base_ptr);
os << tu.add_reg_ptr("pending_trap", arch::traits<ARCH>::PENDING_TRAP, this->regs_base_ptr);
os << tu.add_reg_ptr("cycle", arch::traits<ARCH>::CYCLE, this->regs_base_ptr);
<%if(fcsr != null) {%>
<%if(fcsr != null) {
def flen = constants.find { it.name == 'FLEN' }?.value ?: 0
%>
os << "uint32_t (*fget_flags)()=" << (uintptr_t)&fget_flags << ";\\n";
os << "uint16_t (*fadd_h)(uint16_t v1, uint16_t v2, uint8_t mode)=" << (uintptr_t)&fadd_h << ";\\n";
os << "uint16_t (*fsub_h)(uint16_t v1, uint16_t v2, uint8_t mode)=" << (uintptr_t)&fsub_h << ";\\n";
os << "uint16_t (*fmul_h)(uint16_t v1, uint16_t v2, uint8_t mode)=" << (uintptr_t)&fmul_h << ";\\n";
os << "uint16_t (*fdiv_h)(uint16_t v1, uint16_t v2, uint8_t mode)=" << (uintptr_t)&fdiv_h << ";\\n";
os << "uint16_t (*fsqrt_h)(uint16_t v1, uint8_t mode)=" << (uintptr_t)&fsqrt_h << ";\\n";
os << "uint16_t (*fcmp_h)(uint16_t v1, uint16_t v2, uint16_t op)=" << (uintptr_t)&fcmp_h << ";\\n";
os << "uint16_t (*fmadd_h)(uint16_t v1, uint16_t v2, uint16_t v3, uint16_t op, uint8_t mode)=" << (uintptr_t)&fmadd_h << ";\\n";
os << "uint16_t (*fsel_h)(uint16_t v1, uint16_t v2, uint16_t op)=" << (uintptr_t)&fsel_h << ";\\n";
os << "uint16_t (*fclass_h)(uint16_t v1)=" << (uintptr_t)&fclass_h << ";\\n";
os << "uint16_t (*unbox_h)(uint8_t FLEN, uint64_t v)=" << (uintptr_t)&unbox_h << ";\\n";
os << "uint32_t (*f16toi32)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&f16toi32 << ";\\n";
os << "uint32_t (*f16toui32)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&f16toui32 << ";\\n";
os << "uint16_t (*i32tof16)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&i32tof16 << ";\\n";
os << "uint16_t (*ui32tof16)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&ui32tof16 << ";\\n";
os << "uint64_t (*f16toi64)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&f16toi64 <<";\\n";
os << "uint64_t (*f16toui64)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&f16toui64 <<";\\n";
os << "uint16_t (*i64tof16)(uint64_t v1, uint8_t mode)=" << (uintptr_t)&i64tof16 <<";\\n";
os << "uint16_t (*ui64tof16)(uint64_t v1, uint8_t mode)=" << (uintptr_t)&ui64tof16 <<";\\n";
os << "uint32_t (*fadd_s)(uint32_t v1, uint32_t v2, uint8_t mode)=" << (uintptr_t)&fadd_s << ";\\n";
os << "uint32_t (*fsub_s)(uint32_t v1, uint32_t v2, uint8_t mode)=" << (uintptr_t)&fsub_s << ";\\n";
os << "uint32_t (*fmul_s)(uint32_t v1, uint32_t v2, uint8_t mode)=" << (uintptr_t)&fmul_s << ";\\n";
os << "uint32_t (*fdiv_s)(uint32_t v1, uint32_t v2, uint8_t mode)=" << (uintptr_t)&fdiv_s << ";\\n";
os << "uint32_t (*fsqrt_s)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&fsqrt_s << ";\\n";
os << "uint32_t (*fcmp_s)(uint32_t v1, uint32_t v2, uint32_t op)=" << (uintptr_t)&fcmp_s << ";\\n";
os << "uint32_t (*fcvt_s)(uint32_t v1, uint32_t op, uint8_t mode)=" << (uintptr_t)&fcvt_s << ";\\n";
os << "uint32_t (*fmadd_s)(uint32_t v1, uint32_t v2, uint32_t v3, uint32_t op, uint8_t mode)=" << (uintptr_t)&fmadd_s << ";\\n";
os << "uint32_t (*fsel_s)(uint32_t v1, uint32_t v2, uint32_t op)=" << (uintptr_t)&fsel_s << ";\\n";
os << "uint32_t (*fclass_s)( uint32_t v1 )=" << (uintptr_t)&fclass_s << ";\\n";
os << "uint32_t (*fconv_d2f)(uint64_t v1, uint8_t mode)=" << (uintptr_t)&fconv_d2f << ";\\n";
os << "uint64_t (*fconv_f2d)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&fconv_f2d << ";\\n";
os << "uint32_t (*f32toi32)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&f32toi32 << ";\\n";
os << "uint32_t (*f32toui32)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&f32toui32 << ";\\n";
os << "uint32_t (*i32tof32)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&i32tof32 << ";\\n";
os << "uint32_t (*ui32tof32)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&ui32tof32 << ";\\n";
os << "uint64_t (*f32toi64)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&f32toi64 <<";\\n";
os << "uint64_t (*f32toui64)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&f32toui64 <<";\\n";
os << "uint32_t (*i64tof32)(uint64_t v1, uint8_t mode)=" << (uintptr_t)&i64tof32 <<";\\n";
os << "uint32_t (*ui64tof32)(uint64_t v1, uint8_t mode)=" << (uintptr_t)&ui64tof32 <<";\\n";
<%if(flen > 32) {%>
os << "uint32_t (*unbox_s)(uint8_t FLEN, uint64_t v)=" << (uintptr_t)&unbox_s << ";\\n";
os << "uint64_t (*fadd_d)(uint64_t v1, uint64_t v2, uint8_t mode)=" << (uintptr_t)&fadd_d << ";\\n";
os << "uint64_t (*fsub_d)(uint64_t v1, uint64_t v2, uint8_t mode)=" << (uintptr_t)&fsub_d << ";\\n";
os << "uint64_t (*fmul_d)(uint64_t v1, uint64_t v2, uint8_t mode)=" << (uintptr_t)&fmul_d << ";\\n";
os << "uint64_t (*fdiv_d)(uint64_t v1, uint64_t v2, uint8_t mode)=" << (uintptr_t)&fdiv_d << ";\\n";
os << "uint64_t (*fsqrt_d)(uint64_t v1, uint8_t mode)=" << (uintptr_t)&fsqrt_d << ";\\n";
os << "uint64_t (*fcmp_d)(uint64_t v1, uint64_t v2, uint32_t op)=" << (uintptr_t)&fcmp_d << ";\\n";
os << "uint64_t (*fcvt_d)(uint64_t v1, uint32_t op, uint8_t mode)=" << (uintptr_t)&fcvt_d << ";\\n";
os << "uint64_t (*fmadd_d)(uint64_t v1, uint64_t v2, uint64_t v3, uint32_t op, uint8_t mode)=" << (uintptr_t)&fmadd_d << ";\\n";
os << "uint64_t (*fsel_d)(uint64_t v1, uint64_t v2, uint32_t op)=" << (uintptr_t)&fsel_d << ";\\n";
os << "uint64_t (*fclass_d)(uint64_t v1 )=" << (uintptr_t)&fclass_d << ";\\n";
os << "uint64_t (*fcvt_32_64)(uint32_t v1, uint32_t op, uint8_t mode)=" << (uintptr_t)&fcvt_32_64 << ";\\n";
os << "uint32_t (*fcvt_64_32)(uint64_t v1, uint32_t op, uint8_t mode)=" << (uintptr_t)&fcvt_64_32 << ";\\n";
os << "uint32_t (*unbox_s)(uint64_t v)=" << (uintptr_t)&unbox_s << ";\\n";
<%}%>
os << "uint32_t (*f64tof32)(uint64_t v1, uint8_t mode)=" << (uintptr_t)&f64tof32 << ";\\n";
os << "uint64_t (*f32tof64)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&f32tof64 << ";\\n";
os << "uint64_t (*f64toi64)(uint64_t v1, uint8_t mode)=" << (uintptr_t)&f64toi64 <<";\\n";
os << "uint64_t (*f64toui64)(uint64_t v1, uint8_t mode)=" << (uintptr_t)&f64toui64 <<";\\n";
os << "uint64_t (*i64tof64)(uint64_t v1, uint8_t mode)=" << (uintptr_t)&i64tof64 <<";\\n";
os << "uint64_t (*ui64tof64)(uint64_t v1, uint8_t mode)=" << (uintptr_t)&ui64tof64 <<";\\n";
os << "uint64_t (*i32tof64)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&i32tof64 <<";\\n";
os << "uint64_t (*ui32tof64)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&ui32tof64 <<";\\n";
os << "uint32_t (*f64toi32)(uint64_t v1, uint8_t mode)=" << (uintptr_t)&f64toi32 <<";\\n";
os << "uint32_t (*f64toui32)(uint64_t v1, uint8_t mode)=" << (uintptr_t)&f64toui32 <<";\\n";
<%}
}%>
tu.add_prologue(os.str());
}