Index: include/llvm/Intrinsics.h
===================================================================
RCS file: /var/cvs/llvm/llvm/include/llvm/Intrinsics.h,v
retrieving revision 1.28
diff -u -r1.28 Intrinsics.h
--- include/llvm/Intrinsics.h	28 Feb 2005 19:25:57 -0000	1.28
+++ include/llvm/Intrinsics.h	7 Mar 2005 13:41:56 -0000
@@ -62,6 +62,10 @@
 
     // libm related functions.
     isunordered,    // Return true if either argument is a NaN
+    abs,
+    sqrt,
+    sin,
+    cos,
 
     // Input/Output intrinsics.
     readport,
Index: include/llvm/CodeGen/SelectionDAGNodes.h
===================================================================
RCS file: /var/cvs/llvm/llvm/include/llvm/CodeGen/SelectionDAGNodes.h,v
retrieving revision 1.21
diff -u -r1.21 SelectionDAGNodes.h
--- include/llvm/CodeGen/SelectionDAGNodes.h	21 Jan 2005 21:39:38 -0000	1.21
+++ include/llvm/CodeGen/SelectionDAGNodes.h	10 Mar 2005 14:49:11 -0000
@@ -155,6 +155,9 @@
     // FP_EXTEND - Extend a smaller FP type into a larger FP type.
     FP_EXTEND,
 
+    // Floating point unary operators.
+    FP_ABS, FP_SQRT, FP_SIN, FP_COS,
+
     // Other operators.  LOAD and STORE have token chains as their first
     // operand, then the same operands as an LLVM load/store instruction.
     LOAD, STORE,
Index: lib/Analysis/BasicAliasAnalysis.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Analysis/BasicAliasAnalysis.cpp,v
retrieving revision 1.64
diff -u -r1.64 BasicAliasAnalysis.cpp
--- lib/Analysis/BasicAliasAnalysis.cpp	8 Jan 2005 22:01:16 -0000	1.64
+++ lib/Analysis/BasicAliasAnalysis.cpp	7 Mar 2005 12:09:21 -0000
@@ -698,7 +698,7 @@
 static const char *DoesntAccessMemoryTable[] = {
   // LLVM intrinsics:
   "llvm.frameaddress", "llvm.returnaddress", "llvm.readport",
-  "llvm.isunordered",
+  "llvm.isunordered", "llvm.abs", "llvm.sqrt", "llvm.sin", "llvm.cos",
 
   "abs", "labs", "llabs", "imaxabs", "fabs", "fabsf", "fabsl",
   "trunc", "truncf", "truncl", "ldexp",
Index: lib/CodeGen/IntrinsicLowering.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/IntrinsicLowering.cpp,v
retrieving revision 1.23
diff -u -r1.23 IntrinsicLowering.cpp
--- lib/CodeGen/IntrinsicLowering.cpp	1 Mar 2005 02:07:58 -0000	1.23
+++ lib/CodeGen/IntrinsicLowering.cpp	7 Mar 2005 12:09:21 -0000
@@ -110,6 +110,22 @@
       case Intrinsic::isunordered:
         EnsureFunctionExists(M, "isunordered", I->abegin(), I->aend(), Type::BoolTy);
         break;
+      case Intrinsic::abs:
+        EnsureFunctionExists(M, "abs", I->abegin(), --I->aend(),
+                             I->abegin()->getType());
+        break;
+      case Intrinsic::sqrt:
+        EnsureFunctionExists(M, "sqrt", I->abegin(), --I->aend(),
+                             I->abegin()->getType());
+        break;
+      case Intrinsic::sin:
+        EnsureFunctionExists(M, "sin", I->abegin(), --I->aend(),
+                             I->abegin()->getType());
+        break;
+      case Intrinsic::cos:
+        EnsureFunctionExists(M, "cos", I->abegin(), --I->aend(),
+                             I->abegin()->getType());
+        break;
       }
 
 }
