Add a "clobbers_flags" flag to encoding recipes.

On some ISAs like Intel's, all arithmetic instructions set all or some
of the CPU flags, so flag values can't be live across these
instructions. On ISAs like ARM's Aarch32, flags are clobbered by compact
16-bit encodings but not necessarily by 32-bit encodings of the same
instruction.

The "clobbers_flags" bit on the encoding recipe is used to indicate if
CPU flag values can be live across an instruction, or conversely whether
the encoding can be used where flag values are live.
This commit is contained in:
Jakob Stoklund Olesen
2017-10-16 14:06:04 -07:00
parent 5d065c4d8f
commit 620eb7effe
4 changed files with 75 additions and 16 deletions

View File

@@ -310,16 +310,21 @@ class EncRecipe(object):
branch instructions. It is an `(origin, bits)` tuple describing the exact branch instructions. It is an `(origin, bits)` tuple describing the exact
range that can be encoded in a branch instruction. range that can be encoded in a branch instruction.
For ISAs that use CPU flags in `iflags` and `fflags` value types, the
`clobbers_flags` is used to indicate instruction encodings that clobbers
the CPU flags, so they can't be used where a flag value is live.
:param name: Short mnemonic name for this recipe. :param name: Short mnemonic name for this recipe.
:param format: All encoded instructions must have this :param format: All encoded instructions must have this
:py:class:`InstructionFormat`. :py:class:`InstructionFormat`.
:param size: Number of bytes in the binary encoded instruction. :param size: Number of bytes in the binary encoded instruction.
:param: ins Tuple of register constraints for value operands. :param ins: Tuple of register constraints for value operands.
:param: outs Tuple of register constraints for results. :param outs: Tuple of register constraints for results.
:param: branch_range `(origin, bits)` range for branches. :param branch_range: `(origin, bits)` range for branches.
:param: instp Instruction predicate. :param clobbers_flags: This instruction clobbers `iflags` and `fflags`.
:param: isap ISA predicate. :param instp: Instruction predicate.
:param: emit Rust code for binary emission. :param isap: ISA predicate.
:param emit: Rust code for binary emission.
""" """
def __init__( def __init__(
@@ -330,6 +335,7 @@ class EncRecipe(object):
ins, # type: ConstraintSeq ins, # type: ConstraintSeq
outs, # type: ConstraintSeq outs, # type: ConstraintSeq
branch_range=None, # type: BranchRange branch_range=None, # type: BranchRange
clobbers_flags=True, # type: bool
instp=None, # type: PredNode instp=None, # type: PredNode
isap=None, # type: PredNode isap=None, # type: PredNode
emit=None # type: str emit=None # type: str
@@ -340,6 +346,7 @@ class EncRecipe(object):
assert size >= 0 assert size >= 0
self.size = size self.size = size
self.branch_range = branch_range self.branch_range = branch_range
self.clobbers_flags = clobbers_flags
self.instp = instp self.instp = instp
self.isap = isap self.isap = isap
self.emit = emit self.emit = emit

View File

@@ -766,6 +766,9 @@ def emit_recipe_constraints(isa, fmt):
str(any(isinstance(c, Register) str(any(isinstance(c, Register)
for c in r.outs)).lower()) for c in r.outs)).lower())
fmt.format('tied_ops: {},', str(bool(tied_i2o)).lower()) fmt.format('tied_ops: {},', str(bool(tied_i2o)).lower())
fmt.format(
'clobbers_flags: {},',
str(bool(r.clobbers_flags)).lower())
def emit_operand_constraints( def emit_operand_constraints(

View File

@@ -147,6 +147,7 @@ class TailRecipe:
ins, # type: ConstraintSeq ins, # type: ConstraintSeq
outs, # type: ConstraintSeq outs, # type: ConstraintSeq
branch_range=None, # type: int branch_range=None, # type: int
clobbers_flags=True, # type: bool
instp=None, # type: PredNode instp=None, # type: PredNode
isap=None, # type: PredNode isap=None, # type: PredNode
when_prefixed=None, # type: TailRecipe when_prefixed=None, # type: TailRecipe
@@ -160,6 +161,7 @@ class TailRecipe:
self.ins = ins self.ins = ins
self.outs = outs self.outs = outs
self.branch_range = branch_range self.branch_range = branch_range
self.clobbers_flags = clobbers_flags
self.instp = instp self.instp = instp
self.isap = isap self.isap = isap
self.when_prefixed = when_prefixed self.when_prefixed = when_prefixed
@@ -194,6 +196,7 @@ class TailRecipe:
ins=self.ins, ins=self.ins,
outs=self.outs, outs=self.outs,
branch_range=branch_range, branch_range=branch_range,
clobbers_flags=self.clobbers_flags,
instp=self.instp, instp=self.instp,
isap=self.isap, isap=self.isap,
emit=replace_put_op(self.emit, name)) emit=replace_put_op(self.emit, name))
@@ -236,6 +239,7 @@ class TailRecipe:
ins=self.ins, ins=self.ins,
outs=self.outs, outs=self.outs,
branch_range=branch_range, branch_range=branch_range,
clobbers_flags=self.clobbers_flags,
instp=self.instp, instp=self.instp,
isap=self.isap, isap=self.isap,
emit=replace_put_op(self.emit, name)) emit=replace_put_op(self.emit, name))
@@ -302,9 +306,10 @@ fax = TailRecipe(
''') ''')
# XX /r, but for a unary operator with separate input/output register, like # XX /r, but for a unary operator with separate input/output register, like
# copies. MR form. # copies. MR form, preserving flags.
umr = TailRecipe( umr = TailRecipe(
'umr', Unary, size=1, ins=GPR, outs=GPR, 'umr', Unary, size=1, ins=GPR, outs=GPR,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(out_reg0, in_reg0), sink); PUT_OP(bits, rex2(out_reg0, in_reg0), sink);
modrm_rr(out_reg0, in_reg0, sink); modrm_rr(out_reg0, in_reg0, sink);
@@ -313,6 +318,7 @@ umr = TailRecipe(
# Same as umr, but with FPR -> GPR registers. # Same as umr, but with FPR -> GPR registers.
rfumr = TailRecipe( rfumr = TailRecipe(
'rfumr', Unary, size=1, ins=FPR, outs=GPR, 'rfumr', Unary, size=1, ins=FPR, outs=GPR,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(out_reg0, in_reg0), sink); PUT_OP(bits, rex2(out_reg0, in_reg0), sink);
modrm_rr(out_reg0, in_reg0, sink); modrm_rr(out_reg0, in_reg0, sink);
@@ -339,6 +345,7 @@ urm_abcd = TailRecipe(
# XX /r, RM form, FPR -> FPR. # XX /r, RM form, FPR -> FPR.
furm = TailRecipe( furm = TailRecipe(
'furm', Unary, size=1, ins=FPR, outs=FPR, 'furm', Unary, size=1, ins=FPR, outs=FPR,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg0, out_reg0), sink); PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
modrm_rr(in_reg0, out_reg0, sink); modrm_rr(in_reg0, out_reg0, sink);
@@ -347,6 +354,7 @@ furm = TailRecipe(
# XX /r, RM form, GPR -> FPR. # XX /r, RM form, GPR -> FPR.
frurm = TailRecipe( frurm = TailRecipe(
'frurm', Unary, size=1, ins=GPR, outs=FPR, 'frurm', Unary, size=1, ins=GPR, outs=FPR,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg0, out_reg0), sink); PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
modrm_rr(in_reg0, out_reg0, sink); modrm_rr(in_reg0, out_reg0, sink);
@@ -355,6 +363,7 @@ frurm = TailRecipe(
# XX /r, RM form, FPR -> GPR. # XX /r, RM form, FPR -> GPR.
rfurm = TailRecipe( rfurm = TailRecipe(
'rfurm', Unary, size=1, ins=FPR, outs=GPR, 'rfurm', Unary, size=1, ins=FPR, outs=GPR,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg0, out_reg0), sink); PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
modrm_rr(in_reg0, out_reg0, sink); modrm_rr(in_reg0, out_reg0, sink);
@@ -378,6 +387,7 @@ furmi_rnd = TailRecipe(
# XX /r, for regmove instructions. # XX /r, for regmove instructions.
rmov = TailRecipe( rmov = TailRecipe(
'rmov', RegMove, size=1, ins=GPR, outs=(), 'rmov', RegMove, size=1, ins=GPR, outs=(),
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(dst, src), sink); PUT_OP(bits, rex2(dst, src), sink);
modrm_rr(dst, src, sink); modrm_rr(dst, src, sink);
@@ -386,6 +396,7 @@ rmov = TailRecipe(
# XX /r, for regmove instructions (FPR version, RM encoded). # XX /r, for regmove instructions (FPR version, RM encoded).
frmov = TailRecipe( frmov = TailRecipe(
'frmov', RegMove, size=1, ins=FPR, outs=(), 'frmov', RegMove, size=1, ins=FPR, outs=(),
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(src, dst), sink); PUT_OP(bits, rex2(src, dst), sink);
modrm_rr(src, dst, sink); modrm_rr(src, dst, sink);
@@ -489,6 +500,7 @@ fnaddr8 = TailRecipe(
st = TailRecipe( st = TailRecipe(
'st', Store, size=1, ins=(GPR, GPR), outs=(), 'st', Store, size=1, ins=(GPR, GPR), outs=(),
instp=IsEqual(Store.offset, 0), instp=IsEqual(Store.offset, 0),
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg1, in_reg0), sink); PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_rm(in_reg1, in_reg0, sink); modrm_rm(in_reg1, in_reg0, sink);
@@ -500,6 +512,7 @@ st_abcd = TailRecipe(
'st_abcd', Store, size=1, ins=(ABCD, GPR), outs=(), 'st_abcd', Store, size=1, ins=(ABCD, GPR), outs=(),
instp=IsEqual(Store.offset, 0), instp=IsEqual(Store.offset, 0),
when_prefixed=st, when_prefixed=st,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg1, in_reg0), sink); PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_rm(in_reg1, in_reg0, sink); modrm_rm(in_reg1, in_reg0, sink);
@@ -509,6 +522,7 @@ st_abcd = TailRecipe(
fst = TailRecipe( fst = TailRecipe(
'fst', Store, size=1, ins=(FPR, GPR), outs=(), 'fst', Store, size=1, ins=(FPR, GPR), outs=(),
instp=IsEqual(Store.offset, 0), instp=IsEqual(Store.offset, 0),
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg1, in_reg0), sink); PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_rm(in_reg1, in_reg0, sink); modrm_rm(in_reg1, in_reg0, sink);
@@ -518,6 +532,7 @@ fst = TailRecipe(
stDisp8 = TailRecipe( stDisp8 = TailRecipe(
'stDisp8', Store, size=2, ins=(GPR, GPR), outs=(), 'stDisp8', Store, size=2, ins=(GPR, GPR), outs=(),
instp=IsSignedInt(Store.offset, 8), instp=IsSignedInt(Store.offset, 8),
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg1, in_reg0), sink); PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_disp8(in_reg1, in_reg0, sink); modrm_disp8(in_reg1, in_reg0, sink);
@@ -528,6 +543,7 @@ stDisp8_abcd = TailRecipe(
'stDisp8_abcd', Store, size=2, ins=(ABCD, GPR), outs=(), 'stDisp8_abcd', Store, size=2, ins=(ABCD, GPR), outs=(),
instp=IsSignedInt(Store.offset, 8), instp=IsSignedInt(Store.offset, 8),
when_prefixed=stDisp8, when_prefixed=stDisp8,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg1, in_reg0), sink); PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_disp8(in_reg1, in_reg0, sink); modrm_disp8(in_reg1, in_reg0, sink);
@@ -537,6 +553,7 @@ stDisp8_abcd = TailRecipe(
fstDisp8 = TailRecipe( fstDisp8 = TailRecipe(
'fstDisp8', Store, size=2, ins=(FPR, GPR), outs=(), 'fstDisp8', Store, size=2, ins=(FPR, GPR), outs=(),
instp=IsSignedInt(Store.offset, 8), instp=IsSignedInt(Store.offset, 8),
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg1, in_reg0), sink); PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_disp8(in_reg1, in_reg0, sink); modrm_disp8(in_reg1, in_reg0, sink);
@@ -547,6 +564,7 @@ fstDisp8 = TailRecipe(
# XX /r register-indirect store with 32-bit offset. # XX /r register-indirect store with 32-bit offset.
stDisp32 = TailRecipe( stDisp32 = TailRecipe(
'stDisp32', Store, size=5, ins=(GPR, GPR), outs=(), 'stDisp32', Store, size=5, ins=(GPR, GPR), outs=(),
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg1, in_reg0), sink); PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_disp32(in_reg1, in_reg0, sink); modrm_disp32(in_reg1, in_reg0, sink);
@@ -556,6 +574,7 @@ stDisp32 = TailRecipe(
stDisp32_abcd = TailRecipe( stDisp32_abcd = TailRecipe(
'stDisp32_abcd', Store, size=5, ins=(ABCD, GPR), outs=(), 'stDisp32_abcd', Store, size=5, ins=(ABCD, GPR), outs=(),
when_prefixed=stDisp32, when_prefixed=stDisp32,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg1, in_reg0), sink); PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_disp32(in_reg1, in_reg0, sink); modrm_disp32(in_reg1, in_reg0, sink);
@@ -564,6 +583,7 @@ stDisp32_abcd = TailRecipe(
''') ''')
fstDisp32 = TailRecipe( fstDisp32 = TailRecipe(
'fstDisp32', Store, size=5, ins=(FPR, GPR), outs=(), 'fstDisp32', Store, size=5, ins=(FPR, GPR), outs=(),
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg1, in_reg0), sink); PUT_OP(bits, rex2(in_reg1, in_reg0), sink);
modrm_disp32(in_reg1, in_reg0, sink); modrm_disp32(in_reg1, in_reg0, sink);
@@ -574,6 +594,7 @@ fstDisp32 = TailRecipe(
# Unary spill with SIB and 32-bit displacement. # Unary spill with SIB and 32-bit displacement.
spSib32 = TailRecipe( spSib32 = TailRecipe(
'spSib32', Unary, size=6, ins=GPR, outs=StackGPR32, 'spSib32', Unary, size=6, ins=GPR, outs=StackGPR32,
clobbers_flags=False,
emit=''' emit='''
let base = stk_base(out_stk0.base); let base = stk_base(out_stk0.base);
PUT_OP(bits, rex2(base, in_reg0), sink); PUT_OP(bits, rex2(base, in_reg0), sink);
@@ -583,6 +604,7 @@ spSib32 = TailRecipe(
''') ''')
fspSib32 = TailRecipe( fspSib32 = TailRecipe(
'fspSib32', Unary, size=6, ins=FPR, outs=StackFPR32, 'fspSib32', Unary, size=6, ins=FPR, outs=StackFPR32,
clobbers_flags=False,
emit=''' emit='''
let base = stk_base(out_stk0.base); let base = stk_base(out_stk0.base);
PUT_OP(bits, rex2(base, in_reg0), sink); PUT_OP(bits, rex2(base, in_reg0), sink);
@@ -594,6 +616,7 @@ fspSib32 = TailRecipe(
# Regspill using RSP-relative addressing. # Regspill using RSP-relative addressing.
rsp32 = TailRecipe( rsp32 = TailRecipe(
'rsp32', RegSpill, size=6, ins=GPR, outs=(), 'rsp32', RegSpill, size=6, ins=GPR, outs=(),
clobbers_flags=False,
emit=''' emit='''
let dst = StackRef::sp(dst, &func.stack_slots); let dst = StackRef::sp(dst, &func.stack_slots);
let base = stk_base(dst.base); let base = stk_base(dst.base);
@@ -604,6 +627,7 @@ rsp32 = TailRecipe(
''') ''')
frsp32 = TailRecipe( frsp32 = TailRecipe(
'frsp32', RegSpill, size=6, ins=FPR, outs=(), 'frsp32', RegSpill, size=6, ins=FPR, outs=(),
clobbers_flags=False,
emit=''' emit='''
let dst = StackRef::sp(dst, &func.stack_slots); let dst = StackRef::sp(dst, &func.stack_slots);
let base = stk_base(dst.base); let base = stk_base(dst.base);
@@ -621,6 +645,7 @@ frsp32 = TailRecipe(
ld = TailRecipe( ld = TailRecipe(
'ld', Load, size=1, ins=(GPR), outs=(GPR), 'ld', Load, size=1, ins=(GPR), outs=(GPR),
instp=IsEqual(Load.offset, 0), instp=IsEqual(Load.offset, 0),
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg0, out_reg0), sink); PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
modrm_rm(in_reg0, out_reg0, sink); modrm_rm(in_reg0, out_reg0, sink);
@@ -630,6 +655,7 @@ ld = TailRecipe(
fld = TailRecipe( fld = TailRecipe(
'fld', Load, size=1, ins=(GPR), outs=(FPR), 'fld', Load, size=1, ins=(GPR), outs=(FPR),
instp=IsEqual(Load.offset, 0), instp=IsEqual(Load.offset, 0),
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg0, out_reg0), sink); PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
modrm_rm(in_reg0, out_reg0, sink); modrm_rm(in_reg0, out_reg0, sink);
@@ -639,6 +665,7 @@ fld = TailRecipe(
ldDisp8 = TailRecipe( ldDisp8 = TailRecipe(
'ldDisp8', Load, size=2, ins=(GPR), outs=(GPR), 'ldDisp8', Load, size=2, ins=(GPR), outs=(GPR),
instp=IsSignedInt(Load.offset, 8), instp=IsSignedInt(Load.offset, 8),
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg0, out_reg0), sink); PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
modrm_disp8(in_reg0, out_reg0, sink); modrm_disp8(in_reg0, out_reg0, sink);
@@ -650,6 +677,7 @@ ldDisp8 = TailRecipe(
fldDisp8 = TailRecipe( fldDisp8 = TailRecipe(
'fldDisp8', Load, size=2, ins=(GPR), outs=(FPR), 'fldDisp8', Load, size=2, ins=(GPR), outs=(FPR),
instp=IsSignedInt(Load.offset, 8), instp=IsSignedInt(Load.offset, 8),
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg0, out_reg0), sink); PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
modrm_disp8(in_reg0, out_reg0, sink); modrm_disp8(in_reg0, out_reg0, sink);
@@ -661,6 +689,7 @@ fldDisp8 = TailRecipe(
ldDisp32 = TailRecipe( ldDisp32 = TailRecipe(
'ldDisp32', Load, size=5, ins=(GPR), outs=(GPR), 'ldDisp32', Load, size=5, ins=(GPR), outs=(GPR),
instp=IsSignedInt(Load.offset, 32), instp=IsSignedInt(Load.offset, 32),
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg0, out_reg0), sink); PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
modrm_disp32(in_reg0, out_reg0, sink); modrm_disp32(in_reg0, out_reg0, sink);
@@ -672,6 +701,7 @@ ldDisp32 = TailRecipe(
fldDisp32 = TailRecipe( fldDisp32 = TailRecipe(
'fldDisp32', Load, size=5, ins=(GPR), outs=(FPR), 'fldDisp32', Load, size=5, ins=(GPR), outs=(FPR),
instp=IsSignedInt(Load.offset, 32), instp=IsSignedInt(Load.offset, 32),
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, rex2(in_reg0, out_reg0), sink); PUT_OP(bits, rex2(in_reg0, out_reg0), sink);
modrm_disp32(in_reg0, out_reg0, sink); modrm_disp32(in_reg0, out_reg0, sink);
@@ -682,6 +712,7 @@ fldDisp32 = TailRecipe(
# Unary fill with SIB and 32-bit displacement. # Unary fill with SIB and 32-bit displacement.
fiSib32 = TailRecipe( fiSib32 = TailRecipe(
'fiSib32', Unary, size=6, ins=StackGPR32, outs=GPR, 'fiSib32', Unary, size=6, ins=StackGPR32, outs=GPR,
clobbers_flags=False,
emit=''' emit='''
let base = stk_base(in_stk0.base); let base = stk_base(in_stk0.base);
PUT_OP(bits, rex2(base, out_reg0), sink); PUT_OP(bits, rex2(base, out_reg0), sink);
@@ -691,6 +722,7 @@ fiSib32 = TailRecipe(
''') ''')
ffiSib32 = TailRecipe( ffiSib32 = TailRecipe(
'ffiSib32', Unary, size=6, ins=StackFPR32, outs=FPR, 'ffiSib32', Unary, size=6, ins=StackFPR32, outs=FPR,
clobbers_flags=False,
emit=''' emit='''
let base = stk_base(in_stk0.base); let base = stk_base(in_stk0.base);
PUT_OP(bits, rex2(base, out_reg0), sink); PUT_OP(bits, rex2(base, out_reg0), sink);
@@ -702,6 +734,7 @@ ffiSib32 = TailRecipe(
# Regfill with RSP-relative 32-bit displacement. # Regfill with RSP-relative 32-bit displacement.
rfi32 = TailRecipe( rfi32 = TailRecipe(
'rfi32', RegFill, size=6, ins=StackGPR32, outs=(), 'rfi32', RegFill, size=6, ins=StackGPR32, outs=(),
clobbers_flags=False,
emit=''' emit='''
let src = StackRef::sp(src, &func.stack_slots); let src = StackRef::sp(src, &func.stack_slots);
let base = stk_base(src.base); let base = stk_base(src.base);
@@ -712,6 +745,7 @@ rfi32 = TailRecipe(
''') ''')
frfi32 = TailRecipe( frfi32 = TailRecipe(
'frfi32', RegFill, size=6, ins=StackFPR32, outs=(), 'frfi32', RegFill, size=6, ins=StackFPR32, outs=(),
clobbers_flags=False,
emit=''' emit='''
let src = StackRef::sp(src, &func.stack_slots); let src = StackRef::sp(src, &func.stack_slots);
let base = stk_base(src.base); let base = stk_base(src.base);
@@ -751,6 +785,7 @@ ret = TailRecipe(
jmpb = TailRecipe( jmpb = TailRecipe(
'jmpb', Jump, size=1, ins=(), outs=(), 'jmpb', Jump, size=1, ins=(), outs=(),
branch_range=8, branch_range=8,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, BASE_REX, sink); PUT_OP(bits, BASE_REX, sink);
disp1(destination, func, sink); disp1(destination, func, sink);
@@ -759,6 +794,7 @@ jmpb = TailRecipe(
jmpd = TailRecipe( jmpd = TailRecipe(
'jmpd', Jump, size=4, ins=(), outs=(), 'jmpd', Jump, size=4, ins=(), outs=(),
branch_range=32, branch_range=32,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits, BASE_REX, sink); PUT_OP(bits, BASE_REX, sink);
disp4(destination, func, sink); disp4(destination, func, sink);
@@ -767,6 +803,7 @@ jmpd = TailRecipe(
brib = TailRecipe( brib = TailRecipe(
'brib', BranchInt, size=1, ins=FLAG.eflags, outs=(), 'brib', BranchInt, size=1, ins=FLAG.eflags, outs=(),
branch_range=8, branch_range=8,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits | icc2opc(cond), BASE_REX, sink); PUT_OP(bits | icc2opc(cond), BASE_REX, sink);
disp1(destination, func, sink); disp1(destination, func, sink);
@@ -775,6 +812,7 @@ brib = TailRecipe(
brid = TailRecipe( brid = TailRecipe(
'brid', BranchInt, size=4, ins=FLAG.eflags, outs=(), 'brid', BranchInt, size=4, ins=FLAG.eflags, outs=(),
branch_range=32, branch_range=32,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits | icc2opc(cond), BASE_REX, sink); PUT_OP(bits | icc2opc(cond), BASE_REX, sink);
disp4(destination, func, sink); disp4(destination, func, sink);
@@ -783,6 +821,7 @@ brid = TailRecipe(
brfb = TailRecipe( brfb = TailRecipe(
'brfb', BranchFloat, size=1, ins=FLAG.eflags, outs=(), 'brfb', BranchFloat, size=1, ins=FLAG.eflags, outs=(),
branch_range=8, branch_range=8,
clobbers_flags=False,
instp=floatccs(BranchFloat), instp=floatccs(BranchFloat),
emit=''' emit='''
PUT_OP(bits | fcc2opc(cond), BASE_REX, sink); PUT_OP(bits | fcc2opc(cond), BASE_REX, sink);
@@ -792,6 +831,7 @@ brfb = TailRecipe(
brfd = TailRecipe( brfd = TailRecipe(
'brfd', BranchFloat, size=4, ins=FLAG.eflags, outs=(), 'brfd', BranchFloat, size=4, ins=FLAG.eflags, outs=(),
branch_range=32, branch_range=32,
clobbers_flags=False,
instp=floatccs(BranchFloat), instp=floatccs(BranchFloat),
emit=''' emit='''
PUT_OP(bits | fcc2opc(cond), BASE_REX, sink); PUT_OP(bits | fcc2opc(cond), BASE_REX, sink);
@@ -811,6 +851,7 @@ brfd = TailRecipe(
seti = TailRecipe( seti = TailRecipe(
'seti', IntCond, size=1, ins=FLAG.eflags, outs=GPR, 'seti', IntCond, size=1, ins=FLAG.eflags, outs=GPR,
requires_prefix=True, requires_prefix=True,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits | icc2opc(cond), rex1(out_reg0), sink); PUT_OP(bits | icc2opc(cond), rex1(out_reg0), sink);
modrm_r_bits(out_reg0, bits, sink); modrm_r_bits(out_reg0, bits, sink);
@@ -818,6 +859,7 @@ seti = TailRecipe(
seti_abcd = TailRecipe( seti_abcd = TailRecipe(
'seti_abcd', IntCond, size=1, ins=FLAG.eflags, outs=ABCD, 'seti_abcd', IntCond, size=1, ins=FLAG.eflags, outs=ABCD,
when_prefixed=seti, when_prefixed=seti,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits | icc2opc(cond), rex1(out_reg0), sink); PUT_OP(bits | icc2opc(cond), rex1(out_reg0), sink);
modrm_r_bits(out_reg0, bits, sink); modrm_r_bits(out_reg0, bits, sink);
@@ -826,6 +868,7 @@ seti_abcd = TailRecipe(
setf = TailRecipe( setf = TailRecipe(
'setf', FloatCond, size=1, ins=FLAG.eflags, outs=GPR, 'setf', FloatCond, size=1, ins=FLAG.eflags, outs=GPR,
requires_prefix=True, requires_prefix=True,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits | fcc2opc(cond), rex1(out_reg0), sink); PUT_OP(bits | fcc2opc(cond), rex1(out_reg0), sink);
modrm_r_bits(out_reg0, bits, sink); modrm_r_bits(out_reg0, bits, sink);
@@ -833,6 +876,7 @@ setf = TailRecipe(
setf_abcd = TailRecipe( setf_abcd = TailRecipe(
'setf_abcd', FloatCond, size=1, ins=FLAG.eflags, outs=ABCD, 'setf_abcd', FloatCond, size=1, ins=FLAG.eflags, outs=ABCD,
when_prefixed=setf, when_prefixed=setf,
clobbers_flags=False,
emit=''' emit='''
PUT_OP(bits | fcc2opc(cond), rex1(out_reg0), sink); PUT_OP(bits | fcc2opc(cond), rex1(out_reg0), sink);
modrm_r_bits(out_reg0, bits, sink); modrm_r_bits(out_reg0, bits, sink);

View File

@@ -106,6 +106,11 @@ pub struct RecipeConstraints {
/// Are there any tied operands? /// Are there any tied operands?
pub tied_ops: bool, pub tied_ops: bool,
/// Does this instruction clobber the CPU flags?
///
/// When true, SSA values of type `iflags` or `fflags` can not be live across the instruction.
pub clobbers_flags: bool,
} }
impl RecipeConstraints { impl RecipeConstraints {