xref: /openbmc/linux/arch/arm/nwfpe/fpopcode.h (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
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