Index: include/llvm/CodeGen/SelectionDAGNodes.h
===================================================================
RCS file: /var/cvs/llvm/llvm/include/llvm/CodeGen/SelectionDAGNodes.h,v
retrieving revision 1.34
diff -u -r1.34 SelectionDAGNodes.h
--- include/llvm/CodeGen/SelectionDAGNodes.h	27 Apr 2005 20:10:01 -0000	1.34
+++ include/llvm/CodeGen/SelectionDAGNodes.h	28 Apr 2005 13:40:54 -0000
@@ -168,9 +168,9 @@
     // FP_EXTEND - Extend a smaller FP type into a larger FP type.
     FP_EXTEND,
 
-    // FNEG, FABS - Perform unary floating point negation and absolute value
-    // operations.
-    FNEG, FABS,
+    // FNEG, FABS, FSQRT, FSIN, FCOS - Perform unary floating point negation,
+    // absolute value, square root, sine and cosine operations.
+    FNEG, FABS, FSQRT, FSIN, FCOS,
 
     // Other operators.  LOAD and STORE have token chains as their first
     // operand, then the same operands as an LLVM load/store instruction.
Index: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp,v
retrieving revision 1.91
diff -u -r1.91 LegalizeDAG.cpp
--- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	27 Apr 2005 20:10:01 -0000	1.91
+++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	28 Apr 2005 13:49:38 -0000
@@ -990,6 +990,9 @@
     // Unary operators
   case ISD::FABS:
   case ISD::FNEG:
+  case ISD::FSQRT:
+  case ISD::FSIN:
+  case ISD::FCOS:
     Tmp1 = LegalizeOp(Node->getOperand(0));
     switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
     case TargetLowering::Legal:
@@ -1335,6 +1338,16 @@
     // precision, and these operations don't modify precision at all.
     break;
 
+  case ISD::FSQRT:
+  case ISD::FSIN:
+  case ISD::FCOS:
+    Tmp1 = PromoteOp(Node->getOperand(0));
+    assert(Tmp1.getValueType() == NVT);
+    Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1);
+    if(NoExcessFPPrecision)
+      Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT);
+    break;
+
   case ISD::AND:
   case ISD::OR:
   case ISD::XOR:
Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp,v
retrieving revision 1.96
diff -u -r1.96 SelectionDAG.cpp
--- lib/CodeGen/SelectionDAG/SelectionDAG.cpp	27 Apr 2005 20:10:01 -0000	1.96
+++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp	28 Apr 2005 13:45:09 -0000
@@ -1568,6 +1568,9 @@
   // Unary operators
   case ISD::FABS:   return "fabs";
   case ISD::FNEG:   return "fneg";
+  case ISD::FSQRT:  return "fsqrt";
+  case ISD::FSIN:   return "fsin";
+  case ISD::FCOS:   return "fcos";
 
   // Binary operators
   case ISD::ADD:    return "add";
@@ -1593,7 +1596,7 @@
   case ISD::SRA_PARTS:   return "sra_parts";
   case ISD::SRL_PARTS:   return "srl_parts";
 
-    // Conversion operators.
+  // Conversion operators.
   case ISD::SIGN_EXTEND: return "sign_extend";
   case ISD::ZERO_EXTEND: return "zero_extend";
   case ISD::SIGN_EXTEND_INREG: return "sign_extend_inreg";
Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp,v
retrieving revision 1.44
diff -u -r1.44 SelectionDAGISel.cpp
--- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	27 Apr 2005 20:10:01 -0000	1.44
+++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	28 Apr 2005 14:09:45 -0000
@@ -479,6 +479,35 @@
 }
 
 void SelectionDAGLowering::visitSelect(User &I) {
+/*
+  Lower this pattern to FABS
+  cond = setlt Y, 0
+  tmp  = sub -0.0, Y
+  X    = select cond, tmp, Y 
+*/
+  SetCondInst *CI;
+  llvm::ConstantFP *CFP;
+  BinaryOperator *BO;
+
+  if((CI = dyn_cast<SetCondInst>(I.getOperand(0))) &&
+     CI->getOpcode() == Instruction::BinaryOps::SetLT &&
+     (CFP = dyn_cast<llvm::ConstantFP>(CI->getOperand(1))) &&
+     CFP->isNullValue() &&
+     (BO = dyn_cast<BinaryOperator>(I.getOperand(1))) &&
+     BO->getOpcode() == Instruction::BinaryOps::Sub &&
+     (CFP = dyn_cast<llvm::ConstantFP>(BO->getOperand(0))) &&
+     CFP->isNullValue() &&
+     I.getOperand(2) == BO->getOperand(1) &&
+     I.getOperand(2) == CI->getOperand(0))
+  {
+    SDOperand V = getValue(I.getOperand(2));
+    if(isFloatingPoint(V.getValueType()))
+    {
+      setValue(&I, DAG.getNode(ISD::FABS, V.getValueType(), V));
+      return;
+    }
+  }
+
   SDOperand Cond     = getValue(I.getOperand(0));
   SDOperand TrueVal  = getValue(I.getOperand(1));
   SDOperand FalseVal = getValue(I.getOperand(2));
@@ -656,6 +685,33 @@
             return;
           }
         }
