[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp X86ISelLowering.cpp X86InstrInfo.td
Evan Cheng
evan.cheng at apple.com
Mon Jan 16 13:21:41 PST 2006
Changes in directory llvm/lib/Target/X86:
X86ISelDAGToDAG.cpp updated: 1.32 -> 1.33
X86ISelLowering.cpp updated: 1.42 -> 1.43
X86InstrInfo.td updated: 1.206 -> 1.207
---
Log message:
Fix FP_TO_INT**_IN_MEM lowering.
---
Diffs of the changes: (+132 -103)
X86ISelDAGToDAG.cpp | 58 --------------------
X86ISelLowering.cpp | 150 +++++++++++++++++++++++++++++++++++++---------------
X86InstrInfo.td | 27 ++++++++-
3 files changed, 132 insertions(+), 103 deletions(-)
Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.32 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.33
--- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.32 Sun Jan 15 03:00:21 2006
+++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Mon Jan 16 15:21:29 2006
@@ -642,64 +642,6 @@
return CodeGenMap[N] = CurDAG->getTargetNode(Opc, VT, Result);
break;
}
-
- case X86ISD::FP_TO_INT16_IN_MEM:
- case X86ISD::FP_TO_INT32_IN_MEM:
- case X86ISD::FP_TO_INT64_IN_MEM: {
- assert(N.getOperand(1).getValueType() == MVT::f64);
-
- // Change the floating point control register to use "round towards zero"
- // mode when truncating to an integer value.
- MachineFunction &MF = CurDAG->getMachineFunction();
- int CWFI = MF.getFrameInfo()->CreateStackObject(2, 2);
- SDOperand CWSlot = CurDAG->getFrameIndex(CWFI, MVT::i32);
- SDOperand Base, Scale, Index, Disp;
- (void)SelectAddr(CWSlot, Base, Scale, Index, Disp);
- SDOperand Chain = N.getOperand(0);
-
- // Save the control word.
- Chain = CurDAG->getTargetNode(X86::FNSTCW16m, MVT::Other,
- Base, Scale, Index, Disp, Chain);
-
- // Load the old value of the high byte of the control word.
- SDOperand OldCW =
- CurDAG->getTargetNode(X86::MOV16rm, MVT::i16, MVT::Other,
- Base, Scale, Index, Disp, Chain);
- Chain = OldCW.getValue(1);
-
- // Set the high part to be round to zero...
- Chain = CurDAG->getTargetNode(X86::MOV16mi, MVT::Other,
- Base, Scale, Index, Disp,
- CurDAG->getConstant(0xC7F, MVT::i16),
- Chain);
-
- // Reload the modified control word now...
- Chain = CurDAG->getTargetNode(X86::FLDCW16m, MVT::Other,
- Base, Scale, Index, Disp, Chain);
-
- // Restore the memory image of control word to original value
- Chain = CurDAG->getTargetNode(X86::MOV16mr, MVT::Other,
- Base, Scale, Index, Disp, OldCW, Chain);
-
- switch (Opcode) {
- default: assert(0 && "Unknown FP_TO_INT*_IN_MEM");
- case X86ISD::FP_TO_INT16_IN_MEM: Opc = X86::FpIST16m; break;
- case X86ISD::FP_TO_INT32_IN_MEM: Opc = X86::FpIST32m; break;
- case X86ISD::FP_TO_INT64_IN_MEM: Opc = X86::FpIST64m; break;
- }
-
- SDOperand N1 = Select(N.getOperand(1));
- SDOperand Base2, Scale2, Index2, Disp2;
- (void)SelectAddr(N.getOperand(2), Base2, Scale2, Index2, Disp2);
- Chain = CurDAG->getTargetNode(Opc, MVT::Other,
- Base2, Scale2, Index2, Disp2, N1, Chain);
-
- // Reload the modified control word now...
- CodeGenMap[N] =
- Chain = CurDAG->getTargetNode(X86::FLDCW16m, MVT::Other,
- Base, Scale, Index, Disp, Chain);
- return Chain;
- }
}
return SelectCode(N);
Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.42 llvm/lib/Target/X86/X86ISelLowering.cpp:1.43
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.42 Sun Jan 15 03:00:21 2006
+++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Jan 16 15:21:29 2006
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "X86.h"
+#include "X86InstrBuilder.h"
#include "X86ISelLowering.h"
#include "X86TargetMachine.h"
#include "llvm/CallingConv.h"
@@ -1261,54 +1262,117 @@
MachineBasicBlock *
X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
MachineBasicBlock *BB) {
- assert((MI->getOpcode() == X86::CMOV_FR32 ||
- MI->getOpcode() == X86::CMOV_FR64) &&
- "Unexpected instr type to insert");
-
- // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
- // control-flow pattern. The incoming instruction knows the destination vreg
- // to set, the condition code register to branch on, the true/false values to
- // select between, and a branch opcode to use.
- const BasicBlock *LLVM_BB = BB->getBasicBlock();
- ilist<MachineBasicBlock>::iterator It = BB;
- ++It;
+ switch (MI->getOpcode()) {
+ default: assert(false && "Unexpected instr type to insert");
+ case X86::CMOV_FR32:
+ case X86::CMOV_FR64: {
+ // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
+ // control-flow pattern. The incoming instruction knows the destination vreg
+ // to set, the condition code register to branch on, the true/false values to
+ // select between, and a branch opcode to use.
+ const BasicBlock *LLVM_BB = BB->getBasicBlock();
+ ilist<MachineBasicBlock>::iterator It = BB;
+ ++It;
- // thisMBB:
- // ...
- // TrueVal = ...
- // cmpTY ccX, r1, r2
- // bCC copy1MBB
- // fallthrough --> copy0MBB
- MachineBasicBlock *thisMBB = BB;
- MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
- MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
- unsigned Opc = getCondBrOpcodeForX86CC(MI->getOperand(3).getImmedValue());
- BuildMI(BB, Opc, 1).addMBB(sinkMBB);
- MachineFunction *F = BB->getParent();
- F->getBasicBlockList().insert(It, copy0MBB);
- F->getBasicBlockList().insert(It, sinkMBB);
- // Update machine-CFG edges
- BB->addSuccessor(copy0MBB);
- BB->addSuccessor(sinkMBB);
+ // thisMBB:
+ // ...
+ // TrueVal = ...
+ // cmpTY ccX, r1, r2
+ // bCC copy1MBB
+ // fallthrough --> copy0MBB
+ MachineBasicBlock *thisMBB = BB;
+ MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
+ MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
+ unsigned Opc = getCondBrOpcodeForX86CC(MI->getOperand(3).getImmedValue());
+ BuildMI(BB, Opc, 1).addMBB(sinkMBB);
+ MachineFunction *F = BB->getParent();
+ F->getBasicBlockList().insert(It, copy0MBB);
+ F->getBasicBlockList().insert(It, sinkMBB);
+ // Update machine-CFG edges
+ BB->addSuccessor(copy0MBB);
+ BB->addSuccessor(sinkMBB);
- // copy0MBB:
- // %FalseValue = ...
- // # fallthrough to sinkMBB
- BB = copy0MBB;
+ // copy0MBB:
+ // %FalseValue = ...
+ // # fallthrough to sinkMBB
+ BB = copy0MBB;
- // Update machine-CFG edges
- BB->addSuccessor(sinkMBB);
+ // Update machine-CFG edges
+ BB->addSuccessor(sinkMBB);
- // sinkMBB:
- // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
- // ...
- BB = sinkMBB;
- BuildMI(BB, X86::PHI, 4, MI->getOperand(0).getReg())
- .addReg(MI->getOperand(1).getReg()).addMBB(copy0MBB)
- .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB);
+ // sinkMBB:
+ // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
+ // ...
+ BB = sinkMBB;
+ BuildMI(BB, X86::PHI, 4, MI->getOperand(0).getReg())
+ .addReg(MI->getOperand(1).getReg()).addMBB(copy0MBB)
+ .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB);
+
+ delete MI; // The pseudo instruction is gone now.
+ return BB;
+ }
+
+ case X86::FP_TO_INT16_IN_MEM:
+ case X86::FP_TO_INT32_IN_MEM:
+ case X86::FP_TO_INT64_IN_MEM: {
+ // Change the floating point control register to use "round towards zero"
+ // mode when truncating to an integer value.
+ MachineFunction *F = BB->getParent();
+ int CWFrameIdx = F->getFrameInfo()->CreateStackObject(2, 2);
+ addFrameReference(BuildMI(BB, X86::FNSTCW16m, 4), CWFrameIdx);
+
+ // Load the old value of the high byte of the control word...
+ unsigned OldCW =
+ F->getSSARegMap()->createVirtualRegister(X86::R16RegisterClass);
+ addFrameReference(BuildMI(BB, X86::MOV16rm, 4, OldCW), CWFrameIdx);
+
+ // Set the high part to be round to zero...
+ addFrameReference(BuildMI(BB, X86::MOV16mi, 5), CWFrameIdx).addImm(0xC7F);
- delete MI; // The pseudo instruction is gone now.
- return BB;
+ // Reload the modified control word now...
+ addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx);
+
+ // Restore the memory image of control word to original value
+ addFrameReference(BuildMI(BB, X86::MOV16mr, 5), CWFrameIdx).addReg(OldCW);
+
+ // Get the X86 opcode to use.
+ unsigned Opc;
+ switch (MI->getOpcode()) {
+ case X86::FP_TO_INT16_IN_MEM: Opc = X86::FpIST16m; break;
+ case X86::FP_TO_INT32_IN_MEM: Opc = X86::FpIST32m; break;
+ case X86::FP_TO_INT64_IN_MEM: Opc = X86::FpIST64m; break;
+ }
+
+ X86AddressMode AM;
+ MachineOperand &Op = MI->getOperand(0);
+ if (Op.isRegister()) {
+ AM.BaseType = X86AddressMode::RegBase;
+ AM.Base.Reg = Op.getReg();
+ } else {
+ AM.BaseType = X86AddressMode::FrameIndexBase;
+ AM.Base.FrameIndex = Op.getFrameIndex();
+ }
+ Op = MI->getOperand(1);
+ if (Op.isImmediate())
+ AM.Scale = Op.getImmedValue();
+ Op = MI->getOperand(2);
+ if (Op.isImmediate())
+ AM.IndexReg = Op.getImmedValue();
+ Op = MI->getOperand(3);
+ if (Op.isGlobalAddress()) {
+ AM.GV = Op.getGlobal();
+ } else {
+ AM.Disp = Op.getImmedValue();
+ }
+ addFullAddress(BuildMI(BB, Opc, 5), AM).addReg(MI->getOperand(4).getReg());
+
+ // Reload the original control word now.
+ addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx);
+
+ delete MI; // The pseudo instruction is gone now.
+ return BB;
+ }
+ }
}
Index: llvm/lib/Target/X86/X86InstrInfo.td
diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.206 llvm/lib/Target/X86/X86InstrInfo.td:1.207
--- llvm/lib/Target/X86/X86InstrInfo.td:1.206 Sun Jan 15 04:05:20 2006
+++ llvm/lib/Target/X86/X86InstrInfo.td Mon Jan 16 15:21:29 2006
@@ -52,6 +52,7 @@
SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
def SDTX86Fild : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisPtrTy<1>,
SDTCisVT<2, OtherVT>]>;
+def SDTX86FpToIMem: SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisPtrTy<1>]>;
def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
@@ -102,6 +103,12 @@
[SDNPHasChain]>;
def X86fild : SDNode<"X86ISD::FILD", SDTX86Fild,
[SDNPHasChain]>;
+def X86fp_to_i16mem : SDNode<"X86ISD::FP_TO_INT16_IN_MEM", SDTX86FpToIMem,
+ [SDNPHasChain]>;
+def X86fp_to_i32mem : SDNode<"X86ISD::FP_TO_INT32_IN_MEM", SDTX86FpToIMem,
+ [SDNPHasChain]>;
+def X86fp_to_i64mem : SDNode<"X86ISD::FP_TO_INT64_IN_MEM", SDTX86FpToIMem,
+ [SDNPHasChain]>;
def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr,
[SDNPHasChain, SDNPInFlag]>;
@@ -401,16 +408,32 @@
let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler.
def CMOV_FR32 : I<0, Pseudo,
(ops FR32:$dst, FR32:$t, FR32:$f, i8imm:$cond),
- "#CMOV PSEUDO!",
+ "#CMOV_FR32 PSEUDO!",
[(set FR32:$dst, (X86cmov FR32:$t, FR32:$f, imm:$cond,
STATUS))]>;
def CMOV_FR64 : I<0, Pseudo,
(ops FR64:$dst, FR64:$t, FR64:$f, i8imm:$cond),
- "#CMOV PSEUDO!",
+ "#CMOV_FR64 PSEUDO!",
[(set FR64:$dst, (X86cmov FR64:$t, FR64:$f, imm:$cond,
STATUS))]>;
}
+let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler.
+ def FP_TO_INT16_IN_MEM : I<0, Pseudo,
+ (ops i16mem:$dst, RFP:$src),
+ "#FP_TO_INT16_IN_MEM PSEUDO!",
+ [(X86fp_to_i16mem RFP:$src, addr:$dst)]>;
+ def FP_TO_INT32_IN_MEM : I<0, Pseudo,
+ (ops i32mem:$dst, RFP:$src),
+ "#FP_TO_INT32_IN_MEM PSEUDO!",
+ [(X86fp_to_i32mem RFP:$src, addr:$dst)]>;
+ def FP_TO_INT64_IN_MEM : I<0, Pseudo,
+ (ops i64mem:$dst, RFP:$src),
+ "#FP_TO_INT64_IN_MEM PSEUDO!",
+ [(X86fp_to_i64mem RFP:$src, addr:$dst)]>;
+}
+
+
let isTerminator = 1 in
let Defs = [FP0, FP1, FP2, FP3, FP4, FP5, FP6] in
def FP_REG_KILL : I<0, Pseudo, (ops), "#FP_REG_KILL", []>;
More information about the llvm-commits
mailing list