diff options
author | Björn Gustavsson <bjorn@erlang.org> | 2021-10-09 10:31:27 +0200 |
---|---|---|
committer | Björn Gustavsson <bjorn@erlang.org> | 2021-10-14 04:59:22 +0200 |
commit | 2ac5f27a4115b5c0fcad0e6b3029e679e4c00afd (patch) | |
tree | 14e3eb2bcc904d3062c3212692aa1309a5837ad1 | |
parent | c9bb64f18b7dc3b3a375f99c529c069656519192 (diff) | |
download | erlang-2ac5f27a4115b5c0fcad0e6b3029e679e4c00afd.tar.gz |
Enhance the mov_imm() helper
Generate a shorter instruction for unsigned immediate values that
fit in 32 bits.
-rw-r--r-- | erts/emulator/beam/jit/x86/beam_asm.hpp | 15 | ||||
-rw-r--r-- | 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<T>::value || std::is_pointer<T>::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 |