diff options
author | Chris Lattner <sabre@nondot.org> | 2004-02-29 00:27:00 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-02-29 00:27:00 +0000 |
commit | 1c809c594b8339fff4746c08e34914fffc3242e4 (patch) | |
tree | 65320eb7580761478b569cdbc2069c1afb47c496 | |
parent | da474adb2117ac1647348aa381a95c7b6e1fb524 (diff) | |
download | external_llvm-1c809c594b8339fff4746c08e34914fffc3242e4.zip external_llvm-1c809c594b8339fff4746c08e34914fffc3242e4.tar.gz external_llvm-1c809c594b8339fff4746c08e34914fffc3242e4.tar.bz2 |
Add an instruction selector capable of selecting 'ret void'
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11973 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/Sparc/InstSelectSimple.cpp | 152 | ||||
-rw-r--r-- | lib/Target/Sparc/Sparc.h | 8 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcRegisterInfo.td | 2 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcTargetMachine.cpp | 11 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcV8ISelSimple.cpp | 152 | ||||
-rw-r--r-- | lib/Target/SparcV8/InstSelectSimple.cpp | 152 | ||||
-rw-r--r-- | lib/Target/SparcV8/SparcV8.h | 8 | ||||
-rw-r--r-- | lib/Target/SparcV8/SparcV8ISelSimple.cpp | 152 | ||||
-rw-r--r-- | lib/Target/SparcV8/SparcV8RegisterInfo.td | 2 | ||||
-rw-r--r-- | lib/Target/SparcV8/SparcV8TargetMachine.cpp | 11 |
10 files changed, 636 insertions, 14 deletions
diff --git a/lib/Target/Sparc/InstSelectSimple.cpp b/lib/Target/Sparc/InstSelectSimple.cpp new file mode 100644 index 0000000..c195611 --- /dev/null +++ b/lib/Target/Sparc/InstSelectSimple.cpp @@ -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/Sparc/Sparc.h b/lib/Target/Sparc/Sparc.h index 2f93330..efe3d9f 100644 --- a/lib/Target/Sparc/Sparc.h +++ b/lib/Target/Sparc/Sparc.h @@ -19,12 +19,10 @@ 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/Sparc/SparcRegisterInfo.td b/lib/Target/Sparc/SparcRegisterInfo.td index f58d06a..84b4c31 100644 --- a/lib/Target/Sparc/SparcRegisterInfo.td +++ b/lib/Target/Sparc/SparcRegisterInfo.td @@ -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>; diff --git a/lib/Target/Sparc/SparcTargetMachine.cpp b/lib/Target/Sparc/SparcTargetMachine.cpp index 15401b1..f9a499d 100644 --- a/lib/Target/Sparc/SparcTargetMachine.cpp +++ b/lib/Target/Sparc/SparcTargetMachine.cpp @@ -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 index 0000000..c195611 --- /dev/null +++ b/lib/Target/Sparc/SparcV8ISelSimple.cpp @@ -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 index 0000000..c195611 --- /dev/null +++ b/lib/Target/SparcV8/InstSelectSimple.cpp @@ -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/SparcV8.h b/lib/Target/SparcV8/SparcV8.h index 2f93330..efe3d9f 100644 --- a/lib/Target/SparcV8/SparcV8.h +++ b/lib/Target/SparcV8/SparcV8.h @@ -19,12 +19,10 @@ 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 index 0000000..c195611 --- /dev/null +++ b/lib/Target/SparcV8/SparcV8ISelSimple.cpp @@ -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/SparcV8RegisterInfo.td b/lib/Target/SparcV8/SparcV8RegisterInfo.td index f58d06a..84b4c31 100644 --- a/lib/Target/SparcV8/SparcV8RegisterInfo.td +++ b/lib/Target/SparcV8/SparcV8RegisterInfo.td @@ -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>; diff --git a/lib/Target/SparcV8/SparcV8TargetMachine.cpp b/lib/Target/SparcV8/SparcV8TargetMachine.cpp index 15401b1..f9a499d 100644 --- a/lib/Target/SparcV8/SparcV8TargetMachine.cpp +++ b/lib/Target/SparcV8/SparcV8TargetMachine.cpp @@ -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; } |