aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2023-06-27 13:00:19 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2023-06-27 13:00:19 +0300
commit6aefc5167a64e05580dcf1afc70efa496ed145ac (patch)
tree57032839fd8f5f748b273c679f3766c6911bbca5 /src
parente80d3758a37848cda7990e8eff68ed9df344afa4 (diff)
downloadcopyjit-6aefc5167a64e05580dcf1afc70efa496ed145ac.tar.gz
copyjit-6aefc5167a64e05580dcf1afc70efa496ed145ac.zip
add immediate loading
Diffstat (limited to 'src')
-rw-r--r--src/copyjit.c180
-rw-r--r--src/copyjit.h22
-rw-r--r--src/main.c12
-rw-r--r--src/source.mk6
4 files changed, 184 insertions, 36 deletions
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 <string.h>
#include <stdint.h>
#include <stdlib.h>
+#include <assert.h>
#include <sys/mman.h>
#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)
{
- /* should maybe be uli? */
switch (i) {
- SELECT256(ctx, compile_li);
+ SELECT256(ctx, compile_lia);
}
}
-static void select_uaddi(ctx_t *ctx, uint8_t i)
+static void select_lix(ctx_t *ctx, uint8_t i)
{
switch (i) {
- SELECT256(ctx, compile_addi);
+ 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)
+{
+ switch (i) {
+ SELECT256(ctx, compile_addix);
+ }
+}
+
+static void select_addiy(ctx_t *ctx, uint8_t i)
+{
+ switch (i) {
+ 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_uli(ctx, i);
+ select_lio(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;
+ /* 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;
+ }
- /* start populating */
- select_uli(ctx, i >> (nz * 8));
+ /* otherwise use generic option */
+ compile_lia(ctx, i);
+ return pc;
+}
- size_t shifts = 1;
- for (nz--; nz >= 0; --nz) {
- if (NTH_BYTE(i, nz) == 0) {
- shifts++;
- continue;
- }
+void *compile_fast_lix(ctx_t *ctx, unsigned long i)
+{
+ void *pc = ctx->pc;
- select_slo(ctx, shifts * 8);
- select_uaddi(ctx, NTH_BYTE(i, nz));
- shifts = 1;
+ /* if we can trivially fit the value into a fast block, do it */
+ if (i < 256) {
+ select_lix(ctx, i);
+ return pc;
}
- /* last octet is zero, meaning it fell through the for loop */
- if (shifts != 1)
- select_slo(ctx, (shifts - 1) * 8);
+ /* 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_addix(ctx, i);
+ return pc;
+ }
+
+ 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;
+ }
+
+ 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