📄 cgen-accfp.c
字号:
/* Accurate fp support for CGEN-based simulators. Copyright (C) 1999 Cygnus Solutions. This implemention assumes: typedef USI SF; typedef UDI DF; TODO: - lazy encoding/decoding - checking return code (say by callback) - proper rounding*/#include "sim-main.h"#include "sim-fpu.h"/* SF mode support */static SFaddsf (CGEN_FPU* fpu, SF x, SF y){ sim_fpu op1; sim_fpu op2; sim_fpu ans; unsigned32 res; sim_fpu_status status; sim_fpu_32to (&op1, x); sim_fpu_32to (&op2, y); status = sim_fpu_add (&ans, &op1, &op2); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to32 (&res, &ans); return res;}static SFsubsf (CGEN_FPU* fpu, SF x, SF y){ sim_fpu op1; sim_fpu op2; sim_fpu ans; unsigned32 res; sim_fpu_status status; sim_fpu_32to (&op1, x); sim_fpu_32to (&op2, y); status = sim_fpu_sub (&ans, &op1, &op2); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to32 (&res, &ans); return res;}static SFmulsf (CGEN_FPU* fpu, SF x, SF y){ sim_fpu op1; sim_fpu op2; sim_fpu ans; unsigned32 res; sim_fpu_status status; sim_fpu_32to (&op1, x); sim_fpu_32to (&op2, y); status = sim_fpu_mul (&ans, &op1, &op2); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to32 (&res, &ans); return res;}static SFdivsf (CGEN_FPU* fpu, SF x, SF y){ sim_fpu op1; sim_fpu op2; sim_fpu ans; unsigned32 res; sim_fpu_status status; sim_fpu_32to (&op1, x); sim_fpu_32to (&op2, y); status = sim_fpu_div (&ans, &op1, &op2); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to32 (&res, &ans); return res;}static SFnegsf (CGEN_FPU* fpu, SF x){ sim_fpu op1; sim_fpu ans; unsigned32 res; sim_fpu_status status; sim_fpu_32to (&op1, x); status = sim_fpu_neg (&ans, &op1); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to32 (&res, &ans); return res;}static SFabssf (CGEN_FPU* fpu, SF x){ sim_fpu op1; sim_fpu ans; unsigned32 res; sim_fpu_status status; sim_fpu_32to (&op1, x); status = sim_fpu_abs (&ans, &op1); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to32 (&res, &ans); return res;}static SFsqrtsf (CGEN_FPU* fpu, SF x){ sim_fpu op1; sim_fpu ans; unsigned32 res; sim_fpu_status status; sim_fpu_32to (&op1, x); status = sim_fpu_sqrt (&ans, &op1); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to32 (&res, &ans); return res;}static SFinvsf (CGEN_FPU* fpu, SF x){ sim_fpu op1; sim_fpu ans; unsigned32 res; sim_fpu_status status; sim_fpu_32to (&op1, x); status = sim_fpu_inv (&ans, &op1); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to32 (&res, &ans); return res;}static SFminsf (CGEN_FPU* fpu, SF x, SF y){ sim_fpu op1; sim_fpu op2; sim_fpu ans; unsigned32 res; sim_fpu_status status; sim_fpu_32to (&op1, x); sim_fpu_32to (&op2, y); status = sim_fpu_min (&ans, &op1, &op2); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to32 (&res, &ans); return res;}static SFmaxsf (CGEN_FPU* fpu, SF x, SF y){ sim_fpu op1; sim_fpu op2; sim_fpu ans; unsigned32 res; sim_fpu_status status; sim_fpu_32to (&op1, x); sim_fpu_32to (&op2, y); status = sim_fpu_max (&ans, &op1, &op2); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to32 (&res, &ans); return res;}static CGEN_FP_CMPcmpsf (CGEN_FPU* fpu, SF x, SF y){ sim_fpu op1; sim_fpu op2; sim_fpu_32to (&op1, x); sim_fpu_32to (&op2, y); if (sim_fpu_is_nan (&op1) || sim_fpu_is_nan (&op2)) return FP_CMP_NAN; if (x < y) return FP_CMP_LT; if (x > y) return FP_CMP_GT; return FP_CMP_EQ;}static inteqsf (CGEN_FPU* fpu, SF x, SF y){ sim_fpu op1; sim_fpu op2; sim_fpu_32to (&op1, x); sim_fpu_32to (&op2, y); return sim_fpu_is_eq (&op1, &op2);}static intnesf (CGEN_FPU* fpu, SF x, SF y){ sim_fpu op1; sim_fpu op2; sim_fpu_32to (&op1, x); sim_fpu_32to (&op2, y); return sim_fpu_is_ne (&op1, &op2);}static intltsf (CGEN_FPU* fpu, SF x, SF y){ sim_fpu op1; sim_fpu op2; sim_fpu_32to (&op1, x); sim_fpu_32to (&op2, y); return sim_fpu_is_lt (&op1, &op2);}static intlesf (CGEN_FPU* fpu, SF x, SF y){ sim_fpu op1; sim_fpu op2; sim_fpu_32to (&op1, x); sim_fpu_32to (&op2, y); return sim_fpu_is_le (&op1, &op2);}static intgtsf (CGEN_FPU* fpu, SF x, SF y){ sim_fpu op1; sim_fpu op2; sim_fpu_32to (&op1, x); sim_fpu_32to (&op2, y); return sim_fpu_is_gt (&op1, &op2);}static intgesf (CGEN_FPU* fpu, SF x, SF y){ sim_fpu op1; sim_fpu op2; sim_fpu_32to (&op1, x); sim_fpu_32to (&op2, y); return sim_fpu_is_ge (&op1, &op2);}static DFfextsfdf (CGEN_FPU* fpu, SF x){ sim_fpu op1; unsigned64 res; sim_fpu_32to (&op1, x); sim_fpu_to64 (&res, &op1); return res;}static SFftruncdfsf (CGEN_FPU* fpu, DF x){ sim_fpu op1; unsigned32 res; sim_fpu_64to (&op1, x); sim_fpu_to32 (&res, &op1); return res;}static SFfloatsisf (CGEN_FPU* fpu, SI x){ sim_fpu ans; unsigned32 res; sim_fpu_i32to (&ans, x, sim_fpu_round_near); sim_fpu_to32 (&res, &ans); return res;}static DFfloatsidf (CGEN_FPU* fpu, SI x){ sim_fpu ans; unsigned64 res; sim_fpu_i32to (&ans, x, sim_fpu_round_near); sim_fpu_to64 (&res, &ans); return res;}static SFufloatsisf (CGEN_FPU* fpu, USI x){ sim_fpu ans; unsigned32 res; sim_fpu_u32to (&ans, x, sim_fpu_round_near); sim_fpu_to32 (&res, &ans); return res;}static SIfixsfsi (CGEN_FPU* fpu, SF x){ sim_fpu op1; unsigned32 res; sim_fpu_32to (&op1, x); sim_fpu_to32i (&res, &op1, sim_fpu_round_near); return res;}static SIfixdfsi (CGEN_FPU* fpu, DF x){ sim_fpu op1; unsigned32 res; sim_fpu_64to (&op1, x); sim_fpu_to32i (&res, &op1, sim_fpu_round_near); return res;}static USIufixsfsi (CGEN_FPU* fpu, SF x){ sim_fpu op1; unsigned32 res; sim_fpu_32to (&op1, x); sim_fpu_to32u (&res, &op1, sim_fpu_round_near); return res;}/* DF mode support */static DFadddf (CGEN_FPU* fpu, DF x, DF y){ sim_fpu op1; sim_fpu op2; sim_fpu ans; unsigned64 res; sim_fpu_status status; sim_fpu_64to (&op1, x); sim_fpu_64to (&op2, y); status = sim_fpu_add (&ans, &op1, &op2); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to64 (&res, &ans); return res;}static DFsubdf (CGEN_FPU* fpu, DF x, DF y){ sim_fpu op1; sim_fpu op2; sim_fpu ans; unsigned64 res; sim_fpu_status status; sim_fpu_64to (&op1, x); sim_fpu_64to (&op2, y); status = sim_fpu_sub (&ans, &op1, &op2); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to64 (&res, &ans); return res;}static DFmuldf (CGEN_FPU* fpu, DF x, DF y){ sim_fpu op1; sim_fpu op2; sim_fpu ans; unsigned64 res; sim_fpu_status status; sim_fpu_64to (&op1, x); sim_fpu_64to (&op2, y); status = sim_fpu_mul (&ans, &op1, &op2); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to64 (&res, &ans); return res;}static DFdivdf (CGEN_FPU* fpu, DF x, DF y){ sim_fpu op1; sim_fpu op2; sim_fpu ans; unsigned64 res; sim_fpu_status status; sim_fpu_64to (&op1, x); sim_fpu_64to (&op2, y); status = sim_fpu_div (&ans, &op1, &op2); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to64 (&res, &ans); return res;}static DFnegdf (CGEN_FPU* fpu, DF x){ sim_fpu op1; sim_fpu ans; unsigned64 res; sim_fpu_status status; sim_fpu_64to (&op1, x); status = sim_fpu_neg (&ans, &op1); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to64 (&res, &ans); return res;}static DFabsdf (CGEN_FPU* fpu, DF x){ sim_fpu op1; sim_fpu ans; unsigned64 res; sim_fpu_status status; sim_fpu_64to (&op1, x); status = sim_fpu_abs (&ans, &op1); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to64 (&res, &ans); return res;}static DFsqrtdf (CGEN_FPU* fpu, DF x){ sim_fpu op1; sim_fpu ans; unsigned64 res; sim_fpu_status status; sim_fpu_64to (&op1, x); status = sim_fpu_sqrt (&ans, &op1); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to64 (&res, &ans); return res;}static DFinvdf (CGEN_FPU* fpu, DF x){ sim_fpu op1; sim_fpu ans; unsigned64 res; sim_fpu_status status; sim_fpu_64to (&op1, x); status = sim_fpu_inv (&ans, &op1); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to64 (&res, &ans); return res;}static DFmindf (CGEN_FPU* fpu, DF x, DF y){ sim_fpu op1; sim_fpu op2; sim_fpu ans; unsigned64 res; sim_fpu_status status; sim_fpu_64to (&op1, x); sim_fpu_64to (&op2, y); status = sim_fpu_min (&ans, &op1, &op2); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to64 (&res, &ans); return res;}static DFmaxdf (CGEN_FPU* fpu, DF x, DF y){ sim_fpu op1; sim_fpu op2; sim_fpu ans; unsigned64 res; sim_fpu_status status; sim_fpu_64to (&op1, x); sim_fpu_64to (&op2, y); status = sim_fpu_max (&ans, &op1, &op2); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to64 (&res, &ans); return res;}static CGEN_FP_CMPcmpdf (CGEN_FPU* fpu, DF x, DF y){ sim_fpu op1; sim_fpu op2; sim_fpu_64to (&op1, x); sim_fpu_64to (&op2, y); if (sim_fpu_is_nan (&op1) || sim_fpu_is_nan (&op2)) return FP_CMP_NAN; if (x < y) return FP_CMP_LT; if (x > y) return FP_CMP_GT; return FP_CMP_EQ;}static inteqdf (CGEN_FPU* fpu, DF x, DF y){ sim_fpu op1; sim_fpu op2; sim_fpu_64to (&op1, x); sim_fpu_64to (&op2, y); return sim_fpu_is_eq (&op1, &op2);}static intnedf (CGEN_FPU* fpu, DF x, DF y){ sim_fpu op1; sim_fpu op2; sim_fpu_64to (&op1, x); sim_fpu_64to (&op2, y); return sim_fpu_is_ne (&op1, &op2);}static intltdf (CGEN_FPU* fpu, DF x, DF y){ sim_fpu op1; sim_fpu op2; sim_fpu_64to (&op1, x); sim_fpu_64to (&op2, y); return sim_fpu_is_lt (&op1, &op2);}static intledf (CGEN_FPU* fpu, DF x, DF y){ sim_fpu op1; sim_fpu op2; sim_fpu_64to (&op1, x); sim_fpu_64to (&op2, y); return sim_fpu_is_le (&op1, &op2);}static intgtdf (CGEN_FPU* fpu, DF x, DF y){ sim_fpu op1; sim_fpu op2; sim_fpu_64to (&op1, x); sim_fpu_64to (&op2, y); return sim_fpu_is_gt (&op1, &op2);}static intgedf (CGEN_FPU* fpu, DF x, DF y){ sim_fpu op1; sim_fpu op2; sim_fpu_64to (&op1, x); sim_fpu_64to (&op2, y); return sim_fpu_is_ge (&op1, &op2);}/* Initialize FP_OPS to use accurate library. */voidcgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error){ CGEN_FP_OPS* o; fpu->owner = cpu; /* ??? small memory leak, not freed by sim_close */ fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS)); o = fpu->ops; memset (o, 0, sizeof (*o)); o->error = error; o->addsf = addsf; o->subsf = subsf; o->mulsf = mulsf; o->divsf = divsf; o->negsf = negsf; o->abssf = abssf; o->sqrtsf = sqrtsf; o->invsf = invsf; o->minsf = minsf; o->maxsf = maxsf; o->cmpsf = cmpsf; o->eqsf = eqsf; o->nesf = nesf; o->ltsf = ltsf; o->lesf = lesf; o->gtsf = gtsf; o->gesf = gesf; o->adddf = adddf; o->subdf = subdf; o->muldf = muldf; o->divdf = divdf; o->negdf = negdf; o->absdf = absdf; o->sqrtdf = sqrtdf; o->invdf = invdf; o->mindf = mindf; o->maxdf = maxdf; o->cmpdf = cmpdf; o->eqdf = eqdf; o->nedf = nedf; o->ltdf = ltdf; o->ledf = ledf; o->gtdf = gtdf; o->gedf = gedf; o->fextsfdf = fextsfdf; o->ftruncdfsf = ftruncdfsf; o->floatsisf = floatsisf; o->floatsidf = floatsidf; o->ufloatsisf = ufloatsisf; o->fixsfsi = fixsfsi; o->fixdfsi = fixdfsi; o->ufixsfsi = ufixsfsi;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -