1 /* $NetBSD: db_disasm.c,v 1.18 2022/04/17 21:24:53 andvar Exp $ */
2
3 /* $OpenBSD: db_disasm.c,v 1.9 2000/04/18 20:02:45 mickey Exp $ */
4
5 /*
6 * Copyright (c) 1999,2005 Michael Shalayeff
7 * All rights reserved.
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
18 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21 /*
22 * (c) Copyright 1992 HEWLETT-PACKARD COMPANY
23 *
24 * To anyone who acknowledges that this file is provided "AS IS"
25 * without any express or implied warranty:
26 * permission to use, copy, modify, and distribute this file
27 * for any purpose is hereby granted without fee, provided that
28 * the above copyright notice and this notice appears in all
29 * copies, and that the name of Hewlett-Packard Company not be
30 * used in advertising or publicity pertaining to distribution
31 * of the software without specific, written prior permission.
32 * Hewlett-Packard Company makes no representations about the
33 * suitability of this software for any purpose.
34 */
35
36 /*
37 * unasm.c -- HP_PA Instruction Printer
38 */
39
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.18 2022/04/17 21:24:53 andvar Exp $");
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45
46 #include <machine/db_machdep.h>
47
48 #include <ddb/db_access.h>
49 #include <ddb/db_sym.h>
50 #include <ddb/db_output.h>
51 #include <ddb/db_interface.h>
52
53 #ifndef _KERNEL
54 #include <string.h>
55 #endif
56
57 /* IMPORTANT NOTE:
58 * All modules using this header may assume that the datatype "int" is a
59 * 32-bit (or > 32-bit) signed quantity.
60 */
61
62
63 /* Spectrum Architecturally Defined Datatypes */
64 struct doubleword {
65 int wd0;
66 int wd1;
67 };
68
69 struct quadword {
70 struct doubleword d0;
71 struct doubleword d1;
72 };
73
74 /* datatypes for halfword and byte fields of a word are defined
75 * in ssBits.h */
76
77 /* Memory addressing datatypes */
78 typedef unsigned int SID, /* range [0..MAXSID] */
79 PGID, /* range [0..MAXPGID] */
80 OFS, /* range [0..MAXINT] */
81 REALADR; /* range [0..MAXINT] */
82
83
84 /* data sizes */
85 enum datasize { Byte, Halfword, Word, Doubleword, Quadword, Variable };
86
87 /* Miscellaneous datatypes */
88 typedef unsigned int FLAGS;
89
90 /* struct for entry in unwind table */
91 struct ute {
92 int word1;
93 int word2;
94 int word3;
95 int word4;
96 };
97 /*
98 * Header: /n/schirf/u/baford/CVS/mach4-parisc/kernel_unused/parisc/kdb/unasm.c,v 1.5 1994/07/21 22:32:05 mike Exp
99 *
100 * Spectrum Instruction Set Condition Completer Bit Assignments
101 * Dan Magenheimer - 6/14/82
102 * Terrence Miller - 6/21/82
103 * Computer Research Center, Hewlett-Packard Labs
104 *
105 * (c) copyright 1982
106 * (p) protected 1982
107 * The Hewlett-Packard Company
108 * Hewlett-Packard Laboratories
109 * Computer Research Center
110 * Palo Alto, California
111 *
112 * *** HP Company Confidential ***
113 *
114 * Log: unasm.c,v
115 * Revision 1.5 1994/07/21 22:32:05 mike
116 * official HP copyright notice
117 *
118 * Revision 1.4 1992/07/08 12:19:52 dalton
119 * Checkin before split to 1.0.4 release (by LBS).
120 *
121 * Revision 1.3 92/06/06 16:16:45 dalton
122 * *** empty log message ***
123 *
124 * Revision 1.2 92/06/06 15:42:28 dalton
125 * Changed include to be a path relative to hp800.
126 *
127 * Revision 1.1 92/06/06 14:05:33 dalton
128 * Initial revision
129 *
130 * Revision 1.2 91/04/14 20:29:49 osfrcs
131 * Initial version.
132 * [91/03/30 09:20:34 brezak]
133 *
134 * Revision 1.1.2.2 91/04/02 10:42:50 brezak
135 * Initial version.
136 * [91/03/30 09:20:34 brezak]
137 *
138 * Revision 1.1.1.2 91/03/30 09:20:34 brezak
139 * Initial version.
140 *
141 * Revision 1.1 88/07/11 14:05:15 14:05:15 ren (Bob Naas)
142 * Initial revision
143 *
144 * Revision 5.2 87/07/02 14:45:57 14:45:57 kent (Kent McMullen)
145 * added constants to support addDasm and addDCond added to ssDID.c
146 *
147 * Revision 5.1 87/02/27 11:12:08 11:12:08 kent (Kent McMullen)
148 * update all src to 5.1
149 *
150 * Revision 5.0 87/02/18 16:31:15 16:31:15 kent (Kent McMullen)
151 * update all revision numbers to 5.0 for release
152 *
153 * Revision 1.1 86/07/15 08:34:55 08:34:55 kent (Kent McMullen)
154 * Initial revision
155 *
156 * Revision 4.1 83/10/25 17:01:22 17:01:22 djm (Daniel J Magenheimer)
157 * First release for ACD v4
158 *
159 * Revision 3.0 83/06/13 10:22:59 djm (Daniel Magenheimer)
160 * First release for distribution
161 *
162 *
163 */
164
165
166 /* Arithmetic/Logical Conditions */
167 #define NEV 0x0
168 #define EQZ 0x2
169 #define LT 0x4
170 #define LE 0x6
171 #define LLT 0x8
172 #define NUV 0x8
173 #define LLE 0xA
174 #define ZNV 0xA
175 #define SV 0xC
176 #define OD 0xE
177 #define TR 0x1
178 #define NEQZ 0x3
179 #define GE 0x5
180 #define GT 0x7
181 #define LGE 0x9
182 #define UV 0x9
183 #define LGT 0xB
184 #define VNZ 0xB
185 #define NSV 0xD
186 #define EV 0xF
187
188 /* unit conditions */
189 #define SBZ 0x4
190 #define SHZ 0x6
191 #define SDC 0x8
192 #define SBC 0xC
193 #define SHC 0xE
194 #define NBZ 0x5
195 #define NHZ 0x7
196 #define NDC 0x9
197 #define NBC 0xD
198 #define NHC 0xF
199
200 /*field conditions */
201 #define XEQ 0x1
202 #define XLT 0x2
203 #define XOD 0x3
204 #define XTR 0x4
205 #define XNE 0x5
206 #define XGE 0x6
207 #define XEV 0x7
208
209
210
211 /*
212 * These macros are designed to be portable to all machines that have
213 * a wordsize greater than or equal to 32 bits that support the portable
214 * C compiler and the standard C preprocessor. Wordsize (default 32)
215 * and bitfield assignment (default left-to-right, unlike VAX, PDP-11)
216 * should be predefined using the constants HOSTWDSZ and BITFRL and
217 * the C compiler "-D" flag (e.g., -DHOSTWDSZ=36 -DBITFLR for the DEC-20).
218 * Note that the macro arguments assume that the integer being referenced
219 * is a 32-bit integer (right-justified on the 20) and that bit 0 is the
220 * most significant bit.
221 */
222
223 #ifndef HOSTWDSZ
224 #define HOSTWDSZ 32
225 #endif
226
227 #ifdef vax
228 #ifndef BITFLR
229 #define BITFRL
230 #endif
231 #else
232 #define BITFLR
233 #endif
234
235 /*########################### Macros ######################################*/
236
237 /*---------------------------------------------------------------------------
238 * DeclareBitfield$Reference - Declare a structure to be used to reference
239 * a specified bitfield within an integer (using BitfR, see below).
240 * The argument "n" must be an identifier name not used elsewhere in the
241 * program , "s" and "l" must (alas!) be constants. (Suggestion: if
242 * "s" == 2 and "l" == 8, use _b28 for "n".) The name "BITFLR" should
243 * be pre-defined if the compiler assigns bitfields from left-to-right.
244 * The resultant macro expansion defines a structure in which the bit field
245 * starting at position "s" with length "l" may be referenced by accessing
246 * member "n". [Note: The leftmost bits in a 36-bit word may be accessed
247 * by specifying -4 <= s < 0 on the DEC-20.]
248 *---------------------------------------------------------------------------*/
249
250 #ifdef BITFRL
251 #define DeclBitfR(s,l,n) struct n { int:(HOSTWDSZ-(s)-(l)); unsigned n:l;} n;
252 #else
253 #define DeclBitfR(s,l,n) struct n { int:((s)+(HOSTWDSZ-32)); unsigned n:l;} n;
254 #endif
255
256 /*---------------------------------------------------------------------------
257 * Bitfield$Reference - Reference a specified bitfield within an integer.
258 * The argument "i" must be an addressable variable (i.e., not a register
259 * variable or an expression... but see BitfX below), "n" must be an
260 * identifier name declared in a DeclBitfR invocation. The resultant
261 * macro expansion references the bit field in "i" described by the
262 * DeclBitfR invocation with the same name ("n"). BitfR may be used as
263 * an lvalue or an rvalue. (i.e., either side of an assignment statement)
264 * The "s" and "l" arguments are historical and are now unused. (They
265 * correspond to the "s" and "l" arguments in DeclBitfR)
266 * Translates to a single instruction on both the VAX and the DEC-20.
267 *---------------------------------------------------------------------------*/
268 #define BitfR(i,s,l,n) (i.n.n)
269
270 /*---------------------------------------------------------------------------
271 * Bitfield$eXtract - Extract the specified field from an integer. Arguments
272 * are the same as for BitfR (except no "n"), however both "s" and "l" need
273 * no longer be constants. May only be used as an rvalue. Translates to
274 * two instructions on the VAX, three on the DEC-20.
275 *---------------------------------------------------------------------------*/
276
277 #define BitfX(i,s,l) (((i.w) >> (32-(s)-(l))) & ((1 << (l)) - 1))
278
279
280 /*---------------------------------------------------------------------------
281 * Mask$32bits - Mask the low order 32 bits of passed word. No-op on 32
282 * bit machines.
283 *---------------------------------------------------------------------------*/
284
285 #if HOSTWDSZ > 32
286 #define Mask32(x) ((x) & 0xffffffff)
287 #else
288 #define Mask32(x) (x)
289 #endif
290
291
292 /*---------------------------------------------------------------------------
293 * SignExtend$32bits - Force the high-order bits in machines with wordsize
294 * longer than 32 to match bit 0.
295 *---------------------------------------------------------------------------*/
296
297 #if HOSTWDSZ > 32
298 #define SignEx32(x) (((x) & 0x80000000) ? ((x) | ((unsigned)-1 << 32)) \
299 : Mask32(x))
300 #else
301 #define SignEx32(x) (x)
302 #endif
303
304 /**************************/
305 /* bit field declarations */
306 /**************************/
307
308 /* since the compiler complains if a structure name is declared twice, even
309 * if the declarations are identical, all DeclBitfR invocations are
310 * given here in one file. */
311
312 union insn {
313 int w;
314 DeclBitfR(0,1,_b01)
315 DeclBitfR(0,15,_b015)
316 DeclBitfR(0,16,_b016)
317 DeclBitfR(0,4,_b04)
318 DeclBitfR(0,6,_b06)
319 DeclBitfR(0,8,_b08)
320 DeclBitfR(4,1,_b41)
321 DeclBitfR(4,4,_b44)
322 DeclBitfR(6,1,_b61)
323 DeclBitfR(6,13,_b613)
324 DeclBitfR(6,15,_b615)
325 DeclBitfR(6,17,_b617)
326 DeclBitfR(6,26,_b626)
327 DeclBitfR(6,5,_b65)
328 DeclBitfR(7,1,_b71)
329 DeclBitfR(8,1,_b81)
330 DeclBitfR(8,4,_b84)
331 DeclBitfR(8,8,_b88)
332 DeclBitfR(9,1,_b91)
333 DeclBitfR(10,1,_b101)
334 DeclBitfR(11,1,_b111)
335 DeclBitfR(11,10,_b1110)
336 DeclBitfR(11,4,_b114)
337 DeclBitfR(11,5,_b115)
338 DeclBitfR(12,1,_b121)
339 DeclBitfR(12,4,_b124)
340 DeclBitfR(13,1,_b131)
341 DeclBitfR(14,1,_b141)
342 DeclBitfR(15,1,_b151)
343 DeclBitfR(16,1,_b161)
344 DeclBitfR(16,15,_b1615)
345 DeclBitfR(16,16,_b1616)
346 DeclBitfR(16,2,_b162)
347 DeclBitfR(16,3,_b163)
348 DeclBitfR(16,4,_b164)
349 DeclBitfR(16,5,_b165)
350 DeclBitfR(16,8,_b168)
351 DeclBitfR(17,1,_b171)
352 DeclBitfR(18,1,_b181)
353 DeclBitfR(18,13,_b1813)
354 DeclBitfR(18,2,_b182)
355 DeclBitfR(18,7,_b187)
356 DeclBitfR(19,1,_b191)
357 DeclBitfR(19,8,_b198)
358 DeclBitfR(19,10,_b1910)
359 DeclBitfR(20,11,_b2011)
360 DeclBitfR(20,2,_b202)
361 DeclBitfR(20,4,_b204)
362 DeclBitfR(21,10,_b2110)
363 DeclBitfR(21,2,_b212)
364 DeclBitfR(21,5,_b215)
365 DeclBitfR(22,5,_b225)
366 DeclBitfR(23,3,_b233)
367 DeclBitfR(24,1,_b241)
368 DeclBitfR(24,4,_b244)
369 DeclBitfR(24,8,_b248)
370 DeclBitfR(25,1,_b251)
371 DeclBitfR(26,1,_b261)
372 DeclBitfR(27,1,_b271)
373 DeclBitfR(27,4,_b274)
374 DeclBitfR(27,5,_b275)
375 DeclBitfR(28,1,_b281)
376 DeclBitfR(28,4,_b284)
377 DeclBitfR(29,1,_b291)
378 DeclBitfR(30,1,_b301)
379 DeclBitfR(30,2,_b302)
380 DeclBitfR(31,1,_b311)
381 };
382
383 /******************/
384 /* Word subfields */
385 /******************/
386
387 #define Sign(i) BitfR(i,0,1,_b01)
388 /* halfwords */
389 #define Hwd0(i) BitfR(i,0,16,_b016)
390 #define Hwd1sign(i) BitfR(i,16,1,_b161)
391 #define Hwd1(i) BitfR(i,16,16,_b1616)
392 /* bytes */
393 #define Byte0(i) BitfR(i,0,8,_b08)
394 #define Byte1sign(i) BitfR(i,8,1,_b81)
395 #define Byte1(i) BitfR(i,8,8,_b88)
396 #define Byte2(i) BitfR(i,16,8,_b168)
397 #define Byte3sign(i) BitfR(i,24,1,_b241)
398 #define Byte3(i) BitfR(i,24,8,_b248)
399 /* digits */
400 #define Digit0(i) BitfR(i,0,4,_b04)
401 #define Digit1(i) BitfR(i,4,4,_b44)
402 #define Digit2(i) BitfR(i,8,4,_b84)
403 #define Digit3(i) BitfR(i,12,4,_b124)
404 #define Digit4(i) BitfR(i,16,4,_b164)
405 #define Digit5(i) BitfR(i,20,4,_b204)
406 #define Digit6(i) BitfR(i,24,4,_b244)
407 #define Digit7(i) BitfR(i,28,4,_b284)
408
409 /* Wordsize definitions */
410
411 #define BIT_P_DW 64 /* bits/doubleword */
412 #define BIT_P_WD 32 /* bits/word */
413 #define BIT_P_HW 16 /* bits/halfword */
414 #define BIT_P_BYT 8 /* bits/byte */
415 #define BYT_P_DW 8 /* bytes/doubleword */
416 #define BYT_P_WD 4 /* bytes/word */
417 #define BYT_P_HW 2 /* bytes/halfword */
418
419 /* Masks */
420
421 #define WDMASK 0xffffffff /* 32-bit mask */
422 #define OFSMASK 0xffffffff /* 32-bit mask */
423 #define SIDMASK 0xffffffff /* 32-bit mask */
424 #define SIGNMASK 0x80000000 /* 32 bit word sign bit */
425
426 /* Alignments */
427
428 #define wdalign(ofs) (ofs &= ~3)
429 /*
430 * Header: /n/schirf/u/baford/CVS/mach4-parisc/kernel_unused/parisc/kdb/unasm.c,v 1.5 1994/07/21 22:32:05 mike Exp
431 *
432 * Spectrum Simulator Instruction Opcode Definitions
433 * Dan Magenheimer
434 * Computer Research Center, Hewlett-Packard Labs
435 *
436 * (c) copyright 1982
437 * (p) protected 1982
438 * The Hewlett-Packard Company
439 * Hewlett-Packard Laboratories
440 * Computer Research Center
441 * Palo Alto, California
442 *
443 * *** HP Company Confidential ***
444 *
445 * Log: unasm.c,v
446 * Revision 1.5 1994/07/21 22:32:05 mike
447 * official HP copyright notice
448 *
449 * Revision 1.4 1992/07/08 12:19:52 dalton
450 * Checkin before split to 1.0.4 release (by LBS).
451 *
452 * Revision 1.3 92/06/06 16:16:45 dalton
453 * *** empty log message ***
454 *
455 * Revision 1.2 92/06/06 15:42:28 dalton
456 * Changed include to be a path relative to hp800.
457 *
458 * Revision 1.1 92/06/06 14:05:33 dalton
459 * Initial revision
460 *
461 * Revision 1.2 91/04/14 20:29:49 osfrcs
462 * Initial version.
463 * [91/03/30 09:20:34 brezak]
464 *
465 * Revision 1.1.2.2 91/04/02 10:42:50 brezak
466 * Initial version.
467 * [91/03/30 09:20:34 brezak]
468 *
469 * Revision 1.1.1.2 91/03/30 09:20:34 brezak
470 * Initial version.
471 *
472 * Revision 6.1 89/09/06 10:39:58 burroughs
473 * Added shadow registers for gr0-gr7.
474 * gr0-7 are copied into sh0-7 whenever a trap occurs
475 * the instruction RFIR restores gr0-7 from sh0-7 and returns from
476 * interrupt.
477 * the "sh" command displays the shadow registers
478 * = sh7 0x789 works, too.
479 *
480 * Revision 6.0 89/09/01 15:46:37 15:46:37 burroughs (Greg Burroughs)
481 * baseline for pcx simple offsite
482 *
483 * Revision 5.2 87/09/02 14:30:23 14:30:23 kent
484 * separated stat gathering for indexed vs short.
485 * this will NOT work if cache hints ever get used
486 * since this field was assumed always zero
487 *
488 * Revision 5.1 87/02/27 11:12:16 11:12:16 kent (Kent McMullen)
489 * update all src to 5.1
490 *
491 * Revision 5.0 87/02/18 16:31:35 16:31:35 kent (Kent McMullen)
492 * update all revision numbers to 5.0 for release
493 *
494 * Revision 1.1 86/07/15 08:34:57 08:34:57 kent (Kent McMullen)
495 * Initial revision
496 *
497 * Revision 4.1 83/10/25 17:02:34 17:02:34 djm (Daniel J Magenheimer)
498 * First release for ACD v4
499 *
500 * Revision 3.0 83/06/13 10:24:45 djm (Daniel Magenheimer)
501 * First release for distribution
502 *
503 *
504 */
505
506 /*
507 * Changes:
508 * 01/30/90 ejf Simplify SPOPn support, now only gives assist emulation trap.
509 * 01/19/90 ejf Replace linpak instructions with just FSTQ[SX].
510 * 12/19/89 ejf Add PA89 new floating point opcode 0E.
511 * 12/18/89 ejf Change 5 ops to PA89 format.
512 * 12/01/89 ejf Move additional instructions fmas, fmaa, fld2, fst2 to ssILst
513 * 09/22/89 ejf Fix unbalanced comments.
514 */
515
516
517 /* ..and modified by hand to remove the load/store short references */
518 /* ..and modified by hand to make memory management ops conform to the
519 * requirement that all subops of a major opcode begin in the same
520 * place and have the same length */
521
522 #define LDW 0x12, 0x00, 0, 0 /* LOAD WORD */
523 #define LDWM 0x13, 0x00, 0, 0 /* LOAD WORD and MODIFY */
524 #define LDH 0x11, 0x00, 0, 0 /* LOAD HALFWORD */
525 #define LDB 0x10, 0x00, 0, 0 /* LOAD BYTE */
526 #define LDO 0x0d, 0x00, 0, 0 /* LOAD OFFSET */
527 #define STW 0x1a, 0x00, 0, 0 /* STORE WORD */
528 #define STWM 0x1b, 0x00, 0, 0 /* STORE WORD and MODIFY */
529 #define STH 0x19, 0x00, 0, 0 /* STORE HALFWORD */
530 #define STB 0x18, 0x00, 0, 0 /* STORE BYTE */
531 #define LDWX 0x03, 0x02, 19, 7 /* LOAD WORD INDEXED */
532 #define LDHX 0x03, 0x01, 19, 7 /* LOAD HALFWORD INDEXED */
533 #define LDBX 0x03, 0x00, 19, 7 /* LOAD BYTE INDEXED */
534 #define LDWAX 0x03, 0x06, 19, 7 /* LOAD WORD ABSOLUTE INDEXED */
535 #define LDCWX 0x03, 0x07, 19, 7 /* LOAD and CLEAR WORD INDEXED */
536 #define LDWS 0x03, 0x42, 19, 7 /* LOAD WORD SHORT DISP */
537 #define LDHS 0x03, 0x41, 19, 7 /* LOAD HALFWORD SHORT DISP */
538 #define LDBS 0x03, 0x40, 19, 7 /* LOAD BYTE SHORT DISP */
539 #define LDWAS 0x03, 0x46, 19, 7 /* LOAD WORD ABSOLUTE SHORT DISP */
540 #define LDCWS 0x03, 0x47, 19, 7 /* LOAD and CLEAR WORD SHORT DISP */
541 #define STWS 0x03, 0x4a, 19, 7 /* STORE WORD SHORT DISP */
542 #define STHS 0x03, 0x49, 19, 7 /* STORE HALFWORD SHORT DISP */
543 #define STBS 0x03, 0x48, 19, 7 /* STORE BYTE SHORT DISP */
544 #define STWAS 0x03, 0x4e, 19, 7 /* STORE WORD ABSOLUTE SHORT DISP */
545 #define STBYS 0x03, 0x4c, 19, 7 /* STORE BYTES SHORT DISP */
546 #define LDIL 0x08, 0x00, 0, 0 /* LOAD IMMED LEFT */
547 #define ADDIL 0x0a, 0x00, 0, 0 /* ADD IMMED LEFT */
548 #define BL 0x3a, 0x00, 16, 3 /* BRANCH [and LINK] */
549 #define GATE 0x3a, 0x01, 16, 3 /* GATEWAY */
550 #define BLR 0x3a, 0x02, 16, 3 /* BRANCH and LINK REGISTER */
551 #define BV 0x3a, 0x06, 16, 3 /* BRANCH VECTORED */
552 #define BE 0x38, 0x00, 0, 0 /* BRANCH EXTERNAL */
553 #define BLE 0x39, 0x00, 0, 0 /* BRANCH and LINK EXTERNAL */
554 #define MOVB 0x32, 0x00, 0, 0 /* MOVE and BRANCH */
555 #define MOVIB 0x33, 0x00, 0, 0 /* MOVE IMMED and BRANCH */
556 #define COMBT 0x20, 0x00, 0, 0 /* COMPARE and BRANCH if TRUE */
557 #define COMBF 0x22, 0x00, 0, 0 /* COMPARE and BRANCH if FALSE */
558 #define COMIBT 0x21, 0x00, 0, 0 /* COMPARE IMMED and BRANCH if TRUE */
559 #define COMIBF 0x23, 0x00, 0, 0 /* COMPARE IMMED and BRANCH if FALSE */
560 #define ADDBT 0x28, 0x00, 0, 0 /* ADD and BRANCH if TRUE */
561 #define ADDBF 0x2a, 0x00, 0, 0 /* ADD and BRANCH if FALSE */
562 #define ADDIBT 0x29, 0x00, 0, 0 /* ADD IMMED and BRANCH if TRUE */
563 #define ADDIBF 0x2b, 0x00, 0, 0 /* ADD IMMED and BRANCH if FALSE */
564 #define BVB 0x30, 0x00, 0, 0 /* BRANCH on VARIABLE BIT */
565 #define BB 0x31, 0x00, 0, 0 /* BRANCH on BIT */
566 #define ADD 0x02, 0x30, 20, 7 /* ADD */
567 #define ADDL 0x02, 0x50, 20, 7 /* ADD LOGICAL */
568 #define ADDO 0x02, 0x70, 20, 7 /* ADD and TRAP on OVFLO */
569 #define SH1ADD 0x02, 0x32, 20, 7 /* SHIFT 1, ADD */
570 #define SH1ADDL 0x02, 0x52, 20, 7 /* SHIFT 1, ADD LOGICAL */
571 #define SH1ADDO 0x02, 0x72, 20, 7 /* SHIFT 1, ADD and TRAP on OVFLO */
572 #define SH2ADD 0x02, 0x34, 20, 7 /* SHIFT 2, ADD */
573 #define SH2ADDL 0x02, 0x54, 20, 7 /* SHIFT 2, ADD LOGICAL */
574 #define SH2ADDO 0x02, 0x74, 20, 7 /* SHIFT 2, ADD and TRAP on OVFLO */
575 #define SH3ADD 0x02, 0x36, 20, 7 /* SHIFT 3, ADD */
576 #define SH3ADDL 0x02, 0x56, 20, 7 /* SHIFT 3, ADD LOGICAL */
577 #define SH3ADDO 0x02, 0x76, 20, 7 /* SHIFT 3, ADD and TRAP on OVFLO */
578 #define ADDC 0x02, 0x38, 20, 7 /* ADD with CARRY */
579 #define ADDCO 0x02, 0x78, 20, 7 /* ADD with CARRY and TRAP on OVFLO */
580 #define SUB 0x02, 0x20, 20, 7 /* SUBTRACT */
581 #define SUBO 0x02, 0x60, 20, 7 /* SUBTRACT and TRAP on OVFLO */
582 #define SUBB 0x02, 0x28, 20, 7 /* SUBTRACT with BORROW */
583 #define SUBBO 0x02, 0x68, 20, 7 /* SUBTRACT with BORROW and TRAP on OVFLO */
584 #define SUBT 0x02, 0x26, 20, 7 /* SUBTRACT and TRAP on COND */
585 #define SUBTO 0x02, 0x66, 20, 7 /* SUBTRACT and TRAP on COND or OVFLO */
586 #define DS 0x02, 0x22, 20, 7 /* DIVIDE STEP */
587 #define COMCLR 0x02, 0x44, 20, 7 /* COMPARE and CLEAR */
588 #define OR 0x02, 0x12, 20, 7 /* INCLUSIVE OR */
589 #define XOR 0x02, 0x14, 20, 7 /* EXCLUSIVE OR */
590 #define AND 0x02, 0x10, 20, 7 /* AND */
591 #define ANDCM 0x02, 0x00, 20, 7 /* AND COMPLEMENT */
592 #define UXOR 0x02, 0x1c, 20, 7 /* UNIT XOR */
593 #define UADDCM 0x02, 0x4c, 20, 7 /* UNIT ADD COMPLEMENT */
594 #define UADDCMT 0x02, 0x4e, 20, 7 /* UNIT ADD COMPLEMENT and TRAP on COND */
595 #define DCOR 0x02, 0x5c, 20, 7 /* DECIMAL CORRECT */
596 #define IDCOR 0x02, 0x5e, 20, 7 /* INTERMEDIATE DECIMAL CORRECT */
597 #define ADDI 0x2d, 0x00, 20, 1 /* ADD to IMMED */
598 #define ADDIO 0x2d, 0x01, 20, 1 /* ADD to IMMED and TRAP on OVFLO */
599 #define ADDIT 0x2c, 0x00, 20, 1 /* ADD to IMMED and TRAP on COND */
600 #define ADDITO 0x2c, 0x01, 20, 1 /* ADD to IMMED and TRAP on COND or OVFLO */
601 #define SUBI 0x25, 0x00, 20, 1 /* SUBTRACT from IMMED */
602 #define SUBIO 0x25, 0x01, 20, 1 /* SUBTRACT from IMMED and TRAP on OVFLO */
603 #define COMICLR 0x24, 0x00, 0, 0 /* COMPARE IMMED and CLEAR */
604 #define VSHD 0x34, 0x00, 19, 3 /* VARIABLE SHIFT DOUBLE */
605 #define SHD 0x34, 0x02, 19, 3 /* SHIFT DOUBLE */
606 #define VEXTRU 0x34, 0x04, 19, 3 /* VARIABLE EXTRACT RIGHT UNSIGNED */
607 #define VEXTRS 0x34, 0x05, 19, 3 /* VARIABLE EXTRACT RIGHT SIGNED */
608 #define EXTRU 0x34, 0x06, 19, 3 /* EXTRACT RIGHT UNSIGNED */
609 #define EXTRS 0x34, 0x07, 19, 3 /* EXTRACT RIGHT SIGNED */
610 #define VDEP 0x35, 0x01, 19, 3 /* VARIABLE DEPOSIT */
611 #define DEP 0x35, 0x03, 19, 3 /* DEPOSIT */
612 #define VDEPI 0x35, 0x05, 19, 3 /* VARIABLE DEPOSIT IMMED */
613 #define DEPI 0x35, 0x07, 19, 3 /* DEPOSIT IMMED */
614 #define ZVDEP 0x35, 0x00, 19, 3 /* ZERO and VARIABLE DEPOSIT */
615 #define ZDEP 0x35, 0x02, 19, 3 /* ZERO and DEPOSIT */
616 #define ZVDEPI 0x35, 0x04, 19, 3 /* ZERO and VARIABLE DEPOSIT IMMED */
617 #define ZDEPI 0x35, 0x06, 19, 3 /* ZERO and DEPOSIT IMMED */
618 #define BREAK 0x00, 0x00, 19, 8 /* BREAK */
619 #define RFI 0x00, 0x60, 19, 8 /* RETURN FROM INTERRUPTION */
620 #define RFIR 0x00, 0x65, 19, 8 /* RFI & RESTORE SHADOW REGISTERS */
621 #define SSM 0x00, 0x6b, 19, 8 /* SET SYSTEM MASK */
622 #define RSM 0x00, 0x73, 19, 8 /* RESET SYSTEM MASK */
623 #define MTSM 0x00, 0xc3, 19, 8 /* MOVE TO SYSTEM MASK */
624 #define LDSID 0x00, 0x85, 19, 8 /* LOAD SPACE IDENTIFIER */
625 #define MTSP 0x00, 0xc1, 19, 8 /* MOVE TO SPACE REGISTER */
626 #define MTCTL 0x00, 0xc2, 19, 8 /* MOVE TO SYSTEM CONTROL REGISTER */
627 #define MFSP 0x00, 0x25, 19, 8 /* MOVE FROM SPACE REGISTER */
628 #define MFCTL 0x00, 0x45, 19, 8 /* MOVE FROM SYSTEM CONTROL REGISTER */
629 #define SYNC 0x00, 0x20, 19, 8 /* SYNCHRONIZE DATA CACHE */
630 #define DIAG 0x05, 0x00, 0, 0 /* DIAGNOSE */
631 #define SPOP 0x04, 0x00, 0, 0 /* SPECIAL FUNCTION UNIT */
632 #define COPR 0x0c, 0x00, 0, 0 /* COPROCESSOR */
633 #define CLDWX 0x09, 0x00, 19, 4 /* COPROCESSOR LOAD WORD INDEXED */
634 #define CLDDX 0x0b, 0x00, 19, 4 /* COPROCESSOR LOAD WORD INDEXED */
635 #define CSTWX 0x09, 0x01, 19, 4 /* COPROCESSOR STORE WORD INDEXED */
636 #define CSTDX 0x0b, 0x01, 19, 4 /* COPROCESSOR STORE WORD INDEXED */
637 #define CLDWS 0x09, 0x08, 19, 4 /* COPROCESSOR LOAD WORD SHORT */
638 #define CLDDS 0x0b, 0x08, 19, 4 /* COPROCESSOR LOAD WORD SHORT */
639 #define CSTWS 0x09, 0x09, 19, 4 /* COPROCESSOR STORE WORD SHORT */
640 #define CSTDS 0x0b, 0x09, 19, 4 /* COPROCESSOR STORE WORD SHORT */
641 #define FLOAT0 0x0e, 0x00, 21, 2 /* FLOATING POINT CLASS 0 */
642 #define FLOAT1 0x0e, 0x01, 21, 2 /* FLOATING POINT CLASS 1 */
643 #define FLOAT2 0x0e, 0x02, 21, 2 /* FLOATING POINT CLASS 2 */
644 #define FLOAT3 0x0e, 0x03, 21, 2 /* FLOATING POINT CLASS 3 */
645 #define FMPYSUB 0x26, 0x00, 0, 0 /* FP MULTIPLY AND SUBTRACT */
646 #define FMPYADD 0x06, 0x00, 0, 0 /* FP MULTIPLY AND ADD/TRUNCATE */
647 #define FSTQX 0x0f, 0x01, 19, 4 /* FLOATING POINT STORE QUAD INDEXED */
648 #define FSTQS 0x0f, 0x09, 19, 4 /* FLOATING POINT STORE QUAD SHORT */
649 /* all of the following have been pushed around to conform */
650 #define PROBER 0x01, 0x46, 19, 7 /* PROBE READ ACCESS */
651 #ifdef notdef
652 #define PROBERI 0x01, 0xc6, 19, 7 /* PROBE READ ACCESS IMMEDIATE */
653 #endif
654 #define PROBEW 0x01, 0x47, 19, 7 /* PROBE WRITE ACCESS */
655 #ifdef notdef
656 #define PROBEWI 0x01, 0xc7, 19, 7 /* PROBE WRITE ACCESS IMMEDIATE */
657 #endif
658 #define LPA 0x01, 0x4d, 19, 7 /* LOAD PHYSICAL ADDRESS */
659 #define LHA 0x01, 0x4c, 19, 7 /* LOAD HASH ADDRESS */
660 #define PDTLB 0x01, 0x48, 19, 7 /* PURGE DATA TRANS LOOKASIDE BUFFER */
661 #define PITLB 0x01, 0x08, 19, 7 /* PURGE INST TRANS LOOKASIDE BUFFER */
662 #define PDTLBE 0x01, 0x49, 19, 7 /* PURGE DATA TLB ENTRY */
663 #define PITLBE 0x01, 0x09, 19, 7 /* PURGE INST TLB ENTRY */
664 #define IDTLBA 0x01, 0x41, 19, 7 /* INSERT DATA TLB ADDRESS */
665 #define IITLBA 0x01, 0x01, 19, 7 /* INSERT INSTRUCTION TLB ADDRESS */
666 #define IDTLBP 0x01, 0x40, 19, 7 /* INSERT DATA TLB PROTECTION */
667 #define IITLBP 0x01, 0x00, 19, 7 /* INSERT INSTRUCTION TLB PROTECTION */
668 #define PDC 0x01, 0x4e, 19, 7 /* PURGE DATA CACHE */
669 #define FDC 0x01, 0x4a, 19, 7 /* FLUSH DATA CACHE */
670 #define FIC 0x01, 0x0a, 19, 7 /* FLUSH INSTRUCTION CACHE */
671 #define FDCE 0x01, 0x4b, 19, 7 /* FLUSH DATA CACHE ENTRY */
672 #define FICE 0x01, 0x0b, 19, 7 /* FLUSH DATA CACHE ENTRY */
673
674 /*
675 * Header: /n/schirf/u/baford/CVS/mach4-parisc/kernel_unused/parisc/kdb/unasm.c,v 1.5 1994/07/21 22:32:05 mike Exp
676 *
677 * Spectrum Simulator Instruction Set Constants and Datatypes
678 * Dan Magenheimer - 4/28/82
679 * Computer Research Center, Hewlett-Packard Labs
680 *
681 * (c) copyright 1982
682 * (p) protected 1982
683 * The Hewlett-Packard Company
684 * Hewlett-Packard Laboratories
685 * Computer Research Center
686 * Palo Alto, California
687 *
688 * *** HP Company Confidential ***
689 *
690 * Log: unasm.c,v
691 * Revision 1.5 1994/07/21 22:32:05 mike
692 * official HP copyright notice
693 *
694 * Revision 1.4 1992/07/08 12:19:52 dalton
695 * Checkin before split to 1.0.4 release (by LBS).
696 *
697 * Revision 1.3 92/06/06 16:16:45 dalton
698 * *** empty log message ***
699 *
700 * Revision 1.2 92/06/06 15:42:28 dalton
701 * Changed include to be a path relative to hp800.
702 *
703 * Revision 1.1 92/06/06 14:05:33 dalton
704 * Initial revision
705 *
706 * Revision 1.2 91/04/14 20:29:49 osfrcs
707 * Initial version.
708 * [91/03/30 09:20:34 brezak]
709 *
710 * Revision 1.1.2.2 91/04/02 10:42:50 brezak
711 * Initial version.
712 * [91/03/30 09:20:34 brezak]
713 *
714 * Revision 1.1.1.2 91/03/30 09:20:34 brezak
715 * Initial version.
716 *
717 ;Revision 1.1 88/07/11 14:05:21 14:05:21 ren (Bob Naas)
718 ;Initial revision
719 ;
720 * Revision 5.1 87/02/27 11:12:23 11:12:23 kent (Kent McMullen)
721 * update all src to 5.1
722 *
723 * Revision 5.0 87/02/18 16:31:52 16:31:52 kent (Kent McMullen)
724 * update all revision numbers to 5.0 for release
725 *
726 * Revision 1.1 86/07/15 08:35:00 08:35:00 kent (Kent McMullen)
727 * Initial revision
728 *
729 * Revision 4.3 85/11/12 09:28:44 09:28:44 viggy (Viggy Mokkarala)
730 * first mpsim version, partially stable
731 *
732 * Revision 4.2 84/07/16 17:20:57 17:20:57 djm ()
733 * Define field macros for COPR and SFU insts
734 *
735 * Revision 4.1 83/10/25 17:10:14 djm (Daniel Magenheimer)
736 * First release for ACD v4
737 *
738 * Revision 3.1 83/08/03 14:09:59 djm (Daniel Magenheimer)
739 * Sys calls, args, -S, bug fixes, etc.
740 *
741 * Revision 3.0 83/06/13 10:25:13 djm (Daniel Magenheimer)
742 * First release for distribution
743 *
744 *
745 */
746 /*
747 * Changes:
748 * 12/01/89 ejf Add Rsd(), Rse(), Rtd(), Rte() for 5 ops.
749 * 11/30/89 ejf Make instruction use counters shared, not per CPU.
750 * 11/28/89 ejf Change majoropcode for quicker extension extract.
751 */
752
753
754
755 /*
756 * Dependencies: std.h, ssDefs.h, bits.h
757 */
758
759
760 /* Lookup/Execute structure for instructions */
761 struct inst {
762 u_char majopc; /* major opcode of instruction, 0..MAXOPC */
763 u_char opcext; /* opcode extension, 0 if not applic. */
764 u_char extbs; /* starting bit pos of extension field */
765 u_char extbl; /* bit length of extension field */
766 u_int count; /* frequency counter for analysis */
767 char mnem[8]; /* ascii mnemonic */
768 /* disassembly function */
769 int (*dasmfcn)(const struct inst *, OFS, union insn);
770 };
771
772
773 #define NMAJOPCS 64
774
775 struct majoropcode {
776 const struct inst **subops; /* pointer to table of subops indexed by
777 * opcode extension */
778 u_int maxsubop; /* largest opcode extension value or 0 */
779 u_int extshft; /* right shift amount for extension field */
780 u_int extmask; /* post shift mask for extension field */
781 };
782
783 #define OpExt(i,m) ((i >> m->extshft) & m->extmask) /* extract opcode extension */
784
785
786 /*****************************/
787 /* Miscellaneous definitions */
788 /*****************************/
789
790 /* Load/Store Indexed Opcode Extension Cache Control */
791 #define NOACTION 0
792 #define STACKREF 1
793 #define SEQPASS 2
794 #define PREFETCH 3
795
796 /******************************/
797 /* Fields within instructions */
798 /******************************/
799
800 /* opcode */
801 #define Opcode(i) BitfR(i,0,6,_b06)
802 /* opcode true/false bit */
803 #define OpcTF(i) BitfR(i,4,1,_b41)
804 /* register sources */
805 #define Rsa(i) BitfR(i,11,5,_b115)
806 #define Rsb(i) BitfR(i,6,5,_b65)
807 #define Rsc(i) BitfR(i,27,5,_b275)
808 #define Rsd(i) BitfR(i,21,5,_b215)
809 #define Rse(i) BitfR(i,16,5,_b165)
810 /* register targets */
811 #define Rta(i) BitfR(i,11,5,_b115)
812 #define Rtb(i) BitfR(i,6,5,_b65)
813 #define Rtc(i) BitfR(i,27,5,_b275)
814 #define Rtd(i) BitfR(i,21,5,_b215)
815 #define Rte(i) BitfR(i,16,5,_b165)
816 /* 5-bit immediates (Magnitude, Sign) */
817 #define Imb5(i) BitfR(i,6,5,_b65)
818 #define Ima5M(i) BitfR(i,11,4,_b114)
819 #define Ima5S(i) BitfR(i,15,1,_b151)
820 #define Ima5A(i) BitfR(i,11,5,_b115)
821 #define Imd5(i) BitfR(i,22,5,_b225)
822 #define Imc5M(i) BitfR(i,27,4,_b274)
823 #define Imc5S(i) BitfR(i,31,1,_b311)
824 #define Imc5A(i) BitfR(i,27,5,_b275)
825 /* Other immediates */
826 #define Im21L(i) BitfR(i,18,2,_b182)
827 #define Im21H(i) BitfR(i,20,11,_b2011)
828 #define Im21M1(i) BitfR(i,16,2,_b162)
829 #define Im21M2(i) BitfR(i,11,5,_b115)
830 #define Im21S(i) BitfR(i,31,1,_b311)
831 #define Im11M(i) BitfR(i,21,10,_b2110)
832 #define Im11S(i) BitfR(i,31,1,_b311)
833 /* displacements/offsets */
834 #define DispM(i) BitfR(i,18,13,_b1813)
835 #define DispS(i) BitfR(i,31,1,_b311)
836 #define Off5(i) BitfR(i,11,5,_b115)
837 #define Off11H(i) BitfR(i,19,10,_b1910)
838 #define Off11L(i) BitfR(i,29,1,_b291)
839 #define OffS(i) BitfR(i,31,1,_b311)
840 /* miscellaneous */
841 #define Dss(i) BitfR(i,16,2,_b162)
842 #define Cond(i) BitfR(i,16,3,_b163)
843 #define Cneg(i) BitfR(i,19,1,_b191)
844 #define Cond4(i) BitfR(i,16,4,_b164) /* Cond AND Cneg */
845 #define Nu(i) BitfR(i,30,1,_b301)
846 #define SrL(i) BitfR(i,16,2,_b162)
847 #define SrH(i) BitfR(i,18,1,_b181)
848 #define ShortDisp(i) BitfR(i,19,1,_b191)
849 #define IndxShft(i) BitfR(i,18,1,_b181)
850 #define ModBefore(i) BitfR(i,18,1,_b181)
851 #define CacheCtrl(i) BitfR(i,20,2,_b202)
852 #define Modify(i) BitfR(i,26,1,_b261)
853 #define ProbeI(i) BitfR(i,18,1,_b181)
854 #define Uid(i) BitfR(i,23,3,_b233)
855 #define Sfu(i) BitfR(i,23,3,_b233)
856 #define CopExt17(i) BitfR(i,6,17,_b617)
857 #define CopExt5(i) BitfR(i,27,5,_b275)
858 #define SpopType(i) BitfR(i,21,2,_b212)
859 #define SpopExt15(i) BitfR(i,6,15,_b615)
860 #define SpopExt10(i) BitfR(i,11,10,_b1110)
861 #define SpopExt5L(i) BitfR(i,16,5,_b165)
862 #define SpopExt5(i) BitfR(i,27,5,_b275)
863 #define NoMajOpc(i) BitfR(i,6,26,_b626)
864 #define Bi1(i) BitfR(i,27,5,_b275) /* fields in BREAK */
865 #define Bi2(i) BitfR(i,6,13,_b613)
866
867 /* fragmented field collating macros */
868 #define Ima5(i) (Ima5S(i) ? Ima5M(i) | (int)(~__BITS(3,0)) : Ima5M(i))
869
870 #define Imc5(i) (Imc5S(i) ? Imc5M(i) | (int)(~__BITS(3,0)) : Imc5M(i))
871
872 #define Disp(i) (DispS(i) ? DispM(i) | (int)(~__BITS(12,0)) : DispM(i))
873
874 #define Im21(i) (Im21S(i) << 31 | Im21H(i) << 20 | Im21M1(i) << 18 | \
875 Im21M2(i) << 13 | Im21L(i) << 11)
876
877 #define Im11(i) (Im11S(i) ? Im11M(i) | (int)(~__BITS(9,0)) : Im11M(i))
878
879 #define Bdisp(i) ((OffS(i) ? (Off5(i)<<11 | Off11L(i)<<10|Off11H(i)) \
880 /* branch displacement (bytes) */ | (int)(~__BITS(15,0)) \
881 : (Off5(i)<<11|Off11L(i)<<10|Off11H(i))) << 2)
882
883 #define Cbdisp(i) ((OffS(i) ? (Off11L(i) << 10 | Off11H(i)) \
884 /* compare/branch disp (bytes) */ | (int)(~__BITS(10,0)) \
885 : Off11L(i) << 10 | Off11H(i)) << 2)
886
887 #define Sr(i) (SrH(i)<<2 | SrL(i))
888
889 /* sfu/copr */
890 #define CoprExt1(i) (CopExt17(i))
891 #define CoprExt2(i) (CopExt5(i))
892 #define CoprExt(i) ((CopExt17(i)<<5) | CopExt5(i))
893 #define Spop0Ext(i) ((SpopExt15(i)<<5) | SpopExt5(i))
894 #define Spop1Ext(i) (SpopExt15(i))
895 #define Spop2Ext(i) ((SpopExt10(i)<<5) | SpopExt5(i))
896 #define Spop3Ext(i) ((SpopExt5L(i)<<5) | SpopExt5(i))
897
898
899 /*##################### Globals - Imports ##################################*/
900
901 /* Disassembly functions */
902 int fcoprDasm(union insn, u_int, u_int);
903 const char *edDCond(u_int);
904 const char *unitDCond(u_int);
905 const char *addDCond(u_int);
906 const char *subDCond(u_int);
907 int blDasm(const struct inst *, OFS, union insn);
908 int ldDasm(const struct inst *, OFS, union insn);
909 int stDasm(const struct inst *, OFS, union insn);
910 int addDasm(const struct inst *, OFS, union insn);
911 int unitDasm(const struct inst *, OFS, union insn);
912 int iaDasm(const struct inst *, OFS, union insn);
913 int shdDasm(const struct inst *, OFS, union insn);
914 int extrDasm(const struct inst *, OFS, union insn);
915 int vextrDasm(const struct inst *, OFS, union insn);
916 int depDasm(const struct inst *, OFS, union insn);
917 int vdepDasm(const struct inst *, OFS, union insn);
918 int depiDasm(const struct inst *, OFS, union insn);
919 int vdepiDasm(const struct inst *, OFS, union insn);
920 int limmDasm(const struct inst *, OFS, union insn);
921 int brkDasm(const struct inst *, OFS, union insn);
922 int lpkDasm(const struct inst *, OFS, union insn);
923 int fmpyaddDasm(const struct inst *, OFS, union insn);
924 int fmpysubDasm(const struct inst *, OFS, union insn);
925 int floatDasm(const struct inst *, OFS, union insn);
926 int coprDasm(const struct inst *, OFS, union insn);
927 int diagDasm(const struct inst *, OFS, union insn);
928 int scDasm(const struct inst *, OFS, union insn);
929 int mmgtDasm(const struct inst *, OFS, union insn);
930 int ldxDasm(const struct inst *, OFS, union insn);
931 int stsDasm(const struct inst *, OFS, union insn);
932 int stbysDasm(const struct inst *, OFS, union insn);
933 int brDasm(const struct inst *, OFS, union insn);
934 int bvDasm(const struct inst *, OFS, union insn);
935 int beDasm(const struct inst *, OFS, union insn);
936 int cbDasm(const struct inst *, OFS, union insn);
937 int cbiDasm(const struct inst *, OFS, union insn);
938 int bbDasm(const struct inst *, OFS, union insn);
939 int ariDasm(const struct inst *, OFS, union insn);
940
941 /*##################### Globals - Exports ##################################*/
942 /*##################### Local Variables ####################################*/
943
944 static const char fcoprUndef[] = "copr\t(rsvd or undef.)";
945 static const char fmtStrTbl[][5] = { "sgl", "dbl", "sgl", "quad" };
946 static const char condStrTbl[][7] = {
947 "false?", "false", "?", "!<=>", "=", "=t", "?=", "!<>",
948 "!?>=", "<", "?<", "!>=", "!?>", "<=", "?<=", "!>",
949 "!?<=", ">", "?>", "!<=", "!?<", ">=", "?>=", "!<",
950 "!?=", "<>", "!=", "!=t", "!?", "<=>", "true?", "true"
951 };
952 static const char fsreg[][5] = {
953 "r0L", "r0R", "r1L", "r1R", "r2L", "r2R", "r3L", "r3R",
954 "r4L", "r4R", "r5L", "r5R", "r6L", "r6R", "r7L", "r7R",
955 "r8L", "r8R", "r9L", "r9R", "r10L", "r10R", "r11L", "r11R",
956 "r12L", "r12R", "r13L", "r13R", "r14L", "r14R", "r15L", "r15R",
957 "r16L", "r16R", "r17L", "r17R", "r18L", "r18R", "r19L", "r19R",
958 "r20L", "r20R", "r21L", "r21R", "r22L", "r22R", "r23L", "r23R",
959 "r24L", "r24R", "r25L", "r25R", "r26L", "r26R", "r27L", "r27R",
960 "r28L", "r28R", "r29L", "r29R", "r30L", "r30R", "r31L", "r31R"
961 };
962 static const char fdreg[][4] = {
963 "r0", "r0", "r1", "r1", "r2", "r2", "r3", "r3",
964 "r4", "r4", "r5", "r5", "r6", "r6", "r7", "r7",
965 "r8", "r8", "r9", "r9", "r10", "r10", "r11", "r11",
966 "r12", "r12", "r13", "r13", "r14", "r14", "r15", "r15",
967 "r16", "r16", "r17", "r17", "r18", "r18", "r19", "r19",
968 "r20", "r20", "r21", "r21", "r22", "r22", "r23", "r23",
969 "r24", "r24", "r25", "r25", "r26", "r26", "r27", "r27",
970 "r28", "r28", "r29", "r29", "r30", "r30", "r31", "r31"
971 };
972
973 /*##################### Macros #############################################*/
974
975 #define Match(s) (strncmp(s,i->mnem,sizeof(s)-1) == 0)
976
977 /* bits for assist ops */
978 #define AstNu(w) Modify(w)
979 #define Fpi(w) (Uid(w)>3)
980
981 /* bits for 5 ops */
982 #define SinglePrec(i) Modify(i)
983 #define Ms1(i) ((Rsb(i)<<1)+(SinglePrec(i)?((Rsb(i)>15)?1:32):0))
984 #define Ms2(i) ((Rsa(i)<<1)+(SinglePrec(i)?((Rsa(i)>15)?1:32):0))
985 #define Mt(i) ((Rtc(i)<<1)+(SinglePrec(i)?((Rtc(i)>15)?1:32):0))
986 #define As(i) ((Rsd(i)<<1)+(SinglePrec(i)?((Rsd(i)>15)?1:32):0))
987 #define Ad(i) ((Rte(i)<<1)+(SinglePrec(i)?((Rte(i)>15)?1:32):0))
988
989 /*##################### Globals - Exports ##################################*/
990
991 /* To replace instr function, do the following: */
992 /* a) locate the desired entry in instrs[] below */
993 /* b) change the 3rd field if an alternate mnemonic is */
994 /* desired for window disassembly */
995 /* c) change the 4th field to the name of the function being */
996 /* used for replacement (i.e. ldwRepl instead of ldw) */
997 /* d) change the 5th field if an alternate disassembly routine */
998 /* is desired (i.e. ldDasmRepl) */
999
1000 static const struct inst instrs[] = {
1001 { LDW, 0, "ldw", ldDasm },
1002 { LDH, 0, "ldh", ldDasm },
1003 { LDB, 0, "ldb", ldDasm },
1004 { LDWM, 0, "ldwm", ldDasm },
1005 { LDO, 0, "ldo", ldDasm },
1006 { STW, 0, "stw", stDasm },
1007 { STH, 0, "sth", stDasm },
1008 { STB, 0, "stb", stDasm },
1009 { STWM, 0, "stwm", stDasm },
1010 { LDWX, 0, "ldw", ldxDasm },
1011 { LDHX, 0, "ldh", ldxDasm },
1012 { LDBX, 0, "ldb", ldxDasm },
1013 { LDCWX, 0, "ldcw", ldxDasm },
1014 { LDWAX, 0, "ldwa", ldxDasm },
1015 { LDWS, 0, "ldw", ldxDasm },
1016 { LDHS, 0, "ldh", ldxDasm },
1017 { LDBS, 0, "ldb", ldxDasm },
1018 { LDCWS, 0, "ldcw", ldxDasm },
1019 { LDWAS, 0, "ldwa", ldxDasm },
1020 { STWS, 0, "stws", stsDasm },
1021 { STHS, 0, "sths", stsDasm },
1022 { STBS, 0, "stbs", stsDasm },
1023 { STWAS, 0, "stwas", stsDasm },
1024 { STBYS, 0, "stbys", stbysDasm },
1025 { LDIL, 0, "ldil", limmDasm },
1026 { ADDIL, 0, "addil", limmDasm },
1027 { GATE, 0, "gate", blDasm },
1028 { BL, 0, "b", blDasm },
1029 { BLR, 0, "blr", brDasm },
1030 { BV, 0, "bv", bvDasm },
1031 { BE, 0, "be", beDasm },
1032 { BLE, 0, "ble", beDasm },
1033 { COMBT, 0, "combt", cbDasm },
1034 { COMBF, 0, "combf", cbDasm },
1035 { COMIBT, 0, "comibt", cbiDasm },
1036 { COMIBF, 0, "comibf", cbiDasm },
1037 { ADDBT, 0, "addbt", cbDasm },
1038 { ADDBF, 0, "addbf", cbDasm },
1039 { ADDIBT, 0, "addibt", cbiDasm },
1040 { ADDIBF, 0, "addibf", cbiDasm },
1041 { MOVB, 0, "movb", cbDasm },
1042 { MOVIB, 0, "movib", cbiDasm },
1043 { BB, 0, "bb", bbDasm },
1044 { BVB, 0, "bvb", bbDasm },
1045 { SUBO, 0, "subo", ariDasm },
1046 { ADD, 0, "add", addDasm },
1047 { ADDL, 0, "addl", addDasm },
1048 { ADDO, 0, "addo", ariDasm },
1049 { SH1ADD, 0, "sh1add", ariDasm },
1050 { SH1ADDL,0, "sh1addl", ariDasm },
1051 { SH1ADDO,0, "sh1addo", ariDasm },
1052 { SH2ADD, 0, "sh2add", ariDasm },
1053 { SH2ADDL,0, "sh2addl", ariDasm },
1054 { SH2ADDO,0, "sh2addo", ariDasm },
1055 { SH3ADD, 0, "sh3add", ariDasm },
1056 { SH3ADDL,0, "sh3addl", ariDasm },
1057 { SH3ADDO,0, "sh3addo", ariDasm },
1058 { SUB, 0, "sub", ariDasm },
1059 { ADDCO, 0, "addco", ariDasm },
1060 { SUBBO, 0, "subbo", ariDasm },
1061 { ADDC, 0, "addc", ariDasm },
1062 { SUBB, 0, "subb", ariDasm },
1063 { COMCLR, 0, "comclr", ariDasm },
1064 { OR, 0, "or", ariDasm },
1065 { AND, 0, "and", ariDasm },
1066 { XOR, 0, "xor", ariDasm },
1067 { ANDCM, 0, "andcm", ariDasm },
1068 { DS, 0, "ds", ariDasm },
1069 { UXOR, 0, "uxor", unitDasm },
1070 { UADDCM, 0, "uaddcm", unitDasm },
1071 { UADDCMT,0, "uaddcmt", unitDasm },
1072 { SUBTO, 0, "subto", ariDasm },
1073 { SUBT, 0, "subt", ariDasm },
1074 { DCOR, 0, "dcor", unitDasm },
1075 { IDCOR, 0, "idcor", unitDasm },
1076 { ADDIO, 0, "addio", iaDasm },
1077 { SUBIO, 0, "subio", iaDasm },
1078 { ADDI, 0, "addi", iaDasm },
1079 { SUBI, 0, "subi", iaDasm },
1080 { COMICLR,0, "comiclr", iaDasm },
1081 { ADDITO, 0, "addito", iaDasm },
1082 { ADDIT, 0, "addit", iaDasm },
1083 { SHD, 0, "shd", shdDasm },
1084 { VSHD, 0, "vshd", shdDasm },
1085 { EXTRU, 0, "extru", extrDasm },
1086 { EXTRS, 0, "extrs", extrDasm },
1087 { VEXTRU, 0, "vextru", vextrDasm },
1088 { VEXTRS, 0, "vextrs", vextrDasm },
1089 { DEP, 0, "dep", depDasm },
1090 { VDEP, 0, "vdep", vdepDasm },
1091 { DEPI, 0, "depi", depiDasm },
1092 { VDEPI, 0, "vdepi", vdepiDasm },
1093 { ZDEP, 0, "zdep", depDasm },
1094 { ZVDEP, 0, "zvdep", vdepDasm },
1095 { ZDEPI, 0, "zdepi", depiDasm },
1096 { ZVDEPI, 0, "zvdepi", vdepiDasm },
1097 { BREAK, 0, "break", brkDasm },
1098 { RFI, 0, "rfi", 0 },
1099 { RFIR, 0, "rfir", 0 },
1100 { SSM, 0, "ssm", scDasm },
1101 { RSM, 0, "rsm", scDasm },
1102 { MTSM, 0, "mtsm", scDasm },
1103 { PROBER, 0, "prober", mmgtDasm },
1104 { PROBEW, 0, "probew", mmgtDasm },
1105 { LPA, 0, "lpa", mmgtDasm },
1106 { LHA, 0, "lha", mmgtDasm },
1107 { LDSID, 0, "ldsid", scDasm },
1108 { PDTLB, 0, "pdtlb", mmgtDasm },
1109 { PDTLBE, 0, "pdtlbe", mmgtDasm },
1110 { PITLB, 0, "pitlb", mmgtDasm },
1111 { PITLBE, 0, "pitlbe", mmgtDasm },
1112 { IDTLBA, 0, "idtlba", mmgtDasm },
1113 { IITLBA, 0, "iitlba", mmgtDasm },
1114 { IDTLBP, 0, "idtlbp", mmgtDasm },
1115 { IITLBP, 0, "iitlbp", mmgtDasm },
1116 { FIC, 0, "fic", mmgtDasm },
1117 { FICE, 0, "fice", mmgtDasm },
1118 { PDC, 0, "pdc", mmgtDasm },
1119 { FDC, 0, "fdc", mmgtDasm },
1120 { FDCE, 0, "fdce", mmgtDasm },
1121 { SYNC, 0, "sync", 0 },
1122 { MTSP, 0, "mtsp", scDasm },
1123 { MTCTL, 0, "mtctl", scDasm },
1124 { MFSP, 0, "mfsp", scDasm },
1125 { MFCTL, 0, "mfctl", scDasm },
1126 { DIAG, 0, "diag", diagDasm },
1127 { SPOP, 0, "???", 0 },
1128 { COPR, 0, "copr", coprDasm },
1129 { CLDWX, 0, "cldw", coprDasm },
1130 { CLDDX, 0, "cldd", coprDasm },
1131 { CSTWX, 0, "cstw", coprDasm },
1132 { CSTDX, 0, "cstd", coprDasm },
1133 { CLDWS, 0, "cldw", coprDasm },
1134 { CLDDS, 0, "cldd", coprDasm },
1135 { CSTWS, 0, "cstw", coprDasm },
1136 { CSTDS, 0, "cstd", coprDasm },
1137 { FLOAT0, 0, "f", floatDasm },
1138 { FLOAT1, 0, "fcnv", floatDasm },
1139 { FLOAT2, 0, "f", floatDasm },
1140 { FLOAT3, 0, "f", floatDasm },
1141 { FMPYSUB,0, "fmpy", fmpysubDasm },
1142 { FMPYADD,0, "fmpy", fmpyaddDasm },
1143 { FSTQX, 0, "fstqx", lpkDasm },
1144 { FSTQS, 0, "fstqs", lpkDasm },
1145 { 0, 0, 0, 0, 0, "", NULL}
1146 };
1147
1148
1149 static const struct inst *so_sysop[0xd0];
1150 static const struct inst *so_mmuop[0x50];
1151 static const struct inst *so_arith[0x80];
1152 static const struct inst *so_loads[0x50];
1153 static const struct inst *so_cldw [0x0A];
1154 static const struct inst *so_cldd [0x0A];
1155 static const struct inst *so_float[0x04];
1156 static const struct inst *so_fstq [0x0A];
1157 static const struct inst *so_ebran[0x08];
1158 static const struct inst *so_addit[0x02];
1159 static const struct inst *so_addi [0x02];
1160 static const struct inst *so_subi [0x02];
1161 static const struct inst *so_shext[0x08];
1162 static const struct inst *so_deps [0x08];
1163
1164 #define ILLEG NULL
1165 #define NENTS(a) (sizeof(a)/sizeof(a[0])-1)
1166 static struct majoropcode majopcs[NMAJOPCS] = {
1167 { so_sysop, NENTS(so_sysop), 0, 0 }, /* 00 */
1168 { so_mmuop, NENTS(so_mmuop), 0, 0 }, /* 01 */
1169 { so_arith, NENTS(so_arith), 0, 0 }, /* 02 */
1170 { so_loads, NENTS(so_loads), 0, 0 }, /* 03 */
1171 { ILLEG, 1, 0, 0 }, /* 04 */
1172 { ILLEG, 1, 0, 0 }, /* 05 */
1173 { ILLEG, 1, 0, 0 }, /* 06 */
1174 { ILLEG, 1, 0, 0 }, /* 07 */
1175 { ILLEG, 1, 0, 0 }, /* 08 */
1176 { so_cldw , NENTS(so_cldw ), 0, 0 }, /* 09 */
1177 { ILLEG, 1, 0, 0 }, /* 0A */
1178 { so_cldd , NENTS(so_cldd ), 0, 0 }, /* 0B */
1179 { ILLEG, 1, 0, 0 }, /* 0C */
1180 { ILLEG, 1, 0, 0 }, /* 0D */
1181 { so_float, NENTS(so_float), 0, 0 }, /* 0E */
1182 { so_fstq , NENTS(so_fstq ), 0, 0 }, /* 0F */
1183 { ILLEG, 1, 0, 0 }, /* 10 */
1184 { ILLEG, 1, 0, 0 }, /* 11 */
1185 { ILLEG, 1, 0, 0 }, /* 12 */
1186 { ILLEG, 1, 0, 0 }, /* 13 */
1187 { ILLEG, 1, 0, 0 }, /* 14 */
1188 { ILLEG, 1, 0, 0 }, /* 15 */
1189 { ILLEG, 1, 0, 0 }, /* 16 */
1190 { ILLEG, 1, 0, 0 }, /* 17 */
1191 { ILLEG, 1, 0, 0 }, /* 18 */
1192 { ILLEG, 1, 0, 0 }, /* 19 */
1193 { ILLEG, 1, 0, 0 }, /* 1A */
1194 { ILLEG, 1, 0, 0 }, /* 1B */
1195 { ILLEG, 1, 0, 0 }, /* 1C */
1196 { ILLEG, 1, 0, 0 }, /* 1D */
1197 { ILLEG, 1, 0, 0 }, /* 1E */
1198 { ILLEG, 1, 0, 0 }, /* 1F */
1199 { ILLEG, 1, 0, 0 }, /* 20 */
1200 { ILLEG, 1, 0, 0 }, /* 21 */
1201 { ILLEG, 1, 0, 0 }, /* 22 */
1202 { ILLEG, 1, 0, 0 }, /* 23 */
1203 { ILLEG, 1, 0, 0 }, /* 24 */
1204 { so_subi , NENTS(so_subi ), 0, 0 }, /* 25 */
1205 { ILLEG, 1, 0, 0 }, /* 26 */
1206 { ILLEG, 1, 0, 0 }, /* 27 */
1207 { ILLEG, 1, 0, 0 }, /* 28 */
1208 { ILLEG, 1, 0, 0 }, /* 29 */
1209 { ILLEG, 1, 0, 0 }, /* 2A */
1210 { ILLEG, 1, 0, 0 }, /* 2B */
1211 { so_addit, NENTS(so_addit), 0, 0 }, /* 2C */
1212 { so_addi , NENTS(so_addi ), 0, 0 }, /* 2D */
1213 { ILLEG, 1, 0, 0 }, /* 2E */
1214 { ILLEG, 1, 0, 0 }, /* 2F */
1215 { ILLEG, 1, 0, 0 }, /* 30 */
1216 { ILLEG, 1, 0, 0 }, /* 31 */
1217 { ILLEG, 1, 0, 0 }, /* 32 */
1218 { ILLEG, 1, 0, 0 }, /* 33 */
1219 { so_shext, NENTS(so_shext), 0, 0 }, /* 34 */
1220 { so_deps , NENTS(so_deps ), 0, 0 }, /* 35 */
1221 { ILLEG, 1, 0, 0 }, /* 36 */
1222 { ILLEG, 1, 0, 0 }, /* 37 */
1223 { ILLEG, 1, 0, 0 }, /* 38 */
1224 { ILLEG, 1, 0, 0 }, /* 39 */
1225 { so_ebran, NENTS(so_ebran), 0, 0 }, /* 3A */
1226 { ILLEG, 1, 0, 0 }, /* 3B */
1227 { ILLEG, 1, 0, 0 }, /* 3C */
1228 { ILLEG, 1, 0, 0 }, /* 3D */
1229 { ILLEG, 1, 0, 0 }, /* 3E */
1230 { ILLEG, 1, 0, 0 }, /* 3F */
1231 };
1232 #undef NENTS
1233 #undef ILLEG
1234
1235 /*--------------------------------------------------------------------------
1236 * instruction$ExecutionInitialize - Initialize the instruction execution
1237 * data structures.
1238 *---------------------------------------------------------------------------*/
1239 static int iExInit(void);
1240 static int
iExInit(void)1241 iExInit(void)
1242 {
1243 static int unasm_initted = 0;
1244 const struct inst *i;
1245 struct majoropcode *m;
1246 u_int shft, mask;
1247
1248 if (unasm_initted)
1249 return 0;
1250
1251 /*
1252 * Determine maxsubop for each major opcode.
1253 * Also, check all instructions of a given major opcode
1254 * for consistent opcode extension field definition, and
1255 * save a converted form of this definition in the majopcs
1256 * entry for this major opcode.
1257 */
1258 for (i = &instrs[0]; *i->mnem; i++) {
1259 m = &majopcs[i->majopc];
1260 if (m->maxsubop < i->opcext) {
1261 db_printf("iExInit not enough space for opcode %d",
1262 i->majopc);
1263 return 0;
1264 }
1265 shft = 32 - i->extbs - i->extbl;
1266 mask = (1 << i->extbl) - 1;
1267 if (m->extshft || m->extmask) {
1268 if (m->extshft != shft || m->extmask != mask) {
1269 db_printf("%s - Bad instruction initialization!\n", i->mnem);
1270 return (0);
1271 }
1272 } else {
1273 m->extshft = shft;
1274 m->extmask = mask;
1275 }
1276 }
1277
1278 /*
1279 * Lastly, fill in all legal subops with the appropriate info.
1280 */
1281 for (i = &instrs[0]; *i->mnem; i++) {
1282 m = &majopcs[i->majopc];
1283 if (m->maxsubop == 1)
1284 m->subops = __UNCONST(i);
1285 else
1286 m->subops[i->opcext] = i;
1287 }
1288
1289 unasm_initted++;
1290 return (1);
1291 }
1292
1293
1294
1295 /*##################### Functions and Subroutines ##########################*/
1296
1297 /**************************************/
1298 /* Miscellaneous Disassembly Routines */
1299 /**************************************/
1300
1301 /* Add instructions */
1302 int
addDasm(const struct inst * i,OFS ofs,union insn w)1303 addDasm(const struct inst *i, OFS ofs, union insn w)
1304 {
1305 db_printf("%s\t%%r%d, %%r%d, %%r%d",addDCond(Cond4(w)),
1306 Rsa(w),Rsb(w),Rtc(w));
1307 return (1);
1308 }
1309
1310 /* Unit instructions */
1311 int
unitDasm(const struct inst * i,OFS ofs,union insn w)1312 unitDasm(const struct inst *i, OFS ofs, union insn w)
1313 {
1314 db_printf("%s", unitDCond(Cond4(w)));
1315 if (Match("dcor") || Match("idcor"))
1316 db_printf("\t%%r%d, %%r%d",Rsb(w),Rtc(w));
1317 else
1318 db_printf("\t%%r%d, %%r%d, %%r%d",Rsa(w),Rsb(w),Rtc(w));
1319 return (1);
1320 }
1321
1322 /* Immediate Arithmetic instructions */
1323 int
iaDasm(const struct inst * i,OFS ofs,union insn w)1324 iaDasm(const struct inst *i, OFS ofs, union insn w)
1325 {
1326 if (Match("addi"))
1327 db_printf("%s\t%d, %%r%d, %%r%d",
1328 addDCond(Cond4(w)),Im11(w),Rsb(w),Rta(w));
1329 else
1330 db_printf("%s\t%d, %%r%d, %%r%d",
1331 subDCond(Cond4(w)),Im11(w),Rsb(w),Rta(w));
1332 return (1);
1333 }
1334
1335 /* Shift double instructions */
1336 int
shdDasm(const struct inst * i,OFS ofs,union insn w)1337 shdDasm(const struct inst *i, OFS ofs, union insn w)
1338 {
1339 if (Match("vshd"))
1340 db_printf("%s\t%%r%d, %%r%d, %%r%d",
1341 edDCond(Cond(w)), Rsa(w),Rsb(w),Rtc(w));
1342 else
1343 db_printf("%s\t%%r%d, %%r%d, %d, %%r%d",
1344 edDCond(Cond(w)),Rsa(w),Rsb(w),31-Imd5(w),Rtc(w));
1345 return (1);
1346 }
1347
1348 /* Extract instructions */
1349 int
extrDasm(const struct inst * i,OFS ofs,union insn w)1350 extrDasm(const struct inst *i, OFS ofs, union insn w)
1351 {
1352 db_printf("%s\t%%r%d, %d, %d, %%r%d",
1353 edDCond(Cond(w)),Rsb(w),Imd5(w),32 - Rsc(w),Rta(w));
1354 return (1);
1355 }
1356
1357
1358 /* Variable extract instructions */
1359 int
vextrDasm(const struct inst * i,OFS ofs,union insn w)1360 vextrDasm(const struct inst *i, OFS ofs, union insn w)
1361 {
1362 db_printf("%s\t%%r%d, %d, %%r%d",
1363 edDCond(Cond(w)),Rsb(w),32 - Rsc(w),Rta(w));
1364 return (1);
1365 }
1366
1367
1368 /* Deposit instructions */
1369 int
depDasm(const struct inst * i,OFS ofs,union insn w)1370 depDasm(const struct inst *i, OFS ofs, union insn w)
1371 {
1372 db_printf("%s\t%%r%d, %d, %d, %%r%d",
1373 edDCond(Cond(w)),Rsa(w),31 - Imd5(w),32 - Rsc(w),Rtb(w));
1374 return (1);
1375 }
1376
1377
1378 /* Variable deposit instructions */
1379 int
vdepDasm(const struct inst * i,OFS ofs,union insn w)1380 vdepDasm(const struct inst *i, OFS ofs, union insn w)
1381 {
1382 db_printf("%s\t%%r%d, %d, %%r%d",
1383 edDCond(Cond(w)),Rsa(w),32 - Rsc(w),Rtb(w));
1384 return (1);
1385 }
1386
1387
1388 /* Deposit Immediate instructions */
1389 int
depiDasm(const struct inst * i,OFS ofs,union insn w)1390 depiDasm(const struct inst *i, OFS ofs, union insn w)
1391 {
1392 db_printf("%s\t%d, %d, %d, %%r%d",
1393 edDCond(Cond(w)),Ima5(w),31 - Imd5(w),32 - Imc5A(w),Rtb(w));
1394 return (1);
1395 }
1396
1397 /* Variable Deposit Immediate instructions */
1398 int
vdepiDasm(const struct inst * i,OFS ofs,union insn w)1399 vdepiDasm(const struct inst *i, OFS ofs, union insn w)
1400 {
1401 db_printf("%s\t%d, %d, %%r%d",edDCond(Cond(w)),Ima5(w),32-Imc5A(w),Rtb(w));
1402 return (1);
1403 }
1404
1405 /*---------------------------------------------------------------------------
1406 * conditionType$DisassembleCondition - Return a string which contains the
1407 * ascii description of the passed numeric condition.
1408 *---------------------------------------------------------------------------*/
1409
1410 const char *
subDCond(u_int cond)1411 subDCond(u_int cond)
1412 {
1413 switch(cond) {
1414 case EQZ: return(",=");
1415 case LT: return(",<");
1416 case LE: return(",<=");
1417 case LLT: return(",<<");
1418 case LLE: return(",<<=");
1419 case SV: return(",sv");
1420 case OD: return(",od");
1421 case NEQZ: return(",<>");
1422 case GE: return(",>=");
1423 case GT: return(",>");
1424 case LGE: return(",>>=");
1425 case LGT: return(",>>");
1426 case NSV: return(",nsv");
1427 case EV: return(",ev");
1428 case TR: return(",tr");
1429 case NEV: return("");
1430 default:
1431 return("subDCond: unknown condition");
1432 }
1433 }
1434
1435
1436 /*---------------------------------------------------------------------------
1437 * conditionType$DisassembleCondition - Return a string which contains the
1438 * ascii description of the passed numeric condition.
1439 *---------------------------------------------------------------------------*/
1440
1441 const char *
addDCond(u_int cond)1442 addDCond(u_int cond)
1443 {
1444 switch(cond) {
1445 case EQZ: return(",=");
1446 case LT: return(",<");
1447 case LE: return(",<=");
1448 case NUV: return(",nuv");
1449 case ZNV: return(",znv");
1450 case SV: return(",sv");
1451 case OD: return(",od");
1452 case NEQZ: return(",<>");
1453 case GE: return(",>=");
1454 case GT: return(",>");
1455 case UV: return(",uv");
1456 case VNZ: return(",vnz");
1457 case NSV: return(",nsv");
1458 case EV: return(",ev");
1459 case TR: return(",tr");
1460 case NEV: return("");
1461 default:
1462 return ("addDCond: unknown condition");
1463 }
1464 }
1465
1466 const char *
unitDCond(u_int cond)1467 unitDCond(u_int cond)
1468 {
1469 switch(cond) {
1470 case SHC: return(",shc");
1471 case SHZ: return(",shz");
1472 case SBC: return(",sbc");
1473 case SBZ: return(",sbz");
1474 case SDC: return(",sdc");
1475 case NHC: return(",nhc");
1476 case NHZ: return(",nhz");
1477 case NBC: return(",nbc");
1478 case NBZ: return(",nbz");
1479 case NDC: return(",ndc");
1480 case TR: return(",tr");
1481 case NEV: return("");
1482 default:
1483 return("unitDCond: unknown condition");
1484 }
1485 }
1486
1487 const char *
edDCond(u_int cond)1488 edDCond(u_int cond)
1489 {
1490 switch(cond) {
1491 case XOD: return(",od");
1492 case XTR: return(",tr");
1493 case XNE: return(",<>");
1494 case XLT: return(",<");
1495 case XEQ: return(",=");
1496 case XGE: return(",>=");
1497 case XEV: return(",ev");
1498 case NEV: return("");
1499 default:
1500 return("edDCond: unknown condition");
1501 }
1502 }
1503
1504
1505
1506 /****************************************/
1507 /* Format Specific Disassembly Routines */
1508 /****************************************/
1509
1510
1511 /* Load [modify] instructions */
1512 int
ldDasm(const struct inst * i,OFS ofs,union insn w)1513 ldDasm(const struct inst *i, OFS ofs, union insn w)
1514 {
1515 int d = Disp(w);
1516 char s[2];
1517
1518 s[1] = '\0';
1519 if (d < 0) {
1520 d = -d;
1521 s[0] = '-';
1522 } else
1523 s[0] = '\0';
1524
1525 if (Rsb(w) == 0 && Match("ldo")) {
1526 db_printf("ldi\t%s%X, %%r%d",s,d,Rta(w));
1527 return (1);
1528 }
1529 db_printf("%s\t%s%s%X",i->mnem,(d < 2048? "R'":""), s, d);
1530 if (Dss(w))
1531 db_printf("(%%sr%d, %%r%d), %%r%d",Dss(w),Rsb(w),Rta(w));
1532 else
1533 db_printf("(%%r%d), %%r%d",Rsb(w),Rta(w));
1534 return (1);
1535 }
1536
1537 /* Store [modify] instructions */
1538 int
stDasm(const struct inst * i,OFS ofs,union insn w)1539 stDasm(const struct inst *i, OFS ofs, union insn w)
1540 {
1541 int d = Disp(w);
1542 char s[2];
1543
1544 db_printf("\t%%r%d, ",Rta(w));
1545
1546 s[1] = '\0';
1547 if (d < 0) {
1548 d = -d;
1549 s[0] = '-';
1550 } else
1551 s[0] = '\0';
1552
1553 db_printf("%s%s%X", (d < 2048? "R'":""), s, d);
1554
1555 if (Dss(w))
1556 db_printf("(%%sr%d, %%r%d)",Dss(w),Rsb(w));
1557 else
1558 db_printf("(%%r%d)",Rsb(w));
1559 return (1);
1560 }
1561
1562 /* Load indexed instructions */
1563 int
ldxDasm(const struct inst * i,OFS ofs,union insn w)1564 ldxDasm(const struct inst *i, OFS ofs, union insn w)
1565 {
1566 const char *p;
1567
1568 if (ShortDisp(w)) {
1569 db_printf("s");
1570 if (Modify(w))
1571 db_printf(",m%s", ModBefore(w)? "b": "a");
1572 } else {
1573 db_printf("x");
1574 if (Modify(w))
1575 db_printf(",%sm", IndxShft(w)? "s":"");
1576 }
1577 switch (CacheCtrl(w)) {
1578 default:
1579 case NOACTION: p = ""; break;
1580 case STACKREF: p = ",c"; break;
1581 case SEQPASS: p = ",q"; break;
1582 case PREFETCH: p = ",p"; break;
1583 }
1584 if (ShortDisp(w))
1585 db_printf("%s\t%d", p, Ima5(w));
1586 else
1587 db_printf("%s\t%%r%d", p, Rsa(w));
1588
1589 if (Dss(w))
1590 db_printf("(%%sr%d, %%r%d), %%r%d",Dss(w),Rsb(w),Rtc(w));
1591 else
1592 db_printf("(%%r%d), %%r%d",Rsb(w),Rtc(w));
1593 return (1);
1594 }
1595
1596 /* Store short displacement instructions */
1597 int
stsDasm(const struct inst * i,OFS ofs,union insn w)1598 stsDasm(const struct inst *i, OFS ofs, union insn w)
1599 {
1600 const char *p;
1601
1602 if (Modify(w))
1603 db_printf(",m%s", ModBefore(w)? "b":"a");
1604
1605 switch (CacheCtrl(w)) {
1606 default:
1607 case NOACTION: p = ""; break;
1608 case STACKREF: p = ",c"; break;
1609 case SEQPASS: p = ",q"; break;
1610 case PREFETCH: p = ",p"; break;
1611 }
1612 db_printf("%s\t%%r%d, ", p, Rta(w));
1613 if (Dss(w))
1614 db_printf("%d(%%sr%d, %%r%d)",Imc5(w),Dss(w),Rsb(w));
1615 else
1616 db_printf("%d(%%r%d)",Imc5(w),Rsb(w));
1617 return (1);
1618 }
1619
1620 /* Store Bytes Instruction */
1621 int
stbysDasm(const struct inst * i,OFS ofs,union insn w)1622 stbysDasm(const struct inst *i, OFS ofs, union insn w)
1623 {
1624 const char *p;
1625
1626 db_printf("%s", ModBefore(w)? ",e":",b");
1627 if (Modify(w))
1628 db_printf(",m");
1629 switch (CacheCtrl(w)) {
1630 default:
1631 case NOACTION: p = ""; break;
1632 case STACKREF: p = ",f"; break;
1633 case SEQPASS: p = ",r"; break;
1634 case PREFETCH: p = ",z"; break;
1635 }
1636 db_printf("%s\t%%r%d, ", p, Rta(w));
1637 if (Dss(w))
1638 db_printf("%d(%%sr%d, %%r%d)",Imc5(w),Dss(w),Rsb(w));
1639 else
1640 db_printf("%d(%%r%d)",Imc5(w),Rsb(w));
1641 return (1);
1642 }
1643
1644 /* Long Immediate instructions */
1645 int
limmDasm(const struct inst * i,OFS ofs,union insn w)1646 limmDasm(const struct inst *i, OFS ofs, union insn w)
1647 {
1648 db_printf("\tL'%X, %%r%d", Im21(w), Rtb(w));
1649 return (1);
1650 }
1651
1652
1653 /* Branch and Link instruction(s) (Branch, too!!) */
1654 int
blDasm(const struct inst * i,OFS ofs,union insn w)1655 blDasm(const struct inst *i, OFS ofs, union insn w)
1656 {
1657 OFS tgtofs = ofs + 8 + Bdisp(w);
1658 u_int link = Rtb(w);
1659
1660 if (link && !Match("gate"))
1661 db_printf("l");
1662 if (Nu(w))
1663 db_printf(",n");
1664 db_printf("\t");
1665
1666 db_printsym((db_addr_t)tgtofs, DB_STGY_ANY, db_printf);
1667
1668 if (link || Match("gate"))
1669 db_printf(", %%r%d",link);
1670
1671 return (1);
1672 }
1673
1674 /* Branch Register instruction */
1675 int
brDasm(const struct inst * i,OFS ofs,union insn w)1676 brDasm(const struct inst *i, OFS ofs, union insn w)
1677 {
1678 db_printf("%s\t%%r%d, %%r%d", Nu(w)?",n":"", Rsa(w), Rtb(w));
1679 return (1);
1680 }
1681
1682 /* Dispatch instructions */
1683 int
bvDasm(const struct inst * i,OFS ofs,union insn w)1684 bvDasm(const struct inst *i, OFS ofs, union insn w)
1685 {
1686 db_printf("%s\t%%r%d(%%r%d)", Nu(w)?",n":"", Rsa(w), Rsb(w));
1687 return (1);
1688 }
1689
1690 /* Branch External instructions */
1691 int
beDasm(const struct inst * i,OFS ofs,union insn w)1692 beDasm(const struct inst *i, OFS ofs, union insn w)
1693 {
1694 int d = Bdisp(w);
1695 const char *p;
1696 char s[2];
1697
1698 s[1] = '\0';
1699 if (d < 0) {
1700 d = -d;
1701 s[0] = '-';
1702 } else
1703 s[0] = '\0';
1704
1705 p = Nu(w)? ",n":"";
1706 db_printf("%s\tR'%s%X(%%sr%d, %%r%d)", p,
1707 s, d, Sr(w), Rsb(w));
1708 return (1);
1709 }
1710
1711
1712 /* Compare/Add and Branch instructions */
1713 int
cbDasm(const struct inst * i,OFS ofs,union insn w)1714 cbDasm(const struct inst *i, OFS ofs, union insn w)
1715 {
1716 OFS tgtofs = ofs + 8 + Cbdisp(w);
1717
1718 if (Match("movb"))
1719 db_printf("%s", edDCond(Cond(w)));
1720 else if (Match("addb"))
1721 db_printf("%s", addDCond(Cond(w) << 1));
1722 else
1723 db_printf("%s", subDCond(Cond(w) << 1));
1724 db_printf("%s\t%%r%d, %%r%d, ", Nu(w)?",n":"", Rsa(w), Rsb(w));
1725 db_printsym((db_addr_t)tgtofs, DB_STGY_ANY, db_printf);
1726 return (1);
1727 }
1728
1729 /* Compare/Add and Branch Immediate instructions */
1730 int
cbiDasm(const struct inst * i,OFS ofs,union insn w)1731 cbiDasm(const struct inst *i, OFS ofs, union insn w)
1732 {
1733 OFS tgtofs = ofs + 8 + Cbdisp(w);
1734
1735 if (Match("movib"))
1736 db_printf("%s", edDCond(Cond(w)));
1737 else if (Match("addib"))
1738 db_printf("%s", addDCond(Cond(w) << 1));
1739 else
1740 db_printf("%s", subDCond(Cond(w) << 1));
1741 db_printf("%s\t%d, %%r%d, ", Nu(w)? ",n":"", Ima5(w), Rsb(w));
1742 db_printsym((db_addr_t)tgtofs, DB_STGY_ANY, db_printf);
1743 return (1);
1744 }
1745
1746 /* Branch on Bit instructions */
1747 int
bbDasm(const struct inst * i,OFS ofs,union insn w)1748 bbDasm(const struct inst *i, OFS ofs, union insn w)
1749 {
1750 OFS tgtofs = ofs + 8 + Cbdisp(w);
1751 const char *p;
1752
1753 db_printf("%s", edDCond(Cond(w)));
1754 p = Nu(w)? ",n":"";
1755 if (Match("bvb"))
1756 db_printf("%s\t%%r%d, ", p, Rta(w));
1757 else
1758 db_printf("%s\t%%r%d, %d, ", p, Rsa(w), Imb5(w));
1759 db_printsym((db_addr_t)tgtofs, DB_STGY_ANY, db_printf);
1760 return (1);
1761 }
1762
1763 /* Arithmetic instructions */
1764 int
ariDasm(const struct inst * i,OFS ofs,union insn w)1765 ariDasm(const struct inst *i, OFS ofs, union insn w)
1766 {
1767 if (Match("or") && Rsb(w) == 0 && Cond4(w) == NEV) {
1768 if (Rsa(w) == 0 && Rtc(w) == 0)
1769 db_printf("nop");
1770 else
1771 db_printf("copy\t%%r%d, %%r%d",Rsa(w),Rtc(w));
1772 } else
1773 db_printf("%s%s\t%%r%d, %%r%d, %%r%d", i->mnem,
1774 subDCond(Cond4(w)), Rsa(w),Rsb(w),Rtc(w));
1775 return(1);
1776 }
1777
1778 /* System control operations */
1779 int
scDasm(const struct inst * i,OFS ofs,union insn w)1780 scDasm(const struct inst *i, OFS ofs, union insn w)
1781 {
1782 if (Match("mtctl")) {
1783 if (Rtb(w) == 11)
1784 db_printf("mtsar\t%%r%d",Rsa(w));
1785 else
1786 db_printf("mtctl\t%%r%d, %%cr%d",Rsa(w),Rtb(w));
1787 return (1);
1788 }
1789 db_printf("%s", i->mnem);
1790 if (Match("ssm") || Match("rsm"))
1791 db_printf("\t%d, %%r%d",Ima5A(w),Rtc(w));
1792 else if (Match("mtsm")) db_printf("\t%%r%d",Rsa(w));
1793 else if (Match("ldprid")) db_printf("\t%%r%d",Rtc(w));
1794 else if (Match("mtsp")) db_printf("\t%%r%d, %%sr%d",Rsa(w),Sr(w));
1795 else if (Match("mfsp")) db_printf("\t%%sr%d, %%r%d",Sr(w),Rtc(w));
1796 else if (Match("mfctl")) db_printf("\t%%cr%d, %%r%d",Rsb(w),Rtc(w));
1797 else if (Match("ldsid")) {
1798 if (Dss(w))
1799 db_printf("\t(%%sr%d, %%r%d), %%r%d",Dss(w),Rsb(w),Rtc(w));
1800 else
1801 db_printf("\t(%%r%d), %%r%d",Rsb(w),Rtc(w));
1802 } else {
1803 db_printf("?????");
1804 return (0);
1805 }
1806 return (1);
1807 }
1808
1809 /* Instruction cache/tlb control instructions */
1810 int
mmgtDasm(const struct inst * i,OFS ofs,union insn w)1811 mmgtDasm(const struct inst *i, OFS ofs, union insn w)
1812 {
1813 if (Match("probe")) {
1814 if (ProbeI(w)) {
1815 if (Dss(w))
1816 db_printf("i\t(%%sr%d, %%r%d), %d, %%r%d",
1817 Dss(w),Rsb(w),Rsa(w),Rtc(w));
1818 else
1819 db_printf("i\t(%%r%d), %d, %%r%d",
1820 Rsb(w),Rsa(w),Rtc(w));
1821 } else {
1822 if (Dss(w))
1823 db_printf("\t(%%sr%d, %%r%d), %%r%d, %%r%d",
1824 Dss(w),Rsb(w),Rsa(w),Rtc(w));
1825 else
1826 db_printf("\t(%%r%d), %%r%d, %%r%d",
1827 Rsb(w),Rsa(w),Rtc(w));
1828 }
1829 }
1830 else if (Match("lha") || Match("lpa")) {
1831 if (Modify(w))
1832 db_printf(",m");
1833 if (Dss(w))
1834 db_printf("\t%%r%d(%%sr%d, %%r%d), %%r%d",
1835 Rsa(w),Dss(w),Rsb(w),Rtc(w));
1836 else
1837 db_printf("\t%%r%d(%%r%d), %%r%d",Rsa(w),Rsb(w),Rtc(w));
1838 }
1839 else if (Match("pdtlb") || Match("pdc") || Match("fdc")) {
1840 if (Modify(w)) db_printf(",m");
1841 if (Dss(w))
1842 db_printf("\t%%r%d(%%sr%d, %%r%d)",Rsa(w),Dss(w),Rsb(w));
1843 else
1844 db_printf("\t%%r%d(%%r%d)",Rsa(w),Rsb(w));
1845 }
1846 else if (Match("pitlb") || Match("fic")) {
1847 if (Modify(w))
1848 db_printf(",m");
1849 db_printf("\t%%r%d(%%sr%d, %%r%d)",Rsa(w),Sr(w),Rsb(w));
1850 }
1851 else if (Match("idtlb")) {
1852 if (Dss(w))
1853 db_printf("\t%%r%d, (%%sr%d, %%r%d)",Rsa(w),Dss(w),Rsb(w));
1854 else
1855 db_printf("\t%%r%d, (%%r%d)",Rsa(w),Rsb(w));
1856 }
1857 else if (Match("iitlb"))
1858 db_printf("\t%%r%d, (%%sr%d, %%r%d)",Rsa(w),Sr(w),Rsb(w));
1859 else {
1860 db_printf("?????");
1861 return (0);
1862 }
1863 return(1);
1864 }
1865
1866 /* break instruction */
1867 int
brkDasm(const struct inst * i,OFS ofs,union insn w)1868 brkDasm(const struct inst *i, OFS ofs, union insn w)
1869 {
1870 db_printf("\t%d, %d",Bi1(w),Bi2(w));
1871 return (1);
1872 }
1873
1874 int
floatDasm(const struct inst * i,OFS ofs,union insn w)1875 floatDasm(const struct inst *i, OFS ofs, union insn w)
1876 {
1877 u_int op1, r1, fmt, t;
1878 u_int op2, r2, dfmt;
1879 const char *p;
1880
1881 op1 = CoprExt1(w);
1882 op2 = CoprExt2(w);
1883 fmt = (op1 >> 2) & 3; /* get precision of source */
1884
1885 #define ST(r) ((fmt & 1)? fdreg[(r)]:fsreg[(r)])
1886 /*
1887 * get first (or only) source register
1888 * (independent of class)
1889 */
1890 r1 = (op1 >> 11) & 0x3e;
1891 if ((fmt & 1) == 0 && (Uid(w) & 2))
1892 r1++;
1893
1894 if (op1 & 2) { /* class 2 or 3 */
1895 /*
1896 * get second source register
1897 */
1898 r2 = (op1 >> 6) & 0x3e;
1899 if (fmt == 2)
1900 r2++;
1901
1902 if ((op1 & 1) == 0) { /* class 2 */
1903 /* Opclass 2: 2 sources, no destination */
1904 switch((op1 >> 4) & 7) {
1905 case 0:
1906 p = "cmp";
1907 break;
1908 default:
1909 db_printf("%s", fcoprUndef);
1910 return(0);
1911 }
1912 db_printf("%s,%s",p,fmtStrTbl[fmt]);
1913 db_printf(",%s\t%%f%s, %%f%s",
1914 condStrTbl[op2], ST(r1), ST(r2));
1915 return (1);
1916 }
1917 /*
1918 * get target register (class 3)
1919 */
1920 t = (op2 << 1);
1921 if ((fmt & 1) == 0 && (Uid(w) & 1))
1922 t++;
1923 /* Opclass 3: 2 sources, 1 destination */
1924 switch((op1 >> 4) & 7) {
1925 case 0: p = "add"; break;
1926 case 1: p = "sub"; break;
1927 case 2: p = (Fpi(w)) ? "mpyi" : "mpy"; break;
1928 case 3: p = "div"; break;
1929 case 4: p = "rem"; break;
1930 default: db_printf("%s", fcoprUndef); return (0);
1931 }
1932 db_printf("%s,%s", p, fmtStrTbl[fmt]);
1933 db_printf("\t%%f%s, %%f%s, %%f%s",ST(r1),ST(r2),ST(t));
1934 } else if (op1 & 1) { /* class 1 */
1935 dfmt = (op1 >> 4) & 3;
1936 #define DT(r) ((dfmt & 1)? fdreg[(r)]:fsreg[(r)])
1937
1938 /*
1939 * get target register
1940 */
1941 t = (op2 << 1);
1942 if ((dfmt & 1) == 0 && (Uid(w) & 1))
1943 t++;
1944 /* Opclass 1: 1 source, 1 destination conversions */
1945 p = &"ff\0\0xf\0\0fx\0\0fxt\0"[((op1) >> 4) & 0x0c];
1946 #if 0
1947 switch((op1 >> 6) & 3) {
1948 default:
1949 case 0: p = "ff"; break;
1950 case 1: p = "xf"; break;
1951 case 2: p = "fx"; break;
1952 case 3: p = "fxt"; break;
1953 }
1954 #endif
1955 db_printf("%s,%s", p, fmtStrTbl[fmt]);
1956 db_printf(",%s\t%%f%s, %%f%s",fmtStrTbl[dfmt],ST(r1),DT(t));
1957 } else { /* class 0 */
1958 /*
1959 * get target register
1960 */
1961 t = (op2 << 1);
1962 if ((fmt & 1) == 0 && (Uid(w) & 1))
1963 t++;
1964 /* Opclass 0: 1 source, 1 destination */
1965 switch((op1 >> 4) & 7) {
1966 case 1: p = "rsqrt"; break;
1967 case 2: p = "cpy"; break;
1968 case 3: p = "abs"; break;
1969 case 4: p = "sqrt"; break;
1970 case 5: p = "rnd"; break;
1971 default: db_printf("%s", fcoprUndef); return (0);
1972 }
1973 db_printf("%s,%s",p,fmtStrTbl[fmt]);
1974 db_printf("\t%%f%s, %%f%s",ST(r1),ST(t));
1975 }
1976 return (1);
1977 }
1978
1979 int
fcoprDasm(union insn w,u_int op1,u_int op2)1980 fcoprDasm(union insn w, u_int op1, u_int op2)
1981 {
1982 u_int r1, r2, t, fmt, dfmt;
1983 const char *p;
1984
1985 if (AstNu(w) && op1 == ((1<<4) | 2)) {
1986 if (op2 == 0 || op2 == 1 || op2 == 2) {
1987 db_printf("ftest");
1988 if (op2 == 1)
1989 db_printf(",acc");
1990 else if (op2 == 2)
1991 db_printf(",rej");
1992 return (1);
1993 }
1994 return (0);
1995 } else if (0 == op1 && 0 == op2) {
1996 db_printf("fcopr identify");
1997 return (1);
1998 }
1999 switch(op1 & 3) {
2000 case 0:
2001 /* Opclass 0: 1 source, 1 destination */
2002 r1 = (op1 >> 12) & 0x1f; t = op2; fmt = (op1 >> 2) & 3;
2003 switch((op1 >> 4) & 7) {
2004 case 1: p = "rsqrt"; break;
2005 case 2: p = "cpy"; break;
2006 case 3: p = "abs"; break;
2007 case 4: p = "sqrt"; break;
2008 case 5: p = "rnd"; break;
2009 default: db_printf("%s", fcoprUndef); return(0);
2010 }
2011 db_printf("f%s,%s\t%%fr%d, %%fr%d", p, fmtStrTbl[fmt], r1, t);
2012 break;
2013 case 1:
2014 /* Opclass 1: 1 source, 1 destination conversions */
2015 r1 = (op1 >> 12) & 0x1f; t = op2;
2016 fmt = (op1 >> 2) & 3; dfmt = (op1 >> 4) & 3;
2017 p = &"ff\0\0xf\0\0fx\0\0fxt\0"[((op1) >> 4) & 0x0c];
2018 #if 0
2019 switch((op1 >> 6) & 3) {
2020 case 0: p = "ff"; break;
2021 case 1: p = "xf"; break;
2022 case 2: p = "fx"; break;
2023 case 3: p = "fxt"; break;
2024 }
2025 #endif
2026 db_printf("fcnv%s,%s,%s\t%%fr%d, %%fr%d",
2027 p, fmtStrTbl[fmt], fmtStrTbl[dfmt], r1, t);
2028 break;
2029 case 2:
2030 /* Opclass 2: 2 sources, no destination */
2031 r1 = (op1 >> 12) & 0x1f; r2 = (op1 >> 7) & 0x1f;
2032 fmt = (op1 >> 2) & 3;
2033 switch((op1 >> 4) & 7) {
2034 case 0: p = "fcmp"; break;
2035 default: db_printf("%s", fcoprUndef); return (0);
2036 }
2037 db_printf("%s,%s,%s\t%%fr%d, %%fr%d",
2038 p,fmtStrTbl[fmt],condStrTbl[op2],r1,r2);
2039 break;
2040 case 3:
2041 /* Opclass 3: 2 sources, 1 destination */
2042 r1 = (op1 >> 12) & 0x1f; r2 = (op1 >> 7) & 0x1f; t = op2;
2043 fmt = (op1 >> 2) & 3;
2044 switch((op1 >> 4) & 7) {
2045 case 0: p = "add"; break;
2046 case 1: p = "sub"; break;
2047 case 2: p = "mpy"; break;
2048 case 3: p = "div"; break;
2049 case 4: p = "rem"; break;
2050 default: db_printf("%s", fcoprUndef); return (0);
2051 }
2052 db_printf("f%s,%s\t%%fr%d, %%fr%d, %%fr%d",
2053 p, fmtStrTbl[fmt], r1, r2, t);
2054 break;
2055 default:
2056 db_printf("%s", fcoprUndef);
2057 return(0);
2058 }
2059 return (1);
2060 }
2061
2062 int
coprDasm(const struct inst * i,OFS ofs,union insn w)2063 coprDasm(const struct inst *i, OFS ofs, union insn w)
2064 {
2065 u_int uid = Uid(w);
2066 int load = 0;
2067 const char *pfx = uid > 1 ? "c" : "f";
2068 int dreg = 0;
2069
2070 if (Match("copr")) {
2071 if (uid) {
2072 db_printf("copr,%d,0x%x",uid,CoprExt(w));
2073 if (AstNu(w))
2074 db_printf(",n");
2075 return (1);
2076 }
2077 return fcoprDasm(w, CoprExt1(w),CoprExt2(w));
2078 }
2079 if (Match("cldd")) {
2080 dreg = 1;
2081 load = 1;
2082 db_printf("%sldd",pfx);
2083 } else if (Match("cldw")) {
2084 load = 1;
2085 db_printf("%sldw",pfx);
2086 } else if (Match("cstd")) {
2087 dreg = 1;
2088 db_printf("%sstd",pfx);
2089 } else if (Match("cstw"))
2090 db_printf("%sstw",pfx);
2091 else {
2092 db_printf("copr???");
2093 return (0);
2094 }
2095 if (ShortDisp(w)) {
2096 db_printf("s");
2097 if (AstNu(w))
2098 db_printf(",m%s", ModBefore(w)?"b":"a");
2099 }
2100 else {
2101 db_printf("x");
2102 if (AstNu(w))
2103 db_printf(",%sm", IndxShft(w)?"s":"");
2104 else if (IndxShft(w))
2105 db_printf(",s");
2106 }
2107 switch (CacheCtrl(w)) {
2108 case NOACTION: break;
2109 case STACKREF: db_printf(",c"); break;
2110 case SEQPASS: db_printf(",q"); break;
2111 case PREFETCH: db_printf(",p"); break;
2112 }
2113 if (load) {
2114 const char *p;
2115
2116 if (dreg)
2117 p = fdreg[(Rtc(w)<<1)+(uid&1)];
2118 else
2119 p = fsreg[(Rtc(w)<<1)+(uid&1)];
2120
2121 if (ShortDisp(w))
2122 db_printf("\t%d",Ima5(w));
2123 else
2124 db_printf("\t%%r%d",Rsa(w));
2125 if (Dss(w))
2126 db_printf("(%%sr%d, %%r%d), %%f%s", Dss(w),Rsb(w), p);
2127 else
2128 db_printf("(%%r%d), %%f%s",Rsb(w), p);
2129 } else {
2130 const char *p;
2131
2132 if (dreg)
2133 p = fdreg[(Rsc(w)<<1)+(uid&1)];
2134 else
2135 p = fsreg[(Rsc(w)<<1)+(uid&1)];
2136
2137 if (ShortDisp(w))
2138 db_printf("\t%%f%s, %d", p, Ima5(w));
2139 else
2140 db_printf("\t%%f%s, %%r%d", p, Rta(w));
2141 if (Dss(w))
2142 db_printf("(%%sr%d, %%r%d)",Dss(w),Rsb(w));
2143 else
2144 db_printf("(%%r%d)",Rsb(w));
2145 }
2146 return (1);
2147 }
2148
2149 int
lpkDasm(const struct inst * i,OFS ofs,union insn w)2150 lpkDasm(const struct inst *i, OFS ofs, union insn w)
2151 {
2152 /*
2153 * Floating point STore Quad
2154 * Short or Indexed
2155 */
2156 if (ShortDisp(w)) {
2157 if (Modify(w))
2158 db_printf(",m%s", ModBefore(w)?"b":"a");
2159 } else {
2160 if (Modify(w))
2161 db_printf(",%sm", IndxShft(w)? "s":"");
2162 else if (IndxShft(w))
2163 db_printf(",s");
2164 }
2165 switch (CacheCtrl(w)) {
2166 case NOACTION: break;
2167 case STACKREF: db_printf(",c"); break;
2168 case SEQPASS: db_printf(",q"); break;
2169 case PREFETCH: db_printf(",p"); break;
2170 }
2171 if (ShortDisp(w))
2172 db_printf("\t%%fr%d, %d",Rsc(w),Ima5(w));
2173 else
2174 db_printf("\t%%fr%d, %%r%d",Rsc(w),Rta(w));
2175 if (Dss(w))
2176 db_printf("(%%sr%d, %%r%d)",Dss(w),Rsb(w));
2177 else
2178 db_printf("(%%r%d)",Rsb(w));
2179 return (1);
2180 }
2181
2182 int
diagDasm(const struct inst * i,OFS ofs,union insn w)2183 diagDasm(const struct inst *i, OFS ofs, union insn w)
2184 {
2185 if (0x0b0 == BitfR(w,19,8,_b198)) /* mtcpu */
2186 db_printf("mtcpu\t%%r%d, %%dr%d", Rsa(w), Rtb(w));
2187 else if (0x0d0 == BitfR(w,19,8,_b198)) /* mfcpu */
2188 db_printf("mfcpu\t%%dr%d, %%r%d", Rsb(w), Rta(w));
2189 else {
2190 db_printf("%s", i->mnem);
2191 if (Match("diag"))
2192 db_printf("\t0x%X",w.w & 0x03ffffff);
2193 else {
2194 db_printf("?????");
2195 return (0);
2196 }
2197 }
2198 return (1);
2199 }
2200
2201 int
fmpysubDasm(const struct inst * i,OFS ofs,union insn w)2202 fmpysubDasm(const struct inst *i, OFS ofs, union insn w)
2203 {
2204 if (SinglePrec(w))
2205 db_printf("sub,sgl\t%%f%s, %%f%s, %%f%s, %%f%s, %%f%s",
2206 fsreg[Ms1(w)], fsreg[Ms2(w)], fsreg[Mt(w)],
2207 fsreg[As(w)], fsreg[Ad(w)]);
2208 else
2209 db_printf("sub,dbl\t%%f%s, %%f%s, %%f%s, %%f%s, %%f%s",
2210 fdreg[Ms1(w)], fdreg[Ms2(w)], fdreg[Mt(w)],
2211 fdreg[As(w)], fdreg[Ad(w)]);
2212 return (1);
2213 }
2214
2215 int
fmpyaddDasm(const struct inst * i,OFS ofs,union insn w)2216 fmpyaddDasm(const struct inst *i, OFS ofs, union insn w)
2217 {
2218 const char
2219 *ms1 = SinglePrec(w) ? fsreg[Ms1(w)] : fdreg[Ms1(w)],
2220 *ms2 = SinglePrec(w) ? fsreg[Ms2(w)] : fdreg[Ms2(w)],
2221 *mt = SinglePrec(w) ? fsreg[Mt(w)] : fdreg[Mt(w)],
2222 *as = SinglePrec(w) ? fsreg[As(w)] : fdreg[As(w)],
2223 *ad = SinglePrec(w) ? fsreg[Ad(w)] : fdreg[Ad(w)];
2224
2225 if (Rsd(w) == 0)
2226 db_printf("\t%%fcfxt, %s, %%f%s, %%f%s, %%f%s",
2227 ((SinglePrec(w)) ? "sgl" : "dbl"), ms1, ms2, mt);
2228 else
2229 db_printf("add%s\t%%f%s, %%f%s, %%f%s, %%f%s, %%f%s",
2230 ((SinglePrec(w)) ? "sgl" : "dbl"), ms1, ms2, mt, as, ad);
2231
2232 return (1);
2233 }
2234
2235 vaddr_t
db_disasm(vaddr_t loc,bool flag)2236 db_disasm(vaddr_t loc, bool flag)
2237 {
2238 const struct inst *i;
2239 const struct majoropcode *m;
2240 u_int ext;
2241 union insn instruct;
2242 OFS ofs = loc;
2243
2244 iExInit();
2245
2246 #ifdef _KERNEL
2247 if (USERMODE(loc)) {
2248 if (copyin((void *)(loc &~ HPPA_PC_PRIV_MASK),
2249 &instruct, sizeof(instruct)))
2250 instruct.w = 0;
2251 } else
2252 #endif
2253 instruct.w = *(int *)loc;
2254
2255 m = &majopcs[Opcode(instruct)];
2256 ext = OpExt(instruct.w, m);
2257 if (ext <= m->maxsubop) {
2258 /* special hack for majopcs table layout */
2259 if (m->maxsubop == 1)
2260 i = (const struct inst *)m->subops;
2261 else
2262 i = m->subops[ext];
2263
2264 if (i) {
2265 if (i->dasmfcn != coprDasm && i->dasmfcn != diagDasm &&
2266 i->dasmfcn != ariDasm && i->dasmfcn != scDasm &&
2267 i->dasmfcn != ldDasm)
2268 db_printf("%s", i->mnem);
2269 if (i->dasmfcn)
2270 (*i->dasmfcn)(i, ofs, instruct);
2271 } else {
2272 db_printf("undefined subop");
2273 }
2274 } else
2275 db_printf("undefined");
2276
2277 db_printf("\n");
2278 return (loc + sizeof(instruct));
2279 }
2280