blob: 38eafff3d023a3f3b4b5cac4c82ca8231056a496 [file] [log] [blame]
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001/*
2 * Bitcode compiler (bcc) for Android:
3 * This is an eager-compilation JIT running on Android.
4 *
5 */
6
7#define LOG_TAG "bcc"
8#include <cutils/log.h>
9
10#include <ctype.h>
11#include <errno.h>
12#include <limits.h>
13#include <stdarg.h>
14#include <stdint.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <unistd.h>
19
20#include <cutils/hashmap.h>
21
22#if defined(__i386__)
23#include <sys/mman.h>
24#endif
25
26#if defined(__arm__)
27 #define DEFAULT_ARM_CODEGEN
28 #define PROVIDE_ARM_CODEGEN
29#elif defined(__i386__)
30 #define DEFAULT_X86_CODEGEN
31 #define PROVIDE_X86_CODEGEN
32#elif defined(__x86_64__)
33 #define DEFAULT_X64_CODEGEN
34 #define PROVIDE_X64_CODEGEN
35#endif
36
37#if defined(FORCE_ARM_CODEGEN)
38 #define DEFAULT_ARM_CODEGEN
39 #undef DEFAULT_X86_CODEGEN
40 #undef DEFAULT_X64_CODEGEN
41 #define PROVIDE_ARM_CODEGEN
42 #undef PROVIDE_X86_CODEGEN
43 #undef PROVIDE_X64_CODEGEN
44#elif defined(FORCE_X86_CODEGEN)
45 #undef DEFAULT_ARM_CODEGEN
46 #define DEFAULT_X86_CODEGEN
47 #undef DEFAULT_X64_CODEGEN
48 #undef PROVIDE_ARM_CODEGEN
49 #define PROVIDE_X86_CODEGEN
50 #undef PROVIDE_X64_CODEGEN
51#elif defined(FORCE_X64_CODEGEN)
52 #undef DEFAULT_ARM_CODEGEN
53 #undef DEFAULT_X86_CODEGEN
54 #define DEFAULT_X64_CODEGEN
55 #undef PROVIDE_ARM_CODEGEN
56 #undef PROVIDE_X86_CODEGEN
57 #define PROVIDE_X64_CODEGEN
58#endif
59
60#if defined(DEFAULT_ARM_CODEGEN)
61 #define TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
62#elif defined(DEFAULT_X86_CODEGEN)
63 #define TARGET_TRIPLE_STRING "i686-unknown-linux"
64#elif defined(DEFAULT_X64_CODEGEN)
65 #define TARGET_TRIPLE_STRING "x86_64-unknown-linux"
66#endif
67
68#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
69#define ARM_USE_VFP
70#endif
71
72#include <bcc/bcc.h>
73#include "bcc_runtime.h"
74
75#define LOG_API(...) do {} while(0)
76// #define LOG_API(...) fprintf (stderr, __VA_ARGS__)
77
78#define LOG_STACK(...) do {} while(0)
79// #define LOG_STACK(...) fprintf (stderr, __VA_ARGS__)
80
81// #define PROVIDE_TRACE_CODEGEN
82
83#if defined(USE_DISASSEMBLER)
Shih-wei Liaocd61af32010-04-29 00:02:57 -070084# include "llvm/MC/MCInst.h" /* for class llvm::MCInst */
85# include "llvm/MC/MCAsmInfo.h" /* for class llvm::MCAsmInfo */
86# include "llvm/MC/MCInstPrinter.h" /* for class llvm::MCInstPrinter */
87# include "llvm/MC/MCDisassembler.h" /* for class llvm::MCDisassembler */
Shih-wei Liao3cf39d12010-04-29 19:30:51 -070088// If you want the disassemble results written to file, define this:
89# define USE_DISASSEMBLER_FILE
Shih-wei Liao77ed6142010-04-07 12:21:42 -070090#endif
91
92#include <set>
93#include <map>
94#include <list>
95#include <cmath>
96#include <string>
97#include <cstring>
98#include <algorithm> /* for std::reverse */
99
100// Basic
101#include "llvm/Use.h" /* for class llvm::Use */
102#include "llvm/User.h" /* for class llvm::User */
103#include "llvm/Module.h" /* for class llvm::Module */
104#include "llvm/Function.h" /* for class llvm::Function */
105#include "llvm/Constant.h" /* for class llvm::Constant */
106#include "llvm/Constants.h" /* for class llvm::ConstantExpr */
107#include "llvm/Instruction.h" /* for class llvm::Instruction */
108#include "llvm/PassManager.h" /* for class llvm::PassManager and
109 * llvm::FunctionPassManager
110 */
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700111#include "llvm/LLVMContext.h" /* for class llvm::LLVMContext */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700112#include "llvm/GlobalValue.h" /* for class llvm::GlobalValue */
113#include "llvm/Instructions.h" /* for class llvm::CallInst */
114#include "llvm/OperandTraits.h" /* for macro
115 * DECLARE_TRANSPARENT_OPERAND_ACCESSORS
116 * and macro
117 * DEFINE_TRANSPARENT_OPERAND_ACCESSORS
118 */
119#include "llvm/TypeSymbolTable.h" /* for Type Reflection */
120
121// System
122#include "llvm/System/Host.h" /* for function
123 * llvm::sys::isLittleEndianHost()
124 */
125#include "llvm/System/Memory.h" /* for class llvm::sys::MemoryBlock */
126
127// ADT
128#include "llvm/ADT/APInt.h" /* for class llvm::APInt */
129#include "llvm/ADT/APFloat.h" /* for class llvm::APFloat */
130#include "llvm/ADT/DenseMap.h" /* for class llvm::DenseMap */
131#include "llvm/ADT/ValueMap.h" /* for class llvm::ValueMap and
132 * class llvm::ValueMapConfig
133 */
134#include "llvm/ADT/StringMap.h" /* for class llvm::StringMap */
135#include "llvm/ADT/OwningPtr.h" /* for class llvm::OwningPtr */
136#include "llvm/ADT/SmallString.h" /* for class llvm::SmallString */
137
138// Target
139#include "llvm/Target/TargetData.h" /* for class llvm::TargetData */
140#include "llvm/Target/TargetSelect.h" /* for function
141 * LLVMInitialize[ARM|X86]
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700142 * [TargetInfo|Target|Disassembler|
143 * AsmPrinter]()
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700144 */
145#include "llvm/Target/TargetOptions.h" /* for
146 * variable bool llvm::UseSoftFloat
147 * FloatABI::ABIType llvm::FloatABIType
148 * bool llvm::NoZerosInBSS
149 */
150#include "llvm/Target/TargetMachine.h" /* for class llvm::TargetMachine and
151 * llvm::TargetMachine::AssemblyFile
152 */
153#include "llvm/Target/TargetJITInfo.h" /* for class llvm::TargetJITInfo */
154#include "llvm/Target/TargetRegistry.h" /* for class llvm::TargetRegistry */
155#include "llvm/Target/SubtargetFeature.h"
156 /* for class llvm::SubtargetFeature */
157
158// Support
159#include "llvm/Support/Casting.h" /* for class cast<> */
160#include "llvm/Support/raw_ostream.h" /* for class llvm::raw_ostream and
161 * llvm::raw_string_ostream
162 */
163#include "llvm/Support/ValueHandle.h" /* for class AssertingVH<> */
164#include "llvm/Support/MemoryBuffer.h" /* for class llvm::MemoryBuffer */
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700165#include "llvm/Support/MemoryObject.h" /* for class llvm::MemoryObject */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700166#include "llvm/Support/ManagedStatic.h" /* for class llvm::llvm_shutdown */
167#include "llvm/Support/ErrorHandling.h" /* for function
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700168 * llvm::remove_fatal_error_handler()
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700169 * llvm::install_fatal_error_handler()
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700170 * and macro llvm_unreachable()
171 */
172#include "llvm/Support/StandardPasses.h"/* for function
173 * llvm::createStandardFunctionPasses()
174 * and
175 * llvm::createStandardModulePasses()
176 */
177#include "llvm/Support/FormattedStream.h"
178 /* for
179 * class llvm::formatted_raw_ostream
180 * llvm::formatted_raw_ostream::
181 * PRESERVE_STREAM
182 * llvm::FileModel::Error
183 */
184
185// Bitcode
186#include "llvm/Bitcode/ReaderWriter.h" /* for function
187 * llvm::ParseBitcodeFile()
188 */
189
190// CodeGen
191#include "llvm/CodeGen/Passes.h" /* for
192 * llvm::createLocalRegisterAllocator()
193 * and
194 * llvm::
195 * createLinearScanRegisterAllocator()
196 */
197#include "llvm/CodeGen/JITCodeEmitter.h"/* for class llvm::JITCodeEmitter */
198#include "llvm/CodeGen/MachineFunction.h"
199 /* for class llvm::MachineFunction */
200#include "llvm/CodeGen/RegAllocRegistry.h"
201 /* for class llvm::RegisterRegAlloc */
202#include "llvm/CodeGen/SchedulerRegistry.h"
203 /* for class llvm::RegisterScheduler
204 * and llvm::createDefaultScheduler()
205 */
206#include "llvm/CodeGen/MachineRelocation.h"
207 /* for class llvm::MachineRelocation */
208#include "llvm/CodeGen/MachineModuleInfo.h"
209 /* for class llvm::MachineModuleInfo */
210#include "llvm/CodeGen/MachineCodeEmitter.h"
211 /* for class llvm::MachineCodeEmitter */
212#include "llvm/CodeGen/MachineConstantPool.h"
213 /* for class llvm::MachineConstantPool
214 */
215#include "llvm/CodeGen/MachineJumpTableInfo.h"
216 /* for class llvm::MachineJumpTableInfo
217 */
218
219// ExecutionEngine
220#include "llvm/ExecutionEngine/GenericValue.h"
221 /* for struct llvm::GenericValue */
222#include "llvm/ExecutionEngine/JITMemoryManager.h"
223 /* for class llvm::JITMemoryManager */
224
225
226/*
227 * Compilation class that suits Android's needs.
228 * (Support: no argument passed, ...)
229 */
230
231namespace bcc {
232
233class Compiler {
234 /*
235 * This part is designed to be orthogonal to those exported bcc*() functions
236 * implementation and internal struct BCCscript.
237 */
238
239
240 /*********************************************
241 * The variable section below (e.g., Triple, CodeGenOptLevel)
242 * is initialized in GlobalInitialization()
243 */
244 static bool GlobalInitialized;
245
246 /*
247 * If given, this will be the name of the target triple to compile for.
248 * If not given, the initial values defined in this file will be used.
249 */
250 static std::string Triple;
251
252 static llvm::CodeGenOpt::Level CodeGenOptLevel;
253 /*
254 * End of section of GlobalInitializing variables
255 **********************************************/
256
257 /* If given, the name of the target CPU to generate code for. */
258 static std::string CPU;
259
260 /*
261 * The list of target specific features to enable or disable -- this should
262 * be a list of strings starting with '+' (enable) or '-' (disable).
263 */
264 static std::vector<std::string> Features;
265
266 struct Runtime {
267 const char* mName;
268 void* mPtr;
269 };
270 static struct Runtime Runtimes[];
271
272 static void GlobalInitialization() {
273 if(GlobalInitialized) return;
Shih-wei Liaobe5c5312010-05-09 05:30:09 -0700274
Shih-wei Liaobe5c5312010-05-09 05:30:09 -0700275 // if (!llvm::llvm_is_multithreaded())
276 // llvm::llvm_start_multithreaded();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700277
278 /* Set Triple, CPU and Features here */
279 Triple = TARGET_TRIPLE_STRING;
280
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700281 /* TODO: NEON for JIT */
282 //Features.push_back("+neon");
283 //Features.push_back("+vmlx");
284 //Features.push_back("+neonfp");
Shih-wei Liao3cf39d12010-04-29 19:30:51 -0700285 Features.push_back("+vfp3");
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700286
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700287#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
288 LLVMInitializeARMTargetInfo();
289 LLVMInitializeARMTarget();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700290#if defined(USE_DISASSEMBLER)
291 LLVMInitializeARMDisassembler();
292 LLVMInitializeARMAsmPrinter();
293#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700294#endif
295
296#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN)
297 LLVMInitializeX86TargetInfo();
298 LLVMInitializeX86Target();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700299#if defined(USE_DISASSEMBLER)
300 LLVMInitializeX86Disassembler();
301 LLVMInitializeX86AsmPrinter();
302#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700303#endif
304
305#if defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
306 LLVMInitializeX86TargetInfo();
307 LLVMInitializeX86Target();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700308#if defined(USE_DISASSEMBLER)
309 LLVMInitializeX86Disassembler();
310 LLVMInitializeX86AsmPrinter();
311#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700312#endif
313
314 /*
315 * -O0: llvm::CodeGenOpt::None
316 * -O1: llvm::CodeGenOpt::Less
317 * -O2: llvm::CodeGenOpt::Default
318 * -O3: llvm::CodeGenOpt::Aggressive
319 */
320 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
321
322 /* Below are the global settings to LLVM */
323
324 /* Disable frame pointer elimination optimization */
325 llvm::NoFramePointerElim = false;
326
327 /*
328 * Use hardfloat ABI
329 *
330 * FIXME: Need to detect the CPU capability and decide whether to use
331 * softfp. To use softfp, change following 2 lines to
332 *
333 * llvm::FloatABIType = llvm::FloatABI::Soft;
334 * llvm::UseSoftFloat = true;
335 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700336 llvm::FloatABIType = llvm::FloatABI::Soft;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700337 llvm::UseSoftFloat = false;
338
339 /*
340 * BCC needs all unknown symbols resolved at JIT/compilation time.
341 * So we don't need any dynamic relocation model.
342 */
343 llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static);
344
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700345#if defined(DEFAULT_X64_CODEGEN)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700346 /* Data address in X86_64 architecture may reside in a far-away place */
347 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
348#else
349 /*
350 * This is set for the linker (specify how large of the virtual addresses
351 * we can access for all unknown symbols.)
352 */
353 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
354#endif
355
356 /* Register the scheduler */
357 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
358
359 /*
360 * Register allocation policy:
361 * createLocalRegisterAllocator: fast but bad quality
362 * createLinearScanRegisterAllocator: not so fast but good quality
363 */
364 llvm::RegisterRegAlloc::setDefault
365 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
366 llvm::createLocalRegisterAllocator :
367 llvm::createLinearScanRegisterAllocator);
368
369 GlobalInitialized = true;
370 return;
371 }
372
373 static void LLVMErrorHandler(void *UserData, const std::string &Message) {
Shih-wei Liao066d5ef2010-05-11 03:28:39 -0700374 std::string* Error = static_cast<std::string*>(UserData);
375 Error->assign(Message);
376 LOGE(Message.c_str());
377 return;
378 //fprintf(stderr, "%s\n", Message.c_str());
379 //exit(1);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700380 }
381
382 static const llvm::StringRef PragmaMetadataName;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700383 static const llvm::StringRef ExportVarMetadataName;
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700384 static const llvm::StringRef ExportFuncMetadataName;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700385
386 private:
Shih-wei Liaoc5611992010-05-09 06:37:55 -0700387 std::string mError;
388
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700389 inline bool hasError() const {
390 return !mError.empty();
391 }
392 inline void setError(const char* Error) {
393 mError.assign(Error); // Copying
394 return;
395 }
396 inline void setError(const std::string& Error) {
397 mError = Error;
398 return;
399 }
400
401 typedef std::list< std::pair<std::string, std::string> > PragmaList;
402 PragmaList mPragmas;
403
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700404 typedef std::list<void*> ExportVarList;
405 ExportVarList mExportVars;
406
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700407 typedef std::list<void*> ExportFuncList;
408 ExportFuncList mExportFuncs;
409
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700410 /* Memory manager for the code reside in memory */
411 /*
412 * The memory for our code emitter is very simple and is conforming to the
413 * design decisions of Android RenderScript's Exection Environment:
414 * The code, data, and symbol sizes are limited (currently 100KB.)
415 *
416 * It's very different from typical compiler, which has no limitation
417 * on the code size. How does code emitter know the size of the code
418 * it is about to emit? It does not know beforehand. We want to solve
419 * this without complicating the code emitter too much.
420 *
421 * We solve this by pre-allocating a certain amount of memory,
422 * and then start the code emission. Once the buffer overflows, the emitter
423 * simply discards all the subsequent emission but still has a counter
424 * on how many bytes have been emitted.
425
426 * So once the whole emission is done, if there's a buffer overflow,
427 * it re-allocates the buffer with enough size (based on the
428 * counter from previous emission) and re-emit again.
429 */
430 class CodeMemoryManager : public llvm::JITMemoryManager {
431 /* {{{ */
432 private:
433 static const unsigned int MaxCodeSize = 100 * 1024; /* 100 KiB for code */
434 static const unsigned int MaxGOTSize = 1 * 1024; /* 1 KiB for global
435 offset table (GOT) */
436
437 /*
438 * Our memory layout is as follows:
439 *
440 * The direction of arrows (-> and <-) shows memory's growth direction
441 * when more space is needed.
442 *
443 * @mpCodeMem:
444 * +--------------------------------------------------------------+
445 * | Function Memory ... -> <- ... Global/Stub/GOT |
446 * +--------------------------------------------------------------+
447 * |<------------------ Total: @MaxCodeSize KiB ----------------->|
448 *
449 * Where size of GOT is @MaxGOTSize KiB.
450 *
451 * @mCurFuncMemIdx: The current index (starting from 0) of the last byte
452 * of function code's memoey usage
453 * @mCurGSGMemIdx: The current index (starting from 0) of the last byte
454 * of Global Stub/GOT's memory usage
455 *
456 */
457
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700458 uintptr_t mCurFuncMemIdx;
459 uintptr_t mCurGSGMemIdx;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700460 llvm::sys::MemoryBlock* mpCodeMem;
461
462 /* GOT Base */
463 uint8_t* mpGOTBase;
464
465 typedef std::map<const llvm::Function*, pair<void* /* start address */,
466 void* /* end address */>
467 > FunctionMapTy;
468 FunctionMapTy mFunctionMap;
469
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700470 inline uintptr_t getFreeMemSize() const {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700471 return mCurGSGMemIdx - mCurFuncMemIdx;
472 }
473 inline uint8_t* getCodeMemBase() const {
474 return static_cast<uint8_t*>(mpCodeMem->base());
475 }
476
477 uint8_t* allocateGSGMemory(uintptr_t Size,
478 unsigned Alignment = 1 /* no alignment */)
479 {
480 if(getFreeMemSize() < Size)
481 /* The code size excesses our limit */
482 return NULL;
483
484 if(Alignment == 0)
485 Alignment = 1;
486
487 uint8_t* result = getCodeMemBase() + mCurGSGMemIdx - Size;
488 result = (uint8_t*) (((intptr_t) result) & ~(intptr_t) (Alignment - 1));
489
490 mCurGSGMemIdx = result - getCodeMemBase();
491
492 return result;
493 }
494
495 public:
496 CodeMemoryManager() : mpCodeMem(NULL), mpGOTBase(NULL) {
497 reset();
498 std::string ErrMsg;
499 llvm::sys::MemoryBlock B = llvm::sys::Memory::
500 AllocateRWX(MaxCodeSize, NULL, &ErrMsg);
501 if(B.base() == 0)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700502 llvm::report_fatal_error(
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700503 "Failed to allocate Memory for code emitter\n" + ErrMsg
504 );
505 mpCodeMem = new llvm::sys::MemoryBlock(B.base(), B.size());
506
507 return;
508 }
509
510 /*
511 * setMemoryWritable - When code generation is in progress,
512 * the code pages may need permissions changed.
513 */
514 void setMemoryWritable() {
515 llvm::sys::Memory::setWritable(*mpCodeMem);
516 return;
517 }
518
519 /*
520 * setMemoryExecutable - When code generation is done and we're ready to
521 * start execution, the code pages may need permissions changed.
522 */
523 void setMemoryExecutable() {
524 llvm::sys::Memory::setExecutable(*mpCodeMem);
525 return;
526 }
527
528 /*
529 * setPoisonMemory - Setting this flag to true makes the memory manager
530 * garbage values over freed memory. This is useful for testing and
531 * debugging, and is to be turned on by default in debug mode.
532 */
533 void setPoisonMemory(bool poison) {
534 /* no effect */
535 return;
536 }
537
538 /* Global Offset Table Management */
539
540 /*
541 * AllocateGOT - If the current table requires a Global Offset Table, this
542 * method is invoked to allocate it. This method is required to set HasGOT
543 * to true.
544 */
545 void AllocateGOT() {
546 assert(mpGOTBase != NULL && "Cannot allocate the GOT multiple times");
547 mpGOTBase = allocateGSGMemory(MaxGOTSize);
548 HasGOT = true;
549 return;
550 }
551
552 /*
553 * getGOTBase - If this is managing a Global Offset Table, this method
554 * should return a pointer to its base.
555 */
556 uint8_t* getGOTBase() const {
557 return mpGOTBase;
558 }
559
560 /* Main Allocation Functions */
561
562 /*
563 * startFunctionBody - When we start JITing a function, the JIT calls this
564 * method to allocate a block of free RWX memory, which returns a pointer to
565 * it. If the JIT wants to request a block of memory of at least a certain
566 * size, it passes that value as ActualSize, and this method returns a block
567 * with at least that much space. If the JIT doesn't know ahead of time how
568 * much space it will need to emit the function, it passes 0 for the
569 * ActualSize. In either case, this method is required to pass back the size
570 * of the allocated block through ActualSize. The JIT will be careful to
571 * not write more than the returned ActualSize bytes of memory.
572 */
573 uint8_t* startFunctionBody(const llvm::Function *F, uintptr_t &ActualSize) {
574 if(getFreeMemSize() < ActualSize)
575 /* The code size excesses our limit */
576 return NULL;
577
578 ActualSize = getFreeMemSize();
579 return (getCodeMemBase() + mCurFuncMemIdx);
580 }
581
582 /*
583 * allocateStub - This method is called by the JIT to allocate space for a
584 * function stub (used to handle limited branch displacements) while it is
585 * JIT compiling a function. For example, if foo calls bar, and if bar
586 * either needs to be lazily compiled or is a native function that exists
587 * too
588 * far away from the call site to work, this method will be used to make a
589 * thunk for it. The stub should be "close" to the current function body,
590 * but should not be included in the 'actualsize' returned by
591 * startFunctionBody.
592 */
593 uint8_t* allocateStub(const llvm::GlobalValue* F, unsigned StubSize,
594 unsigned Alignment) {
595 return allocateGSGMemory(StubSize, Alignment);
596 }
597
598 /*
599 * endFunctionBody - This method is called when the JIT is done codegen'ing
600 * the specified function. At this point we know the size of the JIT
601 * compiled function. This passes in FunctionStart (which was returned by
602 * the startFunctionBody method) and FunctionEnd which is a pointer to the
603 * actual end of the function. This method should mark the space allocated
604 * and remember where it is in case the client wants to deallocate it.
605 */
606 void endFunctionBody(const llvm::Function* F, uint8_t* FunctionStart,
607 uint8_t* FunctionEnd) {
608 assert(FunctionEnd > FunctionStart);
609 assert(FunctionStart == (getCodeMemBase() + mCurFuncMemIdx) &&
610 "Mismatched function start/end!");
611
612 /* Advance the pointer */
613 intptr_t FunctionCodeSize = FunctionEnd - FunctionStart;
614 assert(FunctionCodeSize <= getFreeMemSize() &&
615 "Code size excess the limitation!");
616 mCurFuncMemIdx += FunctionCodeSize;
617
618 /* Record there's a function in our memory start from @FunctionStart */
619 assert(mFunctionMap.find(F) == mFunctionMap.end() &&
620 "Function already emitted!");
621 mFunctionMap.insert( make_pair<const llvm::Function*, pair<void*, void*>
622 >(F, make_pair(FunctionStart, FunctionEnd))
623 );
624
625 return;
626 }
627
628 /*
629 * allocateSpace - Allocate a (function code) memory block of the
630 * given size. This method cannot be called between
631 * calls to startFunctionBody and endFunctionBody.
632 */
633 uint8_t* allocateSpace(intptr_t Size, unsigned Alignment) {
634 if(getFreeMemSize() < Size)
635 /* The code size excesses our limit */
636 return NULL;
637
638 if(Alignment == 0)
639 Alignment = 1;
640
641 uint8_t* result = getCodeMemBase() + mCurFuncMemIdx;
642 result = (uint8_t*) (((intptr_t) result + Alignment - 1) &
643 ~(intptr_t) (Alignment - 1)
644 );
645
646 mCurFuncMemIdx = (result + Size) - getCodeMemBase();
647
648 return result;
649 }
650
651 /* allocateGlobal - Allocate memory for a global. */
652 uint8_t* allocateGlobal(uintptr_t Size, unsigned Alignment) {
653 return allocateGSGMemory(Size, Alignment);
654 }
655
656 /*
657 * deallocateFunctionBody - Free the specified function body. The argument
658 * must be the return value from a call to startFunctionBody() that hasn't
659 * been deallocated yet. This is never called when the JIT is currently
660 * emitting a function.
661 */
662 void deallocateFunctionBody(void *Body) {
663 /* linear search */
664 FunctionMapTy::iterator I;
665 for(I = mFunctionMap.begin();
666 I != mFunctionMap.end();
667 I++)
668 if(I->second.first == Body)
669 break;
670
671 assert(I != mFunctionMap.end() && "Memory is never allocated!");
672
673 /* free the memory */
674 uint8_t* FunctionStart = (uint8_t*) I->second.first;
675 uint8_t* FunctionEnd = (uint8_t*) I->second.second;
676 intptr_t SizeNeedMove = (getCodeMemBase() + mCurFuncMemIdx) - FunctionEnd;
677
678 assert(SizeNeedMove >= 0 &&
679 "Internal error: CodeMemoryManager::mCurFuncMemIdx may not"
680 " be correctly calculated!");
681
682 if(SizeNeedMove > 0)
683 /* there's data behind deallocating function */
684 ::memmove(FunctionStart, FunctionEnd, SizeNeedMove);
685 mCurFuncMemIdx -= (FunctionEnd - FunctionStart);
686
687 return;
688 }
689
690 /*
691 * startExceptionTable - When we finished JITing the function, if exception
692 * handling is set, we emit the exception table.
693 */
694 uint8_t* startExceptionTable(const llvm::Function* F, uintptr_t &ActualSize)
695 {
696 assert(false && "Exception is not allowed in our language specification");
697 return NULL;
698 }
699
700 /*
701 * endExceptionTable - This method is called when the JIT is done emitting
702 * the exception table.
703 */
704 void endExceptionTable(const llvm::Function *F, uint8_t *TableStart,
705 uint8_t *TableEnd, uint8_t* FrameRegister) {
706 assert(false && "Exception is not allowed in our language specification");
707 return;
708 }
709
710 /*
711 * deallocateExceptionTable - Free the specified exception table's memory.
712 * The argument must be the return value from a call to
713 * startExceptionTable()
714 * that hasn't been deallocated yet. This is never called when the JIT is
715 * currently emitting an exception table.
716 */
717 void deallocateExceptionTable(void *ET) {
718 assert(false && "Exception is not allowed in our language specification");
719 return;
720 }
721
722 /* Below are the methods we create */
723 void reset() {
724 mpGOTBase = NULL;
725 HasGOT = false;
726
727 mCurFuncMemIdx = 0;
728 mCurGSGMemIdx = MaxCodeSize - 1;
729
730 mFunctionMap.clear();
731
732 return;
733 }
734
735 ~CodeMemoryManager() {
736 if(mpCodeMem != NULL)
737 llvm::sys::Memory::ReleaseRWX(*mpCodeMem);
738 return;
739 }
740 /* }}} */
741 }; /* End of class CodeMemoryManager */
742
743 /* The memory manager for code emitter */
744 llvm::OwningPtr<CodeMemoryManager> mCodeMemMgr;
745 CodeMemoryManager* createCodeMemoryManager() {
746 mCodeMemMgr.reset(new CodeMemoryManager());
747 return mCodeMemMgr.get();
748 }
749
750 /* Code emitter */
751 class CodeEmitter : public llvm::JITCodeEmitter {
752 /* {{{ */
753 public:
754 typedef llvm::DenseMap<const llvm::GlobalValue*, void*> GlobalAddressMapTy;
755 typedef GlobalAddressMapTy::const_iterator global_addresses_const_iterator;
756
757 private:
758 CodeMemoryManager* mpMemMgr;
759
760 /* The JITInfo for the target we are compiling to */
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700761 const llvm::Target* mpTarget;
762
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700763 llvm::TargetJITInfo* mpTJI;
764
765 const llvm::TargetData* mpTD;
766
767 /*
768 * MBBLocations - This vector is a mapping from MBB ID's to their address.
769 * It is filled in by the StartMachineBasicBlock callback and queried by
770 * the getMachineBasicBlockAddress callback.
771 */
772 std::vector<uintptr_t> mMBBLocations;
773
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700774 /* mpConstantPool - The constant pool for the current function. */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700775 llvm::MachineConstantPool* mpConstantPool;
776
777 /* ConstantPoolBase - A pointer to the first entry in the constant pool. */
778 void *mpConstantPoolBase;
779
780 /* ConstPoolAddresses - Addresses of individual constant pool entries. */
781 llvm::SmallVector<uintptr_t, 8> mConstPoolAddresses;
782
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700783 /* mpJumpTable - The jump tables for the current function. */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700784 llvm::MachineJumpTableInfo *mpJumpTable;
785
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700786 /* mpJumpTableBase - A pointer to the first entry in the jump table. */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700787 void *mpJumpTableBase;
788
789 /*
790 * When outputting a function stub in the context of some other function, we
791 * save BufferBegin/BufferEnd/CurBufferPtr here.
792 */
793 uint8_t *mpSavedBufferBegin, *mpSavedBufferEnd, *mpSavedCurBufferPtr;
794
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700795 /* mRelocations - These are the relocations that the function needs,
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700796 as emitted. */
797 std::vector<llvm::MachineRelocation> mRelocations;
798
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700799 /* mLabelLocations - This vector is a mapping from Label ID's to their
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700800 address. */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700801 llvm::DenseMap<llvm::MCSymbol*, uintptr_t> mLabelLocations;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700802
803 class EmittedFunctionCode {
804 public:
805 void* FunctionBody; // Beginning of the function's allocation.
806 void* Code; // The address the function's code actually starts at.
807 int Size; // The size of the function code
808
809 EmittedFunctionCode() : FunctionBody(NULL), Code(NULL) { return; }
810 };
811 EmittedFunctionCode* mpCurEmitFunction;
812
813 typedef std::map<const std::string, EmittedFunctionCode*
814 > EmittedFunctionsMapTy;
815 EmittedFunctionsMapTy mEmittedFunctions;
816
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700817 /* mpMMI - Machine module info for exception informations */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700818 llvm::MachineModuleInfo* mpMMI;
819
820 GlobalAddressMapTy mGlobalAddressMap;
821
822 /*
823 * UpdateGlobalMapping - Replace an existing mapping for GV with a new
824 * address. This updates both maps as required. If "Addr" is null, the
825 * entry for the global is removed from the mappings.
826 */
827 void* UpdateGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
828 if(Addr == NULL) {
829 /* Removing mapping */
830 GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
831 void *OldVal;
832
833 if(I == mGlobalAddressMap.end())
834 OldVal = NULL;
835 else {
836 OldVal = I->second;
837 mGlobalAddressMap.erase(I);
838 }
839
840 return OldVal;
841 }
842
843 void*& CurVal = mGlobalAddressMap[GV];
844 void* OldVal = CurVal;
845
846 CurVal = Addr;
847
848 return OldVal;
849 }
850
851 /*
852 * AddGlobalMapping - Tell the execution engine that the specified global is
853 * at the specified location. This is used internally as functions are
854 * JIT'd
855 * and as global variables are laid out in memory.
856 */
857 void AddGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
858 void*& CurVal = mGlobalAddressMap[GV];
859 assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!");
860 CurVal = Addr;
861 return;
862 }
863
864 /*
865 * GetPointerToGlobalIfAvailable - This returns the address of the specified
866 * global value if it is has already been codegen'd,
867 * otherwise it returns null.
868 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700869 void* GetPointerToGlobalIfAvailable(const llvm::GlobalValue* GV) {
870 GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700871 return ((I != mGlobalAddressMap.end()) ? I->second : NULL);
872 }
873
874 unsigned int GetConstantPoolSizeInBytes(llvm::MachineConstantPool* MCP) {
875 const std::vector<llvm::MachineConstantPoolEntry>& Constants =
876 MCP->getConstants();
877
878 if(Constants.empty())
879 return 0;
880
881 unsigned int Size = 0;
882 for(int i=0;i<Constants.size();i++) {
883 llvm::MachineConstantPoolEntry CPE = Constants[i];
884 unsigned int AlignMask = CPE.getAlignment() - 1;
885 Size = (Size + AlignMask) & ~AlignMask;
886 const llvm::Type* Ty = CPE.getType();
887 Size += mpTD->getTypeAllocSize(Ty);
888 }
889
890 return Size;
891 }
892
893 /*
894 * This function converts a Constant* into a GenericValue. The interesting
895 * part is if C is a ConstantExpr.
896 */
897 void GetConstantValue(const llvm::Constant *C, llvm::GenericValue& Result) {
898 if(C->getValueID() == llvm::Value::UndefValueVal)
899 return;
900 else if(C->getValueID() == llvm::Value::ConstantExprVal) {
901 const llvm::ConstantExpr* CE = (llvm::ConstantExpr*) C;
902 const llvm::Constant* Op0 = CE->getOperand(0);
903
904 switch(CE->getOpcode()) {
905 case llvm::Instruction::GetElementPtr:
906 {
907 /* Compute the index */
908 llvm::SmallVector<llvm::Value*, 8> Indices(CE->op_begin() + 1,
909 CE->op_end());
910 uint64_t Offset = mpTD->getIndexedOffset(Op0->getType(),
911 &Indices[0],
912 Indices.size());
913
914 GetConstantValue(Op0, Result);
915 Result.PointerVal = (char*) Result.PointerVal + Offset;
916
917 return;
918 }
919 break;
920
921 case llvm::Instruction::Trunc:
922 {
923 uint32_t BitWidth =
924 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
925
926 GetConstantValue(Op0, Result);
927 Result.IntVal = Result.IntVal.trunc(BitWidth);
928
929 return;
930 }
931 break;
932
933 case llvm::Instruction::ZExt:
934 {
935 uint32_t BitWidth =
936 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
937
938 GetConstantValue(Op0, Result);
939 Result.IntVal = Result.IntVal.zext(BitWidth);
940
941 return;
942 }
943 break;
944
945 case llvm::Instruction::SExt:
946 {
947 uint32_t BitWidth =
948 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
949
950 GetConstantValue(Op0, Result);
951 Result.IntVal = Result.IntVal.sext(BitWidth);
952
953 return;
954 }
955 break;
956
957
958 case llvm::Instruction::FPTrunc:
959 {
960 /* FIXME long double */
961 GetConstantValue(Op0, Result);
962 Result.FloatVal = float(Result.DoubleVal);
963 return;
964 }
965 break;
966
967
968 case llvm::Instruction::FPExt:
969 {
970 /* FIXME long double */
971 GetConstantValue(Op0, Result);
972 Result.DoubleVal = double(Result.FloatVal);
973 return;
974 }
975 break;
976
977
978 case llvm::Instruction::UIToFP:
979 {
980 GetConstantValue(Op0, Result);
981 if(CE->getType()->isFloatTy())
982 Result.FloatVal = float(Result.IntVal.roundToDouble());
983 else if(CE->getType()->isDoubleTy())
984 Result.DoubleVal = Result.IntVal.roundToDouble();
985 else if(CE->getType()->isX86_FP80Ty()) {
986 const uint64_t zero[] = { 0, 0 };
987 llvm::APFloat apf = llvm::APFloat(llvm::APInt(80, 2, zero));
988 apf.convertFromAPInt(Result.IntVal,
989 false,
990 llvm::APFloat::rmNearestTiesToEven);
991 Result.IntVal = apf.bitcastToAPInt();
992 }
993 return;
994 }
995 break;
996
997 case llvm::Instruction::SIToFP:
998 {
999 GetConstantValue(Op0, Result);
1000 if(CE->getType()->isFloatTy())
1001 Result.FloatVal = float(Result.IntVal.signedRoundToDouble());
1002 else if(CE->getType()->isDoubleTy())
1003 Result.DoubleVal = Result.IntVal.signedRoundToDouble();
1004 else if(CE->getType()->isX86_FP80Ty()) {
1005 const uint64_t zero[] = { 0, 0 };
1006 llvm::APFloat apf = llvm::APFloat(llvm::APInt(80, 2, zero));
1007 apf.convertFromAPInt(Result.IntVal,
1008 true,
1009 llvm::APFloat::rmNearestTiesToEven);
1010 Result.IntVal = apf.bitcastToAPInt();
1011 }
1012 return;
1013 }
1014 break;
1015
1016 /* double->APInt conversion handles sign */
1017 case llvm::Instruction::FPToUI:
1018 case llvm::Instruction::FPToSI:
1019 {
1020 uint32_t BitWidth =
1021 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
1022
1023 GetConstantValue(Op0, Result);
1024 if(Op0->getType()->isFloatTy())
1025 Result.IntVal =
1026 llvm::APIntOps::RoundFloatToAPInt(Result.FloatVal, BitWidth);
1027 else if(Op0->getType()->isDoubleTy())
1028 Result.IntVal =
1029 llvm::APIntOps::RoundDoubleToAPInt(Result.DoubleVal, BitWidth);
1030 else if(Op0->getType()->isX86_FP80Ty()) {
1031 llvm::APFloat apf = llvm::APFloat(Result.IntVal);
1032 uint64_t v;
1033 bool ignored;
1034 apf.convertToInteger(&v,
1035 BitWidth,
1036 CE->getOpcode()
1037 == llvm::Instruction::FPToSI,
1038 llvm::APFloat::rmTowardZero,
1039 &ignored);
1040 Result.IntVal = v; // endian?
1041 }
1042 return;
1043 }
1044 break;
1045
1046 case llvm::Instruction::PtrToInt:
1047 {
1048 uint32_t PtrWidth = mpTD->getPointerSizeInBits();
1049
1050 GetConstantValue(Op0, Result);
1051 Result.IntVal = llvm::APInt(PtrWidth, uintptr_t
1052 (Result.PointerVal));
1053
1054 return;
1055 }
1056 break;
1057
1058 case llvm::Instruction::IntToPtr:
1059 {
1060 uint32_t PtrWidth = mpTD->getPointerSizeInBits();
1061
1062 GetConstantValue(Op0, Result);
1063 if(PtrWidth != Result.IntVal.getBitWidth())
1064 Result.IntVal = Result.IntVal.zextOrTrunc(PtrWidth);
1065 assert(Result.IntVal.getBitWidth() <= 64 && "Bad pointer width");
1066
1067 Result.PointerVal = llvm::PointerTy
1068 (uintptr_t(Result.IntVal.getZExtValue()));
1069
1070 return;
1071 }
1072 break;
1073
1074 case llvm::Instruction::BitCast:
1075 {
1076 GetConstantValue(Op0, Result);
1077 const llvm::Type* DestTy = CE->getType();
1078
1079 switch(Op0->getType()->getTypeID()) {
1080 case llvm::Type::IntegerTyID:
1081 assert(DestTy->isFloatingPointTy() && "invalid bitcast");
1082 if(DestTy->isFloatTy())
1083 Result.FloatVal = Result.IntVal.bitsToFloat();
1084 else if(DestTy->isDoubleTy())
1085 Result.DoubleVal = Result.IntVal.bitsToDouble();
1086 break;
1087
1088 case llvm::Type::FloatTyID:
1089 assert(DestTy->isIntegerTy(32) && "Invalid bitcast");
1090 Result.IntVal.floatToBits(Result.FloatVal);
1091 break;
1092
1093 case llvm::Type::DoubleTyID:
1094 assert(DestTy->isIntegerTy(64) && "Invalid bitcast");
1095 Result.IntVal.doubleToBits(Result.DoubleVal);
1096 break;
1097
1098 case llvm::Type::PointerTyID:
1099 assert(DestTy->isPointerTy() && "Invalid bitcast");
1100 break; // getConstantValue(Op0) above already converted it
1101
1102 default:
1103 llvm_unreachable("Invalid bitcast operand");
1104 break;
1105 }
1106
1107 return;
1108 }
1109 break;
1110
1111 case llvm::Instruction::Add:
1112 case llvm::Instruction::FAdd:
1113 case llvm::Instruction::Sub:
1114 case llvm::Instruction::FSub:
1115 case llvm::Instruction::Mul:
1116 case llvm::Instruction::FMul:
1117 case llvm::Instruction::UDiv:
1118 case llvm::Instruction::SDiv:
1119 case llvm::Instruction::URem:
1120 case llvm::Instruction::SRem:
1121 case llvm::Instruction::And:
1122 case llvm::Instruction::Or:
1123 case llvm::Instruction::Xor:
1124 {
1125 llvm::GenericValue LHS, RHS;
1126 GetConstantValue(Op0, LHS);
1127 GetConstantValue(CE->getOperand(1), RHS);
1128
1129 switch(Op0->getType()->getTypeID()) {
1130 case llvm::Type::IntegerTyID:
1131 switch (CE->getOpcode()) {
1132 case llvm::Instruction::Add:
1133 Result.IntVal = LHS.IntVal + RHS.IntVal;
1134 break;
1135 case llvm::Instruction::Sub:
1136 Result.IntVal = LHS.IntVal - RHS.IntVal;
1137 break;
1138 case llvm::Instruction::Mul:
1139 Result.IntVal = LHS.IntVal * RHS.IntVal;
1140 break;
1141 case llvm::Instruction::UDiv:
1142 Result.IntVal = LHS.IntVal.udiv(RHS.IntVal);
1143 break;
1144 case llvm::Instruction::SDiv:
1145 Result.IntVal = LHS.IntVal.sdiv(RHS.IntVal);
1146 break;
1147 case llvm::Instruction::URem:
1148 Result.IntVal = LHS.IntVal.urem(RHS.IntVal);
1149 break;
1150 case llvm::Instruction::SRem:
1151 Result.IntVal = LHS.IntVal.srem(RHS.IntVal);
1152 break;
1153 case llvm::Instruction::And:
1154 Result.IntVal = LHS.IntVal & RHS.IntVal;
1155 break;
1156 case llvm::Instruction::Or:
1157 Result.IntVal = LHS.IntVal | RHS.IntVal;
1158 break;
1159 case llvm::Instruction::Xor:
1160 Result.IntVal = LHS.IntVal ^ RHS.IntVal;
1161 break;
1162 default:
1163 llvm_unreachable("Invalid integer opcode");
1164 break;
1165 }
1166 break;
1167
1168 case llvm::Type::FloatTyID:
1169 switch (CE->getOpcode()) {
1170 case llvm::Instruction::FAdd:
1171 Result.FloatVal = LHS.FloatVal + RHS.FloatVal;
1172 break;
1173 case llvm::Instruction::FSub:
1174 Result.FloatVal = LHS.FloatVal - RHS.FloatVal;
1175 break;
1176 case llvm::Instruction::FMul:
1177 Result.FloatVal = LHS.FloatVal * RHS.FloatVal;
1178 break;
1179 case llvm::Instruction::FDiv:
1180 Result.FloatVal = LHS.FloatVal / RHS.FloatVal;
1181 break;
1182 case llvm::Instruction::FRem:
1183 Result.FloatVal = ::fmodf(LHS.FloatVal, RHS.FloatVal);
1184 break;
1185 default:
1186 llvm_unreachable("Invalid float opcode");
1187 break;
1188 }
1189 break;
1190
1191 case llvm::Type::DoubleTyID:
1192 switch (CE->getOpcode()) {
1193 case llvm::Instruction::FAdd:
1194 Result.DoubleVal = LHS.DoubleVal + RHS.DoubleVal;
1195 break;
1196 case llvm::Instruction::FSub:
1197 Result.DoubleVal = LHS.DoubleVal - RHS.DoubleVal;
1198 break;
1199 case llvm::Instruction::FMul:
1200 Result.DoubleVal = LHS.DoubleVal * RHS.DoubleVal;
1201 break;
1202 case llvm::Instruction::FDiv:
1203 Result.DoubleVal = LHS.DoubleVal / RHS.DoubleVal;
1204 break;
1205 case llvm::Instruction::FRem:
1206 Result.DoubleVal = ::fmod(LHS.DoubleVal, RHS.DoubleVal);
1207 break;
1208 default:
1209 llvm_unreachable("Invalid double opcode");
1210 break;
1211 }
1212 break;
1213
1214 case llvm::Type::X86_FP80TyID:
1215 case llvm::Type::PPC_FP128TyID:
1216 case llvm::Type::FP128TyID:
1217 {
1218 llvm::APFloat apfLHS = llvm::APFloat(LHS.IntVal);
1219 switch (CE->getOpcode()) {
1220 case llvm::Instruction::FAdd:
1221 apfLHS.add(llvm::APFloat(RHS.IntVal),
1222 llvm::APFloat::rmNearestTiesToEven);
1223 break;
1224 case llvm::Instruction::FSub:
1225 apfLHS.subtract(llvm::APFloat(RHS.IntVal),
1226 llvm::APFloat::rmNearestTiesToEven);
1227 break;
1228 case llvm::Instruction::FMul:
1229 apfLHS.multiply(llvm::APFloat(RHS.IntVal),
1230 llvm::APFloat::rmNearestTiesToEven);
1231 break;
1232 case llvm::Instruction::FDiv:
1233 apfLHS.divide(llvm::APFloat(RHS.IntVal),
1234 llvm::APFloat::rmNearestTiesToEven);
1235 break;
1236 case llvm::Instruction::FRem:
1237 apfLHS.mod(llvm::APFloat(RHS.IntVal),
1238 llvm::APFloat::rmNearestTiesToEven);
1239 break;
1240 default:
1241 llvm_unreachable("Invalid long double opcode");
1242 llvm_unreachable(0);
1243 break;
1244 }
1245
1246 Result.IntVal = apfLHS.bitcastToAPInt();
1247 }
1248 break;
1249
1250 default:
1251 llvm_unreachable("Bad add type!");
1252 break;
1253 } /* End switch(Op0->getType()->getTypeID()) */
1254
1255 return;
1256 }
1257
1258 default:
1259 break;
1260 } /* End switch(CE->getOpcode()) */
1261
1262 std::string msg;
1263 llvm::raw_string_ostream Msg(msg);
1264 Msg << "ConstantExpr not handled: " << *CE;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001265 llvm::report_fatal_error(Msg.str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001266 } /* C->getValueID() == llvm::Value::ConstantExprVal */
1267
1268 switch (C->getType()->getTypeID()) {
1269 case llvm::Type::FloatTyID:
1270 Result.FloatVal = llvm::cast<llvm::ConstantFP>(C)
1271 ->getValueAPF().convertToFloat();
1272 break;
1273
1274 case llvm::Type::DoubleTyID:
1275 Result.DoubleVal = llvm::cast<llvm::ConstantFP>(C)
1276 ->getValueAPF().convertToDouble();
1277 break;
1278
1279 case llvm::Type::X86_FP80TyID:
1280 case llvm::Type::FP128TyID:
1281 case llvm::Type::PPC_FP128TyID:
1282 Result.IntVal = llvm::cast <llvm::ConstantFP>(C)
1283 ->getValueAPF().bitcastToAPInt();
1284 break;
1285
1286 case llvm::Type::IntegerTyID:
1287 Result.IntVal = llvm::cast<llvm::ConstantInt>(C)
1288 ->getValue();
1289 break;
1290
1291 case llvm::Type::PointerTyID:
1292 switch(C->getValueID()) {
1293 case llvm::Value::ConstantPointerNullVal:
1294 Result.PointerVal = NULL;
1295 break;
1296
1297 case llvm::Value::FunctionVal:
1298 {
1299 const llvm::Function* F = (llvm::Function*) C;
1300 Result.PointerVal = GetPointerToFunctionOrStub
1301 (const_cast<llvm::Function*>(F)
1302 );
1303 }
1304 break;
1305
1306 case llvm::Value::GlobalVariableVal:
1307 {
1308 const llvm::GlobalVariable* GV = (llvm::GlobalVariable*) C;
1309 Result.PointerVal = GetOrEmitGlobalVariable
1310 (const_cast<llvm::GlobalVariable*>(GV)
1311 );
1312 }
1313 break;
1314
1315 case llvm::Value::BlockAddressVal:
1316 {
1317 // const llvm::BlockAddress* BA = (llvm::BlockAddress*) C;
1318 // Result.PointerVal = getPointerToBasicBlock
1319 // (const_cast<llvm::BasicBlock*>(BA->getBasicBlock()));
1320 assert(false && "JIT does not support address-of-label yet!");
1321 }
1322 break;
1323
1324 default:
1325 llvm_unreachable("Unknown constant pointer type!");
1326 break;
1327 }
1328 break;
1329
1330 default:
1331 std::string msg;
1332 llvm::raw_string_ostream Msg(msg);
1333 Msg << "ERROR: Constant unimplemented for type: " << *C->getType();
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001334 llvm::report_fatal_error(Msg.str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001335 break;
1336 }
1337
1338 return;
1339 }
1340
1341 /*
1342 * StoreValueToMemory -
1343 * Stores the data in @Val of type @Ty at address @Addr.
1344 */
1345 void StoreValueToMemory(const llvm::GenericValue& Val, void* Addr,
1346 const llvm::Type *Ty) {
1347 const unsigned int StoreBytes = mpTD->getTypeStoreSize(Ty);
1348
1349 switch(Ty->getTypeID()) {
1350 case llvm::Type::IntegerTyID:
1351 {
1352 const llvm::APInt& IntVal = Val.IntVal;
1353 assert((IntVal.getBitWidth() + 7) / 8 >= StoreBytes &&
1354 "Integer too small!");
1355
1356 uint8_t *Src = (uint8_t*) IntVal.getRawData();
1357
1358 if(llvm::sys::isLittleEndianHost()) {
1359 /*
1360 * Little-endian host - the source is ordered from LSB to MSB.
1361 * Order the destination from LSB to MSB: Do a straight copy.
1362 */
1363 memcpy(Addr, Src, StoreBytes);
1364 } else {
1365 /*
1366 * Big-endian host - the source is an array of 64 bit words
1367 * ordered from LSW to MSW.
1368 *
1369 * Each word is ordered from MSB to LSB.
1370 *
1371 * Order the destination from MSB to LSB:
1372 * Reverse the word order, but not the bytes in a word.
1373 */
1374 unsigned int i = StoreBytes;
1375 while(i > sizeof(uint64_t)) {
1376 i -= sizeof(uint64_t);
1377 memcpy((uint8_t*) Addr + i, Src, sizeof(uint64_t));
1378 Src += sizeof(uint64_t);
1379 }
1380
1381 memcpy(Addr, Src + sizeof(uint64_t) - i, i);
1382 }
1383 }
1384 break;
1385
1386 case llvm::Type::FloatTyID:
1387 {
1388 *((float*) Addr) = Val.FloatVal;
1389 }
1390 break;
1391
1392 case llvm::Type::DoubleTyID:
1393 {
1394 *((double*) Addr) = Val.DoubleVal;
1395 }
1396 break;
1397
1398 case llvm::Type::X86_FP80TyID:
1399 {
1400 memcpy(Addr, Val.IntVal.getRawData(), 10);
1401 }
1402 break;
1403
1404 case llvm::Type::PointerTyID:
1405 {
1406 /*
1407 * Ensure 64 bit target pointers are fully
1408 * initialized on 32 bit hosts.
1409 */
1410 if(StoreBytes != sizeof(llvm::PointerTy))
1411 memset(Addr, 0, StoreBytes);
1412 *((llvm::PointerTy*) Addr) = Val.PointerVal;
1413 }
1414 break;
1415
1416 default:
1417 break;
1418 }
1419
1420 if(llvm::sys::isLittleEndianHost() != mpTD->isLittleEndian())
1421 std::reverse((uint8_t*) Addr, (uint8_t*) Addr + StoreBytes);
1422
1423 return;
1424 }
1425
1426 /*
1427 * InitializeConstantToMemory -
1428 * Recursive function to apply a @Constant value into the
1429 * specified memory location @Addr.
1430 */
1431 void InitializeConstantToMemory(const llvm::Constant *C, void *Addr) {
1432 switch(C->getValueID()) {
1433 case llvm::Value::UndefValueVal:
1434 // Nothing to do
1435 break;
1436
1437 case llvm::Value::ConstantVectorVal:
1438 {
1439 // dynamic cast may hurt performance
1440 const llvm::ConstantVector* CP = (llvm::ConstantVector*) C;
1441
1442 unsigned int ElementSize = mpTD->getTypeAllocSize
1443 (CP->getType()->getElementType());
1444
1445 for(int i=0;i<CP->getNumOperands();i++)
1446 InitializeConstantToMemory(CP->getOperand(i),
1447 (char*) Addr + i * ElementSize);
1448 }
1449 break;
1450
1451 case llvm::Value::ConstantAggregateZeroVal:
1452 memset(Addr, 0, (size_t) mpTD->getTypeAllocSize(C->getType()));
1453 break;
1454
1455 case llvm::Value::ConstantArrayVal:
1456 {
1457 const llvm::ConstantArray* CPA = (llvm::ConstantArray*) C;
1458 unsigned int ElementSize = mpTD->getTypeAllocSize
1459 (CPA->getType()->getElementType());
1460
1461 for(int i=0;i<CPA->getNumOperands();i++)
1462 InitializeConstantToMemory(CPA->getOperand(i),
1463 (char*) Addr + i * ElementSize);
1464 }
1465 break;
1466
1467 case llvm::Value::ConstantStructVal:
1468 {
1469 const llvm::ConstantStruct* CPS = (llvm::ConstantStruct*) C;
1470 const llvm::StructLayout* SL = mpTD->getStructLayout
1471 (llvm::cast<llvm::StructType>(CPS->getType()));
1472
1473 for(int i=0;i<CPS->getNumOperands();i++)
1474 InitializeConstantToMemory(CPS->getOperand(i),
1475 (char*) Addr +
1476 SL->getElementOffset(i));
1477 }
1478 break;
1479
1480 default:
1481 {
1482 if(C->getType()->isFirstClassType()) {
1483 llvm::GenericValue Val;
1484 GetConstantValue(C, Val);
1485 StoreValueToMemory(Val, Addr, C->getType());
1486 } else
1487 llvm_unreachable
1488 ("Unknown constant type to initialize memory with!");
1489 }
1490 break;
1491 }
1492
1493 return;
1494 }
1495
1496 void emitConstantPool(llvm::MachineConstantPool *MCP) {
1497 if(mpTJI->hasCustomConstantPool())
1498 return;
1499
1500 /*
1501 * Constant pool address resolution is handled by the target itself in ARM
1502 * (TargetJITInfo::hasCustomConstantPool() return true).
1503 */
1504#if !defined(PROVIDE_ARM_CODEGEN)
1505 const std::vector<llvm::MachineConstantPoolEntry>& Constants =
1506 MCP->getConstants();
1507
1508 if(Constants.empty())
1509 return;
1510
1511 unsigned Size = GetConstantPoolSizeInBytes(MCP);
1512 unsigned Align = MCP->getConstantPoolAlignment();
1513
1514 mpConstantPoolBase = allocateSpace(Size, Align);
1515 mpConstantPool = MCP;
1516
1517 if(mpConstantPoolBase == NULL)
1518 return; /* out of memory */
1519
1520 unsigned Offset = 0;
1521 for(int i=0;i<Constants.size();i++) {
1522 llvm::MachineConstantPoolEntry CPE = Constants[i];
1523 unsigned AlignMask = CPE.getAlignment() - 1;
1524 Offset = (Offset + AlignMask) & ~AlignMask;
1525
1526 uintptr_t CAddr = (uintptr_t) mpConstantPoolBase + Offset;
1527 mConstPoolAddresses.push_back(CAddr);
1528
1529 if(CPE.isMachineConstantPoolEntry())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001530 llvm::report_fatal_error
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001531 ("Initialize memory with machine specific constant pool"
1532 " entry has not been implemented!");
1533
1534 InitializeConstantToMemory(CPE.Val.ConstVal, (void*) CAddr);
1535
1536 const llvm::Type *Ty = CPE.Val.ConstVal->getType();
1537 Offset += mpTD->getTypeAllocSize(Ty);
1538 }
1539#endif
1540 return;
1541 }
1542
1543 void initJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
1544 if(mpTJI->hasCustomJumpTables())
1545 return;
1546
1547 const std::vector<llvm::MachineJumpTableEntry>& JT =
1548 MJTI->getJumpTables();
1549 if(JT.empty())
1550 return;
1551
1552 unsigned NumEntries = 0;
1553 for(int i=0;i<JT.size();i++)
1554 NumEntries += JT[i].MBBs.size();
1555
1556 unsigned EntrySize = MJTI->getEntrySize(*mpTD);
1557
1558 mpJumpTable = MJTI;;
1559 mpJumpTableBase = allocateSpace(NumEntries * EntrySize,
1560 MJTI->getEntryAlignment(*mpTD));
1561
1562 return;
1563 }
1564
1565 void emitJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
1566 if(mpTJI->hasCustomJumpTables())
1567 return;
1568
1569 const std::vector<llvm::MachineJumpTableEntry>& JT =
1570 MJTI->getJumpTables();
1571 if(JT.empty() || mpJumpTableBase == 0)
1572 return;
1573
1574 assert((llvm::TargetMachine::getRelocationModel() == llvm::Reloc::Static)
1575 && "Cross JIT'ing?");
1576 assert(MJTI->getEntrySize(*mpTD) == sizeof(void*) && "Cross JIT'ing?");
1577
1578 /*
1579 * For each jump table, map each target in the jump table to the
1580 * address of an emitted MachineBasicBlock.
1581 */
1582 intptr_t *SlotPtr = (intptr_t*) mpJumpTableBase;
1583 for(int i=0;i<JT.size();i++) {
1584 const std::vector<llvm::MachineBasicBlock*>& MBBs = JT[i].MBBs;
1585 /*
1586 * Store the address of the basic block for this jump table slot in the
1587 * memory we allocated for the jump table in 'initJumpTableInfo'
1588 */
1589 for(int j=0;j<MBBs.size();j++)
1590 *SlotPtr++ = getMachineBasicBlockAddress(MBBs[j]);
1591 }
1592 }
1593
1594 void* GetPointerToGlobal(llvm::GlobalValue* V, void* Reference,
1595 bool MayNeedFarStub) {
1596 switch(V->getValueID()) {
1597 case llvm::Value::FunctionVal:
1598 {
1599 llvm::Function* F = (llvm::Function*) V;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001600
Shih-wei Liao800e9c22010-04-18 16:08:16 -07001601 /* If we have code, go ahead and return that. */
1602 if(void* ResultPtr = GetPointerToGlobalIfAvailable(F))
1603 return ResultPtr;
1604
1605 if(void* FnStub = GetLazyFunctionStubIfAvailable(F))
1606 /*
1607 * Return the function stub if it's already created.
1608 * We do this first so that:
1609 * we're returning the same address for the function
1610 * as any previous call.
1611 *
1612 * TODO: Yes, this is wrong. The lazy stub isn't guaranteed
1613 * to be close enough to call.
1614 */
1615 return FnStub;
1616
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001617 /*
1618 * If we know the target can handle arbitrary-distance calls, try to
1619 * return a direct pointer.
1620 */
1621 if(!MayNeedFarStub) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001622 /*
1623 * x86_64 architecture may encounter the bug
1624 * http://hlvm.llvm.org/bugs/show_bug.cgi?id=5201
1625 * which generate instruction "call" instead of "callq".
1626 *
1627 * And once the real address of stub is
1628 * greater than 64-bit long, the replacement will truncate
1629 * to 32-bit resulting a serious problem.
1630 */
1631#if !defined(__x86_64__)
1632 /*
1633 * If this is an external function pointer,
1634 * we can force the JIT to
1635 * 'compile' it, which really just adds it to the map.
1636 */
1637 if(F->isDeclaration() || F->hasAvailableExternallyLinkage())
1638 return GetPointerToFunction(F, /* AbortOnFailure */true);
1639#endif
1640 }
1641
1642 /*
1643 * Otherwise, we may need a to emit a stub, and, conservatively, we
1644 * always do so.
1645 */
1646 return GetLazyFunctionStub(F);
1647 }
1648 break;
1649
1650 case llvm::Value::GlobalVariableVal:
1651 return GetOrEmitGlobalVariable((llvm::GlobalVariable*) V);
1652 break;
1653
1654 case llvm::Value::GlobalAliasVal:
1655 {
1656 llvm::GlobalAlias* GA = (llvm::GlobalAlias*) V;
1657 const llvm::GlobalValue* GV = GA->resolveAliasedGlobal(false);
1658
1659 switch(GV->getValueID()) {
1660 case llvm::Value::FunctionVal:
1661 /* FIXME: is there's any possibility that the function
1662 is not code-gen'd? */
1663 return GetPointerToFunction(
1664 const_cast<llvm::Function*>((const llvm::Function*) GV),
1665 /* AbortOnFailure */true
1666 );
1667 break;
1668
1669 case llvm::Value::GlobalVariableVal:
1670 {
1671 if(void* p = mGlobalAddressMap[GV])
1672 return p;
1673
1674 llvm::GlobalVariable* GVar = (llvm::GlobalVariable*) GV;
1675 EmitGlobalVariable(GVar);
1676
1677 return mGlobalAddressMap[GV];
1678 }
1679 break;
1680
1681 case llvm::Value::GlobalAliasVal:
1682 assert(false && "Alias should be resolved ultimately!");
1683 break;
1684 }
1685 }
1686 break;
1687
1688 default:
1689 break;
1690 }
1691
1692 llvm_unreachable("Unknown type of global value!");
1693
1694 }
1695
1696 /*
1697 * GetPointerToFunctionOrStub - If the specified function has been
1698 * code-gen'd, return a pointer to the function.
1699 * If not, compile it, or use
1700 * a stub to implement lazy compilation if available.
1701 */
1702 void* GetPointerToFunctionOrStub(llvm::Function* F) {
1703 /*
1704 * If we have already code generated the function,
1705 * just return the address.
1706 */
1707 if(void* Addr = GetPointerToGlobalIfAvailable(F))
1708 return Addr;
1709
1710 /* Get a stub if the target supports it. */
1711 return GetLazyFunctionStub(F);
1712 }
1713
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001714 typedef llvm::DenseMap<const llvm::Function*, void*> FunctionToLazyStubMapTy;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001715 FunctionToLazyStubMapTy mFunctionToLazyStubMap;
1716
1717 void* GetLazyFunctionStubIfAvailable(llvm::Function* F) {
1718 return mFunctionToLazyStubMap.lookup(F);
1719 }
1720
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001721 std::set<const llvm::Function*> PendingFunctions;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001722 void* GetLazyFunctionStub(llvm::Function* F) {
1723 /* If we already have a lazy stub for this function, recycle it. */
1724 void*& Stub = mFunctionToLazyStubMap[F];
1725 if(Stub)
1726 return Stub;
1727
1728 /*
1729 * In any cases, we should NOT resolve function at runtime
1730 * (though we are able to).
1731 * We resolve this right now.
1732 */
1733 void* Actual = NULL;
1734 if(F->isDeclaration() || F->hasAvailableExternallyLinkage())
1735 Actual = GetPointerToFunction(F, /* AbortOnFailure */true);
1736
1737 /*
1738 * Codegen a new stub, calling the actual address of
1739 * the external function, if it was resolved.
1740 */
1741 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
1742 startGVStub(F, SL.Size, SL.Alignment);
1743 Stub = mpTJI->emitFunctionStub(F, Actual, *this);
1744 finishGVStub();
1745
1746 /*
1747 * We really want the address of the stub in the GlobalAddressMap
1748 * for the JIT, not the address of the external function.
1749 */
1750 UpdateGlobalMapping(F, Stub);
1751
1752 if(!Actual)
1753 PendingFunctions.insert(F);
1754 else
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001755 Disassemble(F->getName(), (uint8_t*) Stub, SL.Size, true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001756
1757 return Stub;
1758 }
1759
1760 /* Our resolver to undefined symbol */
1761 BCCSymbolLookupFn mpSymbolLookupFn;
1762 void* mpSymbolLookupContext;
1763
1764 void* GetPointerToFunction(llvm::Function* F, bool AbortOnFailure) {
1765 void* Addr = GetPointerToGlobalIfAvailable(F);
1766 if(Addr)
1767 return Addr;
1768
1769 assert((F->isDeclaration() || F->hasAvailableExternallyLinkage()) &&
1770 "Internal error: only external defined function routes here!");
1771
1772 /* Handle the failure resolution by ourselves. */
1773 Addr = GetPointerToNamedSymbol(F->getName().str().c_str(),
1774 /* AbortOnFailure */ false);
1775
1776 /*
1777 * If we resolved the symbol to a null address (eg. a weak external)
1778 * return a null pointer let the application handle it.
1779 */
1780 if(Addr == NULL)
1781 if(AbortOnFailure)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001782 llvm::report_fatal_error
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001783 ("Could not resolve external function address: " + F->getName()
1784 );
1785 else
1786 return NULL;
1787
1788 AddGlobalMapping(F, Addr);
1789
1790 return Addr;
1791 }
1792
1793 void* GetPointerToNamedSymbol(const std::string& Name,
1794 bool AbortOnFailure) {
1795 if(void* Addr = FindRuntimeFunction(Name.c_str()))
1796 return Addr;
1797
1798 if(mpSymbolLookupFn)
1799 if(void* Addr = mpSymbolLookupFn(mpSymbolLookupContext, Name.c_str()))
1800 return Addr;
1801
1802 if(AbortOnFailure)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001803 llvm::report_fatal_error("Program used external symbol '" + Name +
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001804 "' which could not be resolved!");
1805
1806 return NULL;
1807 }
1808
1809 /*
1810 * GetOrEmitGlobalVariable - Return the address of the specified global
1811 * variable, possibly emitting it to memory if needed. This is used by the
1812 * Emitter.
1813 */
1814 void* GetOrEmitGlobalVariable(const llvm::GlobalVariable *GV) {
1815 void* Ptr = GetPointerToGlobalIfAvailable(GV);
1816 if(Ptr)
1817 return Ptr;
1818
1819 if(GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) {
1820 /* If the global is external, just remember the address. */
1821 Ptr = GetPointerToNamedSymbol(GV->getName().str(), true);
1822 AddGlobalMapping(GV, Ptr);
1823 } else {
1824 /* If the global hasn't been emitted to memory yet,
1825 allocate space and emit it into memory. */
1826 Ptr = GetMemoryForGV(GV);
1827 AddGlobalMapping(GV, Ptr);
1828 EmitGlobalVariable(GV);
1829 }
1830
1831 return Ptr;
1832 }
1833
1834 /*
1835 * GetMemoryForGV - This method abstracts memory allocation of global
1836 * variable so that the JIT can allocate thread local variables depending
1837 * on the target.
1838 */
1839 void* GetMemoryForGV(const llvm::GlobalVariable* GV) {
1840 char* Ptr;
1841
1842 const llvm::Type* GlobalType = GV->getType()->getElementType();
1843 size_t S = mpTD->getTypeAllocSize(GlobalType);
1844 size_t A = mpTD->getPreferredAlignment(GV);
1845
1846 if(GV->isThreadLocal()) {
1847 /*
1848 * We can support TLS by
1849 *
1850 * Ptr = TJI.allocateThreadLocalMemory(S);
1851 *
1852 * But I tend not to .
1853 * (should we disable this in the front-end (i.e. slang)?).
1854 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001855 llvm::report_fatal_error
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001856 ("Compilation of Thread Local Storage (TLS) is disabled!");
1857
1858 } else if(mpTJI->allocateSeparateGVMemory()) {
1859 /*
1860 * On the Apple's ARM target (such as iPhone),
1861 * the global variable should be
1862 * placed in separately allocated heap memory rather than in the same
1863 * code memory.
1864 * The question is, how about the Android?
1865 */
1866 if(A <= 8) {
1867 Ptr = (char*) malloc(S);
1868 } else {
1869 /*
1870 * Allocate (S + A) bytes of memory,
1871 * then use an aligned pointer within that space.
1872 */
1873 Ptr = (char*) malloc(S + A);
1874 unsigned int MisAligned = ((intptr_t) Ptr & (A - 1));
1875 Ptr = Ptr + (MisAligned ? (A - MisAligned) : 0);
1876 }
1877 } else {
1878 Ptr = (char*) allocateGlobal(S, A);
1879 }
1880
1881 return Ptr;
1882 }
1883
1884 void EmitGlobalVariable(const llvm::GlobalVariable *GV) {
1885 void* GA = GetPointerToGlobalIfAvailable(GV);
1886
1887 if(GV->isThreadLocal())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001888 llvm::report_fatal_error
1889 ("We don't support Thread Local Storage (TLS)!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001890
1891 if(GA == NULL) {
1892 /* If it's not already specified, allocate memory for the global. */
1893 GA = GetMemoryForGV(GV);
1894 AddGlobalMapping(GV, GA);
1895 }
1896
1897 InitializeConstantToMemory(GV->getInitializer(), GA);
1898
1899 /* You can do some statistics on global variable here */
1900 return;
1901 }
1902
1903 typedef std::map<llvm::AssertingVH<llvm::GlobalValue>, void*
1904 > GlobalToIndirectSymMapTy;
1905 GlobalToIndirectSymMapTy GlobalToIndirectSymMap;
1906
1907 void* GetPointerToGVIndirectSym(llvm::GlobalValue *V, void *Reference) {
1908 /*
1909 * Make sure GV is emitted first, and create a stub containing the fully
1910 * resolved address.
1911 */
1912 void* GVAddress = GetPointerToGlobal(V, Reference, false);
1913
1914 /* If we already have a stub for this global variable, recycle it. */
1915 void*& IndirectSym = GlobalToIndirectSymMap[V];
1916 /* Otherwise, codegen a new indirect symbol. */
1917 if(!IndirectSym)
1918 IndirectSym = mpTJI->emitGlobalValueIndirectSym(V, GVAddress, *this);
1919
1920 return IndirectSym;
1921 }
1922
1923 /*
1924 * ExternalFnToStubMap - This is the equivalent of FunctionToLazyStubMap
1925 * for external functions.
1926 *
1927 * TODO: Of course, external functions don't need a lazy stub.
1928 * It's actually
1929 * here to make it more likely that far calls succeed, but no single
1930 * stub can guarantee that. I'll remove this in a subsequent checkin
1931 * when I actually fix far calls. (comment from LLVM source)
1932 */
1933 std::map<void*, void*> ExternalFnToStubMap;
1934
1935 /*
1936 * GetExternalFunctionStub - Return a stub for the function at the
1937 * specified address.
1938 */
1939 void* GetExternalFunctionStub(void* FnAddr) {
1940 void*& Stub = ExternalFnToStubMap[FnAddr];
1941 if(Stub)
1942 return Stub;
1943
1944 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
1945 startGVStub(0, SL.Size, SL.Alignment);
1946 Stub = mpTJI->emitFunctionStub(0, FnAddr, *this);
1947 finishGVStub();
1948
1949 return Stub;
1950 }
1951
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001952#if defined(USE_DISASSEMBLER)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001953 const llvm::MCAsmInfo* mpAsmInfo;
1954 const llvm::MCDisassembler* mpDisassmbler;
1955 llvm::MCInstPrinter* mpIP;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001956
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001957 class BufferMemoryObject : public llvm::MemoryObject {
1958 private:
1959 const uint8_t* mBytes;
1960 uint64_t mLength;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001961
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001962 public:
1963 BufferMemoryObject(const uint8_t *Bytes, uint64_t Length) :
1964 mBytes(Bytes), mLength(Length) { }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001965
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001966 uint64_t getBase() const { return 0; }
1967 uint64_t getExtent() const { return mLength; }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001968
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001969 int readByte(uint64_t Addr, uint8_t *Byte) const {
1970 if(Addr > getExtent())
1971 return -1;
1972 *Byte = mBytes[Addr];
1973 return 0;
1974 }
1975 };
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001976
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001977 void Disassemble(const llvm::StringRef& Name, uint8_t* Start,
1978 size_t Length, bool IsStub) {
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001979 llvm::raw_fd_ostream* OS;
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07001980#if defined(USE_DISASSEMBLER_FILE)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001981 std::string ErrorInfo;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001982 OS = new llvm::raw_fd_ostream(
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07001983 "/data/local/tmp/out.S", ErrorInfo, llvm::raw_fd_ostream::F_Append);
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001984 if(!ErrorInfo.empty()) { // some errors occurred
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07001985 //LOGE("Error in creating disassembly file");
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001986 delete OS;
1987 return;
1988 }
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001989#else
1990 OS = &llvm::outs();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001991#endif
1992
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001993
1994 *OS << "JIT: Disassembled code: " << Name
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001995 << ((IsStub) ? " (stub)" : "") << "\n";
1996
1997 if(mpAsmInfo == NULL)
1998 mpAsmInfo = mpTarget->createAsmInfo(Triple);
1999 if(mpDisassmbler == NULL)
2000 mpDisassmbler = mpTarget->createMCDisassembler();
2001 if(mpIP == NULL)
2002 mpIP = mpTarget->createMCInstPrinter(
2003 mpAsmInfo->getAssemblerDialect(), *mpAsmInfo);
2004
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002005 const BufferMemoryObject* BufferMObj =
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002006 new BufferMemoryObject(Start, Length);
2007 uint64_t Size;
2008 uint64_t Index;
2009
2010 for(Index=0;Index<Length;Index+=Size) {
2011 llvm::MCInst Inst;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002012
2013 if(mpDisassmbler->getInstruction(Inst, Size, *BufferMObj, Index,
2014 /* REMOVED */ llvm::nulls()))
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002015 {
2016 OS->indent(4).write("0x", 2).
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002017 write_hex((uint32_t) Start + Index).write(':');
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002018 mpIP->printInst(&Inst, *OS);
2019 *OS << "\n";
2020 } else {
2021 if (Size == 0)
2022 Size = 1; // skip illegible bytes
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002023 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002024 }
2025
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002026 *OS << "\n";
2027 delete BufferMObj;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002028
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002029#if defined(USE_DISASSEMBLER_FILE)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002030 /* If you want the disassemble results write to file, uncomment this */
2031 OS->close();
2032 delete OS;
2033#endif
2034
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002035 return;
2036 }
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002037#else
2038 void Disassemble(const std::string& Name, uint8_t* Start,
2039 size_t Length, bool IsStub) {
2040 return;
2041 }
2042#endif /* defined(USE_DISASSEMBLER) */
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002043
2044 public:
2045 /* Will take the ownership of @MemMgr */
2046 CodeEmitter(CodeMemoryManager* pMemMgr) :
2047 mpMemMgr(pMemMgr),
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002048 mpTarget(NULL),
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002049 mpTJI(NULL),
2050 mpTD(NULL),
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002051#if defined(USE_DISASSEMBLER)
2052 mpAsmInfo(NULL),
2053 mpDisassmbler(NULL),
2054 mpIP(NULL),
2055#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002056 mpCurEmitFunction(NULL),
2057 mpConstantPool(NULL),
2058 mpJumpTable(NULL),
2059 mpMMI(NULL),
2060 mpSymbolLookupFn(NULL),
2061 mpSymbolLookupContext(NULL)
2062 {
2063 return;
2064 }
2065
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002066 inline global_addresses_const_iterator global_address_begin() const {
2067 return mGlobalAddressMap.begin();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002068 }
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002069 inline global_addresses_const_iterator global_address_end() const {
2070 return mGlobalAddressMap.end();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002071 }
2072
2073 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid* pContext) {
2074 mpSymbolLookupFn = pFn;
2075 mpSymbolLookupContext = pContext;
2076 return;
2077 }
2078
2079 void setTargetMachine(llvm::TargetMachine& TM) {
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002080 /* set Target */
2081 mpTarget = &TM.getTarget();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002082 /* set TargetJITInfo */
2083 mpTJI = TM.getJITInfo();
2084 /* set TargetData */
2085 mpTD = TM.getTargetData();
2086
2087 /*
2088 if(mpTJI->needsGOT())
2089 mpMemMgr->AllocateGOT(); // however,
2090 // both X86 and ARM target don't need GOT
2091 // (mpTJI->needsGOT() always returns false)
2092 */
2093 assert(!mpTJI->needsGOT() && "We don't support GOT needed target!");
2094
2095 return;
2096 }
2097
2098 /*
2099 * startFunction - This callback is invoked when the specified function is
2100 * about to be code generated. This initializes the BufferBegin/End/Ptr
2101 * fields.
2102 */
2103 void startFunction(llvm::MachineFunction &F) {
2104 uintptr_t ActualSize = 0;
2105
2106 mpMemMgr->setMemoryWritable();
2107
2108 /*
2109 * BufferBegin, BufferEnd and CurBufferPtr
2110 * are all inherited from class MachineCodeEmitter,
2111 * which is the super class of the class JITCodeEmitter.
2112 *
2113 * BufferBegin/BufferEnd - Pointers to the start and end of the memory
2114 * allocated for this code buffer.
2115 *
2116 * CurBufferPtr - Pointer to the next byte of memory to fill when emitting
2117 * code.
2118 * This is guranteed to be in the range [BufferBegin,BufferEnd]. If
2119 * this pointer is at BufferEnd, it will never move due to code emission,
2120 * and
2121 * all code emission requests will be ignored (this is
2122 * the buffer overflow condition).
2123 */
2124 BufferBegin = CurBufferPtr = mpMemMgr
2125 ->startFunctionBody(F.getFunction(), ActualSize);
2126 BufferEnd = BufferBegin + ActualSize;
2127
2128 if(mpCurEmitFunction == NULL)
2129 mpCurEmitFunction = new EmittedFunctionCode();
2130 mpCurEmitFunction->FunctionBody = BufferBegin;
2131
2132 /* Ensure the constant pool/jump table info is at least 4-byte aligned. */
2133 emitAlignment(16);
2134
2135 emitConstantPool(F.getConstantPool());
2136 if(llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
2137 initJumpTableInfo(MJTI);
2138
2139 /* About to start emitting the machine code for the function. */
2140 emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
2141
2142 UpdateGlobalMapping(F.getFunction(), CurBufferPtr);
2143
2144 mpCurEmitFunction->Code = CurBufferPtr;
2145
2146 mMBBLocations.clear();
2147
2148 return;
2149 }
2150
2151 /*
2152 * finishFunction - This callback is invoked
2153 * when the specified function has
2154 * finished code generation.
2155 * If a buffer overflow has occurred, this method
2156 * returns true (the callee is required to try again), otherwise it returns
2157 * false.
2158 */
2159 bool finishFunction(llvm::MachineFunction &F) {
2160 if(CurBufferPtr == BufferEnd) {
2161 /* No enough memory */
2162 mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
2163 return false;
2164 }
2165
2166 if(llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
2167 emitJumpTableInfo(MJTI);
2168
2169 /*
2170 * FnStart is the start of the text,
2171 * not the start of the constant pool and other per-function data.
2172 */
2173 uint8_t* FnStart = (uint8_t*) GetPointerToGlobalIfAvailable
2174 (F.getFunction());
2175
2176 /* FnEnd is the end of the function's machine code. */
2177 uint8_t* FnEnd = CurBufferPtr;
2178
2179 if(!mRelocations.empty()) {
2180 /* Resolve the relocations to concrete pointers. */
2181 for(int i=0;i<mRelocations.size();i++) {
2182 llvm::MachineRelocation& MR = mRelocations[i];
2183 void* ResultPtr = NULL;
2184
2185 if(!MR.letTargetResolve()) {
2186 if(MR.isExternalSymbol()) {
2187 ResultPtr = GetPointerToNamedSymbol(MR.getExternalSymbol(), true);
2188 if(MR.mayNeedFarStub())
2189 ResultPtr = GetExternalFunctionStub(ResultPtr);
2190 } else if(MR.isGlobalValue()) {
2191 ResultPtr = GetPointerToGlobal(MR.getGlobalValue(),
2192 BufferBegin
2193 + MR.getMachineCodeOffset(),
2194 MR.mayNeedFarStub());
2195 } else if(MR.isIndirectSymbol()) {
2196 ResultPtr = GetPointerToGVIndirectSym
2197 (MR.getGlobalValue(),
2198 BufferBegin + MR.getMachineCodeOffset()
2199 );
2200 } else if(MR.isBasicBlock()) {
2201 ResultPtr =
2202 (void*) getMachineBasicBlockAddress(MR.getBasicBlock());
2203 } else if(MR.isConstantPoolIndex()) {
2204 ResultPtr =
2205 (void*) getConstantPoolEntryAddress
2206 (MR.getConstantPoolIndex());
2207 } else {
2208 assert(MR.isJumpTableIndex() && "Unknown type of relocation");
2209 ResultPtr =
2210 (void*) getJumpTableEntryAddress(MR.getJumpTableIndex());
2211 }
2212
2213 MR.setResultPointer(ResultPtr);
2214 }
2215 }
2216
2217 mpTJI->relocate(BufferBegin, &mRelocations[0], mRelocations.size(),
2218 mpMemMgr->getGOTBase());
2219 }
2220
2221 mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
2222 /*
2223 * CurBufferPtr may have moved beyond FnEnd, due to memory allocation for
2224 * global variables that were referenced in the relocations.
2225 */
2226 if(CurBufferPtr == BufferEnd)
2227 return false;
2228
2229 /* Now that we've succeeded in emitting the function */
2230 mpCurEmitFunction->Size = CurBufferPtr - BufferBegin;
2231 BufferBegin = CurBufferPtr = 0;
2232
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002233 if(F.getFunction()->hasName())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002234 mEmittedFunctions[F.getFunction()->getNameStr()] = mpCurEmitFunction;
2235 mpCurEmitFunction = NULL;
2236
2237 mRelocations.clear();
2238 mConstPoolAddresses.clear();
2239
2240 /* Mark code region readable and executable if it's not so already. */
2241 mpMemMgr->setMemoryExecutable();
2242
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002243 Disassemble(F.getFunction()->getName(), FnStart, FnEnd - FnStart, false);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002244
2245 if(mpMMI)
2246 mpMMI->EndFunction();
2247
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002248 updateFunctionStub(F.getFunction());
2249
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002250 return false;
2251 }
2252
2253 void startGVStub(const llvm::GlobalValue* GV, unsigned StubSize,
2254 unsigned Alignment) {
2255 mpSavedBufferBegin = BufferBegin;
2256 mpSavedBufferEnd = BufferEnd;
2257 mpSavedCurBufferPtr = CurBufferPtr;
2258
2259 BufferBegin = CurBufferPtr = mpMemMgr->allocateStub(GV, StubSize,
2260 Alignment);
2261 BufferEnd = BufferBegin + StubSize + 1;
2262
2263 return;
2264 }
2265
2266 void startGVStub(void* Buffer, unsigned StubSize) {
2267 mpSavedBufferBegin = BufferBegin;
2268 mpSavedBufferEnd = BufferEnd;
2269 mpSavedCurBufferPtr = CurBufferPtr;
2270
2271 BufferBegin = CurBufferPtr = (uint8_t *) Buffer;
2272 BufferEnd = BufferBegin + StubSize + 1;
2273
2274 return;
2275 }
2276
2277 void finishGVStub() {
2278 assert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space.");
2279
2280 /* restore */
2281 BufferBegin = mpSavedBufferBegin;
2282 BufferEnd = mpSavedBufferEnd;
2283 CurBufferPtr = mpSavedCurBufferPtr;
2284
2285 return;
2286 }
2287
2288 /*
2289 * allocIndirectGV - Allocates and fills storage for an indirect
2290 * GlobalValue, and returns the address.
2291 */
2292 void* allocIndirectGV(const llvm::GlobalValue *GV,
2293 const uint8_t *Buffer, size_t Size,
2294 unsigned Alignment) {
2295 uint8_t* IndGV = mpMemMgr->allocateStub(GV, Size, Alignment);
2296 memcpy(IndGV, Buffer, Size);
2297 return IndGV;
2298 }
2299
2300 /* emitLabel - Emits a label */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002301 void emitLabel(llvm::MCSymbol *Label) {
2302 mLabelLocations[Label] = getCurrentPCValue();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002303 return;
2304 }
2305
2306 /*
2307 * allocateGlobal - Allocate memory for a global. Unlike allocateSpace,
2308 * this method does not allocate memory in the current output buffer,
2309 * because a global may live longer than the current function.
2310 */
2311 void* allocateGlobal(uintptr_t Size, unsigned Alignment) {
2312 /* Delegate this call through the memory manager. */
2313 return mpMemMgr->allocateGlobal(Size, Alignment);
2314 }
2315
2316 /*
2317 * StartMachineBasicBlock - This should be called by the target when a new
2318 * basic block is about to be emitted. This way the MCE knows where the
2319 * start of the block is, and can implement getMachineBasicBlockAddress.
2320 */
2321 void StartMachineBasicBlock(llvm::MachineBasicBlock *MBB) {
2322 if(mMBBLocations.size() <= (unsigned) MBB->getNumber())
2323 mMBBLocations.resize((MBB->getNumber() + 1) * 2);
2324 mMBBLocations[MBB->getNumber()] = getCurrentPCValue();
2325 return;
2326 }
2327
2328 /*
2329 * addRelocation - Whenever a relocatable address is needed, it should be
2330 * noted with this interface.
2331 */
2332 void addRelocation(const llvm::MachineRelocation &MR) {
2333 mRelocations.push_back(MR);
2334 return;
2335 }
2336
2337 /*
2338 * getConstantPoolEntryAddress - Return the address of the 'Index' entry in
2339 * the constant pool that was last emitted with
2340 * the emitConstantPool method.
2341 */
2342 uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
2343 assert(Index < mpConstantPool->getConstants().size() &&
2344 "Invalid constant pool index!");
2345 return mConstPoolAddresses[Index];
2346 }
2347
2348 /*
2349 * getJumpTableEntryAddress - Return the address of the jump table
2350 * with index
2351 * 'Index' in the function that last called initJumpTableInfo.
2352 */
2353 uintptr_t getJumpTableEntryAddress(unsigned Index) const {
2354 const std::vector<llvm::MachineJumpTableEntry>& JT =
2355 mpJumpTable->getJumpTables();
2356
2357 assert(Index < JT.size() && "Invalid jump table index!");
2358
2359 unsigned int Offset = 0;
2360 unsigned int EntrySize = mpJumpTable->getEntrySize(*mpTD);
2361
2362 for(int i=0;i<Index;i++)
2363 Offset += JT[i].MBBs.size();
2364 Offset *= EntrySize;
2365
2366 return (uintptr_t)((char *) mpJumpTableBase + Offset);
2367 }
2368
2369 /*
2370 * getMachineBasicBlockAddress - Return the address of the specified
2371 * MachineBasicBlock, only usable after the label for the MBB has been
2372 * emitted.
2373 */
2374 uintptr_t getMachineBasicBlockAddress(llvm::MachineBasicBlock *MBB) const {
2375 assert(mMBBLocations.size() > (unsigned) MBB->getNumber() &&
2376 mMBBLocations[MBB->getNumber()] && "MBB not emitted!");
2377 return mMBBLocations[MBB->getNumber()];
2378 }
2379
2380 /*
2381 * getLabelAddress - Return the address of the specified LabelID,
2382 * only usable after the LabelID has been emitted.
2383 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002384 uintptr_t getLabelAddress(llvm::MCSymbol* Label) const {
2385 assert(mLabelLocations.count(Label) && "Label not emitted!");
2386 return mLabelLocations.find(Label)->second;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002387 }
2388
2389 /*
2390 * Specifies the MachineModuleInfo object.
2391 * This is used for exception handling
2392 * purposes.
2393 */
2394 void setModuleInfo(llvm::MachineModuleInfo* Info) {
2395 mpMMI = Info;
2396 return;
2397 }
2398
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002399 void updateFunctionStub(const llvm::Function* F) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002400 /* Get the empty stub we generated earlier. */
2401 void* Stub;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002402 std::set<const llvm::Function*>::iterator I = PendingFunctions.find(F);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002403 if(I != PendingFunctions.end())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002404 Stub = mFunctionToLazyStubMap[F];
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002405 else
2406 return;
2407
2408 void* Addr = GetPointerToGlobalIfAvailable(F);
2409
2410 assert(Addr != Stub &&
2411 "Function must have non-stub address to be updated.");
2412
2413 /*
2414 * Tell the target jit info to rewrite the stub at the specified address,
2415 * rather than creating a new one.
2416 */
2417 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
2418 startGVStub(Stub, SL.Size);
2419 mpTJI->emitFunctionStub(F, Addr, *this);
2420 finishGVStub();
2421
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002422 Disassemble(F->getName(), (uint8_t*) Stub, SL.Size, true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002423
2424 PendingFunctions.erase(I);
2425
2426 return;
2427 }
2428
2429 /*
2430 * Once you finish the compilation on a translation unit,
2431 * you can call this function to recycle the memory
2432 * (which is used at compilation time and not needed for runtime).
2433 *
2434 * NOTE: You should not call this funtion until the code-gen passes
2435 * for a given module is done.
2436 * Otherwise, the results is undefined and may cause the system crash!
2437 */
2438 void releaseUnnecessary() {
2439 mMBBLocations.clear();
2440 mLabelLocations.clear();
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002441 mGlobalAddressMap.clear();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002442 mFunctionToLazyStubMap.clear();
2443 GlobalToIndirectSymMap.clear();
2444 ExternalFnToStubMap.clear();
2445 PendingFunctions.clear();
2446
2447 return;
2448 }
2449
2450 void reset() {
2451 releaseUnnecessary();
2452
2453 mpSymbolLookupFn = NULL;
2454 mpSymbolLookupContext = NULL;
2455
2456 mpTJI = NULL;
2457 mpTD = NULL;
2458
2459 for(EmittedFunctionsMapTy::iterator I = mEmittedFunctions.begin();
2460 I != mEmittedFunctions.end();
2461 I++)
2462 if(I->second != NULL)
2463 delete I->second;
2464 mEmittedFunctions.clear();
2465
2466 mpMemMgr->reset();
2467
2468 return;
2469 }
2470
2471 void* lookup(const char* Name) {
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002472 return lookup( llvm::StringRef(Name) );
2473 }
2474
2475 void* lookup(const llvm::StringRef& Name) {
2476 EmittedFunctionsMapTy::const_iterator I = mEmittedFunctions.find(Name.str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002477 if(I == mEmittedFunctions.end())
2478 return NULL;
2479 else
2480 return I->second->Code;
2481 }
2482
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002483 void getFunctionNames(BCCsizei* actualFunctionCount,
2484 BCCsizei maxFunctionCount,
2485 BCCchar** functions) {
2486 int functionCount = mEmittedFunctions.size();
2487
2488 if(actualFunctionCount)
2489 *actualFunctionCount = functionCount;
2490 if(functionCount > maxFunctionCount)
2491 functionCount = maxFunctionCount;
2492 if(functions)
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002493 for(EmittedFunctionsMapTy::const_iterator it =
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002494 mEmittedFunctions.begin();
2495 functionCount > 0;
2496 functionCount--, it++)
2497 *functions++ = (BCCchar*) it->first.c_str();
2498
2499 return;
2500 }
2501
2502 void getFunctionBinary(BCCchar* label,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002503 BCCvoid** base,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002504 BCCsizei* length) {
2505 EmittedFunctionsMapTy::const_iterator I = mEmittedFunctions.find(label);
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002506 if(I == mEmittedFunctions.end()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002507 *base = NULL;
2508 *length = 0;
2509 } else {
2510 *base = I->second->Code;
2511 *length = I->second->Size;
2512 }
2513 return;
2514 }
2515
2516 ~CodeEmitter() {
2517 if(mpMemMgr)
2518 delete mpMemMgr;
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002519#if defined(USE_DISASSEMBLER)
2520 if(mpAsmInfo)
2521 delete mpAsmInfo;
2522 if(mpDisassmbler)
2523 delete mpDisassmbler;
2524 if(mpIP)
2525 delete mpIP;
2526#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002527 return;
2528 }
2529 /* }}} */
2530 }; /* End of Class CodeEmitter */
2531
2532 /* The CodeEmitter */
2533 llvm::OwningPtr<CodeEmitter> mCodeEmitter;
2534 CodeEmitter* createCodeEmitter() {
2535 mCodeEmitter.reset(new CodeEmitter(mCodeMemMgr.take()));
2536 return mCodeEmitter.get();
2537 }
2538
2539 BCCSymbolLookupFn mpSymbolLookupFn;
2540 void* mpSymbolLookupContext;
2541
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002542 llvm::LLVMContext* mContext;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002543 llvm::Module* mModule;
2544
2545 bool mTypeInformationPrepared;
2546 std::vector<const llvm::Type*> mTypes;
2547
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002548 public:
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002549 Compiler() :
2550 mpSymbolLookupFn(NULL),
2551 mpSymbolLookupContext(NULL),
2552 mContext(NULL),
2553 mModule(NULL)
2554 {
Shih-wei Liaoc5611992010-05-09 06:37:55 -07002555 llvm::remove_fatal_error_handler();
2556 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002557 mContext = new llvm::LLVMContext();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002558 return;
2559 }
2560
2561 /* interface for BCCscript::registerSymbolCallback() */
2562 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid* pContext) {
2563 mpSymbolLookupFn = pFn;
2564 mpSymbolLookupContext = pContext;
2565 return;
2566 }
2567
2568 int loadModule(const char* bitcode, size_t bitcodeSize) {
2569 llvm::MemoryBuffer* SB = NULL;
2570
2571 if(bitcode == NULL || bitcodeSize <= 0)
2572 return 0;
Shih-wei Liaoc5611992010-05-09 06:37:55 -07002573
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002574 GlobalInitialization();
2575
2576 /* Package input to object MemoryBuffer */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002577 SB = llvm::MemoryBuffer::getMemBuffer(
2578 llvm::StringRef(bitcode, bitcodeSize));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002579 if(SB == NULL) {
Shih-wei Liao7a0e42a2010-05-11 03:41:56 -07002580 LOGE("Error reading input Bitcode into memory");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002581 setError("Error reading input Bitcode into memory");
2582 goto on_bcc_load_module_error;
2583 }
2584
2585 /* Read the input Bitcode as a Module */
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002586 mModule = llvm::ParseBitcodeFile(SB, *mContext, &mError);
Shih-wei Liaoc5611992010-05-09 06:37:55 -07002587
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002588on_bcc_load_module_error:
2589 if (SB)
2590 delete SB;
2591
2592 return hasError();
2593 }
2594
2595 /* interace for bccCompileScript() */
2596 int compile() {
2597 llvm::TargetData* TD = NULL;
2598
2599 llvm::TargetMachine* TM = NULL;
2600 const llvm::Target* Target;
2601 std::string FeaturesStr;
2602
2603 llvm::FunctionPassManager* CodeGenPasses = NULL;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002604
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002605 const llvm::NamedMDNode* PragmaMetadata;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002606 const llvm::NamedMDNode* ExportVarMetadata;
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002607 const llvm::NamedMDNode* ExportFuncMetadata;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002608
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002609 //LOGE("COMPILE");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002610 if(mModule == NULL) /* No module was loaded */
2611 return 0;
2612
2613 /* Create TargetMachine */
2614 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
2615 if(hasError())
2616 goto on_bcc_compile_error;
2617
2618 if(!CPU.empty() || !Features.empty()) {
2619 llvm::SubtargetFeatures F;
2620 F.setCPU(CPU);
2621 for(std::vector<std::string>::const_iterator it = Features.begin();
2622 it != Features.end();
2623 it++)
2624 F.AddFeature(*it);
2625 FeaturesStr = F.getString();
2626 }
2627
2628 TM = Target->createTargetMachine(Triple, FeaturesStr);
2629 if(TM == NULL) {
2630 setError("Failed to create target machine implementation for the"
2631 " specified triple '" + Triple + "'");
2632 goto on_bcc_compile_error;
2633 }
2634
2635 /* Create memory manager for creation of code emitter later */
2636 if(!mCodeMemMgr.get() && !createCodeMemoryManager()) {
2637 setError("Failed to startup memory management for further compilation");
2638 goto on_bcc_compile_error;
2639 }
2640
2641 /* Create code emitter */
2642 if(!mCodeEmitter.get()) {
2643 if(!createCodeEmitter()) {
2644 setError("Failed to create machine code emitter to complete"
2645 " the compilation");
2646 goto on_bcc_compile_error;
2647 }
2648 } else {
2649 /* reuse the code emitter */
2650 mCodeEmitter->reset();
2651 }
2652
2653 mCodeEmitter->setTargetMachine(*TM);
2654 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
2655 mpSymbolLookupContext);
2656
2657 /* Get target data from Module */
2658 TD = new llvm::TargetData(mModule);
2659 /* Create code-gen pass to run the code emitter */
2660 CodeGenPasses = new llvm::FunctionPassManager(mModule);
2661 CodeGenPasses->add(TD); // Will take the ownership of TD
2662
2663 if(TM->addPassesToEmitMachineCode(*CodeGenPasses,
2664 *mCodeEmitter, CodeGenOptLevel)) {
2665 setError("The machine code emission is not supported by BCC on target '"
2666 + Triple + "'");
2667 goto on_bcc_compile_error;
2668 }
2669
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002670 //LOGE("Before CODEGEN");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002671 /*
2672 * Run the pass (the code emitter) on every non-declaration function
2673 * in the module
2674 */
2675 CodeGenPasses->doInitialization();
2676 for(llvm::Module::iterator I = mModule->begin();
2677 I != mModule->end();
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002678 I++) {
2679 //LOGE("CODEGEN 1.");
2680 if(!I->isDeclaration()) {
2681 //LOGE("CODEGEN 2.");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002682 CodeGenPasses->run(*I);
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002683 //LOGE("CODEGEN 3.");
2684 }
2685 }
2686
2687 //LOGE("Before Finalization");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002688
2689 CodeGenPasses->doFinalization();
2690
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002691 //LOGE("After CODEGEN");
2692
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002693 /* Copy the global address mapping from code emitter and remapping */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002694 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
2695 if(ExportVarMetadata) {
2696 for(int i=0;i<ExportVarMetadata->getNumOperands();i++) {
2697 llvm::MDNode* ExportVar = ExportVarMetadata->getOperand(i);
2698 if(ExportVar != NULL && ExportVar->getNumOperands() > 1) {
2699 llvm::Value* ExportVarNameMDS = ExportVar->getOperand(0);
2700 if(ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
2701 llvm::StringRef ExportVarName =
2702 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
2703 CodeEmitter::global_addresses_const_iterator I;
2704 for(I = mCodeEmitter->global_address_begin();
2705 I != mCodeEmitter->global_address_end();
2706 I++)
2707 {
2708 if(I->first->getValueID() != llvm::Value::GlobalVariableVal)
2709 continue;
2710 if(ExportVarName == I->first->getName()) {
2711 mExportVars.push_back(I->second);
2712 break;
2713 }
2714 }
2715 if(I != mCodeEmitter->global_address_end())
2716 continue; // found
2717 }
2718 }
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002719 // if here, the global variable record in metadata is not
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002720 // found, make an empty slot
2721 mExportVars.push_back(NULL);
2722 }
2723 assert((mExportVars.size() == ExportVarMetadata->getNumOperands()) &&
2724 "Number of slots doesn't match the number of export variables!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002725 }
2726
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002727 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
2728 if(ExportFuncMetadata) {
2729 for(int i=0;i<ExportFuncMetadata->getNumOperands();i++) {
2730 llvm::MDNode* ExportFunc = ExportFuncMetadata->getOperand(i);
2731 if(ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
2732 llvm::Value* ExportFuncNameMDS = ExportFunc->getOperand(0);
2733 if(ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
2734 llvm::StringRef ExportFuncName =
2735 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
2736 mExportFuncs.push_back(mCodeEmitter->lookup(ExportFuncName));
2737 }
2738 }
2739 }
2740 }
2741
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002742 /*
2743 * Tell code emitter now can release the memory using
2744 * during the JIT since we have done the code emission
2745 */
2746 mCodeEmitter->releaseUnnecessary();
2747
2748 /*
2749 * Finally, read pragma information from the metadata node
2750 * of the @Module if any
2751 */
2752 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
2753 if(PragmaMetadata)
2754 for(int i=0;i<PragmaMetadata->getNumOperands();i++) {
2755 llvm::MDNode* Pragma = PragmaMetadata->getOperand(i);
2756 if(Pragma != NULL &&
2757 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
2758 llvm::Value* PragmaNameMDS = Pragma->getOperand(0);
2759 llvm::Value* PragmaValueMDS = Pragma->getOperand(1);
2760
2761 if((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
2762 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
2763 llvm::StringRef PragmaName =
2764 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
2765 llvm::StringRef PragmaValue =
2766 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
2767
2768 mPragmas.push_back( make_pair( std::string(PragmaName.data(),
2769 PragmaName.size()),
2770 std::string(PragmaValue.data(),
2771 PragmaValue.size())
2772 )
2773 );
2774 }
2775 }
2776 }
2777
2778 on_bcc_compile_error:
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002779 //LOGE("on_bcc_compiler_error");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002780 if (CodeGenPasses) {
2781 delete CodeGenPasses;
2782 } else if (TD) {
2783 delete TD;
2784 }
2785 if (TM)
2786 delete TM;
2787
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002788 if (mError.empty()) {
2789 return false;
2790 }
2791
2792 // LOGE(getErrorMessage());
2793 return true;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002794 }
2795
2796 /* interface for bccGetScriptInfoLog() */
2797 char* getErrorMessage() {
2798 return const_cast<char*>(mError.c_str());
2799 }
2800
2801 /* interface for bccGetScriptLabel() */
2802 void* lookup(const char* name) {
2803 void* addr = NULL;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002804 if(mCodeEmitter.get())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002805 /* Find function pointer */
2806 addr = mCodeEmitter->lookup(name);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002807 return addr;
2808 }
2809
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002810 /* Interface for bccGetExportVars() */
2811 void getExportVars(BCCsizei* actualVarCount,
2812 BCCsizei maxVarCount,
2813 BCCvoid** vars) {
2814 int varCount = mExportVars.size();
2815
2816 if(actualVarCount)
2817 *actualVarCount = varCount;
2818 if(varCount > maxVarCount)
2819 varCount = maxVarCount;
2820 if(vars)
2821 for(ExportVarList::const_iterator it = mExportVars.begin();
2822 it != mExportVars.end();
2823 it++)
2824 {
2825 *vars++ = *it;
2826 }
2827
2828 return;
2829 }
2830
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002831 /* Interface for bccGetExportFuncs() */
2832 void getExportFuncs(BCCsizei* actualFuncCount,
2833 BCCsizei maxFuncCount,
2834 BCCvoid** funcs) {
2835 int funcCount = mExportFuncs.size();
2836
2837 if(actualFuncCount)
2838 *actualFuncCount = funcCount;
2839 if(funcCount > maxFuncCount)
2840 funcCount = maxFuncCount;
2841 if(funcs)
2842 for(ExportFuncList::const_iterator it = mExportFuncs.begin();
2843 it != mExportFuncs.end();
2844 it++)
2845 {
2846 *funcs++ = *it;
2847 }
2848
2849 return;
2850 }
2851
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002852 /* Interface for bccGetPragmas() */
2853 void getPragmas(BCCsizei* actualStringCount,
2854 BCCsizei maxStringCount,
2855 BCCchar** strings) {
2856 int stringCount = mPragmas.size() * 2;
2857
2858 if(actualStringCount)
2859 *actualStringCount = stringCount;
2860 if(stringCount > maxStringCount)
2861 stringCount = maxStringCount;
2862 if(strings)
2863 for(PragmaList::const_iterator it = mPragmas.begin();
2864 stringCount > 0;
2865 stringCount-=2, it++)
2866 {
2867 *strings++ = (BCCchar*) it->first.c_str();
2868 *strings++ = (BCCchar*) it->second.c_str();
2869 }
2870
2871 return;
2872 }
2873
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002874 /* Interface for bccGetFunctions() */
2875 void getFunctions(BCCsizei* actualFunctionCount,
2876 BCCsizei maxFunctionCount,
2877 BCCchar** functions) {
2878 if(mCodeEmitter.get())
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002879 mCodeEmitter->getFunctionNames(actualFunctionCount,
2880 maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002881 functions);
2882 else
2883 *actualFunctionCount = 0;
2884
2885 return;
2886 }
2887
2888 /* Interface for bccGetFunctionBinary() */
2889 void getFunctionBinary(BCCchar* function,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002890 BCCvoid** base,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002891 BCCsizei* length) {
2892 if(mCodeEmitter.get()) {
2893 mCodeEmitter->getFunctionBinary(function, base, length);
2894 } else {
2895 *base = NULL;
2896 *length = 0;
2897 }
2898 return;
2899 }
2900
2901 inline const llvm::Module* getModule() const {
2902 return mModule;
2903 }
2904
2905 inline const std::vector<const llvm::Type*>& getTypes() const {
2906 return mTypes;
2907 }
2908
2909 ~Compiler() {
2910 delete mModule;
Shih-wei Liaobe5c5312010-05-09 05:30:09 -07002911 //llvm::llvm_shutdown();
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002912 delete mContext;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002913 return;
2914 }
2915}; /* End of Class Compiler */
2916
2917bool Compiler::GlobalInitialized = false;
2918
2919/* Code generation optimization level for the compiler */
2920llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
2921
2922std::string Compiler::Triple;
2923
2924std::string Compiler::CPU;
2925
2926std::vector<std::string> Compiler::Features;
2927
2928/*
2929 * The named of metadata node that pragma resides
2930 * (should be synced with slang.cpp)
2931 */
2932const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
2933
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002934/*
2935 * The named of metadata node that export variable name resides
2936 * (should be synced with slang.cpp)
2937 */
2938const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
2939
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002940/*
2941 * The named of metadata node that export function name resides
2942 * (should be synced with slang.cpp)
2943 */
2944const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
2945
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002946struct BCCscript {
2947 /*
2948 * Part I. Compiler
2949 */
2950
2951 Compiler compiler;
2952
2953 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid* pContext) {
2954 compiler.registerSymbolCallback(pFn, pContext);
2955 }
2956
2957 /*
2958 * Part II. Logistics & Error handling
2959 */
2960
2961 BCCscript() {
2962 bccError = BCC_NO_ERROR;
2963 }
2964
2965 ~BCCscript() {
2966 }
2967
2968 void setError(BCCenum error) {
2969 if (bccError == BCC_NO_ERROR && error != BCC_NO_ERROR) {
2970 bccError = error;
2971 }
2972 }
2973
2974 BCCenum getError() {
2975 BCCenum result = bccError;
2976 bccError = BCC_NO_ERROR;
2977 return result;
2978 }
2979
2980 BCCenum bccError;
2981};
2982
2983
2984extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002985BCCscript* bccCreateScript()
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002986{
2987 return new BCCscript();
2988}
2989
2990extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002991BCCenum bccGetError( BCCscript* script )
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002992{
2993 return script->getError();
2994}
2995
2996extern "C"
2997void bccDeleteScript(BCCscript* script) {
2998 delete script;
2999}
3000
3001extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003002void bccRegisterSymbolCallback(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003003 BCCSymbolLookupFn pFn,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003004 BCCvoid* pContext)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003005{
3006 script->registerSymbolCallback(pFn, pContext);
3007}
3008
3009extern "C"
3010void bccScriptBitcode(BCCscript* script,
3011 const BCCchar* bitcode,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003012 BCCint size)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003013{
3014 script->compiler.loadModule(bitcode, size);
3015}
3016
3017extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003018void bccCompileScript(BCCscript* script)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003019{
3020 int result = script->compiler.compile();
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003021 if (result)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003022 script->setError(BCC_INVALID_OPERATION);
3023}
3024
3025extern "C"
3026void bccGetScriptInfoLog(BCCscript* script,
3027 BCCsizei maxLength,
3028 BCCsizei* length,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003029 BCCchar* infoLog)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003030{
3031 char* message = script->compiler.getErrorMessage();
3032 int messageLength = strlen(message) + 1;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003033 if (length)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003034 *length = messageLength;
3035
3036 if (infoLog && maxLength > 0) {
3037 int trimmedLength = maxLength < messageLength ? maxLength : messageLength;
3038 memcpy(infoLog, message, trimmedLength);
3039 infoLog[trimmedLength] = 0;
3040 }
3041}
3042
3043extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003044void bccGetScriptLabel(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003045 const BCCchar * name,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003046 BCCvoid ** address)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003047{
3048 void* value = script->compiler.lookup(name);
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003049 if (value)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003050 *address = value;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003051 else
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003052 script->setError(BCC_INVALID_VALUE);
3053}
3054
3055extern "C"
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07003056void bccGetExportVars(BCCscript* script,
3057 BCCsizei* actualVarCount,
3058 BCCsizei maxVarCount,
3059 BCCvoid** vars)
3060{
3061 script->compiler.getExportVars(actualVarCount, maxVarCount, vars);
3062}
3063
3064extern "C"
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07003065void bccGetExportFuncs(BCCscript* script,
3066 BCCsizei* actualFuncCount,
3067 BCCsizei maxFuncCount,
3068 BCCvoid** funcs)
3069{
3070 script->compiler.getExportFuncs(actualFuncCount, maxFuncCount, funcs);
3071}
3072
3073extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003074void bccGetPragmas(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003075 BCCsizei* actualStringCount,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003076 BCCsizei maxStringCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003077 BCCchar** strings)
3078{
3079 script->compiler.getPragmas(actualStringCount, maxStringCount, strings);
3080}
3081
3082extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003083void bccGetFunctions(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003084 BCCsizei* actualFunctionCount,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003085 BCCsizei maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003086 BCCchar** functions)
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003087{
3088 script->compiler.getFunctions(actualFunctionCount,
3089 maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003090 functions);
3091}
3092
3093extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003094void bccGetFunctionBinary(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003095 BCCchar* function,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003096 BCCvoid** base,
3097 BCCsizei* length)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003098{
3099 script->compiler.getFunctionBinary(function, base, length);
3100}
3101
3102struct BCCtype {
3103 const Compiler* compiler;
3104 const llvm::Type* t;
3105};
3106
3107} /* End of namespace bcc */