packed literals; faster execution

llvm
Clyne 2 years ago
parent 42d64c6da2
commit c5db61d59f

@ -17,7 +17,7 @@ msp430: alee-msp430
small: CXXFLAGS += -Os small: CXXFLAGS += -Os
small: alee small: alee
fast: CXXFLAGS += -O3 -march=native -mtune=native fast: CXXFLAGS += -O3 -march=native -mtune=native -flto
fast: alee fast: alee
alee: $(LIBFILE) alee: $(LIBFILE)

@ -19,7 +19,7 @@
: here 1 cells @ ; : here 1 cells @ ;
: allot 1 cells +! ; : allot 1 cells +! ;
: _latest 2 cells ; : _latest 2 cells ;
: imm _latest @ dup @ 1 5 << | swap ! ; : imm _latest @ dup @ 1 6 << | swap ! ;
: state 3 cells ; : state 3 cells ;
: postpone 1 4 cells ! ; imm : postpone 1 4 cells ! ; imm
: _input 5 cells ; : _input 5 cells ;
@ -46,7 +46,7 @@
: decimal 10 base ! ; : decimal 10 base ! ;
: hex 16 base ! ; : hex 16 base ! ;
: literal 0 , , ; imm : literal 1 , , ; imm
: ['] ' postpone literal ; imm : ['] ' postpone literal ; imm
: [ 0 state ! ; imm : [ 0 state ! ; imm
: ] 1 state ! ; : ] 1 state ! ;
@ -151,7 +151,7 @@
: create align here bl word count nip cell+ allot align : create align here bl word count nip cell+ allot align
['] _lit , here 3 cells + , ['] exit dup , , ['] _lit , here 3 cells + , ['] exit dup , ,
dup @ 31 & over _latest @ - 6 << or over ! _latest ! ; dup @ 31 & over _latest @ - 7 << or over ! _latest ! ;
: _latword _latest @ : _latword _latest @
dup @ 31 & + cell+ aligned ; dup @ 31 & + cell+ aligned ;
: _does> _latword 2 cells + : _does> _latword 2 cells +

@ -36,7 +36,7 @@ void newdef(Dictionary& dict, Word word)
dict.addDefinition(word); dict.addDefinition(word);
dict.write(addr, dict.write(addr,
(dict.read(addr) & 0x1F) | (dict.read(addr) & 0x1F) |
((addr - dict.latest()) << 6)); ((addr - dict.latest()) << 7));
dict.latest(addr); dict.latest(addr);
}; };
void tick(State& state) void tick(State& state)
@ -45,7 +45,7 @@ void tick(State& state)
if (auto j = state.dict.find(word); j > 0) if (auto j = state.dict.find(word); j > 0)
state.push(state.dict.getexec(j)); state.push(state.dict.getexec(j));
else if (auto i = CoreWords::findi(state, word); i >= 0) else if (auto i = CoreWords::findi(state, word); i >= 0)
state.push(i & ~CoreWords::Immediate); state.push(((i & ~CoreWords::Immediate) << 1) | 1);
else else
state.push(0); state.push(0);
} }
@ -56,14 +56,14 @@ void CoreWords::run(unsigned int index, State& state)
DoubleCell dcell; DoubleCell dcell;
execute: execute:
switch (index) { if ((index & 1) == 0) {
default:
// must be calling a defined subroutine // must be calling a defined subroutine
state.pushr(state.ip); state.pushr(state.ip);
state.ip = index; state.ip = index;
return; return;
} else switch ((index & 0x3E) >> 1) {
case 0: // _lit case 0: // _lit
state.push(state.beyondip()); state.push((index & 0xFF00) ? (index >> 8) - 1 : state.beyondip());
break; break;
case 1: // drop case 1: // drop
state.pop(); state.pop();
@ -165,7 +165,6 @@ execute:
case 24: // execute case 24: // execute
index = state.pop(); index = state.pop();
goto execute; goto execute;
break;
case 25: // exit case 25: // exit
state.ip = state.popr(); state.ip = state.popr();
if (state.ip == 0) { if (state.ip == 0) {
@ -174,7 +173,7 @@ execute:
} }
break; break;
case 26: // semic case 26: // semic
state.dict.add(findi("exit")); state.dict.add((findi("exit") << 1) | 1);
state.compiling(false); state.compiling(false);
break; break;
case 27: // _jmp0 case 27: // _jmp0
@ -213,17 +212,16 @@ execute:
int CoreWords::findi(const char *word) int CoreWords::findi(const char *word)
{ {
const auto size = std::strlen(word); std::size_t i = 0;
std::size_t i;
int wordsi = 0; int wordsi = 0;
for (i = 0; i < sizeof(wordsarr);) { while (i < sizeof(wordsarr)) {
auto end = i; auto end = i;
while (wordsarr[end] > '\1') while (wordsarr[end])
++end; ++end;
if (size == end - i && !std::strncmp(word, wordsarr + i, size)) if (!std::strcmp(word, wordsarr + i))
return wordsarr[end] == '\0' ? wordsi : (wordsi | Immediate); return wordsi;
++wordsi; ++wordsi;
i = end + 1; i = end + 1;
@ -234,16 +232,16 @@ int CoreWords::findi(const char *word)
int CoreWords::findi(State& state, Word word) int CoreWords::findi(State& state, Word word)
{ {
std::size_t i; std::size_t i = 0;
int wordsi = 0; int wordsi = 0;
for (i = 0; i < sizeof(wordsarr);) { while (i < sizeof(wordsarr)) {
auto end = i; auto end = i;
while (wordsarr[end] > '\1') while (wordsarr[end])
++end; ++end;
if (state.dict.equal(word, wordsarr + i, end - i)) if (state.dict.equal(word, wordsarr + i, end - i))
return wordsarr[end] == '\0' ? wordsi : (wordsi | Immediate); return wordsi;
++wordsi; ++wordsi;
i = end + 1; i = end + 1;

@ -29,22 +29,22 @@ class CoreWords
public: public:
constexpr static std::size_t WordCount = 32; constexpr static std::size_t WordCount = 32;
constexpr static Cell Immediate = (1 << 5); constexpr static Cell Immediate = (1 << 6);
constexpr static int Semicolon = 26;
static int findi(const char *); static int findi(const char *);
static int findi(State&, Word); static int findi(State&, Word);
static void run(unsigned int, State&); static void run(unsigned int, State&);
private: private:
// Ends with '\0': regular word
// Ends with '\1': compile-only word
constexpr static char wordsarr[] = constexpr static char wordsarr[] =
"_lit\0drop\0dup\0swap\0pick\0sys\0" "_lit\0drop\0dup\0swap\0pick\0sys\0"
"+\0-\0m*\0_/\0_%\0" "+\0-\0m*\0_/\0_%\0"
"_@\0_!\0>r\0r>\0=\0" "_@\0_!\0>r\0r>\0=\0"
"<\0&\0|\0^\0" "<\0&\0|\0^\0"
"<<\0>>\0:\0'\0execute\0" "<<\0>>\0:\0'\0execute\0"
"exit\0;\1_jmp0\0_jmp\0" "exit\0;\0_jmp0\0_jmp\0"
"depth\0_rdepth\0key\0"; "depth\0_rdepth\0key\0";
}; };

@ -72,7 +72,7 @@ Addr Dictionary::find(Word word) noexcept
if (equal(word, lw)) if (equal(word, lw))
return lt; return lt;
else else
lt -= l >> 6; lt -= l >> 7;
} while (lt != oldlt); } while (lt != oldlt);
return 0; return 0;

@ -62,8 +62,9 @@ int Parser::parseWord(State& state, Word word)
if (ins < 0) { if (ins < 0) {
return parseNumber(state, word); return parseNumber(state, word);
} else { } else {
imm = ins & CoreWords::Immediate; imm = ins == CoreWords::Semicolon;
ins &= ~CoreWords::Immediate; ins &= ~CoreWords::Immediate;
ins = (ins << 1) | 1;
} }
} else { } else {
imm = state.dict.read(ins) & CoreWords::Immediate; imm = state.dict.read(ins) & CoreWords::Immediate;
@ -97,8 +98,14 @@ int Parser::parseNumber(State& state, Word word)
if (ec == std::errc() && ptr == buf + i) { if (ec == std::errc() && ptr == buf + i) {
if (state.compiling()) { if (state.compiling()) {
state.dict.add(CoreWords::findi("_lit")); auto ins = (CoreWords::findi("_lit") << 1) | 1;
state.dict.add(l);
if (l >= 0 && l < 0xFF) {
state.dict.add(ins | ((l + 1) << 8));
} else {
state.dict.add(ins);
state.dict.add(l);
}
} else { } else {
state.push(l); state.push(l);
} }

@ -33,25 +33,24 @@ void State::compiling(bool yes)
State::Error State::execute(Addr addr) State::Error State::execute(Addr addr)
{ {
auto stat = setjmp(jmpbuf); auto stat = static_cast<State::Error>(setjmp(jmpbuf));
if (!stat) {
if (addr < CoreWords::WordCount) { if (stat == State::Error::none) {
CoreWords::run(addr, *this); CoreWords::run(addr, *this);
ip = 0;
} else {
auto ins = addr;
for (;;) { if (ip >= Dictionary::Begin) {
CoreWords::run(ins, *this); // longjmp will exit this loop.
ins = dict.read(ip); for (;;)
} CoreWords::run(dict.read(ip), *this);
} else {
// addr was a CoreWord, all done now.
ip = 0;
} }
} else { } else if (stat == State::Error::exit) {
auto err = static_cast<State::Error>(stat); stat = State::Error::none;
return err == State::Error::exit ? State::Error::none : err;
} }
return State::Error::none; return stat;
} }
std::size_t State::size() const noexcept std::size_t State::size() const noexcept

@ -31,7 +31,7 @@ constexpr unsigned ReturnStackSize = 16;
struct State struct State
{ {
enum class Error : int { enum class Error : int {
none, none = 0,
push, push,
pop, pop,
pushr, pushr,

Loading…
Cancel
Save