OSDN Git Service

Add an instruction selector capable of selecting 'ret void'
authorChris Lattner <sabre@nondot.org>
Sun, 29 Feb 2004 00:27:00 +0000 (00:27 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 29 Feb 2004 00:27:00 +0000 (00:27 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11973 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Sparc/InstSelectSimple.cpp [new file with mode: 0644]
lib/Target/Sparc/Sparc.h
lib/Target/Sparc/SparcRegisterInfo.td
lib/Target/Sparc/SparcTargetMachine.cpp
lib/Target/Sparc/SparcV8ISelSimple.cpp [new file with mode: 0644]
lib/Target/SparcV8/InstSelectSimple.cpp [new file with mode: 0644]
lib/Target/SparcV8/SparcV8.h
lib/Target/SparcV8/SparcV8ISelSimple.cpp [new file with mode: 0644]
lib/Target/SparcV8/SparcV8RegisterInfo.td
lib/Target/SparcV8/SparcV8TargetMachine.cpp

diff --git a/lib/Target/Sparc/InstSelectSimple.cpp b/lib/Target/Sparc/InstSelectSimple.cpp
new file mode 100644 (file)
index 0000000..c195611
--- /dev/null
@@ -0,0 +1,152 @@
+//===-- InstSelectSimple.cpp - A simple instruction selector 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 simple peephole instruction selector for the V8 target
+//
+//===----------------------------------------------------------------------===//
+
+#include "SparcV8.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicLowering.h"
+#include "llvm/Pass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Support/InstVisitor.h"
+#include "llvm/Support/CFG.h"
+using namespace llvm;
+
+namespace {
+  struct V8ISel : public FunctionPass, public InstVisitor<V8ISel> {
+    TargetMachine &TM;
+    MachineFunction *F;                 // The function we are compiling into
+    MachineBasicBlock *BB;              // The current MBB we are compiling
+
+    std::map<Value*, unsigned> RegMap;  // Mapping between Val's and SSA Regs
+
+    // MBBMap - Mapping between LLVM BB -> Machine BB
+    std::map<const BasicBlock*, MachineBasicBlock*> MBBMap;
+
+    V8ISel(TargetMachine &tm) : TM(tm), F(0), BB(0) {}
+
+    /// runOnFunction - Top level implementation of instruction selection for
+    /// the entire function.
+    ///
+    bool runOnFunction(Function &Fn);
+
+    virtual const char *getPassName() const {
+      return "SparcV8 Simple Instruction Selection";
+    }
+
+    /// visitBasicBlock - This method is called when we are visiting a new basic
+    /// block.  This simply creates a new MachineBasicBlock to emit code into
+    /// and adds it to the current MachineFunction.  Subsequent visit* for
+    /// instructions will be invoked for all instructions in the basic block.
+    ///
+    void visitBasicBlock(BasicBlock &LLVM_BB) {
+      BB = MBBMap[&LLVM_BB];
+    }
+
+    void visitReturnInst(ReturnInst &RI);
+
+    void visitInstruction(Instruction &I) {
+      std::cerr << "Unhandled instruction: " << I;
+      abort();
+    }
+
+    /// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the
+    /// function, lowering any calls to unknown intrinsic functions into the
+    /// equivalent LLVM code.
+    void LowerUnknownIntrinsicFunctionCalls(Function &F);
+
+
+    void visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI);
+
+  };
+}
+
+FunctionPass *llvm::createSparcV8SimpleInstructionSelector(TargetMachine &TM) {
+  return new V8ISel(TM);
+}
+
+
+bool V8ISel::runOnFunction(Function &Fn) {
+  // First pass over the function, lower any unknown intrinsic functions
+  // with the IntrinsicLowering class.
+  LowerUnknownIntrinsicFunctionCalls(Fn);
+  
+  F = &MachineFunction::construct(&Fn, TM);
+  
+  // Create all of the machine basic blocks for the function...
+  for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
+    F->getBasicBlockList().push_back(MBBMap[I] = new MachineBasicBlock(I));
+  
+  BB = &F->front();
+  
+  // Set up a frame object for the return address.  This is used by the
+  // llvm.returnaddress & llvm.frameaddress intrinisics.
+  //ReturnAddressIndex = F->getFrameInfo()->CreateFixedObject(4, -4);
+  
+  // Copy incoming arguments off of the stack and out of fixed registers.
+  //LoadArgumentsToVirtualRegs(Fn);
+  
+  // Instruction select everything except PHI nodes
+  visit(Fn);
+  
+  // Select the PHI nodes
+  //SelectPHINodes();
+  
+  RegMap.clear();
+  MBBMap.clear();
+  F = 0;
+  // We always build a machine code representation for the function
+  return true;
+}
+
+
+void V8ISel::visitReturnInst(ReturnInst &I) {
+  if (I.getNumOperands() == 0) {
+    // Just emit a 'ret' instruction
+    BuildMI(BB, V8::JMPLi, 2, V8::G0).addZImm(8).addReg(V8::I7);
+    return;
+  }
+  visitInstruction(I);
+}
+
+
+/// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the
+/// function, lowering any calls to unknown intrinsic functions into the
+/// equivalent LLVM code.
+void V8ISel::LowerUnknownIntrinsicFunctionCalls(Function &F) {
+  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+    for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; )
+      if (CallInst *CI = dyn_cast<CallInst>(I++))
+        if (Function *F = CI->getCalledFunction())
+          switch (F->getIntrinsicID()) {
+          case Intrinsic::not_intrinsic: break;
+          default:
+            // All other intrinsic calls we must lower.
+            Instruction *Before = CI->getPrev();
+            TM.getIntrinsicLowering().LowerIntrinsicCall(CI);
+            if (Before) {        // Move iterator to instruction after call
+              I = Before;  ++I;
+            } else {
+              I = BB->begin();
+            }
+          }
+}
+
+
+void V8ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) {
+  unsigned TmpReg1, TmpReg2;
+  switch (ID) {
+  default: assert(0 && "Intrinsic not supported!");
+  }
+}
index 2f93330..efe3d9f 100644 (file)
 
 namespace llvm {
 
-class FunctionPass;
-class TargetMachine;
+  class FunctionPass;
+  class TargetMachine;
 
-// Here is where you would define factory methods for sparcv8-specific
-// passes. For example:
-// FunctionPass *createSparcV8SimpleInstructionSelector (TargetMachine &TM);
+  FunctionPass *createSparcV8SimpleInstructionSelector(TargetMachine &TM);
 // FunctionPass *createSparcV8CodePrinterPass(std::ostream &OS,
 //                                            TargetMachine &TM);
 
index f58d06a..84b4c31 100644 (file)
@@ -16,7 +16,7 @@ class Ri<bits<5> num> : Register {
   field bits<5> Num = num;        // Numbers are identified with a 5 bit ID
 }
 
-let Namespace = "SparcV8" in {
+let Namespace = "V8" in {
   def G0 : Ri< 0>;    def G1 : Ri< 1>;    def G2 : Ri< 2>;    def G3 : Ri< 3>;
   def G4 : Ri< 4>;    def G5 : Ri< 5>;    def G6 : Ri< 6>;    def G7 : Ri< 7>;
   def O0 : Ri< 8>;    def O1 : Ri< 9>;    def O2 : Ri<10>;    def O3 : Ri<11>;
index 15401b1..f9a499d 100644 (file)
@@ -40,10 +40,19 @@ SparcV8TargetMachine::SparcV8TargetMachine(const Module &M,
 ///
 bool SparcV8TargetMachine::addPassesToEmitAssembly(PassManager &PM,
                                               std::ostream &Out) {
-  // <insert instruction selector passes here>
+  PM.add(createSparcV8SimpleInstructionSelector(*this));
+
+  // Print machine instructions as they are created.
+  PM.add(createMachineFunctionPrinterPass(&std::cerr));
+
   PM.add(createRegisterAllocator());
   PM.add(createPrologEpilogCodeInserter());
   // <insert assembly code output passes here>
+
+  // This is not a correct asm writer by any means, but at least we see what we
+  // are producing.
+  PM.add(createMachineFunctionPrinterPass(&Out));
+
   PM.add(createMachineCodeDeleter());
   return false;
 }
diff --git a/lib/Target/Sparc/SparcV8ISelSimple.cpp b/lib/Target/Sparc/SparcV8ISelSimple.cpp
new file mode 100644 (file)
index 0000000..c195611
--- /dev/null
@@ -0,0 +1,152 @@
+//===-- InstSelectSimple.cpp - A simple instruction selector 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 simple peephole instruction selector for the V8 target
+//
+//===----------------------------------------------------------------------===//
+
+#include "SparcV8.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicLowering.h"
+#include "llvm/Pass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Support/InstVisitor.h"
+#include "llvm/Support/CFG.h"
+using namespace llvm;
+
+namespace {
+  struct V8ISel : public FunctionPass, public InstVisitor<V8ISel> {
+    TargetMachine &TM;
+    MachineFunction *F;                 // The function we are compiling into
+    MachineBasicBlock *BB;              // The current MBB we are compiling
+
+    std::map<Value*, unsigned> RegMap;  // Mapping between Val's and SSA Regs
+
+    // MBBMap - Mapping between LLVM BB -> Machine BB
+    std::map<const BasicBlock*, MachineBasicBlock*> MBBMap;
+
+    V8ISel(TargetMachine &tm) : TM(tm), F(0), BB(0) {}
+
+    /// runOnFunction - Top level implementation of instruction selection for
+    /// the entire function.
+    ///
+    bool runOnFunction(Function &Fn);
+
+    virtual const char *getPassName() const {
+      return "SparcV8 Simple Instruction Selection";
+    }
+
+    /// visitBasicBlock - This method is called when we are visiting a new basic
+    /// block.  This simply creates a new MachineBasicBlock to emit code into
+    /// and adds it to the current MachineFunction.  Subsequent visit* for
+    /// instructions will be invoked for all instructions in the basic block.
+    ///
+    void visitBasicBlock(BasicBlock &LLVM_BB) {
+      BB = MBBMap[&LLVM_BB];
+    }
+
+    void visitReturnInst(ReturnInst &RI);
+
+    void visitInstruction(Instruction &I) {
+      std::cerr << "Unhandled instruction: " << I;
+      abort();
+    }
+
+    /// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the
+    /// function, lowering any calls to unknown intrinsic functions into the
+    /// equivalent LLVM code.
+    void LowerUnknownIntrinsicFunctionCalls(Function &F);
+
+
+    void visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI);
+
+  };
+}
+
+FunctionPass *llvm::createSparcV8SimpleInstructionSelector(TargetMachine &TM) {
+  return new V8ISel(TM);
+}
+
+
+bool V8ISel::runOnFunction(Function &Fn) {
+  // First pass over the function, lower any unknown intrinsic functions
+  // with the IntrinsicLowering class.
+  LowerUnknownIntrinsicFunctionCalls(Fn);
+  
+  F = &MachineFunction::construct(&Fn, TM);
+  
+  // Create all of the machine basic blocks for the function...
+  for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
+    F->getBasicBlockList().push_back(MBBMap[I] = new MachineBasicBlock(I));
+  
+  BB = &F->front();
+  
+  // Set up a frame object for the return address.  This is used by the
+  // llvm.returnaddress & llvm.frameaddress intrinisics.
+  //ReturnAddressIndex = F->getFrameInfo()->CreateFixedObject(4, -4);
+  
+  // Copy incoming arguments off of the stack and out of fixed registers.
+  //LoadArgumentsToVirtualRegs(Fn);
+  
+  // Instruction select everything except PHI nodes
+  visit(Fn);
+  
+  // Select the PHI nodes
+  //SelectPHINodes();
+  
+  RegMap.clear();
+  MBBMap.clear();
+  F = 0;
+  // We always build a machine code representation for the function
+  return true;
+}
+
+
+void V8ISel::visitReturnInst(ReturnInst &I) {
+  if (I.getNumOperands() == 0) {
+    // Just emit a 'ret' instruction
+    BuildMI(BB, V8::JMPLi, 2, V8::G0).addZImm(8).addReg(V8::I7);
+    return;
+  }
+  visitInstruction(I);
+}
+
+
+/// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the
+/// function, lowering any calls to unknown intrinsic functions into the
+/// equivalent LLVM code.
+void V8ISel::LowerUnknownIntrinsicFunctionCalls(Function &F) {
+  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+    for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; )
+      if (CallInst *CI = dyn_cast<CallInst>(I++))
+        if (Function *F = CI->getCalledFunction())
+          switch (F->getIntrinsicID()) {
+          case Intrinsic::not_intrinsic: break;
+          default:
+            // All other intrinsic calls we must lower.
+            Instruction *Before = CI->getPrev();
+            TM.getIntrinsicLowering().LowerIntrinsicCall(CI);
+            if (Before) {        // Move iterator to instruction after call
+              I = Before;  ++I;
+            } else {
+              I = BB->begin();
+            }
+          }
+}
+
+
+void V8ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) {
+  unsigned TmpReg1, TmpReg2;
+  switch (ID) {
+  default: assert(0 && "Intrinsic not supported!");
+  }
+}
diff --git a/lib/Target/SparcV8/InstSelectSimple.cpp b/lib/Target/SparcV8/InstSelectSimple.cpp
new file mode 100644 (file)
index 0000000..c195611
--- /dev/null
@@ -0,0 +1,152 @@
+//===-- InstSelectSimple.cpp - A simple instruction selector 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 simple peephole instruction selector for the V8 target
+//
+//===----------------------------------------------------------------------===//
+
+#include "SparcV8.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicLowering.h"
+#include "llvm/Pass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Support/InstVisitor.h"
+#include "llvm/Support/CFG.h"
+using namespace llvm;
+
+namespace {
+  struct V8ISel : public FunctionPass, public InstVisitor<V8ISel> {
+    TargetMachine &TM;
+    MachineFunction *F;                 // The function we are compiling into
+    MachineBasicBlock *BB;              // The current MBB we are compiling
+
+    std::map<Value*, unsigned> RegMap;  // Mapping between Val's and SSA Regs
+
+    // MBBMap - Mapping between LLVM BB -> Machine BB
+    std::map<const BasicBlock*, MachineBasicBlock*> MBBMap;
+
+    V8ISel(TargetMachine &tm) : TM(tm), F(0), BB(0) {}
+
+    /// runOnFunction - Top level implementation of instruction selection for
+    /// the entire function.
+    ///
+    bool runOnFunction(Function &Fn);
+
+    virtual const char *getPassName() const {
+      return "SparcV8 Simple Instruction Selection";
+    }
+
+    /// visitBasicBlock - This method is called when we are visiting a new basic
+    /// block.  This simply creates a new MachineBasicBlock to emit code into
+    /// and adds it to the current MachineFunction.  Subsequent visit* for
+    /// instructions will be invoked for all instructions in the basic block.
+    ///
+    void visitBasicBlock(BasicBlock &LLVM_BB) {
+      BB = MBBMap[&LLVM_BB];
+    }
+
+    void visitReturnInst(ReturnInst &RI);
+
+    void visitInstruction(Instruction &I) {
+      std::cerr << "Unhandled instruction: " << I;
+      abort();
+    }
+
+    /// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the
+    /// function, lowering any calls to unknown intrinsic functions into the
+    /// equivalent LLVM code.
+    void LowerUnknownIntrinsicFunctionCalls(Function &F);
+
+
+    void visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI);
+
+  };
+}
+
+FunctionPass *llvm::createSparcV8SimpleInstructionSelector(TargetMachine &TM) {
+  return new V8ISel(TM);
+}
+
+
+bool V8ISel::runOnFunction(Function &Fn) {
+  // First pass over the function, lower any unknown intrinsic functions
+  // with the IntrinsicLowering class.
+  LowerUnknownIntrinsicFunctionCalls(Fn);
+  
+  F = &MachineFunction::construct(&Fn, TM);
+  
+  // Create all of the machine basic blocks for the function...
+  for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
+    F->getBasicBlockList().push_back(MBBMap[I] = new MachineBasicBlock(I));
+  
+  BB = &F->front();
+  
+  // Set up a frame object for the return address.  This is used by the
+  // llvm.returnaddress & llvm.frameaddress intrinisics.
+  //ReturnAddressIndex = F->getFrameInfo()->CreateFixedObject(4, -4);
+  
+  // Copy incoming arguments off of the stack and out of fixed registers.
+  //LoadArgumentsToVirtualRegs(Fn);
+  
+  // Instruction select everything except PHI nodes
+  visit(Fn);
+  
+  // Select the PHI nodes
+  //SelectPHINodes();
+  
+  RegMap.clear();
+  MBBMap.clear();
+  F = 0;
+  // We always build a machine code representation for the function
+  return true;
+}
+
+
+void V8ISel::visitReturnInst(ReturnInst &I) {
+  if (I.getNumOperands() == 0) {
+    // Just emit a 'ret' instruction
+    BuildMI(BB, V8::JMPLi, 2, V8::G0).addZImm(8).addReg(V8::I7);
+    return;
+  }
+  visitInstruction(I);
+}
+
+
+/// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the
+/// function, lowering any calls to unknown intrinsic functions into the
+/// equivalent LLVM code.
+void V8ISel::LowerUnknownIntrinsicFunctionCalls(Function &F) {
+  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+    for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; )
+      if (CallInst *CI = dyn_cast<CallInst>(I++))
+        if (Function *F = CI->getCalledFunction())
+          switch (F->getIntrinsicID()) {
+          case Intrinsic::not_intrinsic: break;
+          default:
+            // All other intrinsic calls we must lower.
+            Instruction *Before = CI->getPrev();
+            TM.getIntrinsicLowering().LowerIntrinsicCall(CI);
+            if (Before) {        // Move iterator to instruction after call
+              I = Before;  ++I;
+            } else {
+              I = BB->begin();
+            }
+          }
+}
+
+
+void V8ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) {
+  unsigned TmpReg1, TmpReg2;
+  switch (ID) {
+  default: assert(0 && "Intrinsic not supported!");
+  }
+}
index 2f93330..efe3d9f 100644 (file)
 
 namespace llvm {
 
-class FunctionPass;
-class TargetMachine;
+  class FunctionPass;
+  class TargetMachine;
 
-// Here is where you would define factory methods for sparcv8-specific
-// passes. For example:
-// FunctionPass *createSparcV8SimpleInstructionSelector (TargetMachine &TM);
+  FunctionPass *createSparcV8SimpleInstructionSelector(TargetMachine &TM);
 // FunctionPass *createSparcV8CodePrinterPass(std::ostream &OS,
 //                                            TargetMachine &TM);
 
diff --git a/lib/Target/SparcV8/SparcV8ISelSimple.cpp b/lib/Target/SparcV8/SparcV8ISelSimple.cpp
new file mode 100644 (file)
index 0000000..c195611
--- /dev/null
@@ -0,0 +1,152 @@
+//===-- InstSelectSimple.cpp - A simple instruction selector 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 simple peephole instruction selector for the V8 target
+//
+//===----------------------------------------------------------------------===//
+
+#include "SparcV8.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicLowering.h"
+#include "llvm/Pass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Support/InstVisitor.h"
+#include "llvm/Support/CFG.h"
+using namespace llvm;
+
+namespace {
+  struct V8ISel : public FunctionPass, public InstVisitor<V8ISel> {
+    TargetMachine &TM;
+    MachineFunction *F;                 // The function we are compiling into
+    MachineBasicBlock *BB;              // The current MBB we are compiling
+
+    std::map<Value*, unsigned> RegMap;  // Mapping between Val's and SSA Regs
+
+    // MBBMap - Mapping between LLVM BB -> Machine BB
+    std::map<const BasicBlock*, MachineBasicBlock*> MBBMap;
+
+    V8ISel(TargetMachine &tm) : TM(tm), F(0), BB(0) {}
+
+    /// runOnFunction - Top level implementation of instruction selection for
+    /// the entire function.
+    ///
+    bool runOnFunction(Function &Fn);
+
+    virtual const char *getPassName() const {
+      return "SparcV8 Simple Instruction Selection";
+    }
+
+    /// visitBasicBlock - This method is called when we are visiting a new basic
+    /// block.  This simply creates a new MachineBasicBlock to emit code into
+    /// and adds it to the current MachineFunction.  Subsequent visit* for
+    /// instructions will be invoked for all instructions in the basic block.
+    ///
+    void visitBasicBlock(BasicBlock &LLVM_BB) {
+      BB = MBBMap[&LLVM_BB];
+    }
+
+    void visitReturnInst(ReturnInst &RI);
+
+    void visitInstruction(Instruction &I) {
+      std::cerr << "Unhandled instruction: " << I;
+      abort();
+    }
+
+    /// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the
+    /// function, lowering any calls to unknown intrinsic functions into the
+    /// equivalent LLVM code.
+    void LowerUnknownIntrinsicFunctionCalls(Function &F);
+
+
+    void visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI);
+
+  };
+}
+
+FunctionPass *llvm::createSparcV8SimpleInstructionSelector(TargetMachine &TM) {
+  return new V8ISel(TM);
+}
+
+
+bool V8ISel::runOnFunction(Function &Fn) {
+  // First pass over the function, lower any unknown intrinsic functions
+  // with the IntrinsicLowering class.
+  LowerUnknownIntrinsicFunctionCalls(Fn);
+  
+  F = &MachineFunction::construct(&Fn, TM);
+  
+  // Create all of the machine basic blocks for the function...
+  for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
+    F->getBasicBlockList().push_back(MBBMap[I] = new MachineBasicBlock(I));
+  
+  BB = &F->front();
+  
+  // Set up a frame object for the return address.  This is used by the
+  // llvm.returnaddress & llvm.frameaddress intrinisics.
+  //ReturnAddressIndex = F->getFrameInfo()->CreateFixedObject(4, -4);
+  
+  // Copy incoming arguments off of the stack and out of fixed registers.
+  //LoadArgumentsToVirtualRegs(Fn);
+  
+  // Instruction select everything except PHI nodes
+  visit(Fn);
+  
+  // Select the PHI nodes
+  //SelectPHINodes();
+  
+  RegMap.clear();
+  MBBMap.clear();
+  F = 0;
+  // We always build a machine code representation for the function
+  return true;
+}
+
+
+void V8ISel::visitReturnInst(ReturnInst &I) {
+  if (I.getNumOperands() == 0) {
+    // Just emit a 'ret' instruction
+    BuildMI(BB, V8::JMPLi, 2, V8::G0).addZImm(8).addReg(V8::I7);
+    return;
+  }
+  visitInstruction(I);
+}
+
+
+/// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the
+/// function, lowering any calls to unknown intrinsic functions into the
+/// equivalent LLVM code.
+void V8ISel::LowerUnknownIntrinsicFunctionCalls(Function &F) {
+  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+    for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; )
+      if (CallInst *CI = dyn_cast<CallInst>(I++))
+        if (Function *F = CI->getCalledFunction())
+          switch (F->getIntrinsicID()) {
+          case Intrinsic::not_intrinsic: break;
+          default:
+            // All other intrinsic calls we must lower.
+            Instruction *Before = CI->getPrev();
+            TM.getIntrinsicLowering().LowerIntrinsicCall(CI);
+            if (Before) {        // Move iterator to instruction after call
+              I = Before;  ++I;
+            } else {
+              I = BB->begin();
+            }
+          }
+}
+
+
+void V8ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) {
+  unsigned TmpReg1, TmpReg2;
+  switch (ID) {
+  default: assert(0 && "Intrinsic not supported!");
+  }
+}
index f58d06a..84b4c31 100644 (file)
@@ -16,7 +16,7 @@ class Ri<bits<5> num> : Register {
   field bits<5> Num = num;        // Numbers are identified with a 5 bit ID
 }
 
