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