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

fpa11.c (2459B)


      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 "fpopcode.h"
     13
     14#include "fpmodule.h"
     15#include "fpmodule.inl"
     16
     17#include <linux/compiler.h>
     18#include <linux/string.h>
     19
     20/* Reset the FPA11 chip.  Called to initialize and reset the emulator. */
     21static void resetFPA11(void)
     22{
     23	int i;
     24	FPA11 *fpa11 = GET_FPA11();
     25
     26	/* initialize the register type array */
     27	for (i = 0; i <= 7; i++) {
     28		fpa11->fType[i] = typeNone;
     29	}
     30
     31	/* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */
     32	fpa11->fpsr = FP_EMULATOR | BIT_AC;
     33}
     34
     35int8 SetRoundingMode(const unsigned int opcode)
     36{
     37	switch (opcode & MASK_ROUNDING_MODE) {
     38	default:
     39	case ROUND_TO_NEAREST:
     40		return float_round_nearest_even;
     41
     42	case ROUND_TO_PLUS_INFINITY:
     43		return float_round_up;
     44
     45	case ROUND_TO_MINUS_INFINITY:
     46		return float_round_down;
     47
     48	case ROUND_TO_ZERO:
     49		return float_round_to_zero;
     50	}
     51}
     52
     53int8 SetRoundingPrecision(const unsigned int opcode)
     54{
     55#ifdef CONFIG_FPE_NWFPE_XP
     56	switch (opcode & MASK_ROUNDING_PRECISION) {
     57	case ROUND_SINGLE:
     58		return 32;
     59
     60	case ROUND_DOUBLE:
     61		return 64;
     62
     63	case ROUND_EXTENDED:
     64		return 80;
     65
     66	default:
     67		return 80;
     68	}
     69#endif
     70	return 80;
     71}
     72
     73void nwfpe_init_fpa(union fp_state *fp)
     74{
     75	FPA11 *fpa11 = (FPA11 *)fp;
     76#ifdef NWFPE_DEBUG
     77	printk("NWFPE: setting up state.\n");
     78#endif
     79 	memset(fpa11, 0, sizeof(FPA11));
     80	resetFPA11();
     81	fpa11->initflag = 1;
     82}
     83
     84/* Emulate the instruction in the opcode. */
     85unsigned int EmulateAll(unsigned int opcode)
     86{
     87	unsigned int code;
     88
     89#ifdef NWFPE_DEBUG
     90	printk("NWFPE: emulating opcode %08x\n", opcode);
     91#endif
     92	code = opcode & 0x00000f00;
     93	if (code == 0x00000100 || code == 0x00000200) {
     94		/* For coprocessor 1 or 2 (FPA11) */
     95		code = opcode & 0x0e000000;
     96		if (code == 0x0e000000) {
     97			if (opcode & 0x00000010) {
     98				/* Emulate conversion opcodes. */
     99				/* Emulate register transfer opcodes. */
    100				/* Emulate comparison opcodes. */
    101				return EmulateCPRT(opcode);
    102			} else {
    103				/* Emulate monadic arithmetic opcodes. */
    104				/* Emulate dyadic arithmetic opcodes. */
    105				return EmulateCPDO(opcode);
    106			}
    107		} else if (code == 0x0c000000) {
    108			/* Emulate load/store opcodes. */
    109			/* Emulate load/store multiple opcodes. */
    110			return EmulateCPDT(opcode);
    111		}
    112	}
    113
    114	/* Invalid instruction detected.  Return FALSE. */
    115	return 0;
    116}