Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | \ ========== Copyright Header Begin ========================================== |
2 | \ | |
3 | \ Hypervisor Software File: disforw.fth | |
4 | \ | |
5 | \ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | \ | |
7 | \ - Do no alter or remove copyright notices | |
8 | \ | |
9 | \ - Redistribution and use of this software in source and binary forms, with | |
10 | \ or without modification, are permitted provided that the following | |
11 | \ conditions are met: | |
12 | \ | |
13 | \ - Redistribution of source code must retain the above copyright notice, | |
14 | \ this list of conditions and the following disclaimer. | |
15 | \ | |
16 | \ - Redistribution in binary form must reproduce the above copyright notice, | |
17 | \ this list of conditions and the following disclaimer in the | |
18 | \ documentation and/or other materials provided with the distribution. | |
19 | \ | |
20 | \ Neither the name of Sun Microsystems, Inc. or the names of contributors | |
21 | \ may be used to endorse or promote products derived from this software | |
22 | \ without specific prior written permission. | |
23 | \ | |
24 | \ This software is provided "AS IS," without a warranty of any kind. | |
25 | \ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
26 | \ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
27 | \ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
28 | \ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
29 | \ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
30 | \ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
31 | \ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
32 | \ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
33 | \ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
34 | \ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
35 | \ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
36 | \ | |
37 | \ You acknowledge that this software is not designed, licensed or | |
38 | \ intended for use in the design, construction, operation or maintenance of | |
39 | \ any nuclear facility. | |
40 | \ | |
41 | \ ========== Copyright Header End ============================================ | |
42 | id: @(#)disforw.fth 2.31 06/04/21 17:08:22 | |
43 | purpose: SPARC disassembler - prefix syntax | |
44 | copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved | |
45 | copyright: Use is subject to license terms. | |
46 | ||
47 | \ Copyright 1985-1990 Bradley Forthware | |
48 | ||
49 | \ lddf disassembler needs to specify f register, not i register | |
50 | \ ldxfsr is not properly disassembled | |
51 | headers | |
52 | vocabulary disassembler | |
53 | also disassembler also definitions | |
54 | ||
55 | headerless | |
56 | ||
57 | 64\ true constant sparc-v9? | |
58 | 32\ false constant sparc-v9? | |
59 | ||
60 | string-array real-regs | |
61 | ," %g0" ," %g1" ," %g2" ," %g3" | |
62 | ," %g4" ," %g5" ," %g6" ," %g7" | |
63 | ," %o0" ," %o1" ," %o2" ," %o3" | |
64 | ," %o4" ," %o5" ," %o6" ," %o7" | |
65 | ," %l0" ," %l1" ," %l2" ," %l3" | |
66 | ," %l4" ," %l5" ," %l6" ," %l7" | |
67 | ," %i0" ," %i1" ," %i2" ," %i3" | |
68 | ," %i4" ," %i5" ," %i6" ," %i7" | |
69 | end-string-array | |
70 | ||
71 | defer regs ' real-regs is regs | |
72 | ||
73 | string-array op2s | |
74 | ( 0 ) ," add" ," and" ," or" ," xor" | |
75 | ( 4 ) ," sub" ," andn" ," orn" ," xnor" | |
76 | ( 8 ) ," addx" ," mulx" ," umul" ," smul" | |
77 | ( c ) ," subx" ," udivx" ," udiv" ," sdiv" | |
78 | ( 10 ) ," addcc" ," andcc" ," orcc" ," xorcc" | |
79 | ( 14 ) ," subcc" ," andncc" ," orncc" ," xnorcc" | |
80 | ( 18 ) ," addxcc" ," ???" ," umulcc" ," smulcc" | |
81 | ( 1c ) ," subxcc" ," ???" ," udivcc" ," sdivcc" | |
82 | ( 20 ) ," taddcc" ," tsubcc" ," taddcctv" ," tsubcctv" | |
83 | ( 24 ) ," mulscc" ," sll" ," srl" ," sra" | |
84 | ( 28 ) ," rdasr" ," rdpsr" ," rdpr" ," rdtbr" | |
85 | ( 2c ) ," movcc" ," sdivx" ," popc" ," movr" | |
86 | ( 30 ) ," wrasr" ," wrpsr" ," wrpr" ," wrtbr" | |
87 | ( 34 ) ," fpop1" ," fpop2" ," cpop1" ," cpop2" | |
88 | ( 38 ) ," jmp" ," rett" ," ticc" ," iflush" | |
89 | ( 3c ) ," save" ," restore" ," ???" | |
90 | end-string-array | |
91 | ||
92 | string-array op3s | |
93 | ( 0 ) ," ld" ," ldub" ," lduh" ," ldd" | |
94 | ( 4 ) ," st" ," stb" ," sth" ," std" | |
95 | ( 8 ) ," ldsw" ," ldsb" ," ldsh" ," ldx" | |
96 | ( c ) ," ???" ," ldstub" ," stx" ," swapl" | |
97 | ( 10 ) ," lda" ," lduba" ," lduha" ," ldda" | |
98 | ( 14 ) ," sta" ," stba" ," stha" ," stda" | |
99 | ( 18 ) ," ldswa" ," ldsba" ," ldsha" ," ldxa" | |
100 | ( 1c ) ," ???" ," ldstba" ," stxa" ," swapa" | |
101 | ( 20 ) ," ldf" ," ldfsr" ," ldqf" ," lddf" | |
102 | 32\ ( 24 ) ," stf" ," stfsr" ," stdfq" ," stdf" | |
103 | 64\ ( 24 ) ," stf" ," stfsr" ," stqf" ," stdf" | |
104 | ( 28 ) ," ???" ," ???" ," ???" ," ???" | |
105 | ( 2c ) ," ???" ," prefetch" ," ???" ," ???" | |
106 | ( 30 ) ," ldfa" ," ???" ," ldqfa" ," lddfa" | |
107 | ( 34 ) ," stfa" ," ???" ," stqfa" ," stdfa" | |
108 | ( 38 ) ," ???" ," ???" ," ???" ," ???" | |
109 | ( 3c ) ," casa" ," prefetcha" ," casxa" ," ???" | |
110 | end-string-array | |
111 | ||
112 | string-array fiops \ Op-field - 0xc0 | |
113 | ," ???" ," fstoir" ," fdtoir" ," fxtoir" | |
114 | ," fitos" ," ???" ," fdtos" ," fxtos" | |
115 | ," fitod" ," fstod" ," ???" ," fxtod" | |
116 | ," fitox" ," fstox" ," fdtox" ," ???" | |
117 | ," ???" ," fstoi" ," fdtoi" ," fxtoi" | |
118 | end-string-array | |
119 | ||
120 | string-array f2ops \ Op-field - 0x40 | |
121 | ," ???" ," fadds" ," faddd" ," faddx" | |
122 | ," ???" ," fsubs" ," fsubd" ," fsubx" | |
123 | ," ???" ," fmuls" ," fmuld" ," fmulx" | |
124 | ," ???" ," fdivs" ," fdivd" ," fdivx" | |
125 | end-string-array | |
126 | ||
127 | string-array f2ops+ \ Op-field - 0x60 | |
128 | ," ???" ," ???" ," ???" ," ???" | |
129 | ," ???" ," ???" ," ???" ," ???" | |
130 | ," ???" ," fsmuld" ," ???" ," ???" | |
131 | ," ???" ," ???" ," fdmulx" ," ???" | |
132 | end-string-array | |
133 | ||
134 | string-array fcmpops \ Op-field - 0x50 | |
135 | ," ???" ," fcmps" ," fcmpd" ," fcmpx" | |
136 | ," ???" ," fcmpes" ," fcmped" ," fcmpex" | |
137 | end-string-array | |
138 | ||
139 | string-array conds \ Conditional names for integer branches and traps | |
140 | ( 0 ) ," n" ," e" ," le" ," l" ," leu" ," cs" ," neg" ," vs" | |
141 | ( 8 ) ," a" ," ne" ," gt" ," ge" ," gu" ," cc" ," pos" ," vc" | |
142 | end-string-array | |
143 | ||
144 | string-array fconds \ Conditional names for floating point branches | |
145 | ( 0 ) ," n" ," ne" ," lg" ," ul" ," l" ," ug" ," g" ," u" | |
146 | ( 8 ) ," a" ," e" ," ue" ," ge" ," uge" ," le" ," ule" ," o" | |
147 | end-string-array | |
148 | ||
149 | string-array cconds \ Conditional names for coprocessor branches | |
150 | ( 0 ) ," n" ," 123" ," 12" ," 13" ," 1" ," 23" ," 2" ," 3" | |
151 | ( 8 ) ," a" ," 0" ," 03" ," 02" ," 023" ," 01" ," 013" ," 012" | |
152 | end-string-array | |
153 | ||
154 | string-array rconds \ Conditional names for BPr MOVr and FMOVr | |
155 | ," ??" ," z" ," lez" ," lz" ," ??" ," nz" ," gz" ," gez" | |
156 | end-string-array | |
157 | ||
158 | decimal | |
159 | \ Generates a mask with #bits set in the low part. 4 >mask yields 0000000f | |
160 | variable instruction | |
161 | variable end-found | |
162 | variable display-offset 0 display-offset ! | |
163 | variable branch-target \ Help for tracing/single-stepping | |
164 | variable alternate? alternate? off | |
165 | variable max-branch-target \ Help determine if end was found | |
166 | false value annulled? | |
167 | ||
168 | headers | |
169 | variable pc | |
170 | : pc@ ( -- adr ) pc @ ; | |
171 | : pc! ( adr -- ) pc ! ; | |
172 | : (inst@ ( adr -- opcode ) l@ ; | |
173 | defer inst@ ' (inst@ is inst@ | |
174 | ||
175 | : pc@l@ ( -- opcode ) pc@ inst@ ; | |
176 | ||
177 | headerless | |
178 | ||
179 | : 4u# ( n -- n' ) u# u# u# u# ; | |
180 | : 4u#. ( n -- n' ) 4u# ascii . hold ; | |
181 | ||
182 | headers | |
183 | ||
184 | defer showaddr ( addr -- ) | |
185 | : udis. ( n -- ) | |
186 | <# | |
187 | [ /n /l > [if] ] \ Compile-time test; do we need two more of these? | |
188 | 4u#. | |
189 | 4u#. | |
190 | [ [then] ] | |
191 | 4u#. | |
192 | 4u# | |
193 | u#> type | |
194 | ; | |
195 | ' udis. is showaddr | |
196 | headerless | |
197 | ||
198 | : +offset ( adr -- adr' ) display-offset @ - ; | |
199 | : >mask ( #bits -- mask ) 1 swap << 1- ; | |
200 | : bits ( right-bit #bits -- field ) | |
201 | >mask | |
202 | instruction @ rot >> ( mask shifted-instruction ) | |
203 | and ( field ) | |
204 | ; | |
205 | : 5bits ( right-bit -- field ) 5 bits ; | |
206 | : rd ( -- field ) d# 25 5bits ; | |
207 | : rs1 ( -- field ) d# 14 5bits ; | |
208 | : rs2 ( -- field ) 0 5bits ; | |
209 | : shcnt ( -- field ) 0 6 bits ; | |
210 | : bit? ( bit# -- f ) instruction @ 1 rot << and ; | |
211 | : bit13? ( -- flag ) d# 13 bit? ; | |
212 | : bit12? ( -- flag ) d# 12 bit? ; | |
213 | \ Display formatting | |
214 | variable start-column | |
215 | : op-col ( -- ) start-column @ d# 12 + to-column ; | |
216 | ||
217 | : ., ( -- ) ." , " ; | |
218 | : .reg ( n -- ) regs ". ; | |
219 | : .asreg ( n -- ) ." %r" .d ; | |
220 | : >freg ( n mask -- freg# ) | |
221 | over and swap | |
222 | 1 and 5 << or | |
223 | ; | |
224 | : .(freg#) ( freg# -- ) | |
225 | ." %f" .d | |
226 | ; | |
227 | : .freg ( n -- ) | |
228 | d# 19 2 bits if | |
229 | h# 1e >freg | |
230 | then | |
231 | .(freg#) | |
232 | ; | |
233 | : .creg ( n -- ) ." %c" .d ; | |
234 | : .frsrd ( -- ) rs2 .freg ., rd .freg ; | |
235 | : .3fregs ( -- ) rs1 .freg ., .frsrd ; | |
236 | : op.3fregs ( -- ) op-col .3fregs ; | |
237 | : .frs1rs2 ( -- ) rs1 .freg ., rs2 .freg ; | |
238 | : .rd ( -- ) rd .reg ; | |
239 | : op.rd ( -- ) op-col .rd ; | |
240 | : sext ( n wid' -- n' ) tuck << l->n swap >>a ; \ Sign extend | |
241 | ||
242 | \ Extract the Sign-Extended immediate field (starting at bit-position zero) | |
243 | \ whose width is given. | |
244 | : simm# ( wid -- n' ) | |
245 | 0 over bits ( wid n ) | |
246 | d# 32 rot - ( n wid' ) | |
247 | sext | |
248 | ; | |
249 | \ Three popular sizes of Sign-Extended immediate fields: | |
250 | : immedop ( -- n ) d# 13 simm# ; | |
251 | : simm10 ( -- n ) d# 10 simm# ; | |
252 | : simm11 ( -- n ) d# 11 simm# ; | |
253 | ||
254 | : immasi ( -- asi ) | |
255 | 5 8 bits | |
256 | ; | |
257 | ||
258 | \ Stuff the branch-target and update the max-branch-target | |
259 | : branch-target! ( targ-addr -- ) | |
260 | dup branch-target ! ( targ-addr ) | |
261 | max-branch-target @ umax max-branch-target ! | |
262 | ; | |
263 | ||
264 | \ An unconditional ("always") branch ends the disassembly | |
265 | \ if there are no branch-targets forward of its location. | |
266 | : ?end-found ( -- ) | |
267 | pc@ max-branch-target @ >= end-found ! | |
268 | ; | |
269 | ||
270 | : .?asi ( -- ) | |
271 | alternate? @ if | |
272 | bit13? if ." %asi" | |
273 | else | |
274 | immasi (u.) type | |
275 | then | |
276 | then | |
277 | ; | |
278 | : .rs1 ( -- ) rs1 .reg ; | |
279 | : .rs2 ( -- ) bit13? if immedop (u.) type else rs2 .reg then ; | |
280 | : .src ( -- ) .rs1 ., .rs2 .?asi ; | |
281 | : op.src ( -- ) op-col .src ; | |
282 | : .illegal ( -- ) ." Illegal instruction: " instruction @ u. ; | |
283 | ||
284 | : opcode ( -- n ) d# 19 6 bits ; | |
285 | ||
286 | : .ea-sparc ( -- ) | |
287 | ." [" | |
288 | .rs1 | |
289 | opcode h# 3d and h# 3c = if | |
290 | ." ]" | |
291 | .?asi | |
292 | ., rs2 .reg | |
293 | else | |
294 | bit13? if | |
295 | immedop ?dup if | |
296 | dup 0> if ." + " else ." - " then abs (.) type | |
297 | then | |
298 | else | |
299 | rs2 ?dup if ." + " .reg then | |
300 | then | |
301 | ." ]" | |
302 | .?asi | |
303 | then | |
304 | ; | |
305 | ||
306 | defer .impl-asi-ea ' .ea-sparc is .impl-asi-ea | |
307 | \ This may get re-vectored for variant implementations. | |
308 | ||
309 | \ Non-implementation-dependent or reserved ASIs are: | |
310 | \ 10, 11, 18, 19, 80..83, and 88..bf | |
311 | \ (Ref: SPARC Arch. Manual, sec 6.3.1.3, Table 12) | |
312 | : ea-sparc? ( -- Use-.ea-sparc? ) | |
313 | immasi dup ( asi asi ) | |
314 | " "( 10 11 18 19 80 81 82 83 )" \ Inconveniently-grouped-ASI-list | |
315 | rot scantochar <> nip ( asi match? ) | |
316 | swap h# 88 h# bf between | |
317 | or | |
318 | ; | |
319 | ||
320 | : .ea ( -- ) | |
321 | alternate? @ 0= | |
322 | bit13? or | |
323 | ea-sparc? or | |
324 | if .ea-sparc else .impl-asi-ea then | |
325 | alternate? off | |
326 | ; | |
327 | ||
328 | ||
329 | ||
330 | \ The condition-code field may occur in either of two | |
331 | \ bit-positions within an instruction. | |
332 | \ Take the bit-position as a parameter and print the | |
333 | \ integer conditional name | |
334 | : .#cond ( bit# -- ) 4 bits conds ". ; | |
335 | : .cond ( -- ) d# 25 .#cond ; | |
336 | : .rcond ( n -- ) rconds ". ; | |
337 | ||
338 | \ Likewise the floating point conditional name | |
339 | : .#fcond ( bit# -- ) 4 bits fconds ". ; | |
340 | ||
341 | : .(op2) ( -- ) opcode op2s ". ; | |
342 | : .op2 ( -- ) .(op2) op-col ; | |
343 | ||
344 | : .freg-double ( n -- ) | |
345 | h# 3e >freg .(freg#) | |
346 | ; | |
347 | ||
348 | : .freg-quad ( n -- ) | |
349 | h# 3c >freg .(freg#) | |
350 | ; | |
351 | ||
352 | : .frs1rs2-double ( -- ) rs1 .freg-double ., rs2 .freg-double ; | |
353 | : .3fregs-double ( -- ) .frs1rs2-double ., rd .freg-double ; | |
354 | ||
355 | : .freg-encode ( n -- ) | |
356 | opcode h# 2b and case | |
357 | h# 23 of .freg-double endof \ double operation | |
358 | h# 22 of .freg-quad endof \ quad | |
359 | swap .freg | |
360 | endcase | |
361 | ; | |
362 | ||
363 | : .r/fd ( -- ) | |
364 | rd | |
365 | d# 23 2 bits | |
366 | sparc-v9? if | |
367 | case | |
368 | 2 of .freg-encode endof | |
369 | 3 of d# 19 4 bits | |
370 | h# 0d and h# 0c = if | |
371 | .reg | |
372 | else .freg-encode | |
373 | then | |
374 | endof \ CAS special case | |
375 | swap .reg | |
376 | endcase | |
377 | else | |
378 | case | |
379 | 2 of .freg endof | |
380 | 3 of .creg endof | |
381 | swap .reg | |
382 | endcase | |
383 | then | |
384 | ; | |
385 | : .class3 ( -- ) | |
386 | opcode dup op3s ". op-col ( op-code ) | |
387 | ||
388 | \ XXX Is the next line correct for the "ldc" class of instruction? | |
389 | dup h# 10 and if alternate? on then | |
390 | ||
391 | dup h# 3c = \ CASA | |
392 | over h# 3e = \ CASX | |
393 | or if drop | |
394 | ." [" .rs1 ." ] " .?asi ., .rs2 ., .rd | |
395 | else ( op-code ) | |
396 | dup h# 0c and 4 = | |
397 | swap h# 2f and h# 0e = or | |
398 | if .r/fd ., .ea else .ea ., .r/fd then | |
399 | then ( -- ) | |
400 | alternate? off | |
401 | ; | |
402 | ||
403 | : fp-op ( -- n ) 5 9 bits ; | |
404 | : op.frsrd ( -- ) op-col .frsrd ; | |
405 | : .fpop1 ( -- ) | |
406 | fp-op h# c0 h# d3 between if \ Type conversion operators | |
407 | fp-op h# c0 - fiops ". op.frsrd | |
408 | else | |
409 | fp-op h# 40 h# 4f between if \ Arithmetic operators | |
410 | fp-op h# 40 - f2ops ". op.3fregs | |
411 | else | |
412 | fp-op h# 60 h# 6f between if \ More arithmetic operators | |
413 | fp-op h# 60 - f2ops+ ". op.3fregs | |
414 | else | |
415 | fp-op case \ Miscellaneous operators | |
416 | 1 of ." fmovs" op.frsrd endof | |
417 | 5 of ." fnegs" op.frsrd endof | |
418 | 9 of ." fabss" op.frsrd endof | |
419 | h# 29 of ." fsqrts" op.frsrd endof | |
420 | h# 2a of ." fsqrtd" op.frsrd endof | |
421 | h# 2b of ." fsqrtx" op.frsrd endof | |
422 | ." fpop???" | |
423 | endcase | |
424 | then then then | |
425 | ; | |
426 | : .fpop2 ( -- ) | |
427 | fp-op h# 50 - fcmpops ". op-col .frs1rs2 | |
428 | ; | |
429 | ||
430 | string-array membar-mask | |
431 | ," #LoadLoad " | |
432 | ," #StoreLoad " | |
433 | ," #LoadStore " | |
434 | ," #StoreStore " | |
435 | ," #Lookaside " | |
436 | ," #MemIssue " | |
437 | ," #Sync " | |
438 | end-string-array | |
439 | ||
440 | : .membar ( -- ) | |
441 | ." membar" op-col | |
442 | immedop | |
443 | 7 0 do | |
444 | dup 1 and if | |
445 | i membar-mask ". | |
446 | then | |
447 | 2/ loop drop | |
448 | ; | |
449 | ||
450 | : .stbar ( -- ) ." stbar" ; | |
451 | ||
452 | : .wry ( -- ) ." wry" op.src ; | |
453 | : .rdy ( -- ) ." rdy" op.rd ; | |
454 | ||
455 | : .op2+src+dest ( -- ) .op2 .src ., .rd ; | |
456 | ||
457 | : .op2-wra ( -- ) .op2+src+dest .asreg ; | |
458 | : .op2-rda ( -- ) .op2 rs1 .asreg ., .rd ; | |
459 | ||
460 | defer .impl-wrasr ' .illegal is .impl-wrasr | |
461 | defer .impl-rdasr ' .illegal is .impl-rdasr | |
462 | ||
463 | : .wrasr-v9 ( -- ) | |
464 | rd d# 16 d# 31 between if | |
465 | .impl-wrasr | |
466 | else | |
467 | rd case | |
468 | 0 of .wry endof | |
469 | 2 of ." wrccr" op.src endof | |
470 | 3 of ." wrasi" op.src endof | |
471 | 6 of ." wrfprs" op.src endof | |
472 | d# 15 of | |
473 | rs1 ( 0<> ) if .illegal | |
474 | else bit13? if | |
475 | ." sigm" | |
476 | else | |
477 | .illegal | |
478 | then | |
479 | then | |
480 | endof | |
481 | .illegal | |
482 | endcase | |
483 | then | |
484 | ; | |
485 | : .wrasr-v8 ( -- ) | |
486 | rd ( 0<> ) if | |
487 | .op2-wra | |
488 | else | |
489 | .wry | |
490 | then | |
491 | ; | |
492 | : .wrasr ( -- ) sparc-v9? if .wrasr-v9 else .wrasr-v8 then ; | |
493 | : .rdasr-v9 ( -- ) | |
494 | ||
495 | rs1 d# 16 d# 31 between if | |
496 | .impl-rdasr | |
497 | else | |
498 | rs1 case | |
499 | 0 of .rdy endof | |
500 | 2 of ." rdccr" op.rd endof | |
501 | 3 of ." rdasi" op.rd endof | |
502 | 4 of ." rdtick" op.rd endof | |
503 | 5 of ." rdpc" op.rd endof | |
504 | 6 of ." rdfprs" op.rd endof | |
505 | d# 15 of | |
506 | rd ( 0<> ) if .illegal | |
507 | else bit13? if | |
508 | .membar | |
509 | else | |
510 | .stbar | |
511 | then | |
512 | then | |
513 | endof | |
514 | .illegal | |
515 | endcase | |
516 | then | |
517 | ; | |
518 | : .rdasr-v8 ( -- ) | |
519 | rs1 case | |
520 | 0 of .rdy endof | |
521 | d# 15 of | |
522 | rd ( 0<> ) if .illegal | |
523 | else .stbar | |
524 | then | |
525 | endof | |
526 | .op2-rda | |
527 | endcase | |
528 | ; | |
529 | ||
530 | : .rdasr ( -- ) sparc-v9? if .rdasr-v9 else .rdasr-v8 then ; | |
531 | ||
532 | : .shift ( -- ) \ Called when opcode is between h# 25 thru h# 27 | |
533 | .(op2) bit12? if ." x" then | |
534 | op-col .rs1 ., shcnt bit13? if | |
535 | bit12? if h# 3f else h# 1f then and (u.) type | |
536 | else | |
537 | .reg | |
538 | then ., .rd | |
539 | ; | |
540 | ||
541 | string-array priv-regs | |
542 | ," tpc" ," tnpc" ," tstate" ," tt" | |
543 | ," tick" ," tba" ," pstate" ," tl" | |
544 | ," pil" ," cwp" ," cansave" ," canrestore" | |
545 | ," cleanwin" ," otherwin" ," wstate" ," fq" | |
546 | end-string-array | |
547 | ||
548 | : .rdpr ( -- ) | |
549 | rs1 0 d# 15 between if | |
550 | ." rd" rs1 priv-regs ". op.rd exit | |
551 | then | |
552 | rs1 d# 16 = if | |
553 | ." rdgl" op.rd exit | |
554 | then | |
555 | rs1 d# 31 = if | |
556 | ." rdver" op.rd | |
557 | else | |
558 | .illegal | |
559 | then | |
560 | ; | |
561 | ||
562 | : .wrpr ( -- ) | |
563 | rd 0 d# 14 between if | |
564 | ." wr" rd priv-regs ". op.src exit | |
565 | then | |
566 | rd d# 16 = if | |
567 | ." wrgl" op.src | |
568 | else | |
569 | .illegal | |
570 | then | |
571 | ; | |
572 | ||
573 | \ Depending upon the rcond field in the instruction, generate | |
574 | \ appropriate instruction: | |
575 | \ rcond=001b movrz; rcond=010b movrlez; rcond=011b movrlz | |
576 | \ rcond=101b movrnz; rcond=110b movrgz; rcond=111b movrgez | |
577 | \ rcond=000b or 100b (reserved) movr??? | |
578 | : .movr ( -- ) | |
579 | ." movr" d# 10 3 bits .rcond op-col .rs1 ., bit13? if | |
580 | simm10 (u.) | |
581 | else | |
582 | .rs2 | |
583 | then ., .rd | |
584 | ; | |
585 | \ The cc1|cc0 field may occur in either of two | |
586 | \ bit-positions within an instruction. | |
587 | \ Take the bit-position as a parameter and show the field | |
588 | : .#xcc ( bit# -- ) | |
589 | 2 bits dup 2 = if | |
590 | drop ." %xcc" | |
591 | else | |
592 | 0= if ." %icc" else ." ???" then | |
593 | then ., | |
594 | ; | |
595 | \ Show the cc1|cc0 field of a Class 0, Format 2 | |
596 | \ instruction, (branches Bicc BPcc, BPr, etc.) | |
597 | \ where it occurs in bit-position d# 20 | |
598 | : .cc ( -- ) | |
599 | d# 20 .#xcc | |
600 | ; | |
601 | \ Show the cc1|cc0 field of a Class 2, Format 4 | |
602 | \ instruction, (traps Tcc and MOVcc, FMOVcc) | |
603 | \ where it occurs in bit-position d# 11 | |
604 | : .txcc ( -- ) d# 11 .#xcc ; | |
605 | ||
606 | \ Show the Tcc instruction | |
607 | : .ticc ( -- ) | |
608 | ." t" .cond op-col .txcc | |
609 | .rs1 ., bit13? if | |
610 | \ Extract bits 0..10 as a "simm11" field. | |
611 | \ Bits 7..10 are reserved. | |
612 | ||
613 | \ Let's show what's actually there. | |
614 | simm11 (u.) type | |
615 | \ Alternatively, we could highlight an error, thus: | |
616 | \ simm11 dup (u.) type | |
617 | \ h# 780 and if ." "t"t\ Illegal Trap #" then | |
618 | ||
619 | else rs2 .reg | |
620 | then | |
621 | ; | |
622 | ||
623 | \ Condition field of a MOVcc or MOVFcc instruction | |
624 | : .(mov)cond ( -- ) | |
625 | d# 14 \ bit-position where it occurs | |
626 | d# 18 bit? if .#cond | |
627 | else ." f" .#fcond | |
628 | then | |
629 | ; | |
630 | : .movcc ( -- ) | |
631 | ." mov" .(mov)cond op-col | |
632 | d# 18 bit? if .txcc | |
633 | else d# 11 2 bits ." %fcc" 1 .r ., | |
634 | then bit13? if | |
635 | simm11 (u.) type | |
636 | else rs2 .reg | |
637 | then ., .rd | |
638 | ; | |
639 | ||
640 | : .popc ( -- ) | |
641 | rs1 if | |
642 | .illegal | |
643 | else | |
644 | ." popc" op-col .rs2 ., .rd | |
645 | then | |
646 | ; | |
647 | ||
648 | defer .impdep1 ' .illegal is .impdep1 | |
649 | defer .impdep2 ' .illegal is .impdep2 | |
650 | ||
651 | : .class2 ( -- ) | |
652 | false is annulled? | |
653 | opcode h# 38 h# 39 between end-found ! | |
654 | opcode h# 25 h# 27 between if .shift exit then | |
655 | opcode case | |
656 | h# 28 of .rdasr endof | |
657 | h# 29 of .op2 .rd endof \ RDPSR | |
658 | h# 2a of | |
659 | sparc-v9? if .rdpr else ." rdwim" op.rd then | |
660 | endof | |
661 | h# 2b of | |
662 | sparc-v9? if | |
663 | ." flushw" | |
664 | else | |
665 | .op2 .rd \ RDTBR | |
666 | then | |
667 | endof | |
668 | h# 2c of .movcc endof | |
669 | h# 2e of .popc endof | |
670 | h# 2f of .movr endof | |
671 | h# 30 of .wrasr endof | |
672 | h# 31 of | |
673 | sparc-v9? if | |
674 | rd case | |
675 | 0 of ." saved" endof | |
676 | 1 of ." restored" endof | |
677 | 2 of ." allclean" endof | |
678 | 3 of ." otherw" endof | |
679 | 4 of ." normalw" endof | |
680 | 5 of ." invalw" endof | |
681 | .illegal | |
682 | endcase | |
683 | else | |
684 | .op2 .src \ WRPSR | |
685 | then | |
686 | endof | |
687 | h# 32 of | |
688 | sparc-v9? if .wrpr else ." wrwim" op.src then | |
689 | endof | |
690 | h# 33 of .op2 .src endof \ WRTBR | |
691 | h# 34 of .fpop1 endof | |
692 | h# 35 of .fpop2 endof | |
693 | h# 36 of | |
694 | sparc-v9? if | |
695 | .impdep1 | |
696 | else | |
697 | .op2+src+dest | |
698 | then | |
699 | endof | |
700 | h# 37 of | |
701 | sparc-v9? if | |
702 | .impdep2 | |
703 | else | |
704 | .op2+src+dest | |
705 | then | |
706 | endof | |
707 | h# 3a of .ticc endof | |
708 | h# 3e of | |
709 | ?end-found end-found @ is annulled? | |
710 | rd case | |
711 | 0 of ." done" endof | |
712 | 1 of ." retry" endof | |
713 | end-found off false is annulled? | |
714 | .illegal | |
715 | endcase | |
716 | endof | |
717 | ( default ) .op2+src+dest | |
718 | endcase | |
719 | ; | |
720 | \ Given a signed immediate, show it as a displacement | |
721 | \ Also works for a call instruction, which uses | |
722 | \ all but its upper two bits for the offset. | |
723 | : .disp ( simm|call-instruction -- ) | |
724 | 2 << \ Convert longword offset to byte offset | |
725 | l->n \ Make sure it's sign-extended... | |
726 | pc@ + +offset | |
727 | dup branch-target! \ Might advance max-branch-target | |
728 | showaddr | |
729 | ; | |
730 | : .disp22 ( -- ) | |
731 | op-col d# 22 simm# .disp | |
732 | ; | |
733 | : .disp19 ( -- ) | |
734 | d# 19 simm# .disp | |
735 | ; | |
736 | : .disp16 ( -- ) | |
737 | 0 d# 14 bits d# 20 2 bits d# 14 << or ( n=16bits ) | |
738 | d# 16 ( n wid' ) \ wid=16 which happens to equal wid' (32 - wid) | |
739 | sext \ Sign extend | |
740 | .disp | |
741 | ; | |
742 | : .sethi ( -- ) | |
743 | ." sethi" op-col instruction @ d# 10 << n->l (u.) type ., .rd | |
744 | ; | |
745 | : .call ( -- ) | |
746 | ." call" op-col | |
747 | instruction @ .disp | |
748 | end-found on false is annulled? | |
749 | ; | |
750 | ||
751 | \ Extract the condition field of a Bcc, BPcc, FBcc or CBcc instruction | |
752 | \ For unconditional ("always") branch, check for end of disassembly | |
753 | : (bra)cond@ ( -- condition-code ) | |
754 | d# 25 4 bits ( condition-code ) | |
755 | dup 8 = if ?end-found then ( ) \ cc = 8 ==> "always" | |
756 | ; | |
757 | ||
758 | \ Display the "annulled" field (bit 29) of a branch instruction. | |
759 | \ Also, if the branch that ends the disassembly is annulled, | |
760 | \ suppress displaying the -- possibly non-valid -- non-executed | |
761 | \ delay-slot contents. | |
762 | : .annul ( -- ) d# 29 bit? dup is annulled? if ." ,a" then ; | |
763 | ||
764 | \ Common routine to print the condition-field extracted above, | |
765 | \ after the appropriate condition-list's string-array has been | |
766 | \ invoked. Annul bit (29) is also shared with the Bcc, BPcc, | |
767 | \ FBcc and CBcc instructions, but BPcc differs from the others | |
768 | \ in that it uses 19-bit instead of 22-bit displacement. | |
769 | \ | |
770 | : .(cond) ( p$addr -- ) ". .annul ; | |
771 | ||
772 | \ Common part of Bcc and BPcc | |
773 | : .(bra)cond ( -- ) (bra)cond@ conds .(cond) ; | |
774 | ||
775 | : .bcc ( -- ) ." b" .(bra)cond .disp22 ; | |
776 | : .fbcc ( -- ) ." fb" (bra)cond@ fconds .(cond) .disp22 ; | |
777 | ||
778 | : .predict ( -- ) d# 19 bit? if ." ,pt" else ." ,pn" then ; | |
779 | : .bpcc ( -- ) ." bp" .(bra)cond .predict op-col .cc .disp19 ; | |
780 | ||
781 | : .bpr ( -- ) | |
782 | ." bpr" d# 25 3 bits .rcond | |
783 | .annul .predict | |
784 | op-col .rs1 ., .disp16 | |
785 | ; | |
786 | : .fbpfcc ( -- ) ." fbp %fcc XXX " ; | |
787 | : .cbcc ( -- ) ." cb" (bra)cond@ cconds .(cond) .disp22 ; | |
788 | ||
789 | : .format2 ( -- ) | |
790 | d# 22 3 bits | |
791 | case | |
792 | 0 of sparc-v9? if ." illtrap" else ." unimp" then endof | |
793 | 1 of sparc-v9? if .bpcc else .illegal then endof | |
794 | 2 of .bcc endof | |
795 | 3 of sparc-v9? if .bpr else .illegal then endof | |
796 | 4 of .sethi endof | |
797 | 5 of sparc-v9? if .fbpfcc else .illegal then endof | |
798 | 6 of .fbcc endof | |
799 | 7 of sparc-v9? if .illegal else .cbcc then endof | |
800 | endcase | |
801 | ; | |
802 | : disasm ( 32b -- ) | |
803 | instruction ! | |
804 | d# 30 2 bits | |
805 | case | |
806 | 0 of .format2 endof | |
807 | 1 of .call endof | |
808 | 2 of .class2 endof | |
809 | 3 of .class3 endof | |
810 | endcase | |
811 | ; | |
812 | \ Common code for disassembler access, independent of vectoring of inst@ | |
813 | : (dis1) ( -- ) | |
814 | ??cr | |
815 | pc@ +offset showaddr 4 spaces #out @ start-column ! | |
816 | pc@l@ disasm cr | |
817 | /l pc@ + pc! | |
818 | ; | |
819 | : +(dis) ( -- ) | |
820 | push-hex | |
821 | end-found off max-branch-target off | |
822 | begin (dis1) end-found @ exit? or until | |
823 | annulled? 0= if (dis1) then \ Disassemble the delay instruction too | |
824 | pop-base | |
825 | ; | |
826 | : (dis) ( adr -- ) | |
827 | pc! | |
828 | +(dis) | |
829 | ; | |
830 | ||
831 | headers | |
832 | forth definitions | |
833 | alias disasm disasm | |
834 | : dis1 ( -- ) | |
835 | ['] (inst@ is inst@ | |
836 | (dis1) | |
837 | ; | |
838 | ||
839 | : +dis ( -- ) | |
840 | ['] (inst@ is inst@ | |
841 | +(dis) | |
842 | ; | |
843 | : dis ( adr -- ) | |
844 | ['] (inst@ is inst@ | |
845 | (dis) | |
846 | ; | |
847 | ||
848 | headerless | |
849 | alias (dis dis | |
850 | headers | |
851 | ||
852 | previous previous definitions |