Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / legion / src / host / sparcv9native.c
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: sparcv9native.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.c 1.1 06/12/07 SMI"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "basics.h"
#include "fatal.h"
#include "allocate.h"
#include "simcore.h"
#include "config.h"
#include "xicache.h"
#include "xdcache.h"
#include "tsparcv9.h"
#include "tsparcv9internal.h"
#include "sparcv9cc.h"
#include "magictraps.h"
#include "sparcv9decode.h"
#include "fpsim.h"
static void fp_trap_gen (simcpu_t *sp, int trap_code);
#define IMPL( _n ) void decoded_impl_sparcv9_##_n (simcpu_t *sp, xicache_instn_t * xcip) {
#define ENDI NEXT_INSTN(sp); ENDDEF
#define ENDDEF }
IMPL( faddd )
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->faddd) ((double*) &F64src1, (double*) &F64src2, (double*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "faddd; 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( fsubd )
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->fsubd) ((double*) &F64src1, (double*) &F64src2, (double*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fsubd; 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( fmuld )
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->fmuld) ((double*) &F64src1, (double*) &F64src2, (double*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fmuld; 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( fdivd )
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->fdivd) ((double*) &F64src1, (double*) &F64src2, (double*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fdivd; 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( fsqrtd )
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->fsqrtd) ((double*) &F64src1, (double*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fsqrtd; Fsrc1=0x%llx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, 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( fadds )
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->fadds) ((float*) &F32src1, (float*) &F32src2, (float*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fadds; 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( fsubs )
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->fsubs) ((float*) &F32src1, (float*) &F32src2, (float*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fsubs; 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( fmuls )
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->fmuls) ((float*) &F32src1, (float*) &F32src2, (float*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fmuls; 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( fsmuld )
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->fsmuld) ((float*) &F32src1, (float*) &F32src2, (double*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fsmuld; 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;
}
F64dest = result;
ENDI
IMPL( fdivs )
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->fdivs) ((float*) &F32src1, (float*) &F32src2, (float*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fdivs; 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( fsqrts )
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->fsqrts) ((float*) &F32src1, (float*) &result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fsqrts; Fsrc1=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, 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( fstod )
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->fstod) ((float*) &F32src1, (double*)&result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fstod; Fsrc1=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F32src1, 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( fdtos )
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->fdtos) ((double*) &F64src1, (float*)&result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fdtos; Fsrc1=0x%llx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F64src1, 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( fstox )
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->fstox) ((float*) &F32src1, (void*)&result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fstox; Fsrc1=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F32src1, 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( fdtox )
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->fdtox) ((double*) &F64src1, (void*)&result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fdtox; Fsrc1=0x%llx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, 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( fstoi )
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->fstoi) ((float*) &F32src1, (unsigned int*)&result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fstoi; Fsrc1=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, 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( fdtoi )
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->fdtoi) ((double*) &F64src1, (unsigned int*)&result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fdtoi; Fsrc1=0x%llx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F64src1, 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( fxtos )
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->fxtos) ((void*) &F32src1, (float*)&result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fxtos; Fsrc1=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, 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( fxtod )
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->fxtod) ((void*) &F64src1, (double*)&result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fxtod; Fsrc1=0x%llx, FSR=0x%llx, GSR=0x%llx, result=0x%llx\n", F64src1, 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( fitos )
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->fitos) ((unsigned int*) &F32src1, (float*)&result, fsrcopy, gsrcopy);
DBGFP( lprintf(sp->gid, "fitos; Fsrc1=0x%lx, FSR=0x%llx, GSR=0x%llx, result=0x%lx\n", F32src1, 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( fitod )
FP_EXEC_FPU_ON_CHECK;
int except;
uint64_t result;
struct fpsim_functions *fpsimp = sp->config_procp->proc_typep->fpsimp;
uint64_t fsrcopy = v9_get_fsr(sp);
except = (*fpsimp->fitod) ((unsigned int*) &F32src1, (double*)&result);
DBGFP( lprintf(sp->gid, "fitod; Fsrc1=0x%lx, FSR=0x%llx, result=0x%llx\n", F32src1, fsrcopy, result); );
(*fpsimp->update_fsr) (except, (void*)&fsrcopy);
v9_set_fsr_fp_op(sp, fsrcopy);
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;
}
}