ruby-changes:68557
From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:08:15 +0900 (JST)
Subject: [ruby-changes:68557] 5cf7ccd24a (master): Started porting instruction encoding
https://git.ruby-lang.org/ruby.git/commit/?id=5cf7ccd24a From 5cf7ccd24a9303b2a591bc0289159517cee6e851 Mon Sep 17 00:00:00 2001 From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...> Date: Fri, 4 Sep 2020 17:10:11 -0400 Subject: Started porting instruction encoding --- ujit_asm.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ujit_asm.h | 16 +++++++++---- ujit_asm_tests.c | 11 +++++++++ 3 files changed, 94 insertions(+), 5 deletions(-) diff --git a/ujit_asm.c b/ujit_asm.c index 7ff8792059..bb6ad29a5a 100644 --- a/ujit_asm.c +++ b/ujit_asm.c @@ -115,6 +115,52 @@ void cb_write_int(codeblock_t* cb, uint64_t val, size_t num_bits) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L115 } } +// Ruby instruction prologue and epilogue functions +void cb_write_prologue(codeblock_t* cb) +{ + for (size_t i = 0; i < sizeof(ujit_pre_call_bytes); ++i) + cb_write_byte(cb, ujit_pre_call_bytes[i]); +} + +void cb_write_epilogue(codeblock_t* cb) +{ + for (size_t i = 0; i < sizeof(ujit_post_call_bytes); ++i) + cb_write_byte(cb, ujit_post_call_bytes[i]); +} + +// Write the REX byte +void writeREX( + codeblock_t* cb, + bool w_flag, + uint8_t reg_no, + uint8_t idx_reg_no, + uint8_t rm_reg_no +) +{ + // 0 1 0 0 w r x b + // w - 64-bit operand size flag + // r - MODRM.reg extension + // x - SIB.index extension + // b - MODRM.rm or SIB.base extension + uint8_t w = w_flag? 1:0; + uint8_t r = (reg_no & 8)? 1:0; + uint8_t x = (idx_reg_no & 8)? 1:0; + uint8_t b = (rm_reg_no & 8)? 1:0; + + // Encode and write the REX byte + uint8_t rexByte = 0x40 + (w << 3) + (r << 2) + (x << 1) + (b); + cb_write_byte(cb, rexByte); +} + +// Write an opcode byte with an embedded register operand +/*static void cb_write_opcode(codeblock_t* cb, uint8_t opcode, X86Reg rOpnd) +{ + // Write the reg field into the opcode byte + uint8_t op_byte = opcode | (rOpnd.regNo & 7); + cb_write_byte(cb, op_byte); +} +*/ + // nop - Noop, one or multiple bytes long void nop(codeblock_t* cb, size_t length) { @@ -181,3 +227,29 @@ void nop(codeblock_t* cb, size_t length) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L227 break; } } + +/* +/// push - Push a register on the stack +void push(codeblock_t* cb, X86Reg reg) +{ + assert (reg.size is 64, "can only push 64-bit registers"); + + //cb.writeASM("push", reg); + + if (reg.rexNeeded) + cb_write_rex(cb, false, 0, 0, reg.regNo); + cb_write_byte(cb, 0x50, reg); +} + +/// pop - Pop a register off the stack +void pop(codeblock_t* cb, X86Reg reg) +{ + assert (reg.size is 64); + + //cb.writeASM("pop", reg); + + if (reg.rexNeeded) + cb_write_rex(false, 0, 0, reg.regNo); + cb_write_byte(cb, 0x58, reg); +} +*/ diff --git a/ujit_asm.h b/ujit_asm.h index 998c171d5d..b192588c69 100644 --- a/ujit_asm.h +++ b/ujit_asm.h @@ -51,17 +51,23 @@ typedef struct CodeBlock https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L51 } codeblock_t; +typedef struct X86Opnd +{ + + + + +} x86opnd_t; + void cb_init(codeblock_t* cb, size_t mem_size); uint8_t* cb_get_ptr(codeblock_t* cb, size_t index); void cb_write_byte(codeblock_t* cb, uint8_t byte); void cb_write_bytes(codeblock_t* cb, size_t num_bytes, ...); void cb_write_int(codeblock_t* cb, uint64_t val, size_t num_bits); -// TODO: -// prologue and epilogue functions -// cb_write_prologue() -// cb_write_epilogue -// Test those out +// Ruby instruction prologue and epilogue functions +void cb_write_prologue(codeblock_t* cb); +void cb_write_epilogue(codeblock_t* cb); void nop(codeblock_t* cb, size_t length); diff --git a/ujit_asm_tests.c b/ujit_asm_tests.c index 0c94fb8b04..fc8005e56e 100644 --- a/ujit_asm_tests.c +++ b/ujit_asm_tests.c @@ -5,6 +5,14 @@ https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L5 //fprintf(stderr, format); //exit(-1) +// TODO: make a macro to test encoding sequences +// ***You can use sizeof to know the length*** +// CHECK_BYTES(cb, {}) + + + + + void run_tests() { printf("Running assembler tests\n"); @@ -12,6 +20,9 @@ void run_tests() https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L20 codeblock_t cb; cb_init(&cb, 4096); + cb_write_prologue(&cb); + cb_write_epilogue(&cb); + -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/