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