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