mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23333 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			522 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			522 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #if 0
 | |
| //===- SparcV8ISelPattern.cpp - A pattern matching isel for SparcV8 -------===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file was developed by the LLVM research group and is distributed under
 | |
| // the University of Illinois Open Source License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // This file defines a pattern matching instruction selector for SparcV8.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| //Please note that this file is a work in progress, and not a high
 | |
| //priority for anyone.
 | |
| 
 | |
| #include "SparcV8.h"
 | |
| #include "SparcV8RegisterInfo.h"
 | |
| #include "llvm/Constants.h"                   // FIXME: REMOVE
 | |
| #include "llvm/Function.h"
 | |
| #include "llvm/CodeGen/MachineInstrBuilder.h"
 | |
| #include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE
 | |
| #include "llvm/CodeGen/MachineFunction.h"
 | |
| #include "llvm/CodeGen/MachineFrameInfo.h"
 | |
| #include "llvm/CodeGen/SelectionDAG.h"
 | |
| #include "llvm/CodeGen/SelectionDAGISel.h"
 | |
| #include "llvm/CodeGen/SSARegMap.h"
 | |
| #include "llvm/Target/TargetData.h"
 | |
| #include "llvm/Target/TargetLowering.h"
 | |
| #include "llvm/Support/MathExtras.h"
 | |
| #include "llvm/ADT/Statistic.h"
 | |
| #include "llvm/Support/Debug.h"
 | |
| #include "llvm/Support/CommandLine.h"
 | |
| #include <set>
 | |
| #include <algorithm>
 | |
| using namespace llvm;
 | |
| 
 | |
| //===----------------------------------------------------------------------===//
 | |
| //  V8TargetLowering - SparcV8 Implementation of the TargetLowering interface
 | |
| namespace {
 | |
|   class V8TargetLowering : public TargetLowering {
 | |
|     int VarArgsFrameIndex;            // FrameIndex for start of varargs area.
 | |
|   public:
 | |
|     V8TargetLowering(TargetMachine &TM) : TargetLowering(TM) {
 | |
|       // Set up the TargetLowering object.
 | |
|       //I am having problems with shr n ubyte 1
 | |
|       setShiftAmountType(MVT::i32);
 | |
|       setSetCCResultType(MVT::i32);
 | |
|       setSetCCResultContents(ZeroOrOneSetCCResult);
 | |
| 
 | |
|       //FIXME: get these right
 | |
|       addRegisterClass(MVT::i64, V8::GPRCRegisterClass);
 | |
|       addRegisterClass(MVT::f64, V8::FPRCRegisterClass);
 | |
|       addRegisterClass(MVT::f32, V8::FPRCRegisterClass);
 | |
| 
 | |
|       setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
 | |
|       setOperationAction(ISD::BRTWOWAY_CC,  MVT::Other, Expand);
 | |
|       setOperationAction(ISD::EXTLOAD, MVT::i1,  Promote);
 | |
|       setOperationAction(ISD::EXTLOAD, MVT::f32, Promote);
 | |
| 
 | |
|       setOperationAction(ISD::ZEXTLOAD, MVT::i1, Expand);
 | |
|       setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand);
 | |
| 
 | |
|       setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1,  Expand);
 | |
|       setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8,  Expand);
 | |
|       setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
 | |
|       setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i32, Expand);
 | |
| 
 | |
|       setOperationAction(ISD::UREM, MVT::i32, Expand);
 | |
|       setOperationAction(ISD::SREM, MVT::i32, Expand);
 | |
| 
 | |
|       setOperationAction(ISD::CTPOP, MVT::i32, Expand);
 | |
|       setOperationAction(ISD::CTTZ, MVT::i32, Expand);
 | |
|       setOperationAction(ISD::CTLZ, MVT::i32, Expand);
 | |
| 
 | |
|       setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
 | |
|       setOperationAction(ISD::MEMSET,  MVT::Other, Expand);
 | |
|       setOperationAction(ISD::MEMCPY,  MVT::Other, Expand);
 | |
