1a2bb96e7Sjmcp /*
2a2bb96e7Sjmcp  * CDDL HEADER START
3a2bb96e7Sjmcp  *
4a2bb96e7Sjmcp  * The contents of this file are subject to the terms of the
5a2bb96e7Sjmcp  * Common Development and Distribution License (the "License").
6a2bb96e7Sjmcp  * You may not use this file except in compliance with the License.
7a2bb96e7Sjmcp  *
8a2bb96e7Sjmcp  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9a2bb96e7Sjmcp  * or http://www.opensolaris.org/os/licensing.
10a2bb96e7Sjmcp  * See the License for the specific language governing permissions
11a2bb96e7Sjmcp  * and limitations under the License.
12a2bb96e7Sjmcp  *
13a2bb96e7Sjmcp  * When distributing Covered Code, include this CDDL HEADER in each
14a2bb96e7Sjmcp  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15a2bb96e7Sjmcp  * If applicable, add the following below this CDDL HEADER, with the
16a2bb96e7Sjmcp  * fields enclosed by brackets "[]" replaced with your own identifying
17a2bb96e7Sjmcp  * information: Portions Copyright [yyyy] [name of copyright owner]
18a2bb96e7Sjmcp  *
19a2bb96e7Sjmcp  * CDDL HEADER END
20a2bb96e7Sjmcp  */
21a2bb96e7Sjmcp 
22a2bb96e7Sjmcp /*
239d0d62adSJason Beloro  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24a2bb96e7Sjmcp  * Use is subject to license terms.
25a2bb96e7Sjmcp  */
26a2bb96e7Sjmcp 
27a2bb96e7Sjmcp /*
289d0d62adSJason Beloro  * Copyright 2009 Jason King.  All rights reserved.
29a2bb96e7Sjmcp  * Use is subject to license terms.
30f7184619SJoshua M. Clulow  * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
31a2bb96e7Sjmcp  */
32a2bb96e7Sjmcp 
33a2bb96e7Sjmcp 
34a2bb96e7Sjmcp #include <sys/byteorder.h>
35*e3ed3d33SToomas Soome #include <sys/debug.h>
36a2bb96e7Sjmcp #include <stdarg.h>
37a2bb96e7Sjmcp 
38a2bb96e7Sjmcp #if !defined(DIS_STANDALONE)
39a2bb96e7Sjmcp #include <stdio.h>
40a2bb96e7Sjmcp #endif /* DIS_STANDALONE */
41a2bb96e7Sjmcp 
42a2bb96e7Sjmcp #include "libdisasm.h"
43a2bb96e7Sjmcp #include "libdisasm_impl.h"
44a2bb96e7Sjmcp #include "dis_sparc.h"
45a2bb96e7Sjmcp #include "dis_sparc_fmt.h"
46a2bb96e7Sjmcp 
47a2bb96e7Sjmcp extern char *strncpy(char *, const char *, size_t);
48a2bb96e7Sjmcp extern size_t strlen(const char *);
49a2bb96e7Sjmcp extern int strcmp(const char *, const char *);
50a2bb96e7Sjmcp extern int strncmp(const char *, const char *, size_t);
51a2bb96e7Sjmcp extern size_t strlcat(char *, const char *, size_t);
52a2bb96e7Sjmcp extern size_t strlcpy(char *, const char *, size_t);
53a2bb96e7Sjmcp 
54a2bb96e7Sjmcp /*
55a2bb96e7Sjmcp  * This file has the functions that do all the dirty work of outputting the
56a2bb96e7Sjmcp  * disassembled instruction
57a2bb96e7Sjmcp  *
58a2bb96e7Sjmcp  * All the non-static functions follow the format_fcn (in dis_sparc.h):
59a2bb96e7Sjmcp  * Input:
60a2bb96e7Sjmcp  *	disassembler handle/context
61a2bb96e7Sjmcp  *	instruction to disassemble
62a2bb96e7Sjmcp  *	instruction definition pointer (inst_t *)
63a2bb96e7Sjmcp  *	index in the table of the instruction
64a2bb96e7Sjmcp  * Return:
65a2bb96e7Sjmcp  *	0 Success
66a2bb96e7Sjmcp  *    !0 Invalid instruction
67a2bb96e7Sjmcp  *
68a2bb96e7Sjmcp  * Generally, instructions found in the same table use the same output format
69a2bb96e7Sjmcp  * or have a few minor differences (which are described in the 'flags' field
70a2bb96e7Sjmcp  * of the instruction definition. In some cases, certain instructions differ
71a2bb96e7Sjmcp  * radically enough from those in the same table, that their own format
72a2bb96e7Sjmcp  * function is used.
73a2bb96e7Sjmcp  *
74a2bb96e7Sjmcp  * Typically each table has a unique format function defined in this file.  In
75a2bb96e7Sjmcp  * some cases (such as branches) a common one for all the tables is used.
76a2bb96e7Sjmcp  *
77a2bb96e7Sjmcp  * When adding support for new instructions, it is largely a judgement call
78a2bb96e7Sjmcp  * as to when a new format function is defined.
79a2bb96e7Sjmcp  */
80a2bb96e7Sjmcp 
81a2bb96e7Sjmcp /* The various instruction formats of a sparc instruction */
82a2bb96e7Sjmcp 
83a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
84a2bb96e7Sjmcp typedef struct format1 {
85a2bb96e7Sjmcp 	uint32_t op:2;
86a2bb96e7Sjmcp 	uint32_t disp30:30;
87a2bb96e7Sjmcp } format1_t;
88a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
89a2bb96e7Sjmcp typedef struct format1 {
90a2bb96e7Sjmcp 	uint32_t disp30:30;
91a2bb96e7Sjmcp 	uint32_t op:2;
92a2bb96e7Sjmcp } format1_t;
93a2bb96e7Sjmcp #else
94a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
95a2bb96e7Sjmcp #endif
96a2bb96e7Sjmcp 
97a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
98a2bb96e7Sjmcp typedef struct format2 {
99a2bb96e7Sjmcp 	uint32_t op:2;
100a2bb96e7Sjmcp 	uint32_t rd:5;
101a2bb96e7Sjmcp 	uint32_t op2:3;
102a2bb96e7Sjmcp 	uint32_t imm22:22;
103a2bb96e7Sjmcp } format2_t;
104a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
105a2bb96e7Sjmcp typedef struct format2 {
106a2bb96e7Sjmcp 	uint32_t imm22:22;
107a2bb96e7Sjmcp 	uint32_t op2:3;
108a2bb96e7Sjmcp 	uint32_t rd:5;
109a2bb96e7Sjmcp 	uint32_t op:2;
110a2bb96e7Sjmcp } format2_t;
111a2bb96e7Sjmcp #else
112a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
113a2bb96e7Sjmcp #endif
114a2bb96e7Sjmcp 
115a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
116a2bb96e7Sjmcp typedef struct format2a {
117a2bb96e7Sjmcp 	uint32_t op:2;
118a2bb96e7Sjmcp 	uint32_t a:1;
119a2bb96e7Sjmcp 	uint32_t cond:4;
120a2bb96e7Sjmcp 	uint32_t op2:3;
121a2bb96e7Sjmcp 	uint32_t disp22:22;
122a2bb96e7Sjmcp } format2a_t;
123a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
124a2bb96e7Sjmcp typedef struct format2a {
125a2bb96e7Sjmcp 	uint32_t disp22:22;
126a2bb96e7Sjmcp 	uint32_t op2:3;
127a2bb96e7Sjmcp 	uint32_t cond:4;
128a2bb96e7Sjmcp 	uint32_t a:1;
129a2bb96e7Sjmcp 	uint32_t op:2;
130a2bb96e7Sjmcp } format2a_t;
131a2bb96e7Sjmcp #else
132a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
133a2bb96e7Sjmcp #endif
134a2bb96e7Sjmcp 
135a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
136a2bb96e7Sjmcp typedef struct format2b {
137a2bb96e7Sjmcp 	uint32_t op:2;
138a2bb96e7Sjmcp 	uint32_t a:1;
139a2bb96e7Sjmcp 	uint32_t cond:4;
140a2bb96e7Sjmcp 	uint32_t op2:3;
141a2bb96e7Sjmcp 	uint32_t cc:2;
142a2bb96e7Sjmcp 	uint32_t p:1;
143a2bb96e7Sjmcp 	uint32_t disp19:19;
144a2bb96e7Sjmcp } format2b_t;
145a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
146a2bb96e7Sjmcp typedef struct format2b {
147a2bb96e7Sjmcp 	uint32_t disp19:19;
148a2bb96e7Sjmcp 	uint32_t p:1;
149a2bb96e7Sjmcp 	uint32_t cc:2;
150a2bb96e7Sjmcp 	uint32_t op2:3;
151a2bb96e7Sjmcp 	uint32_t cond:4;
152a2bb96e7Sjmcp 	uint32_t a:1;
153a2bb96e7Sjmcp 	uint32_t op:2;
154a2bb96e7Sjmcp } format2b_t;
155a2bb96e7Sjmcp #else
156a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
157a2bb96e7Sjmcp #endif
158a2bb96e7Sjmcp 
159a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
160a2bb96e7Sjmcp typedef struct format2c {
161a2bb96e7Sjmcp 	uint32_t op:2;
162a2bb96e7Sjmcp 	uint32_t a:1;
163a2bb96e7Sjmcp 	uint32_t cond:4;
164a2bb96e7Sjmcp 	uint32_t op2:3;
165a2bb96e7Sjmcp 	uint32_t d16hi:2;
166a2bb96e7Sjmcp 	uint32_t p:1;
167a2bb96e7Sjmcp 	uint32_t rs1:5;
168a2bb96e7Sjmcp 	uint32_t d16lo:14;
169a2bb96e7Sjmcp } format2c_t;
170a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
171a2bb96e7Sjmcp typedef struct format2c {
172a2bb96e7Sjmcp 	uint32_t d16lo:14;
173a2bb96e7Sjmcp 	uint32_t rs1:5;
174a2bb96e7Sjmcp 	uint32_t p:1;
175a2bb96e7Sjmcp 	uint32_t d16hi:2;
176a2bb96e7Sjmcp 	uint32_t op2:3;
177a2bb96e7Sjmcp 	uint32_t cond:4;
178a2bb96e7Sjmcp 	uint32_t a:1;
179a2bb96e7Sjmcp 	uint32_t op:2;
180a2bb96e7Sjmcp } format2c_t;
181a2bb96e7Sjmcp #else
182a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
183a2bb96e7Sjmcp #endif
184a2bb96e7Sjmcp 
185a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
186a2bb96e7Sjmcp typedef struct format3 {
187a2bb96e7Sjmcp 	uint32_t op:2;
188a2bb96e7Sjmcp 	uint32_t rd:5;
189a2bb96e7Sjmcp 	uint32_t op3:6;
190a2bb96e7Sjmcp 	uint32_t rs1:5;
191a2bb96e7Sjmcp 	uint32_t i:1;
192a2bb96e7Sjmcp 	uint32_t asi:8;
193a2bb96e7Sjmcp 	uint32_t rs2:5;
194a2bb96e7Sjmcp } format3_t;
195a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
196a2bb96e7Sjmcp typedef struct format3 {
197a2bb96e7Sjmcp 	uint32_t rs2:5;
198a2bb96e7Sjmcp 	uint32_t asi:8;
199a2bb96e7Sjmcp 	uint32_t i:1;
200a2bb96e7Sjmcp 	uint32_t rs1:5;
201a2bb96e7Sjmcp 	uint32_t op3:6;
202a2bb96e7Sjmcp 	uint32_t rd:5;
203a2bb96e7Sjmcp 	uint32_t op:2;
204a2bb96e7Sjmcp } format3_t;
205a2bb96e7Sjmcp #else
206a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
207a2bb96e7Sjmcp #endif
208a2bb96e7Sjmcp 
209a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
210a2bb96e7Sjmcp typedef struct format3a {
211a2bb96e7Sjmcp 	uint32_t op:2;
212a2bb96e7Sjmcp 	uint32_t rd:5;
213a2bb96e7Sjmcp 	uint32_t op3:6;
214a2bb96e7Sjmcp 	uint32_t rs1:5;
215a2bb96e7Sjmcp 	uint32_t i:1;
216a2bb96e7Sjmcp 	uint32_t simm13:13;
217a2bb96e7Sjmcp } format3a_t;
218a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
219a2bb96e7Sjmcp typedef struct format3a {
220a2bb96e7Sjmcp 	uint32_t simm13:13;
221a2bb96e7Sjmcp 	uint32_t i:1;
222a2bb96e7Sjmcp 	uint32_t rs1:5;
223a2bb96e7Sjmcp 	uint32_t op3:6;
224a2bb96e7Sjmcp 	uint32_t rd:5;
225a2bb96e7Sjmcp 	uint32_t op:2;
226a2bb96e7Sjmcp } format3a_t;
227a2bb96e7Sjmcp #else
228a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
229a2bb96e7Sjmcp #endif
230a2bb96e7Sjmcp 
231a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
232a2bb96e7Sjmcp typedef struct format3b {
233a2bb96e7Sjmcp 	uint32_t op:2;
234a2bb96e7Sjmcp 	uint32_t rd:5;
235a2bb96e7Sjmcp 	uint32_t op3:6;
236a2bb96e7Sjmcp 	uint32_t rs1:5;
237a2bb96e7Sjmcp 	uint32_t i:1;
238a2bb96e7Sjmcp 	uint32_t x:1;
239a2bb96e7Sjmcp 	uint32_t undef:6;
240a2bb96e7Sjmcp 	uint32_t shcnt:6;
241a2bb96e7Sjmcp } format3b_t;
242a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
243a2bb96e7Sjmcp typedef struct format3b {
244a2bb96e7Sjmcp 	uint32_t shcnt:6;
245a2bb96e7Sjmcp 	uint32_t undef:6;
246a2bb96e7Sjmcp 	uint32_t x:1;
247a2bb96e7Sjmcp 	uint32_t i:1;
248a2bb96e7Sjmcp 	uint32_t rs1:5;
249a2bb96e7Sjmcp 	uint32_t op3:6;
250a2bb96e7Sjmcp 	uint32_t rd:5;
251a2bb96e7Sjmcp 	uint32_t op:2;
252a2bb96e7Sjmcp } format3b_t;
253a2bb96e7Sjmcp #else
254a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
255a2bb96e7Sjmcp #endif
256a2bb96e7Sjmcp 
257a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
258a2bb96e7Sjmcp typedef struct format3c {
259a2bb96e7Sjmcp 	uint32_t op:2;
260a2bb96e7Sjmcp 	uint32_t rd:5;
261a2bb96e7Sjmcp 	uint32_t op3:6;
262a2bb96e7Sjmcp 	uint32_t cc2:1;
263a2bb96e7Sjmcp 	uint32_t cond:4;
264a2bb96e7Sjmcp 	uint32_t i:1;
265a2bb96e7Sjmcp 	uint32_t cc:2;
266a2bb96e7Sjmcp 	uint32_t simm11:11;
267a2bb96e7Sjmcp } format3c_t;
268a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
269a2bb96e7Sjmcp typedef struct format3c {
270a2bb96e7Sjmcp 	uint32_t simm11:11;
271a2bb96e7Sjmcp 	uint32_t cc:2;
272a2bb96e7Sjmcp 	uint32_t i:1;
273a2bb96e7Sjmcp 	uint32_t cond:4;
274a2bb96e7Sjmcp 	uint32_t cc2:1;
275a2bb96e7Sjmcp 	uint32_t op3:6;
276a2bb96e7Sjmcp 	uint32_t rd:5;
277a2bb96e7Sjmcp 	uint32_t op:2;
278a2bb96e7Sjmcp } format3c_t;
279a2bb96e7Sjmcp #else
280a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
281a2bb96e7Sjmcp #endif
282a2bb96e7Sjmcp 
283a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
284a2bb96e7Sjmcp typedef struct format3d {
285a2bb96e7Sjmcp 	uint32_t op:2;
286a2bb96e7Sjmcp 	uint32_t rd:5;
287a2bb96e7Sjmcp 	uint32_t op3:6;
288a2bb96e7Sjmcp 	uint32_t rs1:5;
289a2bb96e7Sjmcp 	uint32_t i:1;
290a2bb96e7Sjmcp 	uint32_t rcond:3;
291a2bb96e7Sjmcp 	uint32_t simm10:10;
292a2bb96e7Sjmcp } format3d_t;
293a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
294a2bb96e7Sjmcp typedef struct format3d {
295a2bb96e7Sjmcp 	uint32_t simm10:10;
296a2bb96e7Sjmcp 	uint32_t rcond:3;
297a2bb96e7Sjmcp 	uint32_t i:1;
298a2bb96e7Sjmcp 	uint32_t rs1:5;
299a2bb96e7Sjmcp 	uint32_t op3:6;
300a2bb96e7Sjmcp 	uint32_t rd:5;
301a2bb96e7Sjmcp 	uint32_t op:2;
302a2bb96e7Sjmcp } format3d_t;
303a2bb96e7Sjmcp #else
304a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
305a2bb96e7Sjmcp #endif
306a2bb96e7Sjmcp 
307a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
308a2bb96e7Sjmcp typedef struct formatcp {
309a2bb96e7Sjmcp 	uint32_t op:2;
310a2bb96e7Sjmcp 	uint32_t rd:5;
311a2bb96e7Sjmcp 	uint32_t op3:6;
312a2bb96e7Sjmcp 	uint32_t rs1:5;
313a2bb96e7Sjmcp 	uint32_t opc:9;
314a2bb96e7Sjmcp 	uint32_t rs2:5;
315a2bb96e7Sjmcp } formatcp_t;
316a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
317a2bb96e7Sjmcp typedef struct formatcp {
318a2bb96e7Sjmcp 	uint32_t rs2:5;
319a2bb96e7Sjmcp 	uint32_t opc:9;
320a2bb96e7Sjmcp 	uint32_t rs1:5;
321a2bb96e7Sjmcp 	uint32_t op3:6;
322a2bb96e7Sjmcp 	uint32_t rd:5;
323a2bb96e7Sjmcp 	uint32_t op:2;
324a2bb96e7Sjmcp } formatcp_t;
325a2bb96e7Sjmcp #else
326a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
327a2bb96e7Sjmcp #endif
328a2bb96e7Sjmcp 
329a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
330a2bb96e7Sjmcp typedef struct formattcc {
331a2bb96e7Sjmcp 	uint32_t op:2;
332a2bb96e7Sjmcp 	uint32_t undef:1;
333a2bb96e7Sjmcp 	uint32_t cond:4;
334a2bb96e7Sjmcp 	uint32_t op3:6;
335a2bb96e7Sjmcp 	uint32_t rs1:5;
336a2bb96e7Sjmcp 	uint32_t i:1;
337a2bb96e7Sjmcp 	uint32_t cc:2;
338a2bb96e7Sjmcp 	uint32_t undef2:3;
339a2bb96e7Sjmcp 	uint32_t immtrap:8;
340a2bb96e7Sjmcp } formattcc_t;
341a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
342a2bb96e7Sjmcp typedef struct formattcc {
343a2bb96e7Sjmcp 	uint32_t immtrap:8;
344a2bb96e7Sjmcp 	uint32_t undef2:3;
345a2bb96e7Sjmcp 	uint32_t cc:2;
346a2bb96e7Sjmcp 	uint32_t i:1;
347a2bb96e7Sjmcp 	uint32_t rs1:5;
348a2bb96e7Sjmcp 	uint32_t op3:6;
349a2bb96e7Sjmcp 	uint32_t cond:4;
350a2bb96e7Sjmcp 	uint32_t undef:1;
351a2bb96e7Sjmcp 	uint32_t op:2;
352a2bb96e7Sjmcp } formattcc_t;
353a2bb96e7Sjmcp #else
354a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
355a2bb96e7Sjmcp #endif
356a2bb96e7Sjmcp 
357a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
358a2bb96e7Sjmcp typedef struct formattcc2 {
359a2bb96e7Sjmcp 	uint32_t op:2;
360a2bb96e7Sjmcp 	uint32_t undef:1;
361a2bb96e7Sjmcp 	uint32_t cond:4;
362a2bb96e7Sjmcp 	uint32_t op3:6;
363a2bb96e7Sjmcp 	uint32_t rs1:5;
364a2bb96e7Sjmcp 	uint32_t i:1;
365a2bb96e7Sjmcp 	uint32_t cc:2;
366a2bb96e7Sjmcp 	uint32_t undef2:6;
367a2bb96e7Sjmcp 	uint32_t rs2:5;
368a2bb96e7Sjmcp } formattcc2_t;
369a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
370a2bb96e7Sjmcp typedef struct formattcc2 {
371a2bb96e7Sjmcp 	uint32_t rs2:5;
372a2bb96e7Sjmcp 	uint32_t undef2:6;
373a2bb96e7Sjmcp 	uint32_t cc:2;
374a2bb96e7Sjmcp 	uint32_t i:1;
375a2bb96e7Sjmcp 	uint32_t rs1:5;
376a2bb96e7Sjmcp 	uint32_t op3:6;
377a2bb96e7Sjmcp 	uint32_t cond:4;
378a2bb96e7Sjmcp 	uint32_t undef:1;
379a2bb96e7Sjmcp 	uint32_t op:2;
380a2bb96e7Sjmcp } formattcc2_t;
381a2bb96e7Sjmcp #else
382a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
383a2bb96e7Sjmcp #endif
384a2bb96e7Sjmcp 
385a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
386a2bb96e7Sjmcp typedef struct formatmbr {
387a2bb96e7Sjmcp 	uint32_t op:2;
388a2bb96e7Sjmcp 	uint32_t rd:5;
389a2bb96e7Sjmcp 	uint32_t op3:6;
390a2bb96e7Sjmcp 	uint32_t rs1:5;
391a2bb96e7Sjmcp 	uint32_t i:1;
3929d0d62adSJason Beloro 	uint32_t undef:6;
3939d0d62adSJason Beloro 	uint32_t cmask:3;
394a2bb96e7Sjmcp 	uint32_t mmask:4;
395a2bb96e7Sjmcp } formatmbr_t;
396a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
397a2bb96e7Sjmcp typedef struct formatmbr {
398a2bb96e7Sjmcp 	uint32_t mmask:4;
3999d0d62adSJason Beloro 	uint32_t cmask:3;
4009d0d62adSJason Beloro 	uint32_t undef:6;
401a2bb96e7Sjmcp 	uint32_t i:1;
402a2bb96e7Sjmcp 	uint32_t rs1:5;
403a2bb96e7Sjmcp 	uint32_t op3:6;
404a2bb96e7Sjmcp 	uint32_t rd:5;
405a2bb96e7Sjmcp 	uint32_t op:2;
406a2bb96e7Sjmcp } formatmbr_t;
407a2bb96e7Sjmcp #else
408a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
409a2bb96e7Sjmcp #endif
410a2bb96e7Sjmcp 
411a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
412a2bb96e7Sjmcp typedef struct formatfcmp {
413a2bb96e7Sjmcp 	uint32_t op:2;
414a2bb96e7Sjmcp 	uint32_t undef:3;
415a2bb96e7Sjmcp 	uint32_t cc:2;
416a2bb96e7Sjmcp 	uint32_t op3:6;
417a2bb96e7Sjmcp 	uint32_t rs1:5;
418a2bb96e7Sjmcp 	uint32_t opf:9;
419a2bb96e7Sjmcp 	uint32_t rs2:5;
420a2bb96e7Sjmcp } formatfcmp_t;
421a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
422a2bb96e7Sjmcp typedef struct formatfcmp {
423a2bb96e7Sjmcp 	uint32_t rs2:5;
424a2bb96e7Sjmcp 	uint32_t opf:9;
425a2bb96e7Sjmcp 	uint32_t rs1:5;
426a2bb96e7Sjmcp 	uint32_t op3:6;
427a2bb96e7Sjmcp 	uint32_t cc:2;
428a2bb96e7Sjmcp 	uint32_t undef:3;
429a2bb96e7Sjmcp 	uint32_t op:2;
430a2bb96e7Sjmcp } formatfcmp_t;
431a2bb96e7Sjmcp #else
432a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
433a2bb96e7Sjmcp #endif
434a2bb96e7Sjmcp 
435a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
436a2bb96e7Sjmcp typedef struct formatfmov {
437a2bb96e7Sjmcp 	uint32_t op:2;
438a2bb96e7Sjmcp 	uint32_t rd:5;
439a2bb96e7Sjmcp 	uint32_t op3:6;
440a2bb96e7Sjmcp 	uint32_t undef:1;
441a2bb96e7Sjmcp 	uint32_t cond:4;
442a2bb96e7Sjmcp 	uint32_t cc:3;
443a2bb96e7Sjmcp 	uint32_t opf:6;
444a2bb96e7Sjmcp 	uint32_t rs2:5;
445a2bb96e7Sjmcp } formatfmov_t;
446a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
447a2bb96e7Sjmcp typedef struct formatfmov {
448a2bb96e7Sjmcp 	uint32_t rs2:5;
449a2bb96e7Sjmcp 	uint32_t opf:6;
450a2bb96e7Sjmcp 	uint32_t cc:3;
451a2bb96e7Sjmcp 	uint32_t cond:4;
452a2bb96e7Sjmcp 	uint32_t undef:1;
453a2bb96e7Sjmcp 	uint32_t op3:6;
454a2bb96e7Sjmcp 	uint32_t rd:5;
455a2bb96e7Sjmcp 	uint32_t op:2;
456a2bb96e7Sjmcp } formatfmov_t;
457a2bb96e7Sjmcp #else
458a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
459a2bb96e7Sjmcp #endif
460a2bb96e7Sjmcp 
461a2bb96e7Sjmcp #if defined(_BIT_FIELDS_HTOL)
462a2bb96e7Sjmcp typedef struct formatfused {
463a2bb96e7Sjmcp 	uint32_t op:2;
464a2bb96e7Sjmcp 	uint32_t rd:5;
465a2bb96e7Sjmcp 	uint32_t op3:6;
466a2bb96e7Sjmcp 	uint32_t rs1:5;
467a2bb96e7Sjmcp 	uint32_t rs3:5;
468a2bb96e7Sjmcp 	uint32_t op5:4;
469a2bb96e7Sjmcp 	uint32_t rs2:5;
470a2bb96e7Sjmcp } formatfused_t;
471a2bb96e7Sjmcp #elif defined(_BIT_FIELDS_LTOH)
472a2bb96e7Sjmcp typedef struct formatfused {
473a2bb96e7Sjmcp 	uint32_t rs2:5;
474a2bb96e7Sjmcp 	uint32_t op5:4;
475a2bb96e7Sjmcp 	uint32_t rs3:5;
476a2bb96e7Sjmcp 	uint32_t rs1:5;
477a2bb96e7Sjmcp 	uint32_t op3:6;
478a2bb96e7Sjmcp 	uint32_t rd:5;
479a2bb96e7Sjmcp 	uint32_t op:2;
480a2bb96e7Sjmcp } formatfused_t;
481a2bb96e7Sjmcp #else
482a2bb96e7Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
483a2bb96e7Sjmcp #endif
484a2bb96e7Sjmcp 
485a2bb96e7Sjmcp typedef union ifmt {
486a2bb96e7Sjmcp 	uint32_t	i;
487a2bb96e7Sjmcp 	format1_t	f1;
488a2bb96e7Sjmcp 	format2_t	f2;
489a2bb96e7Sjmcp 	format2a_t	f2a;
490a2bb96e7Sjmcp 	format2b_t	f2b;
491a2bb96e7Sjmcp 	format2c_t	f2c;
492a2bb96e7Sjmcp 	format3_t	f3;
493a2bb96e7Sjmcp 	format3a_t	f3a;
494a2bb96e7Sjmcp 	format3b_t	f3b;
495a2bb96e7Sjmcp 	format3c_t	f3c;
496a2bb96e7Sjmcp 	format3d_t	f3d;
497a2bb96e7Sjmcp 	formatcp_t	fcp;
498a2bb96e7Sjmcp 	formattcc_t	ftcc;
499a2bb96e7Sjmcp 	formattcc2_t	ftcc2;
500a2bb96e7Sjmcp 	formatfcmp_t	fcmp;
501a2bb96e7Sjmcp 	formatmbr_t	fmb;
502a2bb96e7Sjmcp 	formatfmov_t	fmv;
503a2bb96e7Sjmcp 	formatfused_t	fused;
504a2bb96e7Sjmcp } ifmt_t;
505a2bb96e7Sjmcp 
506a2bb96e7Sjmcp /* integer register names */
507a2bb96e7Sjmcp static const char *reg_names[32] = {
508a2bb96e7Sjmcp 	"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
509a2bb96e7Sjmcp 	"%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",
510a2bb96e7Sjmcp 	"%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
511a2bb96e7Sjmcp 	"%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7"
512a2bb96e7Sjmcp };
513a2bb96e7Sjmcp 
514a2bb96e7Sjmcp /* floating point register names */
515a2bb96e7Sjmcp static const char *freg_names[32] = {
516a2bb96e7Sjmcp 	"%f0",  "%f1",  "%f2",  "%f3",  "%f4",  "%f5",  "%f6",  "%f7",
517a2bb96e7Sjmcp 	"%f8",  "%f9",  "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
518a2bb96e7Sjmcp 	"%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
519a2bb96e7Sjmcp 	"%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31"
520a2bb96e7Sjmcp };
521a2bb96e7Sjmcp 
522a2bb96e7Sjmcp /* double precision register names */
523a2bb96e7Sjmcp static const char *fdreg_names[32] = {
524a2bb96e7Sjmcp 	"%d0",  "%d32", "%d2",  "%d34", "%d4",  "%d36", "%d6",  "%d38",
525a2bb96e7Sjmcp 	"%d8",  "%d40", "%d10", "%d42", "%d12", "%d44", "%d14", "%d46",
526a2bb96e7Sjmcp 	"%d16", "%d48", "%d18", "%d50", "%d20", "%d52", "%d22", "%d54",
527a2bb96e7Sjmcp 	"%d24", "%d56", "%d26", "%d58", "%d28", "%d60", "%d30", "%d62"
528a2bb96e7Sjmcp };
529a2bb96e7Sjmcp 
530a2bb96e7Sjmcp static const char *compat_fdreg_names[32] = {
531a2bb96e7Sjmcp 	"%f0",  "%f32", "%f2",  "%f34", "%f4",  "%f36", "%f6",  "%f38",
532a2bb96e7Sjmcp 	"%f8",  "%f40", "%f10", "%f42", "%f12", "%f44", "%f14", "%f46",
533a2bb96e7Sjmcp 	"%f16", "%f48", "%f18", "%f50", "%f20", "%f52", "%f22", "%f54",
534a2bb96e7Sjmcp 	"%f24", "%f56", "%f26", "%f58", "%f28", "%f60", "%f30", "%f62"
535a2bb96e7Sjmcp };
536a2bb96e7Sjmcp 
537a2bb96e7Sjmcp 
538a2bb96e7Sjmcp static const char *fqreg_names[32] = {
539a2bb96e7Sjmcp 	"%q0",  "%q32", "%f2",  "%f3",  "%f4",  "%q4",  "%q36", "%f6",
540a2bb96e7Sjmcp 	"%f7",  "%q8",  "%q40", "%f10", "%f11", "%q12", "%q44", "%f14",
541a2bb96e7Sjmcp 	"%f15", "%q16", "%q48", "%f18", "%f19", "%q20", "%q52", "%f22",
542a2bb96e7Sjmcp 	"%f23", "%q24", "%q56", "%f26", "%f27", "%q28", "%q60", "%f30",
543a2bb96e7Sjmcp };
544a2bb96e7Sjmcp 
545a2bb96e7Sjmcp 
546a2bb96e7Sjmcp /* coprocessor register names -- sparcv8 only */
547a2bb96e7Sjmcp static const char *cpreg_names[32] = {
548a2bb96e7Sjmcp 	"%c0",  "%c1",  "%c2",  "%c3",  "%c4",  "%c5",  "%c6",  "%c7",
549a2bb96e7Sjmcp 	"%c8",  "%c9",  "%c10", "%c11", "%c12", "%c13", "%c14", "%c15",
550a2bb96e7Sjmcp 	"%c16", "%c17", "%c18", "%c19", "%c20", "%c21", "%c22", "%c23",
551a2bb96e7Sjmcp 	"%c24", "%c25", "%c26", "%c27", "%c28", "%c29", "%c30", "%c31",
552a2bb96e7Sjmcp };
553a2bb96e7Sjmcp 
554a2bb96e7Sjmcp /* floating point condition code names */
555a2bb96e7Sjmcp static const char *fcc_names[4] = {
556a2bb96e7Sjmcp 	"%fcc0", "%fcc1", "%fcc2", "%fcc3"
557a2bb96e7Sjmcp };
558a2bb96e7Sjmcp 
559a2bb96e7Sjmcp /* condition code names */
560a2bb96e7Sjmcp static const char *icc_names[4] = {
561a2bb96e7Sjmcp 	"%icc", NULL, "%xcc", NULL
562a2bb96e7Sjmcp };
563a2bb96e7Sjmcp 
564a2bb96e7Sjmcp /* bitmask values for membar */
565a2bb96e7Sjmcp static const char *membar_mmask[4] = {
566a2bb96e7Sjmcp 	"#LoadLoad", "#StoreLoad", "#LoadStore", "#StoreStore"
567a2bb96e7Sjmcp };
568a2bb96e7Sjmcp 
5699d0d62adSJason Beloro static const char *membar_cmask[3] = {
5709d0d62adSJason Beloro 	"#Lookaside", "#MemIssue", "#Sync"
571a2bb96e7Sjmcp };
572a2bb96e7Sjmcp 
573a2bb96e7Sjmcp /* v8 ancillary state register names */
574a2bb96e7Sjmcp static const char *asr_names[32] = {
575a2bb96e7Sjmcp 	"%y",	"%asr1",  "%asr2",  "%asr3",
576a2bb96e7Sjmcp 	"%asr4",  "%asr5",  "%asr6",  "%asr7",
577a2bb96e7Sjmcp 	"%asr8",  "%asr9",  "%asr10", "%asr11",
578a2bb96e7Sjmcp 	"%asr12", "%asr13", "%asr14", "%asr15",
579a2bb96e7Sjmcp 	NULL,	NULL,	NULL,	NULL,
580a2bb96e7Sjmcp 	NULL,	NULL,	NULL,	NULL,
581a2bb96e7Sjmcp 	NULL,	NULL,	NULL,	NULL,
582a2bb96e7Sjmcp 	NULL,	NULL,	NULL,	NULL
583a2bb96e7Sjmcp };
584a2bb96e7Sjmcp static const uint32_t asr_rdmask = 0x0000ffffL;
585a2bb96e7Sjmcp static const uint32_t asr_wrmask = 0x0000ffffL;
586a2bb96e7Sjmcp 
587a2bb96e7Sjmcp static const char *v9_asr_names[32] = {
588a2bb96e7Sjmcp 	"%y",		NULL,		"%ccr",	"%asi",
589a2bb96e7Sjmcp 	"%tick",	"%pc",		"%fprs",	NULL,
590a2bb96e7Sjmcp 	NULL,		NULL,		NULL,	NULL,
591a2bb96e7Sjmcp 	NULL,		NULL,		NULL,	NULL,
5922f0fcb93SJason Beloro 	"%pcr",		"%pic",		"%dcr",	"%gsr",
593a2bb96e7Sjmcp 	"%softint_set",	"%softint_clr",	"%softint",	"%tick_cmpr",
594a2bb96e7Sjmcp 	"%stick",	"%stick_cmpr",	NULL,	NULL,
5959d0d62adSJason Beloro 	NULL,		NULL,		NULL,	NULL
596a2bb96e7Sjmcp };
597a2bb96e7Sjmcp /*
598a2bb96e7Sjmcp  * on v9, only certain registers are valid for read or writing
599a2bb96e7Sjmcp  * these are bitmasks corresponding to which registers are valid in which
6009d0d62adSJason Beloro  * case. Any access to %dcr is illegal.
601a2bb96e7Sjmcp  */
6029d0d62adSJason Beloro static const uint32_t v9_asr_rdmask = 0x03cb007d;
6039d0d62adSJason Beloro static const uint32_t v9_asr_wrmask = 0x03fb004d;
604a2bb96e7Sjmcp 
605a2bb96e7Sjmcp /* privledged register names on v9 */
606a2bb96e7Sjmcp /* TODO: compat - NULL to %priv_nn */
607a2bb96e7Sjmcp static const char *v9_privreg_names[32] = {
608a2bb96e7Sjmcp 	"%tpc",	 "%tnpc",	"%tstate",  "%tt",
609a2bb96e7Sjmcp 	"%tick",	"%tba",	 "%pstate",  "%tl",
610a2bb96e7Sjmcp 	"%pil",	 "%cwp",	 "%cansave", "%canrestore",
611a2bb96e7Sjmcp 	"%cleanwin", "%otherwin", "%wstate",  "%fq",
612a2bb96e7Sjmcp 	"%gl",	NULL,	NULL,	NULL,
613a2bb96e7Sjmcp 	NULL,	NULL,	NULL,	NULL,
614a2bb96e7Sjmcp 	NULL,	NULL,	NULL,	NULL,
615a2bb96e7Sjmcp 	NULL,	NULL,	NULL,	"%ver"
616a2bb96e7Sjmcp };
617a2bb96e7Sjmcp 
618b8ef3d63SJason King /* hyper privileged register names on v9 */
6192f0fcb93SJason Beloro static const char *v9_hprivreg_names[32] = {
6209d0d62adSJason Beloro 	"%hpstate",	 "%htstate",	NULL,  "%hintp",
6212f0fcb93SJason Beloro 	NULL,	"%htba",	 "%hver",  NULL,
6222f0fcb93SJason Beloro 	NULL,	NULL,	NULL,	NULL,
6232f0fcb93SJason Beloro 	NULL,	NULL,	NULL,	NULL,
6242f0fcb93SJason Beloro 	NULL,	NULL,	NULL,	NULL,
6252f0fcb93SJason Beloro 	NULL,	NULL,	NULL,	NULL,
6262f0fcb93SJason Beloro 	NULL,	NULL,	NULL,	NULL,
6272f0fcb93SJason Beloro 	NULL,	NULL,	NULL,	"%hstick_cmpr"
6282f0fcb93SJason Beloro };
6292f0fcb93SJason Beloro 
630a2bb96e7Sjmcp static const uint32_t v9_pr_rdmask = 0x80017fff;
6312f0fcb93SJason Beloro static const uint32_t v9_pr_wrmask = 0x00017fff;
6329d0d62adSJason Beloro static const uint32_t v9_hpr_rdmask = 0x8000006b;
6339d0d62adSJason Beloro static const uint32_t v9_hpr_wrmask = 0x8000006b;
634a2bb96e7Sjmcp 
635a2bb96e7Sjmcp static const char *prefetch_str[32] = {
636a2bb96e7Sjmcp 	"#n_reads", "#one_read",
637a2bb96e7Sjmcp 	"#n_writes", "#one_write",
638a2bb96e7Sjmcp 	"#page",    NULL, NULL, NULL,
639a2bb96e7Sjmcp 	NULL, NULL, NULL, NULL,
640a2bb96e7Sjmcp 	NULL, NULL, NULL, NULL,
641a2bb96e7Sjmcp 	NULL, "#unified", NULL, NULL,
642a2bb96e7Sjmcp 	"#n_reads_strong", "#one_read_strong",
643a2bb96e7Sjmcp 	"#n_writes_strong", "#one_write_strong",
644a2bb96e7Sjmcp 	NULL, NULL, NULL, NULL,
645a2bb96e7Sjmcp 	NULL, NULL, NULL, NULL
646a2bb96e7Sjmcp };
647a2bb96e7Sjmcp 
648a2bb96e7Sjmcp static void prt_field(const char *, uint32_t, int);
649a2bb96e7Sjmcp 
650a2bb96e7Sjmcp static const char *get_regname(dis_handle_t *, int, uint32_t);
651*e3ed3d33SToomas Soome static int32_t sign_extend(int32_t, uint32_t);
652a2bb96e7Sjmcp 
653a2bb96e7Sjmcp static void prt_name(dis_handle_t *, const char *, int);
654a2bb96e7Sjmcp 
655a2bb96e7Sjmcp #define	IMM_SIGNED 0x01  /* Is immediate value signed		*/
656a2bb96e7Sjmcp #define	IMM_ADDR   0x02  /* Is immediate value part of an address */
657a2bb96e7Sjmcp static void prt_imm(dis_handle_t *, uint32_t, int);
658a2bb96e7Sjmcp 
659a2bb96e7Sjmcp static void prt_asi(dis_handle_t *, uint32_t);
660b8ef3d63SJason King static const char *get_asi_name(uint8_t);
661a2bb96e7Sjmcp static void prt_address(dis_handle_t *, uint32_t, int);
662a2bb96e7Sjmcp static void prt_aluargs(dis_handle_t *, uint32_t, uint32_t);
663a2bb96e7Sjmcp static void bprintf(dis_handle_t *, const char *, ...);
664a2bb96e7Sjmcp 
665a2bb96e7Sjmcp /*
666a2bb96e7Sjmcp  * print out val (which is 'bitlen' bits long) in binary
667a2bb96e7Sjmcp  */
668a2bb96e7Sjmcp #if defined(DIS_STANDALONE)
669a2bb96e7Sjmcp /* ARGSUSED */
670a2bb96e7Sjmcp void
prt_binary(uint32_t val,int bitlen)671a2bb96e7Sjmcp prt_binary(uint32_t val, int bitlen)
672a2bb96e7Sjmcp {
673a2bb96e7Sjmcp 
674a2bb96e7Sjmcp }
675a2bb96e7Sjmcp 
676a2bb96e7Sjmcp #else
677a2bb96e7Sjmcp 
678a2bb96e7Sjmcp void
prt_binary(uint32_t val,int bitlen)679a2bb96e7Sjmcp prt_binary(uint32_t val, int bitlen)
680a2bb96e7Sjmcp {
681a2bb96e7Sjmcp 	int i;
682a2bb96e7Sjmcp 
683a2bb96e7Sjmcp 	for (i = bitlen - 1; i >= 0; --i) {
684a2bb96e7Sjmcp 		(void) fprintf(stderr, ((val & (1L << i)) != 0) ? "1" : "0");
685a2bb96e7Sjmcp 
686a2bb96e7Sjmcp 		if (i % 4 == 0 && i != 0)
687a2bb96e7Sjmcp 			(void) fprintf(stderr, " ");
688a2bb96e7Sjmcp 	}
689a2bb96e7Sjmcp }
690a2bb96e7Sjmcp #endif /* DIS_STANDALONE */
691a2bb96e7Sjmcp 
692a2bb96e7Sjmcp 
693a2bb96e7Sjmcp /*
694a2bb96e7Sjmcp  * print out a call instruction
695a2bb96e7Sjmcp  * format: call address  <name>
696a2bb96e7Sjmcp  */
697a2bb96e7Sjmcp /* ARGSUSED1 */
698a2bb96e7Sjmcp int
fmt_call(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)699a2bb96e7Sjmcp fmt_call(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
700a2bb96e7Sjmcp {
701f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
702a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
703a2bb96e7Sjmcp 
704a2bb96e7Sjmcp 	int32_t disp;
705a2bb96e7Sjmcp 	size_t curlen;
706a2bb96e7Sjmcp 
707a2bb96e7Sjmcp 	int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
708a2bb96e7Sjmcp 
709f7184619SJoshua M. Clulow 	if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
710a2bb96e7Sjmcp 		prt_field("op", f->f1.op, 2);
711a2bb96e7Sjmcp 		prt_field("disp30", f->f1.disp30, 30);
712a2bb96e7Sjmcp 	}
713a2bb96e7Sjmcp 
714a2bb96e7Sjmcp 	disp = sign_extend(f->f1.disp30, 30) * 4;
715a2bb96e7Sjmcp 
716a2bb96e7Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
717a2bb96e7Sjmcp 
718a2bb96e7Sjmcp 	bprintf(dhp, (octal != 0) ? "%s0%-11lo" : "%s0x%-10lx",
719a2bb96e7Sjmcp 	    (disp < 0) ? "-" : "+",
720a2bb96e7Sjmcp 	    (disp < 0) ? (-disp) : disp);
721a2bb96e7Sjmcp 
722f7184619SJoshua M. Clulow 	(void) strlcat(dhx->dhx_buf, " <", dhx->dhx_buflen);
723a2bb96e7Sjmcp 
724f7184619SJoshua M. Clulow 	curlen = strlen(dhx->dhx_buf);
725a2bb96e7Sjmcp 	dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int64_t)disp,
726f7184619SJoshua M. Clulow 	    dhx->dhx_buf + curlen, dhx->dhx_buflen - curlen - 1, NULL,
727a2bb96e7Sjmcp 	    NULL);
728f7184619SJoshua M. Clulow 	(void) strlcat(dhx->dhx_buf, ">", dhx->dhx_buflen);
729a2bb96e7Sjmcp 
730a2bb96e7Sjmcp 
731a2bb96e7Sjmcp 	return (0);
732a2bb96e7Sjmcp }
733a2bb96e7Sjmcp 
734a2bb96e7Sjmcp int
fmt_sethi(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)735a2bb96e7Sjmcp fmt_sethi(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
736a2bb96e7Sjmcp {
737f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
738a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
739a2bb96e7Sjmcp 
740f7184619SJoshua M. Clulow 	if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
741a2bb96e7Sjmcp 		prt_field("op", f->f2.op, 2);
742a2bb96e7Sjmcp 		prt_field("op2", f->f2.op2, 3);
743a2bb96e7Sjmcp 		prt_field("rd", f->f2.rd, 5);
744a2bb96e7Sjmcp 		prt_field("imm22", f->f2.imm22, 22);
745a2bb96e7Sjmcp 	}
746a2bb96e7Sjmcp 
747a2bb96e7Sjmcp 	if (idx == 0) {
748a2bb96e7Sjmcp 		/* unimp / illtrap */
749a2bb96e7Sjmcp 		prt_name(dhp, inp->in_data.in_def.in_name, 1);
750a2bb96e7Sjmcp 		prt_imm(dhp, f->f2.imm22, 0);
751a2bb96e7Sjmcp 		return (0);
752a2bb96e7Sjmcp 	}
753a2bb96e7Sjmcp 
754a2bb96e7Sjmcp 	if (f->f2.imm22 == 0 && f->f2.rd == 0) {
755a2bb96e7Sjmcp 		prt_name(dhp, "nop", 0);
756a2bb96e7Sjmcp 		return (0);
757a2bb96e7Sjmcp 	}
758a2bb96e7Sjmcp 
759a2bb96e7Sjmcp 	/* ?? Should we return -1 if rd == 0 && disp != 0 */
760a2bb96e7Sjmcp 
761a2bb96e7Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
762a2bb96e7Sjmcp 
763a2bb96e7Sjmcp 	bprintf(dhp,
764a2bb96e7Sjmcp 	    ((dhp->dh_flags & DIS_OCTAL) != 0) ?
765a2bb96e7Sjmcp 	    "%%hi(0%lo), %s" : "%%hi(0x%lx), %s",
766a2bb96e7Sjmcp 	    f->f2.imm22 << 10,
767a2bb96e7Sjmcp 	    reg_names[f->f2.rd]);
768a2bb96e7Sjmcp 
769a2bb96e7Sjmcp 	return (0);
770a2bb96e7Sjmcp }
771a2bb96e7Sjmcp 
772a2bb96e7Sjmcp /* ARGSUSED3 */
773a2bb96e7Sjmcp int
fmt_branch(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)774a2bb96e7Sjmcp fmt_branch(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
775a2bb96e7Sjmcp {
776f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
777a2bb96e7Sjmcp 	const char *name = inp->in_data.in_def.in_name;
778a2bb96e7Sjmcp 	const char *r = NULL;
779a2bb96e7Sjmcp 	const char *annul = "";
780a2bb96e7Sjmcp 	const char *pred  = "";
781a2bb96e7Sjmcp 
782a2bb96e7Sjmcp 	char buf[15];
783a2bb96e7Sjmcp 
784a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
785a2bb96e7Sjmcp 
786a2bb96e7Sjmcp 	size_t curlen;
787a2bb96e7Sjmcp 	int32_t disp;
788a2bb96e7Sjmcp 	uint32_t flags = inp->in_data.in_def.in_flags;
789a2bb96e7Sjmcp 	int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
790a2bb96e7Sjmcp 
791f7184619SJoshua M. Clulow 	if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
792a2bb96e7Sjmcp 		prt_field("op", f->f2.op, 2);
793a2bb96e7Sjmcp 		prt_field("op2", f->f2.op2, 3);
794a2bb96e7Sjmcp 
795a2bb96e7Sjmcp 		switch (FLG_DISP_VAL(flags)) {
796a2bb96e7Sjmcp 		case DISP22:
797a2bb96e7Sjmcp 			prt_field("cond", f->f2a.cond, 4);
798a2bb96e7Sjmcp 			prt_field("a", f->f2a.a, 1);
799a2bb96e7Sjmcp 			prt_field("disp22", f->f2a.disp22, 22);
800a2bb96e7Sjmcp 			break;
801a2bb96e7Sjmcp 
802a2bb96e7Sjmcp 		case DISP19:
803a2bb96e7Sjmcp 			prt_field("cond", f->f2a.cond, 4);
804a2bb96e7Sjmcp 			prt_field("a", f->f2a.a, 1);
805a2bb96e7Sjmcp 			prt_field("p", f->f2b.p, 1);
806a2bb96e7Sjmcp 			prt_field("cc", f->f2b.cc, 2);
807a2bb96e7Sjmcp 			prt_field("disp19", f->f2b.disp19, 19);
808a2bb96e7Sjmcp 			break;
809a2bb96e7Sjmcp 
810a2bb96e7Sjmcp 		case DISP16:
811a2bb96e7Sjmcp 			prt_field("bit 28", ((instr & (1L << 28)) >> 28), 1);
812a2bb96e7Sjmcp 			prt_field("rcond", f->f2c.cond, 3);
813a2bb96e7Sjmcp 			prt_field("p", f->f2c.p, 1);
814a2bb96e7Sjmcp 			prt_field("rs1", f->f2c.rs1, 5);
815a2bb96e7Sjmcp 			prt_field("d16hi", f->f2c.d16hi, 2);
816a2bb96e7Sjmcp 			prt_field("d16lo", f->f2c.d16lo, 14);
817a2bb96e7Sjmcp 			break;
818a2bb96e7Sjmcp 		}
819a2bb96e7Sjmcp 	}
820a2bb96e7Sjmcp 
821a2bb96e7Sjmcp 	if (f->f2b.op2 == 0x01 && idx == 0x00 && f->f2b.p == 1 &&
822f7184619SJoshua M. Clulow 	    f->f2b.cc == 0x02 && ((dhx->dhx_debug & DIS_DEBUG_SYN_ALL) != 0)) {
823a2bb96e7Sjmcp 		name = "iprefetch";
824a2bb96e7Sjmcp 		flags = FLG_RS1(REG_NONE)|FLG_DISP(DISP19);
825a2bb96e7Sjmcp 	}
826a2bb96e7Sjmcp 
8272f0fcb93SJason Beloro 
828a2bb96e7Sjmcp 	switch (FLG_DISP_VAL(flags)) {
829a2bb96e7Sjmcp 	case DISP22:
830a2bb96e7Sjmcp 		disp = sign_extend(f->f2a.disp22, 22);
831a2bb96e7Sjmcp 		break;
832a2bb96e7Sjmcp 
833a2bb96e7Sjmcp 	case DISP19:
834a2bb96e7Sjmcp 		disp = sign_extend(f->f2b.disp19, 19);
835a2bb96e7Sjmcp 		break;
836a2bb96e7Sjmcp 
837a2bb96e7Sjmcp 	case DISP16:
838a2bb96e7Sjmcp 		disp = sign_extend((f->f2c.d16hi << 14)|f->f2c.d16lo, 16);
839a2bb96e7Sjmcp 		break;
840a2bb96e7Sjmcp 
841a2bb96e7Sjmcp 	}
842a2bb96e7Sjmcp 
843a2bb96e7Sjmcp 	disp *= 4;
844a2bb96e7Sjmcp 
845a2bb96e7Sjmcp 	if ((FLG_RS1_VAL(flags) == REG_ICC) || (FLG_RS1_VAL(flags) == REG_FCC))
846a2bb96e7Sjmcp 		r = get_regname(dhp, FLG_RS1_VAL(flags), f->f2b.cc);
847a2bb96e7Sjmcp 	else
848a2bb96e7Sjmcp 		r = get_regname(dhp, FLG_RS1_VAL(flags), f->f2c.rs1);
849a2bb96e7Sjmcp 
850a2bb96e7Sjmcp 	if (r == NULL)
851a2bb96e7Sjmcp 		return (-1);
852a2bb96e7Sjmcp 
853a2bb96e7Sjmcp 	if (f->f2a.a == 1)
854a2bb96e7Sjmcp 		annul = ",a";
855a2bb96e7Sjmcp 
856a2bb96e7Sjmcp 	if ((flags & FLG_PRED) != 0) {
857a2bb96e7Sjmcp 		if (f->f2b.p == 0) {
858a2bb96e7Sjmcp 			pred = ",pn";
859a2bb96e7Sjmcp 		} else {
860f7184619SJoshua M. Clulow 			if ((dhx->dhx_debug & DIS_DEBUG_COMPAT) != 0)
861a2bb96e7Sjmcp 				pred = ",pt";
862a2bb96e7Sjmcp 		}
863a2bb96e7Sjmcp 	}
864a2bb96e7Sjmcp 
865f7184619SJoshua M. Clulow 	(void) dis_snprintf(buf, sizeof (buf), "%s%s%s", name, annul, pred);
866a2bb96e7Sjmcp 	prt_name(dhp, buf, 1);
867a2bb96e7Sjmcp 
868a2bb96e7Sjmcp 
869a2bb96e7Sjmcp 	switch (FLG_DISP_VAL(flags)) {
870a2bb96e7Sjmcp 	case DISP22:
871a2bb96e7Sjmcp 		bprintf(dhp,
872a2bb96e7Sjmcp 		    (octal != 0) ? "%s0%-11lo <" : "%s0x%-10lx <",
873a2bb96e7Sjmcp 		    (disp < 0) ? "-" : "+",
874a2bb96e7Sjmcp 		    (disp < 0) ? (-disp) : disp);
875a2bb96e7Sjmcp 		break;
876a2bb96e7Sjmcp 
877a2bb96e7Sjmcp 	case DISP19:
8789d0d62adSJason Beloro 		bprintf(dhp,
8799d0d62adSJason Beloro 		    (octal != 0) ? "%s, %s0%-5lo <" :
8809d0d62adSJason Beloro 		    "%s, %s0x%-04lx <", r,
8819d0d62adSJason Beloro 		    (disp < 0) ? "-" : "+",
8829d0d62adSJason Beloro 		    (disp < 0) ? (-disp) : disp);
883a2bb96e7Sjmcp 		break;
884a2bb96e7Sjmcp 
885a2bb96e7Sjmcp 	case DISP16:
886a2bb96e7Sjmcp 		bprintf(dhp,
887a2bb96e7Sjmcp 		    (octal != 0) ? "%s, %s0%-6lo <" : "%s, %s0x%-5lx <",
888a2bb96e7Sjmcp 		    r,
889a2bb96e7Sjmcp 		    (disp < 0) ? "-" : "+",
890a2bb96e7Sjmcp 		    (disp < 0) ? (-disp) : disp);
891a2bb96e7Sjmcp 		break;
892a2bb96e7Sjmcp 	}
893a2bb96e7Sjmcp 
894f7184619SJoshua M. Clulow 	curlen = strlen(dhx->dhx_buf);
895a2bb96e7Sjmcp 	dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int64_t)disp,
896f7184619SJoshua M. Clulow 	    dhx->dhx_buf + curlen, dhx->dhx_buflen - curlen - 1, NULL, NULL);
897a2bb96e7Sjmcp 
898f7184619SJoshua M. Clulow 	(void) strlcat(dhx->dhx_buf, ">", dhx->dhx_buflen);
899a2bb96e7Sjmcp 
900a2bb96e7Sjmcp 	return (0);
901a2bb96e7Sjmcp }
902a2bb96e7Sjmcp 
903a2bb96e7Sjmcp 
904a2bb96e7Sjmcp 
905a2bb96e7Sjmcp /*
906a2bb96e7Sjmcp  * print out the compare and swap instructions (casa/casxa)
907a2bb96e7Sjmcp  * format: casa/casxa [%rs1] imm_asi, %rs2, %rd
908a2bb96e7Sjmcp  *	    casa/casxa [%rs1] %asi, %rs2, %rd
909a2bb96e7Sjmcp  *
910a2bb96e7Sjmcp  * If DIS_DEBUG_SYN_ALL is set, synthetic instructions are emitted
911a2bb96e7Sjmcp  * when an immediate ASI value is given as follows:
912a2bb96e7Sjmcp  *
913a2bb96e7Sjmcp  * casa  [%rs1]#ASI_P, %rs2, %rd    -> cas   [%rs1], %rs2, %rd
914a2bb96e7Sjmcp  * casa  [%rs1]#ASI_P_L, %rs2, %rd  -> casl  [%rs1], %rs2, %rd
915a2bb96e7Sjmcp  * casxa [%rs1]#ASI_P, %rs2, %rd    -> casx  [%rs1], %rs2, %rd
916a2bb96e7Sjmcp  * casxa [%rs1]#ASI_P_L, %rs2, %rd  -> casxl [%rs1], %rs2, %rd
917a2bb96e7Sjmcp  */
918a2bb96e7Sjmcp static int
fmt_cas(dis_handle_t * dhp,uint32_t instr,const char * name)919a2bb96e7Sjmcp fmt_cas(dis_handle_t *dhp, uint32_t instr, const char *name)
920a2bb96e7Sjmcp {
921f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
922a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
923b8ef3d63SJason King 	const char *asistr = NULL;
924a2bb96e7Sjmcp 	int noasi = 0;
925a2bb96e7Sjmcp 
926b8ef3d63SJason King 	asistr = get_asi_name(f->f3.asi);
927b8ef3d63SJason King 
928f7184619SJoshua M. Clulow 	if ((dhx->dhx_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT)) != 0) {
929a2bb96e7Sjmcp 		if (f->f3.op3 == 0x3c && f->f3.i == 0) {
930a2bb96e7Sjmcp 			if (f->f3.asi == 0x80) {
931a2bb96e7Sjmcp 				noasi = 1;
932a2bb96e7Sjmcp 				name = "cas";
933a2bb96e7Sjmcp 			}
934a2bb96e7Sjmcp 
935a2bb96e7Sjmcp 			if (f->f3.asi == 0x88) {
936a2bb96e7Sjmcp 				noasi = 1;
937a2bb96e7Sjmcp 				name = "casl";
938a2bb96e7Sjmcp 			}
939a2bb96e7Sjmcp 		}
940a2bb96e7Sjmcp 
941a2bb96e7Sjmcp 		if (f->f3.op3 == 0x3e && f->f3.i == 0) {
942a2bb96e7Sjmcp 			if (f->f3.asi == 0x80) {
943a2bb96e7Sjmcp 				noasi = 1;
944a2bb96e7Sjmcp 				name = "casx";
945a2bb96e7Sjmcp 			}
946a2bb96e7Sjmcp 
947a2bb96e7Sjmcp 			if (f->f3.asi == 0x88) {
948a2bb96e7Sjmcp 				noasi = 1;
949a2bb96e7Sjmcp 				name = "casxl";
950a2bb96e7Sjmcp 			}
951a2bb96e7Sjmcp 		}
952a2bb96e7Sjmcp 	}
953a2bb96e7Sjmcp 
954a2bb96e7Sjmcp 	prt_name(dhp, name, 1);
955a2bb96e7Sjmcp 
956a2bb96e7Sjmcp 	bprintf(dhp, "[%s]", reg_names[f->f3.rs1]);
957a2bb96e7Sjmcp 
958a2bb96e7Sjmcp 	if (noasi == 0) {
959f7184619SJoshua M. Clulow 		(void) strlcat(dhx->dhx_buf, " ", dhx->dhx_buflen);
960a2bb96e7Sjmcp 		prt_asi(dhp, instr);
961a2bb96e7Sjmcp 	}
962a2bb96e7Sjmcp 
963a2bb96e7Sjmcp 	bprintf(dhp, ", %s, %s", reg_names[f->f3.rs2], reg_names[f->f3.rd]);
964a2bb96e7Sjmcp 
965b8ef3d63SJason King 	if (noasi == 0 && asistr != NULL)
966b8ef3d63SJason King 		bprintf(dhp, "\t<%s>", asistr);
967b8ef3d63SJason King 
968a2bb96e7Sjmcp 	return (0);
969a2bb96e7Sjmcp }
970a2bb96e7Sjmcp 
971a2bb96e7Sjmcp /*
972a2bb96e7Sjmcp  * format a load/store instruction
973a2bb96e7Sjmcp  * format: ldXX [%rs1 + %rs2], %rd	  load, i==0
974a2bb96e7Sjmcp  *	    ldXX [%rs1 +/- nn], %rd	  load, i==1
975a2bb96e7Sjmcp  *	    ldXX [%rs1 + %rs2] #XX, %rd   load w/ imm_asi, i==0
976a2bb96e7Sjmcp  *	    ldXX [%rs1 +/- nn] %asi, %rd  load from asi[%asi], i==1
977a2bb96e7Sjmcp  *
978a2bb96e7Sjmcp  *	    stXX %rd, [%rs1 + %rs2]	  store, i==0
979a2bb96e7Sjmcp  *	    stXX %rd, [%rs1 +/- nn]	  store, i==1
980a2bb96e7Sjmcp  *	    stXX %rd, [%rs1 + %rs1] #XX   store to imm_asi, i==0
981a2bb96e7Sjmcp  *	    stXX %rd, [%rs1 +/-nn] %asi   store to asi[%asi], i==1
982a2bb96e7Sjmcp  *
983a2bb96e7Sjmcp  * The register sets used for %rd are set in the instructions flags field
984a2bb96e7Sjmcp  * The asi variants are used if FLG_ASI is set in the instructions flags field
985a2bb96e7Sjmcp  *
986a2bb96e7Sjmcp  * If DIS_DEBUG_SYNTH_ALL or DIS_DEBUG_COMPAT are set,
987a2bb96e7Sjmcp  * When %rs1, %rs2 or nn are 0, they are not printed, i.e.
988a2bb96e7Sjmcp  * [ %rs1 + 0x0 ], %rd -> [%rs1], %rd for example
989a2bb96e7Sjmcp  *
990a2bb96e7Sjmcp  * The following synthetic instructions are also implemented:
991a2bb96e7Sjmcp  *
992a2bb96e7Sjmcp  * stb %g0, [addr] -> clrb [addr]    DIS_DEBUG_SYNTH_ALL
993a2bb96e7Sjmcp  * sth %g0, [addr] -> crlh [addr]    DIS_DEBUG_SYNTH_ALL
994a2bb96e7Sjmcp  * stw %g0, [addr] -> clr  [addr]    DIS_DEBUG_SYNTH_ALL|DIS_DEBUG_COMPAT
995a2bb96e7Sjmcp  * stx %g0, [addr] -> clrx [addr]    DIS_DEBUG_SYNTH_ALL
996a2bb96e7Sjmcp  *
997a2bb96e7Sjmcp  * If DIS_DEBUG_COMPAT is set, the following substitutions also take place
998a2bb96e7Sjmcp  *	lduw -> ld
999a2bb96e7Sjmcp  *	ldtw -> ld
1000a2bb96e7Sjmcp  *	stuw -> st
1001a2bb96e7Sjmcp  *	sttw -> st
1002a2bb96e7Sjmcp  */
1003a2bb96e7Sjmcp int
fmt_ls(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)1004a2bb96e7Sjmcp fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1005a2bb96e7Sjmcp {
1006f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
1007a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
1008a2bb96e7Sjmcp 	const char *regstr = NULL;
1009b8ef3d63SJason King 	const char *asistr = NULL;
1010a2bb96e7Sjmcp 
1011a2bb96e7Sjmcp 	const char *iname = inp->in_data.in_def.in_name;
1012a2bb96e7Sjmcp 	uint32_t flags = inp->in_data.in_def.in_flags;
1013a2bb96e7Sjmcp 
1014f7184619SJoshua M. Clulow 	if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
1015a2bb96e7Sjmcp 		prt_field("op", f->f3.op, 2);
1016a2bb96e7Sjmcp 		prt_field("op3", f->f3.op3, 6);
1017a2bb96e7Sjmcp 		prt_field("rs1", f->f3.rs1, 5);
1018a2bb96e7Sjmcp 		prt_field("i", f->f3.i, 1);
1019a2bb96e7Sjmcp 		if (f->f3.i != 0) {
1020a2bb96e7Sjmcp 			prt_field("simm13", f->f3a.simm13, 13);
1021a2bb96e7Sjmcp 		} else {
1022a2bb96e7Sjmcp 			if ((flags & FLG_ASI) != 0)
1023a2bb96e7Sjmcp 				prt_field("imm_asi", f->f3.asi, 8);
1024a2bb96e7Sjmcp 			prt_field("rs2", f->f3.rs2, 5);
1025a2bb96e7Sjmcp 		}
1026a2bb96e7Sjmcp 		prt_field("rd", f->f3.rd, 5);
1027a2bb96e7Sjmcp 	}
1028a2bb96e7Sjmcp 
1029a2bb96e7Sjmcp 	if (idx == 0x2d || idx == 0x3d) {
1030a2bb96e7Sjmcp 		/* prefetch / prefetcha */
1031a2bb96e7Sjmcp 
1032a2bb96e7Sjmcp 		prt_name(dhp, iname, 1);
1033a2bb96e7Sjmcp 
1034a2bb96e7Sjmcp 		prt_address(dhp, instr, 0);
1035a2bb96e7Sjmcp 
1036a2bb96e7Sjmcp 		if (idx == 0x3d) {
1037f7184619SJoshua M. Clulow 			(void) strlcat(dhx->dhx_buf, " ", dhx->dhx_buflen);
1038a2bb96e7Sjmcp 			prt_asi(dhp, instr);
1039a2bb96e7Sjmcp 		}
1040a2bb96e7Sjmcp 
1041f7184619SJoshua M. Clulow 		(void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
1042a2bb96e7Sjmcp 
1043a2bb96e7Sjmcp 		/* fcn field is the same as rd */
1044a2bb96e7Sjmcp 		if (prefetch_str[f->f3.rd] != NULL)
1045f7184619SJoshua M. Clulow 			(void) strlcat(dhx->dhx_buf, prefetch_str[f->f3.rd],
1046f7184619SJoshua M. Clulow 			    dhx->dhx_buflen);
1047a2bb96e7Sjmcp 		else
1048a2bb96e7Sjmcp 			prt_imm(dhp, f->f3.rd, 0);
1049a2bb96e7Sjmcp 
1050b8ef3d63SJason King 		if (idx == 0x3d && f->f3.i == 0) {
1051b8ef3d63SJason King 			asistr = get_asi_name(f->f3.asi);
1052b8ef3d63SJason King 			if (asistr != NULL)
1053b8ef3d63SJason King 				bprintf(dhp, "\t<%s>", asistr);
1054b8ef3d63SJason King 		}
1055b8ef3d63SJason King 
1056a2bb96e7Sjmcp 		return (0);
1057a2bb96e7Sjmcp 	}
1058a2bb96e7Sjmcp 
1059a2bb96e7Sjmcp 	/* casa / casxa */
1060a2bb96e7Sjmcp 	if (idx == 0x3c || idx == 0x3e)
1061a2bb96e7Sjmcp 		return (fmt_cas(dhp, instr, iname));
1062a2bb96e7Sjmcp 
1063a2bb96e7Sjmcp 	/* synthetic instructions & special cases */
1064a2bb96e7Sjmcp 	switch (idx) {
1065a2bb96e7Sjmcp 	case 0x00:
1066a2bb96e7Sjmcp 		/* ld */
1067f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0)
1068a2bb96e7Sjmcp 			iname = "lduw";
1069a2bb96e7Sjmcp 		break;
1070a2bb96e7Sjmcp 
1071a2bb96e7Sjmcp 	case 0x03:
1072f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0)
1073a2bb96e7Sjmcp 			iname = "ldtw";
1074a2bb96e7Sjmcp 		break;
1075a2bb96e7Sjmcp 
1076a2bb96e7Sjmcp 	case 0x04:
1077a2bb96e7Sjmcp 		/* stw */
1078f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0)
1079a2bb96e7Sjmcp 			iname = "stuw";
1080a2bb96e7Sjmcp 
1081a2bb96e7Sjmcp 		if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
1082a2bb96e7Sjmcp 		    == 0)
1083a2bb96e7Sjmcp 			break;
1084a2bb96e7Sjmcp 
1085a2bb96e7Sjmcp 		if (f->f3.rd == 0) {
1086a2bb96e7Sjmcp 			iname = "clr";
1087a2bb96e7Sjmcp 			flags = FLG_RD(REG_NONE);
1088a2bb96e7Sjmcp 		}
1089a2bb96e7Sjmcp 		break;
1090a2bb96e7Sjmcp 
1091a2bb96e7Sjmcp 	case 0x05:
1092a2bb96e7Sjmcp 		/* stb */
1093a2bb96e7Sjmcp 		if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
1094a2bb96e7Sjmcp 		    == 0)
1095a2bb96e7Sjmcp 			break;
1096a2bb96e7Sjmcp 
1097a2bb96e7Sjmcp 		if (f->f3.rd == 0) {
1098a2bb96e7Sjmcp 			iname = "clrb";
1099a2bb96e7Sjmcp 			flags = FLG_RD(REG_NONE);
1100a2bb96e7Sjmcp 		}
1101a2bb96e7Sjmcp 		break;
1102a2bb96e7Sjmcp 
1103a2bb96e7Sjmcp 	case 0x06:
1104a2bb96e7Sjmcp 		/* sth */
1105a2bb96e7Sjmcp 		if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
1106a2bb96e7Sjmcp 		    == 0)
1107a2bb96e7Sjmcp 			break;
1108a2bb96e7Sjmcp 
1109a2bb96e7Sjmcp 		if (f->f3.rd == 0) {
1110a2bb96e7Sjmcp 			iname = "clrh";
1111a2bb96e7Sjmcp 			flags = FLG_RD(REG_NONE);
1112a2bb96e7Sjmcp 		}
1113a2bb96e7Sjmcp 		break;
1114a2bb96e7Sjmcp 
1115a2bb96e7Sjmcp 	case 0x07:
1116f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0)
1117a2bb96e7Sjmcp 			iname = "sttw";
1118a2bb96e7Sjmcp 		break;
1119a2bb96e7Sjmcp 
1120a2bb96e7Sjmcp 	case 0x0e:
1121a2bb96e7Sjmcp 		/* stx */
1122a2bb96e7Sjmcp 
1123a2bb96e7Sjmcp 		if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
1124a2bb96e7Sjmcp 		    == 0)
1125a2bb96e7Sjmcp 			break;
1126a2bb96e7Sjmcp 
1127a2bb96e7Sjmcp 		if (f->f3.rd == 0) {
1128a2bb96e7Sjmcp 			iname = "clrx";
1129a2bb96e7Sjmcp 			flags = FLG_RD(REG_NONE);
1130a2bb96e7Sjmcp 		}
1131a2bb96e7Sjmcp 		break;
1132a2bb96e7Sjmcp 
1133a2bb96e7Sjmcp 	case 0x13:
1134a2bb96e7Sjmcp 		/* ldtwa */
1135f7184619SJoshua M. Clulow 		if (((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0) &&
1136a2bb96e7Sjmcp 		    ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0))
1137a2bb96e7Sjmcp 			iname = "ldtwa";
1138a2bb96e7Sjmcp 		break;
1139a2bb96e7Sjmcp 
1140a2bb96e7Sjmcp 	case 0x17:
1141a2bb96e7Sjmcp 		/* sttwa */
1142f7184619SJoshua M. Clulow 		if (((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0) &&
1143a2bb96e7Sjmcp 		    ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0))
1144a2bb96e7Sjmcp 			iname = "sttwa";
1145a2bb96e7Sjmcp 		break;
1146a2bb96e7Sjmcp 
1147a2bb96e7Sjmcp 	case 0x21:
1148a2bb96e7Sjmcp 	case 0x25:
1149a2bb96e7Sjmcp 		/*
1150a2bb96e7Sjmcp 		 * on sparcv8 it merely says that rd != 1 should generate an
1151a2bb96e7Sjmcp 		 * exception, on v9, it is illegal
1152a2bb96e7Sjmcp 		 */
1153a2bb96e7Sjmcp 		if ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) == 0)
1154a2bb96e7Sjmcp 			break;
1155a2bb96e7Sjmcp 
1156a2bb96e7Sjmcp 		iname = (idx == 0x21) ? "ldx" : "stx";
1157a2bb96e7Sjmcp 
1158a2bb96e7Sjmcp 		if (f->f3.rd > 1)
1159a2bb96e7Sjmcp 			return (-1);
1160a2bb96e7Sjmcp 
1161a2bb96e7Sjmcp 		break;
1162a2bb96e7Sjmcp 
1163a2bb96e7Sjmcp 	case 0x31:
1164a2bb96e7Sjmcp 		/* stda */
1165a2bb96e7Sjmcp 		switch (f->f3.asi) {
1166a2bb96e7Sjmcp 			case 0xc0:
1167a2bb96e7Sjmcp 			case 0xc1:
1168a2bb96e7Sjmcp 			case 0xc8:
1169a2bb96e7Sjmcp 			case 0xc9:
1170a2bb96e7Sjmcp 			case 0xc2:
1171a2bb96e7Sjmcp 			case 0xc3:
1172a2bb96e7Sjmcp 			case 0xca:
1173a2bb96e7Sjmcp 			case 0xcb:
1174a2bb96e7Sjmcp 			case 0xc4:
1175a2bb96e7Sjmcp 			case 0xc5:
1176a2bb96e7Sjmcp 			case 0xcc:
1177a2bb96e7Sjmcp 			case 0xcd:
1178a2bb96e7Sjmcp 				/*
1179a2bb96e7Sjmcp 				 * store partial floating point, only valid w/
1180a2bb96e7Sjmcp 				 * vis
1181a2bb96e7Sjmcp 				 *
1182a2bb96e7Sjmcp 				 * Somewhat confusingly, it uses the same op
1183a2bb96e7Sjmcp 				 * code as 'stda' -- store double to alternate
1184a2bb96e7Sjmcp 				 * space.  It is distinguised by specific
1185a2bb96e7Sjmcp 				 * imm_asi values (as seen above), and
1186a2bb96e7Sjmcp 				 * has a slightly different output syntax
1187a2bb96e7Sjmcp 				 */
1188a2bb96e7Sjmcp 
1189a2bb96e7Sjmcp 				if ((dhp->dh_flags & DIS_SPARC_V9_SGI) == 0)
1190a2bb96e7Sjmcp 					break;
1191a2bb96e7Sjmcp 				if (f->f3.i != 0)
1192a2bb96e7Sjmcp 					break;
1193a2bb96e7Sjmcp 				prt_name(dhp, iname, 1);
1194a2bb96e7Sjmcp 				bprintf(dhp, "%s, %s, [%s] ",
1195a2bb96e7Sjmcp 				    get_regname(dhp, REG_FPD, f->f3.rd),
1196a2bb96e7Sjmcp 				    get_regname(dhp, REG_FPD, f->f3.rs2),
1197a2bb96e7Sjmcp 				    get_regname(dhp, REG_FPD, f->f3.rs1));
1198a2bb96e7Sjmcp 				prt_asi(dhp, instr);
1199b8ef3d63SJason King 				asistr = get_asi_name(f->f3.asi);
1200b8ef3d63SJason King 				if (asistr != NULL)
1201b8ef3d63SJason King 					bprintf(dhp, "\t<%s>", asistr);
1202b8ef3d63SJason King 
1203a2bb96e7Sjmcp 				return (0);
1204a2bb96e7Sjmcp 
1205a2bb96e7Sjmcp 			default:
1206a2bb96e7Sjmcp 				break;
1207a2bb96e7Sjmcp 		}
1208a2bb96e7Sjmcp 
1209a2bb96e7Sjmcp 	}
1210a2bb96e7Sjmcp 
1211a2bb96e7Sjmcp 	regstr = get_regname(dhp, FLG_RD_VAL(flags), f->f3.rd);
1212a2bb96e7Sjmcp 
1213b8ef3d63SJason King 	if (f->f3.i == 0)
1214b8ef3d63SJason King 		asistr = get_asi_name(f->f3.asi);
1215b8ef3d63SJason King 
1216a2bb96e7Sjmcp 	prt_name(dhp, iname, 1);
1217a2bb96e7Sjmcp 
1218a2bb96e7Sjmcp 	if ((flags & FLG_STORE) != 0) {
1219a2bb96e7Sjmcp 		if (regstr[0] != '\0') {
1220f7184619SJoshua M. Clulow 			(void) strlcat(dhx->dhx_buf, regstr, dhx->dhx_buflen);
1221f7184619SJoshua M. Clulow 			(void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
1222a2bb96e7Sjmcp 		}
1223a2bb96e7Sjmcp 
1224a2bb96e7Sjmcp 		prt_address(dhp, instr, 0);
1225a2bb96e7Sjmcp 		if ((flags & FLG_ASI) != 0) {
1226f7184619SJoshua M. Clulow 			(void) strlcat(dhx->dhx_buf, " ", dhx->dhx_buflen);
1227a2bb96e7Sjmcp 			prt_asi(dhp, instr);
1228a2bb96e7Sjmcp 		}
1229a2bb96e7Sjmcp 	} else {
1230a2bb96e7Sjmcp 		prt_address(dhp, instr, 0);
1231a2bb96e7Sjmcp 		if ((flags & FLG_ASI) != 0) {
1232f7184619SJoshua M. Clulow 			(void) strlcat(dhx->dhx_buf, " ", dhx->dhx_buflen);
1233a2bb96e7Sjmcp 			prt_asi(dhp, instr);
1234a2bb96e7Sjmcp 		}
1235a2bb96e7Sjmcp 
1236a2bb96e7Sjmcp 		if (regstr[0] != '\0') {
1237f7184619SJoshua M. Clulow 			(void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
1238f7184619SJoshua M. Clulow 			(void) strlcat(dhx->dhx_buf, regstr, dhx->dhx_buflen);
1239a2bb96e7Sjmcp 		}
1240a2bb96e7Sjmcp 	}
1241a2bb96e7Sjmcp 
1242b8ef3d63SJason King 	if ((flags & FLG_ASI) != 0 && asistr != NULL)
1243b8ef3d63SJason King 		bprintf(dhp, "\t<%s>", asistr);
1244b8ef3d63SJason King 
1245a2bb96e7Sjmcp 	return (0);
1246a2bb96e7Sjmcp }
1247a2bb96e7Sjmcp 
1248a2bb96e7Sjmcp static int
fmt_cpop(dis_handle_t * dhp,uint32_t instr,const inst_t * inp)1249a2bb96e7Sjmcp fmt_cpop(dis_handle_t *dhp, uint32_t instr, const inst_t *inp)
1250a2bb96e7Sjmcp {
1251f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
1252a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
1253a2bb96e7Sjmcp 	int flags = FLG_P1(REG_CP)|FLG_P2(REG_CP)|FLG_NOIMM|FLG_P3(REG_CP);
1254a2bb96e7Sjmcp 
1255f7184619SJoshua M. Clulow 	if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
1256a2bb96e7Sjmcp 		prt_field("op", f->fcp.op, 2);
1257a2bb96e7Sjmcp 		prt_field("op3", f->fcp.op3, 6);
1258a2bb96e7Sjmcp 		prt_field("opc", f->fcp.opc, 9);
1259a2bb96e7Sjmcp 		prt_field("rs1", f->fcp.rs1, 5);
1260a2bb96e7Sjmcp 		prt_field("rs2", f->fcp.rs2, 5);
1261a2bb96e7Sjmcp 		prt_field("rd", f->fcp.rd, 5);
1262a2bb96e7Sjmcp 	}
1263a2bb96e7Sjmcp 
1264a2bb96e7Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
1265a2bb96e7Sjmcp 	prt_imm(dhp, f->fcp.opc, 0);
1266a2bb96e7Sjmcp 
1267f7184619SJoshua M. Clulow 	(void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
1268a2bb96e7Sjmcp 	(void) prt_aluargs(dhp, instr, flags);
1269a2bb96e7Sjmcp 
1270a2bb96e7Sjmcp 	return (0);
1271a2bb96e7Sjmcp }
1272a2bb96e7Sjmcp 
1273a2bb96e7Sjmcp static int
dis_fmt_rdwr(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)1274a2bb96e7Sjmcp dis_fmt_rdwr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1275a2bb96e7Sjmcp {
1276f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
1277a2bb96e7Sjmcp 	const char *psr_str = "%psr";
1278a2bb96e7Sjmcp 	const char *wim_str = "%wim";
1279a2bb96e7Sjmcp 	const char *tbr_str = "%tbr";
1280a2bb96e7Sjmcp 
1281a2bb96e7Sjmcp 	const char *name = inp->in_data.in_def.in_name;
1282a2bb96e7Sjmcp 	const char *regstr = NULL;
1283a2bb96e7Sjmcp 
1284a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
1285a2bb96e7Sjmcp 
1286a2bb96e7Sjmcp 	int rd = (idx < 0x30);
1287a2bb96e7Sjmcp 	int v9 = (dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI));
1288a2bb96e7Sjmcp 	int ridx = f->f3.rs1;
1289a2bb96e7Sjmcp 	int i, first;
1290a2bb96e7Sjmcp 	int pr_rs1 = 1;
1291a2bb96e7Sjmcp 	int pr_rs2 = 1;
1292a2bb96e7Sjmcp 
1293a2bb96e7Sjmcp 	int use_mask = 1;
1294a2bb96e7Sjmcp 	uint32_t mask;
1295a2bb96e7Sjmcp 
1296a2bb96e7Sjmcp 	if (rd == 0)
1297a2bb96e7Sjmcp 		ridx = f->f3.rd;
1298a2bb96e7Sjmcp 
1299a2bb96e7Sjmcp 	switch (idx) {
1300a2bb96e7Sjmcp 	case 0x28:
1301a2bb96e7Sjmcp 		/* rd */
1302a2bb96e7Sjmcp 
1303a2bb96e7Sjmcp 		/* stbar */
1304a2bb96e7Sjmcp 		if ((f->f3.rd == 0) && (f->f3.rs1 == 15) && (f->f3.i == 0)) {
1305a2bb96e7Sjmcp 			prt_name(dhp, "stbar", 0);
1306a2bb96e7Sjmcp 			return (0);
1307a2bb96e7Sjmcp 		}
1308a2bb96e7Sjmcp 
1309a2bb96e7Sjmcp 		/* membar */
1310a2bb96e7Sjmcp 		if ((v9 != 0) && (f->f3.rd == 0) && (f->f3.rs1 == 15) &&
1311a2bb96e7Sjmcp 		    (f->f3.i == 1) && ((f->i & (1L << 12)) == 0)) {
1312a2bb96e7Sjmcp 
1313a2bb96e7Sjmcp 			prt_name(dhp, "membar",
1314a2bb96e7Sjmcp 			    ((f->fmb.cmask != 0) || (f->fmb.mmask != 0)));
1315a2bb96e7Sjmcp 
1316a2bb96e7Sjmcp 			first = 0;
1317a2bb96e7Sjmcp 
13189d0d62adSJason Beloro 			for (i = 0; i < 4; ++i) {
1319a2bb96e7Sjmcp 				if ((f->fmb.cmask & (1L << i)) != 0) {
1320a2bb96e7Sjmcp 					bprintf(dhp, "%s%s",
1321a2bb96e7Sjmcp 					    (first != 0) ? "|" : "",
1322a2bb96e7Sjmcp 					    membar_cmask[i]);
1323a2bb96e7Sjmcp 					first = 1;
1324a2bb96e7Sjmcp 				}
1325a2bb96e7Sjmcp 			}
1326a2bb96e7Sjmcp 
1327a2bb96e7Sjmcp 			for (i = 0; i < 5; ++i) {
1328a2bb96e7Sjmcp 				if ((f->fmb.mmask & (1L << i)) != 0) {
1329a2bb96e7Sjmcp 					bprintf(dhp, "%s%s",
1330a2bb96e7Sjmcp 					    (first != 0) ? "|" : "",
1331a2bb96e7Sjmcp 					    membar_mmask[i]);
1332a2bb96e7Sjmcp 					first = 1;
1333a2bb96e7Sjmcp 				}
1334a2bb96e7Sjmcp 			}
1335a2bb96e7Sjmcp 
1336a2bb96e7Sjmcp 			return (0);
1337a2bb96e7Sjmcp 		}
1338a2bb96e7Sjmcp 
1339a2bb96e7Sjmcp 		if (v9 != 0) {
1340a2bb96e7Sjmcp 			regstr = v9_asr_names[ridx];
1341a2bb96e7Sjmcp 			mask = v9_asr_rdmask;
1342a2bb96e7Sjmcp 		} else {
1343a2bb96e7Sjmcp 			regstr = asr_names[ridx];
1344a2bb96e7Sjmcp 			mask = asr_rdmask;
1345a2bb96e7Sjmcp 		}
1346a2bb96e7Sjmcp 		break;
1347a2bb96e7Sjmcp 
1348a2bb96e7Sjmcp 	case 0x29:
13492f0fcb93SJason Beloro 		if (v9 != 0) {
13502f0fcb93SJason Beloro 			regstr = v9_hprivreg_names[ridx];
13512f0fcb93SJason Beloro 			mask = v9_hpr_rdmask;
13522f0fcb93SJason Beloro 		} else {
13532f0fcb93SJason Beloro 			regstr = psr_str;
13542f0fcb93SJason Beloro 			use_mask = 0;
13552f0fcb93SJason Beloro 		}
1356a2bb96e7Sjmcp 		break;
1357a2bb96e7Sjmcp 
1358a2bb96e7Sjmcp 	case 0x2a:
1359a2bb96e7Sjmcp 		if (v9 != 0) {
1360a2bb96e7Sjmcp 			regstr = v9_privreg_names[ridx];
1361a2bb96e7Sjmcp 			mask = v9_pr_rdmask;
1362a2bb96e7Sjmcp 		} else {
1363a2bb96e7Sjmcp 			regstr = wim_str;
1364a2bb96e7Sjmcp 			use_mask = 0;
1365a2bb96e7Sjmcp 		}
1366a2bb96e7Sjmcp 		break;
1367a2bb96e7Sjmcp 
1368a2bb96e7Sjmcp 	case 0x2b:
1369a2bb96e7Sjmcp 		if (v9 != 0) {
1370a2bb96e7Sjmcp 			/* flushw */
1371a2bb96e7Sjmcp 			prt_name(dhp, name, 0);
1372a2bb96e7Sjmcp 			return (0);
1373a2bb96e7Sjmcp 		}
1374a2bb96e7Sjmcp 
1375a2bb96e7Sjmcp 		regstr = tbr_str;
1376a2bb96e7Sjmcp 		use_mask = 0;
1377a2bb96e7Sjmcp 		break;
1378a2bb96e7Sjmcp 
1379a2bb96e7Sjmcp 	case 0x30:
1380a2bb96e7Sjmcp 		if (v9 != 0) {
1381a2bb96e7Sjmcp 			regstr = v9_asr_names[ridx];
1382a2bb96e7Sjmcp 			mask = v9_asr_wrmask;
1383a2bb96e7Sjmcp 		} else {
1384a2bb96e7Sjmcp 			regstr = asr_names[ridx];
1385a2bb96e7Sjmcp 			mask = asr_wrmask;
1386a2bb96e7Sjmcp 		}
1387a2bb96e7Sjmcp 
1388b8ef3d63SJason King 		/*
1389b8ef3d63SJason King 		 * sir is shoehorned in here, per Ultrasparc 2007
1390b8ef3d63SJason King 		 * hyperprivileged edition, section 7.88, all of
1391b8ef3d63SJason King 		 * these must be true to distinguish from WRasr
1392b8ef3d63SJason King 		 */
1393b8ef3d63SJason King 		if (v9 != 0 && f->f3.rd == 15 && f->f3.rs1 == 0 &&
1394b8ef3d63SJason King 		    f->f3.i == 1) {
1395b8ef3d63SJason King 			prt_name(dhp, "sir", 1);
1396b8ef3d63SJason King 			prt_imm(dhp, sign_extend(f->f3a.simm13, 13),
1397b8ef3d63SJason King 			    IMM_SIGNED);
1398b8ef3d63SJason King 			return (0);
1399b8ef3d63SJason King 		}
1400b8ef3d63SJason King 
1401a2bb96e7Sjmcp 		/* synth: mov */
1402f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
1403a2bb96e7Sjmcp 		    == 0)
1404a2bb96e7Sjmcp 			break;
1405a2bb96e7Sjmcp 
14062f0fcb93SJason Beloro 		if (v9 == 0) {
14072f0fcb93SJason Beloro 			if (f->f3.rs1 == 0) {
14082f0fcb93SJason Beloro 				name = "mov";
14092f0fcb93SJason Beloro 				pr_rs1 = 0;
14102f0fcb93SJason Beloro 			}
1411a2bb96e7Sjmcp 
14122f0fcb93SJason Beloro 			if ((f->f3.i == 0 && f->f3.rs2 == 0) ||
14132f0fcb93SJason Beloro 			    (f->f3.i == 1 && f->f3a.simm13 == 0)) {
14142f0fcb93SJason Beloro 				name = "mov";
14152f0fcb93SJason Beloro 				pr_rs2 = 0;
14162f0fcb93SJason Beloro 			}
1417a2bb96e7Sjmcp 		}
1418a2bb96e7Sjmcp 
1419a2bb96e7Sjmcp 		if (pr_rs1 == 0)
1420a2bb96e7Sjmcp 			pr_rs2 = 1;
1421a2bb96e7Sjmcp 
1422a2bb96e7Sjmcp 		break;
1423a2bb96e7Sjmcp 
1424a2bb96e7Sjmcp 	case 0x31:
1425a2bb96e7Sjmcp 		/*
1426a2bb96e7Sjmcp 		 * NOTE: due to the presence of an overlay entry for another
1427a2bb96e7Sjmcp 		 * table, this case only happens when doing v8 instructions
1428a2bb96e7Sjmcp 		 * only
1429a2bb96e7Sjmcp 		 */
1430a2bb96e7Sjmcp 		regstr = psr_str;
1431a2bb96e7Sjmcp 		use_mask = 0;
1432a2bb96e7Sjmcp 		break;
1433a2bb96e7Sjmcp 
1434a2bb96e7Sjmcp 	case 0x32:
1435a2bb96e7Sjmcp 		if (v9 != 0) {
1436a2bb96e7Sjmcp 			regstr = v9_privreg_names[ridx];
1437a2bb96e7Sjmcp 			mask = v9_pr_wrmask;
1438a2bb96e7Sjmcp 		} else {
1439a2bb96e7Sjmcp 			regstr = wim_str;
1440a2bb96e7Sjmcp 			use_mask = 0;
1441a2bb96e7Sjmcp 		}
1442a2bb96e7Sjmcp 		break;
1443a2bb96e7Sjmcp 
1444a2bb96e7Sjmcp 	case 0x33:
14452f0fcb93SJason Beloro 		if (v9 != 0) {
14462f0fcb93SJason Beloro 			regstr = v9_hprivreg_names[ridx];
14472f0fcb93SJason Beloro 			mask = v9_hpr_wrmask;
14482f0fcb93SJason Beloro 		} else {
14492f0fcb93SJason Beloro 			regstr = tbr_str;
14502f0fcb93SJason Beloro 			use_mask = 0;
14512f0fcb93SJason Beloro 		}
1452a2bb96e7Sjmcp 		break;
1453a2bb96e7Sjmcp 	}
1454a2bb96e7Sjmcp 
1455a2bb96e7Sjmcp 	if (regstr == NULL)
1456a2bb96e7Sjmcp 		return (-1);
1457a2bb96e7Sjmcp 
1458a2bb96e7Sjmcp 	if (use_mask != 0 && ((1L << ridx) & mask) == 0)
1459a2bb96e7Sjmcp 		return (-1);
1460a2bb96e7Sjmcp 
1461a2bb96e7Sjmcp 	prt_name(dhp, name, 1);
1462a2bb96e7Sjmcp 
1463a2bb96e7Sjmcp 	if (rd != 0) {
1464a2bb96e7Sjmcp 		bprintf(dhp, "%s, %s", regstr, reg_names[f->f3.rd]);
1465a2bb96e7Sjmcp 	} else {
1466a2bb96e7Sjmcp 		if (pr_rs1 == 1)
1467a2bb96e7Sjmcp 			bprintf(dhp, "%s, ", reg_names[f->f3.rs1]);
1468a2bb96e7Sjmcp 
1469a2bb96e7Sjmcp 		if (pr_rs2 != 0) {
1470a2bb96e7Sjmcp 			if (f->f3.i == 1)
1471a2bb96e7Sjmcp 				prt_imm(dhp, sign_extend(f->f3a.simm13, 13),
1472a2bb96e7Sjmcp 				    IMM_SIGNED);
1473a2bb96e7Sjmcp 			else
1474f7184619SJoshua M. Clulow 				(void) strlcat(dhx->dhx_buf,
1475f7184619SJoshua M. Clulow 				    reg_names[f->f3.rs2], dhx->dhx_buflen);
1476f7184619SJoshua M. Clulow 			(void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
1477a2bb96e7Sjmcp 		}
1478a2bb96e7Sjmcp 
1479f7184619SJoshua M. Clulow 		(void) strlcat(dhx->dhx_buf, regstr, dhx->dhx_buflen);
1480a2bb96e7Sjmcp 	}
1481a2bb96e7Sjmcp 
1482a2bb96e7Sjmcp 	return (0);
1483a2bb96e7Sjmcp }
1484a2bb96e7Sjmcp 
1485a2bb96e7Sjmcp /* ARGSUSED3 */
1486a2bb96e7Sjmcp int
fmt_trap(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)1487a2bb96e7Sjmcp fmt_trap(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1488a2bb96e7Sjmcp {
1489f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
1490a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
1491a2bb96e7Sjmcp 
1492a2bb96e7Sjmcp 	int v9 = ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0);
1493a2bb96e7Sjmcp 	int p_rs1, p_t;
1494a2bb96e7Sjmcp 
1495a2bb96e7Sjmcp 	if (f->ftcc.undef != 0)
1496a2bb96e7Sjmcp 		return (-1);
1497a2bb96e7Sjmcp 
1498a2bb96e7Sjmcp 	if (icc_names[f->ftcc.cc] == NULL)
1499a2bb96e7Sjmcp 		return (-1);
1500a2bb96e7Sjmcp 
1501a2bb96e7Sjmcp 	if (f->ftcc.i == 1 && f->ftcc.undef2 != 0)
1502a2bb96e7Sjmcp 		return (-1);
1503a2bb96e7Sjmcp 
1504a2bb96e7Sjmcp 	if (f->ftcc2.i == 0 && f->ftcc2.undef2 != 0)
1505a2bb96e7Sjmcp 		return (-1);
1506a2bb96e7Sjmcp 
1507a2bb96e7Sjmcp 	p_rs1 = ((f->ftcc.rs1 != 0) ||
1508f7184619SJoshua M. Clulow 	    ((dhx->dhx_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0));
1509a2bb96e7Sjmcp 
1510a2bb96e7Sjmcp 	if (f->ftcc.i == 0) {
1511a2bb96e7Sjmcp 		p_t = (f->f3.rs2 != 0 || p_rs1 == 0);
1512a2bb96e7Sjmcp 
1513a2bb96e7Sjmcp 		bprintf(dhp, "%-9s %s%s%s%s%s", inp->in_data.in_def.in_name,
1514a2bb96e7Sjmcp 		    (v9 != 0) ? icc_names[f->ftcc2.cc] : "",
1515a2bb96e7Sjmcp 		    (v9 != 0) ? ", " : "",
1516a2bb96e7Sjmcp 		    (p_rs1 != 0) ? reg_names[f->ftcc2.rs1] : "",
1517a2bb96e7Sjmcp 		    (p_rs1 != 0) ? " + " : "",
1518a2bb96e7Sjmcp 		    (p_t != 0) ? reg_names[f->f3.rs2] : "");
1519a2bb96e7Sjmcp 	} else {
1520a2bb96e7Sjmcp 		bprintf(dhp, "%-9s %s%s%s%s0x%x", inp->in_data.in_def.in_name,
1521a2bb96e7Sjmcp 		    (v9 != 0) ? icc_names[f->ftcc2.cc] : "",
1522a2bb96e7Sjmcp 		    (v9 != 0) ? ", " : "",
1523a2bb96e7Sjmcp 		    (p_rs1 != 0) ? reg_names[f->ftcc2.rs1] : "",
1524a2bb96e7Sjmcp 		    (p_rs1 != 0) ? " + " : "",
1525a2bb96e7Sjmcp 		    f->ftcc.immtrap);
1526a2bb96e7Sjmcp 	}
1527a2bb96e7Sjmcp 	return (0);
1528a2bb96e7Sjmcp }
1529a2bb96e7Sjmcp 
1530a2bb96e7Sjmcp static int
prt_shift(dis_handle_t * dhp,uint32_t instr,const inst_t * inp)1531a2bb96e7Sjmcp prt_shift(dis_handle_t *dhp, uint32_t instr, const inst_t *inp)
1532a2bb96e7Sjmcp {
1533a2bb96e7Sjmcp 	char name[5];
1534a2bb96e7Sjmcp 	uint32_t cnt;
1535a2bb96e7Sjmcp 
1536a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
1537a2bb96e7Sjmcp 	int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
1538a2bb96e7Sjmcp 
1539a2bb96e7Sjmcp 	name[0] = '\0';
1540a2bb96e7Sjmcp 	(void) strlcat(name, inp->in_data.in_def.in_name, sizeof (name));
1541a2bb96e7Sjmcp 
1542a2bb96e7Sjmcp 	if (f->f3b.i == 1)
1543a2bb96e7Sjmcp 		cnt = f->f3.rs2;
1544a2bb96e7Sjmcp 
1545a2bb96e7Sjmcp 	if (f->f3b.x == 1 && ((dhp->dh_flags & DIS_SPARC_V8) == 0)) {
1546a2bb96e7Sjmcp 		cnt = f->f3b.shcnt;
1547a2bb96e7Sjmcp 		(void) strlcat(name, "x", sizeof (name));
1548a2bb96e7Sjmcp 	}
1549a2bb96e7Sjmcp 
1550a2bb96e7Sjmcp 	prt_name(dhp, name, 1);
1551a2bb96e7Sjmcp 
1552a2bb96e7Sjmcp 	if (f->f3b.i == 1)
1553a2bb96e7Sjmcp 		bprintf(dhp, (octal != 0) ? "%s, 0%lo, %s" : "%s, 0x%lx, %s",
1554a2bb96e7Sjmcp 		    reg_names[f->f3.rs1], cnt, reg_names[f->f3.rd]);
1555a2bb96e7Sjmcp 	else
1556a2bb96e7Sjmcp 		bprintf(dhp, "%s, %s, %s", reg_names[f->f3.rs1],
1557a2bb96e7Sjmcp 		    reg_names[f->f3.rs2], reg_names[f->f3.rd]);
1558a2bb96e7Sjmcp 
1559a2bb96e7Sjmcp 	return (0);
1560a2bb96e7Sjmcp }
1561a2bb96e7Sjmcp 
1562a2bb96e7Sjmcp /* ARGSUSED3 */
1563a2bb96e7Sjmcp static int
prt_jmpl(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)1564a2bb96e7Sjmcp prt_jmpl(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1565a2bb96e7Sjmcp {
1566f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
1567a2bb96e7Sjmcp 	const char *name = inp->in_data.in_def.in_name;
1568a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
1569a2bb96e7Sjmcp 
1570f7184619SJoshua M. Clulow 	if (f->f3.rd == 15 && ((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0))
1571a2bb96e7Sjmcp 		name = "call";
1572a2bb96e7Sjmcp 
1573a2bb96e7Sjmcp 	if (f->f3.rd == 0) {
1574a2bb96e7Sjmcp 		if (f->f3.i == 1 && f->f3a.simm13 == 8) {
1575a2bb96e7Sjmcp 			if (f->f3.rs1 == 15) {
1576a2bb96e7Sjmcp 				prt_name(dhp, "retl", 0);
1577a2bb96e7Sjmcp 				return (0);
1578a2bb96e7Sjmcp 			}
1579a2bb96e7Sjmcp 
1580a2bb96e7Sjmcp 			if (f->f3.rs1 == 31) {
1581a2bb96e7Sjmcp 				prt_name(dhp, "ret", 0);
1582a2bb96e7Sjmcp 				return (0);
1583a2bb96e7Sjmcp 			}
1584a2bb96e7Sjmcp 		}
1585a2bb96e7Sjmcp 
1586a2bb96e7Sjmcp 		name = "jmp";
1587a2bb96e7Sjmcp 	}
1588a2bb96e7Sjmcp 
1589a2bb96e7Sjmcp 	prt_name(dhp, name, 1);
1590a2bb96e7Sjmcp 	prt_address(dhp, instr, 1);
1591a2bb96e7Sjmcp 
1592a2bb96e7Sjmcp 	if (f->f3.rd == 0)
1593a2bb96e7Sjmcp 		return (0);
1594a2bb96e7Sjmcp 
1595f7184619SJoshua M. Clulow 	if (f->f3.rd == 15 && ((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0))
1596a2bb96e7Sjmcp 		return (0);
1597a2bb96e7Sjmcp 
1598a2bb96e7Sjmcp 	bprintf(dhp, ", %s", reg_names[f->f3.rd]);
1599a2bb96e7Sjmcp 
1600a2bb96e7Sjmcp 	return (0);
1601a2bb96e7Sjmcp }
1602a2bb96e7Sjmcp 
1603a2bb96e7Sjmcp int
fmt_alu(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)1604a2bb96e7Sjmcp fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1605a2bb96e7Sjmcp {
1606f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
1607a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
1608a2bb96e7Sjmcp 
1609a2bb96e7Sjmcp 	const char *name = inp->in_data.in_def.in_name;
1610a2bb96e7Sjmcp 	int flags = inp->in_data.in_def.in_flags;
1611a2bb96e7Sjmcp 	int arg = 0;
1612a2bb96e7Sjmcp 
1613f7184619SJoshua M. Clulow 	if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
1614a2bb96e7Sjmcp 		prt_field("op", f->f3.op, 2);
1615a2bb96e7Sjmcp 		prt_field("op3", f->f3.op3, 6);
1616a2bb96e7Sjmcp 		prt_field("rs1", f->f3.rs1, 5);
1617a2bb96e7Sjmcp 
1618a2bb96e7Sjmcp 		switch (idx) {
1619a2bb96e7Sjmcp 			/* TODO: more formats */
1620a2bb96e7Sjmcp 
1621a2bb96e7Sjmcp 		default:
1622a2bb96e7Sjmcp 			if (f->f3.i == 0)
1623a2bb96e7Sjmcp 				prt_field("rs2", f->f3.rs2, 5);
1624a2bb96e7Sjmcp 			else
1625a2bb96e7Sjmcp 				prt_field("simm13", f->f3a.simm13, 13);
1626a2bb96e7Sjmcp 
1627a2bb96e7Sjmcp 			prt_field("rd", f->f3.rd, 5);
1628a2bb96e7Sjmcp 		}
1629a2bb96e7Sjmcp 
1630a2bb96e7Sjmcp 	}
1631a2bb96e7Sjmcp 
1632a2bb96e7Sjmcp 	switch (idx) {
1633a2bb96e7Sjmcp 	case 0x00:
1634a2bb96e7Sjmcp 		/* add */
1635a2bb96e7Sjmcp 
1636f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & DIS_DEBUG_SYN_ALL) == 0)
1637a2bb96e7Sjmcp 			break;
1638a2bb96e7Sjmcp 
1639a2bb96e7Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1640a2bb96e7Sjmcp 		    f->f3a.simm13 == 1) {
1641a2bb96e7Sjmcp 			name = "inc";
1642a2bb96e7Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
1643a2bb96e7Sjmcp 			break;
1644a2bb96e7Sjmcp 		}
1645a2bb96e7Sjmcp 
1646a2bb96e7Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1647a2bb96e7Sjmcp 		    f->f3a.simm13 != 1) {
1648a2bb96e7Sjmcp 			name = "inc";
1649a2bb96e7Sjmcp 			flags = FLG_P1(REG_NONE);
1650a2bb96e7Sjmcp 			break;
1651a2bb96e7Sjmcp 		}
1652a2bb96e7Sjmcp 		break;
1653a2bb96e7Sjmcp 
1654a2bb96e7Sjmcp 	case 0x02:
1655a2bb96e7Sjmcp 		/* or */
1656a2bb96e7Sjmcp 
1657f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
1658a2bb96e7Sjmcp 		    == 0)
1659a2bb96e7Sjmcp 			break;
1660a2bb96e7Sjmcp 
1661f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & DIS_DEBUG_SYN_ALL) != 0) {
1662a2bb96e7Sjmcp 			if (f->f3.rs1 == f->f3.rd) {
1663a2bb96e7Sjmcp 				name = "bset";
1664a2bb96e7Sjmcp 				flags = FLG_P1(REG_NONE);
1665a2bb96e7Sjmcp 				break;
1666a2bb96e7Sjmcp 			}
1667a2bb96e7Sjmcp 		}
1668a2bb96e7Sjmcp 
1669a2bb96e7Sjmcp 		if (((f->f3.i == 0 && f->f3.rs2 == 0) ||
1670a2bb96e7Sjmcp 		    (f->f3.i == 1 && f->f3a.simm13 == 0)) &&
1671a2bb96e7Sjmcp 		    (f->f3.rs1 == 0)) {
1672a2bb96e7Sjmcp 			name = "clr";
1673a2bb96e7Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
1674a2bb96e7Sjmcp 			break;
1675a2bb96e7Sjmcp 		}
1676a2bb96e7Sjmcp 
1677a2bb96e7Sjmcp 		if (f->f3.rs1 == 0) {
1678a2bb96e7Sjmcp 			name = "mov";
1679a2bb96e7Sjmcp 			flags = FLG_P1(REG_NONE);
1680a2bb96e7Sjmcp 			break;
1681a2bb96e7Sjmcp 		}
1682a2bb96e7Sjmcp 		break;
1683a2bb96e7Sjmcp 
1684a2bb96e7Sjmcp 	case 0x04:
1685a2bb96e7Sjmcp 		/* sub */
1686a2bb96e7Sjmcp 
1687f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
1688a2bb96e7Sjmcp 		    == 0)
1689a2bb96e7Sjmcp 			break;
1690a2bb96e7Sjmcp 
1691a2bb96e7Sjmcp 		if (f->f3.rs1 == 0 && f->f3.i == 0 && f->f3.rs2 == f->f3.rd) {
1692a2bb96e7Sjmcp 			name = "neg";
1693a2bb96e7Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE);
1694a2bb96e7Sjmcp 			break;
1695a2bb96e7Sjmcp 		}
1696a2bb96e7Sjmcp 
1697a2bb96e7Sjmcp 		if (f->f3.rs1 == 0 && f->f3.i == 0 && f->f3.rs2 != f->f3.rd) {
1698a2bb96e7Sjmcp 			name = "neg";
1699a2bb96e7Sjmcp 			flags = FLG_P1(REG_NONE);
1700a2bb96e7Sjmcp 			break;
1701a2bb96e7Sjmcp 		}
1702a2bb96e7Sjmcp 
1703f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & DIS_DEBUG_SYN_ALL) == 0)
1704a2bb96e7Sjmcp 			break;
1705a2bb96e7Sjmcp 
1706a2bb96e7Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1707a2bb96e7Sjmcp 		    f->f3a.simm13 == 1) {
1708a2bb96e7Sjmcp 			name = "dec";
1709a2bb96e7Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
1710a2bb96e7Sjmcp 			break;
1711a2bb96e7Sjmcp 		}
1712a2bb96e7Sjmcp 
1713a2bb96e7Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1714a2bb96e7Sjmcp 		    f->f3a.simm13 != 1) {
1715a2bb96e7Sjmcp 			name = "dec";
1716a2bb96e7Sjmcp 			flags = FLG_P1(REG_NONE);
1717a2bb96e7Sjmcp 			break;
1718a2bb96e7Sjmcp 		}
1719a2bb96e7Sjmcp 		break;
1720a2bb96e7Sjmcp 
1721a2bb96e7Sjmcp 	case 0x07:
1722a2bb96e7Sjmcp 		/* xnor */
1723a2bb96e7Sjmcp 
1724f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
1725a2bb96e7Sjmcp 		    == 0)
1726a2bb96e7Sjmcp 			break;
1727a2bb96e7Sjmcp 
1728a2bb96e7Sjmcp 		/*
1729a2bb96e7Sjmcp 		 * xnor -> not when you have:
1730a2bb96e7Sjmcp 		 *	 xnor %rs1, 0x0 or %g0, %rd
1731a2bb96e7Sjmcp 		 */
1732a2bb96e7Sjmcp 		if ((f->f3.i == 0 && f->f3.rs2 != 0) ||
1733a2bb96e7Sjmcp 		    (f->f3.i == 1 && f->f3a.simm13 != 0))
1734a2bb96e7Sjmcp 			break;
1735a2bb96e7Sjmcp 
1736a2bb96e7Sjmcp 		name = "not";
1737a2bb96e7Sjmcp 
1738a2bb96e7Sjmcp 		if (f->f3.rs1 == f->f3.rd)
1739a2bb96e7Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM|
1740a2bb96e7Sjmcp 			    FLG_P3(REG_INT);
1741a2bb96e7Sjmcp 		else
1742a2bb96e7Sjmcp 			flags = FLG_P1(REG_INT)|FLG_P2(REG_NONE)|FLG_NOIMM|
1743a2bb96e7Sjmcp 			    FLG_P3(REG_INT);
1744a2bb96e7Sjmcp 
1745a2bb96e7Sjmcp 		break;
1746a2bb96e7Sjmcp 
1747a2bb96e7Sjmcp 	case 0x10:
1748a2bb96e7Sjmcp 		/* addcc */
1749a2bb96e7Sjmcp 
1750f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & DIS_DEBUG_SYN_ALL) == 0)
1751a2bb96e7Sjmcp 			break;
1752a2bb96e7Sjmcp 
1753a2bb96e7Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1754a2bb96e7Sjmcp 		    f->f3a.simm13 == 1) {
1755a2bb96e7Sjmcp 			name = "inccc";
1756a2bb96e7Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
1757a2bb96e7Sjmcp 			break;
1758a2bb96e7Sjmcp 		}
1759a2bb96e7Sjmcp 
1760a2bb96e7Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1761a2bb96e7Sjmcp 		    f->f3a.simm13 != 1) {
1762a2bb96e7Sjmcp 			name = "inccc";
1763a2bb96e7Sjmcp 			flags = FLG_P1(REG_NONE);
1764a2bb96e7Sjmcp 			break;
1765a2bb96e7Sjmcp 		}
1766a2bb96e7Sjmcp 		break;
1767a2bb96e7Sjmcp 
1768a2bb96e7Sjmcp 	case 0x11:
1769a2bb96e7Sjmcp 		/* andcc */
1770a2bb96e7Sjmcp 
1771a2bb96e7Sjmcp 		if (f->f3.rd != 0)
1772a2bb96e7Sjmcp 			break;
1773a2bb96e7Sjmcp 
1774f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
1775a2bb96e7Sjmcp 		    == 0)
1776a2bb96e7Sjmcp 			break;
1777a2bb96e7Sjmcp 
1778f7184619SJoshua M. Clulow 		if (((dhx->dhx_debug & DIS_DEBUG_COMPAT) != 0) &&
1779a2bb96e7Sjmcp 		    ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) == 0))
1780a2bb96e7Sjmcp 			break;
1781a2bb96e7Sjmcp 
1782a2bb96e7Sjmcp 		name = "btst";
1783a2bb96e7Sjmcp 		flags = FLG_P1(REG_NONE);
1784a2bb96e7Sjmcp 		f->f3.rd = f->f3.rs1;
1785a2bb96e7Sjmcp 		break;
1786a2bb96e7Sjmcp 
1787a2bb96e7Sjmcp 	case 0x12:
1788a2bb96e7Sjmcp 		/* orcc */
1789a2bb96e7Sjmcp 
1790f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
1791a2bb96e7Sjmcp 		    == 0)
1792a2bb96e7Sjmcp 			break;
1793a2bb96e7Sjmcp 
1794a2bb96e7Sjmcp 		if (f->f3.rs1 == 0 && f->f3.rd == 0 && f->f3.i == 0) {
1795a2bb96e7Sjmcp 			name = "tst";
1796a2bb96e7Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P3(REG_NONE);
1797a2bb96e7Sjmcp 			break;
1798a2bb96e7Sjmcp 		}
1799a2bb96e7Sjmcp 
1800a2bb96e7Sjmcp 		if (f->f3.rs2 == 0 && f->f3.rd == 0 && f->f3.i == 0) {
1801a2bb96e7Sjmcp 			name = "tst";
1802a2bb96e7Sjmcp 			flags = FLG_P2(REG_NONE)|FLG_P3(REG_NONE);
1803a2bb96e7Sjmcp 			break;
1804a2bb96e7Sjmcp 		}
1805a2bb96e7Sjmcp 
1806a2bb96e7Sjmcp 		break;
1807a2bb96e7Sjmcp 
1808a2bb96e7Sjmcp 	case 0x14:
1809a2bb96e7Sjmcp 		/* subcc */
1810a2bb96e7Sjmcp 
1811f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
1812a2bb96e7Sjmcp 		    == 0)
1813a2bb96e7Sjmcp 			break;
1814a2bb96e7Sjmcp 
1815a2bb96e7Sjmcp 		if (f->f3.rd == 0) {
1816a2bb96e7Sjmcp 			name = "cmp";
1817a2bb96e7Sjmcp 			flags = FLG_P3(REG_NONE);
1818a2bb96e7Sjmcp 			break;
1819a2bb96e7Sjmcp 		}
1820a2bb96e7Sjmcp 
1821f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & DIS_DEBUG_COMPAT) != 0)
1822a2bb96e7Sjmcp 			break;
1823a2bb96e7Sjmcp 
1824a2bb96e7Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1825a2bb96e7Sjmcp 		    f->f3a.simm13 == 1) {
1826a2bb96e7Sjmcp 			name = "deccc";
1827a2bb96e7Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
1828a2bb96e7Sjmcp 			break;
1829a2bb96e7Sjmcp 		}
1830a2bb96e7Sjmcp 
1831a2bb96e7Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1832a2bb96e7Sjmcp 		    f->f3a.simm13 != 1) {
1833a2bb96e7Sjmcp 			name = "deccc";
1834a2bb96e7Sjmcp 			flags = FLG_P1(REG_NONE);
1835a2bb96e7Sjmcp 			break;
1836a2bb96e7Sjmcp 		}
1837a2bb96e7Sjmcp 
1838a2bb96e7Sjmcp 		break;
1839a2bb96e7Sjmcp 
1840a2bb96e7Sjmcp 	case 0x25:
1841a2bb96e7Sjmcp 	case 0x26:
1842a2bb96e7Sjmcp 	case 0x27:
1843a2bb96e7Sjmcp 		return (prt_shift(dhp, instr, inp));
1844a2bb96e7Sjmcp 
1845a2bb96e7Sjmcp 	case 0x28:
1846a2bb96e7Sjmcp 	case 0x29:
1847a2bb96e7Sjmcp 	case 0x2a:
1848a2bb96e7Sjmcp 	case 0x2b:
1849a2bb96e7Sjmcp 	case 0x30:
1850a2bb96e7Sjmcp 	case 0x31:
1851a2bb96e7Sjmcp 	case 0x32:
1852a2bb96e7Sjmcp 	case 0x33:
1853a2bb96e7Sjmcp 		return (dis_fmt_rdwr(dhp, instr, inp, idx));
1854a2bb96e7Sjmcp 
1855a2bb96e7Sjmcp 	case 0x36:
1856a2bb96e7Sjmcp 	case 0x37:
1857a2bb96e7Sjmcp 		/* NOTE: overlayed on v9 */
1858a2bb96e7Sjmcp 		if ((dhp->dh_flags & DIS_SPARC_V8) != 0)
1859a2bb96e7Sjmcp 			return (fmt_cpop(dhp, instr, inp));
1860a2bb96e7Sjmcp 		break;
1861a2bb96e7Sjmcp 
1862a2bb96e7Sjmcp 	case 0x38:
1863a2bb96e7Sjmcp 		/* jmpl */
1864a2bb96e7Sjmcp 		return (prt_jmpl(dhp, instr, inp, idx));
1865a2bb96e7Sjmcp 
1866a2bb96e7Sjmcp 	case 0x39:
1867a2bb96e7Sjmcp 		/* rett / return */
1868a2bb96e7Sjmcp 		prt_name(dhp, name, 1);
1869a2bb96e7Sjmcp 		prt_address(dhp, instr, 1);
1870a2bb96e7Sjmcp 		return (0);
1871a2bb96e7Sjmcp 
1872a2bb96e7Sjmcp 	case 0x3b:
18739d0d62adSJason Beloro 		/* flush */
18749d0d62adSJason Beloro 		prt_name(dhp, name, 1);
18759d0d62adSJason Beloro 		prt_address(dhp, instr, 0);
1876a2bb96e7Sjmcp 		return (0);
1877a2bb96e7Sjmcp 
1878a2bb96e7Sjmcp 	case 0x3c:
1879a2bb96e7Sjmcp 	case 0x3d:
1880a2bb96e7Sjmcp 		/* save / restore */
1881f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
1882a2bb96e7Sjmcp 		    == 0)
1883a2bb96e7Sjmcp 			break;
1884a2bb96e7Sjmcp 
1885a2bb96e7Sjmcp 		if (f->f3.rs1 != 0 || f->f3.rs2 != 0 || f->f3.rd != 0)
1886a2bb96e7Sjmcp 			break;
1887a2bb96e7Sjmcp 
1888f7184619SJoshua M. Clulow 		if (f->f3.i != 0 && ((dhx->dhx_debug & DIS_DEBUG_COMPAT) != 0))
1889a2bb96e7Sjmcp 			break;
1890a2bb96e7Sjmcp 
1891a2bb96e7Sjmcp 		prt_name(dhp, name, 0);
1892a2bb96e7Sjmcp 		return (0);
1893a2bb96e7Sjmcp 	}
1894a2bb96e7Sjmcp 
1895a2bb96e7Sjmcp 	if (FLG_P1_VAL(flags) != REG_NONE || FLG_P2_VAL(flags) != REG_NONE ||
1896a2bb96e7Sjmcp 	    FLG_P3_VAL(flags) != REG_NONE)
1897a2bb96e7Sjmcp 		arg = 1;
1898a2bb96e7Sjmcp 
1899a2bb96e7Sjmcp 	prt_name(dhp, name, (arg != 0));
1900a2bb96e7Sjmcp 	prt_aluargs(dhp, instr, flags);
1901a2bb96e7Sjmcp 
1902a2bb96e7Sjmcp 	return (0);
1903a2bb96e7Sjmcp }
1904a2bb96e7Sjmcp 
1905a2bb96e7Sjmcp /* ARGSUSED1 */
1906a2bb96e7Sjmcp int
fmt_regwin(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)1907a2bb96e7Sjmcp fmt_regwin(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1908a2bb96e7Sjmcp {
1909a2bb96e7Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 0);
1910a2bb96e7Sjmcp 	return (0);
1911a2bb96e7Sjmcp }
1912a2bb96e7Sjmcp 
1913a2bb96e7Sjmcp /* ARGSUSED1 */
1914a2bb96e7Sjmcp int
fmt_trap_ret(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)1915a2bb96e7Sjmcp fmt_trap_ret(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1916a2bb96e7Sjmcp {
19172f0fcb93SJason Beloro 	ifmt_t *f = (ifmt_t *)&instr;
19182f0fcb93SJason Beloro 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
19192f0fcb93SJason Beloro 
19202f0fcb93SJason Beloro 	if (f->f3.rd == 0xf) {
19212f0fcb93SJason Beloro 		/* jpriv */
19222f0fcb93SJason Beloro 		prt_address(dhp, instr, 1);
19232f0fcb93SJason Beloro 	}
19242f0fcb93SJason Beloro 
1925a2bb96e7Sjmcp 	return (0);
1926a2bb96e7Sjmcp }
1927a2bb96e7Sjmcp 
1928a2bb96e7Sjmcp /* ARGSUSED3 */
1929a2bb96e7Sjmcp int
fmt_movcc(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)1930a2bb96e7Sjmcp fmt_movcc(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1931a2bb96e7Sjmcp {
1932f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
1933a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
1934a2bb96e7Sjmcp 	const char **regs = NULL;
1935a2bb96e7Sjmcp 
1936f7184619SJoshua M. Clulow 	if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
1937a2bb96e7Sjmcp 		prt_field("op", f->f3c.op, 2);
1938a2bb96e7Sjmcp 		prt_field("op3", f->f3c.op3, 6);
1939a2bb96e7Sjmcp 		prt_field("cond", f->f3c.cond, 4);
1940a2bb96e7Sjmcp 		prt_field("cc2", f->f3c.cc2, 1);
1941a2bb96e7Sjmcp 		prt_field("cc", f->f3c.cc, 2);
1942a2bb96e7Sjmcp 		prt_field("i", f->f3c.i, 1);
1943a2bb96e7Sjmcp 
1944a2bb96e7Sjmcp 		if (f->f3c.i == 0)
1945a2bb96e7Sjmcp 			prt_field("rs2", f->f3.rs2, 5);
1946a2bb96e7Sjmcp 		else
1947a2bb96e7Sjmcp 			prt_field("simm11", f->f3c.simm11, 11);
1948a2bb96e7Sjmcp 
1949a2bb96e7Sjmcp 		prt_field("rd", f->f3.rd, 5);
1950a2bb96e7Sjmcp 	}
1951a2bb96e7Sjmcp 
1952a2bb96e7Sjmcp 	if (f->f3c.cc2 == 0) {
1953a2bb96e7Sjmcp 		regs = fcc_names;
1954a2bb96e7Sjmcp 	} else {
1955a2bb96e7Sjmcp 		regs = icc_names;
1956a2bb96e7Sjmcp 		if (regs[f->f3c.cc] == NULL)
1957a2bb96e7Sjmcp 			return (-1);
1958a2bb96e7Sjmcp 	}
1959a2bb96e7Sjmcp 
1960a2bb96e7Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
1961a2bb96e7Sjmcp 
1962a2bb96e7Sjmcp 	bprintf(dhp, "%s, ", regs[f->f3c.cc]);
1963a2bb96e7Sjmcp 
1964a2bb96e7Sjmcp 	if (f->f3c.i == 1)
1965a2bb96e7Sjmcp 		prt_imm(dhp, sign_extend(f->f3c.simm11, 11), IMM_SIGNED);
1966a2bb96e7Sjmcp 	else
1967f7184619SJoshua M. Clulow 		(void) strlcat(dhx->dhx_buf, reg_names[f->f3.rs2],
1968f7184619SJoshua M. Clulow 		    dhx->dhx_buflen);
1969a2bb96e7Sjmcp 
1970a2bb96e7Sjmcp 	bprintf(dhp, ", %s", reg_names[f->f3.rd]);
1971a2bb96e7Sjmcp 
1972a2bb96e7Sjmcp 	return (0);
1973a2bb96e7Sjmcp }
1974a2bb96e7Sjmcp 
1975a2bb96e7Sjmcp /* ARGSUSED3 */
1976a2bb96e7Sjmcp int
fmt_movr(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)1977a2bb96e7Sjmcp fmt_movr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1978a2bb96e7Sjmcp {
1979f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
1980a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
1981a2bb96e7Sjmcp 
1982a2bb96e7Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
1983a2bb96e7Sjmcp 
1984a2bb96e7Sjmcp 	bprintf(dhp, "%s, ", reg_names[f->f3d.rs1]);
1985a2bb96e7Sjmcp 
1986a2bb96e7Sjmcp 	if (f->f3d.i == 1)
1987a2bb96e7Sjmcp 		prt_imm(dhp, sign_extend(f->f3d.simm10, 10), IMM_SIGNED);
1988a2bb96e7Sjmcp 	else
1989f7184619SJoshua M. Clulow 		(void) strlcat(dhx->dhx_buf, reg_names[f->f3.rs2],
1990f7184619SJoshua M. Clulow 		    dhx->dhx_buflen);
1991a2bb96e7Sjmcp 
1992a2bb96e7Sjmcp 	bprintf(dhp, ", %s", reg_names[f->f3.rd]);
1993a2bb96e7Sjmcp 
1994a2bb96e7Sjmcp 	return (0);
1995a2bb96e7Sjmcp }
1996a2bb96e7Sjmcp 
1997a2bb96e7Sjmcp /* ARGSUSED3 */
1998a2bb96e7Sjmcp int
fmt_fpop1(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)1999a2bb96e7Sjmcp fmt_fpop1(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
2000a2bb96e7Sjmcp {
2001f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
2002a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
2003a2bb96e7Sjmcp 	int flags = inp->in_data.in_def.in_flags;
2004a2bb96e7Sjmcp 
2005a2bb96e7Sjmcp 	flags |= FLG_NOIMM;
2006a2bb96e7Sjmcp 
2007f7184619SJoshua M. Clulow 	if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
2008a2bb96e7Sjmcp 		prt_field("op", f->f3.op, 2);
2009a2bb96e7Sjmcp 		prt_field("op3", f->f3.op3, 6);
2010a2bb96e7Sjmcp 		prt_field("opf", f->fcmp.opf, 9);
2011a2bb96e7Sjmcp 		prt_field("rs1", f->f3.rs1, 5);
2012a2bb96e7Sjmcp 		prt_field("rs2", f->f3.rs2, 5);
2013a2bb96e7Sjmcp 		prt_field("rd", f->f3.rd, 5);
2014a2bb96e7Sjmcp 	}
2015a2bb96e7Sjmcp 
2016a2bb96e7Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
2017a2bb96e7Sjmcp 	prt_aluargs(dhp, instr, flags);
2018a2bb96e7Sjmcp 
2019a2bb96e7Sjmcp 	return (0);
2020a2bb96e7Sjmcp }
2021a2bb96e7Sjmcp 
2022a2bb96e7Sjmcp int
fmt_fpop2(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)2023a2bb96e7Sjmcp fmt_fpop2(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
2024a2bb96e7Sjmcp {
2025a2bb96e7Sjmcp 	static const char *condstr_icc[16] = {
2026a2bb96e7Sjmcp 		"n", "e",  "le", "l",  "leu", "lu",  "neg", "vs",
2027a2bb96e7Sjmcp 		"a", "nz", "g",  "ge", "gu",  "geu", "pos", "vc"
2028a2bb96e7Sjmcp 	};
2029a2bb96e7Sjmcp 
2030a2bb96e7Sjmcp 	static const char *condstr_fcc[16] = {
2031a2bb96e7Sjmcp 		"n", "nz", "lg", "ul", "l",   "ug", "g",   "u",
2032a2bb96e7Sjmcp 		"a", "e",  "ue", "ge", "uge", "le", "ule", "o"
2033a2bb96e7Sjmcp 	};
2034a2bb96e7Sjmcp 
2035f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
2036a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
2037a2bb96e7Sjmcp 	const char *ccstr = "";
2038a2bb96e7Sjmcp 	char name[15];
2039a2bb96e7Sjmcp 
2040a2bb96e7Sjmcp 	int flags = inp->in_data.in_def.in_flags;
2041a2bb96e7Sjmcp 	int is_cmp = (idx == 0x51 || idx == 0x52 || idx == 0x53 ||
2042a2bb96e7Sjmcp 	    idx == 0x55 || idx == 0x56 || idx == 0x57);
2043a2bb96e7Sjmcp 	int is_fmov = (idx & 0x3f);
2044a2bb96e7Sjmcp 	int is_v9 = ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0);
2045f7184619SJoshua M. Clulow 	int is_compat = ((dhx->dhx_debug & DIS_DEBUG_COMPAT) != 0);
2046a2bb96e7Sjmcp 
2047a2bb96e7Sjmcp 	int p_cc = 0;
2048a2bb96e7Sjmcp 
2049a2bb96e7Sjmcp 	is_fmov = (is_fmov == 0x1 || is_fmov == 0x2 || is_fmov == 0x3);
2050a2bb96e7Sjmcp 
2051f7184619SJoshua M. Clulow 	if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
2052a2bb96e7Sjmcp 		prt_field("op", f->f3.op, 2);
2053a2bb96e7Sjmcp 		prt_field("op3", f->f3.op3, 6);
2054a2bb96e7Sjmcp 		prt_field("opf", f->fcmp.opf, 9);
2055a2bb96e7Sjmcp 
2056a2bb96e7Sjmcp 		switch (idx & 0x3f) {
2057a2bb96e7Sjmcp 		case 0x51:
2058a2bb96e7Sjmcp 		case 0x52:
2059a2bb96e7Sjmcp 		case 0x53:
2060a2bb96e7Sjmcp 		case 0x55:
2061a2bb96e7Sjmcp 		case 0x56:
2062a2bb96e7Sjmcp 		case 0x57:
2063a2bb96e7Sjmcp 			prt_field("cc", f->fcmp.cc, 2);
2064a2bb96e7Sjmcp 			prt_field("rs1", f->f3.rs1, 5);
2065a2bb96e7Sjmcp 			prt_field("rs2", f->f3.rs2, 5);
2066a2bb96e7Sjmcp 			break;
2067a2bb96e7Sjmcp 
2068a2bb96e7Sjmcp 		case 0x01:
2069a2bb96e7Sjmcp 		case 0x02:
2070a2bb96e7Sjmcp 		case 0x03:
2071a2bb96e7Sjmcp 			prt_field("opf_low", f->fmv.opf, 6);
2072a2bb96e7Sjmcp 			prt_field("cond", f->fmv.cond, 4);
2073a2bb96e7Sjmcp 			prt_field("opf_cc", f->fmv.cc, 3);
2074a2bb96e7Sjmcp 			prt_field("rs2", f->fmv.rs2, 5);
2075a2bb96e7Sjmcp 			break;
2076a2bb96e7Sjmcp 
2077a2bb96e7Sjmcp 		default:
2078a2bb96e7Sjmcp 			prt_field("rs1", f->f3.rs1, 5);
2079a2bb96e7Sjmcp 			prt_field("rs2", f->f3.rs2, 5);
2080a2bb96e7Sjmcp 			prt_field("rd", f->f3.rd, 5);
2081a2bb96e7Sjmcp 		}
2082a2bb96e7Sjmcp 	}
2083a2bb96e7Sjmcp 
2084a2bb96e7Sjmcp 	name[0] = '\0';
2085a2bb96e7Sjmcp 	(void) strlcat(name, inp->in_data.in_def.in_name, sizeof (name));
2086a2bb96e7Sjmcp 
2087a2bb96e7Sjmcp 	if (is_fmov != 0) {
2088a2bb96e7Sjmcp 		(void) strlcat(name,
2089a2bb96e7Sjmcp 		    (f->fmv.cc < 4) ? condstr_fcc[f->fmv.cond]
2090a2bb96e7Sjmcp 		    : condstr_icc[f->fmv.cond],
2091a2bb96e7Sjmcp 		    sizeof (name));
2092a2bb96e7Sjmcp 	}
2093a2bb96e7Sjmcp 
2094a2bb96e7Sjmcp 	prt_name(dhp, name, 1);
2095a2bb96e7Sjmcp 
2096a2bb96e7Sjmcp 	if (is_cmp != 0)
2097a2bb96e7Sjmcp 		ccstr = fcc_names[f->fcmp.cc];
2098a2bb96e7Sjmcp 
2099a2bb96e7Sjmcp 	if (is_fmov != 0)
2100a2bb96e7Sjmcp 		ccstr = (f->fmv.cc < 4) ? fcc_names[f->fmv.cc & 0x3]
2101a2bb96e7Sjmcp 		    : icc_names[f->fmv.cc & 0x3];
2102a2bb96e7Sjmcp 
2103a2bb96e7Sjmcp 	if (ccstr == NULL)
2104a2bb96e7Sjmcp 		return (-1);
2105a2bb96e7Sjmcp 
2106a2bb96e7Sjmcp 	p_cc = (is_compat == 0 || is_v9 != 0 ||
2107a2bb96e7Sjmcp 	    (is_cmp != 0 && f->fcmp.cc != 0) ||
2108a2bb96e7Sjmcp 	    (is_fmov != 0 && f->fmv.cc != 0));
2109a2bb96e7Sjmcp 
2110a2bb96e7Sjmcp 	if (p_cc != 0)
2111a2bb96e7Sjmcp 		bprintf(dhp, "%s, ", ccstr);
2112a2bb96e7Sjmcp 
2113a2bb96e7Sjmcp 	prt_aluargs(dhp, instr, flags);
2114a2bb96e7Sjmcp 
2115a2bb96e7Sjmcp 	return (0);
2116a2bb96e7Sjmcp }
2117a2bb96e7Sjmcp 
2118a2bb96e7Sjmcp int
fmt_vis(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)2119a2bb96e7Sjmcp fmt_vis(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
2120a2bb96e7Sjmcp {
2121f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
2122a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
2123a2bb96e7Sjmcp 	int flags = inp->in_data.in_def.in_flags;
2124a2bb96e7Sjmcp 
2125f7184619SJoshua M. Clulow 	if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
2126a2bb96e7Sjmcp 		prt_field("op", f->f3.op, 2);
2127a2bb96e7Sjmcp 		prt_field("op3", f->f3.op3, 6);
2128a2bb96e7Sjmcp 		prt_field("opf", f->fcmp.opf, 9);
2129a2bb96e7Sjmcp 
2130a2bb96e7Sjmcp 		if (idx == 0x081) {
2131a2bb96e7Sjmcp 			prt_field("mode", instr & 02L, 2);
2132a2bb96e7Sjmcp 		} else {
2133a2bb96e7Sjmcp 			prt_field("rs1", f->f3.rs1, 5);
2134a2bb96e7Sjmcp 			prt_field("rs2", f->f3.rs2, 5);
2135a2bb96e7Sjmcp 			prt_field("rd", f->f3.rd, 5);
2136a2bb96e7Sjmcp 		}
2137a2bb96e7Sjmcp 	}
2138a2bb96e7Sjmcp 
2139a2bb96e7Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
2140a2bb96e7Sjmcp 
2141a2bb96e7Sjmcp 	if (idx == 0x081) {
2142a2bb96e7Sjmcp 		/* siam */
2143a2bb96e7Sjmcp 		bprintf(dhp, "%d", instr & 0x7L);
2144a2bb96e7Sjmcp 		return (0);
2145a2bb96e7Sjmcp 	}
2146a2bb96e7Sjmcp 
2147a2bb96e7Sjmcp 	prt_aluargs(dhp, instr, flags);
2148a2bb96e7Sjmcp 
2149a2bb96e7Sjmcp 	return (0);
2150a2bb96e7Sjmcp }
2151a2bb96e7Sjmcp 
2152a2bb96e7Sjmcp /* ARGSUSED3 */
2153a2bb96e7Sjmcp int
fmt_fused(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)2154a2bb96e7Sjmcp fmt_fused(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
2155a2bb96e7Sjmcp {
2156a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
2157a2bb96e7Sjmcp 	int flags = inp->in_data.in_def.in_flags;
2158a2bb96e7Sjmcp 
2159a2bb96e7Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
2160a2bb96e7Sjmcp 	bprintf(dhp, "%s, %s, %s, %s",
2161a2bb96e7Sjmcp 	    get_regname(dhp, FLG_P1_VAL(flags), f->fused.rs1),
2162a2bb96e7Sjmcp 	    get_regname(dhp, FLG_P1_VAL(flags), f->fused.rs2),
2163a2bb96e7Sjmcp 	    get_regname(dhp, FLG_P1_VAL(flags), f->fused.rs3),
2164a2bb96e7Sjmcp 	    get_regname(dhp, FLG_P1_VAL(flags), f->fused.rd));
2165a2bb96e7Sjmcp 
2166a2bb96e7Sjmcp 	return (0);
2167a2bb96e7Sjmcp }
2168a2bb96e7Sjmcp /*
2169a2bb96e7Sjmcp  * put name into the output buffer
2170a2bb96e7Sjmcp  * if add_space !=0, append a space after it
2171a2bb96e7Sjmcp  */
2172a2bb96e7Sjmcp static void
prt_name(dis_handle_t * dhp,const char * name,int add_space)2173a2bb96e7Sjmcp prt_name(dis_handle_t *dhp, const char *name, int add_space)
2174a2bb96e7Sjmcp {
2175a2bb96e7Sjmcp 	bprintf(dhp, (add_space == 0) ? "%s" : "%-9s ", name);
2176a2bb96e7Sjmcp }
2177a2bb96e7Sjmcp 
2178a2bb96e7Sjmcp /*
2179a2bb96e7Sjmcp  * For debugging, print out a field of the instruction
2180a2bb96e7Sjmcp  * field is the name of the field
2181a2bb96e7Sjmcp  * val is the value of the field
2182a2bb96e7Sjmcp  * len is the length of the field (in bits)
2183a2bb96e7Sjmcp  */
2184a2bb96e7Sjmcp #if defined(DIS_STANDALONE)
2185a2bb96e7Sjmcp /* ARGSUSED */
2186a2bb96e7Sjmcp static void
prt_field(const char * field,uint32_t val,int len)2187a2bb96e7Sjmcp prt_field(const char *field, uint32_t val, int len)
2188a2bb96e7Sjmcp {
2189a2bb96e7Sjmcp 
2190a2bb96e7Sjmcp }
2191a2bb96e7Sjmcp 
2192a2bb96e7Sjmcp #else
2193a2bb96e7Sjmcp static void
prt_field(const char * field,uint32_t val,int len)2194a2bb96e7Sjmcp prt_field(const char *field, uint32_t val, int len)
2195a2bb96e7Sjmcp {
2196b8ef3d63SJason King 	(void) fprintf(stderr, "DISASM: %8s = 0x%-8x (", field, val);
2197a2bb96e7Sjmcp 	prt_binary(val, len);
2198a2bb96e7Sjmcp 	(void) fprintf(stderr, ")\n");
2199a2bb96e7Sjmcp }
2200a2bb96e7Sjmcp #endif /* DIS_STANDALONE */
2201a2bb96e7Sjmcp 
2202a2bb96e7Sjmcp /*
2203a2bb96e7Sjmcp  * sign extend a val (that is 'bits' bits in length) to a 32-bit signed
2204a2bb96e7Sjmcp  * integer
2205a2bb96e7Sjmcp  */
2206a2bb96e7Sjmcp static int32_t
sign_extend(int32_t val,uint32_t bits)2207*e3ed3d33SToomas Soome sign_extend(int32_t val, uint32_t bits)
2208a2bb96e7Sjmcp {
2209*e3ed3d33SToomas Soome 	uint32_t mask;
2210a2bb96e7Sjmcp 
2211*e3ed3d33SToomas Soome 	ASSERT(bits > 0);
2212*e3ed3d33SToomas Soome 	mask = 1L << (bits - 1);	/* 2**(bits - 1) */
2213*e3ed3d33SToomas Soome 	return (-(val & mask) + (val & ~mask));
2214a2bb96e7Sjmcp }
2215a2bb96e7Sjmcp 
2216a2bb96e7Sjmcp /*
2217a2bb96e7Sjmcp  * print out an immediate (i.e. constant) value
2218a2bb96e7Sjmcp  * val is the value
2219a2bb96e7Sjmcp  * format indicates if it is:
2220a2bb96e7Sjmcp  * 0		 Unsigned
2221a2bb96e7Sjmcp  * IMM_SIGNED  A signed value (prepend +/- to the value)
2222a2bb96e7Sjmcp  * IMM_ADDR    Part of an address expression (prepend +/- but with a space
2223a2bb96e7Sjmcp  *		   between the sign and the value for things like [%i1 + 0x55]
2224a2bb96e7Sjmcp  */
2225a2bb96e7Sjmcp static void
prt_imm(dis_handle_t * dhp,uint32_t val,int format)2226a2bb96e7Sjmcp prt_imm(dis_handle_t *dhp, uint32_t val, int format)
2227a2bb96e7Sjmcp {
2228a2bb96e7Sjmcp 	const char *fmtstr = NULL;
2229a2bb96e7Sjmcp 	int32_t sv = (int32_t)val;
2230a2bb96e7Sjmcp 	int octal = dhp->dh_flags & DIS_OCTAL;
2231a2bb96e7Sjmcp 
2232a2bb96e7Sjmcp 	switch (format) {
2233a2bb96e7Sjmcp 	case IMM_ADDR:
2234a2bb96e7Sjmcp 		if (sv < 0) {
2235a2bb96e7Sjmcp 			sv = -sv;
2236a2bb96e7Sjmcp 			fmtstr = (octal != 0) ? "- 0%lo" : "- 0x%lx";
2237a2bb96e7Sjmcp 		} else {
2238a2bb96e7Sjmcp 			fmtstr = (octal != 0) ? "+ 0%lo" : "+ 0x%lx";
2239a2bb96e7Sjmcp 		}
2240a2bb96e7Sjmcp 		break;
2241a2bb96e7Sjmcp 
2242a2bb96e7Sjmcp 	case IMM_SIGNED:
2243a2bb96e7Sjmcp 		if (sv < 0) {
2244a2bb96e7Sjmcp 			sv = -sv;
2245a2bb96e7Sjmcp 			fmtstr = (octal != 0) ? "-0%lo" : "-0x%lx";
2246a2bb96e7Sjmcp 			break;
2247a2bb96e7Sjmcp 		}
2248a2bb96e7Sjmcp 		/* fall through */
2249a2bb96e7Sjmcp 
2250a2bb96e7Sjmcp 	default:
2251a2bb96e7Sjmcp 		fmtstr = (octal != 0) ? "0%lo" : "0x%lx";
2252a2bb96e7Sjmcp 	}
2253a2bb96e7Sjmcp 
2254a2bb96e7Sjmcp 	bprintf(dhp, fmtstr, sv);
2255a2bb96e7Sjmcp }
2256a2bb96e7Sjmcp 
2257a2bb96e7Sjmcp /*
2258a2bb96e7Sjmcp  * return the symbolic name of a register
2259a2bb96e7Sjmcp  * regset is one of the REG_* values indicating which type of register it is
2260a2bb96e7Sjmcp  * such as integer, floating point, etc.
2261a2bb96e7Sjmcp  * idx is the numeric value of the register
2262a2bb96e7Sjmcp  *
2263a2bb96e7Sjmcp  * If regset is REG_NONE, an empty, but non-NULL string is returned
2264a2bb96e7Sjmcp  * NULL may be returned if the index indicates an invalid register value
2265a2bb96e7Sjmcp  * such as with the %icc/%xcc sets
2266a2bb96e7Sjmcp  */
2267a2bb96e7Sjmcp static const char *
get_regname(dis_handle_t * dhp,int regset,uint32_t idx)2268a2bb96e7Sjmcp get_regname(dis_handle_t *dhp, int regset, uint32_t idx)
2269a2bb96e7Sjmcp {
2270f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
2271a2bb96e7Sjmcp 	const char *regname = NULL;
2272a2bb96e7Sjmcp 
2273a2bb96e7Sjmcp 	switch (regset) {
2274a2bb96e7Sjmcp 	case REG_INT:
2275a2bb96e7Sjmcp 		regname = reg_names[idx];
2276a2bb96e7Sjmcp 		break;
2277a2bb96e7Sjmcp 
2278a2bb96e7Sjmcp 	case REG_FP:
2279a2bb96e7Sjmcp 		regname = freg_names[idx];
2280a2bb96e7Sjmcp 		break;
2281a2bb96e7Sjmcp 
2282a2bb96e7Sjmcp 	case REG_FPD:
2283f7184619SJoshua M. Clulow 		if (((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0) ||
22842f0fcb93SJason Beloro 		    ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0))
2285a2bb96e7Sjmcp 			regname = fdreg_names[idx];
2286a2bb96e7Sjmcp 		else
2287a2bb96e7Sjmcp 			regname = compat_fdreg_names[idx];
2288a2bb96e7Sjmcp 
2289a2bb96e7Sjmcp 		break;
2290a2bb96e7Sjmcp 
2291a2bb96e7Sjmcp 	case REG_FPQ:
2292f7184619SJoshua M. Clulow 		if ((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0)
2293a2bb96e7Sjmcp 			regname = fqreg_names[idx];
2294a2bb96e7Sjmcp 		else
2295a2bb96e7Sjmcp 			regname = freg_names[idx];
2296a2bb96e7Sjmcp 
2297a2bb96e7Sjmcp 		break;
2298a2bb96e7Sjmcp 
2299a2bb96e7Sjmcp 	case REG_CP:
2300a2bb96e7Sjmcp 		regname = cpreg_names[idx];
2301a2bb96e7Sjmcp 		break;
2302a2bb96e7Sjmcp 
2303a2bb96e7Sjmcp 	case REG_ICC:
2304a2bb96e7Sjmcp 		regname = icc_names[idx];
2305a2bb96e7Sjmcp 		break;
2306a2bb96e7Sjmcp 
2307a2bb96e7Sjmcp 	case REG_FCC:
2308a2bb96e7Sjmcp 		regname = fcc_names[idx];
2309a2bb96e7Sjmcp 		break;
2310a2bb96e7Sjmcp 
2311a2bb96e7Sjmcp 	case REG_FSR:
2312a2bb96e7Sjmcp 		regname = "%fsr";
2313a2bb96e7Sjmcp 		break;
2314a2bb96e7Sjmcp 
2315a2bb96e7Sjmcp 	case REG_CSR:
2316a2bb96e7Sjmcp 		regname = "%csr";
2317a2bb96e7Sjmcp 		break;
2318a2bb96e7Sjmcp 
2319a2bb96e7Sjmcp 	case REG_CQ:
2320a2bb96e7Sjmcp 		regname = "%cq";
2321a2bb96e7Sjmcp 		break;
2322a2bb96e7Sjmcp 
2323a2bb96e7Sjmcp 	case REG_NONE:
2324a2bb96e7Sjmcp 		regname = "";
2325a2bb96e7Sjmcp 		break;
2326a2bb96e7Sjmcp 	}
2327a2bb96e7Sjmcp 
2328a2bb96e7Sjmcp 	return (regname);
2329a2bb96e7Sjmcp }
2330a2bb96e7Sjmcp 
2331a2bb96e7Sjmcp /*
2332a2bb96e7Sjmcp  * output the asi value from the instruction
2333a2bb96e7Sjmcp  *
2334a2bb96e7Sjmcp  * TODO: investigate if this should perhaps have a mask -- are undefined ASI
2335a2bb96e7Sjmcp  *	  values for an instruction still disassembled??
2336a2bb96e7Sjmcp  */
2337a2bb96e7Sjmcp static void
prt_asi(dis_handle_t * dhp,uint32_t instr)2338a2bb96e7Sjmcp prt_asi(dis_handle_t *dhp, uint32_t instr)
2339a2bb96e7Sjmcp {
2340a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
2341a2bb96e7Sjmcp 	int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
2342a2bb96e7Sjmcp 
2343a2bb96e7Sjmcp 	if (f->f3.i != 0)
2344a2bb96e7Sjmcp 		bprintf(dhp, "%%asi");
2345a2bb96e7Sjmcp 	else
2346a2bb96e7Sjmcp 		bprintf(dhp, (octal != 0) ? "0%03o" : "0x%02x", f->f3.asi);
2347a2bb96e7Sjmcp 
2348a2bb96e7Sjmcp }
2349a2bb96e7Sjmcp 
2350a2bb96e7Sjmcp /*
2351a2bb96e7Sjmcp  * put an address expression into the output buffer
2352a2bb96e7Sjmcp  *
2353a2bb96e7Sjmcp  * instr is the instruction to use
2354a2bb96e7Sjmcp  * if nobrackets != 0, [] are not added around the instruction
2355a2bb96e7Sjmcp  *
2356a2bb96e7Sjmcp  * Currently this option is set when printing out the address portion
2357a2bb96e7Sjmcp  * of a jmpl instruction, but otherwise 0 for load/stores
2358a2bb96e7Sjmcp  *
2359a2bb96e7Sjmcp  * If no debug flags are set, the full expression is output, even when
2360a2bb96e7Sjmcp  * %g0 or 0x0 appears in the address
2361a2bb96e7Sjmcp  *
2362a2bb96e7Sjmcp  * If DIS_DEBUG_SYN_ALL or DIS_DEBUG_COMPAT are set, when %g0 or 0x0
2363a2bb96e7Sjmcp  * appear in the address, they are not output.  If the wierd (and probably
2364a2bb96e7Sjmcp  * shouldn't happen) address of [%g0 + %g0] or [%g0 + 0x0] is encountered,
2365a2bb96e7Sjmcp  * [%g0] is output
2366a2bb96e7Sjmcp  */
2367a2bb96e7Sjmcp static void
prt_address(dis_handle_t * dhp,uint32_t instr,int nobrackets)2368a2bb96e7Sjmcp prt_address(dis_handle_t *dhp, uint32_t instr, int nobrackets)
2369a2bb96e7Sjmcp {
2370f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
2371a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
2372a2bb96e7Sjmcp 	int32_t simm13;
2373a2bb96e7Sjmcp 	int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
2374f7184619SJoshua M. Clulow 	int p1 = ((dhx->dhx_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0);
2375f7184619SJoshua M. Clulow 	int p2 = ((dhx->dhx_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0);
2376a2bb96e7Sjmcp 
2377a2bb96e7Sjmcp 	if (f->f3a.i == 0) {
2378a2bb96e7Sjmcp 		p1 |= ((f->f3a.rs1 != 0) || f->f3.rs2 == 0);
2379a2bb96e7Sjmcp 		p2 |= (f->f3.rs2 != 0);
2380a2bb96e7Sjmcp 
2381a2bb96e7Sjmcp 		bprintf(dhp, "%s%s%s%s%s",
2382a2bb96e7Sjmcp 		    (nobrackets == 0) ? "[" : "",
2383a2bb96e7Sjmcp 		    (p1 != 0) ? reg_names[f->f3a.rs1] : "",
2384a2bb96e7Sjmcp 		    (p1 != 0 && p2 != 0) ? " + " : "",
2385a2bb96e7Sjmcp 		    (p2 != 0) ? reg_names[f->f3.rs2] : "",
2386a2bb96e7Sjmcp 		    (nobrackets == 0) ? "]" : "");
2387a2bb96e7Sjmcp 	} else {
2388a2bb96e7Sjmcp 		const char *sign;
2389a2bb96e7Sjmcp 
2390a2bb96e7Sjmcp 		simm13 = sign_extend(f->f3a.simm13, 13);
2391a2bb96e7Sjmcp 		sign = (simm13 < 0) ? "-" : "+";
2392a2bb96e7Sjmcp 
2393a2bb96e7Sjmcp 		p1 |= (f->f3a.rs1 != 0);
2394a2bb96e7Sjmcp 		p2 |= (p1 == 0 || simm13 != 0);
2395a2bb96e7Sjmcp 
2396a2bb96e7Sjmcp 		if (p1 == 0 && simm13 == 0)
2397a2bb96e7Sjmcp 			p2 = 1;
2398a2bb96e7Sjmcp 
2399a2bb96e7Sjmcp 		if (p1 == 0 && simm13 >= 0)
2400a2bb96e7Sjmcp 			sign = "";
2401a2bb96e7Sjmcp 
2402a2bb96e7Sjmcp 		if (p2 != 0)
2403a2bb96e7Sjmcp 			bprintf(dhp,
2404a2bb96e7Sjmcp 			    (octal != 0) ? "%s%s%s%s%s0%lo%s" :
2405a2bb96e7Sjmcp 			    "%s%s%s%s%s0x%lx%s",
2406a2bb96e7Sjmcp 			    (nobrackets == 0) ? "[" : "",
2407a2bb96e7Sjmcp 			    (p1 != 0) ? reg_names[f->f3a.rs1] : "",
2408a2bb96e7Sjmcp 			    (p1 != 0) ? " " : "",
2409a2bb96e7Sjmcp 			    sign,
2410a2bb96e7Sjmcp 			    (p1 != 0) ? " " : "",
2411a2bb96e7Sjmcp 			    (simm13 < 0) ? -(simm13) : simm13,
2412a2bb96e7Sjmcp 			    (nobrackets == 0) ? "]" : "");
2413a2bb96e7Sjmcp 		else
2414a2bb96e7Sjmcp 			bprintf(dhp, "%s%s%s",
2415a2bb96e7Sjmcp 			    (nobrackets == 0) ? "[" : "",
2416a2bb96e7Sjmcp 			    reg_names[f->f3a.rs1],
2417a2bb96e7Sjmcp 			    (nobrackets == 0) ? "]" : "");
2418a2bb96e7Sjmcp 	}
2419a2bb96e7Sjmcp }
2420a2bb96e7Sjmcp 
2421a2bb96e7Sjmcp /*
2422a2bb96e7Sjmcp  * print out the arguments to an alu operation (add, sub, etc.)
2423a2bb96e7Sjmcp  * conatined in 'instr'
2424a2bb96e7Sjmcp  *
2425a2bb96e7Sjmcp  * alu instructions have the following format:
2426a2bb96e7Sjmcp  *	 %rs1, %rs2, %rd    (i == 0)
2427a2bb96e7Sjmcp  *	 %rs1, 0xnnn, %rd   (i == 1)
2428a2bb96e7Sjmcp  *	   ^	^	^
2429a2bb96e7Sjmcp  *	   |	|	|
2430a2bb96e7Sjmcp  *	  p1    p2	p3
2431a2bb96e7Sjmcp  *
2432a2bb96e7Sjmcp  * flags indicates the register set to use for each position (p1, p2, p3)
2433a2bb96e7Sjmcp  * as well as if immediate values (i == 1) are allowed
2434a2bb96e7Sjmcp  *
2435a2bb96e7Sjmcp  * if flags indicates a specific position has REG_NONE set as it's register
2436a2bb96e7Sjmcp  * set, it is omitted from the output.  This is primarly used for certain
2437a2bb96e7Sjmcp  * floating point operations
2438a2bb96e7Sjmcp  */
2439a2bb96e7Sjmcp static void
prt_aluargs(dis_handle_t * dhp,uint32_t instr,uint32_t flags)2440a2bb96e7Sjmcp prt_aluargs(dis_handle_t *dhp, uint32_t instr, uint32_t flags)
2441a2bb96e7Sjmcp {
2442f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
2443a2bb96e7Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
2444a2bb96e7Sjmcp 	const char *r1, *r2, *r3;
2445a2bb96e7Sjmcp 	int p1, p2, p3;
24462f0fcb93SJason Beloro 	unsigned int opf = 0;
2447a2bb96e7Sjmcp 
2448a2bb96e7Sjmcp 	r1 = get_regname(dhp, FLG_P1_VAL(flags), f->f3.rs1);
2449a2bb96e7Sjmcp 	r2 = get_regname(dhp, FLG_P2_VAL(flags), f->f3.rs2);
2450a2bb96e7Sjmcp 	r3 = get_regname(dhp, FLG_P3_VAL(flags), f->f3.rd);
2451a2bb96e7Sjmcp 
2452a2bb96e7Sjmcp 	p1 = (FLG_P1_VAL(flags) != REG_NONE);
2453a2bb96e7Sjmcp 	p2 = (((flags & FLG_NOIMM) == 0) || (FLG_P2_VAL(flags) != REG_NONE));
2454a2bb96e7Sjmcp 	p3 = (FLG_RD_VAL(flags) != REG_NONE);
2455a2bb96e7Sjmcp 
2456a2bb96e7Sjmcp 	if (r1 == NULL || r1[0] == '\0')
2457a2bb96e7Sjmcp 		p1 = 0;
2458a2bb96e7Sjmcp 
2459a2bb96e7Sjmcp 	if (f->f3a.i == 0 && (r2 == NULL || r2[0] == '\0'))
2460a2bb96e7Sjmcp 		p2 = 0;
2461a2bb96e7Sjmcp 
2462a2bb96e7Sjmcp 	if (r3 == NULL || r3[0] == '\0')
2463a2bb96e7Sjmcp 		p3 = 0;
2464a2bb96e7Sjmcp 
24652f0fcb93SJason Beloro 	if ((f->fcmp.op == 2) && (f->fcmp.op3 == 0x36) && (f->fcmp.cc != 0))
24662f0fcb93SJason Beloro 		opf = f->fcmp.opf;
24672f0fcb93SJason Beloro 
24682f0fcb93SJason Beloro 	if ((opf == 0x151) || (opf == 0x152)) {
2469f7184619SJoshua M. Clulow 		(void) strlcat(dhx->dhx_buf, r3, dhx->dhx_buflen);
2470f7184619SJoshua M. Clulow 		(void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
24712f0fcb93SJason Beloro 		p3 = 0;
24722f0fcb93SJason Beloro 	}
24732f0fcb93SJason Beloro 
2474a2bb96e7Sjmcp 	if (p1 != 0) {
2475f7184619SJoshua M. Clulow 		(void) strlcat(dhx->dhx_buf, r1, dhx->dhx_buflen);
2476a2bb96e7Sjmcp 		if (p2 != 0 || p3 != 0)
2477f7184619SJoshua M. Clulow 			(void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
2478a2bb96e7Sjmcp 	}
2479a2bb96e7Sjmcp 
2480a2bb96e7Sjmcp 	if (p2 != 0) {
2481a2bb96e7Sjmcp 		if (f->f3.i == 0 || ((flags & FLG_NOIMM) != 0))
2482f7184619SJoshua M. Clulow 			(void) strlcat(dhx->dhx_buf, r2, dhx->dhx_buflen);
2483a2bb96e7Sjmcp 		else
2484a2bb96e7Sjmcp 			prt_imm(dhp, sign_extend(f->f3a.simm13, 13),
2485a2bb96e7Sjmcp 			    IMM_SIGNED);
2486a2bb96e7Sjmcp 
2487a2bb96e7Sjmcp 		if (p3 != 0)
2488f7184619SJoshua M. Clulow 			(void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
2489a2bb96e7Sjmcp 	}
2490a2bb96e7Sjmcp 
2491a2bb96e7Sjmcp 	if (p3 != 0)
2492f7184619SJoshua M. Clulow 		(void) strlcat(dhx->dhx_buf, r3, dhx->dhx_buflen);
2493a2bb96e7Sjmcp }
2494a2bb96e7Sjmcp 
2495b8ef3d63SJason King static const char *
get_asi_name(uint8_t asi)2496b8ef3d63SJason King get_asi_name(uint8_t asi)
2497b8ef3d63SJason King {
2498b8ef3d63SJason King 	switch (asi) {
2499b8ef3d63SJason King 		case 0x04:
2500b8ef3d63SJason King 			return ("ASI_N");
2501b8ef3d63SJason King 
2502b8ef3d63SJason King 		case 0x0c:
2503b8ef3d63SJason King 			return ("ASI_NL");
2504b8ef3d63SJason King 
2505b8ef3d63SJason King 		case 0x10:
2506b8ef3d63SJason King 			return ("ASI_AIUP");
2507b8ef3d63SJason King 
2508b8ef3d63SJason King 		case 0x11:
2509b8ef3d63SJason King 			return ("ASI_AIUS");
2510b8ef3d63SJason King 
2511b8ef3d63SJason King 		case 0x14:
2512b8ef3d63SJason King 			return ("ASI_REAL");
2513b8ef3d63SJason King 
2514b8ef3d63SJason King 		case 0x15:
2515b8ef3d63SJason King 			return ("ASI_REAL_IO");
2516b8ef3d63SJason King 
2517b8ef3d63SJason King 		case 0x16:
2518b8ef3d63SJason King 			return ("ASI_BLK_AIUP");
2519b8ef3d63SJason King 
2520b8ef3d63SJason King 		case 0x17:
2521b8ef3d63SJason King 			return ("ASI_BLK_AIUS");
2522b8ef3d63SJason King 
2523b8ef3d63SJason King 		case 0x18:
2524b8ef3d63SJason King 			return ("ASI_AIUPL");
2525b8ef3d63SJason King 
2526b8ef3d63SJason King 		case 0x19:
2527b8ef3d63SJason King 			return ("ASI_AIUSL");
2528b8ef3d63SJason King 
2529b8ef3d63SJason King 		case 0x1c:
2530b8ef3d63SJason King 			return ("ASI_REAL_L");
2531b8ef3d63SJason King 
2532b8ef3d63SJason King 		case 0x1d:
2533b8ef3d63SJason King 			return ("ASI_REAL_IO_L");
2534b8ef3d63SJason King 
2535b8ef3d63SJason King 		case 0x1e:
2536b8ef3d63SJason King 			return ("ASI_BLK_AIUPL");
2537b8ef3d63SJason King 
2538b8ef3d63SJason King 		case 0x1f:
2539b8ef3d63SJason King 			return ("ASI_BLK_AIUS_L");
2540b8ef3d63SJason King 
2541b8ef3d63SJason King 		case 0x20:
2542b8ef3d63SJason King 			return ("ASI_SCRATCHPAD");
2543b8ef3d63SJason King 
2544b8ef3d63SJason King 		case 0x21:
2545b8ef3d63SJason King 			return ("ASI_MMU_CONTEXTID");
2546b8ef3d63SJason King 
2547b8ef3d63SJason King 		case 0x22:
2548b8ef3d63SJason King 			return ("ASI_TWINX_AIUP");
2549b8ef3d63SJason King 
2550b8ef3d63SJason King 		case 0x23:
2551b8ef3d63SJason King 			return ("ASI_TWINX_AIUS");
2552b8ef3d63SJason King 
2553b8ef3d63SJason King 		case 0x25:
2554b8ef3d63SJason King 			return ("ASI_QUEUE");
2555b8ef3d63SJason King 
2556b8ef3d63SJason King 		case 0x26:
2557b8ef3d63SJason King 			return ("ASI_TWINX_R");
2558b8ef3d63SJason King 
2559b8ef3d63SJason King 		case 0x27:
2560b8ef3d63SJason King 			return ("ASI_TWINX_N");
2561b8ef3d63SJason King 
2562b8ef3d63SJason King 		case 0x2a:
2563b8ef3d63SJason King 			return ("ASI_LDTX_AIUPL");
2564b8ef3d63SJason King 
2565b8ef3d63SJason King 		case 0x2b:
2566b8ef3d63SJason King 			return ("ASI_TWINX_AIUS_L");
2567b8ef3d63SJason King 
2568b8ef3d63SJason King 		case 0x2e:
2569b8ef3d63SJason King 			return ("ASI_TWINX_REAL_L");
2570b8ef3d63SJason King 
2571b8ef3d63SJason King 		case 0x2f:
2572b8ef3d63SJason King 			return ("ASI_TWINX_NL");
2573b8ef3d63SJason King 
2574b8ef3d63SJason King 		case 0x30:
2575b8ef3d63SJason King 			return ("ASI_AIPP");
2576b8ef3d63SJason King 
2577b8ef3d63SJason King 		case 0x31:
2578b8ef3d63SJason King 			return ("ASI_AIPS");
2579b8ef3d63SJason King 
2580b8ef3d63SJason King 		case 0x36:
2581b8ef3d63SJason King 			return ("ASI_AIPN");
2582b8ef3d63SJason King 
2583b8ef3d63SJason King 		case 0x38:
2584b8ef3d63SJason King 			return ("ASI_AIPP_L");
2585b8ef3d63SJason King 
2586b8ef3d63SJason King 		case 0x39:
2587b8ef3d63SJason King 			return ("ASI_AIPS_L");
2588b8ef3d63SJason King 
2589b8ef3d63SJason King 		case 0x3e:
2590b8ef3d63SJason King 			return ("ASI_AIPN_L");
2591b8ef3d63SJason King 
2592b8ef3d63SJason King 		case 0x41:
2593b8ef3d63SJason King 			return ("ASI_CMT_SHARED");
2594b8ef3d63SJason King 
2595b8ef3d63SJason King 		case 0x4f:
2596b8ef3d63SJason King 			return ("ASI_HYP_SCRATCHPAD");
2597b8ef3d63SJason King 
2598b8ef3d63SJason King 		case 0x50:
2599b8ef3d63SJason King 			return ("ASI_IMMU");
2600b8ef3d63SJason King 
2601b8ef3d63SJason King 		case 0x52:
2602b8ef3d63SJason King 			return ("ASI_MMU_REAL");
2603b8ef3d63SJason King 
2604b8ef3d63SJason King 		case 0x54:
2605b8ef3d63SJason King 			return ("ASI_MMU");
2606b8ef3d63SJason King 
2607b8ef3d63SJason King 		case 0x55:
2608b8ef3d63SJason King 			return ("ASI_ITLB_DATA_ACCESS_REG");
2609b8ef3d63SJason King 
2610b8ef3d63SJason King 		case 0x56:
2611b8ef3d63SJason King 			return ("ASI_ITLB_TAG_READ_REG");
2612b8ef3d63SJason King 
2613b8ef3d63SJason King 		case 0x57:
2614b8ef3d63SJason King 			return ("ASI_IMMU_DEMAP");
2615b8ef3d63SJason King 
2616b8ef3d63SJason King 		case 0x58:
2617b8ef3d63SJason King 			return ("ASI_DMMU / ASI_UMMU");
2618b8ef3d63SJason King 
2619b8ef3d63SJason King 		case 0x5c:
2620b8ef3d63SJason King 			return ("ASI_DTLB_DATA_IN_REG");
2621b8ef3d63SJason King 
2622b8ef3d63SJason King 		case 0x5d:
2623b8ef3d63SJason King 			return ("ASI_DTLB_DATA_ACCESS_REG");
2624b8ef3d63SJason King 
2625b8ef3d63SJason King 		case 0x5e:
2626b8ef3d63SJason King 			return ("ASI_DTLB_TAG_READ_REG");
2627b8ef3d63SJason King 
2628b8ef3d63SJason King 		case 0x5f:
2629b8ef3d63SJason King 			return ("ASI_DMMU_DEMAP");
2630b8ef3d63SJason King 
2631b8ef3d63SJason King 		case 0x63:
2632b8ef3d63SJason King 			return ("ASI_CMT_PER_STRAND / ASI_CMT_PER_CORE");
2633b8ef3d63SJason King 
2634b8ef3d63SJason King 		case 0x80:
2635b8ef3d63SJason King 			return ("ASI_P");
2636b8ef3d63SJason King 
2637b8ef3d63SJason King 		case 0x81:
2638b8ef3d63SJason King 			return ("ASI_S");
2639b8ef3d63SJason King 
2640b8ef3d63SJason King 		case 0x82:
2641b8ef3d63SJason King 			return ("ASI_PNF");
2642b8ef3d63SJason King 
2643b8ef3d63SJason King 		case 0x83:
2644b8ef3d63SJason King 			return ("ASI_SNF");
2645b8ef3d63SJason King 
2646b8ef3d63SJason King 		case 0x88:
2647b8ef3d63SJason King 			return ("ASI_PL");
2648b8ef3d63SJason King 
2649b8ef3d63SJason King 		case 0x89:
2650b8ef3d63SJason King 			return ("ASI_SL");
2651b8ef3d63SJason King 
2652b8ef3d63SJason King 		case 0x8a:
2653b8ef3d63SJason King 			return ("ASI_PNFL");
2654b8ef3d63SJason King 
2655b8ef3d63SJason King 		case 0x8b:
2656b8ef3d63SJason King 			return ("ASI_SNFL");
2657b8ef3d63SJason King 
2658b8ef3d63SJason King 		case 0xc0:
2659b8ef3d63SJason King 			return ("ASI_PST8_P");
2660b8ef3d63SJason King 
2661b8ef3d63SJason King 		case 0xc1:
2662b8ef3d63SJason King 			return ("ASI_PST8_S");
2663b8ef3d63SJason King 
2664b8ef3d63SJason King 		case 0xc2:
2665b8ef3d63SJason King 			return ("ASI_PST16_P");
2666b8ef3d63SJason King 
2667b8ef3d63SJason King 		case 0xc3:
2668b8ef3d63SJason King 			return ("ASI_PST16_S");
2669b8ef3d63SJason King 
2670b8ef3d63SJason King 		case 0xc4:
2671b8ef3d63SJason King 			return ("ASI_PST32_P");
2672b8ef3d63SJason King 
2673b8ef3d63SJason King 		case 0xc5:
2674b8ef3d63SJason King 			return ("ASI_PST32_S");
2675b8ef3d63SJason King 
2676b8ef3d63SJason King 		case 0xc8:
2677b8ef3d63SJason King 			return ("ASI_PST8_PL");
2678b8ef3d63SJason King 
2679b8ef3d63SJason King 		case 0xc9:
2680b8ef3d63SJason King 			return ("ASI_PST8_SL");
2681b8ef3d63SJason King 
2682b8ef3d63SJason King 		case 0xca:
2683b8ef3d63SJason King 			return ("ASI_PST16_PL");
2684b8ef3d63SJason King 
2685b8ef3d63SJason King 		case 0xcb:
2686b8ef3d63SJason King 			return ("ASI_PST16_SL");
2687b8ef3d63SJason King 
2688b8ef3d63SJason King 		case 0xcc:
2689b8ef3d63SJason King 			return ("ASI_PST32_PL");
2690b8ef3d63SJason King 
2691b8ef3d63SJason King 		case 0xcd:
2692b8ef3d63SJason King 			return ("ASI_PST32_SL");
2693b8ef3d63SJason King 
2694b8ef3d63SJason King 		case 0xd0:
2695b8ef3d63SJason King 			return ("ASI_FL8_P");
2696b8ef3d63SJason King 
2697b8ef3d63SJason King 		case 0xd1:
2698b8ef3d63SJason King 			return ("ASI_FL8_S");
2699b8ef3d63SJason King 
2700b8ef3d63SJason King 		case 0xd2:
2701b8ef3d63SJason King 			return ("ASI_FL16_P");
2702b8ef3d63SJason King 
2703b8ef3d63SJason King 		case 0xd3:
2704b8ef3d63SJason King 			return ("ASI_FL16_S");
2705b8ef3d63SJason King 
2706b8ef3d63SJason King 		case 0xd8:
2707b8ef3d63SJason King 			return ("ASI_FL8_PL");
2708b8ef3d63SJason King 
2709b8ef3d63SJason King 		case 0xd9:
2710b8ef3d63SJason King 			return ("ASI_FL8_SL");
2711b8ef3d63SJason King 
2712b8ef3d63SJason King 		case 0xda:
2713b8ef3d63SJason King 			return ("ASI_FL16_PL");
2714b8ef3d63SJason King 
2715b8ef3d63SJason King 		case 0xdb:
2716b8ef3d63SJason King 			return ("ASI_FL16_SL");
2717b8ef3d63SJason King 
2718b8ef3d63SJason King 		case 0xe0:
2719b8ef3d63SJason King 			return ("ASI_BLK_COMMIT_P");
2720b8ef3d63SJason King 
2721b8ef3d63SJason King 		case 0xe1:
2722b8ef3d63SJason King 			return ("ASI_BLK_SOMMIT_S");
2723b8ef3d63SJason King 
2724b8ef3d63SJason King 		case 0xe2:
2725b8ef3d63SJason King 			return ("ASI_TWINX_P");
2726b8ef3d63SJason King 
2727b8ef3d63SJason King 		case 0xe3:
2728b8ef3d63SJason King 			return ("ASI_TWINX_S");
2729b8ef3d63SJason King 
2730b8ef3d63SJason King 		case 0xea:
2731b8ef3d63SJason King 			return ("ASI_TWINX_PL");
2732b8ef3d63SJason King 
2733b8ef3d63SJason King 		case 0xeb:
2734b8ef3d63SJason King 			return ("ASI_TWINX_SL");
2735b8ef3d63SJason King 
2736b8ef3d63SJason King 		case 0xf0:
2737b8ef3d63SJason King 			return ("ASI_BLK_P");
2738b8ef3d63SJason King 
2739b8ef3d63SJason King 		case 0xf1:
2740b8ef3d63SJason King 			return ("ASI_BLK_S");
2741b8ef3d63SJason King 
2742b8ef3d63SJason King 		case 0xf8:
2743b8ef3d63SJason King 			return ("ASI_BLK_PL");
2744b8ef3d63SJason King 
2745b8ef3d63SJason King 		case 0xf9:
2746b8ef3d63SJason King 			return ("ASI_BLK_SL");
2747b8ef3d63SJason King 
2748b8ef3d63SJason King 		default:
2749b8ef3d63SJason King 			return (NULL);
2750b8ef3d63SJason King 	}
2751b8ef3d63SJason King }
2752b8ef3d63SJason King 
2753a2bb96e7Sjmcp /*
2754a2bb96e7Sjmcp  * just a handy function that takes care of managing the buffer length
2755a2bb96e7Sjmcp  * w/ printf
2756a2bb96e7Sjmcp  */
2757a2bb96e7Sjmcp 
2758a2bb96e7Sjmcp /*
2759a2bb96e7Sjmcp  * PRINTF LIKE 1
2760a2bb96e7Sjmcp  */
2761a2bb96e7Sjmcp static void
bprintf(dis_handle_t * dhp,const char * fmt,...)2762a2bb96e7Sjmcp bprintf(dis_handle_t *dhp, const char *fmt, ...)
2763a2bb96e7Sjmcp {
2764f7184619SJoshua M. Clulow 	dis_handle_sparc_t *dhx = dhp->dh_arch_private;
2765a2bb96e7Sjmcp 	size_t curlen;
2766a2bb96e7Sjmcp 	va_list ap;
2767a2bb96e7Sjmcp 
2768f7184619SJoshua M. Clulow 	curlen = strlen(dhx->dhx_buf);
2769a2bb96e7Sjmcp 
2770a2bb96e7Sjmcp 	va_start(ap, fmt);
2771f7184619SJoshua M. Clulow 	(void) dis_vsnprintf(dhx->dhx_buf + curlen, dhx->dhx_buflen -
2772f7184619SJoshua M. Clulow 	    curlen, fmt, ap);
2773a2bb96e7Sjmcp 	va_end(ap);
2774a2bb96e7Sjmcp }
2775