cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

single_cpdo.c (2904B)


      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}