| 
 | |
|       // We don't support sin/cos/sqrt
 | |
|       setOperationAction(ISD::FSIN , MVT::f64, Expand);
 | |
|       setOperationAction(ISD::FCOS , MVT::f64, Expand);
 | |
|       setOperationAction(ISD::FSQRT, MVT::f64, Expand);
 | |
|       setOperationAction(ISD::FSIN , MVT::f32, Expand);
 | |
|       setOperationAction(ISD::FCOS , MVT::f32, Expand);
 | |
|       setOperationAction(ISD::FSQRT, MVT::f32, Expand);
 | |
| 
 | |
|       computeRegisterProperties();
 | |
| 
 | |
|       addLegalFPImmediate(+0.0); //F31
 | |
|       addLegalFPImmediate(-0.0); //-F31
 | |
|     }
 | |
| 
 | |
|     /// LowerArguments - This hook must be implemented to indicate how we should
 | |
|     /// lower the arguments for the specified function, into the specified DAG.
 | |
|     virtual std::vector<SDOperand>
 | |
|     LowerArguments(Function &F, SelectionDAG &DAG);
 | |
| 
 | |
|     /// LowerCallTo - This hook lowers an abstract call to a function into an
 | |
|     /// actual call.
 | |
|     virtual std::pair<SDOperand, SDOperand>
 | |
|     LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CC,
 | |
|                 bool isTailCall, SDOperand Callee, ArgListTy &Args,
 | |
|                 SelectionDAG &DAG);
 | |
|   };
 | |
| }
 | |
| 
 | |
| /// AddLiveIn - This helper function adds the specified physical register to the
 | |
| /// MachineFunction as a live in value.  It also creates a corresponding virtual
 | |
| /// register for it.
 | |
| static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
 | |
|                           TargetRegisterClass *RC) {
 | |
|   assert(RC->contains(PReg) && "Not the correct regclass!");
 | |
|   unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC);
 | |
|   MF.addLiveIn(PReg, VReg);
 | |
|   return VReg;
 | |
| }
 | |
| 
 | |
| std::vector<SDOperand>
 | |
| V8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
 | |