+        else if (F->getName() == "sqrt" || F->getName() == "sqrtf") {
+          if (I.getNumOperands() == 2 &&   // Basic sanity checks.
+              I.getOperand(1)->getType()->isFloatingPoint() &&
+              I.getType() == I.getOperand(1)->getType()) {
+            SDOperand Tmp = getValue(I.getOperand(1));
+            setValue(&I, DAG.getNode(ISD::FSQRT, Tmp.getValueType(), Tmp));
+            return;
+          }
+        }
+        else if (F->getName() == "sin" || F->getName() == "sinf") {
+          if (I.getNumOperands() == 2 &&   // Basic sanity checks.
+              I.getOperand(1)->getType()->isFloatingPoint() &&
+              I.getType() == I.getOperand(1)->getType()) {
+            SDOperand Tmp = getValue(I.getOperand(1));
+            setValue(&I, DAG.getNode(ISD::FSIN, Tmp.getValueType(), Tmp));
+            return;
+          }
+        }
+        else if (F->getName() == "cos" || F->getName() == "cosf") {
+          if (I.getNumOperands() == 2 &&   // Basic sanity checks.
+              I.getOperand(1)->getType()->isFloatingPoint() &&
+              I.getType() == I.getOperand(1)->getType()) {
+            SDOperand Tmp = getValue(I.getOperand(1));
+            setValue(&I, DAG.getNode(ISD::FCOS, Tmp.getValueType(), Tmp));
+            return;
+          }
+        }
         break;
       case Intrinsic::vastart:  visitVAStart(I); return;
       case Intrinsic::vaend:    visitVAEnd(I); return;
Index: lib/Target/X86/X86ISelPattern.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/X86/X86ISelPattern.cpp,v
retrieving revision 1.108
diff -u -r1.108 X86ISelPattern.cpp
--- lib/Target/X86/X86ISelPattern.cpp	27 Apr 2005 20:10:01 -0000	1.108
+++ lib/Target/X86/X86ISelPattern.cpp	28 Apr 2005 13:55:07 -0000
@@ -1830,12 +1830,25 @@
     return Result;
 
   case ISD::FABS:
-    Tmp1 = SelectExpr(Node->getOperand(0));
-    BuildMI(BB, X86::FABS, 1, Result).addReg(Tmp1);
-    return Result;
   case ISD::FNEG:
+  case ISD::FSQRT:
+  case ISD::FSIN:
+  case ISD::FCOS:
+    assert(N.getValueType()==MVT::f64 && "Illegal type for this operation");
     Tmp1 = SelectExpr(Node->getOperand(0));
-    BuildMI(BB, X86::FCHS, 1, Result).addReg(Tmp1);
+    switch (N.getOpcode()) {
+    default: assert(0 && "Unreachable!");
+    case ISD::FABS:
+      BuildMI(BB, X86::FABS, 1, Result).addReg(Tmp1); break;
+    case ISD::FNEG:
+      BuildMI(BB, X86::FCHS, 1, Result).addReg(Tmp1); break;
+    case ISD::FSQRT:
+      BuildMI(BB, X86::FSQRT, 1, Result).addReg(Tmp1); break;
+    case ISD::FSIN:
+      BuildMI(BB, X86::FSIN, 1, Result).addReg(Tmp1); break;
+    case ISD::FCOS:
+      BuildMI(BB, X86::FCOS, 1, Result).addReg(Tmp1); break;
+    }
     return Result;
 
   case ISD::MULHU:
