00001 /* 00002 NetWinder Floating Point Emulator 00003 (c) Rebel.COM, 1998,1999 00004 00005 Direct questions, comments to Scott Bambrough <scottb@netwinder.org> 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 2 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 */ 00021 00022 #ifndef __FPOPCODE_H__ 00023 #define __FPOPCODE_H__ 00024 00025 /* 00026 ARM Floating Point Instruction Classes 00027 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 00028 |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 00029 |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 00030 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 00031 |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 00032 |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 00033 |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 00034 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 00035 00036 CPDT data transfer instructions 00037 LDF, STF, LFM, SFM 00038 00039 CPDO dyadic arithmetic instructions 00040 ADF, MUF, SUF, RSF, DVF, RDF, 00041 POW, RPW, RMF, FML, FDV, FRD, POL 00042 00043 CPDO monadic arithmetic instructions 00044 MVF, MNF, ABS, RND, SQT, LOG, LGN, EXP, 00045 SIN, COS, TAN, ASN, ACS, ATN, URD, NRM 00046 00047 CPRT joint arithmetic/data transfer instructions 00048 FIX (arithmetic followed by load/store) 00049 FLT (load/store followed by arithmetic) 00050 CMF, CNF CMFE, CNFE (comparisons) 00051 WFS, RFS (write/read floating point status register) 00052 WFC, RFC (write/read floating point control register) 00053 00054 cond condition codes 00055 P pre/post index bit: 0 = postindex, 1 = preindex 00056 U up/down bit: 0 = stack grows down, 1 = stack grows up 00057 W write back bit: 1 = update base register (Rn) 00058 L load/store bit: 0 = store, 1 = load 00059 Rn base register 00060 Rd destination/source register 00061 Fd floating point destination register 00062 Fn floating point source register 00063 Fm floating point source register or floating point constant 00064 00065 uv transfer length (TABLE 1) 00066 wx register count (TABLE 2) 00067 abcd arithmetic opcode (TABLES 3 & 4) 00068 ef destination size (rounding precision) (TABLE 5) 00069 gh rounding mode (TABLE 6) 00070 j dyadic/monadic bit: 0 = dyadic, 1 = monadic 00071 i constant bit: 1 = constant (TABLE 6) 00072 */ 00073 00074 /* 00075 TABLE 1 00076 +-------------------------+---+---+---------+---------+ 00077 | Precision | u | v | FPSR.EP | length | 00078 +-------------------------+---+---+---------+---------+ 00079 | Single | 0 ü 0 | x | 1 words | 00080 | Double | 1 ü 1 | x | 2 words | 00081 | Extended | 1 ü 1 | x | 3 words | 00082 | Packed decimal | 1 ü 1 | 0 | 3 words | 00083 | Expanded packed decimal | 1 ü 1 | 1 | 4 words | 00084 +-------------------------+---+---+---------+---------+ 00085 Note: x = don't care 00086 */ 00087 00088 /* 00089 TABLE 2 00090 +---+---+---------------------------------+ 00091 | w | x | Number of registers to transfer | 00092 +---+---+---------------------------------+ 00093 | 0 ü 1 | 1 | 00094 | 1 ü 0 | 2 | 00095 | 1 ü 1 | 3 | 00096 | 0 ü 0 | 4 | 00097 +---+---+---------------------------------+ 00098 */ 00099 00100 /* 00101 TABLE 3: Dyadic Floating Point Opcodes 00102 +---+---+---+---+----------+-----------------------+-----------------------+ 00103 | a | b | c | d | Mnemonic | Description | Operation | 00104 +---+---+---+---+----------+-----------------------+-----------------------+ 00105 | 0 | 0 | 0 | 0 | ADF | Add | Fd := Fn + Fm | 00106 | 0 | 0 | 0 | 1 | MUF | Multiply | Fd := Fn * Fm | 00107 | 0 | 0 | 1 | 0 | SUF | Subtract | Fd := Fn - Fm | 00108 | 0 | 0 | 1 | 1 | RSF | Reverse subtract | Fd := Fm - Fn | 00109 | 0 | 1 | 0 | 0 | DVF | Divide | Fd := Fn / Fm | 00110 | 0 | 1 | 0 | 1 | RDF | Reverse divide | Fd := Fm / Fn | 00111 | 0 | 1 | 1 | 0 | POW | Power | Fd := Fn ^ Fm | 00112 | 0 | 1 | 1 | 1 | RPW | Reverse power | Fd := Fm ^ Fn | 00113 | 1 | 0 | 0 | 0 | RMF | Remainder | Fd := IEEE rem(Fn/Fm) | 00114 | 1 | 0 | 0 | 1 | FML | Fast Multiply | Fd := Fn * Fm | 00115 | 1 | 0 | 1 | 0 | FDV | Fast Divide | Fd := Fn / Fm | 00116 | 1 | 0 | 1 | 1 | FRD | Fast reverse divide | Fd := Fm / Fn | 00117 | 1 | 1 | 0 | 0 | POL | Polar angle (ArcTan2) | Fd := arctan2(Fn,Fm) | 00118 | 1 | 1 | 0 | 1 | | undefined instruction | trap | 00119 | 1 | 1 | 1 | 0 | | undefined instruction | trap | 00120 | 1 | 1 | 1 | 1 | | undefined instruction | trap | 00121 +---+---+---+---+----------+-----------------------+-----------------------+ 00122 Note: POW, RPW, POL are deprecated, and are available for backwards 00123 compatibility only. 00124 */ 00125 00126 /* 00127 TABLE 4: Monadic Floating Point Opcodes 00128 +---+---+---+---+----------+-----------------------+-----------------------+ 00129 | a | b | c | d | Mnemonic | Description | Operation | 00130 +---+---+---+---+----------+-----------------------+-----------------------+ 00131 | 0 | 0 | 0 | 0 | MVF | Move | Fd := Fm | 00132 | 0 | 0 | 0 | 1 | MNF | Move negated | Fd := - Fm | 00133 | 0 | 0 | 1 | 0 | ABS | Absolute value | Fd := abs(Fm) | 00134 | 0 | 0 | 1 | 1 | RND | Round to integer | Fd := int(Fm) | 00135 | 0 | 1 | 0 | 0 | SQT | Square root | Fd := sqrt(Fm) | 00136 | 0 | 1 | 0 | 1 | LOG | Log base 10 | Fd := log10(Fm) | 00137 | 0 | 1 | 1 | 0 | LGN | Log base e | Fd := ln(Fm) | 00138 | 0 | 1 | 1 | 1 | EXP | Exponent | Fd := e ^ Fm | 00139 | 1 | 0 | 0 | 0 | SIN | Sine | Fd := sin(Fm) | 00140 | 1 | 0 | 0 | 1 | COS | Cosine | Fd := cos(Fm) | 00141 | 1 | 0 | 1 | 0 | TAN | Tangent | Fd := tan(Fm) | 00142 | 1 | 0 | 1 | 1 | ASN | Arc Sine | Fd := arcsin(Fm) | 00143 | 1 | 1 | 0 | 0 | ACS | Arc Cosine | Fd := arccos(Fm) | 00144 | 1 | 1 | 0 | 1 | ATN | Arc Tangent | Fd := arctan(Fm) | 00145 | 1 | 1 | 1 | 0 | URD | Unnormalized round | Fd := int(Fm) | 00146 | 1 | 1 | 1 | 1 | NRM | Normalize | Fd := norm(Fm) | 00147 +---+---+---+---+----------+-----------------------+-----------------------+ 00148 Note: LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN are deprecated, and are 00149 available for backwards compatibility only. 00150 */ 00151 00152 /* 00153 TABLE 5 00154 +-------------------------+---+---+ 00155 | Rounding Precision | e | f | 00156 +-------------------------+---+---+ 00157 | IEEE Single precision | 0 ü 0 | 00158 | IEEE Double precision | 0 ü 1 | 00159 | IEEE Extended precision | 1 ü 0 | 00160 | undefined (trap) | 1 ü 1 | 00161 +-------------------------+---+---+ 00162 */ 00163 00164 /* 00165 TABLE 5 00166 +---------------------------------+---+---+ 00167 | Rounding Mode | g | h | 00168 +---------------------------------+---+---+ 00169 | Round to nearest (default) | 0 ü 0 | 00170 | Round toward plus infinity | 0 ü 1 | 00171 | Round toward negative infinity | 1 ü 0 | 00172 | Round toward zero | 1 ü 1 | 00173 +---------------------------------+---+---+ 00174 */ 00175 00176 /* 00177 === 00178 === Definitions for load and store instructions 00179 === 00180 */ 00181 00182 /* bit masks */ 00183 #define BIT_PREINDEX 0x01000000 00184 #define BIT_UP 0x00800000 00185 #define BIT_WRITE_BACK 0x00200000 00186 #define BIT_LOAD 0x00100000 00187 00188 /* masks for load/store */ 00189 #define MASK_CPDT 0x0c000000 /* data processing opcode */ 00190 #define MASK_OFFSET 0x000000ff 00191 #define MASK_TRANSFER_LENGTH 0x00408000 00192 #define MASK_REGISTER_COUNT MASK_TRANSFER_LENGTH 00193 #define MASK_COPROCESSOR 0x00000f00 00194 00195 /* Tests for transfer length */ 00196 #define TRANSFER_SINGLE 0x00000000 00197 #define TRANSFER_DOUBLE 0x00008000 00198 #define TRANSFER_EXTENDED 0x00400000 00199 #define TRANSFER_PACKED MASK_TRANSFER_LENGTH 00200 00201 /* Get the coprocessor number from the opcode. */ 00202 #define getCoprocessorNumber(opcode) ((opcode & MASK_COPROCESSOR) >> 8) 00203 00204 /* Get the offset from the opcode. */ 00205 #define getOffset(opcode) (opcode & MASK_OFFSET) 00206 00207 /* Tests for specific data transfer load/store opcodes. */ 00208 #define TEST_OPCODE(opcode,mask) (((opcode) & (mask)) == (mask)) 00209 00210 #define LOAD_OP(opcode) TEST_OPCODE((opcode),MASK_CPDT | BIT_LOAD) 00211 #define STORE_OP(opcode) ((opcode & (MASK_CPDT | BIT_LOAD)) == MASK_CPDT) 00212 00213 #define LDF_OP(opcode) (LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 1)) 00214 #define LFM_OP(opcode) (LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 2)) 00215 #define STF_OP(opcode) (STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 1)) 00216 #define SFM_OP(opcode) (STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 2)) 00217 00218 #define PREINDEXED(opcode) ((opcode & BIT_PREINDEX) != 0) 00219 #define POSTINDEXED(opcode) ((opcode & BIT_PREINDEX) == 0) 00220 #define BIT_UP_SET(opcode) ((opcode & BIT_UP) != 0) 00221 #define BIT_UP_CLEAR(opcode) ((opcode & BIT_DOWN) == 0) 00222 #define WRITE_BACK(opcode) ((opcode & BIT_WRITE_BACK) != 0) 00223 #define LOAD(opcode) ((opcode & BIT_LOAD) != 0) 00224 #define STORE(opcode) ((opcode & BIT_LOAD) == 0) 00225 00226 /* 00227 === 00228 === Definitions for arithmetic instructions 00229 === 00230 */ 00231 /* bit masks */ 00232 #define BIT_MONADIC 0x00008000 00233 #define BIT_CONSTANT 0x00000008 00234 00235 #define CONSTANT_FM(opcode) ((opcode & BIT_CONSTANT) != 0) 00236 #define MONADIC_INSTRUCTION(opcode) ((opcode & BIT_MONADIC) != 0) 00237 00238 /* instruction identification masks */ 00239 #define MASK_CPDO 0x0e000000 /* arithmetic opcode */ 00240 #define MASK_ARITHMETIC_OPCODE 0x00f08000 00241 #define MASK_DESTINATION_SIZE 0x00080080 00242 00243 /* dyadic arithmetic opcodes. */ 00244 #define ADF_CODE 0x00000000 00245 #define MUF_CODE 0x00100000 00246 #define SUF_CODE 0x00200000 00247 #define RSF_CODE 0x00300000 00248 #define DVF_CODE 0x00400000 00249 #define RDF_CODE 0x00500000 00250 #define POW_CODE 0x00600000 00251 #define RPW_CODE 0x00700000 00252 #define RMF_CODE 0x00800000 00253 #define FML_CODE 0x00900000 00254 #define FDV_CODE 0x00a00000 00255 #define FRD_CODE 0x00b00000 00256 #define POL_CODE 0x00c00000 00257 /* 0x00d00000 is an invalid dyadic arithmetic opcode */ 00258 /* 0x00e00000 is an invalid dyadic arithmetic opcode */ 00259 /* 0x00f00000 is an invalid dyadic arithmetic opcode */ 00260 00261 /* monadic arithmetic opcodes. */ 00262 #define MVF_CODE 0x00008000 00263 #define MNF_CODE 0x00108000 00264 #define ABS_CODE 0x00208000 00265 #define RND_CODE 0x00308000 00266 #define SQT_CODE 0x00408000 00267 #define LOG_CODE 0x00508000 00268 #define LGN_CODE 0x00608000 00269 #define EXP_CODE 0x00708000 00270 #define SIN_CODE 0x00808000 00271 #define COS_CODE 0x00908000 00272 #define TAN_CODE 0x00a08000 00273 #define ASN_CODE 0x00b08000 00274 #define ACS_CODE 0x00c08000 00275 #define ATN_CODE 0x00d08000 00276 #define URD_CODE 0x00e08000 00277 #define NRM_CODE 0x00f08000 00278 00279 /* 00280 === 00281 === Definitions for register transfer and comparison instructions 00282 === 00283 */ 00284 00285 #define MASK_CPRT 0x0e000010 /* register transfer opcode */ 00286 #define MASK_CPRT_CODE 0x00f00000 00287 #define FLT_CODE 0x00000000 00288 #define FIX_CODE 0x00100000 00289 #define WFS_CODE 0x00200000 00290 #define RFS_CODE 0x00300000 00291 #define WFC_CODE 0x00400000 00292 #define RFC_CODE 0x00500000 00293 #define CMF_CODE 0x00900000 00294 #define CNF_CODE 0x00b00000 00295 #define CMFE_CODE 0x00d00000 00296 #define CNFE_CODE 0x00f00000 00297 00298 /* 00299 === 00300 === Common definitions 00301 === 00302 */ 00303 00304 /* register masks */ 00305 #define MASK_Rd 0x0000f000 00306 #define MASK_Rn 0x000f0000 00307 #define MASK_Fd 0x00007000 00308 #define MASK_Fm 0x00000007 00309 #define MASK_Fn 0x00070000 00310 00311 /* condition code masks */ 00312 #define CC_MASK 0xf0000000 00313 #define CC_NEGATIVE 0x80000000 00314 #define CC_ZERO 0x40000000 00315 #define CC_CARRY 0x20000000 00316 #define CC_OVERFLOW 0x10000000 00317 #define CC_EQ 0x00000000 00318 #define CC_NE 0x10000000 00319 #define CC_CS 0x20000000 00320 #define CC_HS CC_CS 00321 #define CC_CC 0x30000000 00322 #define CC_LO CC_CC 00323 #define CC_MI 0x40000000 00324 #define CC_PL 0x50000000 00325 #define CC_VS 0x60000000 00326 #define CC_VC 0x70000000 00327 #define CC_HI 0x80000000 00328 #define CC_LS 0x90000000 00329 #define CC_GE 0xa0000000 00330 #define CC_LT 0xb0000000 00331 #define CC_GT 0xc0000000 00332 #define CC_LE 0xd0000000 00333 #define CC_AL 0xe0000000 00334 #define CC_NV 0xf0000000 00335 00336 /* rounding masks/values */ 00337 #define MASK_ROUNDING_MODE 0x00000060 00338 #define ROUND_TO_NEAREST 0x00000000 00339 #define ROUND_TO_PLUS_INFINITY 0x00000020 00340 #define ROUND_TO_MINUS_INFINITY 0x00000040 00341 #define ROUND_TO_ZERO 0x00000060 00342 00343 #define MASK_ROUNDING_PRECISION 0x00080080 00344 #define ROUND_SINGLE 0x00000000 00345 #define ROUND_DOUBLE 0x00000080 00346 #define ROUND_EXTENDED 0x00080000 00347 00348 /* Get the condition code from the opcode. */ 00349 #define getCondition(opcode) (opcode >> 28) 00350 00351 /* Get the source register from the opcode. */ 00352 #define getRn(opcode) ((opcode & MASK_Rn) >> 16) 00353 00354 /* Get the destination floating point register from the opcode. */ 00355 #define getFd(opcode) ((opcode & MASK_Fd) >> 12) 00356 00357 /* Get the first source floating point register from the opcode. */ 00358 #define getFn(opcode) ((opcode & MASK_Fn) >> 16) 00359 00360 /* Get the second source floating point register from the opcode. */ 00361 #define getFm(opcode) (opcode & MASK_Fm) 00362 00363 /* Get the destination register from the opcode. */ 00364 #define getRd(opcode) ((opcode & MASK_Rd) >> 12) 00365 00366 /* Get the rounding mode from the opcode. */ 00367 #define getRoundingMode(opcode) ((opcode & MASK_ROUNDING_MODE) >> 5) 00368 00369 static inline floatx80 getExtendedConstant(const unsigned int nIndex) 00370 { 00371 extern const floatx80 floatx80Constant[]; 00372 return floatx80Constant[nIndex]; 00373 } 00374 00375 static inline float64 getDoubleConstant(const unsigned int nIndex) 00376 { 00377 extern const float64 float64Constant[]; 00378 return float64Constant[nIndex]; 00379 } 00380 00381 static inline float32 getSingleConstant(const unsigned int nIndex) 00382 { 00383 extern const float32 float32Constant[]; 00384 return float32Constant[nIndex]; 00385 } 00386 00387 extern unsigned int getRegisterCount(const unsigned int opcode); 00388 extern unsigned int getDestinationSize(const unsigned int opcode); 00389 00390 #endif