summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Gustavsson <bjorn@erlang.org>2021-10-09 10:31:27 +0200
committerBjörn Gustavsson <bjorn@erlang.org>2021-10-14 04:59:22 +0200
commit2ac5f27a4115b5c0fcad0e6b3029e679e4c00afd (patch)
tree14e3eb2bcc904d3062c3212692aa1309a5837ad1
parentc9bb64f18b7dc3b3a375f99c529c069656519192 (diff)
downloaderlang-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.hpp15
-rw-r--r--erts/emulator/beam/jit/x86/instr_common.cpp7
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