Annotation of gforth/arch/alpha/asm.fs, revision 1.11
1.6 anton 1: \ assembler in forth for alpha
2:
1.11 ! anton 3: \ Copyright (C) 1999,2000,2007 Free Software Foundation, Inc.
1.6 anton 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.10 anton 9: \ as published by the Free Software Foundation, either version 3
1.6 anton 10: \ of the License, or (at your option) any later version.
1.2 anton 11:
1.6 anton 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.10 anton 18: \ along with this program. If not, see http://www.gnu.org/licenses/.
1.6 anton 19:
20: \ contributed by Bernd Thallner
1.1 anton 21:
1.8 anton 22: require ./../../code.fs
1.1 anton 23:
1.4 anton 24: get-current
25: also assembler definitions
1.2 anton 26:
27: \ register
1.1 anton 28:
29: $0 constant v0
30: $1 constant t0
31: $2 constant t1
32: $3 constant t2
33: $4 constant t3
34: $5 constant t4
35: $6 constant t5
36: $7 constant t6
37: $8 constant t7
38: $9 constant s0
39: $a constant s1
40: $b constant s2
41: $c constant s3
42: $d constant s4
43: $e constant s5
44: $f constant fp
1.4 anton 45: \ commented out to avoid shadowing hex numbers
46: \ $10 constant a0
47: \ $11 constant a1
48: \ $12 constant a2
49: \ $13 constant a3
50: \ $14 constant a4
51: \ $15 constant a5
1.1 anton 52: $16 constant t8
53: $17 constant t9
54: $18 constant t10
55: $19 constant t11
56: $1a constant ra
57: $1b constant t12
58: $1c constant at
59: $1d constant gp
60: $1e constant sp
61: $1f constant zero
62:
1.2 anton 63: \ util
64:
65: : h@ ( addr -- n ) \ 32 bit fetch
66: dup dup aligned = if
67: @
68: $00000000ffffffff and
69: else
70: 4 - @
1.3 anton 71: $20 rshift
1.2 anton 72: endif
73: ;
74:
75: : h! ( n addr -- ) \ 32 bit store
76: dup dup aligned = if
77: dup @
78: $ffffffff00000000 and
79: rot or
80: swap !
81: else
82: 4 - dup @
83: $00000000ffffffff and
1.3 anton 84: rot $20 lshift or
1.2 anton 85: swap !
86: endif
87: ;
88:
89: : h, ( h -- ) \ 32 bit store + allot
1.1 anton 90: here here aligned = if
91: here !
92: else
1.3 anton 93: 32 lshift
1.1 anton 94: here 4 - dup
95: @ rot or
96: swap !
97: endif
98: 4 allot
99: ;
100:
1.5 anton 101: \ operands
1.2 anton 102:
1.5 anton 103: : check-range ( u1 u2 u3 -- )
104: within 0= -24 and throw ;
1.1 anton 105:
1.5 anton 106: : rega ( rega code -- code )
107: \ ra field, named rega to avoid conflict with register ra
108: swap dup 0 $20 check-range
109: 21 lshift or ;
110:
111: : rb ( rb code -- code )
112: swap dup 0 $20 check-range
113: 16 lshift or ;
114:
115: : rc ( rc code -- code )
116: swap dup 0 $20 check-range
117: or ;
118:
119: : hint ( addr code -- code )
120: swap 2 rshift $3fff and or ;
121:
122: : disp ( n code -- code )
123: swap dup -$8000 $8000 check-range
124: $ffff and or ;
125:
1.6 anton 126: : branch-rel ( n code -- code )
127: swap dup 3 and 0<> -24 and throw
128: 2/ 2/
1.5 anton 129: dup -$100000 $100000 check-range
130: $1fffff and or ;
131:
1.6 anton 132: : branch-disp ( addr code -- code )
133: swap here 4 + - swap branch-rel ;
134:
1.5 anton 135: : imm ( u code -- code )
136: swap dup 0 $100 check-range
137: 13 lshift or ;
138:
139: : palcode ( u code -- code )
140: swap dup 0 $4000000 check-range or ;
141:
142: \ formats
143:
144: : Bra ( opcode -- ) \ branch instruction format
145: create 26 lshift ,
146: does> ( rega target-addr -- )
147: @ branch-disp rega h, ;
148:
149: : Mbr ( opcode hint -- ) \ memory branch instruction format
150: create 14 lshift swap 26 lshift or ,
151: does> ( rega rb hint -- )
152: @ hint rb rega h, ;
153:
154: : F-P ( opcode func -- ) \ floating-point operate instruction format
155: create 5 lshift swap 26 lshift or ,
156: does> ( fa fb fc -- )
157: @ rc rb rega h, ;
158:
159: : Mem ( opcode -- ) \ memory instruction format
160: create 26 lshift ,
161: does> ( rega memory_disp rb -- )
162: @ rb disp rega h, ;
163:
164: : Mfc ( opcode func -- ) \ memory instruction with function code format
165: create swap 26 lshift or ,
166: does> ( rega rb -- )
167: @ rb rega h, ;
168:
169: : Opr ( opcode.ff ) \ operate instruction format
170: create 5 lshift swap 26 lshift or ,
171: does> ( rega rb rc -- )
172: @ rc rb rega h, ;
173:
174: : Opr# ( opcode func -- ) \ operate instruction format
175: create 5 lshift swap 26 lshift or 1 12 lshift or ,
176: does> ( rega imm rc -- )
177: @ rc imm rega h, ;
178:
179: : Pcd ( opcode -- ) \ palcode instruction format
180: create 26 lshift ,
181: does> ( palcode addr -- )
182: @ palcode h, ;
1.1 anton 183:
1.2 anton 184: \ instructions
185:
1.1 anton 186: $15 $80 F-P addf,
187: $15 $a0 F-P addg,
188: $10 $00 Opr addl,
189: $10 $00 Opr# addl#,
190: $10 $40 Opr addlv,
191: $10 $40 Opr# addlv#,
192: $10 $20 Opr addq,
193: $10 $20 Opr# addq#,
194: $10 $60 Opr addqv,
195: $10 $60 Opr# addqv#,
196: $16 $80 F-P adds,
197: $16 $a0 F-P addt,
198: $11 $00 Opr and,
199: $11 $00 Opr# and#,
200: $39 Bra beq,
201: $3e Bra bge,
202: $3f Bra bgt,
203: $11 $08 Opr bic,
204: $11 $08 Opr# bic#,
205: $11 $20 Opr bis,
206: $11 $20 Opr# bis#,
207: $38 Bra blbc,
208: $3c Bra blbs,
209: $3b Bra ble,
210: $3a Bra blt,
1.5 anton 211: $3d Bra bne,
1.1 anton 212: $30 Bra br,
213: $34 Bra bsr,
214: $00 Pcd call_pal,
215: $11 $24 Opr cmoveq,
216: $11 $24 Opr# cmoveq#,
217: $11 $46 Opr cmovge,
218: $11 $46 Opr# cmovge#,
219: $11 $66 Opr cmovgt,
220: $11 $66 Opr# cmovgt#,
221: $11 $16 Opr cmovlbc,
222: $11 $16 Opr# cmovlbc#,
223: $11 $14 Opr cmovlbs,
224: $11 $14 Opr# cmovlbs#,
225: $11 $64 Opr cmovle,
226: $11 $64 Opr# cmovle#,
227: $11 $44 Opr cmovlt,
228: $11 $44 Opr# cmovlt#,
229: $11 $26 Opr cmovne,
230: $11 $26 Opr# cmovne#,
231: $10 $0f Opr cmpbge,
232: $10 $0f Opr# cmpbge#,
233: $10 $2d Opr cmpeq,
234: $10 $2d Opr# cmpeq#,
235: $15 $a5 F-P cmpgeq,
236: $15 $a7 F-P cmpgle,
237: $15 $a6 F-P cmpglt,
238: $10 $6d Opr cmple,
239: $10 $6d Opr# cmple#,
240: $10 $4d Opr cmplt,
241: $10 $4d Opr# cmplt#,
242: $16 $a5 F-P cmpteq,
243: $16 $a7 F-P cmptle,
244: $16 $a6 F-P cmptlt,
245: $16 $a4 F-P cmptun,
246: $10 $3d Opr cmpule,
247: $10 $3d Opr# cmpule#,
248: $10 $1d Opr cmpult,
249: $10 $1d Opr# cmpult#,
250: $17 $20 F-P cpys,
251: $17 $22 F-P cpyse,
252: $17 $21 F-P cpysn,
253: $15 $9e F-P cvtdg,
254: $15 $ad F-P cvtgd,
255: $15 $ac F-P cvtgf,
256: $15 $af F-P cvtgq,
257: $17 $10 F-P cvtlq,
258: $15 $bc F-P cvtqf,
259: $15 $be F-P cvtqg,
260: $17 $30 F-P cvtql,
261: $17 $530 F-P cvtqlsv,
262: $17 $130 F-P cvtqlv,
263: $16 $bc F-P cvtqs,
264: $16 $be F-P cvtqt,
265: $16 $2ac F-P cvtst,
266: $16 $af F-P cvttq,
267: $16 $ac F-P cvtts,
268: $15 $83 F-P divf,
269: $15 $a3 F-P divg,
270: $16 $83 F-P divs,
271: $16 $a3 F-P divt,
272: $11 $48 Opr eqv,
273: $11 $48 Opr# eqv#,
274: $18 $400 Mfc excb,
275: $12 $06 Opr extbl,
276: $12 $06 Opr# extbl#,
277: $12 $6a Opr extlh,
278: $12 $6a Opr# extlh#,
279: $12 $26 Opr extll,
280: $12 $26 Opr# extll#,
281: $12 $7a Opr extqh,
282: $12 $7a Opr# extqh#,
283: $12 $36 Opr extql,
284: $12 $36 Opr# extql#,
285: $12 $5a Opr extwh,
286: $12 $5a Opr# extwh#,
287: $12 $16 Opr extwl,
288: $12 $16 Opr# extwl#,
289: $31 Bra fbeq,
290: $36 Bra fbge,
291: $37 Bra fbgt,
292: $33 Bra fble,
293: $32 Bra fblt,
294: $35 Bra fbne,
295: $17 $2a F-P fcmoveq,
296: $17 $2d F-P fcmovge,
297: $17 $2f F-P fcmovgt,
298: $17 $2e F-P fcmovle,
299: $17 $2c F-P fcmovlt,
300: $17 $2b F-P fcmovne,
301: $18 $8000 Mfc fetch,
302: $18 $a000 Mfc fetch_m,
303: $12 $0b Opr insbl,
304: $12 $0b Opr# insbl#,
305: $12 $67 Opr inslh,
306: $12 $67 Opr# inslh#,
307: $12 $2b Opr insll,
308: $12 $2b Opr# insll#,
309: $12 $77 Opr insqh,
310: $12 $77 Opr# insqh#,
311: $12 $3b Opr insql,
312: $12 $3b Opr# insql#,
313: $12 $57 Opr inswh,
314: $12 $57 Opr# inswh#,
315: $12 $1b Opr inswl,
316: $12 $1b Opr# inswl#,
317: $1a $00 Mbr jmp,
318: $1a $01 Mbr jsr,
319: $1a $03 Mbr jsr_coroutine,
320: $08 Mem lda,
321: $09 Mem ldah,
322: $20 Mem ldf,
323: $21 Mem ldg,
324: $28 Mem ldl,
325: $2a Mem ldl_l,
326: $29 Mem ldq,
327: $2b Mem ldq_l,
328: $0b Mem ldq_u,
329: $22 Mem lds,
330: $23 Mem ldt,
331: $18 $4000 Mfc mb,
332: $17 $25 F-P mf_fpcr,
333: $12 $02 Opr mskbl,
334: $12 $02 Opr# mskbl#,
335: $12 $62 Opr msklh,
336: $12 $62 Opr# msklh#,
337: $12 $22 Opr mskll,
338: $12 $22 Opr# mskll#,
339: $12 $72 Opr mskqh,
340: $12 $72 Opr# mskqh#,
341: $12 $32 Opr mskql,
342: $12 $32 Opr# mskql#,
343: $12 $52 Opr mskwh,
344: $12 $52 Opr# mskwh#,
345: $12 $12 Opr mskwl,
346: $12 $12 Opr# mskwl#,
347: $17 $24 F-P mt_fpcr,
348: $15 $82 F-P mulf,
349: $15 $a2 F-P mulg,
350: $13 $00 Opr mull,
351: $13 $00 Opr# mull#,
352: $13 $40 Opr mullv,
353: $13 $40 Opr# mullv#,
354: $13 $20 Opr mullq,
355: $13 $20 Opr# mullq#,
356: $13 $60 Opr mullqv,
357: $13 $60 Opr# mullqv#,
358: $16 $82 F-P mulls,
359: $16 $a2 F-P mullt,
360: $11 $28 Opr ornot,
361: $11 $28 Opr# ornot#,
362: $18 $e000 Mfc rc,
363: $1a $02 Mbr ret,
364: $18 $c000 Mfc rpcc,
365: $18 $f000 Mfc rs,
366: $10 $02 Opr s4addl,
367: $10 $02 Opr# s4addl#,
368: $10 $22 Opr s4addq,
369: $10 $22 Opr# s4addq#,
370: $10 $0b Opr s4subl,
371: $10 $0b Opr# s4subl#,
372: $10 $2b Opr s4subq,
373: $10 $2b Opr# s4subq#,
374: $10 $12 Opr s8addl,
375: $10 $12 Opr# s8addl#,
376: $10 $32 Opr s8addq,
377: $10 $32 Opr# s8addq#,
378: $10 $1b Opr s8ubl,
379: $10 $1b Opr# s8ubl#,
380: $10 $3b Opr s8ubq,
381: $10 $3b Opr# s8ubq#,
382: $12 $39 Opr sll,
383: $12 $39 Opr# sll#,
384: $12 $3c Opr sra,
385: $12 $3c Opr# sra#,
386: $12 $34 Opr srl,
387: $12 $34 Opr# srl#,
388: $24 Mem stf,
389: $25 Mem stg,
390: $26 Mem sts,
391: $2c Mem stl,
392: $2e Mem stl_c,
393: $2d Mem stq,
394: $2f Mem stq_c,
395: $0f Mem stq_u,
396: $27 Mem stt,
397: $15 $81 F-P subf,
398: $15 $a1 F-P subg,
399: $10 $09 Opr subl,
400: $10 $09 Opr# subl#,
401: $10 $49 Opr sublv,
402: $10 $49 Opr# sublv#,
403: $10 $29 Opr subq,
404: $10 $29 Opr# subq#,
405: $10 $69 Opr subqv,
406: $10 $69 Opr# subqv#,
407: $16 $81 F-P subs,
408: $16 $a1 F-P subt,
409: $18 $00 Mfc trapb,
410: $13 $30 Opr umulh,
411: $13 $30 Opr# umulh#,
412: $18 $4400 Mfc wmb,
413: $11 $40 Opr xor,
414: $11 $40 Opr# xor#,
415: $12 $30 Opr zap,
416: $12 $30 Opr# zap#,
417: $12 $31 Opr zapnot,
418: $12 $31 Opr# zapnot#,
1.2 anton 419:
1.6 anton 420: \ conditions; they are reversed because of the if and until logic (the
421: \ stuff enclosed by if is performed if the branch around has the
422: \ inverse condition).
1.5 anton 423:
424: ' beq, constant ne
425: ' bge, constant lt
426: ' bgt, constant le
427: ' blbc, constant lbs
428: ' blbs, constant lbc
429: ' ble, constant gt
430: ' blt, constant ge
431: ' bne, constant eq
432: ' fbeq, constant fne
433: ' fbge, constant flt
434: ' fbgt, constant fle
435: ' fble, constant fgt
436: ' fblt, constant fge
437: ' fbne, constant feq
438:
439: \ control structures
1.2 anton 440:
1.6 anton 441: : magic-asm ( u1 u2 -- u3 u4 )
442: \ turns a magic number into an asm-magic number or back
443: $fedcba0987654321 xor ;
444:
445: : patch-branch ( behind-branch-addr target-addr -- )
446: \ there is a branch just before behind-branch-addr; PATCH-BRANCH
447: \ patches this branch to branch to target-addr
448: over - ( behind-branch-addr rel )
449: swap 4 - dup >r ( rel branch-addr R:branch-addr )
450: h@ branch-rel r> h! ; \ !! relies on the imm field being 0 before
451:
452: : if, ( reg xt -- asm-orig )
453: \ xt is for a branch word ( reg addr -- )
454: here 4 + swap execute \ put 0 into the disp field
455: here live-orig magic-asm live-orig ;
456:
457: : ahead, ( -- asm-orig )
458: zero ['] br, if, ;
459:
460: : then, ( asm-orig -- )
461: orig? magic-asm orig?
462: here patch-branch ;
463:
464: : begin, ( -- asm-dest )
465: here dest magic-asm dest ;
466:
467: : until, ( asm-dest reg xt -- )
468: \ xt is a condition ( reg addr -- )
469: here 4 + swap execute
470: dest? magic-asm dest?
471: here swap patch-branch ;
472:
473: : again, ( asm-dest -- )
474: zero ['] br, until, ;
475:
476: : while, ( asm-dest -- asm-orig asm-dest )
477: if, 1 cs-roll ;
1.2 anton 478:
1.6 anton 479: : else, ( asm-orig1 -- asm-orig2 )
480: ahead, 1 cs-roll then, ;
1.2 anton 481:
1.6 anton 482: : repeat, ( asm-orig asm-dest -- )
483: again, then, ;
1.2 anton 484:
1.6 anton 485: : endif, ( asm-orig -- )
486: then, ;
1.2 anton 487:
1.4 anton 488: \ \ jump marks
1.3 anton 489:
1.4 anton 490: \ \ example:
1.2 anton 491:
1.4 anton 492: \ \ init_marktbl \ initializes mark table
493: \ \ 31 0 br,
494: \ \ 0 store_branch \ store jump address for mark 0
495: \ \ 1 2 3 addf,
496: \ \ 0 set_mark \ store mark 0
497: \ \ 2 3 4 addf,
498: \ \ 2 0 beq,
499: \ \ 0 store_branch \ store jump address for mark 0
500: \ \ calculate_marks \ calculate all jumps
501:
502: \ \ with <mark_address> <jump_address> calculate_branch you can calculate the
503: \ \ displacement field without the mark_table for one branch
504:
505: \ \ example:
506: \ \ here 31 0 br,
507: \ \ here 1 2 3 addf,
508: \ \ calculate_branch
509:
510: \ 5 constant mark_numbers
511: \ 5 constant mark_uses
512:
513: \ create mark_table
514: \ mark_numbers mark_uses 1+ * cells allot
515:
516: \ : init_marktbl ( -- ) \ initializes mark table
517: \ mark_table mark_numbers mark_uses 1+ * cells +
518: \ mark_table
519: \ begin
520: \ over over >
521: \ while
522: \ dup 0 swap !
523: \ 1 cells +
524: \ repeat
525: \ drop drop
526: \ ;
527:
528: \ : set_mark ( mark_number -- ) \ sets mark, store address in mark table
529: \ dup mark_numbers >= abort" error, illegal mark number"
530: \ mark_uses 1+ * cells
531: \ mark_table + here 8 - swap !
532: \ ;
533:
534: \ : store_branch ( mark_number -- ) \ stores address of branch in mark table
535: \ dup mark_numbers >= abort" error, illegal mark number"
536: \ mark_uses 1+ * cells
537: \ mark_table + 1 cells +
538: \ dup mark_uses cells + swap
539: \ begin
540: \ over over > over @ and
541: \ while
542: \ 1 cells +
543: \ repeat
544: \ swap over = abort" error, not enough space in mark_table, increase mark_uses"
545: \ here 4 - swap !
546: \ ;
547:
548: \ : calculate_branch ( mark_addr branch_addr -- ) \ calculate branch displacement field for one branch
549: \ swap over - 4 + 4 /
550: \ $1fffff and
551: \ over h@ or swap h!
552: \ ;
553:
554: \ : calculate_mark ( tb mark_address -- tb ) \ calculates branch displacement field for one mark
555: \ over 1 cells +
556: \ dup mark_uses cells + swap
557: \ begin
558: \ over over >
559: \ while
560: \ 2over swap drop ( ei i markaddr ej j markaddr )
561: \ over @
562: \ dup if
563: \ calculate_branch
564: \ else
565: \ drop drop
566: \ endif
567: \ 1 cells +
568: \ repeat drop drop drop
569: \ ;
570:
571: \ : calculate_marks ( -- ) \ calculates branch displacement field for all marks
572: \ mark_table mark_numbers 1- mark_uses 1+ * cells +
573: \ mark_table
574: \ begin
575: \ over over >=
576: \ while
577: \ dup @
578: \ dup if \ used mark
579: \ calculate_mark
580: \ else
581: \ drop
582: \ endif
583: \ mark_uses 1+ cells +
584: \ repeat
585: \ drop drop
586: \ ;
587:
588: previous set-current
1.5 anton 589:
1.2 anton 590:
591:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>