target/i386: emulate: microoptimize and explain ADD_COUT_VEC/SUB_COUT_VEC
The logic is the same, but the majority(NOT a, b, c) is brought out to a separate macro and implemented without NOT operations. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
3fec86e95c
commit
767149d3d0
1 changed files with 21 additions and 5 deletions
|
|
@ -45,14 +45,30 @@
|
|||
#define LF_MASK_CF (0x01 << LF_BIT_CF)
|
||||
#define LF_MASK_PO (0x01 << LF_BIT_PO)
|
||||
|
||||
/* majority(NOT a, b, c) = (a ^ b) ? b : c */
|
||||
#define MAJ_INV1(a, b, c) ((((a) ^ (b)) & ((b) ^ (c))) ^ (c))
|
||||
|
||||
/*
|
||||
* ADD_COUT_VEC(x, y) = majority((x + y) ^ x ^ y, x, y)
|
||||
*
|
||||
* If two corresponding bits in x and y are the same, that's the carry
|
||||
* independent of the value (x+y)^x^y. Hence x^y can be replaced with
|
||||
* 1 in (x+y)^x^y, resulting in majority(NOT (x+y), x, y)
|
||||
*/
|
||||
#define ADD_COUT_VEC(op1, op2, result) \
|
||||
(((op1) & (op2)) | (((op1) | (op2)) & (~(result))))
|
||||
MAJ_INV1(result, op1, op2)
|
||||
|
||||
/*
|
||||
* SUB_COUT_VEC(x, y) = NOT majority(x, NOT y, (x - y) ^ x ^ NOT y)
|
||||
* = majority(NOT x, y, (x - y) ^ x ^ y)
|
||||
*
|
||||
* Note that the carry out is actually a borrow, i.e. it is inverted.
|
||||
* If two corresponding bits in x and y are different, the value of the
|
||||
* bit in (x-y)^x^y likewise does not matter. Hence, x^y can be replaced
|
||||
* with 0 in (x-y)^x^y, resulting in majority(NOT x, y, x-y)
|
||||
*/
|
||||
#define SUB_COUT_VEC(op1, op2, result) \
|
||||
(((~(op1)) & (op2)) | (((~(op1)) ^ (op2)) & (result)))
|
||||
|
||||
#define GET_ADD_OVERFLOW(op1, op2, result, mask) \
|
||||
((((op1) ^ (result)) & ((op2) ^ (result))) & (mask))
|
||||
MAJ_INV1(op1, op2, result)
|
||||
|
||||
/* ******************* */
|
||||
/* OSZAPC */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue