mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-27 14:34:58 +00:00
Revert r112176; it broke test/CodeGen/Thumb2/thumb2-cmn.ll.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112191 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6cb8c23db1
commit
4b7dff9a79
@ -2141,60 +2141,18 @@ defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
|
||||
defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
|
||||
BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
|
||||
|
||||
// FIXME: There seems to be a (potential) hardware bug with the CMN instruction
|
||||
// and comparison with 0. These two pieces of code should give identical
|
||||
// results:
|
||||
//
|
||||
// rsbs r1, r1, 0
|
||||
// cmp r0, r1
|
||||
// mov r0, #0
|
||||
// it ls
|
||||
// mov r0, #1
|
||||
//
|
||||
// and:
|
||||
//
|
||||
// cmn r0, r1
|
||||
// mov r0, #0
|
||||
// it ls
|
||||
// mov r0, #1
|
||||
//
|
||||
// However, the CMN gives the *opposite* result when r1 is 0. This is because
|
||||
// the carry flag is set in the CMP case but not in the CMN case. In short, the
|
||||
// CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the
|
||||
// value of r0 and the carry bit (because the "carry bit" parameter to
|
||||
// AddWithCarry is defined as 1 in this case, the carry flag will always be set
|
||||
// when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is
|
||||
// never a "carry" when this AddWithCarry is performed (because the "carry bit"
|
||||
// parameter to AddWithCarry is defined as 0).
|
||||
//
|
||||
// The AddWithCarry in the CMP case seems to be relying upon the identity:
|
||||
//
|
||||
// ~x + 1 = -x
|
||||
//
|
||||
// However when x is 0 and unsigned, this doesn't hold:
|
||||
//
|
||||
// x = 0
|
||||
// ~x = 0xFFFF FFFF
|
||||
// ~x + 1 = 0x1 0000 0000
|
||||
// (-x = 0) != (0x1 0000 0000 = ~x + 1)
|
||||
//
|
||||
// Therefore, we should disable *all* versions of CMN, especially when comparing
|
||||
// against zero, until we can limit when the CMN instruction is used (when we
|
||||
// know that the RHS is not 0) or when we have a hardware fix for this.
|
||||
//
|
||||
// (See the ARM docs for the "AddWithCarry" pseudo-code.)
|
||||
//
|
||||
// This is related to <rdar://problem/7569620>.
|
||||
//
|
||||
//FIXME: Disable CMN, as CCodes are backwards from compare expectations
|
||||
// Compare-to-zero still works out, just not the relationals
|
||||
//defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
|
||||
// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
|
||||
//defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
|
||||
// BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
|
||||
//
|
||||
defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
|
||||
BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
|
||||
|
||||
//def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
|
||||
// (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
|
||||
//def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
|
||||
// (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
|
||||
|
||||
def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
|
||||
(t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
|
||||
|
||||
defm t2TST : T2I_cmp_irs<0b0000, "tst",
|
||||
BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
|
||||
|
Loading…
x
Reference in New Issue
Block a user