[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86ISelPattern.cpp X86InstrInfo.td
Evan Cheng
evan.cheng at apple.com
Wed Jan 11 14:16:01 PST 2006
Changes in directory llvm/lib/Target/X86:
X86ISelLowering.cpp updated: 1.29 -> 1.30
X86ISelLowering.h updated: 1.13 -> 1.14
X86ISelPattern.cpp updated: 1.193 -> 1.194
X86InstrInfo.td updated: 1.196 -> 1.197
---
Log message:
Support for MEMCPY and MEMSET.
---
Diffs of the changes: (+137 -10)
X86ISelLowering.cpp | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++
X86ISelLowering.h | 10 +++-
X86ISelPattern.cpp | 4 -
X86InstrInfo.td | 25 +++++++++---
4 files changed, 137 insertions(+), 10 deletions(-)
Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.29 llvm/lib/Target/X86/X86ISelLowering.cpp:1.30
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.29 Wed Jan 11 15:21:00 2006
+++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Jan 11 16:15:48 2006
@@ -147,6 +147,9 @@
setOperationAction(ISD::SHL_PARTS , MVT::i32 , Custom);
setOperationAction(ISD::SRA_PARTS , MVT::i32 , Custom);
setOperationAction(ISD::SRL_PARTS , MVT::i32 , Custom);
+ // X86 wants to expand memset / memcpy itself.
+ setOperationAction(ISD::MEMSET , MVT::Other, Custom);
+ setOperationAction(ISD::MEMCPY , MVT::Other, Custom);
}
// We don't have line number support yet.
@@ -1614,6 +1617,109 @@
return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Op.getOperand(0),
DAG.getConstant(getBytesToPopOnReturn(), MVT::i16));
}
+ case ISD::MEMSET: {
+ SDOperand InFlag;
+ SDOperand Chain = Op.getOperand(0);
+ unsigned Align =
+ (unsigned)cast<ConstantSDNode>(Op.getOperand(4))->getValue();
+ if (Align == 0) Align = 1;
+
+ MVT::ValueType AVT;
+ SDOperand Count;
+ if (ConstantSDNode *ValC = dyn_cast<ConstantSDNode>(Op.getOperand(2))) {
+ unsigned ValReg;
+ unsigned Val = ValC->getValue() & 255;
+
+ // If the value is a constant, then we can potentially use larger sets.
+ switch (Align & 3) {
+ case 2: // WORD aligned
+ AVT = MVT::i16;
+ if (ConstantSDNode *I = dyn_cast<ConstantSDNode>(Op.getOperand(3)))
+ Count = DAG.getConstant(I->getValue() / 2, MVT::i32);
+ else
+ Count = DAG.getNode(ISD::SRL, MVT::i32, Op.getOperand(3),
+ DAG.getConstant(1, MVT::i8));
+ Val = (Val << 8) | Val;
+ ValReg = X86::AX;
+ break;
+ case 0: // DWORD aligned
+ AVT = MVT::i32;
+ if (ConstantSDNode *I = dyn_cast<ConstantSDNode>(Op.getOperand(3)))
+ Count = DAG.getConstant(I->getValue() / 4, MVT::i32);
+ else
+ Count = DAG.getNode(ISD::SRL, MVT::i32, Op.getOperand(3),
+ DAG.getConstant(2, MVT::i8));
+ Val = (Val << 8) | Val;
+ Val = (Val << 16) | Val;
+ ValReg = X86::EAX;
+ break;
+ default: // Byte aligned
+ AVT = MVT::i8;
+ Count = Op.getOperand(3);
+ ValReg = X86::AL;
+ break;
+ }
+
+ Chain = DAG.getCopyToReg(Chain, ValReg, DAG.getConstant(Val, AVT),
+ InFlag);
+ InFlag = Chain.getValue(1);
+ } else {
+ AVT = MVT::i8;
+ Count = Op.getOperand(3);
+ Chain = DAG.getCopyToReg(Chain, X86::AL, Op.getOperand(2), InFlag);
+ InFlag = Chain.getValue(1);
+ }
+
+ Chain = DAG.getCopyToReg(Chain, X86::ECX, Count, InFlag);
+ InFlag = Chain.getValue(1);
+ Chain = DAG.getCopyToReg(Chain, X86::EDI, Op.getOperand(1), InFlag);
+ InFlag = Chain.getValue(1);
+
+ return DAG.getNode(X86ISD::REP_STOS, MVT::Other, Chain,
+ DAG.getValueType(AVT), InFlag);
+ }
+ case ISD::MEMCPY: {
+ SDOperand Chain = Op.getOperand(0);
+ unsigned Align =
+ (unsigned)cast<ConstantSDNode>(Op.getOperand(4))->getValue();
+ if (Align == 0) Align = 1;
+
+ MVT::ValueType AVT;
+ SDOperand Count;
+ switch (Align & 3) {
+ case 2: // WORD aligned
+ AVT = MVT::i16;
+ if (ConstantSDNode *I = dyn_cast<ConstantSDNode>(Op.getOperand(3)))
+ Count = DAG.getConstant(I->getValue() / 2, MVT::i32);
+ else
+ Count = DAG.getNode(ISD::SRL, MVT::i32, Op.getOperand(3),
+ DAG.getConstant(1, MVT::i8));
+ break;
+ case 0: // DWORD aligned
+ AVT = MVT::i32;
+ if (ConstantSDNode *I = dyn_cast<ConstantSDNode>(Op.getOperand(3)))
+ Count = DAG.getConstant(I->getValue() / 4, MVT::i32);
+ else
+ Count = DAG.getNode(ISD::SRL, MVT::i32, Op.getOperand(3),
+ DAG.getConstant(2, MVT::i8));
+ break;
+ default: // Byte aligned
+ AVT = MVT::i8;
+ Count = Op.getOperand(3);
+ break;
+ }
+
+ SDOperand InFlag;
+ Chain = DAG.getCopyToReg(Chain, X86::ECX, Count, InFlag);
+ InFlag = Chain.getValue(1);
+ Chain = DAG.getCopyToReg(Chain, X86::EDI, Op.getOperand(1), InFlag);
+ InFlag = Chain.getValue(1);
+ Chain = DAG.getCopyToReg(Chain, X86::ESI, Op.getOperand(2), InFlag);
+ InFlag = Chain.getValue(1);
+
+ return DAG.getNode(X86ISD::REP_MOVS, MVT::Other, Chain,
+ DAG.getValueType(AVT), InFlag);
+ }
case ISD::GlobalAddress: {
GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
SDOperand GVOp = DAG.getTargetGlobalAddress(GV, getPointerTy());
@@ -1659,6 +1765,8 @@
case X86ISD::CMOV: return "X86ISD::CMOV";
case X86ISD::BRCOND: return "X86ISD::BRCOND";
case X86ISD::RET_FLAG: return "X86ISD::RET_FLAG";
+ case X86ISD::REP_STOS: return "X86ISD::RET_STOS";
+ case X86ISD::REP_MOVS: return "X86ISD::RET_MOVS";
}
}
Index: llvm/lib/Target/X86/X86ISelLowering.h
diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.13 llvm/lib/Target/X86/X86ISelLowering.h:1.14
--- llvm/lib/Target/X86/X86ISelLowering.h:1.13 Tue Jan 10 18:33:36 2006
+++ llvm/lib/Target/X86/X86ISelLowering.h Wed Jan 11 16:15:48 2006
@@ -123,9 +123,15 @@
/// or TEST instruction.
BRCOND,
- /// Return with a flag operand. Operand 1 is the number of bytes of stack
- /// to pop, operand 2 is the chain and operand 3 is a flag operand.
+ /// Return with a flag operand. Operand 1 is the chain operand, operand
+ /// 2 is the number of bytes of stack to pop.
RET_FLAG,
+
+ /// REP_STOS - Repeat fill, corresponds to X86::REP_STOSx.
+ REP_STOS,
+
+ /// REP_MOVS - Repeat move, corresponds to X86::REP_MOVSx.
+ REP_MOVS,
};
// X86 specific condition code. These correspond to X86_*_COND in
Index: llvm/lib/Target/X86/X86ISelPattern.cpp
diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.193 llvm/lib/Target/X86/X86ISelPattern.cpp:1.194
--- llvm/lib/Target/X86/X86ISelPattern.cpp:1.193 Wed Jan 11 00:09:51 2006
+++ llvm/lib/Target/X86/X86ISelPattern.cpp Wed Jan 11 16:15:48 2006
@@ -3558,8 +3558,8 @@
Opcode = X86::REP_STOSB;
}
- // No matter what the alignment is, we put the source in ESI, the
- // destination in EDI, and the count in ECX.
+ // No matter what the alignment is, we put the destination in EDI, and the
+ // count in ECX.
unsigned TmpReg1 = SelectExpr(Node->getOperand(1));
BuildMI(BB, X86::MOV32rr, 1, X86::ECX).addReg(CountReg);
BuildMI(BB, X86::MOV32rr, 1, X86::EDI).addReg(TmpReg1);
Index: llvm/lib/Target/X86/X86InstrInfo.td
diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.196 llvm/lib/Target/X86/X86InstrInfo.td:1.197
--- llvm/lib/Target/X86/X86InstrInfo.td:1.196 Wed Jan 11 00:09:51 2006
+++ llvm/lib/Target/X86/X86InstrInfo.td Wed Jan 11 16:15:48 2006
@@ -52,6 +52,8 @@
SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
def SDTX86Fild64m : SDTypeProfile<1, 1, [SDTCisVT<0, f64>, SDTCisPtrTy<1>]>;
+def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
+
def SDTX86RdTsc : SDTypeProfile<0, 0, []>;
def X86addflag : SDNode<"X86ISD::ADD_FLAG", SDTIntBinOp ,
@@ -99,6 +101,11 @@
def X86fild64m : SDNode<"X86ISD::FILD64m", SDTX86Fild64m,
[SDNPHasChain]>;
+def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr,
+ [SDNPHasChain, SDNPInFlag]>;
+def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
+ [SDNPHasChain, SDNPInFlag]>;
+
def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc,
[SDNPHasChain, SDNPOutFlag]>;
@@ -549,18 +556,24 @@
"lea{l} {$src|$dst}, {$dst|$src}",
[(set R32:$dst, leaaddr:$src)]>;
-def REP_MOVSB : I<0xA4, RawFrm, (ops), "{rep;movsb|rep movsb}", []>,
+def REP_MOVSB : I<0xA4, RawFrm, (ops), "{rep;movsb|rep movsb}",
+ [(X86rep_movs i8)]>,
Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP;
-def REP_MOVSW : I<0xA5, RawFrm, (ops), "{rep;movsw|rep movsw}", []>,
+def REP_MOVSW : I<0xA5, RawFrm, (ops), "{rep;movsw|rep movsw}",
+ [(X86rep_movs i16)]>,
Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP, OpSize;
-def REP_MOVSD : I<0xA5, RawFrm, (ops), "{rep;movsd|rep movsd}", []>,
+def REP_MOVSD : I<0xA5, RawFrm, (ops), "{rep;movsd|rep movsd}",
+ [(X86rep_movs i32)]>,
Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP;
-def REP_STOSB : I<0xAA, RawFrm, (ops), "{rep;stosb|rep stosb}", []>,
+def REP_STOSB : I<0xAA, RawFrm, (ops), "{rep;stosb|rep stosb}",
+ [(X86rep_stos i8)]>,
Imp<[AL,ECX,EDI], [ECX,EDI]>, REP;
-def REP_STOSW : I<0xAB, RawFrm, (ops), "{rep;stosw|rep stosw}", []>,
+def REP_STOSW : I<0xAB, RawFrm, (ops), "{rep;stosw|rep stosw}",
+ [(X86rep_stos i16)]>,
Imp<[AX,ECX,EDI], [ECX,EDI]>, REP, OpSize;
-def REP_STOSD : I<0xAB, RawFrm, (ops), "{rep;stosl|rep stosd}", []>,
+def REP_STOSD : I<0xAB, RawFrm, (ops), "{rep;stosl|rep stosd}",
+ [(X86rep_stos i32)]>,
Imp<[EAX,ECX,EDI], [ECX,EDI]>, REP;
More information about the llvm-commits
mailing list