@@ -216,6 +232,30 @@
                              "isunordered", CI));
     break;
   }
+  case Intrinsic::abs: {
+    static Function *absFCache = 0;
+    ReplaceCallWith("abs", CI, CI->op_begin()+1, CI->op_end(),
+                    (*(CI->op_begin()+1))->getType(), absFCache);
+    break;
+  }
+  case Intrinsic::sqrt: {
+    static Function *sqrtFCache = 0;
+    ReplaceCallWith("sqrt", CI, CI->op_begin()+1, CI->op_end(),
+                    (*(CI->op_begin()+1))->getType(), sqrtFCache);
+    break;
+  }
+  case Intrinsic::sin: {
+    static Function *sinFCache = 0;
+    ReplaceCallWith("sin", CI, CI->op_begin()+1, CI->op_end(),
+                    (*(CI->op_begin()+1))->getType(), sinFCache);
+    break;
+  }
+  case Intrinsic::cos: {
+    static Function *cosFCache = 0;
+    ReplaceCallWith("cos", CI, CI->op_begin()+1, CI->op_end(),
+                    (*(CI->op_begin()+1))->getType(), cosFCache);
+    break;
+  }
   }
   
   assert(CI->use_empty() &&
Index: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp,v
retrieving revision 1.61
diff -u -r1.61 LegalizeDAG.cpp
--- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	22 Feb 2005 07:23:39 -0000	1.61
+++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	11 Mar 2005 16:18:32 -0000
@@ -914,6 +914,15 @@
       }
     }
     break;
+  case ISD::FP_ABS:
+  case ISD::FP_SQRT:
+  case ISD::FP_SIN:
+  case ISD::FP_COS:
+    Tmp1 = LegalizeOp(Node->getOperand(0));
+    Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);
+    break;
+
+    break;
   case ISD::FP_ROUND_INREG:
   case ISD::SIGN_EXTEND_INREG:
   case ISD::ZERO_EXTEND_INREG: {
@@ -1165,6 +1174,16 @@
       Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT);
     break;
 
+  case ISD::FP_ABS:
+  case ISD::FP_SQRT:
+  case ISD::FP_SIN:
+  case ISD::FP_COS:
+    Tmp1 = PromoteOp(Node->getOperand(0));
+    Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1);
+    if(NoExcessFPPrecision)
+      Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT);
+    break;
+
   case ISD::SDIV:
   case ISD::SREM:
     // These operators require that their input be sign extended.
Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp,v
retrieving revision 1.32
diff -u -r1.32 SelectionDAGISel.cpp
--- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	17 Feb 2005 21:39:27 -0000	1.32
+++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	11 Mar 2005 15:39:50 -0000
@@ -359,6 +359,7 @@
   void visitFrameReturnAddress(CallInst &I, bool isFrameAddress);
 
   void visitMemIntrinsic(CallInst &I, unsigned Op);
+  void visitFPIntrinsic(CallInst &I, unsigned Op);
 
   void visitUserOp1(Instruction &I) {
     assert(0 && "UserOp1 should not exist at instruction selection time!");
@@ -650,7 +651,10 @@
     case Intrinsic::memcpy:  visitMemIntrinsic(I, ISD::MEMCPY); return;
     case Intrinsic::memset:  visitMemIntrinsic(I, ISD::MEMSET); return;
     case Intrinsic::memmove: visitMemIntrinsic(I, ISD::MEMMOVE); return;
-      
+    case Intrinsic::abs:     visitFPIntrinsic(I, ISD::FP_ABS); return;
+    case Intrinsic::sqrt:    visitFPIntrinsic(I, ISD::FP_SQRT); return;
+    case Intrinsic::sin:     visitFPIntrinsic(I, ISD::FP_SIN); return;
+    case Intrinsic::cos:     visitFPIntrinsic(I, ISD::FP_COS); return;
     case Intrinsic::isunordered:
       setValue(&I, DAG.getSetCC(ISD::SETUO, MVT::i1, getValue(I.getOperand(1)),
                                 getValue(I.getOperand(2))));
@@ -812,6 +816,21 @@
   DAG.setRoot(DAG.getNode(Op, MVT::Other, Ops));
 }
 