Index: lib/Target/X86/X86ISelSimple.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/X86/X86ISelSimple.cpp,v
retrieving revision 1.314
diff -u -r1.314 X86ISelSimple.cpp
--- lib/Target/X86/X86ISelSimple.cpp	21 Apr 2005 23:38:14 -0000	1.314
+++ lib/Target/X86/X86ISelSimple.cpp	28 Apr 2005 14:17:14 -0000
@@ -1737,6 +1737,47 @@
       return;
     }
 
+    if (F->getName() == "fabs" || F->getName() == "fabsf") {
+      if (CI.getNumOperands() == 2 &&   // Basic sanity checks.
+          CI.getOperand(1)->getType()->isFloatingPoint() &&
+          CI.getType() == CI.getOperand(1)->getType()) {
+        unsigned op1Reg = getReg(CI.getOperand(1));
+        unsigned DestReg = getReg(CI);
+        BuildMI(BB, X86::FABS, 1, DestReg).addReg(op1Reg);
+        return;
+      }
+    }
+    else if (F->getName() == "sqrt" || F->getName() == "sqrtf") {
+      if (CI.getNumOperands() == 2 &&   // Basic sanity checks.
+          CI.getOperand(1)->getType()->isFloatingPoint() &&
+          CI.getType() == CI.getOperand(1)->getType()) {
+        unsigned op1Reg = getReg(CI.getOperand(1));
+        unsigned DestReg = getReg(CI);
+        BuildMI(BB, X86::FSQRT, 1, DestReg).addReg(op1Reg);
+        return;
+      }
+    }
+    else if (F->getName() == "sin" || F->getName() == "sinf") {
+      if (CI.getNumOperands() == 2 &&   // Basic sanity checks.
+          CI.getOperand(1)->getType()->isFloatingPoint() &&
+          CI.getType() == CI.getOperand(1)->getType()) {
+        unsigned op1Reg = getReg(CI.getOperand(1));
+        unsigned DestReg = getReg(CI);
+        BuildMI(BB, X86::FSIN, 1, DestReg).addReg(op1Reg);
+        return;
+      }
+    }
+    else if (F->getName() == "cos" || F->getName() == "cosf") {
+      if (CI.getNumOperands() == 2 &&   // Basic sanity checks.
+          CI.getOperand(1)->getType()->isFloatingPoint() &&
+          CI.getType() == CI.getOperand(1)->getType()) {
+        unsigned op1Reg = getReg(CI.getOperand(1));
+        unsigned DestReg = getReg(CI);
+        BuildMI(BB, X86::FCOS, 1, DestReg).addReg(op1Reg);
+        return;
+      }
+    }
+
     // Emit a CALL instruction with PC-relative displacement.
     TheCall = BuildMI(X86::CALLpcrel32, 1).addGlobalAddress(F, true);
   } else {  // Emit an indirect call...
Index: lib/Target/X86/X86InstrInfo.td
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/X86/X86InstrInfo.td,v
retrieving revision 1.121
diff -u -r1.121 X86InstrInfo.td
--- lib/Target/X86/X86InstrInfo.td	6 Apr 2005 04:19:22 -0000	1.121
+++ lib/Target/X86/X86InstrInfo.td	28 Apr 2005 13:33:40 -0000
@@ -1535,9 +1535,12 @@
 
 
 // Unary operations...
-def FCHS : FPI<0xE0, RawFrm, OneArgFPRW, (ops), "fchs">, D9;   // f1 = fchs f2
-def FABS : FPI<0xE1, RawFrm, OneArgFPRW, (ops), "fabs">, D9;   // f1 = fabs f2
-def FTST : FPI<0xE4, RawFrm, OneArgFP, (ops), "ftst">, D9;     // ftst ST(0)
+def FCHS  : FPI<0xE0, RawFrm, OneArgFPRW, (ops), "fchs">, D9;   // f1 = fchs f2
+def FABS  : FPI<0xE1, RawFrm, OneArgFPRW, (ops), "fabs">, D9;   // f1 = fabs f2
+def FTST  : FPI<0xE4, RawFrm, OneArgFP, (ops), "ftst">, D9;     // ftst ST(0)
+def FSQRT : FPI<0xFA, RawFrm, OneArgFPRW, (ops), "fsqrt">, D9; // fsqrt ST(0)
+def FSIN  : FPI<0xFE, RawFrm, OneArgFPRW, (ops), "fsin">,  D9; // fsin  ST(0)
+def FCOS  : FPI<0xFF, RawFrm, OneArgFPRW, (ops), "fcos">,  D9; // fcos  ST(0)
 
 // Binary arithmetic operations...
 class FPST0rInst<bits<8> o, dag ops, string asm>
