// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: N2_Fpu.cc
// 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 ============================================
N2_Fpu::FloatTrapType
N2_Fpu::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
) /*{{{*/
int tem
; // Trap Enable Mask
int fef
; // Floating Exception Flags
int eft
; // Enabled floating traps
uint64_t fsr_ns
; // floating point status register non-standard
uint64_t gsr_im
; // GSR register interval arithmetic mode
FloatTrapType ftt
= FTT_NOTRAP
;
bool rd_sign
; // result sign
uint64_t rnd_mode
= (uint64_t)float_rounding_mode
; // rounding mode
bool guzr
= false; // gross underflow zero result
bool ur
= false; // underflow result
bool gor
= false; // generated overflow result
bool fpop_subnormal
= false; // is fp operation need to be subnormally handled
bool src1_subnorm
= false; // source one subnormal
bool src2_subnorm
= false; // source two subnormal
bool rd_subnorm
= false; // result subnormal
bool rd_positive
= false; // sign of the result
bool src1_zero
= false; // source one zero
bool src2_zero
= false; // source two zero
bool rd_small_norm
= false;
int eguf
; // exponent gross underflow limit
int emax
; // maximum exponent value
fef
= float_exception_flags
;
if ( (src_fpop
== FP_OP_PSUBNORMAL
) || (src_fpop
== FP_OP_NSUBNORMAL
) )
if ( (src2_fpop
== FP_OP_PSUBNORMAL
) || (src2_fpop
== FP_OP_NSUBNORMAL
) )
if ( (rd_fpop
== FP_OP_PZERO
) || (rd_fpop
== FP_OP_NZERO
) )
if ( (rd_fpop
== FP_OP_PSUBNORMAL
) || (rd_fpop
== FP_OP_NSUBNORMAL
) ||
( ((fef
& EXC_UNDERFLOW
) == EXC_UNDERFLOW
) &&
((fef
& EXC_INEXACT
) == EXC_INEXACT
) &&
if ( (rd_fpop
== FP_OP_PSUBNORMAL
) || (rd_fpop
== FP_OP_PZERO
) )
if ( (src_fpop
== FP_OP_PZERO
) || (src_fpop
== FP_OP_NZERO
) )
if ( (src2_fpop
== FP_OP_PZERO
) || (src2_fpop
== FP_OP_NZERO
) )
if ( (src_fpop
== FP_OP_QNAN
) || (src_fpop
== FP_OP_SNAN
) )
if ( (src2_fpop
== FP_OP_QNAN
) || (src2_fpop
== FP_OP_SNAN
) )
if ( (src1_subnorm
) || (src2_subnorm
) || (rd_subnorm
) )
case SP_TYPE
: emax
= SP_EMAX
; eguf
= SP_EGUF
; break;
case DP_TYPE
: emax
= DP_EMAX
; eguf
= DP_EGUF
; break;
// In Standard Mode deal with the subnormals
if ((fsr_ns
== 0) || (gsr_im
== 1)) {
if ( src1_subnorm
|| src2_subnorm
) {
if ( (!src1_nan
) && (src_fpop
!= FP_OP_INF
) &&
(!src2_nan
) && (src2_fpop
!= FP_OP_INF
))
ftt
= FTT_UNFINISHED_FPOP
;
if ( (!src1_nan
) && (src_fpop
!= FP_OP_INF
) && (src1_zero
!= true) &&
(!src2_nan
) && (src2_fpop
!= FP_OP_INF
) && (src2_zero
!= true) ) {
// Emax(P) > Er > EGUF(P)
// Er <= EGUF(P) & Signr=0 & RND=RP
// Er <= EGUF(P) & Signr=1 & RND=RM
if (((emax
> Er
) && (Er
> eguf
)) ||
( (Er
<= eguf
) && (rd_positive
== true) && (rnd_mode
== ROUND_UP
) ) ||
( (Er
<= eguf
) && (rd_positive
== false) && (rnd_mode
== ROUND_DOWN
) ) ) {
ftt
= FTT_UNFINISHED_FPOP
;
if ( (!src1_nan
) && (src_fpop
!= FP_OP_INF
) && (!src1_zero
) &&
(!src2_nan
) && (src2_fpop
!= FP_OP_INF
) && (!src2_zero
) ) {
// Er <= EGUF(P) & Signr=0 & RND=RP
// Er <= EGUF(P) & Signr=1 & RND=RM
if ( ((emax
> Er
) && (Er
> eguf
)) ||
( (Er
<= eguf
) && (rd_positive
== true) && (rnd_mode
== ROUND_UP
) ) ||
( (Er
<= eguf
) && (rd_positive
== false) && (rnd_mode
== ROUND_DOWN
) ) ) {
ftt
= FTT_UNFINISHED_FPOP
;
// if (!(OP_NaN or OP_inf or OP_0))
if ( (!src1_nan
) && (src_fpop
!= FP_OP_INF
) && (src1_zero
!= true) &&
(!src2_nan
) && (src2_fpop
!= FP_OP_INF
) && (src2_zero
!= true) ) {
ftt
= FTT_UNFINISHED_FPOP
;
// if (! (OP_NaN or OP_inf))
if ( (!src2_nan
) && (src2_fpop
!= FP_OP_INF
) )
if (src2_fpop
== FP_OP_NSUBNORMAL
)
fef
= EXC_INVALID
; // set FSR.NV
if ( (fef
& tem
& EXC_INVALID
) == EXC_INVALID
) {
ftt
= FTT_IEEE_754_EXCEPTION
; // generate invalid exception
(*rd_dp_value
) = QNAN_64
;
(*rd_sp_value
) = QNAN_32
;
ftt
= FTT_UNFINISHED_FPOP
;
// if (! (OP_NaN or OP_inf))
if ( (!src2_nan
) && (src2_fpop
!= FP_OP_INF
) ) {
ftt
= FTT_UNFINISHED_FPOP
;
if ( (!src2_nan
) && (src2_fpop
!= FP_OP_INF
) ) {
if ( ( (rd_positive
== true) && (rnd_mode
== ROUND_UP
) ) ||
( (rd_positive
== false) && (rnd_mode
== ROUND_DOWN
) ) ) {
ftt
= FTT_UNFINISHED_FPOP
;
} else if ( ( (src_fpop
== FP_OP_NORMAL
) && (src2_fpop
== FP_OP_NORMAL
) ) ||
( (src_fpop
== FP_OP_NONE
) && (src2_fpop
== FP_OP_NORMAL
) ) ) {
ftt
= FTT_UNFINISHED_FPOP
;
// Check whether there is a difference between softfloat's underflow and
// if a number is subnormal, pzero or nzero
bool sf_uf
= ( (fef
& EXC_UNDERFLOW
) == EXC_UNDERFLOW
);
bool fgu_uf
= rd_subnorm
|| (rd_fpop
== FP_OP_PZERO
) || (rd_fpop
== FP_OP_PZERO
);
if ( ( rd_subnorm
&& (Er
> eguf
) ) || // (sf_uf && (Er > eguf)) //(1 > Erb) && (Er > EGUF(P))
(rnd_mode
== ROUND_UP
) ) || // Er <= EGUF(P) & Signr=0 & RND=RP
(rd_positive
== false) &&
(rnd_mode
== ROUND_DOWN
) ) ) { // Er <= EGUF(P) & Signr=1 & RND=RM
// generate unfinished trap
ftt
= FTT_UNFINISHED_FPOP
;
// generate gross underflow zero result
// generate gross overflow result
if ( ( (1 > Er
) && (Er
> eguf
)) || // 1 > Er > EGUF(P)
(rnd_mode
== ROUND_UP
) ) || // Er <= EGUF(P) & Signr=0 & RND=RP
(rd_positive
== false) &&
(rnd_mode
== ROUND_DOWN
) ) ) { // Er <= EGUF(P) & Signr=1 & RND=RM
ftt
= FTT_UNFINISHED_FPOP
;
// generate gross underflow zero result
} else if ((fsr_ns
== 1) && (gsr_im
== 0)) {
// In Non-standard Mode we flush the subnormals to zero
// Based on Table 2-29 in Chapter 2.1.10 of the Millennium PRM
if ( src1_subnorm
|| src2_subnorm
) {
if ( (!src1_nan
) && (src_fpop
!= FP_OP_INF
) && (!src2_nan
) && (src2_fpop
!= FP_OP_INF
) ) {
if ( (!src1_nan
) && (src1_zero
!= true) && (!src2_nan
) && (src2_zero
!= true) ) {
if ( (src2_fpop
!= FP_OP_INF
) && (src_fpop
!= FP_OP_INF
) ) {
fef
= EXC_INEXACT
; // set FSR.NX
fef
= EXC_INVALID
; // set FSR.NV
(*rd_dp_value
) = QNAN_64
;
(*rd_sp_value
) = QNAN_32
;
if ( (!src2_nan
) && (!src1_nan
) ) {
if ( (src_fpop
!= FP_OP_INF
) &&
(src2_fpop
!= FP_OP_INF
) &&
if ( src1_subnorm
&& src2_subnorm
) {
} else if ( src2_subnorm
== true) {
} else if ( (src_fpop
== FP_OP_INF
) || (src2_fpop
== FP_OP_INF
) ) {
} else if ( (src1_zero
== true) || (src2_zero
== true) ) {
// Clear out FSR.DZ? I don't think it has been set
//---->This case overides DZ, so I might need to do something different
// Could cause FSR.DZ to be set to zero, would be caught above
if ( (!src2_nan
) && (src2_fpop
!= FP_OP_INF
) ) {
if (src2_fpop
== FP_OP_NSUBNORMAL
) {
(*rd_dp_value
) = to_nil(*rd_dp_value
);
(*rd_sp_value
) = to_nil(*rd_sp_value
);
(*rd_dp_value
) = to_nil(*rd_dp_value
);
(*rd_sp_value
) = to_nil(*rd_sp_value
);
} else if ( ( (src_fpop
== FP_OP_NORMAL
) && (src2_fpop
== FP_OP_NORMAL
) ) ||
( (src_fpop
== FP_OP_NONE
) && (src2_fpop
== FP_OP_NORMAL
) ) ) {
if (Er
< emax
) { // !(Er >= EMAX(P))
gor
= true; // generate overflow result
// If there was no subnormal or the subnormals didn't trap, check for other trap conditions
if ( (fef
& EXC_OVERFLOW
) == EXC_OVERFLOW
)
else if ( (eft
& EXC_DIVBYZERO
) == EXC_DIVBYZERO
)
ftt
= FTT_IEEE_754_EXCEPTION
;
else if ( (eft
& EXC_INVALID
) == EXC_INVALID
)
ftt
= FTT_IEEE_754_EXCEPTION
;
else if ( ((fef
& EXC_UNDERFLOW
) == EXC_UNDERFLOW
) && !fpop_subnormal
)
if (((eft
& EXC_INEXACT
) == EXC_INEXACT
) && (guzr
!= true) && (gor
!= true) && (ftt
== FTT_NOTRAP
))
ftt
= FTT_IEEE_754_EXCEPTION
; // generate underflow trap
if ( (guzr
== true) || (ur
== true) )
(*rd_dp_value
) = to_nil(*rd_dp_value
);
(*rd_sp_value
) = to_nil(*rd_sp_value
);
if ( ((tem
& EXC_UNDERFLOW
) != EXC_UNDERFLOW
) && ((tem
& EXC_INEXACT
) != EXC_INEXACT
) )
// if (FSR.UFM=0 && FSR.NXM=0)
fef
= EXC_UNDERFLOW
| EXC_INEXACT
;
else if (((tem
& EXC_UNDERFLOW
) == EXC_UNDERFLOW
) || ((tem
& EXC_INEXACT
) == EXC_INEXACT
) )
// if (FSR.UFM=1 OR FSR.NXM=1)
ftt
= FTT_IEEE_754_EXCEPTION
;
if ( ((tem
& EXC_UNDERFLOW
) != EXC_UNDERFLOW
) && ((tem
& EXC_INEXACT
) == EXC_INEXACT
) )
if ((tem
& EXC_UNDERFLOW
) == EXC_UNDERFLOW
)
else if ( (gor
== true) || ( ((fef
& EXC_OVERFLOW
) == EXC_OVERFLOW
) && (ftt
== FTT_NOTRAP
) ) )
// (FSR.OFM = 0 && FSR.NXM = 0)
if ( ((tem
& EXC_OVERFLOW
) != EXC_OVERFLOW
) && ((tem
& EXC_INEXACT
) != EXC_INEXACT
) )
fef
= EXC_OVERFLOW
| EXC_INEXACT
;
else if ( ((tem
& EXC_OVERFLOW
) == EXC_OVERFLOW
) || ((tem
& EXC_INEXACT
) == EXC_INEXACT
) )
{ // (FSR.OFM = 1 || FSR.NXM = 1)
ftt
= FTT_IEEE_754_EXCEPTION
;
if ( ((tem
& EXC_OVERFLOW
) != EXC_OVERFLOW
) && ((tem
& EXC_INEXACT
) == EXC_INEXACT
) )
if ( (tem
& EXC_OVERFLOW
) == EXC_OVERFLOW
)
float_exception_flags
= cexc
;
SS_Vaddr
N2_Fpu::exe_fff( Instr instr
, SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
uint64_t dp_value
[2], dp_result
;
uint32_t sp_value
[2], sp_result
;
uint64_t orig_dp_value
[2];
uint32_t orig_sp_value
[2];
int Er
= 0; // Exponent result
Precision src1_type
= UNKNOWN_TYPE
;
Precision src2_type
= UNKNOWN_TYPE
;
Precision dest_type
= UNKNOWN_TYPE
;
if (s
->sim_state
.fp_disabled())
return (s
->trap
)(pc
,npc
,s
,i
,SS_Trap::FP_DISABLED
);
dest_type
= src1_type
= src2_type
= SP_TYPE
;
sp_value
[0] = orig_sp_value
[0] = s
->get_frf(i
->rs1
);
sp_value
[1] = orig_sp_value
[1] = s
->get_frf(i
->rs2
);
src1_fptype
= fpu_optype(sp_value
[0]);
src2_fptype
= fpu_optype(sp_value
[1]);
src1_type
= src2_type
= SP_TYPE
;
sp_value
[0] = orig_sp_value
[0] = s
->get_frf(i
->rs1
);
sp_value
[1] = orig_sp_value
[1] = s
->get_frf(i
->rs2
);
src1_fptype
= fpu_optype(sp_value
[0]);
src2_fptype
= fpu_optype(sp_value
[1]);
dest_type
= src1_type
= src2_type
= DP_TYPE
;
dp_value
[0] = orig_dp_value
[0] = s
->get_drf(i
->rs1
);
dp_value
[1] = orig_dp_value
[1] = s
->get_drf(i
->rs2
);
src1_fptype
= fpu_optype(dp_value
[0]);
src2_fptype
= fpu_optype(dp_value
[1]);
if ((s
->fsr
.ns() == 1) && (s
->gsr
.im() == 0))
if (is_sub(sp_value
[0]) && !is_nan_or_inf(sp_value
[1]))
sp_value
[0] = to_nil(sp_value
[0]);
if (is_sub(sp_value
[1]) && !is_nan_or_inf(sp_value
[0]))
sp_value
[1] = to_nil(sp_value
[1]);
if (is_sub(dp_value
[0]) && !is_nan_or_inf(dp_value
[1]))
dp_value
[0] = to_nil(dp_value
[0]);
if (is_sub(dp_value
[1]) && !is_nan_or_inf(dp_value
[0]))
dp_value
[1] = to_nil(dp_value
[1]);
if (is_sub(sp_value
[0]) && !is_nan(sp_value
[1]))
sp_value
[0] = to_nil(sp_value
[0]);
if (is_sub(sp_value
[1]) && !is_nan(sp_value
[0]))
sp_value
[1] = to_nil(sp_value
[1]);
if (is_sub(dp_value
[0]) && !is_nan(dp_value
[1]))
dp_value
[0] = to_nil(dp_value
[0]);
if (is_sub(dp_value
[1]) && !is_nan(dp_value
[0]))
dp_value
[1] = to_nil(dp_value
[1]);
if (is_sub(sp_value
[0]) && !is_nan_or_inf(sp_value
[1]) && !is_nil(sp_value
[1]))
sp_value
[0] = to_nil(sp_value
[0]);
if (is_sub(sp_value
[1]) && !is_nan_or_inf(sp_value
[0]) && !is_nil(sp_value
[0]))
sp_value
[1] = to_nil(sp_value
[1]);
if (is_sub(dp_value
[0]) && !is_nan_or_inf(dp_value
[1]) && !is_nil(dp_value
[1]))
dp_value
[0] = to_nil(dp_value
[0]);
if (is_sub(dp_value
[1]) && !is_nan_or_inf(dp_value
[0]) && !is_nil(dp_value
[0]))
dp_value
[1] = to_nil(dp_value
[1]);
float_exception_flags
= EXC_NONE
;
float_rounding_mode
= Rounding(s
->gsr
.im() ? s
->gsr
.irnd() : s
->fsr
.rd());
sp_result
= float32_add( sp_value
[0], sp_value
[1], false );
dest_fptype
= fpu_optype(sp_result
);
dp_result
= float64_add( dp_value
[0], dp_value
[1], false );
dest_fptype
= fpu_optype(dp_result
);
sp_result
= float32_sub( sp_value
[0], sp_value
[1], false );
dest_fptype
= fpu_optype(sp_result
);
dp_result
= float64_sub( dp_value
[0], dp_value
[1], false );
dest_fptype
= fpu_optype(dp_result
);
sp_result
= float32_mul( sp_value
[0], sp_value
[1], false );
Er
= to_exp(sp_value
[0]) + to_exp(sp_value
[1]) - SP_BIAS
;
dest_fptype
= fpu_optype(sp_result
);
dp_result
= float64_mul( dp_value
[0], dp_value
[1], false );
Er
= to_exp(dp_value
[0]) + to_exp(dp_value
[1]) - DP_BIAS
;
dest_fptype
= fpu_optype(dp_result
);
sp_result
= float32_div( sp_value
[0], sp_value
[1] );
Er
= to_exp(sp_value
[0]) - to_exp(sp_value
[1]) + SP_BIAS
- 1;
dest_fptype
= fpu_optype(sp_result
);
dp_result
= float64_div( dp_value
[0], dp_value
[1] );
Er
= to_exp(dp_value
[0]) - to_exp(dp_value
[1]) + DP_BIAS
- 1;
dest_fptype
= fpu_optype(dp_result
);
dp_result
= float64_mul( float32_to_float64( sp_value
[0] ), float32_to_float64( sp_value
[1] ), false );
dest_fptype
= fpu_optype(dp_result
);
FloatTrapType ftt
= fpu_postprocess(instr
,s
,src1_fptype
,src2_fptype
,Er
,dest_fptype
,dest_type
,&dp_result
,&sp_result
);
case FADDS
: case FSUBS
: case FMULS
: case FDIVS
:
sp_result
= nan_postprocess(orig_sp_value
[0],orig_sp_value
[1],sp_result
);
s
->get_frf(i
->rd
) = sp_result
;
case FADDD
: case FSUBD
: case FMULD
: case FDIVD
:
dp_result
= nan_postprocess(orig_dp_value
[0],orig_dp_value
[1],dp_result
);
s
->get_drf(i
->rd
) = dp_result
;
dp_result
= nan_postprocess(orig_sp_value
[0],orig_sp_value
[1],dp_result
);
s
->get_drf(i
->rd
) = dp_result
;
return exe_end(pc
,npc
,s
,i
,ftt
,float_exception_flags
);
SS_Vaddr
N2_Fpu::exe_fof( Instr instr
, SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
Precision src2_type
= UNKNOWN_TYPE
;
Precision dest_type
= UNKNOWN_TYPE
;
int Er
= 0; // Exponent result
if (s
->sim_state
.fp_disabled())
return (s
->trap
)(pc
,npc
,s
,i
,SS_Trap::FP_DISABLED
);
sp_value
= s
->get_frf(i
->rs2
);
src2_fptype
= fpu_optype(sp_value
);
dp_value
= s
->get_drf(i
->rs2
);
src2_fptype
= fpu_optype(dp_value
);
sp_value
= s
->get_frf(i
->rs2
);
src2_fptype
= fpu_optype(sp_value
);
dp_value
= s
->get_drf(i
->rs2
);
src2_fptype
= fpu_optype(dp_value
);
if ((s
->fsr
.ns() == 1) && (s
->gsr
.im() == 0)) // Non-standard Mode
sp_value
= to_nil(sp_value
);
dp_value
= to_nil(dp_value
);
float_exception_flags
= EXC_NONE
;
if ((instr
== FSTOX
) || (instr
== FSTOI
) || (instr
== FDTOX
) || (instr
== FDTOI
))
float_rounding_mode
= ROUND_TO_ZERO
;
float_rounding_mode
= Rounding(s
->gsr
.im() ? s
->gsr
.irnd() : s
->fsr
.rd());
dest_fptype
= fpu_optype(sp_value
);
dest_fptype
= fpu_optype(dp_value
);
sp_value
= to_neg(sp_value
);
dest_fptype
= fpu_optype(sp_value
);
dp_value
= to_neg(dp_value
);
dest_fptype
= fpu_optype(dp_value
);
sp_value
= to_abs(sp_value
);
dest_fptype
= fpu_optype(sp_value
);
dp_value
= to_abs(dp_value
);
dest_fptype
= fpu_optype(dp_value
);
sp_value
= float32_to_int32(sp_value
);
dest_fptype
= fpu_optype(sp_value
);
dp_value
= float32_to_int64(sp_value
);
dest_fptype
= fpu_optype(dp_value
);
sp_value
= int32_to_float32(sp_value
);
dest_fptype
= fpu_optype(sp_value
);
dp_value
= int32_to_float64(sp_value
);
dest_fptype
= fpu_optype(dp_value
);
sp_value
= float64_to_int32(dp_value
);
dest_fptype
= fpu_optype(sp_value
);
dp_value
= float64_to_int64(dp_value
);
dest_fptype
= fpu_optype(dp_value
);
sp_value
= int64_to_float32(dp_value
);
dest_fptype
= fpu_optype(sp_value
);
dp_value
= int64_to_float64(dp_value
);
dest_fptype
= fpu_optype(dp_value
);
dp_value
= float32_to_float64(sp_value
);
dest_fptype
= fpu_optype(dp_value
);
sp_value
= float32_sqrt(sp_value
);
dest_fptype
= fpu_optype(sp_value
);
dp_value
= float64_sqrt(dp_value
);
dest_fptype
= fpu_optype(dp_value
);
Er
= to_exp(dp_value
) - DP_BIAS
+ SP_BIAS
;
sp_value
= float64_to_float32(dp_value
);
dest_fptype
= fpu_optype(sp_value
);
FloatTrapType ftt
= fpu_postprocess(instr
,s
,FP_OP_NONE
,src2_fptype
,Er
,dest_fptype
,dest_type
,&dp_value
,&sp_value
);
case SP_TYPE
: s
->get_frf(i
->rd
) = sp_value
; break;
case DP_TYPE
: s
->get_drf(i
->rd
) = dp_value
; break;
return exe_end(pc
,npc
,s
,i
,ftt
,float_exception_flags
);
SS_Vaddr
N2_Fpu::exe_off( Instr instr
, SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
if (s
->sim_state
.fp_disabled())
return (s
->trap
)(pc
,npc
,s
,i
,SS_Trap::FP_DISABLED
);
float_exception_flags
= EXC_NONE
;
float_rounding_mode
= Rounding(s
->gsr
.im() ? s
->gsr
.irnd() : s
->fsr
.rd());
uint32_t a
= s
->get_frf(i
->rs1
);
uint32_t b
= s
->get_frf(i
->rs2
);
l
= float32_lt_quiet(a
,b
);
g
= float32_lt_quiet(b
,a
) && !e
;
uint32_t a
= s
->get_frf(i
->rs1
);
uint32_t b
= s
->get_frf(i
->rs2
);
e
= float32_eq_signaling(a
,b
);
g
= float32_lt(b
,a
) && !e
;
uint64_t a
= s
->get_drf(i
->rs1
);
uint64_t b
= s
->get_drf(i
->rs2
);
l
= float64_lt_quiet(a
,b
);
g
= float64_lt_quiet(b
,a
) && !e
;
uint64_t a
= s
->get_drf(i
->rs1
);
uint64_t b
= s
->get_drf(i
->rs2
);
e
= float64_eq_signaling(a
,b
);
g
= float64_lt(b
,a
) && !e
;
FloatTrapType ftt
= FTT_NOTRAP
;
int eft
= float_exception_flags
& s
->fsr
.tem();
ftt
= FTT_IEEE_754_EXCEPTION
;
set_fcc(s
->fsr
,ConditionField(i
->rd
),(e
? EQ
: (l
? LT
: (g
? GT
: UN
))));
return exe_end(pc
,npc
,s
,i
,ftt
,float_exception_flags
);
SS_Vaddr
n2_exe_fadds( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fff(N2_Fpu::FADDS
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fsubs( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fff(N2_Fpu::FSUBS
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fmuls( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fff(N2_Fpu::FMULS
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fdivs( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fff(N2_Fpu::FDIVS
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_faddd( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fff(N2_Fpu::FADDD
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fsubd( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fff(N2_Fpu::FSUBD
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fmuld( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fff(N2_Fpu::FMULD
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fdivd( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fff(N2_Fpu::FDIVD
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fsmuld( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fff(N2_Fpu::FSMULD
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fstoi( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FSTOI
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fstox( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FSTOX
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fstod( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FSTOD
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fitos( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FITOS
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fitod( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FITOD
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fdtoi( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FDTOI
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fdtox( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FDTOX
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fdtos( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FDTOS
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fxtos( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FXTOS
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fxtod( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FXTOD
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fmovs( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FMOVS
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fnegs( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FNEGS
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fabss( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FABSS
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fmovd( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FMOVD
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fnegd( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FNEGD
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fabsd( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FABSD
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fsqrts( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FSQRTS
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fsqrtd( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_fof(N2_Fpu::FSQRTD
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fcmps( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_off(N2_Fpu::FCMPS
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fcmpd( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_off(N2_Fpu::FCMPD
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fcmpes( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_off(N2_Fpu::FCMPES
,pc
,npc
,s
,i
);
SS_Vaddr
n2_exe_fcmped( SS_Vaddr pc
, SS_Vaddr npc
, SS_Strand
* s
, SS_Instr
* i
)/*{{{*/
return ((N2_Strand
*)s
)->fpu
.exe_off(N2_Fpu::FCMPED
,pc
,npc
,s
,i
);