1/*	$NetBSD: instr.h,v 1.12 2022/08/30 11:05:59 rin Exp $ */
2
3/*
4 * Copyright (c) 1992, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
10 *
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 *	This product includes software developed by the University of
14 *	California, Lawrence Berkeley Laboratory.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 *    notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 *    notice, this list of conditions and the following disclaimer in the
23 *    documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 *    may be used to endorse or promote products derived from this software
26 *    without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 *	@(#)instr.h	8.1 (Berkeley) 6/11/93
41 */
42
43#ifndef _POWERPC_INSTR_H_
44#define _POWERPC_INSTR_H_
45
46/*
47 * An instruction.
48 */
49union instr {
50	int	i_int;			/* as a whole */
51
52
53	/*
54	 * Any instruction type.
55	 */
56	struct {
57		u_int	i_opcd:6;	/* first-level decode */
58		u_int	:25;
59		u_int	i_rc:1;
60	} i_any;
61
62	/*
63	 * Format A
64	 */
65	struct {
66		u_int	i_opcd:6;
67		u_int	i_frt:5;
68		u_int	i_fra:5;
69		u_int	i_frb:5;
70		u_int	i_frc:5;
71		u_int	i_xo:5;
72		u_int	i_rc:1;
73	} i_a;
74
75	/*
76	 * Format B
77	 */
78	struct {
79		u_int	i_opcd:6;
80		u_int	i_bo:5;
81		u_int	i_bi:5;
82		int	i_bd:14;
83		u_int	i_aa:1;
84		u_int	i_lk:1;
85	} i_b;
86
87	/*
88	 * Format D
89	 */
90	struct {
91		u_int	i_opcd:6;
92		u_int	i_rs:5;
93		u_int	i_ra:5;
94		int	i_d:16;
95	} i_d;
96
97	/*
98	 * Format DE
99	 */
100	struct {
101		u_int	i_opcd:6;
102		u_int	i_rs:5;
103		u_int	i_ra:5;
104		int	i_d:12;
105		u_int	i_xo:4;
106	} i_de;
107
108	/*
109	 * Format I
110	 */
111	struct {
112		u_int	i_opcd:6;
113		int	i_li:24;
114		int	i_aa:1;
115		int	i_lk:1;
116	} i_i;
117
118	/*
119	 * Format M
120	 */
121	struct {
122		u_int	i_opcd:6;
123		u_int	i_rs:5;
124		u_int	i_ra:5;
125		u_int	i_rb:5;
126		int	i_mb:5;
127		int	i_me:5;
128		u_int	i_rc:1;
129	} i_m;
130
131	/*
132	 * Format MD
133	 */
134	struct {
135		u_int	i_opcd:6;
136		u_int	i_rs:5;
137		u_int	i_ra:5;
138		int	i_sh1_5:5;
139		int	i_mb:6;
140		u_int	i_xo:3;
141		int	i_sh0:1;
142		u_int	i_rc:1;
143	} i_md;
144
145	/*
146	 * Format MDS
147	 */
148	struct {
149		u_int	i_opcd:6;
150		u_int	i_rs:5;
151		u_int	i_ra:5;
152		u_int	i_rb:5;
153		int	i_mb:6;
154		u_int	i_xo:4;
155		u_int	i_rc:1;
156	} i_mds;
157
158
159	/*
160	 * Format S
161	 */
162	struct {
163		u_int	i_opcd:6;
164		int	:24;
165		int	i_i:1;
166		int	:1;
167	} i_s;
168
169	/*
170	 * Format X
171	 */
172	struct {
173		u_int	i_opcd:6;
174		u_int	i_rs:5;
175		u_int	i_ra:5;
176		u_int	i_rb:5;
177		u_int	i_xo:10;
178		u_int	i_rc:1;
179	} i_x;
180
181	/*
182	 * Format XFL
183	 */
184	struct {
185		u_int	i_opcd:6;
186		int	:1;
187		int	i_flm:8;
188		int	:1;
189		int	i_frb:5;
190		u_int	i_xo:10;
191		int	:1;
192	} i_xfl;
193
194	/*
195	 * Format XFX
196	 */
197	struct {
198		u_int	i_opcd:6;
199		int	i_dcrn:10;
200		u_int	i_xo:10;
201		int	:1;
202	} i_xfx;
203
204	/*
205	 * Format XL
206	 */
207	struct {
208		u_int	i_opcd:6;
209		int	i_bt:5;
210		int	i_ba:5;
211		int	i_bb:5;
212		u_int	i_xo:10;
213		int	i_lk:1;
214	} i_xl;
215
216	/*
217	 * Format XS
218	 */
219	struct {
220		u_int	i_opcd:6;
221		u_int	i_rs:5;
222		u_int	i_ra:5;
223		int	i_sh0_4:5;
224		u_int	i_xo:9;
225		int	i_sh5:1;
226		u_int	i_rc:1;
227	} i_xs;
228
229};
230
231#define	i_rt	i_rs
232
233/*
234 * Primary opcode numbers:
235 */
236
237#define	OPC_TDI		0x02
238#define	OPC_TWI		0x03
239#define	OPC_MULLI	0x07
240#define	OPC_SUBFIC	0x08
241#define	OPC_BCE		0x09
242#define	OPC_CMPLI	0x0a
243#define	OPC_CMPI	0x0b
244#define	OPC_ADDIC	0x0c
245#define	OPC_ADDIC_DOT	0x0d
246#define	OPC_ADDI	0x0e
247#define	OPC_ADDIS	0x0f
248#define	OPC_BC		0x10
249#define	OPC_SC		0x11
250#define	OPC_B		0x12
251#define	OPC_branch_19	0x13
252#define	OPC_RLWIMI	0x14
253#define	OPC_RLWINM	0x15
254#define	OPC_BE		0x16
255#define	OPC_RLWNM	0x17
256#define	OPC_ORI		0x18
257#define	OPC_ORIS	0x19
258#define	OPC_XORI	0x1a
259#define	OPC_XORIS	0x1b
260#define	OPC_ANDI	0x1c
261#define	OPC_ANDIS	0x1d
262#define	OPC_dwe_rot_30	0x1e
263#define	OPC_integer_31	0x1f
264#define	OPC_LWZ		0x20
265#define	OPC_LWZU	0x21
266#define	OPC_LBZ		0x22
267#define	OPC_LBZU	0x23
268#define	OPC_STW		0x24
269#define	OPC_STWU	0x25
270#define	OPC_STB		0x26
271#define	OPC_STBU	0x27
272#define	OPC_LHZ		0x28
273#define	OPC_LHZU	0x29
274#define	OPC_LHA		0x2a
275#define	OPC_LHAU	0x2b
276#define	OPC_STH		0x2c
277#define	OPC_STHU	0x2d
278#define	OPC_LMW		0x2e
279#define	OPC_STMW	0x2f
280#define	OPC_LFS		0x30
281#define	OPC_LFSU	0x31
282#define	OPC_LFD		0x32
283#define	OPC_LFDU	0x33
284#define	OPC_STFS	0x34
285#define	OPC_STFSU	0x35
286#define	OPC_STFD	0x36
287#define	OPC_STFDU	0x37
288#define	OPC_load_st_58	0x3a
289#define	OPC_sp_fp_59	0x3b
290#define	OPC_load_st_62	0x3e
291#define	OPC_dp_fp_63	0x3f
292
293/*
294 * Opcode 31 sub-types (FP only)
295 */
296#define	OPC31_TW	0x004
297#define	OPC31_LFSX	0x217
298#define	OPC31_LFSUX	0x237
299#define	OPC31_LFDX	0x257
300#define	OPC31_LFDUX	0x277
301#define	OPC31_STFSX	0x297
302#define	OPC31_STFSUX	0x2b7
303#define	OPC31_STFDX	0x2d7
304#define	OPC31_STFDUX	0x2f7
305#define	OPC31_STFIWX	0x3d7
306
307/* Mask for all valid indexed FP load/store ops (except stfiwx) */
308#define	OPC31_FPMASK	0x31f
309#define	OPC31_FPOP	0x217
310
311/* m[ft]spr are also opcode 31; ra/rb encode the spr */
312#define	OPC31_MFSPR	0x153
313#define OPC31_MTSPR	0x1d3
314
315/*
316 * Opcode 31 sub-types (integer only)
317 */
318#define OPC31_OR	0x1bc
319
320/*
321 * Opcode 31 sub-types (load/store multiple bytes)
322 */
323#define	OPC31_LWZX	0x017
324#define	OPC31_LWZUX	0x037
325#define	OPC31_STWX	0x097
326#define	OPC31_STWUX	0x0b7
327#define	OPC31_LHZX	0x117
328#define	OPC31_LHZUX	0x137
329#define	OPC31_LHAX	0x157
330#define	OPC31_LHAUX	0x177
331#define	OPC31_STHX	0x197
332#define	OPC31_STHUX	0x1b7
333#define	OPC31_LWBRX	0x216
334#define	OPC31_STWBRX	0x296
335#define	OPC31_LHBRX	0x316
336#define	OPC31_STHBRX	0x396
337
338/*
339 * Opcode 59 sub-types:
340 */
341
342#define	OPC59_FDIVS	0x12
343#define	OPC59_FSUBS	0x14
344#define	OPC59_FADDS	0x15
345#define	OPC59_FSQRTS	0x16
346#define	OPC59_FRES	0x18
347#define	OPC59_FMULS	0x19
348#define	OPC59_FMSUBS	0x1c
349#define	OPC59_FMADDS	0x1d
350#define	OPC59_FNMSUBS	0x1e
351#define	OPC59_FNMADDS	0x1f
352
353/*
354 * Opcode 62 sub-types:
355 */
356#define	OPC62_LDE	0x0
357#define	OPC62_LDEU	0x1
358#define	OPC62_LFSE	0x4
359#define	OPC62_LFSEU	0x5
360#define	OPC62_LFDE	0x6
361#define	OPC62_LFDEU	0x7
362#define	OPC62_STDE	0x8
363#define	OPC62_STDEU	0x9
364#define	OPC62_STFSE	0xc
365#define	OPC62_STFSEU	0xd
366#define	OPC62_STFDE	0xe
367#define	OPC62_STFDEU	0xf
368
369/*
370 * Opcode 63 sub-types:
371 *
372 * (The first group are masks....)
373 */
374
375#define	OPC63M_MASK	0x10
376#define	OPC63M_FDIV	0x12
377#define	OPC63M_FSUB	0x14
378#define	OPC63M_FADD	0x15
379#define	OPC63M_FSQRT	0x16
380#define	OPC63M_FSEL	0x17
381#define	OPC63M_FMUL	0x19
382#define	OPC63M_FRSQRTE	0x1a
383#define	OPC63M_FMSUB	0x1c
384#define	OPC63M_FMADD	0x1d
385#define	OPC63M_FNMSUB	0x1e
386#define	OPC63M_FNMADD	0x1f
387
388#define	OPC63_FCMPU	0x00
389#define	OPC63_FRSP	0x0c
390#define	OPC63_FCTIW	0x0e
391#define	OPC63_FCTIWZ	0x0f
392#define	OPC63_FCMPO	0x20
393#define	OPC63_MTFSB1	0x26
394#define	OPC63_FNEG	0x28
395#define	OPC63_MCRFS	0x40
396#define	OPC63_MTFSB0	0x46
397#define	OPC63_FMR	0x48
398#define	OPC63_MTFSFI	0x86
399#define	OPC63_FNABS	0x88
400#define	OPC63_FABS	0x108
401#define	OPC63_MFFS	0x247
402#define	OPC63_MTFSF	0x2c7
403#define	OPC63_FCTID	0x32e
404#define	OPC63_FCTIDZ	0x32f
405#define	OPC63_FCFID	0x34e
406
407/*
408 * Branch instruction modifiers.
409 */
410#define	B_LK		0x01	/* Link flag (LR=CIA+4) */
411#define	B_AA		0x02	/* Absolute flag */
412
413/*
414 * Helpers for decoding mfspr
415 */
416#define	OPC_MFSPR_CODE		0x7c0002a6
417#define	OPC_MFSPR_MASK		(~(0x1f << 21))
418#define	OPC_MFSPR(spr)		(OPC_MFSPR_CODE |\
419				 (((spr) & 0x1f) << 16) |\
420				 (((spr) & 0x3e0) << 6))
421#define	OPC_MFSPR_REG(o)	(((o) >> 21) & 0x1f)
422#define	OPC_MFSPR_P(o, spr)	(((o) & OPC_MFSPR_MASK) == OPC_MFSPR(spr))
423
424/*
425 * booke doesn't have lwsync even though gcc emits it so we have to emulate it.
426 */
427#define	OPC_LWSYNC		0x7c2004ac
428
429/*
430 * FPCSR rounding modes.
431 */
432#define	  FSR_RD_RN	0		/* round to nearest */
433#define	  FSR_RD_RZ	1		/* round towards 0 */
434#define	  FSR_RD_RP	2		/* round towards +inf */
435#define	  FSR_RD_RM	3		/* round towards -inf */
436
437/*
438 * Convert an address to an offset used in a PowerPC branch instruction.
439 * We simply shift away the low bits since we are going convert the bl
440 * to a bla.
441 */
442#define	fixup_addr2offset(x)	((uintptr_t)(x) >> 2)
443struct powerpc_jump_fixup_info {
444	uint32_t jfi_stub;
445	uint32_t jfi_real;
446};
447
448void	powerpc_fixup_stubs(uint32_t *, uint32_t *, uint32_t *, uint32_t *);
449
450
451#endif /* !_POWERPC_INSTR_H_ */
452