Skip to content

Commit

Permalink
[mono][jit] Improved imm64 for negative numbers (#93602)
Browse files Browse the repository at this point in the history
* emit_imm64 on arm64 should now emit optimal code even for negative int constants.

* Handle edge case.
  • Loading branch information
jandupej authored Oct 26, 2023
1 parent 40f23e3 commit 2f6f3c5
Showing 1 changed file with 29 additions and 14 deletions.
43 changes: 29 additions & 14 deletions src/mono/mono/mini/mini-arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,24 +509,39 @@ emit_imm (guint8 *code, int dreg, int imm)
static guint8*
emit_imm64 (guint8 *code, int dreg, guint64 imm)
{
if (imm == 0) {
arm_movzx (code, dreg, 0, 0);
} else {
gboolean is_inited = FALSE;
// Determine if there is more advantage to using movn or movz for initialization.
int num0 = 0, num1 = 0;
for (int idx = 0; idx < 64; idx+=16) {
int w = (imm >> idx) & 0xffff;
if (w == 0)
num0++;
else if (w == 0xffff)
num1++;
}

for (int idx = 0; idx < 64; idx += 16) {
int w = (imm >> idx) & 0xffff;
gboolean is_negated = num1 > num0;
gboolean is_inited = FALSE;

if (w) {
if (is_inited) {
arm_movkx (code, dreg, w, idx);
} else {
arm_movzx (code, dreg, w, idx);
is_inited = TRUE;
}
}
for (int idx = 0; idx < 64; idx+=16) {
int w = (imm >> idx) & 0xffff;
if (!is_inited && is_negated && w != 0xffff) {
arm_movnx (code, dreg, (~w) & 0xffff, idx);
is_inited = TRUE;
} else if (!is_inited && !is_negated && w != 0x0) {
arm_movzx (code, dreg, w, idx);
is_inited = TRUE;
} else if (is_inited && ((is_negated && w != 0xffff) || (!is_negated && w != 0x0))) {
arm_movkx (code, dreg, w, idx);
}
}

if (!is_inited) {
if (is_negated)
arm_movnx (code, dreg, 0, 0);
else
arm_movzx (code, dreg, 0, 0);
}

return code;
}

Expand Down

0 comments on commit 2f6f3c5

Please sign in to comment.