Add Intel legalization for division and multiplication.
These operations need custom legalization in order to use Intel's div and idiv instructions.
This commit is contained in:
@@ -55,9 +55,29 @@ ebb0(v0: i32, v1: i32):
|
|||||||
return v2
|
return v2
|
||||||
}
|
}
|
||||||
|
|
||||||
; function %i32_div(i32, i32) -> i32
|
function %i32_div_s(i32, i32) -> i32 {
|
||||||
; function %i32_rem_s(i32, i32) -> i32
|
ebb0(v0: i32, v1: i32):
|
||||||
; function %i32_rem_u(i32, i32) -> i32
|
v2 = sdiv v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
function %i32_div_u(i32, i32) -> i32 {
|
||||||
|
ebb0(v0: i32, v1: i32):
|
||||||
|
v2 = udiv v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
function %i32_rem_s(i32, i32) -> i32 {
|
||||||
|
ebb0(v0: i32, v1: i32):
|
||||||
|
v2 = srem v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
function %i32_rem_u(i32, i32) -> i32 {
|
||||||
|
ebb0(v0: i32, v1: i32):
|
||||||
|
v2 = urem v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
function %i32_and(i32, i32) -> i32 {
|
function %i32_and(i32, i32) -> i32 {
|
||||||
ebb0(v0: i32, v1: i32):
|
ebb0(v0: i32, v1: i32):
|
||||||
|
|||||||
@@ -52,9 +52,29 @@ ebb0(v0: i64, v1: i64):
|
|||||||
return v2
|
return v2
|
||||||
}
|
}
|
||||||
|
|
||||||
; function %i64_div(i64, i64) -> i64
|
function %i32_div_s(i32, i32) -> i32 {
|
||||||
; function %i64_rem_s(i64, i64) -> i64
|
ebb0(v0: i32, v1: i32):
|
||||||
; function %i64_rem_u(i64, i64) -> i64
|
v2 = sdiv v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
function %i32_div_u(i32, i32) -> i32 {
|
||||||
|
ebb0(v0: i32, v1: i32):
|
||||||
|
v2 = udiv v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
function %i32_rem_s(i32, i32) -> i32 {
|
||||||
|
ebb0(v0: i32, v1: i32):
|
||||||
|
v2 = srem v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
function %i32_rem_u(i32, i32) -> i32 {
|
||||||
|
ebb0(v0: i32, v1: i32):
|
||||||
|
v2 = urem v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
function %i64_and(i64, i64) -> i64 {
|
function %i64_and(i64, i64) -> i64 {
|
||||||
ebb0(v0: i64, v1: i64):
|
ebb0(v0: i64, v1: i64):
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ from .instructions import band, bor, bxor, isplit, iconcat
|
|||||||
from .instructions import bnot, band_not, bor_not, bxor_not
|
from .instructions import bnot, band_not, bor_not, bxor_not
|
||||||
from .instructions import icmp, icmp_imm
|
from .instructions import icmp, icmp_imm
|
||||||
from .instructions import iconst, bint
|
from .instructions import iconst, bint
|
||||||
|
from .instructions import ishl, ishl_imm, sshr, sshr_imm, ushr, ushr_imm
|
||||||
|
from .instructions import rotl, rotl_imm, rotr, rotr_imm
|
||||||
from cdsl.ast import Var
|
from cdsl.ast import Var
|
||||||
from cdsl.xform import Rtl, XFormGroup
|
from cdsl.xform import Rtl, XFormGroup
|
||||||
|
|
||||||
@@ -153,6 +155,20 @@ expand.legalize(
|
|||||||
a << iadd(x, a1)
|
a << iadd(x, a1)
|
||||||
))
|
))
|
||||||
|
|
||||||
|
# Rotates and shifts.
|
||||||
|
for inst_imm, inst in [
|
||||||
|
(rotl_imm, rotl),
|
||||||
|
(rotr_imm, rotr),
|
||||||
|
(ishl_imm, ishl),
|
||||||
|
(sshr_imm, sshr),
|
||||||
|
(ushr_imm, ushr)]:
|
||||||
|
expand.legalize(
|
||||||
|
a << inst_imm(x, y),
|
||||||
|
Rtl(
|
||||||
|
a1 << iconst.i32(y),
|
||||||
|
a << inst(x, a1)
|
||||||
|
))
|
||||||
|
|
||||||
expand.legalize(
|
expand.legalize(
|
||||||
a << icmp_imm(cc, x, y),
|
a << icmp_imm(cc, x, y),
|
||||||
Rtl(
|
Rtl(
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from .defs import I32, I64
|
|||||||
from . import recipes as r
|
from . import recipes as r
|
||||||
from . import settings as cfg
|
from . import settings as cfg
|
||||||
from . import instructions as x86
|
from . import instructions as x86
|
||||||
|
from .legalize import intel_expand
|
||||||
from base.legalize import narrow, expand
|
from base.legalize import narrow, expand
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -21,14 +22,14 @@ except ImportError:
|
|||||||
|
|
||||||
I32.legalize_type(
|
I32.legalize_type(
|
||||||
default=narrow,
|
default=narrow,
|
||||||
i32=expand,
|
i32=intel_expand,
|
||||||
f32=expand,
|
f32=expand,
|
||||||
f64=expand)
|
f64=expand)
|
||||||
|
|
||||||
I64.legalize_type(
|
I64.legalize_type(
|
||||||
default=narrow,
|
default=narrow,
|
||||||
i32=expand,
|
i32=intel_expand,
|
||||||
i64=expand,
|
i64=intel_expand,
|
||||||
f32=expand,
|
f32=expand,
|
||||||
f64=expand)
|
f64=expand)
|
||||||
|
|
||||||
|
|||||||
@@ -6,17 +6,19 @@ target ISA.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from cdsl.operands import Operand
|
from cdsl.operands import Operand
|
||||||
|
from cdsl.typevar import TypeVar
|
||||||
from cdsl.instructions import Instruction, InstructionGroup
|
from cdsl.instructions import Instruction, InstructionGroup
|
||||||
from base.instructions import iB
|
|
||||||
|
|
||||||
|
|
||||||
GROUP = InstructionGroup("x86", "Intel-specific instruction set")
|
GROUP = InstructionGroup("x86", "Intel-specific instruction set")
|
||||||
|
|
||||||
nlo = Operand('nlo', iB, doc='Low part of numerator')
|
iWord = TypeVar('iWord', 'A scalar integer machine word', ints=(32, 64))
|
||||||
nhi = Operand('nhi', iB, doc='High part of numerator')
|
|
||||||
d = Operand('d', iB, doc='Denominator')
|
nlo = Operand('nlo', iWord, doc='Low part of numerator')
|
||||||
q = Operand('q', iB, doc='Quotient')
|
nhi = Operand('nhi', iWord, doc='High part of numerator')
|
||||||
r = Operand('r', iB, doc='Remainder')
|
d = Operand('d', iWord, doc='Denominator')
|
||||||
|
q = Operand('q', iWord, doc='Quotient')
|
||||||
|
r = Operand('r', iWord, doc='Remainder')
|
||||||
|
|
||||||
udivmodx = Instruction(
|
udivmodx = Instruction(
|
||||||
'x86_udivmodx', r"""
|
'x86_udivmodx', r"""
|
||||||
|
|||||||
58
lib/cretonne/meta/isa/intel/legalize.py
Normal file
58
lib/cretonne/meta/isa/intel/legalize.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
"""
|
||||||
|
Custom legalization patterns for Intel.
|
||||||
|
"""
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from cdsl.ast import Var
|
||||||
|
from cdsl.xform import Rtl, XFormGroup
|
||||||
|
from base.immediates import imm64
|
||||||
|
from base.types import i32, i64
|
||||||
|
from base import legalize as shared
|
||||||
|
from base import instructions as insts
|
||||||
|
from . import instructions as x86
|
||||||
|
from .defs import ISA
|
||||||
|
|
||||||
|
intel_expand = XFormGroup(
|
||||||
|
'intel_expand',
|
||||||
|
"""
|
||||||
|
Legalize instructions by expansion.
|
||||||
|
|
||||||
|
Use Intel-specific instructions if needed.
|
||||||
|
""",
|
||||||
|
isa=ISA, chain=shared.expand)
|
||||||
|
|
||||||
|
a = Var('a')
|
||||||
|
dead = Var('dead')
|
||||||
|
x = Var('x')
|
||||||
|
xhi = Var('xhi')
|
||||||
|
y = Var('y')
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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)
|
||||||
|
))
|
||||||
|
intel_expand.legalize(
|
||||||
|
a << insts.srem.bind(ty)(x, y),
|
||||||
|
Rtl(
|
||||||
|
xhi << insts.sshr_imm(x, imm64(ty.lane_bits() - 1)),
|
||||||
|
(dead, a) << x86.sdivmodx(x, xhi, y)
|
||||||
|
))
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
//! Encoding tables for Intel ISAs.
|
//! Encoding tables for Intel ISAs.
|
||||||
|
|
||||||
|
use bitset::BitSet;
|
||||||
use ir;
|
use ir;
|
||||||
use isa;
|
|
||||||
use isa::constraints::*;
|
use isa::constraints::*;
|
||||||
use isa::enc_tables::*;
|
use isa::enc_tables::*;
|
||||||
use isa::encoding::RecipeSizing;
|
use isa::encoding::RecipeSizing;
|
||||||
|
use isa;
|
||||||
use predicates;
|
use predicates;
|
||||||
use super::registers::*;
|
use super::registers::*;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user