For PR1839: add initial support for __builtin_trap. llvm-gcc part is missed
authorAnton Korobeynikov <asl@math.spbu.ru>
Tue, 15 Jan 2008 07:02:33 +0000 (07:02 +0000)
committerAnton Korobeynikov <asl@math.spbu.ru>
Tue, 15 Jan 2008 07:02:33 +0000 (07:02 +0000)
as well as PPC codegen

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46001 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAGNodes.h
include/llvm/Intrinsics.td
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h
lib/Target/X86/X86InstrInfo.td

index 47e3feb1388bdba4fc1bec0308ec0a95d1adbf9c..30823833b7925dabfbc5b47b083c74ac0e1512cc 100644 (file)
@@ -563,6 +563,9 @@ namespace ISD {
     // chain as output.
     TRAMPOLINE,
 
+    // TRAP - Trapping instruction
+    TRAP,
+
     // BUILTIN_OP_END - This must be the last enum value in this list.
     BUILTIN_OP_END
   };
index 94e5670c96be81f6a53fcab4fa23c6e42f0d4d64..703b794eb1cff32cc1d9dea96819638ad16b0440 100644 (file)
@@ -266,6 +266,8 @@ def int_init_trampoline : Intrinsic<[llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty,
 //
 def int_flt_rounds : Intrinsic<[llvm_i32_ty]>,
                      GCCBuiltin<"__builtin_flt_rounds">;
+def int_trap : Intrinsic<[llvm_void_ty]>,
+               GCCBuiltin<"__builtin_trap">;
 
 //===----------------------------------------------------------------------===//
 // Target-specific intrinsics
index dd7c0e9f33a18a6563578a1872aabd050abfc0b6..8e9cd7423395d84a994a763589e576aa882aa802 100644 (file)
@@ -3733,6 +3733,25 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       Result = DAG.getConstant(1, VT);
       break;
     }
+  }
+   case ISD::TRAP: {
+    MVT::ValueType VT = Node->getValueType(0);
+    switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
+    default: assert(0 && "This action not supported for this op yet!");
+    case TargetLowering::Custom:
+      Result = TLI.LowerOperation(Op, DAG);
+      if (Result.Val) break;
+      // Fall Thru
+    case TargetLowering::Legal:
+      // If this operation is not supported, lower it to 'abort()' call
+      SDOperand Chain = LegalizeOp(Node->getOperand(0));
+      TargetLowering::ArgListTy Args;
+      std::pair<SDOperand,SDOperand> CallResult =
+        TLI.LowerCallTo(Chain, Type::VoidTy, false, false, CallingConv::C, false,
+                        DAG.getExternalSymbol("abort", MVT::Other), Args, DAG);
+      Result = CallResult.second;
+      break;
+    }
   }
   }
   
index 2206515649771013f601b1b7345f8d5a81a4374b..381e9dec646c3996df0d23a99a454415e582bd49 100644 (file)
@@ -3770,7 +3770,8 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
   case ISD::BUILD_PAIR:         return "build_pair";
   case ISD::STACKSAVE:          return "stacksave";
   case ISD::STACKRESTORE:       return "stackrestore";
-    
+  case ISD::TRAP:               return "trap";
+
   // Block memory operations.
   case ISD::MEMSET:  return "memset";
   case ISD::MEMCPY:  return "memcpy";
index 2934345b603589440655ad9018a69e41b5dad6e0..67da406e7e717c54be49fcd05b0566037078798c 100644 (file)
@@ -2932,6 +2932,11 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
     setValue(&I, DAG.getNode(ISD::FLT_ROUNDS, MVT::i32));
     return 0;
   }
+
+  case Intrinsic::trap: {
+    DAG.setRoot(DAG.getNode(ISD::TRAP, MVT::Other, getRoot()));
+    return 0;
+  }
   }
 }
 
index 84502524481c91e650e0e3547078d36027303480..0587dfa664c8382d81d7b21c969055560dfc4966 100644 (file)
@@ -294,6 +294,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   
   setOperationAction(ISD::TRAMPOLINE, MVT::Other, Custom);
 
+  setOperationAction(ISD::TRAP, MVT::Other, Custom);
+
   // VASTART needs to be custom lowered to use the VarArgsFrameIndex
   setOperationAction(ISD::VASTART           , MVT::Other, Custom);
   setOperationAction(ISD::VAARG             , MVT::Other, Expand);
