linux/arch/arm/nwfpe/single_cpdo.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3    NetWinder Floating Point Emulator
   4    (c) Rebel.COM, 1998,1999
   5    (c) Philip Blundell, 2001
   6
   7    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
   8
   9*/
  10
  11#include "fpa11.h"
  12#include "softfloat.h"
  13#include "fpopcode.h"
  14
  15float32 float32_exp(float32 Fm);
  16float32 float32_ln(float32 Fm);
  17float32 float32_sin(float32 rFm);
  18float32 float32_cos(float32 rFm);
  19float32 float32_arcsin(float32 rFm);
  20float32 float32_arctan(float32 rFm);
  21float32 float32_log(float32 rFm);
  22float32 float32_tan(float32 rFm);
  23float32 float32_arccos(float32 rFm);
  24float32 float32_pow(float32 rFn, float32 rFm);
  25float32 float32_pol(float32 rFn, float32 rFm);
  26
  27static float32 float32_rsf(struct roundingData *roundData, float32 rFn, float32 rFm)
  28{
  29        return float32_sub(roundData, rFm, rFn);
  30}
  31
  32static float32 float32_rdv(struct roundingData *roundData, float32 rFn, float32 rFm)
  33{
  34        return float32_div(roundData, rFm, rFn);
  35}
  36
  37static float32 (*const dyadic_single[16])(struct roundingData *, float32 rFn, float32 rFm) = {
  38        [ADF_CODE >> 20] = float32_add,
  39        [MUF_CODE >> 20] = float32_mul,
  40        [SUF_CODE >> 20] = float32_sub,
  41        [RSF_CODE >> 20] = float32_rsf,
  42        [DVF_CODE >> 20] = float32_div,
  43        [RDF_CODE >> 20] = float32_rdv,
  44        [RMF_CODE >> 20] = float32_rem,
  45
  46        [FML_CODE >> 20] = float32_mul,
  47        [FDV_CODE >> 20] = float32_div,
  48        [FRD_CODE >> 20] = float32_rdv,
  49};
  50
  51static float32 float32_mvf(struct roundingData *roundData, float32 rFm)
  52{
  53        return rFm;
  54}
  55
  56static float32 float32_mnf(struct roundingData *roundData, float32 rFm)
  57{
  58        return rFm ^ 0x80000000;
  59}
  60
  61static float32 float32_abs(struct roundingData *roundData, float32 rFm)
  62{
  63        return rFm & 0x7fffffff;
  64}
  65
  66static float32 (*const monadic_single[16])(struct roundingData*, float32 rFm) = {
  67        [MVF_CODE >> 20] = float32_mvf,
  68        [MNF_CODE >> 20] = float32_mnf,
  69        [ABS_CODE >> 20] = float32_abs,
  70        [RND_CODE >> 20] = float32_round_to_int,
  71        [URD_CODE >> 20] = float32_round_to_int,
  72        [SQT_CODE >> 20] = float32_sqrt,
  73        [NRM_CODE >> 20] = float32_mvf,
  74};
  75
  76unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
  77{
  78        FPA11 *fpa11 = GET_FPA11();
  79        float32 rFm;
  80        unsigned int Fm, opc_mask_shift;
  81
  82        Fm = getFm(opcode);
  83        if (CONSTANT_FM(opcode)) {
  84                rFm = getSingleConstant(Fm);
  85        } else if (fpa11->fType[Fm] == typeSingle) {
  86                rFm = fpa11->fpreg[Fm].fSingle;
  87        } else {
  88                return 0;
  89        }
  90
  91        opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20;
  92        if (!MONADIC_INSTRUCTION(opcode)) {
  93                unsigned int Fn = getFn(opcode);
  94                float32 rFn;
  95
  96                if (fpa11->fType[Fn] == typeSingle &&
  97                    dyadic_single[opc_mask_shift]) {
  98                        rFn = fpa11->fpreg[Fn].fSingle;
  99                        rFd->fSingle = dyadic_single[opc_mask_shift](roundData, rFn, rFm);
 100                } else {
 101                        return 0;
 102                }
 103        } else {
 104                if (monadic_single[opc_mask_shift]) {
 105                        rFd->fSingle = monadic_single[opc_mask_shift](roundData, rFm);
 106                } else {
 107                        return 0;
 108                }
 109        }
 110
 111        return 1;
 112}
 113