Bug 1763054 - adjust the encoding of arm64 fp constants. r=nbp

Following Clang11, encode a 0.0 as MOVI and a -0.0 as MOVI+FNEG.  This
avoids gpr->fpr moves and loads from memory everywhere and probably
insulates us a little from microarchitectural differences.

Differential Revision: https://phabricator.services.mozilla.com/D143018
This commit is contained in:
Lars T Hansen 2022-04-06 11:49:19 +00:00
Родитель d93d2c78e3
Коммит 9db44075c2
2 изменённых файлов: 24 добавлений и 7 удалений

Просмотреть файл

@ -298,7 +298,7 @@ codegenTestARM64_adhoc(
(func (export "f") (param $a f64) (param $b f64) (param $c f64) (param $d f64) (result f64)
(select (local.get $b) (local.get $d) (f64.lt (f64.const 0) (local.get $c)))))`,
'f',
`9e6703e0 fmov d0, xzr
`2f00e400 movi d0, #0x0
1e622000 fcmp d0, d2
1e633c20 fcsel d0, d1, d3, lo`)

Просмотреть файл

@ -1585,14 +1585,31 @@ class MacroAssemblerCompat : public vixl::MacroAssembler {
}
void loadConstantDouble(double d, FloatRegister dest) {
// Note, for -0.0 this will turn into a pc-relative load from memory, not a
// `fmov + fneg` sequence. The former is believed to be better, as gcc,
// clang, and vixl all choose it.
Fmov(ARMFPRegister(dest, 64), d);
ARMFPRegister r(dest, 64);
if (d == 0.0) {
// Clang11 does movi for 0 and movi+fneg for -0, and this seems like a
// good implementation-independent strategy as it avoids any gpr->fpr
// moves or memory traffic.
Movi(r, 0);
if (std::signbit(d)) {
Fneg(r, r);
}
} else {
Fmov(r, d);
}
}
void loadConstantFloat32(float f, FloatRegister dest) {
// See comment in loadConstantDouble.
Fmov(ARMFPRegister(dest, 32), f);
ARMFPRegister r(dest, 32);
if (f == 0.0) {
// See comments above. There's not a movi variant for a single register,
// so clear the double.
Movi(ARMFPRegister(dest, 64), 0);
if (std::signbit(f)) {
Fneg(r, r);
}
} else {
Fmov(r, f);
}
}
void cmpTag(Register tag, ImmTag ref) {