Add an avoid_div_traps setting.
This enables code generation that never causes a SIGFPE signal to be raised from a division instruction. Instead, division and remainder calculations are protected by explicit traps.
This commit is contained in:
@@ -41,6 +41,18 @@ return_at_end = BoolSetting(
|
||||
instruction at the end.
|
||||
""")
|
||||
|
||||
avoid_div_traps = BoolSetting(
|
||||
"""
|
||||
Generate explicit checks around native division instructions to avoid
|
||||
their trapping.
|
||||
|
||||
This is primarily used by SpiderMonkey which doesn't install a signal
|
||||
handler for SIGFPE, but expects a SIGILL trap for division by zero.
|
||||
|
||||
On ISAs like ARM where the native division instructions don't trap,
|
||||
this setting has no effect - explicit checks are always inserted.
|
||||
""")
|
||||
|
||||
is_compressed = BoolSetting("Enable compressed instructions")
|
||||
|
||||
enable_float = BoolSetting(
|
||||
|
||||
@@ -5,7 +5,6 @@ from __future__ import absolute_import
|
||||
from cdsl.ast import Var
|
||||
from cdsl.xform import Rtl, XFormGroup
|
||||
from base.immediates import imm64, intcc, floatcc
|
||||
from base.types import i32, i64
|
||||
from base import legalize as shared
|
||||
from base import instructions as insts
|
||||
from . import instructions as x86
|
||||
@@ -31,31 +30,12 @@ a2 = Var('a2')
|
||||
#
|
||||
# Division and remainder.
|
||||
#
|
||||
intel_expand.legalize(
|
||||
a << insts.udiv(x, y),
|
||||
Rtl(
|
||||
xhi << insts.iconst(imm64(0)),
|
||||
(a, dead) << x86.udivmodx(x, xhi, y)
|
||||
))
|
||||
|
||||
intel_expand.legalize(
|
||||
a << insts.urem(x, y),
|
||||
Rtl(
|
||||
xhi << insts.iconst(imm64(0)),
|
||||
(dead, a) << x86.udivmodx(x, xhi, y)
|
||||
))
|
||||
|
||||
for ty in [i32, i64]:
|
||||
intel_expand.legalize(
|
||||
a << insts.sdiv.bind(ty)(x, y),
|
||||
Rtl(
|
||||
xhi << insts.sshr_imm(x, imm64(ty.lane_bits() - 1)),
|
||||
(a, dead) << x86.sdivmodx(x, xhi, y)
|
||||
))
|
||||
|
||||
# The srem expansion requires custom code because srem INT_MIN, -1 is not
|
||||
# allowed to trap.
|
||||
intel_expand.custom_legalize(insts.srem, 'expand_srem')
|
||||
# allowed to trap. The other ops need to check avoid_div_traps.
|
||||
intel_expand.custom_legalize(insts.sdiv, 'expand_sdivrem')
|
||||
intel_expand.custom_legalize(insts.srem, 'expand_sdivrem')
|
||||
intel_expand.custom_legalize(insts.udiv, 'expand_udivrem')
|
||||
intel_expand.custom_legalize(insts.urem, 'expand_udivrem')
|
||||
|
||||
# Floating point condition codes.
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user