diff options
author | Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> | 2020-09-17 17:09:42 -0400 |
---|---|---|
committer | Alan Wu <XrXr@users.noreply.github.com> | 2021-10-20 18:19:23 -0400 |
commit | b8a3f2ed6177c753a35feaa4239a47de0a97ee77 (patch) | |
tree | 0d09d5143b633bff6f3edeeb138219fb3a8360d1 | |
parent | 77cfdb24d4d7445a6e8f4a110d4e2159360f3c2b (diff) |
Add function to print strings from generated code
-rw-r--r-- | common.mk | 1 | ||||
-rw-r--r-- | ujit_asm.c | 12 | ||||
-rw-r--r-- | ujit_asm.h | 1 | ||||
-rw-r--r-- | ujit_compile.c | 2 | ||||
-rw-r--r-- | ujit_utils.c | 96 | ||||
-rw-r--r-- | ujit_utils.h | 13 |
6 files changed, 118 insertions, 7 deletions
@@ -151,6 +151,7 @@ COMMONOBJS = array.$(OBJEXT) \ vm_sync.$(OBJEXT) \ vm_trace.$(OBJEXT) \ ujit_asm.$(OBJEXT) \ + ujit_utils.$(OBJEXT) \ ujit_compile.$(OBJEXT) \ $(COROUTINE_OBJ) \ $(DTRACE_OBJ) \ diff --git a/ujit_asm.c b/ujit_asm.c index c7221091ca..55dc517bdb 100644 --- a/ujit_asm.c +++ b/ujit_asm.c @@ -1084,15 +1084,13 @@ void jmp8(CodeBlock cb, int8_t offset) } */ -/* -/// jmp - Jump with relative 32-bit offset -void jmp32(CodeBlock cb, int32_t offset) +// jmp - Jump with relative 32-bit offset +void jmp32(codeblock_t* cb, int32_t offset) { - cb.writeASM("jmp", ((offset > 0)? "+":"-") ~ to!string(offset)); - cb.writeByte(JMP_REL32_OPCODE); - cb.writeInt(offset, 32); + //cb.writeASM("jmp", ((offset > 0)? "+":"-") ~ to!string(offset)); + cb_write_byte(cb, 0xE9); + cb_write_int(cb, offset, 32); } -*/ /// lea - Load Effective Address void lea(codeblock_t* cb, x86opnd_t dst, x86opnd_t src) diff --git a/ujit_asm.h b/ujit_asm.h index f47e5a2059..595e20eed1 100644 --- a/ujit_asm.h +++ b/ujit_asm.h @@ -265,6 +265,7 @@ void js(codeblock_t* cb, size_t label_idx); void jz(codeblock_t* cb, size_t label_idx); void jmp(codeblock_t* cb, size_t label_idx); void jmp_rm(codeblock_t* cb, x86opnd_t opnd); +void jmp32(codeblock_t* cb, int32_t offset); void lea(codeblock_t* cb, x86opnd_t dst, x86opnd_t src); void mov(codeblock_t* cb, x86opnd_t dst, x86opnd_t src); void neg(codeblock_t* cb, x86opnd_t opnd); diff --git a/ujit_compile.c b/ujit_compile.c index 2b4b1ad03e..30657f88bf 100644 --- a/ujit_compile.c +++ b/ujit_compile.c @@ -7,8 +7,10 @@ #include "insns_info.inc" #include "ujit_compile.h" #include "ujit_asm.h" +#include "ujit_utils.h" // TODO: give ujit_examples.h some more meaningful file name +// eg ujit_hook.h #include "ujit_examples.h" // Code generation context diff --git a/ujit_utils.c b/ujit_utils.c new file mode 100644 index 0000000000..35fe8f4f8c --- /dev/null +++ b/ujit_utils.c @@ -0,0 +1,96 @@ +#include <stdio.h> +#include <string.h> +#include "ujit_utils.h" +#include "ujit_asm.h" + +// Save caller-save registers on the stack before a C call +void push_regs(codeblock_t* cb) +{ + push(cb, RAX); + push(cb, RCX); + push(cb, RDX); + push(cb, RSI); + push(cb, RDI); + push(cb, R8); + push(cb, R9); + push(cb, R10); + push(cb, R11); + pushfq(cb); +} + +// Restore caller-save registers from the after a C call +void pop_regs(codeblock_t* cb) +{ + popfq(cb); + pop(cb, R11); + pop(cb, R10); + pop(cb, R9); + pop(cb, R8); + pop(cb, RDI); + pop(cb, RSI); + pop(cb, RDX); + pop(cb, RCX); + pop(cb, RAX); +} + +static void print_str_fn(const char* str) +{ + printf("%s", str); +} + +/* +void printInt(CodeBlock as, X86Opnd opnd) +{ + extern (C) void printIntFn(int64_t v) + { + writefln("%s", v); + } + + size_t opndSz; + if (opnd.isImm) + opndSz = 64; + else if (opnd.isGPR) + opndSz = opnd.reg.size; + else if (opnd.isMem) + opndSz = opnd.mem.size; + else + assert (false); + + as.pushRegs(); + + if (opndSz < 64) + as.movsx(cargRegs[0].opnd(64), opnd); + else + as.mov(cargRegs[0].opnd(64), opnd); + + // Call the print function + as.ptr(scrRegs[0], &printIntFn); + as.call(scrRegs[0]); + + as.popRegs(); +} +*/ + +// Print a constant string to stdout +void print_str(codeblock_t* cb, const char* str) +{ + //as.comment("printStr(\"" ~ str ~ "\")"); + size_t len = strlen(str); + + push_regs(cb); + + // Load the string address and jump over the string data + lea(cb, RDI, mem_opnd(8, RIP, 5)); + jmp32(cb, (int32_t)len + 1); + + // Write the string chars and a null terminator + for (size_t i = 0; i < len; ++i) + cb_write_byte(cb, (uint8_t)str[i]); + cb_write_byte(cb, 0); + + // Call the print function + mov(cb, RAX, const_ptr_opnd(&print_str_fn)); + call(cb, RAX); + + pop_regs(cb); +} diff --git a/ujit_utils.h b/ujit_utils.h new file mode 100644 index 0000000000..eaaba4288d --- /dev/null +++ b/ujit_utils.h @@ -0,0 +1,13 @@ +#ifndef UJIT_UTILS_H +#define UJIT_UTILS_H 1 + +#include <stdint.h> +#include <stddef.h> +#include <stdbool.h> +#include "ujit_asm.h" + +void push_regs(codeblock_t* cb); +void pop_regs(codeblock_t* cb); +void print_str(codeblock_t* cb, const char* str); + +#endif // #ifndef UJIT_UTILS_H |