Tweak instruction set to accelerate some common tasks

This commit is contained in:
psf 2022-05-17 23:10:08 -07:00
parent ca8ced9494
commit 2543097fec

View file

@ -78,7 +78,7 @@ enum Op {
RET = 0xffe0, TOR = 0xffe2, RTO = 0xffe4, LD = 0xffe6, RET = 0xffe0, TOR = 0xffe2, RTO = 0xffe4, LD = 0xffe6,
ST = 0xffe8, DUP = 0xffea, SWP = 0xffec, DRP = 0xffee, ST = 0xffe8, DUP = 0xffea, SWP = 0xffec, DRP = 0xffee,
Q = 0xfff0, ADD = 0xfff2, SFT = 0xfff4, OR = 0xfff6, Q = 0xfff0, ADD = 0xfff2, SFT = 0xfff4, OR = 0xfff6,
INV = 0xfff8, ULT = 0xfffa, IO = 0xfffc, NOP = 0xfffe, AND = 0xfff8, INV = 0xfffa, GEQ = 0xfffc, IO = 0xfffe,
} }
const PRIMITIVES: [Primitive; 16] = [ const PRIMITIVES: [Primitive; 16] = [
@ -135,14 +135,19 @@ const PRIMITIVES: [Primitive; 16] = [
let v2 = x.dstack.pop(); let v2 = x.dstack.pop();
x.dstack.push(v1 | v2); x.dstack.push(v1 | v2);
}, },
| x | { // and
let v1 = x.dstack.pop();
let v2 = x.dstack.pop();
x.dstack.push(v1 & v2);
},
| x | { // inv | x | { // inv
let v1 = x.dstack.pop(); let v1 = x.dstack.pop();
x.dstack.push(!v1); x.dstack.push(!v1);
}, },
| x | { // ult | x | { // geq (unsigned)
let v1 = x.dstack.pop(); let v1 = x.dstack.pop();
let v2 = x.dstack.pop(); let v2 = x.dstack.pop();
x.dstack.push(if v1 < v2 { 0xffff } else { 0 }); x.dstack.push(if v1 >= v2 { 0xffff } else { 0 });
}, },
| x | { // io | x | { // io
let port = x.dstack.pop(); let port = x.dstack.pop();
@ -163,8 +168,7 @@ const PRIMITIVES: [Primitive; 16] = [
} }
_ => {} _ => {}
} }
}, }
| _x | { /* nop */ }
]; ];
/* --- The memory map --- /* --- The memory map ---
@ -247,10 +251,6 @@ fn build_dictionary(c: &mut Core) {
d.entry(); d.name(1, *b"- "); let sub = d.here; d.entry(); d.name(1, *b"- "); let sub = d.here;
forth!(INV, Literal(1), ADD, ADD, RET); forth!(INV, Literal(1), ADD, ADD, RET);
// and ( a b -- a&b )
d.entry(); d.name(3, *b"and"); let and = d.here;
forth!(INV, SWP, INV, OR, INV, RET);
let zero = d.here; let zero = d.here;
forth!(Literal(0), RTO, DRP, RET); forth!(Literal(0), RTO, DRP, RET);
@ -260,7 +260,7 @@ fn build_dictionary(c: &mut Core) {
// >= ( a b -- a>=b ) // note: signed comparison // >= ( a b -- a>=b ) // note: signed comparison
d.entry(); d.name(2, *b">= "); let geq = d.here; d.entry(); d.name(2, *b">= "); let geq = d.here;
forth!(sub, Literal(0x4000), DUP, ADD, and, zero_eq, RET); forth!(sub, Literal(0x4000), DUP, ADD, AND, zero_eq, RET);
// = ( a b -- a=b ) // = ( a b -- a=b )
d.entry(); d.name(1, *b"= "); let eq = d.here; d.entry(); d.name(1, *b"= "); let eq = d.here;
@ -291,11 +291,11 @@ fn build_dictionary(c: &mut Core) {
// c@ ( a -- n ) // c@ ( a -- n )
d.entry(); d.name(2, *b"c@ "); let cld = d.here; d.entry(); d.name(2, *b"c@ "); let cld = d.here;
forth!(LD, Literal(0xff), and, RET); forth!(LD, Literal(0xff), AND, RET);
// c! ( n a -- ) // c! ( n a -- )
d.entry(); d.name(2, *b"c! "); let cst = d.here; d.entry(); d.name(2, *b"c! "); let cst = d.here;
forth!(DUP, LD, Literal(0xff), INV, and, SWP, TOR, OR, RTO, ST, RET); forth!(DUP, LD, Literal(0xff), INV, AND, SWP, TOR, OR, RTO, ST, RET);
// Load 1 letter into buffer. // Load 1 letter into buffer.
let stchar = d.here; let stchar = d.here;
@ -328,8 +328,8 @@ fn build_dictionary(c: &mut Core) {
forth!(Literal(2), ADD, TOR, forth!(Literal(2), ADD, TOR,
Literal(word_buf), DUP, Literal(2), ADD, LD, SWP, LD, Literal(word_buf), DUP, Literal(2), ADD, LD, SWP, LD,
RTO, DUP, TOR, RTO, DUP, TOR,
LD, Literal(0x0080), INV, and, eq, LD, Literal(0x0080), INV, AND, eq,
SWP, RTO, Literal(2), ADD, LD, eq, and, RET); SWP, RTO, Literal(2), ADD, LD, eq, AND, RET);
let matched = d.here; let matched = d.here;
forth!(Literal(6), ADD, RTO, DRP, RET); forth!(Literal(6), ADD, RTO, DRP, RET);
@ -382,7 +382,7 @@ fn build_dictionary(c: &mut Core) {
// unsmudge ( -- ) // unsmudge ( -- )
d.entry(); d.name(8 | 0x80, *b"uns"); let unsmudge = d.here; d.entry(); d.name(8 | 0x80, *b"uns"); let unsmudge = d.here;
forth!(word_addr, DUP, LD, Literal(0x0040), INV, and, SWP, ST, RET); forth!(word_addr, DUP, LD, Literal(0x0040), INV, AND, SWP, ST, RET);
// [ ( -- ) // [ ( -- )
d.entry(); d.name(1 | 0x80, *b"[ "); let lbracket = d.here; d.entry(); d.name(1 | 0x80, *b"[ "); let lbracket = d.here;
@ -398,7 +398,7 @@ fn build_dictionary(c: &mut Core) {
here, LD, Literal(2), ADD, here, ST, RET); here, LD, Literal(2), ADD, here, ST, RET);
let compile_call = d.here; let compile_call = d.here;
forth!(DUP, Literal(4), sub, LD, Literal(0x0080), and, state, LD, OR, Q, RET, forth!(DUP, Literal(4), sub, LD, Literal(0x0080), AND, state, LD, OR, Q, RET,
comma, RTO, DRP, RET); comma, RTO, DRP, RET);
let compile_lit = d.here; let compile_lit = d.here;
@ -473,13 +473,12 @@ fn build_dictionary(c: &mut Core) {
d.entry(); d.name(1, *b"+ "); forth!(ADD, RET); d.entry(); d.name(1, *b"+ "); forth!(ADD, RET);
d.entry(); d.name(5, *b"shi"); forth!(SFT, RET); d.entry(); d.name(5, *b"shi"); forth!(SFT, RET);
d.entry(); d.name(2, *b"or "); forth!(OR, RET); d.entry(); d.name(2, *b"or "); forth!(OR, RET);
d.entry(); d.name(6, *b"inv"); forth!(INV, RET); d.entry(); d.name(3, *b"and"); forth!(AND, RET);
d.entry(); d.name(2, *b"u< "); forth!(ULT, RET); d.entry(); d.name(3, *b"inv"); forth!(INV, RET);
d.entry(); d.name(2, *b"io "); forth!(IO, RET); d.entry(); d.name(3, *b"geq"); forth!(GEQ, RET);
d.entry(); d.name(2, *b"io "); let io = d.here; forth!(IO, RET);
d.entry(); d.name(3, *b"nop"); let nop = d.here; forth!(NOP, RET); d.c.store(latest_ptr, io-6);
d.c.store(latest_ptr, nop-6);
d.c.store(here_ptr, d.here); d.c.store(here_ptr, d.here);
d.c.store(state_ptr, 0xffff); d.c.store(state_ptr, 0xffff);
d.c.store(0, quit); d.c.store(0, quit);