Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | /* NetWinder Floating Point Emulator (c) Rebel.COM, 1998,1999 Direct questions, comments to Scott Bambrough <scottb@netwinder.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "fpa11.h" #include "softfloat.h" #include "fpopcode.h" #include "fpsr.h" #include "fpmodule.h" #include "fpmodule.inl" const floatx80 floatx80Constant[] = { { 0x0000, 0x0000000000000000ULL}, /* extended 0.0 */ { 0x3fff, 0x8000000000000000ULL}, /* extended 1.0 */ { 0x4000, 0x8000000000000000ULL}, /* extended 2.0 */ { 0x4000, 0xc000000000000000ULL}, /* extended 3.0 */ { 0x4001, 0x8000000000000000ULL}, /* extended 4.0 */ { 0x4001, 0xa000000000000000ULL}, /* extended 5.0 */ { 0x3ffe, 0x8000000000000000ULL}, /* extended 0.5 */ { 0x4002, 0xa000000000000000ULL} /* extended 10.0 */ }; const float64 float64Constant[] = { 0x0000000000000000ULL, /* double 0.0 */ 0x3ff0000000000000ULL, /* double 1.0 */ 0x4000000000000000ULL, /* double 2.0 */ 0x4008000000000000ULL, /* double 3.0 */ 0x4010000000000000ULL, /* double 4.0 */ 0x4014000000000000ULL, /* double 5.0 */ 0x3fe0000000000000ULL, /* double 0.5 */ 0x4024000000000000ULL /* double 10.0 */ }; const float32 float32Constant[] = { 0x00000000, /* single 0.0 */ 0x3f800000, /* single 1.0 */ 0x40000000, /* single 2.0 */ 0x40400000, /* single 3.0 */ 0x40800000, /* single 4.0 */ 0x40a00000, /* single 5.0 */ 0x3f000000, /* single 0.5 */ 0x41200000 /* single 10.0 */ }; unsigned int getTransferLength(const unsigned int opcode) { unsigned int nRc; switch (opcode & MASK_TRANSFER_LENGTH) { case 0x00000000: nRc = 1; break; /* single precision */ case 0x00008000: nRc = 2; break; /* double precision */ case 0x00400000: nRc = 3; break; /* extended precision */ default: nRc = 0; } return(nRc); } unsigned int getRegisterCount(const unsigned int opcode) { unsigned int nRc; switch (opcode & MASK_REGISTER_COUNT) { case 0x00000000: nRc = 4; break; case 0x00008000: nRc = 1; break; case 0x00400000: nRc = 2; break; case 0x00408000: nRc = 3; break; default: nRc = 0; } return(nRc); } unsigned int getRoundingPrecision(const unsigned int opcode) { unsigned int nRc; switch (opcode & MASK_ROUNDING_PRECISION) { case 0x00000000: nRc = 1; break; case 0x00000080: nRc = 2; break; case 0x00080000: nRc = 3; break; default: nRc = 0; } return(nRc); } unsigned int getDestinationSize(const unsigned int opcode) { unsigned int nRc; switch (opcode & MASK_DESTINATION_SIZE) { case 0x00000000: nRc = typeSingle; break; case 0x00000080: nRc = typeDouble; break; case 0x00080000: nRc = typeExtended; break; default: nRc = typeNone; } return(nRc); } /* condition code lookup table index into the table is test code: EQ, NE, ... LT, GT, AL, NV bit position in short is condition code: NZCV */ static const unsigned short aCC[16] = { 0xF0F0, // EQ == Z set 0x0F0F, // NE 0xCCCC, // CS == C set 0x3333, // CC 0xFF00, // MI == N set 0x00FF, // PL 0xAAAA, // VS == V set 0x5555, // VC 0x0C0C, // HI == C set && Z clear 0xF3F3, // LS == C clear || Z set 0xAA55, // GE == (N==V) 0x55AA, // LT == (N!=V) 0x0A05, // GT == (!Z && (N==V)) 0xF5FA, // LE == (Z || (N!=V)) 0xFFFF, // AL always 0 // NV }; unsigned int checkCondition(const unsigned int opcode, const unsigned int ccodes) { return (aCC[opcode>>28] >> (ccodes>>28)) & 1; } |