From lattner at cs.uiuc.edu Mon Feb 20 00:38:47 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 20 Feb 2006 00:38:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200602200638.AAA15363@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.306 -> 1.307 --- Log message: Fix a problem on itanium with memset. The value to set has been promoted to i64 before this code, so zero_ext doesn't work. --- Diffs of the changes: (+6 -2) LegalizeDAG.cpp | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.306 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.307 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.306 Thu Feb 16 23:43:56 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Feb 20 00:38:35 2006 @@ -1661,8 +1661,12 @@ const char *FnName = 0; if (Node->getOpcode() == ISD::MEMSET) { Args.push_back(std::make_pair(Tmp2, IntPtrTy)); - // Extend the ubyte argument to be an int value for the call. - Tmp3 = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Tmp3); + // Extend the (previously legalized) ubyte argument to be an int value + // for the call. + if (Tmp3.getValueType() > MVT::i32) + Tmp3 = DAG.getNode(ISD::TRUNCATE, MVT::i32, Tmp3); + else + Tmp3 = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Tmp3); Args.push_back(std::make_pair(Tmp3, Type::IntTy)); Args.push_back(std::make_pair(Tmp4, IntPtrTy)); From lattner at cs.uiuc.edu Mon Feb 20 00:51:16 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 20 Feb 2006 00:51:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200602200651.AAA15436@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.108 -> 1.109 --- Log message: Fix a problem Nate and Duraid reported where simplifying nodes can cause them to get ressurected, in which case, deleting the undead nodes is unfriendly. --- Diffs of the changes: (+8 -4) DAGCombiner.cpp | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.108 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.109 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.108 Fri Feb 17 20:40:58 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Feb 20 00:51:04 2006 @@ -120,18 +120,22 @@ std::vector NowDead; DAG.ReplaceAllUsesOfValueWith(TLO.Old, TLO.New, NowDead); - // Push the new node and any (now) users onto the worklist. + // Push the new node and any (possibly new) users onto the worklist. WorkList.push_back(TLO.New.Val); AddUsersToWorkList(TLO.New.Val); // Nodes can end up on the worklist more than once. Make sure we do // not process a node that has been replaced. - removeFromWorkList(TLO.Old.Val); for (unsigned i = 0, e = NowDead.size(); i != e; ++i) removeFromWorkList(NowDead[i]); - // Finally, since the node is now dead, remove it from the graph. - DAG.DeleteNode(TLO.Old.Val); + // Finally, if the node is now dead, remove it from the graph. The node + // may not be dead if the replacement process recursively simplified to + // something else needing this node. + if (TLO.Old.Val->use_empty()) { + removeFromWorkList(TLO.Old.Val); + DAG.DeleteNode(TLO.Old.Val); + } return true; } From evan.cheng at apple.com Mon Feb 20 13:58:38 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 20 Feb 2006 13:58:38 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602201958.NAA29779@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.57 -> 1.58 --- Log message: Some updates --- Diffs of the changes: (+31 -9) README.txt | 40 +++++++++++++++++++++++++++++++--------- 1 files changed, 31 insertions(+), 9 deletions(-) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.57 llvm/lib/Target/X86/README.txt:1.58 --- llvm/lib/Target/X86/README.txt:1.57 Thu Feb 16 22:20:13 2006 +++ llvm/lib/Target/X86/README.txt Mon Feb 20 13:58:27 2006 @@ -39,6 +39,19 @@ This should use fiadd on chips where it is profitable: double foo(double P, int *I) { return P+*I; } +We have fiadd patterns now but the followings have the same cost and +complexity. We need a way to specify the later is more profitable. + +def FpADD32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fadd RFP:$src1, + (extloadf64f32 addr:$src2)))]>; + // ST(0) = ST(0) + [mem32] + +def FpIADD32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fadd RFP:$src1, + (X86fild addr:$src2, i32)))]>; + // ST(0) = ST(0) + [mem32int] + //===---------------------------------------------------------------------===// The FP stackifier needs to be global. Also, it should handle simple permutates @@ -386,11 +399,6 @@ //===---------------------------------------------------------------------===// -The x86 backend currently supports dynamic-no-pic. Need to add asm -printer support for static and PIC. - -//===---------------------------------------------------------------------===// - We should generate bts/btr/etc instructions on targets where they are cheap or when codesize is important. e.g., for: @@ -419,10 +427,6 @@ //===---------------------------------------------------------------------===// -Use fisttp to do FP to integer conversion whenever it is available. - -//===---------------------------------------------------------------------===// - Instead of the following for memset char*, 1, 10: movl $16843009, 4(%edx) @@ -475,3 +479,21 @@ which is probably slower, but it's interesting at least :) +//===---------------------------------------------------------------------===// + +Currently the x86 codegen isn't very good at mixing SSE and FPStack +code: + +unsigned int foo(double x) { return x; } + +foo: + subl $20, %esp + movsd 24(%esp), %xmm0 + movsd %xmm0, 8(%esp) + fldl 8(%esp) + fisttpll (%esp) + movl (%esp), %eax + addl $20, %esp + ret + +This will be solved when we go to a dynamic programming based isel. From alenhar2 at cs.uiuc.edu Mon Feb 20 16:03:27 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 20 Feb 2006 16:03:27 -0600 Subject: [llvm-commits] CVS: llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp Message-ID: <200602202203.QAA30526@zion.cs.uiuc.edu> Changes in directory llvm-poolalloc/lib/PoolAllocate: PointerCompress.cpp updated: 1.65 -> 1.66 --- Log message: Fix cae of malloc of array of objects instead of just malloc of objects Fixes Shootout/lists (see regression directory for test case) --- Diffs of the changes: (+13 -0) PointerCompress.cpp | 13 +++++++++++++ 1 files changed, 13 insertions(+) Index: llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp diff -u llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp:1.65 llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp:1.66 --- llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp:1.65 Wed Jan 25 16:07:36 2006 +++ llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp Mon Feb 20 16:03:14 2006 @@ -654,6 +654,19 @@ // pointed to the start of a node! const Type *NTy = PointerType::get(PI->getNewType()); + //Check if we have a pointer to an array of Original Types this happens if + //you do a malloc of [n x OrigTy] for a pool of Type OrigTy + if(isa(GEPI.getOperand(0)->getType())) { + const Type* PT = + cast(GEPI.getOperand(0)->getType())->getElementType(); + if(isa(PT)) { + if (cast(PT)->getElementType() == PI->getNode()->getType()) + NTy = PointerType::get(ArrayType::get(PI->getNewType(), + cast(PT)->getNumElements())); + } + } + + gep_type_iterator GTI = gep_type_begin(GEPI), E = gep_type_end(GEPI); for (unsigned i = 1, e = GEPI.getNumOperands(); i != e; ++i, ++GTI) { Value *Idx = GEPI.getOperand(i); From evan.cheng at apple.com Mon Feb 20 16:35:06 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 20 Feb 2006 16:35:06 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Target.td Message-ID: <200602202235.QAA30633@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: Target.td updated: 1.70 -> 1.71 --- Log message: Added x86 integer vector types: 64-bit packed byte integer (v16i8), 64-bit packed word integer (v8i16), and 64-bit packed doubleword integer (v2i32). --- Diffs of the changes: (+9 -6) Target.td | 15 +++++++++------ 1 files changed, 9 insertions(+), 6 deletions(-) Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.70 llvm/lib/Target/Target.td:1.71 --- llvm/lib/Target/Target.td:1.70 Fri Jan 27 02:09:42 2006 +++ llvm/lib/Target/Target.td Mon Feb 20 16:34:53 2006 @@ -39,12 +39,15 @@ def FlagVT : ValueType<0 , 11>; // Condition code or machine flag def isVoid : ValueType<0 , 12>; // Produces no value def Vector : ValueType<0 , 13>; // Abstract vector value -def v16i8 : ValueType<128, 14>; // 16 x i8 vector value -def v8i16 : ValueType<128, 15>; // 8 x i16 vector value -def v4i32 : ValueType<128, 16>; // 4 x i32 vector value -def v2i64 : ValueType<128, 17>; // 2 x i64 vector value -def v4f32 : ValueType<128, 18>; // 4 x f32 vector value -def v2f64 : ValueType<128, 19>; // 2 x f64 vector value +def v8i8 : ValueType<64 , 14>; // 8 x i8 vector value +def v4i16 : ValueType<64 , 15>; // 4 x i16 vector value +def v2i32 : ValueType<64 , 16>; // 2 x i32 vector value +def v16i8 : ValueType<128, 17>; // 16 x i8 vector value +def v8i16 : ValueType<128, 18>; // 8 x i16 vector value +def v4i32 : ValueType<128, 19>; // 4 x i32 vector value +def v2i64 : ValueType<128, 20>; // 2 x i64 vector value +def v4f32 : ValueType<128, 21>; // 4 x f32 vector value +def v2f64 : ValueType<128, 22>; // 2 x f64 vector value //===----------------------------------------------------------------------===// // Register file description - These classes are used to fill in the target From evan.cheng at apple.com Mon Feb 20 16:35:06 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 20 Feb 2006 16:35:06 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ValueTypes.cpp Message-ID: <200602202235.QAA30637@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: ValueTypes.cpp updated: 1.6 -> 1.7 --- Log message: Added x86 integer vector types: 64-bit packed byte integer (v16i8), 64-bit packed word integer (v8i16), and 64-bit packed doubleword integer (v2i32). --- Diffs of the changes: (+3 -0) ValueTypes.cpp | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/lib/CodeGen/ValueTypes.cpp diff -u llvm/lib/CodeGen/ValueTypes.cpp:1.6 llvm/lib/CodeGen/ValueTypes.cpp:1.7 --- llvm/lib/CodeGen/ValueTypes.cpp:1.6 Mon Nov 28 23:45:28 2005 +++ llvm/lib/CodeGen/ValueTypes.cpp Mon Feb 20 16:34:53 2006 @@ -34,6 +34,9 @@ case MVT::Other: return "ch"; case MVT::Flag: return "flag"; case MVT::Vector:return "vec"; + case MVT::v8i8: return "v8i8"; + case MVT::v4i16: return "v4i16"; + case MVT::v2i32: return "v2i32"; case MVT::v16i8: return "v16i8"; case MVT::v8i16: return "v8i16"; case MVT::v4i32: return "v4i32"; From evan.cheng at apple.com Mon Feb 20 16:35:07 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 20 Feb 2006 16:35:07 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ValueTypes.h Message-ID: <200602202235.QAA30645@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ValueTypes.h updated: 1.17 -> 1.18 --- Log message: Added x86 integer vector types: 64-bit packed byte integer (v16i8), 64-bit packed word integer (v8i16), and 64-bit packed doubleword integer (v2i32). --- Diffs of the changes: (+13 -7) ValueTypes.h | 20 +++++++++++++------- 1 files changed, 13 insertions(+), 7 deletions(-) Index: llvm/include/llvm/CodeGen/ValueTypes.h diff -u llvm/include/llvm/CodeGen/ValueTypes.h:1.17 llvm/include/llvm/CodeGen/ValueTypes.h:1.18 --- llvm/include/llvm/CodeGen/ValueTypes.h:1.17 Tue Feb 7 20:05:45 2006 +++ llvm/include/llvm/CodeGen/ValueTypes.h Mon Feb 20 16:34:53 2006 @@ -48,13 +48,16 @@ Vector = 13, // This is an abstract vector type, which will // be expanded into a target vector type, or scalars // if no matching vector type is available. - v16i8 = 14, // 16 x i8 - v8i16 = 15, // 8 x i16 - v4i32 = 16, // 4 x i32 - v2i64 = 17, // 2 x i64 + v8i8 = 14, // 8 x i8 + v4i16 = 15, // 4 x i16 + v2i32 = 16, // 2 x i32 + v16i8 = 17, // 16 x i8 + v8i16 = 18, // 8 x i16 + v4i32 = 19, // 4 x i32 + v2i64 = 20, // 2 x i64 - v4f32 = 18, // 4 x f32 - v2f64 = 19, // 2 x f64 + v4f32 = 21, // 4 x f32 + v2f64 = 22, // 2 x f64 LAST_VALUETYPE, // This always remains at the end of the list. }; @@ -96,7 +99,10 @@ case MVT::f32 : case MVT::i32 : return 32; case MVT::f64 : - case MVT::i64 : return 64; + case MVT::i64 : + case MVT::v8i8: + case MVT::v4i16: + case MVT::v2i32:return 64; case MVT::f80 : return 80; case MVT::f128: case MVT::i128: From evan.cheng at apple.com Mon Feb 20 16:35:07 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 20 Feb 2006 16:35:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td X86RegisterInfo.cpp X86RegisterInfo.td Message-ID: <200602202235.QAA30651@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.239 -> 1.240 X86RegisterInfo.cpp updated: 1.124 -> 1.125 X86RegisterInfo.td updated: 1.28 -> 1.29 --- Log message: Added x86 integer vector types: 64-bit packed byte integer (v16i8), 64-bit packed word integer (v8i16), and 64-bit packed doubleword integer (v2i32). --- Diffs of the changes: (+37 -20) X86InstrInfo.td | 16 ++++++++-------- X86RegisterInfo.cpp | 12 ++++++------ X86RegisterInfo.td | 29 +++++++++++++++++++++++------ 3 files changed, 37 insertions(+), 20 deletions(-) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.239 llvm/lib/Target/X86/X86InstrInfo.td:1.240 --- llvm/lib/Target/X86/X86InstrInfo.td:1.239 Fri Feb 17 20:36:28 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Mon Feb 20 16:34:53 2006 @@ -3026,32 +3026,32 @@ // XMM Packed Floating point support (requires SSE / SSE2) //===----------------------------------------------------------------------===// -def MOVAPSrr : I<0x28, MRMSrcReg, (ops V4F4:$dst, V4F4:$src), +def MOVAPSrr : I<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), "movaps {$src, $dst|$dst, $src}", []>, Requires<[HasSSE1]>, TB; -def MOVAPDrr : I<0x28, MRMSrcReg, (ops V2F8:$dst, V2F8:$src), +def MOVAPDrr : I<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), "movapd {$src, $dst|$dst, $src}", []>, Requires<[HasSSE2]>, TB, OpSize; -def MOVAPSrm : I<0x28, MRMSrcMem, (ops V4F4:$dst, f128mem:$src), +def MOVAPSrm : I<0x28, MRMSrcMem, (ops V4F32:$dst, f128mem:$src), "movaps {$src, $dst|$dst, $src}", []>, Requires<[HasSSE1]>, TB; -def MOVAPSmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V4F4:$src), +def MOVAPSmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V4F32:$src), "movaps {$src, $dst|$dst, $src}",[]>, Requires<[HasSSE1]>, TB; -def MOVAPDrm : I<0x28, MRMSrcMem, (ops V2F8:$dst, f128mem:$src), +def MOVAPDrm : I<0x28, MRMSrcMem, (ops V2F64:$dst, f128mem:$src), "movapd {$src, $dst|$dst, $src}", []>, Requires<[HasSSE1]>, TB, OpSize; -def MOVAPDmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V2F8:$src), +def MOVAPDmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V2F64:$src), "movapd {$src, $dst|$dst, $src}",[]>, Requires<[HasSSE2]>, TB, OpSize; // Alias instructions to do FR32 / FR64 reg-to-reg copy using movaps / movapd. // Upper bits are disregarded. -def FsMOVAPSrr : I<0x28, MRMSrcReg, (ops V4F4:$dst, V4F4:$src), +def FsMOVAPSrr : I<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), "movaps {$src, $dst|$dst, $src}", []>, Requires<[HasSSE1]>, TB; -def FsMOVAPDrr : I<0x28, MRMSrcReg, (ops V2F8:$dst, V2F8:$src), +def FsMOVAPDrr : I<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), "movapd {$src, $dst|$dst, $src}", []>, Requires<[HasSSE2]>, TB, OpSize; Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.124 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.125 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.124 Thu Feb 16 16:45:17 2006 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Mon Feb 20 16:34:53 2006 @@ -61,9 +61,9 @@ Opc = X86::MOVSSmr; } else if (RC == &X86::FR64RegClass) { Opc = X86::MOVSDmr; - } else if (RC == &X86::V4F4RegClass) { + } else if (RC == &X86::V4F32RegClass) { Opc = X86::MOVAPSmr; - } else if (RC == &X86::V2F8RegClass) { + } else if (RC == &X86::V2F64RegClass) { Opc = X86::MOVAPDmr; } else { assert(0 && "Unknown regclass"); @@ -89,9 +89,9 @@ Opc = X86::MOVSSrm; } else if (RC == &X86::FR64RegClass) { Opc = X86::MOVSDrm; - } else if (RC == &X86::V4F4RegClass) { + } else if (RC == &X86::V4F32RegClass) { Opc = X86::MOVAPSrm; - } else if (RC == &X86::V2F8RegClass) { + } else if (RC == &X86::V2F64RegClass) { Opc = X86::MOVAPDrm; } else { assert(0 && "Unknown regclass"); @@ -113,9 +113,9 @@ Opc = X86::MOV16rr; } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) { Opc = X86::FpMOV; - } else if (RC == &X86::FR32RegClass || RC == &X86::V4F4RegClass) { + } else if (RC == &X86::FR32RegClass || RC == &X86::V4F32RegClass) { Opc = X86::FsMOVAPSrr; - } else if (RC == &X86::FR64RegClass || RC == &X86::V2F8RegClass) { + } else if (RC == &X86::FR64RegClass || RC == &X86::V2F64RegClass) { Opc = X86::FsMOVAPDrr; } else { assert(0 && "Unknown regclass"); Index: llvm/lib/Target/X86/X86RegisterInfo.td diff -u llvm/lib/Target/X86/X86RegisterInfo.td:1.28 llvm/lib/Target/X86/X86RegisterInfo.td:1.29 --- llvm/lib/Target/X86/X86RegisterInfo.td:1.28 Wed Jan 25 18:29:36 2006 +++ llvm/lib/Target/X86/X86RegisterInfo.td Mon Feb 20 16:34:53 2006 @@ -40,6 +40,12 @@ def DL : RegisterGroup<"DL", [DX,EDX]>; def BL : RegisterGroup<"BL",[BX,EBX]>; def AH : RegisterGroup<"AH", [AX,EAX]>; def CH : RegisterGroup<"CH",[CX,ECX]>; def DH : RegisterGroup<"DH", [DX,EDX]>; def BH : RegisterGroup<"BH",[BX,EBX]>; + + // MMX Registers. These are actually aliased to ST0 .. ST7 + def MM0 : Register<"MM0">; def MM1 : Register<"MM1">; + def MM2 : Register<"MM2">; def MM3 : Register<"MM3">; + def MM4 : Register<"MM4">; def MM5 : Register<"MM5">; + def MM6 : Register<"MM6">; def MM7 : Register<"MM7">; // Pseudo Floating Point registers def FP0 : Register<"FP0">; def FP1 : Register<"FP1">; @@ -108,12 +114,6 @@ [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; def FR64 : RegisterClass<"X86", [f64], 64, [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; -// Vector floating point registers: V4F4, the 4 x f32 class, and V2F8, -// the 2 x f64 class. -def V4F4 : RegisterClass<"X86", [f32], 32, - [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; -def V2F8 : RegisterClass<"X86", [f64], 64, - [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; // FIXME: This sets up the floating point register files as though they are f64 // values, though they really are f80 values. This will cause us to spill @@ -138,3 +138,20 @@ } }]; } + +// Vector integer registers: V8I8, the 8 x i8 class, V4I16, the 4 x i16 class, +// and V2I32, the 2 x i32 class. +def V8I8 : RegisterClass<"X86", [v8i8], 64, [MM0, MM1, MM2, MM3, MM4, MM5, + MM6, MM7]>; +def V4I16 : RegisterClass<"X86", [v4i16], 64, [MM0, MM1, MM2, MM3, MM4, MM5, + MM6, MM7]>; +def V2I32 : RegisterClass<"X86", [v2i32], 64, [MM0, MM1, MM2, MM3, MM4, MM5, + MM6, MM7]>; + +// Vector floating point registers: V4F4, the 4 x f32 class, and V2F8, +// the 2 x f64 class. +def V4F32 : RegisterClass<"X86", [v4f32], 128, + [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; +def V2F64 : RegisterClass<"X86", [v2f64], 128, + [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; + From evan.cheng at apple.com Mon Feb 20 16:35:07 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 20 Feb 2006 16:35:07 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenTarget.cpp Message-ID: <200602202235.QAA30641@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenTarget.cpp updated: 1.54 -> 1.55 --- Log message: Added x86 integer vector types: 64-bit packed byte integer (v16i8), 64-bit packed word integer (v8i16), and 64-bit packed doubleword integer (v2i32). --- Diffs of the changes: (+3 -0) CodeGenTarget.cpp | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/utils/TableGen/CodeGenTarget.cpp diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.54 llvm/utils/TableGen/CodeGenTarget.cpp:1.55 --- llvm/utils/TableGen/CodeGenTarget.cpp:1.54 Thu Jan 26 19:45:06 2006 +++ llvm/utils/TableGen/CodeGenTarget.cpp Mon Feb 20 16:34:53 2006 @@ -47,6 +47,9 @@ case MVT::f128: return "f128"; case MVT::Flag: return "Flag"; case MVT::isVoid:return "void"; + case MVT::v8i8: return "v8i8"; + case MVT::v4i16: return "v4i16"; + case MVT::v2i32: return "v2i32"; case MVT::v16i8: return "v16i8"; case MVT::v8i16: return "v8i16"; case MVT::v4i32: return "v4i32"; From evan.cheng at apple.com Mon Feb 20 19:38:33 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 20 Feb 2006 19:38:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp X86RegisterInfo.td Message-ID: <200602210138.TAA31561@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.125 -> 1.126 X86RegisterInfo.td updated: 1.29 -> 1.30 --- Log message: Added SSE2 128-bit integer packed types: V16I8, V8I16, V4I32, and V2I64. Added generic vector types: VR64 and VR128. --- Diffs of the changes: (+27 -9) X86RegisterInfo.cpp | 8 ++++++-- X86RegisterInfo.td | 28 +++++++++++++++++++++------- 2 files changed, 27 insertions(+), 9 deletions(-) Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.125 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.126 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.125 Mon Feb 20 16:34:53 2006 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Mon Feb 20 19:38:21 2006 @@ -113,10 +113,14 @@ Opc = X86::MOV16rr; } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) { Opc = X86::FpMOV; - } else if (RC == &X86::FR32RegClass || RC == &X86::V4F32RegClass) { + } else if (RC == &X86::FR32RegClass) { Opc = X86::FsMOVAPSrr; - } else if (RC == &X86::FR64RegClass || RC == &X86::V2F64RegClass) { + } else if (RC == &X86::FR64RegClass) { Opc = X86::FsMOVAPDrr; + } else if (RC == &X86::V4F32RegClass) { + Opc = X86::MOVAPSrr; + } else if (RC == &X86::V2F64RegClass) { + Opc = X86::MOVAPDrr; } else { assert(0 && "Unknown regclass"); abort(); Index: llvm/lib/Target/X86/X86RegisterInfo.td diff -u llvm/lib/Target/X86/X86RegisterInfo.td:1.29 llvm/lib/Target/X86/X86RegisterInfo.td:1.30 --- llvm/lib/Target/X86/X86RegisterInfo.td:1.29 Mon Feb 20 16:34:53 2006 +++ llvm/lib/Target/X86/X86RegisterInfo.td Mon Feb 20 19:38:21 2006 @@ -140,13 +140,22 @@ } // Vector integer registers: V8I8, the 8 x i8 class, V4I16, the 4 x i16 class, -// and V2I32, the 2 x i32 class. -def V8I8 : RegisterClass<"X86", [v8i8], 64, [MM0, MM1, MM2, MM3, MM4, MM5, - MM6, MM7]>; -def V4I16 : RegisterClass<"X86", [v4i16], 64, [MM0, MM1, MM2, MM3, MM4, MM5, - MM6, MM7]>; -def V2I32 : RegisterClass<"X86", [v2i32], 64, [MM0, MM1, MM2, MM3, MM4, MM5, - MM6, MM7]>; +// V2I32, the 2 x i32 class, V16I8, the 16 x i8 class, V8I16, the 8 x i16 class, +// V4I32, the 4 x i32 class, and V2I64, the 2 x i64 class. +def V8I8 : RegisterClass<"X86", [v8i8], 64, + [MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7]>; +def V4I16 : RegisterClass<"X86", [v4i16], 64, + [MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7]>; +def V2I32 : RegisterClass<"X86", [v2i32], 64, + [MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7]>; +def V16I8 : RegisterClass<"X86", [v16i8], 128, + [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; +def V8I16 : RegisterClass<"X86", [v8i16], 128, + [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; +def V4I32 : RegisterClass<"X86", [v4i32], 128, + [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; +def V2I64 : RegisterClass<"X86", [v2i64], 128, + [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; // Vector floating point registers: V4F4, the 4 x f32 class, and V2F8, // the 2 x f64 class. @@ -155,3 +164,8 @@ def V2F64 : RegisterClass<"X86", [v2f64], 128, [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; +// Generic vector registers: VR64 and VR128. +def VR64 : RegisterClass<"X86", [v8i8, v4i16, v2i32], 64, + [MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7]>; +def VR128 : RegisterClass<"X86", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],128, + [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; From evan.cheng at apple.com Mon Feb 20 19:40:09 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 20 Feb 2006 19:40:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200602210140.TAA31581@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.240 -> 1.241 --- Log message: Added MMX and XMM packed integer move instructions, movd and movq. --- Diffs of the changes: (+46 -0) X86InstrInfo.td | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 46 insertions(+) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.240 llvm/lib/Target/X86/X86InstrInfo.td:1.241 --- llvm/lib/Target/X86/X86InstrInfo.td:1.240 Mon Feb 20 16:34:53 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Mon Feb 20 19:39:57 2006 @@ -3023,6 +3023,52 @@ //===----------------------------------------------------------------------===// +// MMX and XMM Packed Integer support (requires MMX, SSE, and SSE2) +//===----------------------------------------------------------------------===// + +// Move Instructions +def MOVD64rr : I<0x6E, MRMSrcReg, (ops VR64:$dst, R32:$src), + "movd {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasSSE1]>; +def MOVD64rm : I<0x6E, MRMSrcMem, (ops VR64:$dst, i32mem:$src), + "movd {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasSSE1]>; +def MOVD64mr : I<0x7E, MRMDestMem, (ops i32mem:$dst, VR64:$src), + "movd {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasSSE1]>; + +def MOVD128rr : I<0x6E, MRMSrcReg, (ops VR128:$dst, R32:$src), + "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, + Requires<[HasSSE2]>; +def MOVD128rm : I<0x6E, MRMSrcMem, (ops VR128:$dst, i32mem:$src), + "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, + Requires<[HasSSE2]>; +def MOVD128mr : I<0x7E, MRMDestMem, (ops i32mem:$dst, VR128:$src), + "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, + Requires<[HasSSE2]>; + + +def MOVQ64rr : I<0x6F, MRMSrcReg, (ops VR64:$dst, VR64:$src), + "movq {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasSSE1]>; +def MOVQ64rm : I<0x6F, MRMSrcMem, (ops VR64:$dst, i64mem:$src), + "movq {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasSSE1]>; +def MOVQ64mr : I<0x7F, MRMDestMem, (ops i64mem:$dst, VR64:$src), + "movq {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasSSE1]>; + +def MOVQ128rr : I<0x7E, MRMSrcReg, (ops VR128:$dst, VR64:$src), + "movq {$src, $dst|$dst, $src}", []>, XS, + Requires<[HasSSE2]>; +def MOVQ128rm : I<0x7E, MRMSrcMem, (ops VR128:$dst, i64mem:$src), + "movq {$src, $dst|$dst, $src}", []>, XS, + Requires<[HasSSE2]>; +def MOVQ128mr : I<0xD6, MRMSrcMem, (ops i64mem:$dst, VR128:$src), + "movq {$src, $dst|$dst, $src}", []>, TB, OpSize, + Requires<[HasSSE2]>; + +//===----------------------------------------------------------------------===// // XMM Packed Floating point support (requires SSE / SSE2) //===----------------------------------------------------------------------===// From evan.cheng at apple.com Mon Feb 20 20:24:49 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 20 Feb 2006 20:24:49 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200602210224.UAA31701@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.241 -> 1.242 --- Log message: Added separate alias instructions for SSE logical ops that operate on non-packed types. --- Diffs of the changes: (+171 -96) X86InstrInfo.td | 267 +++++++++++++++++++++++++++++++++++--------------------- 1 files changed, 171 insertions(+), 96 deletions(-) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.241 llvm/lib/Target/X86/X86InstrInfo.td:1.242 --- llvm/lib/Target/X86/X86InstrInfo.td:1.241 Mon Feb 20 19:39:57 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Mon Feb 20 20:24:38 2006 @@ -356,8 +356,11 @@ def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extload node:$ptr, i1))>; def extloadf64f32 : PatFrag<(ops node:$ptr), (f64 (extload node:$ptr, f32))>; -def X86loadpf32 : PatFrag<(ops node:$ptr), (f32 (X86loadp node:$ptr))>; -def X86loadpf64 : PatFrag<(ops node:$ptr), (f64 (X86loadp node:$ptr))>; +def X86loadpf32 : PatFrag<(ops node:$ptr), (f32 (X86loadp node:$ptr))>; +def X86loadpf64 : PatFrag<(ops node:$ptr), (f64 (X86loadp node:$ptr))>; + +def X86loadpv4f32 : PatFrag<(ops node:$ptr), (v4f32 (X86loadp node:$ptr))>; +def X86loadpv2f64 : PatFrag<(ops node:$ptr), (v2f64 (X86loadp node:$ptr))>; //===----------------------------------------------------------------------===// // Instruction templates... @@ -705,18 +708,6 @@ "mov{l} {$src, $dst|$dst, $src}", [(store R32:$src, addr:$dst)]>; -// Pseudo-instructions that map movr0 to xor. -// FIXME: remove when we can teach regalloc that xor reg, reg is ok. -def MOV8r0 : I<0x30, MRMInitReg, (ops R8 :$dst), - "xor{b} $dst, $dst", - [(set R8:$dst, 0)]>; -def MOV16r0 : I<0x31, MRMInitReg, (ops R16:$dst), - "xor{w} $dst, $dst", - [(set R16:$dst, 0)]>, OpSize; -def MOV32r0 : I<0x31, MRMInitReg, (ops R32:$dst), - "xor{l} $dst, $dst", - [(set R32:$dst, 0)]>; - //===----------------------------------------------------------------------===// // Fixed-Register Multiplication and Division Instructions... // @@ -2485,15 +2476,6 @@ [(X86cmp FR64:$src1, (loadf64 addr:$src2))]>, Requires<[HasSSE2]>, TB, OpSize; -// Pseudo-instructions that map fld0 to pxor for sse. -// FIXME: remove when we can teach regalloc that xor reg, reg is ok. -def FLD0SS : I<0xEF, MRMInitReg, (ops FR32:$dst), - "pxor $dst, $dst", [(set FR32:$dst, fp32imm0)]>, - Requires<[HasSSE1]>, TB, OpSize; -def FLD0SD : I<0xEF, MRMInitReg, (ops FR64:$dst), - "pxor $dst, $dst", [(set FR64:$dst, fp64imm0)]>, - Requires<[HasSSE2]>, TB, OpSize; - let isTwoAddress = 1 in { // SSE Scalar Arithmetic let isCommutable = 1 in { @@ -2583,71 +2565,6 @@ (ops FR64:$dst, FR64:$src1, f64mem:$src, SSECC:$cc), "cmp${cc}sd {$src, $dst|$dst, $src}", []>, Requires<[HasSSE2]>, XD; - -// SSE Logical - these all operate on packed values -let isCommutable = 1 in { -def ANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "andps {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fand FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, TB; -def ANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "andpd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fand FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; -def ORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "orps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ORPDrr : I<0x56, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "orpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def XORPSrr : I<0x57, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "xorps {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fxor FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, TB; -def XORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "xorpd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fxor FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; -} -def ANDPSrm : I<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), - "andps {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fand FR32:$src1, - (X86loadpf32 addr:$src2)))]>, - Requires<[HasSSE1]>, TB; -def ANDPDrm : I<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), - "andpd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fand FR64:$src1, - (X86loadpf64 addr:$src2)))]>, - Requires<[HasSSE2]>, TB, OpSize; -def ORPSrm : I<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), - "orps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ORPDrm : I<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), - "orpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def XORPSrm : I<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), - "xorps {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fxor FR32:$src1, - (X86loadpf32 addr:$src2)))]>, - Requires<[HasSSE1]>, TB; -def XORPDrm : I<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), - "xorpd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fxor FR64:$src1, - (X86loadpf64 addr:$src2)))]>, - Requires<[HasSSE2]>, TB, OpSize; - -def ANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "andnps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ANDNPSrm : I<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), - "andnps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "andnpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def ANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), - "andnpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; } //===----------------------------------------------------------------------===// @@ -3076,7 +2993,7 @@ "movaps {$src, $dst|$dst, $src}", []>, Requires<[HasSSE1]>, TB; def MOVAPDrr : I<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), - "movapd {$src, $dst|$dst, $src}", []>, + "movapd {$src, $dst|$dst, $src}v2", []>, Requires<[HasSSE2]>, TB, OpSize; def MOVAPSrm : I<0x28, MRMSrcMem, (ops V4F32:$dst, f128mem:$src), @@ -3092,6 +3009,106 @@ "movapd {$src, $dst|$dst, $src}",[]>, Requires<[HasSSE2]>, TB, OpSize; +// Logical +let isTwoAddress = 1 in { +let isCommutable = 1 in { +def ANDPSrr : I<0x54, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "andps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (X86fand V4F32:$src1, V4F32:$src2))]>, + Requires<[HasSSE1]>, TB; +def ANDPDrr : I<0x54, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "andpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (X86fand V2F64:$src1, V2F64:$src2))]>, + Requires<[HasSSE2]>, TB, OpSize; +def ORPSrr : I<0x56, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "orps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def ORPDrr : I<0x56, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +def XORPSrr : I<0x57, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "xorps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (X86fxor V4F32:$src1, V4F32:$src2))]>, + Requires<[HasSSE1]>, TB; +def XORPDrr : I<0x57, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "xorpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (X86fxor V2F64:$src1, V2F64:$src2))]>, + Requires<[HasSSE2]>, TB, OpSize; +} +def ANDPSrm : I<0x54, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "andps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (X86fand V4F32:$src1, + (X86loadpv4f32 addr:$src2)))]>, + Requires<[HasSSE1]>, TB; +def ANDPDrm : I<0x54, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "andpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (X86fand V2F64:$src1, + (X86loadpv2f64 addr:$src2)))]>, + Requires<[HasSSE2]>, TB, OpSize; +def ORPSrm : I<0x56, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "orps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def ORPDrm : I<0x56, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +def XORPSrm : I<0x57, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "xorps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (X86fxor V4F32:$src1, + (X86loadpv4f32 addr:$src2)))]>, + Requires<[HasSSE1]>, TB; +def XORPDrm : I<0x57, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "xorpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (X86fxor V2F64:$src1, + (X86loadpv2f64 addr:$src2)))]>, + Requires<[HasSSE2]>, TB, OpSize; + +def ANDNPSrr : I<0x55, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def ANDNPSrm : I<0x55, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def ANDNPDrr : I<0x55, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +def ANDNPDrm : I<0x55, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +} + +//===----------------------------------------------------------------------===// +// Miscellaneous Instructions +//===----------------------------------------------------------------------===// + +def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", [(X86rdtsc)]>, + TB, Imp<[],[EAX,EDX]>; + + +//===----------------------------------------------------------------------===// +// Alias Instructions +//===----------------------------------------------------------------------===// + +// Alias instructions that map movr0 to xor. +// FIXME: remove when we can teach regalloc that xor reg, reg is ok. +def MOV8r0 : I<0x30, MRMInitReg, (ops R8 :$dst), + "xor{b} $dst, $dst", + [(set R8:$dst, 0)]>; +def MOV16r0 : I<0x31, MRMInitReg, (ops R16:$dst), + "xor{w} $dst, $dst", + [(set R16:$dst, 0)]>, OpSize; +def MOV32r0 : I<0x31, MRMInitReg, (ops R32:$dst), + "xor{l} $dst, $dst", + [(set R32:$dst, 0)]>; + +// Alias instructions that map fld0 to pxor for sse. +// FIXME: remove when we can teach regalloc that xor reg, reg is ok. +def FLD0SS : I<0xEF, MRMInitReg, (ops FR32:$dst), + "pxor $dst, $dst", [(set FR32:$dst, fp32imm0)]>, + Requires<[HasSSE1]>, TB, OpSize; +def FLD0SD : I<0xEF, MRMInitReg, (ops FR64:$dst), + "pxor $dst, $dst", [(set FR64:$dst, fp64imm0)]>, + Requires<[HasSSE2]>, TB, OpSize; + // Alias instructions to do FR32 / FR64 reg-to-reg copy using movaps / movapd. // Upper bits are disregarded. def FsMOVAPSrr : I<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), @@ -3112,14 +3129,72 @@ [(set FR64:$dst, (X86loadpf64 addr:$src))]>, Requires<[HasSSE2]>, TB, OpSize; +// Alias bitwise logical operations using SSE logical ops on packed FP values. +let isTwoAddress = 1 in { +let isCommutable = 1 in { +def FsANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "andps {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (X86fand FR32:$src1, FR32:$src2))]>, + Requires<[HasSSE1]>, TB; +def FsANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "andpd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (X86fand FR64:$src1, FR64:$src2))]>, + Requires<[HasSSE2]>, TB, OpSize; +def FsORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "orps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def FsORPDrr : I<0x56, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +def FsXORPSrr : I<0x57, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "xorps {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (X86fxor FR32:$src1, FR32:$src2))]>, + Requires<[HasSSE1]>, TB; +def FsXORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "xorpd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (X86fxor FR64:$src1, FR64:$src2))]>, + Requires<[HasSSE2]>, TB, OpSize; +} +def FsANDPSrm : I<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + "andps {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (X86fand FR32:$src1, + (X86loadpf32 addr:$src2)))]>, + Requires<[HasSSE1]>, TB; +def FsANDPDrm : I<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + "andpd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (X86fand FR64:$src1, + (X86loadpf64 addr:$src2)))]>, + Requires<[HasSSE2]>, TB, OpSize; +def FsORPSrm : I<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + "orps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def FsORPDrm : I<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +def FsXORPSrm : I<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + "xorps {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (X86fxor FR32:$src1, + (X86loadpf32 addr:$src2)))]>, + Requires<[HasSSE1]>, TB; +def FsXORPDrm : I<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + "xorpd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (X86fxor FR64:$src1, + (X86loadpf64 addr:$src2)))]>, + Requires<[HasSSE2]>, TB, OpSize; -//===----------------------------------------------------------------------===// -// Miscellaneous Instructions -//===----------------------------------------------------------------------===// - -def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", [(X86rdtsc)]>, - TB, Imp<[],[EAX,EDX]>; - +def FsANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def FsANDNPSrm : I<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def FsANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +def FsANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +} //===----------------------------------------------------------------------===// // Non-Instruction Patterns From lattner at cs.uiuc.edu Tue Feb 21 12:04:54 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 21 Feb 2006 12:04:54 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrInfo.td Message-ID: <200602211804.MAA15616@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrInfo.td updated: 1.122 -> 1.123 --- Log message: The HasNoV9 hack isn't needed here, now that tblgen knows that CustomDAGSchedInserter instructions are expensive. --- Diffs of the changes: (+2 -3) SparcInstrInfo.td | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) Index: llvm/lib/Target/Sparc/SparcInstrInfo.td diff -u llvm/lib/Target/Sparc/SparcInstrInfo.td:1.122 llvm/lib/Target/Sparc/SparcInstrInfo.td:1.123 --- llvm/lib/Target/Sparc/SparcInstrInfo.td:1.122 Thu Feb 16 23:43:56 2006 +++ llvm/lib/Target/Sparc/SparcInstrInfo.td Tue Feb 21 12:04:32 2006 @@ -191,7 +191,7 @@ // FpMOVD/FpNEGD/FpABSD - These are lowered to single-precision ops by the // fpmover pass. -let Predicates = [HasNoV9] in { // Only emit these in SP mode. +let Predicates = [HasNoV9] in { // Only emit these in V8 mode. def FpMOVD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src), "!FpMOVD $src, $dst", []>; def FpNEGD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src), @@ -205,8 +205,7 @@ // SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded by the // scheduler into a branch sequence. This has to handle all permutations of // selection between i32/f32/f64 on ICC and FCC. -let usesCustomDAGSchedInserter = 1, // Expanded by the scheduler. - Predicates = [HasNoV9] in { // V9 has conditional moves +let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. def SELECT_CC_Int_ICC : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond), "; SELECT_CC_Int_ICC PSEUDO!", From lattner at cs.uiuc.edu Tue Feb 21 12:29:56 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 21 Feb 2006 12:29:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/README.txt Message-ID: <200602211829.MAA15950@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: README.txt updated: 1.7 -> 1.8 --- Log message: missed optzn --- Diffs of the changes: (+11 -0) README.txt | 11 +++++++++++ 1 files changed, 11 insertions(+) Index: llvm/lib/Target/README.txt diff -u llvm/lib/Target/README.txt:1.7 llvm/lib/Target/README.txt:1.8 --- llvm/lib/Target/README.txt:1.7 Wed Feb 15 16:14:34 2006 +++ llvm/lib/Target/README.txt Tue Feb 21 12:29:44 2006 @@ -68,3 +68,14 @@ This sort of thing occurs in the alloca lowering code and other places that are generating alignment of an already aligned value. +//===---------------------------------------------------------------------===// + +Turn this into a signed shift right in instcombine: + +int f(unsigned x) { + return x >> 31 ? -1 : 0; +} + +http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25600 +http://gcc.gnu.org/ml/gcc-patches/2006-02/msg01492.html + From evan.cheng at apple.com Tue Feb 21 13:14:05 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 21 Feb 2006 13:14:05 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrFPStack.td X86InstrMMX.td X86InstrSSE.td X86InstrInfo.td Message-ID: <200602211914.NAA16240@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrFPStack.td added (r1.1) X86InstrMMX.td added (r1.1) X86InstrSSE.td added (r1.1) X86InstrInfo.td updated: 1.242 -> 1.243 --- Log message: Split instruction info into multiple files, one for each of x87, MMX, and SSE. --- Diffs of the changes: (+644 -590) X86InstrFPStack.td | 482 +++++++++++++++++++++++++++++++++++++++++++ X86InstrInfo.td | 594 ----------------------------------------------------- X86InstrMMX.td | 57 +++++ X86InstrSSE.td | 101 +++++++++ 4 files changed, 644 insertions(+), 590 deletions(-) Index: llvm/lib/Target/X86/X86InstrFPStack.td diff -c /dev/null llvm/lib/Target/X86/X86InstrFPStack.td:1.1 *** /dev/null Tue Feb 21 13:14:03 2006 --- llvm/lib/Target/X86/X86InstrFPStack.td Tue Feb 21 13:13:53 2006 *************** *** 0 **** --- 1,482 ---- + //==- X86InstrFPStack.td - Describe the X86 Instruction Set -------*- C++ -*-=// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the Evan Cheng and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file describes the X86 x87 FPU instruction set, defining the + // instructions, and properties of the instructions which are needed for code + // generation, machine code emission, and analysis. + // + //===----------------------------------------------------------------------===// + + // All FP Stack operations are represented with two instructions here. The + // first instruction, generated by the instruction selector, uses "RFP" + // registers: a traditional register file to reference floating point values. + // These instructions are all psuedo instructions and use the "Fp" prefix. + // The second instruction is defined with FPI, which is the actual instruction + // emitted by the assembler. The FP stackifier pass converts one to the other + // after register allocation occurs. + // + // Note that the FpI instruction should have instruction selection info (e.g. + // a pattern) and the FPI instruction should have emission info (e.g. opcode + // encoding and asm printing info). + + // FPI - Floating Point Instruction template. + class FPI o, Format F, dag ops, string asm> : I {} + + // FpI_ - Floating Point Psuedo Instruction template. Not Predicated. + class FpI_ pattern> + : X86Inst<0, Pseudo, NoImm, ops, ""> { + let FPForm = fp; let FPFormBits = FPForm.Value; + let Pattern = pattern; + } + + // Random Pseudo Instructions. + def FpGETRESULT : FpI_<(ops RFP:$dst), SpecialFP, + [(set RFP:$dst, X86fpget)]>; // FPR = ST(0) + + let noResults = 1 in + def FpSETRESULT : FpI_<(ops RFP:$src), SpecialFP, + [(X86fpset RFP:$src)]>, Imp<[], [ST0]>; // ST(0) = FPR + + // FpI - Floating Point Psuedo Instruction template. Predicated on FPStack. + class FpI pattern> : + FpI_, Requires<[FPStack]>; + + + def FpMOV : FpI<(ops RFP:$dst, RFP:$src), SpecialFP, []>; // f1 = fmov f2 + + // Arithmetic + // Add, Sub, Mul, Div. + def FpADD : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP, + [(set RFP:$dst, (fadd RFP:$src1, RFP:$src2))]>; + def FpSUB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP, + [(set RFP:$dst, (fsub RFP:$src1, RFP:$src2))]>; + def FpMUL : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP, + [(set RFP:$dst, (fmul RFP:$src1, RFP:$src2))]>; + def FpDIV : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP, + [(set RFP:$dst, (fdiv RFP:$src1, RFP:$src2))]>; + + class FPST0rInst o, string asm> + : FPI, D8; + class FPrST0Inst o, string asm> + : FPI, DC; + class FPrST0PInst o, string asm> + : FPI, DE; + + // Binary Ops with a memory source. + def FpADD32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fadd RFP:$src1, + (extloadf64f32 addr:$src2)))]>; + // ST(0) = ST(0) + [mem32] + def FpADD64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fadd RFP:$src1, (loadf64 addr:$src2)))]>; + // ST(0) = ST(0) + [mem64] + def FpMUL32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fmul RFP:$src1, + (extloadf64f32 addr:$src2)))]>; + // ST(0) = ST(0) * [mem32] + def FpMUL64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fmul RFP:$src1, (loadf64 addr:$src2)))]>; + // ST(0) = ST(0) * [mem64] + def FpSUB32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fsub RFP:$src1, + (extloadf64f32 addr:$src2)))]>; + // ST(0) = ST(0) - [mem32] + def FpSUB64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fsub RFP:$src1, (loadf64 addr:$src2)))]>; + // ST(0) = ST(0) - [mem64] + def FpSUBR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fsub (extloadf64f32 addr:$src2), + RFP:$src1))]>; + // ST(0) = [mem32] - ST(0) + def FpSUBR64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fsub (loadf64 addr:$src2), RFP:$src1))]>; + // ST(0) = [mem64] - ST(0) + def FpDIV32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fdiv RFP:$src1, + (extloadf64f32 addr:$src2)))]>; + // ST(0) = ST(0) / [mem32] + def FpDIV64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fdiv RFP:$src1, (loadf64 addr:$src2)))]>; + // ST(0) = ST(0) / [mem64] + def FpDIVR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fdiv (extloadf64f32 addr:$src2), + RFP:$src1))]>; + // ST(0) = [mem32] / ST(0) + def FpDIVR64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fdiv (loadf64 addr:$src2), RFP:$src1))]>; + // ST(0) = [mem64] / ST(0) + + + def FADD32m : FPI<0xD8, MRM0m, (ops f32mem:$src), "fadd{s} $src">; + def FADD64m : FPI<0xDC, MRM0m, (ops f64mem:$src), "fadd{l} $src">; + def FMUL32m : FPI<0xD8, MRM1m, (ops f32mem:$src), "fmul{s} $src">; + def FMUL64m : FPI<0xDC, MRM1m, (ops f64mem:$src), "fmul{l} $src">; + def FSUB32m : FPI<0xD8, MRM4m, (ops f32mem:$src), "fsub{s} $src">; + def FSUB64m : FPI<0xDC, MRM4m, (ops f64mem:$src), "fsub{l} $src">; + def FSUBR32m : FPI<0xD8, MRM5m, (ops f32mem:$src), "fsubr{s} $src">; + def FSUBR64m : FPI<0xDC, MRM5m, (ops f64mem:$src), "fsubr{l} $src">; + def FDIV32m : FPI<0xD8, MRM6m, (ops f32mem:$src), "fdiv{s} $src">; + def FDIV64m : FPI<0xDC, MRM6m, (ops f64mem:$src), "fdiv{l} $src">; + def FDIVR32m : FPI<0xD8, MRM7m, (ops f32mem:$src), "fdivr{s} $src">; + def FDIVR64m : FPI<0xDC, MRM7m, (ops f64mem:$src), "fdivr{l} $src">; + + def FpIADD16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fadd RFP:$src1, + (X86fild addr:$src2, i16)))]>; + // ST(0) = ST(0) + [mem16int] + def FpIADD32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fadd RFP:$src1, + (X86fild addr:$src2, i32)))]>; + // ST(0) = ST(0) + [mem32int] + def FpIMUL16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fmul RFP:$src1, + (X86fild addr:$src2, i16)))]>; + // ST(0) = ST(0) * [mem16int] + def FpIMUL32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fmul RFP:$src1, + (X86fild addr:$src2, i32)))]>; + // ST(0) = ST(0) * [mem32int] + def FpISUB16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fsub RFP:$src1, + (X86fild addr:$src2, i16)))]>; + // ST(0) = ST(0) - [mem16int] + def FpISUB32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fsub RFP:$src1, + (X86fild addr:$src2, i32)))]>; + // ST(0) = ST(0) - [mem32int] + def FpISUBR16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fsub (X86fild addr:$src2, i16), + RFP:$src1))]>; + // ST(0) = [mem16int] - ST(0) + def FpISUBR32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fsub (X86fild addr:$src2, i32), + RFP:$src1))]>; + // ST(0) = [mem32int] - ST(0) + def FpIDIV16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fdiv RFP:$src1, + (X86fild addr:$src2, i16)))]>; + // ST(0) = ST(0) / [mem16int] + def FpIDIV32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fdiv RFP:$src1, + (X86fild addr:$src2, i32)))]>; + // ST(0) = ST(0) / [mem32int] + def FpIDIVR16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fdiv (X86fild addr:$src2, i16), + RFP:$src1))]>; + // ST(0) = [mem16int] / ST(0) + def FpIDIVR32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW, + [(set RFP:$dst, (fdiv (X86fild addr:$src2, i32), + RFP:$src1))]>; + // ST(0) = [mem32int] / ST(0) + + def FIADD16m : FPI<0xDE, MRM0m, (ops i16mem:$src), "fiadd{s} $src">; + def FIADD32m : FPI<0xDA, MRM0m, (ops i32mem:$src), "fiadd{l} $src">; + def FIMUL16m : FPI<0xDE, MRM1m, (ops i16mem:$src), "fimul{s} $src">; + def FIMUL32m : FPI<0xDA, MRM1m, (ops i32mem:$src), "fimul{l} $src">; + def FISUB16m : FPI<0xDE, MRM4m, (ops i16mem:$src), "fisub{s} $src">; + def FISUB32m : FPI<0xDA, MRM4m, (ops i32mem:$src), "fisub{l} $src">; + def FISUBR16m : FPI<0xDE, MRM5m, (ops i16mem:$src), "fisubr{s} $src">; + def FISUBR32m : FPI<0xDA, MRM5m, (ops i32mem:$src), "fisubr{l} $src">; + def FIDIV16m : FPI<0xDE, MRM6m, (ops i16mem:$src), "fidiv{s} $src">; + def FIDIV32m : FPI<0xDA, MRM6m, (ops i32mem:$src), "fidiv{l} $src">; + def FIDIVR16m : FPI<0xDE, MRM7m, (ops i16mem:$src), "fidivr{s} $src">; + def FIDIVR32m : FPI<0xDA, MRM7m, (ops i32mem:$src), "fidivr{l} $src">; + + // NOTE: GAS and apparently all other AT&T style assemblers have a broken notion + // of some of the 'reverse' forms of the fsub and fdiv instructions. As such, + // we have to put some 'r's in and take them out of weird places. + def FADDST0r : FPST0rInst <0xC0, "fadd $op">; + def FADDrST0 : FPrST0Inst <0xC0, "fadd {%st(0), $op|$op, %ST(0)}">; + def FADDPrST0 : FPrST0PInst<0xC0, "faddp $op">; + def FSUBRST0r : FPST0rInst <0xE8, "fsubr $op">; + def FSUBrST0 : FPrST0Inst <0xE8, "fsub{r} {%st(0), $op|$op, %ST(0)}">; + def FSUBPrST0 : FPrST0PInst<0xE8, "fsub{r}p $op">; + def FSUBST0r : FPST0rInst <0xE0, "fsub $op">; + def FSUBRrST0 : FPrST0Inst <0xE0, "fsub{|r} {%st(0), $op|$op, %ST(0)}">; + def FSUBRPrST0 : FPrST0PInst<0xE0, "fsub{|r}p $op">; + def FMULST0r : FPST0rInst <0xC8, "fmul $op">; + def FMULrST0 : FPrST0Inst <0xC8, "fmul {%st(0), $op|$op, %ST(0)}">; + def FMULPrST0 : FPrST0PInst<0xC8, "fmulp $op">; + def FDIVRST0r : FPST0rInst <0xF8, "fdivr $op">; + def FDIVrST0 : FPrST0Inst <0xF8, "fdiv{r} {%st(0), $op|$op, %ST(0)}">; + def FDIVPrST0 : FPrST0PInst<0xF8, "fdiv{r}p $op">; + def FDIVST0r : FPST0rInst <0xF0, "fdiv $op">; + def FDIVRrST0 : FPrST0Inst <0xF0, "fdiv{|r} {%st(0), $op|$op, %ST(0)}">; + def FDIVRPrST0 : FPrST0PInst<0xF0, "fdiv{|r}p $op">; + + + // Unary operations. + def FpCHS : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW, + [(set RFP:$dst, (fneg RFP:$src))]>; + def FpABS : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW, + [(set RFP:$dst, (fabs RFP:$src))]>; + def FpSQRT : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW, + [(set RFP:$dst, (fsqrt RFP:$src))]>; + def FpSIN : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW, + [(set RFP:$dst, (fsin RFP:$src))]>; + def FpCOS : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW, + [(set RFP:$dst, (fcos RFP:$src))]>; + def FpTST : FpI<(ops RFP:$src), OneArgFP, + []>; + + def FCHS : FPI<0xE0, RawFrm, (ops), "fchs">, D9; + def FABS : FPI<0xE1, RawFrm, (ops), "fabs">, D9; + def FSQRT : FPI<0xFA, RawFrm, (ops), "fsqrt">, D9; + def FSIN : FPI<0xFE, RawFrm, (ops), "fsin">, D9; + def FCOS : FPI<0xFF, RawFrm, (ops), "fcos">, D9; + def FTST : FPI<0xE4, RawFrm, (ops), "ftst">, D9; + + + // Floating point cmovs. + let isTwoAddress = 1 in { + def FpCMOVB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, + [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, + X86_COND_B))]>; + def FpCMOVBE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, + [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, + X86_COND_BE))]>; + def FpCMOVE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, + [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, + X86_COND_E))]>; + def FpCMOVP : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, + [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, + X86_COND_P))]>; + def FpCMOVNB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, + [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, + X86_COND_AE))]>; + def FpCMOVNBE: FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, + [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, + X86_COND_A))]>; + def FpCMOVNE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, + [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, + X86_COND_NE))]>; + def FpCMOVNP : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, + [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, + X86_COND_NP))]>; + } + + def FCMOVB : FPI<0xC0, AddRegFrm, (ops RST:$op), + "fcmovb {$op, %st(0)|%ST(0), $op}">, DA; + def FCMOVBE : FPI<0xD0, AddRegFrm, (ops RST:$op), + "fcmovbe {$op, %st(0)|%ST(0), $op}">, DA; + def FCMOVE : FPI<0xC8, AddRegFrm, (ops RST:$op), + "fcmove {$op, %st(0)|%ST(0), $op}">, DA; + def FCMOVP : FPI<0xD8, AddRegFrm, (ops RST:$op), + "fcmovu {$op, %st(0)|%ST(0), $op}">, DA; + def FCMOVNB : FPI<0xC0, AddRegFrm, (ops RST:$op), + "fcmovnb {$op, %st(0)|%ST(0), $op}">, DB; + def FCMOVNBE : FPI<0xD0, AddRegFrm, (ops RST:$op), + "fcmovnbe {$op, %st(0)|%ST(0), $op}">, DB; + def FCMOVNE : FPI<0xC8, AddRegFrm, (ops RST:$op), + "fcmovne {$op, %st(0)|%ST(0), $op}">, DB; + def FCMOVNP : FPI<0xD8, AddRegFrm, (ops RST:$op), + "fcmovnu {$op, %st(0)|%ST(0), $op}">, DB; + + // Floating point loads & stores. + def FpLD32m : FpI<(ops RFP:$dst, f32mem:$src), ZeroArgFP, + [(set RFP:$dst, (extloadf64f32 addr:$src))]>; + def FpLD64m : FpI<(ops RFP:$dst, f64mem:$src), ZeroArgFP, + [(set RFP:$dst, (loadf64 addr:$src))]>; + def FpILD16m : FpI<(ops RFP:$dst, i16mem:$src), ZeroArgFP, + [(set RFP:$dst, (X86fild addr:$src, i16))]>; + def FpILD32m : FpI<(ops RFP:$dst, i32mem:$src), ZeroArgFP, + [(set RFP:$dst, (X86fild addr:$src, i32))]>; + def FpILD64m : FpI<(ops RFP:$dst, i64mem:$src), ZeroArgFP, + [(set RFP:$dst, (X86fild addr:$src, i64))]>; + + def FpST32m : FpI<(ops f32mem:$op, RFP:$src), OneArgFP, + [(truncstore RFP:$src, addr:$op, f32)]>; + def FpST64m : FpI<(ops f64mem:$op, RFP:$src), OneArgFP, + [(store RFP:$src, addr:$op)]>; + + def FpSTP32m : FpI<(ops f32mem:$op, RFP:$src), OneArgFP, []>; + def FpSTP64m : FpI<(ops f64mem:$op, RFP:$src), OneArgFP, []>; + def FpIST16m : FpI<(ops i16mem:$op, RFP:$src), OneArgFP, []>; + def FpIST32m : FpI<(ops i32mem:$op, RFP:$src), OneArgFP, []>; + def FpIST64m : FpI<(ops i64mem:$op, RFP:$src), OneArgFP, []>; + + def FLD32m : FPI<0xD9, MRM0m, (ops f32mem:$src), "fld{s} $src">; + def FLD64m : FPI<0xDD, MRM0m, (ops f64mem:$src), "fld{l} $src">; + def FILD16m : FPI<0xDF, MRM0m, (ops i16mem:$src), "fild{s} $src">; + def FILD32m : FPI<0xDB, MRM0m, (ops i32mem:$src), "fild{l} $src">; + def FILD64m : FPI<0xDF, MRM5m, (ops i64mem:$src), "fild{ll} $src">; + def FST32m : FPI<0xD9, MRM2m, (ops f32mem:$dst), "fst{s} $dst">; + def FST64m : FPI<0xDD, MRM2m, (ops f64mem:$dst), "fst{l} $dst">; + def FSTP32m : FPI<0xD9, MRM3m, (ops f32mem:$dst), "fstp{s} $dst">; + def FSTP64m : FPI<0xDD, MRM3m, (ops f64mem:$dst), "fstp{l} $dst">; + def FIST16m : FPI<0xDF, MRM2m, (ops i16mem:$dst), "fist{s} $dst">; + def FIST32m : FPI<0xDB, MRM2m, (ops i32mem:$dst), "fist{l} $dst">; + def FISTP16m : FPI<0xDF, MRM3m, (ops i16mem:$dst), "fistp{s} $dst">; + def FISTP32m : FPI<0xDB, MRM3m, (ops i32mem:$dst), "fistp{l} $dst">; + def FISTP64m : FPI<0xDF, MRM7m, (ops i64mem:$dst), "fistp{ll} $dst">; + + // FISTTP requires SSE3 even though it's a FPStack op. + def FpISTT16m : FpI_<(ops i16mem:$op, RFP:$src), OneArgFP, + [(X86fp_to_i16mem RFP:$src, addr:$op)]>, + Requires<[HasSSE3]>; + def FpISTT32m : FpI_<(ops i32mem:$op, RFP:$src), OneArgFP, + [(X86fp_to_i32mem RFP:$src, addr:$op)]>, + Requires<[HasSSE3]>; + def FpISTT64m : FpI_<(ops i64mem:$op, RFP:$src), OneArgFP, + [(X86fp_to_i64mem RFP:$src, addr:$op)]>, + Requires<[HasSSE3]>; + + def FISTTP16m : FPI<0xDF, MRM1m, (ops i16mem:$dst), "fisttp{s} $dst">; + def FISTTP32m : FPI<0xDB, MRM1m, (ops i32mem:$dst), "fisttp{l} $dst">; + def FISTTP64m : FPI<0xDD, MRM1m, (ops i64mem:$dst), "fisttp{ll} $dst">; + + // FP Stack manipulation instructions. + def FLDrr : FPI<0xC0, AddRegFrm, (ops RST:$op), "fld $op">, D9; + def FSTrr : FPI<0xD0, AddRegFrm, (ops RST:$op), "fst $op">, DD; + def FSTPrr : FPI<0xD8, AddRegFrm, (ops RST:$op), "fstp $op">, DD; + def FXCH : FPI<0xC8, AddRegFrm, (ops RST:$op), "fxch $op">, D9; + + // Floating point constant loads. + def FpLD0 : FpI<(ops RFP:$dst), ZeroArgFP, + [(set RFP:$dst, fp64imm0)]>; + def FpLD1 : FpI<(ops RFP:$dst), ZeroArgFP, + [(set RFP:$dst, fp64imm1)]>; + + def FLD0 : FPI<0xEE, RawFrm, (ops), "fldz">, D9; + def FLD1 : FPI<0xE8, RawFrm, (ops), "fld1">, D9; + + + // Floating point compares. + def FpUCOMr : FpI<(ops RFP:$lhs, RFP:$rhs), CompareFP, + []>; // FPSW = cmp ST(0) with ST(i) + def FpUCOMIr : FpI<(ops RFP:$lhs, RFP:$rhs), CompareFP, + [(X86cmp RFP:$lhs, RFP:$rhs)]>; // CC = cmp ST(0) with ST(i) + + def FUCOMr : FPI<0xE0, AddRegFrm, // FPSW = cmp ST(0) with ST(i) + (ops RST:$reg), + "fucom $reg">, DD, Imp<[ST0],[]>; + def FUCOMPr : FPI<0xE8, AddRegFrm, // FPSW = cmp ST(0) with ST(i), pop + (ops RST:$reg), + "fucomp $reg">, DD, Imp<[ST0],[]>; + def FUCOMPPr : FPI<0xE9, RawFrm, // cmp ST(0) with ST(1), pop, pop + (ops), + "fucompp">, DA, Imp<[ST0],[]>; + + def FUCOMIr : FPI<0xE8, AddRegFrm, // CC = cmp ST(0) with ST(i) + (ops RST:$reg), + "fucomi {$reg, %st(0)|%ST(0), $reg}">, DB, Imp<[ST0],[]>; + def FUCOMIPr : FPI<0xE8, AddRegFrm, // CC = cmp ST(0) with ST(i), pop + (ops RST:$reg), + "fucomip {$reg, %st(0)|%ST(0), $reg}">, DF, Imp<[ST0],[]>; + + + // Floating point flag ops. + def FNSTSW8r : I<0xE0, RawFrm, // AX = fp flags + (ops), "fnstsw", []>, DF, Imp<[],[AX]>; + + def FNSTCW16m : I<0xD9, MRM7m, // [mem16] = X87 control world + (ops i16mem:$dst), "fnstcw $dst", []>; + def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16] + (ops i16mem:$dst), "fldcw $dst", []>; + + + //===----------------------------------------------------------------------===// + // Alias Instructions + //===----------------------------------------------------------------------===// + + // Alias instructions that map fld0 to pxor for sse. + // FIXME: remove when we can teach regalloc that xor reg, reg is ok. + def FsFLD0SS : I<0xEF, MRMInitReg, (ops FR32:$dst), + "pxor $dst, $dst", [(set FR32:$dst, fp32imm0)]>, + Requires<[HasSSE1]>, TB, OpSize; + def FsFLD0SD : I<0xEF, MRMInitReg, (ops FR64:$dst), + "pxor $dst, $dst", [(set FR64:$dst, fp64imm0)]>, + Requires<[HasSSE2]>, TB, OpSize; + + // Alias instructions to do FR32 / FR64 reg-to-reg copy using movaps / movapd. + // Upper bits are disregarded. + def FsMOVAPSrr : I<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), + "movaps {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, TB; + def FsMOVAPDrr : I<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), + "movapd {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE2]>, TB, OpSize; + + // Alias instructions to load FR32 / FR64 from f128mem using movaps / movapd. + // Upper bits are disregarded. + def FsMOVAPSrm : I<0x28, MRMSrcMem, (ops FR32:$dst, f128mem:$src), + "movaps {$src, $dst|$dst, $src}", + [(set FR32:$dst, (X86loadpf32 addr:$src))]>, + Requires<[HasSSE1]>, TB; + def FsMOVAPDrm : I<0x28, MRMSrcMem, (ops FR64:$dst, f128mem:$src), + "movapd {$src, $dst|$dst, $src}", + [(set FR64:$dst, (X86loadpf64 addr:$src))]>, + Requires<[HasSSE2]>, TB, OpSize; + + // Alias bitwise logical operations using SSE logical ops on packed FP values. + let isTwoAddress = 1 in { + let isCommutable = 1 in { + def FsANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "andps {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (X86fand FR32:$src1, FR32:$src2))]>, + Requires<[HasSSE1]>, TB; + def FsANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "andpd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (X86fand FR64:$src1, FR64:$src2))]>, + Requires<[HasSSE2]>, TB, OpSize; + def FsORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "orps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; + def FsORPDrr : I<0x56, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; + def FsXORPSrr : I<0x57, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "xorps {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (X86fxor FR32:$src1, FR32:$src2))]>, + Requires<[HasSSE1]>, TB; + def FsXORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "xorpd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (X86fxor FR64:$src1, FR64:$src2))]>, + Requires<[HasSSE2]>, TB, OpSize; + } + def FsANDPSrm : I<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + "andps {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (X86fand FR32:$src1, + (X86loadpf32 addr:$src2)))]>, + Requires<[HasSSE1]>, TB; + def FsANDPDrm : I<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + "andpd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (X86fand FR64:$src1, + (X86loadpf64 addr:$src2)))]>, + Requires<[HasSSE2]>, TB, OpSize; + def FsORPSrm : I<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + "orps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; + def FsORPDrm : I<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; + def FsXORPSrm : I<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + "xorps {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (X86fxor FR32:$src1, + (X86loadpf32 addr:$src2)))]>, + Requires<[HasSSE1]>, TB; + def FsXORPDrm : I<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + "xorpd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (X86fxor FR64:$src1, + (X86loadpf64 addr:$src2)))]>, + Requires<[HasSSE2]>, TB, OpSize; + + def FsANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; + def FsANDNPSrm : I<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; + def FsANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; + def FsANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; + } Index: llvm/lib/Target/X86/X86InstrMMX.td diff -c /dev/null llvm/lib/Target/X86/X86InstrMMX.td:1.1 *** /dev/null Tue Feb 21 13:14:05 2006 --- llvm/lib/Target/X86/X86InstrMMX.td Tue Feb 21 13:13:53 2006 *************** *** 0 **** --- 1,57 ---- + //====- X86InstrMMX.td - Describe the X86 Instruction Set -------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the Evan Cheng and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file describes the X86 MMX instruction set, defining the instructions, + // and properties of the instructions which are needed for code generation, + // machine code emission, and analysis. + // + //===----------------------------------------------------------------------===// + + // Move Instructions + def MOVD64rr : I<0x6E, MRMSrcReg, (ops VR64:$dst, R32:$src), + "movd {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasMMX]>; + def MOVD64rm : I<0x6E, MRMSrcMem, (ops VR64:$dst, i32mem:$src), + "movd {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasMMX]>; + def MOVD64mr : I<0x7E, MRMDestMem, (ops i32mem:$dst, VR64:$src), + "movd {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasMMX]>; + + def MOVD128rr : I<0x6E, MRMSrcReg, (ops VR128:$dst, R32:$src), + "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, + Requires<[HasSSE2]>; + def MOVD128rm : I<0x6E, MRMSrcMem, (ops VR128:$dst, i32mem:$src), + "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, + Requires<[HasSSE2]>; + def MOVD128mr : I<0x7E, MRMDestMem, (ops i32mem:$dst, VR128:$src), + "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, + Requires<[HasSSE2]>; + + + def MOVQ64rr : I<0x6F, MRMSrcReg, (ops VR64:$dst, VR64:$src), + "movq {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasMMX]>; + def MOVQ64rm : I<0x6F, MRMSrcMem, (ops VR64:$dst, i64mem:$src), + "movq {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasMMX]>; + def MOVQ64mr : I<0x7F, MRMDestMem, (ops i64mem:$dst, VR64:$src), + "movq {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasMMX]>; + + def MOVQ128rr : I<0x7E, MRMSrcReg, (ops VR128:$dst, VR64:$src), + "movq {$src, $dst|$dst, $src}", []>, XS, + Requires<[HasSSE2]>; + def MOVQ128rm : I<0x7E, MRMSrcMem, (ops VR128:$dst, i64mem:$src), + "movq {$src, $dst|$dst, $src}", []>, XS, + Requires<[HasSSE2]>; + def MOVQ128mr : I<0xD6, MRMSrcMem, (ops i64mem:$dst, VR128:$src), + "movq {$src, $dst|$dst, $src}", []>, TB, OpSize, + Requires<[HasSSE2]>; + Index: llvm/lib/Target/X86/X86InstrSSE.td diff -c /dev/null llvm/lib/Target/X86/X86InstrSSE.td:1.1 *** /dev/null Tue Feb 21 13:14:05 2006 --- llvm/lib/Target/X86/X86InstrSSE.td Tue Feb 21 13:13:53 2006 *************** *** 0 **** --- 1,101 ---- + //====- X86InstrSSE.td - Describe the X86 Instruction Set -------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the Evan Cheng and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file describes the X86 SSE instruction set, defining the instructions, + // and properties of the instructions which are needed for code generation, + // machine code emission, and analysis. + // + //===----------------------------------------------------------------------===// + + def MOVAPSrr : I<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), + "movaps {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, TB; + def MOVAPDrr : I<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), + "movapd {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE2]>, TB, OpSize; + + def MOVAPSrm : I<0x28, MRMSrcMem, (ops V4F32:$dst, f128mem:$src), + "movaps {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, TB; + def MOVAPSmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V4F32:$src), + "movaps {$src, $dst|$dst, $src}",[]>, + Requires<[HasSSE1]>, TB; + def MOVAPDrm : I<0x28, MRMSrcMem, (ops V2F64:$dst, f128mem:$src), + "movapd {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, TB, OpSize; + def MOVAPDmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V2F64:$src), + "movapd {$src, $dst|$dst, $src}",[]>, + Requires<[HasSSE2]>, TB, OpSize; + + // Logical + let isTwoAddress = 1 in { + let isCommutable = 1 in { + def ANDPSrr : I<0x54, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "andps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (X86fand V4F32:$src1, V4F32:$src2))]>, + Requires<[HasSSE1]>, TB; + def ANDPDrr : I<0x54, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "andpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (X86fand V2F64:$src1, V2F64:$src2))]>, + Requires<[HasSSE2]>, TB, OpSize; + def ORPSrr : I<0x56, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "orps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; + def ORPDrr : I<0x56, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; + def XORPSrr : I<0x57, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "xorps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (X86fxor V4F32:$src1, V4F32:$src2))]>, + Requires<[HasSSE1]>, TB; + def XORPDrr : I<0x57, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "xorpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (X86fxor V2F64:$src1, V2F64:$src2))]>, + Requires<[HasSSE2]>, TB, OpSize; + } + def ANDPSrm : I<0x54, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "andps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (X86fand V4F32:$src1, + (X86loadpv4f32 addr:$src2)))]>, + Requires<[HasSSE1]>, TB; + def ANDPDrm : I<0x54, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "andpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (X86fand V2F64:$src1, + (X86loadpv2f64 addr:$src2)))]>, + Requires<[HasSSE2]>, TB, OpSize; + def ORPSrm : I<0x56, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "orps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; + def ORPDrm : I<0x56, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; + def XORPSrm : I<0x57, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "xorps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (X86fxor V4F32:$src1, + (X86loadpv4f32 addr:$src2)))]>, + Requires<[HasSSE1]>, TB; + def XORPDrm : I<0x57, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "xorpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (X86fxor V2F64:$src1, + (X86loadpv2f64 addr:$src2)))]>, + Requires<[HasSSE2]>, TB, OpSize; + + def ANDNPSrr : I<0x55, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; + def ANDNPSrm : I<0x55, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; + def ANDNPDrr : I<0x55, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; + def ANDNPDrm : I<0x55, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; + } Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.242 llvm/lib/Target/X86/X86InstrInfo.td:1.243 --- llvm/lib/Target/X86/X86InstrInfo.td:1.242 Mon Feb 20 20:24:38 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Tue Feb 21 13:13:53 2006 @@ -191,6 +191,7 @@ //===----------------------------------------------------------------------===// // X86 Instruction Predicate Definitions. +def HasMMX : Predicate<"Subtarget->hasMMX()">; def HasSSE1 : Predicate<"Subtarget->hasSSE1()">; def HasSSE2 : Predicate<"Subtarget->hasSSE2()">; def HasSSE3 : Predicate<"Subtarget->hasSSE3()">; @@ -2571,510 +2572,19 @@ // Floating Point Stack Support //===----------------------------------------------------------------------===// -// Floating point support. All FP Stack operations are represented with two -// instructions here. The first instruction, generated by the instruction -// selector, uses "RFP" registers: a traditional register file to reference -// floating point values. These instructions are all psuedo instructions and -// use the "Fp" prefix. The second instruction is defined with FPI, which is -// the actual instruction emitted by the assembler. The FP stackifier pass -// converts one to the other after register allocation occurs. -// -// Note that the FpI instruction should have instruction selection info (e.g. -// a pattern) and the FPI instruction should have emission info (e.g. opcode -// encoding and asm printing info). - -// FPI - Floating Point Instruction template. -class FPI o, Format F, dag ops, string asm> : I {} - -// FpI_ - Floating Point Psuedo Instruction template. Not Predicated. -class FpI_ pattern> - : X86Inst<0, Pseudo, NoImm, ops, ""> { - let FPForm = fp; let FPFormBits = FPForm.Value; - let Pattern = pattern; -} - -// Random Pseudo Instructions. -def FpGETRESULT : FpI_<(ops RFP:$dst), SpecialFP, - [(set RFP:$dst, X86fpget)]>; // FPR = ST(0) - -let noResults = 1 in - def FpSETRESULT : FpI_<(ops RFP:$src), SpecialFP, - [(X86fpset RFP:$src)]>, Imp<[], [ST0]>; // ST(0) = FPR - -// FpI - Floating Point Psuedo Instruction template. Predicated on FPStack. -class FpI pattern> : - FpI_, Requires<[FPStack]>; - - -def FpMOV : FpI<(ops RFP:$dst, RFP:$src), SpecialFP, []>; // f1 = fmov f2 - -// Arithmetic -// Add, Sub, Mul, Div. -def FpADD : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP, - [(set RFP:$dst, (fadd RFP:$src1, RFP:$src2))]>; -def FpSUB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP, - [(set RFP:$dst, (fsub RFP:$src1, RFP:$src2))]>; -def FpMUL : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP, - [(set RFP:$dst, (fmul RFP:$src1, RFP:$src2))]>; -def FpDIV : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP, - [(set RFP:$dst, (fdiv RFP:$src1, RFP:$src2))]>; - -class FPST0rInst o, string asm> - : FPI, D8; -class FPrST0Inst o, string asm> - : FPI, DC; -class FPrST0PInst o, string asm> - : FPI, DE; - -// Binary Ops with a memory source. -def FpADD32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fadd RFP:$src1, - (extloadf64f32 addr:$src2)))]>; - // ST(0) = ST(0) + [mem32] -def FpADD64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fadd RFP:$src1, (loadf64 addr:$src2)))]>; - // ST(0) = ST(0) + [mem64] -def FpMUL32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fmul RFP:$src1, - (extloadf64f32 addr:$src2)))]>; - // ST(0) = ST(0) * [mem32] -def FpMUL64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fmul RFP:$src1, (loadf64 addr:$src2)))]>; - // ST(0) = ST(0) * [mem64] -def FpSUB32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fsub RFP:$src1, - (extloadf64f32 addr:$src2)))]>; - // ST(0) = ST(0) - [mem32] -def FpSUB64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fsub RFP:$src1, (loadf64 addr:$src2)))]>; - // ST(0) = ST(0) - [mem64] -def FpSUBR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fsub (extloadf64f32 addr:$src2), - RFP:$src1))]>; - // ST(0) = [mem32] - ST(0) -def FpSUBR64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fsub (loadf64 addr:$src2), RFP:$src1))]>; - // ST(0) = [mem64] - ST(0) -def FpDIV32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fdiv RFP:$src1, - (extloadf64f32 addr:$src2)))]>; - // ST(0) = ST(0) / [mem32] -def FpDIV64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fdiv RFP:$src1, (loadf64 addr:$src2)))]>; - // ST(0) = ST(0) / [mem64] -def FpDIVR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fdiv (extloadf64f32 addr:$src2), - RFP:$src1))]>; - // ST(0) = [mem32] / ST(0) -def FpDIVR64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fdiv (loadf64 addr:$src2), RFP:$src1))]>; - // ST(0) = [mem64] / ST(0) - - -def FADD32m : FPI<0xD8, MRM0m, (ops f32mem:$src), "fadd{s} $src">; -def FADD64m : FPI<0xDC, MRM0m, (ops f64mem:$src), "fadd{l} $src">; -def FMUL32m : FPI<0xD8, MRM1m, (ops f32mem:$src), "fmul{s} $src">; -def FMUL64m : FPI<0xDC, MRM1m, (ops f64mem:$src), "fmul{l} $src">; -def FSUB32m : FPI<0xD8, MRM4m, (ops f32mem:$src), "fsub{s} $src">; -def FSUB64m : FPI<0xDC, MRM4m, (ops f64mem:$src), "fsub{l} $src">; -def FSUBR32m : FPI<0xD8, MRM5m, (ops f32mem:$src), "fsubr{s} $src">; -def FSUBR64m : FPI<0xDC, MRM5m, (ops f64mem:$src), "fsubr{l} $src">; -def FDIV32m : FPI<0xD8, MRM6m, (ops f32mem:$src), "fdiv{s} $src">; -def FDIV64m : FPI<0xDC, MRM6m, (ops f64mem:$src), "fdiv{l} $src">; -def FDIVR32m : FPI<0xD8, MRM7m, (ops f32mem:$src), "fdivr{s} $src">; -def FDIVR64m : FPI<0xDC, MRM7m, (ops f64mem:$src), "fdivr{l} $src">; - -def FpIADD16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fadd RFP:$src1, - (X86fild addr:$src2, i16)))]>; - // ST(0) = ST(0) + [mem16int] -def FpIADD32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fadd RFP:$src1, - (X86fild addr:$src2, i32)))]>; - // ST(0) = ST(0) + [mem32int] -def FpIMUL16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fmul RFP:$src1, - (X86fild addr:$src2, i16)))]>; - // ST(0) = ST(0) * [mem16int] -def FpIMUL32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fmul RFP:$src1, - (X86fild addr:$src2, i32)))]>; - // ST(0) = ST(0) * [mem32int] -def FpISUB16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fsub RFP:$src1, - (X86fild addr:$src2, i16)))]>; - // ST(0) = ST(0) - [mem16int] -def FpISUB32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fsub RFP:$src1, - (X86fild addr:$src2, i32)))]>; - // ST(0) = ST(0) - [mem32int] -def FpISUBR16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fsub (X86fild addr:$src2, i16), - RFP:$src1))]>; - // ST(0) = [mem16int] - ST(0) -def FpISUBR32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fsub (X86fild addr:$src2, i32), - RFP:$src1))]>; - // ST(0) = [mem32int] - ST(0) -def FpIDIV16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fdiv RFP:$src1, - (X86fild addr:$src2, i16)))]>; - // ST(0) = ST(0) / [mem16int] -def FpIDIV32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fdiv RFP:$src1, - (X86fild addr:$src2, i32)))]>; - // ST(0) = ST(0) / [mem32int] -def FpIDIVR16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fdiv (X86fild addr:$src2, i16), - RFP:$src1))]>; - // ST(0) = [mem16int] / ST(0) -def FpIDIVR32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fdiv (X86fild addr:$src2, i32), - RFP:$src1))]>; - // ST(0) = [mem32int] / ST(0) - -def FIADD16m : FPI<0xDE, MRM0m, (ops i16mem:$src), "fiadd{s} $src">; -def FIADD32m : FPI<0xDA, MRM0m, (ops i32mem:$src), "fiadd{l} $src">; -def FIMUL16m : FPI<0xDE, MRM1m, (ops i16mem:$src), "fimul{s} $src">; -def FIMUL32m : FPI<0xDA, MRM1m, (ops i32mem:$src), "fimul{l} $src">; -def FISUB16m : FPI<0xDE, MRM4m, (ops i16mem:$src), "fisub{s} $src">; -def FISUB32m : FPI<0xDA, MRM4m, (ops i32mem:$src), "fisub{l} $src">; -def FISUBR16m : FPI<0xDE, MRM5m, (ops i16mem:$src), "fisubr{s} $src">; -def FISUBR32m : FPI<0xDA, MRM5m, (ops i32mem:$src), "fisubr{l} $src">; -def FIDIV16m : FPI<0xDE, MRM6m, (ops i16mem:$src), "fidiv{s} $src">; -def FIDIV32m : FPI<0xDA, MRM6m, (ops i32mem:$src), "fidiv{l} $src">; -def FIDIVR16m : FPI<0xDE, MRM7m, (ops i16mem:$src), "fidivr{s} $src">; -def FIDIVR32m : FPI<0xDA, MRM7m, (ops i32mem:$src), "fidivr{l} $src">; - -// NOTE: GAS and apparently all other AT&T style assemblers have a broken notion -// of some of the 'reverse' forms of the fsub and fdiv instructions. As such, -// we have to put some 'r's in and take them out of weird places. -def FADDST0r : FPST0rInst <0xC0, "fadd $op">; -def FADDrST0 : FPrST0Inst <0xC0, "fadd {%st(0), $op|$op, %ST(0)}">; -def FADDPrST0 : FPrST0PInst<0xC0, "faddp $op">; -def FSUBRST0r : FPST0rInst <0xE8, "fsubr $op">; -def FSUBrST0 : FPrST0Inst <0xE8, "fsub{r} {%st(0), $op|$op, %ST(0)}">; -def FSUBPrST0 : FPrST0PInst<0xE8, "fsub{r}p $op">; -def FSUBST0r : FPST0rInst <0xE0, "fsub $op">; -def FSUBRrST0 : FPrST0Inst <0xE0, "fsub{|r} {%st(0), $op|$op, %ST(0)}">; -def FSUBRPrST0 : FPrST0PInst<0xE0, "fsub{|r}p $op">; -def FMULST0r : FPST0rInst <0xC8, "fmul $op">; -def FMULrST0 : FPrST0Inst <0xC8, "fmul {%st(0), $op|$op, %ST(0)}">; -def FMULPrST0 : FPrST0PInst<0xC8, "fmulp $op">; -def FDIVRST0r : FPST0rInst <0xF8, "fdivr $op">; -def FDIVrST0 : FPrST0Inst <0xF8, "fdiv{r} {%st(0), $op|$op, %ST(0)}">; -def FDIVPrST0 : FPrST0PInst<0xF8, "fdiv{r}p $op">; -def FDIVST0r : FPST0rInst <0xF0, "fdiv $op">; -def FDIVRrST0 : FPrST0Inst <0xF0, "fdiv{|r} {%st(0), $op|$op, %ST(0)}">; -def FDIVRPrST0 : FPrST0PInst<0xF0, "fdiv{|r}p $op">; - - -// Unary operations. -def FpCHS : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW, - [(set RFP:$dst, (fneg RFP:$src))]>; -def FpABS : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW, - [(set RFP:$dst, (fabs RFP:$src))]>; -def FpSQRT : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW, - [(set RFP:$dst, (fsqrt RFP:$src))]>; -def FpSIN : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW, - [(set RFP:$dst, (fsin RFP:$src))]>; -def FpCOS : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW, - [(set RFP:$dst, (fcos RFP:$src))]>; -def FpTST : FpI<(ops RFP:$src), OneArgFP, - []>; - -def FCHS : FPI<0xE0, RawFrm, (ops), "fchs">, D9; -def FABS : FPI<0xE1, RawFrm, (ops), "fabs">, D9; -def FSQRT : FPI<0xFA, RawFrm, (ops), "fsqrt">, D9; -def FSIN : FPI<0xFE, RawFrm, (ops), "fsin">, D9; -def FCOS : FPI<0xFF, RawFrm, (ops), "fcos">, D9; -def FTST : FPI<0xE4, RawFrm, (ops), "ftst">, D9; - - -// Floating point cmovs. -let isTwoAddress = 1 in { - def FpCMOVB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, - [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, - X86_COND_B))]>; - def FpCMOVBE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, - [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, - X86_COND_BE))]>; - def FpCMOVE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, - [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, - X86_COND_E))]>; - def FpCMOVP : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, - [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, - X86_COND_P))]>; - def FpCMOVNB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, - [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, - X86_COND_AE))]>; - def FpCMOVNBE: FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, - [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, - X86_COND_A))]>; - def FpCMOVNE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, - [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, - X86_COND_NE))]>; - def FpCMOVNP : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP, - [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2, - X86_COND_NP))]>; -} - -def FCMOVB : FPI<0xC0, AddRegFrm, (ops RST:$op), - "fcmovb {$op, %st(0)|%ST(0), $op}">, DA; -def FCMOVBE : FPI<0xD0, AddRegFrm, (ops RST:$op), - "fcmovbe {$op, %st(0)|%ST(0), $op}">, DA; -def FCMOVE : FPI<0xC8, AddRegFrm, (ops RST:$op), - "fcmove {$op, %st(0)|%ST(0), $op}">, DA; -def FCMOVP : FPI<0xD8, AddRegFrm, (ops RST:$op), - "fcmovu {$op, %st(0)|%ST(0), $op}">, DA; -def FCMOVNB : FPI<0xC0, AddRegFrm, (ops RST:$op), - "fcmovnb {$op, %st(0)|%ST(0), $op}">, DB; -def FCMOVNBE : FPI<0xD0, AddRegFrm, (ops RST:$op), - "fcmovnbe {$op, %st(0)|%ST(0), $op}">, DB; -def FCMOVNE : FPI<0xC8, AddRegFrm, (ops RST:$op), - "fcmovne {$op, %st(0)|%ST(0), $op}">, DB; -def FCMOVNP : FPI<0xD8, AddRegFrm, (ops RST:$op), - "fcmovnu {$op, %st(0)|%ST(0), $op}">, DB; - -// Floating point loads & stores. -def FpLD32m : FpI<(ops RFP:$dst, f32mem:$src), ZeroArgFP, - [(set RFP:$dst, (extloadf64f32 addr:$src))]>; -def FpLD64m : FpI<(ops RFP:$dst, f64mem:$src), ZeroArgFP, - [(set RFP:$dst, (loadf64 addr:$src))]>; -def FpILD16m : FpI<(ops RFP:$dst, i16mem:$src), ZeroArgFP, - [(set RFP:$dst, (X86fild addr:$src, i16))]>; -def FpILD32m : FpI<(ops RFP:$dst, i32mem:$src), ZeroArgFP, - [(set RFP:$dst, (X86fild addr:$src, i32))]>; -def FpILD64m : FpI<(ops RFP:$dst, i64mem:$src), ZeroArgFP, - [(set RFP:$dst, (X86fild addr:$src, i64))]>; - -def FpST32m : FpI<(ops f32mem:$op, RFP:$src), OneArgFP, - [(truncstore RFP:$src, addr:$op, f32)]>; -def FpST64m : FpI<(ops f64mem:$op, RFP:$src), OneArgFP, - [(store RFP:$src, addr:$op)]>; - -def FpSTP32m : FpI<(ops f32mem:$op, RFP:$src), OneArgFP, []>; -def FpSTP64m : FpI<(ops f64mem:$op, RFP:$src), OneArgFP, []>; -def FpIST16m : FpI<(ops i16mem:$op, RFP:$src), OneArgFP, []>; -def FpIST32m : FpI<(ops i32mem:$op, RFP:$src), OneArgFP, []>; -def FpIST64m : FpI<(ops i64mem:$op, RFP:$src), OneArgFP, []>; - -def FLD32m : FPI<0xD9, MRM0m, (ops f32mem:$src), "fld{s} $src">; -def FLD64m : FPI<0xDD, MRM0m, (ops f64mem:$src), "fld{l} $src">; -def FILD16m : FPI<0xDF, MRM0m, (ops i16mem:$src), "fild{s} $src">; -def FILD32m : FPI<0xDB, MRM0m, (ops i32mem:$src), "fild{l} $src">; -def FILD64m : FPI<0xDF, MRM5m, (ops i64mem:$src), "fild{ll} $src">; -def FST32m : FPI<0xD9, MRM2m, (ops f32mem:$dst), "fst{s} $dst">; -def FST64m : FPI<0xDD, MRM2m, (ops f64mem:$dst), "fst{l} $dst">; -def FSTP32m : FPI<0xD9, MRM3m, (ops f32mem:$dst), "fstp{s} $dst">; -def FSTP64m : FPI<0xDD, MRM3m, (ops f64mem:$dst), "fstp{l} $dst">; -def FIST16m : FPI<0xDF, MRM2m, (ops i16mem:$dst), "fist{s} $dst">; -def FIST32m : FPI<0xDB, MRM2m, (ops i32mem:$dst), "fist{l} $dst">; -def FISTP16m : FPI<0xDF, MRM3m, (ops i16mem:$dst), "fistp{s} $dst">; -def FISTP32m : FPI<0xDB, MRM3m, (ops i32mem:$dst), "fistp{l} $dst">; -def FISTP64m : FPI<0xDF, MRM7m, (ops i64mem:$dst), "fistp{ll} $dst">; - -// FISTTP requires SSE3 even though it's a FPStack op. -def FpISTT16m : FpI_<(ops i16mem:$op, RFP:$src), OneArgFP, - [(X86fp_to_i16mem RFP:$src, addr:$op)]>, - Requires<[HasSSE3]>; -def FpISTT32m : FpI_<(ops i32mem:$op, RFP:$src), OneArgFP, - [(X86fp_to_i32mem RFP:$src, addr:$op)]>, - Requires<[HasSSE3]>; -def FpISTT64m : FpI_<(ops i64mem:$op, RFP:$src), OneArgFP, - [(X86fp_to_i64mem RFP:$src, addr:$op)]>, - Requires<[HasSSE3]>; - -def FISTTP16m : FPI<0xDF, MRM1m, (ops i16mem:$dst), "fisttp{s} $dst">; -def FISTTP32m : FPI<0xDB, MRM1m, (ops i32mem:$dst), "fisttp{l} $dst">; -def FISTTP64m : FPI<0xDD, MRM1m, (ops i64mem:$dst), "fisttp{ll} $dst">; - -// FP Stack manipulation instructions. -def FLDrr : FPI<0xC0, AddRegFrm, (ops RST:$op), "fld $op">, D9; -def FSTrr : FPI<0xD0, AddRegFrm, (ops RST:$op), "fst $op">, DD; -def FSTPrr : FPI<0xD8, AddRegFrm, (ops RST:$op), "fstp $op">, DD; -def FXCH : FPI<0xC8, AddRegFrm, (ops RST:$op), "fxch $op">, D9; - -// Floating point constant loads. -def FpLD0 : FpI<(ops RFP:$dst), ZeroArgFP, - [(set RFP:$dst, fp64imm0)]>; -def FpLD1 : FpI<(ops RFP:$dst), ZeroArgFP, - [(set RFP:$dst, fp64imm1)]>; - -def FLD0 : FPI<0xEE, RawFrm, (ops), "fldz">, D9; -def FLD1 : FPI<0xE8, RawFrm, (ops), "fld1">, D9; - - -// Floating point compares. -def FpUCOMr : FpI<(ops RFP:$lhs, RFP:$rhs), CompareFP, - []>; // FPSW = cmp ST(0) with ST(i) -def FpUCOMIr : FpI<(ops RFP:$lhs, RFP:$rhs), CompareFP, - [(X86cmp RFP:$lhs, RFP:$rhs)]>; // CC = cmp ST(0) with ST(i) - -def FUCOMr : FPI<0xE0, AddRegFrm, // FPSW = cmp ST(0) with ST(i) - (ops RST:$reg), - "fucom $reg">, DD, Imp<[ST0],[]>; -def FUCOMPr : FPI<0xE8, AddRegFrm, // FPSW = cmp ST(0) with ST(i), pop - (ops RST:$reg), - "fucomp $reg">, DD, Imp<[ST0],[]>; -def FUCOMPPr : FPI<0xE9, RawFrm, // cmp ST(0) with ST(1), pop, pop - (ops), - "fucompp">, DA, Imp<[ST0],[]>; - -def FUCOMIr : FPI<0xE8, AddRegFrm, // CC = cmp ST(0) with ST(i) - (ops RST:$reg), - "fucomi {$reg, %st(0)|%ST(0), $reg}">, DB, Imp<[ST0],[]>; -def FUCOMIPr : FPI<0xE8, AddRegFrm, // CC = cmp ST(0) with ST(i), pop - (ops RST:$reg), - "fucomip {$reg, %st(0)|%ST(0), $reg}">, DF, Imp<[ST0],[]>; - - -// Floating point flag ops. -def FNSTSW8r : I<0xE0, RawFrm, // AX = fp flags - (ops), "fnstsw", []>, DF, Imp<[],[AX]>; - -def FNSTCW16m : I<0xD9, MRM7m, // [mem16] = X87 control world - (ops i16mem:$dst), "fnstcw $dst", []>; -def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16] - (ops i16mem:$dst), "fldcw $dst", []>; - +include "X86InstrFPStack.td" //===----------------------------------------------------------------------===// // MMX and XMM Packed Integer support (requires MMX, SSE, and SSE2) //===----------------------------------------------------------------------===// -// Move Instructions -def MOVD64rr : I<0x6E, MRMSrcReg, (ops VR64:$dst, R32:$src), - "movd {$src, $dst|$dst, $src}", []>, TB, - Requires<[HasSSE1]>; -def MOVD64rm : I<0x6E, MRMSrcMem, (ops VR64:$dst, i32mem:$src), - "movd {$src, $dst|$dst, $src}", []>, TB, - Requires<[HasSSE1]>; -def MOVD64mr : I<0x7E, MRMDestMem, (ops i32mem:$dst, VR64:$src), - "movd {$src, $dst|$dst, $src}", []>, TB, - Requires<[HasSSE1]>; - -def MOVD128rr : I<0x6E, MRMSrcReg, (ops VR128:$dst, R32:$src), - "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, - Requires<[HasSSE2]>; -def MOVD128rm : I<0x6E, MRMSrcMem, (ops VR128:$dst, i32mem:$src), - "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, - Requires<[HasSSE2]>; -def MOVD128mr : I<0x7E, MRMDestMem, (ops i32mem:$dst, VR128:$src), - "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, - Requires<[HasSSE2]>; - - -def MOVQ64rr : I<0x6F, MRMSrcReg, (ops VR64:$dst, VR64:$src), - "movq {$src, $dst|$dst, $src}", []>, TB, - Requires<[HasSSE1]>; -def MOVQ64rm : I<0x6F, MRMSrcMem, (ops VR64:$dst, i64mem:$src), - "movq {$src, $dst|$dst, $src}", []>, TB, - Requires<[HasSSE1]>; -def MOVQ64mr : I<0x7F, MRMDestMem, (ops i64mem:$dst, VR64:$src), - "movq {$src, $dst|$dst, $src}", []>, TB, - Requires<[HasSSE1]>; - -def MOVQ128rr : I<0x7E, MRMSrcReg, (ops VR128:$dst, VR64:$src), - "movq {$src, $dst|$dst, $src}", []>, XS, - Requires<[HasSSE2]>; -def MOVQ128rm : I<0x7E, MRMSrcMem, (ops VR128:$dst, i64mem:$src), - "movq {$src, $dst|$dst, $src}", []>, XS, - Requires<[HasSSE2]>; -def MOVQ128mr : I<0xD6, MRMSrcMem, (ops i64mem:$dst, VR128:$src), - "movq {$src, $dst|$dst, $src}", []>, TB, OpSize, - Requires<[HasSSE2]>; +include "X86InstrMMX.td" //===----------------------------------------------------------------------===// // XMM Packed Floating point support (requires SSE / SSE2) //===----------------------------------------------------------------------===// -def MOVAPSrr : I<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), - "movaps {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, TB; -def MOVAPDrr : I<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), - "movapd {$src, $dst|$dst, $src}v2", []>, - Requires<[HasSSE2]>, TB, OpSize; - -def MOVAPSrm : I<0x28, MRMSrcMem, (ops V4F32:$dst, f128mem:$src), - "movaps {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, TB; -def MOVAPSmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V4F32:$src), - "movaps {$src, $dst|$dst, $src}",[]>, - Requires<[HasSSE1]>, TB; -def MOVAPDrm : I<0x28, MRMSrcMem, (ops V2F64:$dst, f128mem:$src), - "movapd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, TB, OpSize; -def MOVAPDmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V2F64:$src), - "movapd {$src, $dst|$dst, $src}",[]>, - Requires<[HasSSE2]>, TB, OpSize; - -// Logical -let isTwoAddress = 1 in { -let isCommutable = 1 in { -def ANDPSrr : I<0x54, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), - "andps {$src2, $dst|$dst, $src2}", - [(set V4F32:$dst, (X86fand V4F32:$src1, V4F32:$src2))]>, - Requires<[HasSSE1]>, TB; -def ANDPDrr : I<0x54, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), - "andpd {$src2, $dst|$dst, $src2}", - [(set V2F64:$dst, (X86fand V2F64:$src1, V2F64:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; -def ORPSrr : I<0x56, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), - "orps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ORPDrr : I<0x56, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), - "orpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def XORPSrr : I<0x57, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), - "xorps {$src2, $dst|$dst, $src2}", - [(set V4F32:$dst, (X86fxor V4F32:$src1, V4F32:$src2))]>, - Requires<[HasSSE1]>, TB; -def XORPDrr : I<0x57, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), - "xorpd {$src2, $dst|$dst, $src2}", - [(set V2F64:$dst, (X86fxor V2F64:$src1, V2F64:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; -} -def ANDPSrm : I<0x54, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), - "andps {$src2, $dst|$dst, $src2}", - [(set V4F32:$dst, (X86fand V4F32:$src1, - (X86loadpv4f32 addr:$src2)))]>, - Requires<[HasSSE1]>, TB; -def ANDPDrm : I<0x54, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), - "andpd {$src2, $dst|$dst, $src2}", - [(set V2F64:$dst, (X86fand V2F64:$src1, - (X86loadpv2f64 addr:$src2)))]>, - Requires<[HasSSE2]>, TB, OpSize; -def ORPSrm : I<0x56, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), - "orps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ORPDrm : I<0x56, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), - "orpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def XORPSrm : I<0x57, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), - "xorps {$src2, $dst|$dst, $src2}", - [(set V4F32:$dst, (X86fxor V4F32:$src1, - (X86loadpv4f32 addr:$src2)))]>, - Requires<[HasSSE1]>, TB; -def XORPDrm : I<0x57, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), - "xorpd {$src2, $dst|$dst, $src2}", - [(set V2F64:$dst, (X86fxor V2F64:$src1, - (X86loadpv2f64 addr:$src2)))]>, - Requires<[HasSSE2]>, TB, OpSize; - -def ANDNPSrr : I<0x55, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), - "andnps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ANDNPSrm : I<0x55, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), - "andnps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ANDNPDrr : I<0x55, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), - "andnpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def ANDNPDrm : I<0x55, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), - "andnpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -} +include "X86InstrSSE.td" //===----------------------------------------------------------------------===// // Miscellaneous Instructions @@ -3100,102 +2610,6 @@ "xor{l} $dst, $dst", [(set R32:$dst, 0)]>; -// Alias instructions that map fld0 to pxor for sse. -// FIXME: remove when we can teach regalloc that xor reg, reg is ok. -def FLD0SS : I<0xEF, MRMInitReg, (ops FR32:$dst), - "pxor $dst, $dst", [(set FR32:$dst, fp32imm0)]>, - Requires<[HasSSE1]>, TB, OpSize; -def FLD0SD : I<0xEF, MRMInitReg, (ops FR64:$dst), - "pxor $dst, $dst", [(set FR64:$dst, fp64imm0)]>, - Requires<[HasSSE2]>, TB, OpSize; - -// Alias instructions to do FR32 / FR64 reg-to-reg copy using movaps / movapd. -// Upper bits are disregarded. -def FsMOVAPSrr : I<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), - "movaps {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, TB; -def FsMOVAPDrr : I<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), - "movapd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE2]>, TB, OpSize; - -// Alias instructions to load FR32 / FR64 from f128mem using movaps / movapd. -// Upper bits are disregarded. -def FsMOVAPSrm : I<0x28, MRMSrcMem, (ops FR32:$dst, f128mem:$src), - "movaps {$src, $dst|$dst, $src}", - [(set FR32:$dst, (X86loadpf32 addr:$src))]>, - Requires<[HasSSE1]>, TB; -def FsMOVAPDrm : I<0x28, MRMSrcMem, (ops FR64:$dst, f128mem:$src), - "movapd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (X86loadpf64 addr:$src))]>, - Requires<[HasSSE2]>, TB, OpSize; - -// Alias bitwise logical operations using SSE logical ops on packed FP values. -let isTwoAddress = 1 in { -let isCommutable = 1 in { -def FsANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "andps {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fand FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, TB; -def FsANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "andpd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fand FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; -def FsORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "orps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def FsORPDrr : I<0x56, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "orpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def FsXORPSrr : I<0x57, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "xorps {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fxor FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, TB; -def FsXORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "xorpd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fxor FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; -} -def FsANDPSrm : I<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), - "andps {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fand FR32:$src1, - (X86loadpf32 addr:$src2)))]>, - Requires<[HasSSE1]>, TB; -def FsANDPDrm : I<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), - "andpd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fand FR64:$src1, - (X86loadpf64 addr:$src2)))]>, - Requires<[HasSSE2]>, TB, OpSize; -def FsORPSrm : I<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), - "orps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def FsORPDrm : I<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), - "orpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def FsXORPSrm : I<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), - "xorps {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fxor FR32:$src1, - (X86loadpf32 addr:$src2)))]>, - Requires<[HasSSE1]>, TB; -def FsXORPDrm : I<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), - "xorpd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fxor FR64:$src1, - (X86loadpf64 addr:$src2)))]>, - Requires<[HasSSE2]>, TB, OpSize; - -def FsANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "andnps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def FsANDNPSrm : I<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), - "andnps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def FsANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "andnpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def FsANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), - "andnpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -} - //===----------------------------------------------------------------------===// // Non-Instruction Patterns //===----------------------------------------------------------------------===// From evan.cheng at apple.com Tue Feb 21 13:27:04 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 21 Feb 2006 13:27:04 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrFPStack.td X86InstrInfo.td X86InstrSSE.td Message-ID: <200602211927.NAA16362@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrFPStack.td updated: 1.1 -> 1.2 X86InstrInfo.td updated: 1.243 -> 1.244 X86InstrSSE.td updated: 1.1 -> 1.2 --- Log message: Moving things to their proper places. --- Diffs of the changes: (+303 -303) X86InstrFPStack.td | 101 ----------------- X86InstrInfo.td | 202 ----------------------------------- X86InstrSSE.td | 303 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 303 insertions(+), 303 deletions(-) Index: llvm/lib/Target/X86/X86InstrFPStack.td diff -u llvm/lib/Target/X86/X86InstrFPStack.td:1.1 llvm/lib/Target/X86/X86InstrFPStack.td:1.2 --- llvm/lib/Target/X86/X86InstrFPStack.td:1.1 Tue Feb 21 13:13:53 2006 +++ llvm/lib/Target/X86/X86InstrFPStack.td Tue Feb 21 13:26:52 2006 @@ -379,104 +379,3 @@ (ops i16mem:$dst), "fnstcw $dst", []>; def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16] (ops i16mem:$dst), "fldcw $dst", []>; - - -//===----------------------------------------------------------------------===// -// Alias Instructions -//===----------------------------------------------------------------------===// - -// Alias instructions that map fld0 to pxor for sse. -// FIXME: remove when we can teach regalloc that xor reg, reg is ok. -def FsFLD0SS : I<0xEF, MRMInitReg, (ops FR32:$dst), - "pxor $dst, $dst", [(set FR32:$dst, fp32imm0)]>, - Requires<[HasSSE1]>, TB, OpSize; -def FsFLD0SD : I<0xEF, MRMInitReg, (ops FR64:$dst), - "pxor $dst, $dst", [(set FR64:$dst, fp64imm0)]>, - Requires<[HasSSE2]>, TB, OpSize; - -// Alias instructions to do FR32 / FR64 reg-to-reg copy using movaps / movapd. -// Upper bits are disregarded. -def FsMOVAPSrr : I<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), - "movaps {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, TB; -def FsMOVAPDrr : I<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), - "movapd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE2]>, TB, OpSize; - -// Alias instructions to load FR32 / FR64 from f128mem using movaps / movapd. -// Upper bits are disregarded. -def FsMOVAPSrm : I<0x28, MRMSrcMem, (ops FR32:$dst, f128mem:$src), - "movaps {$src, $dst|$dst, $src}", - [(set FR32:$dst, (X86loadpf32 addr:$src))]>, - Requires<[HasSSE1]>, TB; -def FsMOVAPDrm : I<0x28, MRMSrcMem, (ops FR64:$dst, f128mem:$src), - "movapd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (X86loadpf64 addr:$src))]>, - Requires<[HasSSE2]>, TB, OpSize; - -// Alias bitwise logical operations using SSE logical ops on packed FP values. -let isTwoAddress = 1 in { -let isCommutable = 1 in { -def FsANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "andps {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fand FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, TB; -def FsANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "andpd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fand FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; -def FsORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "orps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def FsORPDrr : I<0x56, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "orpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def FsXORPSrr : I<0x57, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "xorps {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fxor FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, TB; -def FsXORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "xorpd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fxor FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; -} -def FsANDPSrm : I<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), - "andps {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fand FR32:$src1, - (X86loadpf32 addr:$src2)))]>, - Requires<[HasSSE1]>, TB; -def FsANDPDrm : I<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), - "andpd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fand FR64:$src1, - (X86loadpf64 addr:$src2)))]>, - Requires<[HasSSE2]>, TB, OpSize; -def FsORPSrm : I<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), - "orps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def FsORPDrm : I<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), - "orpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def FsXORPSrm : I<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), - "xorps {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fxor FR32:$src1, - (X86loadpf32 addr:$src2)))]>, - Requires<[HasSSE1]>, TB; -def FsXORPDrm : I<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), - "xorpd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fxor FR64:$src1, - (X86loadpf64 addr:$src2)))]>, - Requires<[HasSSE2]>, TB, OpSize; - -def FsANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "andnps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def FsANDNPSrm : I<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), - "andnps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def FsANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "andnpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def FsANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), - "andnpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -} Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.243 llvm/lib/Target/X86/X86InstrInfo.td:1.244 --- llvm/lib/Target/X86/X86InstrInfo.td:1.243 Tue Feb 21 13:13:53 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Tue Feb 21 13:26:52 2006 @@ -2367,208 +2367,6 @@ [(set R32:$dst, (zextloadi32i16 addr:$src))]>, TB; //===----------------------------------------------------------------------===// -// XMM Floating point support (requires SSE / SSE2) -//===----------------------------------------------------------------------===// - -def MOVSSrr : I<0x10, MRMSrcReg, (ops FR32:$dst, FR32:$src), - "movss {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, XS; -def MOVSDrr : I<0x10, MRMSrcReg, (ops FR64:$dst, FR64:$src), - "movsd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE2]>, XD; - -def MOVSSrm : I<0x10, MRMSrcMem, (ops FR32:$dst, f32mem:$src), - "movss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (loadf32 addr:$src))]>, - Requires<[HasSSE1]>, XS; -def MOVSSmr : I<0x11, MRMDestMem, (ops f32mem:$dst, FR32:$src), - "movss {$src, $dst|$dst, $src}", - [(store FR32:$src, addr:$dst)]>, - Requires<[HasSSE1]>, XS; -def MOVSDrm : I<0x10, MRMSrcMem, (ops FR64:$dst, f64mem:$src), - "movsd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (loadf64 addr:$src))]>, - Requires<[HasSSE2]>, XD; -def MOVSDmr : I<0x11, MRMDestMem, (ops f64mem:$dst, FR64:$src), - "movsd {$src, $dst|$dst, $src}", - [(store FR64:$src, addr:$dst)]>, - Requires<[HasSSE2]>, XD; - -def CVTTSS2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR32:$src), - "cvttss2si {$src, $dst|$dst, $src}", - [(set R32:$dst, (fp_to_sint FR32:$src))]>, - Requires<[HasSSE1]>, XS; -def CVTTSS2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f32mem:$src), - "cvttss2si {$src, $dst|$dst, $src}", - [(set R32:$dst, (fp_to_sint (loadf32 addr:$src)))]>, - Requires<[HasSSE1]>, XS; -def CVTTSD2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR64:$src), - "cvttsd2si {$src, $dst|$dst, $src}", - [(set R32:$dst, (fp_to_sint FR64:$src))]>, - Requires<[HasSSE2]>, XD; -def CVTTSD2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f64mem:$src), - "cvttsd2si {$src, $dst|$dst, $src}", - [(set R32:$dst, (fp_to_sint (loadf64 addr:$src)))]>, - Requires<[HasSSE2]>, XD; -def CVTSS2SDrr: I<0x5A, MRMSrcReg, (ops FR64:$dst, FR32:$src), - "cvtss2sd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (fextend FR32:$src))]>, - Requires<[HasSSE2]>, XS; -def CVTSS2SDrm: I<0x5A, MRMSrcMem, (ops FR64:$dst, f32mem:$src), - "cvtss2sd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (fextend (loadf32 addr:$src)))]>, - Requires<[HasSSE2]>, XS; -def CVTSD2SSrr: I<0x5A, MRMSrcReg, (ops FR32:$dst, FR64:$src), - "cvtsd2ss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (fround FR64:$src))]>, - Requires<[HasSSE2]>, XD; -def CVTSD2SSrm: I<0x5A, MRMSrcMem, (ops FR32:$dst, f64mem:$src), - "cvtsd2ss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (fround (loadf64 addr:$src)))]>, - Requires<[HasSSE2]>, XD; -def CVTSI2SSrr: I<0x2A, MRMSrcReg, (ops FR32:$dst, R32:$src), - "cvtsi2ss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (sint_to_fp R32:$src))]>, - Requires<[HasSSE2]>, XS; -def CVTSI2SSrm: I<0x2A, MRMSrcMem, (ops FR32:$dst, i32mem:$src), - "cvtsi2ss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (sint_to_fp (loadi32 addr:$src)))]>, - Requires<[HasSSE2]>, XS; -def CVTSI2SDrr: I<0x2A, MRMSrcReg, (ops FR64:$dst, R32:$src), - "cvtsi2sd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (sint_to_fp R32:$src))]>, - Requires<[HasSSE2]>, XD; -def CVTSI2SDrm: I<0x2A, MRMSrcMem, (ops FR64:$dst, i32mem:$src), - "cvtsi2sd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (sint_to_fp (loadi32 addr:$src)))]>, - Requires<[HasSSE2]>, XD; - -def SQRTSSrr : I<0x51, MRMSrcReg, (ops FR32:$dst, FR32:$src), - "sqrtss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (fsqrt FR32:$src))]>, - Requires<[HasSSE1]>, XS; -def SQRTSSrm : I<0x51, MRMSrcMem, (ops FR32:$dst, f32mem:$src), - "sqrtss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (fsqrt (loadf32 addr:$src)))]>, - Requires<[HasSSE1]>, XS; -def SQRTSDrr : I<0x51, MRMSrcReg, (ops FR64:$dst, FR64:$src), - "sqrtsd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (fsqrt FR64:$src))]>, - Requires<[HasSSE2]>, XD; -def SQRTSDrm : I<0x51, MRMSrcMem, (ops FR64:$dst, f64mem:$src), - "sqrtsd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (fsqrt (loadf64 addr:$src)))]>, - Requires<[HasSSE2]>, XD; - -def UCOMISSrr: I<0x2E, MRMSrcReg, (ops FR32:$src1, FR32:$src2), - "ucomiss {$src2, $src1|$src1, $src2}", - [(X86cmp FR32:$src1, FR32:$src2)]>, - Requires<[HasSSE1]>, TB; -def UCOMISSrm: I<0x2E, MRMSrcMem, (ops FR32:$src1, f32mem:$src2), - "ucomiss {$src2, $src1|$src1, $src2}", - [(X86cmp FR32:$src1, (loadf32 addr:$src2))]>, - Requires<[HasSSE1]>, TB; -def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$src1, FR64:$src2), - "ucomisd {$src2, $src1|$src1, $src2}", - [(X86cmp FR64:$src1, FR64:$src2)]>, - Requires<[HasSSE2]>, TB, OpSize; -def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$src1, f64mem:$src2), - "ucomisd {$src2, $src1|$src1, $src2}", - [(X86cmp FR64:$src1, (loadf64 addr:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; - -let isTwoAddress = 1 in { -// SSE Scalar Arithmetic -let isCommutable = 1 in { -def ADDSSrr : I<0x58, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "addss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fadd FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, XS; -def ADDSDrr : I<0x58, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "addsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fadd FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, XD; -def MULSSrr : I<0x59, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "mulss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fmul FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, XS; -def MULSDrr : I<0x59, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "mulsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fmul FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, XD; -} - -def ADDSSrm : I<0x58, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), - "addss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fadd FR32:$src1, (loadf32 addr:$src2)))]>, - Requires<[HasSSE1]>, XS; -def ADDSDrm : I<0x58, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), - "addsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fadd FR64:$src1, (loadf64 addr:$src2)))]>, - Requires<[HasSSE2]>, XD; -def MULSSrm : I<0x59, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), - "mulss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fmul FR32:$src1, (loadf32 addr:$src2)))]>, - Requires<[HasSSE1]>, XS; -def MULSDrm : I<0x59, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), - "mulsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fmul FR64:$src1, (loadf64 addr:$src2)))]>, - Requires<[HasSSE2]>, XD; - -def DIVSSrr : I<0x5E, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "divss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fdiv FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, XS; -def DIVSSrm : I<0x5E, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), - "divss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fdiv FR32:$src1, (loadf32 addr:$src2)))]>, - Requires<[HasSSE1]>, XS; -def DIVSDrr : I<0x5E, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "divsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fdiv FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, XD; -def DIVSDrm : I<0x5E, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), - "divsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fdiv FR64:$src1, (loadf64 addr:$src2)))]>, - Requires<[HasSSE2]>, XD; - -def SUBSSrr : I<0x5C, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "subss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fsub FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, XS; -def SUBSSrm : I<0x5C, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), - "subss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fsub FR32:$src1, (loadf32 addr:$src2)))]>, - Requires<[HasSSE1]>, XS; -def SUBSDrr : I<0x5C, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "subsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fsub FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, XD; -def SUBSDrm : I<0x5C, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), - "subsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fsub FR64:$src1, (loadf64 addr:$src2)))]>, - Requires<[HasSSE2]>, XD; - -// SSE compare -def CMPSSrr : I<0xC2, MRMSrcReg, - (ops FR32:$dst, FR32:$src1, FR32:$src, SSECC:$cc), - "cmp${cc}ss {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, XS; -def CMPSSrm : I<0xC2, MRMSrcMem, - (ops FR32:$dst, FR32:$src1, f32mem:$src, SSECC:$cc), - "cmp${cc}ss {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, XS; -def CMPSDrr : I<0xC2, MRMSrcReg, - (ops FR64:$dst, FR64:$src1, FR64:$src, SSECC:$cc), - "cmp${cc}sd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, XD; -def CMPSDrm : I<0xC2, MRMSrcMem, - (ops FR64:$dst, FR64:$src1, f64mem:$src, SSECC:$cc), - "cmp${cc}sd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE2]>, XD; -} - -//===----------------------------------------------------------------------===// // Floating Point Stack Support //===----------------------------------------------------------------------===// Index: llvm/lib/Target/X86/X86InstrSSE.td diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.1 llvm/lib/Target/X86/X86InstrSSE.td:1.2 --- llvm/lib/Target/X86/X86InstrSSE.td:1.1 Tue Feb 21 13:13:53 2006 +++ llvm/lib/Target/X86/X86InstrSSE.td Tue Feb 21 13:26:52 2006 @@ -99,3 +99,306 @@ "andnpd {$src2, $dst|$dst, $src2}", []>, Requires<[HasSSE2]>, TB, OpSize; } + +//===----------------------------------------------------------------------===// +// XMM Floating point support (requires SSE / SSE2) +//===----------------------------------------------------------------------===// + +def MOVSSrr : I<0x10, MRMSrcReg, (ops FR32:$dst, FR32:$src), + "movss {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, XS; +def MOVSDrr : I<0x10, MRMSrcReg, (ops FR64:$dst, FR64:$src), + "movsd {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE2]>, XD; + +def MOVSSrm : I<0x10, MRMSrcMem, (ops FR32:$dst, f32mem:$src), + "movss {$src, $dst|$dst, $src}", + [(set FR32:$dst, (loadf32 addr:$src))]>, + Requires<[HasSSE1]>, XS; +def MOVSSmr : I<0x11, MRMDestMem, (ops f32mem:$dst, FR32:$src), + "movss {$src, $dst|$dst, $src}", + [(store FR32:$src, addr:$dst)]>, + Requires<[HasSSE1]>, XS; +def MOVSDrm : I<0x10, MRMSrcMem, (ops FR64:$dst, f64mem:$src), + "movsd {$src, $dst|$dst, $src}", + [(set FR64:$dst, (loadf64 addr:$src))]>, + Requires<[HasSSE2]>, XD; +def MOVSDmr : I<0x11, MRMDestMem, (ops f64mem:$dst, FR64:$src), + "movsd {$src, $dst|$dst, $src}", + [(store FR64:$src, addr:$dst)]>, + Requires<[HasSSE2]>, XD; + +def CVTTSS2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR32:$src), + "cvttss2si {$src, $dst|$dst, $src}", + [(set R32:$dst, (fp_to_sint FR32:$src))]>, + Requires<[HasSSE1]>, XS; +def CVTTSS2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f32mem:$src), + "cvttss2si {$src, $dst|$dst, $src}", + [(set R32:$dst, (fp_to_sint (loadf32 addr:$src)))]>, + Requires<[HasSSE1]>, XS; +def CVTTSD2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR64:$src), + "cvttsd2si {$src, $dst|$dst, $src}", + [(set R32:$dst, (fp_to_sint FR64:$src))]>, + Requires<[HasSSE2]>, XD; +def CVTTSD2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f64mem:$src), + "cvttsd2si {$src, $dst|$dst, $src}", + [(set R32:$dst, (fp_to_sint (loadf64 addr:$src)))]>, + Requires<[HasSSE2]>, XD; +def CVTSS2SDrr: I<0x5A, MRMSrcReg, (ops FR64:$dst, FR32:$src), + "cvtss2sd {$src, $dst|$dst, $src}", + [(set FR64:$dst, (fextend FR32:$src))]>, + Requires<[HasSSE2]>, XS; +def CVTSS2SDrm: I<0x5A, MRMSrcMem, (ops FR64:$dst, f32mem:$src), + "cvtss2sd {$src, $dst|$dst, $src}", + [(set FR64:$dst, (fextend (loadf32 addr:$src)))]>, + Requires<[HasSSE2]>, XS; +def CVTSD2SSrr: I<0x5A, MRMSrcReg, (ops FR32:$dst, FR64:$src), + "cvtsd2ss {$src, $dst|$dst, $src}", + [(set FR32:$dst, (fround FR64:$src))]>, + Requires<[HasSSE2]>, XD; +def CVTSD2SSrm: I<0x5A, MRMSrcMem, (ops FR32:$dst, f64mem:$src), + "cvtsd2ss {$src, $dst|$dst, $src}", + [(set FR32:$dst, (fround (loadf64 addr:$src)))]>, + Requires<[HasSSE2]>, XD; +def CVTSI2SSrr: I<0x2A, MRMSrcReg, (ops FR32:$dst, R32:$src), + "cvtsi2ss {$src, $dst|$dst, $src}", + [(set FR32:$dst, (sint_to_fp R32:$src))]>, + Requires<[HasSSE2]>, XS; +def CVTSI2SSrm: I<0x2A, MRMSrcMem, (ops FR32:$dst, i32mem:$src), + "cvtsi2ss {$src, $dst|$dst, $src}", + [(set FR32:$dst, (sint_to_fp (loadi32 addr:$src)))]>, + Requires<[HasSSE2]>, XS; +def CVTSI2SDrr: I<0x2A, MRMSrcReg, (ops FR64:$dst, R32:$src), + "cvtsi2sd {$src, $dst|$dst, $src}", + [(set FR64:$dst, (sint_to_fp R32:$src))]>, + Requires<[HasSSE2]>, XD; +def CVTSI2SDrm: I<0x2A, MRMSrcMem, (ops FR64:$dst, i32mem:$src), + "cvtsi2sd {$src, $dst|$dst, $src}", + [(set FR64:$dst, (sint_to_fp (loadi32 addr:$src)))]>, + Requires<[HasSSE2]>, XD; + +def SQRTSSrr : I<0x51, MRMSrcReg, (ops FR32:$dst, FR32:$src), + "sqrtss {$src, $dst|$dst, $src}", + [(set FR32:$dst, (fsqrt FR32:$src))]>, + Requires<[HasSSE1]>, XS; +def SQRTSSrm : I<0x51, MRMSrcMem, (ops FR32:$dst, f32mem:$src), + "sqrtss {$src, $dst|$dst, $src}", + [(set FR32:$dst, (fsqrt (loadf32 addr:$src)))]>, + Requires<[HasSSE1]>, XS; +def SQRTSDrr : I<0x51, MRMSrcReg, (ops FR64:$dst, FR64:$src), + "sqrtsd {$src, $dst|$dst, $src}", + [(set FR64:$dst, (fsqrt FR64:$src))]>, + Requires<[HasSSE2]>, XD; +def SQRTSDrm : I<0x51, MRMSrcMem, (ops FR64:$dst, f64mem:$src), + "sqrtsd {$src, $dst|$dst, $src}", + [(set FR64:$dst, (fsqrt (loadf64 addr:$src)))]>, + Requires<[HasSSE2]>, XD; + +def UCOMISSrr: I<0x2E, MRMSrcReg, (ops FR32:$src1, FR32:$src2), + "ucomiss {$src2, $src1|$src1, $src2}", + [(X86cmp FR32:$src1, FR32:$src2)]>, + Requires<[HasSSE1]>, TB; +def UCOMISSrm: I<0x2E, MRMSrcMem, (ops FR32:$src1, f32mem:$src2), + "ucomiss {$src2, $src1|$src1, $src2}", + [(X86cmp FR32:$src1, (loadf32 addr:$src2))]>, + Requires<[HasSSE1]>, TB; +def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$src1, FR64:$src2), + "ucomisd {$src2, $src1|$src1, $src2}", + [(X86cmp FR64:$src1, FR64:$src2)]>, + Requires<[HasSSE2]>, TB, OpSize; +def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$src1, f64mem:$src2), + "ucomisd {$src2, $src1|$src1, $src2}", + [(X86cmp FR64:$src1, (loadf64 addr:$src2))]>, + Requires<[HasSSE2]>, TB, OpSize; + +let isTwoAddress = 1 in { +// SSE Scalar Arithmetic +let isCommutable = 1 in { +def ADDSSrr : I<0x58, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "addss {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (fadd FR32:$src1, FR32:$src2))]>, + Requires<[HasSSE1]>, XS; +def ADDSDrr : I<0x58, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "addsd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (fadd FR64:$src1, FR64:$src2))]>, + Requires<[HasSSE2]>, XD; +def MULSSrr : I<0x59, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "mulss {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (fmul FR32:$src1, FR32:$src2))]>, + Requires<[HasSSE1]>, XS; +def MULSDrr : I<0x59, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "mulsd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (fmul FR64:$src1, FR64:$src2))]>, + Requires<[HasSSE2]>, XD; +} + +def ADDSSrm : I<0x58, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), + "addss {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (fadd FR32:$src1, (loadf32 addr:$src2)))]>, + Requires<[HasSSE1]>, XS; +def ADDSDrm : I<0x58, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), + "addsd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (fadd FR64:$src1, (loadf64 addr:$src2)))]>, + Requires<[HasSSE2]>, XD; +def MULSSrm : I<0x59, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), + "mulss {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (fmul FR32:$src1, (loadf32 addr:$src2)))]>, + Requires<[HasSSE1]>, XS; +def MULSDrm : I<0x59, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), + "mulsd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (fmul FR64:$src1, (loadf64 addr:$src2)))]>, + Requires<[HasSSE2]>, XD; + +def DIVSSrr : I<0x5E, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "divss {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (fdiv FR32:$src1, FR32:$src2))]>, + Requires<[HasSSE1]>, XS; +def DIVSSrm : I<0x5E, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), + "divss {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (fdiv FR32:$src1, (loadf32 addr:$src2)))]>, + Requires<[HasSSE1]>, XS; +def DIVSDrr : I<0x5E, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "divsd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (fdiv FR64:$src1, FR64:$src2))]>, + Requires<[HasSSE2]>, XD; +def DIVSDrm : I<0x5E, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), + "divsd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (fdiv FR64:$src1, (loadf64 addr:$src2)))]>, + Requires<[HasSSE2]>, XD; + +def SUBSSrr : I<0x5C, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "subss {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (fsub FR32:$src1, FR32:$src2))]>, + Requires<[HasSSE1]>, XS; +def SUBSSrm : I<0x5C, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), + "subss {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (fsub FR32:$src1, (loadf32 addr:$src2)))]>, + Requires<[HasSSE1]>, XS; +def SUBSDrr : I<0x5C, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "subsd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (fsub FR64:$src1, FR64:$src2))]>, + Requires<[HasSSE2]>, XD; +def SUBSDrm : I<0x5C, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), + "subsd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (fsub FR64:$src1, (loadf64 addr:$src2)))]>, + Requires<[HasSSE2]>, XD; + +// SSE compare +def CMPSSrr : I<0xC2, MRMSrcReg, + (ops FR32:$dst, FR32:$src1, FR32:$src, SSECC:$cc), + "cmp${cc}ss {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, XS; +def CMPSSrm : I<0xC2, MRMSrcMem, + (ops FR32:$dst, FR32:$src1, f32mem:$src, SSECC:$cc), + "cmp${cc}ss {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, XS; +def CMPSDrr : I<0xC2, MRMSrcReg, + (ops FR64:$dst, FR64:$src1, FR64:$src, SSECC:$cc), + "cmp${cc}sd {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, XD; +def CMPSDrm : I<0xC2, MRMSrcMem, + (ops FR64:$dst, FR64:$src1, f64mem:$src, SSECC:$cc), + "cmp${cc}sd {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE2]>, XD; +} + + +//===----------------------------------------------------------------------===// +// Alias Instructions +//===----------------------------------------------------------------------===// + +// Alias instructions that map fld0 to pxor for sse. +// FIXME: remove when we can teach regalloc that xor reg, reg is ok. +def FsFLD0SS : I<0xEF, MRMInitReg, (ops FR32:$dst), + "pxor $dst, $dst", [(set FR32:$dst, fp32imm0)]>, + Requires<[HasSSE1]>, TB, OpSize; +def FsFLD0SD : I<0xEF, MRMInitReg, (ops FR64:$dst), + "pxor $dst, $dst", [(set FR64:$dst, fp64imm0)]>, + Requires<[HasSSE2]>, TB, OpSize; + +// Alias instructions to do FR32 / FR64 reg-to-reg copy using movaps / movapd. +// Upper bits are disregarded. +def FsMOVAPSrr : I<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), + "movaps {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, TB; +def FsMOVAPDrr : I<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), + "movapd {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE2]>, TB, OpSize; + +// Alias instructions to load FR32 / FR64 from f128mem using movaps / movapd. +// Upper bits are disregarded. +def FsMOVAPSrm : I<0x28, MRMSrcMem, (ops FR32:$dst, f128mem:$src), + "movaps {$src, $dst|$dst, $src}", + [(set FR32:$dst, (X86loadpf32 addr:$src))]>, + Requires<[HasSSE1]>, TB; +def FsMOVAPDrm : I<0x28, MRMSrcMem, (ops FR64:$dst, f128mem:$src), + "movapd {$src, $dst|$dst, $src}", + [(set FR64:$dst, (X86loadpf64 addr:$src))]>, + Requires<[HasSSE2]>, TB, OpSize; + +// Alias bitwise logical operations using SSE logical ops on packed FP values. +let isTwoAddress = 1 in { +let isCommutable = 1 in { +def FsANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "andps {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (X86fand FR32:$src1, FR32:$src2))]>, + Requires<[HasSSE1]>, TB; +def FsANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "andpd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (X86fand FR64:$src1, FR64:$src2))]>, + Requires<[HasSSE2]>, TB, OpSize; +def FsORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "orps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def FsORPDrr : I<0x56, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +def FsXORPSrr : I<0x57, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "xorps {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (X86fxor FR32:$src1, FR32:$src2))]>, + Requires<[HasSSE1]>, TB; +def FsXORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "xorpd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (X86fxor FR64:$src1, FR64:$src2))]>, + Requires<[HasSSE2]>, TB, OpSize; +} +def FsANDPSrm : I<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + "andps {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (X86fand FR32:$src1, + (X86loadpf32 addr:$src2)))]>, + Requires<[HasSSE1]>, TB; +def FsANDPDrm : I<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + "andpd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (X86fand FR64:$src1, + (X86loadpf64 addr:$src2)))]>, + Requires<[HasSSE2]>, TB, OpSize; +def FsORPSrm : I<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + "orps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def FsORPDrm : I<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +def FsXORPSrm : I<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + "xorps {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (X86fxor FR32:$src1, + (X86loadpf32 addr:$src2)))]>, + Requires<[HasSSE1]>, TB; +def FsXORPDrm : I<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + "xorpd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (X86fxor FR64:$src1, + (X86loadpf64 addr:$src2)))]>, + Requires<[HasSSE2]>, TB, OpSize; + +def FsANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def FsANDNPSrm : I<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def FsANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +def FsANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +} From evan.cheng at apple.com Tue Feb 21 13:30:42 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 21 Feb 2006 13:30:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td X86InstrSSE.td Message-ID: <200602211930.NAA16397@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.244 -> 1.245 X86InstrSSE.td updated: 1.2 -> 1.3 --- Log message: A big more cleaning up. --- Diffs of the changes: (+18 -23) X86InstrInfo.td | 37 ++++++++++++++++++------------------- X86InstrSSE.td | 4 ---- 2 files changed, 18 insertions(+), 23 deletions(-) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.244 llvm/lib/Target/X86/X86InstrInfo.td:1.245 --- llvm/lib/Target/X86/X86InstrInfo.td:1.244 Tue Feb 21 13:26:52 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Tue Feb 21 13:30:30 2006 @@ -2367,31 +2367,12 @@ [(set R32:$dst, (zextloadi32i16 addr:$src))]>, TB; //===----------------------------------------------------------------------===// -// Floating Point Stack Support -//===----------------------------------------------------------------------===// - -include "X86InstrFPStack.td" - -//===----------------------------------------------------------------------===// -// MMX and XMM Packed Integer support (requires MMX, SSE, and SSE2) -//===----------------------------------------------------------------------===// - -include "X86InstrMMX.td" - -//===----------------------------------------------------------------------===// -// XMM Packed Floating point support (requires SSE / SSE2) -//===----------------------------------------------------------------------===// - -include "X86InstrSSE.td" - -//===----------------------------------------------------------------------===// // Miscellaneous Instructions //===----------------------------------------------------------------------===// def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", [(X86rdtsc)]>, TB, Imp<[],[EAX,EDX]>; - //===----------------------------------------------------------------------===// // Alias Instructions //===----------------------------------------------------------------------===// @@ -2409,6 +2390,24 @@ [(set R32:$dst, 0)]>; //===----------------------------------------------------------------------===// +// Floating Point Stack Support +//===----------------------------------------------------------------------===// + +include "X86InstrFPStack.td" + +//===----------------------------------------------------------------------===// +// MMX and XMM Packed Integer support (requires MMX, SSE, and SSE2) +//===----------------------------------------------------------------------===// + +include "X86InstrMMX.td" + +//===----------------------------------------------------------------------===// +// XMM Floating point support (requires SSE / SSE2) +//===----------------------------------------------------------------------===// + +include "X86InstrSSE.td" + +//===----------------------------------------------------------------------===// // Non-Instruction Patterns //===----------------------------------------------------------------------===// Index: llvm/lib/Target/X86/X86InstrSSE.td diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.2 llvm/lib/Target/X86/X86InstrSSE.td:1.3 --- llvm/lib/Target/X86/X86InstrSSE.td:1.2 Tue Feb 21 13:26:52 2006 +++ llvm/lib/Target/X86/X86InstrSSE.td Tue Feb 21 13:30:30 2006 @@ -100,10 +100,6 @@ Requires<[HasSSE2]>, TB, OpSize; } -//===----------------------------------------------------------------------===// -// XMM Floating point support (requires SSE / SSE2) -//===----------------------------------------------------------------------===// - def MOVSSrr : I<0x10, MRMSrcReg, (ops FR32:$dst, FR32:$src), "movss {$src, $dst|$dst, $src}", []>, Requires<[HasSSE1]>, XS; From evan.cheng at apple.com Tue Feb 21 14:00:31 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 21 Feb 2006 14:00:31 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrFPStack.td X86InstrInfo.td X86InstrMMX.td X86InstrSSE.td Message-ID: <200602212000.OAA16563@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrFPStack.td updated: 1.2 -> 1.3 X86InstrInfo.td updated: 1.245 -> 1.246 X86InstrMMX.td updated: 1.1 -> 1.2 X86InstrSSE.td updated: 1.3 -> 1.4 --- Log message: One more round of reorg so sabre doesn't freak out. :-) --- Diffs of the changes: (+240 -222) X86InstrFPStack.td | 39 ++++++ X86InstrInfo.td | 94 +++------------- X86InstrMMX.td | 22 --- X86InstrSSE.td | 307 +++++++++++++++++++++++++++++++---------------------- 4 files changed, 240 insertions(+), 222 deletions(-) Index: llvm/lib/Target/X86/X86InstrFPStack.td diff -u llvm/lib/Target/X86/X86InstrFPStack.td:1.2 llvm/lib/Target/X86/X86InstrFPStack.td:1.3 --- llvm/lib/Target/X86/X86InstrFPStack.td:1.2 Tue Feb 21 13:26:52 2006 +++ llvm/lib/Target/X86/X86InstrFPStack.td Tue Feb 21 14:00:20 2006 @@ -13,6 +13,26 @@ // //===----------------------------------------------------------------------===// +// Some 'special' instructions +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", []>; + // All FP Stack operations are represented with two instructions here. The // first instruction, generated by the instruction selector, uses "RFP" // registers: a traditional register file to reference floating point values. @@ -379,3 +399,22 @@ (ops i16mem:$dst), "fnstcw $dst", []>; def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16] (ops i16mem:$dst), "fldcw $dst", []>; + +//===----------------------------------------------------------------------===// +// Non-Instruction Patterns +//===----------------------------------------------------------------------===// + +// Required for RET of f32 / f64 values. +def : Pat<(X86fld addr:$src, f32), (FpLD32m addr:$src)>; +def : Pat<(X86fld addr:$src, f64), (FpLD64m addr:$src)>; + +// Required for CALL which return f32 / f64 values. +def : Pat<(X86fst RFP:$src, addr:$op, f32), (FpST32m addr:$op, RFP:$src)>; +def : Pat<(X86fst RFP:$src, addr:$op, f64), (FpST64m addr:$op, RFP:$src)>; + +// Floating point constant -0.0 and -1.0 +def : Pat<(f64 fp64immneg0), (FpCHS (FpLD0))>, Requires<[FPStack]>; +def : Pat<(f64 fp64immneg1), (FpCHS (FpLD1))>, Requires<[FPStack]>; + +// Used to conv. i64 to f64 since there isn't a SSE version. +def : Pat<(X86fildflag addr:$src, i64), (FpILD64m addr:$src)>; Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.245 llvm/lib/Target/X86/X86InstrInfo.td:1.246 --- llvm/lib/Target/X86/X86InstrInfo.td:1.245 Tue Feb 21 13:30:30 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Tue Feb 21 14:00:20 2006 @@ -403,47 +403,6 @@ def IMPLICIT_DEF_R32 : I<0, Pseudo, (ops R32:$dst), "#IMPLICIT_DEF $dst", [(set R32:$dst, (undef))]>; -def IMPLICIT_DEF_FR32 : I<0, Pseudo, (ops FR32:$dst), - "#IMPLICIT_DEF $dst", - [(set FR32:$dst, (undef))]>, Requires<[HasSSE2]>; -def IMPLICIT_DEF_FR64 : I<0, Pseudo, (ops FR64:$dst), - "#IMPLICIT_DEF $dst", - [(set FR64:$dst, (undef))]>, Requires<[HasSSE2]>; - - -// CMOV* - Used to implement the SSE SELECT DAG operation. Expanded by the -// scheduler into a branch sequence. -let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. - def CMOV_FR32 : I<0, Pseudo, - (ops FR32:$dst, FR32:$t, FR32:$f, i8imm:$cond), - "#CMOV_FR32 PSEUDO!", - [(set FR32:$dst, (X86cmov FR32:$t, FR32:$f, imm:$cond))]>; - def CMOV_FR64 : I<0, Pseudo, - (ops FR64:$dst, FR64:$t, FR64:$f, i8imm:$cond), - "#CMOV_FR64 PSEUDO!", - [(set FR64:$dst, (X86cmov FR64:$t, FR64:$f, imm:$cond))]>; -} - -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", []>; - // Nop def NOOP : I<0x90, RawFrm, (ops), "nop", []>; @@ -1690,7 +1649,6 @@ // Double shift instructions (generalizations of rotate) - def SHLD32rrCL : I<0xA5, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2), "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}", [(set R32:$dst, (X86shld R32:$src1, R32:$src2, CL))]>, @@ -2390,24 +2348,6 @@ [(set R32:$dst, 0)]>; //===----------------------------------------------------------------------===// -// Floating Point Stack Support -//===----------------------------------------------------------------------===// - -include "X86InstrFPStack.td" - -//===----------------------------------------------------------------------===// -// MMX and XMM Packed Integer support (requires MMX, SSE, and SSE2) -//===----------------------------------------------------------------------===// - -include "X86InstrMMX.td" - -//===----------------------------------------------------------------------===// -// XMM Floating point support (requires SSE / SSE2) -//===----------------------------------------------------------------------===// - -include "X86InstrSSE.td" - -//===----------------------------------------------------------------------===// // Non-Instruction Patterns //===----------------------------------------------------------------------===// @@ -2460,21 +2400,6 @@ def : Pat<(i32 (anyext R8 :$src)), (MOVZX32rr8 R8 :$src)>; def : Pat<(i32 (anyext R16:$src)), (MOVZX32rr16 R16:$src)>; -// Required for RET of f32 / f64 values. -def : Pat<(X86fld addr:$src, f32), (FpLD32m addr:$src)>; -def : Pat<(X86fld addr:$src, f64), (FpLD64m addr:$src)>; - -// Required for CALL which return f32 / f64 values. -def : Pat<(X86fst RFP:$src, addr:$op, f32), (FpST32m addr:$op, RFP:$src)>; -def : Pat<(X86fst RFP:$src, addr:$op, f64), (FpST64m addr:$op, RFP:$src)>; - -// Floating point constant -0.0 and -1.0 -def : Pat<(f64 fp64immneg0), (FpCHS (FpLD0))>, Requires<[FPStack]>; -def : Pat<(f64 fp64immneg1), (FpCHS (FpLD1))>, Requires<[FPStack]>; - -// Used to conv. i64 to f64 since there isn't a SSE version. -def : Pat<(X86fildflag addr:$src, i64), (FpILD64m addr:$src)>; - //===----------------------------------------------------------------------===// // Some peepholes //===----------------------------------------------------------------------===// @@ -2519,3 +2444,22 @@ def : Pat<(store (or (shl (loadi16 addr:$dst), CL:$amt), (srl R16:$src2, (sub 16, CL:$amt))), addr:$dst), (SHLD16mrCL addr:$dst, R16:$src2)>; + + +//===----------------------------------------------------------------------===// +// Floating Point Stack Support +//===----------------------------------------------------------------------===// + +include "X86InstrFPStack.td" + +//===----------------------------------------------------------------------===// +// MMX and XMM Packed Integer support (requires MMX, SSE, and SSE2) +//===----------------------------------------------------------------------===// + +include "X86InstrMMX.td" + +//===----------------------------------------------------------------------===// +// XMM Floating point support (requires SSE / SSE2) +//===----------------------------------------------------------------------===// + +include "X86InstrSSE.td" Index: llvm/lib/Target/X86/X86InstrMMX.td diff -u llvm/lib/Target/X86/X86InstrMMX.td:1.1 llvm/lib/Target/X86/X86InstrMMX.td:1.2 --- llvm/lib/Target/X86/X86InstrMMX.td:1.1 Tue Feb 21 13:13:53 2006 +++ llvm/lib/Target/X86/X86InstrMMX.td Tue Feb 21 14:00:20 2006 @@ -24,17 +24,6 @@ "movd {$src, $dst|$dst, $src}", []>, TB, Requires<[HasMMX]>; -def MOVD128rr : I<0x6E, MRMSrcReg, (ops VR128:$dst, R32:$src), - "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, - Requires<[HasSSE2]>; -def MOVD128rm : I<0x6E, MRMSrcMem, (ops VR128:$dst, i32mem:$src), - "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, - Requires<[HasSSE2]>; -def MOVD128mr : I<0x7E, MRMDestMem, (ops i32mem:$dst, VR128:$src), - "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, - Requires<[HasSSE2]>; - - def MOVQ64rr : I<0x6F, MRMSrcReg, (ops VR64:$dst, VR64:$src), "movq {$src, $dst|$dst, $src}", []>, TB, Requires<[HasMMX]>; @@ -44,14 +33,3 @@ def MOVQ64mr : I<0x7F, MRMDestMem, (ops i64mem:$dst, VR64:$src), "movq {$src, $dst|$dst, $src}", []>, TB, Requires<[HasMMX]>; - -def MOVQ128rr : I<0x7E, MRMSrcReg, (ops VR128:$dst, VR64:$src), - "movq {$src, $dst|$dst, $src}", []>, XS, - Requires<[HasSSE2]>; -def MOVQ128rm : I<0x7E, MRMSrcMem, (ops VR128:$dst, i64mem:$src), - "movq {$src, $dst|$dst, $src}", []>, XS, - Requires<[HasSSE2]>; -def MOVQ128mr : I<0xD6, MRMSrcMem, (ops i64mem:$dst, VR128:$src), - "movq {$src, $dst|$dst, $src}", []>, TB, OpSize, - Requires<[HasSSE2]>; - Index: llvm/lib/Target/X86/X86InstrSSE.td diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.3 llvm/lib/Target/X86/X86InstrSSE.td:1.4 --- llvm/lib/Target/X86/X86InstrSSE.td:1.3 Tue Feb 21 13:30:30 2006 +++ llvm/lib/Target/X86/X86InstrSSE.td Tue Feb 21 14:00:20 2006 @@ -13,93 +13,32 @@ // //===----------------------------------------------------------------------===// -def MOVAPSrr : I<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), - "movaps {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, TB; -def MOVAPDrr : I<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), - "movapd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE2]>, TB, OpSize; - -def MOVAPSrm : I<0x28, MRMSrcMem, (ops V4F32:$dst, f128mem:$src), - "movaps {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, TB; -def MOVAPSmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V4F32:$src), - "movaps {$src, $dst|$dst, $src}",[]>, - Requires<[HasSSE1]>, TB; -def MOVAPDrm : I<0x28, MRMSrcMem, (ops V2F64:$dst, f128mem:$src), - "movapd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, TB, OpSize; -def MOVAPDmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V2F64:$src), - "movapd {$src, $dst|$dst, $src}",[]>, - Requires<[HasSSE2]>, TB, OpSize; - -// Logical -let isTwoAddress = 1 in { -let isCommutable = 1 in { -def ANDPSrr : I<0x54, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), - "andps {$src2, $dst|$dst, $src2}", - [(set V4F32:$dst, (X86fand V4F32:$src1, V4F32:$src2))]>, - Requires<[HasSSE1]>, TB; -def ANDPDrr : I<0x54, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), - "andpd {$src2, $dst|$dst, $src2}", - [(set V2F64:$dst, (X86fand V2F64:$src1, V2F64:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; -def ORPSrr : I<0x56, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), - "orps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ORPDrr : I<0x56, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), - "orpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def XORPSrr : I<0x57, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), - "xorps {$src2, $dst|$dst, $src2}", - [(set V4F32:$dst, (X86fxor V4F32:$src1, V4F32:$src2))]>, - Requires<[HasSSE1]>, TB; -def XORPDrr : I<0x57, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), - "xorpd {$src2, $dst|$dst, $src2}", - [(set V2F64:$dst, (X86fxor V2F64:$src1, V2F64:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; -} -def ANDPSrm : I<0x54, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), - "andps {$src2, $dst|$dst, $src2}", - [(set V4F32:$dst, (X86fand V4F32:$src1, - (X86loadpv4f32 addr:$src2)))]>, - Requires<[HasSSE1]>, TB; -def ANDPDrm : I<0x54, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), - "andpd {$src2, $dst|$dst, $src2}", - [(set V2F64:$dst, (X86fand V2F64:$src1, - (X86loadpv2f64 addr:$src2)))]>, - Requires<[HasSSE2]>, TB, OpSize; -def ORPSrm : I<0x56, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), - "orps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ORPDrm : I<0x56, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), - "orpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def XORPSrm : I<0x57, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), - "xorps {$src2, $dst|$dst, $src2}", - [(set V4F32:$dst, (X86fxor V4F32:$src1, - (X86loadpv4f32 addr:$src2)))]>, - Requires<[HasSSE1]>, TB; -def XORPDrm : I<0x57, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), - "xorpd {$src2, $dst|$dst, $src2}", - [(set V2F64:$dst, (X86fxor V2F64:$src1, - (X86loadpv2f64 addr:$src2)))]>, - Requires<[HasSSE2]>, TB, OpSize; +//===----------------------------------------------------------------------===// +// SSE scalar FP Instructions +//===----------------------------------------------------------------------===// -def ANDNPSrr : I<0x55, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), - "andnps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ANDNPSrm : I<0x55, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), - "andnps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ANDNPDrr : I<0x55, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), - "andnpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def ANDNPDrm : I<0x55, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), - "andnpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; +// Some 'special' instructions +def IMPLICIT_DEF_FR32 : I<0, Pseudo, (ops FR32:$dst), + "#IMPLICIT_DEF $dst", + [(set FR32:$dst, (undef))]>, Requires<[HasSSE2]>; +def IMPLICIT_DEF_FR64 : I<0, Pseudo, (ops FR64:$dst), + "#IMPLICIT_DEF $dst", + [(set FR64:$dst, (undef))]>, Requires<[HasSSE2]>; + +// CMOV* - Used to implement the SSE SELECT DAG operation. Expanded by the +// scheduler into a branch sequence. +let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. + def CMOV_FR32 : I<0, Pseudo, + (ops FR32:$dst, FR32:$t, FR32:$f, i8imm:$cond), + "#CMOV_FR32 PSEUDO!", + [(set FR32:$dst, (X86cmov FR32:$t, FR32:$f, imm:$cond))]>; + def CMOV_FR64 : I<0, Pseudo, + (ops FR64:$dst, FR64:$t, FR64:$f, i8imm:$cond), + "#CMOV_FR64 PSEUDO!", + [(set FR64:$dst, (X86cmov FR64:$t, FR64:$f, imm:$cond))]>; } +// Move Instructions def MOVSSrr : I<0x10, MRMSrcReg, (ops FR32:$dst, FR32:$src), "movss {$src, $dst|$dst, $src}", []>, Requires<[HasSSE1]>, XS; @@ -124,6 +63,7 @@ [(store FR64:$src, addr:$dst)]>, Requires<[HasSSE2]>, XD; +// Conversion instructions def CVTTSS2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR32:$src), "cvttss2si {$src, $dst|$dst, $src}", [(set R32:$dst, (fp_to_sint FR32:$src))]>, @@ -173,42 +113,8 @@ [(set FR64:$dst, (sint_to_fp (loadi32 addr:$src)))]>, Requires<[HasSSE2]>, XD; -def SQRTSSrr : I<0x51, MRMSrcReg, (ops FR32:$dst, FR32:$src), - "sqrtss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (fsqrt FR32:$src))]>, - Requires<[HasSSE1]>, XS; -def SQRTSSrm : I<0x51, MRMSrcMem, (ops FR32:$dst, f32mem:$src), - "sqrtss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (fsqrt (loadf32 addr:$src)))]>, - Requires<[HasSSE1]>, XS; -def SQRTSDrr : I<0x51, MRMSrcReg, (ops FR64:$dst, FR64:$src), - "sqrtsd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (fsqrt FR64:$src))]>, - Requires<[HasSSE2]>, XD; -def SQRTSDrm : I<0x51, MRMSrcMem, (ops FR64:$dst, f64mem:$src), - "sqrtsd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (fsqrt (loadf64 addr:$src)))]>, - Requires<[HasSSE2]>, XD; - -def UCOMISSrr: I<0x2E, MRMSrcReg, (ops FR32:$src1, FR32:$src2), - "ucomiss {$src2, $src1|$src1, $src2}", - [(X86cmp FR32:$src1, FR32:$src2)]>, - Requires<[HasSSE1]>, TB; -def UCOMISSrm: I<0x2E, MRMSrcMem, (ops FR32:$src1, f32mem:$src2), - "ucomiss {$src2, $src1|$src1, $src2}", - [(X86cmp FR32:$src1, (loadf32 addr:$src2))]>, - Requires<[HasSSE1]>, TB; -def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$src1, FR64:$src2), - "ucomisd {$src2, $src1|$src1, $src2}", - [(X86cmp FR64:$src1, FR64:$src2)]>, - Requires<[HasSSE2]>, TB, OpSize; -def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$src1, f64mem:$src2), - "ucomisd {$src2, $src1|$src1, $src2}", - [(X86cmp FR64:$src1, (loadf64 addr:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; - +// Arithmetic instructions let isTwoAddress = 1 in { -// SSE Scalar Arithmetic let isCommutable = 1 in { def ADDSSrr : I<0x58, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), "addss {$src2, $dst|$dst, $src2}", @@ -278,8 +184,27 @@ "subsd {$src2, $dst|$dst, $src2}", [(set FR64:$dst, (fsub FR64:$src1, (loadf64 addr:$src2)))]>, Requires<[HasSSE2]>, XD; +} -// SSE compare +def SQRTSSrr : I<0x51, MRMSrcReg, (ops FR32:$dst, FR32:$src), + "sqrtss {$src, $dst|$dst, $src}", + [(set FR32:$dst, (fsqrt FR32:$src))]>, + Requires<[HasSSE1]>, XS; +def SQRTSSrm : I<0x51, MRMSrcMem, (ops FR32:$dst, f32mem:$src), + "sqrtss {$src, $dst|$dst, $src}", + [(set FR32:$dst, (fsqrt (loadf32 addr:$src)))]>, + Requires<[HasSSE1]>, XS; +def SQRTSDrr : I<0x51, MRMSrcReg, (ops FR64:$dst, FR64:$src), + "sqrtsd {$src, $dst|$dst, $src}", + [(set FR64:$dst, (fsqrt FR64:$src))]>, + Requires<[HasSSE2]>, XD; +def SQRTSDrm : I<0x51, MRMSrcMem, (ops FR64:$dst, f64mem:$src), + "sqrtsd {$src, $dst|$dst, $src}", + [(set FR64:$dst, (fsqrt (loadf64 addr:$src)))]>, + Requires<[HasSSE2]>, XD; + +// Comparison instructions +let isTwoAddress = 1 in { def CMPSSrr : I<0xC2, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src, SSECC:$cc), "cmp${cc}ss {$src, $dst|$dst, $src}", []>, @@ -298,10 +223,25 @@ Requires<[HasSSE2]>, XD; } +def UCOMISSrr: I<0x2E, MRMSrcReg, (ops FR32:$src1, FR32:$src2), + "ucomiss {$src2, $src1|$src1, $src2}", + [(X86cmp FR32:$src1, FR32:$src2)]>, + Requires<[HasSSE1]>, TB; +def UCOMISSrm: I<0x2E, MRMSrcMem, (ops FR32:$src1, f32mem:$src2), + "ucomiss {$src2, $src1|$src1, $src2}", + [(X86cmp FR32:$src1, (loadf32 addr:$src2))]>, + Requires<[HasSSE1]>, TB; +def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$src1, FR64:$src2), + "ucomisd {$src2, $src1|$src1, $src2}", + [(X86cmp FR64:$src1, FR64:$src2)]>, + Requires<[HasSSE2]>, TB, OpSize; +def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$src1, f64mem:$src2), + "ucomisd {$src2, $src1|$src1, $src2}", + [(X86cmp FR64:$src1, (loadf64 addr:$src2))]>, + Requires<[HasSSE2]>, TB, OpSize; -//===----------------------------------------------------------------------===// -// Alias Instructions -//===----------------------------------------------------------------------===// +// Aliases of packed instructions for scalar use. These all have names that +// start with 'Fs'. // Alias instructions that map fld0 to pxor for sse. // FIXME: remove when we can teach regalloc that xor reg, reg is ok. @@ -314,10 +254,10 @@ // Alias instructions to do FR32 / FR64 reg-to-reg copy using movaps / movapd. // Upper bits are disregarded. -def FsMOVAPSrr : I<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), +def FsMOVAPSrr : I<0x28, MRMSrcReg, (ops FR32:$dst, FR32:$src), "movaps {$src, $dst|$dst, $src}", []>, Requires<[HasSSE1]>, TB; -def FsMOVAPDrr : I<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), +def FsMOVAPDrr : I<0x28, MRMSrcReg, (ops FR64:$dst, FR64:$src), "movapd {$src, $dst|$dst, $src}", []>, Requires<[HasSSE2]>, TB, OpSize; @@ -398,3 +338,120 @@ "andnpd {$src2, $dst|$dst, $src2}", []>, Requires<[HasSSE2]>, TB, OpSize; } + +//===----------------------------------------------------------------------===// +// SSE packed FP Instructions +//===----------------------------------------------------------------------===// + +// Move Instructions +def MOVAPSrr : I<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), + "movaps {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, TB; +def MOVAPDrr : I<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), + "movapd {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE2]>, TB, OpSize; + +def MOVAPSrm : I<0x28, MRMSrcMem, (ops V4F32:$dst, f128mem:$src), + "movaps {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, TB; +def MOVAPSmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V4F32:$src), + "movaps {$src, $dst|$dst, $src}",[]>, + Requires<[HasSSE1]>, TB; +def MOVAPDrm : I<0x28, MRMSrcMem, (ops V2F64:$dst, f128mem:$src), + "movapd {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, TB, OpSize; +def MOVAPDmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V2F64:$src), + "movapd {$src, $dst|$dst, $src}",[]>, + Requires<[HasSSE2]>, TB, OpSize; + +// Logical +let isTwoAddress = 1 in { +let isCommutable = 1 in { +def ANDPSrr : I<0x54, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "andps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (X86fand V4F32:$src1, V4F32:$src2))]>, + Requires<[HasSSE1]>, TB; +def ANDPDrr : I<0x54, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "andpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (X86fand V2F64:$src1, V2F64:$src2))]>, + Requires<[HasSSE2]>, TB, OpSize; +def ORPSrr : I<0x56, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "orps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def ORPDrr : I<0x56, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +def XORPSrr : I<0x57, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "xorps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (X86fxor V4F32:$src1, V4F32:$src2))]>, + Requires<[HasSSE1]>, TB; +def XORPDrr : I<0x57, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "xorpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (X86fxor V2F64:$src1, V2F64:$src2))]>, + Requires<[HasSSE2]>, TB, OpSize; +} +def ANDPSrm : I<0x54, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "andps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (X86fand V4F32:$src1, + (X86loadpv4f32 addr:$src2)))]>, + Requires<[HasSSE1]>, TB; +def ANDPDrm : I<0x54, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "andpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (X86fand V2F64:$src1, + (X86loadpv2f64 addr:$src2)))]>, + Requires<[HasSSE2]>, TB, OpSize; +def ORPSrm : I<0x56, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "orps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def ORPDrm : I<0x56, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +def XORPSrm : I<0x57, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "xorps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (X86fxor V4F32:$src1, + (X86loadpv4f32 addr:$src2)))]>, + Requires<[HasSSE1]>, TB; +def XORPDrm : I<0x57, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "xorpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (X86fxor V2F64:$src1, + (X86loadpv2f64 addr:$src2)))]>, + Requires<[HasSSE2]>, TB, OpSize; + +def ANDNPSrr : I<0x55, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def ANDNPSrm : I<0x55, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def ANDNPDrr : I<0x55, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +def ANDNPDrm : I<0x55, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +} + +//===----------------------------------------------------------------------===// +// SSE integer instructions +//===----------------------------------------------------------------------===// + +// Move Instructions +def MOVD128rr : I<0x6E, MRMSrcReg, (ops VR128:$dst, R32:$src), + "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, + Requires<[HasSSE2]>; +def MOVD128rm : I<0x6E, MRMSrcMem, (ops VR128:$dst, i32mem:$src), + "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, + Requires<[HasSSE2]>; +def MOVD128mr : I<0x7E, MRMDestMem, (ops i32mem:$dst, VR128:$src), + "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, + Requires<[HasSSE2]>; + +def MOVQ128rr : I<0x7E, MRMSrcReg, (ops VR128:$dst, VR64:$src), + "movq {$src, $dst|$dst, $src}", []>, XS, + Requires<[HasSSE2]>; +def MOVQ128rm : I<0x7E, MRMSrcMem, (ops VR128:$dst, i64mem:$src), + "movq {$src, $dst|$dst, $src}", []>, XS, + Requires<[HasSSE2]>; +def MOVQ128mr : I<0xD6, MRMSrcMem, (ops i64mem:$dst, VR128:$src), + "movq {$src, $dst|$dst, $src}", []>, TB, OpSize, + Requires<[HasSSE2]>; From lattner at cs.uiuc.edu Tue Feb 21 17:10:41 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 21 Feb 2006 17:10:41 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200602212310.RAA17742@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.51 -> 1.52 --- Log message: Pass in a value type to getRegForInlineAsmConstraint, allowing targets to select different sets of registers depending on the type requested. --- Diffs of the changes: (+2 -1) TargetLowering.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.51 llvm/include/llvm/Target/TargetLowering.h:1.52 --- llvm/include/llvm/Target/TargetLowering.h:1.51 Fri Feb 17 12:06:19 2006 +++ llvm/include/llvm/Target/TargetLowering.h Tue Feb 21 17:10:29 2006 @@ -496,7 +496,8 @@ /// satisfy the constraint. This should only be used for physregs and /// C_RegisterClass constraints. virtual std::vector - getRegForInlineAsmConstraint(const std::string &Constraint) const; + getRegForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const; /// isOperandValidForConstraint - Return true if the specified SDOperand is /// valid for the specified target constraint letter. From lattner at cs.uiuc.edu Tue Feb 21 17:11:13 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 21 Feb 2006 17:11:13 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h Message-ID: <200602212311.RAA17792@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.90 -> 1.91 X86ISelLowering.h updated: 1.28 -> 1.29 --- Log message: Updates to match change of getRegForInlineAsmConstraint prototype --- Diffs of the changes: (+5 -3) X86ISelLowering.cpp | 5 +++-- X86ISelLowering.h | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.90 llvm/lib/Target/X86/X86ISelLowering.cpp:1.91 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.90 Sat Feb 18 01:26:17 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Feb 21 17:11:00 2006 @@ -1961,7 +1961,8 @@ } std::vector X86TargetLowering:: -getRegForInlineAsmConstraint(const std::string &Constraint) const { +getRegForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const { if (Constraint.size() == 1) { // FIXME: not handling fp-stack yet! // FIXME: not handling MMX registers yet ('y' constraint). @@ -1993,5 +1994,5 @@ } // Handle explicit register names. - return TargetLowering::getRegForInlineAsmConstraint(Constraint); + return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.28 llvm/lib/Target/X86/X86ISelLowering.h:1.29 --- llvm/lib/Target/X86/X86ISelLowering.h:1.28 Fri Feb 17 18:15:05 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Tue Feb 21 17:11:00 2006 @@ -224,7 +224,8 @@ SDOperand getReturnAddressFrameIndex(SelectionDAG &DAG); std::vector - getRegForInlineAsmConstraint(const std::string &Constraint) const; + getRegForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const; private: // C Calling Convention implementation. std::vector LowerCCCArguments(Function &F, SelectionDAG &DAG); From lattner at cs.uiuc.edu Tue Feb 21 17:11:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 21 Feb 2006 17:11:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp PPCISelLowering.h Message-ID: <200602212311.RAA17800@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.88 -> 1.89 PPCISelLowering.h updated: 1.21 -> 1.22 --- Log message: Updates to match change of getRegForInlineAsmConstraint prototype --- Diffs of the changes: (+5 -3) PPCISelLowering.cpp | 5 +++-- PPCISelLowering.h | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.88 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.89 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.88 Fri Feb 17 18:08:58 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Tue Feb 21 17:11:00 2006 @@ -999,7 +999,8 @@ std::vector PPCTargetLowering:: -getRegForInlineAsmConstraint(const std::string &Constraint) const { +getRegForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const { if (Constraint.size() == 1) { switch (Constraint[0]) { // GCC RS6000 Constraint Letters default: break; // Unknown constriant letter @@ -1051,7 +1052,7 @@ } // Handle explicit register names. - return TargetLowering::getRegForInlineAsmConstraint(Constraint); + return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); } // isOperandValidForConstraint Index: llvm/lib/Target/PowerPC/PPCISelLowering.h diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.21 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.22 --- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.21 Tue Feb 7 14:16:30 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.h Tue Feb 21 17:11:00 2006 @@ -99,7 +99,8 @@ ConstraintType getConstraintType(char ConstraintLetter) const; std::vector - getRegForInlineAsmConstraint(const std::string &Constraint) const; + getRegForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const; bool isOperandValidForConstraint(SDOperand Op, char ConstraintLetter); }; } From lattner at cs.uiuc.edu Tue Feb 21 17:11:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 21 Feb 2006 17:11:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200602212311.RAA17802@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.33 -> 1.34 --- Log message: Updates to match change of getRegForInlineAsmConstraint prototype --- Diffs of the changes: (+2 -1) TargetLowering.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.33 llvm/lib/Target/TargetLowering.cpp:1.34 --- llvm/lib/Target/TargetLowering.cpp:1.33 Fri Feb 17 20:43:25 2006 +++ llvm/lib/Target/TargetLowering.cpp Tue Feb 21 17:11:00 2006 @@ -745,7 +745,8 @@ std::vector TargetLowering:: -getRegForInlineAsmConstraint(const std::string &Constraint) const { +getRegForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const { // Not a physreg, must not be a register reference or something. if (Constraint[0] != '{') return std::vector(); assert(*(Constraint.end()-1) == '}' && "Not a brace enclosed constraint?"); From lattner at cs.uiuc.edu Tue Feb 21 17:12:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 21 Feb 2006 17:12:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200602212312.RAA17866@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.164 -> 1.165 --- Log message: Adjust to changes in getRegForInlineAsmConstraint prototype --- Diffs of the changes: (+18 -18) SelectionDAGISel.cpp | 36 ++++++++++++++++++------------------ 1 files changed, 18 insertions(+), 18 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.164 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.165 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.164 Thu Feb 16 17:11:42 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Feb 21 17:12:12 2006 @@ -1198,13 +1198,6 @@ SDOperand Chain = getRoot(); SDOperand Flag; - // Loop over all of the inputs, copying the operand values into the - // appropriate registers and processing the output regs. - unsigned RetValReg = 0; - std::vector > IndirectStoresToEmit; - unsigned OpNum = 1; - bool FoundOutputConstraint = false; - // We fully assign registers here at isel time. This is not optimal, but // should work. For register classes that correspond to LLVM classes, we // could let the LLVM RA do its thing, but we currently don't. Do a prepass @@ -1215,7 +1208,7 @@ std::string &ConstraintCode = Constraints[i].Codes[0]; std::vector Regs = - TLI.getRegForInlineAsmConstraint(ConstraintCode); + TLI.getRegForInlineAsmConstraint(ConstraintCode, MVT::Other); if (Regs.size() != 1) continue; // Not assigned a fixed reg. unsigned TheReg = Regs[0]; @@ -1240,14 +1233,23 @@ } } + // Loop over all of the inputs, copying the operand values into the + // appropriate registers and processing the output regs. + unsigned RetValReg = 0; + std::vector > IndirectStoresToEmit; + bool FoundOutputConstraint = false; + unsigned OpNum = 1; + for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { assert(Constraints[i].Codes.size() == 1 && "Only handles one code so far!"); std::string &ConstraintCode = Constraints[i].Codes[0]; + Value *CallOperand = I.getOperand(OpNum); + MVT::ValueType CallOpVT = TLI.getValueType(CallOperand->getType()); switch (Constraints[i].Type) { case InlineAsm::isOutput: { // Copy the output from the appropriate register. std::vector Regs = - TLI.getRegForInlineAsmConstraint(ConstraintCode); + TLI.getRegForInlineAsmConstraint(ConstraintCode, CallOpVT); // Find a regsister that we can use. unsigned DestReg; @@ -1276,9 +1278,8 @@ RetValReg = DestReg; OpTy = I.getType(); } else { - IndirectStoresToEmit.push_back(std::make_pair(DestReg, - I.getOperand(OpNum))); - OpTy = I.getOperand(OpNum)->getType(); + IndirectStoresToEmit.push_back(std::make_pair(DestReg, CallOperand)); + OpTy = CallOperand->getType(); OpTy = cast(OpTy)->getElementType(); OpNum++; // Consumes a call operand. } @@ -1292,21 +1293,20 @@ break; } case InlineAsm::isInput: { - Value *Operand = I.getOperand(OpNum); - const Type *OpTy = Operand->getType(); + const Type *OpTy = CallOperand->getType(); OpNum++; // Consumes a call operand. unsigned SrcReg; SDOperand ResOp; unsigned ResOpType; - SDOperand InOperandVal = getValue(Operand); + SDOperand InOperandVal = getValue(CallOperand); if (isdigit(ConstraintCode[0])) { // Matching constraint? // If this is required to match an output register we have already set, // just use its register. unsigned OperandNo = atoi(ConstraintCode.c_str()); SrcReg = cast(AsmNodeOperands[OperandNo*2+2])->getReg(); - ResOp = DAG.getRegister(SrcReg, TLI.getValueType(OpTy)); + ResOp = DAG.getRegister(SrcReg, CallOpVT); ResOpType = 1; Chain = DAG.getCopyToReg(Chain, SrcReg, InOperandVal, Flag); @@ -1321,7 +1321,7 @@ case TargetLowering::C_RegisterClass: { // Copy the input into the appropriate register. std::vector Regs = - TLI.getRegForInlineAsmConstraint(ConstraintCode); + TLI.getRegForInlineAsmConstraint(ConstraintCode, CallOpVT); if (Regs.size() == 1) SrcReg = Regs[0]; else @@ -1332,7 +1332,7 @@ Chain = DAG.getCopyToReg(Chain, SrcReg, InOperandVal, Flag); Flag = Chain.getValue(1); - ResOp = DAG.getRegister(SrcReg, TLI.getValueType(OpTy)); + ResOp = DAG.getRegister(SrcReg, CallOpVT); ResOpType = 1; break; } From lattner at cs.uiuc.edu Tue Feb 21 17:52:09 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 21 Feb 2006 17:52:09 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200602212352.RAA18252@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.68 -> 1.69 --- Log message: expose the set of values types holdable in a regclass to clients --- Diffs of the changes: (+17 -1) MRegisterInfo.h | 18 +++++++++++++++++- 1 files changed, 17 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.68 llvm/include/llvm/Target/MRegisterInfo.h:1.69 --- llvm/include/llvm/Target/MRegisterInfo.h:1.68 Thu Feb 2 14:11:55 2006 +++ llvm/include/llvm/Target/MRegisterInfo.h Tue Feb 21 17:51:58 2006 @@ -44,8 +44,9 @@ typedef const unsigned* iterator; typedef const unsigned* const_iterator; + typedef const MVT::ValueType* vt_iterator; private: - const MVT::ValueType* VTs; + const vt_iterator VTs; const unsigned RegSize, Alignment; // Size & Alignment of register in bytes const iterator RegsBegin, RegsEnd; public: @@ -84,6 +85,21 @@ return false; } + /// vt_begin - Loop over all of the value types that can be represented by + /// values in this register class. + vt_iterator vt_begin() const { + return VTs; + } + + /// vt_begin - Loop over all of the value types that can be represented by + /// values in this register class. + vt_iterator vt_end() const { + vt_iterator I = VTs; + while (*I != MVT::Other) ++I; + return I; + } + + /// allocation_order_begin/end - These methods define a range of registers /// which specify the registers in this class that are valid to register /// allocate, and the preferred order to allocate them in. For example, From lattner at cs.uiuc.edu Tue Feb 21 18:56:13 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 21 Feb 2006 18:56:13 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200602220056.SAA18672@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.52 -> 1.53 --- Log message: split register class handling from explicit physreg handling. --- Diffs of the changes: (+16 -6) TargetLowering.h | 22 ++++++++++++++++------ 1 files changed, 16 insertions(+), 6 deletions(-) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.52 llvm/include/llvm/Target/TargetLowering.h:1.53 --- llvm/include/llvm/Target/TargetLowering.h:1.52 Tue Feb 21 17:10:29 2006 +++ llvm/include/llvm/Target/TargetLowering.h Tue Feb 21 18:56:01 2006 @@ -481,6 +481,7 @@ // enum ConstraintType { + C_Register, // Constraint represents a single register. C_RegisterClass, // Constraint represents one or more registers. C_Other, // Something else. C_Unknown // Unsupported constraint. @@ -491,13 +492,22 @@ /// constraint it is for this target. virtual ConstraintType getConstraintType(char ConstraintLetter) const; - /// getRegForInlineAsmConstraint - Given a constraint letter or register - /// name (e.g. "r" or "edx"), return a list of registers that can be used to - /// satisfy the constraint. This should only be used for physregs and - /// C_RegisterClass constraints. + + /// getRegClassForInlineAsmConstraint - Given a constraint letter (e.g. "r"), + /// return a list of registers that can be used to satisfy the constraint. + /// This should only be used for C_RegisterClass constraints. virtual std::vector - getRegForInlineAsmConstraint(const std::string &Constraint, - MVT::ValueType VT) const; + getRegClassForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const; + + /// getRegForInlineAsmConstraint - Given a physical register constraint (e.g. + /// {edx}), return the register number and the register class for the + /// register. This should only be used for C_Register constraints. On error, + /// this returns a register number of 0. + virtual std::pair + getRegForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const; + /// isOperandValidForConstraint - Return true if the specified SDOperand is /// valid for the specified target constraint letter. From lattner at cs.uiuc.edu Tue Feb 21 18:56:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 21 Feb 2006 18:56:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200602220056.SAA18705@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.165 -> 1.166 --- Log message: split register class handling from explicit physreg handling. --- Diffs of the changes: (+77 -34) SelectionDAGISel.cpp | 111 +++++++++++++++++++++++++++++++++++---------------- 1 files changed, 77 insertions(+), 34 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.165 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.166 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.165 Tue Feb 21 17:12:12 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Feb 21 18:56:12 2006 @@ -1187,6 +1187,7 @@ bool hasSideEffects = IA->hasSideEffects(); std::vector Constraints = IA->ParseConstraints(); + std::vector ConstraintVTs; /// AsmNodeOperands - A list of pairs. The first element is a register, the /// second is a bitfield where bit #0 is set if it is a use and bit #1 is set @@ -1203,14 +1204,43 @@ // could let the LLVM RA do its thing, but we currently don't. Do a prepass // over the constraints, collecting fixed registers that we know we can't use. std::set OutputRegs, InputRegs; + unsigned OpNum = 1; for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { assert(Constraints[i].Codes.size() == 1 && "Only handles one code so far!"); std::string &ConstraintCode = Constraints[i].Codes[0]; - std::vector Regs = - TLI.getRegForInlineAsmConstraint(ConstraintCode, MVT::Other); - if (Regs.size() != 1) continue; // Not assigned a fixed reg. - unsigned TheReg = Regs[0]; + MVT::ValueType OpVT; + + // Compute the value type for each operand and add it to ConstraintVTs. + switch (Constraints[i].Type) { + case InlineAsm::isOutput: + if (!Constraints[i].isIndirectOutput) { + assert(I.getType() != Type::VoidTy && "Bad inline asm!"); + OpVT = TLI.getValueType(I.getType()); + } else { + Value *CallOperand = I.getOperand(OpNum); + const Type *OpTy = CallOperand->getType(); + OpVT = TLI.getValueType(cast(OpTy)->getElementType()); + OpNum++; // Consumes a call operand. + } + break; + case InlineAsm::isInput: + OpVT = TLI.getValueType(I.getOperand(OpNum)->getType()); + OpNum++; // Consumes a call operand. + break; + case InlineAsm::isClobber: + OpVT = MVT::Other; + break; + } + + ConstraintVTs.push_back(OpVT); + + std::pair Reg = + TLI.getRegForInlineAsmConstraint(ConstraintCode, OpVT); + if (Reg.first == 0) continue; // Not assigned a fixed reg. + unsigned TheReg = Reg.first; + + // FIXME: Handle expanded physreg refs! switch (Constraints[i].Type) { case InlineAsm::isOutput: @@ -1221,15 +1251,15 @@ if (Constraints[i].isEarlyClobber || Constraints[i].hasMatchingInput) InputRegs.insert(TheReg); break; + case InlineAsm::isInput: + // We can't assign any other input to this register. + InputRegs.insert(TheReg); + break; case InlineAsm::isClobber: // Clobbered regs cannot be used as inputs or outputs. InputRegs.insert(TheReg); OutputRegs.insert(TheReg); break; - case InlineAsm::isInput: - // We can't assign any other input to this register. - InputRegs.insert(TheReg); - break; } } @@ -1238,28 +1268,32 @@ unsigned RetValReg = 0; std::vector > IndirectStoresToEmit; bool FoundOutputConstraint = false; - unsigned OpNum = 1; + OpNum = 1; for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { assert(Constraints[i].Codes.size() == 1 && "Only handles one code so far!"); std::string &ConstraintCode = Constraints[i].Codes[0]; - Value *CallOperand = I.getOperand(OpNum); - MVT::ValueType CallOpVT = TLI.getValueType(CallOperand->getType()); + switch (Constraints[i].Type) { case InlineAsm::isOutput: { - // Copy the output from the appropriate register. - std::vector Regs = - TLI.getRegForInlineAsmConstraint(ConstraintCode, CallOpVT); - - // Find a regsister that we can use. + // Copy the output from the appropriate register. Find a regsister that + // we can use. + + // Check to see if this is a physreg reference. + std::pair PhysReg = + TLI.getRegForInlineAsmConstraint(ConstraintCode, ConstraintVTs[i]); unsigned DestReg; - if (Regs.size() == 1) - DestReg = Regs[0]; + if (PhysReg.first) + DestReg = PhysReg.first; else { - bool UsesInputRegister = false; + std::vector Regs = + TLI.getRegClassForInlineAsmConstraint(ConstraintCode, + ConstraintVTs[i]); + // If this is an early-clobber output, or if there is an input // constraint that matches this, we need to reserve the input register // so no other inputs allocate to it. + bool UsesInputRegister = false; if (Constraints[i].isEarlyClobber || Constraints[i].hasMatchingInput) UsesInputRegister = true; DestReg = GetAvailableRegister(true, UsesInputRegister, @@ -1276,24 +1310,21 @@ assert(I.getType() != Type::VoidTy && "Bad inline asm!"); RetValReg = DestReg; - OpTy = I.getType(); } else { + Value *CallOperand = I.getOperand(OpNum); IndirectStoresToEmit.push_back(std::make_pair(DestReg, CallOperand)); - OpTy = CallOperand->getType(); - OpTy = cast(OpTy)->getElementType(); OpNum++; // Consumes a call operand. } // Add information to the INLINEASM node to know that this register is // set. - AsmNodeOperands.push_back(DAG.getRegister(DestReg, - TLI.getValueType(OpTy))); + AsmNodeOperands.push_back(DAG.getRegister(DestReg, ConstraintVTs[i])); AsmNodeOperands.push_back(DAG.getConstant(2, MVT::i32)); // ISDEF break; } case InlineAsm::isInput: { - const Type *OpTy = CallOperand->getType(); + Value *CallOperand = I.getOperand(OpNum); OpNum++; // Consumes a call operand. unsigned SrcReg; @@ -1306,33 +1337,45 @@ // just use its register. unsigned OperandNo = atoi(ConstraintCode.c_str()); SrcReg = cast(AsmNodeOperands[OperandNo*2+2])->getReg(); - ResOp = DAG.getRegister(SrcReg, CallOpVT); + ResOp = DAG.getRegister(SrcReg, ConstraintVTs[i]); ResOpType = 1; Chain = DAG.getCopyToReg(Chain, SrcReg, InOperandVal, Flag); Flag = Chain.getValue(1); } else { - TargetLowering::ConstraintType CTy = TargetLowering::C_RegisterClass; + TargetLowering::ConstraintType CTy = TargetLowering::C_Register; if (ConstraintCode.size() == 1) // not a physreg name. CTy = TLI.getConstraintType(ConstraintCode[0]); switch (CTy) { default: assert(0 && "Unknown constraint type! FAIL!"); + case TargetLowering::C_Register: { + std::pair PhysReg = + TLI.getRegForInlineAsmConstraint(ConstraintCode, ConstraintVTs[i]); + // FIXME: should be match fail. + assert(PhysReg.first && "Unknown physical register name!"); + SrcReg = PhysReg.first; + + Chain = DAG.getCopyToReg(Chain, SrcReg, InOperandVal, Flag); + Flag = Chain.getValue(1); + + ResOp = DAG.getRegister(SrcReg, ConstraintVTs[i]); + ResOpType = 1; + break; + } case TargetLowering::C_RegisterClass: { // Copy the input into the appropriate register. std::vector Regs = - TLI.getRegForInlineAsmConstraint(ConstraintCode, CallOpVT); - if (Regs.size() == 1) - SrcReg = Regs[0]; - else - SrcReg = GetAvailableRegister(false, true, Regs, - OutputRegs, InputRegs); + TLI.getRegClassForInlineAsmConstraint(ConstraintCode, + ConstraintVTs[i]); + SrcReg = GetAvailableRegister(false, true, Regs, + OutputRegs, InputRegs); // FIXME: should be match fail. assert(SrcReg && "Wasn't able to allocate register!"); Chain = DAG.getCopyToReg(Chain, SrcReg, InOperandVal, Flag); Flag = Chain.getValue(1); - ResOp = DAG.getRegister(SrcReg, CallOpVT); + ResOp = DAG.getRegister(SrcReg, ConstraintVTs[i]); ResOpType = 1; break; } From lattner at cs.uiuc.edu Tue Feb 21 18:56:51 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 21 Feb 2006 18:56:51 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp PPCISelLowering.h Message-ID: <200602220056.SAA18777@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.89 -> 1.90 PPCISelLowering.h updated: 1.22 -> 1.23 --- Log message: split register class handling from explicit physreg handling. --- Diffs of the changes: (+5 -6) PPCISelLowering.cpp | 7 +++---- PPCISelLowering.h | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.89 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.90 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.89 Tue Feb 21 17:11:00 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Tue Feb 21 18:56:38 2006 @@ -999,8 +999,8 @@ std::vector PPCTargetLowering:: -getRegForInlineAsmConstraint(const std::string &Constraint, - MVT::ValueType VT) const { +getRegClassForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const { if (Constraint.size() == 1) { switch (Constraint[0]) { // GCC RS6000 Constraint Letters default: break; // Unknown constriant letter @@ -1051,8 +1051,7 @@ } } - // Handle explicit register names. - return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); + return std::vector(); } // isOperandValidForConstraint Index: llvm/lib/Target/PowerPC/PPCISelLowering.h diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.22 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.23 --- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.22 Tue Feb 21 17:11:00 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.h Tue Feb 21 18:56:38 2006 @@ -99,8 +99,8 @@ ConstraintType getConstraintType(char ConstraintLetter) const; std::vector - getRegForInlineAsmConstraint(const std::string &Constraint, - MVT::ValueType VT) const; + getRegClassForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const; bool isOperandValidForConstraint(SDOperand Op, char ConstraintLetter); }; } From lattner at cs.uiuc.edu Tue Feb 21 18:56:52 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 21 Feb 2006 18:56:52 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h Message-ID: <200602220056.SAA18787@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.91 -> 1.92 X86ISelLowering.h updated: 1.29 -> 1.30 --- Log message: split register class handling from explicit physreg handling. --- Diffs of the changes: (+5 -6) X86ISelLowering.cpp | 7 +++---- X86ISelLowering.h | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.91 llvm/lib/Target/X86/X86ISelLowering.cpp:1.92 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.91 Tue Feb 21 17:11:00 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Feb 21 18:56:39 2006 @@ -1961,8 +1961,8 @@ } std::vector X86TargetLowering:: -getRegForInlineAsmConstraint(const std::string &Constraint, - MVT::ValueType VT) const { +getRegClassForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const { if (Constraint.size() == 1) { // FIXME: not handling fp-stack yet! // FIXME: not handling MMX registers yet ('y' constraint). @@ -1993,6 +1993,5 @@ } } - // Handle explicit register names. - return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); + return std::vector(); } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.29 llvm/lib/Target/X86/X86ISelLowering.h:1.30 --- llvm/lib/Target/X86/X86ISelLowering.h:1.29 Tue Feb 21 17:11:00 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Tue Feb 21 18:56:39 2006 @@ -224,8 +224,8 @@ SDOperand getReturnAddressFrameIndex(SelectionDAG &DAG); std::vector - getRegForInlineAsmConstraint(const std::string &Constraint, - MVT::ValueType VT) const; + getRegClassForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const; private: // C Calling Convention implementation. std::vector LowerCCCArguments(Function &F, SelectionDAG &DAG); From lattner at cs.uiuc.edu Tue Feb 21 18:56:52 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 21 Feb 2006 18:56:52 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200602220056.SAA18781@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.34 -> 1.35 --- Log message: split register class handling from explicit physreg handling. --- Diffs of the changes: (+21 -11) TargetLowering.cpp | 32 +++++++++++++++++++++----------- 1 files changed, 21 insertions(+), 11 deletions(-) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.34 llvm/lib/Target/TargetLowering.cpp:1.35 --- llvm/lib/Target/TargetLowering.cpp:1.34 Tue Feb 21 17:11:00 2006 +++ llvm/lib/Target/TargetLowering.cpp Tue Feb 21 18:56:38 2006 @@ -745,24 +745,34 @@ std::vector TargetLowering:: +getRegClassForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const { + return std::vector(); +} + + +std::pair TargetLowering:: getRegForInlineAsmConstraint(const std::string &Constraint, MVT::ValueType VT) const { - // Not a physreg, must not be a register reference or something. - if (Constraint[0] != '{') return std::vector(); + if (Constraint[0] != '{') + return std::pair(0, 0); assert(*(Constraint.end()-1) == '}' && "Not a brace enclosed constraint?"); // Remove the braces from around the name. std::string RegName(Constraint.begin()+1, Constraint.end()-1); - - // Scan to see if this constraint is a register name. + + // Figure out which register class contains this reg. const MRegisterInfo *RI = TM.getRegisterInfo(); - for (unsigned i = 1, e = RI->getNumRegs(); i != e; ++i) { - if (const char *Name = RI->get(i).Name) - if (StringsEqualNoCase(RegName, Name)) - return std::vector(1, i); + for (MRegisterInfo::regclass_iterator RCI = RI->regclass_begin(), + E = RI->regclass_end(); RCI != E; ++RCI) { + const TargetRegisterClass *RC = *RCI; + for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end(); + I != E; ++I) { + if (StringsEqualNoCase(RegName, RI->get(*I).Name)) { + return std::make_pair(*I, RC); + } + } } - // Unknown physreg. - return std::vector(); + return std::pair(0, 0); } - From lattner at cs.uiuc.edu Tue Feb 21 18:59:18 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 21 Feb 2006 18:59:18 -0600 Subject: [llvm-commits] CVS: llvm/tools/opt/Makefile Message-ID: <200602220059.SAA19011@zion.cs.uiuc.edu> Changes in directory llvm/tools/opt: Makefile updated: 1.53 -> 1.54 --- Log message: reorder some libraries --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/tools/opt/Makefile diff -u llvm/tools/opt/Makefile:1.53 llvm/tools/opt/Makefile:1.54 --- llvm/tools/opt/Makefile:1.53 Thu Oct 27 10:54:34 2005 +++ llvm/tools/opt/Makefile Tue Feb 21 18:59:06 2006 @@ -11,7 +11,7 @@ USEDLIBS = LLVMBCReader LLVMBCWriter LLVMInstrumentation.a \ LLVMScalarOpts.a LLVMipo.a LLVMipa.a LLVMDataStructure LLVMTransforms.a \ - LLVMTarget.a LLVMAnalysis.a LLVMTransformUtils.a LLVMCore LLVMSupport.a \ + LLVMTarget.a LLVMTransformUtils.a LLVMAnalysis.a LLVMCore LLVMSupport.a \ LLVMbzip2 LLVMSystem.a include $(LEVEL)/Makefile.common From evan.cheng at apple.com Tue Feb 21 20:26:42 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 21 Feb 2006 20:26:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.h X86ISelLowering.cpp X86InstrInfo.td X86InstrSSE.td X86IntelAsmPrinter.h Message-ID: <200602220226.UAA19520@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ATTAsmPrinter.h updated: 1.7 -> 1.8 X86ISelLowering.cpp updated: 1.92 -> 1.93 X86InstrInfo.td updated: 1.246 -> 1.247 X86InstrSSE.td updated: 1.4 -> 1.5 X86IntelAsmPrinter.h updated: 1.8 -> 1.9 --- Log message: Added MMX, SSE1, and SSE2 vector instructions and some simple patterns. Fixed some existing bugs (wrong predicates, prefixes) at the same time. --- Diffs of the changes: (+542 -283) X86ATTAsmPrinter.h | 3 X86ISelLowering.cpp | 38 ++ X86InstrInfo.td | 7 X86InstrSSE.td | 773 ++++++++++++++++++++++++++++++++------------------- X86IntelAsmPrinter.h | 4 5 files changed, 542 insertions(+), 283 deletions(-) Index: llvm/lib/Target/X86/X86ATTAsmPrinter.h diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.h:1.7 llvm/lib/Target/X86/X86ATTAsmPrinter.h:1.8 --- llvm/lib/Target/X86/X86ATTAsmPrinter.h:1.7 Fri Feb 17 18:15:05 2006 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.h Tue Feb 21 20:26:30 2006 @@ -49,6 +49,9 @@ void printi64mem(const MachineInstr *MI, unsigned OpNo) { printMemReference(MI, OpNo); } + void printi128mem(const MachineInstr *MI, unsigned OpNo) { + printMemReference(MI, OpNo); + } void printf32mem(const MachineInstr *MI, unsigned OpNo) { printMemReference(MI, OpNo); } Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.92 llvm/lib/Target/X86/X86ISelLowering.cpp:1.93 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.92 Tue Feb 21 18:56:39 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Feb 21 20:26:30 2006 @@ -236,6 +236,44 @@ addLegalFPImmediate(-0.0); // FLD0/FCHS addLegalFPImmediate(-1.0); // FLD1/FCHS } + + if (TM.getSubtarget().hasMMX()) { + addRegisterClass(MVT::v8i8, X86::VR64RegisterClass); + addRegisterClass(MVT::v4i16, X86::VR64RegisterClass); + addRegisterClass(MVT::v2i32, X86::VR64RegisterClass); + + // FIXME: We don't support any ConstantVec's yet. We should custom expand + // the ones we do! + setOperationAction(ISD::ConstantVec, MVT::v8i8, Expand); + setOperationAction(ISD::ConstantVec, MVT::v4i16, Expand); + setOperationAction(ISD::ConstantVec, MVT::v2i32, Expand); + } + + if (TM.getSubtarget().hasSSE1()) { + addRegisterClass(MVT::v4f32, X86::VR128RegisterClass); + + // FIXME: We don't support any ConstantVec's yet. We should custom expand + // the ones we do! + setOperationAction(ISD::ConstantVec, MVT::v4f32, Expand); + } + + if (TM.getSubtarget().hasSSE2()) { + addRegisterClass(MVT::v2f64, X86::VR128RegisterClass); + addRegisterClass(MVT::v16i8, X86::VR128RegisterClass); + addRegisterClass(MVT::v8i16, X86::VR128RegisterClass); + addRegisterClass(MVT::v4i32, X86::VR128RegisterClass); + addRegisterClass(MVT::v2i64, X86::VR128RegisterClass); + + + // FIXME: We don't support any ConstantVec's yet. We should custom expand + // the ones we do! + setOperationAction(ISD::ConstantVec, MVT::v2f64, Expand); + setOperationAction(ISD::ConstantVec, MVT::v16i8, Expand); + setOperationAction(ISD::ConstantVec, MVT::v8i16, Expand); + setOperationAction(ISD::ConstantVec, MVT::v4i32, Expand); + setOperationAction(ISD::ConstantVec, MVT::v2i64, Expand); + } + computeRegisterProperties(); // FIXME: These should be based on subtarget info. Plus, the values should Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.246 llvm/lib/Target/X86/X86InstrInfo.td:1.247 --- llvm/lib/Target/X86/X86InstrInfo.td:1.246 Tue Feb 21 14:00:20 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Tue Feb 21 20:26:30 2006 @@ -136,6 +136,7 @@ def i16mem : X86MemOperand<"printi16mem">; def i32mem : X86MemOperand<"printi32mem">; def i64mem : X86MemOperand<"printi64mem">; +def i128mem : X86MemOperand<"printi128mem">; def f32mem : X86MemOperand<"printf32mem">; def f64mem : X86MemOperand<"printf64mem">; def f128mem : X86MemOperand<"printf128mem">; @@ -341,6 +342,9 @@ def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>; def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>; +def X86loadv4f32 : PatFrag<(ops node:$ptr), (v4f32 (load node:$ptr))>; +def X86loadv2f64 : PatFrag<(ops node:$ptr), (v2f64 (load node:$ptr))>; + def sextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (sextload node:$ptr, i1))>; def sextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (sextload node:$ptr, i1))>; def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextload node:$ptr, i8))>; @@ -360,9 +364,6 @@ def X86loadpf32 : PatFrag<(ops node:$ptr), (f32 (X86loadp node:$ptr))>; def X86loadpf64 : PatFrag<(ops node:$ptr), (f64 (X86loadp node:$ptr))>; -def X86loadpv4f32 : PatFrag<(ops node:$ptr), (v4f32 (X86loadp node:$ptr))>; -def X86loadpv2f64 : PatFrag<(ops node:$ptr), (v2f64 (X86loadp node:$ptr))>; - //===----------------------------------------------------------------------===// // Instruction templates... Index: llvm/lib/Target/X86/X86InstrSSE.td diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.4 llvm/lib/Target/X86/X86InstrSSE.td:1.5 --- llvm/lib/Target/X86/X86InstrSSE.td:1.4 Tue Feb 21 14:00:20 2006 +++ llvm/lib/Target/X86/X86InstrSSE.td Tue Feb 21 20:26:30 2006 @@ -17,6 +17,20 @@ // SSE scalar FP Instructions //===----------------------------------------------------------------------===// +// Instruction templates +// SSI - SSE1 instructions with XS prefix. +// SDI - SSE2 instructions with XD prefix. +// PSI - SSE1 instructions with TB prefix. +// PDI - SSE2 instructions with TB and OpSize prefixes. +class SSI o, Format F, dag ops, string asm, list pattern> + : I, XS, Requires<[HasSSE1]>; +class SDI o, Format F, dag ops, string asm, list pattern> + : I, XD, Requires<[HasSSE2]>; +class PSI o, Format F, dag ops, string asm, list pattern> + : I, TB, Requires<[HasSSE1]>; +class PDI o, Format F, dag ops, string asm, list pattern> + : I, TB, OpSize, Requires<[HasSSE2]>; + // Some 'special' instructions def IMPLICIT_DEF_FR32 : I<0, Pseudo, (ops FR32:$dst), "#IMPLICIT_DEF $dst", @@ -39,206 +53,189 @@ } // Move Instructions -def MOVSSrr : I<0x10, MRMSrcReg, (ops FR32:$dst, FR32:$src), - "movss {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, XS; -def MOVSDrr : I<0x10, MRMSrcReg, (ops FR64:$dst, FR64:$src), - "movsd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE2]>, XD; - -def MOVSSrm : I<0x10, MRMSrcMem, (ops FR32:$dst, f32mem:$src), - "movss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (loadf32 addr:$src))]>, - Requires<[HasSSE1]>, XS; -def MOVSSmr : I<0x11, MRMDestMem, (ops f32mem:$dst, FR32:$src), +def MOVSSrr : SSI<0x10, MRMSrcReg, (ops FR32:$dst, FR32:$src), + "movss {$src, $dst|$dst, $src}", []>; +def MOVSSrm : SSI<0x10, MRMSrcMem, (ops FR32:$dst, f32mem:$src), "movss {$src, $dst|$dst, $src}", - [(store FR32:$src, addr:$dst)]>, - Requires<[HasSSE1]>, XS; -def MOVSDrm : I<0x10, MRMSrcMem, (ops FR64:$dst, f64mem:$src), + [(set FR32:$dst, (loadf32 addr:$src))]>; +def MOVSDrr : SDI<0x10, MRMSrcReg, (ops FR64:$dst, FR64:$src), + "movsd {$src, $dst|$dst, $src}", []>; +def MOVSDrm : SDI<0x10, MRMSrcMem, (ops FR64:$dst, f64mem:$src), "movsd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (loadf64 addr:$src))]>, - Requires<[HasSSE2]>, XD; -def MOVSDmr : I<0x11, MRMDestMem, (ops f64mem:$dst, FR64:$src), + [(set FR64:$dst, (loadf64 addr:$src))]>; + +def MOVSSmr : SSI<0x11, MRMDestMem, (ops f32mem:$dst, FR32:$src), + "movss {$src, $dst|$dst, $src}", + [(store FR32:$src, addr:$dst)]>; +def MOVSDmr : SDI<0x11, MRMDestMem, (ops f64mem:$dst, FR64:$src), "movsd {$src, $dst|$dst, $src}", - [(store FR64:$src, addr:$dst)]>, - Requires<[HasSSE2]>, XD; + [(store FR64:$src, addr:$dst)]>; // Conversion instructions -def CVTTSS2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR32:$src), +def CVTTSS2SIrr: SSI<0x2C, MRMSrcReg, (ops R32:$dst, FR32:$src), "cvttss2si {$src, $dst|$dst, $src}", - [(set R32:$dst, (fp_to_sint FR32:$src))]>, - Requires<[HasSSE1]>, XS; -def CVTTSS2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f32mem:$src), + [(set R32:$dst, (fp_to_sint FR32:$src))]>; +def CVTTSS2SIrm: SSI<0x2C, MRMSrcMem, (ops R32:$dst, f32mem:$src), "cvttss2si {$src, $dst|$dst, $src}", - [(set R32:$dst, (fp_to_sint (loadf32 addr:$src)))]>, - Requires<[HasSSE1]>, XS; -def CVTTSD2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR64:$src), + [(set R32:$dst, (fp_to_sint (loadf32 addr:$src)))]>; +def CVTTSD2SIrr: SDI<0x2C, MRMSrcReg, (ops R32:$dst, FR64:$src), "cvttsd2si {$src, $dst|$dst, $src}", - [(set R32:$dst, (fp_to_sint FR64:$src))]>, - Requires<[HasSSE2]>, XD; -def CVTTSD2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f64mem:$src), + [(set R32:$dst, (fp_to_sint FR64:$src))]>; +def CVTTSD2SIrm: SDI<0x2C, MRMSrcMem, (ops R32:$dst, f64mem:$src), "cvttsd2si {$src, $dst|$dst, $src}", - [(set R32:$dst, (fp_to_sint (loadf64 addr:$src)))]>, - Requires<[HasSSE2]>, XD; -def CVTSS2SDrr: I<0x5A, MRMSrcReg, (ops FR64:$dst, FR32:$src), - "cvtss2sd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (fextend FR32:$src))]>, - Requires<[HasSSE2]>, XS; -def CVTSS2SDrm: I<0x5A, MRMSrcMem, (ops FR64:$dst, f32mem:$src), - "cvtss2sd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (fextend (loadf32 addr:$src)))]>, - Requires<[HasSSE2]>, XS; -def CVTSD2SSrr: I<0x5A, MRMSrcReg, (ops FR32:$dst, FR64:$src), + [(set R32:$dst, (fp_to_sint (loadf64 addr:$src)))]>; +def CVTSD2SSrr: SDI<0x5A, MRMSrcReg, (ops FR32:$dst, FR64:$src), "cvtsd2ss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (fround FR64:$src))]>, - Requires<[HasSSE2]>, XD; -def CVTSD2SSrm: I<0x5A, MRMSrcMem, (ops FR32:$dst, f64mem:$src), + [(set FR32:$dst, (fround FR64:$src))]>; +def CVTSD2SSrm: SDI<0x5A, MRMSrcMem, (ops FR32:$dst, f64mem:$src), "cvtsd2ss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (fround (loadf64 addr:$src)))]>, - Requires<[HasSSE2]>, XD; -def CVTSI2SSrr: I<0x2A, MRMSrcReg, (ops FR32:$dst, R32:$src), + [(set FR32:$dst, (fround (loadf64 addr:$src)))]>; +def CVTSI2SSrr: SSI<0x2A, MRMSrcReg, (ops FR32:$dst, R32:$src), "cvtsi2ss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (sint_to_fp R32:$src))]>, - Requires<[HasSSE2]>, XS; -def CVTSI2SSrm: I<0x2A, MRMSrcMem, (ops FR32:$dst, i32mem:$src), + [(set FR32:$dst, (sint_to_fp R32:$src))]>; +def CVTSI2SSrm: SSI<0x2A, MRMSrcMem, (ops FR32:$dst, i32mem:$src), "cvtsi2ss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (sint_to_fp (loadi32 addr:$src)))]>, - Requires<[HasSSE2]>, XS; -def CVTSI2SDrr: I<0x2A, MRMSrcReg, (ops FR64:$dst, R32:$src), + [(set FR32:$dst, (sint_to_fp (loadi32 addr:$src)))]>; +def CVTSI2SDrr: SDI<0x2A, MRMSrcReg, (ops FR64:$dst, R32:$src), "cvtsi2sd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (sint_to_fp R32:$src))]>, - Requires<[HasSSE2]>, XD; -def CVTSI2SDrm: I<0x2A, MRMSrcMem, (ops FR64:$dst, i32mem:$src), + [(set FR64:$dst, (sint_to_fp R32:$src))]>; +def CVTSI2SDrm: SDI<0x2A, MRMSrcMem, (ops FR64:$dst, i32mem:$src), "cvtsi2sd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (sint_to_fp (loadi32 addr:$src)))]>, - Requires<[HasSSE2]>, XD; + [(set FR64:$dst, (sint_to_fp (loadi32 addr:$src)))]>; +// SSE2 instructions with XS prefix +def CVTSS2SDrr: I<0x5A, MRMSrcReg, (ops FR64:$dst, FR32:$src), + "cvtss2sd {$src, $dst|$dst, $src}", + [(set FR64:$dst, (fextend FR32:$src))]>, XS, + Requires<[HasSSE2]>; +def CVTSS2SDrm: I<0x5A, MRMSrcMem, (ops FR64:$dst, f32mem:$src), + "cvtss2sd {$src, $dst|$dst, $src}", + [(set FR64:$dst, (fextend (loadf32 addr:$src)))]>, XS, + Requires<[HasSSE2]>; // Arithmetic instructions let isTwoAddress = 1 in { let isCommutable = 1 in { -def ADDSSrr : I<0x58, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), +def ADDSSrr : SSI<0x58, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), "addss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fadd FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, XS; -def ADDSDrr : I<0x58, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + [(set FR32:$dst, (fadd FR32:$src1, FR32:$src2))]>; +def ADDSDrr : SDI<0x58, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), "addsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fadd FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, XD; -def MULSSrr : I<0x59, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + [(set FR64:$dst, (fadd FR64:$src1, FR64:$src2))]>; +def MULSSrr : SSI<0x59, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), "mulss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fmul FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, XS; -def MULSDrr : I<0x59, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + [(set FR32:$dst, (fmul FR32:$src1, FR32:$src2))]>; +def MULSDrr : SDI<0x59, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), "mulsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fmul FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, XD; + [(set FR64:$dst, (fmul FR64:$src1, FR64:$src2))]>; } -def ADDSSrm : I<0x58, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), +def ADDSSrm : SSI<0x58, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), "addss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fadd FR32:$src1, (loadf32 addr:$src2)))]>, - Requires<[HasSSE1]>, XS; -def ADDSDrm : I<0x58, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), + [(set FR32:$dst, (fadd FR32:$src1, (loadf32 addr:$src2)))]>; +def ADDSDrm : SDI<0x58, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), "addsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fadd FR64:$src1, (loadf64 addr:$src2)))]>, - Requires<[HasSSE2]>, XD; -def MULSSrm : I<0x59, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), + [(set FR64:$dst, (fadd FR64:$src1, (loadf64 addr:$src2)))]>; +def MULSSrm : SSI<0x59, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), "mulss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fmul FR32:$src1, (loadf32 addr:$src2)))]>, - Requires<[HasSSE1]>, XS; -def MULSDrm : I<0x59, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), + [(set FR32:$dst, (fmul FR32:$src1, (loadf32 addr:$src2)))]>; +def MULSDrm : SDI<0x59, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), "mulsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fmul FR64:$src1, (loadf64 addr:$src2)))]>, - Requires<[HasSSE2]>, XD; + [(set FR64:$dst, (fmul FR64:$src1, (loadf64 addr:$src2)))]>; -def DIVSSrr : I<0x5E, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), +def DIVSSrr : SSI<0x5E, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), "divss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fdiv FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, XS; -def DIVSSrm : I<0x5E, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), + [(set FR32:$dst, (fdiv FR32:$src1, FR32:$src2))]>; +def DIVSSrm : SSI<0x5E, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), "divss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fdiv FR32:$src1, (loadf32 addr:$src2)))]>, - Requires<[HasSSE1]>, XS; -def DIVSDrr : I<0x5E, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + [(set FR32:$dst, (fdiv FR32:$src1, (loadf32 addr:$src2)))]>; +def DIVSDrr : SDI<0x5E, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), "divsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fdiv FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, XD; -def DIVSDrm : I<0x5E, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), + [(set FR64:$dst, (fdiv FR64:$src1, FR64:$src2))]>; +def DIVSDrm : SDI<0x5E, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), "divsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fdiv FR64:$src1, (loadf64 addr:$src2)))]>, - Requires<[HasSSE2]>, XD; + [(set FR64:$dst, (fdiv FR64:$src1, (loadf64 addr:$src2)))]>; -def SUBSSrr : I<0x5C, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), +def SUBSSrr : SSI<0x5C, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), "subss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fsub FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, XS; -def SUBSSrm : I<0x5C, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), + [(set FR32:$dst, (fsub FR32:$src1, FR32:$src2))]>; +def SUBSSrm : SSI<0x5C, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), "subss {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (fsub FR32:$src1, (loadf32 addr:$src2)))]>, - Requires<[HasSSE1]>, XS; -def SUBSDrr : I<0x5C, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + [(set FR32:$dst, (fsub FR32:$src1, (loadf32 addr:$src2)))]>; +def SUBSDrr : SDI<0x5C, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), "subsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fsub FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, XD; -def SUBSDrm : I<0x5C, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), + [(set FR64:$dst, (fsub FR64:$src1, FR64:$src2))]>; +def SUBSDrm : SDI<0x5C, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), "subsd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (fsub FR64:$src1, (loadf64 addr:$src2)))]>, - Requires<[HasSSE2]>, XD; + [(set FR64:$dst, (fsub FR64:$src1, (loadf64 addr:$src2)))]>; } -def SQRTSSrr : I<0x51, MRMSrcReg, (ops FR32:$dst, FR32:$src), +def SQRTSSrr : SSI<0x51, MRMSrcReg, (ops FR32:$dst, FR32:$src), "sqrtss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (fsqrt FR32:$src))]>, - Requires<[HasSSE1]>, XS; -def SQRTSSrm : I<0x51, MRMSrcMem, (ops FR32:$dst, f32mem:$src), + [(set FR32:$dst, (fsqrt FR32:$src))]>; +def SQRTSSrm : SSI<0x51, MRMSrcMem, (ops FR32:$dst, f32mem:$src), "sqrtss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (fsqrt (loadf32 addr:$src)))]>, - Requires<[HasSSE1]>, XS; -def SQRTSDrr : I<0x51, MRMSrcReg, (ops FR64:$dst, FR64:$src), + [(set FR32:$dst, (fsqrt (loadf32 addr:$src)))]>; +def SQRTSDrr : SDI<0x51, MRMSrcReg, (ops FR64:$dst, FR64:$src), "sqrtsd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (fsqrt FR64:$src))]>, - Requires<[HasSSE2]>, XD; -def SQRTSDrm : I<0x51, MRMSrcMem, (ops FR64:$dst, f64mem:$src), + [(set FR64:$dst, (fsqrt FR64:$src))]>; +def SQRTSDrm : SDI<0x51, MRMSrcMem, (ops FR64:$dst, f64mem:$src), "sqrtsd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (fsqrt (loadf64 addr:$src)))]>, - Requires<[HasSSE2]>, XD; + [(set FR64:$dst, (fsqrt (loadf64 addr:$src)))]>; + +def RSQRTSSrr : SSI<0x52, MRMSrcReg, (ops FR32:$dst, FR32:$src), + "rsqrtss {$src, $dst|$dst, $src}", []>; +def RSQRTSSrm : SSI<0x52, MRMSrcMem, (ops FR32:$dst, f32mem:$src), + "rsqrtss {$src, $dst|$dst, $src}", []>; +def RCPSSrr : SSI<0x53, MRMSrcReg, (ops FR32:$dst, FR32:$src), + "rcpss {$src, $dst|$dst, $src}", []>; +def RCPSSrm : SSI<0x53, MRMSrcMem, (ops FR32:$dst, f32mem:$src), + "rcpss {$src, $dst|$dst, $src}", []>; + +def MAXSSrr : SSI<0x5F, MRMSrcReg, (ops FR32:$dst, FR32:$src), + "maxss {$src, $dst|$dst, $src}", []>; +def MAXSSrm : SSI<0x5F, MRMSrcMem, (ops FR32:$dst, f32mem:$src), + "maxss {$src, $dst|$dst, $src}", []>; +def MAXSDrr : SDI<0x5F, MRMSrcReg, (ops FR64:$dst, FR64:$src), + "maxsd {$src, $dst|$dst, $src}", []>; +def MAXSDrm : SDI<0x5F, MRMSrcMem, (ops FR64:$dst, f64mem:$src), + "maxsd {$src, $dst|$dst, $src}", []>; +def MINSSrr : SSI<0x5D, MRMSrcReg, (ops FR32:$dst, FR32:$src), + "minss {$src, $dst|$dst, $src}", []>; +def MINSSrm : SSI<0x5D, MRMSrcMem, (ops FR32:$dst, f32mem:$src), + "minss {$src, $dst|$dst, $src}", []>; +def MINSDrr : SDI<0x5D, MRMSrcReg, (ops FR64:$dst, FR64:$src), + "minsd {$src, $dst|$dst, $src}", []>; +def MINSDrm : SDI<0x5D, MRMSrcMem, (ops FR64:$dst, f64mem:$src), + "minsd {$src, $dst|$dst, $src}", []>; // Comparison instructions let isTwoAddress = 1 in { -def CMPSSrr : I<0xC2, MRMSrcReg, +def CMPSSrr : SSI<0xC2, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src, SSECC:$cc), - "cmp${cc}ss {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, XS; -def CMPSSrm : I<0xC2, MRMSrcMem, + "cmp${cc}ss {$src, $dst|$dst, $src}", []>; +def CMPSSrm : SSI<0xC2, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src, SSECC:$cc), - "cmp${cc}ss {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, XS; -def CMPSDrr : I<0xC2, MRMSrcReg, + "cmp${cc}ss {$src, $dst|$dst, $src}", []>; +def CMPSDrr : SDI<0xC2, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src, SSECC:$cc), - "cmp${cc}sd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, XD; -def CMPSDrm : I<0xC2, MRMSrcMem, + "cmp${cc}sd {$src, $dst|$dst, $src}", []>; +def CMPSDrm : SDI<0xC2, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src, SSECC:$cc), - "cmp${cc}sd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE2]>, XD; + "cmp${cc}sd {$src, $dst|$dst, $src}", []>; } -def UCOMISSrr: I<0x2E, MRMSrcReg, (ops FR32:$src1, FR32:$src2), +def UCOMISSrr: PSI<0x2E, MRMSrcReg, (ops FR32:$src1, FR32:$src2), "ucomiss {$src2, $src1|$src1, $src2}", - [(X86cmp FR32:$src1, FR32:$src2)]>, - Requires<[HasSSE1]>, TB; -def UCOMISSrm: I<0x2E, MRMSrcMem, (ops FR32:$src1, f32mem:$src2), + [(X86cmp FR32:$src1, FR32:$src2)]>; +def UCOMISSrm: PSI<0x2E, MRMSrcMem, (ops FR32:$src1, f32mem:$src2), "ucomiss {$src2, $src1|$src1, $src2}", - [(X86cmp FR32:$src1, (loadf32 addr:$src2))]>, - Requires<[HasSSE1]>, TB; -def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$src1, FR64:$src2), + [(X86cmp FR32:$src1, (loadf32 addr:$src2))]>; +def UCOMISDrr: PDI<0x2E, MRMSrcReg, (ops FR64:$src1, FR64:$src2), "ucomisd {$src2, $src1|$src1, $src2}", - [(X86cmp FR64:$src1, FR64:$src2)]>, - Requires<[HasSSE2]>, TB, OpSize; -def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$src1, f64mem:$src2), + [(X86cmp FR64:$src1, FR64:$src2)]>; +def UCOMISDrm: PDI<0x2E, MRMSrcMem, (ops FR64:$src1, f64mem:$src2), "ucomisd {$src2, $src1|$src1, $src2}", - [(X86cmp FR64:$src1, (loadf64 addr:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; + [(X86cmp FR64:$src1, (loadf64 addr:$src2))]>; // Aliases of packed instructions for scalar use. These all have names that // start with 'Fs'. @@ -254,89 +251,69 @@ // Alias instructions to do FR32 / FR64 reg-to-reg copy using movaps / movapd. // Upper bits are disregarded. -def FsMOVAPSrr : I<0x28, MRMSrcReg, (ops FR32:$dst, FR32:$src), - "movaps {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, TB; -def FsMOVAPDrr : I<0x28, MRMSrcReg, (ops FR64:$dst, FR64:$src), - "movapd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE2]>, TB, OpSize; +def FsMOVAPSrr : PSI<0x28, MRMSrcReg, (ops FR32:$dst, FR32:$src), + "movaps {$src, $dst|$dst, $src}", []>; +def FsMOVAPDrr : PDI<0x28, MRMSrcReg, (ops FR64:$dst, FR64:$src), + "movapd {$src, $dst|$dst, $src}", []>; // Alias instructions to load FR32 / FR64 from f128mem using movaps / movapd. // Upper bits are disregarded. -def FsMOVAPSrm : I<0x28, MRMSrcMem, (ops FR32:$dst, f128mem:$src), +def FsMOVAPSrm : PSI<0x28, MRMSrcMem, (ops FR32:$dst, f128mem:$src), "movaps {$src, $dst|$dst, $src}", - [(set FR32:$dst, (X86loadpf32 addr:$src))]>, - Requires<[HasSSE1]>, TB; -def FsMOVAPDrm : I<0x28, MRMSrcMem, (ops FR64:$dst, f128mem:$src), + [(set FR32:$dst, (X86loadpf32 addr:$src))]>; +def FsMOVAPDrm : PDI<0x28, MRMSrcMem, (ops FR64:$dst, f128mem:$src), "movapd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (X86loadpf64 addr:$src))]>, - Requires<[HasSSE2]>, TB, OpSize; + [(set FR64:$dst, (X86loadpf64 addr:$src))]>; // Alias bitwise logical operations using SSE logical ops on packed FP values. let isTwoAddress = 1 in { let isCommutable = 1 in { -def FsANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), +def FsANDPSrr : PSI<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), "andps {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fand FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, TB; -def FsANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + [(set FR32:$dst, (X86fand FR32:$src1, FR32:$src2))]>; +def FsANDPDrr : PDI<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), "andpd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fand FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; -def FsORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "orps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def FsORPDrr : I<0x56, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "orpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def FsXORPSrr : I<0x57, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + [(set FR64:$dst, (X86fand FR64:$src1, FR64:$src2))]>; +def FsORPSrr : PSI<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "orps {$src2, $dst|$dst, $src2}", []>; +def FsORPDrr : PDI<0x56, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>; +def FsXORPSrr : PSI<0x57, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), "xorps {$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fxor FR32:$src1, FR32:$src2))]>, - Requires<[HasSSE1]>, TB; -def FsXORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + [(set FR32:$dst, (X86fxor FR32:$src1, FR32:$src2))]>; +def FsXORPDrr : PDI<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), "xorpd {$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fxor FR64:$src1, FR64:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; + [(set FR64:$dst, (X86fxor FR64:$src1, FR64:$src2))]>; } -def FsANDPSrm : I<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), +def FsANDPSrm : PSI<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), "andps {$src2, $dst|$dst, $src2}", [(set FR32:$dst, (X86fand FR32:$src1, - (X86loadpf32 addr:$src2)))]>, - Requires<[HasSSE1]>, TB; -def FsANDPDrm : I<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + (X86loadpf32 addr:$src2)))]>; +def FsANDPDrm : PDI<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), "andpd {$src2, $dst|$dst, $src2}", [(set FR64:$dst, (X86fand FR64:$src1, - (X86loadpf64 addr:$src2)))]>, - Requires<[HasSSE2]>, TB, OpSize; -def FsORPSrm : I<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), - "orps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def FsORPDrm : I<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), - "orpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def FsXORPSrm : I<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + (X86loadpf64 addr:$src2)))]>; +def FsORPSrm : PSI<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + "orps {$src2, $dst|$dst, $src2}", []>; +def FsORPDrm : PDI<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>; +def FsXORPSrm : PSI<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), "xorps {$src2, $dst|$dst, $src2}", [(set FR32:$dst, (X86fxor FR32:$src1, - (X86loadpf32 addr:$src2)))]>, - Requires<[HasSSE1]>, TB; -def FsXORPDrm : I<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + (X86loadpf32 addr:$src2)))]>; +def FsXORPDrm : PDI<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), "xorpd {$src2, $dst|$dst, $src2}", [(set FR64:$dst, (X86fxor FR64:$src1, - (X86loadpf64 addr:$src2)))]>, - Requires<[HasSSE2]>, TB, OpSize; + (X86loadpf64 addr:$src2)))]>; -def FsANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "andnps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def FsANDNPSrm : I<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), - "andnps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def FsANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "andnpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def FsANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), - "andnpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; +def FsANDNPSrr : PSI<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>; +def FsANDNPSrm : PSI<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>; +def FsANDNPDrr : PDI<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>; +def FsANDNPDrm : PDI<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>; } //===----------------------------------------------------------------------===// @@ -344,114 +321,350 @@ //===----------------------------------------------------------------------===// // Move Instructions -def MOVAPSrr : I<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), - "movaps {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, TB; -def MOVAPDrr : I<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), - "movapd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE2]>, TB, OpSize; +def MOVAPSrr : PSI<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), + "movaps {$src, $dst|$dst, $src}", []>; +def MOVAPSrm : PSI<0x28, MRMSrcMem, (ops V4F32:$dst, f128mem:$src), + "movaps {$src, $dst|$dst, $src}", + [(set V4F32:$dst, (X86loadv4f32 addr:$src))]>; +def MOVAPDrr : PDI<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), + "movapd {$src, $dst|$dst, $src}", []>; +def MOVAPDrm : PDI<0x28, MRMSrcMem, (ops V2F64:$dst, f128mem:$src), + "movapd {$src, $dst|$dst, $src}", + [(set V2F64:$dst, (X86loadv2f64 addr:$src))]>; -def MOVAPSrm : I<0x28, MRMSrcMem, (ops V4F32:$dst, f128mem:$src), - "movaps {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, TB; -def MOVAPSmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V4F32:$src), - "movaps {$src, $dst|$dst, $src}",[]>, - Requires<[HasSSE1]>, TB; -def MOVAPDrm : I<0x28, MRMSrcMem, (ops V2F64:$dst, f128mem:$src), - "movapd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, TB, OpSize; -def MOVAPDmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V2F64:$src), - "movapd {$src, $dst|$dst, $src}",[]>, - Requires<[HasSSE2]>, TB, OpSize; +def MOVAPSmr : PSI<0x29, MRMDestMem, (ops f128mem:$dst, V4F32:$src), + "movaps {$src, $dst|$dst, $src}", + [(store V4F32:$src, addr:$dst)]>; +def MOVAPDmr : PDI<0x29, MRMDestMem, (ops f128mem:$dst, V2F64:$src), + "movapd {$src, $dst|$dst, $src}", + [(store V2F64:$src, addr:$dst)]>; + +def MOVUPSrr : PSI<0x10, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), + "movups {$src, $dst|$dst, $src}", []>; +def MOVUPSrm : PSI<0x10, MRMSrcMem, (ops V4F32:$dst, f128mem:$src), + "movups {$src, $dst|$dst, $src}", []>; +def MOVUPSmr : PSI<0x11, MRMDestMem, (ops f128mem:$dst, V4F32:$src), + "movups {$src, $dst|$dst, $src}", []>; +def MOVUPDrr : PDI<0x10, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), + "movupd {$src, $dst|$dst, $src}", []>; +def MOVUPDrm : PDI<0x10, MRMSrcMem, (ops V2F64:$dst, f128mem:$src), + "movupd {$src, $dst|$dst, $src}", []>; +def MOVUPDmr : PDI<0x11, MRMDestMem, (ops f128mem:$dst, V2F64:$src), + "movupd {$src, $dst|$dst, $src}", []>; + +def MOVLPSrm : PSI<0x12, MRMSrcMem, (ops V4F32:$dst, f64mem:$src), + "movlps {$src, $dst|$dst, $src}", []>; +def MOVLPSmr : PSI<0x13, MRMDestMem, (ops f64mem:$dst, V4F32:$src), + "movlps {$src, $dst|$dst, $src}", []>; +def MOVLPDrm : PDI<0x12, MRMSrcMem, (ops V2F64:$dst, f64mem:$src), + "movlpd {$src, $dst|$dst, $src}", []>; +def MOVLPDmr : PDI<0x13, MRMDestMem, (ops f64mem:$dst, V2F64:$src), + "movlpd {$src, $dst|$dst, $src}", []>; + +def MOVHPSrm : PSI<0x16, MRMSrcMem, (ops V4F32:$dst, f64mem:$src), + "movhps {$src, $dst|$dst, $src}", []>; +def MOVHPSmr : PSI<0x17, MRMDestMem, (ops f64mem:$dst, V4F32:$src), + "movhps {$src, $dst|$dst, $src}", []>; +def MOVHPDrm : PDI<0x16, MRMSrcMem, (ops V2F64:$dst, f64mem:$src), + "movhpd {$src, $dst|$dst, $src}", []>; +def MOVHPDmr : PDI<0x17, MRMDestMem, (ops f64mem:$dst, V2F64:$src), + "movhpd {$src, $dst|$dst, $src}", []>; + +def MOVLHPSrr : PSI<0x16, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), + "movlhps {$src, $dst|$dst, $src}", []>; +def MOVHLPSrr : PSI<0x12, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), + "movlhps {$src, $dst|$dst, $src}", []>; + +def MOVMSKPSrr : PSI<0x50, MRMSrcReg, (ops R32:$dst, V4F32:$src), + "movmskps {$src, $dst|$dst, $src}", []>; +def MOVMSKPDrr : PSI<0x50, MRMSrcReg, (ops R32:$dst, V2F64:$src), + "movmskpd {$src, $dst|$dst, $src}", []>; + +// Conversion instructions +def CVTPI2PSrr : PSI<0x2A, MRMSrcReg, (ops V4F32:$dst, V2I32:$src), + "cvtpi2ps {$src, $dst|$dst, $src}", []>; +def CVTPI2PSrm : PSI<0x2A, MRMSrcMem, (ops V4F32:$dst, i64mem:$src), + "cvtpi2ps {$src, $dst|$dst, $src}", []>; +def CVTPI2PDrr : PDI<0x2A, MRMSrcReg, (ops V2F64:$dst, V2I32:$src), + "cvtpi2pd {$src, $dst|$dst, $src}", []>; +def CVTPI2PDrm : PDI<0x2A, MRMSrcMem, (ops V2F64:$dst, i64mem:$src), + "cvtpi2pd {$src, $dst|$dst, $src}", []>; + +// SSE2 instructions without OpSize prefix +def CVTDQ2PSrr : I<0x5B, MRMSrcReg, (ops V4F32:$dst, V4I32:$src), + "cvtdq2ps {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasSSE2]>; +def CVTDQ2PSrm : I<0x5B, MRMSrcMem, (ops V4F32:$dst, i128mem:$src), + "cvtdq2ps {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasSSE2]>; + +// SSE2 instructions with XS prefix +def CVTDQ2PDrr : I<0xE6, MRMSrcReg, (ops V2F64:$dst, V2I32:$src), + "cvtdq2pd {$src, $dst|$dst, $src}", []>, + XS, Requires<[HasSSE2]>; +def CVTDQ2PDrm : I<0xE6, MRMSrcMem, (ops V4F32:$dst, i64mem:$src), + "cvtdq2pd {$src, $dst|$dst, $src}", []>, + XS, Requires<[HasSSE2]>; + +def CVTPS2PIrr : PSI<0x2D, MRMSrcReg, (ops V2I32:$dst, V4F32:$src), + "cvtps2pi {$src, $dst|$dst, $src}", []>; +def CVTPS2PIrm : PSI<0x2D, MRMSrcMem, (ops V2I32:$dst, f64mem:$src), + "cvtps2pi {$src, $dst|$dst, $src}", []>; +def CVTPD2PIrr : PDI<0x2D, MRMSrcReg, (ops V2I32:$dst, V2F64:$src), + "cvtpd2pi {$src, $dst|$dst, $src}", []>; +def CVTPD2PIrm : PDI<0x2D, MRMSrcMem, (ops V2I32:$dst, f128mem:$src), + "cvtpd2pi {$src, $dst|$dst, $src}", []>; + +def CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (ops V4I32:$dst, V4F32:$src), + "cvtps2dq {$src, $dst|$dst, $src}", []>; +def CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (ops V4I32:$dst, f128mem:$src), + "cvtps2dq {$src, $dst|$dst, $src}", []>; +// SSE2 packed instructions with XD prefix +def CVTPD2DQrr : SDI<0xE6, MRMSrcReg, (ops V4I32:$dst, V2F64:$src), + "cvtpd2dq {$src, $dst|$dst, $src}", []>; +def CVTPD2DQrm : SDI<0xE6, MRMSrcMem, (ops V4I32:$dst, f128mem:$src), + "cvtpd2dq {$src, $dst|$dst, $src}", []>; + +// SSE2 instructions without OpSize prefix +def CVTPS2PDrr : I<0x5A, MRMSrcReg, (ops V4I32:$dst, V2F64:$src), + "cvtps2pd {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasSSE2]>; +def CVTPS2PDrm : I<0x5A, MRMSrcReg, (ops V4I32:$dst, f64mem:$src), + "cvtps2pd {$src, $dst|$dst, $src}", []>, TB, + Requires<[HasSSE2]>; + +def CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (ops V4F32:$dst, V2F64:$src), + "cvtpd2ps {$src, $dst|$dst, $src}", []>; +def CVTPD2PSrm : PDI<0x5A, MRMSrcReg, (ops V4F32:$dst, f128mem:$src), + "cvtpd2ps {$src, $dst|$dst, $src}", []>; + +// Arithmetic +let isTwoAddress = 1 in { +let isCommutable = 1 in { +def ADDPSrr : PSI<0x58, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "addps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (fadd V4F32:$src1, V4F32:$src2))]>; +def ADDPDrr : PDI<0x58, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "addpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (fadd V2F64:$src1, V2F64:$src2))]>; +def MULPSrr : PSI<0x59, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "mulps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (fmul V4F32:$src1, V4F32:$src2))]>; +def MULPDrr : PDI<0x59, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "mulpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (fmul V2F64:$src1, V2F64:$src2))]>; +} + +def ADDPSrm : PSI<0x58, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "addps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (fadd V4F32:$src1, + (X86loadv4f32 addr:$src2)))]>; +def ADDPDrm : PDI<0x58, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "addpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (fadd V2F64:$src1, + (X86loadv2f64 addr:$src2)))]>; +def MULPSrm : PSI<0x59, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "mulps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (fmul V4F32:$src1, + (X86loadv4f32 addr:$src2)))]>; +def MULPDrm : PDI<0x59, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "mulpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (fmul V2F64:$src1, + (X86loadv2f64 addr:$src2)))]>; + +def DIVPSrr : PSI<0x5E, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "divps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (fdiv V4F32:$src1, V4F32:$src2))]>; +def DIVPSrm : PSI<0x5E, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "divps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (fdiv V4F32:$src1, + (X86loadv4f32 addr:$src2)))]>; +def DIVPDrr : PDI<0x5E, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "divpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (fdiv V2F64:$src1, V2F64:$src2))]>; +def DIVPDrm : PDI<0x5E, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "divpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (fdiv V2F64:$src1, + (X86loadv2f64 addr:$src2)))]>; + +def SUBPSrr : PSI<0x5C, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "subps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (fsub V4F32:$src1, V4F32:$src2))]>; +def SUBPSrm : PSI<0x5C, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "subps {$src2, $dst|$dst, $src2}", + [(set V4F32:$dst, (fsub V4F32:$src1, + (X86loadv4f32 addr:$src2)))]>; +def SUBPDrr : PDI<0x5C, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "subpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (fsub V2F64:$src1, V2F64:$src2))]>; +def SUBPDrm : PDI<0x5C, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "subpd {$src2, $dst|$dst, $src2}", + [(set V2F64:$dst, (fsub V2F64:$src1, + (X86loadv2f64 addr:$src2)))]>; +} + +def SQRTPSrr : PSI<0x51, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), + "sqrtps {$src, $dst|$dst, $src}", + [(set V4F32:$dst, (fsqrt V4F32:$src))]>; +def SQRTPSrm : PSI<0x51, MRMSrcMem, (ops V4F32:$dst, f128mem:$src), + "sqrtps {$src, $dst|$dst, $src}", + [(set V4F32:$dst, (fsqrt (X86loadv4f32 addr:$src)))]>; +def SQRTPDrr : PDI<0x51, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), + "sqrtpd {$src, $dst|$dst, $src}", + [(set V2F64:$dst, (fsqrt V2F64:$src))]>; +def SQRTPDrm : PDI<0x51, MRMSrcMem, (ops V2F64:$dst, f128mem:$src), + "sqrtpd {$src, $dst|$dst, $src}", + [(set V2F64:$dst, (fsqrt (X86loadv2f64 addr:$src)))]>; + +def RSQRTPSrr : PSI<0x52, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), + "rsqrtps {$src, $dst|$dst, $src}", []>; +def RSQRTPSrm : PSI<0x52, MRMSrcMem, (ops V4F32:$dst, f128mem:$src), + "rsqrtps {$src, $dst|$dst, $src}", []>; +def RCPPSrr : PSI<0x53, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), + "rcpps {$src, $dst|$dst, $src}", []>; +def RCPPSrm : PSI<0x53, MRMSrcMem, (ops V4F32:$dst, f128mem:$src), + "rcpps {$src, $dst|$dst, $src}", []>; + +def MAXPSrr : PSI<0x5F, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), + "maxps {$src, $dst|$dst, $src}", []>; +def MAXPSrm : PSI<0x5F, MRMSrcMem, (ops V4F32:$dst, f128mem:$src), + "maxps {$src, $dst|$dst, $src}", []>; +def MAXPDrr : PDI<0x5F, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), + "maxpd {$src, $dst|$dst, $src}", []>; +def MAXPDrm : PDI<0x5F, MRMSrcMem, (ops V2F64:$dst, f128mem:$src), + "maxpd {$src, $dst|$dst, $src}", []>; +def MINPSrr : PSI<0x5D, MRMSrcReg, (ops V4F32:$dst, V4F32:$src), + "minps {$src, $dst|$dst, $src}", []>; +def MINPSrm : PSI<0x5D, MRMSrcMem, (ops V4F32:$dst, f128mem:$src), + "minps {$src, $dst|$dst, $src}", []>; +def MINPDrr : PDI<0x5D, MRMSrcReg, (ops V2F64:$dst, V2F64:$src), + "minpd {$src, $dst|$dst, $src}", []>; +def MINPDrm : PDI<0x5D, MRMSrcMem, (ops V2F64:$dst, f128mem:$src), + "minpd {$src, $dst|$dst, $src}", []>; // Logical let isTwoAddress = 1 in { let isCommutable = 1 in { -def ANDPSrr : I<0x54, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), +def ANDPSrr : PSI<0x54, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), "andps {$src2, $dst|$dst, $src2}", - [(set V4F32:$dst, (X86fand V4F32:$src1, V4F32:$src2))]>, - Requires<[HasSSE1]>, TB; -def ANDPDrr : I<0x54, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + [(set V4F32:$dst, (X86fand V4F32:$src1, V4F32:$src2))]>; +def ANDPDrr : PDI<0x54, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), "andpd {$src2, $dst|$dst, $src2}", - [(set V2F64:$dst, (X86fand V2F64:$src1, V2F64:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; -def ORPSrr : I<0x56, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), - "orps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ORPDrr : I<0x56, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), - "orpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def XORPSrr : I<0x57, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + [(set V2F64:$dst, (X86fand V2F64:$src1, V2F64:$src2))]>; +def ORPSrr : PSI<0x56, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "orps {$src2, $dst|$dst, $src2}", []>; +def ORPDrr : PDI<0x56, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>; +def XORPSrr : PSI<0x57, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), "xorps {$src2, $dst|$dst, $src2}", - [(set V4F32:$dst, (X86fxor V4F32:$src1, V4F32:$src2))]>, - Requires<[HasSSE1]>, TB; -def XORPDrr : I<0x57, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + [(set V4F32:$dst, (X86fxor V4F32:$src1, V4F32:$src2))]>; +def XORPDrr : PDI<0x57, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), "xorpd {$src2, $dst|$dst, $src2}", - [(set V2F64:$dst, (X86fxor V2F64:$src1, V2F64:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; + [(set V2F64:$dst, (X86fxor V2F64:$src1, V2F64:$src2))]>; } -def ANDPSrm : I<0x54, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), +def ANDPSrm : PSI<0x54, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), "andps {$src2, $dst|$dst, $src2}", [(set V4F32:$dst, (X86fand V4F32:$src1, - (X86loadpv4f32 addr:$src2)))]>, - Requires<[HasSSE1]>, TB; -def ANDPDrm : I<0x54, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + (X86loadv4f32 addr:$src2)))]>; +def ANDPDrm : PDI<0x54, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), "andpd {$src2, $dst|$dst, $src2}", [(set V2F64:$dst, (X86fand V2F64:$src1, - (X86loadpv2f64 addr:$src2)))]>, - Requires<[HasSSE2]>, TB, OpSize; -def ORPSrm : I<0x56, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), - "orps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ORPDrm : I<0x56, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), - "orpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def XORPSrm : I<0x57, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + (X86loadv2f64 addr:$src2)))]>; +def ORPSrm : PSI<0x56, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "orps {$src2, $dst|$dst, $src2}", []>; +def ORPDrm : PDI<0x56, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>; +def XORPSrm : PSI<0x57, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), "xorps {$src2, $dst|$dst, $src2}", [(set V4F32:$dst, (X86fxor V4F32:$src1, - (X86loadpv4f32 addr:$src2)))]>, - Requires<[HasSSE1]>, TB; -def XORPDrm : I<0x57, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + (X86loadv4f32 addr:$src2)))]>; +def XORPDrm : PDI<0x57, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), "xorpd {$src2, $dst|$dst, $src2}", [(set V2F64:$dst, (X86fxor V2F64:$src1, - (X86loadpv2f64 addr:$src2)))]>, - Requires<[HasSSE2]>, TB, OpSize; + (X86loadv2f64 addr:$src2)))]>; +def ANDNPSrr : PSI<0x55, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>; +def ANDNPSrm : PSI<0x55, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>; +def ANDNPDrr : PDI<0x55, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>; +def ANDNPDrm : PDI<0x55, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>; +} -def ANDNPSrr : I<0x55, MRMSrcReg, (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), - "andnps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ANDNPSrm : I<0x55, MRMSrcMem, (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), - "andnps {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE1]>, TB; -def ANDNPDrr : I<0x55, MRMSrcReg, (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), - "andnpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def ANDNPDrm : I<0x55, MRMSrcMem, (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), - "andnpd {$src2, $dst|$dst, $src2}", []>, - Requires<[HasSSE2]>, TB, OpSize; +let isTwoAddress = 1 in { +def CMPPSrr : PSI<0xC2, MRMSrcReg, + (ops V4F32:$dst, V4F32:$src1, V4F32:$src, SSECC:$cc), + "cmp${cc}ps {$src, $dst|$dst, $src}", []>; +def CMPPSrm : PSI<0xC2, MRMSrcMem, + (ops V4F32:$dst, V4F32:$src1, f128mem:$src, SSECC:$cc), + "cmp${cc}ps {$src, $dst|$dst, $src}", []>; +def CMPPDrr : PDI<0xC2, MRMSrcReg, + (ops V2F64:$dst, V2F64:$src1, V2F64:$src, SSECC:$cc), + "cmp${cc}pd {$src, $dst|$dst, $src}", []>; +def CMPPDrm : PDI<0xC2, MRMSrcMem, + (ops V2F64:$dst, V2F64:$src1, f128mem:$src, SSECC:$cc), + "cmp${cc}pd {$src, $dst|$dst, $src}", []>; } +// Shuffle and unpack instructions +def SHUFPSrr : PSI<0xC6, MRMSrcReg, + (ops V4F32:$dst, V4F32:$src1, V4F32:$src2, i8imm:$src3), + "shufps {$src3, $src2, $dst|$dst, $src2, $src3}", []>; +def SHUFPSrm : PSI<0xC6, MRMSrcMem, + (ops V4F32:$dst, V4F32:$src1, f128mem:$src2, i8imm:$src3), + "shufps {$src3, $src2, $dst|$dst, $src2, $src3}", []>; +def SHUFPDrr : PDI<0xC6, MRMSrcReg, + (ops V2F64:$dst, V2F64:$src1, V2F64:$src2, i8imm:$src3), + "shufpd {$src3, $src2, $dst|$dst, $src2, $src3}", []>; +def SHUFPDrm : PDI<0xC6, MRMSrcMem, + (ops V2F64:$dst, V2F64:$src1, f128mem:$src2, i8imm:$src3), + "shufpd {$src3, $src2, $dst|$dst, $src2, $src3}", []>; + +def UNPCKHPSrr : PSI<0x15, MRMSrcReg, + (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "unpckhps {$src2, $dst|$dst, $src2}", []>; +def UNPCKHPSrm : PSI<0x15, MRMSrcMem, + (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "unpckhps {$src2, $dst|$dst, $src2}", []>; +def UNPCKHPDrr : PDI<0x15, MRMSrcReg, + (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "unpckhpd {$src2, $dst|$dst, $src2}", []>; +def UNPCKHPDrm : PDI<0x15, MRMSrcMem, + (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "unpckhpd {$src2, $dst|$dst, $src2}", []>; +def UNPCKLPSrr : PSI<0x14, MRMSrcReg, + (ops V4F32:$dst, V4F32:$src1, V4F32:$src2), + "unpcklps {$src2, $dst|$dst, $src2}", []>; +def UNPCKLPSrm : PSI<0x14, MRMSrcMem, + (ops V4F32:$dst, V4F32:$src1, f128mem:$src2), + "unpcklps {$src2, $dst|$dst, $src2}", []>; +def UNPCKLPDrr : PDI<0x14, MRMSrcReg, + (ops V2F64:$dst, V2F64:$src1, V2F64:$src2), + "unpcklpd {$src2, $dst|$dst, $src2}", []>; +def UNPCKLPDrm : PDI<0x14, MRMSrcMem, + (ops V2F64:$dst, V2F64:$src1, f128mem:$src2), + "unpcklpd {$src2, $dst|$dst, $src2}", []>; + //===----------------------------------------------------------------------===// // SSE integer instructions //===----------------------------------------------------------------------===// // Move Instructions -def MOVD128rr : I<0x6E, MRMSrcReg, (ops VR128:$dst, R32:$src), - "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, - Requires<[HasSSE2]>; -def MOVD128rm : I<0x6E, MRMSrcMem, (ops VR128:$dst, i32mem:$src), - "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, - Requires<[HasSSE2]>; -def MOVD128mr : I<0x7E, MRMDestMem, (ops i32mem:$dst, VR128:$src), - "movd {$src, $dst|$dst, $src}", []>, TB, OpSize, - Requires<[HasSSE2]>; +def MOVD128rr : PDI<0x6E, MRMSrcReg, (ops VR128:$dst, R32:$src), + "movd {$src, $dst|$dst, $src}", []>; +def MOVD128rm : PDI<0x6E, MRMSrcMem, (ops VR128:$dst, i32mem:$src), + "movd {$src, $dst|$dst, $src}", []>; +def MOVD128mr : PDI<0x7E, MRMDestMem, (ops i32mem:$dst, VR128:$src), + "movd {$src, $dst|$dst, $src}", []>; +// SSE2 instructions with XS prefix def MOVQ128rr : I<0x7E, MRMSrcReg, (ops VR128:$dst, VR64:$src), "movq {$src, $dst|$dst, $src}", []>, XS, Requires<[HasSSE2]>; def MOVQ128rm : I<0x7E, MRMSrcMem, (ops VR128:$dst, i64mem:$src), "movq {$src, $dst|$dst, $src}", []>, XS, Requires<[HasSSE2]>; -def MOVQ128mr : I<0xD6, MRMSrcMem, (ops i64mem:$dst, VR128:$src), - "movq {$src, $dst|$dst, $src}", []>, TB, OpSize, - Requires<[HasSSE2]>; + +def MOVQ128mr : PDI<0xD6, MRMSrcMem, (ops i64mem:$dst, VR128:$src), + "movq {$src, $dst|$dst, $src}", []>; Index: llvm/lib/Target/X86/X86IntelAsmPrinter.h diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.h:1.8 llvm/lib/Target/X86/X86IntelAsmPrinter.h:1.9 --- llvm/lib/Target/X86/X86IntelAsmPrinter.h:1.8 Fri Feb 17 18:15:05 2006 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.h Tue Feb 21 20:26:30 2006 @@ -65,6 +65,10 @@ O << "QWORD PTR "; printMemReference(MI, OpNo); } + void printi128mem(const MachineInstr *MI, unsigned OpNo) { + O << "XMMWORD PTR "; + printMemReference(MI, OpNo); + } void printf32mem(const MachineInstr *MI, unsigned OpNo) { O << "DWORD PTR "; printMemReference(MI, OpNo); From lattner at cs.uiuc.edu Wed Feb 22 00:37:26 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 00:37:26 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopUnswitch.cpp Message-ID: <200602220637.AAA21286@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopUnswitch.cpp updated: 1.33 -> 1.34 --- Log message: Add some comments, simplify some code, and fix a bug that caused rewriting to rewrite with the wrong value. --- Diffs of the changes: (+26 -34) LoopUnswitch.cpp | 60 +++++++++++++++++++++++-------------------------------- 1 files changed, 26 insertions(+), 34 deletions(-) Index: llvm/lib/Transforms/Scalar/LoopUnswitch.cpp diff -u llvm/lib/Transforms/Scalar/LoopUnswitch.cpp:1.33 llvm/lib/Transforms/Scalar/LoopUnswitch.cpp:1.34 --- llvm/lib/Transforms/Scalar/LoopUnswitch.cpp:1.33 Sat Feb 18 01:57:38 2006 +++ llvm/lib/Transforms/Scalar/LoopUnswitch.cpp Wed Feb 22 00:37:14 2006 @@ -88,7 +88,7 @@ bool UnswitchIfProfitable(Value *LoopCond, Constant *Val,Loop *L); unsigned getLoopUnswitchCost(Loop *L, Value *LIC); void UnswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val, - bool EntersWhenTrue, BasicBlock *ExitBlock); + BasicBlock *ExitBlock); void UnswitchNontrivialCondition(Value *LIC, Constant *OnVal, Loop *L); BasicBlock *SplitEdge(BasicBlock *From, BasicBlock *To); BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt); @@ -282,16 +282,17 @@ /// code duplications (equivalently, it produces a simpler loop and a new empty /// loop, which gets deleted). /// -/// If this is a trivial condition, return ConstantBool::True if the loop body -/// runs when the condition is true, False if the loop body executes when the -/// condition is false. Otherwise, return null to indicate a complex condition. -static bool IsTrivialUnswitchCondition(Loop *L, Value *Cond, - Constant **Val = 0, - bool *EntersWhenTrue = 0, +/// If this is a trivial condition, return true, otherwise return false. When +/// returning true, this sets Cond and Val to the condition that controls the +/// trivial condition: when Cond dynamically equals Val, the loop is known to +/// exit. Finally, this sets LoopExit to the BB that the loop exits to when +/// Cond == Val. +/// +static bool IsTrivialUnswitchCondition(Loop *L, Value *Cond, Constant **Val = 0, BasicBlock **LoopExit = 0) { BasicBlock *Header = L->getHeader(); TerminatorInst *HeaderTerm = Header->getTerminator(); - + BasicBlock *LoopExitBB = 0; if (BranchInst *BI = dyn_cast(HeaderTerm)) { // If the header block doesn't end with a conditional branch on Cond, we @@ -304,9 +305,9 @@ // side-effects. If so, determine the value of Cond that causes it to do // this. if ((LoopExitBB = isTrivialLoopExitBlock(L, BI->getSuccessor(0)))) { - if (Val) *Val = ConstantBool::False; - } else if ((LoopExitBB = isTrivialLoopExitBlock(L, BI->getSuccessor(1)))) { if (Val) *Val = ConstantBool::True; + } else if ((LoopExitBB = isTrivialLoopExitBlock(L, BI->getSuccessor(1)))) { + if (Val) *Val = ConstantBool::False; } } else if (SwitchInst *SI = dyn_cast(HeaderTerm)) { // If this isn't a switch on Cond, we can't handle it. @@ -320,7 +321,6 @@ if ((LoopExitBB = isTrivialLoopExitBlock(L, SI->getSuccessor(i)))) { // Okay, we found a trivial case, remember the value that is trivial. if (Val) *Val = SI->getCaseValue(i); - if (EntersWhenTrue) *EntersWhenTrue = false; break; } } @@ -395,11 +395,9 @@ // If this is a trivial condition to unswitch (which results in no code // duplication), do it now. Constant *CondVal; - bool EntersWhenTrue = true; BasicBlock *ExitBlock; - if (IsTrivialUnswitchCondition(L, LoopCond, &CondVal, - &EntersWhenTrue, &ExitBlock)) { - UnswitchTrivialCondition(L, LoopCond, CondVal, EntersWhenTrue, ExitBlock); + if (IsTrivialUnswitchCondition(L, LoopCond, &CondVal, &ExitBlock)) { + UnswitchTrivialCondition(L, LoopCond, CondVal, ExitBlock); } else { UnswitchNontrivialCondition(LoopCond, Val, L); } @@ -525,13 +523,12 @@ /// side-effects), unswitch it. This doesn't involve any code duplication, just /// moving the conditional branch outside of the loop and updating loop info. void LoopUnswitch::UnswitchTrivialCondition(Loop *L, Value *Cond, - Constant *Val, bool EntersWhenTrue, + Constant *Val, BasicBlock *ExitBlock) { DEBUG(std::cerr << "loop-unswitch: Trivial-Unswitch loop %" << L->getHeader()->getName() << " [" << L->getBlocks().size() << " blocks] in Function " << L->getHeader()->getParent()->getName() - << " on cond: " << *Val << (EntersWhenTrue ? " == " : " != ") << - *Cond << "\n"); + << " on cond: " << *Val << " == " << *Cond << "\n"); // First step, split the preheader, so that we know that there is a safe place // to insert the conditional branch. We will change 'OrigPH' to have a @@ -552,12 +549,8 @@ // Okay, now we have a position to branch from and a position to branch to, // insert the new conditional branch. - { - BasicBlock *TrueDest = NewPH, *FalseDest = NewExit; - if (!EntersWhenTrue) std::swap(TrueDest, FalseDest); - EmitPreheaderBranchOnCondition(Cond, Val, TrueDest, FalseDest, - OrigPH->getTerminator()); - } + EmitPreheaderBranchOnCondition(Cond, Val, NewExit, NewPH, + OrigPH->getTerminator()); OrigPH->getTerminator()->eraseFromParent(); // We need to reprocess this loop, it could be unswitched again. @@ -566,7 +559,7 @@ // Now that we know that the loop is never entered when this condition is a // particular value, rewrite the loop with this info. We know that this will // at least eliminate the old branch. - RewriteLoopBodyWithConditionConstant(L, Cond, Val, EntersWhenTrue); + RewriteLoopBodyWithConditionConstant(L, Cond, Val, false); ++NumTrivial; } @@ -912,11 +905,6 @@ // ... // if (li1 > li2) // ... - - // NotVal - If Val is a bool, this contains its inverse. - Constant *NotVal = 0; - if (ConstantBool *CB = dyn_cast(Val)) - NotVal = ConstantBool::get(!CB->getValue()); // FOLD boolean conditions (X|LIC), (X&LIC). Fold conditional branches, // selects, switches. @@ -925,8 +913,12 @@ // If we know that LIC == Val, or that LIC == NotVal, just replace uses of LIC // in the loop with the appropriate one directly. - if (IsEqual || NotVal) { - Value *Replacement = NotVal ? NotVal : Val; + if (IsEqual || isa(Val)) { + Value *Replacement; + if (IsEqual) + Replacement = Val; + else + Replacement = ConstantBool::get(!cast(Val)->getValue()); for (unsigned i = 0, e = Users.size(); i != e; ++i) if (Instruction *U = cast(Users[i])) { @@ -978,7 +970,6 @@ /// pass. /// void LoopUnswitch::SimplifyCode(std::vector &Worklist) { - Worklist.back()->getParent()->getParent()->viewCFG(); while (!Worklist.empty()) { Instruction *I = Worklist.back(); Worklist.pop_back(); @@ -1066,9 +1057,10 @@ Succ->eraseFromParent(); ++NumSimplify; } else if (ConstantBool *CB = dyn_cast(BI->getCondition())){ - break; // FIXME: Enable. // Conditional branch. Turn it into an unconditional branch, then // remove dead blocks. + break; // FIXME: Enable. + DEBUG(std::cerr << "Folded branch: " << *BI); BasicBlock *DeadSucc = BI->getSuccessor(CB->getValue()); BasicBlock *LiveSucc = BI->getSuccessor(!CB->getValue()); From lattner at cs.uiuc.edu Wed Feb 22 01:34:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 01:34:01 -0600 Subject: [llvm-commits] CVS: llvm/tools/gccas/gccas.cpp Message-ID: <200602220734.BAA21606@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccas: gccas.cpp updated: 1.114 -> 1.115 --- Log message: Turn on loop unswitching tonight --- Diffs of the changes: (+1 -0) gccas.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/tools/gccas/gccas.cpp diff -u llvm/tools/gccas/gccas.cpp:1.114 llvm/tools/gccas/gccas.cpp:1.115 --- llvm/tools/gccas/gccas.cpp:1.114 Sat May 7 17:45:35 2005 +++ llvm/tools/gccas/gccas.cpp Wed Feb 22 01:33:49 2006 @@ -109,6 +109,7 @@ addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs addPass(PM, createReassociatePass()); // Reassociate expressions addPass(PM, createLICMPass()); // Hoist loop invariants + addPass(PM, createLoopUnswitchPass()); // Unswitch loops. addPass(PM, createInstructionCombiningPass()); // Clean up after LICM/reassoc addPass(PM, createIndVarSimplifyPass()); // Canonicalize indvars addPass(PM, createLoopUnrollPass()); // Unroll small loops From lattner at cs.uiuc.edu Wed Feb 22 10:24:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 10:24:05 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h TargetLowering.h Message-ID: <200602221624.KAA04991@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.69 -> 1.70 TargetLowering.h updated: 1.53 -> 1.54 --- Log message: Make the LLVM headers "-ansi -pedantic -Wno-long-long" clean. Patch by Martin Partel! --- Diffs of the changes: (+5 -5) MRegisterInfo.h | 2 +- TargetLowering.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.69 llvm/include/llvm/Target/MRegisterInfo.h:1.70 --- llvm/include/llvm/Target/MRegisterInfo.h:1.69 Tue Feb 21 17:51:58 2006 +++ llvm/include/llvm/Target/MRegisterInfo.h Wed Feb 22 10:23:43 2006 @@ -169,7 +169,7 @@ /// namespace. This must be the same for all targets, which means that each /// target is limited to 1024 registers. /// - FirstVirtualRegister = 1024, + FirstVirtualRegister = 1024 }; /// isPhysicalRegister - Return true if the specified register number is in Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.53 llvm/include/llvm/Target/TargetLowering.h:1.54 --- llvm/include/llvm/Target/TargetLowering.h:1.53 Tue Feb 21 18:56:01 2006 +++ llvm/include/llvm/Target/TargetLowering.h Wed Feb 22 10:23:43 2006 @@ -56,24 +56,24 @@ Legal, // The target natively supports this operation. Promote, // This operation should be executed in a larger type. Expand, // Try to expand this to other ops, otherwise use a libcall. - Custom, // Use the LowerOperation hook to implement custom lowering. + Custom // Use the LowerOperation hook to implement custom lowering. }; enum OutOfRangeShiftAmount { Undefined, // Oversized shift amounts are undefined (default). Mask, // Shift amounts are auto masked (anded) to value size. - Extend, // Oversized shift pulls in zeros or sign bits. + Extend // Oversized shift pulls in zeros or sign bits. }; enum SetCCResultValue { UndefinedSetCCResult, // SetCC returns a garbage/unknown extend. ZeroOrOneSetCCResult, // SetCC returns a zero extended result. - ZeroOrNegativeOneSetCCResult, // SetCC returns a sign extended result. + ZeroOrNegativeOneSetCCResult // SetCC returns a sign extended result. }; enum SchedPreference { SchedulingForLatency, // Scheduling for shortest total latency. - SchedulingForRegPressure, // Scheduling for lowest register pressure. + SchedulingForRegPressure // Scheduling for lowest register pressure. }; TargetLowering(TargetMachine &TM); From lattner at cs.uiuc.edu Wed Feb 22 10:24:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 10:24:05 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/LinkAllPasses.h RSProfiling.h Message-ID: <200602221624.KAA04995@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: LinkAllPasses.h updated: 1.28 -> 1.29 RSProfiling.h updated: 1.1 -> 1.2 --- Log message: Make the LLVM headers "-ansi -pedantic -Wno-long-long" clean. Patch by Martin Partel! --- Diffs of the changes: (+2 -2) LinkAllPasses.h | 2 +- RSProfiling.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/include/llvm/Transforms/LinkAllPasses.h diff -u llvm/include/llvm/Transforms/LinkAllPasses.h:1.28 llvm/include/llvm/Transforms/LinkAllPasses.h:1.29 --- llvm/include/llvm/Transforms/LinkAllPasses.h:1.28 Sun Jan 15 19:05:24 2006 +++ llvm/include/llvm/Transforms/LinkAllPasses.h Wed Feb 22 10:23:43 2006 @@ -110,6 +110,6 @@ } } ForcePassLinking; -}; +} #endif Index: llvm/include/llvm/Transforms/RSProfiling.h diff -u llvm/include/llvm/Transforms/RSProfiling.h:1.1 llvm/include/llvm/Transforms/RSProfiling.h:1.2 --- llvm/include/llvm/Transforms/RSProfiling.h:1.1 Mon Nov 28 12:00:28 2005 +++ llvm/include/llvm/Transforms/RSProfiling.h Wed Feb 22 10:23:43 2006 @@ -27,4 +27,4 @@ /// inserted by the profiler. virtual bool isProfiling(Value* v) = 0; }; -}; +} From lattner at cs.uiuc.edu Wed Feb 22 10:24:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 10:24:05 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/System/MappedFile.h Path.h TimeValue.h Message-ID: <200602221624.KAA05005@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/System: MappedFile.h updated: 1.8 -> 1.9 Path.h updated: 1.27 -> 1.28 TimeValue.h updated: 1.13 -> 1.14 --- Log message: Make the LLVM headers "-ansi -pedantic -Wno-long-long" clean. Patch by Martin Partel! --- Diffs of the changes: (+3 -3) MappedFile.h | 2 +- Path.h | 2 +- TimeValue.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/include/llvm/System/MappedFile.h diff -u llvm/include/llvm/System/MappedFile.h:1.8 llvm/include/llvm/System/MappedFile.h:1.9 --- llvm/include/llvm/System/MappedFile.h:1.8 Thu May 5 17:31:47 2005 +++ llvm/include/llvm/System/MappedFile.h Wed Feb 22 10:23:43 2006 @@ -38,7 +38,7 @@ READ_ACCESS = 0x0001, ///< Map the file for reading WRITE_ACCESS = 0x0002, ///< Map the file for write access EXEC_ACCESS = 0x0004, ///< Map the file for execution access - SHARED_MAPPING = 0x0008, ///< Map the file shared with other processes + SHARED_MAPPING = 0x0008 ///< Map the file shared with other processes }; /// @} /// @name Constructors Index: llvm/include/llvm/System/Path.h diff -u llvm/include/llvm/System/Path.h:1.27 llvm/include/llvm/System/Path.h:1.28 --- llvm/include/llvm/System/Path.h:1.27 Wed Jul 27 00:53:43 2005 +++ llvm/include/llvm/System/Path.h Wed Feb 22 10:23:43 2006 @@ -553,7 +553,7 @@ UnknownFileType = 0, ///< Unrecognized file BytecodeFileType = 1, ///< Uncompressed bytecode file CompressedBytecodeFileType = 2, ///< Compressed bytecode file - ArchiveFileType = 3, ///< ar style archive file + ArchiveFileType = 3 ///< ar style archive file }; /// This utility function allows any memory block to be examined in order Index: llvm/include/llvm/System/TimeValue.h diff -u llvm/include/llvm/System/TimeValue.h:1.13 llvm/include/llvm/System/TimeValue.h:1.14 --- llvm/include/llvm/System/TimeValue.h:1.13 Thu May 5 17:31:47 2005 +++ llvm/include/llvm/System/TimeValue.h Wed Feb 22 10:23:43 2006 @@ -75,7 +75,7 @@ NANOSECONDS_PER_MICROSECOND = 1000, ///< One Thousand NANOSECONDS_PER_MILLISECOND = 1000000,///< One Million NANOSECONDS_PER_POSIX_TICK = 100, ///< Posix tick is 100 Hz (10ms) - NANOSECONDS_PER_WIN32_TICK = 100, ///< Win32 tick is 100 Hz (10ms) + NANOSECONDS_PER_WIN32_TICK = 100 ///< Win32 tick is 100 Hz (10ms) }; /// @} From lattner at cs.uiuc.edu Wed Feb 22 10:24:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 10:24:05 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Bytecode/Archive.h Format.h Message-ID: <200602221624.KAA04992@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Bytecode: Archive.h updated: 1.13 -> 1.14 Format.h updated: 1.12 -> 1.13 --- Log message: Make the LLVM headers "-ansi -pedantic -Wno-long-long" clean. Patch by Martin Partel! --- Diffs of the changes: (+2 -2) Archive.h | 2 +- Format.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/include/llvm/Bytecode/Archive.h diff -u llvm/include/llvm/Bytecode/Archive.h:1.13 llvm/include/llvm/Bytecode/Archive.h:1.14 --- llvm/include/llvm/Bytecode/Archive.h:1.13 Tue Nov 29 23:26:03 2005 +++ llvm/include/llvm/Bytecode/Archive.h Wed Feb 22 10:23:42 2006 @@ -56,7 +56,7 @@ CompressedBytecodeFlag = 32, ///< Member is compressed bytecode HasPathFlag = 64, ///< Member has a full or partial path HasLongFilenameFlag = 128, ///< Member uses the long filename syntax - StringTableFlag = 256, ///< Member is an ar(1) format string table + StringTableFlag = 256 ///< Member is an ar(1) format string table }; /// @} Index: llvm/include/llvm/Bytecode/Format.h diff -u llvm/include/llvm/Bytecode/Format.h:1.12 llvm/include/llvm/Bytecode/Format.h:1.13 --- llvm/include/llvm/Bytecode/Format.h:1.12 Thu Apr 21 15:34:13 2005 +++ llvm/include/llvm/Bytecode/Format.h Wed Feb 22 10:23:42 2006 @@ -47,7 +47,7 @@ // tables for a function, allowing the indices used within the function to // be as small as possible. This often allows the instructions to be // encoded more efficiently. - CompactionTable = 0x33, + CompactionTable = 0x33 }; /// In LLVM 1.3 format, the identifier and the size of the block are From lattner at cs.uiuc.edu Wed Feb 22 10:24:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 10:24:05 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSGraph.h DSNode.h DSSupport.h Message-ID: <200602221624.KAA04993@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSGraph.h updated: 1.109 -> 1.110 DSNode.h updated: 1.56 -> 1.57 DSSupport.h updated: 1.40 -> 1.41 --- Log message: Make the LLVM headers "-ansi -pedantic -Wno-long-long" clean. Patch by Martin Partel! --- Diffs of the changes: (+5 -5) DSGraph.h | 6 +++--- DSNode.h | 2 +- DSSupport.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) Index: llvm/include/llvm/Analysis/DataStructure/DSGraph.h diff -u llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.109 llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.110 --- llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.109 Thu Apr 21 15:18:05 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSGraph.h Wed Feb 22 10:23:42 2006 @@ -411,7 +411,7 @@ // enum MarkIncompleteFlags { MarkFormalArgs = 1, IgnoreFormalArgs = 0, - IgnoreGlobals = 2, MarkGlobalsIncomplete = 0, + IgnoreGlobals = 2, MarkGlobalsIncomplete = 0 }; void markIncompleteNodes(unsigned Flags); @@ -421,7 +421,7 @@ // graph entirely. This is only appropriate to use when inlining graphs. // enum RemoveDeadNodesFlags { - RemoveUnreachableGlobals = 1, KeepUnreachableGlobals = 0, + RemoveUnreachableGlobals = 1, KeepUnreachableGlobals = 0 }; void removeDeadNodes(unsigned Flags); @@ -432,7 +432,7 @@ DontCloneCallNodes = 1 << 1, CloneCallNodes = 0, DontCloneAuxCallNodes = 1 << 2, CloneAuxCallNodes = 0, StripModRefBits = 1 << 3, KeepModRefBits = 0, - StripIncompleteBit = 1 << 4, KeepIncompleteBit = 0, + StripIncompleteBit = 1 << 4, KeepIncompleteBit = 0 }; void updateFromGlobalGraph(); Index: llvm/include/llvm/Analysis/DataStructure/DSNode.h diff -u llvm/include/llvm/Analysis/DataStructure/DSNode.h:1.56 llvm/include/llvm/Analysis/DataStructure/DSNode.h:1.57 --- llvm/include/llvm/Analysis/DataStructure/DSNode.h:1.56 Tue Dec 6 12:16:08 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSNode.h Wed Feb 22 10:23:42 2006 @@ -95,7 +95,7 @@ DEAD = 1 << 8, // This node is dead and should not be pointed to //#endif - Composition = AllocaNode | HeapNode | GlobalNode | UnknownNode, + Composition = AllocaNode | HeapNode | GlobalNode | UnknownNode }; /// NodeType - A union of the above bits. "Shadow" nodes do not add any flags Index: llvm/include/llvm/Analysis/DataStructure/DSSupport.h diff -u llvm/include/llvm/Analysis/DataStructure/DSSupport.h:1.40 llvm/include/llvm/Analysis/DataStructure/DSSupport.h:1.41 --- llvm/include/llvm/Analysis/DataStructure/DSSupport.h:1.40 Thu Apr 21 15:18:05 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSSupport.h Wed Feb 22 10:23:42 2006 @@ -40,7 +40,7 @@ /// a pointer. /// bool isPointerType(const Type *Ty); -}; +} //===----------------------------------------------------------------------===// /// DSNodeHandle - Implement a "handle" to a data structure node that takes care From lattner at cs.uiuc.edu Wed Feb 22 10:24:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 10:24:05 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CallingConv.h Linker.h PassAnalysisSupport.h Message-ID: <200602221624.KAA04999@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: CallingConv.h updated: 1.1 -> 1.2 Linker.h updated: 1.18 -> 1.19 PassAnalysisSupport.h updated: 1.21 -> 1.22 --- Log message: Make the LLVM headers "-ansi -pedantic -Wno-long-long" clean. Patch by Martin Partel! --- Diffs of the changes: (+4 -2) CallingConv.h | 2 +- Linker.h | 2 +- PassAnalysisSupport.h | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/include/llvm/CallingConv.h diff -u llvm/include/llvm/CallingConv.h:1.1 llvm/include/llvm/CallingConv.h:1.2 --- llvm/include/llvm/CallingConv.h:1.1 Fri May 6 14:59:08 2005 +++ llvm/include/llvm/CallingConv.h Wed Feb 22 10:23:42 2006 @@ -45,7 +45,7 @@ // Target - This is the start of the target-specific calling conventions, // e.g. fastcall and thiscall on X86. - FirstTargetCC = 64, + FirstTargetCC = 64 }; } // End CallingConv namespace Index: llvm/include/llvm/Linker.h diff -u llvm/include/llvm/Linker.h:1.18 llvm/include/llvm/Linker.h:1.19 --- llvm/include/llvm/Linker.h:1.18 Mon Jan 9 21:14:40 2006 +++ llvm/include/llvm/Linker.h Wed Feb 22 10:23:42 2006 @@ -53,7 +53,7 @@ enum ControlFlags { Verbose = 1, ///< Print to std::cerr what steps the linker is taking QuietWarnings = 2, ///< Don't print errors and warnings to std::cerr. - QuietErrors = 4, ///< Indicate that this link is for a native executable + QuietErrors = 4 ///< Indicate that this link is for a native executable }; /// @} Index: llvm/include/llvm/PassAnalysisSupport.h diff -u llvm/include/llvm/PassAnalysisSupport.h:1.21 llvm/include/llvm/PassAnalysisSupport.h:1.22 --- llvm/include/llvm/PassAnalysisSupport.h:1.21 Sun Apr 24 20:01:35 2005 +++ llvm/include/llvm/PassAnalysisSupport.h Wed Feb 22 10:23:42 2006 @@ -19,6 +19,8 @@ #ifndef LLVM_PASS_ANALYSIS_SUPPORT_H #define LLVM_PASS_ANALYSIS_SUPPORT_H +#include + namespace llvm { // No need to include Pass.h, we are being included by it! From lattner at cs.uiuc.edu Wed Feb 22 10:24:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 10:24:05 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/AliasAnalysis.h LinkAllAnalyses.h Message-ID: <200602221624.KAA04997@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: AliasAnalysis.h updated: 1.22 -> 1.23 LinkAllAnalyses.h updated: 1.3 -> 1.4 --- Log message: Make the LLVM headers "-ansi -pedantic -Wno-long-long" clean. Patch by Martin Partel! --- Diffs of the changes: (+2 -2) AliasAnalysis.h | 2 +- LinkAllAnalyses.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/include/llvm/Analysis/AliasAnalysis.h diff -u llvm/include/llvm/Analysis/AliasAnalysis.h:1.22 llvm/include/llvm/Analysis/AliasAnalysis.h:1.23 --- llvm/include/llvm/Analysis/AliasAnalysis.h:1.22 Mon Jun 20 10:24:23 2005 +++ llvm/include/llvm/Analysis/AliasAnalysis.h Wed Feb 22 10:23:42 2006 @@ -178,7 +178,7 @@ /// CallsThrough - Indirect calls are made through the specified function /// pointer. - CallsThrough, + CallsThrough }; }; Index: llvm/include/llvm/Analysis/LinkAllAnalyses.h diff -u llvm/include/llvm/Analysis/LinkAllAnalyses.h:1.3 llvm/include/llvm/Analysis/LinkAllAnalyses.h:1.4 --- llvm/include/llvm/Analysis/LinkAllAnalyses.h:1.3 Thu Dec 22 00:07:52 2005 +++ llvm/include/llvm/Analysis/LinkAllAnalyses.h Wed Feb 22 10:23:42 2006 @@ -55,6 +55,6 @@ X.add((llvm::Value*)0, 0); // for -print-alias-sets } } ForceAnalysisPassLinking; -}; +} #endif From lattner at cs.uiuc.edu Wed Feb 22 10:24:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 10:24:05 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ELFWriter.h LiveIntervalAnalysis.h MachineInstr.h ScheduleDAG.h SelectionDAGNodes.h ValueTypes.h Message-ID: <200602221624.KAA05006@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ELFWriter.h updated: 1.11 -> 1.12 LiveIntervalAnalysis.h updated: 1.50 -> 1.51 MachineInstr.h updated: 1.163 -> 1.164 ScheduleDAG.h updated: 1.8 -> 1.9 SelectionDAGNodes.h updated: 1.102 -> 1.103 ValueTypes.h updated: 1.18 -> 1.19 --- Log message: Make the LLVM headers "-ansi -pedantic -Wno-long-long" clean. Patch by Martin Partel! --- Diffs of the changes: (+9 -9) ELFWriter.h | 2 +- LiveIntervalAnalysis.h | 2 +- MachineInstr.h | 4 ++-- ScheduleDAG.h | 2 +- SelectionDAGNodes.h | 4 ++-- ValueTypes.h | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) Index: llvm/include/llvm/CodeGen/ELFWriter.h diff -u llvm/include/llvm/CodeGen/ELFWriter.h:1.11 llvm/include/llvm/CodeGen/ELFWriter.h:1.12 --- llvm/include/llvm/CodeGen/ELFWriter.h:1.11 Mon Feb 6 21:34:35 2006 +++ llvm/include/llvm/CodeGen/ELFWriter.h Wed Feb 22 10:23:43 2006 @@ -131,7 +131,7 @@ SHF_LINK_ORDER = 1 << 7, // Preserve order after combining SHF_OS_NONCONFORMING = 1 << 8, // nonstandard OS support required SHF_GROUP = 1 << 9, // Section is a member of a group - SHF_TLS = 1 << 10,// Section holds thread-local data + SHF_TLS = 1 << 10 // Section holds thread-local data }; ELFSection(const std::string &name) Index: llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h diff -u llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h:1.50 llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h:1.51 --- llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h:1.50 Sun Jan 29 01:59:37 2006 +++ llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h Wed Feb 22 10:23:43 2006 @@ -60,7 +60,7 @@ USE = 1, DEF = 2, STORE = 3, - NUM = 4, + NUM = 4 }; }; Index: llvm/include/llvm/CodeGen/MachineInstr.h diff -u llvm/include/llvm/CodeGen/MachineInstr.h:1.163 llvm/include/llvm/CodeGen/MachineInstr.h:1.164 --- llvm/include/llvm/CodeGen/MachineInstr.h:1.163 Mon Aug 1 15:38:31 2005 +++ llvm/include/llvm/CodeGen/MachineInstr.h Wed Feb 22 10:23:43 2006 @@ -79,7 +79,7 @@ LOFLAG32 = 0x08, // operand is %lo32(value_or_immedVal) HIFLAG64 = 0x10, // operand is %hi64(value_or_immedVal) LOFLAG64 = 0x20, // operand is %lo64(value_or_immedVal) - PCRELATIVE = 0x40, // Operand is relative to PC, not a global address + PCRELATIVE = 0x40 // Operand is relative to PC, not a global address }; public: @@ -106,7 +106,7 @@ MO_FrameIndex, // Abstract Stack Frame Index MO_ConstantPoolIndex, // Address of indexed Constant in Constant Pool MO_ExternalSymbol, // Name of external global symbol - MO_GlobalAddress, // Address of a global value + MO_GlobalAddress // Address of a global value }; private: Index: llvm/include/llvm/CodeGen/ScheduleDAG.h diff -u llvm/include/llvm/CodeGen/ScheduleDAG.h:1.8 llvm/include/llvm/CodeGen/ScheduleDAG.h:1.9 --- llvm/include/llvm/CodeGen/ScheduleDAG.h:1.8 Sat Feb 4 00:49:00 2006 +++ llvm/include/llvm/CodeGen/ScheduleDAG.h Wed Feb 22 10:23:43 2006 @@ -41,7 +41,7 @@ noScheduling, // No scheduling, emit breath first sequence. simpleScheduling, // Two pass, min. critical path, max. utilization. simpleNoItinScheduling, // Same as above exact using generic latency. - listSchedulingBURR, // Bottom up reg reduction list scheduling. + listSchedulingBURR // Bottom up reg reduction list scheduling. }; Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.102 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.103 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.102 Thu Feb 16 23:43:56 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Wed Feb 22 10:23:43 2006 @@ -402,7 +402,7 @@ DEBUG_LABEL, // BUILTIN_OP_END - This must be the last enum value in this list. - BUILTIN_OP_END, + BUILTIN_OP_END }; //===--------------------------------------------------------------------===// @@ -447,7 +447,7 @@ SETNE, // 1 X 1 1 0 True if not equal SETTRUE2, // 1 X 1 1 1 Always true (always folded) - SETCC_INVALID, // Marker value. + SETCC_INVALID // Marker value. }; /// isSignedIntSetCC - Return true if this is a setcc instruction that Index: llvm/include/llvm/CodeGen/ValueTypes.h diff -u llvm/include/llvm/CodeGen/ValueTypes.h:1.18 llvm/include/llvm/CodeGen/ValueTypes.h:1.19 --- llvm/include/llvm/CodeGen/ValueTypes.h:1.18 Mon Feb 20 16:34:53 2006 +++ llvm/include/llvm/CodeGen/ValueTypes.h Wed Feb 22 10:23:43 2006 @@ -59,7 +59,7 @@ v4f32 = 21, // 4 x f32 v2f64 = 22, // 2 x f64 - LAST_VALUETYPE, // This always remains at the end of the list. + LAST_VALUETYPE // This always remains at the end of the list. }; static inline bool isInteger(ValueType VT) { @@ -136,7 +136,7 @@ /// to the specified ValueType. For integer types, this returns an unsigned /// type. Note that this will abort for types that cannot be represented. const Type *getTypeForValueType(ValueType VT); -}; +} } // End llvm namespace From lattner at cs.uiuc.edu Wed Feb 22 10:24:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 10:24:05 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/ADT/BitSetVector.h PostOrderIterator.h VectorExtras.h Message-ID: <200602221624.KAA05000@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/ADT: BitSetVector.h updated: 1.14 -> 1.15 PostOrderIterator.h updated: 1.20 -> 1.21 VectorExtras.h updated: 1.5 -> 1.6 --- Log message: Make the LLVM headers "-ansi -pedantic -Wno-long-long" clean. Patch by Martin Partel! --- Diffs of the changes: (+3 -1) BitSetVector.h | 2 +- PostOrderIterator.h | 1 + VectorExtras.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/include/llvm/ADT/BitSetVector.h diff -u llvm/include/llvm/ADT/BitSetVector.h:1.14 llvm/include/llvm/ADT/BitSetVector.h:1.15 --- llvm/include/llvm/ADT/BitSetVector.h:1.14 Thu Apr 21 15:13:50 2005 +++ llvm/include/llvm/ADT/BitSetVector.h Wed Feb 22 10:23:42 2006 @@ -252,7 +252,7 @@ { bset.print(O); return O; -}; +} /// Index: llvm/include/llvm/ADT/PostOrderIterator.h diff -u llvm/include/llvm/ADT/PostOrderIterator.h:1.20 llvm/include/llvm/ADT/PostOrderIterator.h:1.21 --- llvm/include/llvm/ADT/PostOrderIterator.h:1.20 Tue Dec 6 23:41:44 2005 +++ llvm/include/llvm/ADT/PostOrderIterator.h Wed Feb 22 10:23:42 2006 @@ -20,6 +20,7 @@ #include "llvm/ADT/iterator" #include #include +#include namespace llvm { Index: llvm/include/llvm/ADT/VectorExtras.h diff -u llvm/include/llvm/ADT/VectorExtras.h:1.5 llvm/include/llvm/ADT/VectorExtras.h:1.6 --- llvm/include/llvm/ADT/VectorExtras.h:1.5 Thu Apr 21 15:13:50 2005 +++ llvm/include/llvm/ADT/VectorExtras.h Wed Feb 22 10:23:42 2006 @@ -16,6 +16,7 @@ #define LLVM_ADT_VECTOREXTRAS_H #include +#include namespace llvm { From jlaskey at apple.com Wed Feb 22 13:02:23 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 22 Feb 2006 13:02:23 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/DwarfWriter.h MachineDebugInfo.h Message-ID: <200602221902.NAA06258@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: DwarfWriter.h updated: 1.23 -> 1.24 MachineDebugInfo.h updated: 1.16 -> 1.17 --- Log message: Coordinate activities with llvm-gcc4 and dwarf. --- Diffs of the changes: (+64 -71) DwarfWriter.h | 86 +++++++++++++++++++++-------------------------------- MachineDebugInfo.h | 49 +++++++++++++++++------------- 2 files changed, 64 insertions(+), 71 deletions(-) Index: llvm/include/llvm/CodeGen/DwarfWriter.h diff -u llvm/include/llvm/CodeGen/DwarfWriter.h:1.23 llvm/include/llvm/CodeGen/DwarfWriter.h:1.24 --- llvm/include/llvm/CodeGen/DwarfWriter.h:1.23 Mon Feb 6 09:33:21 2006 +++ llvm/include/llvm/CodeGen/DwarfWriter.h Wed Feb 22 13:02:11 2006 @@ -34,12 +34,14 @@ // class AsmPrinter; class CompileUnitDesc; + class DebugInfoDesc; class DIE; - class DwarfWriter; - class DWContext; + class DwarfWriter; + class GlobalVariableDesc; class MachineDebugInfo; class MachineFunction; class Module; + class SubprogramDesc; class Type; //===--------------------------------------------------------------------===// @@ -116,6 +118,7 @@ unsigned getTag() const { return Tag; } unsigned getChildrenFlag() const { return ChildrenFlag; } const std::vector &getData() const { return Data; } + void setChildrenFlag(unsigned CF) { ChildrenFlag = CF; } /// operator== - Used by UniqueVector to locate entry. /// @@ -312,24 +315,21 @@ unsigned AbbrevID; // Decribing abbreviation ID. unsigned Offset; // Offset in debug info section. unsigned Size; // Size of instance + children. - DWContext *Context; // Context for types and values. std::vector Children; // Children DIEs. std::vector Values; // Attributes values. public: - DIE(unsigned Tag, unsigned ChildrenFlag); + DIE(unsigned Tag); ~DIE(); // Accessors unsigned getAbbrevID() const { return AbbrevID; } unsigned getOffset() const { return Offset; } unsigned getSize() const { return Size; } - DWContext *getContext() const { return Context; } const std::vector &getChildren() const { return Children; } const std::vector &getValues() const { return Values; } void setOffset(unsigned O) { Offset = O; } void setSize(unsigned S) { Size = S; } - void setContext(DWContext *C) { Context = C; } /// SiblingOffset - Return the offset of the debug information entry's /// sibling. @@ -376,40 +376,6 @@ }; //===--------------------------------------------------------------------===// - /// DWContext - Name context for types and values. - /// - class DWContext { - private: - DwarfWriter &DW; // DwarfWriter for global information. - DWContext *Parent; // Next context level searched. - DIE *Owner; // Owning debug information entry. - std::map Types; // Named types in context. - std::map Variables;// Named variables in context. - - public: - DWContext(DwarfWriter &D, DWContext *P, DIE *O) - : DW(D) - , Parent(P) - , Owner(O) - , Types() - , Variables() - { - Owner->setContext(this); - } - ~DWContext() {} - - /// NewBasicType - Creates a new basic type, if necessary, then adds to the - /// context and owner. - DIE *NewBasicType(const Type *Ty, unsigned Size, unsigned Align); - - /// NewVariable - Creates a basic variable, if necessary, then adds to the - /// context and owner. - DIE *NewGlobalVariable(const std::string &Name, - const std::string &MangledName, - DIE *Type); - }; - - //===--------------------------------------------------------------------===// // DwarfWriter - Emits Dwarf debug and exception handling directives. // class DwarfWriter { @@ -460,6 +426,15 @@ /// UniqueVector StringPool; + /// DescToDieMap - Tracks the mapping of debug informaton descriptors to + /// DIES. + std::map DescToDieMap; + + /// TypeToDieMap - Type to DIEType map. + /// + // FIXME - Should not be needed. + std::map TypeToDieMap; + //===------------------------------------------------------------------===// // Properties to be set by the derived class ctor, used to configure the // Dwarf writer. @@ -637,6 +612,11 @@ /// DWLabel NewString(const std::string &String); + /// NewBasicType - Creates a new basic type if necessary, then adds to the + /// owner. + /// FIXME - Should never be needed. + DIE *NewBasicType(DIE *Owner, Type *Ty); + /// NewGlobalType - Make the type visible globally using the given name. /// void NewGlobalType(const std::string &Name, DIE *Type); @@ -644,20 +624,20 @@ /// NewGlobalEntity - Make the entity visible globally using the given name. /// void NewGlobalEntity(const std::string &Name, DIE *Entity); + +private: - /// NewGlobalVariable - Add a new global variable DIE to the context. + /// NewGlobalVariable - Make a new global variable DIE. /// - void NewGlobalVariable(DWContext *Context, - const std::string &Name, - const std::string &MangledName, - const Type *Ty, - unsigned Size, unsigned Align); + DIE *NewGlobalVariable(GlobalVariableDesc *GVD); -private: + /// NewSubprogram - Add a new subprogram DIE. + /// + DIE *NewSubprogram(SubprogramDesc *SPD); /// NewCompileUnit - Create new compile unit information. /// - DIE *NewCompileUnit(const CompileUnitDesc *CompileUnit); + DIE *NewCompileUnit(CompileUnitDesc *CompileUnit); /// EmitInitial - Emit initial Dwarf declarations. /// @@ -669,7 +649,7 @@ /// SizeAndOffsetDie - Compute the size and offset of a DIE. /// - unsigned SizeAndOffsetDie(DIE *Die, unsigned Offset) const; + unsigned SizeAndOffsetDie(DIE *Die, unsigned Offset); /// SizeAndOffsets - Compute the size and offset of all the DIEs. /// @@ -723,10 +703,14 @@ /// header file. void ConstructCompileUnitDIEs(); - /// ConstructGlobalDIEs - Create DIEs for each of the externally visible global - /// variables. + /// ConstructGlobalDIEs - Create DIEs for each of the externally visible + /// global variables. void ConstructGlobalDIEs(Module &M); + /// ConstructSubprogramDIEs - Create DIEs for each of the externally visible + /// subprograms. + void ConstructSubprogramDIEs(Module &M); + /// ShouldEmitDwarf - Returns true if Dwarf declarations should be made. /// When called it also checks to see if debug info is newly available. if /// so the initial Dwarf headers are emitted. Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.16 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.17 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.16 Mon Feb 13 10:56:43 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Wed Feb 22 13:02:11 2006 @@ -310,18 +310,21 @@ class GlobalVariableDesc : public GlobalDesc { private: GlobalVariable *Global; // llvm global. + unsigned Line; // Source line number. public: GlobalVariableDesc(); // Accessors. GlobalVariable *getGlobalVariable() const { return Global; } + unsigned getLine() const { return Line; } void setGlobalVariable(GlobalVariable *GV) { Global = GV; } - + void setLine(unsigned L) { Line = L; } + // Implement isa/cast/dyncast. static bool classof(const GlobalVariableDesc *) { return true; } static bool classof(const DebugInfoDesc *D) { - return D->getTag() == DI_TAG_global_variable; + return D->getTag() == DI_TAG_global_variable; } /// ApplyToFields - Target the visitor to the fields of the @@ -350,25 +353,12 @@ /// subprogram/function. class SubprogramDesc : public GlobalDesc { private: - DebugInfoDesc *Context; // Context debug descriptor. - std::string Name; // Subprogram name. - // FIXME - Use a descriptor. - GlobalVariable *TyDesc; // Type debug descriptor. - bool IsStatic; // Is the subprogram a static. - bool IsDefinition; // Is the subprogram defined in context. + // FIXME - Other attributes public: SubprogramDesc(); // Accessors - DebugInfoDesc *getContext() const { return Context; } - const std::string &getName() const { return Name; } - bool isStatic() const { return IsStatic; } - bool isDefinition() const { return IsDefinition; } - void setContext(DebugInfoDesc *C) { Context = C; } - void setName(const std::string &N) { Name = N; } - void setIsStatic(bool IS) { IsStatic = IS; } - void setIsDefinition(bool ID) { IsDefinition = ID; } // FIXME - Other getters/setters. // Implement isa/cast/dyncast. @@ -604,10 +594,14 @@ /// RecordSource - Register a source file with debug info. Returns an source /// ID. unsigned RecordSource(const std::string &Directory, - const std::string &Source) { + const std::string &Source) { unsigned DirectoryID = Directories.insert(Directory); return SourceFiles.insert(SourceFileInfo(DirectoryID, Source)); } + unsigned RecordSource(const CompileUnitDesc *CompileUnit) { + return RecordSource(CompileUnit->getDirectory(), + CompileUnit->getFileName()); + } /// getDirectories - Return the UniqueVector of std::string representing /// directories. @@ -634,10 +628,25 @@ /// getCompileUnits - Return a vector of debug compile units. /// const UniqueVector getCompileUnits() const; + + /// getGlobalVariablesUsing - Return all of the GlobalVariables that use the + /// named GlobalVariable. + std::vector + getGlobalVariablesUsing(Module &M, const std::string &RootName); + + /// getAnchoredDescriptors - Return a vector of anchored debug descriptors. + /// + template std::vector getAnchoredDescriptors(Module &M) { + T Desc; + std::vector Globals = + getGlobalVariablesUsing(M, Desc.getAnchorString()); + std::vector AnchoredDescs; + for (unsigned i = 0, N = Globals.size(); i < N; ++i) { + AnchoredDescs.push_back(static_cast(DR.Deserialize(Globals[i]))); + } - /// getGlobalVariables - Return a vector of debug GlobalVariables. - /// - std::vector getGlobalVariables(Module &M); + return AnchoredDescs; + } }; // End class MachineDebugInfo From jlaskey at apple.com Wed Feb 22 13:02:24 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 22 Feb 2006 13:02:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp MachineDebugInfo.cpp Message-ID: <200602221902.NAA06264@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.26 -> 1.27 MachineDebugInfo.cpp updated: 1.14 -> 1.15 --- Log message: Coordinate activities with llvm-gcc4 and dwarf. --- Diffs of the changes: (+257 -195) DwarfWriter.cpp | 406 ++++++++++++++++++++++++++++++--------------------- MachineDebugInfo.cpp | 46 +---- 2 files changed, 257 insertions(+), 195 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.26 llvm/lib/CodeGen/DwarfWriter.cpp:1.27 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.26 Tue Feb 14 16:01:57 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Wed Feb 22 13:02:11 2006 @@ -774,12 +774,11 @@ //===----------------------------------------------------------------------===// -DIE::DIE(unsigned Tag, unsigned ChildrenFlag) -: Abbrev(new DIEAbbrev(Tag, ChildrenFlag)) +DIE::DIE(unsigned Tag) +: Abbrev(new DIEAbbrev(Tag, DW_CHILDREN_no)) , AbbrevID(0) , Offset(0) , Size(0) -, Context(NULL) , Children() , Values() {} @@ -794,8 +793,6 @@ for (unsigned j = 0, M = Values.size(); j < M; ++j) { delete Values[j]; } - - if (Context) delete Context; } /// AddUInt - Add an unsigned integer attribute data and value. @@ -875,115 +872,14 @@ /// AddChild - Add a child to the DIE. /// void DIE::AddChild(DIE *Child) { + assert(Abbrev && "Adding children without an abbreviation"); + Abbrev->setChildrenFlag(DW_CHILDREN_yes); Children.push_back(Child); } //===----------------------------------------------------------------------===// -/// NewBasicType - Creates a new basic type if necessary, then adds to the -/// context and owner. -DIE *DWContext::NewBasicType(const Type *Ty, unsigned Size, unsigned Align) { - DIE *TypeDie = Types[Ty]; - - // If first occurance of type. - if (!TypeDie) { - const char *Name; - unsigned Encoding = 0; - - switch (Ty->getTypeID()) { - case Type::UByteTyID: - Name = "unsigned char"; - Encoding = DW_ATE_unsigned_char; - break; - case Type::SByteTyID: - Name = "char"; - Encoding = DW_ATE_signed_char; - break; - case Type::UShortTyID: - Name = "unsigned short"; - Encoding = DW_ATE_unsigned; - break; - case Type::ShortTyID: - Name = "short"; - Encoding = DW_ATE_signed; - break; - case Type::UIntTyID: - Name = "unsigned int"; - Encoding = DW_ATE_unsigned; - break; - case Type::IntTyID: - Name = "int"; - Encoding = DW_ATE_signed; - break; - case Type::ULongTyID: - Name = "unsigned long long"; - Encoding = DW_ATE_unsigned; - break; - case Type::LongTyID: - Name = "long long"; - Encoding = DW_ATE_signed; - break; - case Type::FloatTyID: - Name = "float"; - Encoding = DW_ATE_float; - break; - case Type::DoubleTyID: - Name = "float"; - Encoding = DW_ATE_float; - break; - default: - // FIXME - handle more complex types. - Name = "unknown"; - Encoding = DW_ATE_address; - break; - } - - // construct the type DIE. - TypeDie = new DIE(DW_TAG_base_type, DW_CHILDREN_no); - TypeDie->AddString(DW_AT_name, DW_FORM_string, Name); - TypeDie->AddUInt (DW_AT_byte_size, 0, Size); - TypeDie->AddUInt (DW_AT_encoding, DW_FORM_data1, Encoding); - TypeDie->Complete(DW); - - // Add to context owner. - Owner->AddChild(TypeDie); - - // Add to map. - Types[Ty] = TypeDie; - } - - return TypeDie; -} - -/// NewGlobalVariable - Creates a global variable, if necessary, then adds in -/// the context and owner. -DIE *DWContext::NewGlobalVariable(const std::string &Name, - const std::string &MangledName, - DIE *Type) { - DIE *VariableDie = Variables[MangledName]; - - // If first occurance of variable. - if (!VariableDie) { - // FIXME - need source file name line number. - VariableDie = new DIE(DW_TAG_variable, DW_CHILDREN_no); - VariableDie->AddString (DW_AT_name, DW_FORM_string, Name); - VariableDie->AddUInt (DW_AT_decl_file, 0, 0); - VariableDie->AddUInt (DW_AT_decl_line, 0, 0); - VariableDie->AddDIEntry (DW_AT_type, DW_FORM_ref4, Type); - VariableDie->AddUInt (DW_AT_external, DW_FORM_flag, 1); - // FIXME - needs to be a proper expression. - VariableDie->AddObjectLabel(DW_AT_location, DW_FORM_block1, MangledName); - VariableDie->Complete(DW); - - // Add to context owner. - Owner->AddChild(VariableDie); - - // Add to map. - Variables[MangledName] = VariableDie; - } - - return VariableDie; -} +/// DWContext //===----------------------------------------------------------------------===// @@ -1088,14 +984,14 @@ /// void DwarfWriter::EmitInt8(int Value) const { O << Asm->Data8bitsDirective; - PrintHex(Value); + PrintHex(Value & 0xFF); } /// EmitInt16 - Emit a short directive and value. /// void DwarfWriter::EmitInt16(int Value) const { O << Asm->Data16bitsDirective; - PrintHex(Value); + PrintHex(Value & 0xFFFF); } /// EmitInt32 - Emit a long directive and value. @@ -1161,8 +1057,8 @@ void DwarfWriter::PrintLabelName(const char *Tag, unsigned Number) const { O << Asm->PrivateGlobalPrefix << "debug_" - << Tag - << Number; + << Tag; + if (Number) O << Number; } /// EmitLabel - Emit location label for internal use by Dwarf. @@ -1240,6 +1136,88 @@ return DWLabel("string", StringID); } +/// NewBasicType - Creates a new basic type if necessary, then adds to the +/// owner. +/// FIXME - Should never be needed. +DIE *DwarfWriter::NewBasicType(DIE *Owner, Type *Ty) { + DIE *&Slot = TypeToDieMap[Ty]; + if (Slot) return Slot; + + const char *Name; + unsigned Size; + unsigned Encoding = 0; + + switch (Ty->getTypeID()) { + case Type::UByteTyID: + Name = "unsigned char"; + Size = 1; + Encoding = DW_ATE_unsigned_char; + break; + case Type::SByteTyID: + Name = "char"; + Size = 1; + Encoding = DW_ATE_signed_char; + break; + case Type::UShortTyID: + Name = "unsigned short"; + Size = 2; + Encoding = DW_ATE_unsigned; + break; + case Type::ShortTyID: + Name = "short"; + Size = 2; + Encoding = DW_ATE_signed; + break; + case Type::UIntTyID: + Name = "unsigned int"; + Size = 4; + Encoding = DW_ATE_unsigned; + break; + case Type::IntTyID: + Name = "int"; + Size = 4; + Encoding = DW_ATE_signed; + break; + case Type::ULongTyID: + Name = "unsigned long long"; + Size = 7; + Encoding = DW_ATE_unsigned; + break; + case Type::LongTyID: + Name = "long long"; + Size = 7; + Encoding = DW_ATE_signed; + break; + case Type::FloatTyID: + Name = "float"; + Size = 4; + Encoding = DW_ATE_float; + break; + case Type::DoubleTyID: + Name = "double"; + Size = 8; + Encoding = DW_ATE_float; + break; + default: + // FIXME - handle more complex types. + Name = "unknown"; + Size = 1; + Encoding = DW_ATE_address; + break; + } + + // construct the type DIE. + Slot = new DIE(DW_TAG_base_type); + Slot->AddString(DW_AT_name, DW_FORM_string, Name); + Slot->AddUInt (DW_AT_byte_size, 0, Size); + Slot->AddUInt (DW_AT_encoding, DW_FORM_data1, Encoding); + + // Add to context owner. + Owner->AddChild(Slot); + + return Slot; +} + /// NewGlobalType - Make the type visible globally using the given name. /// void DwarfWriter::NewGlobalType(const std::string &Name, DIE *Type) { @@ -1254,49 +1232,142 @@ GlobalEntities[Name] = Entity; } -/// NewGlobalVariable - Add a new global variable DIE to the context. -/// -void DwarfWriter::NewGlobalVariable(DWContext *Context, - const std::string &Name, - const std::string &MangledName, - const Type *Ty, - unsigned Size, unsigned Align) { - // Get the DIE type for the global. - DIE *Type = Context->NewBasicType(Ty, Size, Align); - DIE *Variable = Context->NewGlobalVariable(Name, MangledName, Type); - NewGlobalEntity(Name, Variable); -} - /// NewCompileUnit - Create new compile unit information. /// -DIE *DwarfWriter::NewCompileUnit(const CompileUnitDesc *CompileUnit) { - DIE *Unit = new DIE(DW_TAG_compile_unit, DW_CHILDREN_yes); +DIE *DwarfWriter::NewCompileUnit(CompileUnitDesc *CompileUnit) { + // Check for pre-existence. + DIE *&Slot = DescToDieMap[CompileUnit]; + if (Slot) return Slot; + + DIE *Unit = new DIE(DW_TAG_compile_unit); // FIXME - use the correct line set. - Unit->AddLabel (DW_AT_stmt_list, DW_FORM_data4, DWLabel("line", 0)); + Unit->AddLabel (DW_AT_stmt_list, DW_FORM_data4, DWLabel("section_line", 0)); Unit->AddLabel (DW_AT_high_pc, DW_FORM_addr, DWLabel("text_end", 0)); Unit->AddLabel (DW_AT_low_pc, DW_FORM_addr, DWLabel("text_begin", 0)); Unit->AddString(DW_AT_producer, DW_FORM_string, CompileUnit->getProducer()); Unit->AddUInt (DW_AT_language, DW_FORM_data1, CompileUnit->getLanguage()); Unit->AddString(DW_AT_name, DW_FORM_string, CompileUnit->getFileName()); Unit->AddString(DW_AT_comp_dir, DW_FORM_string, CompileUnit->getDirectory()); - Unit->Complete(*this); + + Slot = Unit; return Unit; } +/// NewGlobalVariable - Add a new global variable DIE. +/// +DIE *DwarfWriter::NewGlobalVariable(GlobalVariableDesc *GVD) { + // Check for pre-existence. + DIE *&Slot = DescToDieMap[GVD]; + if (Slot) return Slot; + + // Get the compile unit context. + CompileUnitDesc *CompileUnit = + static_cast(GVD->getContext()); + DIE *Unit = NewCompileUnit(CompileUnit); + // Get the global variable itself. + GlobalVariable *GV = GVD->getGlobalVariable(); + // Generate the mangled name. + std::string MangledName = Asm->Mang->getValueName(GV); + + // Gather the details (simplify add attribute code.) + const std::string &Name = GVD->getName(); + unsigned FileID = DebugInfo->RecordSource(CompileUnit); + unsigned Line = GVD->getLine(); + + // FIXME - faking the type for the time being. + DIE *Type = NewBasicType(Unit, Type::IntTy); + + DIE *VariableDie = new DIE(DW_TAG_variable); + VariableDie->AddString (DW_AT_name, DW_FORM_string, Name); + VariableDie->AddUInt (DW_AT_decl_file, 0, FileID); + VariableDie->AddUInt (DW_AT_decl_line, 0, Line); + VariableDie->AddDIEntry (DW_AT_type, DW_FORM_ref4, Type); + VariableDie->AddUInt (DW_AT_external, DW_FORM_flag, 1); + // FIXME - needs to be a proper expression. + VariableDie->AddObjectLabel(DW_AT_location, DW_FORM_block1, MangledName); + + // Add to map. + Slot = VariableDie; + + // Add to context owner. + Unit->AddChild(VariableDie); + + // Expose as global. + NewGlobalEntity(Name, VariableDie); + + return VariableDie; +} + +/// NewSubprogram - Add a new subprogram DIE. +/// +DIE *DwarfWriter::NewSubprogram(SubprogramDesc *SPD) { + // Check for pre-existence. + DIE *&Slot = DescToDieMap[SPD]; + if (Slot) return Slot; + + // Get the compile unit context. + CompileUnitDesc *CompileUnit = + static_cast(SPD->getContext()); + DIE *Unit = NewCompileUnit(CompileUnit); + + // Gather the details (simplify add attribute code.) + const std::string &Name = SPD->getName(); + unsigned FileID = DebugInfo->RecordSource(CompileUnit); + // FIXME - faking the line for the time being. + unsigned Line = 1; + + // FIXME - faking the type for the time being. + DIE *Type = NewBasicType(Unit, Type::IntTy); + + DIE *SubprogramDie = new DIE(DW_TAG_variable); + SubprogramDie->AddString (DW_AT_name, DW_FORM_string, Name); + SubprogramDie->AddUInt (DW_AT_decl_file, 0, FileID); + SubprogramDie->AddUInt (DW_AT_decl_line, 0, Line); + SubprogramDie->AddDIEntry (DW_AT_type, DW_FORM_ref4, Type); + SubprogramDie->AddUInt (DW_AT_external, DW_FORM_flag, 1); + + // Add to map. + Slot = SubprogramDie; + + // Add to context owner. + Unit->AddChild(SubprogramDie); + + // Expose as global. + NewGlobalEntity(Name, SubprogramDie); + + return SubprogramDie; +} + /// EmitInitial - Emit initial Dwarf declarations. This is necessary for cc /// tools to recognize the object file contains Dwarf information. /// void DwarfWriter::EmitInitial() const { // Dwarf sections base addresses. - Asm->SwitchSection(DwarfAbbrevSection, 0); - EmitLabel("abbrev", 0); + Asm->SwitchSection(DwarfFrameSection, 0); + EmitLabel("section_frame", 0); Asm->SwitchSection(DwarfInfoSection, 0); + EmitLabel("section_info", 0); EmitLabel("info", 0); + Asm->SwitchSection(DwarfAbbrevSection, 0); + EmitLabel("section_abbrev", 0); + EmitLabel("abbrev", 0); + Asm->SwitchSection(DwarfARangesSection, 0); + EmitLabel("section_aranges", 0); + Asm->SwitchSection(DwarfMacInfoSection, 0); + EmitLabel("section_macinfo", 0); Asm->SwitchSection(DwarfLineSection, 0); + EmitLabel("section_line", 0); EmitLabel("line", 0); - - // Standard sections base addresses. + Asm->SwitchSection(DwarfLocSection, 0); + EmitLabel("section_loc", 0); + Asm->SwitchSection(DwarfPubNamesSection, 0); + EmitLabel("section_pubnames", 0); + Asm->SwitchSection(DwarfStrSection, 0); + EmitLabel("section_str", 0); + Asm->SwitchSection(DwarfRangesSection, 0); + EmitLabel("section_ranges", 0); + Asm->SwitchSection(TextSection, 0); EmitLabel("text_begin", 0); Asm->SwitchSection(DataSection, 0); @@ -1358,7 +1429,10 @@ /// SizeAndOffsetDie - Compute the size and offset of a DIE. /// -unsigned DwarfWriter::SizeAndOffsetDie(DIE *Die, unsigned Offset) const { +unsigned DwarfWriter::SizeAndOffsetDie(DIE *Die, unsigned Offset) { + // Record the abbreviation. + Die->Complete(*this); + // Get the abbreviation for this DIE. unsigned AbbrevID = Die->getAbbrevID(); const DIEAbbrev &Abbrev = Abbreviations[AbbrevID]; @@ -1550,6 +1624,17 @@ // Construct rows of the address, source, line, column matrix. for (unsigned i = 0, N = LineInfos.size(); i < N; ++i) { SourceLineInfo *LineInfo = LineInfos[i]; + + if (DwarfVerbose) { + unsigned SourceID = LineInfo->getSourceID(); + const SourceFileInfo &SourceFile = SourceFiles[SourceID]; + unsigned DirectoryID = SourceFile.getDirectoryID(); + O << "\t" + << Asm->CommentString << " " + << Directories[DirectoryID] + << SourceFile.getName() << ":" + << LineInfo->getLine() << "\n"; + } // Define the line address. EmitInt8(0); EOL("Extended Op"); @@ -1589,6 +1674,12 @@ } } + // Define last address. + EmitInt8(0); EOL("Extended Op"); + EmitInt8(4 + 1); EOL("Op size"); + EmitInt8(DW_LNE_set_address); EOL("DW_LNE_set_address"); + EmitReference("text_end", 0); EOL("Location label"); + // Mark end of matrix. EmitInt8(0); EOL("DW_LNE_end_sequence"); EmitULEB128Bytes(1); O << "\n"; @@ -1727,7 +1818,6 @@ for (unsigned i = 1, N = CUW.size(); i <= N; ++i) { DIE *Unit = NewCompileUnit(CUW[i]); - DWContext *Context = new DWContext(*this, NULL, Unit); CompileUnits.push_back(Unit); } } @@ -1735,39 +1825,26 @@ /// ConstructGlobalDIEs - Create DIEs for each of the externally visible global /// variables. void DwarfWriter::ConstructGlobalDIEs(Module &M) { - const TargetData &TD = Asm->TM.getTargetData(); - std::vector GlobalVariables = - DebugInfo->getGlobalVariables(M); + DebugInfo->getAnchoredDescriptors(M); for (unsigned i = 0, N = GlobalVariables.size(); i < N; ++i) { GlobalVariableDesc *GVD = GlobalVariables[i]; - GlobalVariable *GV = GVD->getGlobalVariable(); - - if (!GV->hasInitializer()) continue; // External global require no code - - // FIXME - Use global info type information when available. - std::string Name = Asm->Mang->getValueName(GV); - Constant *C = GV->getInitializer(); - const Type *Ty = C->getType(); - unsigned Size = TD.getTypeSize(Ty); - unsigned Align = TD.getTypeAlignmentShift(Ty); - - if (C->isNullValue() && /* FIXME: Verify correct */ - (GV->hasInternalLinkage() || GV->hasWeakLinkage() || - GV->hasLinkOnceLinkage())) { - if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - } - - /// FIXME - Get correct compile unit context. - assert(CompileUnits.size() && "No compile units"); - DWContext *Context = CompileUnits[0]->getContext(); - - /// Create new global. - NewGlobalVariable(Context, GV->getName(), Name, Ty, Size, Align); + NewGlobalVariable(GVD); } } +/// ConstructSubprogramDIEs - Create DIEs for each of the externally visible +/// subprograms. +void DwarfWriter::ConstructSubprogramDIEs(Module &M) { + std::vector Subprograms = + DebugInfo->getAnchoredDescriptors(M); + + for (unsigned i = 0, N = Subprograms.size(); i < N; ++i) { + SubprogramDesc *SPD = Subprograms[i]; + NewSubprogram(SPD); + } +} /// ShouldEmitDwarf - Determine if Dwarf declarations should be made. /// @@ -1799,6 +1876,8 @@ , GlobalTypes() , GlobalEntities() , StringPool() +, DescToDieMap() +, TypeToDieMap() , AddressSize(sizeof(int32_t)) , hasLEB128(false) , hasDotLoc(false) @@ -1849,6 +1928,9 @@ // Create DIEs for each of the externally visible global variables. ConstructGlobalDIEs(M); + // Create DIEs for each of the externally visible subprograms. + ConstructSubprogramDIEs(M); + // Compute DIE offsets and sizes. SizeAndOffsets(); Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.14 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.15 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.14 Mon Feb 13 06:50:38 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Wed Feb 22 13:02:11 2006 @@ -579,6 +579,7 @@ GlobalDesc::ApplyToFields(Visitor); Visitor->Apply(Global); + Visitor->Apply(Line); } /// getDescString - Return a string used to compose global names and labels. @@ -607,7 +608,8 @@ << "Name(\"" << getName() << "\"), " << "IsStatic(" << (isStatic() ? "true" : "false") << "), " << "IsDefinition(" << (isDefinition() ? "true" : "false") << "), " - << "Global(" << Global << ")\n"; + << "Global(" << Global << "), " + << "Line(" << Line << ")\n"; } #endif @@ -910,16 +912,10 @@ /// SetupCompileUnits - Set up the unique vector of compile units. /// void MachineDebugInfo::SetupCompileUnits(Module &M) { - // Get vector of all debug compile units. - CompileUnitDesc CompileUnit; - std::vector Globals = - getGlobalVariablesUsing(M, CompileUnit.getAnchorString()); - - // Scan all compile unit globals. - for (unsigned i = 0, N = Globals.size(); i < N; ++i) { - // Add compile unit to result. - CompileUnits.insert( - static_cast(DR.Deserialize(Globals[i]))); + std::vectorCU = getAnchoredDescriptors(M); + + for (unsigned i = 0, N = CU.size(); i < N; i++) { + CompileUnits.insert(CU[i]); } } @@ -929,26 +925,10 @@ return CompileUnits; } -/// getGlobalVariables - Return a vector of debug GlobalVariables. -/// -std::vector -MachineDebugInfo::getGlobalVariables(Module &M) { - // Get vector of all debug global objects. - GlobalVariableDesc Global; - std::vector Globals = - getGlobalVariablesUsing(M, Global.getAnchorString()); - - // Accumulation of GlobalVariables. - std::vector GlobalVariables; - - // Scan all globals. - for (unsigned i = 0, N = Globals.size(); i < N; ++i) { - GlobalVariable *GV = Globals[i]; - GlobalVariableDesc *GVD = - static_cast(DR.Deserialize(GV)); - GlobalVariables.push_back(GVD); - } - - return GlobalVariables; +/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the +/// named GlobalVariable. +std::vector +MachineDebugInfo::getGlobalVariablesUsing(Module &M, + const std::string &RootName) { + return ::getGlobalVariablesUsing(M, RootName); } - From jlaskey at apple.com Wed Feb 22 13:02:24 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 22 Feb 2006 13:02:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200602221902.NAA06268@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.152 -> 1.153 --- Log message: Coordinate activities with llvm-gcc4 and dwarf. --- Diffs of the changes: (+11 -12) PPCAsmPrinter.cpp | 23 +++++++++++------------ 1 files changed, 11 insertions(+), 12 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.152 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.153 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.152 Fri Feb 17 18:08:58 2006 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Wed Feb 22 13:02:11 2006 @@ -223,18 +223,17 @@ : DwarfWriter(o, ap) { needsSet = true; - DwarfAbbrevSection = ".section __DWARF,__debug_abbrev"; - DwarfInfoSection = ".section __DWARF,__debug_info"; - DwarfLineSection = ".section __DWARF,__debug_line"; - DwarfFrameSection = - ".section __DWARF,__debug_frame,,coalesced,no_toc+strip_static_syms"; - DwarfPubNamesSection = ".section __DWARF,__debug_pubnames"; - DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes"; - DwarfStrSection = ".section __DWARF,__debug_str"; - DwarfLocSection = ".section __DWARF,__debug_loc"; - DwarfARangesSection = ".section __DWARF,__debug_aranges"; - DwarfRangesSection = ".section __DWARF,__debug_ranges"; - DwarfMacInfoSection = ".section __DWARF,__debug_macinfo"; + DwarfAbbrevSection = ".section __DWARFA,__debug_abbrev"; + DwarfInfoSection = ".section __DWARFA,__debug_info"; + DwarfLineSection = ".section __DWARFA,__debug_line"; + DwarfFrameSection = ".section __DWARFA,__debug_frame"; + DwarfPubNamesSection = ".section __DWARFA,__debug_pubnames"; + DwarfPubTypesSection = ".section __DWARFA,__debug_pubtypes"; + DwarfStrSection = ".section __DWARFA,__debug_str"; + DwarfLocSection = ".section __DWARFA,__debug_loc"; + DwarfARangesSection = ".section __DWARFA,__debug_aranges"; + DwarfRangesSection = ".section __DWARFA,__debug_ranges"; + DwarfMacInfoSection = ".section __DWARFA,__debug_macinfo"; TextSection = ".text"; DataSection = ".data"; } From evan.cheng at apple.com Wed Feb 22 14:19:55 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 22 Feb 2006 14:19:55 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86CodeEmitter.cpp X86ISelLowering.cpp X86IntelAsmPrinter.cpp X86TargetMachine.cpp Message-ID: <200602222019.OAA06753@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ATTAsmPrinter.cpp updated: 1.23 -> 1.24 X86CodeEmitter.cpp updated: 1.90 -> 1.91 X86ISelLowering.cpp updated: 1.93 -> 1.94 X86IntelAsmPrinter.cpp updated: 1.17 -> 1.18 X86TargetMachine.cpp updated: 1.104 -> 1.105 --- Log message: - Added option -relocation-model to set relocation model. Valid values include static, pic, dynamic-no-pic, and default. PPC and x86 default is dynamic-no-pic for Darwin, pic for others. - Removed options -enable-pic and -ppc-static. --- Diffs of the changes: (+29 -20) X86ATTAsmPrinter.cpp | 14 +++++++------- X86CodeEmitter.cpp | 4 +++- X86ISelLowering.cpp | 9 +++++---- X86IntelAsmPrinter.cpp | 13 +++++++------ X86TargetMachine.cpp | 9 +++++++-- 5 files changed, 29 insertions(+), 20 deletions(-) Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.23 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.24 --- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.23 Fri Feb 17 18:15:05 2006 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Wed Feb 22 14:19:42 2006 @@ -119,7 +119,7 @@ bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp && !isCallOp) O << '$'; // Darwin block shameless ripped from PPCAsmPrinter.cpp - if (forDarwin) { + if (forDarwin && TM.getRelocationModel() != Reloc::Static) { GlobalValue *GV = MO.getGlobal(); std::string Name = Mang->getValueName(GV); // Link-once, External, or Weakly-linked global variables need @@ -133,7 +133,7 @@ } else { GVStubs.insert(Name); O << "L" << Name << "$non_lazy_ptr"; - if (PICEnabled) + if (TM.getRelocationModel() == Reloc::PIC) O << "-\"L" << getFunctionNumber() << "$pb\""; } } else { @@ -150,14 +150,14 @@ } case MachineOperand::MO_ExternalSymbol: { bool isCallOp = Modifier && !strcmp(Modifier, "call"); - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - if (isCallOp && forDarwin) { - std::string Name(GlobalPrefix); Name += MO.getSymbolName(); + if (isCallOp && forDarwin && TM.getRelocationModel() != Reloc::Static) { + std::string Name(GlobalPrefix); + Name += MO.getSymbolName(); FnStubs.insert(Name); O << "L" << Name << "$stub"; return; } - if (!isMemOp && !isCallOp) O << '$'; + if (!isCallOp) O << '$'; O << GlobalPrefix << MO.getSymbolName(); return; } @@ -198,7 +198,7 @@ } else if (BaseReg.isConstantPoolIndex()) { O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" << BaseReg.getConstantPoolIndex(); - if (forDarwin && PICEnabled) + if (forDarwin && TM.getRelocationModel() == Reloc::PIC) O << "-\"L" << getFunctionNumber() << "$pb\""; if (DispSpec.getImmedValue()) O << "+" << DispSpec.getImmedValue(); Index: llvm/lib/Target/X86/X86CodeEmitter.cpp diff -u llvm/lib/Target/X86/X86CodeEmitter.cpp:1.90 llvm/lib/Target/X86/X86CodeEmitter.cpp:1.91 --- llvm/lib/Target/X86/X86CodeEmitter.cpp:1.90 Fri Feb 17 18:57:10 2006 +++ llvm/lib/Target/X86/X86CodeEmitter.cpp Wed Feb 22 14:19:42 2006 @@ -77,6 +77,9 @@ } bool Emitter::runOnMachineFunction(MachineFunction &MF) { + assert((MF.getTarget().getRelocationModel() != Reloc::Default || + MF.getTarget().getRelocationModel() != Reloc::Static) && + "JIT relocation model must be set to static or default!"); II = ((X86TargetMachine&)MF.getTarget()).getInstrInfo(); MCE.startFunction(MF); @@ -97,7 +100,6 @@ } void Emitter::emitBasicBlock(const MachineBasicBlock &MBB) { - assert(!PICEnabled && "CodeEmitter does not support PIC!"); if (uint64_t Addr = MCE.getCurrentPCValue()) BasicBlockAddrs[&MBB] = Addr; Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.93 llvm/lib/Target/X86/X86ISelLowering.cpp:1.94 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.93 Tue Feb 21 20:26:30 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Feb 22 14:19:42 2006 @@ -1836,7 +1836,7 @@ if (getTargetMachine(). getSubtarget().isTargetDarwin()) { // With PIC, the address is actually $g + Offset. - if (PICEnabled) + if (getTargetMachine().getRelocationModel() == Reloc::PIC) Result = DAG.getNode(ISD::ADD, getPointerTy(), DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Result); } @@ -1851,7 +1851,7 @@ GlobalValue *GV = cast(Op)->getGlobal(); SDOperand Addr = DAG.getTargetGlobalAddress(GV, getPointerTy()); // With PIC, the address is actually $g + Offset. - if (PICEnabled) + if (getTargetMachine().getRelocationModel() == Reloc::PIC) Addr = DAG.getNode(ISD::ADD, getPointerTy(), DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Addr); @@ -1859,8 +1859,9 @@ // the value at address GV, not the value of GV itself. This means that // the GlobalAddress must be in the base or index register of the address, // not the GV offset field. - if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || - (GV->isExternal() && !GV->hasNotBeenReadFromBytecode())) + if (getTargetMachine().getRelocationModel() != Reloc::Static && + (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || + (GV->isExternal() && !GV->hasNotBeenReadFromBytecode()))) Result = DAG.getLoad(MVT::i32, DAG.getEntryNode(), Addr, DAG.getSrcValue(NULL)); } Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.17 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.18 --- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.17 Fri Feb 17 18:15:05 2006 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Wed Feb 22 14:19:42 2006 @@ -113,7 +113,7 @@ bool isCallOp = Modifier && !strcmp(Modifier, "call"); bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp && !isCallOp) O << "OFFSET "; - if (forDarwin) { + if (forDarwin && TM.getRelocationModel() != Reloc::Static) { GlobalValue *GV = MO.getGlobal(); std::string Name = Mang->getValueName(GV); if (!isMemOp && !isCallOp) O << '$'; @@ -128,7 +128,7 @@ } else { GVStubs.insert(Name); O << "L" << Name << "$non_lazy_ptr"; - if (PICEnabled) + if (TM.getRelocationModel() == Reloc::PIC) O << "-\"L" << getFunctionNumber() << "$pb\""; } } else { @@ -145,13 +145,14 @@ } case MachineOperand::MO_ExternalSymbol: { bool isCallOp = Modifier && !strcmp(Modifier, "call"); - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - if (isCallOp && forDarwin) { - std::string Name(GlobalPrefix); Name += MO.getSymbolName(); + if (isCallOp && forDarwin && TM.getRelocationModel() != Reloc::Static) { + std::string Name(GlobalPrefix); + Name += MO.getSymbolName(); FnStubs.insert(Name); O << "L" << Name << "$stub"; return; } + if (!isCallOp) O << "OFFSET "; O << GlobalPrefix << MO.getSymbolName(); return; } @@ -177,7 +178,7 @@ } else if (BaseReg.isConstantPoolIndex()) { O << "[" << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" << BaseReg.getConstantPoolIndex(); - if (forDarwin && PICEnabled) + if (forDarwin && TM.getRelocationModel() == Reloc::PIC) O << "-\"L" << getFunctionNumber() << "$pb\""; if (IndexReg.getReg()) { Index: llvm/lib/Target/X86/X86TargetMachine.cpp diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.104 llvm/lib/Target/X86/X86TargetMachine.cpp:1.105 --- llvm/lib/Target/X86/X86TargetMachine.cpp:1.104 Fri Feb 17 19:49:25 2006 +++ llvm/lib/Target/X86/X86TargetMachine.cpp Wed Feb 22 14:19:42 2006 @@ -76,6 +76,11 @@ FrameInfo(TargetFrameInfo::StackGrowsDown, Subtarget.getStackAlignment(), -4), JITInfo(*this) { + if (getRelocationModel() == Reloc::Default) + if (Subtarget.isTargetDarwin()) + setRelocationModel(Reloc::DynamicNoPIC); + else + setRelocationModel(Reloc::PIC); } @@ -149,8 +154,8 @@ /// not supported for this target. /// void X86JITInfo::addPassesToJITCompile(FunctionPassManager &PM) { - // The JIT does not support or need PIC. - PICEnabled = false; + // The JIT should use static relocation model. + TM.setRelocationModel(Reloc::Static); // FIXME: Implement efficient support for garbage collection intrinsics. PM.add(createLowerGCPass()); From evan.cheng at apple.com Wed Feb 22 14:19:56 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 22 Feb 2006 14:19:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetMachine.cpp Message-ID: <200602222019.OAA06777@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetMachine.cpp updated: 1.41 -> 1.42 --- Log message: - Added option -relocation-model to set relocation model. Valid values include static, pic, dynamic-no-pic, and default. PPC and x86 default is dynamic-no-pic for Darwin, pic for others. - Removed options -enable-pic and -ppc-static. --- Diffs of the changes: (+28 -6) TargetMachine.cpp | 34 ++++++++++++++++++++++++++++------ 1 files changed, 28 insertions(+), 6 deletions(-) Index: llvm/lib/Target/TargetMachine.cpp diff -u llvm/lib/Target/TargetMachine.cpp:1.41 llvm/lib/Target/TargetMachine.cpp:1.42 --- llvm/lib/Target/TargetMachine.cpp:1.41 Thu Aug 18 18:53:15 2005 +++ llvm/lib/Target/TargetMachine.cpp Wed Feb 22 14:19:42 2006 @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" #include "llvm/Type.h" #include "llvm/CodeGen/IntrinsicLowering.h" #include "llvm/Support/CommandLine.h" @@ -26,7 +27,7 @@ bool NoFramePointerElim; bool NoExcessFPPrecision; bool UnsafeFPMath; - bool PICEnabled; + Reloc::Model RelocationModel; }; namespace { cl::opt PrintCode("print-machineinstrs", @@ -48,11 +49,22 @@ cl::desc("Enable optimizations that may decrease FP precision"), cl::location(UnsafeFPMath), cl::init(false)); - cl::opt - EnablePIC("enable-pic", - cl::desc("Enable generation of position independant code"), - cl::location(PICEnabled), - cl::init(false)); + cl::opt + DefRelocationModel( + "relocation-model", + cl::desc("Choose relocation model"), + cl::location(RelocationModel), + cl::init(Reloc::Default), + cl::values( + clEnumValN(Reloc::Default, "default", + "Target default relocation model"), + clEnumValN(Reloc::Static, "static", + "Non-relocatable code"), + clEnumValN(Reloc::PIC, "pic", + "Fully relocatable, position independent code"), + clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic", + "Relocatable external references, non-relocatable code"), + clEnumValEnd)); }; //--------------------------------------------------------------------------- @@ -87,3 +99,13 @@ delete IL; } +/// getRelocationModel - Returns the code generation relocation model. The +/// choices are static, PIC, and dynamic-no-pic, and target default. +Reloc::Model TargetMachine::getRelocationModel() { + return RelocationModel; +} + +/// setRelocationModel - Sets the code generation relocation model. +void TargetMachine::setRelocationModel(Reloc::Model Model) { + RelocationModel = Model; +} From evan.cheng at apple.com Wed Feb 22 14:19:56 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 22 Feb 2006 14:19:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC.h PPCAsmPrinter.cpp PPCCodeEmitter.cpp PPCISelLowering.cpp PPCSubtarget.cpp PPCTargetMachine.cpp Message-ID: <200602222019.OAA06773@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC.h updated: 1.26 -> 1.27 PPCAsmPrinter.cpp updated: 1.153 -> 1.154 PPCCodeEmitter.cpp updated: 1.46 -> 1.47 PPCISelLowering.cpp updated: 1.90 -> 1.91 PPCSubtarget.cpp updated: 1.17 -> 1.18 PPCTargetMachine.cpp updated: 1.79 -> 1.80 --- Log message: - Added option -relocation-model to set relocation model. Valid values include static, pic, dynamic-no-pic, and default. PPC and x86 default is dynamic-no-pic for Darwin, pic for others. - Removed options -enable-pic and -ppc-static. --- Diffs of the changes: (+21 -21) PPC.h | 1 - PPCAsmPrinter.cpp | 12 ++++++------ PPCCodeEmitter.cpp | 4 +++- PPCISelLowering.cpp | 8 ++++---- PPCSubtarget.cpp | 8 +------- PPCTargetMachine.cpp | 9 +++++++-- 6 files changed, 21 insertions(+), 21 deletions(-) Index: llvm/lib/Target/PowerPC/PPC.h diff -u llvm/lib/Target/PowerPC/PPC.h:1.26 llvm/lib/Target/PowerPC/PPC.h:1.27 --- llvm/lib/Target/PowerPC/PPC.h:1.26 Fri Feb 17 18:08:58 2006 +++ llvm/lib/Target/PowerPC/PPC.h Wed Feb 22 14:19:42 2006 @@ -31,7 +31,6 @@ FunctionPass *createDarwinAsmPrinter(std::ostream &OS, TargetMachine &TM); FunctionPass *createAIXAsmPrinter(std::ostream &OS, TargetMachine &TM); -extern bool PPCGenerateStaticCode; extern PPCTargetEnum PPCTarget; } // end namespace llvm; Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.153 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.154 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.153 Wed Feb 22 13:02:11 2006 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Wed Feb 22 14:19:42 2006 @@ -132,7 +132,7 @@ } void printCallOperand(const MachineInstr *MI, unsigned OpNo) { const MachineOperand &MO = MI->getOperand(OpNo); - if (!PPCGenerateStaticCode) { + if (TM.getRelocationModel() != Reloc::Static) { if (MO.getType() == MachineOperand::MO_GlobalAddress) { GlobalValue *GV = MO.getGlobal(); if (((GV->isExternal() || GV->hasWeakLinkage() || @@ -167,7 +167,7 @@ } else { O << "ha16("; printOp(MI->getOperand(OpNo)); - if (PICEnabled) + if (TM.getRelocationModel() == Reloc::PIC) O << "-\"L" << getFunctionNumber() << "$pb\")"; else O << ')'; @@ -179,7 +179,7 @@ } else { O << "lo16("; printOp(MI->getOperand(OpNo)); - if (PICEnabled) + if (TM.getRelocationModel() == Reloc::PIC) O << "-\"L" << getFunctionNumber() << "$pb\")"; else O << ')'; @@ -362,7 +362,7 @@ return; case MachineOperand::MO_ExternalSymbol: // Computing the address of an external symbol, not calling it. - if (!PPCGenerateStaticCode) { + if (TM.getRelocationModel() != Reloc::Static) { std::string Name(GlobalPrefix); Name += MO.getSymbolName(); GVStubs.insert(Name); O << "L" << Name << "$non_lazy_ptr"; @@ -377,7 +377,7 @@ int offset = MO.getOffset(); // External or weakly linked global variables need non-lazily-resolved stubs - if (!PPCGenerateStaticCode) { + if (TM.getRelocationModel() != Reloc::Static) { if (((GV->isExternal() || GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()))) { GVStubs.insert(Name); @@ -585,7 +585,7 @@ } // Output stubs for dynamically-linked functions - if (PICEnabled) { + if (TM.getRelocationModel() == Reloc::PIC) { for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); i != e; ++i) { SwitchSection(".section __TEXT,__picsymbolstub1,symbol_stubs," Index: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp diff -u llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.46 llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.47 --- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.46 Fri Feb 17 18:08:58 2006 +++ llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Wed Feb 22 14:19:42 2006 @@ -86,6 +86,9 @@ } bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) { + assert((MF.getTarget().getRelocationModel() != Reloc::Default || + MF.getTarget().getRelocationModel() != Reloc::Static) && + "JIT relocation model must be set to static or default!"); MCE.startFunction(MF); MCE.emitConstantPool(MF.getConstantPool()); for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) @@ -118,7 +121,6 @@ } void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { - assert(!PICEnabled && "CodeEmitter does not support PIC!"); BBLocations[&MBB] = MCE.getCurrentPCValue(); for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){ MachineInstr &MI = *I; Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.90 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.91 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.90 Tue Feb 21 18:56:38 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Wed Feb 22 14:19:42 2006 @@ -396,7 +396,7 @@ SDOperand CPI = DAG.getTargetConstantPool(C, MVT::i32, CP->getAlignment()); SDOperand Zero = DAG.getConstant(0, MVT::i32); - if (PPCGenerateStaticCode) { + if (getTargetMachine().getRelocationModel() == Reloc::Static) { // Generate non-pic code that has direct accesses to the constant pool. // The address of the global is just (hi(&g)+lo(&g)). SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, CPI, Zero); @@ -407,7 +407,7 @@ // Only lower ConstantPool on Darwin. if (!getTargetMachine().getSubtarget().isDarwin()) break; SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, CPI, Zero); - if (PICEnabled) { + if (getTargetMachine().getRelocationModel() == Reloc::PIC) { // With PIC, the first instruction is actually "GR+hi(&G)". Hi = DAG.getNode(ISD::ADD, MVT::i32, DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi); @@ -423,7 +423,7 @@ SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32, GSDN->getOffset()); SDOperand Zero = DAG.getConstant(0, MVT::i32); - if (PPCGenerateStaticCode) { + if (getTargetMachine().getRelocationModel() == Reloc::Static) { // Generate non-pic code that has direct accesses to globals. // The address of the global is just (hi(&g)+lo(&g)). SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, GA, Zero); @@ -435,7 +435,7 @@ if (!getTargetMachine().getSubtarget().isDarwin()) break; SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, GA, Zero); - if (PICEnabled) { + if (getTargetMachine().getRelocationModel() == Reloc::PIC) { // With PIC, the first instruction is actually "GR+hi(&G)". Hi = DAG.getNode(ISD::ADD, MVT::i32, DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi); Index: llvm/lib/Target/PowerPC/PPCSubtarget.cpp diff -u llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.17 llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.18 --- llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.17 Fri Jan 27 23:40:47 2006 +++ llvm/lib/Target/PowerPC/PPCSubtarget.cpp Wed Feb 22 14:19:42 2006 @@ -19,7 +19,6 @@ using namespace llvm; PPCTargetEnum llvm::PPCTarget = TargetDefault; -bool llvm::PPCGenerateStaticCode = false; namespace llvm { cl::opt @@ -29,12 +28,7 @@ clEnumValN(TargetDarwin,"darwin", " Enable Darwin codegen"), clEnumValEnd), - cl::location(PPCTarget), cl::init(TargetDefault)); - - cl::opt - PPCStaticCode("ppc-static", - cl::desc("PowerPC: generate completely non-pic code"), - cl::location(PPCGenerateStaticCode)); + cl::location(PPCTarget), cl::init(TargetDefault)); } #if defined(__APPLE__) Index: llvm/lib/Target/PowerPC/PPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.79 llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.80 --- llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.79 Wed Jan 11 19:46:07 2006 +++ llvm/lib/Target/PowerPC/PPCTargetMachine.cpp Wed Feb 22 14:19:42 2006 @@ -67,6 +67,11 @@ if (Subtarget.isAIX()) PPCTarget = TargetAIX; if (Subtarget.isDarwin()) PPCTarget = TargetDarwin; } + if (getRelocationModel() == Reloc::Default) + if (Subtarget.isDarwin()) + setRelocationModel(Reloc::DynamicNoPIC); + else + setRelocationModel(Reloc::PIC); } /// addPassesToEmitFile - Add passes to the specified pass manager to implement @@ -129,8 +134,8 @@ } void PPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) { - // The JIT does not support or need PIC. - PICEnabled = false; + // The JIT should use static relocation model. + TM.setRelocationModel(Reloc::Static); // Run loop strength reduction before anything else. PM.add(createLoopStrengthReducePass()); From evan.cheng at apple.com Wed Feb 22 14:19:56 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 22 Feb 2006 14:19:56 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetMachine.h TargetOptions.h Message-ID: <200602222019.OAA06759@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetMachine.h updated: 1.59 -> 1.60 TargetOptions.h updated: 1.7 -> 1.8 --- Log message: - Added option -relocation-model to set relocation model. Valid values include static, pic, dynamic-no-pic, and default. PPC and x86 default is dynamic-no-pic for Darwin, pic for others. - Removed options -enable-pic and -ppc-static. --- Diffs of the changes: (+17 -6) TargetMachine.h | 17 +++++++++++++++++ TargetOptions.h | 6 ------ 2 files changed, 17 insertions(+), 6 deletions(-) Index: llvm/include/llvm/Target/TargetMachine.h diff -u llvm/include/llvm/Target/TargetMachine.h:1.59 llvm/include/llvm/Target/TargetMachine.h:1.60 --- llvm/include/llvm/Target/TargetMachine.h:1.59 Mon Nov 7 20:10:16 2005 +++ llvm/include/llvm/Target/TargetMachine.h Wed Feb 22 14:19:42 2006 @@ -34,6 +34,16 @@ class Pass; class IntrinsicLowering; +// Relocation model types. +namespace Reloc { + enum Model { + Default, + Static, + PIC, + DynamicNoPIC + }; +} + //===----------------------------------------------------------------------===// /// /// TargetMachine - Primary interface to the complete machine description for @@ -135,6 +145,13 @@ virtual const TargetSchedInfo *getSchedInfo() const { return 0; } virtual const SparcV9RegInfo *getRegInfo() const { return 0; } + /// getRelocationModel - Returns the code generation relocation model. The + /// choices are static, PIC, and dynamic-no-pic, and target default. + static Reloc::Model getRelocationModel(); + + /// setRelocationModel - Sets the code generation relocation model. + static void setRelocationModel(Reloc::Model Model); + /// CodeGenFileType - These enums are meant to be passed into /// addPassesToEmitFile to indicate what type of file to emit. enum CodeGenFileType { Index: llvm/include/llvm/Target/TargetOptions.h diff -u llvm/include/llvm/Target/TargetOptions.h:1.7 llvm/include/llvm/Target/TargetOptions.h:1.8 --- llvm/include/llvm/Target/TargetOptions.h:1.7 Fri Feb 17 18:06:03 2006 +++ llvm/include/llvm/Target/TargetOptions.h Wed Feb 22 14:19:42 2006 @@ -40,12 +40,6 @@ /// produce results that are "less precise" than IEEE allows. This includes /// use of X86 instructions like FSIN and FCOS instead of libcalls. extern bool UnsafeFPMath; - - /// PICEnabled - This flag is enabled when the -enable-pic flag is specified - /// on the command line. When this flag is on, the code generator produces - /// position independant code. - extern bool PICEnabled; - } // End llvm namespace #endif From lattner at cs.uiuc.edu Wed Feb 22 16:37:25 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 16:37:25 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200602222237.QAA15015@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.166 -> 1.167 --- Log message: Change a whole bunch of code to be built around RegsForValue instead of a single register number. This fully implements promotion for inline asms, expand is close but not quite right yet. --- Diffs of the changes: (+248 -124) SelectionDAGISel.cpp | 372 ++++++++++++++++++++++++++++++++++----------------- 1 files changed, 248 insertions(+), 124 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.166 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.167 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.166 Tue Feb 21 18:56:12 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Feb 22 16:37:12 2006 @@ -78,6 +78,43 @@ clEnumValEnd)); } // namespace +namespace { + /// RegsForValue - This struct represents the physical registers that a + /// particular value is assigned and the type information about the value. + /// This is needed because values can be promoted into larger registers and + /// expanded into multiple smaller registers than the value. + struct RegsForValue { + /// Regs - This list hold the register (for legal and promoted values) + /// or register set (for expanded values) that the value should be assigned + /// to. + std::vector Regs; + + /// RegVT - The value type of each register. + /// + MVT::ValueType RegVT; + + /// ValueVT - The value type of the LLVM value, which may be promoted from + /// RegVT or made from merging the two expanded parts. + MVT::ValueType ValueVT; + + RegsForValue() : RegVT(MVT::Other), ValueVT(MVT::Other) {} + + RegsForValue(unsigned Reg, MVT::ValueType regvt, MVT::ValueType valuevt) + : RegVT(regvt), ValueVT(valuevt) { + Regs.push_back(Reg); + } + RegsForValue(const std::vector ®s, + MVT::ValueType regvt, MVT::ValueType valuevt) + : Regs(regs), RegVT(regvt), ValueVT(valuevt) { + } + + /// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from + /// this value and returns the result as a ValueVT value. This uses + /// Chain/Flag as the input and updates them for the output Chain/Flag. + SDOperand getCopyFromRegs(SelectionDAG &DAG, + SDOperand &Chain, SDOperand &Flag); + }; +} namespace llvm { //===--------------------------------------------------------------------===// @@ -120,7 +157,7 @@ } // If this value is represented with multiple target registers, make sure - // to create enough consequtive registers of the right (smaller) type. + // to create enough consecutive registers of the right (smaller) type. unsigned NT = VT-1; // Find the type to use. while (TLI.getNumElements((MVT::ValueType)NT) != 1) --NT; @@ -412,11 +449,12 @@ return N = NewN; } - unsigned GetAvailableRegister(bool OutReg, bool InReg, - const std::vector &RegChoices, - std::set &OutputRegs, - std::set &InputRegs); - + RegsForValue GetRegistersForValue(const std::string &ConstrCode, + MVT::ValueType VT, + bool OutReg, bool InReg, + std::set &OutputRegs, + std::set &InputRegs); + // Terminator instructions. void visitRet(ReturnInst &I); void visitBr(BranchInst &I); @@ -1130,49 +1168,145 @@ DAG.setRoot(Result.second); } -/// GetAvailableRegister - Pick a register from RegChoices that is available -/// for input and/or output as specified by isOutReg/isInReg. If an allocatable -/// register is found, it is returned and added to the specified set of used -/// registers. If not, zero is returned. -unsigned SelectionDAGLowering:: -GetAvailableRegister(bool isOutReg, bool isInReg, - const std::vector &RegChoices, - std::set &OutputRegs, +SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG, + SDOperand &Chain, SDOperand &Flag) { + SDOperand Val = DAG.getCopyFromReg(Chain, Regs[0], RegVT, Flag); + Chain = Val.getValue(1); + Flag = Val.getValue(2); + + // If the result was expanded, copy from the top part. + if (Regs.size() > 1) { + assert(Regs.size() == 2 && + "Cannot expand to more than 2 elts yet!"); + SDOperand Hi = DAG.getCopyFromReg(Chain, Regs[1], RegVT, Flag); + Chain = Val.getValue(1); + Flag = Val.getValue(2); + return DAG.getNode(ISD::MERGE_VALUES, ValueVT, Val, Hi); + } + + // Otherwise, if the return value was promoted, truncate it to the + // appropriate type. + if (RegVT == ValueVT) + return Val; + + if (MVT::isInteger(RegVT)) + return DAG.getNode(ISD::TRUNCATE, ValueVT, Val); + else + return DAG.getNode(ISD::FP_ROUND, ValueVT, Val); +} + + + +/// isAllocatableRegister - If the specified register is safe to allocate, +/// i.e. it isn't a stack pointer or some other special register, return the +/// register class for the register. Otherwise, return null. +static const TargetRegisterClass * +isAllocatableRegister(unsigned Reg, MachineFunction &MF, + const MRegisterInfo *MRI) { + for (MRegisterInfo::regclass_iterator RC = MRI->regclass_begin(), + E = MRI->regclass_end(); RC != E; ++RC) { + // NOTE: This isn't ideal. In particular, this might allocate the + // frame pointer in functions that need it (due to them not being taken + // out of allocation, because a variable sized allocation hasn't been seen + // yet). This is a slight code pessimization, but should still work. + for (TargetRegisterClass::iterator I = (*RC)->allocation_order_begin(MF), + E = (*RC)->allocation_order_end(MF); I != E; ++I) + if (*I == Reg) + return *RC; + } + return 0; +} + +RegsForValue SelectionDAGLowering:: +GetRegistersForValue(const std::string &ConstrCode, + MVT::ValueType VT, bool isOutReg, bool isInReg, + std::set &OutputRegs, std::set &InputRegs) { + std::pair PhysReg = + TLI.getRegForInlineAsmConstraint(ConstrCode, VT); + std::vector Regs; + + unsigned NumRegs = VT != MVT::Other ? TLI.getNumElements(VT) : 1; + MVT::ValueType RegVT; + MVT::ValueType ValueVT = VT; + + if (PhysReg.first) { + if (VT == MVT::Other) + ValueVT = *PhysReg.second->vt_begin(); + RegVT = VT; + + // This is a explicit reference to a physical register. + Regs.push_back(PhysReg.first); + + // If this is an expanded reference, add the rest of the regs to Regs. + if (NumRegs != 1) { + RegVT = *PhysReg.second->vt_begin(); + TargetRegisterClass::iterator I = PhysReg.second->begin(); + TargetRegisterClass::iterator E = PhysReg.second->end(); + for (; *I != PhysReg.first; ++I) + assert(I != E && "Didn't find reg!"); + + // Already added the first reg. + --NumRegs; ++I; + for (; NumRegs; --NumRegs, ++I) { + assert(I != E && "Ran out of registers to allocate!"); + Regs.push_back(*I); + } + } + return RegsForValue(Regs, RegVT, ValueVT); + } + + // This is a reference to a register class. Allocate NumRegs consecutive, + // available, registers from the class. + std::vector RegClassRegs = + TLI.getRegClassForInlineAsmConstraint(ConstrCode, VT); + const MRegisterInfo *MRI = DAG.getTarget().getRegisterInfo(); MachineFunction &MF = *CurMBB->getParent(); - for (unsigned i = 0, e = RegChoices.size(); i != e; ++i) { - unsigned Reg = RegChoices[i]; + unsigned NumAllocated = 0; + for (unsigned i = 0, e = RegClassRegs.size(); i != e; ++i) { + unsigned Reg = RegClassRegs[i]; // See if this register is available. - if (isOutReg && OutputRegs.count(Reg)) continue; // Already used. - if (isInReg && InputRegs.count(Reg)) continue; // Already used. - + if ((isOutReg && OutputRegs.count(Reg)) || // Already used. + (isInReg && InputRegs.count(Reg))) { // Already used. + // Make sure we find consecutive registers. + NumAllocated = 0; + continue; + } + // Check to see if this register is allocatable (i.e. don't give out the // stack pointer). - bool Found = false; - for (MRegisterInfo::regclass_iterator RC = MRI->regclass_begin(), - E = MRI->regclass_end(); !Found && RC != E; ++RC) { - // NOTE: This isn't ideal. In particular, this might allocate the - // frame pointer in functions that need it (due to them not being taken - // out of allocation, because a variable sized allocation hasn't been seen - // yet). This is a slight code pessimization, but should still work. - for (TargetRegisterClass::iterator I = (*RC)->allocation_order_begin(MF), - E = (*RC)->allocation_order_end(MF); I != E; ++I) - if (*I == Reg) { - Found = true; - break; - } + const TargetRegisterClass *RC = isAllocatableRegister(Reg, MF, MRI); + if (!RC) { + // Make sure we find consecutive registers. + NumAllocated = 0; + continue; } - if (!Found) continue; - // Okay, this register is good, return it. - if (isOutReg) OutputRegs.insert(Reg); // Mark used. - if (isInReg) InputRegs.insert(Reg); // Mark used. - return Reg; + // Okay, this register is good, we can use it. + ++NumAllocated; + + // If we allocated enough consecutive + if (NumAllocated == NumRegs) { + unsigned RegStart = (i-NumAllocated)+1; + unsigned RegEnd = i+1; + // Mark all of the allocated registers used. + for (unsigned i = RegStart; i != RegEnd; ++i) { + unsigned Reg = RegClassRegs[i]; + Regs.push_back(Reg); + if (isOutReg) OutputRegs.insert(Reg); // Mark reg used. + if (isInReg) InputRegs.insert(Reg); // Mark reg used. + } + + return RegsForValue(Regs, *RC->vt_begin(), VT); + } } - return 0; + + // Otherwise, we couldn't allocate enough registers for this. + return RegsForValue(); } + /// visitInlineAsm - Handle a call to an InlineAsm object. /// void SelectionDAGLowering::visitInlineAsm(CallInst &I) { @@ -1235,39 +1369,40 @@ ConstraintVTs.push_back(OpVT); - std::pair Reg = - TLI.getRegForInlineAsmConstraint(ConstraintCode, OpVT); - if (Reg.first == 0) continue; // Not assigned a fixed reg. - unsigned TheReg = Reg.first; + if (TLI.getRegForInlineAsmConstraint(ConstraintCode, OpVT).first == 0) + continue; // Not assigned a fixed reg. - // FIXME: Handle expanded physreg refs! + // Build a list of regs that this operand uses. This always has a single + // element for promoted/expanded operands. + RegsForValue Regs = GetRegistersForValue(ConstraintCode, OpVT, + false, false, + OutputRegs, InputRegs); switch (Constraints[i].Type) { case InlineAsm::isOutput: // We can't assign any other output to this register. - OutputRegs.insert(TheReg); + OutputRegs.insert(Regs.Regs.begin(), Regs.Regs.end()); // If this is an early-clobber output, it cannot be assigned to the same // value as the input reg. if (Constraints[i].isEarlyClobber || Constraints[i].hasMatchingInput) - InputRegs.insert(TheReg); + InputRegs.insert(Regs.Regs.begin(), Regs.Regs.end()); break; case InlineAsm::isInput: // We can't assign any other input to this register. - InputRegs.insert(TheReg); + InputRegs.insert(Regs.Regs.begin(), Regs.Regs.end()); break; case InlineAsm::isClobber: // Clobbered regs cannot be used as inputs or outputs. - InputRegs.insert(TheReg); - OutputRegs.insert(TheReg); + InputRegs.insert(Regs.Regs.begin(), Regs.Regs.end()); + OutputRegs.insert(Regs.Regs.begin(), Regs.Regs.end()); break; } } // Loop over all of the inputs, copying the operand values into the // appropriate registers and processing the output regs. - unsigned RetValReg = 0; - std::vector > IndirectStoresToEmit; - bool FoundOutputConstraint = false; + RegsForValue RetValRegs; + std::vector > IndirectStoresToEmit; OpNum = 1; for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { @@ -1276,58 +1411,47 @@ switch (Constraints[i].Type) { case InlineAsm::isOutput: { - // Copy the output from the appropriate register. Find a regsister that - // we can use. - - // Check to see if this is a physreg reference. - std::pair PhysReg = - TLI.getRegForInlineAsmConstraint(ConstraintCode, ConstraintVTs[i]); - unsigned DestReg; - if (PhysReg.first) - DestReg = PhysReg.first; - else { - std::vector Regs = - TLI.getRegClassForInlineAsmConstraint(ConstraintCode, - ConstraintVTs[i]); - - // If this is an early-clobber output, or if there is an input - // constraint that matches this, we need to reserve the input register - // so no other inputs allocate to it. - bool UsesInputRegister = false; - if (Constraints[i].isEarlyClobber || Constraints[i].hasMatchingInput) - UsesInputRegister = true; - DestReg = GetAvailableRegister(true, UsesInputRegister, - Regs, OutputRegs, InputRegs); - } + // If this is an early-clobber output, or if there is an input + // constraint that matches this, we need to reserve the input register + // so no other inputs allocate to it. + bool UsesInputRegister = false; + if (Constraints[i].isEarlyClobber || Constraints[i].hasMatchingInput) + UsesInputRegister = true; - assert(DestReg && "Couldn't allocate output reg!"); + // Copy the output from the appropriate register. Find a register that + // we can use. + RegsForValue Regs = + GetRegistersForValue(ConstraintCode, ConstraintVTs[i], + true, UsesInputRegister, + OutputRegs, InputRegs); + assert(!Regs.Regs.empty() && "Couldn't allocate output reg!"); - const Type *OpTy; if (!Constraints[i].isIndirectOutput) { - assert(!FoundOutputConstraint && + assert(RetValRegs.Regs.empty() && "Cannot have multiple output constraints yet!"); - FoundOutputConstraint = true; assert(I.getType() != Type::VoidTy && "Bad inline asm!"); - - RetValReg = DestReg; + RetValRegs = Regs; } else { Value *CallOperand = I.getOperand(OpNum); - IndirectStoresToEmit.push_back(std::make_pair(DestReg, CallOperand)); + IndirectStoresToEmit.push_back(std::make_pair(Regs, CallOperand)); OpNum++; // Consumes a call operand. } // Add information to the INLINEASM node to know that this register is // set. - AsmNodeOperands.push_back(DAG.getRegister(DestReg, ConstraintVTs[i])); - AsmNodeOperands.push_back(DAG.getConstant(2, MVT::i32)); // ISDEF + // FIXME: + // FIXME: Handle multiple regs here. + // FIXME: + unsigned DestReg = Regs.Regs[0]; + AsmNodeOperands.push_back(DAG.getRegister(DestReg, Regs.RegVT)); + AsmNodeOperands.push_back(DAG.getConstant(2, MVT::i32)); // ISDEF break; } case InlineAsm::isInput: { Value *CallOperand = I.getOperand(OpNum); OpNum++; // Consumes a call operand. - unsigned SrcReg; SDOperand ResOp; unsigned ResOpType; SDOperand InOperandVal = getValue(CallOperand); @@ -1336,6 +1460,7 @@ // If this is required to match an output register we have already set, // just use its register. unsigned OperandNo = atoi(ConstraintCode.c_str()); + unsigned SrcReg; SrcReg = cast(AsmNodeOperands[OperandNo*2+2])->getReg(); ResOp = DAG.getRegister(SrcReg, ConstraintVTs[i]); ResOpType = 1; @@ -1343,39 +1468,46 @@ Chain = DAG.getCopyToReg(Chain, SrcReg, InOperandVal, Flag); Flag = Chain.getValue(1); } else { - TargetLowering::ConstraintType CTy = TargetLowering::C_Register; + TargetLowering::ConstraintType CTy = TargetLowering::C_RegisterClass; if (ConstraintCode.size() == 1) // not a physreg name. CTy = TLI.getConstraintType(ConstraintCode[0]); switch (CTy) { default: assert(0 && "Unknown constraint type! FAIL!"); - case TargetLowering::C_Register: { - std::pair PhysReg = - TLI.getRegForInlineAsmConstraint(ConstraintCode, ConstraintVTs[i]); - // FIXME: should be match fail. - assert(PhysReg.first && "Unknown physical register name!"); - SrcReg = PhysReg.first; - - Chain = DAG.getCopyToReg(Chain, SrcReg, InOperandVal, Flag); - Flag = Chain.getValue(1); - - ResOp = DAG.getRegister(SrcReg, ConstraintVTs[i]); - ResOpType = 1; - break; - } case TargetLowering::C_RegisterClass: { - // Copy the input into the appropriate register. - std::vector Regs = - TLI.getRegClassForInlineAsmConstraint(ConstraintCode, - ConstraintVTs[i]); - SrcReg = GetAvailableRegister(false, true, Regs, - OutputRegs, InputRegs); + // Copy the input into the appropriate registers. + RegsForValue InRegs = + GetRegistersForValue(ConstraintCode, ConstraintVTs[i], + false, true, OutputRegs, InputRegs); // FIXME: should be match fail. - assert(SrcReg && "Wasn't able to allocate register!"); - Chain = DAG.getCopyToReg(Chain, SrcReg, InOperandVal, Flag); - Flag = Chain.getValue(1); + assert(!InRegs.Regs.empty() && "Couldn't allocate input reg!"); + + if (InRegs.Regs.size() == 1) { + // If there is a single register and the types differ, this must be + // a promotion. + if (InRegs.RegVT != InRegs.ValueVT) { + if (MVT::isInteger(InRegs.RegVT)) + InOperandVal = DAG.getNode(ISD::ANY_EXTEND, InRegs.RegVT, + InOperandVal); + else + InOperandVal = DAG.getNode(ISD::FP_EXTEND, InRegs.RegVT, + InOperandVal); + } + Chain = DAG.getCopyToReg(Chain, InRegs.Regs[0], InOperandVal, Flag); + Flag = Chain.getValue(1); + + ResOp = DAG.getRegister(InRegs.Regs[0], InRegs.RegVT); + } else { + for (unsigned i = 0, e = InRegs.Regs.size(); i != e; ++i) { + SDOperand Part = DAG.getNode(ISD::EXTRACT_ELEMENT, InRegs.RegVT, + InOperandVal, + DAG.getConstant(i, MVT::i32)); + Chain = DAG.getCopyToReg(Chain, InRegs.Regs[i], Part, Flag); + Flag = Chain.getValue(1); + } + ResOp = DAG.getRegister(InRegs.Regs[0], InRegs.RegVT); + } - ResOp = DAG.getRegister(SrcReg, ConstraintVTs[i]); ResOpType = 1; break; } @@ -1411,26 +1543,18 @@ // If this asm returns a register value, copy the result from that register // and set it as the value of the call. - if (RetValReg) { - SDOperand Val = DAG.getCopyFromReg(Chain, RetValReg, - TLI.getValueType(I.getType()), Flag); - Chain = Val.getValue(1); - Flag = Val.getValue(2); - setValue(&I, Val); - } + if (!RetValRegs.Regs.empty()) + setValue(&I, RetValRegs.getCopyFromRegs(DAG, Chain, Flag)); std::vector > StoresToEmit; // Process indirect outputs, first output all of the flagged copies out of // physregs. for (unsigned i = 0, e = IndirectStoresToEmit.size(); i != e; ++i) { + RegsForValue &OutRegs = IndirectStoresToEmit[i].first; Value *Ptr = IndirectStoresToEmit[i].second; - const Type *Ty = cast(Ptr->getType())->getElementType(); - SDOperand Val = DAG.getCopyFromReg(Chain, IndirectStoresToEmit[i].first, - TLI.getValueType(Ty), Flag); - Chain = Val.getValue(1); - Flag = Val.getValue(2); - StoresToEmit.push_back(std::make_pair(Val, Ptr)); + SDOperand OutVal = OutRegs.getCopyFromRegs(DAG, Chain, Flag); + StoresToEmit.push_back(std::make_pair(OutVal, Ptr)); } // Emit the non-flagged stores from the physregs. @@ -1689,8 +1813,8 @@ SDOperand Value = getMemsetValue(Op2, VT, DAG); SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, getRoot(), Value, - getMemBasePlusOffset(Op1, Offset, DAG, TLI), - DAG.getSrcValue(I.getOperand(1), Offset)); + getMemBasePlusOffset(Op1, Offset, DAG, TLI), + DAG.getSrcValue(I.getOperand(1), Offset)); OutChains.push_back(Store); Offset += VTSize; } From lattner at cs.uiuc.edu Wed Feb 22 17:01:03 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 17:01:03 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200602222301.RAA15194@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.35 -> 1.36 --- Log message: Don't return registers from register classes that aren't legal. --- Diffs of the changes: (+15 -2) TargetLowering.cpp | 17 +++++++++++++++-- 1 files changed, 15 insertions(+), 2 deletions(-) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.35 llvm/lib/Target/TargetLowering.cpp:1.36 --- llvm/lib/Target/TargetLowering.cpp:1.35 Tue Feb 21 18:56:38 2006 +++ llvm/lib/Target/TargetLowering.cpp Wed Feb 22 17:00:51 2006 @@ -766,11 +766,24 @@ for (MRegisterInfo::regclass_iterator RCI = RI->regclass_begin(), E = RI->regclass_end(); RCI != E; ++RCI) { const TargetRegisterClass *RC = *RCI; + + // If none of the the value types for this register class are valid, we + // can't use it. For example, 64-bit reg classes on 32-bit targets. + bool isLegal = false; + for (TargetRegisterClass::vt_iterator I = RC->vt_begin(), E = RC->vt_end(); + I != E; ++I) { + if (isTypeLegal(*I)) { + isLegal = true; + break; + } + } + + if (!isLegal) continue; + for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end(); I != E; ++I) { - if (StringsEqualNoCase(RegName, RI->get(*I).Name)) { + if (StringsEqualNoCase(RegName, RI->get(*I).Name)) return std::make_pair(*I, RC); - } } } From lattner at cs.uiuc.edu Wed Feb 22 17:09:15 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 17:09:15 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200602222309.RAA15287@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.167 -> 1.168 --- Log message: This fixes a couple of problems with expansion --- Diffs of the changes: (+23 -9) SelectionDAGISel.cpp | 32 +++++++++++++++++++++++--------- 1 files changed, 23 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.167 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.168 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.167 Wed Feb 22 16:37:12 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Feb 22 17:09:03 2006 @@ -1181,7 +1181,7 @@ SDOperand Hi = DAG.getCopyFromReg(Chain, Regs[1], RegVT, Flag); Chain = Val.getValue(1); Flag = Val.getValue(2); - return DAG.getNode(ISD::MERGE_VALUES, ValueVT, Val, Hi); + return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Val, Hi); } // Otherwise, if the return value was promoted, truncate it to the @@ -1201,18 +1201,32 @@ /// i.e. it isn't a stack pointer or some other special register, return the /// register class for the register. Otherwise, return null. static const TargetRegisterClass * -isAllocatableRegister(unsigned Reg, MachineFunction &MF, - const MRegisterInfo *MRI) { - for (MRegisterInfo::regclass_iterator RC = MRI->regclass_begin(), - E = MRI->regclass_end(); RC != E; ++RC) { +isAllocatableRegister(unsigned Reg, MachineFunction &MF, + const TargetLowering &TLI, const MRegisterInfo *MRI) { + for (MRegisterInfo::regclass_iterator RCI = MRI->regclass_begin(), + E = MRI->regclass_end(); RCI != E; ++RCI) { + const TargetRegisterClass *RC = *RCI; + // If none of the the value types for this register class are valid, we + // can't use it. For example, 64-bit reg classes on 32-bit targets. + bool isLegal = false; + for (TargetRegisterClass::vt_iterator I = RC->vt_begin(), E = RC->vt_end(); + I != E; ++I) { + if (TLI.isTypeLegal(*I)) { + isLegal = true; + break; + } + } + + if (!isLegal) continue; + // NOTE: This isn't ideal. In particular, this might allocate the // frame pointer in functions that need it (due to them not being taken // out of allocation, because a variable sized allocation hasn't been seen // yet). This is a slight code pessimization, but should still work. - for (TargetRegisterClass::iterator I = (*RC)->allocation_order_begin(MF), - E = (*RC)->allocation_order_end(MF); I != E; ++I) + for (TargetRegisterClass::iterator I = RC->allocation_order_begin(MF), + E = RC->allocation_order_end(MF); I != E; ++I) if (*I == Reg) - return *RC; + return RC; } return 0; } @@ -1276,7 +1290,7 @@ // Check to see if this register is allocatable (i.e. don't give out the // stack pointer). - const TargetRegisterClass *RC = isAllocatableRegister(Reg, MF, MRI); + const TargetRegisterClass *RC = isAllocatableRegister(Reg, MF, TLI, MRI); if (!RC) { // Make sure we find consecutive registers. NumAllocated = 0; From lattner at cs.uiuc.edu Wed Feb 22 17:54:27 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 17:54:27 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LoopUnswitch/2006-02-22-UnswitchCrash.ll Message-ID: <200602222354.RAA07818@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LoopUnswitch: 2006-02-22-UnswitchCrash.ll added (r1.1) --- Log message: new testcase distilled from SPASS --- Diffs of the changes: (+42 -0) 2006-02-22-UnswitchCrash.ll | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 42 insertions(+) Index: llvm/test/Regression/Transforms/LoopUnswitch/2006-02-22-UnswitchCrash.ll diff -c /dev/null llvm/test/Regression/Transforms/LoopUnswitch/2006-02-22-UnswitchCrash.ll:1.1 *** /dev/null Wed Feb 22 17:54:25 2006 --- llvm/test/Regression/Transforms/LoopUnswitch/2006-02-22-UnswitchCrash.ll Wed Feb 22 17:54:15 2006 *************** *** 0 **** --- 1,42 ---- + ; RUN: llvm-as < %s | opt -loop-unswitch -disable-output + + void %sort_Eq(int * %S2) { + entry: + br bool false, label %list_Length.exit, label %cond_true.i + + cond_true.i: ; preds = %entry + ret void + + list_Length.exit: ; preds = %entry + br bool false, label %list_Length.exit9, label %cond_true.i5 + + cond_true.i5: ; preds = %list_Length.exit + ret void + + list_Length.exit9: ; preds = %list_Length.exit + br bool false, label %bb78, label %return + + bb44: ; preds = %bb78, %cond_next68 + br bool %tmp49.not, label %bb62, label %bb62.loopexit + + bb62.loopexit: ; preds = %bb44 + br label %bb62 + + bb62: ; preds = %bb62.loopexit, %bb44 + br bool false, label %return.loopexit, label %cond_next68 + + cond_next68: ; preds = %bb62 + br bool false, label %return.loopexit, label %bb44 + + bb78: ; preds = %list_Length.exit9 + %tmp49.not = seteq int* %S2, null ; [#uses=1] + br label %bb44 + + return.loopexit: ; preds = %cond_next68, %bb62 + %retval.0.ph = phi uint [ 1, %cond_next68 ], [ 0, %bb62 ] ; [#uses=1] + br label %return + + return: ; preds = %return.loopexit, %list_Length.exit9 + %retval.0 = phi uint [ 0, %list_Length.exit9 ], [ %retval.0.ph, %return.loopexit ] ; [#uses=0] + ret void + } From lattner at cs.uiuc.edu Wed Feb 22 17:55:12 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 17:55:12 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopUnswitch.cpp Message-ID: <200602222355.RAA07856@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopUnswitch.cpp updated: 1.34 -> 1.35 --- Log message: Fix Regression/Transforms/LoopUnswitch/2006-02-22-UnswitchCrash.ll, which caused SPASS to fail building last night. We can't trivially unswitch a loop if the exit block has phi nodes in it, because we don't know which predecessor to use. --- Diffs of the changes: (+3 -1) LoopUnswitch.cpp | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/LoopUnswitch.cpp diff -u llvm/lib/Transforms/Scalar/LoopUnswitch.cpp:1.34 llvm/lib/Transforms/Scalar/LoopUnswitch.cpp:1.35 --- llvm/lib/Transforms/Scalar/LoopUnswitch.cpp:1.34 Wed Feb 22 00:37:14 2006 +++ llvm/lib/Transforms/Scalar/LoopUnswitch.cpp Wed Feb 22 17:55:00 2006 @@ -325,7 +325,9 @@ } } - if (!LoopExitBB) + // If we didn't find a single unique LoopExit block, or if the loop exit block + // contains phi nodes, this isn't trivial. + if (!LoopExitBB || isa(LoopExitBB->begin())) return false; // Can't handle this. if (LoopExit) *LoopExit = LoopExitBB; From evan.cheng at apple.com Wed Feb 22 18:00:10 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 22 Feb 2006 18:00:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Message-ID: <200602230000.SAA07943@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ATTAsmPrinter.cpp updated: 1.24 -> 1.25 --- Log message: Missing .globl for weak / link-once .text symbols. --- Diffs of the changes: (+1 -0) X86ATTAsmPrinter.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.24 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.25 --- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.24 Wed Feb 22 14:19:42 2006 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Wed Feb 22 17:59:57 2006 @@ -51,6 +51,7 @@ if (forDarwin) { SwitchSection(".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F); + O << "\t.globl\t" << CurrentFnName << "\n"; O << "\t.weak_definition\t" << CurrentFnName << "\n"; } else { EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. From evan.cheng at apple.com Wed Feb 22 18:12:24 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 22 Feb 2006 18:12:24 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/lea.ll Message-ID: <200602230012.SAA08098@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: lea.ll added (r1.1) --- Log message: Add a test case for 'lea'. --- Diffs of the changes: (+10 -0) lea.ll | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/test/Regression/CodeGen/X86/lea.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/lea.ll:1.1 *** /dev/null Wed Feb 22 18:12:22 2006 --- llvm/test/Regression/CodeGen/X86/lea.ll Wed Feb 22 18:12:12 2006 *************** *** 0 **** --- 1,10 ---- + ; RUN: llvm-as < %s | llc -march=x86 | grep lea + + %G = weak global int 0 + int %test1(int* %P, int %X) { + %tmp.1 = getelementptr int* %P, int %X + %tmp.2 = load int* %tmp.1 + store int %tmp.2, int* %G + %tmp.3 = sub int %tmp.2, 9 + ret int %tmp.3 + } From evan.cheng at apple.com Wed Feb 22 18:14:10 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 22 Feb 2006 18:14:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200602230014.SAA08139@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.50 -> 1.51 --- Log message: X86 codegen tweak to use lea in another case: Suppose base == %eax and it has multiple uses, then instead of movl %eax, %ecx addl $8, %ecx use leal 8(%eax), %ecx. --- Diffs of the changes: (+12 -9) X86ISelDAGToDAG.cpp | 21 ++++++++++++--------- 1 files changed, 12 insertions(+), 9 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.50 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.51 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.50 Fri Feb 17 18:15:05 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Wed Feb 22 18:13:58 2006 @@ -457,23 +457,19 @@ SDOperand &Index, SDOperand &Disp) { X86ISelAddressMode AM; if (!MatchAddress(N, AM)) { - bool SelectBase = false; bool SelectIndex = false; bool Check = false; if (AM.BaseType == X86ISelAddressMode::RegBase) { - if (AM.Base.Reg.Val) { - Check = true; - SelectBase = true; - } else { + if (AM.Base.Reg.Val) + Check = true; + else AM.Base.Reg = CurDAG->getRegister(0, MVT::i32); - } } - if (AM.IndexReg.Val) { + if (AM.IndexReg.Val) SelectIndex = true; - } else { + else AM.IndexReg = CurDAG->getRegister(0, MVT::i32); - } if (Check) { unsigned Complexity = 0; @@ -485,6 +481,13 @@ Complexity++; else if (AM.Disp > 1) Complexity++; + // Suppose base == %eax and it has multiple uses, then instead of + // movl %eax, %ecx + // addl $8, %ecx + // use + // leal 8(%eax), %ecx. + if (AM.Base.Reg.Val->use_size() > 1) + Complexity++; if (Complexity <= 1) return false; } From evan.cheng at apple.com Wed Feb 22 20:44:04 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 22 Feb 2006 20:44:04 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86AsmPrinter.cpp X86ISelDAGToDAG.cpp X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td X86IntelAsmPrinter.cpp Message-ID: <200602230244.UAA09074@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ATTAsmPrinter.cpp updated: 1.25 -> 1.26 X86AsmPrinter.cpp updated: 1.165 -> 1.166 X86ISelDAGToDAG.cpp updated: 1.51 -> 1.52 X86ISelLowering.cpp updated: 1.94 -> 1.95 X86ISelLowering.h updated: 1.30 -> 1.31 X86InstrInfo.td updated: 1.247 -> 1.248 X86IntelAsmPrinter.cpp updated: 1.18 -> 1.19 --- Log message: PIC related bug fixes. 1. Various asm printer bug. 2. Lowering bug. Now TargetGlobalAddress is wrapped in X86ISD::TGAWrapper. --- Diffs of the changes: (+45 -14) X86ATTAsmPrinter.cpp | 8 ++++---- X86AsmPrinter.cpp | 4 ++-- X86ISelDAGToDAG.cpp | 24 ++++++++++++++++++++++++ X86ISelLowering.cpp | 13 +++++++------ X86ISelLowering.h | 4 ++++ X86InstrInfo.td | 2 ++ X86IntelAsmPrinter.cpp | 4 ++-- 7 files changed, 45 insertions(+), 14 deletions(-) Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.25 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.26 --- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.25 Wed Feb 22 17:59:57 2006 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Wed Feb 22 20:43:52 2006 @@ -134,13 +134,13 @@ } else { GVStubs.insert(Name); O << "L" << Name << "$non_lazy_ptr"; - if (TM.getRelocationModel() == Reloc::PIC) - O << "-\"L" << getFunctionNumber() << "$pb\""; } } else { O << Mang->getValueName(GV); - } - } else + } + if (!isCallOp && TM.getRelocationModel() == Reloc::PIC) + O << "-\"L" << getFunctionNumber() << "$pb\""; + } else O << Mang->getValueName(MO.getGlobal()); int Offset = MO.getOffset(); if (Offset > 0) Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.165 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.166 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.165 Tue Feb 14 19:56:23 2006 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Wed Feb 22 20:43:52 2006 @@ -100,7 +100,7 @@ (forDarwin && I->hasExternalLinkage() && !I->hasSection()))) { if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. if (I->hasExternalLinkage()) { - O << "\t.global\t" << name << "\n"; + O << "\t.globl\t" << name << "\n"; O << "\t.zerofill __DATA__, __common, " << name << ", " << Size << ", " << Align; } else { @@ -119,8 +119,8 @@ if (COMMDirectiveTakesAlignment) O << "," << (AlignmentIsInBytes ? (1 << Align) : Align); } - O << "\t\t" << CommentString << " " << I->getName() << "\n"; } + O << "\t\t" << CommentString << " " << I->getName() << "\n"; } else { switch (I->getLinkage()) { case GlobalValue::LinkOnceLinkage: Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.51 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.52 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.51 Wed Feb 22 18:13:58 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Wed Feb 22 20:43:52 2006 @@ -314,6 +314,13 @@ } break; + case X86ISD::TGAWrapper: + if (AM.GV == 0) { + AM.GV = cast(N.getOperand(0))->getGlobal(); + return false; + } + break; + case ISD::Constant: AM.Disp += cast(N)->getValue(); return false; @@ -486,6 +493,16 @@ // addl $8, %ecx // use // leal 8(%eax), %ecx. + // FIXME: If the other uses ended up being scheduled ahead of the leal + // then it would have been better to use the addl. The proper way to + // handle this is with using X86InstrInfo::convertToThreeAddress hook. + // From an email: + // BTW, this problem is the one that inspired the + // "X86InstrInfo::convertToThreeAddress" hook (which would handle this + // the "right" way). Unfortunately the X86 implementation of this is + // disabled, because we don't currently have enough information handy to + // know that the flags from the add is dead when the hook is called (from + // the register allocator). if (AM.Base.Reg.Val->use_size() > 1) Complexity++; if (Complexity <= 1) @@ -557,6 +574,13 @@ switch (Opcode) { default: break; + case X86ISD::TGAWrapper: { + GlobalValue *GV = cast(N.getOperand(0))->getGlobal(); + SDOperand TGA = CurDAG->getTargetGlobalAddress(GV, MVT::i32); + Result = CodeGenMap[N] = + SDOperand(CurDAG->getTargetNode(X86::MOV32ri, MVT::i32, TGA), 0); + return; + } case ISD::MULHU: case ISD::MULHS: { if (Opcode == ISD::MULHU) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.94 llvm/lib/Target/X86/X86ISelLowering.cpp:1.95 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.94 Wed Feb 22 14:19:42 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Feb 22 20:43:52 2006 @@ -1833,8 +1833,7 @@ SDOperand Result = DAG.getTargetConstantPool(CP->get(), getPointerTy(), CP->getAlignment()); // Only lower ConstantPool on Darwin. - if (getTargetMachine(). - getSubtarget().isTargetDarwin()) { + if (getTargetMachine().getSubtarget().isTargetDarwin()) { // With PIC, the address is actually $g + Offset. if (getTargetMachine().getRelocationModel() == Reloc::PIC) Result = DAG.getNode(ISD::ADD, getPointerTy(), @@ -1849,11 +1848,12 @@ if (getTargetMachine(). getSubtarget().isTargetDarwin()) { GlobalValue *GV = cast(Op)->getGlobal(); - SDOperand Addr = DAG.getTargetGlobalAddress(GV, getPointerTy()); + Result = DAG.getNode(X86ISD::TGAWrapper, getPointerTy(), + DAG.getTargetGlobalAddress(GV, getPointerTy())); // With PIC, the address is actually $g + Offset. if (getTargetMachine().getRelocationModel() == Reloc::PIC) - Addr = DAG.getNode(ISD::ADD, getPointerTy(), - DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Addr); + Result = DAG.getNode(ISD::ADD, getPointerTy(), + DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Result); // For Darwin, external and weak symbols are indirect, so we want to load // the value at address GV, not the value of GV itself. This means that @@ -1863,7 +1863,7 @@ (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || (GV->isExternal() && !GV->hasNotBeenReadFromBytecode()))) Result = DAG.getLoad(MVT::i32, DAG.getEntryNode(), - Addr, DAG.getSrcValue(NULL)); + Result, DAG.getSrcValue(NULL)); } return Result; @@ -1977,6 +1977,7 @@ case X86ISD::REP_MOVS: return "X86ISD::RET_MOVS"; case X86ISD::LOAD_PACK: return "X86ISD::LOAD_PACK"; case X86ISD::GlobalBaseReg: return "X86ISD::GlobalBaseReg"; + case X86ISD::TGAWrapper: return "X86ISD::TGAWrapper"; } } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.30 llvm/lib/Target/X86/X86ISelLowering.h:1.31 --- llvm/lib/Target/X86/X86ISelLowering.h:1.30 Tue Feb 21 18:56:39 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Wed Feb 22 20:43:52 2006 @@ -141,6 +141,10 @@ /// GlobalBaseReg - On Darwin, this node represents the result of the popl /// at function entry, used for PIC code. GlobalBaseReg, + + /// TGAWrapper - A wrapper node for TargetGlobalAddress, only used on + /// Darwin. + TGAWrapper, }; // X86 specific condition code. These correspond to X86_*_COND in Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.247 llvm/lib/Target/X86/X86InstrInfo.td:1.248 --- llvm/lib/Target/X86/X86InstrInfo.td:1.247 Tue Feb 21 20:26:30 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Wed Feb 22 20:43:52 2006 @@ -120,6 +120,8 @@ def X86loadp : SDNode<"X86ISD::LOAD_PACK", SDTLoad, [SDNPHasChain]>; +def X86TGAWrapper : SDNode<"X86ISD::TGAWrapper", SDTIntUnaryOp>; + //===----------------------------------------------------------------------===// // X86 Operand Definitions. // Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.18 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.19 --- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.18 Wed Feb 22 14:19:42 2006 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Wed Feb 22 20:43:52 2006 @@ -128,12 +128,12 @@ } else { GVStubs.insert(Name); O << "L" << Name << "$non_lazy_ptr"; - if (TM.getRelocationModel() == Reloc::PIC) - O << "-\"L" << getFunctionNumber() << "$pb\""; } } else { O << Mang->getValueName(GV); } + if (!isCallOp && TM.getRelocationModel() == Reloc::PIC) + O << "-\"L" << getFunctionNumber() << "$pb\""; } else O << Mang->getValueName(MO.getGlobal()); int Offset = MO.getOffset(); From evan.cheng at apple.com Wed Feb 22 20:50:33 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 22 Feb 2006 20:50:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602230250.UAA09112@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.58 -> 1.59 --- Log message: A couple of new entries. --- Diffs of the changes: (+9 -0) README.txt | 9 +++++++++ 1 files changed, 9 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.58 llvm/lib/Target/X86/README.txt:1.59 --- llvm/lib/Target/X86/README.txt:1.58 Mon Feb 20 13:58:27 2006 +++ llvm/lib/Target/X86/README.txt Wed Feb 22 20:50:21 2006 @@ -497,3 +497,12 @@ ret This will be solved when we go to a dynamic programming based isel. + +//===---------------------------------------------------------------------===// + +Make use of floating point min / max instructions. Perhaps introduce ISD::FMIN +and ISD::FMAX node types? + +//===---------------------------------------------------------------------===// + +Select (add, x, GlobalAddress) to ADD32ri, etc. when it's appropriate. From lattner at cs.uiuc.edu Wed Feb 22 23:17:55 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 23:17:55 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602230517.XAA19769@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.59 -> 1.60 --- Log message: add a small and simple case. --- Diffs of the changes: (+28 -0) README.txt | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.59 llvm/lib/Target/X86/README.txt:1.60 --- llvm/lib/Target/X86/README.txt:1.59 Wed Feb 22 20:50:21 2006 +++ llvm/lib/Target/X86/README.txt Wed Feb 22 23:17:43 2006 @@ -506,3 +506,31 @@ //===---------------------------------------------------------------------===// Select (add, x, GlobalAddress) to ADD32ri, etc. when it's appropriate. + +//===---------------------------------------------------------------------===// + +The first BB of this code: + +declare bool %foo() +int %bar() { + %V = call bool %foo() + br bool %V, label %T, label %F +T: + ret int 1 +F: + call bool %foo() + ret int 12 +} + +compiles to: + +_bar: + subl $12, %esp + call L_foo$stub + xorb $1, %al + testb %al, %al + jne LBB_bar_2 # F + +It would be better to emit "cmp %al, 1" than a xor and test. + + From lattner at cs.uiuc.edu Wed Feb 22 23:25:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 22 Feb 2006 23:25:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86AsmPrinter.cpp Message-ID: <200602230525.XAA20171@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86AsmPrinter.cpp updated: 1.166 -> 1.167 --- Log message: "." isn't enough to get a private label on linux, use ".L". --- Diffs of the changes: (+1 -0) X86AsmPrinter.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.166 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.167 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.166 Wed Feb 22 20:43:52 2006 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Wed Feb 22 23:25:02 2006 @@ -45,6 +45,7 @@ const X86Subtarget *Subtarget = &TM.getSubtarget(); forDarwin = false; + PrivateGlobalPrefix = ".L"; switch (Subtarget->TargetType) { case X86Subtarget::isDarwin: From lattner at cs.uiuc.edu Thu Feb 23 00:44:29 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 00:44:29 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp Message-ID: <200602230644.AAA21479@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLinearScan.cpp updated: 1.118 -> 1.119 --- Log message: Code cleanups, no functionality change --- Diffs of the changes: (+10 -23) RegAllocLinearScan.cpp | 33 ++++++++++----------------------- 1 files changed, 10 insertions(+), 23 deletions(-) Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.118 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.119 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.118 Sun Jan 22 17:39:54 2006 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Thu Feb 23 00:44:17 2006 @@ -651,26 +651,17 @@ IntervalPtrs::iterator it; if ((it = FindIntervalInVector(active_, i)) != active_.end()) { active_.erase(it); - if (MRegisterInfo::isPhysicalRegister(i->reg)) { - assert(0 && "daksjlfd"); - prt_->delRegUse(i->reg); + assert(!MRegisterInfo::isPhysicalRegister(i->reg)); + if (!spilled.count(i->reg)) unhandled_.push(i); - } else { - if (!spilled.count(i->reg)) - unhandled_.push(i); - prt_->delRegUse(vrm_->getPhys(i->reg)); - vrm_->clearVirt(i->reg); - } + prt_->delRegUse(vrm_->getPhys(i->reg)); + vrm_->clearVirt(i->reg); } else if ((it = FindIntervalInVector(inactive_, i)) != inactive_.end()) { inactive_.erase(it); - if (MRegisterInfo::isPhysicalRegister(i->reg)) { - assert(0 && "daksjlfd"); + assert(!MRegisterInfo::isPhysicalRegister(i->reg)); + if (!spilled.count(i->reg)) unhandled_.push(i); - } else { - if (!spilled.count(i->reg)) - unhandled_.push(i); - vrm_->clearVirt(i->reg); - } + vrm_->clearVirt(i->reg); } else { assert(MRegisterInfo::isVirtualRegister(i->reg) && "Can only allocate virtual registers!"); @@ -694,11 +685,8 @@ HI->expiredAt(cur->beginNumber())) { DEBUG(std::cerr << "\t\t\tundo changes for: " << *HI << '\n'); active_.push_back(std::make_pair(HI, HI->begin())); - if (MRegisterInfo::isPhysicalRegister(HI->reg)) { - assert(0 &&"sdflkajsdf"); - prt_->addRegUse(HI->reg); - } else - prt_->addRegUse(vrm_->getPhys(HI->reg)); + assert(!MRegisterInfo::isPhysicalRegister(HI->reg)); + prt_->addRegUse(vrm_->getPhys(HI->reg)); } } @@ -709,8 +697,7 @@ /// getFreePhysReg - return a free physical register for this virtual register /// interval if we have one, otherwise return 0. -unsigned RA::getFreePhysReg(LiveInterval* cur) -{ +unsigned RA::getFreePhysReg(LiveInterval *cur) { std::vector inactiveCounts(mri_->getNumRegs(), 0); unsigned MaxInactiveCount = 0; From lattner at cs.uiuc.edu Thu Feb 23 10:14:44 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 10:14:44 -0600 Subject: [llvm-commits] CVS: llvm/docs/index.html Message-ID: <200602231614.KAA03212@zion.cs.uiuc.edu> Changes in directory llvm/docs: index.html updated: 1.48 -> 1.49 --- Log message: document the llvm-testresults list --- Diffs of the changes: (+6 -1) index.html | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletion(-) Index: llvm/docs/index.html diff -u llvm/docs/index.html:1.48 llvm/docs/index.html:1.49 --- llvm/docs/index.html:1.48 Wed Nov 30 00:35:34 2005 +++ llvm/docs/index.html Thu Feb 23 10:14:22 2006 @@ -233,6 +233,11 @@ want to stay on the bleeding edge of LLVM development. This list is very high volume. +
  • The +testresults Archive: A message is automatically sent to this list by every +active nightly tester when it completes. As such, this list gets email several +times each day, making it a high volume list.
  • + @@ -245,6 +250,6 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/11/30 06:35:34 $ + Last modified: $Date: 2006/02/23 16:14:22 $ From lattner at cs.uiuc.edu Thu Feb 23 10:18:41 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 10:18:41 -0600 Subject: [llvm-commits] CVS: llvm/docs/index.html Message-ID: <200602231618.KAA03282@zion.cs.uiuc.edu> Changes in directory llvm/docs: index.html updated: 1.49 -> 1.50 --- Log message: Match the case of other mailing lists in the list --- Diffs of the changes: (+2 -2) index.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/docs/index.html diff -u llvm/docs/index.html:1.49 llvm/docs/index.html:1.50 --- llvm/docs/index.html:1.49 Thu Feb 23 10:14:22 2006 +++ llvm/docs/index.html Thu Feb 23 10:18:29 2006 @@ -234,7 +234,7 @@ volume.
  • The -testresults Archive: A message is automatically sent to this list by every +Test Results Archive: A message is automatically sent to this list by every active nightly tester when it completes. As such, this list gets email several times each day, making it a high volume list.
  • @@ -250,6 +250,6 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> LLVM Compiler Infrastructure
    - Last modified: $Date: 2006/02/23 16:14:22 $ + Last modified: $Date: 2006/02/23 16:18:29 $ From jlaskey at apple.com Thu Feb 23 10:58:30 2006 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 23 Feb 2006 10:58:30 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp MachineDebugInfo.cpp Message-ID: <200602231658.KAA03498@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.27 -> 1.28 MachineDebugInfo.cpp updated: 1.15 -> 1.16 --- Log message: DwarfWriter reading basic type information from llvm-gcc4 code. --- Diffs of the changes: (+126 -7) DwarfWriter.cpp | 42 +++++++++++++++++++++-- MachineDebugInfo.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 126 insertions(+), 7 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.27 llvm/lib/CodeGen/DwarfWriter.cpp:1.28 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.27 Wed Feb 22 13:02:11 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Thu Feb 23 10:58:18 2006 @@ -1232,7 +1232,40 @@ GlobalEntities[Name] = Entity; } -/// NewCompileUnit - Create new compile unit information. +/// NewType - Create a new type DIE. +/// +DIE *DwarfWriter::NewType(DIE *Unit, TypeDesc *TyDesc) { + // Check for pre-existence. + DIE *&Slot = DescToDieMap[TyDesc]; + if (Slot) return Slot; + + // Get core information. + const std::string &Name = TyDesc->getName(); + // FIXME - handle larger sizes. + unsigned Size = TyDesc->getSize() >> 3; + + // Determine how to handle. + if (BasicTypeDesc *BasicTyDesc = dyn_cast(TyDesc)) { + unsigned Encoding = BasicTyDesc->getEncoding(); + + DIE *Ty = new DIE(DW_TAG_base_type); + if (!Name.empty()) Ty->AddString(DW_AT_name, DW_FORM_string, Name); + + Ty->AddUInt (DW_AT_byte_size, 0, Size); + Ty->AddUInt (DW_AT_encoding, DW_FORM_data1, Encoding); + + Slot = Ty; + } else { + assert(0 && "Type not supported yet"); + } + + // Add to context owner. + Unit->AddChild(Slot); + + return Slot; +} + +/// NewCompileUnit - Create new compile unit DIE. /// DIE *DwarfWriter::NewCompileUnit(CompileUnitDesc *CompileUnit) { // Check for pre-existence. @@ -1275,9 +1308,10 @@ unsigned FileID = DebugInfo->RecordSource(CompileUnit); unsigned Line = GVD->getLine(); - // FIXME - faking the type for the time being. - DIE *Type = NewBasicType(Unit, Type::IntTy); - + // Get the global's type. + DIE *Type = NewType(Unit, GVD->getTypeDesc()); + + // Create the globale variable DIE. DIE *VariableDie = new DIE(DW_TAG_variable); VariableDie->AddString (DW_AT_name, DW_FORM_string, Name); VariableDie->AddUInt (DW_AT_decl_file, 0, FileID); Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.15 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.16 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.15 Wed Feb 22 13:02:11 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Thu Feb 23 10:58:18 2006 @@ -197,6 +197,7 @@ /// virtual void Apply(int &Field) { ++Count; } virtual void Apply(unsigned &Field) { ++Count; } + virtual void Apply(uint64_t &Field) { ++Count; } virtual void Apply(bool &Field) { ++Count; } virtual void Apply(std::string &Field) { ++Count; } virtual void Apply(DebugInfoDesc *&Field) { ++Count; } @@ -230,6 +231,10 @@ Constant *C = CI->getOperand(I++); Field = cast(C)->getValue(); } + virtual void Apply(uint64_t &Field) { + Constant *C = CI->getOperand(I++); + Field = cast(C)->getValue(); + } virtual void Apply(bool &Field) { Constant *C = CI->getOperand(I++); Field = cast(C)->getValue(); @@ -271,6 +276,9 @@ virtual void Apply(unsigned &Field) { Elements.push_back(ConstantUInt::get(Type::UIntTy, Field)); } + virtual void Apply(uint64_t &Field) { + Elements.push_back(ConstantUInt::get(Type::UIntTy, Field)); + } virtual void Apply(bool &Field) { Elements.push_back(ConstantBool::get(Field)); } @@ -327,6 +335,9 @@ virtual void Apply(unsigned &Field) { Fields.push_back(Type::UIntTy); } + virtual void Apply(uint64_t &Field) { + Fields.push_back(Type::UIntTy); + } virtual void Apply(bool &Field) { Fields.push_back(Type::BoolTy); } @@ -377,6 +388,10 @@ Constant *C = CI->getOperand(I++); IsValid = IsValid && isa(C); } + virtual void Apply(uint64_t &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isa(C); + } virtual void Apply(bool &Field) { Constant *C = CI->getOperand(I++); IsValid = IsValid && isa(C); @@ -414,6 +429,7 @@ case DI_TAG_compile_unit: return new CompileUnitDesc(); case DI_TAG_global_variable: return new GlobalVariableDesc(); case DI_TAG_subprogram: return new SubprogramDesc(); + case DI_TAG_basictype: return new BasicTypeDesc(); default: break; } return NULL; @@ -545,6 +561,75 @@ //===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// + +TypeDesc::TypeDesc(unsigned T) +: DebugInfoDesc(T) +, Context(NULL) +, Name("") +, Size(0) +{} + +/// ApplyToFields - Target the visitor to the fields of the TypeDesc. +/// +void TypeDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply(Context); + Visitor->Apply(Name); + Visitor->Apply(Size); +} + +/// getDescString - Return a string used to compose global names and labels. +/// +const char *TypeDesc::getDescString() const { + return "llvm.dbg.type"; +} + +/// getTypeString - Return a string used to label this descriptor's type. +/// +const char *TypeDesc::getTypeString() const { + return "llvm.dbg.type.type"; +} + +#ifndef NDEBUG +void TypeDesc::dump() { + std::cerr << getDescString() << " " + << "Tag(" << getTag() << "), " + << "Context(" << Context << "), " + << "Name(\"" << Name << "\"), " + << "Size(" << Size << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + +BasicTypeDesc::BasicTypeDesc() +: TypeDesc(DI_TAG_basictype) +, Encoding(0) +{} + +/// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc. +/// +void BasicTypeDesc::ApplyToFields(DIVisitor *Visitor) { + TypeDesc::ApplyToFields(Visitor); + + Visitor->Apply(Encoding); +} + +#ifndef NDEBUG +void BasicTypeDesc::dump() { + std::cerr << getDescString() << " " + << "Tag(" << getTag() << "), " + << "Context(" << getContext() << "), " + << "Name(\"" << getName() << "\"), " + << "Size(" << getSize() << "), " + << "Encoding(" << Encoding << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + GlobalDesc::GlobalDesc(unsigned T) : AnchoredDesc(T) , Context(0) @@ -561,7 +646,7 @@ Visitor->Apply(Context); Visitor->Apply(Name); - Visitor->Apply(TyDesc); + Visitor->Apply((DebugInfoDesc *&)TyDesc); Visitor->Apply(IsStatic); Visitor->Apply(IsDefinition); } @@ -606,6 +691,7 @@ << "Tag(" << getTag() << "), " << "Anchor(" << getAnchor() << "), " << "Name(\"" << getName() << "\"), " + << "Type(\"" << getTypeDesc() << "\"), " << "IsStatic(" << (isStatic() ? "true" : "false") << "), " << "IsDefinition(" << (isDefinition() ? "true" : "false") << "), " << "Global(" << Global << "), " @@ -649,13 +735,12 @@ << "Tag(" << getTag() << "), " << "Anchor(" << getAnchor() << "), " << "Name(\"" << getName() << "\"), " + << "Type(\"" << getTypeDesc() << "\"), " << "IsStatic(" << (isStatic() ? "true" : "false") << "), " << "IsDefinition(" << (isDefinition() ? "true" : "false") << ")\n"; } #endif -//===----------------------------------------------------------------------===// - DebugInfoDesc *DIDeserializer::Deserialize(Value *V) { return Deserialize(getGlobalVariable(V)); } From jlaskey at apple.com Thu Feb 23 10:58:31 2006 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 23 Feb 2006 10:58:31 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/DwarfWriter.h MachineDebugInfo.h Message-ID: <200602231658.KAA03504@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: DwarfWriter.h updated: 1.24 -> 1.25 MachineDebugInfo.h updated: 1.17 -> 1.18 --- Log message: DwarfWriter reading basic type information from llvm-gcc4 code. --- Diffs of the changes: (+82 -7) DwarfWriter.h | 13 ++++++--- MachineDebugInfo.h | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 82 insertions(+), 7 deletions(-) Index: llvm/include/llvm/CodeGen/DwarfWriter.h diff -u llvm/include/llvm/CodeGen/DwarfWriter.h:1.24 llvm/include/llvm/CodeGen/DwarfWriter.h:1.25 --- llvm/include/llvm/CodeGen/DwarfWriter.h:1.24 Wed Feb 22 13:02:11 2006 +++ llvm/include/llvm/CodeGen/DwarfWriter.h Thu Feb 23 10:58:18 2006 @@ -43,6 +43,7 @@ class Module; class SubprogramDesc; class Type; + class TypeDesc; //===--------------------------------------------------------------------===// // DWLabel - Labels are used to track locations in the assembler file. @@ -626,6 +627,14 @@ void NewGlobalEntity(const std::string &Name, DIE *Entity); private: + + /// NewType - Create a new type DIE. + /// + DIE *NewType(DIE *Unit, TypeDesc *TyDesc); + + /// NewCompileUnit - Create new compile unit DIE. + /// + DIE *NewCompileUnit(CompileUnitDesc *CompileUnit); /// NewGlobalVariable - Make a new global variable DIE. /// @@ -635,10 +644,6 @@ /// DIE *NewSubprogram(SubprogramDesc *SPD); - /// NewCompileUnit - Create new compile unit information. - /// - DIE *NewCompileUnit(CompileUnitDesc *CompileUnit); - /// EmitInitial - Emit initial Dwarf declarations. /// void EmitInitial() const; Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.17 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.18 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.17 Wed Feb 22 13:02:11 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Thu Feb 23 10:58:18 2006 @@ -61,7 +61,8 @@ DI_TAG_anchor = 0, DI_TAG_compile_unit, DI_TAG_global_variable, - DI_TAG_subprogram + DI_TAG_subprogram, + DI_TAG_basictype }; //===----------------------------------------------------------------------===// @@ -80,6 +81,7 @@ /// appropriate action for the type of field. virtual void Apply(int &Field) = 0; virtual void Apply(unsigned &Field) = 0; + virtual void Apply(uint64_t &Field) = 0; virtual void Apply(bool &Field) = 0; virtual void Apply(std::string &Field) = 0; virtual void Apply(DebugInfoDesc *&Field) = 0; @@ -274,14 +276,80 @@ }; //===----------------------------------------------------------------------===// +/// TypeDesc - This class packages debug information associated with a type. +/// +class TypeDesc : public DebugInfoDesc { +private: + DebugInfoDesc *Context; // Context debug descriptor. + std::string Name; // Type name. + uint64_t Size; // Type size. + +protected: + TypeDesc(unsigned T); + +public: + // Accessors + DebugInfoDesc *getContext() const { return Context; } + const std::string &getName() const { return Name; } + uint64_t getSize() const { return Size; } + void setContext(DebugInfoDesc *C) { Context = C; } + void setName(const std::string &N) { Name = N; } + void setSize(uint64_t S) { Size = S; } + + /// ApplyToFields - Target the visitor to the fields of the TypeDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +/// BasicTypeDesc - This class packages debug information associated with a +/// basic type (eg. int, bool, double.) +class BasicTypeDesc : public TypeDesc { +private: + unsigned Encoding; // Type encoding. + +public: + BasicTypeDesc(); + + // Accessors + unsigned getEncoding() const { return Encoding; } + void setEncoding(unsigned E) { Encoding = E; } + + // Implement isa/cast/dyncast. + static bool classof(const BasicTypeDesc *) { return true; } + static bool classof(const DebugInfoDesc *D) { + return D->getTag() == DI_TAG_basictype; + } + + /// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// /// GlobalDesc - This class is the base descriptor for global functions and /// variables. class GlobalDesc : public AnchoredDesc { private: DebugInfoDesc *Context; // Context debug descriptor. std::string Name; // Global name. - // FIXME - Use a descriptor. - GlobalVariable *TyDesc; // Type debug descriptor. + TypeDesc *TyDesc; // Type debug descriptor. bool IsStatic; // Is the global a static. bool IsDefinition; // Is the global defined in context. @@ -292,10 +360,12 @@ // Accessors DebugInfoDesc *getContext() const { return Context; } const std::string &getName() const { return Name; } + TypeDesc *getTypeDesc() const { return TyDesc; } bool isStatic() const { return IsStatic; } bool isDefinition() const { return IsDefinition; } void setContext(DebugInfoDesc *C) { Context = C; } void setName(const std::string &N) { Name = N; } + void setTypeDesc(TypeDesc *T) { TyDesc = T; } void setIsStatic(bool IS) { IsStatic = IS; } void setIsDefinition(bool ID) { IsDefinition = ID; } From lattner at cs.uiuc.edu Thu Feb 23 13:21:16 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 13:21:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp SelectionDAGISel.cpp Message-ID: <200602231921.NAA04691@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.66 -> 1.67 SelectionDAGISel.cpp updated: 1.168 -> 1.169 --- Log message: Record all of the expanded registers in the DAG and machine instr, fixing several bugs in inline asm expanded operands. --- Diffs of the changes: (+125 -74) ScheduleDAG.cpp | 31 ++++++--- SelectionDAGISel.cpp | 168 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 125 insertions(+), 74 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.66 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.67 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.66 Wed Feb 8 20:23:13 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Thu Feb 23 13:21:04 2006 @@ -309,23 +309,32 @@ MI->addExternalSymbolOperand(AsmStr, false); // Add all of the operand registers to the instruction. - for (unsigned i = 2; i != NumOps; i += 2) { - unsigned Flags =cast(Node->getOperand(i+1))->getValue(); - switch (Flags) { + for (unsigned i = 2; i != NumOps;) { + unsigned Flags = cast(Node->getOperand(i))->getValue(); + unsigned NumOps = Flags >> 3; + + MI->addZeroExtImm64Operand(NumOps); + ++i; // Skip the ID value. + + switch (Flags & 7) { default: assert(0 && "Bad flags!"); - case 1: { // Use of register. - unsigned Reg = cast(Node->getOperand(i))->getReg(); - MI->addMachineRegOperand(Reg, MachineOperand::Use); + case 1: // Use of register. + for (; NumOps; --NumOps, ++i) { + unsigned Reg = cast(Node->getOperand(i))->getReg(); + MI->addMachineRegOperand(Reg, MachineOperand::Use); + } break; - } - case 2: { // Def of register. - unsigned Reg = cast(Node->getOperand(i))->getReg(); - MI->addMachineRegOperand(Reg, MachineOperand::Def); + case 2: // Def of register. + for (; NumOps; --NumOps, ++i) { + unsigned Reg = cast(Node->getOperand(i))->getReg(); + MI->addMachineRegOperand(Reg, MachineOperand::Def); + } break; - } case 3: { // Immediate. + assert(NumOps == 1 && "Unknown immediate value!"); uint64_t Val = cast(Node->getOperand(i))->getValue(); MI->addZeroExtImm64Operand(Val); + ++i; break; } } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.168 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.169 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.168 Wed Feb 22 17:09:03 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Feb 23 13:21:04 2006 @@ -113,6 +113,18 @@ /// Chain/Flag as the input and updates them for the output Chain/Flag. SDOperand getCopyFromRegs(SelectionDAG &DAG, SDOperand &Chain, SDOperand &Flag); + + /// getCopyToRegs - Emit a series of CopyToReg nodes that copies the + /// specified value into the registers specified by this object. This uses + /// Chain/Flag as the input and updates them for the output Chain/Flag. + void getCopyToRegs(SDOperand Val, SelectionDAG &DAG, + SDOperand &Chain, SDOperand &Flag); + + /// AddInlineAsmOperands - Add this value to the specified inlineasm node + /// operand list. This adds the code marker and includes the number of + /// values added into it. + void AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG, + std::vector &Ops); }; } @@ -1195,7 +1207,41 @@ return DAG.getNode(ISD::FP_ROUND, ValueVT, Val); } +/// getCopyToRegs - Emit a series of CopyToReg nodes that copies the +/// specified value into the registers specified by this object. This uses +/// Chain/Flag as the input and updates them for the output Chain/Flag. +void RegsForValue::getCopyToRegs(SDOperand Val, SelectionDAG &DAG, + SDOperand &Chain, SDOperand &Flag) { + if (Regs.size() == 1) { + // If there is a single register and the types differ, this must be + // a promotion. + if (RegVT != ValueVT) { + if (MVT::isInteger(RegVT)) + Val = DAG.getNode(ISD::ANY_EXTEND, RegVT, Val); + else + Val = DAG.getNode(ISD::FP_EXTEND, RegVT, Val); + } + Chain = DAG.getCopyToReg(Chain, Regs[0], Val, Flag); + Flag = Chain.getValue(1); + } else { + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + SDOperand Part = DAG.getNode(ISD::EXTRACT_ELEMENT, RegVT, Val, + DAG.getConstant(i, MVT::i32)); + Chain = DAG.getCopyToReg(Chain, Regs[i], Part, Flag); + Flag = Chain.getValue(1); + } + } +} +/// AddInlineAsmOperands - Add this value to the specified inlineasm node +/// operand list. This adds the code marker and includes the number of +/// values added into it. +void RegsForValue::AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG, + std::vector &Ops) { + Ops.push_back(DAG.getConstant(Code | (Regs.size() << 3), MVT::i32)); + for (unsigned i = 0, e = Regs.size(); i != e; ++i) + Ops.push_back(DAG.getRegister(Regs[i], RegVT)); +} /// isAllocatableRegister - If the specified register is safe to allocate, /// i.e. it isn't a stack pointer or some other special register, return the @@ -1453,96 +1499,92 @@ // Add information to the INLINEASM node to know that this register is // set. - - // FIXME: - // FIXME: Handle multiple regs here. - // FIXME: - unsigned DestReg = Regs.Regs[0]; - AsmNodeOperands.push_back(DAG.getRegister(DestReg, Regs.RegVT)); - AsmNodeOperands.push_back(DAG.getConstant(2, MVT::i32)); // ISDEF + Regs.AddInlineAsmOperands(2 /*REGDEF*/, DAG, AsmNodeOperands); break; } case InlineAsm::isInput: { Value *CallOperand = I.getOperand(OpNum); OpNum++; // Consumes a call operand. - SDOperand ResOp; - unsigned ResOpType; SDOperand InOperandVal = getValue(CallOperand); if (isdigit(ConstraintCode[0])) { // Matching constraint? // If this is required to match an output register we have already set, // just use its register. unsigned OperandNo = atoi(ConstraintCode.c_str()); - unsigned SrcReg; - SrcReg = cast(AsmNodeOperands[OperandNo*2+2])->getReg(); - ResOp = DAG.getRegister(SrcReg, ConstraintVTs[i]); - ResOpType = 1; - Chain = DAG.getCopyToReg(Chain, SrcReg, InOperandVal, Flag); - Flag = Chain.getValue(1); + // Scan until we find the definition we already emitted of this operand. + // When we find it, create a RegsForValue operand. + unsigned CurOp = 2; // The first operand. + for (; OperandNo; --OperandNo) { + // Advance to the next operand. + unsigned NumOps = + cast(AsmNodeOperands[CurOp])->getValue(); + assert((NumOps & 7) == 2 /*REGDEF*/ && + "Skipped past definitions?"); + CurOp += (NumOps>>3)+1; + } + + unsigned NumOps = + cast(AsmNodeOperands[CurOp])->getValue(); + assert((NumOps & 7) == 2 /*REGDEF*/ && + "Skipped past definitions?"); + + // Add NumOps>>3 registers to MatchedRegs. + RegsForValue MatchedRegs; + MatchedRegs.ValueVT = InOperandVal.getValueType(); + MatchedRegs.RegVT = AsmNodeOperands[CurOp+1].getValueType(); + for (unsigned i = 0, e = NumOps>>3; i != e; ++i) { + unsigned Reg=cast(AsmNodeOperands[++CurOp])->getReg(); + MatchedRegs.Regs.push_back(Reg); + } + + // Use the produced MatchedRegs object to + MatchedRegs.getCopyToRegs(InOperandVal, DAG, Chain, Flag); + MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands); } else { TargetLowering::ConstraintType CTy = TargetLowering::C_RegisterClass; if (ConstraintCode.size() == 1) // not a physreg name. CTy = TLI.getConstraintType(ConstraintCode[0]); - switch (CTy) { - default: assert(0 && "Unknown constraint type! FAIL!"); - case TargetLowering::C_RegisterClass: { - // Copy the input into the appropriate registers. - RegsForValue InRegs = - GetRegistersForValue(ConstraintCode, ConstraintVTs[i], - false, true, OutputRegs, InputRegs); - // FIXME: should be match fail. - assert(!InRegs.Regs.empty() && "Couldn't allocate input reg!"); - - if (InRegs.Regs.size() == 1) { - // If there is a single register and the types differ, this must be - // a promotion. - if (InRegs.RegVT != InRegs.ValueVT) { - if (MVT::isInteger(InRegs.RegVT)) - InOperandVal = DAG.getNode(ISD::ANY_EXTEND, InRegs.RegVT, - InOperandVal); - else - InOperandVal = DAG.getNode(ISD::FP_EXTEND, InRegs.RegVT, - InOperandVal); - } - Chain = DAG.getCopyToReg(Chain, InRegs.Regs[0], InOperandVal, Flag); - Flag = Chain.getValue(1); - - ResOp = DAG.getRegister(InRegs.Regs[0], InRegs.RegVT); - } else { - for (unsigned i = 0, e = InRegs.Regs.size(); i != e; ++i) { - SDOperand Part = DAG.getNode(ISD::EXTRACT_ELEMENT, InRegs.RegVT, - InOperandVal, - DAG.getConstant(i, MVT::i32)); - Chain = DAG.getCopyToReg(Chain, InRegs.Regs[i], Part, Flag); - Flag = Chain.getValue(1); - } - ResOp = DAG.getRegister(InRegs.Regs[0], InRegs.RegVT); - } - - ResOpType = 1; - break; - } - case TargetLowering::C_Other: + if (CTy == TargetLowering::C_Other) { if (!TLI.isOperandValidForConstraint(InOperandVal, ConstraintCode[0])) assert(0 && "MATCH FAIL!"); - ResOp = InOperandVal; - ResOpType = 3; + + // Add information to the INLINEASM node to know about this input. + unsigned ResOpType = 3 /*imm*/ | (1 << 3); + AsmNodeOperands.push_back(DAG.getConstant(ResOpType, MVT::i32)); + AsmNodeOperands.push_back(InOperandVal); break; } + + assert(CTy == TargetLowering::C_RegisterClass && "Unknown op type!"); + + // Copy the input into the appropriate registers. + RegsForValue InRegs = + GetRegistersForValue(ConstraintCode, ConstraintVTs[i], + false, true, OutputRegs, InputRegs); + // FIXME: should be match fail. + assert(!InRegs.Regs.empty() && "Couldn't allocate input reg!"); + + InRegs.getCopyToRegs(InOperandVal, DAG, Chain, Flag); + + InRegs.AddInlineAsmOperands(1/*REGUSE*/, DAG, AsmNodeOperands); + break; } - - // Add information to the INLINEASM node to know about this input. - AsmNodeOperands.push_back(ResOp); - AsmNodeOperands.push_back(DAG.getConstant(ResOpType, MVT::i32)); break; } - case InlineAsm::isClobber: - // Nothing to do. + case InlineAsm::isClobber: { + RegsForValue ClobberedRegs = + GetRegistersForValue(ConstraintCode, MVT::Other, false, false, + OutputRegs, InputRegs); + // Add the clobbered value to the operand list, so that the register + // allocator is aware that the physreg got clobbered. + if (!ClobberedRegs.Regs.empty()) + ClobberedRegs.AddInlineAsmOperands(2/*REGDEF*/, DAG, AsmNodeOperands); break; } + } } // Finish up input operands. From lattner at cs.uiuc.edu Thu Feb 23 13:21:16 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 13:21:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200602231921.NAA04695@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.52 -> 1.53 --- Log message: Record all of the expanded registers in the DAG and machine instr, fixing several bugs in inline asm expanded operands. --- Diffs of the changes: (+12 -5) AsmPrinter.cpp | 17 ++++++++++++----- 1 files changed, 12 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.52 llvm/lib/CodeGen/AsmPrinter.cpp:1.53 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.52 Wed Feb 8 22:46:04 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Thu Feb 23 13:21:04 2006 @@ -569,19 +569,26 @@ exit(1); } - char ExtraCode = 0; // FIXME: - - // Okay, we finally have an operand number. Ask the target to print this + // Okay, we finally have a value number. Ask the target to print this // operand! - if (CurVariant == -1 || CurVariant == AsmPrinterVariant) + if (CurVariant == -1 || CurVariant == AsmPrinterVariant) { + unsigned OpNo = 1; + + // Scan to find the machine operand number for the operand. + for (; Val; --Val) + OpNo += MI->getOperand(OpNo).getImmedValue()+1; + + ++OpNo; // Skip over the ID number. + if (const_cast(this)-> - PrintAsmOperand(MI, Val+1, AsmPrinterVariant, + PrintAsmOperand(MI, OpNo, AsmPrinterVariant, Modifier[0] ? Modifier : 0)) { std::cerr << "Invalid operand found in inline asm: '" << AsmStr << "'\n"; MI->dump(); exit(1); } + } break; } case '{': From lattner at cs.uiuc.edu Thu Feb 23 13:31:22 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 13:31:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200602231931.NAA04867@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.154 -> 1.155 --- Log message: Implement the PPC inline asm "L" modifier. This allows us to compile: long long test(long long X) { __asm__("foo %0 %L0 %1 %L1" : "=r"(X): "r"(X)); return X; } to: foo r2 r3 r2 r3 --- Diffs of the changes: (+28 -4) PPCAsmPrinter.cpp | 32 ++++++++++++++++++++++++++++---- 1 files changed, 28 insertions(+), 4 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.154 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.155 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.154 Wed Feb 22 14:19:42 2006 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Thu Feb 23 13:31:10 2006 @@ -97,10 +97,7 @@ } bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode) { - printOperand(MI, OpNo); - return false; - } + unsigned AsmVariant, const char *ExtraCode); void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo) { unsigned char value = MI->getOperand(OpNo).getImmedValue(); @@ -396,6 +393,33 @@ } } +/// PrintAsmOperand - Print out an operand for an inline asm expression. +/// +bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, + const char *ExtraCode) { + // Does this asm operand have a single letter operand modifier? + if (ExtraCode && ExtraCode[0]) { + if (ExtraCode[1] != 0) return true; // Unknown modifier. + + switch (ExtraCode[0]) { + default: return true; // Unknown modifier. + case 'L': // Write second word of DImode reference. + // Verify that this operand has two consecutive registers. + if (!MI->getOperand(OpNo).isRegister() || + OpNo+1 == MI->getNumOperands() || + !MI->getOperand(OpNo+1).isRegister()) + return true; + ++OpNo; // Return the high-part. + break; + } + } + + printOperand(MI, OpNo); + return false; +} + + /// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to /// the current output stream. /// From lattner at cs.uiuc.edu Thu Feb 23 14:07:10 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 14:07:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200602232007.OAA05216@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.169 -> 1.170 --- Log message: Fix an endianness problem on big-endian targets with expanded operands to inline asms. Mark some methods const. --- Diffs of the changes: (+16 -9) SelectionDAGISel.cpp | 25 ++++++++++++++++--------- 1 files changed, 16 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.169 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.170 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.169 Thu Feb 23 13:21:04 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Feb 23 14:06:57 2006 @@ -112,19 +112,19 @@ /// this value and returns the result as a ValueVT value. This uses /// Chain/Flag as the input and updates them for the output Chain/Flag. SDOperand getCopyFromRegs(SelectionDAG &DAG, - SDOperand &Chain, SDOperand &Flag); + SDOperand &Chain, SDOperand &Flag) const; /// getCopyToRegs - Emit a series of CopyToReg nodes that copies the /// specified value into the registers specified by this object. This uses /// Chain/Flag as the input and updates them for the output Chain/Flag. void getCopyToRegs(SDOperand Val, SelectionDAG &DAG, - SDOperand &Chain, SDOperand &Flag); + SDOperand &Chain, SDOperand &Flag) const; /// AddInlineAsmOperands - Add this value to the specified inlineasm node /// operand list. This adds the code marker and includes the number of /// values added into it. void AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG, - std::vector &Ops); + std::vector &Ops) const; }; } @@ -1181,7 +1181,7 @@ } SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG, - SDOperand &Chain, SDOperand &Flag) { + SDOperand &Chain, SDOperand &Flag)const{ SDOperand Val = DAG.getCopyFromReg(Chain, Regs[0], RegVT, Flag); Chain = Val.getValue(1); Flag = Val.getValue(2); @@ -1193,7 +1193,10 @@ SDOperand Hi = DAG.getCopyFromReg(Chain, Regs[1], RegVT, Flag); Chain = Val.getValue(1); Flag = Val.getValue(2); - return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Val, Hi); + if (DAG.getTargetLoweringInfo().isLittleEndian()) + return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Val, Hi); + else + return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Hi, Val); } // Otherwise, if the return value was promoted, truncate it to the @@ -1211,7 +1214,7 @@ /// specified value into the registers specified by this object. This uses /// Chain/Flag as the input and updates them for the output Chain/Flag. void RegsForValue::getCopyToRegs(SDOperand Val, SelectionDAG &DAG, - SDOperand &Chain, SDOperand &Flag) { + SDOperand &Chain, SDOperand &Flag) const { if (Regs.size() == 1) { // If there is a single register and the types differ, this must be // a promotion. @@ -1224,10 +1227,14 @@ Chain = DAG.getCopyToReg(Chain, Regs[0], Val, Flag); Flag = Chain.getValue(1); } else { - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + std::vector R(Regs); + if (!DAG.getTargetLoweringInfo().isLittleEndian()) + std::reverse(R.begin(), R.end()); + + for (unsigned i = 0, e = R.size(); i != e; ++i) { SDOperand Part = DAG.getNode(ISD::EXTRACT_ELEMENT, RegVT, Val, DAG.getConstant(i, MVT::i32)); - Chain = DAG.getCopyToReg(Chain, Regs[i], Part, Flag); + Chain = DAG.getCopyToReg(Chain, R[i], Part, Flag); Flag = Chain.getValue(1); } } @@ -1237,7 +1244,7 @@ /// operand list. This adds the code marker and includes the number of /// values added into it. void RegsForValue::AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG, - std::vector &Ops) { + std::vector &Ops) const { Ops.push_back(DAG.getConstant(Code | (Regs.size() << 3), MVT::i32)); for (unsigned i = 0, e = Regs.size(); i != e; ++i) Ops.push_back(DAG.getRegister(Regs[i], RegVT)); From evan.cheng at apple.com Thu Feb 23 14:41:30 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 23 Feb 2006 14:41:30 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td Message-ID: <200602232041.OAA05516@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.52 -> 1.53 X86ISelLowering.cpp updated: 1.95 -> 1.96 X86ISelLowering.h updated: 1.31 -> 1.32 X86InstrInfo.td updated: 1.248 -> 1.249 --- Log message: - Clean up the lowering and selection code of ConstantPool, GlobalAddress, and ExternalSymbol. - Use C++ code (rather than tblgen'd selection code) to match the above mentioned leaf nodes. Do not mutate and nodes and do not record the selection in CodeGenMap. These nodes should be safe to duplicate. This is a performance win. --- Diffs of the changes: (+81 -37) X86ISelDAGToDAG.cpp | 71 +++++++++++++++++++++++++++++++++++++++------------- X86ISelLowering.cpp | 31 ++++++++++++++++------ X86ISelLowering.h | 6 ++-- X86InstrInfo.td | 10 +------ 4 files changed, 81 insertions(+), 37 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.52 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.53 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.52 Wed Feb 22 20:43:52 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Thu Feb 23 14:41:18 2006 @@ -295,7 +295,6 @@ break; case ISD::ConstantPool: - case ISD::TargetConstantPool: if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) { if (ConstantPoolSDNode *CP = dyn_cast(N)) { AM.BaseType = X86ISelAddressMode::ConstantPoolBase; @@ -307,17 +306,27 @@ break; case ISD::GlobalAddress: - case ISD::TargetGlobalAddress: if (AM.GV == 0) { AM.GV = cast(N)->getGlobal(); return false; } break; - case X86ISD::TGAWrapper: - if (AM.GV == 0) { - AM.GV = cast(N.getOperand(0))->getGlobal(); - return false; + case X86ISD::Wrapper: + if (ConstantPoolSDNode *CP = + dyn_cast(N.getOperand(0))) { + if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) { + AM.BaseType = X86ISelAddressMode::ConstantPoolBase; + AM.Base.Reg = CurDAG->getTargetConstantPool(CP->get(), MVT::i32, + CP->getAlignment()); + return false; + } + } else if (GlobalAddressSDNode *G = + dyn_cast(N.getOperand(0))) { + if (AM.GV == 0) { + AM.GV = cast(N.getOperand(0))->getGlobal(); + return false; + } } break; @@ -484,9 +493,11 @@ Complexity++; if (SelectIndex) Complexity++; - if (AM.GV) + if (AM.GV) { Complexity++; - else if (AM.Disp > 1) + if (AM.Disp) + Complexity++; + } else if (AM.Disp > 1) Complexity++; // Suppose base == %eax and it has multiple uses, then instead of // movl %eax, %ecx @@ -574,13 +585,43 @@ switch (Opcode) { default: break; - case X86ISD::TGAWrapper: { - GlobalValue *GV = cast(N.getOperand(0))->getGlobal(); - SDOperand TGA = CurDAG->getTargetGlobalAddress(GV, MVT::i32); - Result = CodeGenMap[N] = - SDOperand(CurDAG->getTargetNode(X86::MOV32ri, MVT::i32, TGA), 0); + case X86ISD::GlobalBaseReg: + Result = getGlobalBaseReg(); + return; + + case X86ISD::Wrapper: { + // It's beneficial to manully select the wrapper nodes here rather + // then using tablgen'd code to match this. We do not want to mutate the + // node to MOV32ri and we do not want to record this in CodeGenMap. + // We want to allow the wrapped leaf nodes be duplicated so they can + // be used in addressing modes. + // e.g. + // 0xa59e4a0: i32 = TargetGlobalAddress 0 + // 0xa59e740: i32 = X86ISD::Wrapper 0xa59e4a0 + // ... + // 0xa59e880: i32 = add 0xa59e740, 0xa59e800 + // ... + // 0xa59e880: + // 0xa59e970: i32 = add 0xa59e880, 0xa59e910 + // ... + // 0xa59ea60: i32,ch = load 0xa589780, 0xa59e970, 0xa59ea00 + // ... + // 0xa59e880: + // 0xa59eb60: ch = CopyToReg 0xa59ea60:1, 0xa59eaf0, 0xa59e880 + // By allowing the TargetGlobalAddress to be duplicated, it can appear + // in the load address as well as an operand of the add. + Result = SDOperand(CurDAG->getTargetNode(X86::MOV32ri, MVT::i32, + N.getOperand(0)), 0); +#ifndef NDEBUG + DEBUG(std::cerr << std::string(Indent-2, ' ')); + DEBUG(std::cerr << "== "); + DEBUG(Result.Val->dump(CurDAG)); + DEBUG(std::cerr << "\n"); + Indent -= 2; +#endif return; } + case ISD::MULHU: case ISD::MULHS: { if (Opcode == ISD::MULHU) @@ -666,10 +707,6 @@ return; } - case X86ISD::GlobalBaseReg: - Result = getGlobalBaseReg(); - return; - case ISD::SDIV: case ISD::UDIV: case ISD::SREM: Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.95 llvm/lib/Target/X86/X86ISelLowering.cpp:1.96 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.95 Wed Feb 22 20:43:52 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu Feb 23 14:41:18 2006 @@ -165,6 +165,7 @@ // Darwin ABI issue. setOperationAction(ISD::ConstantPool , MVT::i32 , Custom); setOperationAction(ISD::GlobalAddress , MVT::i32 , Custom); + setOperationAction(ISD::ExternalSymbol , MVT::i32 , Custom); // 64-bit addm sub, shl, sra, srl (iff 32-bit x86) setOperationAction(ISD::SHL_PARTS , MVT::i32 , Custom); setOperationAction(ISD::SRA_PARTS , MVT::i32 , Custom); @@ -1830,9 +1831,9 @@ } case ISD::ConstantPool: { ConstantPoolSDNode *CP = cast(Op); - SDOperand Result = - DAG.getTargetConstantPool(CP->get(), getPointerTy(), CP->getAlignment()); - // Only lower ConstantPool on Darwin. + SDOperand Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), + DAG.getTargetConstantPool(CP->get(), getPointerTy(), + CP->getAlignment())); if (getTargetMachine().getSubtarget().isTargetDarwin()) { // With PIC, the address is actually $g + Offset. if (getTargetMachine().getRelocationModel() == Reloc::PIC) @@ -1843,13 +1844,11 @@ return Result; } case ISD::GlobalAddress: { - SDOperand Result; - // Only lower GlobalAddress on Darwin. + GlobalValue *GV = cast(Op)->getGlobal(); + SDOperand Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), + DAG.getTargetGlobalAddress(GV, getPointerTy())); if (getTargetMachine(). getSubtarget().isTargetDarwin()) { - GlobalValue *GV = cast(Op)->getGlobal(); - Result = DAG.getNode(X86ISD::TGAWrapper, getPointerTy(), - DAG.getTargetGlobalAddress(GV, getPointerTy())); // With PIC, the address is actually $g + Offset. if (getTargetMachine().getRelocationModel() == Reloc::PIC) Result = DAG.getNode(ISD::ADD, getPointerTy(), @@ -1868,6 +1867,20 @@ return Result; } + case ISD::ExternalSymbol: { + const char *Sym = cast(Op)->getSymbol(); + SDOperand Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), + DAG.getTargetExternalSymbol(Sym, getPointerTy())); + if (getTargetMachine(). + getSubtarget().isTargetDarwin()) { + // With PIC, the address is actually $g + Offset. + if (getTargetMachine().getRelocationModel() == Reloc::PIC) + Result = DAG.getNode(ISD::ADD, getPointerTy(), + DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Result); + } + + return Result; + } case ISD::VASTART: { // vastart just stores the address of the VarArgsFrameIndex slot into the // memory location argument. @@ -1977,7 +1990,7 @@ case X86ISD::REP_MOVS: return "X86ISD::RET_MOVS"; case X86ISD::LOAD_PACK: return "X86ISD::LOAD_PACK"; case X86ISD::GlobalBaseReg: return "X86ISD::GlobalBaseReg"; - case X86ISD::TGAWrapper: return "X86ISD::TGAWrapper"; + case X86ISD::Wrapper: return "X86ISD::Wrapper"; } } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.31 llvm/lib/Target/X86/X86ISelLowering.h:1.32 --- llvm/lib/Target/X86/X86ISelLowering.h:1.31 Wed Feb 22 20:43:52 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Thu Feb 23 14:41:18 2006 @@ -142,9 +142,9 @@ /// at function entry, used for PIC code. GlobalBaseReg, - /// TGAWrapper - A wrapper node for TargetGlobalAddress, only used on - /// Darwin. - TGAWrapper, + /// TCPWrapper - A wrapper node for TargetConstantPool, + /// TargetExternalSymbol, and TargetGlobalAddress. + Wrapper, }; // X86 specific condition code. These correspond to X86_*_COND in Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.248 llvm/lib/Target/X86/X86InstrInfo.td:1.249 --- llvm/lib/Target/X86/X86InstrInfo.td:1.248 Wed Feb 22 20:43:52 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Thu Feb 23 14:41:18 2006 @@ -117,11 +117,9 @@ def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc, [SDNPHasChain, SDNPOutFlag]>; -def X86loadp : SDNode<"X86ISD::LOAD_PACK", SDTLoad, +def X86loadp : SDNode<"X86ISD::LOAD_PACK", SDTLoad, [SDNPHasChain]>; -def X86TGAWrapper : SDNode<"X86ISD::TGAWrapper", SDTIntUnaryOp>; - //===----------------------------------------------------------------------===// // X86 Operand Definitions. // @@ -167,7 +165,7 @@ // Define X86 specific addressing mode. def addr : ComplexPattern; def leaaddr : ComplexPattern; + [add, frameindex]>; //===----------------------------------------------------------------------===// // X86 Instruction Format Definitions. @@ -2354,10 +2352,6 @@ // Non-Instruction Patterns //===----------------------------------------------------------------------===// -// GlobalAddress and ExternalSymbol -def : Pat<(i32 globaladdr:$dst), (MOV32ri tglobaladdr:$dst)>; -def : Pat<(i32 externalsym:$dst), (MOV32ri texternalsym:$dst)>; - // Calls def : Pat<(X86call tglobaladdr:$dst), (CALLpcrel32 tglobaladdr:$dst)>; From lattner at cs.uiuc.edu Thu Feb 23 15:39:50 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 15:39:50 -0600 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/Makefile.spec Message-ID: <200602232139.PAA06861@zion.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC: Makefile.spec updated: 1.49 -> 1.50 --- Log message: Add support for .cpp files --- Diffs of the changes: (+4 -2) Makefile.spec | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm-test/External/SPEC/Makefile.spec diff -u llvm-test/External/SPEC/Makefile.spec:1.49 llvm-test/External/SPEC/Makefile.spec:1.50 --- llvm-test/External/SPEC/Makefile.spec:1.49 Sun May 8 18:39:14 2005 +++ llvm-test/External/SPEC/Makefile.spec Thu Feb 23 15:39:38 2006 @@ -30,8 +30,10 @@ PROG := $(BENCH_NAME) ifndef Source -Source := $(wildcard $(SPEC_BENCH_DIR)/src/*.c $(SPEC_BENCH_DIR)/src/*.cc) -Source += $(wildcard $(SPEC_BENCH_DIR)/src/*.f) +Source := $(wildcard $(SPEC_BENCH_DIR)/src/*.c \ + $(SPEC_BENCH_DIR)/src/*.cc) \ + $(SPEC_BENCH_DIR)/src/*.cpp) \ + $(SPEC_BENCH_DIR)/src/*.f) endif # Disable the default Output/%.out-* targets... From lattner at cs.uiuc.edu Thu Feb 23 15:46:02 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 15:46:02 -0600 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/Makefile.spec Message-ID: <200602232146.PAA07011@zion.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC: Makefile.spec updated: 1.50 -> 1.51 --- Log message: fix a typo --- Diffs of the changes: (+3 -3) Makefile.spec | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm-test/External/SPEC/Makefile.spec diff -u llvm-test/External/SPEC/Makefile.spec:1.50 llvm-test/External/SPEC/Makefile.spec:1.51 --- llvm-test/External/SPEC/Makefile.spec:1.50 Thu Feb 23 15:39:38 2006 +++ llvm-test/External/SPEC/Makefile.spec Thu Feb 23 15:45:50 2006 @@ -31,9 +31,9 @@ PROG := $(BENCH_NAME) ifndef Source Source := $(wildcard $(SPEC_BENCH_DIR)/src/*.c \ - $(SPEC_BENCH_DIR)/src/*.cc) \ - $(SPEC_BENCH_DIR)/src/*.cpp) \ - $(SPEC_BENCH_DIR)/src/*.f) + $(SPEC_BENCH_DIR)/src/*.cc \ + $(SPEC_BENCH_DIR)/src/*.cpp \ + $(SPEC_BENCH_DIR)/src/*.f) endif # Disable the default Output/%.out-* targets... From evan.cheng at apple.com Thu Feb 23 16:18:19 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 23 Feb 2006 16:18:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCTargetMachine.cpp Message-ID: <200602232218.QAA12352@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCTargetMachine.cpp updated: 1.80 -> 1.81 --- Log message: PPC JIT relocation model should be DynamicNoPIC. --- Diffs of the changes: (+2 -2) PPCTargetMachine.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.80 llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.81 --- llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.80 Wed Feb 22 14:19:42 2006 +++ llvm/lib/Target/PowerPC/PPCTargetMachine.cpp Thu Feb 23 16:18:07 2006 @@ -134,8 +134,8 @@ } void PPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) { - // The JIT should use static relocation model. - TM.setRelocationModel(Reloc::Static); + // The JIT should use dynamic-no-pic relocation model. + TM.setRelocationModel(Reloc::DynamicNoPIC); // Run loop strength reduction before anything else. PM.add(createLoopStrengthReducePass()); From jlaskey at apple.com Thu Feb 23 16:37:43 2006 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 23 Feb 2006 16:37:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp MachineDebugInfo.cpp Message-ID: <200602232237.QAA12700@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.28 -> 1.29 MachineDebugInfo.cpp updated: 1.16 -> 1.17 --- Log message: Added basic support for typedefs. --- Diffs of the changes: (+56 -15) DwarfWriter.cpp | 37 ++++++++++++++++++++++++------------- MachineDebugInfo.cpp | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 15 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.28 llvm/lib/CodeGen/DwarfWriter.cpp:1.29 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.28 Thu Feb 23 10:58:18 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Thu Feb 23 16:37:30 2006 @@ -1244,23 +1244,34 @@ // FIXME - handle larger sizes. unsigned Size = TyDesc->getSize() >> 3; - // Determine how to handle. - if (BasicTypeDesc *BasicTyDesc = dyn_cast(TyDesc)) { - unsigned Encoding = BasicTyDesc->getEncoding(); + DIE *Ty = NULL; - DIE *Ty = new DIE(DW_TAG_base_type); - if (!Name.empty()) Ty->AddString(DW_AT_name, DW_FORM_string, Name); - - Ty->AddUInt (DW_AT_byte_size, 0, Size); - Ty->AddUInt (DW_AT_encoding, DW_FORM_data1, Encoding); - - Slot = Ty; - } else { - assert(0 && "Type not supported yet"); + // Determine how to handle. + if (BasicTypeDesc *BasicTy = dyn_cast(TyDesc)) { + Slot = Ty = new DIE(DW_TAG_base_type); + unsigned Encoding = BasicTy->getEncoding(); + Ty->AddUInt (DW_AT_encoding, DW_FORM_data1, Encoding); + } else if (TypedefDesc *TypedefTy = dyn_cast(TyDesc)) { + Slot = Ty = new DIE(DW_TAG_typedef); + TypeDesc *FromTy = TypedefTy->getFromType(); + DIE *FromTyDie = NewType(Unit, FromTy); + CompileUnitDesc *File = TypedefTy->getFile(); + unsigned FileID = DebugInfo->RecordSource(File); + int Line = TypedefTy->getLine(); + + Ty->AddDIEntry(DW_AT_type, DW_FORM_ref4, FromTyDie); + Ty->AddUInt (DW_AT_decl_file, 0, FileID); + Ty->AddUInt (DW_AT_decl_line, 0, Line); } + + assert(Ty && "Type not supported yet"); + // Add common information. + if (Size) Ty->AddUInt(DW_AT_byte_size, 0, Size); + if (!Name.empty()) Ty->AddString(DW_AT_name, DW_FORM_string, Name); + // Add to context owner. - Unit->AddChild(Slot); + Unit->AddChild(Ty); return Slot; } Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.16 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.17 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.16 Thu Feb 23 10:58:18 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Thu Feb 23 16:37:30 2006 @@ -430,6 +430,7 @@ case DI_TAG_global_variable: return new GlobalVariableDesc(); case DI_TAG_subprogram: return new SubprogramDesc(); case DI_TAG_basictype: return new BasicTypeDesc(); + case DI_TAG_typedef: return new TypedefDesc(); default: break; } return NULL; @@ -561,8 +562,6 @@ //===----------------------------------------------------------------------===// -//===----------------------------------------------------------------------===// - TypeDesc::TypeDesc(unsigned T) : DebugInfoDesc(T) , Context(NULL) @@ -627,6 +626,37 @@ << "Encoding(" << Encoding << ")\n"; } #endif +//===----------------------------------------------------------------------===// + +TypedefDesc::TypedefDesc() +: TypeDesc(DI_TAG_typedef) +, FromType(NULL) +, File(NULL) +, Line(0) +{} + +/// ApplyToFields - Target the visitor to the fields of the TypedefDesc. +/// +void TypedefDesc::ApplyToFields(DIVisitor *Visitor) { + TypeDesc::ApplyToFields(Visitor); + + Visitor->Apply((DebugInfoDesc *&)FromType); + Visitor->Apply((DebugInfoDesc *&)File); + Visitor->Apply(Line); +} + +#ifndef NDEBUG +void TypedefDesc::dump() { + std::cerr << getDescString() << " " + << "Tag(" << getTag() << "), " + << "Context(" << getContext() << "), " + << "Name(\"" << getName() << "\"), " + << "Size(" << getSize() << "), " + << "FromType(" << FromType << "), " + << "File(" << File << "), " + << "Line(" << Line << ")\n"; +} +#endif //===----------------------------------------------------------------------===// From jlaskey at apple.com Thu Feb 23 16:37:43 2006 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 23 Feb 2006 16:37:43 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineDebugInfo.h Message-ID: <200602232237.QAA12704@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineDebugInfo.h updated: 1.18 -> 1.19 --- Log message: Added basic support for typedefs. --- Diffs of the changes: (+39 -2) MachineDebugInfo.h | 41 +++++++++++++++++++++++++++++++++++++++-- 1 files changed, 39 insertions(+), 2 deletions(-) Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.18 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.19 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.18 Thu Feb 23 10:58:18 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Thu Feb 23 16:37:30 2006 @@ -62,7 +62,8 @@ DI_TAG_compile_unit, DI_TAG_global_variable, DI_TAG_subprogram, - DI_TAG_basictype + DI_TAG_basictype, + DI_TAG_typedef }; //===----------------------------------------------------------------------===// @@ -342,6 +343,42 @@ #endif }; + +//===----------------------------------------------------------------------===// +/// TypedefDesc - This class packages debug information associated with a +/// derived typedef. +class TypedefDesc : public TypeDesc { +private: + TypeDesc *FromType; // Type derived from. + CompileUnitDesc *File; // Declared compile unit. + int Line; // Declared line#. + +public: + TypedefDesc(); + + // Accessors + TypeDesc *getFromType() const { return FromType; } + CompileUnitDesc *getFile() const { return File; } + int getLine() const { return Line; } + void setFromType(TypeDesc *F) { FromType = F; } + void setFile(CompileUnitDesc *U) { File = U; } + void setLine(int L) { Line = L; } + + // Implement isa/cast/dyncast. + static bool classof(const TypedefDesc *) { return true; } + static bool classof(const DebugInfoDesc *D) { + return D->getTag() == DI_TAG_typedef; + } + + /// ApplyToFields - Target the visitor to the fields of the TypedefDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + //===----------------------------------------------------------------------===// /// GlobalDesc - This class is the base descriptor for global functions and /// variables. @@ -712,7 +749,7 @@ getGlobalVariablesUsing(M, Desc.getAnchorString()); std::vector AnchoredDescs; for (unsigned i = 0, N = Globals.size(); i < N; ++i) { - AnchoredDescs.push_back(static_cast(DR.Deserialize(Globals[i]))); + AnchoredDescs.push_back(cast(DR.Deserialize(Globals[i]))); } return AnchoredDescs; From lattner at cs.uiuc.edu Thu Feb 23 17:36:37 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 17:36:37 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/InlineAsm.h Message-ID: <200602232336.RAA20732@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: InlineAsm.h updated: 1.9 -> 1.10 --- Log message: add a new flag --- Diffs of the changes: (+4 -0) InlineAsm.h | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/include/llvm/InlineAsm.h diff -u llvm/include/llvm/InlineAsm.h:1.9 llvm/include/llvm/InlineAsm.h:1.10 --- llvm/include/llvm/InlineAsm.h:1.9 Mon Feb 6 19:12:49 2006 +++ llvm/include/llvm/InlineAsm.h Thu Feb 23 17:36:23 2006 @@ -90,6 +90,10 @@ /// there is an input constraint that is required to match it (e.g. "0"). bool hasMatchingInput; + /// isCommutative - This is set to true for a constraint that is commutative + /// with the next operand. + bool isCommutative; + /// Code - The constraint code, either the register name (in braces) or the /// constraint letter/number. std::vector Codes; From lattner at cs.uiuc.edu Thu Feb 23 17:37:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 17:37:05 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/InlineAsm.cpp Message-ID: <200602232337.RAA20771@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: InlineAsm.cpp updated: 1.8 -> 1.9 --- Log message: Parse the %*# constraint modifiers --- Diffs of the changes: (+11 -1) InlineAsm.cpp | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletion(-) Index: llvm/lib/VMCore/InlineAsm.cpp diff -u llvm/lib/VMCore/InlineAsm.cpp:1.8 llvm/lib/VMCore/InlineAsm.cpp:1.9 --- llvm/lib/VMCore/InlineAsm.cpp:1.8 Wed Feb 1 18:23:53 2006 +++ llvm/lib/VMCore/InlineAsm.cpp Thu Feb 23 17:36:53 2006 @@ -51,6 +51,7 @@ isEarlyClobber = false; isIndirectOutput = false; hasMatchingInput = false; + isCommutative = false; // Parse the prefix. if (*I == '~') { @@ -74,12 +75,21 @@ default: DoneWithModifiers = true; break; - case '&': + case '&': // Early clobber. if (Type != isOutput || // Cannot early clobber anything but output. isEarlyClobber) // Reject &&&&&& return true; isEarlyClobber = true; break; + case '%': // Commutative. + if (Type == isClobber || // Cannot commute clobbers. + isCommutative) // Reject %%%%% + return true; + isCommutative = true; + break; + case '#': // Comment. + case '*': // Register preferencing. + return true; // Not supported. } if (!DoneWithModifiers) { From lattner at cs.uiuc.edu Thu Feb 23 19:03:13 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 19:03:13 -0600 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/Sandbox.sh Message-ID: <200602240103.TAA28214@zion.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC: Sandbox.sh updated: 1.8 -> 1.9 --- Log message: Add support for sandy bz2 files --- Diffs of the changes: (+7 -4) Sandbox.sh | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-) Index: llvm-test/External/SPEC/Sandbox.sh diff -u llvm-test/External/SPEC/Sandbox.sh:1.8 llvm-test/External/SPEC/Sandbox.sh:1.9 --- llvm-test/External/SPEC/Sandbox.sh:1.8 Tue Jun 24 13:49:38 2003 +++ llvm-test/External/SPEC/Sandbox.sh Thu Feb 23 19:03:01 2006 @@ -18,16 +18,19 @@ cd Output/$TEST_UID rm -rf * -# Copy all of the test input files into the current directory... +# Copy all of the test input files into the current directory. cp -r $INPUT_DIR/* . -# If there is an "all" input directory, take it as well... +# If there is an "all" input directory, take it as well. cp -r $INPUT_DIR/../../all/input/* . > /dev/null 2>&1 -# Run the program now... +# If any of the input files is a .bz2 file, uncompress it now. +bunzip2 *.bz2 + +# Run the program now. echo Running: $* $* -# This script is always successful... +# This script is always successful. exit 0 From lattner at cs.uiuc.edu Thu Feb 23 19:05:10 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 19:05:10 -0600 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/Sandbox.sh Message-ID: <200602240105.TAA28290@zion.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC: Sandbox.sh updated: 1.9 -> 1.10 --- Log message: Don't complain if there are no .bz2 files --- Diffs of the changes: (+1 -1) Sandbox.sh | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/External/SPEC/Sandbox.sh diff -u llvm-test/External/SPEC/Sandbox.sh:1.9 llvm-test/External/SPEC/Sandbox.sh:1.10 --- llvm-test/External/SPEC/Sandbox.sh:1.9 Thu Feb 23 19:03:01 2006 +++ llvm-test/External/SPEC/Sandbox.sh Thu Feb 23 19:04:58 2006 @@ -25,7 +25,7 @@ cp -r $INPUT_DIR/../../all/input/* . > /dev/null 2>&1 # If any of the input files is a .bz2 file, uncompress it now. -bunzip2 *.bz2 +bunzip2 *.bz2 > /dev/null 2>&1 # Run the program now. echo Running: $* From lattner at cs.uiuc.edu Thu Feb 23 19:10:25 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 19:10:25 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200602240110.TAA28375@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.54 -> 1.55 --- Log message: Add C_Memory operand type --- Diffs of the changes: (+1 -1) TargetLowering.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.54 llvm/include/llvm/Target/TargetLowering.h:1.55 --- llvm/include/llvm/Target/TargetLowering.h:1.54 Wed Feb 22 10:23:43 2006 +++ llvm/include/llvm/Target/TargetLowering.h Thu Feb 23 19:10:14 2006 @@ -483,9 +483,9 @@ enum ConstraintType { C_Register, // Constraint represents a single register. C_RegisterClass, // Constraint represents one or more registers. + C_Memory, // Memory constraint. C_Other, // Something else. C_Unknown // Unsupported constraint. - // INTEGER, ADDRESS, MEMORY? }; /// getConstraintType - Given a constraint letter, return the type of From lattner at cs.uiuc.edu Thu Feb 23 19:10:58 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 19:10:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200602240110.TAA28439@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.36 -> 1.37 --- Log message: Recognize memory operand codes --- Diffs of the changes: (+6 -1) TargetLowering.cpp | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletion(-) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.36 llvm/lib/Target/TargetLowering.cpp:1.37 --- llvm/lib/Target/TargetLowering.cpp:1.36 Wed Feb 22 17:00:51 2006 +++ llvm/lib/Target/TargetLowering.cpp Thu Feb 23 19:10:46 2006 @@ -718,6 +718,10 @@ switch (ConstraintLetter) { default: return C_Unknown; case 'r': return C_RegisterClass; + case 'm': // memory + case 'o': // offsetable + case 'V': // not offsetable + return C_Memory; case 'i': // Simple Integer or Relocatable Constant case 'n': // Simple Integer case 's': // Relocatable Constant @@ -728,7 +732,8 @@ case 'M': case 'N': case 'O': - case 'P': return C_Other; + case 'P': + return C_Other; } } From lattner at cs.uiuc.edu Thu Feb 23 19:11:36 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 19:11:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200602240111.TAA28500@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.170 -> 1.171 --- Log message: Lower C_Memory operands. --- Diffs of the changes: (+44 -25) SelectionDAGISel.cpp | 69 ++++++++++++++++++++++++++++++++------------------- 1 files changed, 44 insertions(+), 25 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.170 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.171 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.170 Thu Feb 23 14:06:57 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Feb 23 19:11:24 2006 @@ -1549,36 +1549,55 @@ // Use the produced MatchedRegs object to MatchedRegs.getCopyToRegs(InOperandVal, DAG, Chain, Flag); MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands); - } else { - TargetLowering::ConstraintType CTy = TargetLowering::C_RegisterClass; - if (ConstraintCode.size() == 1) // not a physreg name. - CTy = TLI.getConstraintType(ConstraintCode[0]); + break; + } + + TargetLowering::ConstraintType CTy = TargetLowering::C_RegisterClass; + if (ConstraintCode.size() == 1) // not a physreg name. + CTy = TLI.getConstraintType(ConstraintCode[0]); - if (CTy == TargetLowering::C_Other) { - if (!TLI.isOperandValidForConstraint(InOperandVal, ConstraintCode[0])) - assert(0 && "MATCH FAIL!"); - - // Add information to the INLINEASM node to know about this input. - unsigned ResOpType = 3 /*imm*/ | (1 << 3); - AsmNodeOperands.push_back(DAG.getConstant(ResOpType, MVT::i32)); - AsmNodeOperands.push_back(InOperandVal); - break; - } + if (CTy == TargetLowering::C_Other) { + if (!TLI.isOperandValidForConstraint(InOperandVal, ConstraintCode[0])) + assert(0 && "MATCH FAIL!"); - assert(CTy == TargetLowering::C_RegisterClass && "Unknown op type!"); - - // Copy the input into the appropriate registers. - RegsForValue InRegs = - GetRegistersForValue(ConstraintCode, ConstraintVTs[i], - false, true, OutputRegs, InputRegs); - // FIXME: should be match fail. - assert(!InRegs.Regs.empty() && "Couldn't allocate input reg!"); - - InRegs.getCopyToRegs(InOperandVal, DAG, Chain, Flag); + // Add information to the INLINEASM node to know about this input. + unsigned ResOpType = 3 /*IMM*/ | (1 << 3); + AsmNodeOperands.push_back(DAG.getConstant(ResOpType, MVT::i32)); + AsmNodeOperands.push_back(InOperandVal); + break; + } else if (CTy == TargetLowering::C_Memory) { + // Memory input. + + // Check that the operand isn't a float. + if (!MVT::isInteger(InOperandVal.getValueType())) + assert(0 && "MATCH FAIL!"); - InRegs.AddInlineAsmOperands(1/*REGUSE*/, DAG, AsmNodeOperands); + // Extend/truncate to the right pointer type if needed. + MVT::ValueType PtrType = TLI.getPointerTy(); + if (InOperandVal.getValueType() < PtrType) + InOperandVal = DAG.getNode(ISD::ZERO_EXTEND, PtrType, InOperandVal); + else if (InOperandVal.getValueType() > PtrType) + InOperandVal = DAG.getNode(ISD::TRUNCATE, PtrType, InOperandVal); + + // Add information to the INLINEASM node to know about this input. + unsigned ResOpType = 4/*MEM*/ | (1 << 3); + AsmNodeOperands.push_back(DAG.getConstant(ResOpType, MVT::i32)); + AsmNodeOperands.push_back(InOperandVal); break; } + + assert(CTy == TargetLowering::C_RegisterClass && "Unknown op type!"); + + // Copy the input into the appropriate registers. + RegsForValue InRegs = + GetRegistersForValue(ConstraintCode, ConstraintVTs[i], + false, true, OutputRegs, InputRegs); + // FIXME: should be match fail. + assert(!InRegs.Regs.empty() && "Couldn't allocate input reg!"); + + InRegs.getCopyToRegs(InOperandVal, DAG, Chain, Flag); + + InRegs.AddInlineAsmOperands(1/*REGUSE*/, DAG, AsmNodeOperands); break; } case InlineAsm::isClobber: { From lattner at cs.uiuc.edu Thu Feb 23 20:13:04 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 20:13:04 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGISel.h Message-ID: <200602240213.UAA29033@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGISel.h updated: 1.8 -> 1.9 --- Log message: Add some hooks for selecting memory addresses. --- Diffs of the changes: (+17 -0) SelectionDAGISel.h | 17 +++++++++++++++++ 1 files changed, 17 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAGISel.h diff -u llvm/include/llvm/CodeGen/SelectionDAGISel.h:1.8 llvm/include/llvm/CodeGen/SelectionDAGISel.h:1.9 --- llvm/include/llvm/CodeGen/SelectionDAGISel.h:1.8 Fri Jan 20 20:32:06 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGISel.h Thu Feb 23 20:12:52 2006 @@ -49,11 +49,28 @@ virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {} virtual void InstructionSelectBasicBlock(SelectionDAG &SD) = 0; + /// SelectInlineAsmMemoryOperand - Select the specified address as a target + /// addressing mode, according to the specified constraint code. If this does + /// not match or is not implemented, return true. The resultant operands + /// (which will appear in the machine instruction) should be added to the + /// OutOps vector. + virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op, + char ConstraintCode, + std::vector &OutOps, + SelectionDAG &DAG) { + return true; + } + protected: /// Pick a safe ordering and emit instructions for each target node in the /// graph. void ScheduleAndEmitDAG(SelectionDAG &DAG); + /// SelectInlineAsmMemoryOperands - Calls to this are automatically generated + /// by tblgen. Others should not call it. + void SelectInlineAsmMemoryOperands(std::vector &Ops, + SelectionDAG &DAG); + private: SDOperand CopyValueToVirtualRegister(SelectionDAGLowering &SDL, Value *V, unsigned Reg); From lattner at cs.uiuc.edu Thu Feb 23 20:13:23 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 20:13:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Message-ID: <200602240213.UAA29075@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.159 -> 1.160 --- Log message: Implement selection of inline asm memory operands --- Diffs of the changes: (+29 -0) PPCISelDAGToDAG.cpp | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.159 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.160 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.159 Thu Feb 16 23:43:56 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Thu Feb 23 20:13:12 2006 @@ -83,6 +83,35 @@ /// represented as an indexed [r+r] operation. bool SelectAddrIdxOnly(SDOperand N, SDOperand &Base, SDOperand &Index); + /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for + /// inline asm expressions. + virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op, + char ConstraintCode, + std::vector &OutOps, + SelectionDAG &DAG) { + SDOperand Op0, Op1; + switch (ConstraintCode) { + default: return true; + case 'm': // memory + if (!SelectAddrIdx(Op, Op0, Op1)) + SelectAddrImm(Op, Op0, Op1); + break; + case 'o': // offsetable + if (!SelectAddrImm(Op, Op0, Op1)) { + Select(Op0, Op); // r+0. + Op1 = getI32Imm(0); + } + break; + case 'v': // not offsetable + SelectAddrIdxOnly(Op, Op0, Op1); + break; + } + + OutOps.push_back(Op0); + OutOps.push_back(Op1); + return false; + } + SDOperand BuildSDIVSequence(SDNode *N); SDOperand BuildUDIVSequence(SDNode *N); From lattner at cs.uiuc.edu Thu Feb 23 20:13:43 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 20:13:43 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200602240213.UAA29139@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.173 -> 1.174 --- Log message: Select inline asm memory operands. --- Diffs of the changes: (+1 -0) DAGISelEmitter.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.173 llvm/utils/TableGen/DAGISelEmitter.cpp:1.174 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.173 Fri Feb 17 20:33:09 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Feb 23 20:13:31 2006 @@ -2986,6 +2986,7 @@ << " // Select the flag operand.\n" << " if (Ops.back().getValueType() == MVT::Flag)\n" << " Select(Ops.back(), Ops.back());\n" + << " SelectInlineAsmMemoryOperands(Ops, *CurDAG);\n" << " std::vector VTs;\n" << " VTs.push_back(MVT::Other);\n" << " VTs.push_back(MVT::Flag);\n" From lattner at cs.uiuc.edu Thu Feb 23 20:14:06 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 23 Feb 2006 20:14:06 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200602240214.UAA29173@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.171 -> 1.172 --- Log message: Implement (most of) selection of inline asm memory operands. --- Diffs of the changes: (+42 -0) SelectionDAGISel.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 42 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.171 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.172 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.171 Thu Feb 23 19:11:24 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Feb 23 20:13:54 2006 @@ -2437,3 +2437,45 @@ BB = SL->Run(); delete SL; } + +/// SelectInlineAsmMemoryOperands - Calls to this are automatically generated +/// by tblgen. Others should not call it. +void SelectionDAGISel:: +SelectInlineAsmMemoryOperands(std::vector &Ops, SelectionDAG &DAG) { + std::vector InOps; + std::swap(InOps, Ops); + + Ops.push_back(InOps[0]); // input chain. + Ops.push_back(InOps[1]); // input asm string. + + const char *AsmStr = cast(InOps[1])->getSymbol(); + unsigned i = 2, e = InOps.size(); + if (InOps[e-1].getValueType() == MVT::Flag) + --e; // Don't process a flag operand if it is here. + + while (i != e) { + unsigned Flags = cast(InOps[i])->getValue(); + if ((Flags & 7) != 4 /*MEM*/) { + // Just skip over this operand, copying the operands verbatim. + Ops.insert(Ops.end(), InOps.begin()+i, InOps.begin()+i+(Flags >> 3) + 1); + i += (Flags >> 3) + 1; + } else { + assert((Flags >> 3) == 1 && "Memory operand with multiple values?"); + // Otherwise, this is a memory operand. Ask the target to select it. + std::vector SelOps; + if (SelectInlineAsmMemoryOperand(InOps[i+1], 'm', SelOps, DAG)) { + std::cerr << "Could not match memory address. Inline asm failure!\n"; + exit(1); + } + + // Add this to the output node. + Ops.push_back(DAG.getConstant(4/*MEM*/ | (SelOps.size() << 3), MVT::i32)); + Ops.insert(Ops.end(), SelOps.begin(), SelOps.end()); + i += 2; + } + } + + // Add the flag input back if present. + if (e != InOps.size()) + Ops.push_back(InOps.back()); +} From jeffc at jolt-lang.org Thu Feb 23 20:52:52 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Thu, 23 Feb 2006 20:52:52 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineDebugInfo.h Message-ID: <200602240252.UAA29419@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineDebugInfo.h updated: 1.19 -> 1.20 --- Log message: Get VC++ building again. --- Diffs of the changes: (+1 -0) MachineDebugInfo.h | 1 + 1 files changed, 1 insertion(+) Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.19 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.20 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.19 Thu Feb 23 16:37:30 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Thu Feb 23 20:52:40 2006 @@ -31,6 +31,7 @@ #define LLVM_CODEGEN_MACHINEDEBUGINFO_H #include "llvm/Support/Dwarf.h" +#include "llvm/Support/DataTypes.h" #include "llvm/ADT/UniqueVector.h" #include "llvm/GlobalValue.h" #include "llvm/Pass.h" From jeffc at jolt-lang.org Thu Feb 23 20:52:53 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Thu, 23 Feb 2006 20:52:53 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200602240252.UAA29423@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.172 -> 1.173 --- Log message: Get VC++ building again. --- Diffs of the changes: (+1 -0) SelectionDAGISel.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.172 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.173 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.172 Thu Feb 23 20:13:54 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Feb 23 20:52:40 2006 @@ -42,6 +42,7 @@ #include #include #include +#include using namespace llvm; #ifndef NDEBUG From alenhar2 at cs.uiuc.edu Thu Feb 23 21:20:16 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 23 Feb 2006 21:20:16 -0600 Subject: [llvm-commits] CVS: llvm-poolalloc/Regressions/2006-02-23.memcpy.ll Message-ID: <200602240320.VAA29713@zion.cs.uiuc.edu> Changes in directory llvm-poolalloc/Regressions: 2006-02-23.memcpy.ll added (r1.1) --- Log message: reduction from bzip2 --- Diffs of the changes: (+35 -0) 2006-02-23.memcpy.ll | 35 +++++++++++++++++++++++++++++++++++ 1 files changed, 35 insertions(+) Index: llvm-poolalloc/Regressions/2006-02-23.memcpy.ll diff -c /dev/null llvm-poolalloc/Regressions/2006-02-23.memcpy.ll:1.1 *** /dev/null Thu Feb 23 21:20:14 2006 --- llvm-poolalloc/Regressions/2006-02-23.memcpy.ll Thu Feb 23 21:20:04 2006 *************** *** 0 **** --- 1,35 ---- + ; pointer compression tries to turn the llvm.memcpy into llvm.memcpy_pc + ; this is of course bad. It should materialize the pointers. + target endian = little + target pointersize = 64 + target triple = "alphaev6-unknown-linux-gnu" + deplibs = [ "c", "crtend" ] + %struct.spec_fd_t = type { int, int, int, ubyte* } + %spec_fd = external global [3 x %struct.spec_fd_t] ; <[3 x %struct.spec_fd_t]*> [#uses=2] + + implementation ; Functions: + + declare void %llvm.memcpy(sbyte*, sbyte*, ulong, uint) + + void %main() { + entry: + br bool false, label %no_exit.0.i161, label %endif.0 + + endif.0: ; preds = %entry + ret void + + no_exit.0.i161: ; preds = %entry + %tmp.25.i = getelementptr [3 x %struct.spec_fd_t]* %spec_fd, long 0, int 0, uint 3 ; [#uses=1] + %tmp.26.i = malloc ubyte, uint 0 ; [#uses=1] + store ubyte* %tmp.26.i, ubyte** %tmp.25.i + br bool false, label %no_exit.1.i, label %then.4 + + no_exit.1.i: ; preds = %no_exit.0.i161 + %tmp.103.i = load ubyte** getelementptr ([3 x %struct.spec_fd_t]* %spec_fd, long 0, int 0, uint 3) ; [#uses=1] + %tmp.118.i = cast ubyte* %tmp.103.i to sbyte* ; [#uses=1] + tail call void %llvm.memcpy( sbyte* null, sbyte* %tmp.118.i, ulong 0, uint 1 ) + ret void + + then.4: ; preds = %no_exit.0.i161 + ret void + } From alenhar2 at cs.uiuc.edu Thu Feb 23 21:22:19 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 23 Feb 2006 21:22:19 -0600 Subject: [llvm-commits] CVS: llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp Message-ID: <200602240322.VAA29761@zion.cs.uiuc.edu> Changes in directory llvm-poolalloc/lib/PoolAllocate: PointerCompress.cpp updated: 1.66 -> 1.67 --- Log message: fix llvm-poolalloc/Regressions/2006-02-23.memcpy.ll --- Diffs of the changes: (+23 -0) PointerCompress.cpp | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+) Index: llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp diff -u llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp:1.66 llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp:1.67 --- llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp:1.66 Mon Feb 20 16:03:14 2006 +++ llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp Thu Feb 23 21:22:07 2006 @@ -944,6 +944,29 @@ CI.setOperand(1, SrcPtr); return; } + } else if (Callee->getName() == "llvm.memcpy") { + bool doret = false; + if (const CompressedPoolInfo *DestPI = getPoolInfo(CI.getOperand(1))) { + std::vector Ops; + Ops.push_back(getTransformedValue(CI.getOperand(1))); + Value *BasePtr = DestPI->EmitPoolBaseLoad(CI); + Value *SrcPtr = new GetElementPtrInst(BasePtr, Ops, + CI.getOperand(1)->getName()+".pp", &CI); + SrcPtr = new CastInst(SrcPtr, CI.getOperand(1)->getType(), "", &CI); + CI.setOperand(1, SrcPtr); + doret = true; + } + if (const CompressedPoolInfo *DestPI = getPoolInfo(CI.getOperand(2))) { + std::vector Ops; + Ops.push_back(getTransformedValue(CI.getOperand(2))); + Value *BasePtr = DestPI->EmitPoolBaseLoad(CI); + Value *SrcPtr = new GetElementPtrInst(BasePtr, Ops, + CI.getOperand(2)->getName()+".pp", &CI); + SrcPtr = new CastInst(SrcPtr, CI.getOperand(2)->getType(), "", &CI); + CI.setOperand(2, SrcPtr); + doret = true; + } + if (doret) return; } From alenhar2 at cs.uiuc.edu Thu Feb 23 21:34:41 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 23 Feb 2006 21:34:41 -0600 Subject: [llvm-commits] CVS: llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp Message-ID: <200602240334.VAA29876@zion.cs.uiuc.edu> Changes in directory llvm-poolalloc/lib/PoolAllocate: PointerCompress.cpp updated: 1.67 -> 1.68 --- Log message: read can't handle compressed pointers either. ah the joys of making spec work --- Diffs of the changes: (+11 -0) PointerCompress.cpp | 11 +++++++++++ 1 files changed, 11 insertions(+) Index: llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp diff -u llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp:1.67 llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp:1.68 --- llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp:1.67 Thu Feb 23 21:22:07 2006 +++ llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp Thu Feb 23 21:34:29 2006 @@ -933,6 +933,17 @@ getPoolInfo(CI.getOperand(i))) CI.setOperand(i, getTransformedValue(CI.getOperand(i))); return; + } else if (Callee->getName() == "read") { + if (const CompressedPoolInfo *DestPI = getPoolInfo(CI.getOperand(2))) { + std::vector Ops; + Ops.push_back(getTransformedValue(CI.getOperand(2))); + Value *BasePtr = DestPI->EmitPoolBaseLoad(CI); + Value *SrcPtr = new GetElementPtrInst(BasePtr, Ops, + CI.getOperand(2)->getName()+".pp", &CI); + SrcPtr = new CastInst(SrcPtr, CI.getOperand(2)->getType(), "", &CI); + CI.setOperand(2, SrcPtr); + return; + } } else if (Callee->getName() == "llvm.memset") { if (const CompressedPoolInfo *DestPI = getPoolInfo(CI.getOperand(1))) { std::vector Ops; From jlaskey at apple.com Fri Feb 24 10:47:02 2006 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 24 Feb 2006 10:47:02 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineDebugInfo.h Message-ID: <200602241647.KAA04557@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineDebugInfo.h updated: 1.20 -> 1.21 --- Log message: Add pointer and reference types. Added short-term code to ignore NULL types (to allow llvm-gcc4 to build.) --- Diffs of the changes: (+19 -16) MachineDebugInfo.h | 35 +++++++++++++++++++---------------- 1 files changed, 19 insertions(+), 16 deletions(-) Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.20 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.21 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.20 Thu Feb 23 20:52:40 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Fri Feb 24 10:46:40 2006 @@ -64,7 +64,9 @@ DI_TAG_global_variable, DI_TAG_subprogram, DI_TAG_basictype, - DI_TAG_typedef + DI_TAG_typedef, + DI_TAG_pointer, + DI_TAG_reference }; //===----------------------------------------------------------------------===// @@ -283,8 +285,10 @@ class TypeDesc : public DebugInfoDesc { private: DebugInfoDesc *Context; // Context debug descriptor. - std::string Name; // Type name. - uint64_t Size; // Type size. + std::string Name; // Type name (may be empty.) + CompileUnitDesc *File; // Declared compile unit (may be NULL.) + int Line; // Declared line# (may be zero.) + uint64_t Size; // Type size (may be zero.) protected: TypeDesc(unsigned T); @@ -293,9 +297,13 @@ // Accessors DebugInfoDesc *getContext() const { return Context; } const std::string &getName() const { return Name; } + CompileUnitDesc *getFile() const { return File; } + int getLine() const { return Line; } uint64_t getSize() const { return Size; } void setContext(DebugInfoDesc *C) { Context = C; } void setName(const std::string &N) { Name = N; } + void setFile(CompileUnitDesc *U) { File = U; } + void setLine(int L) { Line = L; } void setSize(uint64_t S) { Size = S; } /// ApplyToFields - Target the visitor to the fields of the TypeDesc. @@ -346,32 +354,27 @@ //===----------------------------------------------------------------------===// -/// TypedefDesc - This class packages debug information associated with a -/// derived typedef. -class TypedefDesc : public TypeDesc { +/// DerivedTypeDesc - This class packages debug information associated with a +/// derived types (eg., typedef, pointer, reference.) +class DerivedTypeDesc : public TypeDesc { private: TypeDesc *FromType; // Type derived from. - CompileUnitDesc *File; // Declared compile unit. - int Line; // Declared line#. public: - TypedefDesc(); + DerivedTypeDesc(unsigned T); // Accessors TypeDesc *getFromType() const { return FromType; } - CompileUnitDesc *getFile() const { return File; } - int getLine() const { return Line; } void setFromType(TypeDesc *F) { FromType = F; } - void setFile(CompileUnitDesc *U) { File = U; } - void setLine(int L) { Line = L; } // Implement isa/cast/dyncast. - static bool classof(const TypedefDesc *) { return true; } + static bool classof(const DerivedTypeDesc *) { return true; } static bool classof(const DebugInfoDesc *D) { - return D->getTag() == DI_TAG_typedef; + unsigned T = D->getTag(); + return T == DI_TAG_typedef || T == DI_TAG_pointer || T == DI_TAG_reference; } - /// ApplyToFields - Target the visitor to the fields of the TypedefDesc. + /// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc. /// virtual void ApplyToFields(DIVisitor *Visitor); From jlaskey at apple.com Fri Feb 24 10:47:02 2006 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 24 Feb 2006 10:47:02 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp MachineDebugInfo.cpp Message-ID: <200602241647.KAA04558@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.29 -> 1.30 MachineDebugInfo.cpp updated: 1.17 -> 1.18 --- Log message: Add pointer and reference types. Added short-term code to ignore NULL types (to allow llvm-gcc4 to build.) --- Diffs of the changes: (+52 -29) DwarfWriter.cpp | 43 ++++++++++++++++++++++++++++++------------- MachineDebugInfo.cpp | 38 ++++++++++++++++++++++---------------- 2 files changed, 52 insertions(+), 29 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.29 llvm/lib/CodeGen/DwarfWriter.cpp:1.30 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.29 Thu Feb 23 16:37:30 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Fri Feb 24 10:46:40 2006 @@ -1235,6 +1235,9 @@ /// NewType - Create a new type DIE. /// DIE *DwarfWriter::NewType(DIE *Unit, TypeDesc *TyDesc) { + // FIXME - hack to get around NULL types short term. + if (!TyDesc) return NewBasicType(Unit, Type::IntTy); + // Check for pre-existence. DIE *&Slot = DescToDieMap[TyDesc]; if (Slot) return Slot; @@ -1246,29 +1249,43 @@ DIE *Ty = NULL; - // Determine how to handle. if (BasicTypeDesc *BasicTy = dyn_cast(TyDesc)) { + // Fundamental types like int, float, bool Slot = Ty = new DIE(DW_TAG_base_type); unsigned Encoding = BasicTy->getEncoding(); Ty->AddUInt (DW_AT_encoding, DW_FORM_data1, Encoding); - } else if (TypedefDesc *TypedefTy = dyn_cast(TyDesc)) { - Slot = Ty = new DIE(DW_TAG_typedef); - TypeDesc *FromTy = TypedefTy->getFromType(); - DIE *FromTyDie = NewType(Unit, FromTy); - CompileUnitDesc *File = TypedefTy->getFile(); - unsigned FileID = DebugInfo->RecordSource(File); - int Line = TypedefTy->getLine(); - - Ty->AddDIEntry(DW_AT_type, DW_FORM_ref4, FromTyDie); - Ty->AddUInt (DW_AT_decl_file, 0, FileID); - Ty->AddUInt (DW_AT_decl_line, 0, Line); + } else if (DerivedTypeDesc *DerivedTy = dyn_cast(TyDesc)) { + // Determine which derived type. + unsigned T = 0; + switch (DerivedTy->getTag()) { + case DI_TAG_typedef: T = DW_TAG_typedef; break; + case DI_TAG_pointer: T = DW_TAG_pointer_type; break; + case DI_TAG_reference: T = DW_TAG_reference_type; break; + default: assert( 0 && "Unknown tag on derived type"); + } + + // Create specific DIE. + Slot = Ty = new DIE(T); + + // Map to main type, void will not have a type. + if (TypeDesc *FromTy = DerivedTy->getFromType()) { + Ty->AddDIEntry(DW_AT_type, DW_FORM_ref4, NewType(Unit, FromTy)); + } } assert(Ty && "Type not supported yet"); - // Add common information. + // Add size if non-zero (derived types don't have a size.) if (Size) Ty->AddUInt(DW_AT_byte_size, 0, Size); + // Add name if not anonymous or intermediate type. if (!Name.empty()) Ty->AddString(DW_AT_name, DW_FORM_string, Name); + // Add source line info if present. + if (CompileUnitDesc *File = TyDesc->getFile()) { + unsigned FileID = DebugInfo->RecordSource(File); + int Line = TyDesc->getLine(); + Ty->AddUInt(DW_AT_decl_file, 0, FileID); + Ty->AddUInt(DW_AT_decl_line, 0, Line); + } // Add to context owner. Unit->AddChild(Ty); Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.17 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.18 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.17 Thu Feb 23 16:37:30 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Fri Feb 24 10:46:40 2006 @@ -430,7 +430,9 @@ case DI_TAG_global_variable: return new GlobalVariableDesc(); case DI_TAG_subprogram: return new SubprogramDesc(); case DI_TAG_basictype: return new BasicTypeDesc(); - case DI_TAG_typedef: return new TypedefDesc(); + case DI_TAG_typedef: return new DerivedTypeDesc(DI_TAG_typedef); + case DI_TAG_pointer: return new DerivedTypeDesc(DI_TAG_pointer); + case DI_TAG_reference: return new DerivedTypeDesc(DI_TAG_reference); default: break; } return NULL; @@ -566,16 +568,19 @@ : DebugInfoDesc(T) , Context(NULL) , Name("") +, File(NULL) , Size(0) {} -/// ApplyToFields - Target the visitor to the fields of the TypeDesc. +/// ApplyToFields - Target the visitor to the fields of the TypeDesc. /// void TypeDesc::ApplyToFields(DIVisitor *Visitor) { DebugInfoDesc::ApplyToFields(Visitor); Visitor->Apply(Context); Visitor->Apply(Name); + Visitor->Apply((DebugInfoDesc *&)File); + Visitor->Apply(Line); Visitor->Apply(Size); } @@ -597,6 +602,8 @@ << "Tag(" << getTag() << "), " << "Context(" << Context << "), " << "Name(\"" << Name << "\"), " + << "File(" << File << "), " + << "Line(" << Line << "), " << "Size(" << Size << ")\n"; } #endif @@ -608,7 +615,7 @@ , Encoding(0) {} -/// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc. +/// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc. /// void BasicTypeDesc::ApplyToFields(DIVisitor *Visitor) { TypeDesc::ApplyToFields(Visitor); @@ -628,33 +635,32 @@ #endif //===----------------------------------------------------------------------===// -TypedefDesc::TypedefDesc() -: TypeDesc(DI_TAG_typedef) +DerivedTypeDesc::DerivedTypeDesc(unsigned T) +: TypeDesc(T) , FromType(NULL) -, File(NULL) -, Line(0) -{} +{ + assert((T == DI_TAG_typedef || T == DI_TAG_pointer || T == DI_TAG_reference)&& + "Unknown derived type."); +} -/// ApplyToFields - Target the visitor to the fields of the TypedefDesc. +/// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc. /// -void TypedefDesc::ApplyToFields(DIVisitor *Visitor) { +void DerivedTypeDesc::ApplyToFields(DIVisitor *Visitor) { TypeDesc::ApplyToFields(Visitor); Visitor->Apply((DebugInfoDesc *&)FromType); - Visitor->Apply((DebugInfoDesc *&)File); - Visitor->Apply(Line); } #ifndef NDEBUG -void TypedefDesc::dump() { +void DerivedTypeDesc::dump() { std::cerr << getDescString() << " " << "Tag(" << getTag() << "), " << "Context(" << getContext() << "), " << "Name(\"" << getName() << "\"), " << "Size(" << getSize() << "), " - << "FromType(" << FromType << "), " - << "File(" << File << "), " - << "Line(" << Line << ")\n"; + << "File(" << getFile() << "), " + << "Line(" << getLine() << "), " + << "FromType(" << FromType << ")\n"; } #endif From lattner at cs.uiuc.edu Fri Feb 24 12:06:10 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 24 Feb 2006 12:06:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200602241806.MAA05137@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.437 -> 1.438 --- Log message: Fix a problem that Nate noticed that boils down to an over conservative check in the code that does "select C, (X+Y), (X-Y) --> (X+(select C, Y, (-Y)))". We now compile this loop: LBB1_1: ; no_exit add r6, r2, r3 subf r3, r2, r3 cmpwi cr0, r2, 0 addi r7, r5, 4 lwz r2, 0(r5) addi r4, r4, 1 blt cr0, LBB1_4 ; no_exit LBB1_3: ; no_exit mr r3, r6 LBB1_4: ; no_exit cmpwi cr0, r4, 16 mr r5, r7 bne cr0, LBB1_1 ; no_exit into this instead: LBB1_1: ; no_exit srawi r6, r2, 31 add r2, r2, r6 xor r6, r2, r6 addi r7, r5, 4 lwz r2, 0(r5) addi r4, r4, 1 add r3, r3, r6 cmpwi cr0, r4, 16 mr r5, r7 bne cr0, LBB1_1 ; no_exit --- Diffs of the changes: (+18 -23) InstructionCombining.cpp | 41 ++++++++++++++++++----------------------- 1 files changed, 18 insertions(+), 23 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.437 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.438 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.437 Fri Feb 17 21:20:33 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Feb 24 12:05:58 2006 @@ -5074,30 +5074,25 @@ } if (OtherAddOp) { - // So at this point we know we have: - // select C, (add X, Y), (sub X, ?) - // We can do the transform profitably if either 'Y' = '?' or '?' is - // a constant. - if (SubOp->getOperand(1) == AddOp || - isa(SubOp->getOperand(1))) { - Value *NegVal; - if (Constant *C = dyn_cast(SubOp->getOperand(1))) { - NegVal = ConstantExpr::getNeg(C); - } else { - NegVal = InsertNewInstBefore( - BinaryOperator::createNeg(SubOp->getOperand(1)), SI); - } - - Value *NewTrueOp = OtherAddOp; - Value *NewFalseOp = NegVal; - if (AddOp != TI) - std::swap(NewTrueOp, NewFalseOp); - Instruction *NewSel = - new SelectInst(CondVal, NewTrueOp,NewFalseOp,SI.getName()+".p"); - - NewSel = InsertNewInstBefore(NewSel, SI); - return BinaryOperator::createAdd(SubOp->getOperand(0), NewSel); + // So at this point we know we have (Y -> OtherAddOp): + // select C, (add X, Y), (sub X, Z) + Value *NegVal; // Compute -Z + if (Constant *C = dyn_cast(SubOp->getOperand(1))) { + NegVal = ConstantExpr::getNeg(C); + } else { + NegVal = InsertNewInstBefore( + BinaryOperator::createNeg(SubOp->getOperand(1), "tmp"), SI); } + + Value *NewTrueOp = OtherAddOp; + Value *NewFalseOp = NegVal; + if (AddOp != TI) + std::swap(NewTrueOp, NewFalseOp); + Instruction *NewSel = + new SelectInst(CondVal, NewTrueOp,NewFalseOp,SI.getName()+".p"); + + NewSel = InsertNewInstBefore(NewSel, SI); + return BinaryOperator::createAdd(SubOp->getOperand(0), NewSel); } } } From lattner at cs.uiuc.edu Fri Feb 24 12:54:03 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 24 Feb 2006 12:54:03 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ScheduleDAG.h Message-ID: <200602241854.MAA05577@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ScheduleDAG.h updated: 1.9 -> 1.10 --- Log message: add a method --- Diffs of the changes: (+3 -0) ScheduleDAG.h | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/include/llvm/CodeGen/ScheduleDAG.h diff -u llvm/include/llvm/CodeGen/ScheduleDAG.h:1.9 llvm/include/llvm/CodeGen/ScheduleDAG.h:1.10 --- llvm/include/llvm/CodeGen/ScheduleDAG.h:1.9 Wed Feb 22 10:23:43 2006 +++ llvm/include/llvm/CodeGen/ScheduleDAG.h Fri Feb 24 12:53:51 2006 @@ -335,6 +335,9 @@ virtual void dump() const; private: + void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum, + const TargetInstrDescriptor *II); + /// PrepareNodeInfo - Set up the basic minimum node info for scheduling. /// void PrepareNodeInfo(); From lattner at cs.uiuc.edu Fri Feb 24 12:54:15 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 24 Feb 2006 12:54:15 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200602241854.MAA05587@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.67 -> 1.68 --- Log message: Refactor operand adding out to a new AddOperand method --- Diffs of the changes: (+81 -66) ScheduleDAG.cpp | 147 ++++++++++++++++++++++++++++++-------------------------- 1 files changed, 81 insertions(+), 66 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.67 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.68 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.67 Thu Feb 23 13:21:04 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Feb 24 12:54:03 2006 @@ -110,6 +110,85 @@ return ResultReg; } +/// AddOperand - Add the specified operand to the specified machine instr. II +/// specifies the instruction information for the node, and IIOpNum is the +/// operand number (in the II) that we are adding. IIOpNum and II are used for +/// assertions only. +void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op, + unsigned IIOpNum, + const TargetInstrDescriptor *II) { + if (Op.isTargetOpcode()) { + // Note that this case is redundant with the final else block, but we + // include it because it is the most common and it makes the logic + // simpler here. + assert(Op.getValueType() != MVT::Other && + Op.getValueType() != MVT::Flag && + "Chain and flag operands should occur at end of operand list!"); + + // Get/emit the operand. + unsigned VReg = getVR(Op); + MI->addRegOperand(VReg, MachineOperand::Use); + + // Verify that it is right. + assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); + if (II) { + assert(II->OpInfo[IIOpNum].RegClass && + "Don't have operand info for this instruction!"); + assert(RegMap->getRegClass(VReg) == II->OpInfo[IIOpNum].RegClass && + "Register class of operand and regclass of use don't agree!"); + } + } else if (ConstantSDNode *C = + dyn_cast(Op)) { + MI->addZeroExtImm64Operand(C->getValue()); + } else if (RegisterSDNode*R = + dyn_cast(Op)) { + MI->addRegOperand(R->getReg(), MachineOperand::Use); + } else if (GlobalAddressSDNode *TGA = + dyn_cast(Op)) { + MI->addGlobalAddressOperand(TGA->getGlobal(), false, TGA->getOffset()); + } else if (BasicBlockSDNode *BB = + dyn_cast(Op)) { + MI->addMachineBasicBlockOperand(BB->getBasicBlock()); + } else if (FrameIndexSDNode *FI = + dyn_cast(Op)) { + MI->addFrameIndexOperand(FI->getIndex()); + } else if (ConstantPoolSDNode *CP = + dyn_cast(Op)) { + unsigned Align = CP->getAlignment(); + // MachineConstantPool wants an explicit alignment. + if (Align == 0) { + if (CP->get()->getType() == Type::DoubleTy) + Align = 3; // always 8-byte align doubles. + else + Align = TM.getTargetData() + .getTypeAlignmentShift(CP->get()->getType()); + } + + unsigned Idx = ConstPool->getConstantPoolIndex(CP->get(), Align); + MI->addConstantPoolIndexOperand(Idx); + } else if (ExternalSymbolSDNode *ES = + dyn_cast(Op)) { + MI->addExternalSymbolOperand(ES->getSymbol(), false); + } else { + assert(Op.getValueType() != MVT::Other && + Op.getValueType() != MVT::Flag && + "Chain and flag operands should occur at end of operand list!"); + unsigned VReg = getVR(Op); + MI->addRegOperand(VReg, MachineOperand::Use); + + // Verify that it is right. + assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); + if (II) { + assert(II->OpInfo[IIOpNum].RegClass && + "Don't have operand info for this instruction!"); + assert(RegMap->getRegClass(VReg) == II->OpInfo[IIOpNum].RegClass && + "Register class of operand and regclass of use don't agree!"); + } + } + +} + + /// EmitNode - Generate machine code for an node and needed dependencies. /// void ScheduleDAG::EmitNode(NodeInfo *NI) { @@ -159,72 +238,8 @@ // Emit all of the actual operands of this instruction, adding them to the // instruction as appropriate. - for (unsigned i = 0; i != NodeOperands; ++i) { - if (Node->getOperand(i).isTargetOpcode()) { - // Note that this case is redundant with the final else block, but we - // include it because it is the most common and it makes the logic - // simpler here. - assert(Node->getOperand(i).getValueType() != MVT::Other && - Node->getOperand(i).getValueType() != MVT::Flag && - "Chain and flag operands should occur at end of operand list!"); - - // Get/emit the operand. - unsigned VReg = getVR(Node->getOperand(i)); - MI->addRegOperand(VReg, MachineOperand::Use); - - // Verify that it is right. - assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); - assert(II.OpInfo[i+NumResults].RegClass && - "Don't have operand info for this instruction!"); - assert(RegMap->getRegClass(VReg) == II.OpInfo[i+NumResults].RegClass && - "Register class of operand and regclass of use don't agree!"); - } else if (ConstantSDNode *C = - dyn_cast(Node->getOperand(i))) { - MI->addZeroExtImm64Operand(C->getValue()); - } else if (RegisterSDNode*R = - dyn_cast(Node->getOperand(i))) { - MI->addRegOperand(R->getReg(), MachineOperand::Use); - } else if (GlobalAddressSDNode *TGA = - dyn_cast(Node->getOperand(i))) { - MI->addGlobalAddressOperand(TGA->getGlobal(), false, TGA->getOffset()); - } else if (BasicBlockSDNode *BB = - dyn_cast(Node->getOperand(i))) { - MI->addMachineBasicBlockOperand(BB->getBasicBlock()); - } else if (FrameIndexSDNode *FI = - dyn_cast(Node->getOperand(i))) { - MI->addFrameIndexOperand(FI->getIndex()); - } else if (ConstantPoolSDNode *CP = - dyn_cast(Node->getOperand(i))) { - unsigned Align = CP->getAlignment(); - // MachineConstantPool wants an explicit alignment. - if (Align == 0) { - if (CP->get()->getType() == Type::DoubleTy) - Align = 3; // always 8-byte align doubles. - else - Align = TM.getTargetData() - .getTypeAlignmentShift(CP->get()->getType()); - } - - unsigned Idx = ConstPool->getConstantPoolIndex(CP->get(), Align); - MI->addConstantPoolIndexOperand(Idx); - } else if (ExternalSymbolSDNode *ES = - dyn_cast(Node->getOperand(i))) { - MI->addExternalSymbolOperand(ES->getSymbol(), false); - } else { - assert(Node->getOperand(i).getValueType() != MVT::Other && - Node->getOperand(i).getValueType() != MVT::Flag && - "Chain and flag operands should occur at end of operand list!"); - unsigned VReg = getVR(Node->getOperand(i)); - MI->addRegOperand(VReg, MachineOperand::Use); - - // Verify that it is right. - assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); - assert(II.OpInfo[i+NumResults].RegClass && - "Don't have operand info for this instruction!"); - assert(RegMap->getRegClass(VReg) == II.OpInfo[i+NumResults].RegClass && - "Register class of operand and regclass of use don't agree!"); - } - } + for (unsigned i = 0; i != NodeOperands; ++i) + AddOperand(MI, Node->getOperand(i), i+NumResults, &II); // Now that we have emitted all operands, emit this instruction itself. if ((II.Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION) == 0) { From natebegeman at mac.com Fri Feb 24 13:05:06 2006 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 24 Feb 2006 13:05:06 -0600 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/Makefile.spec Message-ID: <200602241905.NAA05693@zion.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC: Makefile.spec updated: 1.51 -> 1.52 --- Log message: More makefile goodness --- Diffs of the changes: (+3 -1) Makefile.spec | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm-test/External/SPEC/Makefile.spec diff -u llvm-test/External/SPEC/Makefile.spec:1.51 llvm-test/External/SPEC/Makefile.spec:1.52 --- llvm-test/External/SPEC/Makefile.spec:1.51 Thu Feb 23 15:45:50 2006 +++ llvm-test/External/SPEC/Makefile.spec Fri Feb 24 13:04:54 2006 @@ -33,7 +33,9 @@ Source := $(wildcard $(SPEC_BENCH_DIR)/src/*.c \ $(SPEC_BENCH_DIR)/src/*.cc \ $(SPEC_BENCH_DIR)/src/*.cpp \ - $(SPEC_BENCH_DIR)/src/*.f) + $(SPEC_BENCH_DIR)/src/*.f \ + $(SPEC_BENCH_DIR)/src/*.f90 \ + $(SPEC_BENCH_DIR)/src/*.F90) endif # Disable the default Output/%.out-* targets... From lattner at cs.uiuc.edu Fri Feb 24 13:11:56 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 24 Feb 2006 13:11:56 -0600 Subject: [llvm-commits] CVS: llvm-test/Makefile.nagfortran Message-ID: <200602241911.NAA05774@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.nagfortran updated: 1.3 -> 1.4 --- Log message: Don't remove .f90/.F90 files from the srcdir! --- Diffs of the changes: (+3 -1) Makefile.nagfortran | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm-test/Makefile.nagfortran diff -u llvm-test/Makefile.nagfortran:1.3 llvm-test/Makefile.nagfortran:1.4 --- llvm-test/Makefile.nagfortran:1.3 Tue Jul 19 20:13:42 2005 +++ llvm-test/Makefile.nagfortran Fri Feb 24 13:11:45 2006 @@ -30,7 +30,9 @@ .PRECIOUS: %.c clean:: - rm -f $(Source:%.f=%.c) + rm -f $(patsubst %.f,%.c, $(filter %.f,$(Source))) \ + $(patsubst %.f90,%.c, $(filter %.f90,$(Source))) \ + $(patsubst %.F90,%.c, $(filter %.F90,$(Source))) %.c: %.f $(F95) -w -S -O2 $< -o $@ $(NAGFORTRAN_FLAGS) From lattner at cs.uiuc.edu Fri Feb 24 13:18:32 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 24 Feb 2006 13:18:32 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200602241918.NAA05895@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.68 -> 1.69 --- Log message: rename NumOps -> NumVals to avoid shadowing a NumOps var in an outer scope. Add support for addressing modes. --- Diffs of the changes: (+11 -5) ScheduleDAG.cpp | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.68 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.69 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.68 Fri Feb 24 12:54:03 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Feb 24 13:18:20 2006 @@ -326,32 +326,38 @@ // Add all of the operand registers to the instruction. for (unsigned i = 2; i != NumOps;) { unsigned Flags = cast(Node->getOperand(i))->getValue(); - unsigned NumOps = Flags >> 3; + unsigned NumVals = Flags >> 3; - MI->addZeroExtImm64Operand(NumOps); + MI->addZeroExtImm64Operand(NumVals); ++i; // Skip the ID value. switch (Flags & 7) { default: assert(0 && "Bad flags!"); case 1: // Use of register. - for (; NumOps; --NumOps, ++i) { + for (; NumVals; --NumVals, ++i) { unsigned Reg = cast(Node->getOperand(i))->getReg(); MI->addMachineRegOperand(Reg, MachineOperand::Use); } break; case 2: // Def of register. - for (; NumOps; --NumOps, ++i) { + for (; NumVals; --NumVals, ++i) { unsigned Reg = cast(Node->getOperand(i))->getReg(); MI->addMachineRegOperand(Reg, MachineOperand::Def); } break; case 3: { // Immediate. - assert(NumOps == 1 && "Unknown immediate value!"); + assert(NumVals == 1 && "Unknown immediate value!"); uint64_t Val = cast(Node->getOperand(i))->getValue(); MI->addZeroExtImm64Operand(Val); ++i; break; } + case 4: // Addressing mode. + // The addressing mode has been selected, just add all of the + // operands to the machine instruction. + for (; NumVals; --NumVals, ++i) + AddOperand(MI, Node->getOperand(i), 0, 0); + break; } } break; From lattner at cs.uiuc.edu Fri Feb 24 13:51:12 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 24 Feb 2006 13:51:12 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200602241951.NAA20370@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.53 -> 1.54 --- Log message: Pass all the flags to the asm printer, not just the # operands. --- Diffs of the changes: (+4 -2) AsmPrinter.cpp | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.53 llvm/lib/CodeGen/AsmPrinter.cpp:1.54 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.53 Thu Feb 23 13:21:04 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Fri Feb 24 13:50:58 2006 @@ -575,8 +575,10 @@ unsigned OpNo = 1; // Scan to find the machine operand number for the operand. - for (; Val; --Val) - OpNo += MI->getOperand(OpNo).getImmedValue()+1; + for (; Val; --Val) { + unsigned OpFlags = MI->getOperand(OpNo).getImmedValue(); + OpNo += (OpFlags >> 3) + 1; + } ++OpNo; // Skip over the ID number. From lattner at cs.uiuc.edu Fri Feb 24 13:51:12 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 24 Feb 2006 13:51:12 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200602241951.NAA20374@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.69 -> 1.70 --- Log message: Pass all the flags to the asm printer, not just the # operands. --- Diffs of the changes: (+1 -1) ScheduleDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.69 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.70 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.69 Fri Feb 24 13:18:20 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Feb 24 13:50:58 2006 @@ -328,7 +328,7 @@ unsigned Flags = cast(Node->getOperand(i))->getValue(); unsigned NumVals = Flags >> 3; - MI->addZeroExtImm64Operand(NumVals); + MI->addZeroExtImm64Operand(Flags); ++i; // Skip the ID value. switch (Flags & 7) { From lattner at cs.uiuc.edu Fri Feb 24 14:21:23 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 24 Feb 2006 14:21:23 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/AsmPrinter.h Message-ID: <200602242021.OAA17124@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: AsmPrinter.h updated: 1.30 -> 1.31 --- Log message: Add a PrintAsmMemoryOperand method for printing addresses --- Diffs of the changes: (+9 -1) AsmPrinter.h | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/AsmPrinter.h diff -u llvm/include/llvm/CodeGen/AsmPrinter.h:1.30 llvm/include/llvm/CodeGen/AsmPrinter.h:1.31 --- llvm/include/llvm/CodeGen/AsmPrinter.h:1.30 Wed Feb 8 17:41:34 2006 +++ llvm/include/llvm/CodeGen/AsmPrinter.h Fri Feb 24 14:21:12 2006 @@ -198,11 +198,19 @@ /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM /// instruction, using the specified assembler variant. Targets should - /// overried this to format as appropriate. This method can return true if + /// override this to format as appropriate. This method can return true if /// the operand is erroneous. virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode); + /// PrintAsmMemoryOperand - Print the specified operand of MI, an INLINEASM + /// instruction, using the specified assembler variant as an address. + /// Targets should override this to format as appropriate. This method can + /// return true if the operand is erroneous. + virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, + const char *ExtraCode); + /// SetupMachineFunction - This should be called when a new MachineFunction /// is being processed from runOnMachineFunction. void SetupMachineFunction(MachineFunction &MF); From lattner at cs.uiuc.edu Fri Feb 24 14:22:10 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 24 Feb 2006 14:22:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200602242022.OAA17190@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.54 -> 1.55 --- Log message: Use the PrintAsmMemoryOperand to print addressing modes. --- Diffs of the changes: (+19 -4) AsmPrinter.cpp | 23 +++++++++++++++++++---- 1 files changed, 19 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.54 llvm/lib/CodeGen/AsmPrinter.cpp:1.55 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.54 Fri Feb 24 13:50:58 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Fri Feb 24 14:21:58 2006 @@ -580,11 +580,19 @@ OpNo += (OpFlags >> 3) + 1; } + unsigned OpFlags = MI->getOperand(OpNo).getImmedValue(); ++OpNo; // Skip over the ID number. - - if (const_cast(this)-> - PrintAsmOperand(MI, OpNo, AsmPrinterVariant, - Modifier[0] ? Modifier : 0)) { + + bool Error; + AsmPrinter *AP = const_cast(this); + if ((OpFlags & 7) == 4 /*ADDR MODE*/) { + Error = AP->PrintAsmMemoryOperand(MI, OpNo, AsmPrinterVariant, + Modifier[0] ? Modifier : 0); + } else { + Error = AP->PrintAsmOperand(MI, OpNo, AsmPrinterVariant, + Modifier[0] ? Modifier : 0); + } + if (Error) { std::cerr << "Invalid operand found in inline asm: '" << AsmStr << "'\n"; MI->dump(); @@ -633,3 +641,10 @@ // Target doesn't support this yet! return true; } + +bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, + const char *ExtraCode) { + // Target doesn't support this yet! + return true; +} From lattner at cs.uiuc.edu Fri Feb 24 14:27:52 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 24 Feb 2006 14:27:52 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200602242027.OAA17327@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.155 -> 1.156 --- Log message: Add memory printing support for PPC. Input memory operands now work with inline asms! :) --- Diffs of the changes: (+12 -1) PPCAsmPrinter.cpp | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.155 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.156 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.155 Thu Feb 23 13:31:10 2006 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Fri Feb 24 14:27:40 2006 @@ -98,6 +98,9 @@ bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode); + bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, const char *ExtraCode); + void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo) { unsigned char value = MI->getOperand(OpNo).getImmedValue(); @@ -187,7 +190,7 @@ unsigned RegNo = enumRegToMachineReg(CCReg); O << (0x80 >> RegNo); } - // The new addressing mode printers, currently empty + // The new addressing mode printers. void printMemRegImm(const MachineInstr *MI, unsigned OpNo) { printSymbolLo(MI, OpNo); O << '('; @@ -419,6 +422,14 @@ return false; } +bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, + const char *ExtraCode) { + if (ExtraCode && ExtraCode[0]) + return true; // Unknown modifier. + printMemRegReg(MI, OpNo); + return false; +} /// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to /// the current output stream. From evan.cheng at apple.com Fri Feb 24 19:37:14 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 24 Feb 2006 19:37:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp Message-ID: <200602250137.TAA20193@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.126 -> 1.127 --- Log message: Fix an obvious bug exposed when we are doing ADD X, 4 ==> MOV32ri $X+4, ... --- Diffs of the changes: (+2 -1) X86RegisterInfo.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.126 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.127 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.126 Mon Feb 20 19:38:21 2006 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Fri Feb 24 19:37:02 2006 @@ -154,7 +154,8 @@ .addZImm(MI->getOperand(1).getImmedValue()); else if (MI->getOperand(1).isGlobalAddress()) return addFrameReference(BuildMI(Opcode, 5), FrameIndex) - .addGlobalAddress(MI->getOperand(1).getGlobal()); + .addGlobalAddress(MI->getOperand(1).getGlobal(), + false, MI->getOperand(1).getOffset()); assert(0 && "Unknown operand for MakeMI!"); return 0; } From lattner at cs.uiuc.edu Fri Feb 24 19:51:46 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 24 Feb 2006 19:51:46 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200602250151.TAA20322@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.55 -> 1.56 --- Log message: Refactor some code from being inline to being out in a new class with methods. This gets rid of two gotos, which is always nice, and also adds some comments. No functionality change, this is just a refactor. --- Diffs of the changes: (+97 -42) VirtRegMap.cpp | 139 +++++++++++++++++++++++++++++++++++++++------------------ 1 files changed, 97 insertions(+), 42 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.55 llvm/lib/CodeGen/VirtRegMap.cpp:1.56 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.55 Fri Feb 3 21:27:39 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 24 19:51:33 2006 @@ -269,6 +269,8 @@ return I->second >> 1; // Remove the CanClobber bit. return 0; } + + const MRegisterInfo *getRegInfo() const { return MRI; } /// addAvailable - Mark that the specified stack slot is available in the /// specified physreg. If CanClobber is true, the physreg can be modified at @@ -375,6 +377,88 @@ : Operand(o), StackSlot(ss), PhysRegReused(prr), AssignedPhysReg(apr), VirtReg(vreg) {} }; + + /// ReuseInfo - This maintains a collection of ReuseOp's for each operand that + /// is reused instead of reloaded. + class ReuseInfo { + MachineInstr &MI; + std::vector Reuses; + public: + ReuseInfo(MachineInstr &mi) : MI(mi) {} + + bool hasReuses() const { + return !Reuses.empty(); + } + + /// addReuse - If we choose to reuse a virtual register that is already + /// available instead of reloading it, remember that we did so. + void addReuse(unsigned OpNo, unsigned StackSlot, + unsigned PhysRegReused, unsigned AssignedPhysReg, + unsigned VirtReg) { + // If the reload is to the assigned register anyway, no undo will be + // required. + if (PhysRegReused == AssignedPhysReg) return; + + // Otherwise, remember this. + Reuses.push_back(ReusedOp(OpNo, StackSlot, PhysRegReused, + AssignedPhysReg, VirtReg)); + } + + /// GetRegForReload - We are about to emit a reload into PhysReg. If there + /// is some other operand that is using the specified register, either pick + /// a new register to use, or evict the previous reload and use this reg. + unsigned GetRegForReload(unsigned PhysReg, MachineInstr *MI, + AvailableSpills &Spills, + std::map &MaybeDeadStores) { + if (Reuses.empty()) return PhysReg; // This is most often empty. + + for (unsigned ro = 0, e = Reuses.size(); ro != e; ++ro) { + ReusedOp &Op = Reuses[ro]; + // If we find some other reuse that was supposed to use this register + // exactly for its reload, we can change this reload to use ITS reload + // register. + if (Op.PhysRegReused == PhysReg) { + // Yup, use the reload register that we didn't use before. + return GetRegForReload(Op.AssignedPhysReg, MI, + Spills, MaybeDeadStores); + } else { + // Otherwise, we might also have a problem if a previously reused + // value aliases the new register. If so, codegen the previous reload + // and use this one. + unsigned PRRU = Op.PhysRegReused; + const MRegisterInfo *MRI = Spills.getRegInfo(); + if (MRI->areAliases(PRRU, PhysReg)) { + // Okay, we found out that an alias of a reused register + // was used. This isn't good because it means we have + // to undo a previous reuse. + MachineBasicBlock *MBB = MI->getParent(); + const TargetRegisterClass *AliasRC = + MBB->getParent()->getSSARegMap()->getRegClass(Op.VirtReg); + MRI->loadRegFromStackSlot(*MBB, MI, Op.AssignedPhysReg, + Op.StackSlot, AliasRC); + Spills.ClobberPhysReg(Op.AssignedPhysReg); + Spills.ClobberPhysReg(Op.PhysRegReused); + + // Any stores to this stack slot are not dead anymore. + MaybeDeadStores.erase(Op.StackSlot); + + MI->SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg); + + Spills.addAvailable(Op.StackSlot, Op.AssignedPhysReg); + ++NumLoads; + DEBUG(MachineBasicBlock::iterator MII = MI; + std::cerr << '\t' << *prior(MII)); + + DEBUG(std::cerr << "Reuse undone!\n"); + Reuses.erase(Reuses.begin()+ro); + --NumReused; + return PhysReg; + } + } + } + return PhysReg; + } + }; } @@ -388,8 +472,6 @@ // that we can choose to reuse the physregs instead of emitting reloads. AvailableSpills Spills(MRI, TII); - std::vector ReusedOperands; - // DefAndUseVReg - When we see a def&use operand that is spilled, keep track // of it. ".first" is the machine operand index (should always be 0 for now), // and ".second" is the virtual register that is spilled. @@ -405,12 +487,18 @@ bool *PhysRegsUsed = MBB.getParent()->getUsedPhysregs(); + if (MBB.getBasicBlock()->getName() == "endif.3.i") + std::cerr << "HERE\n"; + for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end(); MII != E; ) { MachineInstr &MI = *MII; MachineBasicBlock::iterator NextMII = MII; ++NextMII; - ReusedOperands.clear(); + /// ReusedOperands - Keep track of operand reuse in case we need to undo + /// reuse. + ReuseInfo ReusedOperands(MI); + DefAndUseVReg.clear(); // Process all of the spilled uses and all non spilled reg references. @@ -480,8 +568,8 @@ // or R0 and R1 might not be compatible with each other. In this // case, we actually insert a reload for V1 in R1, ensuring that // we can get at R0 or its alias. - ReusedOperands.push_back(ReusedOp(i, StackSlot, PhysReg, - VRM.getPhys(VirtReg), VirtReg)); + ReusedOperands.addReuse(i, StackSlot, PhysReg, + VRM.getPhys(VirtReg), VirtReg); ++NumReused; continue; } @@ -492,47 +580,14 @@ const TargetRegisterClass* RC = MBB.getParent()->getSSARegMap()->getRegClass(VirtReg); - RecheckRegister: // Note that, if we reused a register for a previous operand, the // register we want to reload into might not actually be // available. If this occurs, use the register indicated by the // reuser. - if (!ReusedOperands.empty()) // This is most often empty. - for (unsigned ro = 0, e = ReusedOperands.size(); ro != e; ++ro) - if (ReusedOperands[ro].PhysRegReused == PhysReg) { - // Yup, use the reload register that we didn't use before. - PhysReg = ReusedOperands[ro].AssignedPhysReg; - goto RecheckRegister; - } else { - ReusedOp &Op = ReusedOperands[ro]; - unsigned PRRU = Op.PhysRegReused; - if (MRI->areAliases(PRRU, PhysReg)) { - // Okay, we found out that an alias of a reused register - // was used. This isn't good because it means we have - // to undo a previous reuse. - const TargetRegisterClass *AliasRC = - MBB.getParent()->getSSARegMap()->getRegClass(Op.VirtReg); - MRI->loadRegFromStackSlot(MBB, &MI, Op.AssignedPhysReg, - Op.StackSlot, AliasRC); - Spills.ClobberPhysReg(Op.AssignedPhysReg); - Spills.ClobberPhysReg(Op.PhysRegReused); - - // Any stores to this stack slot are not dead anymore. - MaybeDeadStores.erase(Op.StackSlot); - - MI.SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg); - - Spills.addAvailable(Op.StackSlot, Op.AssignedPhysReg); - ++NumLoads; - DEBUG(std::cerr << '\t' << *prior(MII)); - - DEBUG(std::cerr << "Reuse undone!\n"); - ReusedOperands.erase(ReusedOperands.begin()+ro); - --NumReused; - goto ContinueReload; - } - } - ContinueReload: + if (ReusedOperands.hasReuses()) + PhysReg = ReusedOperands.GetRegForReload(PhysReg, &MI, + Spills, MaybeDeadStores); + PhysRegsUsed[PhysReg] = true; MRI->loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot, RC); // This invalidates PhysReg. From lattner at cs.uiuc.edu Fri Feb 24 20:03:52 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 24 Feb 2006 20:03:52 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200602250203.UAA20506@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.56 -> 1.57 --- Log message: Remove debugging printout :) Add a minor compile time win, no codegen change. --- Diffs of the changes: (+6 -5) VirtRegMap.cpp | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.56 llvm/lib/CodeGen/VirtRegMap.cpp:1.57 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.56 Fri Feb 24 19:51:33 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 24 20:03:40 2006 @@ -419,8 +419,12 @@ // register. if (Op.PhysRegReused == PhysReg) { // Yup, use the reload register that we didn't use before. - return GetRegForReload(Op.AssignedPhysReg, MI, - Spills, MaybeDeadStores); + unsigned NewReg = Op.AssignedPhysReg; + + // Remove the record for the previous reuse. We know it can never be + // invalidated now. + Reuses.erase(Reuses.begin()+ro); + return GetRegForReload(NewReg, MI, Spills, MaybeDeadStores); } else { // Otherwise, we might also have a problem if a previously reused // value aliases the new register. If so, codegen the previous reload @@ -487,9 +491,6 @@ bool *PhysRegsUsed = MBB.getParent()->getUsedPhysregs(); - if (MBB.getBasicBlock()->getName() == "endif.3.i") - std::cerr << "HERE\n"; - for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end(); MII != E; ) { MachineInstr &MI = *MII; From lattner at cs.uiuc.edu Fri Feb 24 20:17:43 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 24 Feb 2006 20:17:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200602250217.UAA20647@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.57 -> 1.58 --- Log message: Fix a bug that Evan exposed with some changes he's making, and that was exposed with a fastcc problem (breaking pcompress2 on x86 with -enable-x86-fastcc). When reloading a reused reg, make sure to invalidate the reloaded reg, and check to see if there are any other pending uses of the same register. --- Diffs of the changes: (+23 -9) VirtRegMap.cpp | 32 +++++++++++++++++++++++--------- 1 files changed, 23 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.57 llvm/lib/CodeGen/VirtRegMap.cpp:1.58 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.57 Fri Feb 24 20:03:40 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 24 20:17:31 2006 @@ -437,25 +437,39 @@ // to undo a previous reuse. MachineBasicBlock *MBB = MI->getParent(); const TargetRegisterClass *AliasRC = - MBB->getParent()->getSSARegMap()->getRegClass(Op.VirtReg); - MRI->loadRegFromStackSlot(*MBB, MI, Op.AssignedPhysReg, - Op.StackSlot, AliasRC); - Spills.ClobberPhysReg(Op.AssignedPhysReg); - Spills.ClobberPhysReg(Op.PhysRegReused); + MBB->getParent()->getSSARegMap()->getRegClass(Op.VirtReg); + + // Copy Op out of the vector and remove it, we're going to insert an + // explicit load for it. + ReusedOp NewOp = Op; + Reuses.erase(Reuses.begin()+ro); + + // Ok, we're going to try to reload the assigned physreg into the + // slot that we were supposed to in the first place. However, that + // register could hold a reuse. Check to see if it conflicts or + // would prefer us to use a different register. + unsigned NewPhysReg = GetRegForReload(NewOp.AssignedPhysReg, + MI, Spills, MaybeDeadStores); + + MRI->loadRegFromStackSlot(*MBB, MI, NewPhysReg, + NewOp.StackSlot, AliasRC); + Spills.ClobberPhysReg(NewPhysReg); + Spills.ClobberPhysReg(NewOp.PhysRegReused); // Any stores to this stack slot are not dead anymore. - MaybeDeadStores.erase(Op.StackSlot); + MaybeDeadStores.erase(NewOp.StackSlot); - MI->SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg); + MI->SetMachineOperandReg(NewOp.Operand, NewPhysReg); - Spills.addAvailable(Op.StackSlot, Op.AssignedPhysReg); + Spills.addAvailable(NewOp.StackSlot, NewPhysReg); ++NumLoads; DEBUG(MachineBasicBlock::iterator MII = MI; std::cerr << '\t' << *prior(MII)); DEBUG(std::cerr << "Reuse undone!\n"); - Reuses.erase(Reuses.begin()+ro); --NumReused; + + // Finally, PhysReg is now available, go ahead and use it. return PhysReg; } } From lattner at cs.uiuc.edu Sat Feb 25 02:18:55 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 25 Feb 2006 02:18:55 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/div-2.ll Message-ID: <200602250818.CAA29150@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: div-2.ll updated: 1.2 -> 1.3 --- Log message: this fails, mark it as such --- Diffs of the changes: (+2 -0) div-2.ll | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/div-2.ll diff -u llvm/test/Regression/CodeGen/PowerPC/div-2.ll:1.2 llvm/test/Regression/CodeGen/PowerPC/div-2.ll:1.3 --- llvm/test/Regression/CodeGen/PowerPC/div-2.ll:1.2 Fri Oct 7 10:27:12 2005 +++ llvm/test/Regression/CodeGen/PowerPC/div-2.ll Sat Feb 25 02:18:43 2006 @@ -1,6 +1,8 @@ ; RUN: llvm-as < %s | llc -march=ppc32 | not grep srawi && ; RUN: llvm-as < %s | llc -march=ppc32 | grep blr +; XFAIL: * + int %test1(int %X) { %Y = and int %X, 15 %Z = div int %Y, 4 From evan.cheng at apple.com Sat Feb 25 03:53:08 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 25 Feb 2006 03:53:08 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineInstr.h MachineInstrBuilder.h SelectionDAG.h SelectionDAGNodes.h Message-ID: <200602250953.DAA26858@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineInstr.h updated: 1.164 -> 1.165 MachineInstrBuilder.h updated: 1.28 -> 1.29 SelectionDAG.h updated: 1.99 -> 1.100 SelectionDAGNodes.h updated: 1.103 -> 1.104 --- Log message: Added an offset field to ConstantPoolSDNode. --- Diffs of the changes: (+33 -22) MachineInstr.h | 16 ++++++++++------ MachineInstrBuilder.h | 8 +++++--- SelectionDAG.h | 10 ++++++---- SelectionDAGNodes.h | 21 ++++++++++++--------- 4 files changed, 33 insertions(+), 22 deletions(-) Index: llvm/include/llvm/CodeGen/MachineInstr.h diff -u llvm/include/llvm/CodeGen/MachineInstr.h:1.164 llvm/include/llvm/CodeGen/MachineInstr.h:1.165 --- llvm/include/llvm/CodeGen/MachineInstr.h:1.164 Wed Feb 22 10:23:43 2006 +++ llvm/include/llvm/CodeGen/MachineInstr.h Sat Feb 25 03:52:55 2006 @@ -131,7 +131,8 @@ // will be set for a value after reg allocation int offset; // Offset to address of global or external, only - // valid for MO_GlobalAddress and MO_ExternalSym + // valid for MO_GlobalAddress, MO_ExternalSym + // and MO_ConstantPoolIndex } extra; void zeroContents () { @@ -140,11 +141,14 @@ } MachineOperand(int64_t ImmVal = 0, - MachineOperandType OpTy = MO_VirtualRegister) + MachineOperandType OpTy = MO_VirtualRegister, int Offset = 0) : flags(0), opType(OpTy) { zeroContents (); contents.immedVal = ImmVal; - extra.regNum = -1; + if (OpTy == MachineOperand::MO_ConstantPoolIndex) + extra.offset = Offset; + else + extra.regNum = -1; } MachineOperand(int Reg, MachineOperandType OpTy, UseType UseTy) @@ -286,7 +290,7 @@ return (GlobalValue*)contents.value; } int getOffset() const { - assert((isGlobalAddress() || isExternalSymbol()) && + assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) && "Wrong MachineOperand accessor"); return extra.offset; } @@ -344,7 +348,7 @@ } void setOffset(int Offset) { - assert((isGlobalAddress() || isExternalSymbol()) && + assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) && "Wrong MachineOperand accessor"); extra.offset = Offset; } @@ -644,7 +648,7 @@ /// addConstantPoolndexOperand - Add a constant pool object index to the /// instruction. /// - void addConstantPoolIndexOperand(unsigned I) { + void addConstantPoolIndexOperand(unsigned I, int Offset=0) { assert(!OperandsComplete() && "Trying to add an operand to a machine instr that is already done!"); operands.push_back(MachineOperand(I, MachineOperand::MO_ConstantPoolIndex)); Index: llvm/include/llvm/CodeGen/MachineInstrBuilder.h diff -u llvm/include/llvm/CodeGen/MachineInstrBuilder.h:1.28 llvm/include/llvm/CodeGen/MachineInstrBuilder.h:1.29 --- llvm/include/llvm/CodeGen/MachineInstrBuilder.h:1.28 Thu Apr 21 15:38:00 2005 +++ llvm/include/llvm/CodeGen/MachineInstrBuilder.h Sat Feb 25 03:52:55 2006 @@ -125,13 +125,15 @@ return *this; } - const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx) const { - MI->addConstantPoolIndexOperand(Idx); + const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx, + int Offset = 0) const { + MI->addConstantPoolIndexOperand(Idx, Offset); return *this; } const MachineInstrBuilder &addGlobalAddress(GlobalValue *GV, - bool isPCRelative = false, int Offset = 0) const { + bool isPCRelative = false, + int Offset = 0) const { MI->addGlobalAddressOperand(GV, isPCRelative, Offset); return *this; } Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.99 llvm/include/llvm/CodeGen/SelectionDAG.h:1.100 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.99 Fri Feb 17 15:57:00 2006 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Sat Feb 25 03:52:55 2006 @@ -121,9 +121,9 @@ SDOperand getFrameIndex(int FI, MVT::ValueType VT); SDOperand getTargetFrameIndex(int FI, MVT::ValueType VT); SDOperand getConstantPool(Constant *C, MVT::ValueType VT, - unsigned Alignment=0); + unsigned Alignment=0, int offset = 0); SDOperand getTargetConstantPool(Constant *C, MVT::ValueType VT, - unsigned Alignment=0); + unsigned Alignment=0, int offset = 0); SDOperand getBasicBlock(MachineBasicBlock *MBB); SDOperand getExternalSymbol(const char *Sym, MVT::ValueType VT); SDOperand getTargetExternalSymbol(const char *Sym, MVT::ValueType VT); @@ -469,8 +469,10 @@ std::map, SDNode*> ConstantFPs; std::map, SDNode*> TargetConstantFPs; std::map FrameIndices, TargetFrameIndices; - std::map, SDNode*> ConstantPoolIndices; - std::map, SDNode*> TargetConstantPoolIndices; + std::map >, SDNode*> ConstantPoolIndices; + std::map >, SDNode*> TargetConstantPoolIndices; std::map BBNodes; std::vector ValueTypeNodes; std::map ExternalSymbols; Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.103 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.104 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.103 Wed Feb 22 10:23:43 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Sat Feb 25 03:52:55 2006 @@ -1028,19 +1028,19 @@ class GlobalAddressSDNode : public SDNode { GlobalValue *TheGlobal; - int offset; + int Offset; protected: friend class SelectionDAG; GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, MVT::ValueType VT, int o=0) - : SDNode(isTarget ? ISD::TargetGlobalAddress : ISD::GlobalAddress, VT) { + : SDNode(isTarget ? ISD::TargetGlobalAddress : ISD::GlobalAddress, VT), + Offset(o) { TheGlobal = const_cast(GA); - offset = o; } public: GlobalValue *getGlobal() const { return TheGlobal; } - int getOffset() const { return offset; } + int getOffset() const { return Offset; } static bool classof(const GlobalAddressSDNode *) { return true; } static bool classof(const SDNode *N) { @@ -1069,19 +1069,22 @@ class ConstantPoolSDNode : public SDNode { Constant *C; + int Offset; unsigned Alignment; protected: friend class SelectionDAG; - ConstantPoolSDNode(Constant *c, MVT::ValueType VT, bool isTarget) + ConstantPoolSDNode(bool isTarget, Constant *c, MVT::ValueType VT, + int o=0) : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, VT), - C(c), Alignment(0) {} - ConstantPoolSDNode(Constant *c, MVT::ValueType VT, unsigned Align, - bool isTarget) + C(c), Offset(o), Alignment(0) {} + ConstantPoolSDNode(bool isTarget, Constant *c, MVT::ValueType VT, int o, + unsigned Align) : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, VT), - C(c), Alignment(Align) {} + C(c), Offset(o), Alignment(Align) {} public: Constant *get() const { return C; } + int getOffset() const { return Offset; } // Return the alignment of this constant pool object, which is either 0 (for // default alignment) or log2 of the desired value. From evan.cheng at apple.com Sat Feb 25 03:54:01 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 25 Feb 2006 03:54:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp SelectionDAG.cpp Message-ID: <200602250954.DAA26985@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.70 -> 1.71 SelectionDAG.cpp updated: 1.259 -> 1.260 --- Log message: Added an offset field to ConstantPoolSDNode. --- Diffs of the changes: (+14 -9) ScheduleDAG.cpp | 3 ++- SelectionDAG.cpp | 20 ++++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.70 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.71 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.70 Fri Feb 24 13:50:58 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Sat Feb 25 03:53:49 2006 @@ -154,6 +154,7 @@ MI->addFrameIndexOperand(FI->getIndex()); } else if (ConstantPoolSDNode *CP = dyn_cast(Op)) { + int Offset = CP->getOffset(); unsigned Align = CP->getAlignment(); // MachineConstantPool wants an explicit alignment. if (Align == 0) { @@ -165,7 +166,7 @@ } unsigned Idx = ConstPool->getConstantPoolIndex(CP->get(), Align); - MI->addConstantPoolIndexOperand(Idx); + MI->addConstantPoolIndexOperand(Idx, Offset); } else if (ExternalSymbolSDNode *ES = dyn_cast(Op)) { MI->addExternalSymbolOperand(ES->getSymbol(), false); Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.259 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.260 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.259 Fri Feb 17 20:40:58 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Feb 25 03:53:49 2006 @@ -302,12 +302,14 @@ case ISD::ConstantPool: Erased = ConstantPoolIndices. erase(std::make_pair(cast(N)->get(), - cast(N)->getAlignment())); + std::make_pair(cast(N)->getOffset(), + cast(N)->getAlignment()))); break; case ISD::TargetConstantPool: Erased = TargetConstantPoolIndices. erase(std::make_pair(cast(N)->get(), - cast(N)->getAlignment())); + std::make_pair(cast(N)->getOffset(), + cast(N)->getAlignment()))); break; case ISD::BasicBlock: Erased = BBNodes.erase(cast(N)->getBasicBlock()); @@ -650,19 +652,21 @@ } SDOperand SelectionDAG::getConstantPool(Constant *C, MVT::ValueType VT, - unsigned Alignment) { - SDNode *&N = ConstantPoolIndices[std::make_pair(C, Alignment)]; + unsigned Alignment, int Offset) { + SDNode *&N = ConstantPoolIndices[std::make_pair(C, + std::make_pair(Offset, Alignment))]; if (N) return SDOperand(N, 0); - N = new ConstantPoolSDNode(C, VT, Alignment, false); + N = new ConstantPoolSDNode(false, C, VT, Offset, Alignment); AllNodes.push_back(N); return SDOperand(N, 0); } SDOperand SelectionDAG::getTargetConstantPool(Constant *C, MVT::ValueType VT, - unsigned Alignment) { - SDNode *&N = TargetConstantPoolIndices[std::make_pair(C, Alignment)]; + unsigned Alignment, int Offset) { + SDNode *&N = TargetConstantPoolIndices[std::make_pair(C, + std::make_pair(Offset, Alignment))]; if (N) return SDOperand(N, 0); - N = new ConstantPoolSDNode(C, VT, Alignment, true); + N = new ConstantPoolSDNode(true, C, VT, Offset, Alignment); AllNodes.push_back(N); return SDOperand(N, 0); } From evan.cheng at apple.com Sat Feb 25 03:55:04 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 25 Feb 2006 03:55:04 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp X86ATTAsmPrinter.cpp Message-ID: <200602250955.DAA27168@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86IntelAsmPrinter.cpp updated: 1.19 -> 1.20 X86ATTAsmPrinter.cpp updated: 1.26 -> 1.27 --- Log message: Added an offset field to ConstantPoolSDNode. --- Diffs of the changes: (+17 -32) X86ATTAsmPrinter.cpp | 23 ++++++++--------------- X86IntelAsmPrinter.cpp | 26 +++++++++----------------- 2 files changed, 17 insertions(+), 32 deletions(-) Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.19 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.20 --- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.19 Wed Feb 22 20:43:52 2006 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Sat Feb 25 03:54:52 2006 @@ -175,23 +175,6 @@ O << " + " << DispSpec.getImmedValue(); O << "]"; return; - } else if (BaseReg.isConstantPoolIndex()) { - O << "[" << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" - << BaseReg.getConstantPoolIndex(); - if (forDarwin && TM.getRelocationModel() == Reloc::PIC) - O << "-\"L" << getFunctionNumber() << "$pb\""; - - if (IndexReg.getReg()) { - O << " + "; - if (ScaleVal != 1) - O << ScaleVal << "*"; - printOp(IndexReg); - } - - if (DispSpec.getImmedValue()) - O << " + " << DispSpec.getImmedValue(); - O << "]"; - return; } O << "["; @@ -213,6 +196,15 @@ if (NeedPlus) O << " + "; printOp(DispSpec, "mem"); + } else if (DispSpec.isConstantPoolIndex()) { + O << "[" << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" + << DispSpec.getConstantPoolIndex(); + if (forDarwin && TM.getRelocationModel() == Reloc::PIC) + O << "-\"L" << getFunctionNumber() << "$pb\""; + if (DispSpec.getOffset()) + O << " + " << DispSpec.getOffset(); + O << "]"; + return; } else { int DispVal = DispSpec.getImmedValue(); if (DispVal || (!BaseReg.getReg() && !IndexReg.getReg())) { Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.26 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.27 --- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.26 Wed Feb 22 20:43:52 2006 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Sat Feb 25 03:54:52 2006 @@ -196,25 +196,18 @@ O << " + " << DispSpec.getImmedValue(); O << "]"; return; - } else if (BaseReg.isConstantPoolIndex()) { - O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" - << BaseReg.getConstantPoolIndex(); - if (forDarwin && TM.getRelocationModel() == Reloc::PIC) - O << "-\"L" << getFunctionNumber() << "$pb\""; - if (DispSpec.getImmedValue()) - O << "+" << DispSpec.getImmedValue(); - if (IndexReg.getReg()) { - O << "(,"; - printOperand(MI, Op+2); - if (ScaleVal != 1) - O << "," << ScaleVal; - O << ")"; - } - return; } if (DispSpec.isGlobalAddress()) { printOperand(MI, Op+3, "mem"); + } else if (DispSpec.isConstantPoolIndex()) { + O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" + << DispSpec.getConstantPoolIndex(); + if (forDarwin && TM.getRelocationModel() == Reloc::PIC) + O << "-\"L" << getFunctionNumber() << "$pb\""; + if (DispSpec.getOffset()) + O << "+" << DispSpec.getOffset(); + return; } else { int DispVal = DispSpec.getImmedValue(); if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) From evan.cheng at apple.com Sat Feb 25 03:55:32 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 25 Feb 2006 03:55:32 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200602250955.DAA27242@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.96 -> 1.97 --- Log message: Added a common about the need for X86ISD::Wrapper. --- Diffs of the changes: (+7 -0) X86ISelLowering.cpp | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.96 llvm/lib/Target/X86/X86ISelLowering.cpp:1.97 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.96 Thu Feb 23 14:41:18 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sat Feb 25 03:55:19 2006 @@ -1829,6 +1829,13 @@ return DAG.getNode(X86ISD::REP_MOVS, MVT::Other, Chain, DAG.getValueType(AVT), InFlag); } + + // ConstantPool, GlobalAddress, and ExternalSymbol are lowered as their + // target countpart wrapped in the X86ISD::Wrapper node. Suppose N is + // one of the above mentioned nodes. It has to be wrapped because otherwise + // Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only + // be used to form addressing mode. These wrapped nodes will be selected + // into MOV32ri. case ISD::ConstantPool: { ConstantPoolSDNode *CP = cast(Op); SDOperand Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), From evan.cheng at apple.com Sat Feb 25 03:57:02 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 25 Feb 2006 03:57:02 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86AsmPrinter.h Message-ID: <200602250957.DAA28938@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86AsmPrinter.h updated: 1.10 -> 1.11 --- Log message: ConstantPoolIndex is now the displacement field of addressing mode. --- Diffs of the changes: (+4 -3) X86AsmPrinter.h | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm/lib/Target/X86/X86AsmPrinter.h diff -u llvm/lib/Target/X86/X86AsmPrinter.h:1.10 llvm/lib/Target/X86/X86AsmPrinter.h:1.11 --- llvm/lib/Target/X86/X86AsmPrinter.h:1.10 Tue Dec 13 00:32:50 2005 +++ llvm/lib/Target/X86/X86AsmPrinter.h Sat Feb 25 03:56:50 2006 @@ -47,11 +47,12 @@ inline static bool isMem(const MachineInstr *MI, unsigned Op) { if (MI->getOperand(Op).isFrameIndex()) return true; - if (MI->getOperand(Op).isConstantPoolIndex()) return true; return Op+4 <= MI->getNumOperands() && MI->getOperand(Op ).isRegister() && isScale(MI->getOperand(Op+1)) && - MI->getOperand(Op+2).isRegister() && (MI->getOperand(Op+3).isImmediate()|| - MI->getOperand(Op+3).isGlobalAddress()); + MI->getOperand(Op+2).isRegister() && + (MI->getOperand(Op+3).isImmediate() || + MI->getOperand(Op+3).isGlobalAddress() || + MI->getOperand(Op+3).isConstantPoolIndex()); } }; From evan.cheng at apple.com Sat Feb 25 04:02:34 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 25 Feb 2006 04:02:34 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200602251002.EAA31222@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.249 -> 1.250 --- Log message: * Allow mul, shl nodes to be codegen'd as LEA (if appropriate). * Add patterns to handle GlobalAddress, ConstantPool, etc. MOV32ri to materialize these nodes in registers. ADD32ri to handle %reg + GA, etc. MOV32mi to handle store GA, etc. to memory. --- Diffs of the changes: (+24 -1) X86InstrInfo.td | 25 ++++++++++++++++++++++++- 1 files changed, 24 insertions(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.249 llvm/lib/Target/X86/X86InstrInfo.td:1.250 --- llvm/lib/Target/X86/X86InstrInfo.td:1.249 Thu Feb 23 14:41:18 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Sat Feb 25 04:02:21 2006 @@ -56,6 +56,8 @@ def SDTX86RdTsc : SDTypeProfile<0, 0, []>; +def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; + def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>; def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>; @@ -120,6 +122,8 @@ def X86loadp : SDNode<"X86ISD::LOAD_PACK", SDTLoad, [SDNPHasChain]>; +def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>; + //===----------------------------------------------------------------------===// // X86 Operand Definitions. // @@ -165,7 +169,7 @@ // Define X86 specific addressing mode. def addr : ComplexPattern; def leaaddr : ComplexPattern; + [add, mul, shl, frameindex]>; //===----------------------------------------------------------------------===// // X86 Instruction Format Definitions. @@ -2352,6 +2356,25 @@ // Non-Instruction Patterns //===----------------------------------------------------------------------===// +// ConstantPool GlobalAddress, ExternalSymbol +def : Pat<(i32 (X86Wrapper tconstpool :$dst)), (MOV32ri tconstpool :$dst)>; +def : Pat<(i32 (X86Wrapper tglobaladdr :$dst)), (MOV32ri tglobaladdr :$dst)>; +def : Pat<(i32 (X86Wrapper texternalsym:$dst)), (MOV32ri texternalsym:$dst)>; + +def : Pat<(add R32:$src1, (X86Wrapper tconstpool:$src2)), + (ADD32ri R32:$src1, tconstpool:$src2)>; +def : Pat<(add R32:$src1, (X86Wrapper tglobaladdr :$src2)), + (ADD32ri R32:$src1, tglobaladdr:$src2)>; +def : Pat<(add R32:$src1, (X86Wrapper texternalsym:$src2)), + (ADD32ri R32:$src1, texternalsym:$src2)>; + +def : Pat<(store (X86Wrapper tconstpool:$src), addr:$dst), + (MOV32mi addr:$dst, tconstpool:$src)>; +def : Pat<(store (X86Wrapper tglobaladdr:$src), addr:$dst), + (MOV32mi addr:$dst, tglobaladdr:$src)>; +def : Pat<(store (X86Wrapper texternalsym:$src), addr:$dst), + (MOV32mi addr:$dst, texternalsym:$src)>; + // Calls def : Pat<(X86call tglobaladdr:$dst), (CALLpcrel32 tglobaladdr:$dst)>; From evan.cheng at apple.com Sat Feb 25 04:04:21 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 25 Feb 2006 04:04:21 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602251004.EAA31588@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.60 -> 1.61 --- Log message: Updates. --- Diffs of the changes: (+3 -20) README.txt | 23 +++-------------------- 1 files changed, 3 insertions(+), 20 deletions(-) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.60 llvm/lib/Target/X86/README.txt:1.61 --- llvm/lib/Target/X86/README.txt:1.60 Wed Feb 22 23:17:43 2006 +++ llvm/lib/Target/X86/README.txt Sat Feb 25 04:04:07 2006 @@ -157,6 +157,7 @@ Use push/pop instructions in prolog/epilog sequences instead of stores off ESP (certain code size win, perf win on some [which?] processors). +Also, it appears icc use push for parameter passing. Need to investigate. //===---------------------------------------------------------------------===// @@ -411,22 +412,6 @@ //===---------------------------------------------------------------------===// -Easy: Global addresses are not always allowed as immediates. For this: - -int dst = 0; int *ptr = 0; -void foo() { ptr = &dst; } - -we get this: - -_foo: - movl $_dst, %eax - movl %eax, _ptr - ret - -When: "movl $_dst, _ptr" is sufficient. - -//===---------------------------------------------------------------------===// - Instead of the following for memset char*, 1, 10: movl $16843009, 4(%edx) @@ -505,10 +490,6 @@ //===---------------------------------------------------------------------===// -Select (add, x, GlobalAddress) to ADD32ri, etc. when it's appropriate. - -//===---------------------------------------------------------------------===// - The first BB of this code: declare bool %foo() @@ -533,4 +514,6 @@ It would be better to emit "cmp %al, 1" than a xor and test. +//===---------------------------------------------------------------------===// +Enable X86InstrInfo::convertToThreeAddress(). From evan.cheng at apple.com Sat Feb 25 04:09:21 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 25 Feb 2006 04:09:21 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200602251009.EAA32599@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.53 -> 1.54 --- Log message: * Cleaned up addressing mode matching code. * Cleaned up and tweaked LEA cost analysis code. Removed some hacks. * Handle ADD $X, c to MOV32ri $X+c. These patterns cannot be autogen'd and they need to be matched before LEA. --- Diffs of the changes: (+127 -156) X86ISelDAGToDAG.cpp | 283 +++++++++++++++++++++++----------------------------- 1 files changed, 127 insertions(+), 156 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.53 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.54 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.53 Thu Feb 23 14:41:18 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Sat Feb 25 04:09:08 2006 @@ -46,7 +46,6 @@ enum { RegBase, FrameIndexBase, - ConstantPoolBase } BaseType; struct { // This is really a union, discriminated by BaseType! @@ -58,9 +57,12 @@ SDOperand IndexReg; unsigned Disp; GlobalValue *GV; + Constant *CP; + unsigned Align; // CP alignment. X86ISelAddressMode() - : BaseType(RegBase), Scale(1), IndexReg(), Disp(0), GV(0) { + : BaseType(RegBase), Scale(1), IndexReg(), Disp(0), GV(0), + CP(0), Align(0) { } }; } @@ -132,7 +134,9 @@ Scale = getI8Imm(AM.Scale); Index = AM.IndexReg; Disp = AM.GV ? CurDAG->getTargetGlobalAddress(AM.GV, MVT::i32, AM.Disp) - : getI32Imm(AM.Disp); + : (AM.CP ? + CurDAG->getTargetConstantPool(AM.CP, MVT::i32, AM.Align, AM.Disp) + : getI32Imm(AM.Disp)); } /// getI8Imm - Return a target constant with the specified value, of type @@ -266,76 +270,54 @@ /// addressing mode bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM, bool isRoot) { - bool StopHere = false; - // If N has already been selected, we may or may not want to fold its - // operands into the addressing mode. It will result in code duplication! - // FIXME: Right now we do. That is, as long as the selected target node - // does not produce a chain. This may require a more sophisticated heuristics. + bool Available = false; + // If N has already been selected, reuse the result unless in some very + // specific cases. std::map::iterator CGMI= CodeGenMap.find(N.getValue(0)); if (CGMI != CodeGenMap.end()) { - if (isRoot) - // Stop here if it is a root. It's probably not profitable to go deeper. - StopHere = true; - else { - for (unsigned i = 0, e = CGMI->second.Val->getNumValues(); i != e; ++i) { - if (CGMI->second.Val->getValueType(i) == MVT::Other) - StopHere = true; - } - } + Available = true; } switch (N.getOpcode()) { default: break; - case ISD::FrameIndex: - if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) { - AM.BaseType = X86ISelAddressMode::FrameIndexBase; - AM.Base.FrameIndex = cast(N)->getIndex(); - return false; - } - break; + case ISD::Constant: + AM.Disp += cast(N)->getValue(); + return false; - case ISD::ConstantPool: - if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) { - if (ConstantPoolSDNode *CP = dyn_cast(N)) { - AM.BaseType = X86ISelAddressMode::ConstantPoolBase; - AM.Base.Reg = CurDAG->getTargetConstantPool(CP->get(), MVT::i32, - CP->getAlignment()); - return false; + case X86ISD::Wrapper: + // If both base and index components have been picked, we can't fit + // the result available in the register in the addressing mode. Duplicate + // GlobalAddress or ConstantPool as displacement. + if (!Available || (AM.Base.Reg.Val && AM.IndexReg.Val)) { + if (ConstantPoolSDNode *CP = + dyn_cast(N.getOperand(0))) { + if (AM.CP == 0) { + AM.CP = CP->get(); + AM.Align = CP->getAlignment(); + AM.Disp += CP->getOffset(); + return false; + } + } else if (GlobalAddressSDNode *G = + dyn_cast(N.getOperand(0))) { + if (AM.GV == 0) { + AM.GV = G->getGlobal(); + AM.Disp += G->getOffset(); + return false; + } } } break; - case ISD::GlobalAddress: - if (AM.GV == 0) { - AM.GV = cast(N)->getGlobal(); + case ISD::FrameIndex: + if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) { + AM.BaseType = X86ISelAddressMode::FrameIndexBase; + AM.Base.FrameIndex = cast(N)->getIndex(); return false; } break; - case X86ISD::Wrapper: - if (ConstantPoolSDNode *CP = - dyn_cast(N.getOperand(0))) { - if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) { - AM.BaseType = X86ISelAddressMode::ConstantPoolBase; - AM.Base.Reg = CurDAG->getTargetConstantPool(CP->get(), MVT::i32, - CP->getAlignment()); - return false; - } - } else if (GlobalAddressSDNode *G = - dyn_cast(N.getOperand(0))) { - if (AM.GV == 0) { - AM.GV = cast(N.getOperand(0))->getGlobal(); - return false; - } - } - break; - - case ISD::Constant: - AM.Disp += cast(N)->getValue(); - return false; - case ISD::SHL: - if (!StopHere && AM.IndexReg.Val == 0 && AM.Scale == 1) + if (!Available && AM.IndexReg.Val == 0 && AM.Scale == 1) if (ConstantSDNode *CN = dyn_cast(N.Val->getOperand(1))) { unsigned Val = CN->getValue(); if (Val == 1 || Val == 2 || Val == 3) { @@ -361,8 +343,10 @@ case ISD::MUL: // X*[3,5,9] -> X+X*[2,4,8] - if (!StopHere && AM.IndexReg.Val == 0 && AM.BaseType == X86ISelAddressMode::RegBase && - AM.Base.Reg.Val == 0) + if (!Available && + AM.BaseType == X86ISelAddressMode::RegBase && + AM.Base.Reg.Val == 0 && + AM.IndexReg.Val == 0) if (ConstantSDNode *CN = dyn_cast(N.Val->getOperand(1))) if (CN->getValue() == 3 || CN->getValue() == 5 || CN->getValue() == 9) { AM.Scale = unsigned(CN->getValue())-1; @@ -389,7 +373,7 @@ break; case ISD::ADD: { - if (!StopHere) { + if (!Available) { X86ISelAddressMode Backup = AM; if (!MatchAddress(N.Val->getOperand(0), AM, false) && !MatchAddress(N.Val->getOperand(1), AM, false)) @@ -406,10 +390,6 @@ // Is the base register already occupied? if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base.Reg.Val) { - // TargetConstantPool cannot be anything but the base. - if (N.getOpcode() == ISD::TargetConstantPool) - return true; - // If so, check to see if the scale index register is set. if (AM.IndexReg.Val == 0) { AM.IndexReg = N; @@ -445,24 +425,8 @@ AM.IndexReg = CurDAG->getRegister(0, MVT::i32); getAddressOperands(AM, Base, Scale, Index, Disp); - return true; -} - -bool X86DAGToDAGISel::TryFoldLoad(SDOperand P, SDOperand N, - SDOperand &Base, SDOperand &Scale, - SDOperand &Index, SDOperand &Disp) { - if (N.getOpcode() == ISD::LOAD && - N.hasOneUse() && - !CodeGenMap.count(N.getValue(0)) && - (P.getNumOperands() == 1 || !isNonImmUse(P.Val, N.Val))) - return SelectAddr(N.getOperand(1), Base, Scale, Index, Disp); - return false; -} -static bool isRegister0(SDOperand Op) { - if (RegisterSDNode *R = dyn_cast(Op)) - return (R->getReg() == 0); - return false; + return true; } /// SelectLEAAddr - it calls SelectAddr and determines if the maximal addressing @@ -472,57 +436,59 @@ SDOperand &Scale, SDOperand &Index, SDOperand &Disp) { X86ISelAddressMode AM; - if (!MatchAddress(N, AM)) { - bool SelectIndex = false; - bool Check = false; - if (AM.BaseType == X86ISelAddressMode::RegBase) { - if (AM.Base.Reg.Val) - Check = true; - else - AM.Base.Reg = CurDAG->getRegister(0, MVT::i32); - } + if (MatchAddress(N, AM)) + return false; - if (AM.IndexReg.Val) - SelectIndex = true; + unsigned Complexity = 0; + if (AM.BaseType == X86ISelAddressMode::RegBase) + if (AM.Base.Reg.Val) + Complexity = 1; else - AM.IndexReg = CurDAG->getRegister(0, MVT::i32); + AM.Base.Reg = CurDAG->getRegister(0, MVT::i32); + else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase) + Complexity = 4; - if (Check) { - unsigned Complexity = 0; - if (AM.Scale > 1) - Complexity++; - if (SelectIndex) - Complexity++; - if (AM.GV) { - Complexity++; - if (AM.Disp) - Complexity++; - } else if (AM.Disp > 1) - Complexity++; - // Suppose base == %eax and it has multiple uses, then instead of - // movl %eax, %ecx - // addl $8, %ecx - // use - // leal 8(%eax), %ecx. - // FIXME: If the other uses ended up being scheduled ahead of the leal - // then it would have been better to use the addl. The proper way to - // handle this is with using X86InstrInfo::convertToThreeAddress hook. - // From an email: - // BTW, this problem is the one that inspired the - // "X86InstrInfo::convertToThreeAddress" hook (which would handle this - // the "right" way). Unfortunately the X86 implementation of this is - // disabled, because we don't currently have enough information handy to - // know that the flags from the add is dead when the hook is called (from - // the register allocator). - if (AM.Base.Reg.Val->use_size() > 1) - Complexity++; - if (Complexity <= 1) - return false; - } + if (AM.IndexReg.Val) + Complexity++; + else + AM.IndexReg = CurDAG->getRegister(0, MVT::i32); + if (AM.Scale > 1) + Complexity += 2; + + // FIXME: We are artificially lowering the criteria to turn ADD %reg, $GA + // to a LEA. This is determined with some expermentation but is by no means + // optimal (especially for code size consideration). LEA is nice because of + // its three-address nature. Tweak the cost function again when we can run + // convertToThreeAddress() at register allocation time. + if (AM.GV || AM.CP) + Complexity += 2; + + if (AM.Disp && (AM.Base.Reg.Val || AM.IndexReg.Val)) + Complexity++; + + if (Complexity > 2) { getAddressOperands(AM, Base, Scale, Index, Disp); return true; } + + return false; +} + +bool X86DAGToDAGISel::TryFoldLoad(SDOperand P, SDOperand N, + SDOperand &Base, SDOperand &Scale, + SDOperand &Index, SDOperand &Disp) { + if (N.getOpcode() == ISD::LOAD && + N.hasOneUse() && + !CodeGenMap.count(N.getValue(0)) && + (P.getNumOperands() == 1 || !isNonImmUse(P.Val, N.Val))) + return SelectAddr(N.getOperand(1), Base, Scale, Index, Disp); + return false; +} + +static bool isRegister0(SDOperand Op) { + if (RegisterSDNode *R = dyn_cast(Op)) + return (R->getReg() == 0); return false; } @@ -589,37 +555,42 @@ Result = getGlobalBaseReg(); return; - case X86ISD::Wrapper: { - // It's beneficial to manully select the wrapper nodes here rather - // then using tablgen'd code to match this. We do not want to mutate the - // node to MOV32ri and we do not want to record this in CodeGenMap. - // We want to allow the wrapped leaf nodes be duplicated so they can - // be used in addressing modes. - // e.g. - // 0xa59e4a0: i32 = TargetGlobalAddress 0 - // 0xa59e740: i32 = X86ISD::Wrapper 0xa59e4a0 - // ... - // 0xa59e880: i32 = add 0xa59e740, 0xa59e800 - // ... - // 0xa59e880: - // 0xa59e970: i32 = add 0xa59e880, 0xa59e910 - // ... - // 0xa59ea60: i32,ch = load 0xa589780, 0xa59e970, 0xa59ea00 - // ... - // 0xa59e880: - // 0xa59eb60: ch = CopyToReg 0xa59ea60:1, 0xa59eaf0, 0xa59e880 - // By allowing the TargetGlobalAddress to be duplicated, it can appear - // in the load address as well as an operand of the add. - Result = SDOperand(CurDAG->getTargetNode(X86::MOV32ri, MVT::i32, - N.getOperand(0)), 0); -#ifndef NDEBUG - DEBUG(std::cerr << std::string(Indent-2, ' ')); - DEBUG(std::cerr << "== "); - DEBUG(Result.Val->dump(CurDAG)); - DEBUG(std::cerr << "\n"); - Indent -= 2; -#endif - return; + case ISD::ADD: { + // Turn ADD X, c to MOV32ri X+c. This cannot be done with tblgen'd + // code and is matched first so to prevent it from being turned into + // LEA32r X+c. + SDOperand N0 = N.getOperand(0); + SDOperand N1 = N.getOperand(1); + if (N.Val->getValueType(0) == MVT::i32 && + N0.getOpcode() == X86ISD::Wrapper && + N1.getOpcode() == ISD::Constant) { + unsigned Offset = (unsigned)cast(N1)->getValue(); + SDOperand C(0, 0); + // TODO: handle ExternalSymbolSDNode. + if (GlobalAddressSDNode *G = + dyn_cast(N0.getOperand(0))) { + C = CurDAG->getTargetGlobalAddress(G->getGlobal(), MVT::i32, + G->getOffset() + Offset); + } else if (ConstantPoolSDNode *CP = + dyn_cast(N0.getOperand(0))) { + C = CurDAG->getTargetConstantPool(CP->get(), MVT::i32, + CP->getAlignment(), + CP->getOffset()+Offset); + } + + if (C.Val) { + if (N.Val->hasOneUse()) { + Result = CurDAG->SelectNodeTo(N.Val, X86::MOV32ri, MVT::i32, C); + } else { + SDNode *ResNode = CurDAG->getTargetNode(X86::MOV32ri, MVT::i32, C); + Result = CodeGenMap[N] = SDOperand(ResNode, 0); + } + return; + } + } + + // Other cases are handled by auto-generated code. + break; } case ISD::MULHU: From evan.cheng at apple.com Sat Feb 25 04:15:36 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 25 Feb 2006 04:15:36 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/lea.ll Message-ID: <200602251015.EAA00893@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: lea.ll updated: 1.1 -> 1.2 --- Log message: lea.ll is XFAIL until we implement convertToThreeAddress. --- Diffs of the changes: (+2 -0) lea.ll | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/test/Regression/CodeGen/X86/lea.ll diff -u llvm/test/Regression/CodeGen/X86/lea.ll:1.1 llvm/test/Regression/CodeGen/X86/lea.ll:1.2 --- llvm/test/Regression/CodeGen/X86/lea.ll:1.1 Wed Feb 22 18:12:12 2006 +++ llvm/test/Regression/CodeGen/X86/lea.ll Sat Feb 25 04:15:22 2006 @@ -1,5 +1,7 @@ ; RUN: llvm-as < %s | llc -march=x86 | grep lea +; XFAIL: * + %G = weak global int 0 int %test1(int* %P, int %X) { %tmp.1 = getelementptr int* %P, int %X From evan.cheng at apple.com Sat Feb 25 04:16:23 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 25 Feb 2006 04:16:23 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/imul-lea.ll store-global-address.ll Message-ID: <200602251016.EAA00979@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: imul-lea.ll added (r1.1) store-global-address.ll added (r1.1) --- Log message: New test case: use lea for imul by some constants. --- Diffs of the changes: (+17 -0) imul-lea.ll | 8 ++++++++ store-global-address.ll | 9 +++++++++ 2 files changed, 17 insertions(+) Index: llvm/test/Regression/CodeGen/X86/imul-lea.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/imul-lea.ll:1.1 *** /dev/null Sat Feb 25 04:16:20 2006 --- llvm/test/Regression/CodeGen/X86/imul-lea.ll Sat Feb 25 04:16:10 2006 *************** *** 0 **** --- 1,8 ---- + ; RUN: llvm-as < %s | llc -march=x86 | grep lea + + declare int %foo() + int %test() { + %tmp.0 = tail call int %foo( ) ; [#uses=1] + %tmp.1 = mul int %tmp.0, 9 ; [#uses=1] + ret int %tmp.1 + } Index: llvm/test/Regression/CodeGen/X86/store-global-address.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/store-global-address.ll:1.1 *** /dev/null Sat Feb 25 04:16:23 2006 --- llvm/test/Regression/CodeGen/X86/store-global-address.ll Sat Feb 25 04:16:10 2006 *************** *** 0 **** --- 1,9 ---- + ; RUN: llvm-as < %s | llc -march=x86 | grep movl | wc -l | grep 1 + + %dst = global int 0 + %ptr = global int* null + + void %test() { + store int* %dst, int** %ptr + ret void + } From jlaskey at apple.com Sat Feb 25 06:27:16 2006 From: jlaskey at apple.com (Jim Laskey) Date: Sat, 25 Feb 2006 06:27:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AsmWriter.cpp Message-ID: <200602251227.GAA27598@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AsmWriter.cpp updated: 1.191 -> 1.192 --- Log message: Format large struct constants for readability. --- Diffs of the changes: (+13 -4) AsmWriter.cpp | 17 +++++++++++++---- 1 files changed, 13 insertions(+), 4 deletions(-) Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.191 llvm/lib/VMCore/AsmWriter.cpp:1.192 --- llvm/lib/VMCore/AsmWriter.cpp:1.191 Wed Jan 25 16:26:05 2006 +++ llvm/lib/VMCore/AsmWriter.cpp Sat Feb 25 06:27:03 2006 @@ -419,6 +419,7 @@ bool PrintName, std::map &TypeTable, SlotMachine *Machine) { + static std::string Indent = "\n"; if (const ConstantBool *CB = dyn_cast(CV)) { Out << (CB == ConstantBool::True ? "true" : "false"); } else if (const ConstantSInt *CI = dyn_cast(CV)) { @@ -482,22 +483,30 @@ } } else if (const ConstantStruct *CS = dyn_cast(CV)) { Out << '{'; - if (CS->getNumOperands()) { - Out << ' '; + unsigned N = CS->getNumOperands(); + if (N) { + if (N > 2) { + Indent += " "; + Out << Indent; + } else { + Out << ' '; + } printTypeInt(Out, CS->getOperand(0)->getType(), TypeTable); WriteAsOperandInternal(Out, CS->getOperand(0), PrintName, TypeTable, Machine); - for (unsigned i = 1; i < CS->getNumOperands(); i++) { + for (unsigned i = 1; i < N; i++) { Out << ", "; + if (N > 2) Out << Indent; printTypeInt(Out, CS->getOperand(i)->getType(), TypeTable); WriteAsOperandInternal(Out, CS->getOperand(i), PrintName, TypeTable, Machine); } + if (N > 2) Indent.resize(Indent.size() - 4); } - + Out << " }"; } else if (const ConstantPacked *CP = dyn_cast(CV)) { const Type *ETy = CP->getType()->getElementType(); From lattner at cs.uiuc.edu Sat Feb 25 12:37:54 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 25 Feb 2006 12:37:54 -0600 Subject: [llvm-commits] CVS: llvm-www/testresults/index.html Message-ID: <200602251837.MAA32256@zion.cs.uiuc.edu> Changes in directory llvm-www/testresults: index.html updated: 1.41 -> 1.42 --- Log message: Remove dead tester --- Diffs of the changes: (+1 -3) index.html | 4 +--- 1 files changed, 1 insertion(+), 3 deletions(-) Index: llvm-www/testresults/index.html diff -u llvm-www/testresults/index.html:1.41 llvm-www/testresults/index.html:1.42 --- llvm-www/testresults/index.html:1.41 Tue Jan 31 10:09:35 2006 +++ llvm-www/testresults/index.html Sat Feb 25 12:37:42 2006 @@ -45,13 +45,11 @@ "Tiger" on PowerPC G5 (dual 1.8Ghz CPU) -- debug build -

    Sparc V9

    +

    SPARC

    1. SunOS 5.8 on Sun Fire V240 (dual 1Ghz CPU) -- debug build ("V8" backend)
    2. -
    3. SunOS 5.8 on Sun Fire V240 (dual 1Ghz CPU) -- debug -build (dead)

    X86

    From evan.cheng at apple.com Sun Feb 26 02:28:24 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sun, 26 Feb 2006 02:28:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp X86ATTAsmPrinter.cpp Message-ID: <200602260828.CAA15515@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86IntelAsmPrinter.cpp updated: 1.20 -> 1.21 X86ATTAsmPrinter.cpp updated: 1.27 -> 1.28 --- Log message: Fixed ConstantPoolIndex operand asm print bug. This fixed 2005-07-17-INT-To-FP and 2005-05-12-Int64ToFP. --- Diffs of the changes: (+31 -19) X86ATTAsmPrinter.cpp | 24 +++++++++++++++--------- X86IntelAsmPrinter.cpp | 26 ++++++++++++++++---------- 2 files changed, 31 insertions(+), 19 deletions(-) Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.20 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.21 --- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.20 Sat Feb 25 03:54:52 2006 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Sun Feb 26 02:28:12 2006 @@ -109,6 +109,21 @@ assert(0 && "Shouldn't use addPCDisp() when building X86 MachineInstrs"); abort (); return; + case MachineOperand::MO_ConstantPoolIndex: { + bool isMemOp = Modifier && !strcmp(Modifier, "mem"); + if (!isMemOp) O << "OFFSET "; + O << "[" << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" + << MO.getConstantPoolIndex(); + if (forDarwin && TM.getRelocationModel() == Reloc::PIC) + O << "-\"L" << getFunctionNumber() << "$pb\""; + int Offset = MO.getOffset(); + if (Offset > 0) + O << " + " << Offset; + else if (Offset < 0) + O << Offset; + O << "]"; + return; + } case MachineOperand::MO_GlobalAddress: { bool isCallOp = Modifier && !strcmp(Modifier, "call"); bool isMemOp = Modifier && !strcmp(Modifier, "mem"); @@ -192,19 +207,10 @@ NeedPlus = true; } - if (DispSpec.isGlobalAddress()) { + if (DispSpec.isGlobalAddress() || DispSpec.isConstantPoolIndex()) { if (NeedPlus) O << " + "; printOp(DispSpec, "mem"); - } else if (DispSpec.isConstantPoolIndex()) { - O << "[" << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" - << DispSpec.getConstantPoolIndex(); - if (forDarwin && TM.getRelocationModel() == Reloc::PIC) - O << "-\"L" << getFunctionNumber() << "$pb\""; - if (DispSpec.getOffset()) - O << " + " << DispSpec.getOffset(); - O << "]"; - return; } else { int DispVal = DispSpec.getImmedValue(); if (DispVal || (!BaseReg.getReg() && !IndexReg.getReg())) { Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.27 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.28 --- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.27 Sat Feb 25 03:54:52 2006 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Sun Feb 26 02:28:12 2006 @@ -115,6 +115,20 @@ std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs"; abort (); return; + case MachineOperand::MO_ConstantPoolIndex: { + bool isMemOp = Modifier && !strcmp(Modifier, "mem"); + if (!isMemOp) O << '$'; + O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" + << MO.getConstantPoolIndex(); + if (forDarwin && TM.getRelocationModel() == Reloc::PIC) + O << "-\"L" << getFunctionNumber() << "$pb\""; + int Offset = MO.getOffset(); + if (Offset > 0) + O << "+" << Offset; + else if (Offset < 0) + O << Offset; + return; + } case MachineOperand::MO_GlobalAddress: { bool isCallOp = Modifier && !strcmp(Modifier, "call"); bool isMemOp = Modifier && !strcmp(Modifier, "mem"); @@ -198,16 +212,8 @@ return; } - if (DispSpec.isGlobalAddress()) { + if (DispSpec.isGlobalAddress() || DispSpec.isConstantPoolIndex()) { printOperand(MI, Op+3, "mem"); - } else if (DispSpec.isConstantPoolIndex()) { - O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" - << DispSpec.getConstantPoolIndex(); - if (forDarwin && TM.getRelocationModel() == Reloc::PIC) - O << "-\"L" << getFunctionNumber() << "$pb\""; - if (DispSpec.getOffset()) - O << "+" << DispSpec.getOffset(); - return; } else { int DispVal = DispSpec.getImmedValue(); if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) From evan.cheng at apple.com Sun Feb 26 02:37:09 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sun, 26 Feb 2006 02:37:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200602260837.CAA16895@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.260 -> 1.261 --- Log message: Print ConstantPoolSDNode offset field. --- Diffs of the changes: (+5 -0) SelectionDAG.cpp | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.260 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.261 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.260 Sat Feb 25 03:53:49 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sun Feb 26 02:36:57 2006 @@ -2761,7 +2761,12 @@ } else if (const FrameIndexSDNode *FIDN = dyn_cast(this)) { std::cerr << "<" << FIDN->getIndex() << ">"; } else if (const ConstantPoolSDNode *CP = dyn_cast(this)){ + int offset = CP->getOffset(); std::cerr << "<" << *CP->get() << ">"; + if (offset > 0) + std::cerr << " + " << offset; + else + std::cerr << " " << offset; } else if (const BasicBlockSDNode *BBDN = dyn_cast(this)) { std::cerr << "<"; const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock(); From evan.cheng at apple.com Sun Feb 26 03:12:50 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sun, 26 Feb 2006 03:12:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86CodeEmitter.cpp Message-ID: <200602260912.DAA04874@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86CodeEmitter.cpp updated: 1.91 -> 1.92 --- Log message: ConstantPoolIndex is now the displacement portion of the address (rather than base). --- Diffs of the changes: (+4 -10) X86CodeEmitter.cpp | 14 ++++---------- 1 files changed, 4 insertions(+), 10 deletions(-) Index: llvm/lib/Target/X86/X86CodeEmitter.cpp diff -u llvm/lib/Target/X86/X86CodeEmitter.cpp:1.91 llvm/lib/Target/X86/X86CodeEmitter.cpp:1.92 --- llvm/lib/Target/X86/X86CodeEmitter.cpp:1.91 Wed Feb 22 14:19:42 2006 +++ llvm/lib/Target/X86/X86CodeEmitter.cpp Sun Feb 26 03:12:34 2006 @@ -239,6 +239,9 @@ if (Op3.isGlobalAddress()) { GV = Op3.getGlobal(); DispVal = Op3.getOffset(); + } else if (Op3.isConstantPoolIndex()) { + DispVal += MCE.getConstantPoolEntryAddress(Op3.getConstantPoolIndex()); + DispVal += Op3.getOffset(); } else { DispVal = Op3.getImmedValue(); } @@ -247,16 +250,7 @@ const MachineOperand &Scale = MI.getOperand(Op+1); const MachineOperand &IndexReg = MI.getOperand(Op+2); - unsigned BaseReg = 0; - - if (Base.isConstantPoolIndex()) { - // Emit a direct address reference [disp32] where the displacement of the - // constant pool entry is controlled by the MCE. - assert(!GV && "Constant Pool reference cannot be relative to global!"); - DispVal += MCE.getConstantPoolEntryAddress(Base.getConstantPoolIndex()); - } else { - BaseReg = Base.getReg(); - } + unsigned BaseReg = Base.getReg(); // Is a SIB byte needed? if (IndexReg.getReg() == 0 && BaseReg != X86::ESP) { From jlaskey at apple.com Sun Feb 26 04:16:28 2006 From: jlaskey at apple.com (Jim Laskey) Date: Sun, 26 Feb 2006 04:16:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AsmWriter.cpp Message-ID: <200602261016.EAA14510@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AsmWriter.cpp updated: 1.192 -> 1.193 --- Log message: Reverting. Didn't realize some developers were embedding constants in their target assembler code gen. --- Diffs of the changes: (+1 -9) AsmWriter.cpp | 10 +--------- 1 files changed, 1 insertion(+), 9 deletions(-) Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.192 llvm/lib/VMCore/AsmWriter.cpp:1.193 --- llvm/lib/VMCore/AsmWriter.cpp:1.192 Sat Feb 25 06:27:03 2006 +++ llvm/lib/VMCore/AsmWriter.cpp Sun Feb 26 04:16:05 2006 @@ -419,7 +419,6 @@ bool PrintName, std::map &TypeTable, SlotMachine *Machine) { - static std::string Indent = "\n"; if (const ConstantBool *CB = dyn_cast(CV)) { Out << (CB == ConstantBool::True ? "true" : "false"); } else if (const ConstantSInt *CI = dyn_cast(CV)) { @@ -485,12 +484,7 @@ Out << '{'; unsigned N = CS->getNumOperands(); if (N) { - if (N > 2) { - Indent += " "; - Out << Indent; - } else { - Out << ' '; - } + Out << ' '; printTypeInt(Out, CS->getOperand(0)->getType(), TypeTable); WriteAsOperandInternal(Out, CS->getOperand(0), @@ -498,13 +492,11 @@ for (unsigned i = 1; i < N; i++) { Out << ", "; - if (N > 2) Out << Indent; printTypeInt(Out, CS->getOperand(i)->getType(), TypeTable); WriteAsOperandInternal(Out, CS->getOperand(i), PrintName, TypeTable, Machine); } - if (N > 2) Indent.resize(Indent.size() - 4); } Out << " }"; From lattner at cs.uiuc.edu Sun Feb 26 13:55:52 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 26 Feb 2006 13:55:52 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/or.ll Message-ID: <200602261955.NAA31105@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: or.ll updated: 1.31 -> 1.32 --- Log message: new testcase --- Diffs of the changes: (+8 -1) or.ll | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletion(-) Index: llvm/test/Regression/Transforms/InstCombine/or.ll diff -u llvm/test/Regression/Transforms/InstCombine/or.ll:1.31 llvm/test/Regression/Transforms/InstCombine/or.ll:1.32 --- llvm/test/Regression/Transforms/InstCombine/or.ll:1.31 Sun Feb 12 02:01:35 2006 +++ llvm/test/Regression/Transforms/InstCombine/or.ll Sun Feb 26 13:55:30 2006 @@ -1,6 +1,7 @@ ; This test makes sure that these instructions are properly eliminated. ; +; RUN: llvm-as < %s | opt -instcombine -disable-output && ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep -v xor | not grep 'or ' implementation @@ -148,4 +149,10 @@ %ELIM5 = or int %ELIM41, %ELIM7 ; [#uses=1] ret int %ELIM5 } - + +ushort %test23(ushort %A) { + %B = shr ushort %A, ubyte 1 + %C = or ushort %B, 32768 ;; fold or into xor + %D = xor ushort %C, 8193 + ret ushort %D +} From lattner at cs.uiuc.edu Sun Feb 26 13:58:07 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 26 Feb 2006 13:58:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200602261958.NAA31196@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.438 -> 1.439 --- Log message: Fold (X|C1)^C2 -> X^(C1|C2) when possible. This implements InstCombine/or.ll:test23. --- Diffs of the changes: (+14 -0) InstructionCombining.cpp | 14 ++++++++++++++ 1 files changed, 14 insertions(+) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.438 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.439 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.438 Fri Feb 24 12:05:58 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sun Feb 26 13:57:54 2006 @@ -2846,6 +2846,20 @@ ConstantInt::get(I.getType(), 1)), Op0I->getOperand(0)); } + } else if (Op0I->getOpcode() == Instruction::Or) { + // (X|C1)^C2 -> X^(C1|C2) iff X&~C1 == 0 + if (MaskedValueIsZero(Op0I->getOperand(0), Op0CI->getZExtValue())) { + Constant *NewRHS = ConstantExpr::getOr(Op0CI, RHS); + // Anything in both C1 and C2 is known to be zero, remove it from + // NewRHS. + Constant *CommonBits = ConstantExpr::getAnd(Op0CI, RHS); + NewRHS = ConstantExpr::getAnd(NewRHS, + ConstantExpr::getNot(CommonBits)); + WorkList.push_back(Op0I); + I.setOperand(0, Op0I->getOperand(0)); + I.setOperand(1, NewRHS); + return &I; + } } } From lattner at cs.uiuc.edu Sun Feb 26 17:36:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 26 Feb 2006 17:36:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200602262336.RAA02346@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.37 -> 1.38 --- Log message: Add a bunch of missed cases. Perhaps the most significant of which is that assertzext produces zero bits. --- Diffs of the changes: (+206 -40) TargetLowering.cpp | 246 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 206 insertions(+), 40 deletions(-) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.37 llvm/lib/Target/TargetLowering.cpp:1.38 --- llvm/lib/Target/TargetLowering.cpp:1.37 Thu Feb 23 19:10:46 2006 +++ llvm/lib/Target/TargetLowering.cpp Sun Feb 26 17:36:02 2006 @@ -141,7 +141,7 @@ /// constant and return true. bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(SDOperand Op, uint64_t Demanded) { - // FIXME: ISD::SELECT + // FIXME: ISD::SELECT, ISD::SELECT_CC switch(Op.getOpcode()) { default: break; case ISD::AND: @@ -199,15 +199,13 @@ // We know all of the bits for a constant! KnownOne = cast(Op)->getValue() & DemandedMask; KnownZero = ~KnownOne & DemandedMask; - return false; + return false; // Don't fall through, will infinitely loop. case ISD::AND: // If either the LHS or the RHS are Zero, the result is zero. if (SimplifyDemandedBits(Op.getOperand(1), DemandedMask, KnownZero, KnownOne, TLO, Depth+1)) return true; assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); - // If something is known zero on the RHS, the bits aren't demanded on the - // LHS. if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask & ~KnownZero, KnownZero2, KnownOne2, TLO, Depth+1)) return true; @@ -338,6 +336,24 @@ KnownOne &= KnownOne2; KnownZero &= KnownZero2; break; + case ISD::SELECT_CC: + if (SimplifyDemandedBits(Op.getOperand(3), DemandedMask, KnownZero, + KnownOne, TLO, Depth+1)) + return true; + if (SimplifyDemandedBits(Op.getOperand(2), DemandedMask, KnownZero2, + KnownOne2, TLO, Depth+1)) + return true; + assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); + assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); + + // If the operands are constants, see if we can simplify them. + if (TLO.ShrinkDemandedConstant(Op, DemandedMask)) + return true; + + // Only known if known in both the LHS and RHS. + KnownOne &= KnownOne2; + KnownZero &= KnownZero2; + break; case ISD::SHL: if (ConstantSDNode *SA = dyn_cast(Op.getOperand(1))) { if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask >> SA->getValue(), @@ -408,19 +424,20 @@ MVT::ValueType VT = Op.getValueType(); MVT::ValueType EVT = cast(Op.getOperand(1))->getVT(); - // Sign or Zero extension. Compute the bits in the result that are not + // Sign extension. Compute the demanded bits in the result that are not // present in the input. - uint64_t NotIn = ~MVT::getIntVTBitMask(EVT); - uint64_t NewBits = MVT::getIntVTBitMask(VT) & NotIn; + uint64_t NewBits = ~MVT::getIntVTBitMask(EVT) & DemandedMask; - // Sign extension. + // If none of the extended bits are demanded, eliminate the sextinreg. + if (NewBits == 0) + return TLO.CombineTo(Op, Op.getOperand(0)); + uint64_t InSignBit = MVT::getIntVTSignBit(EVT); int64_t InputDemandedBits = DemandedMask & MVT::getIntVTBitMask(EVT); - // If any of the sign extended bits are demanded, we know that the sign + // Since the sign extended bits are demanded, we know that the sign // bit is demanded. - if (NewBits & DemandedMask) - InputDemandedBits |= InSignBit; + InputDemandedBits |= InSignBit; if (SimplifyDemandedBits(Op.getOperand(0), InputDemandedBits, KnownZero, KnownOne, TLO, Depth+1)) @@ -430,19 +447,105 @@ // If the sign bit of the input is known set or clear, then we know the // top bits of the result. - // If the input sign bit is known zero, or if the NewBits are not demanded - // convert this into a zero extension. - if ((KnownZero & InSignBit) || (NewBits & ~DemandedMask) == NewBits) { - return TLO.CombineTo(Op, Op.getOperand(0)); - } else if (KnownOne & InSignBit) { // Input sign bit known set + // If the input sign bit is known zero, convert this into a zero extension. + if (KnownZero & InSignBit) + return TLO.CombineTo(Op, + TLO.DAG.getZeroExtendInReg(Op.getOperand(0), EVT)); + + if (KnownOne & InSignBit) { // Input sign bit known set KnownOne |= NewBits; KnownZero &= ~NewBits; - } else { // Input sign bit unknown + } else { // Input sign bit unknown KnownZero &= ~NewBits; KnownOne &= ~NewBits; } break; } + case ISD::CTTZ: + case ISD::CTLZ: + case ISD::CTPOP: { + MVT::ValueType VT = Op.getValueType(); + unsigned LowBits = Log2_32(MVT::getSizeInBits(VT))+1; + KnownZero = ~((1ULL << LowBits)-1) & MVT::getIntVTBitMask(VT); + KnownOne = 0; + break; + } + case ISD::ZEXTLOAD: { + MVT::ValueType VT = cast(Op.getOperand(3))->getVT(); + KnownZero |= ~MVT::getIntVTBitMask(VT) & DemandedMask; + break; + } + case ISD::ZERO_EXTEND: { + uint64_t InMask = MVT::getIntVTBitMask(Op.getOperand(0).getValueType()); + + // If none of the top bits are demanded, convert this into an any_extend. + uint64_t NewBits = (~InMask) & DemandedMask; + if (NewBits == 0) + return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ANY_EXTEND, + Op.getValueType(), + Op.getOperand(0))); + + if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask & InMask, + KnownZero, KnownOne, TLO, Depth+1)) + return true; + assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); + KnownZero |= NewBits; + break; + } + case ISD::SIGN_EXTEND: { + MVT::ValueType InVT = Op.getOperand(0).getValueType(); + uint64_t InMask = MVT::getIntVTBitMask(InVT); + uint64_t InSignBit = MVT::getIntVTSignBit(InVT); + uint64_t NewBits = (~InMask) & DemandedMask; + + // If none of the top bits are demanded, convert this into an any_extend. + if (NewBits == 0) + return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ANY_EXTEND,Op.getValueType(), + Op.getOperand(0))); + + // Since some of the sign extended bits are demanded, we know that the sign + // bit is demanded. + uint64_t InDemandedBits = DemandedMask & InMask; + InDemandedBits |= InSignBit; + + if (SimplifyDemandedBits(Op.getOperand(0), InDemandedBits, KnownZero, + KnownOne, TLO, Depth+1)) + return true; + + // If the sign bit is known zero, convert this to a zero extend. + if (KnownZero & InSignBit) + return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ZERO_EXTEND, + Op.getValueType(), + Op.getOperand(0))); + + // If the sign bit is known one, the top bits match. + if (KnownOne & InSignBit) { + KnownOne |= NewBits; + KnownZero &= ~NewBits; + } else { // Otherwise, top bits aren't known. + KnownOne &= ~NewBits; + KnownZero &= ~NewBits; + } + break; + } + case ISD::ANY_EXTEND: { + uint64_t InMask = MVT::getIntVTBitMask(Op.getOperand(0).getValueType()); + if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask & InMask, + KnownZero, KnownOne, TLO, Depth+1)) + return true; + assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); + break; + } + case ISD::AssertZext: { + MVT::ValueType VT = cast(Op.getOperand(1))->getVT(); + uint64_t InMask = MVT::getIntVTBitMask(VT); + if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask & InMask, + KnownZero, KnownOne, TLO, Depth+1)) + return true; + assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); + KnownZero |= ~InMask & DemandedMask; + break; + } case ISD::ADD: if (ConstantSDNode *AA = dyn_cast(Op.getOperand(1))) { if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask, KnownZero, @@ -479,16 +582,13 @@ } } break; - case ISD::CTTZ: - case ISD::CTLZ: - case ISD::CTPOP: { - MVT::ValueType VT = Op.getValueType(); - unsigned LowBits = Log2_32(MVT::getSizeInBits(VT))+1; - KnownZero = ~((1ULL << LowBits)-1) & MVT::getIntVTBitMask(VT); - KnownOne = 0; - break; - } } + + // If we know the value of all of the demanded bits, return this as a + // constant. + if ((DemandedMask & (KnownZero|KnownOne)) == DemandedMask) + return TLO.CombineTo(Op, TLO.DAG.getConstant(KnownOne, Op.getValueType())); + return false; } @@ -630,6 +730,40 @@ } } return; + case ISD::SIGN_EXTEND_INREG: { + MVT::ValueType VT = Op.getValueType(); + MVT::ValueType EVT = cast(Op.getOperand(1))->getVT(); + + // Sign extension. Compute the demanded bits in the result that are not + // present in the input. + uint64_t NewBits = ~MVT::getIntVTBitMask(EVT) & Mask; + + uint64_t InSignBit = MVT::getIntVTSignBit(EVT); + int64_t InputDemandedBits = Mask & MVT::getIntVTBitMask(EVT); + + // If the sign extended bits are demanded, we know that the sign + // bit is demanded. + if (NewBits) + InputDemandedBits |= InSignBit; + + ComputeMaskedBits(Op.getOperand(0), InputDemandedBits, + KnownZero, KnownOne, Depth+1); + assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); + + // If the sign bit of the input is known set or clear, then we know the + // top bits of the result. + if (KnownZero & InSignBit) { // Input sign bit known clear + KnownZero |= NewBits; + KnownOne &= ~NewBits; + } else if (KnownOne & InSignBit) { // Input sign bit known set + KnownOne |= NewBits; + KnownZero &= ~NewBits; + } else { // Input sign bit unknown + KnownZero &= ~NewBits; + KnownOne &= ~NewBits; + } + return; + } case ISD::CTTZ: case ISD::CTLZ: case ISD::CTPOP: { @@ -640,28 +774,59 @@ return; } case ISD::ZEXTLOAD: { - unsigned SrcBits = - MVT::getSizeInBits(cast(Op.getOperand(3))->getVT()); - KnownZero |= ~((1ULL << SrcBits)-1); + MVT::ValueType VT = cast(Op.getOperand(3))->getVT(); + KnownZero |= ~MVT::getIntVTBitMask(VT) & Mask; return; } case ISD::ZERO_EXTEND: { - unsigned SrcBits = - MVT::getSizeInBits(Op.getOperand(0).getValueType()); - KnownZero |= ~((1ULL << SrcBits)-1); + uint64_t InMask = MVT::getIntVTBitMask(Op.getOperand(0).getValueType()); + uint64_t NewBits = (~InMask) & Mask; + ComputeMaskedBits(Op.getOperand(0), Mask & InMask, KnownZero, + KnownOne, Depth+1); + KnownZero |= NewBits & Mask; + KnownOne &= ~NewBits; + return; + } + case ISD::SIGN_EXTEND: { + MVT::ValueType InVT = Op.getOperand(0).getValueType(); + unsigned InBits = MVT::getSizeInBits(InVT); + uint64_t InMask = MVT::getIntVTBitMask(InVT); + uint64_t InSignBit = 1ULL << (InBits-1); + uint64_t NewBits = (~InMask) & Mask; + uint64_t InDemandedBits = Mask & InMask; + + // If any of the sign extended bits are demanded, we know that the sign + // bit is demanded. + if (NewBits & Mask) + InDemandedBits |= InSignBit; + + ComputeMaskedBits(Op.getOperand(0), InDemandedBits, KnownZero, + KnownOne, Depth+1); + // If the sign bit is known zero or one, the top bits match. + if (KnownZero & InSignBit) { + KnownZero |= NewBits; + KnownOne &= ~NewBits; + } else if (KnownOne & InSignBit) { + KnownOne |= NewBits; + KnownZero &= ~NewBits; + } else { // Otherwise, top bits aren't known. + KnownOne &= ~NewBits; + KnownZero &= ~NewBits; + } return; } case ISD::ANY_EXTEND: { - unsigned SrcBits = - MVT::getSizeInBits(Op.getOperand(0).getValueType()); - KnownZero &= ((1ULL << SrcBits)-1); - KnownOne &= ((1ULL << SrcBits)-1); + MVT::ValueType VT = Op.getOperand(0).getValueType(); + ComputeMaskedBits(Op.getOperand(0), Mask & MVT::getIntVTBitMask(VT), + KnownZero, KnownOne, Depth+1); return; } case ISD::AssertZext: { - unsigned SrcBits = - MVT::getSizeInBits(cast(Op.getOperand(1))->getVT()); - KnownZero |= ~((1ULL << SrcBits)-1); + MVT::ValueType VT = cast(Op.getOperand(1))->getVT(); + uint64_t InMask = MVT::getIntVTBitMask(VT); + ComputeMaskedBits(Op.getOperand(0), Mask & InMask, KnownZero, + KnownOne, Depth+1); + KnownZero |= (~InMask) & Mask; return; } case ISD::ADD: { @@ -683,7 +848,8 @@ case ISD::SUB: // We know that the top bits of C-X are clear if X contains less bits // than C (i.e. no wrap-around can happen). For example, 20-X is - // positive if we can prove that X is >= 0 and < 16. + // positive if we can prove that X is >= 0 and < 16. Remember to update + // SimplifyDemandedBits if/when this is implemented. return; default: // Allow the target to implement this method for its nodes. From lattner at cs.uiuc.edu Sun Feb 26 18:20:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 26 Feb 2006 18:20:35 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/and-elim.ll Message-ID: <200602270020.SAA03732@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: and-elim.ll updated: 1.1 -> 1.2 --- Log message: new testcase --- Diffs of the changes: (+7 -0) and-elim.ll | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/and-elim.ll diff -u llvm/test/Regression/CodeGen/PowerPC/and-elim.ll:1.1 llvm/test/Regression/CodeGen/PowerPC/and-elim.ll:1.2 --- llvm/test/Regression/CodeGen/PowerPC/and-elim.ll:1.1 Mon Oct 10 16:21:36 2005 +++ llvm/test/Regression/CodeGen/PowerPC/and-elim.ll Sun Feb 26 18:20:23 2006 @@ -9,3 +9,10 @@ store ubyte %Z, ubyte* %P ret void } + +ushort %test2(ushort %crc) { ; No and's should be needed for the ushorts here. + %tmp.1 = shr ushort %crc, ubyte 1 + %tmp.7 = xor ushort %tmp.1, 40961 + ret ushort %tmp.7 +} + From lattner at cs.uiuc.edu Sun Feb 26 18:22:39 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 26 Feb 2006 18:22:39 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200602270022.SAA03745@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.38 -> 1.39 --- Log message: Just like we use the RHS of an AND to simplify the LHS, use the LHS to simplify the RHS. This allows for the elimination of many thousands of ands from multisource, and compiles CodeGen/PowerPC/and-elim.ll:test2 into this: _test2: srwi r2, r3, 1 xori r3, r2, 40961 blr instead of this: _test2: rlwinm r2, r3, 31, 17, 31 xori r2, r2, 40961 rlwinm r3, r2, 0, 16, 31 blr --- Diffs of the changes: (+17 -0) TargetLowering.cpp | 17 +++++++++++++++++ 1 files changed, 17 insertions(+) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.38 llvm/lib/Target/TargetLowering.cpp:1.39 --- llvm/lib/Target/TargetLowering.cpp:1.38 Sun Feb 26 17:36:02 2006 +++ llvm/lib/Target/TargetLowering.cpp Sun Feb 26 18:22:28 2006 @@ -223,6 +223,23 @@ // If the RHS is a constant, see if we can simplify it. if (TLO.ShrinkDemandedConstant(Op, DemandedMask & ~KnownZero2)) return true; + + // If the RHS is a constant, check to see if the LHS would be zero without + // using the bits from the RHS. Above, we used knowledge about the RHS to + // simplify the LHS, here we're using information from the LHS to simplify + // the RHS. + if (ConstantSDNode *RHSC = dyn_cast(Op.getOperand(1))) { + uint64_t LHSZero, LHSOne; + ComputeMaskedBits(Op.getOperand(0), DemandedMask, + LHSZero, LHSOne, Depth+1); + // If the LHS already has zeros where RHSC does, this and is dead. + if ((LHSZero & DemandedMask) == (~RHSC->getValue() & DemandedMask)) + return TLO.CombineTo(Op, Op.getOperand(0)); + // If any of the set bits in the RHS are known zero on the LHS, shrink + // the constant. + if (TLO.ShrinkDemandedConstant(Op, ~LHSZero & DemandedMask)) + return true; + } // Output known-1 bits are only known if set in both the LHS & RHS. KnownOne &= KnownOne2; From lattner at cs.uiuc.edu Sun Feb 26 18:36:39 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 26 Feb 2006 18:36:39 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200602270036.SAA03832@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.39 -> 1.40 --- Log message: Check RHS simplification before LHS simplification to avoid infinitely looping on PowerPC/small-arguments.ll --- Diffs of the changes: (+17 -18) TargetLowering.cpp | 35 +++++++++++++++++------------------ 1 files changed, 17 insertions(+), 18 deletions(-) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.39 llvm/lib/Target/TargetLowering.cpp:1.40 --- llvm/lib/Target/TargetLowering.cpp:1.39 Sun Feb 26 18:22:28 2006 +++ llvm/lib/Target/TargetLowering.cpp Sun Feb 26 18:36:27 2006 @@ -201,7 +201,23 @@ KnownZero = ~KnownOne & DemandedMask; return false; // Don't fall through, will infinitely loop. case ISD::AND: - // If either the LHS or the RHS are Zero, the result is zero. + // If the RHS is a constant, check to see if the LHS would be zero without + // using the bits from the RHS. Below, we use knowledge about the RHS to + // simplify the LHS, here we're using information from the LHS to simplify + // the RHS. + if (ConstantSDNode *RHSC = dyn_cast(Op.getOperand(1))) { + uint64_t LHSZero, LHSOne; + ComputeMaskedBits(Op.getOperand(0), DemandedMask, + LHSZero, LHSOne, Depth+1); + // If the LHS already has zeros where RHSC does, this and is dead. + if ((LHSZero & DemandedMask) == (~RHSC->getValue() & DemandedMask)) + return TLO.CombineTo(Op, Op.getOperand(0)); + // If any of the set bits in the RHS are known zero on the LHS, shrink + // the constant. + if (TLO.ShrinkDemandedConstant(Op, ~LHSZero & DemandedMask)) + return true; + } + if (SimplifyDemandedBits(Op.getOperand(1), DemandedMask, KnownZero, KnownOne, TLO, Depth+1)) return true; @@ -224,23 +240,6 @@ if (TLO.ShrinkDemandedConstant(Op, DemandedMask & ~KnownZero2)) return true; - // If the RHS is a constant, check to see if the LHS would be zero without - // using the bits from the RHS. Above, we used knowledge about the RHS to - // simplify the LHS, here we're using information from the LHS to simplify - // the RHS. - if (ConstantSDNode *RHSC = dyn_cast(Op.getOperand(1))) { - uint64_t LHSZero, LHSOne; - ComputeMaskedBits(Op.getOperand(0), DemandedMask, - LHSZero, LHSOne, Depth+1); - // If the LHS already has zeros where RHSC does, this and is dead. - if ((LHSZero & DemandedMask) == (~RHSC->getValue() & DemandedMask)) - return TLO.CombineTo(Op, Op.getOperand(0)); - // If any of the set bits in the RHS are known zero on the LHS, shrink - // the constant. - if (TLO.ShrinkDemandedConstant(Op, ~LHSZero & DemandedMask)) - return true; - } - // Output known-1 bits are only known if set in both the LHS & RHS. KnownOne &= KnownOne2; // Output known-0 are known to be clear if zero in either the LHS | RHS. From lattner at cs.uiuc.edu Sun Feb 26 18:39:43 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 26 Feb 2006 18:39:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200602270039.SAA03916@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.109 -> 1.110 --- Log message: remove some completed notes --- Diffs of the changes: (+0 -4) DAGCombiner.cpp | 4 ---- 1 files changed, 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.109 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.110 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.109 Mon Feb 20 00:51:04 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sun Feb 26 18:39:31 2006 @@ -16,10 +16,6 @@ // some kind of hint from the target that int div is expensive. // various folds of mulh[s,u] by constants such as -1, powers of 2, etc. // -// FIXME: Should add a corresponding version of fold AND with -// ZERO_EXTEND/SIGN_EXTEND by converting them to an ANY_EXTEND node which -// we don't have yet. -// // FIXME: select C, pow2, pow2 -> something smart // FIXME: trunc(select X, Y, Z) -> select X, trunc(Y), trunc(Z) // FIXME: Dead stores -> nuke From lattner at cs.uiuc.edu Sun Feb 26 19:00:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 26 Feb 2006 19:00:24 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/div-2.ll Message-ID: <200602270100.TAA04146@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: div-2.ll updated: 1.3 -> 1.4 --- Log message: Reenable this --- Diffs of the changes: (+0 -2) div-2.ll | 2 -- 1 files changed, 2 deletions(-) Index: llvm/test/Regression/CodeGen/PowerPC/div-2.ll diff -u llvm/test/Regression/CodeGen/PowerPC/div-2.ll:1.3 llvm/test/Regression/CodeGen/PowerPC/div-2.ll:1.4 --- llvm/test/Regression/CodeGen/PowerPC/div-2.ll:1.3 Sat Feb 25 02:18:43 2006 +++ llvm/test/Regression/CodeGen/PowerPC/div-2.ll Sun Feb 26 19:00:12 2006 @@ -1,8 +1,6 @@ ; RUN: llvm-as < %s | llc -march=ppc32 | not grep srawi && ; RUN: llvm-as < %s | llc -march=ppc32 | grep blr -; XFAIL: * - int %test1(int %X) { %Y = and int %X, 15 %Z = div int %Y, 4 From lattner at cs.uiuc.edu Sun Feb 26 19:00:54 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 26 Feb 2006 19:00:54 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200602270100.TAA04179@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.40 -> 1.41 --- Log message: Implement bit propagation through sub nodes, this (re)implements PowerPC/div-2.ll --- Diffs of the changes: (+29 -3) TargetLowering.cpp | 32 +++++++++++++++++++++++++++++--- 1 files changed, 29 insertions(+), 3 deletions(-) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.40 llvm/lib/Target/TargetLowering.cpp:1.41 --- llvm/lib/Target/TargetLowering.cpp:1.40 Sun Feb 26 18:36:27 2006 +++ llvm/lib/Target/TargetLowering.cpp Sun Feb 26 19:00:42 2006 @@ -598,6 +598,12 @@ } } break; + case ISD::SUB: + // Just use ComputeMaskedBits to compute output bits, there are no + // simplifications that can be done here, and sub always demands all input + // bits. + ComputeMaskedBits(Op, DemandedMask, KnownZero, KnownOne, Depth); + break; } // If we know the value of all of the demanded bits, return this as a @@ -861,12 +867,32 @@ KnownOne = 0; return; } - case ISD::SUB: + case ISD::SUB: { + ConstantSDNode *CLHS = dyn_cast(Op.getOperand(0)); + if (!CLHS) return; + // We know that the top bits of C-X are clear if X contains less bits // than C (i.e. no wrap-around can happen). For example, 20-X is - // positive if we can prove that X is >= 0 and < 16. Remember to update - // SimplifyDemandedBits if/when this is implemented. + // positive if we can prove that X is >= 0 and < 16. + MVT::ValueType VT = CLHS->getValueType(0); + if ((CLHS->getValue() & MVT::getIntVTSignBit(VT)) == 0) { // sign bit clear + unsigned NLZ = CountLeadingZeros_64(CLHS->getValue()+1); + uint64_t MaskV = (1ULL << (63-NLZ))-1; // NLZ can't be 64 with no sign bit + MaskV = ~MaskV & MVT::getIntVTBitMask(VT); + ComputeMaskedBits(Op.getOperand(1), MaskV, KnownZero, KnownOne, Depth+1); + + // If all of the MaskV bits are known to be zero, then we know the output + // top bits are zero, because we now know that the output is from [0-C]. + if ((KnownZero & MaskV) == MaskV) { + unsigned NLZ2 = CountLeadingZeros_64(CLHS->getValue()); + KnownZero = ~((1ULL << (64-NLZ2))-1) & Mask; // Top bits known zero. + KnownOne = 0; // No one bits known. + } else { + KnownOne = KnownOne = 0; // Otherwise, nothing known. + } + } return; + } default: // Allow the target to implement this method for its nodes. if (Op.getOpcode() >= ISD::BUILTIN_OP_END) From lattner at cs.uiuc.edu Sun Feb 26 19:43:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 26 Feb 2006 19:43:14 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/xor.ll sub.ll Message-ID: <200602270143.TAA04390@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: xor.ll updated: 1.15 -> 1.16 sub.ll updated: 1.21 -> 1.22 --- Log message: New testcases --- Diffs of the changes: (+24 -0) sub.ll | 13 +++++++++++++ xor.ll | 11 +++++++++++ 2 files changed, 24 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/xor.ll diff -u llvm/test/Regression/Transforms/InstCombine/xor.ll:1.15 llvm/test/Regression/Transforms/InstCombine/xor.ll:1.16 --- llvm/test/Regression/Transforms/InstCombine/xor.ll:1.15 Sat Feb 11 19:32:58 2006 +++ llvm/test/Regression/Transforms/InstCombine/xor.ll Sun Feb 26 19:43:02 2006 @@ -155,3 +155,14 @@ ret int %Q } +bool %test23(int %a, int %b) { + %tmp.2 = xor int %b, %a + %tmp.4 = seteq int %tmp.2, %a + ret bool %tmp.4 +} + +bool %test24(int %c, int %d) { + %tmp.2 = xor int %d, %c + %tmp.4 = setne int %tmp.2, %c + ret bool %tmp.4 +} Index: llvm/test/Regression/Transforms/InstCombine/sub.ll diff -u llvm/test/Regression/Transforms/InstCombine/sub.ll:1.21 llvm/test/Regression/Transforms/InstCombine/sub.ll:1.22 --- llvm/test/Regression/Transforms/InstCombine/sub.ll:1.21 Thu Apr 7 11:41:45 2005 +++ llvm/test/Regression/Transforms/InstCombine/sub.ll Sun Feb 26 19:43:02 2006 @@ -124,3 +124,16 @@ %Q = add int %Z, %Y ret int %Q } + +bool %test20(int %g, int %h) { + %tmp.2 = sub int %g, %h + %tmp.4 = setne int %tmp.2, %g + ret bool %tmp.4 +} + +bool %test21(int %g, int %h) { + %tmp.2 = sub int %g, %h + %tmp.4 = setne int %tmp.2, %g + ret bool %tmp.4 +} + From lattner at cs.uiuc.edu Sun Feb 26 19:44:23 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 26 Feb 2006 19:44:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200602270144.TAA04427@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.439 -> 1.440 --- Log message: Fold (A^B) == A -> B == 0 and (A-B) == A -> B == 0 --- Diffs of the changes: (+26 -0) InstructionCombining.cpp | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.439 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.440 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.439 Sun Feb 26 13:57:54 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sun Feb 26 19:44:11 2006 @@ -3876,6 +3876,32 @@ if (Instruction *R = visitSetCondInstWithCastAndCast(I)) return R; } + + if (I.getOpcode() == Instruction::SetNE || + I.getOpcode() == Instruction::SetEQ) { + Value *A, *B; + if (match(Op0, m_Xor(m_Value(A), m_Value(B))) && + (A == Op1 || B == Op1)) { + // (A^B) == A -> B == 0 + Value *OtherVal = A == Op1 ? B : A; + return BinaryOperator::create(I.getOpcode(), OtherVal, + Constant::getNullValue(A->getType())); + } else if (match(Op1, m_Xor(m_Value(A), m_Value(B))) && + (A == Op0 || B == Op0)) { + // A == (A^B) -> B == 0 + Value *OtherVal = A == Op0 ? B : A; + return BinaryOperator::create(I.getOpcode(), OtherVal, + Constant::getNullValue(A->getType())); + } else if (match(Op0, m_Sub(m_Value(A), m_Value(B))) && A == Op1) { + // (A-B) == A -> B == 0 + return BinaryOperator::create(I.getOpcode(), B, + Constant::getNullValue(B->getType())); + } else if (match(Op1, m_Sub(m_Value(A), m_Value(B))) && A == Op0) { + // A == (A-B) -> B == 0 + return BinaryOperator::create(I.getOpcode(), B, + Constant::getNullValue(B->getType())); + } + } return Changed ? &I : 0; } From lattner at cs.uiuc.edu Sun Feb 26 20:36:31 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 26 Feb 2006 20:36:31 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/set.ll Message-ID: <200602270236.UAA05031@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: set.ll updated: 1.18 -> 1.19 --- Log message: new testcases --- Diffs of the changes: (+16 -0) set.ll | 16 ++++++++++++++++ 1 files changed, 16 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/set.ll diff -u llvm/test/Regression/Transforms/InstCombine/set.ll:1.18 llvm/test/Regression/Transforms/InstCombine/set.ll:1.19 --- llvm/test/Regression/Transforms/InstCombine/set.ll:1.18 Sat Feb 11 20:06:31 2006 +++ llvm/test/Regression/Transforms/InstCombine/set.ll Sun Feb 26 20:36:19 2006 @@ -129,3 +129,19 @@ %R = or bool %C, %Z ret bool %R } + +int %test23(int %a) { + %tmp.1 = and int %a, 1 + %tmp.2 = seteq int %tmp.1, 0 + %tmp.3 = cast bool %tmp.2 to int ;; xor tmp1, 1 + ret int %tmp.3 +} + +int %test24(uint %a) { + %tmp1 = and uint %a, 4 + %tmp.1 = shr uint %tmp1, ubyte 2 + %tmp.2 = seteq uint %tmp.1, 0 + %tmp.3 = cast bool %tmp.2 to int ;; xor tmp1, 1 + ret int %tmp.3 +} + From lattner at cs.uiuc.edu Sun Feb 26 20:38:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 26 Feb 2006 20:38:34 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200602270238.UAA05105@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.440 -> 1.441 --- Log message: Merge two almost-identical pieces of code. Make this code more powerful by using ComputeMaskedBits instead of looking for an AND operand. This lets us fold this: int %test23(int %a) { %tmp.1 = and int %a, 1 %tmp.2 = seteq int %tmp.1, 0 %tmp.3 = cast bool %tmp.2 to int ;; xor tmp1, 1 ret int %tmp.3 } into: xor (and a, 1), 1 --- Diffs of the changes: (+42 -46) InstructionCombining.cpp | 88 ++++++++++++++++++++++------------------------- 1 files changed, 42 insertions(+), 46 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.440 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.441 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.440 Sun Feb 26 19:44:11 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sun Feb 26 20:38:23 2006 @@ -4777,63 +4777,59 @@ } break; + case Instruction::SetEQ: case Instruction::SetNE: + // We if we are just checking for a seteq of a single bit and casting it + // to an integer. If so, shift the bit to the appropriate place then + // cast to integer to avoid the comparison. if (ConstantInt *Op1C = dyn_cast(Op1)) { - if (Op1C->getRawValue() == 0) { - // If the input only has the low bit set, simplify directly. - Constant *Not1 = - ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1)); - // cast (X != 0) to int --> X if X&~1 == 0 - if (MaskedValueIsZero(Op0, - cast(Not1)->getZExtValue())) { - if (CI.getType() == Op0->getType()) - return ReplaceInstUsesWith(CI, Op0); - else - return new CastInst(Op0, CI.getType()); - } - - // If the input is an and with a single bit, shift then simplify. - ConstantInt *AndRHS; - if (match(Op0, m_And(m_Value(), m_ConstantInt(AndRHS)))) - if (AndRHS->getRawValue() && - (AndRHS->getRawValue() & (AndRHS->getRawValue()-1)) == 0) { - unsigned ShiftAmt = Log2_64(AndRHS->getRawValue()); + uint64_t Op1CV = Op1C->getZExtValue(); + // cast (X == 0) to int --> X^1 iff X has only the low bit set. + // cast (X == 0) to int --> (X>>1)^1 iff X has only the 2nd bit set. + // cast (X == 1) to int --> X iff X has only the low bit set. + // cast (X == 2) to int --> X>>1 iff X has only the 2nd bit set. + // cast (X != 0) to int --> X iff X has only the low bit set. + // cast (X != 0) to int --> X>>1 iff X has only the 2nd bit set. + // cast (X != 1) to int --> X^1 iff X has only the low bit set. + // cast (X != 2) to int --> (X>>1)^1 iff X has only the 2nd bit set. + if (Op1CV == 0 || isPowerOf2_64(Op1CV)) { + // If Op1C some other power of two, convert: + uint64_t KnownZero, KnownOne; + uint64_t TypeMask = Op1->getType()->getIntegralTypeMask(); + ComputeMaskedBits(Op0, TypeMask, KnownZero, KnownOne); + + if (isPowerOf2_64(KnownZero^TypeMask)) { // Exactly one possible 1? + bool isSetNE = SrcI->getOpcode() == Instruction::SetNE; + if (Op1CV && (Op1CV != (KnownZero^TypeMask))) { + // (X&4) == 2 --> false + // (X&4) != 2 --> true + return ReplaceInstUsesWith(CI, ConstantBool::get(isSetNE)); + } + + unsigned ShiftAmt = Log2_64(KnownZero^TypeMask); + Value *In = Op0; + if (ShiftAmt) { // Perform an unsigned shr by shiftamt. Convert input to // unsigned if it is signed. - Value *In = Op0; if (In->getType()->isSigned()) In = InsertNewInstBefore(new CastInst(In, In->getType()->getUnsignedVersion(), In->getName()),CI); // Insert the shift to put the result in the low bit. In = InsertNewInstBefore(new ShiftInst(Instruction::Shr, In, - ConstantInt::get(Type::UByteTy, ShiftAmt), - In->getName()+".lobit"), CI); - if (CI.getType() == In->getType()) - return ReplaceInstUsesWith(CI, In); - else - return new CastInst(In, CI.getType()); + ConstantInt::get(Type::UByteTy, ShiftAmt), + In->getName()+".lobit"), CI); } - } - } - break; - case Instruction::SetEQ: - // We if we are just checking for a seteq of a single bit and casting it - // to an integer. If so, shift the bit to the appropriate place then - // cast to integer to avoid the comparison. - if (ConstantInt *Op1C = dyn_cast(Op1)) { - // Is Op1C a power of two or zero? - if ((Op1C->getRawValue() & Op1C->getRawValue()-1) == 0) { - // cast (X == 1) to int -> X iff X has only the low bit set. - if (Op1C->getRawValue() == 1) { - Constant *Not1 = - ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1)); - if (MaskedValueIsZero(Op0, - cast(Not1)->getZExtValue())) { - if (CI.getType() == Op0->getType()) - return ReplaceInstUsesWith(CI, Op0); - else - return new CastInst(Op0, CI.getType()); + + if ((Op1CV != 0) == isSetNE) { // Toggle the low bit. + Constant *One = ConstantInt::get(In->getType(), 1); + In = BinaryOperator::createXor(In, One, "tmp"); + InsertNewInstBefore(cast(In), CI); } + + if (CI.getType() == In->getType()) + return ReplaceInstUsesWith(CI, In); + else + return new CastInst(In, CI.getType()); } } } From lattner at cs.uiuc.edu Sun Feb 26 23:39:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 26 Feb 2006 23:39:14 -0600 Subject: [llvm-commits] CVS: llvm/autoconf/configure.ac Message-ID: <200602270539.XAA08590@zion.cs.uiuc.edu> Changes in directory llvm/autoconf: configure.ac updated: 1.210 -> 1.211 --- Log message: Use -emit-llvm -S to get .ll file output from llvm-gcc --- Diffs of the changes: (+1 -1) configure.ac | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/autoconf/configure.ac diff -u llvm/autoconf/configure.ac:1.210 llvm/autoconf/configure.ac:1.211 --- llvm/autoconf/configure.ac:1.210 Thu Feb 16 15:11:49 2006 +++ llvm/autoconf/configure.ac Sun Feb 26 23:39:00 2006 @@ -568,7 +568,7 @@ [llvm_cv_llvmgcc_sanity="no" if test -x "$LLVMGCC" ; then cp /dev/null conftest.c - "$LLVMGCC" -S -o - conftest.c | grep implementation > /dev/null 2>&1 + "$LLVMGCC" -emit-llvm -S -o - conftest.c | grep implementation > /dev/null 2>&1 if test $? -eq 0 ; then llvm_cv_llvmgcc_sanity="yes" fi From lattner at cs.uiuc.edu Sun Feb 26 23:39:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 26 Feb 2006 23:39:14 -0600 Subject: [llvm-commits] CVS: llvm/configure Message-ID: <200602270539.XAA08594@zion.cs.uiuc.edu> Changes in directory llvm: configure updated: 1.212 -> 1.213 --- Log message: Use -emit-llvm -S to get .ll file output from llvm-gcc --- Diffs of the changes: (+1 -1) configure | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/configure diff -u llvm/configure:1.212 llvm/configure:1.213 --- llvm/configure:1.212 Thu Feb 16 15:12:54 2006 +++ llvm/configure Sun Feb 26 23:39:00 2006 @@ -30613,7 +30613,7 @@ llvm_cv_llvmgcc_sanity="no" if test -x "$LLVMGCC" ; then cp /dev/null conftest.c - "$LLVMGCC" -S -o - conftest.c | grep implementation > /dev/null 2>&1 + "$LLVMGCC" -emit-llvm -S -o - conftest.c | grep implementation > /dev/null 2>&1 if test $? -eq 0 ; then llvm_cv_llvmgcc_sanity="yes" fi