Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* |
| 2 | NetWinder Floating Point Emulator |
| 3 | (c) Rebel.COM, 1998,1999 |
| 4 | (c) Philip Blundell, 2001 |
| 5 | |
| 6 | Direct questions, comments to Scott Bambrough <scottb@netwinder.org> |
| 7 | |
| 8 | This program is free software; you can redistribute it and/or modify |
| 9 | it under the terms of the GNU General Public License as published by |
| 10 | the Free Software Foundation; either version 2 of the License, or |
| 11 | (at your option) any later version. |
| 12 | |
| 13 | This program is distributed in the hope that it will be useful, |
| 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | GNU General Public License for more details. |
| 17 | |
| 18 | You should have received a copy of the GNU General Public License |
| 19 | along with this program; if not, write to the Free Software |
| 20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 21 | */ |
| 22 | |
| 23 | #ifndef __FPOPCODE_H__ |
| 24 | #define __FPOPCODE_H__ |
| 25 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 26 | |
| 27 | /* |
| 28 | ARM Floating Point Instruction Classes |
| 29 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| 30 | |c o n d|1 1 0 P|U|u|W|L| Rn |v| Fd |0|0|0|1| o f f s e t | CPDT |
| 31 | |c o n d|1 1 0 P|U|w|W|L| Rn |x| Fd |0|0|1|0| o f f s e t | CPDT (copro 2) |
| 32 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| 33 | |c o n d|1 1 1 0|a|b|c|d|e| Fn |j| Fd |0|0|0|1|f|g|h|0|i| Fm | CPDO |
| 34 | |c o n d|1 1 1 0|a|b|c|L|e| Fn | Rd |0|0|0|1|f|g|h|1|i| Fm | CPRT |
| 35 | |c o n d|1 1 1 0|a|b|c|1|e| Fn |1|1|1|1|0|0|0|1|f|g|h|1|i| Fm | comparisons |
| 36 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| 37 | |
| 38 | CPDT data transfer instructions |
| 39 | LDF, STF, LFM (copro 2), SFM (copro 2) |
| 40 | |
| 41 | CPDO dyadic arithmetic instructions |
| 42 | ADF, MUF, SUF, RSF, DVF, RDF, |
| 43 | POW, RPW, RMF, FML, FDV, FRD, POL |
| 44 | |
| 45 | CPDO monadic arithmetic instructions |
| 46 | MVF, MNF, ABS, RND, SQT, LOG, LGN, EXP, |
| 47 | SIN, COS, TAN, ASN, ACS, ATN, URD, NRM |
| 48 | |
| 49 | CPRT joint arithmetic/data transfer instructions |
| 50 | FIX (arithmetic followed by load/store) |
| 51 | FLT (load/store followed by arithmetic) |
| 52 | CMF, CNF CMFE, CNFE (comparisons) |
| 53 | WFS, RFS (write/read floating point status register) |
| 54 | WFC, RFC (write/read floating point control register) |
| 55 | |
| 56 | cond condition codes |
| 57 | P pre/post index bit: 0 = postindex, 1 = preindex |
| 58 | U up/down bit: 0 = stack grows down, 1 = stack grows up |
| 59 | W write back bit: 1 = update base register (Rn) |
| 60 | L load/store bit: 0 = store, 1 = load |
| 61 | Rn base register |
| 62 | Rd destination/source register |
| 63 | Fd floating point destination register |
| 64 | Fn floating point source register |
| 65 | Fm floating point source register or floating point constant |
| 66 | |
| 67 | uv transfer length (TABLE 1) |
| 68 | wx register count (TABLE 2) |
| 69 | abcd arithmetic opcode (TABLES 3 & 4) |
| 70 | ef destination size (rounding precision) (TABLE 5) |
| 71 | gh rounding mode (TABLE 6) |
| 72 | j dyadic/monadic bit: 0 = dyadic, 1 = monadic |
| 73 | i constant bit: 1 = constant (TABLE 6) |
| 74 | */ |
| 75 | |
| 76 | /* |
| 77 | TABLE 1 |
| 78 | +-------------------------+---+---+---------+---------+ |
| 79 | | Precision | u | v | FPSR.EP | length | |
| 80 | +-------------------------+---+---+---------+---------+ |
Jan Engelhardt | 96de0e2 | 2007-10-19 23:21:04 +0200 | [diff] [blame] | 81 | | Single | 0 | 0 | x | 1 words | |
| 82 | | Double | 1 | 1 | x | 2 words | |
| 83 | | Extended | 1 | 1 | x | 3 words | |
| 84 | | Packed decimal | 1 | 1 | 0 | 3 words | |
| 85 | | Expanded packed decimal | 1 | 1 | 1 | 4 words | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 86 | +-------------------------+---+---+---------+---------+ |
| 87 | Note: x = don't care |
| 88 | */ |
| 89 | |
| 90 | /* |
| 91 | TABLE 2 |
| 92 | +---+---+---------------------------------+ |
| 93 | | w | x | Number of registers to transfer | |
| 94 | +---+---+---------------------------------+ |
Jan Engelhardt | 96de0e2 | 2007-10-19 23:21:04 +0200 | [diff] [blame] | 95 | | 0 | 1 | 1 | |
| 96 | | 1 | 0 | 2 | |
| 97 | | 1 | 1 | 3 | |
| 98 | | 0 | 0 | 4 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 99 | +---+---+---------------------------------+ |
| 100 | */ |
| 101 | |
| 102 | /* |
| 103 | TABLE 3: Dyadic Floating Point Opcodes |
| 104 | +---+---+---+---+----------+-----------------------+-----------------------+ |
| 105 | | a | b | c | d | Mnemonic | Description | Operation | |
| 106 | +---+---+---+---+----------+-----------------------+-----------------------+ |
| 107 | | 0 | 0 | 0 | 0 | ADF | Add | Fd := Fn + Fm | |
| 108 | | 0 | 0 | 0 | 1 | MUF | Multiply | Fd := Fn * Fm | |
| 109 | | 0 | 0 | 1 | 0 | SUF | Subtract | Fd := Fn - Fm | |
| 110 | | 0 | 0 | 1 | 1 | RSF | Reverse subtract | Fd := Fm - Fn | |
| 111 | | 0 | 1 | 0 | 0 | DVF | Divide | Fd := Fn / Fm | |
| 112 | | 0 | 1 | 0 | 1 | RDF | Reverse divide | Fd := Fm / Fn | |
| 113 | | 0 | 1 | 1 | 0 | POW | Power | Fd := Fn ^ Fm | |
| 114 | | 0 | 1 | 1 | 1 | RPW | Reverse power | Fd := Fm ^ Fn | |
| 115 | | 1 | 0 | 0 | 0 | RMF | Remainder | Fd := IEEE rem(Fn/Fm) | |
| 116 | | 1 | 0 | 0 | 1 | FML | Fast Multiply | Fd := Fn * Fm | |
| 117 | | 1 | 0 | 1 | 0 | FDV | Fast Divide | Fd := Fn / Fm | |
| 118 | | 1 | 0 | 1 | 1 | FRD | Fast reverse divide | Fd := Fm / Fn | |
| 119 | | 1 | 1 | 0 | 0 | POL | Polar angle (ArcTan2) | Fd := arctan2(Fn,Fm) | |
| 120 | | 1 | 1 | 0 | 1 | | undefined instruction | trap | |
| 121 | | 1 | 1 | 1 | 0 | | undefined instruction | trap | |
| 122 | | 1 | 1 | 1 | 1 | | undefined instruction | trap | |
| 123 | +---+---+---+---+----------+-----------------------+-----------------------+ |
| 124 | Note: POW, RPW, POL are deprecated, and are available for backwards |
| 125 | compatibility only. |
| 126 | */ |
| 127 | |
| 128 | /* |
| 129 | TABLE 4: Monadic Floating Point Opcodes |
| 130 | +---+---+---+---+----------+-----------------------+-----------------------+ |
| 131 | | a | b | c | d | Mnemonic | Description | Operation | |
| 132 | +---+---+---+---+----------+-----------------------+-----------------------+ |
| 133 | | 0 | 0 | 0 | 0 | MVF | Move | Fd := Fm | |
| 134 | | 0 | 0 | 0 | 1 | MNF | Move negated | Fd := - Fm | |
| 135 | | 0 | 0 | 1 | 0 | ABS | Absolute value | Fd := abs(Fm) | |
| 136 | | 0 | 0 | 1 | 1 | RND | Round to integer | Fd := int(Fm) | |
| 137 | | 0 | 1 | 0 | 0 | SQT | Square root | Fd := sqrt(Fm) | |
| 138 | | 0 | 1 | 0 | 1 | LOG | Log base 10 | Fd := log10(Fm) | |
| 139 | | 0 | 1 | 1 | 0 | LGN | Log base e | Fd := ln(Fm) | |
| 140 | | 0 | 1 | 1 | 1 | EXP | Exponent | Fd := e ^ Fm | |
| 141 | | 1 | 0 | 0 | 0 | SIN | Sine | Fd := sin(Fm) | |
| 142 | | 1 | 0 | 0 | 1 | COS | Cosine | Fd := cos(Fm) | |
| 143 | | 1 | 0 | 1 | 0 | TAN | Tangent | Fd := tan(Fm) | |
| 144 | | 1 | 0 | 1 | 1 | ASN | Arc Sine | Fd := arcsin(Fm) | |
| 145 | | 1 | 1 | 0 | 0 | ACS | Arc Cosine | Fd := arccos(Fm) | |
| 146 | | 1 | 1 | 0 | 1 | ATN | Arc Tangent | Fd := arctan(Fm) | |
| 147 | | 1 | 1 | 1 | 0 | URD | Unnormalized round | Fd := int(Fm) | |
| 148 | | 1 | 1 | 1 | 1 | NRM | Normalize | Fd := norm(Fm) | |
| 149 | +---+---+---+---+----------+-----------------------+-----------------------+ |
| 150 | Note: LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN are deprecated, and are |
| 151 | available for backwards compatibility only. |
| 152 | */ |
| 153 | |
| 154 | /* |
| 155 | TABLE 5 |
| 156 | +-------------------------+---+---+ |
| 157 | | Rounding Precision | e | f | |
| 158 | +-------------------------+---+---+ |
Jan Engelhardt | 96de0e2 | 2007-10-19 23:21:04 +0200 | [diff] [blame] | 159 | | IEEE Single precision | 0 | 0 | |
| 160 | | IEEE Double precision | 0 | 1 | |
| 161 | | IEEE Extended precision | 1 | 0 | |
| 162 | | undefined (trap) | 1 | 1 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 163 | +-------------------------+---+---+ |
| 164 | */ |
| 165 | |
| 166 | /* |
| 167 | TABLE 5 |
| 168 | +---------------------------------+---+---+ |
| 169 | | Rounding Mode | g | h | |
| 170 | +---------------------------------+---+---+ |
Jan Engelhardt | 96de0e2 | 2007-10-19 23:21:04 +0200 | [diff] [blame] | 171 | | Round to nearest (default) | 0 | 0 | |
| 172 | | Round toward plus infinity | 0 | 1 | |
| 173 | | Round toward negative infinity | 1 | 0 | |
| 174 | | Round toward zero | 1 | 1 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 175 | +---------------------------------+---+---+ |
| 176 | */ |
| 177 | |
| 178 | /* |
| 179 | === |
| 180 | === Definitions for load and store instructions |
| 181 | === |
| 182 | */ |
| 183 | |
| 184 | /* bit masks */ |
| 185 | #define BIT_PREINDEX 0x01000000 |
| 186 | #define BIT_UP 0x00800000 |
| 187 | #define BIT_WRITE_BACK 0x00200000 |
| 188 | #define BIT_LOAD 0x00100000 |
| 189 | |
| 190 | /* masks for load/store */ |
| 191 | #define MASK_CPDT 0x0c000000 /* data processing opcode */ |
| 192 | #define MASK_OFFSET 0x000000ff |
| 193 | #define MASK_TRANSFER_LENGTH 0x00408000 |
| 194 | #define MASK_REGISTER_COUNT MASK_TRANSFER_LENGTH |
| 195 | #define MASK_COPROCESSOR 0x00000f00 |
| 196 | |
| 197 | /* Tests for transfer length */ |
| 198 | #define TRANSFER_SINGLE 0x00000000 |
| 199 | #define TRANSFER_DOUBLE 0x00008000 |
| 200 | #define TRANSFER_EXTENDED 0x00400000 |
| 201 | #define TRANSFER_PACKED MASK_TRANSFER_LENGTH |
| 202 | |
| 203 | /* Get the coprocessor number from the opcode. */ |
| 204 | #define getCoprocessorNumber(opcode) ((opcode & MASK_COPROCESSOR) >> 8) |
| 205 | |
| 206 | /* Get the offset from the opcode. */ |
| 207 | #define getOffset(opcode) (opcode & MASK_OFFSET) |
| 208 | |
| 209 | /* Tests for specific data transfer load/store opcodes. */ |
| 210 | #define TEST_OPCODE(opcode,mask) (((opcode) & (mask)) == (mask)) |
| 211 | |
| 212 | #define LOAD_OP(opcode) TEST_OPCODE((opcode),MASK_CPDT | BIT_LOAD) |
| 213 | #define STORE_OP(opcode) ((opcode & (MASK_CPDT | BIT_LOAD)) == MASK_CPDT) |
| 214 | |
| 215 | #define LDF_OP(opcode) (LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 1)) |
| 216 | #define LFM_OP(opcode) (LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 2)) |
| 217 | #define STF_OP(opcode) (STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 1)) |
| 218 | #define SFM_OP(opcode) (STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 2)) |
| 219 | |
| 220 | #define PREINDEXED(opcode) ((opcode & BIT_PREINDEX) != 0) |
| 221 | #define POSTINDEXED(opcode) ((opcode & BIT_PREINDEX) == 0) |
| 222 | #define BIT_UP_SET(opcode) ((opcode & BIT_UP) != 0) |
| 223 | #define BIT_UP_CLEAR(opcode) ((opcode & BIT_DOWN) == 0) |
| 224 | #define WRITE_BACK(opcode) ((opcode & BIT_WRITE_BACK) != 0) |
| 225 | #define LOAD(opcode) ((opcode & BIT_LOAD) != 0) |
| 226 | #define STORE(opcode) ((opcode & BIT_LOAD) == 0) |
| 227 | |
| 228 | /* |
| 229 | === |
| 230 | === Definitions for arithmetic instructions |
| 231 | === |
| 232 | */ |
| 233 | /* bit masks */ |
| 234 | #define BIT_MONADIC 0x00008000 |
| 235 | #define BIT_CONSTANT 0x00000008 |
| 236 | |
| 237 | #define CONSTANT_FM(opcode) ((opcode & BIT_CONSTANT) != 0) |
| 238 | #define MONADIC_INSTRUCTION(opcode) ((opcode & BIT_MONADIC) != 0) |
| 239 | |
| 240 | /* instruction identification masks */ |
| 241 | #define MASK_CPDO 0x0e000000 /* arithmetic opcode */ |
| 242 | #define MASK_ARITHMETIC_OPCODE 0x00f08000 |
| 243 | #define MASK_DESTINATION_SIZE 0x00080080 |
| 244 | |
| 245 | /* dyadic arithmetic opcodes. */ |
| 246 | #define ADF_CODE 0x00000000 |
| 247 | #define MUF_CODE 0x00100000 |
| 248 | #define SUF_CODE 0x00200000 |
| 249 | #define RSF_CODE 0x00300000 |
| 250 | #define DVF_CODE 0x00400000 |
| 251 | #define RDF_CODE 0x00500000 |
| 252 | #define POW_CODE 0x00600000 |
| 253 | #define RPW_CODE 0x00700000 |
| 254 | #define RMF_CODE 0x00800000 |
| 255 | #define FML_CODE 0x00900000 |
| 256 | #define FDV_CODE 0x00a00000 |
| 257 | #define FRD_CODE 0x00b00000 |
| 258 | #define POL_CODE 0x00c00000 |
| 259 | /* 0x00d00000 is an invalid dyadic arithmetic opcode */ |
| 260 | /* 0x00e00000 is an invalid dyadic arithmetic opcode */ |
| 261 | /* 0x00f00000 is an invalid dyadic arithmetic opcode */ |
| 262 | |
| 263 | /* monadic arithmetic opcodes. */ |
| 264 | #define MVF_CODE 0x00008000 |
| 265 | #define MNF_CODE 0x00108000 |
| 266 | #define ABS_CODE 0x00208000 |
| 267 | #define RND_CODE 0x00308000 |
| 268 | #define SQT_CODE 0x00408000 |
| 269 | #define LOG_CODE 0x00508000 |
| 270 | #define LGN_CODE 0x00608000 |
| 271 | #define EXP_CODE 0x00708000 |
| 272 | #define SIN_CODE 0x00808000 |
| 273 | #define COS_CODE 0x00908000 |
| 274 | #define TAN_CODE 0x00a08000 |
| 275 | #define ASN_CODE 0x00b08000 |
| 276 | #define ACS_CODE 0x00c08000 |
| 277 | #define ATN_CODE 0x00d08000 |
| 278 | #define URD_CODE 0x00e08000 |
| 279 | #define NRM_CODE 0x00f08000 |
| 280 | |
| 281 | /* |
| 282 | === |
| 283 | === Definitions for register transfer and comparison instructions |
| 284 | === |
| 285 | */ |
| 286 | |
| 287 | #define MASK_CPRT 0x0e000010 /* register transfer opcode */ |
| 288 | #define MASK_CPRT_CODE 0x00f00000 |
| 289 | #define FLT_CODE 0x00000000 |
| 290 | #define FIX_CODE 0x00100000 |
| 291 | #define WFS_CODE 0x00200000 |
| 292 | #define RFS_CODE 0x00300000 |
| 293 | #define WFC_CODE 0x00400000 |
| 294 | #define RFC_CODE 0x00500000 |
| 295 | #define CMF_CODE 0x00900000 |
| 296 | #define CNF_CODE 0x00b00000 |
| 297 | #define CMFE_CODE 0x00d00000 |
| 298 | #define CNFE_CODE 0x00f00000 |
| 299 | |
| 300 | /* |
| 301 | === |
| 302 | === Common definitions |
| 303 | === |
| 304 | */ |
| 305 | |
| 306 | /* register masks */ |
| 307 | #define MASK_Rd 0x0000f000 |
| 308 | #define MASK_Rn 0x000f0000 |
| 309 | #define MASK_Fd 0x00007000 |
| 310 | #define MASK_Fm 0x00000007 |
| 311 | #define MASK_Fn 0x00070000 |
| 312 | |
| 313 | /* condition code masks */ |
| 314 | #define CC_MASK 0xf0000000 |
| 315 | #define CC_NEGATIVE 0x80000000 |
| 316 | #define CC_ZERO 0x40000000 |
| 317 | #define CC_CARRY 0x20000000 |
| 318 | #define CC_OVERFLOW 0x10000000 |
| 319 | #define CC_EQ 0x00000000 |
| 320 | #define CC_NE 0x10000000 |
| 321 | #define CC_CS 0x20000000 |
| 322 | #define CC_HS CC_CS |
| 323 | #define CC_CC 0x30000000 |
| 324 | #define CC_LO CC_CC |
| 325 | #define CC_MI 0x40000000 |
| 326 | #define CC_PL 0x50000000 |
| 327 | #define CC_VS 0x60000000 |
| 328 | #define CC_VC 0x70000000 |
| 329 | #define CC_HI 0x80000000 |
| 330 | #define CC_LS 0x90000000 |
| 331 | #define CC_GE 0xa0000000 |
| 332 | #define CC_LT 0xb0000000 |
| 333 | #define CC_GT 0xc0000000 |
| 334 | #define CC_LE 0xd0000000 |
| 335 | #define CC_AL 0xe0000000 |
| 336 | #define CC_NV 0xf0000000 |
| 337 | |
| 338 | /* rounding masks/values */ |
| 339 | #define MASK_ROUNDING_MODE 0x00000060 |
| 340 | #define ROUND_TO_NEAREST 0x00000000 |
| 341 | #define ROUND_TO_PLUS_INFINITY 0x00000020 |
| 342 | #define ROUND_TO_MINUS_INFINITY 0x00000040 |
| 343 | #define ROUND_TO_ZERO 0x00000060 |
| 344 | |
| 345 | #define MASK_ROUNDING_PRECISION 0x00080080 |
| 346 | #define ROUND_SINGLE 0x00000000 |
| 347 | #define ROUND_DOUBLE 0x00000080 |
| 348 | #define ROUND_EXTENDED 0x00080000 |
| 349 | |
| 350 | /* Get the condition code from the opcode. */ |
| 351 | #define getCondition(opcode) (opcode >> 28) |
| 352 | |
| 353 | /* Get the source register from the opcode. */ |
| 354 | #define getRn(opcode) ((opcode & MASK_Rn) >> 16) |
| 355 | |
| 356 | /* Get the destination floating point register from the opcode. */ |
| 357 | #define getFd(opcode) ((opcode & MASK_Fd) >> 12) |
| 358 | |
| 359 | /* Get the first source floating point register from the opcode. */ |
| 360 | #define getFn(opcode) ((opcode & MASK_Fn) >> 16) |
| 361 | |
| 362 | /* Get the second source floating point register from the opcode. */ |
| 363 | #define getFm(opcode) (opcode & MASK_Fm) |
| 364 | |
| 365 | /* Get the destination register from the opcode. */ |
| 366 | #define getRd(opcode) ((opcode & MASK_Rd) >> 12) |
| 367 | |
| 368 | /* Get the rounding mode from the opcode. */ |
| 369 | #define getRoundingMode(opcode) ((opcode & MASK_ROUNDING_MODE) >> 5) |
| 370 | |
| 371 | #ifdef CONFIG_FPE_NWFPE_XP |
Ralf Baechle | e8c4431 | 2007-10-18 03:07:07 -0700 | [diff] [blame] | 372 | static inline floatx80 __pure getExtendedConstant(const unsigned int nIndex) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 373 | { |
| 374 | extern const floatx80 floatx80Constant[]; |
| 375 | return floatx80Constant[nIndex]; |
| 376 | } |
| 377 | #endif |
| 378 | |
Ralf Baechle | e8c4431 | 2007-10-18 03:07:07 -0700 | [diff] [blame] | 379 | static inline float64 __pure getDoubleConstant(const unsigned int nIndex) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 380 | { |
| 381 | extern const float64 float64Constant[]; |
| 382 | return float64Constant[nIndex]; |
| 383 | } |
| 384 | |
Ralf Baechle | e8c4431 | 2007-10-18 03:07:07 -0700 | [diff] [blame] | 385 | static inline float32 __pure getSingleConstant(const unsigned int nIndex) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 386 | { |
| 387 | extern const float32 float32Constant[]; |
| 388 | return float32Constant[nIndex]; |
| 389 | } |
| 390 | |
| 391 | static inline unsigned int getTransferLength(const unsigned int opcode) |
| 392 | { |
| 393 | unsigned int nRc; |
| 394 | |
| 395 | switch (opcode & MASK_TRANSFER_LENGTH) { |
| 396 | case 0x00000000: |
| 397 | nRc = 1; |
| 398 | break; /* single precision */ |
| 399 | case 0x00008000: |
| 400 | nRc = 2; |
| 401 | break; /* double precision */ |
| 402 | case 0x00400000: |
| 403 | nRc = 3; |
| 404 | break; /* extended precision */ |
| 405 | default: |
| 406 | nRc = 0; |
| 407 | } |
| 408 | |
| 409 | return (nRc); |
| 410 | } |
| 411 | |
| 412 | static inline unsigned int getRegisterCount(const unsigned int opcode) |
| 413 | { |
| 414 | unsigned int nRc; |
| 415 | |
| 416 | switch (opcode & MASK_REGISTER_COUNT) { |
| 417 | case 0x00000000: |
| 418 | nRc = 4; |
| 419 | break; |
| 420 | case 0x00008000: |
| 421 | nRc = 1; |
| 422 | break; |
| 423 | case 0x00400000: |
| 424 | nRc = 2; |
| 425 | break; |
| 426 | case 0x00408000: |
| 427 | nRc = 3; |
| 428 | break; |
| 429 | default: |
| 430 | nRc = 0; |
| 431 | } |
| 432 | |
| 433 | return (nRc); |
| 434 | } |
| 435 | |
| 436 | static inline unsigned int getRoundingPrecision(const unsigned int opcode) |
| 437 | { |
| 438 | unsigned int nRc; |
| 439 | |
| 440 | switch (opcode & MASK_ROUNDING_PRECISION) { |
| 441 | case 0x00000000: |
| 442 | nRc = 1; |
| 443 | break; |
| 444 | case 0x00000080: |
| 445 | nRc = 2; |
| 446 | break; |
| 447 | case 0x00080000: |
| 448 | nRc = 3; |
| 449 | break; |
| 450 | default: |
| 451 | nRc = 0; |
| 452 | } |
| 453 | |
| 454 | return (nRc); |
| 455 | } |
| 456 | |
| 457 | static inline unsigned int getDestinationSize(const unsigned int opcode) |
| 458 | { |
| 459 | unsigned int nRc; |
| 460 | |
| 461 | switch (opcode & MASK_DESTINATION_SIZE) { |
| 462 | case 0x00000000: |
| 463 | nRc = typeSingle; |
| 464 | break; |
| 465 | case 0x00000080: |
| 466 | nRc = typeDouble; |
| 467 | break; |
| 468 | case 0x00080000: |
| 469 | nRc = typeExtended; |
| 470 | break; |
| 471 | default: |
| 472 | nRc = typeNone; |
| 473 | } |
| 474 | |
| 475 | return (nRc); |
| 476 | } |
| 477 | |
Ben Dooks | 6ec5e7f | 2005-10-12 19:58:10 +0100 | [diff] [blame] | 478 | extern unsigned int checkCondition(const unsigned int opcode, |
| 479 | const unsigned int ccodes); |
| 480 | |
| 481 | extern const float64 float64Constant[]; |
| 482 | extern const float32 float32Constant[]; |
| 483 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 484 | #endif |