| {
 | |
|   static const unsigned IncomingArgRegs[] =
 | |
|     { V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5 };
 | |
|   std::vector<SDOperand> ArgValues;
 | |
| 
 | |
|   MachineFunction &MF = DAG.getMachineFunction();
 | |
|   MachineFrameInfo*MFI = MF.getFrameInfo();
 | |
| 
 | |
|   MachineBasicBlock& BB = MF.front();
 | |
| 
 | |
|   unsigned ArgNo = 0;
 | |
|   unsigned ArgOffset = 92;
 | |
|   for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end();
 | |
|        I != E; ++I, ++ArgNo) {
 | |
|     MVT::ValueType VT = getValueType(I->getType());
 | |
|     SDOperand argt;
 | |
|     if (ArgNo < 6) {
 | |
|       switch(VT) {
 | |
|       default:
 | |
|         std::cerr << "Unknown Type " << VT << "\n";
 | |
|         abort();
 | |
|       case MVT::f64:
 | |
|       case MVT::i64:
 | |
|         //FIXME: figure out the build pair thing
 | |
|         assert(0 && "doubles and longs not supported yet");
 | |
|       case MVT::f32:
 | |
|         argt = DAG.getCopyFromReg(AddLiveIn(MF, IncomingArgRegs[ArgNo],
 | |
|                                             MVT::i32),
 | |
|                                   VT, DAG.getRoot());
 | |
|         //copy out of Int reg
 | |
|         argt = DAG.getNode(ISD::FP_TO_UINT, MVT::f32, argt);
 | |
|         break;
 | |
|       case MVT::i1:
 | |
|       case MVT::i8:
 | |
|       case MVT::i16:
 | |
|       case MVT::i32:
 | |
|         argt = DAG.getCopyFromReg(AddLiveIn(MF, IncomingArgRegs[ArgNo],
 | |
|                                             getRegClassFor(MVT::i32)),
 | |
|                                   VT, DAG.getRoot());
 | |
|         if (VT != MVT::i32)
 | |
|           argt = DAG.getNode(ISD::TRUNCATE, VT, argt);
 | |
|         break;
 | |
|       }
 | |
|       DAG.setRoot(argt.getValue(1));
 | |
|     } else {
 | |
|       //stack passed
 | |
|       switch(VT) {
 | |
|       default:
 | |
|         std::cerr << "Unknown Type " << VT << "\n";
 | |
|         abort();
 | |
|       case MVT::f64:
 | |
|       case MVT::i64:
 | |
|         //FIXME: figure out the build pair thing
 | |
|         assert(0 && "doubles and longs not supported yet");
 | |
|       case MVT::f32:
 | |
|       case MVT::i1:
 | |
|       case MVT::i8:
 | |
|       case MVT::i16:
 | |
|       case MVT::i32:
 | |
|       // Create the frame index object for this incoming parameter...
 | |
|       int FI = MFI->CreateFixedObject(4, ArgOffset);
 | |
|       argt = DAG.getLoad(VT,
 | |
|                          DAG.getEntryNode(),
 | |
|                          DAG.getFramIndex(FI, MVT::i32),
 | |
|                          DAG.getSrcValue(NULL));
 | |
|       ArgOffset += 4;
 | |
|       break;
 | |
|       }
 | |
|       ArgValues.push_back(argt);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   //return the arguments
 | |
|   return ArgValues;
 | |
| }
 | |
| 
 | |
| std::pair<SDOperand, SDOperand>
 | |
| V8TargetLowering::LowerCallTo(SDOperand Chain,
 | |
|                                  const Type *RetTy, bool isVarArg,
 | |
|                                  unsigned CallingConv, bool isTailCall,
 | |
|                                  SDOperand Callee, ArgListTy &Args,
 | |
|                                  SelectionDAG &DAG) {
 | |
|   //FIXME
 | |
|   return std::make_pair(Chain, Chain);
 | |
| }
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| //===--------------------------------------------------------------------===//
 | |
| /// ISel - V8 specific code to select V8 machine instructions for
 | |
| /// SelectionDAG operations.
 | |
| //===--------------------------------------------------------------------===//
 | |
| class ISel : public SelectionDAGISel {
 | |
| 
 | |
|   /// V8Lowering - This object fully describes how to lower LLVM code to an
 | |
|   /// V8-specific SelectionDAG.
 | |
|   V8TargetLowering V8Lowering;
 | |
| 
 | |
|   SelectionDAG *ISelDAG;  // Hack to support us having a dag->dag transform
 | |
|                           // for sdiv and udiv until it is put into the future
 | |
|                           // dag combiner.
 | |
| 
 | |
|   /// ExprMap - As shared expressions are codegen'd, we keep track of which
 | |
|   /// vreg the value is produced in, so we only emit one copy of each compiled
 | |
|   /// tree.
 | |
|   static const unsigned notIn = (unsigned)(-1);
 | |
|   std::map<SDOperand, unsigned> ExprMap;
 | |
| 
 | |
| public:
 | |
|   ISel(TargetMachine &TM) : SelectionDAGISel(V8Lowering), V8Lowering(TM)
 | |
|   {}
 | |
| 
 | |
|   /// InstructionSelectBasicBlock - This callback is invoked by
 | |
|   /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
 | |
|   virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
 | |
|     DEBUG(BB->dump());
 | |
| 
 | |
|     // Codegen the basic block.
 | |
|     ISelDAG = &DAG;
 | |
|     max_depth = DAG.getRoot().getNodeDepth();
 | |
|     Select(DAG.getRoot());
 | |
| 
 | |
|     // Clear state used for selection.
 | |
|     ExprMap.clear();
 | |
|   }
 | |
| 
 | |
|   unsigned SelectExpr(SDOperand N);
 | |
|   void Select(SDOperand N);
 | |
| 
 | |
| };
 | |
