Blob


1 // s5 - data stack pointer
2 // s6 - return stack pointer
3 // s7 - program counter
5 #define DSP s5
6 #define RSP s6
7 #define PC s7
9 .set F_HIDDEN, 0x80
10 .set F_IMMED, 0x40
11 .set F_LENMASK, 0x1f
12 .set WORDLEN, 32
13 .set name_0, 0
15 .macro def name, namelen, label, prev, flags=0
16 .section .rodata
17 .align 8
18 .global name_\label
19 .type name_\label, @object
20 name_\label :
21 .quad name_\prev
22 .byte \flags + \namelen
23 .ascii "\name"
24 .skip (8 - ((\namelen + 1) & 7)) & 7
25 .global \label
26 .type \label, @object
27 \label:
28 .endm
30 .macro defword name, namelen, label, prev, flags=0
31 def "\name", \namelen, \label, \prev, \flags
32 .quad DOCOL
33 .endm
35 .macro defcode name, namelen, label, prev, flags=0
36 def "\name", \namelen, \label, \prev, \flags
37 .quad code_\label
38 .section .text
39 .align 4
40 .global code_\label
41 code_\label:
42 .endm
44 .macro defvar name, namelen, label, prev, initial=0, flags=0
45 defcode \name, \namelen, \label, \prev, \flags
46 la t0, var_\name
47 PUSH t0
48 NEXT
50 .section .data
51 var_\name:
52 .quad \initial
53 .endm
55 .macro defconst name, namelen, label, prev, value, flags=0
56 defcode \name, \namelen, \label, \prev, \flags
57 la t0, \value
58 PUSH t0
59 NEXT
60 .endm
62 .macro NEXT
63 ld t0, 0(PC)
64 addi PC, PC, 8
65 ld t1, 0(t0)
66 jr t1
67 .endm
69 .macro PUSH, reg
70 addi DSP, DSP, -8
71 sd \reg, 0(DSP)
72 .endm
74 .macro POP, reg
75 ld \reg, 0(DSP)
76 addi DSP, DSP, 8
77 .endm
79 .macro PUSHRSP, reg
80 addi RSP, RSP, -8
81 sd \reg, 0(RSP)
82 .endm
84 .macro POPRSP, reg
85 ld \reg, 0(RSP)
86 addi RSP, RSP, 8
87 .endm
89 .macro GOTO, label
90 .quad BRANCH
91 .quad (\label - .)
92 .endm
94 .macro GOTOZ, label
95 .quad ZBRANCH
96 .quad (\label - .)
97 .endm
99 .macro GOTONZ, label
100 .quad EQZ
101 .quad ZBRANCH
102 .quad (\label - .)
103 .endm
105 .section .text
106 .global DOCOL
107 .type DOCOL, @function
108 DOCOL:
109 PUSHRSP PC
110 add t0, t0, 8
111 mv PC, t0
112 NEXT
114 .global main
115 .type main, @function
116 main:
117 addi sp, sp, -64
118 sd ra, 0(sp)
119 sd DSP, 8(sp)
120 sd RSP, 16(sp)
121 sd PC, 24(sp)
122 sd s0, 32(sp)
123 sd s1, 40(sp)
124 sd s2, 48(sp)
125 sd s3, 56(sp)
127 la DSP, data_stack
128 la RSP, return_stack
129 la PC, cold_start
130 la t0, var_S0
131 sd DSP, 0(t0)
132 NEXT
133 .size main, . - main
135 return:
136 mv a0, zero
137 ld s3, 56(sp)
138 ld s2, 48(sp)
139 ld s1, 40(sp)
140 ld s0, 32(sp)
141 ld PC, 24(sp)
142 ld RSP, 16(sp)
143 ld DSP, 8(sp)
144 ld ra, 0(sp)
145 addi sp, sp, 64
146 jr ra
147 .size return, . - return
149 .section .rodata
150 .align 8
151 cold_start:
152 .quad QUIT
154 .section .text
156 // return:
157 // a0 - word
158 // a1 - wordlen
159 _WORD:
160 addi sp, sp, -32
161 sd ra, 0(sp)
162 sd s0, 8(sp)
163 sd s1, 16(sp)
165 la s0, wordbuf
166 mv s1, zero
168 1:
169 jal _KEY
170 li t0, ' '
171 beq a0, t0, 1b
172 li t0, '\n'
173 beq a0, t0, 1b
174 li t0, '\r'
175 beq a0, t0, 1b
176 li t0, '\b'
177 beq a0, t0, 1b
178 j 3f
180 2:
181 li t0, ' '
182 beq a0, t0, nl
183 li t0, '\n'
184 beq a0, t0, nl
185 li t0, '\b'
186 beq a0, t0, bs
187 li t0, '\r'
188 beq a0, t0, 1f
189 3:
190 li t0, -1
191 beq a0, t0, nl
193 add t0, s0, s1
194 sb a0, 0(t0)
195 addi s1, s1, 1
197 1:
198 jal _KEY
199 j 2b
201 nl:
202 add t0, s0, s1
203 sb zero, 0(t0)
205 la t0, wordlen
206 sd s1, 0(t0)
207 mv a0, s0
208 mv a1, s1
210 ld s1, 16(sp)
211 ld s0, 8(sp)
212 ld ra, 0(sp)
213 addi sp, sp, 32
214 jr ra
216 bs:
217 beq s1, zero, _WORD
218 jal _EMIT
219 li a0, ' '
220 jal _EMIT
221 li a0, '\b'
222 jal _EMIT
223 addi s1, s1, -1
224 j 1b
225 .size _WORD, . - _WORD
227 _EMIT:
228 j putchar
229 .size _EMIT, . - _EMIT
231 _KEY:
232 j getchar
233 .size _KEY, . - _KEY
235 defcode "DONE", 4, DONE, 0
236 POP a0
237 jal exit
239 defcode "EXIT", 4, EXIT, DONE
240 POPRSP PC
241 NEXT
243 defcode "DROP", 4, DROP, EXIT
244 addi DSP, DSP, 8
245 NEXT
247 defword "2DROP", 5, TDROP, DROP
248 .quad DROP
249 .quad DROP
250 .quad EXIT
252 defcode "SWAP", 4, SWAP, TDROP
253 ld t0, 0(DSP)
254 ld t1, 8(DSP)
255 sd t0, 8(DSP)
256 sd t1, 0(DSP)
257 NEXT
259 defcode "OVER", 4, OVER, SWAP
260 ld t0, 8(DSP)
261 PUSH t0
262 NEXT
264 // ( X Y Z -- Z X Y )
265 defcode "ROT", 3, ROT, OVER
266 ld t0, 0(DSP)
267 ld t1, 8(DSP)
268 ld t2, 16(DSP)
269 sd t1, 16(DSP)
270 sd t0, 8(DSP)
271 sd t2, 0(DSP)
272 NEXT
274 // ( X Y Z -- Y Z X )
275 // ( Z X Y ) -- ( X Y Z )
276 defcode "-ROT", 4, NROT, ROT
277 ld t0, 0(DSP)
278 ld t1, 8(DSP)
279 ld t2, 16(DSP)
280 sd t0, 16(DSP)
281 sd t2, 8(DSP)
282 sd t1, 0(DSP)
283 NEXT
285 defcode "DUP", 3, DUP, NROT
286 ld t0, 0(DSP)
287 PUSH t0
288 NEXT
290 defcode "2DUP", 3, TDUP, DUP
291 ld t0, 8(DSP)
292 ld t1, 0(DSP)
293 PUSH t0
294 PUSH t1
295 NEXT
297 defcode "?DUP", 4, QDUP, TDUP
298 ld t0, 0(DSP)
299 beq t0, zero, 1f
300 PUSH t0
301 1:
302 NEXT
304 defword "1+", 2, INC, QDUP
305 .quad LIT, 1
306 .quad ADD
307 .quad EXIT
309 defword "1-", 2, DEC, INC
310 .quad LIT, 1
311 .quad SUB
312 .quad EXIT
314 defcode "+", 1, ADD, DEC
315 POP t1
316 POP t0
317 add t0, t0, t1
318 PUSH t0
319 NEXT
321 defcode "-", 1, SUB, ADD
322 POP t1
323 POP t0
324 sub t0, t0, t1
325 PUSH t0
326 NEXT
328 defcode "*", 1, MUL, SUB
329 POP t1
330 POP t0
331 mul t0, t0, t1
332 PUSH t0
333 NEXT
335 defcode "AND", 3, AND, MUL
336 POP t1
337 POP t0
338 and t0, t0, t1
339 PUSH t0
340 NEXT
342 defcode "OR", 2, OR, AND
343 POP t1
344 POP t0
345 or t0, t0, t1
346 PUSH t0
347 NEXT
349 defcode "XOR", 3, XOR, OR
350 POP t1
351 POP t0
352 xor t0, t0, t1
353 PUSH t0
354 NEXT
356 defcode "RSHIFT", 6, RSHIFT, XOR
357 POP t1
358 POP t0
359 srl t0, t0, t1
360 PUSH t0
361 NEXT
363 defcode "0=", 2, EQZ, RSHIFT
364 POP t0
365 beq t0, zero, 1f
366 PUSH zero
367 NEXT
369 1:
370 li t0, -1
371 PUSH t0
372 NEXT
374 // ( x y -- b )
375 defword "=", 1, EQ, EQZ
376 .quad SUB
377 .quad EQZ
378 .quad EXIT
380 // ( x y -- b )
381 defcode "<", 1, LT, EQ
382 POP t0
383 POP t1
384 sltu t0, t0, t1
385 PUSH t0
386 NEXT
388 defword ">", 1, GT, LT
389 .quad SWAP
390 .quad LT
391 .quad EXIT
393 defcode "KEY", 3, KEY, GT
394 jal _KEY
395 PUSH a0
396 NEXT
398 // ( -- word wordlen )
399 defcode "WORD", 4, WORD, KEY
400 jal _WORD
401 PUSH a1
402 PUSH a0
403 NEXT
405 // ( s1 s2 len -- eql )
406 defword "MEMEQ", 5, MEMEQ, WORD
407 .quad ROT // ( len s1 s2 )
408 .quad DUP // ( len len s1 s2 )
409 GOTOZ 4f // ( len s1 s2 )
411 .quad TOR // ( s1 s2 -- len )
413 1: // ( s1 s2 -- len )
414 .quad DUP // ( s1 s1 s2 -- len )
415 .quad FETCHBYTE // ( c1 s1 s2 -- len )
416 .quad TOR // ( s1 s2 -- c1 len )
417 .quad SWAP // ( s2 s1 -- c1 len )
418 .quad DUP // ( s2 s2 s1 -- c1 len )
419 .quad FETCHBYTE // ( c2 s2 s1 -- c1 len )
420 .quad FROMR // ( c1 c2 s2 s1 -- len )
421 .quad SUB // ( eql s2 s1 -- len )
422 GOTONZ 3f // ( s2 s1 -- len )
424 .quad FROMR // ( len s2 s1 )
425 .quad DEC // ( len-1 s2 s1 )
426 .quad DUP // ( len-1 len-1 s2 s1 )
427 GOTOZ 4f // ( len-1 s2 s1 )
429 .quad TOR // ( s2 s1 -- len-1 )
430 .quad INC // ( s2+1 s1 -- len-1 )
431 .quad SWAP // ( s1 s2+1 -- len-1 )
432 .quad INC // ( s1+1 s2+1 -- len-1 )
433 GOTO 1b
436 3: // not equal // ( s2 s1 -- len )
437 .quad FROMR // ( len s2 s1 )
438 .quad TDROP // ( s1 )
439 .quad DROP // ( )
440 .quad LIT, 0 // ( 0 )
441 .quad EXIT
443 4: // equal // ( len s2 s1 )
444 .quad TDROP // ( s1 )
445 .quad DROP // ( )
446 .quad LIT, -1 // ( 0 )
447 .quad EXIT
449 // ( name namelen -- &word )
450 defword "FIND", 4, FIND, MEMEQ
451 .quad TOR // ( namelen -- name )
452 .quad TOR // ( -- namelen name )
453 .quad LATEST // ( &LATEST -- namelen name )
454 .quad FETCH // ( LATEST -- namelen name )
456 1: // ( &word -- namelen name )
457 .quad DUP // ( &word &word -- namelen name )
458 .quad LIT, 8 // ( 8 &word &word -- namelen name )
459 .quad ADD // ( &flags &word -- namelen name )
460 .quad FETCHBYTE // ( flags &word -- namelen name )
461 .quad DUP // ( flags flags &word -- namelen name )
462 .quad LIT, F_HIDDEN // ( F_HIDDEN flags flags &word -- namelen name )
463 .quad AND // ( hidden flags &word -- namelen name )
464 GOTONZ 4f // ( flags &word -- namelen name )
465 .quad LIT, F_LENMASK // ( F_LENMASK flags &word -- namelen name )
466 .quad AND // ( len &word -- namelen name )
467 .quad RSPFETCH // ( RSP len &word -- namelen name )
468 .quad FETCH // ( namelen len &word -- namelen name )
469 .quad SUB // ( eql &word -- namelen name )
470 GOTONZ 2f // ( &word -- namelen name )
472 .quad DUP // ( &word &word -- namelen name )
473 .quad LIT, 9 // ( 9 &word &word -- namelen name )
474 .quad ADD // ( &wname &word -- namelen name )
476 .quad RSPFETCH // ( &namelen wname &word -- namelen name )
477 .quad FETCH // ( namelen wname &word -- namelen name )
478 .quad SWAP // ( &wname namelen &word -- namelen name )
479 .quad RSPFETCH // ( RSP wname namelen &word -- namelen name )
480 .quad LIT, 8 // ( 8 RSP wname namelen &word -- namelen name )
481 .quad ADD // ( &name wname namelen &word -- namelen name )
482 .quad FETCH // ( name wname namelen &word -- namelen name )
483 .quad MEMEQ // ( eql &word -- namelen name )
484 GOTOZ 2f // ( &word -- namelen name )
486 3:
487 .quad RDROP // ( &word -- name )
488 .quad RDROP // ( &word )
489 .quad EXIT // noreturn
491 4: // hidden // ( flags &word -- namelen name )
492 .quad DROP // ( &word -- namelen name )
494 2: // hidden or not equal // ( &word -- namelen name )
495 .quad FETCH // ( &next -- namelen name )
496 .quad DUP // ( &next &next -- namelen name )
497 GOTONZ 1b // ( &next -- namelen name )
498 GOTO 3b // ( 0 -- namelen name )
500 defcode "BRANCH", 6, BRANCH, FIND
501 ld t0, 0(PC)
502 add PC, PC, t0
503 NEXT
505 defcode "0BRANCH", 7, ZBRANCH, BRANCH
506 POP a0
507 beq a0, zero, code_BRANCH
508 addi PC, PC, 8
509 NEXT
511 defcode ">R", 2, TOR, ZBRANCH
512 POP t0
513 PUSHRSP t0
514 NEXT
516 defcode "R>", 2, FROMR, TOR
517 POPRSP t0
518 PUSH t0
519 NEXT
521 defcode "RSP!", 4, RSPSTORE, FROMR
522 POP RSP
523 NEXT
525 defcode "RSP@", 4, RSPFETCH, RSPSTORE
526 PUSH RSP
527 NEXT
529 defcode "RDROP", 5, RDROP, RSPFETCH
530 POPRSP t0
531 NEXT
533 defcode "DSP!", 4, DSPSTORE, RDROP
534 POP DSP
535 NEXT
537 defcode "DSP@", 4, DSPFETCH, DSPSTORE
538 mv t0, DSP
539 PUSH t0
540 NEXT
542 // ( src dest len -- )
543 defword "CMOVE", 5, CMOVE, DSPFETCH
545 1:
546 .quad ROT // ( len src dest )
547 .quad DUP // ( len len src dest )
548 GOTOZ 2f // ( len src dest )
549 .quad NROT // ( src dest len )
550 .quad TDUP // ( src dest src dest len )
551 .quad FETCHBYTE // ( byte dest src dest len )
552 .quad SWAP // ( dest byte src dest len )
553 .quad STORE // ( src dest len )
554 .quad INC // ( src+1 dest len )
555 .quad NROT // ( dest len src+1 )
556 .quad INC // ( dest+1 len src+1 )
557 .quad NROT // ( len src+1 dest+1 )
558 .quad DEC // ( len-1 src+1 dest+1 )
559 .quad NROT // ( src+1 dest+1 len-1 )
560 GOTO 1b // noreturn
562 2: // ( len src dest )
563 .quad TDROP // ( dest )
564 .quad DROP // ( )
565 .quad EXIT
567 // ( name namelen -- )
568 defword "CREATE", 6, CREATE, CMOVE
569 // store the link pointer
570 .quad LATEST, FETCH
571 .quad HERE, FETCH
572 .quad STORE
574 // update LATEST
575 .quad HERE, FETCH
576 .quad LATEST
577 .quad STORE
579 // store name length
580 .quad OVER
581 .quad HERE, FETCH
582 .quad LIT, 8
583 .quad ADD
584 .quad STOREBYTE
586 // HERE += 9
587 .quad HERE
588 .quad DUP
589 .quad FETCH
590 .quad LIT, 9
591 .quad ADD
592 .quad SWAP
593 .quad STORE
595 // copy name
596 .quad OVER
597 .quad SWAP
598 .quad HERE, FETCH
599 .quad SWAP
600 .quad CMOVE
602 // update HERE
603 .quad HERE // ( &HERE namelen )
604 .quad DUP // ( &HERE &HERE namelen )
605 .quad FETCH // ( HERE &HERE namelen )
606 .quad ROT // ( namelen HERE &HERE )
607 .quad ADD // ( newHERE &HERE )
608 .quad LIT, 7 // ( 7 newHERE &HERE )
609 .quad ADD // ( newHERE &HERE)
610 .quad LIT, ~7 // ( ~7 newHERE &HERE )
611 .quad AND // ( newHERE &HERE )
612 .quad SWAP // ( &HERE newHERE )
613 .quad STORE // ( )
615 .quad EXIT
617 // ( str len -- err val )
618 defword "NUMBER", 6, NUMBER, CREATE
619 .quad OVER // ( len str len )
620 GOTOZ 1f // ( str len )
622 .quad DUP // ( str str len )
623 .quad FETCHBYTE // ( ch str len )
624 .quad LIT, '-' // ( '-' ch str len )
625 .quad EQ // ( eql str len )
626 GOTOZ 2f // ( str len )
628 .quad LIT, -1 // ( -1 str len )
629 .quad TOR // ( str len -- -1 )
630 .quad INC // ( str+1 len -- -1 )
631 .quad SWAP // ( len str+1 -- -1 )
632 .quad DEC // ( len-1 str+1 -- -1 )
633 .quad SWAP // ( str+1 len -- -1 )
634 .quad OVER // ( len str+1 len -- -1 )
635 .quad EQZ // ( !len str+1 len -- -1 )
636 GOTOZ 3f // ( str+1 len -- -1 )
638 .quad RDROP // ( str len )
639 GOTO 1f // noreturn
641 2:
642 .quad LIT, 1 // ( 1 str len )
643 .quad TOR // ( str len -- 1 )
645 3:
646 .quad LIT, 0 // ( 0 str len -- neg )
647 .quad TOR // ( str len -- 0 neg )
649 4: // ( str len -- 0 neg )
650 .quad DUP // ( str str len -- val neg )
651 .quad FETCHBYTE // ( ch str len -- val neg )
652 .quad LIT, '0' // ( '0' ch str len -- val neg )
653 .quad OVER // ( ch '0' ch str len -- val neg )
654 .quad LT // ( lt ch str len -- val neg )
655 GOTONZ 5f // ( ch str len -- val neg )
657 // ( ch str len -- val neg )
658 .quad DUP // ( ch ch str len -- val neg )
659 .quad LIT, '9' // ( '9' ch ch str len -- val neg )
660 .quad LT // ( lt ch str len -- val neg )
661 GOTONZ 5f // ( ch str len -- val neg )
663 .quad LIT, '0' // ( '0' ch str len -- val neg )
664 .quad SUB // ( dig str len -- val neg )
665 .quad FROMR // ( val dig str len -- neg )
666 .quad LIT, 10 // ( 10 val dig str len -- neg )
667 .quad MUL // ( val dig str len -- neg )
668 .quad ADD // ( val str len -- neg )
669 .quad TOR // ( str len -- val neg )
671 .quad INC // ( str+1 len -- val neg )
672 .quad SWAP // ( len str+1 -- val neg )
673 .quad DEC // ( len-1 str+1 -- val neg )
674 .quad SWAP // ( str+1 len-1 -- val neg )
675 .quad OVER // ( len-1 str+1 len-1 -- val neg )
676 GOTONZ 4b // ( str+1 len-1 -- val neg )
678 .quad TDROP // ( -- val neg )
679 .quad FROMR // ( val -- neg )
680 .quad FROMR // ( neg val )
681 .quad MUL // ( val )
682 .quad LIT, -1 // ( -1 val )
683 .quad EXIT
685 5: // invalid char ( ch str len -- val neg )
686 .quad DROP // ( str len -- val neg )
687 .quad RDROP // ( str len -- neg )
688 .quad RDROP // ( str len )
689 GOTO 1f // noreturn
691 1: // empty string ( str len )
692 .quad TDROP // ( )
693 .quad LIT, 0 // ( 0 )
694 .quad DUP // ( 0 0 )
695 .quad EXIT // noreturn
698 defcode "ERROR", 5, ERROR, NUMBER
699 la a0, .Lerr
700 jal puts
701 la PC, cold_start
702 NEXT
704 defcode "TELL", 4, TELL, ERROR
705 li a0, 1
706 POP a1
707 POP a2
708 jal write
709 NEXT
711 defcode "ENTER", 5, ENTER, TELL
712 POP t0
713 ld a0, 0(t0)
714 jr a0
716 defword "INTERPRET", 9, INTERPRET, ENTER
717 .quad WORD // ( word wordlen )
719 // check if length=0
720 .quad OVER // ( wordlen word wordlen )
721 .quad EQZ // ( wordlen==0 word wordlen )
722 GOTOZ 1f // ( word wordlen )
723 .quad LIT, 0 // ( 0 )
724 .quad DONE // noreturn
726 1: // find word in dictionary
727 .quad TDUP // ( name namelen name namelen )
728 .quad FIND // ( word name namelen )
730 // word == NULL ?
731 .quad DUP // ( word word name namelen )
732 GOTOZ 2f // ( word name namelen )
734 // clean up stack
735 .quad TOR // ( name namelen -- word )
736 .quad TDROP // ( -- word )
737 .quad FROMR // ( word )
739 // check if word is immediate
740 .quad DUP // ( word word )
741 .quad LIT, 8 // ( 8 word word )
742 .quad ADD // ( word+8 word )
743 .quad FETCHBYTE // ( nf word )
744 .quad LIT, F_IMMED // ( F_IMMED nf word )
745 .quad AND // ( imm word )
746 .quad EQZ // ( !imm word )
747 GOTOZ 3f // ( word )
749 // check if were compiling
750 .quad STATE, FETCH // ( state word )
751 GOTOZ 3f // ( word )
753 .quad TCFA // ( *cw )
754 .quad COMMA // ( )
755 .quad EXIT // noreturn
757 3: // execute word
758 .quad TCFA // ( &cw )
759 .quad ENTER // noreturn
760 .quad EXIT
762 2: // not found, maybe number ( word name namelen )
763 .quad DROP // ( name namelen )
764 .quad NUMBER // ( err value )
765 GOTOZ 4f // ( value )
767 .quad STATE, FETCH // ( imm value )
768 GOTOZ 5f // ( value )
770 // compile number
771 .quad LIT, LIT // ( LIT value )
772 .quad COMMA // ( value )
773 .quad COMMA // ( )
774 .quad EXIT // noreturn
776 5: // push number
777 .quad EXIT // ( value ), noreturn
779 4: // not found
780 .quad DROP // ( )
781 .quad ERROR // noreturn
783 defword "QUIT", 4, QUIT, INTERPRET
784 .quad R0, RSPSTORE
785 .quad INTERPRET
786 .quad BRANCH, -16
788 defcode "!", 1, STORE, QUIT
789 POP t0
790 POP t1
791 sd t1, 0(t0)
792 NEXT
794 defcode "@", 1, FETCH, STORE
795 POP t0
796 ld t0, 0(t0)
797 PUSH t0
798 NEXT
800 defcode "C!", 2, STOREBYTE, FETCH
801 POP t0
802 POP t1
803 sb t1, 0(t0)
804 NEXT
806 defcode "C@", 2, FETCHBYTE, STOREBYTE
807 POP t0
808 lbu t0, 0(t0)
809 PUSH t0
810 NEXT
812 defcode ".", 1, PRINT, FETCHBYTE
813 POP a1
814 la a0, .Lfmt
815 jal printf
816 NEXT
818 // ( word )
819 defword ",", 1, COMMA, PRINT
820 .quad HERE // ( &HERE word )
821 .quad SWAP // ( word &HERE )
822 .quad OVER // ( &HERE word &HERE )
823 .quad FETCH // ( HERE word &HERE )
824 .quad SWAP // ( word HERE &HERE )
825 .quad OVER // ( HERE word HERE &HERE )
826 .quad STORE // ( HERE &HERE )
827 .quad LIT, 8 // ( 8 HERE &HERE )
828 .quad ADD // ( HERE+8 &HERE )
829 .quad SWAP // ( &HERE HERE+8 )
830 .quad STORE // ( )
831 .quad EXIT // noreturn
833 defcode "'", 1, TICK, COMMA
834 ld a0, 0(PC)
835 addi PC, PC, 8
836 PUSH a0
837 NEXT
839 defword "[']", 3, BTICK, TICK, F_IMMED
840 .quad WORD
841 .quad FIND
842 .quad TCFA
843 .quad EXIT
845 defword "[", 1, LBRACK, BTICK, F_IMMED
846 .quad LIT, 0
847 .quad STATE
848 .quad STORE
849 .quad EXIT
851 defword "]", 1, RBRACK, LBRACK
852 .quad LIT, 1
853 .quad STATE
854 .quad STORE
855 .quad EXIT
857 defword "HIDDEN", 6, HIDDEN, RBRACK
858 .quad LIT, 8
859 .quad ADD
860 .quad DUP
861 .quad FETCHBYTE
862 .quad LIT, F_HIDDEN
863 .quad XOR
864 .quad SWAP
865 .quad STOREBYTE
866 .quad EXIT
868 defword "HIDE", 4, HIDE, HIDDEN
869 .quad LATEST, FETCH
870 .quad HIDDEN
871 .quad EXIT
873 defword "IMMEDIATE", 9, IMMEDIATE, HIDE
874 .quad LATEST, FETCH
875 .quad LIT, 8
876 .quad ADD
877 .quad DUP
878 .quad FETCHBYTE
879 .quad LIT, F_IMMED
880 .quad XOR
881 .quad SWAP
882 .quad STOREBYTE
883 .quad EXIT
885 defcode "LIT", 3, LIT, IMMEDIATE
886 ld t0, 0(PC)
887 addi PC, PC, 8
888 PUSH t0
889 NEXT
891 defword ":", 1, COLON, LIT
892 .quad WORD
893 .quad CREATE
894 .quad LIT, DOCOL, COMMA
895 .quad LATEST, FETCH, HIDDEN
896 .quad RBRACK
897 .quad EXIT
899 defword ";", 1, SEMICOLON, COLON, F_IMMED
900 .quad LIT, EXIT, COMMA
901 .quad LATEST, FETCH, HIDDEN
902 .quad LBRACK
903 .quad EXIT
905 defcode "EXECUTE", 7, EXECUTE, SEMICOLON
906 POP a0
907 jr a0
909 defcode "EMIT", 4, EMIT, EXECUTE
910 POP a0
911 jal _EMIT
912 NEXT
914 defcode "CHAR", 4, CHAR, EMIT
915 jal _WORD
916 lbu a0, 0(a0)
917 PUSH a0
918 NEXT
920 // ( word -- &cw )
921 defword "TCFA", 4, TCFA, CHAR
922 .quad LIT, 8 // ( 8 word )
923 .quad ADD // ( &flags )
924 .quad DUP // ( &flags &flags )
925 .quad FETCHBYTE // ( flags &flags )
926 .quad LIT, F_LENMASK // ( F_LENMASK flags &flags )
927 .quad AND // ( len &flags )
928 .quad ADD // ( ptr )
929 .quad LIT, 8 // ( 8 ptr )
930 .quad ADD // ( ptr )
931 .quad LIT, ~7 // ( ~7 ptr )
932 .quad AND // ( &cw )
933 .quad EXIT
935 defword "RECURSE", 7, RECURSE, TCFA, F_IMMED
936 .quad LATEST, FETCH
937 .quad TCFA
938 .quad COMMA
939 .quad EXIT
941 defvar "LATEST", 6, LATEST, RECURSE, name_R0
942 defvar "HERE", 4, HERE, LATEST, memory
943 defvar "STATE", 5, STATE, HERE
944 defvar "S0", 2, S0, STATE
945 defconst "R0", 2, R0, S0, return_stack
947 .section .rodata
948 .Lerr:
949 .asciz "not found"
950 .Lfmt:
951 .asciz "%d\n"
952 .Lhex:
953 .asciz "%#x\n"
955 .section .bss
956 wordlen:
957 .skip 8
958 wordbuf:
959 .skip WORDLEN + 1
961 .align 8
962 .skip 4096
963 return_stack:
964 .skip 4096
965 data_stack:
966 .align 8
967 memory:
968 .skip 65536