/* CGEN fpu support
- Copyright (C) 1999 Cygnus Solutions. */
+ Copyright (C) 1999 Cygnus Solutions.
+ Copyright (C) 2010 Doug Evans. */
#ifndef CGEN_FPU_H
#define CGEN_FPU_H
#define TARGET_EXT_FP_WORDS 4
#endif
+/* Supported floating point conversion kinds (rounding modes).
+ FIXME: The IEEE rounding modes need to be implemented. */
+
+typedef enum {
+ FPCONV_DEFAULT = 0,
+ FPCONV_TIES_TO_EVEN = 1,
+ FPCONV_TIES_TO_AWAY = 2,
+ FPCONV_TOWARD_ZERO = 3,
+ FPCONV_TOWARD_POSITIVE = 4,
+ FPCONV_TOWARD_NEGATIVE = 5
+} CGEN_FPCONV_KIND;
+
/* forward decl */
typedef struct cgen_fp_ops CGEN_FP_OPS;
/* SF/DF conversion ops */
- DF (*fextsfdf) (CGEN_FPU*, SF);
- SF (*ftruncdfsf) (CGEN_FPU*, DF);
+ DF (*fextsfdf) (CGEN_FPU*, int, SF);
+ SF (*ftruncdfsf) (CGEN_FPU*, int, DF);
- SF (*floatsisf) (CGEN_FPU*, SI);
- SF (*floatdisf) (CGEN_FPU*, DI);
- SF (*ufloatsisf) (CGEN_FPU*, USI);
- SF (*ufloatdisf) (CGEN_FPU*, UDI);
+ SF (*floatsisf) (CGEN_FPU*, int, SI);
+ SF (*floatdisf) (CGEN_FPU*, int, DI);
+ SF (*ufloatsisf) (CGEN_FPU*, int, USI);
+ SF (*ufloatdisf) (CGEN_FPU*, int, UDI);
- SI (*fixsfsi) (CGEN_FPU*, SF);
- DI (*fixsfdi) (CGEN_FPU*, SF);
- USI (*ufixsfsi) (CGEN_FPU*, SF);
- UDI (*ufixsfdi) (CGEN_FPU*, SF);
+ SI (*fixsfsi) (CGEN_FPU*, int, SF);
+ DI (*fixsfdi) (CGEN_FPU*, int, SF);
+ USI (*ufixsfsi) (CGEN_FPU*, int, SF);
+ UDI (*ufixsfdi) (CGEN_FPU*, int, SF);
- DF (*floatsidf) (CGEN_FPU*, SI);
- DF (*floatdidf) (CGEN_FPU*, DI);
- DF (*ufloatsidf) (CGEN_FPU*, USI);
- DF (*ufloatdidf) (CGEN_FPU*, UDI);
+ DF (*floatsidf) (CGEN_FPU*, int, SI);
+ DF (*floatdidf) (CGEN_FPU*, int, DI);
+ DF (*ufloatsidf) (CGEN_FPU*, int, USI);
+ DF (*ufloatdidf) (CGEN_FPU*, int, UDI);
- SI (*fixdfsi) (CGEN_FPU*, DF);
- DI (*fixdfdi) (CGEN_FPU*, DF);
- USI (*ufixdfsi) (CGEN_FPU*, DF);
- UDI (*ufixdfdi) (CGEN_FPU*, DF);
+ SI (*fixdfsi) (CGEN_FPU*, int, DF);
+ DI (*fixdfdi) (CGEN_FPU*, int, DF);
+ USI (*ufixdfsi) (CGEN_FPU*, int, DF);
+ UDI (*ufixdfdi) (CGEN_FPU*, int, DF);
/* XF mode support (kept separate 'cus not always present) */
int (*gtxf) (CGEN_FPU*, XF, XF);
int (*gexf) (CGEN_FPU*, XF, XF);
- XF (*extsfxf) (CGEN_FPU*, SF);
- XF (*extdfxf) (CGEN_FPU*, DF);
- SF (*truncxfsf) (CGEN_FPU*, XF);
- DF (*truncxfdf) (CGEN_FPU*, XF);
+ XF (*extsfxf) (CGEN_FPU*, int, SF);
+ XF (*extdfxf) (CGEN_FPU*, int, DF);
+ SF (*truncxfsf) (CGEN_FPU*, int, XF);
+ DF (*truncxfdf) (CGEN_FPU*, int, XF);
- XF (*floatsixf) (CGEN_FPU*, SI);
- XF (*floatdixf) (CGEN_FPU*, DI);
- XF (*ufloatsixf) (CGEN_FPU*, USI);
- XF (*ufloatdixf) (CGEN_FPU*, UDI);
+ XF (*floatsixf) (CGEN_FPU*, int, SI);
+ XF (*floatdixf) (CGEN_FPU*, int, DI);
+ XF (*ufloatsixf) (CGEN_FPU*, int, USI);
+ XF (*ufloatdixf) (CGEN_FPU*, int, UDI);
- SI (*fixxfsi) (CGEN_FPU*, XF);
- DI (*fixxfdi) (CGEN_FPU*, XF);
- USI (*ufixxfsi) (CGEN_FPU*, XF);
- UDI (*ufixxfdi) (CGEN_FPU*, XF);
+ SI (*fixxfsi) (CGEN_FPU*, int, XF);
+ DI (*fixxfdi) (CGEN_FPU*, int, XF);
+ USI (*ufixxfsi) (CGEN_FPU*, int, XF);
+ UDI (*ufixxfdi) (CGEN_FPU*, int, XF);
/* TF mode support (kept separate 'cus not always present) */
int (*gttf) (CGEN_FPU*, TF, TF);
int (*getf) (CGEN_FPU*, TF, TF);
- TF (*extsftf) (CGEN_FPU*, SF);
- TF (*extdftf) (CGEN_FPU*, DF);
- SF (*trunctfsf) (CGEN_FPU*, TF);
- DF (*trunctfdf) (CGEN_FPU*, TF);
+ TF (*extsftf) (CGEN_FPU*, int, SF);
+ TF (*extdftf) (CGEN_FPU*, int, DF);
+ SF (*trunctfsf) (CGEN_FPU*, int, TF);
+ DF (*trunctfdf) (CGEN_FPU*, int, TF);
- TF (*floatsitf) (CGEN_FPU*, SI);
- TF (*floatditf) (CGEN_FPU*, DI);
- TF (*ufloatsitf) (CGEN_FPU*, USI);
- TF (*ufloatditf) (CGEN_FPU*, UDI);
+ TF (*floatsitf) (CGEN_FPU*, int, SI);
+ TF (*floatditf) (CGEN_FPU*, int, DI);
+ TF (*ufloatsitf) (CGEN_FPU*, int, USI);
+ TF (*ufloatditf) (CGEN_FPU*, int, UDI);
- SI (*fixtfsi) (CGEN_FPU*, TF);
- DI (*fixtfdi) (CGEN_FPU*, TF);
- USI (*ufixtfsi) (CGEN_FPU*, TF);
- UDI (*ufixtfdi) (CGEN_FPU*, TF);
+ SI (*fixtfsi) (CGEN_FPU*, int, TF);
+ DI (*fixtfdi) (CGEN_FPU*, int, TF);
+ USI (*ufixtfsi) (CGEN_FPU*, int, TF);
+ UDI (*ufixtfdi) (CGEN_FPU*, int, TF);
};
SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
{
- SF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsisf (CGEN_CPU_FPU (current_cpu), GET_H_FR_INT (FLD (f_FRj)));
+ SF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsisf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR_INT (FLD (f_FRj)));
sim_queue_fn_sf_write (current_cpu, frvbf_h_fr_set, FLD (f_FRk), opval);
TRACE_RESULT (current_cpu, abuf, "fr", 'f', opval);
}
SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
{
- SI opval = CGEN_CPU_FPU (current_cpu)->ops->fixsfsi (CGEN_CPU_FPU (current_cpu), GET_H_FR (FLD (f_FRj)));
+ SI opval = CGEN_CPU_FPU (current_cpu)->ops->fixsfsi (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR (FLD (f_FRj)));
sim_queue_fn_si_write (current_cpu, frvbf_h_fr_int_set, FLD (f_FRk), opval);
TRACE_RESULT (current_cpu, abuf, "fr_int", 'x', opval);
}
SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
{
- DF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsidf (CGEN_CPU_FPU (current_cpu), GET_H_FR_INT (FLD (f_FRj)));
+ DF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsidf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR_INT (FLD (f_FRj)));
sim_queue_fn_df_write (current_cpu, frvbf_h_fr_double_set, FLD (f_FRk), opval);
TRACE_RESULT (current_cpu, abuf, "fr_double", 'f', opval);
}
SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
{
- SI opval = CGEN_CPU_FPU (current_cpu)->ops->fixdfsi (CGEN_CPU_FPU (current_cpu), GET_H_FR_DOUBLE (FLD (f_FRj)));
+ SI opval = CGEN_CPU_FPU (current_cpu)->ops->fixdfsi (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR_DOUBLE (FLD (f_FRj)));
sim_queue_fn_si_write (current_cpu, frvbf_h_fr_int_set, FLD (f_FRk), opval);
TRACE_RESULT (current_cpu, abuf, "fr_int", 'x', opval);
}
{
{
- SF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsisf (CGEN_CPU_FPU (current_cpu), GET_H_FR_INT (FLD (f_FRj)));
+ SF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsisf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR_INT (FLD (f_FRj)));
sim_queue_fn_sf_write (current_cpu, frvbf_h_fr_set, FLD (f_FRk), opval);
TRACE_RESULT (current_cpu, abuf, "fr", 'f', opval);
}
{
- SF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsisf (CGEN_CPU_FPU (current_cpu), GET_H_FR_INT (ADDSI (FLD (f_FRj), 1)));
+ SF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsisf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR_INT (ADDSI (FLD (f_FRj), 1)));
sim_queue_fn_sf_write (current_cpu, frvbf_h_fr_set, ADDSI (FLD (f_FRk), 1), opval);
TRACE_RESULT (current_cpu, abuf, "fr", 'f', opval);
}
{
{
- SI opval = CGEN_CPU_FPU (current_cpu)->ops->fixsfsi (CGEN_CPU_FPU (current_cpu), GET_H_FR (FLD (f_FRj)));
+ SI opval = CGEN_CPU_FPU (current_cpu)->ops->fixsfsi (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR (FLD (f_FRj)));
sim_queue_fn_si_write (current_cpu, frvbf_h_fr_int_set, FLD (f_FRk), opval);
TRACE_RESULT (current_cpu, abuf, "fr_int", 'x', opval);
}
{
- USI opval = CGEN_CPU_FPU (current_cpu)->ops->fixsfsi (CGEN_CPU_FPU (current_cpu), GET_H_FR (ADDSI (FLD (f_FRj), 1)));
+ USI opval = CGEN_CPU_FPU (current_cpu)->ops->fixsfsi (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR (ADDSI (FLD (f_FRj), 1)));
sim_queue_fn_si_write (current_cpu, frvbf_h_fr_int_set, ADDSI (FLD (f_FRk), 1), opval);
TRACE_RESULT (current_cpu, abuf, "fr_int", 'x', opval);
}
{
frvbf_set_ne_index (current_cpu, FLD (f_FRk));
{
- SF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsisf (CGEN_CPU_FPU (current_cpu), GET_H_FR_INT (FLD (f_FRj)));
+ SF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsisf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR_INT (FLD (f_FRj)));
sim_queue_fn_sf_write (current_cpu, frvbf_h_fr_set, FLD (f_FRk), opval);
TRACE_RESULT (current_cpu, abuf, "fr", 'f', opval);
}
frvbf_set_ne_index (current_cpu, ADDSI (FLD (f_FRk), 1));
{
- SF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsisf (CGEN_CPU_FPU (current_cpu), GET_H_FR_INT (ADDSI (FLD (f_FRj), 1)));
+ SF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsisf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR_INT (ADDSI (FLD (f_FRj), 1)));
sim_queue_fn_sf_write (current_cpu, frvbf_h_fr_set, ADDSI (FLD (f_FRk), 1), opval);
TRACE_RESULT (current_cpu, abuf, "fr", 'f', opval);
}
{
frvbf_set_ne_index (current_cpu, FLD (f_FRk));
{
- SI opval = CGEN_CPU_FPU (current_cpu)->ops->fixsfsi (CGEN_CPU_FPU (current_cpu), GET_H_FR (FLD (f_FRj)));
+ SI opval = CGEN_CPU_FPU (current_cpu)->ops->fixsfsi (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR (FLD (f_FRj)));
sim_queue_fn_si_write (current_cpu, frvbf_h_fr_int_set, FLD (f_FRk), opval);
TRACE_RESULT (current_cpu, abuf, "fr_int", 'x', opval);
}
frvbf_set_ne_index (current_cpu, ADDSI (FLD (f_FRk), 1));
{
- USI opval = CGEN_CPU_FPU (current_cpu)->ops->fixsfsi (CGEN_CPU_FPU (current_cpu), GET_H_FR (ADDSI (FLD (f_FRj), 1)));
+ USI opval = CGEN_CPU_FPU (current_cpu)->ops->fixsfsi (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR (ADDSI (FLD (f_FRj), 1)));
sim_queue_fn_si_write (current_cpu, frvbf_h_fr_int_set, ADDSI (FLD (f_FRk), 1), opval);
TRACE_RESULT (current_cpu, abuf, "fr_int", 'x', opval);
}
if (EQQI (CPU (h_cccr[FLD (f_CCi)]), ORSI (FLD (f_cond), 2))) {
{
- SF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsisf (CGEN_CPU_FPU (current_cpu), GET_H_FR_INT (FLD (f_FRj)));
+ SF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsisf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR_INT (FLD (f_FRj)));
sim_queue_fn_sf_write (current_cpu, frvbf_h_fr_set, FLD (f_FRk), opval);
written |= (1 << 3);
TRACE_RESULT (current_cpu, abuf, "fr", 'f', opval);
if (EQQI (CPU (h_cccr[FLD (f_CCi)]), ORSI (FLD (f_cond), 2))) {
{
- SI opval = CGEN_CPU_FPU (current_cpu)->ops->fixsfsi (CGEN_CPU_FPU (current_cpu), GET_H_FR (FLD (f_FRj)));
+ SI opval = CGEN_CPU_FPU (current_cpu)->ops->fixsfsi (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR (FLD (f_FRj)));
sim_queue_fn_si_write (current_cpu, frvbf_h_fr_int_set, FLD (f_FRk), opval);
written |= (1 << 3);
TRACE_RESULT (current_cpu, abuf, "fr_int", 'x', opval);
{
frvbf_set_ne_index (current_cpu, FLD (f_FRk));
{
- SF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsisf (CGEN_CPU_FPU (current_cpu), GET_H_FR_INT (FLD (f_FRj)));
+ SF opval = CGEN_CPU_FPU (current_cpu)->ops->floatsisf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR_INT (FLD (f_FRj)));
sim_queue_fn_sf_write (current_cpu, frvbf_h_fr_set, FLD (f_FRk), opval);
TRACE_RESULT (current_cpu, abuf, "fr", 'f', opval);
}
{
frvbf_set_ne_index (current_cpu, FLD (f_FRk));
{
- SI opval = CGEN_CPU_FPU (current_cpu)->ops->fixsfsi (CGEN_CPU_FPU (current_cpu), GET_H_FR (FLD (f_FRj)));
+ SI opval = CGEN_CPU_FPU (current_cpu)->ops->fixsfsi (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR (FLD (f_FRj)));
sim_queue_fn_si_write (current_cpu, frvbf_h_fr_int_set, FLD (f_FRk), opval);
TRACE_RESULT (current_cpu, abuf, "fr_int", 'x', opval);
}
{
{
- SF opval = CGEN_CPU_FPU (current_cpu)->ops->ftruncdfsf (CGEN_CPU_FPU (current_cpu), CGEN_CPU_FPU (current_cpu)->ops->muldf (CGEN_CPU_FPU (current_cpu), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), GET_H_FR (FLD (f_FRi))), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), GET_H_FR (FLD (f_FRj)))));
+ SF opval = CGEN_CPU_FPU (current_cpu)->ops->ftruncdfsf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, CGEN_CPU_FPU (current_cpu)->ops->muldf (CGEN_CPU_FPU (current_cpu), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR (FLD (f_FRi))), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR (FLD (f_FRj)))));
sim_queue_fn_sf_write (current_cpu, frvbf_h_fr_set, FLD (f_FRk), opval);
TRACE_RESULT (current_cpu, abuf, "fr", 'f', opval);
}
{
- SF opval = CGEN_CPU_FPU (current_cpu)->ops->ftruncdfsf (CGEN_CPU_FPU (current_cpu), CGEN_CPU_FPU (current_cpu)->ops->adddf (CGEN_CPU_FPU (current_cpu), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), GET_H_FR (ADDSI (FLD (f_FRi), 1))), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), GET_H_FR (ADDSI (FLD (f_FRj), 1)))));
+ SF opval = CGEN_CPU_FPU (current_cpu)->ops->ftruncdfsf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, CGEN_CPU_FPU (current_cpu)->ops->adddf (CGEN_CPU_FPU (current_cpu), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR (ADDSI (FLD (f_FRi), 1))), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR (ADDSI (FLD (f_FRj), 1)))));
sim_queue_fn_sf_write (current_cpu, frvbf_h_fr_set, ADDSI (FLD (f_FRk), 1), opval);
TRACE_RESULT (current_cpu, abuf, "fr", 'f', opval);
}
{
{
- SF opval = CGEN_CPU_FPU (current_cpu)->ops->ftruncdfsf (CGEN_CPU_FPU (current_cpu), CGEN_CPU_FPU (current_cpu)->ops->muldf (CGEN_CPU_FPU (current_cpu), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), GET_H_FR (FLD (f_FRi))), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), GET_H_FR (FLD (f_FRj)))));
+ SF opval = CGEN_CPU_FPU (current_cpu)->ops->ftruncdfsf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, CGEN_CPU_FPU (current_cpu)->ops->muldf (CGEN_CPU_FPU (current_cpu), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR (FLD (f_FRi))), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR (FLD (f_FRj)))));
sim_queue_fn_sf_write (current_cpu, frvbf_h_fr_set, FLD (f_FRk), opval);
TRACE_RESULT (current_cpu, abuf, "fr", 'f', opval);
}
{
- SF opval = CGEN_CPU_FPU (current_cpu)->ops->ftruncdfsf (CGEN_CPU_FPU (current_cpu), CGEN_CPU_FPU (current_cpu)->ops->subdf (CGEN_CPU_FPU (current_cpu), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), GET_H_FR (ADDSI (FLD (f_FRi), 1))), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), GET_H_FR (ADDSI (FLD (f_FRj), 1)))));
+ SF opval = CGEN_CPU_FPU (current_cpu)->ops->ftruncdfsf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, CGEN_CPU_FPU (current_cpu)->ops->subdf (CGEN_CPU_FPU (current_cpu), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR (ADDSI (FLD (f_FRi), 1))), CGEN_CPU_FPU (current_cpu)->ops->fextsfdf (CGEN_CPU_FPU (current_cpu), FPCONV_DEFAULT, GET_H_FR (ADDSI (FLD (f_FRj), 1)))));
sim_queue_fn_sf_write (current_cpu, frvbf_h_fr_set, ADDSI (FLD (f_FRk), 1), opval);
TRACE_RESULT (current_cpu, abuf, "fr", 'f', opval);
}