| }
 | |
| 
 | |
| //These describe LDAx
 | |
| static const int IMM_LOW  = -32768;
 | |
| static const int IMM_HIGH = 32767;
 | |
| static const int IMM_MULT = 65536;
 | |
| 
 | |
| static long getUpper16(long l)
 | |
| {
 | |
|   long y = l / IMM_MULT;
 | |
|   if (l % IMM_MULT > IMM_HIGH)
 | |
|     ++y;
 | |
|   return y;
 | |
| }
 | |
| 
 | |
| static long getLower16(long l)
 | |
| {
 | |
|   long h = getUpper16(l);
 | |
|   return l - h * IMM_MULT;
 | |
| }
 | |
| 
 | |
| unsigned ISel::SelectExpr(SDOperand N) {
 | |
|   unsigned Result;
 | |
|   unsigned Tmp1, Tmp2 = 0, Tmp3;
 | |
|   unsigned Opc = 0;
 | |
|   unsigned opcode = N.getOpcode();
 | |
| 
 | |
|   SDNode *Node = N.Val;
 | |
|   MVT::ValueType DestType = N.getValueType();
 | |
| 
 | |
|   unsigned &Reg = ExprMap[N];
 | |
|   if (Reg) return Reg;
 | |
| 
 | |
|   if (N.getOpcode() != ISD::CALL && N.getOpcode() != ISD::TAILCALL)
 | |
|     Reg = Result = (N.getValueType() != MVT::Other) ?
 | |
|       MakeReg(N.getValueType()) : notIn;
 | |
|   else {
 | |
|     // If this is a call instruction, make sure to prepare ALL of the result
 | |
|     // values as well as the chain.
 | |
|     if (Node->getNumValues() == 1)
 | |
|       Reg = Result = notIn;  // Void call, just a chain.
 | |
|     else {
 | |
|       Result = MakeReg(Node->getValueType(0));
 | |
|       ExprMap[N.getValue(0)] = Result;
 | |
|       for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
 | |
|         ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
 | |
|       ExprMap[SDOperand(Node, Node->getNumValues()-1)] = notIn;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   switch (opcode) {
 | |
|   default:
 | |
|     Node->dump();
 | |
|     assert(0 && "Node not handled!\n");
 | |
| 
 | |
|   case ISD::EXTLOAD:
 | |
|   case ISD::ZEXTLOAD:
 | |
|   case ISD::SEXTLOAD:
 | |
|   case ISD::LOAD:
 | |
|     {
 | |
|       // Make sure we generate both values.
 | |
|       if (Result != notIn)
 | |
|         ExprMap[N.getValue(1)] = notIn;   // Generate the token
 | |
|       else
 | |
|         Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
 | |
| 
 | |
|       SDOperand Chain   = N.getOperand(0);
 | |
|       SDOperand Address = N.getOperand(1);
 | |
|       Select(Chain);
 | |
|       unsigned Adr = SelectExpr(Address);
 | |
|       switch(cast<VTSDNode>(Node->getOperand(3))->getVT()) {
 | |
|       case MVT::i32: Opc = V8::LD;
 | |
|       case MVT::i16: Opc = opcode == ISD::ZEXTLOAD ? V8::LDUH : V8::LDSH; break;
 | |
|       case MVT::i8:  Opc = opcode == ISD::ZEXTLOAD ? V8::LDUB : V8::LDSB; break;
 | |
|       case MVT::f64: Opc = V8::LDFSRrr;
 | |
|       case MVT::f32: Opc = V8::LDDFrr;
 | |
|       default:
 | |
|         Node->dump();
 | |
|         assert(0 && "Bad type!");
 | |
|         break;
 | |
|       }
 | |
|       BuildMI(BB, Opc, 1, Result).addReg(Adr);
 | |
|       return Result;
 | |
|     }
 | |
| 
 | |
|   case ISD::TAILCALL:
 | |
|   case ISD::CALL:
 | |
|     {
 | |
|       //FIXME:
 | |
|       abort();
 | |
|       return Result;
 | |
|     }
 | |
| 
 | |
|   case ISD::CopyFromReg:
 | |
|     {
 | |
|       // Make sure we generate both values.
 | |
|       if (Result != notIn)
 | |
|         ExprMap[N.getValue(1)] = notIn;   // Generate the token
 | |
|       else
 | |
|         Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
 | |
| 
 | |
|       SDOperand Chain   = N.getOperand(0);
 | |
|       Select(Chain);
 | |
|       unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
 | |
| 
 | |
|       BuildMI(BB, V8::ORrr, 2, Result).addReg(r).addReg(V8::G0);
 | |
|       return Result;
 | |
|     }
 | |
| 
 | |
|     //Most of the plain arithmetic and logic share the same form, and the same
 | |
|     //constant immediate test
 | |
|   case ISD::XOR:
 | |
|   case ISD::AND:
 | |
|   case ISD::OR:
 | |
|   case ISD::SHL:
 | |
|   case ISD::SRL:
 | |
|   case ISD::SRA:
 | |
|   case ISD::ADD:
 | |
|   case ISD::SUB:
 | |
|   case ISD::SDIV:
 | |
|   case ISD::UDIV:
 | |
|   case ISD::SMUL:
 | |
|   case ISD::UMUL:
 | |
|     switch(opcode) {
 | |
|     case ISD::XOR:  Opc = V8::XORrr; break;
 | |
|     case ISD::AND:  Opc = V8::ANDrr; break;
 | |
|     case ISD::OR:   Opc = V8::ORrr; break;
 | |
|     case ISD::SHL:  Opc = V8::SLLrr; break;
 | |
|     case ISD::SRL:  Opc = V8::SRLrr; break;
 | |
|     case ISD::SRA:  Opc = V8::SRArr; break;
 | |
|     case ISD::ADD:  Opc = V8::ADDrr; break;
 | |
|     case ISD::SUB:  Opc = V8::SUBrr; break;
 | |
|     case ISD::SDIV: Opc = V8::SDIVrr; break;
 | |
|     case ISD::UDIV: Opc = V8::UDIVrr; break;
 | |
|     case ISD::SMUL: Opc = V8::SMULrr; break;
 | |
|     case ISD::UMUL: Opc = V8::UMULrr; break;
 | |
|     }
 | |
|     Tmp1 = SelectExpr(N.getOperand(0));
 | |
|     Tmp2 = SelectExpr(N.getOperand(1));
 | |
|     BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
 | |
|     return Result;
 | |
| 
 | |
|   }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| void ISel::Select(SDOperand N) {
 | |
|   unsigned Tmp1, Tmp2, Opc;
 | |
|   unsigned opcode = N.getOpcode();
 | |
| 
 | |
|   if (!ExprMap.insert(std::make_pair(N, notIn)).second)
 | |
|     return;  // Already selected.
 | |
| 
 | |
|   SDNode *Node = N.Val;
 | |
| 
 | |
|   switch (opcode) {
 | |
| 
 | |
|   default:
 | |
|     Node->dump(); std::cerr << "\n";
 | |
|     assert(0 && "Node not handled yet!");
 | |
| 
 | |
|   case ISD::BRCOND: {
 | |
|     //FIXME
 | |
|     abort();
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   case ISD::BR: {
 | |
|     MachineBasicBlock *Dest =
 | |
|       cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
 | |
| 
 | |
|     Select(N.getOperand(0));
 | |
|     BuildMI(BB, V8::BA, 1).addMBB(Dest);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   case ISD::ImplicitDef:
 | |
|     Select(N.getOperand(0));
 | |
|     BuildMI(BB, V8::IMPLICIT_DEF, 0, cast<RegSDNode>(N)->getReg());
 | |
|     return;
 | |
| 
 | |
|   case ISD::EntryToken: return;  // Noop
 | |
| 
 | |
|   case ISD::TokenFactor:
 | |
|     for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
 | |
|       Select(Node->getOperand(i));
 | |
|     return;
 | |
| 
 | |
|   case ISD::CopyToReg:
 | |
|     Select(N.getOperand(0));
 | |
|     Tmp1 = SelectExpr(N.getOperand(1));
 | |
|     Tmp2 = cast<RegSDNode>(N)->getReg();
 | |
| 
 | |
|     if (Tmp1 != Tmp2) {
 | |
|       if (N.getOperand(1).getValueType() == MVT::f64 ||
 | |
|           N.getOperand(1).getValueType() == MVT::f32)
 | |
|         BuildMI(BB, V8::FMOVS, 2, Tmp2).addReg(Tmp1);
 | |
|       else
 | |
|         BuildMI(BB, V8::ORrr, 2, Tmp2).addReg(Tmp1).addReg(V8::G0);
 | |
|     }
 | |
|     return;
 | |
| 
 | |
|   case ISD::RET:
 | |
|     //FIXME:
 | |
|     abort();
 | |
|     return;
 | |
| 
 | |
|   case ISD::TRUNCSTORE:
 | |
|   case ISD::STORE:
 | |
|     {
 | |
|       SDOperand Chain   = N.getOperand(0);
 | |
|       SDOperand Value = N.getOperand(1);
 | |
|       SDOperand Address = N.getOperand(2);
 | |
|       Select(Chain);
 | |
| 
 | |
|       Tmp1 = SelectExpr(Value);
 | |
|       Tmp2 = SelectExpr(Address);
 | |
| 
 | |
|       unsigned VT = opcode == ISD::STORE ?
 | |
|         Value.getValueType() : cast<VTSDNode>(Node->getOperand(4))->getVT();
 | |
|       switch(VT) {
 | |
|       default: assert(0 && "unknown Type in store");
 | |
|       case MVT::f64: Opc = V8::STDFrr; break;
 | |
|       case MVT::f32: Opc = V8::STFrr; break;
 | |
|       case MVT::i1:  //FIXME: DAG does not promote this load
 | |
|       case MVT::i8:  Opc = V8::STBrr; break;
 | |
|       case MVT::i16: Opc = V8::STHrr; break;
 | |
|       case MVT::i32: Opc = V8::STLrr; break;
 | |
|       case MVT::i64: Opc = V8::STDrr; break;
 | |
|       }
 | |
| 
 | |
|       BuildMI(BB,Opc,2).addReg(Tmp1).addReg(Tmp2);
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|   case ISD::EXTLOAD:
 | |
|   case ISD::SEXTLOAD:
 | |
|   case ISD::ZEXTLOAD:
 | |
|   case ISD::LOAD:
 | |
|   case ISD::CopyFromReg:
 | |
|   case ISD::TAILCALL:
 | |
|   case ISD::CALL:
 | |
|   case ISD::DYNAMIC_STACKALLOC:
 | |
|     ExprMap.erase(N);
 | |
|     SelectExpr(N);
 | |
|     return;
 | |
| 
 | |
|   case ISD::CALLSEQ_START:
 | |
|   case ISD::CALLSEQ_END:
 | |
|     Select(N.getOperand(0));
 | |
|     Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
 | |
| 
 | |
|     Opc = N.getOpcode() == ISD::CALLSEQ_START ? V8::ADJUSTCALLSTACKDOWN :
 | |
|       V8::ADJUSTCALLSTACKUP;
 | |
|     BuildMI(BB, Opc, 1).addImm(Tmp1);
 | |
|     return;
 | |
|   }
 | |
|   assert(0 && "Should not be reached!");
 | |
| }
 | |
| 
 | |
| 
 | |
| /// createV8PatternInstructionSelector - This pass converts an LLVM function
 | |
| /// into a machine code representation using pattern matching and a machine
 | |
| /// description file.
 | |
| ///
 | |
| FunctionPass *llvm::createV8PatternInstructionSelector(TargetMachine &TM) {
 | |
|   return new ISel(TM);
 | |
| }
 | |
| 
 | |
| #endif
 |