+void SelectionDAGLowering::visitFPIntrinsic(CallInst &I, unsigned Op) {
+  if(I.getType() == llvm::Type::FloatTy)
+  {
+    setValue(&I, DAG.getNode(Op, MVT::f32, getValue(I.getOperand(1))));
+  }
+  else if(I.getType() == llvm::Type::DoubleTy)
+  {
+    setValue(&I, DAG.getNode(Op, MVT::f64, getValue(I.getOperand(1))));
+  }
+  else
+  {
+    assert(0 && "Illegal FP Intrinsic");
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // SelectionDAGISel code
 //===----------------------------------------------------------------------===//
Index: lib/Target/X86/X86ISelPattern.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/X86/X86ISelPattern.cpp,v
retrieving revision 1.90
diff -u -r1.90 X86ISelPattern.cpp
--- lib/Target/X86/X86ISelPattern.cpp	23 Feb 2005 05:57:21 -0000	1.90
+++ lib/Target/X86/X86ISelPattern.cpp	11 Mar 2005 15:22:17 -0000
@@ -2274,6 +2274,25 @@
     BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
     return Result;
 
+  case ISD::FP_ABS:
+  case ISD::FP_SQRT:
+  case ISD::FP_SIN:
+  case ISD::FP_COS:
+    assert(N.getValueType()==MVT::f64 && "Illegal type for this operation");
+    Tmp1 = SelectExpr(N.getOperand(0));
+    switch (N.getOpcode()) {
+    default: assert(0 && "Unreachable!");
+    case ISD::FP_ABS:
+      BuildMI(BB, X86::FABS, 1, Result).addReg(Tmp1); break;
+    case ISD::FP_SQRT:
+      BuildMI(BB, X86::FSQRT, 1, Result).addReg(Tmp1); break;
+    case ISD::FP_SIN:
+      BuildMI(BB, X86::FSIN, 1, Result).addReg(Tmp1); break;
+    case ISD::FP_COS:
+      BuildMI(BB, X86::FCOS, 1, Result).addReg(Tmp1); break;
+    }
+    return Result;
+
   case ISD::SETCC:
     EmitCMP(N.getOperand(0), N.getOperand(1), Node->hasOneUse());
     EmitSetCC(BB, Result, cast<SetCCSDNode>(N)->getCondition(),
Index: lib/Target/X86/X86ISelSimple.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/X86/X86ISelSimple.cpp,v
retrieving revision 1.308
diff -u -r1.308 X86ISelSimple.cpp
--- lib/Target/X86/X86ISelSimple.cpp	9 Jan 2005 01:49:29 -0000	1.308
+++ lib/Target/X86/X86ISelSimple.cpp	7 Mar 2005 12:09:21 -0000
@@ -1757,6 +1757,10 @@
           case Intrinsic::isunordered:
           case Intrinsic::readport:
           case Intrinsic::writeport:
+          case Intrinsic::abs:
+          case Intrinsic::sqrt:
+          case Intrinsic::sin:
+          case Intrinsic::cos:
             // We directly implement these intrinsics
             break;
           case Intrinsic::readio: {
@@ -2047,7 +2051,30 @@
     BuildMI(BB, Opc[Class], 0);
     return;
   }
-    
+  case Intrinsic::abs: {
+    unsigned op1Reg = getReg(CI.getOperand(1));
+    unsigned DestReg = getReg(CI);
+    BuildMI(BB, X86::FABS, 1, DestReg).addReg(op1Reg);
+    return;
+  }
+  case Intrinsic::sqrt: {
+    unsigned op1Reg = getReg(CI.getOperand(1));
+    unsigned DestReg = getReg(CI);
+    BuildMI(BB, X86::FSQRT, 1, DestReg).addReg(op1Reg);
+    return;
+  }
+  case Intrinsic::sin: {
+    unsigned op1Reg = getReg(CI.getOperand(1));
+    unsigned DestReg = getReg(CI);
+    BuildMI(BB, X86::FSIN, 1, DestReg).addReg(op1Reg);
+    return;
+  }
+  case Intrinsic::cos: {
+    unsigned op1Reg = getReg(CI.getOperand(1));
+    unsigned DestReg = getReg(CI);
+    BuildMI(BB, X86::FCOS, 1, DestReg).addReg(op1Reg);
+    return;
+  }
   default: assert(0 && "Error: unknown intrinsics should have been lowered!");
   }
 }
Index: lib/Target/X86/X86InstrInfo.td
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/X86/X86InstrInfo.td,v
retrieving revision 1.119
diff -u -r1.119 X86InstrInfo.td
--- lib/Target/X86/X86InstrInfo.td	27 Feb 2005 06:16:27 -0000	1.119
+++ lib/Target/X86/X86InstrInfo.td	7 Mar 2005 13:45:54 -0000
@@ -1522,8 +1522,12 @@
 
 
 // Unary operations...
-def FCHS : FPI<0xE0, RawFrm, OneArgFPRW, (ops), "fchs">, D9;   // f1 = fchs 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; // fabs  ST(0)
+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>
Index: lib/VMCore/Function.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/VMCore/Function.cpp,v
retrieving revision 1.90
diff -u -r1.90 Function.cpp
--- lib/VMCore/Function.cpp	5 Mar 2005 19:51:50 -0000	1.90
+++ lib/VMCore/Function.cpp	7 Mar 2005 12:09:38 -0000
@@ -206,6 +206,12 @@
   assert(getName().size() != 5 && "'llvm.' is an invalid intrinsic name!");
   
   switch (getName()[5]) {
+  case 'a':
+    if (getName() == "llvm.abs")   return Intrinsic::abs;
+    break;
+  case 'c':
+    if (getName() == "llvm.cos")   return Intrinsic::cos;
+    break;
   case 'd':
     if (getName() == "llvm.dbg.stoppoint")   return Intrinsic::dbg_stoppoint;
     if (getName() == "llvm.dbg.region.start")return Intrinsic::dbg_region_start;
@@ -244,6 +250,8 @@
     if (getName() == "llvm.setjmp")     return Intrinsic::setjmp;
     if (getName() == "llvm.sigsetjmp")  return Intrinsic::sigsetjmp;
     if (getName() == "llvm.siglongjmp") return Intrinsic::siglongjmp;
+    if (getName() == "llvm.sqrt")       return Intrinsic::sqrt;
+    if (getName() == "llvm.sin")        return Intrinsic::sin;
     break;
   case 'v':
     if (getName() == "llvm.va_copy")  return Intrinsic::vacopy;
Index: lib/VMCore/Verifier.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/VMCore/Verifier.cpp,v
retrieving revision 1.127
diff -u -r1.127 Verifier.cpp
--- lib/VMCore/Verifier.cpp	28 Feb 2005 19:27:42 -0000	1.127
+++ lib/VMCore/Verifier.cpp	7 Mar 2005 12:09:38 -0000
@@ -723,6 +723,19 @@
     NumArgs = 2;
     break;
 
+  case Intrinsic::abs:
+  case Intrinsic::sqrt:
+  case Intrinsic::sin:
+  case Intrinsic::cos:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getParamType(0)->isFloatingPoint(),
+            "Argument is not a floating point type!", IF);
+    Assert1(FT->getReturnType()->isFloatingPoint(),
+            "Return type is not a floating point type!", IF);
+    NumArgs = 1;
+    break;
+
   case Intrinsic::setjmp:          NumArgs = 1; break;
   case Intrinsic::longjmp:         NumArgs = 2; break;
   case Intrinsic::sigsetjmp:       NumArgs = 2; break;
