OpenRISC FPU Updates for 8.1
A few fixes and updates to bring OpenRISC inline with the latest architecture spec updates: - Allow FPCSR to be accessed in user mode - Select tininess detection before rounding - Fix FPE Exception PC value -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE2cRzVK74bBA6Je/xw7McLV5mJ+QFAmRfPIEACgkQw7McLV5m J+RFuhAAt4xxci52fxvPpgUu/mjKU6mbYNjBEPEh+OAcb+m/BrvKhazZDACkyLMe ehavWtI856jfy6DsIA5wj5+zhgV8W5DR6a1mHIhmSAoVq7e+NnC5y0GJC9B0Xd/2 FNOq/LZPtv/w7u+D1pFJaTb07hAaFVIC05Arn4dXa1k3yBuyjqIJnlrXa3Jt0pLW To/z1zch1rUp6RhFmGxU+8/qvTbzqkm/F3kbe8l2z34371lTd6KhPwvKaImMpTYQ dvULTMXjZ6Dp8BmUrDcnLMTL3NbYcPrI+qOHX1X+dwzNFyui2I8Ci7IfEKJ460ja Fe2Ku/aDfHSZYYayWaYSlrrZ1AH0fLLwIkHSs95+xUMsl81mtS6lIysj7fAFRnM5 7tU4ov1T/leupvvUCUX5N4Yje/yvbuoAqGyhjDHzJ98vIe6fDhutU4Bm8/30q6Dy nKnfSgRHrrTrH042xW32DJnzaN2pEWrNtOMaegLMaqZ60app2YDaKJvtHLua1VjD b+g+X/+xBNb34k5e/f4z+GeGPoqE2wvwMcSkD+NBE8je3idPdMS/u5lQrvqvcbI/ DJBRoPifNME/oYoTxPVKRnrCQIWQ6YkeLWVmqMfCVpjCF97gexo+UBUawJimTXFr gmcIYxv87oKF4KbCn7LsLlXGSpWSihKSBTHDxFPaKiRbnYZ5ais= =zqbX -----END PGP SIGNATURE----- Merge tag 'or1k-pull-request-20230513' of https://github.com/stffrdhrn/qemu into staging OpenRISC FPU Updates for 8.1 A few fixes and updates to bring OpenRISC inline with the latest architecture spec updates: - Allow FPCSR to be accessed in user mode - Select tininess detection before rounding - Fix FPE Exception PC value # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEE2cRzVK74bBA6Je/xw7McLV5mJ+QFAmRfPIEACgkQw7McLV5m # J+RFuhAAt4xxci52fxvPpgUu/mjKU6mbYNjBEPEh+OAcb+m/BrvKhazZDACkyLMe # ehavWtI856jfy6DsIA5wj5+zhgV8W5DR6a1mHIhmSAoVq7e+NnC5y0GJC9B0Xd/2 # FNOq/LZPtv/w7u+D1pFJaTb07hAaFVIC05Arn4dXa1k3yBuyjqIJnlrXa3Jt0pLW # To/z1zch1rUp6RhFmGxU+8/qvTbzqkm/F3kbe8l2z34371lTd6KhPwvKaImMpTYQ # dvULTMXjZ6Dp8BmUrDcnLMTL3NbYcPrI+qOHX1X+dwzNFyui2I8Ci7IfEKJ460ja # Fe2Ku/aDfHSZYYayWaYSlrrZ1AH0fLLwIkHSs95+xUMsl81mtS6lIysj7fAFRnM5 # 7tU4ov1T/leupvvUCUX5N4Yje/yvbuoAqGyhjDHzJ98vIe6fDhutU4Bm8/30q6Dy # nKnfSgRHrrTrH042xW32DJnzaN2pEWrNtOMaegLMaqZ60app2YDaKJvtHLua1VjD # b+g+X/+xBNb34k5e/f4z+GeGPoqE2wvwMcSkD+NBE8je3idPdMS/u5lQrvqvcbI/ # DJBRoPifNME/oYoTxPVKRnrCQIWQ6YkeLWVmqMfCVpjCF97gexo+UBUawJimTXFr # gmcIYxv87oKF4KbCn7LsLlXGSpWSihKSBTHDxFPaKiRbnYZ5ais= # =zqbX # -----END PGP SIGNATURE----- # gpg: Signature made Sat 13 May 2023 08:30:09 AM BST # gpg: using RSA key D9C47354AEF86C103A25EFF1C3B31C2D5E6627E4 # gpg: Good signature from "Stafford Horne <shorne@gmail.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: D9C4 7354 AEF8 6C10 3A25 EFF1 C3B3 1C2D 5E66 27E4 * tag 'or1k-pull-request-20230513' of https://github.com/stffrdhrn/qemu: target/openrisc: Setup FPU for detecting tininess before rounding target/openrisc: Set PC to cpu state on FPU exception target/openrisc: Allow fpcsr access in user mode Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
8844bb8d89
@ -22,6 +22,7 @@
|
||||
#include "qemu/qemu-print.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "fpu/softfloat-helpers.h"
|
||||
#include "tcg/tcg.h"
|
||||
|
||||
static void openrisc_cpu_set_pc(CPUState *cs, vaddr value)
|
||||
@ -90,6 +91,9 @@ static void openrisc_cpu_reset_hold(Object *obj)
|
||||
s->exception_index = -1;
|
||||
cpu_set_fpcsr(&cpu->env, 0);
|
||||
|
||||
set_float_detect_tininess(float_tininess_before_rounding,
|
||||
&cpu->env.fp_status);
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
cpu->env.picmr = 0x00000000;
|
||||
cpu->env.picsr = 0x00000000;
|
||||
|
@ -20,8 +20,8 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "exec/helper-proto.h"
|
||||
#include "exception.h"
|
||||
#include "fpu/softfloat.h"
|
||||
|
||||
static int ieee_ex_to_openrisc(int fexcp)
|
||||
@ -45,6 +45,15 @@ static int ieee_ex_to_openrisc(int fexcp)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static G_NORETURN
|
||||
void do_fpe(CPUOpenRISCState *env, uintptr_t pc)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
|
||||
cs->exception_index = EXCP_FPE;
|
||||
cpu_loop_exit_restore(cs, pc);
|
||||
}
|
||||
|
||||
void HELPER(update_fpcsr)(CPUOpenRISCState *env)
|
||||
{
|
||||
int tmp = get_float_exception_flags(&env->fp_status);
|
||||
@ -55,7 +64,7 @@ void HELPER(update_fpcsr)(CPUOpenRISCState *env)
|
||||
if (tmp) {
|
||||
env->fpcsr |= tmp;
|
||||
if (env->fpcsr & FPCSR_FPEE) {
|
||||
helper_exception(env, EXCP_FPE);
|
||||
do_fpe(env, GETPC());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,17 +29,37 @@
|
||||
|
||||
#define TO_SPR(group, number) (((group) << 11) + (number))
|
||||
|
||||
static inline bool is_user(CPUOpenRISCState *env)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
return true;
|
||||
#else
|
||||
return (env->sr & SR_SM) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
OpenRISCCPU *cpu = env_archcpu(env);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
CPUState *cs = env_cpu(env);
|
||||
target_ulong mr;
|
||||
int idx;
|
||||
#endif
|
||||
|
||||
/* Handle user accessible SPRs first. */
|
||||
switch (spr) {
|
||||
case TO_SPR(0, 20): /* FPCSR */
|
||||
cpu_set_fpcsr(env, rb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_user(env)) {
|
||||
raise_exception(cpu, EXCP_ILLEGAL);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
switch (spr) {
|
||||
case TO_SPR(0, 11): /* EVBAR */
|
||||
env->evbar = rb;
|
||||
break;
|
||||
@ -187,27 +207,33 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
|
||||
cpu_openrisc_timer_update(cpu);
|
||||
qemu_mutex_unlock_iothread();
|
||||
break;
|
||||
#endif
|
||||
|
||||
case TO_SPR(0, 20): /* FPCSR */
|
||||
cpu_set_fpcsr(env, rb);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
|
||||
target_ulong spr)
|
||||
{
|
||||
OpenRISCCPU *cpu = env_archcpu(env);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
uint64_t data[TARGET_INSN_START_WORDS];
|
||||
MachineState *ms = MACHINE(qdev_get_machine());
|
||||
OpenRISCCPU *cpu = env_archcpu(env);
|
||||
CPUState *cs = env_cpu(env);
|
||||
int idx;
|
||||
#endif
|
||||
|
||||
/* Handle user accessible SPRs first. */
|
||||
switch (spr) {
|
||||
case TO_SPR(0, 20): /* FPCSR */
|
||||
return env->fpcsr;
|
||||
}
|
||||
|
||||
if (is_user(env)) {
|
||||
raise_exception(cpu, EXCP_ILLEGAL);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
switch (spr) {
|
||||
case TO_SPR(0, 0): /* VR */
|
||||
return env->vr;
|
||||
|
||||
@ -324,11 +350,8 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
|
||||
cpu_openrisc_count_update(cpu);
|
||||
qemu_mutex_unlock_iothread();
|
||||
return cpu_openrisc_count_get(cpu);
|
||||
#endif
|
||||
|
||||
case TO_SPR(0, 20): /* FPCSR */
|
||||
return env->fpcsr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* for rd is passed in, if rd unchanged, just keep it back. */
|
||||
return rd;
|
||||
|
@ -819,13 +819,10 @@ static bool trans_l_xori(DisasContext *dc, arg_rri *a)
|
||||
|
||||
static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a)
|
||||
{
|
||||
check_r0_write(dc, a->d);
|
||||
|
||||
if (is_user(dc)) {
|
||||
gen_illegal_exception(dc);
|
||||
} else {
|
||||
TCGv spr = tcg_temp_new();
|
||||
|
||||
check_r0_write(dc, a->d);
|
||||
|
||||
if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
|
||||
gen_io_start();
|
||||
if (dc->delayed_branch) {
|
||||
@ -839,21 +836,18 @@ static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a)
|
||||
|
||||
tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
|
||||
gen_helper_mfspr(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->d), spr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a)
|
||||
{
|
||||
if (is_user(dc)) {
|
||||
gen_illegal_exception(dc);
|
||||
} else {
|
||||
TCGv spr;
|
||||
TCGv spr = tcg_temp_new();
|
||||
|
||||
if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
|
||||
gen_io_start();
|
||||
}
|
||||
/* For SR, we will need to exit the TB to recognize the new
|
||||
/*
|
||||
* For SR, we will need to exit the TB to recognize the new
|
||||
* exception state. For NPC, in theory this counts as a branch
|
||||
* (although the SPR only exists for use by an ICE). Save all
|
||||
* of the cpu state first, allowing it to be overwritten.
|
||||
@ -866,10 +860,8 @@ static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a)
|
||||
}
|
||||
dc->base.is_jmp = DISAS_EXIT;
|
||||
|
||||
spr = tcg_temp_new();
|
||||
tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
|
||||
gen_helper_mtspr(cpu_env, spr, cpu_R(dc, a->b));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user