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

extended_cpdo.c (3476B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3    NetWinder Floating Point Emulator
      4    (c) Rebel.COM, 1998,1999
      5
      6    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
      7
      8*/
      9
     10#include "fpa11.h"
     11#include "softfloat.h"
     12#include "fpopcode.h"
     13
     14floatx80 floatx80_exp(floatx80 Fm);
     15floatx80 floatx80_ln(floatx80 Fm);
     16floatx80 floatx80_sin(floatx80 rFm);
     17floatx80 floatx80_cos(floatx80 rFm);
     18floatx80 floatx80_arcsin(floatx80 rFm);
     19floatx80 floatx80_arctan(floatx80 rFm);
     20floatx80 floatx80_log(floatx80 rFm);
     21floatx80 floatx80_tan(floatx80 rFm);
     22floatx80 floatx80_arccos(floatx80 rFm);
     23floatx80 floatx80_pow(floatx80 rFn, floatx80 rFm);
     24floatx80 floatx80_pol(floatx80 rFn, floatx80 rFm);
     25
     26static floatx80 floatx80_rsf(struct roundingData *roundData, floatx80 rFn, floatx80 rFm)
     27{
     28	return floatx80_sub(roundData, rFm, rFn);
     29}
     30
     31static floatx80 floatx80_rdv(struct roundingData *roundData, floatx80 rFn, floatx80 rFm)
     32{
     33	return floatx80_div(roundData, rFm, rFn);
     34}
     35
     36static floatx80 (*const dyadic_extended[16])(struct roundingData*, floatx80 rFn, floatx80 rFm) = {
     37	[ADF_CODE >> 20] = floatx80_add,
     38	[MUF_CODE >> 20] = floatx80_mul,
     39	[SUF_CODE >> 20] = floatx80_sub,
     40	[RSF_CODE >> 20] = floatx80_rsf,
     41	[DVF_CODE >> 20] = floatx80_div,
     42	[RDF_CODE >> 20] = floatx80_rdv,
     43	[RMF_CODE >> 20] = floatx80_rem,
     44
     45	/* strictly, these opcodes should not be implemented */
     46	[FML_CODE >> 20] = floatx80_mul,
     47	[FDV_CODE >> 20] = floatx80_div,
     48	[FRD_CODE >> 20] = floatx80_rdv,
     49};
     50
     51static floatx80 floatx80_mvf(struct roundingData *roundData, floatx80 rFm)
     52{
     53	return rFm;
     54}
     55
     56static floatx80 floatx80_mnf(struct roundingData *roundData, floatx80 rFm)
     57{
     58	rFm.high ^= 0x8000;
     59	return rFm;
     60}
     61
     62static floatx80 floatx80_abs(struct roundingData *roundData, floatx80 rFm)
     63{
     64	rFm.high &= 0x7fff;
     65	return rFm;
     66}
     67
     68static floatx80 (*const monadic_extended[16])(struct roundingData*, floatx80 rFm) = {
     69	[MVF_CODE >> 20] = floatx80_mvf,
     70	[MNF_CODE >> 20] = floatx80_mnf,
     71	[ABS_CODE >> 20] = floatx80_abs,
     72	[RND_CODE >> 20] = floatx80_round_to_int,
     73	[URD_CODE >> 20] = floatx80_round_to_int,
     74	[SQT_CODE >> 20] = floatx80_sqrt,
     75	[NRM_CODE >> 20] = floatx80_mvf,
     76};
     77
     78unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
     79{
     80	FPA11 *fpa11 = GET_FPA11();
     81	floatx80 rFm;
     82	unsigned int Fm, opc_mask_shift;
     83
     84	Fm = getFm(opcode);
     85	if (CONSTANT_FM(opcode)) {
     86		rFm = getExtendedConstant(Fm);
     87	} else {
     88		switch (fpa11->fType[Fm]) {
     89		case typeSingle:
     90			rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
     91			break;
     92
     93		case typeDouble:
     94			rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
     95			break;
     96
     97		case typeExtended:
     98			rFm = fpa11->fpreg[Fm].fExtended;
     99			break;
    100
    101		default:
    102			return 0;
    103		}
    104	}
    105
    106	opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20;
    107	if (!MONADIC_INSTRUCTION(opcode)) {
    108		unsigned int Fn = getFn(opcode);
    109		floatx80 rFn;
    110
    111		switch (fpa11->fType[Fn]) {
    112		case typeSingle:
    113			rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
    114			break;
    115
    116		case typeDouble:
    117			rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
    118			break;
    119
    120		case typeExtended:
    121			rFn = fpa11->fpreg[Fn].fExtended;
    122			break;
    123
    124		default:
    125			return 0;
    126		}
    127
    128		if (dyadic_extended[opc_mask_shift]) {
    129			rFd->fExtended = dyadic_extended[opc_mask_shift](roundData, rFn, rFm);
    130		} else {
    131			return 0;
    132		}
    133	} else {
    134		if (monadic_extended[opc_mask_shift]) {
    135			rFd->fExtended = monadic_extended[opc_mask_shift](roundData, rFm);
    136		} else {
    137			return 0;
    138		}
    139	}
    140
    141	return 1;
    142}