xref: /openbmc/linux/arch/arm/nwfpe/fpopcode.h (revision e8c44319c691dfb4a0b039b095204c040df9b01a)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds     NetWinder Floating Point Emulator
31da177e4SLinus Torvalds     (c) Rebel.COM, 1998,1999
41da177e4SLinus Torvalds     (c) Philip Blundell, 2001
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds     This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds     it under the terms of the GNU General Public License as published by
101da177e4SLinus Torvalds     the Free Software Foundation; either version 2 of the License, or
111da177e4SLinus Torvalds     (at your option) any later version.
121da177e4SLinus Torvalds 
131da177e4SLinus Torvalds     This program is distributed in the hope that it will be useful,
141da177e4SLinus Torvalds     but WITHOUT ANY WARRANTY; without even the implied warranty of
151da177e4SLinus Torvalds     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
161da177e4SLinus Torvalds     GNU General Public License for more details.
171da177e4SLinus Torvalds 
181da177e4SLinus Torvalds     You should have received a copy of the GNU General Public License
191da177e4SLinus Torvalds     along with this program; if not, write to the Free Software
201da177e4SLinus Torvalds     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
211da177e4SLinus Torvalds */
221da177e4SLinus Torvalds 
231da177e4SLinus Torvalds #ifndef __FPOPCODE_H__
241da177e4SLinus Torvalds #define __FPOPCODE_H__
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds 
271da177e4SLinus Torvalds /*
281da177e4SLinus Torvalds ARM Floating Point Instruction Classes
291da177e4SLinus Torvalds | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
301da177e4SLinus 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
311da177e4SLinus 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)
321da177e4SLinus Torvalds | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
331da177e4SLinus 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
341da177e4SLinus 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
351da177e4SLinus 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
361da177e4SLinus Torvalds | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
371da177e4SLinus Torvalds 
381da177e4SLinus Torvalds CPDT		data transfer instructions
391da177e4SLinus Torvalds 		LDF, STF, LFM (copro 2), SFM (copro 2)
401da177e4SLinus Torvalds 
411da177e4SLinus Torvalds CPDO		dyadic arithmetic instructions
421da177e4SLinus Torvalds 		ADF, MUF, SUF, RSF, DVF, RDF,
431da177e4SLinus Torvalds 		POW, RPW, RMF, FML, FDV, FRD, POL
441da177e4SLinus Torvalds 
451da177e4SLinus Torvalds CPDO		monadic arithmetic instructions
461da177e4SLinus Torvalds 		MVF, MNF, ABS, RND, SQT, LOG, LGN, EXP,
471da177e4SLinus Torvalds 		SIN, COS, TAN, ASN, ACS, ATN, URD, NRM
481da177e4SLinus Torvalds 
491da177e4SLinus Torvalds CPRT		joint arithmetic/data transfer instructions
501da177e4SLinus Torvalds 		FIX (arithmetic followed by load/store)
511da177e4SLinus Torvalds 		FLT (load/store followed by arithmetic)
521da177e4SLinus Torvalds 		CMF, CNF CMFE, CNFE (comparisons)
531da177e4SLinus Torvalds 		WFS, RFS (write/read floating point status register)
541da177e4SLinus Torvalds 		WFC, RFC (write/read floating point control register)
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds cond		condition codes
571da177e4SLinus Torvalds P		pre/post index bit: 0 = postindex, 1 = preindex
581da177e4SLinus Torvalds U		up/down bit: 0 = stack grows down, 1 = stack grows up
591da177e4SLinus Torvalds W		write back bit: 1 = update base register (Rn)
601da177e4SLinus Torvalds L		load/store bit: 0 = store, 1 = load
611da177e4SLinus Torvalds Rn		base register
621da177e4SLinus Torvalds Rd		destination/source register
631da177e4SLinus Torvalds Fd		floating point destination register
641da177e4SLinus Torvalds Fn		floating point source register
651da177e4SLinus Torvalds Fm		floating point source register or floating point constant
661da177e4SLinus Torvalds 
671da177e4SLinus Torvalds uv		transfer length (TABLE 1)
681da177e4SLinus Torvalds wx		register count (TABLE 2)
691da177e4SLinus Torvalds abcd		arithmetic opcode (TABLES 3 & 4)
701da177e4SLinus Torvalds ef		destination size (rounding precision) (TABLE 5)
711da177e4SLinus Torvalds gh		rounding mode (TABLE 6)
721da177e4SLinus Torvalds j		dyadic/monadic bit: 0 = dyadic, 1 = monadic
731da177e4SLinus Torvalds i 		constant bit: 1 = constant (TABLE 6)
741da177e4SLinus Torvalds */
751da177e4SLinus Torvalds 
761da177e4SLinus Torvalds /*
771da177e4SLinus Torvalds TABLE 1
781da177e4SLinus Torvalds +-------------------------+---+---+---------+---------+
791da177e4SLinus Torvalds |  Precision              | u | v | FPSR.EP | length  |
801da177e4SLinus Torvalds +-------------------------+---+---+---------+---------+
811da177e4SLinus Torvalds | Single                  | 0 � 0 |    x    | 1 words |
821da177e4SLinus Torvalds | Double                  | 1 � 1 |    x    | 2 words |
831da177e4SLinus Torvalds | Extended                | 1 � 1 |    x    | 3 words |
841da177e4SLinus Torvalds | Packed decimal          | 1 � 1 |    0    | 3 words |
851da177e4SLinus Torvalds | Expanded packed decimal | 1 � 1 |    1    | 4 words |
861da177e4SLinus Torvalds +-------------------------+---+---+---------+---------+
871da177e4SLinus Torvalds Note: x = don't care
881da177e4SLinus Torvalds */
891da177e4SLinus Torvalds 
901da177e4SLinus Torvalds /*
911da177e4SLinus Torvalds TABLE 2
921da177e4SLinus Torvalds +---+---+---------------------------------+
931da177e4SLinus Torvalds | w | x | Number of registers to transfer |
941da177e4SLinus Torvalds +---+---+---------------------------------+
951da177e4SLinus Torvalds | 0 � 1 |  1                              |
961da177e4SLinus Torvalds | 1 � 0 |  2                              |
971da177e4SLinus Torvalds | 1 � 1 |  3                              |
981da177e4SLinus Torvalds | 0 � 0 |  4                              |
991da177e4SLinus Torvalds +---+---+---------------------------------+
1001da177e4SLinus Torvalds */
1011da177e4SLinus Torvalds 
1021da177e4SLinus Torvalds /*
1031da177e4SLinus Torvalds TABLE 3: Dyadic Floating Point Opcodes
1041da177e4SLinus Torvalds +---+---+---+---+----------+-----------------------+-----------------------+
1051da177e4SLinus Torvalds | a | b | c | d | Mnemonic | Description           | Operation             |
1061da177e4SLinus Torvalds +---+---+---+---+----------+-----------------------+-----------------------+
1071da177e4SLinus Torvalds | 0 | 0 | 0 | 0 | ADF      | Add                   | Fd := Fn + Fm         |
1081da177e4SLinus Torvalds | 0 | 0 | 0 | 1 | MUF      | Multiply              | Fd := Fn * Fm         |
1091da177e4SLinus Torvalds | 0 | 0 | 1 | 0 | SUF      | Subtract              | Fd := Fn - Fm         |
1101da177e4SLinus Torvalds | 0 | 0 | 1 | 1 | RSF      | Reverse subtract      | Fd := Fm - Fn         |
1111da177e4SLinus Torvalds | 0 | 1 | 0 | 0 | DVF      | Divide                | Fd := Fn / Fm         |
1121da177e4SLinus Torvalds | 0 | 1 | 0 | 1 | RDF      | Reverse divide        | Fd := Fm / Fn         |
1131da177e4SLinus Torvalds | 0 | 1 | 1 | 0 | POW      | Power                 | Fd := Fn ^ Fm         |
1141da177e4SLinus Torvalds | 0 | 1 | 1 | 1 | RPW      | Reverse power         | Fd := Fm ^ Fn         |
1151da177e4SLinus Torvalds | 1 | 0 | 0 | 0 | RMF      | Remainder             | Fd := IEEE rem(Fn/Fm) |
1161da177e4SLinus Torvalds | 1 | 0 | 0 | 1 | FML      | Fast Multiply         | Fd := Fn * Fm         |
1171da177e4SLinus Torvalds | 1 | 0 | 1 | 0 | FDV      | Fast Divide           | Fd := Fn / Fm         |
1181da177e4SLinus Torvalds | 1 | 0 | 1 | 1 | FRD      | Fast reverse divide   | Fd := Fm / Fn         |
1191da177e4SLinus Torvalds | 1 | 1 | 0 | 0 | POL      | Polar angle (ArcTan2) | Fd := arctan2(Fn,Fm)  |
1201da177e4SLinus Torvalds | 1 | 1 | 0 | 1 |          | undefined instruction | trap                  |
1211da177e4SLinus Torvalds | 1 | 1 | 1 | 0 |          | undefined instruction | trap                  |
1221da177e4SLinus Torvalds | 1 | 1 | 1 | 1 |          | undefined instruction | trap                  |
1231da177e4SLinus Torvalds +---+---+---+---+----------+-----------------------+-----------------------+
1241da177e4SLinus Torvalds Note: POW, RPW, POL are deprecated, and are available for backwards
1251da177e4SLinus Torvalds       compatibility only.
1261da177e4SLinus Torvalds */
1271da177e4SLinus Torvalds 
1281da177e4SLinus Torvalds /*
1291da177e4SLinus Torvalds TABLE 4: Monadic Floating Point Opcodes
1301da177e4SLinus Torvalds +---+---+---+---+----------+-----------------------+-----------------------+
1311da177e4SLinus Torvalds | a | b | c | d | Mnemonic | Description           | Operation             |
1321da177e4SLinus Torvalds +---+---+---+---+----------+-----------------------+-----------------------+
1331da177e4SLinus Torvalds | 0 | 0 | 0 | 0 | MVF      | Move                  | Fd := Fm              |
1341da177e4SLinus Torvalds | 0 | 0 | 0 | 1 | MNF      | Move negated          | Fd := - Fm            |
1351da177e4SLinus Torvalds | 0 | 0 | 1 | 0 | ABS      | Absolute value        | Fd := abs(Fm)         |
1361da177e4SLinus Torvalds | 0 | 0 | 1 | 1 | RND      | Round to integer      | Fd := int(Fm)         |
1371da177e4SLinus Torvalds | 0 | 1 | 0 | 0 | SQT      | Square root           | Fd := sqrt(Fm)        |
1381da177e4SLinus Torvalds | 0 | 1 | 0 | 1 | LOG      | Log base 10           | Fd := log10(Fm)       |
1391da177e4SLinus Torvalds | 0 | 1 | 1 | 0 | LGN      | Log base e            | Fd := ln(Fm)          |
1401da177e4SLinus Torvalds | 0 | 1 | 1 | 1 | EXP      | Exponent              | Fd := e ^ Fm          |
1411da177e4SLinus Torvalds | 1 | 0 | 0 | 0 | SIN      | Sine                  | Fd := sin(Fm)         |
1421da177e4SLinus Torvalds | 1 | 0 | 0 | 1 | COS      | Cosine                | Fd := cos(Fm)         |
1431da177e4SLinus Torvalds | 1 | 0 | 1 | 0 | TAN      | Tangent               | Fd := tan(Fm)         |
1441da177e4SLinus Torvalds | 1 | 0 | 1 | 1 | ASN      | Arc Sine              | Fd := arcsin(Fm)      |
1451da177e4SLinus Torvalds | 1 | 1 | 0 | 0 | ACS      | Arc Cosine            | Fd := arccos(Fm)      |
1461da177e4SLinus Torvalds | 1 | 1 | 0 | 1 | ATN      | Arc Tangent           | Fd := arctan(Fm)      |
1471da177e4SLinus Torvalds | 1 | 1 | 1 | 0 | URD      | Unnormalized round    | Fd := int(Fm)         |
1481da177e4SLinus Torvalds | 1 | 1 | 1 | 1 | NRM      | Normalize             | Fd := norm(Fm)        |
1491da177e4SLinus Torvalds +---+---+---+---+----------+-----------------------+-----------------------+
1501da177e4SLinus Torvalds Note: LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN are deprecated, and are
1511da177e4SLinus Torvalds       available for backwards compatibility only.
1521da177e4SLinus Torvalds */
1531da177e4SLinus Torvalds 
1541da177e4SLinus Torvalds /*
1551da177e4SLinus Torvalds TABLE 5
1561da177e4SLinus Torvalds +-------------------------+---+---+
1571da177e4SLinus Torvalds |  Rounding Precision     | e | f |
1581da177e4SLinus Torvalds +-------------------------+---+---+
1591da177e4SLinus Torvalds | IEEE Single precision   | 0 � 0 |
1601da177e4SLinus Torvalds | IEEE Double precision   | 0 � 1 |
1611da177e4SLinus Torvalds | IEEE Extended precision | 1 � 0 |
1621da177e4SLinus Torvalds | undefined (trap)        | 1 � 1 |
1631da177e4SLinus Torvalds +-------------------------+---+---+
1641da177e4SLinus Torvalds */
1651da177e4SLinus Torvalds 
1661da177e4SLinus Torvalds /*
1671da177e4SLinus Torvalds TABLE 5
1681da177e4SLinus Torvalds +---------------------------------+---+---+
1691da177e4SLinus Torvalds |  Rounding Mode                  | g | h |
1701da177e4SLinus Torvalds +---------------------------------+---+---+
1711da177e4SLinus Torvalds | Round to nearest (default)      | 0 � 0 |
1721da177e4SLinus Torvalds | Round toward plus infinity      | 0 � 1 |
1731da177e4SLinus Torvalds | Round toward negative infinity  | 1 � 0 |
1741da177e4SLinus Torvalds | Round toward zero               | 1 � 1 |
1751da177e4SLinus Torvalds +---------------------------------+---+---+
1761da177e4SLinus Torvalds */
1771da177e4SLinus Torvalds 
1781da177e4SLinus Torvalds /*
1791da177e4SLinus Torvalds ===
1801da177e4SLinus Torvalds === Definitions for load and store instructions
1811da177e4SLinus Torvalds ===
1821da177e4SLinus Torvalds */
1831da177e4SLinus Torvalds 
1841da177e4SLinus Torvalds /* bit masks */
1851da177e4SLinus Torvalds #define BIT_PREINDEX	0x01000000
1861da177e4SLinus Torvalds #define BIT_UP		0x00800000
1871da177e4SLinus Torvalds #define BIT_WRITE_BACK	0x00200000
1881da177e4SLinus Torvalds #define BIT_LOAD	0x00100000
1891da177e4SLinus Torvalds 
1901da177e4SLinus Torvalds /* masks for load/store */
1911da177e4SLinus Torvalds #define MASK_CPDT		0x0c000000	/* data processing opcode */
1921da177e4SLinus Torvalds #define MASK_OFFSET		0x000000ff
1931da177e4SLinus Torvalds #define MASK_TRANSFER_LENGTH	0x00408000
1941da177e4SLinus Torvalds #define MASK_REGISTER_COUNT	MASK_TRANSFER_LENGTH
1951da177e4SLinus Torvalds #define MASK_COPROCESSOR	0x00000f00
1961da177e4SLinus Torvalds 
1971da177e4SLinus Torvalds /* Tests for transfer length */
1981da177e4SLinus Torvalds #define TRANSFER_SINGLE		0x00000000
1991da177e4SLinus Torvalds #define TRANSFER_DOUBLE		0x00008000
2001da177e4SLinus Torvalds #define TRANSFER_EXTENDED	0x00400000
2011da177e4SLinus Torvalds #define TRANSFER_PACKED		MASK_TRANSFER_LENGTH
2021da177e4SLinus Torvalds 
2031da177e4SLinus Torvalds /* Get the coprocessor number from the opcode. */
2041da177e4SLinus Torvalds #define getCoprocessorNumber(opcode)	((opcode & MASK_COPROCESSOR) >> 8)
2051da177e4SLinus Torvalds 
2061da177e4SLinus Torvalds /* Get the offset from the opcode. */
2071da177e4SLinus Torvalds #define getOffset(opcode)		(opcode & MASK_OFFSET)
2081da177e4SLinus Torvalds 
2091da177e4SLinus Torvalds /* Tests for specific data transfer load/store opcodes. */
2101da177e4SLinus Torvalds #define TEST_OPCODE(opcode,mask)	(((opcode) & (mask)) == (mask))
2111da177e4SLinus Torvalds 
2121da177e4SLinus Torvalds #define LOAD_OP(opcode)   TEST_OPCODE((opcode),MASK_CPDT | BIT_LOAD)
2131da177e4SLinus Torvalds #define STORE_OP(opcode)  ((opcode & (MASK_CPDT | BIT_LOAD)) == MASK_CPDT)
2141da177e4SLinus Torvalds 
2151da177e4SLinus Torvalds #define LDF_OP(opcode)	(LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 1))
2161da177e4SLinus Torvalds #define LFM_OP(opcode)	(LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 2))
2171da177e4SLinus Torvalds #define STF_OP(opcode)	(STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 1))
2181da177e4SLinus Torvalds #define SFM_OP(opcode)	(STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 2))
2191da177e4SLinus Torvalds 
2201da177e4SLinus Torvalds #define PREINDEXED(opcode)		((opcode & BIT_PREINDEX) != 0)
2211da177e4SLinus Torvalds #define POSTINDEXED(opcode)		((opcode & BIT_PREINDEX) == 0)
2221da177e4SLinus Torvalds #define BIT_UP_SET(opcode)		((opcode & BIT_UP) != 0)
2231da177e4SLinus Torvalds #define BIT_UP_CLEAR(opcode)		((opcode & BIT_DOWN) == 0)
2241da177e4SLinus Torvalds #define WRITE_BACK(opcode)		((opcode & BIT_WRITE_BACK) != 0)
2251da177e4SLinus Torvalds #define LOAD(opcode)			((opcode & BIT_LOAD) != 0)
2261da177e4SLinus Torvalds #define STORE(opcode)			((opcode & BIT_LOAD) == 0)
2271da177e4SLinus Torvalds 
2281da177e4SLinus Torvalds /*
2291da177e4SLinus Torvalds ===
2301da177e4SLinus Torvalds === Definitions for arithmetic instructions
2311da177e4SLinus Torvalds ===
2321da177e4SLinus Torvalds */
2331da177e4SLinus Torvalds /* bit masks */
2341da177e4SLinus Torvalds #define BIT_MONADIC	0x00008000
2351da177e4SLinus Torvalds #define BIT_CONSTANT	0x00000008
2361da177e4SLinus Torvalds 
2371da177e4SLinus Torvalds #define CONSTANT_FM(opcode)		((opcode & BIT_CONSTANT) != 0)
2381da177e4SLinus Torvalds #define MONADIC_INSTRUCTION(opcode)	((opcode & BIT_MONADIC) != 0)
2391da177e4SLinus Torvalds 
2401da177e4SLinus Torvalds /* instruction identification masks */
2411da177e4SLinus Torvalds #define MASK_CPDO		0x0e000000	/* arithmetic opcode */
2421da177e4SLinus Torvalds #define MASK_ARITHMETIC_OPCODE	0x00f08000
2431da177e4SLinus Torvalds #define MASK_DESTINATION_SIZE	0x00080080
2441da177e4SLinus Torvalds 
2451da177e4SLinus Torvalds /* dyadic arithmetic opcodes. */
2461da177e4SLinus Torvalds #define ADF_CODE	0x00000000
2471da177e4SLinus Torvalds #define MUF_CODE	0x00100000
2481da177e4SLinus Torvalds #define SUF_CODE	0x00200000
2491da177e4SLinus Torvalds #define RSF_CODE	0x00300000
2501da177e4SLinus Torvalds #define DVF_CODE	0x00400000
2511da177e4SLinus Torvalds #define RDF_CODE	0x00500000
2521da177e4SLinus Torvalds #define POW_CODE	0x00600000
2531da177e4SLinus Torvalds #define RPW_CODE	0x00700000
2541da177e4SLinus Torvalds #define RMF_CODE	0x00800000
2551da177e4SLinus Torvalds #define FML_CODE	0x00900000
2561da177e4SLinus Torvalds #define FDV_CODE	0x00a00000
2571da177e4SLinus Torvalds #define FRD_CODE	0x00b00000
2581da177e4SLinus Torvalds #define POL_CODE	0x00c00000
2591da177e4SLinus Torvalds /* 0x00d00000 is an invalid dyadic arithmetic opcode */
2601da177e4SLinus Torvalds /* 0x00e00000 is an invalid dyadic arithmetic opcode */
2611da177e4SLinus Torvalds /* 0x00f00000 is an invalid dyadic arithmetic opcode */
2621da177e4SLinus Torvalds 
2631da177e4SLinus Torvalds /* monadic arithmetic opcodes. */
2641da177e4SLinus Torvalds #define MVF_CODE	0x00008000
2651da177e4SLinus Torvalds #define MNF_CODE	0x00108000
2661da177e4SLinus Torvalds #define ABS_CODE	0x00208000
2671da177e4SLinus Torvalds #define RND_CODE	0x00308000
2681da177e4SLinus Torvalds #define SQT_CODE	0x00408000
2691da177e4SLinus Torvalds #define LOG_CODE	0x00508000
2701da177e4SLinus Torvalds #define LGN_CODE	0x00608000
2711da177e4SLinus Torvalds #define EXP_CODE	0x00708000
2721da177e4SLinus Torvalds #define SIN_CODE	0x00808000
2731da177e4SLinus Torvalds #define COS_CODE	0x00908000
2741da177e4SLinus Torvalds #define TAN_CODE	0x00a08000
2751da177e4SLinus Torvalds #define ASN_CODE	0x00b08000
2761da177e4SLinus Torvalds #define ACS_CODE	0x00c08000
2771da177e4SLinus Torvalds #define ATN_CODE	0x00d08000
2781da177e4SLinus Torvalds #define URD_CODE	0x00e08000
2791da177e4SLinus Torvalds #define NRM_CODE	0x00f08000
2801da177e4SLinus Torvalds 
2811da177e4SLinus Torvalds /*
2821da177e4SLinus Torvalds ===
2831da177e4SLinus Torvalds === Definitions for register transfer and comparison instructions
2841da177e4SLinus Torvalds ===
2851da177e4SLinus Torvalds */
2861da177e4SLinus Torvalds 
2871da177e4SLinus Torvalds #define MASK_CPRT		0x0e000010	/* register transfer opcode */
2881da177e4SLinus Torvalds #define MASK_CPRT_CODE		0x00f00000
2891da177e4SLinus Torvalds #define FLT_CODE		0x00000000
2901da177e4SLinus Torvalds #define FIX_CODE		0x00100000
2911da177e4SLinus Torvalds #define WFS_CODE		0x00200000
2921da177e4SLinus Torvalds #define RFS_CODE		0x00300000
2931da177e4SLinus Torvalds #define WFC_CODE		0x00400000
2941da177e4SLinus Torvalds #define RFC_CODE		0x00500000
2951da177e4SLinus Torvalds #define CMF_CODE		0x00900000
2961da177e4SLinus Torvalds #define CNF_CODE		0x00b00000
2971da177e4SLinus Torvalds #define CMFE_CODE		0x00d00000
2981da177e4SLinus Torvalds #define CNFE_CODE		0x00f00000
2991da177e4SLinus Torvalds 
3001da177e4SLinus Torvalds /*
3011da177e4SLinus Torvalds ===
3021da177e4SLinus Torvalds === Common definitions
3031da177e4SLinus Torvalds ===
3041da177e4SLinus Torvalds */
3051da177e4SLinus Torvalds 
3061da177e4SLinus Torvalds /* register masks */
3071da177e4SLinus Torvalds #define MASK_Rd		0x0000f000
3081da177e4SLinus Torvalds #define MASK_Rn		0x000f0000
3091da177e4SLinus Torvalds #define MASK_Fd		0x00007000
3101da177e4SLinus Torvalds #define MASK_Fm		0x00000007
3111da177e4SLinus Torvalds #define MASK_Fn		0x00070000
3121da177e4SLinus Torvalds 
3131da177e4SLinus Torvalds /* condition code masks */
3141da177e4SLinus Torvalds #define CC_MASK		0xf0000000
3151da177e4SLinus Torvalds #define CC_NEGATIVE	0x80000000
3161da177e4SLinus Torvalds #define CC_ZERO		0x40000000
3171da177e4SLinus Torvalds #define CC_CARRY	0x20000000
3181da177e4SLinus Torvalds #define CC_OVERFLOW	0x10000000
3191da177e4SLinus Torvalds #define CC_EQ		0x00000000
3201da177e4SLinus Torvalds #define CC_NE		0x10000000
3211da177e4SLinus Torvalds #define CC_CS		0x20000000
3221da177e4SLinus Torvalds #define CC_HS		CC_CS
3231da177e4SLinus Torvalds #define CC_CC		0x30000000
3241da177e4SLinus Torvalds #define CC_LO		CC_CC
3251da177e4SLinus Torvalds #define CC_MI		0x40000000
3261da177e4SLinus Torvalds #define CC_PL		0x50000000
3271da177e4SLinus Torvalds #define CC_VS		0x60000000
3281da177e4SLinus Torvalds #define CC_VC		0x70000000
3291da177e4SLinus Torvalds #define CC_HI		0x80000000
3301da177e4SLinus Torvalds #define CC_LS		0x90000000
3311da177e4SLinus Torvalds #define CC_GE		0xa0000000
3321da177e4SLinus Torvalds #define CC_LT		0xb0000000
3331da177e4SLinus Torvalds #define CC_GT		0xc0000000
3341da177e4SLinus Torvalds #define CC_LE		0xd0000000
3351da177e4SLinus Torvalds #define CC_AL		0xe0000000
3361da177e4SLinus Torvalds #define CC_NV		0xf0000000
3371da177e4SLinus Torvalds 
3381da177e4SLinus Torvalds /* rounding masks/values */
3391da177e4SLinus Torvalds #define MASK_ROUNDING_MODE	0x00000060
3401da177e4SLinus Torvalds #define ROUND_TO_NEAREST	0x00000000
3411da177e4SLinus Torvalds #define ROUND_TO_PLUS_INFINITY	0x00000020
3421da177e4SLinus Torvalds #define ROUND_TO_MINUS_INFINITY	0x00000040
3431da177e4SLinus Torvalds #define ROUND_TO_ZERO		0x00000060
3441da177e4SLinus Torvalds 
3451da177e4SLinus Torvalds #define MASK_ROUNDING_PRECISION	0x00080080
3461da177e4SLinus Torvalds #define ROUND_SINGLE		0x00000000
3471da177e4SLinus Torvalds #define ROUND_DOUBLE		0x00000080
3481da177e4SLinus Torvalds #define ROUND_EXTENDED		0x00080000
3491da177e4SLinus Torvalds 
3501da177e4SLinus Torvalds /* Get the condition code from the opcode. */
3511da177e4SLinus Torvalds #define getCondition(opcode)		(opcode >> 28)
3521da177e4SLinus Torvalds 
3531da177e4SLinus Torvalds /* Get the source register from the opcode. */
3541da177e4SLinus Torvalds #define getRn(opcode)			((opcode & MASK_Rn) >> 16)
3551da177e4SLinus Torvalds 
3561da177e4SLinus Torvalds /* Get the destination floating point register from the opcode. */
3571da177e4SLinus Torvalds #define getFd(opcode)			((opcode & MASK_Fd) >> 12)
3581da177e4SLinus Torvalds 
3591da177e4SLinus Torvalds /* Get the first source floating point register from the opcode. */
3601da177e4SLinus Torvalds #define getFn(opcode)		((opcode & MASK_Fn) >> 16)
3611da177e4SLinus Torvalds 
3621da177e4SLinus Torvalds /* Get the second source floating point register from the opcode. */
3631da177e4SLinus Torvalds #define getFm(opcode)		(opcode & MASK_Fm)
3641da177e4SLinus Torvalds 
3651da177e4SLinus Torvalds /* Get the destination register from the opcode. */
3661da177e4SLinus Torvalds #define getRd(opcode)		((opcode & MASK_Rd) >> 12)
3671da177e4SLinus Torvalds 
3681da177e4SLinus Torvalds /* Get the rounding mode from the opcode. */
3691da177e4SLinus Torvalds #define getRoundingMode(opcode)		((opcode & MASK_ROUNDING_MODE) >> 5)
3701da177e4SLinus Torvalds 
3711da177e4SLinus Torvalds #ifdef CONFIG_FPE_NWFPE_XP
372*e8c44319SRalf Baechle static inline floatx80 __pure getExtendedConstant(const unsigned int nIndex)
3731da177e4SLinus Torvalds {
3741da177e4SLinus Torvalds 	extern const floatx80 floatx80Constant[];
3751da177e4SLinus Torvalds 	return floatx80Constant[nIndex];
3761da177e4SLinus Torvalds }
3771da177e4SLinus Torvalds #endif
3781da177e4SLinus Torvalds 
379*e8c44319SRalf Baechle static inline float64 __pure getDoubleConstant(const unsigned int nIndex)
3801da177e4SLinus Torvalds {
3811da177e4SLinus Torvalds 	extern const float64 float64Constant[];
3821da177e4SLinus Torvalds 	return float64Constant[nIndex];
3831da177e4SLinus Torvalds }
3841da177e4SLinus Torvalds 
385*e8c44319SRalf Baechle static inline float32 __pure getSingleConstant(const unsigned int nIndex)
3861da177e4SLinus Torvalds {
3871da177e4SLinus Torvalds 	extern const float32 float32Constant[];
3881da177e4SLinus Torvalds 	return float32Constant[nIndex];
3891da177e4SLinus Torvalds }
3901da177e4SLinus Torvalds 
3911da177e4SLinus Torvalds static inline unsigned int getTransferLength(const unsigned int opcode)
3921da177e4SLinus Torvalds {
3931da177e4SLinus Torvalds 	unsigned int nRc;
3941da177e4SLinus Torvalds 
3951da177e4SLinus Torvalds 	switch (opcode & MASK_TRANSFER_LENGTH) {
3961da177e4SLinus Torvalds 	case 0x00000000:
3971da177e4SLinus Torvalds 		nRc = 1;
3981da177e4SLinus Torvalds 		break;		/* single precision */
3991da177e4SLinus Torvalds 	case 0x00008000:
4001da177e4SLinus Torvalds 		nRc = 2;
4011da177e4SLinus Torvalds 		break;		/* double precision */
4021da177e4SLinus Torvalds 	case 0x00400000:
4031da177e4SLinus Torvalds 		nRc = 3;
4041da177e4SLinus Torvalds 		break;		/* extended precision */
4051da177e4SLinus Torvalds 	default:
4061da177e4SLinus Torvalds 		nRc = 0;
4071da177e4SLinus Torvalds 	}
4081da177e4SLinus Torvalds 
4091da177e4SLinus Torvalds 	return (nRc);
4101da177e4SLinus Torvalds }
4111da177e4SLinus Torvalds 
4121da177e4SLinus Torvalds static inline unsigned int getRegisterCount(const unsigned int opcode)
4131da177e4SLinus Torvalds {
4141da177e4SLinus Torvalds 	unsigned int nRc;
4151da177e4SLinus Torvalds 
4161da177e4SLinus Torvalds 	switch (opcode & MASK_REGISTER_COUNT) {
4171da177e4SLinus Torvalds 	case 0x00000000:
4181da177e4SLinus Torvalds 		nRc = 4;
4191da177e4SLinus Torvalds 		break;
4201da177e4SLinus Torvalds 	case 0x00008000:
4211da177e4SLinus Torvalds 		nRc = 1;
4221da177e4SLinus Torvalds 		break;
4231da177e4SLinus Torvalds 	case 0x00400000:
4241da177e4SLinus Torvalds 		nRc = 2;
4251da177e4SLinus Torvalds 		break;
4261da177e4SLinus Torvalds 	case 0x00408000:
4271da177e4SLinus Torvalds 		nRc = 3;
4281da177e4SLinus Torvalds 		break;
4291da177e4SLinus Torvalds 	default:
4301da177e4SLinus Torvalds 		nRc = 0;
4311da177e4SLinus Torvalds 	}
4321da177e4SLinus Torvalds 
4331da177e4SLinus Torvalds 	return (nRc);
4341da177e4SLinus Torvalds }
4351da177e4SLinus Torvalds 
4361da177e4SLinus Torvalds static inline unsigned int getRoundingPrecision(const unsigned int opcode)
4371da177e4SLinus Torvalds {
4381da177e4SLinus Torvalds 	unsigned int nRc;
4391da177e4SLinus Torvalds 
4401da177e4SLinus Torvalds 	switch (opcode & MASK_ROUNDING_PRECISION) {
4411da177e4SLinus Torvalds 	case 0x00000000:
4421da177e4SLinus Torvalds 		nRc = 1;
4431da177e4SLinus Torvalds 		break;
4441da177e4SLinus Torvalds 	case 0x00000080:
4451da177e4SLinus Torvalds 		nRc = 2;
4461da177e4SLinus Torvalds 		break;
4471da177e4SLinus Torvalds 	case 0x00080000:
4481da177e4SLinus Torvalds 		nRc = 3;
4491da177e4SLinus Torvalds 		break;
4501da177e4SLinus Torvalds 	default:
4511da177e4SLinus Torvalds 		nRc = 0;
4521da177e4SLinus Torvalds 	}
4531da177e4SLinus Torvalds 
4541da177e4SLinus Torvalds 	return (nRc);
4551da177e4SLinus Torvalds }
4561da177e4SLinus Torvalds 
4571da177e4SLinus Torvalds static inline unsigned int getDestinationSize(const unsigned int opcode)
4581da177e4SLinus Torvalds {
4591da177e4SLinus Torvalds 	unsigned int nRc;
4601da177e4SLinus Torvalds 
4611da177e4SLinus Torvalds 	switch (opcode & MASK_DESTINATION_SIZE) {
4621da177e4SLinus Torvalds 	case 0x00000000:
4631da177e4SLinus Torvalds 		nRc = typeSingle;
4641da177e4SLinus Torvalds 		break;
4651da177e4SLinus Torvalds 	case 0x00000080:
4661da177e4SLinus Torvalds 		nRc = typeDouble;
4671da177e4SLinus Torvalds 		break;
4681da177e4SLinus Torvalds 	case 0x00080000:
4691da177e4SLinus Torvalds 		nRc = typeExtended;
4701da177e4SLinus Torvalds 		break;
4711da177e4SLinus Torvalds 	default:
4721da177e4SLinus Torvalds 		nRc = typeNone;
4731da177e4SLinus Torvalds 	}
4741da177e4SLinus Torvalds 
4751da177e4SLinus Torvalds 	return (nRc);
4761da177e4SLinus Torvalds }
4771da177e4SLinus Torvalds 
4786ec5e7f3SBen Dooks extern unsigned int checkCondition(const unsigned int opcode,
4796ec5e7f3SBen Dooks 				   const unsigned int ccodes);
4806ec5e7f3SBen Dooks 
4816ec5e7f3SBen Dooks extern const float64 float64Constant[];
4826ec5e7f3SBen Dooks extern const float32 float32Constant[];
4836ec5e7f3SBen Dooks 
4841da177e4SLinus Torvalds #endif
485