0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "fpa11.h"
0012 #include "fpopcode.h"
0013
0014 #include "fpmodule.h"
0015 #include "fpmodule.inl"
0016
0017 #include <linux/compiler.h>
0018 #include <linux/string.h>
0019
0020
0021 static void resetFPA11(void)
0022 {
0023 int i;
0024 FPA11 *fpa11 = GET_FPA11();
0025
0026
0027 for (i = 0; i <= 7; i++) {
0028 fpa11->fType[i] = typeNone;
0029 }
0030
0031
0032 fpa11->fpsr = FP_EMULATOR | BIT_AC;
0033 }
0034
0035 int8 SetRoundingMode(const unsigned int opcode)
0036 {
0037 switch (opcode & MASK_ROUNDING_MODE) {
0038 default:
0039 case ROUND_TO_NEAREST:
0040 return float_round_nearest_even;
0041
0042 case ROUND_TO_PLUS_INFINITY:
0043 return float_round_up;
0044
0045 case ROUND_TO_MINUS_INFINITY:
0046 return float_round_down;
0047
0048 case ROUND_TO_ZERO:
0049 return float_round_to_zero;
0050 }
0051 }
0052
0053 int8 SetRoundingPrecision(const unsigned int opcode)
0054 {
0055 #ifdef CONFIG_FPE_NWFPE_XP
0056 switch (opcode & MASK_ROUNDING_PRECISION) {
0057 case ROUND_SINGLE:
0058 return 32;
0059
0060 case ROUND_DOUBLE:
0061 return 64;
0062
0063 case ROUND_EXTENDED:
0064 return 80;
0065
0066 default:
0067 return 80;
0068 }
0069 #endif
0070 return 80;
0071 }
0072
0073 void nwfpe_init_fpa(union fp_state *fp)
0074 {
0075 FPA11 *fpa11 = (FPA11 *)fp;
0076 #ifdef NWFPE_DEBUG
0077 printk("NWFPE: setting up state.\n");
0078 #endif
0079 memset(fpa11, 0, sizeof(FPA11));
0080 resetFPA11();
0081 fpa11->initflag = 1;
0082 }
0083
0084
0085 unsigned int EmulateAll(unsigned int opcode)
0086 {
0087 unsigned int code;
0088
0089 #ifdef NWFPE_DEBUG
0090 printk("NWFPE: emulating opcode %08x\n", opcode);
0091 #endif
0092 code = opcode & 0x00000f00;
0093 if (code == 0x00000100 || code == 0x00000200) {
0094
0095 code = opcode & 0x0e000000;
0096 if (code == 0x0e000000) {
0097 if (opcode & 0x00000010) {
0098
0099
0100
0101 return EmulateCPRT(opcode);
0102 } else {
0103
0104
0105 return EmulateCPDO(opcode);
0106 }
0107 } else if (code == 0x0c000000) {
0108
0109
0110 return EmulateCPDT(opcode);
0111 }
0112 }
0113
0114
0115 return 0;
0116 }