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 /lib/Target/Sparc/InstSelectSimple.cpp | |
parent | da474adb2117ac1647348aa381a95c7b6e1fb524 (diff) |
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
Diffstat (limited to 'lib/Target/Sparc/InstSelectSimple.cpp')
-rw-r--r-- | lib/Target/Sparc/InstSelectSimple.cpp | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/lib/Target/Sparc/InstSelectSimple.cpp b/lib/Target/Sparc/InstSelectSimple.cpp new file mode 100644 index 0000000000..c195611618 --- /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!"); + } +} |