mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
target-tricore: Add FPU infrastructure
This patch adds a file for all the FPU related helpers with all the includes, useful defines, and a function to update the status bits. Additionally it adds a mask for the rounding mode bits of PSW as well as all the opcodes for the FPU instructions. Reviewed-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> Message-Id: <1457708597-3025-2-git-send-email-kbastian@mail.uni-paderborn.de>
This commit is contained in:
parent
1bd3e2fc3d
commit
996a729f9b
7 changed files with 116 additions and 4 deletions
|
@ -113,7 +113,7 @@ const float16 float16_default_nan = const_float16(0xFE00);
|
|||
#if defined(TARGET_SPARC)
|
||||
const float32 float32_default_nan = const_float32(0x7FFFFFFF);
|
||||
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
|
||||
defined(TARGET_XTENSA) || defined(TARGET_S390X)
|
||||
defined(TARGET_XTENSA) || defined(TARGET_S390X) || defined(TARGET_TRICORE)
|
||||
const float32 float32_default_nan = const_float32(0x7FC00000);
|
||||
#elif SNAN_BIT_IS_ONE
|
||||
const float32 float32_default_nan = const_float32(0x7FBFFFFF);
|
||||
|
|
|
@ -1 +1 @@
|
|||
obj-y += translate.o helper.o cpu.o op_helper.o
|
||||
obj-y += translate.o helper.o cpu.o op_helper.o fpu_helper.o
|
||||
|
|
|
@ -183,8 +183,7 @@ struct CPUTriCoreState {
|
|||
uint32_t M2CNT;
|
||||
uint32_t M3CNT;
|
||||
/* Floating Point Registers */
|
||||
/* XXX: */
|
||||
|
||||
float_status fp_status;
|
||||
/* QEMU */
|
||||
int error_code;
|
||||
uint32_t hflags; /* CPU State */
|
||||
|
@ -217,6 +216,7 @@ struct CPUTriCoreState {
|
|||
#define MASK_PSW_GW 0x00000100
|
||||
#define MASK_PSW_CDE 0x00000080
|
||||
#define MASK_PSW_CDC 0x0000007f
|
||||
#define MASK_PSW_FPU_RM 0x3000000
|
||||
|
||||
#define MASK_SYSCON_PRO_TEN 0x2
|
||||
#define MASK_SYSCON_FCD_SF 0x1
|
||||
|
@ -339,6 +339,8 @@ enum {
|
|||
uint32_t psw_read(CPUTriCoreState *env);
|
||||
void psw_write(CPUTriCoreState *env, uint32_t val);
|
||||
|
||||
void fpu_set_state(CPUTriCoreState *env);
|
||||
|
||||
#include "cpu-qom.h"
|
||||
#define MMU_USER_IDX 2
|
||||
|
||||
|
|
81
target-tricore/fpu_helper.c
Normal file
81
target-tricore/fpu_helper.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* TriCore emulation for qemu: fpu helper.
|
||||
*
|
||||
* Copyright (c) 2016 Bastian Koppelmann University of Paderborn
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/helper-proto.h"
|
||||
|
||||
#define ADD_NAN 0x7cf00001
|
||||
#define DIV_NAN 0x7fc00008
|
||||
#define MUL_NAN 0x7fc00002
|
||||
#define FPU_FS PSW_USB_C
|
||||
#define FPU_FI PSW_USB_V
|
||||
#define FPU_FV PSW_USB_SV
|
||||
#define FPU_FZ PSW_USB_AV
|
||||
#define FPU_FU PSW_USB_SAV
|
||||
|
||||
/* we don't care about input_denormal */
|
||||
static inline uint8_t f_get_excp_flags(CPUTriCoreState *env)
|
||||
{
|
||||
return get_float_exception_flags(&env->fp_status)
|
||||
& (float_flag_invalid
|
||||
| float_flag_overflow
|
||||
| float_flag_underflow
|
||||
| float_flag_output_denormal
|
||||
| float_flag_divbyzero
|
||||
| float_flag_inexact);
|
||||
}
|
||||
|
||||
static inline bool f_is_denormal(float32 arg)
|
||||
{
|
||||
return float32_is_zero_or_denormal(arg) && !float32_is_zero(arg);
|
||||
}
|
||||
|
||||
static inline void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags)
|
||||
{
|
||||
uint8_t some_excp = 0;
|
||||
set_float_exception_flags(0, &env->fp_status);
|
||||
|
||||
if (flags & float_flag_invalid) {
|
||||
env->FPU_FI = 1 << 31;
|
||||
some_excp = 1;
|
||||
}
|
||||
|
||||
if (flags & float_flag_overflow) {
|
||||
env->FPU_FV = 1 << 31;
|
||||
some_excp = 1;
|
||||
}
|
||||
|
||||
if (flags & float_flag_underflow || flags & float_flag_output_denormal) {
|
||||
env->FPU_FU = 1 << 31;
|
||||
some_excp = 1;
|
||||
}
|
||||
|
||||
if (flags & float_flag_divbyzero) {
|
||||
env->FPU_FZ = 1 << 31;
|
||||
some_excp = 1;
|
||||
}
|
||||
|
||||
if (flags & float_flag_inexact || flags & float_flag_output_denormal) {
|
||||
env->PSW |= 1 << 26;
|
||||
some_excp = 1;
|
||||
}
|
||||
|
||||
env->FPU_FS = some_excp;
|
||||
}
|
|
@ -110,6 +110,14 @@ void tricore_cpu_list(FILE *f, fprintf_function cpu_fprintf)
|
|||
g_slist_free(list);
|
||||
}
|
||||
|
||||
void fpu_set_state(CPUTriCoreState *env)
|
||||
{
|
||||
set_float_rounding_mode(env->PSW & MASK_PSW_FPU_RM, &env->fp_status);
|
||||
set_flush_inputs_to_zero(1, &env->fp_status);
|
||||
set_flush_to_zero(1, &env->fp_status);
|
||||
set_default_nan_mode(1, &env->fp_status);
|
||||
}
|
||||
|
||||
uint32_t psw_read(CPUTriCoreState *env)
|
||||
{
|
||||
/* clear all USB bits */
|
||||
|
@ -132,4 +140,6 @@ void psw_write(CPUTriCoreState *env, uint32_t val)
|
|||
env->PSW_USB_AV = (val & MASK_USB_AV) << 3;
|
||||
env->PSW_USB_SAV = (val & MASK_USB_SAV) << 4;
|
||||
env->PSW = val;
|
||||
|
||||
fpu_set_state(env);
|
||||
}
|
||||
|
|
|
@ -8773,6 +8773,7 @@ void cpu_state_reset(CPUTriCoreState *env)
|
|||
{
|
||||
/* Reset Regs to Default Value */
|
||||
env->PSW = 0xb80;
|
||||
fpu_set_state(env);
|
||||
}
|
||||
|
||||
static void tricore_tcg_init_csfr(void)
|
||||
|
|
|
@ -1126,6 +1126,20 @@ enum {
|
|||
OPC2_32_RR_CRC32 = 0x03,
|
||||
OPC2_32_RR_DIV = 0x20,
|
||||
OPC2_32_RR_DIV_U = 0x21,
|
||||
OPC2_32_RR_MUL_F = 0x04,
|
||||
OPC2_32_RR_DIV_F = 0x05,
|
||||
OPC2_32_RR_FTOI = 0x10,
|
||||
OPC2_32_RR_ITOF = 0x14,
|
||||
OPC2_32_RR_CMP_F = 0x00,
|
||||
OPC2_32_RR_FTOIZ = 0x13,
|
||||
OPC2_32_RR_FTOQ31 = 0x11,
|
||||
OPC2_32_RR_FTOQ31Z = 0x18,
|
||||
OPC2_32_RR_FTOU = 0x12,
|
||||
OPC2_32_RR_FTOUZ = 0x17,
|
||||
OPC2_32_RR_Q31TOF = 0x15,
|
||||
OPC2_32_RR_QSEED_F = 0x19,
|
||||
OPC2_32_RR_UPDFL = 0x0c,
|
||||
OPC2_32_RR_UTOF = 0x16,
|
||||
};
|
||||
/* OPCM_32_RR_IDIRECT */
|
||||
enum {
|
||||
|
@ -1209,6 +1223,10 @@ enum {
|
|||
OPC2_32_RRR_IXMIN = 0x08,
|
||||
OPC2_32_RRR_IXMIN_U = 0x09,
|
||||
OPC2_32_RRR_PACK = 0x00,
|
||||
OPC2_32_RRR_ADD_F = 0x02,
|
||||
OPC2_32_RRR_SUB_F = 0x03,
|
||||
OPC2_32_RRR_MADD_F = 0x06,
|
||||
OPC2_32_RRR_MSUB_F = 0x07,
|
||||
};
|
||||
/*
|
||||
* RRR1 Format
|
||||
|
|
Loading…
Reference in a new issue