From 6aefc5167a64e05580dcf1afc70efa496ed145ac Mon Sep 17 00:00:00 2001 From: Kimplul Date: Tue, 27 Jun 2023 13:00:19 +0300 Subject: add immediate loading --- src/copyjit.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++---------- src/copyjit.h | 22 ++++++- src/main.c | 12 ++-- src/source.mk | 6 ++ 4 files changed, 187 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/copyjit.c b/src/copyjit.c index f1cf62c..f09cb99 100644 --- a/src/copyjit.c +++ b/src/copyjit.c @@ -3,12 +3,17 @@ #include #include #include +#include #include #include "copyjit.h" #include "../lib/ops.h" -#include "../lib/defns.h" +#include "../lib/op_defns.h" + +#include "../lib/imm.h" +#include "../lib/imm_defns.h" + #include "../ops/common.h" #define SELECT(i, ctx, name) \ @@ -275,18 +280,59 @@ case i: name##i (ctx); break; SELECT(254, ctx, name) \ SELECT(255, ctx, name) -static void select_uli(ctx_t *ctx, uint8_t i) +static void select_lio(ctx_t *ctx, uint8_t i) +{ + switch (i) { + SELECT256(ctx, compile_lio); + } +} + +static void select_lia(ctx_t *ctx, uint8_t i) +{ + switch (i) { + SELECT256(ctx, compile_lia); + } +} + +static void select_lix(ctx_t *ctx, uint8_t i) +{ + switch (i) { + SELECT256(ctx, compile_lix); + } +} + +static void select_liy(ctx_t *ctx, uint8_t i) +{ + switch (i) { + SELECT256(ctx, compile_liy); + } +} + +static void select_addio(ctx_t *ctx, uint8_t i) +{ + switch (i) { + SELECT256(ctx, compile_addio); + } +} + +static void select_addia(ctx_t *ctx, uint8_t i) +{ + switch (i) { + SELECT256(ctx, compile_addia); + } +} + +static void select_addix(ctx_t *ctx, uint8_t i) { - /* should maybe be uli? */ switch (i) { - SELECT256(ctx, compile_li); + SELECT256(ctx, compile_addix); } } -static void select_uaddi(ctx_t *ctx, uint8_t i) +static void select_addiy(ctx_t *ctx, uint8_t i) { switch (i) { - SELECT256(ctx, compile_addi); + SELECT256(ctx, compile_addiy); } } @@ -297,41 +343,119 @@ static void select_slo(ctx_t *ctx, uint8_t i) } } -#define NTH_BYTE(i, n) ((i) >> ((n) * 8) & 0xff) -void *compile_uli(ctx_t *ctx, unsigned long i) +void *compile_fast_lio(ctx_t *ctx, unsigned long i) +{ + void *pc = ctx->pc; + + /* if we can trivially fit the value into a fast block, do it */ + if (i < 256) { + select_lio(ctx, i); + return pc; + } + + /* otherwise use generic option */ + compile_lio(ctx, i); + return pc; +} + +void *compile_fast_lia(ctx_t *ctx, unsigned long i) +{ + void *pc = ctx->pc; + + /* if we can trivially fit the value into a fast block, do it */ + if (i < 256) { + select_lia(ctx, i); + return pc; + } + + /* otherwise use generic option */ + compile_lia(ctx, i); + return pc; +} + +void *compile_fast_lix(ctx_t *ctx, unsigned long i) +{ + void *pc = ctx->pc; + + /* if we can trivially fit the value into a fast block, do it */ + if (i < 256) { + select_lix(ctx, i); + return pc; + } + + /* otherwise use generic option */ + compile_lix(ctx, i); + return pc; +} + +void *compile_fast_liy(ctx_t *ctx, unsigned long i) +{ + void *pc = ctx->pc; + + /* if we can trivially fit the value into a fast block, do it */ + if (i < 256) { + select_liy(ctx, i); + return pc; + } + + /* otherwise use generic option */ + compile_liy(ctx, i); + return pc; +} + +void *compile_fast_addio(ctx_t *ctx, unsigned long i) +{ + void *pc = ctx->pc; + if (i < 256) { + select_addio(ctx, i); + return pc; + } + + compile_addio(ctx, i); + return pc; +} + +void *compile_fast_addia(ctx_t *ctx, unsigned long i) { void *pc = ctx->pc; + if (i < 256) { + select_addia(ctx, i); + return pc; + } + + compile_addia(ctx, i); + return pc; +} +void *compile_fast_addix(ctx_t *ctx, unsigned long i) +{ + void *pc = ctx->pc; if (i < 256) { - select_uli(ctx, i); + select_addix(ctx, i); return pc; } - /* find first non-zero byte */ - int nz = sizeof(unsigned long) - 1; - for (; nz >= 0; --nz) - if (NTH_BYTE(i, nz) != 0) - break; - - /* start populating */ - select_uli(ctx, i >> (nz * 8)); - - size_t shifts = 1; - for (nz--; nz >= 0; --nz) { - if (NTH_BYTE(i, nz) == 0) { - shifts++; - continue; - } - - select_slo(ctx, shifts * 8); - select_uaddi(ctx, NTH_BYTE(i, nz)); - shifts = 1; + compile_addix(ctx, i); + return pc; +} + +void *compile_fast_addiy(ctx_t *ctx, unsigned long i) +{ + void *pc = ctx->pc; + if (i < 256) { + select_addiy(ctx, i); + return pc; } - /* last octet is zero, meaning it fell through the for loop */ - if (shifts != 1) - select_slo(ctx, (shifts - 1) * 8); + compile_addiy(ctx, i); + return pc; +} +void *compile_slo(ctx_t *ctx, unsigned long i) +{ + assert(i < 64); + void *pc = ctx->pc; + select_slo(ctx, i); return pc; } diff --git a/src/copyjit.h b/src/copyjit.h index 69c34cb..6c0a247 100644 --- a/src/copyjit.h +++ b/src/copyjit.h @@ -9,9 +9,27 @@ typedef struct { size_t size; } ctx_t; -#include "../lib/decls.h" +#include "../lib/op_decls.h" +#include "../lib/imm_decls.h" + +void *compile_fast_lio(ctx_t *ctx, unsigned long i); +void *compile_fast_lia(ctx_t *ctx, unsigned long i); +void *compile_fast_lix(ctx_t *ctx, unsigned long i); +void *compile_fast_liy(ctx_t *ctx, unsigned long i); + +void *compile_fast_addio(ctx_t *ctx, unsigned long i); +void *compile_fast_addia(ctx_t *ctx, unsigned long i); +void *compile_fast_addix(ctx_t *ctx, unsigned long i); +void *compile_fast_addiy(ctx_t *ctx, unsigned long i); + +void *compile_slo(ctx_t *ctx, unsigned long i); +void *compile_sla(ctx_t *ctx, unsigned long i); +void *compile_slx(ctx_t *ctx, unsigned long i); +void *compile_sly(ctx_t *ctx, unsigned long i); + +/** @todo add in placeholders (for example for load immediate but we don't know + * what the immediate is yet) */ -void *compile_uli(ctx_t *ctx, unsigned long i); void compile_start(ctx_t *ctx); void compile_finish(ctx_t *ctx); void run(ctx_t *ctx); diff --git a/src/main.c b/src/main.c index c0e757f..78f9f9e 100644 --- a/src/main.c +++ b/src/main.c @@ -10,20 +10,20 @@ int main() ctx_t ctx; compile_start(&ctx); - compile_uli(&ctx, 0); // total in a - compile_movao(&ctx); + compile_fast_lia(&ctx, 0); // total in a - compile_uli(&ctx, 0); - compile_movyo(&ctx); // iter in y + compile_fast_liy(&ctx, 0); void *top = compile_movxa(&ctx); // iter + total in a compile_add(&ctx); compile_incy(&ctx); // increment iter - compile_uli(&ctx, 1000000000); // limit in o + compile_fast_lio(&ctx, 1000000000); // limit in o compile_subyo(&ctx); - compile_uli(&ctx, (uintptr_t)top); // branch target in o + compile_fast_lio(&ctx, (uintptr_t)top); // branch target in o + /* if we already know the offset, we could generate a ban with immediate + * offsets to save one register? */ compile_ban(&ctx); compile_end(&ctx); diff --git a/src/source.mk b/src/source.mk index de98d32..618d385 100644 --- a/src/source.mk +++ b/src/source.mk @@ -1,2 +1,8 @@ SRC_LOCAL != echo src/*.c SOURCES += $(SRC_LOCAL) + +# a bit ugly maybe, but I'm not aware of a better way to tell make +# "hey, these files have to generate some stuff for us" +src/main.c: src/copyjit.h +src/copyjit.c: src/copyjit.h +src/copyjit.h: lib/op_decls.h lib/imm_decls.h -- cgit v1.3