From 2ac5f27a4115b5c0fcad0e6b3029e679e4c00afd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Sat, 9 Oct 2021 10:31:27 +0200 Subject: Enhance the mov_imm() helper Generate a shorter instruction for unsigned immediate values that fit in 32 bits. --- erts/emulator/beam/jit/x86/beam_asm.hpp | 15 ++++++++++++++- erts/emulator/beam/jit/x86/instr_common.cpp | 7 ++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/erts/emulator/beam/jit/x86/beam_asm.hpp b/erts/emulator/beam/jit/x86/beam_asm.hpp index dee1edebb5..5e83c7e83c 100644 --- a/erts/emulator/beam/jit/x86/beam_asm.hpp +++ b/erts/emulator/beam/jit/x86/beam_asm.hpp @@ -795,7 +795,20 @@ protected: void mov_imm(x86::Gp to, T value) { static_assert(std::is_integral::value || std::is_pointer::value); if (value) { - a.mov(to, imm(value)); + /* Generate the shortest instruction to set the register to an + * immediate. + * + * 48 c7 c0 2a 00 00 00 mov rax, 42 + * b8 2a 00 00 00 mov eax, 42 + * + * 49 c7 c0 2a 00 00 00 mov r8, 42 + * 41 b8 2a 00 00 00 mov r8d, 42 + */ + if (Support::isUInt32((Uint)value)) { + a.mov(to.r32(), imm(value)); + } else { + a.mov(to, imm(value)); + } } else { /* * Generate the shortest instruction to set the register to zero. diff --git a/erts/emulator/beam/jit/x86/instr_common.cpp b/erts/emulator/beam/jit/x86/instr_common.cpp index e0dd4d792b..8d046db40e 100644 --- a/erts/emulator/beam/jit/x86/instr_common.cpp +++ b/erts/emulator/beam/jit/x86/instr_common.cpp @@ -25,10 +25,15 @@ * one byte shorter than instructions that use 64-bits registers * (e.g. rax). This does not apply to registers r8-r15 beacuse they'll * always need a rex prefix. The `and`, `or`, and `cmp` instructions - * are even shorter than operating on the RETb (al) register. The + * are even shorter when operating on the RETb (al) register. The * `test` instruction with an immediate second operand is shorter * when operating on an 8-bit register. * + * When loading an immediate value to a register, storing to the + * 32-bit register in one or two bytes shorter than storing to + * the corresponding 64-bit register. The mov_imm() helper + * will automatically choose the shortest instruction. + * * On both Unix and Windows, instructions can be shortened by using * RETd, ARG1d, or ARG2d instead of RET, ARG1, or ARG2, respectively. * On Unix, but not on Windows, ARG3d and ARG4d will also result in -- cgit v1.2.1