Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / legion / src / host / sparcv9native_ua200x.c
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: sparcv9native_ua200x.c
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
*
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
*
* The above named program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ========== Copyright Header End ============================================
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "@(#)sparcv9native_ua200x.c 1.1 06/12/07 SMI"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h> /* memcpy/memset */
#include <strings.h>
#include <thread.h>
#include "ss_common.h"
#include "rock.h"
#include "fpsim.h"
static void fp_trap_gen (simcpu_t *sp, int trap_code);
#define IMPL( _n ) void decoded_impl_rock_##_n (simcpu_t *sp, xicache_instn_t * xcip) {
#define ENDI NEXT_INSTN(sp); ENDDEF
#define ENDDEF }
/* negated and half add fp ops */
IMPL( rk_fnadds )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint32_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fnadds) ((float*) &F32src1, (float*) &F32src2, \
(float*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fnadds; Fsrc1=0x%lx, Fsrc2=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, F32src2, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F32dest = result;
ENDI
IMPL( rk_fnaddd )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint64_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fnaddd) ((double*) &F64src1, (double*) &F64src2, \
(double*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fnaddd; Fsrc1=0x%llx, Fsrc2=0x%llx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, F64src2, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F64dest = result;
ENDI
IMPL( rk_fnmuls )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint32_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fnmuls) ((float*) &F32src1, (float*) &F32src2, \
(float*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fnmuls; Fsrc1=0x%lx, Fsrc2=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, F32src2, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F32dest = result;
ENDI
IMPL( rk_fnmuld )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint64_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fnmuld) ((double*) &F64src1, (double*) &F64src2, \
(double*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fnmuld; Fsrc1=0x%llx, Fsrc2=0x%llx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, F64src2, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F64dest = result;
ENDI
IMPL( rk_fhadds )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint32_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fhadds) ((float*) &F32src1, (float*) &F32src2, \
(float*) &result, fsrcopy, gsrcopy, FHA_ADD);
DBGFP( lprintf(sp->gid, "fhadds; Fsrc1=0x%lx, Fsrc2=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, F32src2, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F32dest = result;
ENDI
IMPL( rk_fhaddd )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint64_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fhaddd) ((double*) &F64src1, (double*) &F64src2, \
(double*) &result, fsrcopy, gsrcopy, FHA_ADD);
DBGFP( lprintf(sp->gid, "fhaddd; Fsrc1=0x%llx, Fsrc2=0x%llx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, F64src2, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F64dest = result;
ENDI
IMPL( rk_fhsubs )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint32_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fhadds) ((float*) &F32src1, (float*) &F32src2, \
(float*) &result, fsrcopy, gsrcopy, FHA_SUB);
DBGFP( lprintf(sp->gid, "fhsubs; Fsrc1=0x%lx, Fsrc2=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, F32src2, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F32dest = result;
ENDI
IMPL( rk_fhsubd )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint64_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fhaddd) ((double*) &F64src1, (double*) &F64src2, \
(double*) &result, fsrcopy, gsrcopy, FHA_SUB);
DBGFP( lprintf(sp->gid, "fhsubd; Fsrc1=0x%llx, Fsrc2=0x%llx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, F64src2, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F64dest = result;
ENDI
IMPL( rk_fnhadds )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint32_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fhadds) ((float*) &F32src1, (float*) &F32src2, \
(float*) &result, fsrcopy, gsrcopy, FHA_ADD_NEG);
DBGFP( lprintf(sp->gid, "fnhadds; Fsrc1=0x%lx, Fsrc2=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, F32src2, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F32dest = result;
ENDI
IMPL( rk_fnhaddd )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint64_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fhaddd) ((double*) &F64src1, (double*) &F64src2, \
(double*) &result, fsrcopy, gsrcopy, FHA_ADD_NEG);
DBGFP( lprintf(sp->gid, "fnhaddd; Fsrc1=0x%llx, Fsrc2=0x%llx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, F64src2, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F64dest = result;
ENDI
IMPL( rk_fnsmuld )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint64_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fnsmuld) ((float*) &F32src1, (float*) &F32src2, \
(double*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fnsmuld; Fsrc1=0x%llx, Fsrc2=0x%llx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F32src1, F32src2, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F64dest = result;
ENDI
/* fused multiply add fp ops */
IMPL( rk_fmadds )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint32_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fmadds) ((float*) &F32src1, (float*) &F32src2, (float*) &F32src3, \
(float*) &result, fsrcopy, gsrcopy, FMA_ADD_POS);
DBGFP( lprintf(sp->gid, "fmadds; Fsrc1=0x%lx, Fsrc2=0x%lx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, F32src2, F32src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F32dest = result;
ENDI
IMPL( rk_fmaddd )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint64_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fmaddd) ((double*) &F64src1, (double*) &F64src2, (double*) &F64src3, \
(double*) &result, fsrcopy, gsrcopy, FMA_ADD_POS);
DBGFP( lprintf(sp->gid, "fmaddd; Fsrc1=0x%llx, Fsrc2=0x%llx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, F64src2, F64src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F64dest = result;
ENDI
IMPL( rk_fmsubs )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint32_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fmadds) ((float*) &F32src1, (float*) &F32src2, (float*) &F32src3, \
(float*) &result, fsrcopy, gsrcopy, FMA_SUB_POS);
DBGFP( lprintf(sp->gid, "fmsubs; Fsrc1=0x%lx, Fsrc2=0x%lx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, F32src2, F32src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F32dest = result;
ENDI
IMPL( rk_fmsubd )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint64_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fmaddd) ((double*) &F64src1, (double*) &F64src2, (double*) &F64src3, \
(double*) &result, fsrcopy, gsrcopy, FMA_SUB_POS);
DBGFP( lprintf(sp->gid, "fmsubd; Fsrc1=0x%llx, Fsrc2=0x%llx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, F64src2, F64src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F64dest = result;
ENDI
IMPL( rk_fnmsubs )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint32_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fmadds) ((float*) &F32src1, (float*) &F32src2, (float*) &F32src3, \
(float*) &result, fsrcopy, gsrcopy, FMA_SUB_NEG);
DBGFP( lprintf(sp->gid, "fnmsubs; Fsrc1=0x%lx, Fsrc2=0x%lx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, F32src2, F32src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F32dest = result;
ENDI
IMPL( rk_fnmsubd )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint64_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fmaddd) ((double*) &F64src1, (double*) &F64src2, (double*) &F64src3, \
(double*) &result, fsrcopy, gsrcopy, FMA_SUB_NEG);
DBGFP( lprintf(sp->gid, "fnmsubd; Fsrc1=0x%llx, Fsrc2=0x%llx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, F64src2, F64src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F64dest = result;
ENDI
IMPL( rk_fnmadds )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint32_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fmadds) ((float*) &F32src1, (float*) &F32src2, (float*) &F32src3, \
(float*) &result, fsrcopy, gsrcopy, FMA_ADD_NEG);
DBGFP( lprintf(sp->gid, "fnmadds; Fsrc1=0x%lx, Fsrc2=0x%lx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, F32src2, F32src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F32dest = result;
ENDI
IMPL( rk_fnmaddd )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint64_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fmaddd) ((double*) &F64src1, (double*) &F64src2, (double*) &F64src3, \
(double*) &result, fsrcopy, gsrcopy, FMA_ADD_NEG);
DBGFP( lprintf(sp->gid, "fnmaddd; Fsrc1=0x%llx, Fsrc2=0x%llx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, F64src2, F64src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F64dest = result;
ENDI
/* unfused multiply add fp ops */
IMPL( rk_fumadds )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint32_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fumadds) ((float*) &F32src1, (float*) &F32src2, (float*) &F32src3, \
(float*) &result, fsrcopy, gsrcopy, FMA_ADD_POS);
DBGFP( lprintf(sp->gid, "fumadds; Fsrc1=0x%lx, Fsrc2=0x%lx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, F32src2, F32src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F32dest = result;
ENDI
IMPL( rk_fumaddd )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint64_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fumaddd) ((double*) &F64src1, (double*) &F64src2, (double*) &F64src3, \
(double*) &result, fsrcopy, gsrcopy, FMA_ADD_POS);
DBGFP( lprintf(sp->gid, "fumaddd; Fsrc1=0x%llx, Fsrc2=0x%llx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, F64src2, F64src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F64dest = result;
ENDI
IMPL( rk_fumsubs )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint32_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fumadds) ((float*) &F32src1, (float*) &F32src2, (float*) &F32src3, \
(float*) &result, fsrcopy, gsrcopy, FMA_SUB_POS);
DBGFP( lprintf(sp->gid, "fumsubs; Fsrc1=0x%lx, Fsrc2=0x%lx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, F32src2, F32src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F32dest = result;
ENDI
IMPL( rk_fumsubd )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint64_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fumaddd) ((double*) &F64src1, (double*) &F64src2, (double*) &F64src3, \
(double*) &result, fsrcopy, gsrcopy, FMA_SUB_POS);
DBGFP( lprintf(sp->gid, "fumsubd; Fsrc1=0x%llx, Fsrc3=0x%llx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, F64src2, F64src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F64dest = result;
ENDI
IMPL( rk_fnumsubs )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint32_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fumadds) ((float*) &F32src1, (float*) &F32src2, (float*) &F32src3, \
(float*) &result, fsrcopy, gsrcopy, FMA_SUB_NEG);
DBGFP( lprintf(sp->gid, "fnumsubs; Fsrc1=0x%lx, Fsrc2=0x%lx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, F32src2, F32src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F32dest = result;
ENDI
IMPL( rk_fnumsubd )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint64_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fumaddd) ((double*) &F64src1, (double*) &F64src2, (double*) &F64src3, \
(double*) &result, fsrcopy, gsrcopy, FMA_SUB_NEG);
DBGFP( lprintf(sp->gid, "fnumsubd; Fsrc1=0x%llx, Fsrc2=0x%llx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, F64src2, F64src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F64dest = result;
ENDI
IMPL( rk_fnumadds )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint32_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fumadds) ((float*) &F32src1, (float*) &F32src2, (float*) &F32src3, \
(float*) &result, fsrcopy, gsrcopy, FMA_ADD_NEG);
DBGFP( lprintf(sp->gid, "fnumadds; Fsrc1=0x%lx, Fsrc3=0x%lx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, F32src2, F32src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F32dest = result;
ENDI
IMPL( rk_fnumaddd )
FP_EXEC_FPU_ON_CHECK;
int except, trap_code;
uint64_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
uint64_t gsrcopy = sp->v9_gsr;
except = (*fpsimp->fumaddd) ((double*) &F64src1, (double*) &F64src2, (double*) &F64src3, \
(double*) &result, fsrcopy, gsrcopy, FMA_ADD_NEG);
DBGFP( lprintf(sp->gid, "fnumaddd; Fsrc1=0x%llx, Fsrc2=0x%llx, Fsrc3=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, F64src2, F64src3, fsrcopy, gsrcopy, result); );
trap_code = (*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
if ( trap_code != 0 ) {
fp_trap_gen(sp, trap_code);
return;
}
F64dest = result;
ENDI
static void fp_trap_gen (simcpu_t *sp, int trap_code) {
sparcv9_cpu_t * v9p = (sparcv9_cpu_t*)(sp->specificp);
switch (trap_code) {
case 0x21:
v9p->post_precise_trap(sp, Sparcv9_trap_fp_exception_ieee_754);
return;
case 0x22:
v9p->post_precise_trap(sp, Sparcv9_trap_fp_exception_other);
return;
case 0x10:
v9p->post_precise_trap(sp, Sparcv9_trap_illegal_instruction);
return;
default:
fatal ("unknown fp lib trap_code");
return;
}
}