diff options
author | Chris Lattner <sabre@nondot.org> | 2004-03-31 22:03:35 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-03-31 22:03:35 +0000 |
commit | 352eb48f8e23b0758877d3ae8d9f37533302b7f8 (patch) | |
tree | cff7366a945d269748e5f3276dbe7750c4325bf9 /lib | |
parent | c1bab32bc56e6d27d1223431716523bbe35e4d2e (diff) |
Codegen FP select instructions into X86 conditional moves. Annoyingly enough
the X86 does not support a full set of fp cmove instructions, so we can't always
fold the condition into the select. :( Yuck.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12577 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/X86/InstSelectSimple.cpp | 50 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelSimple.cpp | 50 |
2 files changed, 72 insertions, 28 deletions
diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp index 35dc177e1d..e60aed3c8a 100644 --- a/lib/Target/X86/InstSelectSimple.cpp +++ b/lib/Target/X86/InstSelectSimple.cpp @@ -990,10 +990,37 @@ void ISel::emitSelectOperation(MachineBasicBlock *MBB, // cmovS switch (SelectClass) { - default: - case cFP: - assert(0 && "We don't support floating point selects yet, they should " - "have been lowered!"); + default: assert(0 && "Unknown value class!"); + case cFP: { + // Annoyingly, we don't have a full set of floating point conditional + // moves. :( + static const unsigned OpcodeTab[2][8] = { + { X86::FCMOVNE, X86::FCMOVE, X86::FCMOVAE, X86::FCMOVB, + X86::FCMOVBE, X86::FCMOVA, 0, 0 }, + { X86::FCMOVNE, X86::FCMOVE, 0, 0, 0, 0, 0, 0 }, + }; + Opcode = OpcodeTab[isSigned][OpNum]; + + // If opcode == 0, we hit a case that we don't support. Output a setcc + // and compare the result against zero. + if (Opcode == 0) { + unsigned CompClass = getClassB(CompTy); + unsigned CondReg; + if (CompClass != cLong || OpNum < 2) { + CondReg = makeAnotherReg(Type::BoolTy); + // Handle normal comparisons with a setcc instruction... + BuildMI(*MBB, IP, SetCCOpcodeTab[isSigned][OpNum], 0, CondReg); + } else { + // Long comparisons end up in the BL register. + CondReg = X86::BL; + } + + // FIXME: Should generate a 'tst r, r' + BuildMI(*MBB, IP, X86::CMP8ri, 2).addReg(CondReg).addImm(0); + Opcode = X86::FCMOVE; + } + break; + } case cByte: case cShort: { static const unsigned OpcodeTab[2][8] = { @@ -1020,20 +1047,15 @@ void ISel::emitSelectOperation(MachineBasicBlock *MBB, } else { // Get the value being branched on, and use it to set the condition codes. unsigned CondReg = getReg(Cond, MBB, IP); + // FIXME: Should generate a 'tst r, r' BuildMI(*MBB, IP, X86::CMP8ri, 2).addReg(CondReg).addImm(0); switch (SelectClass) { - default: - case cFP: - assert(0 && "We don't support floating point selects yet, they should " - "have been lowered!"); + default: assert(0 && "Unknown value class!"); + case cFP: Opcode = X86::FCMOVE; break; case cByte: - case cShort: - Opcode = X86::CMOVE16rr; - break; + case cShort: Opcode = X86::CMOVE16rr; break; case cInt: - case cLong: - Opcode = X86::CMOVE32rr; - break; + case cLong: Opcode = X86::CMOVE32rr; break; } } diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index 35dc177e1d..e60aed3c8a 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.cpp @@ -990,10 +990,37 @@ void ISel::emitSelectOperation(MachineBasicBlock *MBB, // cmovS switch (SelectClass) { - default: - case cFP: - assert(0 && "We don't support floating point selects yet, they should " - "have been lowered!"); + default: assert(0 && "Unknown value class!"); + case cFP: { + // Annoyingly, we don't have a full set of floating point conditional + // moves. :( + static const unsigned OpcodeTab[2][8] = { + { X86::FCMOVNE, X86::FCMOVE, X86::FCMOVAE, X86::FCMOVB, + X86::FCMOVBE, X86::FCMOVA, 0, 0 }, + { X86::FCMOVNE, X86::FCMOVE, 0, 0, 0, 0, 0, 0 }, + }; + Opcode = OpcodeTab[isSigned][OpNum]; + + // If opcode == 0, we hit a case that we don't support. Output a setcc + // and compare the result against zero. + if (Opcode == 0) { + unsigned CompClass = getClassB(CompTy); + unsigned CondReg; + if (CompClass != cLong || OpNum < 2) { + CondReg = makeAnotherReg(Type::BoolTy); + // Handle normal comparisons with a setcc instruction... + BuildMI(*MBB, IP, SetCCOpcodeTab[isSigned][OpNum], 0, CondReg); + } else { + // Long comparisons end up in the BL register. + CondReg = X86::BL; + } + + // FIXME: Should generate a 'tst r, r' + BuildMI(*MBB, IP, X86::CMP8ri, 2).addReg(CondReg).addImm(0); + Opcode = X86::FCMOVE; + } + break; + } case cByte: case cShort: { static const unsigned OpcodeTab[2][8] = { @@ -1020,20 +1047,15 @@ void ISel::emitSelectOperation(MachineBasicBlock *MBB, } else { // Get the value being branched on, and use it to set the condition codes. unsigned CondReg = getReg(Cond, MBB, IP); + // FIXME: Should generate a 'tst r, r' BuildMI(*MBB, IP, X86::CMP8ri, 2).addReg(CondReg).addImm(0); switch (SelectClass) { - default: - case cFP: - assert(0 && "We don't support floating point selects yet, they should " - "have been lowered!"); + default: assert(0 && "Unknown value class!"); + case cFP: Opcode = X86::FCMOVE; break; case cByte: - case cShort: - Opcode = X86::CMOVE16rr; - break; + case cShort: Opcode = X86::CMOVE16rr; break; case cInt: - case cLong: - Opcode = X86::CMOVE32rr; - break; + case cLong: Opcode = X86::CMOVE32rr; break; } } |