1d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands//===-- TargetMachine.cpp -------------------------------------------------===//
2d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands//
3d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands//                     The LLVM Compiler Infrastructure
4d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands//
5d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands// This file is distributed under the University of Illinois Open Source
6d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands// License. See LICENSE.TXT for details.
7d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands//
8d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands//===----------------------------------------------------------------------===//
9d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands//
10d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands// This file implements the LLVM-C part of TargetMachine.h
11d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands//
12d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands//===----------------------------------------------------------------------===//
13d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm-c/TargetMachine.h"
15d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands#include "llvm-c/Core.h"
16d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands#include "llvm-c/Target.h"
170b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h"
180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h"
19d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands#include "llvm/PassManager.h"
20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/CodeGen.h"
21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/FormattedStream.h"
22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/TargetRegistry.h"
23d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/raw_ostream.h"
24d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetMachine.h"
25d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands#include <cassert>
26d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands#include <cstdlib>
27d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands#include <cstring>
28d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
29d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sandsusing namespace llvm;
30d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
31d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
32d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
33d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan SandsLLVMTargetRef LLVMGetFirstTarget() {
34d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands   const Target* target = &*TargetRegistry::begin();
35d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands   return wrap(target);
36d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands}
37d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan SandsLLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) {
38d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  return wrap(unwrap(T)->getNext());
39d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands}
40d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
41d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sandsconst char * LLVMGetTargetName(LLVMTargetRef T) {
42d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  return unwrap(T)->getName();
43d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands}
44d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
45d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sandsconst char * LLVMGetTargetDescription(LLVMTargetRef T) {
46d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  return unwrap(T)->getShortDescription();
47d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands}
48d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
49d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan SandsLLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {
50d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  return unwrap(T)->hasJIT();
51d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands}
52d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
53d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan SandsLLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {
54d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  return unwrap(T)->hasTargetMachine();
55d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands}
56d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
57d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan SandsLLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {
58d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  return unwrap(T)->hasMCAsmBackend();
59d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands}
60d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
61d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan SandsLLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T, char* Triple,
62d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  char* CPU, char* Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
63d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  LLVMCodeModel CodeModel) {
64d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  Reloc::Model RM;
65d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  switch (Reloc){
66d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    case LLVMRelocStatic:
67d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      RM = Reloc::Static;
68d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
69d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    case LLVMRelocPIC:
70d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      RM = Reloc::PIC_;
71d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
72d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    case LLVMRelocDynamicNoPic:
73d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      RM = Reloc::DynamicNoPIC;
74d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
75d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    default:
76d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      RM = Reloc::Default;
77d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
78d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  }
79d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
80d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  CodeModel::Model CM;
81d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  switch (CodeModel) {
82d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    case LLVMCodeModelJITDefault:
83d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      CM = CodeModel::JITDefault;
84d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
85d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    case LLVMCodeModelSmall:
86d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      CM = CodeModel::Small;
87d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
88d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    case LLVMCodeModelKernel:
89d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      CM = CodeModel::Kernel;
90d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
91d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    case LLVMCodeModelMedium:
92d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      CM = CodeModel::Medium;
93d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
94d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    case LLVMCodeModelLarge:
95d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      CM = CodeModel::Large;
96d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
97d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    default:
98d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      CM = CodeModel::Default;
99d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
100d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  }
101d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  CodeGenOpt::Level OL;
102d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
103d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  switch (Level) {
104d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    case LLVMCodeGenLevelNone:
105d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      OL = CodeGenOpt::None;
106d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
107d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    case LLVMCodeGenLevelLess:
108d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      OL = CodeGenOpt::Less;
109d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
110d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    case LLVMCodeGenLevelAggressive:
111d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      OL = CodeGenOpt::Aggressive;
112d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
113d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    default:
114d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      OL = CodeGenOpt::Default;
115d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
116d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  }
117d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
118d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  TargetOptions opt;
119d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM,
120d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    CM, OL));
121d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands}
122d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
123d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
124d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sandsvoid LLVMDisposeTargetMachine(LLVMTargetMachineRef T) {
125d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  delete unwrap(T);
126d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands}
127d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
128d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan SandsLLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {
129d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  const Target* target = &(unwrap(T)->getTarget());
130d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  return wrap(target);
131d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands}
132d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
133d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sandschar* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) {
134d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  std::string StringRep = unwrap(T)->getTargetTriple();
135d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  return strdup(StringRep.c_str());
136d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands}
137d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
138d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sandschar* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) {
139d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  std::string StringRep = unwrap(T)->getTargetCPU();
140d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  return strdup(StringRep.c_str());
141d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands}
142d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
143d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sandschar* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {
144d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  std::string StringRep = unwrap(T)->getTargetFeatureString();
145d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  return strdup(StringRep.c_str());
146d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands}
147d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
148d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan SandsLLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T) {
1493574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow  return wrap(unwrap(T)->getDataLayout());
150d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands}
151d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
152d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan SandsLLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
153d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) {
154d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  TargetMachine* TM = unwrap(T);
155d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  Module* Mod = unwrap(M);
156d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
157d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  PassManager pass;
158d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
159d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  std::string error;
160d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
1613574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow  const DataLayout* td = TM->getDataLayout();
162d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
163d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  if (!td) {
1643574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow    error = "No DataLayout in TargetMachine";
165d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    *ErrorMessage = strdup(error.c_str());
166d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    return true;
167d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  }
1683574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow  pass.add(new DataLayout(*td));
169d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
170d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  TargetMachine::CodeGenFileType ft;
171d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  switch (codegen) {
172d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    case LLVMAssemblyFile:
173d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      ft = TargetMachine::CGFT_AssemblyFile;
174d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
175d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    default:
176d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      ft = TargetMachine::CGFT_ObjectFile;
177d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands      break;
178d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  }
179d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  raw_fd_ostream dest(Filename, error, raw_fd_ostream::F_Binary);
180d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  formatted_raw_ostream destf(dest);
181d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  if (!error.empty()) {
182d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    *ErrorMessage = strdup(error.c_str());
183d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    return true;
184d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  }
185d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
186d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  if (TM->addPassesToEmitFile(pass, destf, ft)) {
187f3a64c00c189c1961a49aed9ce6f21e133bdde03Nick Lewycky    error = "TargetMachine can't emit a file of this type";
188d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    *ErrorMessage = strdup(error.c_str());
189d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands    return true;
190d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  }
191d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
192d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  pass.run(*Mod);
193d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands
194d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  destf.flush();
195d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  dest.flush();
196d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands  return false;
197d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42Duncan Sands}
198