root/arch/arm/nwfpe/fpa11.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. resetFPA11
  2. SetRoundingMode
  3. SetRoundingPrecision
  4. nwfpe_init_fpa
  5. EmulateAll

   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. */
  21 static 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 
  35 int8 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 
  53 int8 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 
  73 void 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. */
  85 unsigned 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 }

/* [<][>][^][v][top][bottom][index][help] */