tcg-i386: use LEA for 3-operand 64-bit addition

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: use OT_* consistently

Reviewed-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: introduce gen_ext_tl

Introduce a function that abstracts extracting an 8, 16, 32 or 64-bit value
with or without sign, generalizing gen_extu and gen_exts.

Reviewed-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: factor setting of s->cc_op handling for string functions

Set it to the appropriate CC_OP_SUBx constant in gen_scas/gen_cmps.
In the repz case it can be overridden to CC_OP_DYNAMIC after generating
the code.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: drop cc_op argument of gen_jcc1

As in the gen_repz_scas/gen_repz_cmps case, delay setting
CC_OP_DYNAMIC in gen_jcc until after code generation.  All of
gen_jcc1/is_fast_jcc/gen_setcc_slow_T0 now work on s->cc_op, which makes
things a bit easier to follow and to patch.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: move carry computation for inc/dec closer to gen_op_set_cc_op

This ensures the invariant that cpu_cc_op matches s->cc_op when calling
the helpers.  The next patches need this because gen_compute_eflags and
gen_compute_eflags_c will take care of setting cpu_cc_op.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: move eflags computation closer to gen_op_set_cc_op

This ensures the invariant that cpu_cc_op matches s->cc_op when calling
the helpers.  The next patches need this because gen_compute_eflags and
gen_compute_eflags_c will take care of setting cpu_cc_op.

Always compute EFLAGS first since it is needed whenever the shift is
non-zero, i.e. most of the time.  This makes it possible to remove some
writes of CC_OP_EFLAGS to cpu_cc_op and more importantly removes cases
where s->cc_op becomes CC_OP_DYNAMIC.  These are slow and we want to
avoid them: CC_OP_EFLAGS is quite efficient once we paid the initial
cost of computing the flags.

Finally, always follow gen_compute_eflags(cpu_cc_src) by setting s->cc_op
and discarding cpu_cc_dst.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: compute eflags outside rcl/rcr helper

Always compute EFLAGS first since it is needed whenever
the shift is non-zero, i.e. most of the time.  This makes it possible
to remove some writes of CC_OP_EFLAGS to cpu_cc_op and more importantly
removes cases where s->cc_op becomes CC_OP_DYNAMIC.  Also, we can
remove cc_tmp and just modify cc_src from within the helper.

Finally, always follow gen_compute_eflags(cpu_cc_src) by setting s->cc_op
and discarding cpu_cc_dst.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: clean up sahf

Discard CC_DST and set s->cc_op immediately after computing EFLAGS.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: use gen_jcc1 to compile loopz

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: factor gen_op_set_cc_op/tcg_gen_discard_tl around computing flags

Before computing flags we need to store the cc_op to memory.  Move this
to gen_compute_eflags_c and gen_compute_eflags rather than doing it all
over the place.

Alo, after computing the flags in cpu_cc_src we are in EFLAGS mode.
Set s->cc_op and discard cpu_cc_dst in gen_compute_eflags, rather than
doing it all over the place.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: add helper functions to get other flags

Introduce new functions to extract PF, SF, OF, ZF in addition to CF.
These provide single entry points for optimizing accesses to a single
flag.

Reviewed-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: do not compute eflags multiple times consecutively

After calling gen_compute_eflags, leave the computed value in cc_reg_src
and set cc_op to CC_OP_EFLAGS.  The next few patches will remove anyway
most calls to gen_compute_eflags.

As a result of this change it is more natural to remove the register
argument from gen_compute_eflags and change all the callers.

Reviewed-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: no need to flush out cc_op before gen_eob

This makes code more similar to the other callers of gen_eob, especially
loopz/loopnz/jcxz.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: do not call helper to compute ZF/SF

ZF, SF and PF can always be computed from CC_DST except in the
CC_OP_EFLAGS case (and CC_OP_DYNAMIC, which just resolves to CC_OP_EFLAGS
in gen_compute_eflags).  Use setcond to compute ZF and SF.

We could also use a table lookup to compute PF.

Reviewed-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: use inverted setcond when computing NS or NZ

Make gen_compute_eflags_z and gen_compute_eflags_s able to compute the
inverted condition, and use this in gen_setcc_slow_T0.  We cannot do it
yet in gen_compute_eflags_c, but prepare the code for it anyway.  It is
not worthwhile for PF, as usual.

shr+and+xor could be replaced by and+setcond.  I'm not doing it yet.

Reviewed-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: convert gen_compute_eflags_c to TCG

Do the switch at translation time, converting the helper templates to
TCG opcodes.  In some cases CF can be computed with a single setcond,
though others it may require a little more work.

In the CC_OP_DYNAMIC case, compute the whole EFLAGS, same as for ZF/SF/PF.

Reviewed-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: change gen_setcc_slow_T0 to gen_setcc_slow

Do not hard code the destination register.

Reviewed-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: optimize setbe

This is looking at EFLAGS, but it can do so more efficiently with
setcond.

Reviewed-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
i386: optimize setle

And allow gen_setcc_slow to operate on cpu_cc_src.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>