Intel encodings for nearest/floor/ceil/trunc.
These floating point rounding operations all use the roundss/roundsd instructions that are available in SSE 4.1.
This commit is contained in:
@@ -38,6 +38,7 @@ def gen_recipe(recipe, fmt):
|
||||
with fmt.indented(
|
||||
'if let InstructionData::{} {{'.format(iform.name),
|
||||
'}'):
|
||||
fmt.line('opcode,')
|
||||
for f in iform.imm_fields:
|
||||
fmt.line('{},'.format(f.member))
|
||||
if want_args:
|
||||
|
||||
@@ -11,9 +11,10 @@ from . import settings as cfg
|
||||
from . import instructions as x86
|
||||
from .legalize import intel_expand
|
||||
from base.legalize import narrow, expand
|
||||
from .settings import use_sse41
|
||||
|
||||
try:
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any # noqa
|
||||
if TYPE_CHECKING:
|
||||
from cdsl.instructions import MaybeBoundInst # noqa
|
||||
except ImportError:
|
||||
@@ -82,7 +83,7 @@ def enc_i32_i64_ld_st(inst, w_bit, recipe, *args, **kwargs):
|
||||
|
||||
|
||||
def enc_flt(inst, recipe, *args, **kwargs):
|
||||
# type: (MaybeBoundInst, r.TailRecipe, *int, **int) -> None
|
||||
# type: (MaybeBoundInst, r.TailRecipe, *int, **Any) -> None
|
||||
"""
|
||||
Add encodings for floating point instruction `inst` to both I32 and I64.
|
||||
"""
|
||||
@@ -363,6 +364,16 @@ enc_flt(base.fdemote.f32.f64, r.furm, 0xf2, 0x0f, 0x5a)
|
||||
enc_flt(base.sqrt.f32, r.furm, 0xf3, 0x0f, 0x51)
|
||||
enc_flt(base.sqrt.f64, r.furm, 0xf2, 0x0f, 0x51)
|
||||
|
||||
# Rounding. The recipe looks at the opcode to pick an immediate.
|
||||
for inst in [
|
||||
base.nearest,
|
||||
base.floor,
|
||||
base.ceil,
|
||||
base.trunc]:
|
||||
enc_flt(inst.f32, r.furmi_rnd, 0x66, 0x0f, 0x3a, 0x0a, isap=use_sse41)
|
||||
enc_flt(inst.f64, r.furmi_rnd, 0x66, 0x0f, 0x3a, 0x0b, isap=use_sse41)
|
||||
|
||||
|
||||
# Binary arithmetic ops.
|
||||
for inst, opc in [
|
||||
(base.fadd, 0x58),
|
||||
|
||||
@@ -289,6 +289,21 @@ frurm = TailRecipe(
|
||||
modrm_rr(in_reg0, out_reg0, sink);
|
||||
''')
|
||||
|
||||
# XX /r, RMI form for one of the roundXX SSE 4.1 instructions.
|
||||
furmi_rnd = TailRecipe(
|
||||
'furmi_rnd', Unary, size=2, ins=FPR, outs=FPR,
|
||||
emit='''
|
||||
PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
|
||||
modrm_rr(in_reg0, out_reg0, sink);
|
||||
sink.put1(match opcode {
|
||||
Opcode::Nearest => 0b00,
|
||||
Opcode::Floor => 0b01,
|
||||
Opcode::Ceil => 0b10,
|
||||
Opcode::Trunc => 0b11,
|
||||
x => panic!("{} unexpected for furmi_rnd", opcode),
|
||||
});
|
||||
''')
|
||||
|
||||
# XX /r, for regmove instructions.
|
||||
rmov = TailRecipe(
|
||||
'ur', RegMove, size=1, ins=GPR, outs=(),
|
||||
|
||||
Reference in New Issue
Block a user