diff options
author | Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> | 2020-09-04 17:10:11 -0400 |
---|---|---|
committer | Alan Wu <XrXr@users.noreply.github.com> | 2021-10-20 18:19:22 -0400 |
commit | 5cf7ccd24a9303b2a591bc0289159517cee6e851 (patch) | |
tree | ffe8527a7eba7640e3247f0c495c70d24b1f5155 /ujit_asm.c | |
parent | 0a5dcc056e22bab849d8d7877928d300201af823 (diff) |
Started porting instruction encoding
Diffstat (limited to 'ujit_asm.c')
-rw-r--r-- | ujit_asm.c | 72 |
1 files changed, 72 insertions, 0 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) } } +// 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) 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); +} +*/ |