@@ -4948,6 +4950,10 @@ SDOperand X86TargetLowering::LowerFLT_ROUNDS(SDOperand Op, SelectionDAG &DAG) {
                       ISD::TRUNCATE : ISD::ZERO_EXTEND), VT, RetVal);
 }
 
+SDOperand X86TargetLowering::LowerTRAP(SDOperand Op, SelectionDAG &DAG) {
+  return DAG.getNode(X86ISD::TRAP, MVT::Other, Op.getOperand(0));
+}
+
 SDOperand X86TargetLowering::LowerCTLZ(SDOperand Op, SelectionDAG &DAG) {
   MVT::ValueType VT = Op.getValueType();
   MVT::ValueType OpVT = VT;
@@ -5052,6 +5058,7 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   case ISD::FLT_ROUNDS:         return LowerFLT_ROUNDS(Op, DAG);
   case ISD::CTLZ:               return LowerCTLZ(Op, DAG);
   case ISD::CTTZ:               return LowerCTTZ(Op, DAG);
+  case ISD::TRAP:               return LowerTRAP(Op, DAG);
       
   // FIXME: REMOVE THIS WHEN LegalizeDAGTypes lands.
   case ISD::READCYCLECOUNTER:
@@ -5091,6 +5098,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
   case X86ISD::CALL:               return "X86ISD::CALL";
   case X86ISD::TAILCALL:           return "X86ISD::TAILCALL";
   case X86ISD::RDTSC_DAG:          return "X86ISD::RDTSC_DAG";
+  case X86ISD::TRAP:               return "X86ISD::TRAP";
   case X86ISD::CMP:                return "X86ISD::CMP";
   case X86ISD::COMI:               return "X86ISD::COMI";
   case X86ISD::UCOMI:              return "X86ISD::UCOMI";
index 64324f3dc596f805551463a22d9f53b819d97ea8..959e61021519951c2e8be1aa76be799c748aaab4 100644 (file)
@@ -197,7 +197,10 @@ namespace llvm {
       TC_RETURN,
 
       // Store FP control world into i16 memory
-      FNSTCW16m
+      FNSTCW16m,
+
+      // Trapping instruction
+      TRAP
     };
   }
 
@@ -484,6 +487,7 @@ namespace llvm {
     SDOperand LowerEH_RETURN(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerTRAMPOLINE(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerFLT_ROUNDS(SDOperand Op, SelectionDAG &DAG);
+    SDOperand LowerTRAP(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerCTLZ(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerCTTZ(SDOperand Op, SelectionDAG &DAG);
     SDNode *ExpandFP_TO_SINT(SDNode *N, SelectionDAG &DAG);
index 02fc0772ecdec8f7faf7175670b86caccac35a6c..f9bdfc4f8bdb283a6f22bc6ad22228dae6aeeaed 100644 (file)
@@ -57,6 +57,8 @@ def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
 
 def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
 
+def SDT_X86TRAP  : SDTypeProfile<0, 0, []>;
+
 def X86bsf     : SDNode<"X86ISD::BSF",      SDTIntUnaryOp>;
 def X86bsr     : SDNode<"X86ISD::BSR",      SDTIntUnaryOp>;
 def X86shld    : SDNode<"X86ISD::SHLD",     SDTIntShiftDOp>;
@@ -107,6 +109,9 @@ def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
 def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET, 
                         [SDNPHasChain,  SDNPOptInFlag]>;
 
+def X86trap  : SDNode<"X86ISD::TRAP", SDT_X86TRAP,
+                        [SDNPHasChain, SDNPOutFlag, SDNPSideEffect]>;
+
 //===----------------------------------------------------------------------===//
 // X86 Operand Definitions.
 //
@@ -484,6 +489,11 @@ let Defs = [RAX, RDX] in
 def RDTSC : I<0x31, RawFrm, (outs), (ins), "rdtsc", [(X86rdtsc)]>,
             TB;
 
+let isBarrier = 1, hasCtrlDep = 1 in {
+// FIXME: Should use 0x0F0B opcode
+def TRAP    : I<0, RawFrm, (outs), (ins), "ud2", [(X86trap)]>;
+}
+
 //===----------------------------------------------------------------------===//
 //  Input/Output Instructions...
 //