Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / rst / rstzip3 / rz_insttypes.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: rz_insttypes.h
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23/* rz_insttypes.h
24 * lightweight spix-like calls to determine inst types and
25 * extract information like effective addresses from sparcv9 insts
26 *
27 * Copyright (c) 2004 by Sun Microsystems, Inc.
28 * All rights reserved.
29 *
30 */
31
32
33#ifndef _rz_insttypes_h_
34#define _rz_insttypes_h_
35
36
37/* Notes
38 *
39 * rz_insttypes.h contains a set of macros and functions used to
40 * decode and classify SPARC V9 instructions. It is meant as a
41 * light-weight replacement for SPIX. All functions take the 32-bit
42 * instr word as the sole argument
43 *
44 * Here is a list of the functions available, their spix equivalents,
45 * and crucial differences between spix and this library:
46 *
47 * rz_is_dcti() -- equivalent to spix_sparc_iop_isdcti()
48 *
49 * rz_is_branch() -- equivalent to spix_sparc_iop_isbranch()
50 *
51 * rz_isubranch_always() -- equivalent to spix_sparc_iop_isubranch()
52 *
53 * rz_isubranch_never() -- true for BRANCH NEVER instructions
54 *
55 * rz_isubranch() -- unconditional branches (ALWAYS and NEVER)
56 * NOT equivalent to spix_sparc_iop_isubranch()
57 *
58 * rz_iscbranch() -- conditional branches (does not include BRANCH NEVER)
59 * NOT equivalent to spix_sparc_iop_iscbranch()
60 *
61 * rz_isbpr(), rz_isbpcc(), rz_isbicc(), rz_fbfcc(), rz_isfbpcc(),
62 * rz_iscall(), rz_isreturn(), rz_isdone(), rz_isretry()
63 *
64 * rz_isprefetch() -- equivalent to spix_sparc_iop_isprefetch()
65 *
66 * rz_isload() -- true for loads but not load-store or prefetch insts
67 * NOT equivalent to spix_sparc_iop_isload()
68 *
69 * rz_is_load_store() -- conditional AND unconditional load-store insts
70 * rz_isustore() -- contains unconditional stores and unconditional load-stores
71 *
72 * rz_is_load_store_conditional() -- equivalent to spix_sparc_iop_iscstore()
73*/
74
75
76
77#define sign_ext_hi_bit(x, n) (((x) >> ((n)-1)) & 1)
78#define sign_ext_1(x, n) (sign_ext_hi_bit(x, n) ? (~0ull)<<((n)-1) : 0ull)
79
80#define sign_ext_lo_mask(n) ((1ull << (n)) - 1)
81#define sign_ext_2(x, n) ((x) & sign_ext_lo_mask(n))
82
83//#define sign_ext(x, n) (sign_ext_1((x), (n)) | sign_ext_2((x), (n)))
84static inline int64_t sign_ext(int64_t imm, int sz) {
85 int64_t rv = (imm << (64 - sz));
86 rv = (rv >> (64-sz));
87 return rv;
88}
89
90
91
92#define BPcc_OPCODE_MASK 0xc1c00000u
93#define BPcc_OPCODE_BITS 0x00400000u
94#define BPcc_DISP(_opc_) (sign_ext((_opc_ & 0x7ffff), 19) << 2)
95
96static inline bool rz_is_bpcc(uint32_t instr)
97{
98 return ((instr & BPcc_OPCODE_MASK) == BPcc_OPCODE_BITS);
99} // static inline bool rz_is_bpcc(uint32_t instr)
100
101
102#define BPR_OPCODE_MASK 0xd1c00000u
103#define BPR_OPCODE_BITS 0x00c00000u
104#define BPR_DISP_d16hi(_opc_) (((_opc_) >> 20) & 0x3)
105#define BPR_DISP_d16lo(_opc_) ((_opc_) & 0x3fff)
106#define BPR_DISP_d16(_opc_) ((BPR_DISP_d16hi(_opc_) << 14) | BPR_DISP_d16lo(_opc_))
107#define BPR_DISP(_opc_) (sign_ext(BPR_DISP_d16(_opc_), 16) << 2)
108
109static inline bool rz_is_bpr(uint32_t instr) {
110 if ((instr & BPR_OPCODE_MASK) == BPR_OPCODE_BITS) {
111 uint32_t rcond = (instr >> 25) & 0x7;
112 return ((rcond & 3) != 0);
113 } else {
114 return false;
115 }
116} // static inline bool rz_is_bpr(uint32_t instr) {
117
118#define FBfcc_OPCODE_MASK 0xc1c00000u
119#define FBfcc_OPCODE_BITS 0x01800000u
120#define FBfcc_DISP(_opc_) (sign_ext((_opc_ & 0x3fffff), 22) << 2)
121
122static inline bool rz_is_fbfcc(uint32_t instr)
123{
124 return ((instr & FBfcc_OPCODE_MASK) == FBfcc_OPCODE_BITS);
125}
126
127
128#define FBPfcc_OPCODE_MASK 0xc1c00000u
129#define FBPfcc_OPCODE_BITS 0x01400000u
130#define FBPfcc_DISP(_opc_) (sign_ext((_opc_ & 0x7ffff), 19) << 2)
131
132
133static inline bool rz_is_fbpfcc(uint32_t instr)
134{
135 return ((instr & FBPfcc_OPCODE_MASK) == FBPfcc_OPCODE_BITS);
136} // static inline bool rz_is_fbpfcc(uint32_t instr)
137
138
139#define Bicc_OPCODE_MASK 0xc1c00000u
140#define Bicc_OPCODE_BITS 0x00800000u
141#define Bicc_DISP(_opc_) (sign_ext((_opc_ & 0x3fffff), 22) << 2)
142
143
144
145static inline bool rz_is_bicc(uint32_t instr)
146{
147 return ((instr & Bicc_OPCODE_MASK) == Bicc_OPCODE_BITS);
148} // static inline bool rz_is_bicc(uint32_t instr)
149
150
151
152#define CALL_OPCODE_MASK 0xc0000000u
153#define CALL_OPCODE_BITS 0x40000000u
154#define CALL_DISP(_opc_) (sign_ext((_opc_ & 0x3fffffff), 30) << 2)
155
156
157
158static inline bool rz_is_call(uint32_t instr)
159{
160 return ((instr & CALL_OPCODE_MASK) == CALL_OPCODE_BITS);
161} // static inline bool rz_is_call(uint32_t instr)
162
163
164
165#define UBRANCH_OPCODE_MASK 0xdfc00000u
166
167#define FBA_OPCODE_BITS 0x11400000u
168#define FBN_OPCODE_BITS 0x01400000u
169
170#define FBPA_OPCODE_BITS 0x11400000u
171#define FBPN_OPCODE_BITS 0x01400000u
172
173#define BA_OPCODE_BITS 0x10400000u
174#define BN_OPCODE_BITS 0x00400000u
175
176#define BPA_OPCODE_BITS 0x10400000u
177#define BPN_OPCODE_BITS 0x00400000u
178
179#define RESTORE_OPCODE_MASK 0xc1f80000
180#define RESTORE_OPCODE_BITS 0x81e80000
181
182#define MOV_G1_G7_INSTR 0x9e100001
183
184
185#define JMPL_OPCODE_MASK 0xc1f80000
186#define JMPL_OPCODE_BITS 0x81c00000
187static inline bool rz_is_jmpl(uint32_t instr)
188{
189 return ((instr & JMPL_OPCODE_MASK) == JMPL_OPCODE_BITS);
190} // static inline bool rz_is_jmpl(uint32_t instr)
191
192
193#define RETURN_OPCODE_MASK 0xc1f80000
194#define RETURN_OPCODE_BITS 0x81c80000
195static inline bool rz_is_return(uint32_t instr)
196{
197 return ((instr & RETURN_OPCODE_MASK) == RETURN_OPCODE_BITS);
198} //static inline bool rz_is_return(uint32_t instr)
199
200
201static inline bool rz_is_branch(uint32_t instr) {
202 return rz_is_bpr(instr) || rz_is_fbfcc(instr) || rz_is_fbpfcc(instr) || rz_is_bicc(instr) || rz_is_bpcc(instr);
203}
204
205static inline bool rz_is_ubranch_always(uint32_t instr) {
206 // op=0, (op2 =~ ?01 or op2 =~ ?10), cond == 8
207 return ((instr & 0xdec00000) == 0x10800000) || ((instr & 0xdec00000) == 0x10400000);
208}
209
210static inline bool rz_is_ubranch_never(uint32_t instr) {
211 // op=0, (op2 =~ ?01 or op2 =~ ?10), cond == 0
212 return ((instr & 0xdec00000) == 0x00800000) || ((instr & 0xdec00000) == 0x00400000);
213}
214
215static inline bool rz_is_ubranch(uint32_t instr) {
216 return rz_is_ubranch_always(instr) || rz_is_ubranch_never(instr);
217}
218
219// DIFFERENCE FROM SPIX: spix _iscbranch() includes branch_never. ours does NOT.
220static inline bool rz_is_cbranch(uint32_t instr) {
221 return (rz_is_branch(instr) && ! rz_is_ubranch(instr));
222}
223
224static inline bool rz_is_dcti(uint32_t instr)
225{
226 return rz_is_branch(instr) || rz_is_call(instr) || rz_is_jmpl(instr) || rz_is_return(instr);
227} // static inline bool rz_is_dcti(uint32_t instr)
228
229
230static inline bool rz_is_pc_relative_cti(uint32_t instr)
231{
232 return rz_is_branch(instr) || rz_is_call(instr);
233}
234
235#define DONE_RETRY_OPCODE_MASK 0xfff80000
236#define DONE_OPCODE_BITS 0x81f00000
237#define RETRY_OPCODE_BITS 0x83f00000
238static inline bool rz_is_done(uint32_t instr)
239{
240 return ((instr & DONE_RETRY_OPCODE_MASK) == DONE_OPCODE_BITS);
241}
242
243
244static inline bool rz_is_retry(uint32_t instr)
245{
246 return ((instr & DONE_RETRY_OPCODE_MASK) == RETRY_OPCODE_BITS);
247} // static inline bool rz_is_retry(uint32_t instr)
248
249
250
251static inline bool rz_is_ldstpf(uint32_t instr)
252{
253 return ((instr >> 30) == 0x3);
254} // static inline bool rz_is_ldstpf(uint32_t instr)
255
256
257// does *not* include load-store insts, unlike spix _isload()
258// also does *not* include prefetches, unlike spix _isload()
259static inline bool rz_is_load(uint32_t instr)
260{
261 // op3 =~ ?? ?0??
262 return ((instr & 0xc0200000) == 0xc0000000);
263}
264
265
266// does *not* include load-store insts. spix _isstore() includes unconditional ldst insts
267static inline bool rz_is_store(uint32_t instr)
268{
269 // op3 =~ ?? 01?? or op3 =~ 0? 1110
270 return ((instr & 0xc0600000) == 0xc0200000) || ((instr & 0xc1780000) == 0xc0700000);
271}
272
273// load and cond store (CAS/CASA) - same as spix _iscstore()
274static inline bool rz_is_load_store_conditional(uint32_t instr)
275{
276 // op=3, op3=11 11?0
277 return ((instr & 0xc1e80000) == 0xc1e00000);
278}
279
280
281// ldstub, swap
282static inline bool rz_is_load_store_unconditional(uint32_t instr)
283{
284 // op=3 op3=0? 11?1
285 return ((instr & 0xc1680000) == 0xc0680000);
286}
287
288
289// include conditional as well as unconditional ldst insts (ldst + cas + swap)
290static inline bool rz_is_load_store(uint32_t instr)
291{
292 return rz_is_load_store_conditional(instr) || rz_is_load_store_unconditional(instr);
293}
294
295
296static inline bool rz_is_prefetch(uint32_t instr)
297{
298 // op3 =~ 1? 1101
299 return ((instr & 0xc1780000) == 0xc1680000);
300}
301
302static inline bool rz_is_sethi(uint32_t instr)
303{
304 // op==0 op2=100
305 return ( ((instr & 0xc1c00000) == 0x01000000) && (instr & 0x3e000000) );
306}
307
308#endif // _rz_insttypes_h_