-let Namespace = "SparcV8" in {
+let Namespace = "V8" in {
   def G0 : Ri< 0>;    def G1 : Ri< 1>;    def G2 : Ri< 2>;    def G3 : Ri< 3>;
   def G4 : Ri< 4>;    def G5 : Ri< 5>;    def G6 : Ri< 6>;    def G7 : Ri< 7>;
   def O0 : Ri< 8>;    def O1 : Ri< 9>;    def O2 : Ri<10>;    def O3 : Ri<11>;
index 15401b1..f9a499d 100644 (file)
@@ -40,10 +40,19 @@ SparcV8TargetMachine::SparcV8TargetMachine(const Module &M,
 ///
 bool SparcV8TargetMachine::addPassesToEmitAssembly(PassManager &PM,
                                               std::ostream &Out) {
-  // <insert instruction selector passes here>
+  PM.add(createSparcV8SimpleInstructionSelector(*this));
+
+  // Print machine instructions as they are created.
+  PM.add(createMachineFunctionPrinterPass(&std::cerr));
+
   PM.add(createRegisterAllocator());
   PM.add(createPrologEpilogCodeInserter());
   // <insert assembly code output passes here>
+
+  // This is not a correct asm writer by any means, but at least we see what we
+  // are producing.
+  PM.add(createMachineFunctionPrinterPass(&Out));
+
   PM.add(createMachineCodeDeleter());
   return false;
 }