Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / n2 / lib / cpu / src / N2_Fpu.h
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: N2_Fpu.h
* 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 ============================================
*/
#ifndef __N2_Fpu_h__
#define __N2_Fpu_h__
#include "SS_Fpu.h"
extern "C" SS_Vaddr n2_exe_fadds( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fsubs( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fmuls( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fdivs( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fmovs( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fnegs( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fabss( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fsqrts( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fsmuld( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fstoi( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fstox( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fstod( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fitos( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fitod( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_faddd( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fsubd( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fmuld( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fdivd( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fmovd( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fnegd( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fabsd( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fsqrtd( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fdtoi( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fdtox( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fdtos( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fxtos( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fxtod( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fcmps( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fcmpd( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fcmpes( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
extern "C" SS_Vaddr n2_exe_fcmped( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
class N2_Fpu : public SS_Fpu
{
public:
N2_Fpu() : SS_Fpu() {}
enum Instr
{
FSTOI, FDTOI,
FSTOX, FDTOX,
FSTOD, FDTOS,
FITOS, FITOD,
FXTOS, FXTOD,
FMOVS, FMOVD,
FABSS, FABSD,
FNEGS, FNEGD,
FSQRTS, FSQRTD,
FADDS, FADDD,
FSUBS, FSUBD,
FMULS, FMULD,
FDIVS, FDIVD,
FSMULD,
FCMPS, FCMPD,
FCMPES, FCMPED
};
SS_Vaddr exe_off( Instr instr, SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
SS_Vaddr exe_fof( Instr instr, SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
SS_Vaddr exe_fff( Instr instr, SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );
private:
static const int SP_BIAS = 127;
static const int SP_EMAX = 255;
static const int SP_EGUF = -25;
static const int DP_BIAS = 1023;
static const int DP_EMAX = 2047;
static const int DP_EGUF = -54;
enum Precision
{
SP_TYPE,
DP_TYPE,
UNKNOWN_TYPE
};
enum NumberType
{
FP_OP_NONE,
FP_OP_QNAN,
FP_OP_SNAN,
FP_OP_INF,
FP_OP_NSUBNORMAL,
FP_OP_PSUBNORMAL,
FP_OP_NZERO,
FP_OP_PZERO,
FP_OP_NORMAL
};
NumberType fpu_optype( uint32_t sp_value )/*{{{*/
{
if (is_nan_or_inf(sp_value))
{
if (is_inf(sp_value))
return FP_OP_INF;
else if (is_qnan(sp_value))
return FP_OP_QNAN;
else
return FP_OP_SNAN;
}
else if (is_sub_or_nil(sp_value))
{
if (is_sub(sp_value))
return to_sgn(sp_value) ? FP_OP_NSUBNORMAL : FP_OP_PSUBNORMAL;
else
return to_sgn(sp_value) ? FP_OP_NZERO : FP_OP_PZERO;
}
else
{
return FP_OP_NORMAL;
}
}
/*}}}*/
NumberType N2_Fpu::fpu_optype( uint64_t dp_value )/*{{{*/
{
if (is_nan_or_inf(dp_value))
{
if (is_inf(dp_value))
return FP_OP_INF;
else if (is_qnan(dp_value))
return FP_OP_QNAN;
else
return FP_OP_SNAN;
}
else if (is_sub_or_nil(dp_value))
{
if (is_sub(dp_value))
return to_sgn(dp_value) ? FP_OP_NSUBNORMAL : FP_OP_PSUBNORMAL;
else
return to_sgn(dp_value) ? FP_OP_NZERO : FP_OP_PZERO;
}
else
{
return FP_OP_NORMAL;
}
}
/*}}}*/
uint32_t nan_postprocess( uint32_t src1_sp_value, uint32_t src2_sp_value, uint32_t dest_sp_value )/*{{{*/
{
if (is_nan(src2_sp_value))
{
if (is_snan(src2_sp_value))
return to_qnan(src2_sp_value);
else if (is_snan(src1_sp_value))
return to_qnan(src1_sp_value);
else
return to_qnan(src2_sp_value);
}
else if (is_nan(src1_sp_value))
return to_qnan(src1_sp_value);
else
return dest_sp_value;
}
/*}}}*/
uint64_t nan_postprocess( uint64_t src1_dp_value, uint64_t src2_dp_value, uint64_t dest_dp_value )/*{{{*/
{
if (is_nan(src2_dp_value))
{
if (is_snan(src2_dp_value))
return to_qnan(src2_dp_value);
else if (is_snan(src1_dp_value))
return to_qnan(src1_dp_value);
else
return to_qnan(src2_dp_value);
}
else if (is_nan(src1_dp_value))
return to_qnan(src1_dp_value);
else
return dest_dp_value;
}
/*}}}*/
uint64_t nan_postprocess( uint32_t src1_sp_value, uint32_t src2_sp_value, uint64_t dest_dp_value )/*{{{*/
{
if (is_nan(src2_sp_value))
{
if (is_snan(src2_sp_value))
return to_qnan(to_nand(src2_sp_value));
else if (is_snan(src1_sp_value))
return to_qnan(to_nand(src1_sp_value));
else
return to_qnan(to_nand(src2_sp_value));
}
else if (is_nan(src1_sp_value))
return to_qnan(to_nand(src1_sp_value));
else
return dest_dp_value;
}
/*}}}*/
FloatTrapType fpu_postprocess( Instr instr, SS_Strand* s, NumberType src_fpop, NumberType src2_fpop, int Er, NumberType rd_fpop,
Precision dest_type, uint64_t *rd_dp_value, uint32_t *rd_sp_value );
};
#endif