feat(v4.0.0): C@ is call-free
One case per byte position, like C!: the cell is shifted down with a 2/ loop and masked. It replaces the version built on LSHIFT, RSHIFT and SWAP calls. C@ now leaves its caller 7 return entries (was 4), and the words above it gain with it: TYPE 6 (was 3), DUMP 4, Q.PRINT, U. and U.R 3 (were 2). The signed number words stay at 2: their sign waits on the return stack. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
e50cc1f73a
commit
7c5be22799
@@ -15,6 +15,7 @@
|
||||
* as the text between "System initialization complete." and "Goodbye!".
|
||||
*
|
||||
* On a node of its own, like test_pictured.c. SWAP, LSHIFT, RSHIFT and C@
|
||||
* (call-free, so it no longer uses the other three)
|
||||
* are assembled again here as they are in test_foundation.c.
|
||||
*/
|
||||
#include "v4/asm.h"
|
||||
@@ -91,12 +92,37 @@ static void build(void)
|
||||
HERE_(a);
|
||||
O(DROP); O(DROP); O(SEMI);
|
||||
|
||||
/* : C@ ( baddr -- c )
|
||||
* dup 3 and 3 LSHIFT SWAP 2 RSHIFT a! @ SWAP RSHIFT 255 and ; */
|
||||
/* : C@ ( baddr -- c ) call-free, 5.3
|
||||
* dup 2/ 2/ a! 3 and k A: word address
|
||||
* if K0 -1 + if K1 -1 + if K2
|
||||
* drop @ 23 FOR 2/ UNEXT 255 and ; byte 3
|
||||
* K2: drop @ 15 FOR 2/ UNEXT 255 and ; byte 2
|
||||
* K1: drop @ 7 FOR 2/ UNEXT 255 and ; byte 1
|
||||
* K0: drop @ 255 and ; byte 0 */
|
||||
w_cfetch = v4_asm_label(&as);
|
||||
O(DUP); LIT(3); O(AND); LIT(3); CALL(w_lshift);
|
||||
CALL(w_swap); LIT(2); CALL(w_rshift); O(BANG_A); O(FETCH_A);
|
||||
CALL(w_swap); CALL(w_rshift); LIT(255); O(AND); O(SEMI);
|
||||
{
|
||||
v4_asm_ref f0, f1, f2;
|
||||
O(DUP); O(TWO_SLASH); O(TWO_SLASH); O(BANG_A); LIT(3); O(AND);
|
||||
f0 = v4_asm_branch_fwd(&as, V4_OP_IF);
|
||||
LIT(-1); O(ADD); f1 = v4_asm_branch_fwd(&as, V4_OP_IF);
|
||||
LIT(-1); O(ADD); f2 = v4_asm_branch_fwd(&as, V4_OP_IF);
|
||||
O(DROP); O(FETCH_A); LIT(23); O(PUSH);
|
||||
(void)v4_asm_label(&as);
|
||||
O(TWO_SLASH); O(UNEXT);
|
||||
LIT(255); O(AND); O(SEMI);
|
||||
v4_asm_resolve(&as, f2, v4_asm_label(&as));
|
||||
O(DROP); O(FETCH_A); LIT(15); O(PUSH);
|
||||
(void)v4_asm_label(&as);
|
||||
O(TWO_SLASH); O(UNEXT);
|
||||
LIT(255); O(AND); O(SEMI);
|
||||
v4_asm_resolve(&as, f1, v4_asm_label(&as));
|
||||
O(DROP); O(FETCH_A); LIT(7); O(PUSH);
|
||||
(void)v4_asm_label(&as);
|
||||
O(TWO_SLASH); O(UNEXT);
|
||||
LIT(255); O(AND); O(SEMI);
|
||||
v4_asm_resolve(&as, f0, v4_asm_label(&as));
|
||||
O(DROP); O(FETCH_A); LIT(255); O(AND); O(SEMI);
|
||||
}
|
||||
|
||||
/* ---- terminal output, 5.10 ---- */
|
||||
|
||||
@@ -272,7 +298,7 @@ int main(void)
|
||||
CHECK(dh >= 7 && rh >= 7, "EMIT leaves room");
|
||||
headroom("CR", w_cr, 0, 0, 0, "\n", 1, &dh, &rh);
|
||||
headroom("TYPE", w_type, 2, STR_BADDR + 17, 9, text + 17, 9, &dh, &rh);
|
||||
CHECK(dh >= 2 && rh >= 2, "TYPE leaves room");
|
||||
CHECK(dh >= 5 && rh >= 6, "TYPE leaves room");
|
||||
}
|
||||
|
||||
CHECK(v4_node_guards_intact(&n), "guards intact");
|
||||
|
||||
Reference in New Issue
Block a user