]>
git.proxmox.com Git - rustc.git/blob - src/llvm/lib/Target/Mips/MipsOs16.cpp
1 //===---- MipsOs16.cpp for Mips Option -Os16 --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines an optimization phase for the MIPS target.
12 //===----------------------------------------------------------------------===//
15 #include "llvm/IR/Module.h"
16 #include "llvm/Support/CommandLine.h"
17 #include "llvm/Support/Debug.h"
18 #include "llvm/Support/raw_ostream.h"
20 #define DEBUG_TYPE "mips-os16"
23 static cl::opt
<std::string
> Mips32FunctionMask(
24 "mips32-function-mask",
26 cl::desc("Force function to be mips32"),
31 // Figure out if we need float point based on the function signature.
32 // We need to move variables in and/or out of floating point
33 // registers because of the ABI
35 bool needsFPFromSig(Function
&F
) {
36 Type
* RetType
= F
.getReturnType();
37 switch (RetType
->getTypeID()) {
39 case Type::DoubleTyID
:
44 if (F
.arg_size() >=1) {
45 Argument
&Arg
= F
.getArgumentList().front();
46 switch (Arg
.getType()->getTypeID()) {
48 case Type::DoubleTyID
:
57 // Figure out if the function will need floating point operations
59 bool needsFP(Function
&F
) {
60 if (needsFPFromSig(F
))
62 for (Function::const_iterator BB
= F
.begin(), E
= F
.end(); BB
!= E
; ++BB
)
63 for (BasicBlock::const_iterator I
= BB
->begin(), E
= BB
->end();
65 const Instruction
&Inst
= *I
;
66 switch (Inst
.getOpcode()) {
67 case Instruction::FAdd
:
68 case Instruction::FSub
:
69 case Instruction::FMul
:
70 case Instruction::FDiv
:
71 case Instruction::FRem
:
72 case Instruction::FPToUI
:
73 case Instruction::FPToSI
:
74 case Instruction::UIToFP
:
75 case Instruction::SIToFP
:
76 case Instruction::FPTrunc
:
77 case Instruction::FPExt
:
78 case Instruction::FCmp
:
83 if (const CallInst
*CI
= dyn_cast
<CallInst
>(I
)) {
84 DEBUG(dbgs() << "Working on call" << "\n");
85 Function
&F_
= *CI
->getCalledFunction();
86 if (needsFPFromSig(F_
))
96 bool MipsOs16::runOnModule(Module
&M
) {
97 bool usingMask
= Mips32FunctionMask
.length() > 0;
98 bool doneUsingMask
= false; // this will make it stop repeating
99 DEBUG(dbgs() << "Run on Module MipsOs16 \n" << Mips32FunctionMask
<< "\n");
101 DEBUG(dbgs() << "using mask \n" << Mips32FunctionMask
<< "\n");
102 unsigned int functionIndex
= 0;
103 bool modified
= false;
104 for (Module::iterator F
= M
.begin(), E
= M
.end(); F
!= E
; ++F
) {
105 if (F
->isDeclaration()) continue;
106 DEBUG(dbgs() << "Working on " << F
->getName() << "\n");
108 if (!doneUsingMask
) {
109 if (functionIndex
== Mips32FunctionMask
.length())
111 switch (Mips32FunctionMask
[functionIndex
]) {
113 DEBUG(dbgs() << "mask forced mips32: " << F
->getName() << "\n");
114 F
->addFnAttr("nomips16");
117 doneUsingMask
= true;
127 DEBUG(dbgs() << "os16 forced mips32: " << F
->getName() << "\n");
128 F
->addFnAttr("nomips16");
131 DEBUG(dbgs() << "os16 forced mips16: " << F
->getName() << "\n");
132 F
->addFnAttr("mips16");
139 char MipsOs16::ID
= 0;
143 ModulePass
*llvm::createMipsOs16(MipsTargetMachine
&TM
) {