Annotation of gforth/arch/mips/asm.fs, revision 1.19
1.1 anton 1: \ asm.fs assembler file (for MIPS R3000)
2: \
1.17 anton 3: \ Copyright (C) 2000 Free Software Foundation, Inc.
4:
5: \ This file is part of Gforth.
6:
7: \ Gforth is free software; you can redistribute it and/or
8: \ modify it under the terms of the GNU General Public License
1.19 ! anton 9: \ as published by the Free Software Foundation, either version 3
1.17 anton 10: \ of the License, or (at your option) any later version.
11:
12: \ This program is distributed in the hope that it will be useful,
13: \ but WITHOUT ANY WARRANTY; without even the implied warranty of
14: \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: \ GNU General Public License for more details.
16:
17: \ You should have received a copy of the GNU General Public License
1.19 ! anton 18: \ along with this program. If not, see http://www.gnu.org/licenses/.
1.1 anton 19:
1.8 anton 20: \ test this with
21: \ gforth arch/mips/asm.fs -e "also assembler here" arch/mips/testasm.fs -e "here over - here" arch/mips/testdisasm.fs -e "here over - compare throw bye"
22:
1.16 anton 23: require ./../../code.fs
1.4 anton 24:
1.7 anton 25: get-current
1.4 anton 26: also assembler definitions
27:
1.1 anton 28: $20 constant asm-registers
29:
1.3 anton 30: \ register names
31: 0 constant $zero
32: 1 constant $at
33: 2 constant $v0
34: 3 constant $v1
35: \ 4 constant $a0 \ commented out to avoid shadowing hex numbers
36: \ 5 constant $a1
37: \ 6 constant $a2
38: \ 7 constant $a3
39: 8 constant $t0
40: 9 constant $t1
41: 10 constant $t2
42: 11 constant $t3
43: 12 constant $t4
44: 13 constant $t5
45: 14 constant $t6
46: 15 constant $t7
47: 16 constant $s0
48: 17 constant $s1
49: 18 constant $s2
50: 19 constant $s3
51: 20 constant $s4
52: 21 constant $s5
53: 22 constant $s6
54: 23 constant $s7
55: 24 constant $t8
56: 25 constant $t9
57: 26 constant $k0
58: 27 constant $k1
59: 28 constant $gp
60: 29 constant $sp
61: 30 constant $s8
62: 31 constant $ra
1.1 anton 63:
64: $00 constant asm-init-code
65:
1.3 anton 66: $1F constant asm-bm05
67: $3F constant asm-bm06
68: $FFFF constant asm-bm10
69: $3FFFFFF constant asm-bm1A
1.1 anton 70:
71: : asm-op ( n -- code )
72: asm-bm06 and $1a lshift ;
73:
1.8 anton 74: : check-range ( u1 u2 u3 -- )
75: within 0= -24 and throw ;
76:
77: : asm-rs ( u code -- code )
78: over 0 $20 check-range
79: swap $15 lshift or ;
1.1 anton 80:
81: : asm-rt ( n code -- code )
1.8 anton 82: over 0 $20 check-range
83: swap $10 lshift or ;
1.1 anton 84:
85: : asm-imm ( n code -- code )
1.8 anton 86: over -$8000 $8000 check-range
87: swap $ffff and or ;
1.1 anton 88: ' asm-imm alias asm-offset
89:
1.8 anton 90: : asm-uimm ( u code -- code )
91: over 0 $10000 check-range
92: or ;
93:
94: : asm-rel ( n code -- code )
95: over 3 and 0<> -24 and throw \ check lower 2 bits
96: swap 2/ 2/ swap asm-imm ;
97:
1.1 anton 98: : asm-target ( n code -- code )
1.8 anton 99: over here cell+ xor $f0000003 and 0<> -24 and throw
1.1 anton 100: swap 2 rshift asm-bm1A and or ;
101:
102: : asm-rd ( n code -- code )
1.8 anton 103: over 0 $20 check-range
104: swap $b lshift or ;
1.1 anton 105:
106: : asm-shamt ( n code -- code )
1.8 anton 107: over 0 $20 check-range
108: swap $6 lshift or ;
1.1 anton 109: ' asm-shamt alias asm-sa
110:
111: : asm-funct ( n code -- code )
112: swap asm-bm06 and or ;
113:
1.3 anton 114: : asm-special ( code1 -- code2 )
115: asm-init-code asm-funct ;
116:
1.1 anton 117: \ ***** I-types
1.3 anton 118: : asm-I-rt,imm ( code -- )
119: create ,
120: does> ( rt imm -- )
121: @ asm-imm asm-rt , ;
122:
1.7 anton 123: : asm-I-rt,uimm ( code -- )
124: create ,
125: does> ( rt uimm -- )
126: @ asm-uimm asm-rt , ;
127:
1.3 anton 128: : asm-I-rs,imm ( code -- )
129: create ,
130: does> ( rs imm -- )
1.8 anton 131: @ asm-rel asm-rs , ;
1.3 anton 132:
133: : asm-I-rt,rs,imm ( code -- )
134: create ,
135: does> ( rt rs imm -- )
136: @ asm-imm asm-rs asm-rt , ;
137:
1.7 anton 138: : asm-I-rt,rs,uimm ( code -- )
139: create ,
140: does> ( rt rs uimm -- )
141: @ asm-uimm asm-rs asm-rt , ;
142:
1.3 anton 143: : asm-I-rs,rt,imm ( code -- )
144: create ,
145: does> ( rs rt imm -- )
1.8 anton 146: @ asm-rel asm-rt asm-rs , ;
1.3 anton 147:
148: : asm-I-rt,offset,rs ( code -- )
149: create ,
150: does> ( rt offset rs -- )
151: @ asm-rs asm-offset asm-rt , ;
1.1 anton 152:
153: \ ***** regimm types
154: : asm-regimm-rs,imm ( funct -- )
155: $01 asm-op asm-rt asm-I-rs,imm ;
156:
157: \ ***** copz types 1
158:
1.3 anton 159: : asm-I-imm,z ( code -- )
160: create ,
161: does> ( imm z -- )
1.8 anton 162: @ swap asm-op or asm-rel , ;
1.1 anton 163:
164: : asm-copz-imm ( code -- )
165: $10 asm-op or asm-I-imm,z ;
166:
1.3 anton 167: : asm-I-rt,offset,rs,z ( code -- )
168: create ,
169: does> ( rt offset rs z -- )
170: @ swap asm-op or asm-rs asm-offset asm-rt , ;
1.1 anton 171:
172: : asm-copz-rt,offset,rs ( code -- )
173: asm-op asm-I-rt,offset,rs,z ;
174:
1.3 anton 175: : asm-J-target ( code -- )
176: create ,
177: does> ( target -- )
178: @ asm-target , ;
1.1 anton 179:
180: \ ***** special types
1.3 anton 181: : asm-special-nothing ( code -- )
182: asm-special create ,
183: does> ( addr -- )
184: @ , ;
185:
186: : asm-special-rd ( code -- )
187: asm-special create ,
188: does> ( rd addr -- )
189: @ asm-rd , ;
190:
191: : asm-special-rs ( code -- )
192: asm-special create ,
193: does> ( rs addr -- )
194: @ asm-rs , ;
195:
196: : asm-special-rd,rs ( code -- )
197: asm-special create ,
198: does> ( rd rs addr -- )
199: @ asm-rs asm-rd , ;
200:
201: : asm-special-rs,rt ( code -- )
202: asm-special create ,
203: does> ( rs rt addr -- )
204: @ asm-rt asm-rs , ;
205:
206: : asm-special-rd,rs,rt ( code -- )
207: asm-special create ,
208: does> ( rd rs rt addr -- )
209: @ asm-rt asm-rs asm-rd , ;
210:
211: : asm-special-rd,rt,rs ( code -- )
212: asm-special create ,
213: does> ( rd rt rs addr -- )
214: @ asm-rs asm-rt asm-rd , ;
215:
216: : asm-special-rd,rt,sa ( code -- )
217: asm-special create ,
218: does> ( rd rt sa addr -- )
219: @ asm-sa asm-rt asm-rd , ;
1.1 anton 220:
221: \ ***** copz types 2
222: : asm-copz0 ( funct -- )
1.3 anton 223: $10 $10 asm-op asm-rs asm-funct create ,
224: does> ( addr -- )
225: @ , ;
1.1 anton 226:
227: : asm-copz-rt,rd ( funct -- )
1.3 anton 228: $10 asm-op or create ,
229: does> ( rt rd z addr -- )
230: @ swap asm-op or asm-rd asm-rt , ;
1.1 anton 231:
232: : nop, ( -- )
1.3 anton 233: 0 , ;
1.1 anton 234:
1.5 anton 235: include ./insts.fs
1.1 anton 236:
237: : move, ( rd rs -- )
1.3 anton 238: $zero addu, ;
1.1 anton 239:
1.9 anton 240: \ commented out to reduce delay slot exceptions
241: \ : abs, ( rd rs -- )
242: \ dup $0008 bgez,
243: \ 2dup move,
244: \ $zero swap subu, ;
1.1 anton 245:
246: : neg, ( rd rs -- )
1.3 anton 247: $zero swap subu, ;
1.1 anton 248:
249: : negu, ( rd rs -- )
1.3 anton 250: $zero swap subu, ;
1.1 anton 251:
252: : not, ( rd rs -- )
1.3 anton 253: $zero nor, ;
1.1 anton 254:
255: : li, ( rd imm -- )
256: dup 0= if
1.3 anton 257: drop dup $zero = if
1.1 anton 258: drop nop, assert( false )
259: else
1.3 anton 260: $zero move,
1.1 anton 261: endif
262: else
263: dup $8000 u< if
1.3 anton 264: $zero swap addiu,
1.1 anton 265: else
266: dup $10000 u< if
1.3 anton 267: $zero swap ori,
1.1 anton 268: else
269: dup $ffff and 0= if
270: $10 rshift lui,
271: else
272: dup $ffff8000 and $ffff8000 = if
1.3 anton 273: $zero swap addiu,
1.1 anton 274: else
275: 2dup $10 rshift lui,
276: over swap ori,
277: endif
278: endif
279: endif
280: endif
281: endif ;
282:
283: : blt, ( rs rt imm -- ) \ <
1.3 anton 284: >r $at rot rot slt,
285: $at $zero r> bne, ;
1.1 anton 286:
287: : ble, ( rs rt imm -- ) \ <=
1.3 anton 288: >r $at rot rot swap slt,
289: $at $zero r> beq, ;
1.1 anton 290:
291: : bgt, ( rs rt imm -- ) \ >
1.3 anton 292: >r $at rot rot swap slt,
293: $at $zero r> bne, ;
1.1 anton 294:
295: : bge, ( rs rt imm -- ) \ >=
1.3 anton 296: >r $at rot rot slt,
297: $at $zero r> beq, ;
1.1 anton 298:
299: : bltu, ( rs rt imm -- ) \ < unsigned
1.3 anton 300: >r $at rot rot sltu,
301: $at $zero r> bne, ;
1.1 anton 302:
303: : bleu, ( rs rt imm -- ) \ <= unsigned
1.3 anton 304: >r $at rot rot swap sltu,
305: $at $zero r> beq, ;
1.1 anton 306:
307: : bgtu, ( rs rt imm -- ) \ > unsigned
1.3 anton 308: >r $at rot rot swap sltu,
309: $at $zero r> bne, ;
1.1 anton 310:
311: : bgeu, ( rs rt imm -- ) \ >= unsigned
1.3 anton 312: >r $at rot rot sltu,
313: $at $zero r> beq, ;
1.9 anton 314:
315: \ control structures
316:
317: \ conditions; they are reversed because of the if and until logic (the
318: \ stuff enclosed by if is performed if the branch around has the
1.10 anton 319: \ inverse condition, cf. 0branch).
1.9 anton 320:
321: ' beq, constant ne
322: ' bne, constant eq
323: ' blez, constant gtz
324: ' bgtz, constant lez
325: ' bltz, constant gez
326: ' bgez, constant ltz
1.13 anton 327: \ bczf, bczt, \ these don't take the relative address as last argument
1.9 anton 328: ' blt, constant ge
329: ' ble, constant gt
330: ' bgt, constant le
331: ' bge, constant lt
332: ' bltu, constant geu
333: ' bleu, constant gtu
334: ' bgtu, constant leu
335: ' bgeu, constant ltu
336:
1.10 anton 337: \ an asm-cs-item consists of ( addr magic1 magic2 ). addr is the
338: \ address behind the branch or the destination. magic2 is LIVE-ORIG or
339: \ DEST xored with asm-magic to make it harder to confuse with a
340: \ register number or immediate value. magic1 is LIVE-orig or DEST.
341: \ It's there to make CS-ROLL etc. work.
1.9 anton 342:
1.10 anton 343: : magic-asm ( u1 u2 -- u3 u4 )
1.9 anton 344: \ turns a magic number into an asm-magic number or back
345: $87654321 xor ;
346:
1.10 anton 347: : patch-branch ( branch-delay-addr target-addr -- )
348: \ there is a branch just before branch-delay-addr; PATCH-BRANCH
349: \ patches this branch to branch to target-addr
350: over - ( branch-delay-addr rel )
351: swap cell - dup >r ( rel branch-addr R:branch-addr )
352: @ asm-rel r> ! ; \ !! relies on the imm field being 0 before
353:
1.9 anton 354: : if, ( ... xt -- asm-orig )
355: \ xt is for a branch word ( ... addr -- )
356: 0 swap execute
1.10 anton 357: here live-orig magic-asm live-orig ;
1.9 anton 358:
359: : ahead, ( -- asm-orig )
360: $zero $zero ne if, ;
361:
362: : then, ( asm-orig -- )
1.10 anton 363: orig? magic-asm orig?
364: here patch-branch ;
365:
366: : begin, ( -- asm-dest )
367: here dest magic-asm dest ;
368:
369: : until, ( asm-dest ... xt -- )
370: \ xt is a condition and ... are its arguments
371: 0 swap execute
372: dest? magic-asm dest?
373: here swap patch-branch ;
374:
375: : again, ( asm-dest -- )
376: $zero $zero ne until, ;
377:
378: : while, ( asm-dest -- asm-orig asm-dest )
379: if, 1 cs-roll ;
380:
1.11 anton 381: : delayed-then, ( asm-orig -- )
382: \ set the target of asm-orig to one instruction after the current one
383: 0 , then, -1 cells allot ;
384:
385: : else, ( asm-orig1 -- asm-orig2 )
386: ahead, 1 cs-roll delayed-then, ;
387:
1.10 anton 388: : repeat, ( asm-orig asm-dest -- )
1.11 anton 389: again, delayed-then, ;
1.1 anton 390:
1.12 anton 391: : endif, ( asm-orig -- )
392: then, ;
393:
1.4 anton 394: previous
1.10 anton 395: set-current
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>