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