ruby-changes:68580
From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:09:57 +0900 (JST)
Subject: [ruby-changes:68580] b8a3f2ed61 (master): Add function to print strings from generated code
https://git.ruby-lang.org/ruby.git/commit/?id=b8a3f2ed61 From b8a3f2ed6177c753a35feaa4239a47de0a97ee77 Mon Sep 17 00:00:00 2001 From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...> Date: Thu, 17 Sep 2020 17:09:42 -0400 Subject: Add function to print strings from generated code --- common.mk | 1 + ujit_asm.c | 12 +++----- ujit_asm.h | 1 + ujit_compile.c | 2 ++ ujit_utils.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ujit_utils.h | 13 ++++++++ 6 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 ujit_utils.c create mode 100644 ujit_utils.h diff --git a/common.mk b/common.mk index 7f29300c9e..dc0c558b9c 100644 --- a/common.mk +++ b/common.mk @@ -151,6 +151,7 @@ COMMONOBJS = array.$(OBJEXT) \ https://github.com/ruby/ruby/blob/trunk/common.mk#L151 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) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L1084 } */ -/* -/// 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); https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L265 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 @@ https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L7 #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 @@ https://github.com/ruby/ruby/blob/trunk/ujit_utils.c#L1 +#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 @@ https://github.com/ruby/ruby/blob/trunk/ujit_utils.h#L1 +#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 -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/