ruby-changes:68684
From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:12:21 +0900 (JST)
Subject: [ruby-changes:68684] b761f5c96f (master): Implemented mechanism for rel32 call
https://git.ruby-lang.org/ruby.git/commit/?id=b761f5c96f From b761f5c96ff1635aeeb26bb7ba6cb2b30adcddaf Mon Sep 17 00:00:00 2001 From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...> Date: Fri, 23 Oct 2020 10:59:22 -0400 Subject: Implemented mechanism for rel32 call --- ujit_asm.c | 36 +++++++++++++++++++++++++++++++++++- ujit_asm.h | 1 + ujit_compile.c | 3 +-- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/ujit_asm.c b/ujit_asm.c index c99ad37d66..0b833445b2 100644 --- a/ujit_asm.c +++ b/ujit_asm.c @@ -758,7 +758,7 @@ void cb_write_jcc_ptr(codeblock_t* cb, const char* mnem, uint8_t op0, uint8_t op https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L758 cb_write_byte(cb, op0); cb_write_byte(cb, op1); - // Pointer to the end of this jump + // Pointer to the end of this jump instruction uint8_t* end_ptr = &cb->mem_block[cb->write_pos] + 4; // Compute the jump offset @@ -822,6 +822,40 @@ void and(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L822 ); } +// call - Call to a pointer with a 32-bit displacement offset +void call_rel32(codeblock_t* cb, int32_t rel32) +{ + //cb.writeASM("call", rel32); + + // Write the opcode + cb_write_byte(cb, 0xE8); + + // Write the relative 32-bit jump offset + cb_write_int(cb, (int32_t)rel32, 32); +} + +// call - Call a pointer, encode with a 32-bit offset if possible +void call_ptr(codeblock_t* cb, x86opnd_t scratch_reg, uint8_t* dst_ptr) +{ + assert (scratch_reg.type == OPND_REG); + + // Pointer to the end of this call instruction + uint8_t* end_ptr = &cb->mem_block[cb->write_pos] + 5; + + // Compute the jump offset + int64_t rel64 = (int64_t)(dst_ptr - end_ptr); + + // If the offset fits in 32-bit + if (rel64 >= -2147483648 && rel64 <= 2147483647) + { + return call_rel32(cb, (int32_t)rel64); + } + + // Move the pointer into the scratch register and call + mov(cb, scratch_reg, const_ptr_opnd(dst_ptr)); + call(cb, scratch_reg); +} + /// call - Call to label with 32-bit offset void call_label(codeblock_t* cb, size_t label_idx) { diff --git a/ujit_asm.h b/ujit_asm.h index 6d6b18b0a9..ca5e8884ce 100644 --- a/ujit_asm.h +++ b/ujit_asm.h @@ -254,6 +254,7 @@ void cb_link_labels(codeblock_t* cb); https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L254 // Encode individual instructions into a code block void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1); void and(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1); +void call_ptr(codeblock_t* cb, x86opnd_t scratch_reg, uint8_t* dst_ptr); void call_label(codeblock_t* cb, size_t label_idx); void call(codeblock_t* cb, x86opnd_t opnd); void cmova(codeblock_t* cb, x86opnd_t dst, x86opnd_t src); diff --git a/ujit_compile.c b/ujit_compile.c index dcf4b672c9..678f84c977 100644 --- a/ujit_compile.c +++ b/ujit_compile.c @@ -668,8 +668,7 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L668 // Call the C function // VALUE ret = (cfunc->func)(recv, argv[0], argv[1]); - mov(cb, REG0, const_ptr_opnd(cfunc->func)); - call(cb, REG0); + call_ptr(cb, REG0, cfunc->func); //print_str(cb, "after C call"); -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/