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