Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / cpu / sparc / assem.fth
CommitLineData
920dae64
AT
1\ ========== Copyright Header Begin ==========================================
2\
3\ Hypervisor Software File: assem.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\ @(#)assem.fth 2.29 06/02/16
43\ Copyright 1985-1990 Bradley Forthware
44\ copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved
45\ copyright: Use is subject to license terms.
46
47\ requires case.f
48\ requires string-array.f
49
50vocabulary srassembler
51also srassembler definitions
52
53headerless
54alias lor or \ Because "or" gets redefined in the assembler
55alias land and \ Because "and" gets redefined in the assembler
56
57defer here \ For switching between resident and meta assembling
58defer asm-allot \ For switching between resident and meta assembling
59defer asm@ \ For switching between resident and meta assembling
60defer asm! \ For switching between resident and meta assembling
61defer /asm
62
63\ Install as a resident assembler
64: resident-assembler ( -- )
65 [ also forth ] ['] /l [ previous ] is /asm
66 [ also forth ] ['] here [ previous ] is here
67 [ also forth ] ['] allot [ previous ] is asm-allot
68 [ also forth ] ['] l@ [ previous ] is asm@
69 [ also forth ] ['] instruction! [ previous ] is asm!
70;
71
72resident-assembler
73
74
75decimal
76
77h# 1fff constant immedmask
78immedmask 1 + constant immedbit
79immedmask constant maximmed
80maximmed negate constant minimmed
81h# 1f constant regmask
82h# 1000.0000 constant regmagic
83h# ff constant asimask
84
85: reg ( n -- ) regmagic + ;
86: register \ name ( n -- )
87 create w, does> w@ reg
88;
89
90headers
91
92 0 register %g0 1 register %g1 2 register %g2 3 register %g3
93 4 register %g4 5 register %g5 6 register %g6 7 register %g7
94 8 register %o0 9 register %o1 10 register %o2 11 register %o3
9512 register %o4 13 register %o5 14 register %o6 15 register %o7
9616 register %l0 17 register %l1 18 register %l2 19 register %l3
9720 register %l4 21 register %l5 22 register %l6 23 register %l7
9824 register %i0 25 register %i1 26 register %i2 27 register %i3
9928 register %i4 29 register %i5 30 register %i6 31 register %i7
100
101 0 register %r0 1 register %r1 2 register %r2 3 register %r3
102 4 register %r4 5 register %r5 6 register %r6 7 register %r7
103 8 register %r8 9 register %r9 10 register %r10 11 register %r11
10412 register %r12 13 register %r13 14 register %r14 15 register %r15
10516 register %r16 17 register %r17 18 register %r18 19 register %r19
10620 register %r20 21 register %r21 22 register %r22 23 register %r23
10724 register %r24 25 register %r25 26 register %r26 27 register %r27
10828 register %r28 29 register %r29 30 register %r30 31 register %r31
109
11064 register %f0 65 register %f1 66 register %f2 67 register %f3
11168 register %f4 69 register %f5 70 register %f6 71 register %f7
11272 register %f8 73 register %f9 74 register %f10 75 register %f11
11376 register %f12 77 register %f13 78 register %f14 79 register %f15
11480 register %f16 81 register %f17 82 register %f18 83 register %f19
11584 register %f20 85 register %f21 86 register %f22 87 register %f23
11688 register %f24 89 register %f25 90 register %f26 91 register %f27
11792 register %f28 93 register %f29 94 register %f30 95 register %f31
118
119097 register %f32 099 register %f34 101 register %f36 103 register %f38
120105 register %f40 107 register %f42 109 register %f44 111 register %f46
121113 register %f48 115 register %f50 117 register %f52 119 register %f54
122121 register %f56 123 register %f58 125 register %f60 127 register %f62
123
124128 register %asi 129 register %xcc 130 register %icc
125
126headerless
127: isimmed? ( [ rs2 | imm ] -- f ) minimmed maximmed between ;
128: ?freg ( r -- r )
129 dup %f0 %f62 between 0= abort" Floating point register required"
130;
131: ?ireg ( r -- r )
132 dup %g0 %i7 between 0= abort" Integer register required"
133;
134: setbits ( opcode -- ) here /asm asm-allot asm! ;
135: opaddr ( -- addr ) here /asm - ;
136: tcc? ( -- flag )
137 opaddr asm@ d# 19 rshift h# 3f and b# 11.1010 =
138;
139: addbits ( bits -- ) opaddr asm@ lor opaddr asm! ;
140: clearbits ( bits -- ) invert opaddr asm@ and opaddr asm! ;
141: regset ( reg shift -- ) swap regmask land swap << addbits ;
142: rs ( rs -- ) 14 regset ;
143: rd ( rd -- ) 25 regset ;
144: rs2 ( rs2 -- ) 0 regset ;
145: src ( rs1 [ rs2 | imm ] -- )
146 dup isimmed? if ( rs1 imm )
147 immedmask land immedbit lor addbits
148 else ( rs1 rs2 )
149 rs2
150 then ( rs1 )
151 rs
152;
153: %asi? ( asi -- flag ) %asi = ;
154: asrc ( rs1 [ rs2 | imm ] asi -- )
155 dup %asi? if ( rs1 imm asi )
156 drop dup isimmed? 0= ( rs1 imm flag )
157 abort" Immediate must be used with alternate space instructions"
158 else ( rs1 rs2 asi )
159 asimask land 5 << addbits ( rs1 rs2 )
160 dup isimmed? ( rs1 rs2 flag )
161 abort" Immediate fields can't be used with alternate space instructions"
162 then
163 src
164;
165
166: cas-src ( rs1 asi -- )
167 dup %asi? if ( rs1 %asi )
168 drop ( rs1 )
169 immedbit addbits ( rs1 )
170 else ( rs1 asi )
171 asimask land 5 << addbits ( rs1 )
172 then
173 rs
174;
175: set-op ( n class -- ) d# 30 << swap d# 19 << + setbits ;
176: wcreate ( n -- ) create w, [compile] does> compile w@ ; immediate
177: set-op2 ( n -- ) 2 set-op ;
178: w@set-op3 ( adr -- ) w@ 3 set-op ;
179: w@set-op2 ( adr -- ) w@ set-op2 ;
180: createw, ( n -- ) create w, ;
181
182\ Class 3 operations, loads and stores
183: op3 ( opcode -- )
184 createw, does> w@set-op3 ( rs1 [ rs2 | imm ] rd ) rd src
185;
186
187\ Load from alternate address space instructions
188: opa ( opcode -- )
189 createw, does> w@set-op3 ( rs1 rs2 asi rd ) rd asrc
190;
191
192\ For store instructions, where rd comes first
193: sop3 ( opcode -- )
194 createw, does> w@set-op3 ( rd rs1 [ rs2 | imm ] ) src rd
195;
196
197\ For store alternate instructions, where rd comes first
198: sopa ( opcode -- )
199 createw, does> w@set-op3 ( rd rs1 rs2 asi ) asrc rd
200;
201
202\ Class 3 operations, loads and stores
203: op3a ( opcode -- )
204 createw, does> w@set-op3 ( rs1 rs2 asi rd ) rd rs2 cas-src
205;
206
207headers
208
209hex
21000 op3 lduw 04 sop3 st 08 op3 ldsw
21101 op3 ldub 05 sop3 stb 09 op3 ldsb 0d op3 ldstub
21202 op3 lduh 06 sop3 sth 0a op3 ldsh 0e sop3 stx
21303 op3 ldd 07 sop3 std 0b op3 ldx 0f op3 swapl
214
21500 op3 ld \ V8 name for lduw
216
21710 opa lda 14 sopa sta 18 opa ldswa
21811 opa lduba 15 sopa stba 19 opa ldsba 1d opa ldstba
21912 opa lduha 16 sopa stha 1a opa ldsha 1e sopa stxa
22013 opa ldda 17 sopa stda 1b opa ldxa 1f opa swapa
221
22220 op3 ldf 24 sop3 stf
22321 op3 ldfsr 25 sop3 stfsr
224
22532\ 22 op3 ldqf 26 sop3 stdfq
22664\ 22 op3 ldqf 26 sop3 stqf 2d op3 prefetch
227
22823 op3 lddf 27 sop3 stdf
229
23030 op3 ldfa
231 3c op3a casa
23232 opa ldqfa 3d opa prefetcha
23333 opa lddfa 36 sopa stqfa 3e op3a casxa
23434 sopa stfa 37 sopa stdfa
235
236: stxfsr %g1 -rot stfsr ; : ldxfsr %g1 ldfsr ;
237: stfsr %g0 -rot stfsr ; : ldfsr %g0 ldfsr ;
238
239\ XXX should these be op3's instead of opa's???
240\ 30 opa ldc 34 sopa stc 38 op3 ldc2 3c op3 stc2
241\ 31 opa ldcsr 35 sopa stcsr 39 op3 ldc3 3d op3 stc3
242\ 36 sopa stdcq
243\ 33 opa lddc 37 sopa stdc
244
24528 op3 ldf2 2c sop3 stf2 \ V8 Only
24629 op3 ldf3 2d sop3 stf3 \ V8 Only
247
248headerless
249\ Class 2 operations, arithmetic and logical
250: op2 ( opcode -- )
251 createw, does> w@set-op2 ( rs1 [ rs2 | imm ] rd ) rd src
252;
253\ For store instructions, where rd comes first
254: sop2 ( opcode -- )
255 createw, does> w@set-op3 ( rd rs1 [ rs2 | imm ] ) src rd
256;
257
258\ Fixed source
259: dstop2 ( opcode -- )
260 createw, does> w@set-op2 ( rd ) rd
261;
262\ Fixed destination
263: srcop2 ( opcode -- )
264 createw, does> w@set-op2 ( rs1 [ rs2 | imm ] ) src
265;
266headers
267
26800 op2 add 08 op2 addc 10 op2 addcc 18 op2 addccc
26901 op2 and 09 op2 mulx 11 op2 andcc
27002 op2 or 0a op2 umul 12 op2 orcc 1a op2 umulcc
27103 op2 xor 0b op2 smul 13 op2 xorcc 1b op2 smulcc
27204 op2 sub 0c op2 subc 14 op2 subcc 1c op2 subccc
27305 op2 andn 0d op2 udivx 15 op2 andncc
27406 op2 orn 0e op2 udiv 16 op2 orncc 1e op2 udivcc
27507 op2 xnor 0f op2 sdiv 17 op2 xnorcc 1f op2 sdivcc
276
27720 op2 taddcc 28 op2 rdasr 30 op2 wrasr 38 op2 jmpl
27821 op2 tsubcc ( saved/restored ) 39 op2 return
27922 op2 taddcctv 2a op2 rdpr 32 op2 wrpr ( Tcc )
28023 op2 tsubcctv ( flushw ) ( iflush )
28124 op2 mulscc ( MOVcc ) ( FPop1 ) 3c op2 save
28225 op2 sll 2d op2 sdivx ( FPop2 ) 3d op2 restore
28326 op2 srl 2e op2 popc ( IMPDEP1 ) ( done/retry )
28427 op2 sra ( MOVr ) ( IMPDEP2 )
285
28629 dstop2 rdpsr \ V8 Only
2872a dstop2 rdwim \ V8 Only
2882b dstop2 rdtbr \ V8 Only
28931 srcop2 wrpsr \ V8 Only
29032 srcop2 wrwim \ V8 Only
29133 srcop2 wrtbr \ V8 Only
29239 op2 rett \ V8 Only
293
294 1 constant #LoadLoad
295 2 constant #StoreLoad
296 4 constant #LoadStore
297 8 constant #StoreStore
29810 constant #Lookaside
29920 constant #MemIssue
30040 constant #Sync
301
302: membar ( imm -- ) %o7 swap %g0 rdasr ;
303
304\ rd is always 0 for return
305: return ( rs1 { rs2 | imm } -- ) %g0 return ;
306
307\ rs2 is always %g0 for RDASR Instruction
308: rdasr ( rs1 rd -- ) %g0 swap rdasr ;
309
310\ rs2 is always %g0 for RDPR Instruction
311: rdpr ( rs1 rd -- ) %g0 swap rdpr ;
312
313alias addx addc \ 08 op2 addx SPARC V8 name
314alias subx subc \ 0c op2 subx SPARC V8 name
315alias addxcc addccc \ 18 op2 addxcc SPARC V8 name
316alias subxcc subccc \ 1c op2 subxcc SPARC V8 name
317
318
319: sllx sll 1000 addbits ; \ V9
320: srlx srl 1000 addbits ; \ V9
321: srax sra 1000 addbits ; \ V9
322
323: rdy ( rd -- ) %g0 swap rdasr ; \ Special case of RDASR
324: wry ( rs1 [ rs2 | imm ] -- ) %g0 wrasr ; \ Special case of WRASR
325
326: rdccr ( rd -- ) %g2 swap rdasr ; \ Special case of RDASR
327: wrccr ( rs1 [ rs2 | imm ] -- ) %g2 wrasr ; \ Special case of WRASR
328
329: rdasi ( rd -- ) %g3 swap rdasr ; \ Special case of RDASR
330: wrasi ( rs1 [ rs2 | imm ] -- ) %g3 wrasr ; \ Special case of WRASR
331
332: rdtick ( rd -- ) %g4 swap rdasr ; \ Special case of RDASR
333
334: rdpc ( rd -- ) %g5 swap rdasr ; \ Special case of RDASR
335
336: rdfprs ( rd -- ) %g6 swap rdasr ; \ Special case of RDASR
337: wrfprs ( rs1 [ rs2 | imm ] -- ) %g6 wrasr ; \ Special case of WRASR
338
339: popc ( [ rs2 | imm ] rd -- ) %g0 -rot popc ; \ V9
340: flushw ( -- ) 2b set-op2 ; \ V9
341: saved ( -- ) 31 set-op2 %g0 rd ; \ V9
342: restored ( -- ) 31 set-op2 %g1 rd ; \ V9
343: done ( -- ) 3e set-op2 %g0 rd ; \ V9
344: retry ( -- ) 3e set-op2 %g1 rd ; \ V9
345
346headerless
347: wrpr: ( rd --) \ name
348 create c, does> c@ %g0 lor ( rs1 rs2 rd ) wrpr
349;
350: rdpr: ( rs1 --) \ name
351 create c, does> c@ %g0 lor ( rd rs1 ) swap rdpr
352;
353headers
354
355d# 0 wrpr: wrtpc ( rs1 [ rs2 | imm ] -- )
356d# 1 wrpr: wrtnpc ( rs1 [ rs2 | imm ] -- )
357d# 2 wrpr: wrtstate ( rs1 [ rs2 | imm ] -- )
358d# 3 wrpr: wrtt ( rs1 [ rs2 | imm ] -- )
359d# 4 wrpr: wrtick ( rs1 [ rs2 | imm ] -- )
360d# 5 wrpr: wrtba ( rs1 [ rs2 | imm ] -- )
361d# 6 wrpr: wrpstate ( rs1 [ rs2 | imm ] -- )
362d# 7 wrpr: wrtl ( rs1 [ rs2 | imm ] -- )
363d# 8 wrpr: wrpil ( rs1 [ rs2 | imm ] -- )
364d# 9 wrpr: wrcwp ( rs1 [ rs2 | imm ] -- )
365d# 10 wrpr: wrcansave ( rs1 [ rs2 | imm ] -- )
366d# 11 wrpr: wrcanrestore ( rs1 [ rs2 | imm ] -- )
367d# 12 wrpr: wrcleanwin ( rs1 [ rs2 | imm ] -- )
368d# 13 wrpr: wrotherwin ( rs1 [ rs2 | imm ] -- )
369d# 14 wrpr: wrwstate ( rs1 [ rs2 | imm ] -- )
370
371d# 0 rdpr: rdtpc ( rd -- )
372d# 1 rdpr: rdtnpc ( rd -- )
373d# 2 rdpr: rdtstate ( rd -- )
374d# 3 rdpr: rdtt ( rd -- )
375d# 4 rdpr: rdtick ( rd -- )
376d# 5 rdpr: rdtba ( rd -- )
377d# 6 rdpr: rdpstate ( rd -- )
378d# 7 rdpr: rdtl ( rd -- )
379d# 8 rdpr: rdpil ( rd -- )
380d# 9 rdpr: rdcwp ( rd -- )
381d# 10 rdpr: rdcansave ( rd -- )
382d# 11 rdpr: rdcanrestore ( rd -- )
383d# 12 rdpr: rdcleanwin ( rd -- )
384d# 13 rdpr: rdotherwin ( rd -- )
385d# 14 rdpr: rdwstate ( rd -- )
386[ifndef] SUN4V
387d# 31 rdpr: rdver ( rd -- )
388[then]
389
390: ,%icc ( -- )
391 tcc? if h# 1800 else h# 30.0000 then
392 clearbits
393;
394: ,%xcc ( -- )
395 ,%icc tcc? if h# 1000 else h# 20.0000 then
396 addbits
397;
398
399: trapif ( src cond -- )
400 h# 3a set-op2 addbits
401 dup isimmed? if h# 7f land then
402 src
40364\ ,%xcc
404;
405
406: iflush ( src -- ) 3b set-op2 src ;
407: stbar ( -- ) %o7 %g0 rdasr ;
408\ This really should be a sethi instruction, because the %g0 can generate
409\ a pipeline dependency interlock resulting in a wasted cycle.
410\ : nop %g0 %g0 %g0 add ;
411
412\ Floating-point operations
413
414headerless
415: set-opf ( apf -- ) 34 set-op2 w@ 5 << addbits ;
416: ffop \ name ( opcode -- )
417 createw, does> set-opf ( frs frd ) ?freg rd ?freg rs2
418;
419headers
420
4210c9 ffop fstod 0cd ffop fstox
4220c6 ffop fdtos 0ce ffop fdtox
4230c7 ffop fxtos 0cb ffop fxtod
424
425001 ffop fmovs 002 ffop fmovd 003 ffop fmovq
426005 ffop fnegs 006 ffop fnegd 007 ffop fnegq
427009 ffop fabss 00a ffop fabsd 00b ffop fabsq
428029 ffop fsqrts 02a ffop fsqrtd 02b ffop fsqrtx
429
4300c4 ffop fitos 0c8 ffop fitod 0cc ffop fitox
431
4320c1 ffop fstoir 0c2 ffop fdtoir 0c3 ffop fxtoir
4330d1 ffop fstoi 0d2 ffop fdtoi 0d3 ffop fxtoi
434
435headerless
436: f2op \ name ( opcode -- )
437 createw,
438 does> set-opf ( frs1 frs2 frd ) ?freg rd ?freg rs2 ?freg rs
439;
440headers
441041 f2op fadds 042 f2op faddd 043 f2op faddx
442045 f2op fsubs 046 f2op fsubd 047 f2op fsubx
443049 f2op fmuls 04a f2op fmuld 04b f2op fmulx
44404d f2op fdivs 04e f2op fdivd 04f f2op fdivx
445
446headerless
447: fcmpop \ name ( opcode -- )
448 createw, does> set-opf ( frs1 frs2 )
449 1 d# 19 << addbits ( frs1 frs2 apf )
450 ?freg rs2 ?freg rs
451;
452headers
453051 fcmpop fcmps 052 fcmpop fcmpd 053 fcmpop fcmpx
454055 fcmpop fcmpes 056 fcmpop fcmped 057 fcmpop fcmpex
455
456headerless
457hex
458: cond ( bits -- ) createw, does> w@ d# 25 << ;
459
460headers
461\ Condition names. There are more of these near the end of the file.
462
4638 cond always 0 cond never c cond hi 4 cond ls
464d cond cc 5 cond cs 9 cond ne 1 cond eq
465f cond vc 7 cond vs e cond pl 6 cond mi
466b cond ge 3 cond lt a cond gt 2 cond le
467
468headerless
469: -cond ( condition -- not-condition )
470 h# 1000.0000 [ also forth ] xor [ previous ]
471;
472
473: op0 ( op -- ) d# 22 << setbits ;
474headers
475: unimp ( -- ) 0 op0 ;
476: sethi ( value rd -- ) 4 op0 rd n->l d# 10 >> addbits ;
477: nop ( -- ) 0 %g0 sethi ;
478headerless
479: fits-immediate-field? ( value -- flag )
480 h# ffff.f000 l->n h# 0000.0fff between
481;
482headers
483: setuw ( value rd -- )
484 over n->l fits-immediate-field? if
485 \ The value is small enough to omit the sethi instruction
486\ h# 1fff land %g0 swap add
487 %g0 rot h# 1fff land rot or
488 else
489 \ We have to use sethi for the high-order bits
490 2dup sethi ( value rd )
491 swap h# 0000.03ff land tuck ( masked-value rd masked-value )
492 if tuck or \ Merge in the low bits
493 else 2drop \ No need to merge in low-order zeroes
494 then
495 then
496;
497alias set setuw
498
499: setsw ( value rd -- )
500 2dup set ( value rd )
501 swap 0< if ( rd )
502 %g0 over sra ( )
503 else ( rd )
504 drop
505 then
506;
507: setx ( value reg rd -- )
508 rot dup fits-immediate-field? if ( reg rd value )
509 %g0 swap rot or drop exit ( )
510 then ( reg rd value )
511 dup d# 32 >> ?dup if ( reg rd value value-hi )
512 2over drop tuck setuw ( reg rd value reg )
513 over n->l if ( reg rd value reg )
514 d# 32 over sllx ( reg rd value )
515 else ( reg rd value reg )
516 2over d# 32 swap sllx drop ( reg rd value reg )
517 then ( reg rd value )
518 n->l tuck if ( reg val-lo rd )
519 tuck setuw ( reg rd )
520 tuck or ( )
521 else ( reg value rd )
522 3drop ( )
523 then ( )
524 else ( reg rd value )
525 swap setuw drop ( )
526 then ( )
527;
528
529: ret ( -- ) %i7 8 %g0 jmpl ;
530: retl ( -- ) %o7 8 %g0 jmpl ;
531
532: ,a ( -- ) h# 2000.0000 addbits ;
533: ,pt ( -- ) h# 0008.0000 addbits ;
534: ,pn ( -- ) h# 0008.0000 clearbits ;
535alias annul ,a
536
537headerless
538: offset-22 ( target-adr branch-adr -- masked-displacement )
539 - 2 >>a
540 dup h# -001f.ffff h# 001f.ffff between
541 0= abort" displacement out of 22-bit range"
542 h# 3f.ffff land
543;
544\ All longword displacements are guaranteed to be in a 30 bit range
545: offset-30 ( destination-adr branch-adr -- masked-displacement )
546 - 2 >>a
547 h# 3fff.ffff land
548;
549: branch: \ name ( op -- )
550 createw,
551 does> w@ ( adr condition type ) op0 addbits opaddr offset-22 addbits
552;
553
554: offset-16 ( target-adr branch-adr -- disp16lo disp16hi )
555 - 2 >>a
556 dup h# -0000.7fff h# 0000.7fff between
557 0= abort" displacement out of 16-bit range"
558 h# 0.ffff land
559 dup h# 0.3fff land swap
560 d# 13 >> d# 20 << lor
561;
562
563: offset-19 ( target-adr branch-adr -- masked-displacement )
564 - 2 >>a
565 dup h# -0007.ffff h# 0007.ffff between
566 0= abort" displacement out of 19-bit range"
567 h# 07.ffff land
568;
569: %icc? ( reg -- flag ) %icc = ;
570: %xcc? ( reg -- flag ) %xcc = ;
571: bpcc: \ name ( op -- )
572 createw,
573 does> w@ ( [ icc | xcc ] adr cond type )
574 op0 ( [ icc | xcc ] adr cond )
575 addbits ( [ icc | xcc ] adr )
576 opaddr offset-19 addbits ( [ icc | xcc ] )
577 dup %icc? if
578 drop ,%icc
579 else
580 dup %xcc? if
581 drop ,%xcc
582 else
583 ??cr ." Bad CC register " .x cr
584 then
585 then
586 ,pt
587;
588: bpr: \ name ( rcond -- )
589 createw,
590 does> w@ ( rs1 adr condition )
591 3 op0 ( rs1 adr condition )
592 d# 25 << addbits ( rs1 adr )
593 opaddr ( rs1 target-adr branch-adr )
594 offset-16 addbits rs ,pt
595;
596
597: offset-19/22 ( target-adr branch-adr -- displacement )
598 dup asm@ d# 22 >> 7 land 1 = if offset-19 else offset-22 then
599;
600headers
6012 branch: brif ( adr condition -- ) \ Integer Cond. Codes
6026 branch: brfif ( adr condition -- ) \ Floating Point Cond. Codes
6037 branch: brcif ( adr condition -- ) \ Coprocessor Cond. Codes
604
605: branch! ( target-adr branch-adr -- )
606 tuck offset-22 3080.0000 + swap asm!
607;
608
6091 bpcc: bprif ( [ icc | xcc ] adr cond -- ) \ Prediction reg. Integer CC
6105 bpcc: bprfif ( [ icc | xcc ] adr cond -- ) \ Prediction reg. Floating CC
611: bpra ( [ icc | xcc ] adr -- ) always bprif ;
612
613: bra ( adr -- ) always brif ;
614
6151 bpr: brz 2 bpr: brlez 3 bpr: brlz
6165 bpr: brnz 6 bpr: brgz 7 bpr: brgez
617
618: call ( adr -- ) h# 4000.0000 setbits opaddr offset-30 addbits ;
619
620: but ( mark1 mark2 -- mark2 mark1 ) swap ;
621
62264\ : brif ( adr condition -- ) %xcc -rot bprif ;
623
624headerless
625: <mark ( -- <mark ) here ;
626: >mark ( -- >mark ) here ;
627: >resolve ( >mark -- )
628 here over ( >mark here >mark )
629 offset-19/22 ( >mark displacement )
630 over asm@ + ( >mark opcode )
631 swap asm! ( )
632;
633
634\ >+resolve is used when the resolution follows a branch,
635\ so the delay slot must be skipped
636: >+resolve ( >mark -- )
637 here la1+ over ( >mark here+4 >mark )
638 offset-19/22 ( >mark displacement )
639 over asm@ + ( >mark opcode )
640 swap asm! ( )
641;
642: <resolve ( -- ) ;
643headers
644
645\ Define these last to delay overloading of the forth versions
646
647hex
6481 cond = 1 cond 0=
6492 cond <= 2 cond 0<=
6503 cond <
6514 cond u<=
6525 cond u<
653 6 cond 0<
6549 cond <> 9 cond 0<>
655a cond > a cond 0>
656b cond >=
657c cond u>
658d cond u>=
659 e cond 0>=
660
661
662: if ( cond -- >mark ) >mark here rot -cond brif ;
663: ahead ( -- >mark ) never if ;
664: then ( >mark -- ) >resolve ;
665: else ( >mark -- >mark1 ) ahead but >+resolve ;
666: begin ( -- <mark ) <mark ;
667: while ( <mark cond -- <mark >mark ) if but ;
668: until ( <mark cond -- ) -cond brif ;
669: again ( <mark -- ) bra ;
670: repeat ( <mark >mark -- ) again >+resolve ;
671
672previous definitions