ppc64: Don't set Kp bit on SLB
[openbios.git] / forth / device / fcode.fs
blob9083ed0e0c3792f41760417af0a017dc8b3fb491
1 \ tag: FCode implementation functions
2 \
3 \ this code implements IEEE 1275-1994 ch. 5.3.3
4 \
5 \ Copyright (C) 2003 Stefan Reinauer
6 \
7 \ See the file "COPYING" for further information about
8 \ the copyright and warranty status of this work.
9 \
11 hex
13 0 value fcode-sys-table \ table with built-in fcodes (0-0x7ff)
15 true value ?fcode-offset16 \ fcode offsets are 16 instead of 8 bit?
16 1 value fcode-spread \ fcode spread (1, 2 or 4)
17 0 value fcode-table \ pointer to fcode table
18 false value ?fcode-verbose \ do verbose fcode execution?
20 defer _fcode-debug? \ If true, save names for FCodes with headers
21 true value fcode-headers? \ If true, possibly save names for FCodes.
23 0 value fcode-stream-start \ start address of fcode stream
24 0 value fcode-stream \ current fcode stream address
26 variable fcode-end \ state variable, if true, fcode program terminates.
27 defer fcode-c@ \ get byte
29 : fcode-push-state ( -- <state information> )
30 ?fcode-offset16
31 fcode-spread
32 fcode-table
33 fcode-headers?
34 fcode-stream-start
35 fcode-stream
36 fcode-end @
37 ['] fcode-c@ behavior
40 : fcode-pop-state ( <state information> -- )
41 to fcode-c@
42 fcode-end !
43 to fcode-stream
44 to fcode-stream-start
45 to fcode-headers?
46 to fcode-table
47 to fcode-spread
48 to ?fcode-offset16
52 \ fcode access helper functions
55 \ fcode-ptr
56 \ convert FCode number to pointer to xt in FCode table.
58 : fcode-ptr ( u16 -- *xt )
59 cells
60 fcode-table ?dup if + exit then
62 \ we are not parsing fcode at the moment
63 dup 800 cells u>= abort" User FCODE# referenced."
64 fcode-sys-table +
67 \ fcode>xt
68 \ get xt according to an FCode#
70 : fcode>xt ( u16 -- xt )
71 fcode-ptr @
74 \ fcode-num8
75 \ get 8bit from FCode stream, taking spread into regard.
77 : fcode-num8 ( -- c ) ( F: c -- )
78 fcode-stream
79 dup fcode-spread + to fcode-stream
80 fcode-c@
83 \ fcode-num8-signed ( -- c ) ( F: c -- )
84 \ get 8bit signed from FCode stream
86 : fcode-num8-signed
87 fcode-num8
88 dup 80 and 0> if
89 ff invert or
90 then
93 \ fcode-num16
94 \ get 16bit from FCode stream
96 : fcode-num16 ( -- num16 )
97 fcode-num8 fcode-num8 swap bwjoin
100 \ fcode-num16-signed ( -- c ) ( F: c -- )
101 \ get 16bit signed from FCode stream
103 : fcode-num16-signed
104 fcode-num16
105 dup 8000 and 0> if
106 ffff invert or
107 then
110 \ fcode-num32
111 \ get 32bit from FCode stream
113 : fcode-num32 ( -- num32 )
114 fcode-num8 fcode-num8
115 fcode-num8 fcode-num8
116 swap 2swap swap bljoin
119 \ fcode#
120 \ Get an FCode# from FCode stream
122 : fcode# ( -- fcode# )
123 fcode-num8
124 dup 1 f between if
125 fcode-num8 swap bwjoin
126 then
129 \ fcode-offset
130 \ get offset from FCode stream.
132 : fcode-offset ( -- offset )
133 ?fcode-offset16 if
134 fcode-num16-signed
135 else
136 fcode-num8-signed
137 then
139 \ Display offset in verbose mode
140 ?fcode-verbose if
141 dup ." (offset) " . cr
142 then
145 \ fcode-string
146 \ get a string from FCode stream, store in pocket.
148 : fcode-string ( -- addr len )
149 pocket dup
150 fcode-num8
151 dup rot c!
152 2dup bounds ?do
153 fcode-num8 i c!
154 loop
156 \ Display string in verbose mode
157 ?fcode-verbose if
158 2dup ." (const) " type cr
159 then
162 \ fcode-header
163 \ retrieve FCode header from FCode stream
165 : fcode-header
166 fcode-num8
167 fcode-num16
168 fcode-num32
169 ?fcode-verbose if
170 ." Found FCode header:" cr rot
171 ." Format : " u. cr swap
172 ." Checksum : " u. cr
173 ." Length : " u. cr
174 else
175 3drop
176 then
177 \ TODO checksum
180 \ writes currently created word as fcode# read from stream
183 : fcode! ( F:FCode# -- )
184 here fcode#
186 \ Display fcode# in verbose mode
187 ?fcode-verbose if
188 dup ." (fcode#) " . cr
189 then
190 fcode-ptr !
195 \ 5.3.3.1 Defining new FCode functions.
198 \ instance ( -- )
199 \ Mark next defining word as instance specific.
200 \ (defined in bootstrap.fs)
202 \ instance-init ( wid buffer -- )
203 \ Copy template from specified wordlist to instance
206 : instance-init
207 swap
208 begin @ dup 0<> while
209 dup /n + @ instance-cfa? if \ buffer dict
210 2dup 2 /n* + @ + \ buffer dict dest
211 over 3 /n* + @ \ buffer dict dest size
212 2 pick 4 /n* + \ buffer dict dest size src
213 -rot
214 move
215 then
216 repeat
217 2drop
221 \ new-token ( F:/FCode#/ -- )
222 \ Create a new unnamed FCode function
224 : new-token
225 0 0 header
226 fcode!
230 \ named-token (F:FCode-string FCode#/ -- )
231 \ Create a new possibly named FCode function.
233 : named-token
234 fcode-string
235 _fcode-debug? not if
236 2drop 0 0
237 then
238 header
239 fcode!
243 \ external-token (F:/FCode-string FCode#/ -- )
244 \ Create a new named FCode function
246 : external-token
247 fcode-string header
248 fcode!
252 \ b(;) ( -- )
253 \ End an FCode colon definition.
255 : b(;)
256 ['] ; execute
257 ; immediate
260 \ b(:) ( -- ) ( E: ... -- ??? )
261 \ Defines type of new FCode function as colon definition.
263 : b(:)
264 1 , ]
268 \ b(buffer:) ( size -- ) ( E: -- a-addr )
269 \ Defines type of new FCode function as buffer:.
271 : b(buffer:)
272 4 , allot
273 reveal
276 \ b(constant) ( nl -- ) ( E: -- nl )
277 \ Defines type of new FCode function as constant.
279 : b(constant)
280 3 , ,
281 reveal
285 \ b(create) ( -- ) ( E: -- a-addr )
286 \ Defines type of new FCode function as create word.
288 : b(create)
289 6 ,
290 ['] noop ,
291 reveal
295 \ b(defer) ( -- ) ( E: ... -- ??? )
296 \ Defines type of new FCode function as defer word.
298 : b(defer)
300 ['] (undefined-defer) ,
301 ['] (semis) ,
302 reveal
306 \ b(field) ( offset size -- offset+size ) ( E: addr -- addr+offset )
307 \ Defines type of new FCode function as field.
309 : b(field)
311 ['] noop ,
312 reveal
313 over ,
315 does>
320 \ b(value) ( x -- ) (E: -- x )
321 \ Defines type of new FCode function as value.
323 : b(value)
324 3 , , reveal
328 \ b(variable) ( -- ) ( E: -- a-addr )
329 \ Defines type of new FCode function as variable.
331 : b(variable)
332 4 , 0 ,
333 reveal
337 \ (is-user-word) ( name-str name-len xt -- ) ( E: ... -- ??? )
338 \ Create a new named user interface command.
340 : (is-user-word)
344 \ get-token ( fcode# -- xt immediate? )
345 \ Convert FCode number to function execution token.
347 : get-token
348 fcode>xt dup immediate?
352 \ set-token ( xt immediate? fcode# -- )
353 \ Assign FCode number to existing function.
355 : set-token
356 nip \ TODO we use the xt's immediate state for now.
357 fcode-ptr !
364 \ 5.3.3.2 Literals
368 \ b(lit) ( -- n1 )
369 \ Numeric literal FCode. Followed by FCode-num32.
371 64bit? [IF]
372 : b(lit)
373 fcode-num32 32>64
374 state @ if
375 ['] (lit) , ,
376 then
377 ; immediate
378 [ELSE]
379 : b(lit)
380 fcode-num32
381 state @ if
382 ['] (lit) , ,
383 then
384 ; immediate
385 [THEN]
388 \ b(') ( -- xt )
389 \ Function literal FCode. Followed by FCode#
391 : b(')
392 fcode# fcode>xt
393 state @ if
394 ['] (lit) , ,
395 then
396 ; immediate
399 \ b(") ( -- str len )
400 \ String literal FCode. Followed by FCode-string.
402 : b(")
403 fcode-string
404 state @ if
405 \ only run handle-text in compile-mode,
406 \ otherwise we would waste a pocket.
407 handle-text
408 then
409 ; immediate
413 \ 5.3.3.3 Controlling values and defers
416 \ behavior ( defer-xt -- contents-xt )
417 \ defined in bootstrap.fs
419 \ b(to) ( new-value -- )
420 \ FCode for setting values and defers. Followed by FCode#.
422 : b(to)
423 fcode# fcode>xt
424 1 handle-lit
425 ['] (to)
426 state @ if
428 else
429 execute
430 then
431 ; immediate
436 \ 5.3.3.4 Control flow
440 \ offset16 ( -- )
441 \ Makes subsequent FCode-offsets use 16-bit (not 8-bit) form.
443 : offset16
444 true to ?fcode-offset16
448 \ bbranch ( -- )
449 \ Unconditional branch FCode. Followed by FCode-offset.
451 : bbranch
452 fcode-offset 0< if \ if we jump backwards, we can forsee where it goes
453 ['] dobranch ,
454 resolve-dest
455 execute-tmp-comp
456 else
457 setup-tmp-comp ['] dobranch ,
458 here 0
460 2swap
461 then
462 ; immediate
465 \ b?branch ( continue? -- )
466 \ Conditional branch FCode. Followed by FCode-offset.
468 : b?branch
469 fcode-offset 0< if \ if we jump backwards, we can forsee where it goes
470 ['] do?branch ,
471 resolve-dest
472 execute-tmp-comp
473 else
474 setup-tmp-comp ['] do?branch ,
475 here 0
477 then
478 ; immediate
481 \ b(<mark) ( -- )
482 \ Target of backward branches.
484 : b(<mark)
485 setup-tmp-comp
486 here 1
487 ; immediate
490 \ b(>resolve) ( -- )
491 \ Target of forward branches.
493 : b(>resolve)
494 resolve-orig
495 execute-tmp-comp
496 ; immediate
499 \ b(loop) ( -- )
500 \ End FCode do..loop. Followed by FCode-offset.
502 : b(loop)
503 fcode-offset drop
504 postpone loop
505 ; immediate
508 \ b(+loop) ( delta -- )
509 \ End FCode do..+loop. Followed by FCode-offset.
511 : b(+loop)
512 fcode-offset drop
513 postpone +loop
514 ; immediate
517 \ b(do) ( limit start -- )
518 \ Begin FCode do..loop. Followed by FCode-offset.
520 : b(do)
521 fcode-offset drop
522 postpone do
523 ; immediate
526 \ b(?do) ( limit start -- )
527 \ Begin FCode ?do..loop. Followed by FCode-offset.
529 : b(?do)
530 fcode-offset drop
531 postpone ?do
532 ; immediate
535 \ b(leave) ( -- )
536 \ Exit from a do..loop.
538 : b(leave)
539 postpone leave
540 ; immediate
543 \ b(case) ( sel -- sel )
544 \ Begin a case (multiple selection) statement.
546 : b(case)
547 postpone case
548 ; immediate
551 \ b(endcase) ( sel | <nothing> -- )
552 \ End a case (multiple selection) statement.
554 : b(endcase)
555 postpone endcase
556 ; immediate
559 \ b(of) ( sel of-val -- sel | <nothing> )
560 \ FCode for of in case statement. Followed by FCode-offset.
562 : b(of)
563 fcode-offset drop
564 postpone of
565 ; immediate
567 \ b(endof) ( -- )
568 \ FCode for endof in case statement. Followed by FCode-offset.
570 : b(endof)
571 fcode-offset drop
572 postpone endof
573 ; immediate