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