summaryrefslogtreecommitdiff
path: root/misc
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2021-11-05 15:44:29 -0400
committerGitHub <noreply@github.com>2021-11-05 15:44:29 -0400
commit91a9062626733c7d11ea4795bd1957a21f2adec6 (patch)
treee844b4b0c7c8c52e26701539b0fba103a58425f6 /misc
parent82ae9b092cf51062c49b95e81ad184e1dea0df1e (diff)
downloadruby-91a9062626733c7d11ea4795bd1957a21f2adec6.tar.gz
YJIT: use shorter encoding for mov(r64,imm) when unambiguous (#5081)
* YJIT: use shorter encoding for mov(r64,imm) when unambiguous Previously, for small constants such as `mov(RAX, imm_opnd(Qundef))`, we emit an instruction with an 8-byte immediate. This form commonly gets the `movabs` mnemonic. In 64-bit mode, 32-bit operands get zero extended to 64-bit to fill the register, so when the immediate is small enough, we can save 4 bytes by using the `mov` variant that takes a 32-bit immediate and does a zero extension. Not implement with this change, there is an imm32 variant of `mov` that does sign extension we could use. When the constant is negative, we fallback to the `movabs` form. In railsbench, this change yields roughly a 12% code size reduction for the outlined block. Co-authored-by: Jemma Issroff <jemmaissroff@gmail.com> * [ci skip] comment edit. Please squash. Co-authored-by: Jemma Issroff <jemmaissroff@gmail.com>
Diffstat (limited to 'misc')
-rw-r--r--misc/yjit_asm_tests.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/misc/yjit_asm_tests.c b/misc/yjit_asm_tests.c
index 5708d3abad..5548af07f5 100644
--- a/misc/yjit_asm_tests.c
+++ b/misc/yjit_asm_tests.c
@@ -182,10 +182,20 @@ void run_assembler_tests(void)
// mov
cb_set_pos(cb, 0); mov(cb, EAX, imm_opnd(7)); check_bytes(cb, "B807000000");
cb_set_pos(cb, 0); mov(cb, EAX, imm_opnd(-3)); check_bytes(cb, "B8FDFFFFFF");
- cb_set_pos(cb, 0); mov(cb, R15, imm_opnd(3)); check_bytes(cb, "49BF0300000000000000");
+ cb_set_pos(cb, 0); mov(cb, R15, imm_opnd(3)); check_bytes(cb, "41BF03000000");
cb_set_pos(cb, 0); mov(cb, EAX, EBX); check_bytes(cb, "89D8");
cb_set_pos(cb, 0); mov(cb, EAX, ECX); check_bytes(cb, "89C8");
cb_set_pos(cb, 0); mov(cb, EDX, mem_opnd(32, RBX, 128)); check_bytes(cb, "8B9380000000");
+
+ // Test `mov rax, 3` => `mov eax, 3` optimization
+ cb_set_pos(cb, 0); mov(cb, R8, imm_opnd(0x34)); check_bytes(cb, "41B834000000");
+ cb_set_pos(cb, 0); mov(cb, R8, imm_opnd(0x80000000)); check_bytes(cb, "49B80000008000000000");
+ cb_set_pos(cb, 0); mov(cb, R8, imm_opnd(-1)); check_bytes(cb, "49B8FFFFFFFFFFFFFFFF");
+
+ cb_set_pos(cb, 0); mov(cb, RAX, imm_opnd(0x34)); check_bytes(cb, "B834000000");
+ cb_set_pos(cb, 0); mov(cb, RAX, imm_opnd(0x80000000)); check_bytes(cb, "48B80000008000000000");
+ cb_set_pos(cb, 0); mov(cb, RAX, imm_opnd(-52)); check_bytes(cb, "48B8CCFFFFFFFFFFFFFF");
+ cb_set_pos(cb, 0); mov(cb, RAX, imm_opnd(-1)); check_bytes(cb, "48B8FFFFFFFFFFFFFFFF");
/*
test(
delegate void (CodeBlock cb) { cb.mov(X86Opnd(AL), X86Opnd(8, RCX, 0, 1, RDX)); },