blob: 1a561c23b245324f3744e0dbf863a36d51ccab1e [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;
Shih-wei Liaobe5c5312010-05-09 05:30:09 -0700253
254 static std::string mError;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700255 /*
256 * End of section of GlobalInitializing variables
257 **********************************************/
258
259 /* If given, the name of the target CPU to generate code for. */
260 static std::string CPU;
261
262 /*
263 * The list of target specific features to enable or disable -- this should
264 * be a list of strings starting with '+' (enable) or '-' (disable).
265 */
266 static std::vector<std::string> Features;
267
268 struct Runtime {
269 const char* mName;
270 void* mPtr;
271 };
272 static struct Runtime Runtimes[];
273
274 static void GlobalInitialization() {
275 if(GlobalInitialized) return;
Shih-wei Liaobe5c5312010-05-09 05:30:09 -0700276 LOGE("INIT");
277
278 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
279 // if (!llvm::llvm_is_multithreaded())
280 // llvm::llvm_start_multithreaded();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700281
282 /* Set Triple, CPU and Features here */
283 Triple = TARGET_TRIPLE_STRING;
284
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700285 /* TODO: NEON for JIT */
286 //Features.push_back("+neon");
287 //Features.push_back("+vmlx");
288 //Features.push_back("+neonfp");
Shih-wei Liao3cf39d12010-04-29 19:30:51 -0700289 Features.push_back("+vfp3");
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700290
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700291#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
292 LLVMInitializeARMTargetInfo();
293 LLVMInitializeARMTarget();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700294#if defined(USE_DISASSEMBLER)
295 LLVMInitializeARMDisassembler();
296 LLVMInitializeARMAsmPrinter();
297#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700298#endif
299
300#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN)
301 LLVMInitializeX86TargetInfo();
302 LLVMInitializeX86Target();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700303#if defined(USE_DISASSEMBLER)
304 LLVMInitializeX86Disassembler();
305 LLVMInitializeX86AsmPrinter();
306#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700307#endif
308
309#if defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
310 LLVMInitializeX86TargetInfo();
311 LLVMInitializeX86Target();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700312#if defined(USE_DISASSEMBLER)
313 LLVMInitializeX86Disassembler();
314 LLVMInitializeX86AsmPrinter();
315#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700316#endif
317
318 /*
319 * -O0: llvm::CodeGenOpt::None
320 * -O1: llvm::CodeGenOpt::Less
321 * -O2: llvm::CodeGenOpt::Default
322 * -O3: llvm::CodeGenOpt::Aggressive
323 */
324 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
325
326 /* Below are the global settings to LLVM */
327
328 /* Disable frame pointer elimination optimization */
329 llvm::NoFramePointerElim = false;
330
331 /*
332 * Use hardfloat ABI
333 *
334 * FIXME: Need to detect the CPU capability and decide whether to use
335 * softfp. To use softfp, change following 2 lines to
336 *
337 * llvm::FloatABIType = llvm::FloatABI::Soft;
338 * llvm::UseSoftFloat = true;
339 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700340 llvm::FloatABIType = llvm::FloatABI::Soft;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700341 llvm::UseSoftFloat = false;
342
343 /*
344 * BCC needs all unknown symbols resolved at JIT/compilation time.
345 * So we don't need any dynamic relocation model.
346 */
347 llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static);
348
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700349#if defined(DEFAULT_X64_CODEGEN)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700350 /* Data address in X86_64 architecture may reside in a far-away place */
351 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
352#else
353 /*
354 * This is set for the linker (specify how large of the virtual addresses
355 * we can access for all unknown symbols.)
356 */
357 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
358#endif
359
360 /* Register the scheduler */
361 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
362
363 /*
364 * Register allocation policy:
365 * createLocalRegisterAllocator: fast but bad quality
366 * createLinearScanRegisterAllocator: not so fast but good quality
367 */
368 llvm::RegisterRegAlloc::setDefault
369 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
370 llvm::createLocalRegisterAllocator :
371 llvm::createLinearScanRegisterAllocator);
372
373 GlobalInitialized = true;
374 return;
375 }
376
377 static void LLVMErrorHandler(void *UserData, const std::string &Message) {
378 // std::string* Error = static_cast<std::string*>(UserData);
379 // Error->assign(Message);
380 // return;
381 fprintf(stderr, "%s\n", Message.c_str());
382 exit(1);
383 }
384
385 static const llvm::StringRef PragmaMetadataName;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700386 static const llvm::StringRef ExportVarMetadataName;
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700387 static const llvm::StringRef ExportFuncMetadataName;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700388
389 private:
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700390 inline bool hasError() const {
391 return !mError.empty();
392 }
393 inline void setError(const char* Error) {
394 mError.assign(Error); // Copying
395 return;
396 }
397 inline void setError(const std::string& Error) {
398 mError = Error;
399 return;
400 }
401
402 typedef std::list< std::pair<std::string, std::string> > PragmaList;
403 PragmaList mPragmas;
404
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700405 typedef std::list<void*> ExportVarList;
406 ExportVarList mExportVars;
407
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700408 typedef std::list<void*> ExportFuncList;
409 ExportFuncList mExportFuncs;
410
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700411 /* Memory manager for the code reside in memory */
412 /*
413 * The memory for our code emitter is very simple and is conforming to the
414 * design decisions of Android RenderScript's Exection Environment:
415 * The code, data, and symbol sizes are limited (currently 100KB.)
416 *
417 * It's very different from typical compiler, which has no limitation
418 * on the code size. How does code emitter know the size of the code
419 * it is about to emit? It does not know beforehand. We want to solve
420 * this without complicating the code emitter too much.
421 *
422 * We solve this by pre-allocating a certain amount of memory,
423 * and then start the code emission. Once the buffer overflows, the emitter
424 * simply discards all the subsequent emission but still has a counter
425 * on how many bytes have been emitted.
426
427 * So once the whole emission is done, if there's a buffer overflow,
428 * it re-allocates the buffer with enough size (based on the
429 * counter from previous emission) and re-emit again.
430 */
431 class CodeMemoryManager : public llvm::JITMemoryManager {
432 /* {{{ */
433 private:
434 static const unsigned int MaxCodeSize = 100 * 1024; /* 100 KiB for code */
435 static const unsigned int MaxGOTSize = 1 * 1024; /* 1 KiB for global
436 offset table (GOT) */
437
438 /*
439 * Our memory layout is as follows:
440 *
441 * The direction of arrows (-> and <-) shows memory's growth direction
442 * when more space is needed.
443 *
444 * @mpCodeMem:
445 * +--------------------------------------------------------------+
446 * | Function Memory ... -> <- ... Global/Stub/GOT |
447 * +--------------------------------------------------------------+
448 * |<------------------ Total: @MaxCodeSize KiB ----------------->|
449 *
450 * Where size of GOT is @MaxGOTSize KiB.
451 *
452 * @mCurFuncMemIdx: The current index (starting from 0) of the last byte
453 * of function code's memoey usage
454 * @mCurGSGMemIdx: The current index (starting from 0) of the last byte
455 * of Global Stub/GOT's memory usage
456 *
457 */
458
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700459 uintptr_t mCurFuncMemIdx;
460 uintptr_t mCurGSGMemIdx;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700461 llvm::sys::MemoryBlock* mpCodeMem;
462
463 /* GOT Base */
464 uint8_t* mpGOTBase;
465
466 typedef std::map<const llvm::Function*, pair<void* /* start address */,
467 void* /* end address */>
468 > FunctionMapTy;
469 FunctionMapTy mFunctionMap;
470
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700471 inline uintptr_t getFreeMemSize() const {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700472 return mCurGSGMemIdx - mCurFuncMemIdx;
473 }
474 inline uint8_t* getCodeMemBase() const {
475 return static_cast<uint8_t*>(mpCodeMem->base());
476 }
477
478 uint8_t* allocateGSGMemory(uintptr_t Size,
479 unsigned Alignment = 1 /* no alignment */)
480 {
481 if(getFreeMemSize() < Size)
482 /* The code size excesses our limit */
483 return NULL;
484
485 if(Alignment == 0)
486 Alignment = 1;
487
488 uint8_t* result = getCodeMemBase() + mCurGSGMemIdx - Size;
489 result = (uint8_t*) (((intptr_t) result) & ~(intptr_t) (Alignment - 1));
490
491 mCurGSGMemIdx = result - getCodeMemBase();
492
493 return result;
494 }
495
496 public:
497 CodeMemoryManager() : mpCodeMem(NULL), mpGOTBase(NULL) {
498 reset();
499 std::string ErrMsg;
500 llvm::sys::MemoryBlock B = llvm::sys::Memory::
501 AllocateRWX(MaxCodeSize, NULL, &ErrMsg);
502 if(B.base() == 0)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700503 llvm::report_fatal_error(
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700504 "Failed to allocate Memory for code emitter\n" + ErrMsg
505 );
506 mpCodeMem = new llvm::sys::MemoryBlock(B.base(), B.size());
507
508 return;
509 }
510
511 /*
512 * setMemoryWritable - When code generation is in progress,
513 * the code pages may need permissions changed.
514 */
515 void setMemoryWritable() {
516 llvm::sys::Memory::setWritable(*mpCodeMem);
517 return;
518 }
519
520 /*
521 * setMemoryExecutable - When code generation is done and we're ready to
522 * start execution, the code pages may need permissions changed.
523 */
524 void setMemoryExecutable() {
525 llvm::sys::Memory::setExecutable(*mpCodeMem);
526 return;
527 }
528
529 /*
530 * setPoisonMemory - Setting this flag to true makes the memory manager
531 * garbage values over freed memory. This is useful for testing and
532 * debugging, and is to be turned on by default in debug mode.
533 */
534 void setPoisonMemory(bool poison) {
535 /* no effect */
536 return;
537 }
538
539 /* Global Offset Table Management */
540
541 /*
542 * AllocateGOT - If the current table requires a Global Offset Table, this
543 * method is invoked to allocate it. This method is required to set HasGOT
544 * to true.
545 */
546 void AllocateGOT() {
547 assert(mpGOTBase != NULL && "Cannot allocate the GOT multiple times");
548 mpGOTBase = allocateGSGMemory(MaxGOTSize);
549 HasGOT = true;
550 return;
551 }
552
553 /*
554 * getGOTBase - If this is managing a Global Offset Table, this method
555 * should return a pointer to its base.
556 */
557 uint8_t* getGOTBase() const {
558 return mpGOTBase;
559 }
560
561 /* Main Allocation Functions */
562
563 /*
564 * startFunctionBody - When we start JITing a function, the JIT calls this
565 * method to allocate a block of free RWX memory, which returns a pointer to
566 * it. If the JIT wants to request a block of memory of at least a certain
567 * size, it passes that value as ActualSize, and this method returns a block
568 * with at least that much space. If the JIT doesn't know ahead of time how
569 * much space it will need to emit the function, it passes 0 for the
570 * ActualSize. In either case, this method is required to pass back the size
571 * of the allocated block through ActualSize. The JIT will be careful to
572 * not write more than the returned ActualSize bytes of memory.
573 */
574 uint8_t* startFunctionBody(const llvm::Function *F, uintptr_t &ActualSize) {
575 if(getFreeMemSize() < ActualSize)
576 /* The code size excesses our limit */
577 return NULL;
578
579 ActualSize = getFreeMemSize();
580 return (getCodeMemBase() + mCurFuncMemIdx);
581 }
582
583 /*
584 * allocateStub - This method is called by the JIT to allocate space for a
585 * function stub (used to handle limited branch displacements) while it is
586 * JIT compiling a function. For example, if foo calls bar, and if bar
587 * either needs to be lazily compiled or is a native function that exists
588 * too
589 * far away from the call site to work, this method will be used to make a
590 * thunk for it. The stub should be "close" to the current function body,
591 * but should not be included in the 'actualsize' returned by
592 * startFunctionBody.
593 */
594 uint8_t* allocateStub(const llvm::GlobalValue* F, unsigned StubSize,
595 unsigned Alignment) {
596 return allocateGSGMemory(StubSize, Alignment);
597 }
598
599 /*
600 * endFunctionBody - This method is called when the JIT is done codegen'ing
601 * the specified function. At this point we know the size of the JIT
602 * compiled function. This passes in FunctionStart (which was returned by
603 * the startFunctionBody method) and FunctionEnd which is a pointer to the
604 * actual end of the function. This method should mark the space allocated
605 * and remember where it is in case the client wants to deallocate it.
606 */
607 void endFunctionBody(const llvm::Function* F, uint8_t* FunctionStart,
608 uint8_t* FunctionEnd) {
609 assert(FunctionEnd > FunctionStart);
610 assert(FunctionStart == (getCodeMemBase() + mCurFuncMemIdx) &&
611 "Mismatched function start/end!");
612
613 /* Advance the pointer */
614 intptr_t FunctionCodeSize = FunctionEnd - FunctionStart;
615 assert(FunctionCodeSize <= getFreeMemSize() &&
616 "Code size excess the limitation!");
617 mCurFuncMemIdx += FunctionCodeSize;
618
619 /* Record there's a function in our memory start from @FunctionStart */
620 assert(mFunctionMap.find(F) == mFunctionMap.end() &&
621 "Function already emitted!");
622 mFunctionMap.insert( make_pair<const llvm::Function*, pair<void*, void*>
623 >(F, make_pair(FunctionStart, FunctionEnd))
624 );
625
626 return;
627 }
628
629 /*
630 * allocateSpace - Allocate a (function code) memory block of the
631 * given size. This method cannot be called between
632 * calls to startFunctionBody and endFunctionBody.
633 */
634 uint8_t* allocateSpace(intptr_t Size, unsigned Alignment) {
635 if(getFreeMemSize() < Size)
636 /* The code size excesses our limit */
637 return NULL;
638
639 if(Alignment == 0)
640 Alignment = 1;
641
642 uint8_t* result = getCodeMemBase() + mCurFuncMemIdx;
643 result = (uint8_t*) (((intptr_t) result + Alignment - 1) &
644 ~(intptr_t) (Alignment - 1)
645 );
646
647 mCurFuncMemIdx = (result + Size) - getCodeMemBase();
648
649 return result;
650 }
651
652 /* allocateGlobal - Allocate memory for a global. */
653 uint8_t* allocateGlobal(uintptr_t Size, unsigned Alignment) {
654 return allocateGSGMemory(Size, Alignment);
655 }
656
657 /*
658 * deallocateFunctionBody - Free the specified function body. The argument
659 * must be the return value from a call to startFunctionBody() that hasn't
660 * been deallocated yet. This is never called when the JIT is currently
661 * emitting a function.
662 */
663 void deallocateFunctionBody(void *Body) {
664 /* linear search */
665 FunctionMapTy::iterator I;
666 for(I = mFunctionMap.begin();
667 I != mFunctionMap.end();
668 I++)
669 if(I->second.first == Body)
670 break;
671
672 assert(I != mFunctionMap.end() && "Memory is never allocated!");
673
674 /* free the memory */
675 uint8_t* FunctionStart = (uint8_t*) I->second.first;
676 uint8_t* FunctionEnd = (uint8_t*) I->second.second;
677 intptr_t SizeNeedMove = (getCodeMemBase() + mCurFuncMemIdx) - FunctionEnd;
678
679 assert(SizeNeedMove >= 0 &&
680 "Internal error: CodeMemoryManager::mCurFuncMemIdx may not"
681 " be correctly calculated!");
682
683 if(SizeNeedMove > 0)
684 /* there's data behind deallocating function */
685 ::memmove(FunctionStart, FunctionEnd, SizeNeedMove);
686 mCurFuncMemIdx -= (FunctionEnd - FunctionStart);
687
688 return;
689 }
690
691 /*
692 * startExceptionTable - When we finished JITing the function, if exception
693 * handling is set, we emit the exception table.
694 */
695 uint8_t* startExceptionTable(const llvm::Function* F, uintptr_t &ActualSize)
696 {
697 assert(false && "Exception is not allowed in our language specification");
698 return NULL;
699 }
700
701 /*
702 * endExceptionTable - This method is called when the JIT is done emitting
703 * the exception table.
704 */
705 void endExceptionTable(const llvm::Function *F, uint8_t *TableStart,
706 uint8_t *TableEnd, uint8_t* FrameRegister) {
707 assert(false && "Exception is not allowed in our language specification");
708 return;
709 }
710
711 /*
712 * deallocateExceptionTable - Free the specified exception table's memory.
713 * The argument must be the return value from a call to
714 * startExceptionTable()
715 * that hasn't been deallocated yet. This is never called when the JIT is
716 * currently emitting an exception table.
717 */
718 void deallocateExceptionTable(void *ET) {
719 assert(false && "Exception is not allowed in our language specification");
720 return;
721 }
722
723 /* Below are the methods we create */
724 void reset() {
725 mpGOTBase = NULL;
726 HasGOT = false;
727
728 mCurFuncMemIdx = 0;
729 mCurGSGMemIdx = MaxCodeSize - 1;
730
731 mFunctionMap.clear();
732
733 return;
734 }
735
736 ~CodeMemoryManager() {
737 if(mpCodeMem != NULL)
738 llvm::sys::Memory::ReleaseRWX(*mpCodeMem);
739 return;
740 }
741 /* }}} */
742 }; /* End of class CodeMemoryManager */
743
744 /* The memory manager for code emitter */
745 llvm::OwningPtr<CodeMemoryManager> mCodeMemMgr;
746 CodeMemoryManager* createCodeMemoryManager() {
747 mCodeMemMgr.reset(new CodeMemoryManager());
748 return mCodeMemMgr.get();
749 }
750
751 /* Code emitter */
752 class CodeEmitter : public llvm::JITCodeEmitter {
753 /* {{{ */
754 public:
755 typedef llvm::DenseMap<const llvm::GlobalValue*, void*> GlobalAddressMapTy;
756 typedef GlobalAddressMapTy::const_iterator global_addresses_const_iterator;
757
758 private:
759 CodeMemoryManager* mpMemMgr;
760
761 /* The JITInfo for the target we are compiling to */
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700762 const llvm::Target* mpTarget;
763
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700764 llvm::TargetJITInfo* mpTJI;
765
766 const llvm::TargetData* mpTD;
767
768 /*
769 * MBBLocations - This vector is a mapping from MBB ID's to their address.
770 * It is filled in by the StartMachineBasicBlock callback and queried by
771 * the getMachineBasicBlockAddress callback.
772 */
773 std::vector<uintptr_t> mMBBLocations;
774
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700775 /* mpConstantPool - The constant pool for the current function. */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700776 llvm::MachineConstantPool* mpConstantPool;
777
778 /* ConstantPoolBase - A pointer to the first entry in the constant pool. */
779 void *mpConstantPoolBase;
780
781 /* ConstPoolAddresses - Addresses of individual constant pool entries. */
782 llvm::SmallVector<uintptr_t, 8> mConstPoolAddresses;
783
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700784 /* mpJumpTable - The jump tables for the current function. */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700785 llvm::MachineJumpTableInfo *mpJumpTable;
786
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700787 /* mpJumpTableBase - A pointer to the first entry in the jump table. */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700788 void *mpJumpTableBase;
789
790 /*
791 * When outputting a function stub in the context of some other function, we
792 * save BufferBegin/BufferEnd/CurBufferPtr here.
793 */
794 uint8_t *mpSavedBufferBegin, *mpSavedBufferEnd, *mpSavedCurBufferPtr;
795
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700796 /* mRelocations - These are the relocations that the function needs,
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700797 as emitted. */
798 std::vector<llvm::MachineRelocation> mRelocations;
799
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700800 /* mLabelLocations - This vector is a mapping from Label ID's to their
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700801 address. */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700802 llvm::DenseMap<llvm::MCSymbol*, uintptr_t> mLabelLocations;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700803
804 class EmittedFunctionCode {
805 public:
806 void* FunctionBody; // Beginning of the function's allocation.
807 void* Code; // The address the function's code actually starts at.
808 int Size; // The size of the function code
809
810 EmittedFunctionCode() : FunctionBody(NULL), Code(NULL) { return; }
811 };
812 EmittedFunctionCode* mpCurEmitFunction;
813
814 typedef std::map<const std::string, EmittedFunctionCode*
815 > EmittedFunctionsMapTy;
816 EmittedFunctionsMapTy mEmittedFunctions;
817
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700818 /* mpMMI - Machine module info for exception informations */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700819 llvm::MachineModuleInfo* mpMMI;
820
821 GlobalAddressMapTy mGlobalAddressMap;
822
823 /*
824 * UpdateGlobalMapping - Replace an existing mapping for GV with a new
825 * address. This updates both maps as required. If "Addr" is null, the
826 * entry for the global is removed from the mappings.
827 */
828 void* UpdateGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
829 if(Addr == NULL) {
830 /* Removing mapping */
831 GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
832 void *OldVal;
833
834 if(I == mGlobalAddressMap.end())
835 OldVal = NULL;
836 else {
837 OldVal = I->second;
838 mGlobalAddressMap.erase(I);
839 }
840
841 return OldVal;
842 }
843
844 void*& CurVal = mGlobalAddressMap[GV];
845 void* OldVal = CurVal;
846
847 CurVal = Addr;
848
849 return OldVal;
850 }
851
852 /*
853 * AddGlobalMapping - Tell the execution engine that the specified global is
854 * at the specified location. This is used internally as functions are
855 * JIT'd
856 * and as global variables are laid out in memory.
857 */
858 void AddGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
859 void*& CurVal = mGlobalAddressMap[GV];
860 assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!");
861 CurVal = Addr;
862 return;
863 }
864
865 /*
866 * GetPointerToGlobalIfAvailable - This returns the address of the specified
867 * global value if it is has already been codegen'd,
868 * otherwise it returns null.
869 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700870 void* GetPointerToGlobalIfAvailable(const llvm::GlobalValue* GV) {
871 GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700872 return ((I != mGlobalAddressMap.end()) ? I->second : NULL);
873 }
874
875 unsigned int GetConstantPoolSizeInBytes(llvm::MachineConstantPool* MCP) {
876 const std::vector<llvm::MachineConstantPoolEntry>& Constants =
877 MCP->getConstants();
878
879 if(Constants.empty())
880 return 0;
881
882 unsigned int Size = 0;
883 for(int i=0;i<Constants.size();i++) {
884 llvm::MachineConstantPoolEntry CPE = Constants[i];
885 unsigned int AlignMask = CPE.getAlignment() - 1;
886 Size = (Size + AlignMask) & ~AlignMask;
887 const llvm::Type* Ty = CPE.getType();
888 Size += mpTD->getTypeAllocSize(Ty);
889 }
890
891 return Size;
892 }
893
894 /*
895 * This function converts a Constant* into a GenericValue. The interesting
896 * part is if C is a ConstantExpr.
897 */
898 void GetConstantValue(const llvm::Constant *C, llvm::GenericValue& Result) {
899 if(C->getValueID() == llvm::Value::UndefValueVal)
900 return;
901 else if(C->getValueID() == llvm::Value::ConstantExprVal) {
902 const llvm::ConstantExpr* CE = (llvm::ConstantExpr*) C;
903 const llvm::Constant* Op0 = CE->getOperand(0);
904
905 switch(CE->getOpcode()) {
906 case llvm::Instruction::GetElementPtr:
907 {
908 /* Compute the index */
909 llvm::SmallVector<llvm::Value*, 8> Indices(CE->op_begin() + 1,
910 CE->op_end());
911 uint64_t Offset = mpTD->getIndexedOffset(Op0->getType(),
912 &Indices[0],
913 Indices.size());
914
915 GetConstantValue(Op0, Result);
916 Result.PointerVal = (char*) Result.PointerVal + Offset;
917
918 return;
919 }
920 break;
921
922 case llvm::Instruction::Trunc:
923 {
924 uint32_t BitWidth =
925 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
926
927 GetConstantValue(Op0, Result);
928 Result.IntVal = Result.IntVal.trunc(BitWidth);
929
930 return;
931 }
932 break;
933
934 case llvm::Instruction::ZExt:
935 {
936 uint32_t BitWidth =
937 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
938
939 GetConstantValue(Op0, Result);
940 Result.IntVal = Result.IntVal.zext(BitWidth);
941
942 return;
943 }
944 break;
945
946 case llvm::Instruction::SExt:
947 {
948 uint32_t BitWidth =
949 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
950
951 GetConstantValue(Op0, Result);
952 Result.IntVal = Result.IntVal.sext(BitWidth);
953
954 return;
955 }
956 break;
957
958
959 case llvm::Instruction::FPTrunc:
960 {
961 /* FIXME long double */
962 GetConstantValue(Op0, Result);
963 Result.FloatVal = float(Result.DoubleVal);
964 return;
965 }
966 break;
967
968
969 case llvm::Instruction::FPExt:
970 {
971 /* FIXME long double */
972 GetConstantValue(Op0, Result);
973 Result.DoubleVal = double(Result.FloatVal);
974 return;
975 }
976 break;
977
978
979 case llvm::Instruction::UIToFP:
980 {
981 GetConstantValue(Op0, Result);
982 if(CE->getType()->isFloatTy())
983 Result.FloatVal = float(Result.IntVal.roundToDouble());
984 else if(CE->getType()->isDoubleTy())
985 Result.DoubleVal = Result.IntVal.roundToDouble();
986 else if(CE->getType()->isX86_FP80Ty()) {
987 const uint64_t zero[] = { 0, 0 };
988 llvm::APFloat apf = llvm::APFloat(llvm::APInt(80, 2, zero));
989 apf.convertFromAPInt(Result.IntVal,
990 false,
991 llvm::APFloat::rmNearestTiesToEven);
992 Result.IntVal = apf.bitcastToAPInt();
993 }
994 return;
995 }
996 break;
997
998 case llvm::Instruction::SIToFP:
999 {
1000 GetConstantValue(Op0, Result);
1001 if(CE->getType()->isFloatTy())
1002 Result.FloatVal = float(Result.IntVal.signedRoundToDouble());
1003 else if(CE->getType()->isDoubleTy())
1004 Result.DoubleVal = Result.IntVal.signedRoundToDouble();
1005 else if(CE->getType()->isX86_FP80Ty()) {
1006 const uint64_t zero[] = { 0, 0 };
1007 llvm::APFloat apf = llvm::APFloat(llvm::APInt(80, 2, zero));
1008 apf.convertFromAPInt(Result.IntVal,
1009 true,
1010 llvm::APFloat::rmNearestTiesToEven);
1011 Result.IntVal = apf.bitcastToAPInt();
1012 }
1013 return;
1014 }
1015 break;
1016
1017 /* double->APInt conversion handles sign */
1018 case llvm::Instruction::FPToUI:
1019 case llvm::Instruction::FPToSI:
1020 {
1021 uint32_t BitWidth =
1022 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
1023
1024 GetConstantValue(Op0, Result);
1025 if(Op0->getType()->isFloatTy())
1026 Result.IntVal =
1027 llvm::APIntOps::RoundFloatToAPInt(Result.FloatVal, BitWidth);
1028 else if(Op0->getType()->isDoubleTy())
1029 Result.IntVal =
1030 llvm::APIntOps::RoundDoubleToAPInt(Result.DoubleVal, BitWidth);
1031 else if(Op0->getType()->isX86_FP80Ty()) {
1032 llvm::APFloat apf = llvm::APFloat(Result.IntVal);
1033 uint64_t v;
1034 bool ignored;
1035 apf.convertToInteger(&v,
1036 BitWidth,
1037 CE->getOpcode()
1038 == llvm::Instruction::FPToSI,
1039 llvm::APFloat::rmTowardZero,
1040 &ignored);
1041 Result.IntVal = v; // endian?
1042 }
1043 return;
1044 }
1045 break;
1046
1047 case llvm::Instruction::PtrToInt:
1048 {
1049 uint32_t PtrWidth = mpTD->getPointerSizeInBits();
1050
1051 GetConstantValue(Op0, Result);
1052 Result.IntVal = llvm::APInt(PtrWidth, uintptr_t
1053 (Result.PointerVal));
1054
1055 return;
1056 }
1057 break;
1058
1059 case llvm::Instruction::IntToPtr:
1060 {
1061 uint32_t PtrWidth = mpTD->getPointerSizeInBits();
1062
1063 GetConstantValue(Op0, Result);
1064 if(PtrWidth != Result.IntVal.getBitWidth())
1065 Result.IntVal = Result.IntVal.zextOrTrunc(PtrWidth);
1066 assert(Result.IntVal.getBitWidth() <= 64 && "Bad pointer width");
1067
1068 Result.PointerVal = llvm::PointerTy
1069 (uintptr_t(Result.IntVal.getZExtValue()));
1070
1071 return;
1072 }
1073 break;
1074
1075 case llvm::Instruction::BitCast:
1076 {
1077 GetConstantValue(Op0, Result);
1078 const llvm::Type* DestTy = CE->getType();
1079
1080 switch(Op0->getType()->getTypeID()) {
1081 case llvm::Type::IntegerTyID:
1082 assert(DestTy->isFloatingPointTy() && "invalid bitcast");
1083 if(DestTy->isFloatTy())
1084 Result.FloatVal = Result.IntVal.bitsToFloat();
1085 else if(DestTy->isDoubleTy())
1086 Result.DoubleVal = Result.IntVal.bitsToDouble();
1087 break;
1088
1089 case llvm::Type::FloatTyID:
1090 assert(DestTy->isIntegerTy(32) && "Invalid bitcast");
1091 Result.IntVal.floatToBits(Result.FloatVal);
1092 break;
1093
1094 case llvm::Type::DoubleTyID:
1095 assert(DestTy->isIntegerTy(64) && "Invalid bitcast");
1096 Result.IntVal.doubleToBits(Result.DoubleVal);
1097 break;
1098
1099 case llvm::Type::PointerTyID:
1100 assert(DestTy->isPointerTy() && "Invalid bitcast");
1101 break; // getConstantValue(Op0) above already converted it
1102
1103 default:
1104 llvm_unreachable("Invalid bitcast operand");
1105 break;
1106 }
1107
1108 return;
1109 }
1110 break;
1111
1112 case llvm::Instruction::Add:
1113 case llvm::Instruction::FAdd:
1114 case llvm::Instruction::Sub:
1115 case llvm::Instruction::FSub:
1116 case llvm::Instruction::Mul:
1117 case llvm::Instruction::FMul:
1118 case llvm::Instruction::UDiv:
1119 case llvm::Instruction::SDiv:
1120 case llvm::Instruction::URem:
1121 case llvm::Instruction::SRem:
1122 case llvm::Instruction::And:
1123 case llvm::Instruction::Or:
1124 case llvm::Instruction::Xor:
1125 {
1126 llvm::GenericValue LHS, RHS;
1127 GetConstantValue(Op0, LHS);
1128 GetConstantValue(CE->getOperand(1), RHS);
1129
1130 switch(Op0->getType()->getTypeID()) {
1131 case llvm::Type::IntegerTyID:
1132 switch (CE->getOpcode()) {
1133 case llvm::Instruction::Add:
1134 Result.IntVal = LHS.IntVal + RHS.IntVal;
1135 break;
1136 case llvm::Instruction::Sub:
1137 Result.IntVal = LHS.IntVal - RHS.IntVal;
1138 break;
1139 case llvm::Instruction::Mul:
1140 Result.IntVal = LHS.IntVal * RHS.IntVal;
1141 break;
1142 case llvm::Instruction::UDiv:
1143 Result.IntVal = LHS.IntVal.udiv(RHS.IntVal);
1144 break;
1145 case llvm::Instruction::SDiv:
1146 Result.IntVal = LHS.IntVal.sdiv(RHS.IntVal);
1147 break;
1148 case llvm::Instruction::URem:
1149 Result.IntVal = LHS.IntVal.urem(RHS.IntVal);
1150 break;
1151 case llvm::Instruction::SRem:
1152 Result.IntVal = LHS.IntVal.srem(RHS.IntVal);
1153 break;
1154 case llvm::Instruction::And:
1155 Result.IntVal = LHS.IntVal & RHS.IntVal;
1156 break;
1157 case llvm::Instruction::Or:
1158 Result.IntVal = LHS.IntVal | RHS.IntVal;
1159 break;
1160 case llvm::Instruction::Xor:
1161 Result.IntVal = LHS.IntVal ^ RHS.IntVal;
1162 break;
1163 default:
1164 llvm_unreachable("Invalid integer opcode");
1165 break;
1166 }
1167 break;
1168
1169 case llvm::Type::FloatTyID:
1170 switch (CE->getOpcode()) {
1171 case llvm::Instruction::FAdd:
1172 Result.FloatVal = LHS.FloatVal + RHS.FloatVal;
1173 break;
1174 case llvm::Instruction::FSub:
1175 Result.FloatVal = LHS.FloatVal - RHS.FloatVal;
1176 break;
1177 case llvm::Instruction::FMul:
1178 Result.FloatVal = LHS.FloatVal * RHS.FloatVal;
1179 break;
1180 case llvm::Instruction::FDiv:
1181 Result.FloatVal = LHS.FloatVal / RHS.FloatVal;
1182 break;
1183 case llvm::Instruction::FRem:
1184 Result.FloatVal = ::fmodf(LHS.FloatVal, RHS.FloatVal);
1185 break;
1186 default:
1187 llvm_unreachable("Invalid float opcode");
1188 break;
1189 }
1190 break;
1191
1192 case llvm::Type::DoubleTyID:
1193 switch (CE->getOpcode()) {
1194 case llvm::Instruction::FAdd:
1195 Result.DoubleVal = LHS.DoubleVal + RHS.DoubleVal;
1196 break;
1197 case llvm::Instruction::FSub:
1198 Result.DoubleVal = LHS.DoubleVal - RHS.DoubleVal;
1199 break;
1200 case llvm::Instruction::FMul:
1201 Result.DoubleVal = LHS.DoubleVal * RHS.DoubleVal;
1202 break;
1203 case llvm::Instruction::FDiv:
1204 Result.DoubleVal = LHS.DoubleVal / RHS.DoubleVal;
1205 break;
1206 case llvm::Instruction::FRem:
1207 Result.DoubleVal = ::fmod(LHS.DoubleVal, RHS.DoubleVal);
1208 break;
1209 default:
1210 llvm_unreachable("Invalid double opcode");
1211 break;
1212 }
1213 break;
1214
1215 case llvm::Type::X86_FP80TyID:
1216 case llvm::Type::PPC_FP128TyID:
1217 case llvm::Type::FP128TyID:
1218 {
1219 llvm::APFloat apfLHS = llvm::APFloat(LHS.IntVal);
1220 switch (CE->getOpcode()) {
1221 case llvm::Instruction::FAdd:
1222 apfLHS.add(llvm::APFloat(RHS.IntVal),
1223 llvm::APFloat::rmNearestTiesToEven);
1224 break;
1225 case llvm::Instruction::FSub:
1226 apfLHS.subtract(llvm::APFloat(RHS.IntVal),
1227 llvm::APFloat::rmNearestTiesToEven);
1228 break;
1229 case llvm::Instruction::FMul:
1230 apfLHS.multiply(llvm::APFloat(RHS.IntVal),
1231 llvm::APFloat::rmNearestTiesToEven);
1232 break;
1233 case llvm::Instruction::FDiv:
1234 apfLHS.divide(llvm::APFloat(RHS.IntVal),
1235 llvm::APFloat::rmNearestTiesToEven);
1236 break;
1237 case llvm::Instruction::FRem:
1238 apfLHS.mod(llvm::APFloat(RHS.IntVal),
1239 llvm::APFloat::rmNearestTiesToEven);
1240 break;
1241 default:
1242 llvm_unreachable("Invalid long double opcode");
1243 llvm_unreachable(0);
1244 break;
1245 }
1246
1247 Result.IntVal = apfLHS.bitcastToAPInt();
1248 }
1249 break;
1250
1251 default:
1252 llvm_unreachable("Bad add type!");
1253 break;
1254 } /* End switch(Op0->getType()->getTypeID()) */
1255
1256 return;
1257 }
1258
1259 default:
1260 break;
1261 } /* End switch(CE->getOpcode()) */
1262
1263 std::string msg;
1264 llvm::raw_string_ostream Msg(msg);
1265 Msg << "ConstantExpr not handled: " << *CE;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001266 llvm::report_fatal_error(Msg.str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001267 } /* C->getValueID() == llvm::Value::ConstantExprVal */
1268
1269 switch (C->getType()->getTypeID()) {
1270 case llvm::Type::FloatTyID:
1271 Result.FloatVal = llvm::cast<llvm::ConstantFP>(C)
1272 ->getValueAPF().convertToFloat();
1273 break;
1274
1275 case llvm::Type::DoubleTyID:
1276 Result.DoubleVal = llvm::cast<llvm::ConstantFP>(C)
1277 ->getValueAPF().convertToDouble();
1278 break;
1279
1280 case llvm::Type::X86_FP80TyID:
1281 case llvm::Type::FP128TyID:
1282 case llvm::Type::PPC_FP128TyID:
1283 Result.IntVal = llvm::cast <llvm::ConstantFP>(C)
1284 ->getValueAPF().bitcastToAPInt();
1285 break;
1286
1287 case llvm::Type::IntegerTyID:
1288 Result.IntVal = llvm::cast<llvm::ConstantInt>(C)
1289 ->getValue();
1290 break;
1291
1292 case llvm::Type::PointerTyID:
1293 switch(C->getValueID()) {
1294 case llvm::Value::ConstantPointerNullVal:
1295 Result.PointerVal = NULL;
1296 break;
1297
1298 case llvm::Value::FunctionVal:
1299 {
1300 const llvm::Function* F = (llvm::Function*) C;
1301 Result.PointerVal = GetPointerToFunctionOrStub
1302 (const_cast<llvm::Function*>(F)
1303 );
1304 }
1305 break;
1306
1307 case llvm::Value::GlobalVariableVal:
1308 {
1309 const llvm::GlobalVariable* GV = (llvm::GlobalVariable*) C;
1310 Result.PointerVal = GetOrEmitGlobalVariable
1311 (const_cast<llvm::GlobalVariable*>(GV)
1312 );
1313 }
1314 break;
1315
1316 case llvm::Value::BlockAddressVal:
1317 {
1318 // const llvm::BlockAddress* BA = (llvm::BlockAddress*) C;
1319 // Result.PointerVal = getPointerToBasicBlock
1320 // (const_cast<llvm::BasicBlock*>(BA->getBasicBlock()));
1321 assert(false && "JIT does not support address-of-label yet!");
1322 }
1323 break;
1324
1325 default:
1326 llvm_unreachable("Unknown constant pointer type!");
1327 break;
1328 }
1329 break;
1330
1331 default:
1332 std::string msg;
1333 llvm::raw_string_ostream Msg(msg);
1334 Msg << "ERROR: Constant unimplemented for type: " << *C->getType();
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001335 llvm::report_fatal_error(Msg.str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001336 break;
1337 }
1338
1339 return;
1340 }
1341
1342 /*
1343 * StoreValueToMemory -
1344 * Stores the data in @Val of type @Ty at address @Addr.
1345 */
1346 void StoreValueToMemory(const llvm::GenericValue& Val, void* Addr,
1347 const llvm::Type *Ty) {
1348 const unsigned int StoreBytes = mpTD->getTypeStoreSize(Ty);
1349
1350 switch(Ty->getTypeID()) {
1351 case llvm::Type::IntegerTyID:
1352 {
1353 const llvm::APInt& IntVal = Val.IntVal;
1354 assert((IntVal.getBitWidth() + 7) / 8 >= StoreBytes &&
1355 "Integer too small!");
1356
1357 uint8_t *Src = (uint8_t*) IntVal.getRawData();
1358
1359 if(llvm::sys::isLittleEndianHost()) {
1360 /*
1361 * Little-endian host - the source is ordered from LSB to MSB.
1362 * Order the destination from LSB to MSB: Do a straight copy.
1363 */
1364 memcpy(Addr, Src, StoreBytes);
1365 } else {
1366 /*
1367 * Big-endian host - the source is an array of 64 bit words
1368 * ordered from LSW to MSW.
1369 *
1370 * Each word is ordered from MSB to LSB.
1371 *
1372 * Order the destination from MSB to LSB:
1373 * Reverse the word order, but not the bytes in a word.
1374 */
1375 unsigned int i = StoreBytes;
1376 while(i > sizeof(uint64_t)) {
1377 i -= sizeof(uint64_t);
1378 memcpy((uint8_t*) Addr + i, Src, sizeof(uint64_t));
1379 Src += sizeof(uint64_t);
1380 }
1381
1382 memcpy(Addr, Src + sizeof(uint64_t) - i, i);
1383 }
1384 }
1385 break;
1386
1387 case llvm::Type::FloatTyID:
1388 {
1389 *((float*) Addr) = Val.FloatVal;
1390 }
1391 break;
1392
1393 case llvm::Type::DoubleTyID:
1394 {
1395 *((double*) Addr) = Val.DoubleVal;
1396 }
1397 break;
1398
1399 case llvm::Type::X86_FP80TyID:
1400 {
1401 memcpy(Addr, Val.IntVal.getRawData(), 10);
1402 }
1403 break;
1404
1405 case llvm::Type::PointerTyID:
1406 {
1407 /*
1408 * Ensure 64 bit target pointers are fully
1409 * initialized on 32 bit hosts.
1410 */
1411 if(StoreBytes != sizeof(llvm::PointerTy))
1412 memset(Addr, 0, StoreBytes);
1413 *((llvm::PointerTy*) Addr) = Val.PointerVal;
1414 }
1415 break;
1416
1417 default:
1418 break;
1419 }
1420
1421 if(llvm::sys::isLittleEndianHost() != mpTD->isLittleEndian())
1422 std::reverse((uint8_t*) Addr, (uint8_t*) Addr + StoreBytes);
1423
1424 return;
1425 }
1426
1427 /*
1428 * InitializeConstantToMemory -
1429 * Recursive function to apply a @Constant value into the
1430 * specified memory location @Addr.
1431 */
1432 void InitializeConstantToMemory(const llvm::Constant *C, void *Addr) {
1433 switch(C->getValueID()) {
1434 case llvm::Value::UndefValueVal:
1435 // Nothing to do
1436 break;
1437
1438 case llvm::Value::ConstantVectorVal:
1439 {
1440 // dynamic cast may hurt performance
1441 const llvm::ConstantVector* CP = (llvm::ConstantVector*) C;
1442
1443 unsigned int ElementSize = mpTD->getTypeAllocSize
1444 (CP->getType()->getElementType());
1445
1446 for(int i=0;i<CP->getNumOperands();i++)
1447 InitializeConstantToMemory(CP->getOperand(i),
1448 (char*) Addr + i * ElementSize);
1449 }
1450 break;
1451
1452 case llvm::Value::ConstantAggregateZeroVal:
1453 memset(Addr, 0, (size_t) mpTD->getTypeAllocSize(C->getType()));
1454 break;
1455
1456 case llvm::Value::ConstantArrayVal:
1457 {
1458 const llvm::ConstantArray* CPA = (llvm::ConstantArray*) C;
1459 unsigned int ElementSize = mpTD->getTypeAllocSize
1460 (CPA->getType()->getElementType());
1461
1462 for(int i=0;i<CPA->getNumOperands();i++)
1463 InitializeConstantToMemory(CPA->getOperand(i),
1464 (char*) Addr + i * ElementSize);
1465 }
1466 break;
1467
1468 case llvm::Value::ConstantStructVal:
1469 {
1470 const llvm::ConstantStruct* CPS = (llvm::ConstantStruct*) C;
1471 const llvm::StructLayout* SL = mpTD->getStructLayout
1472 (llvm::cast<llvm::StructType>(CPS->getType()));
1473
1474 for(int i=0;i<CPS->getNumOperands();i++)
1475 InitializeConstantToMemory(CPS->getOperand(i),
1476 (char*) Addr +
1477 SL->getElementOffset(i));
1478 }
1479 break;
1480
1481 default:
1482 {
1483 if(C->getType()->isFirstClassType()) {
1484 llvm::GenericValue Val;
1485 GetConstantValue(C, Val);
1486 StoreValueToMemory(Val, Addr, C->getType());
1487 } else
1488 llvm_unreachable
1489 ("Unknown constant type to initialize memory with!");
1490 }
1491 break;
1492 }
1493
1494 return;
1495 }
1496
1497 void emitConstantPool(llvm::MachineConstantPool *MCP) {
1498 if(mpTJI->hasCustomConstantPool())
1499 return;
1500
1501 /*
1502 * Constant pool address resolution is handled by the target itself in ARM
1503 * (TargetJITInfo::hasCustomConstantPool() return true).
1504 */
1505#if !defined(PROVIDE_ARM_CODEGEN)
1506 const std::vector<llvm::MachineConstantPoolEntry>& Constants =
1507 MCP->getConstants();
1508
1509 if(Constants.empty())
1510 return;
1511
1512 unsigned Size = GetConstantPoolSizeInBytes(MCP);
1513 unsigned Align = MCP->getConstantPoolAlignment();
1514
1515 mpConstantPoolBase = allocateSpace(Size, Align);
1516 mpConstantPool = MCP;
1517
1518 if(mpConstantPoolBase == NULL)
1519 return; /* out of memory */
1520
1521 unsigned Offset = 0;
1522 for(int i=0;i<Constants.size();i++) {
1523 llvm::MachineConstantPoolEntry CPE = Constants[i];
1524 unsigned AlignMask = CPE.getAlignment() - 1;
1525 Offset = (Offset + AlignMask) & ~AlignMask;
1526
1527 uintptr_t CAddr = (uintptr_t) mpConstantPoolBase + Offset;
1528 mConstPoolAddresses.push_back(CAddr);
1529
1530 if(CPE.isMachineConstantPoolEntry())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001531 llvm::report_fatal_error
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001532 ("Initialize memory with machine specific constant pool"
1533 " entry has not been implemented!");
1534
1535 InitializeConstantToMemory(CPE.Val.ConstVal, (void*) CAddr);
1536
1537 const llvm::Type *Ty = CPE.Val.ConstVal->getType();
1538 Offset += mpTD->getTypeAllocSize(Ty);
1539 }
1540#endif
1541 return;
1542 }
1543
1544 void initJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
1545 if(mpTJI->hasCustomJumpTables())
1546 return;
1547
1548 const std::vector<llvm::MachineJumpTableEntry>& JT =
1549 MJTI->getJumpTables();
1550 if(JT.empty())
1551 return;
1552
1553 unsigned NumEntries = 0;
1554 for(int i=0;i<JT.size();i++)
1555 NumEntries += JT[i].MBBs.size();
1556
1557 unsigned EntrySize = MJTI->getEntrySize(*mpTD);
1558
1559 mpJumpTable = MJTI;;
1560 mpJumpTableBase = allocateSpace(NumEntries * EntrySize,
1561 MJTI->getEntryAlignment(*mpTD));
1562
1563 return;
1564 }
1565
1566 void emitJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
1567 if(mpTJI->hasCustomJumpTables())
1568 return;
1569
1570 const std::vector<llvm::MachineJumpTableEntry>& JT =
1571 MJTI->getJumpTables();
1572 if(JT.empty() || mpJumpTableBase == 0)
1573 return;
1574
1575 assert((llvm::TargetMachine::getRelocationModel() == llvm::Reloc::Static)
1576 && "Cross JIT'ing?");
1577 assert(MJTI->getEntrySize(*mpTD) == sizeof(void*) && "Cross JIT'ing?");
1578
1579 /*
1580 * For each jump table, map each target in the jump table to the
1581 * address of an emitted MachineBasicBlock.
1582 */
1583 intptr_t *SlotPtr = (intptr_t*) mpJumpTableBase;
1584 for(int i=0;i<JT.size();i++) {
1585 const std::vector<llvm::MachineBasicBlock*>& MBBs = JT[i].MBBs;
1586 /*
1587 * Store the address of the basic block for this jump table slot in the
1588 * memory we allocated for the jump table in 'initJumpTableInfo'
1589 */
1590 for(int j=0;j<MBBs.size();j++)
1591 *SlotPtr++ = getMachineBasicBlockAddress(MBBs[j]);
1592 }
1593 }
1594
1595 void* GetPointerToGlobal(llvm::GlobalValue* V, void* Reference,
1596 bool MayNeedFarStub) {
1597 switch(V->getValueID()) {
1598 case llvm::Value::FunctionVal:
1599 {
1600 llvm::Function* F = (llvm::Function*) V;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001601
Shih-wei Liao800e9c22010-04-18 16:08:16 -07001602 /* If we have code, go ahead and return that. */
1603 if(void* ResultPtr = GetPointerToGlobalIfAvailable(F))
1604 return ResultPtr;
1605
1606 if(void* FnStub = GetLazyFunctionStubIfAvailable(F))
1607 /*
1608 * Return the function stub if it's already created.
1609 * We do this first so that:
1610 * we're returning the same address for the function
1611 * as any previous call.
1612 *
1613 * TODO: Yes, this is wrong. The lazy stub isn't guaranteed
1614 * to be close enough to call.
1615 */
1616 return FnStub;
1617
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001618 /*
1619 * If we know the target can handle arbitrary-distance calls, try to
1620 * return a direct pointer.
1621 */
1622 if(!MayNeedFarStub) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001623 /*
1624 * x86_64 architecture may encounter the bug
1625 * http://hlvm.llvm.org/bugs/show_bug.cgi?id=5201
1626 * which generate instruction "call" instead of "callq".
1627 *
1628 * And once the real address of stub is
1629 * greater than 64-bit long, the replacement will truncate
1630 * to 32-bit resulting a serious problem.
1631 */
1632#if !defined(__x86_64__)
1633 /*
1634 * If this is an external function pointer,
1635 * we can force the JIT to
1636 * 'compile' it, which really just adds it to the map.
1637 */
1638 if(F->isDeclaration() || F->hasAvailableExternallyLinkage())
1639 return GetPointerToFunction(F, /* AbortOnFailure */true);
1640#endif
1641 }
1642
1643 /*
1644 * Otherwise, we may need a to emit a stub, and, conservatively, we
1645 * always do so.
1646 */
1647 return GetLazyFunctionStub(F);
1648 }
1649 break;
1650
1651 case llvm::Value::GlobalVariableVal:
1652 return GetOrEmitGlobalVariable((llvm::GlobalVariable*) V);
1653 break;
1654
1655 case llvm::Value::GlobalAliasVal:
1656 {
1657 llvm::GlobalAlias* GA = (llvm::GlobalAlias*) V;
1658 const llvm::GlobalValue* GV = GA->resolveAliasedGlobal(false);
1659
1660 switch(GV->getValueID()) {
1661 case llvm::Value::FunctionVal:
1662 /* FIXME: is there's any possibility that the function
1663 is not code-gen'd? */
1664 return GetPointerToFunction(
1665 const_cast<llvm::Function*>((const llvm::Function*) GV),
1666 /* AbortOnFailure */true
1667 );
1668 break;
1669
1670 case llvm::Value::GlobalVariableVal:
1671 {
1672 if(void* p = mGlobalAddressMap[GV])
1673 return p;
1674
1675 llvm::GlobalVariable* GVar = (llvm::GlobalVariable*) GV;
1676 EmitGlobalVariable(GVar);
1677
1678 return mGlobalAddressMap[GV];
1679 }
1680 break;
1681
1682 case llvm::Value::GlobalAliasVal:
1683 assert(false && "Alias should be resolved ultimately!");
1684 break;
1685 }
1686 }
1687 break;
1688
1689 default:
1690 break;
1691 }
1692
1693 llvm_unreachable("Unknown type of global value!");
1694
1695 }
1696
1697 /*
1698 * GetPointerToFunctionOrStub - If the specified function has been
1699 * code-gen'd, return a pointer to the function.
1700 * If not, compile it, or use
1701 * a stub to implement lazy compilation if available.
1702 */
1703 void* GetPointerToFunctionOrStub(llvm::Function* F) {
1704 /*
1705 * If we have already code generated the function,
1706 * just return the address.
1707 */
1708 if(void* Addr = GetPointerToGlobalIfAvailable(F))
1709 return Addr;
1710
1711 /* Get a stub if the target supports it. */
1712 return GetLazyFunctionStub(F);
1713 }
1714
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001715 typedef llvm::DenseMap<const llvm::Function*, void*> FunctionToLazyStubMapTy;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001716 FunctionToLazyStubMapTy mFunctionToLazyStubMap;
1717
1718 void* GetLazyFunctionStubIfAvailable(llvm::Function* F) {
1719 return mFunctionToLazyStubMap.lookup(F);
1720 }
1721
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001722 std::set<const llvm::Function*> PendingFunctions;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001723 void* GetLazyFunctionStub(llvm::Function* F) {
1724 /* If we already have a lazy stub for this function, recycle it. */
1725 void*& Stub = mFunctionToLazyStubMap[F];
1726 if(Stub)
1727 return Stub;
1728
1729 /*
1730 * In any cases, we should NOT resolve function at runtime
1731 * (though we are able to).
1732 * We resolve this right now.
1733 */
1734 void* Actual = NULL;
1735 if(F->isDeclaration() || F->hasAvailableExternallyLinkage())
1736 Actual = GetPointerToFunction(F, /* AbortOnFailure */true);
1737
1738 /*
1739 * Codegen a new stub, calling the actual address of
1740 * the external function, if it was resolved.
1741 */
1742 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
1743 startGVStub(F, SL.Size, SL.Alignment);
1744 Stub = mpTJI->emitFunctionStub(F, Actual, *this);
1745 finishGVStub();
1746
1747 /*
1748 * We really want the address of the stub in the GlobalAddressMap
1749 * for the JIT, not the address of the external function.
1750 */
1751 UpdateGlobalMapping(F, Stub);
1752
1753 if(!Actual)
1754 PendingFunctions.insert(F);
1755 else
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001756 Disassemble(F->getName(), (uint8_t*) Stub, SL.Size, true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001757
1758 return Stub;
1759 }
1760
1761 /* Our resolver to undefined symbol */
1762 BCCSymbolLookupFn mpSymbolLookupFn;
1763 void* mpSymbolLookupContext;
1764
1765 void* GetPointerToFunction(llvm::Function* F, bool AbortOnFailure) {
1766 void* Addr = GetPointerToGlobalIfAvailable(F);
1767 if(Addr)
1768 return Addr;
1769
1770 assert((F->isDeclaration() || F->hasAvailableExternallyLinkage()) &&
1771 "Internal error: only external defined function routes here!");
1772
1773 /* Handle the failure resolution by ourselves. */
1774 Addr = GetPointerToNamedSymbol(F->getName().str().c_str(),
1775 /* AbortOnFailure */ false);
1776
1777 /*
1778 * If we resolved the symbol to a null address (eg. a weak external)
1779 * return a null pointer let the application handle it.
1780 */
1781 if(Addr == NULL)
1782 if(AbortOnFailure)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001783 llvm::report_fatal_error
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001784 ("Could not resolve external function address: " + F->getName()
1785 );
1786 else
1787 return NULL;
1788
1789 AddGlobalMapping(F, Addr);
1790
1791 return Addr;
1792 }
1793
1794 void* GetPointerToNamedSymbol(const std::string& Name,
1795 bool AbortOnFailure) {
1796 if(void* Addr = FindRuntimeFunction(Name.c_str()))
1797 return Addr;
1798
1799 if(mpSymbolLookupFn)
1800 if(void* Addr = mpSymbolLookupFn(mpSymbolLookupContext, Name.c_str()))
1801 return Addr;
1802
1803 if(AbortOnFailure)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001804 llvm::report_fatal_error("Program used external symbol '" + Name +
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001805 "' which could not be resolved!");
1806
1807 return NULL;
1808 }
1809
1810 /*
1811 * GetOrEmitGlobalVariable - Return the address of the specified global
1812 * variable, possibly emitting it to memory if needed. This is used by the
1813 * Emitter.
1814 */
1815 void* GetOrEmitGlobalVariable(const llvm::GlobalVariable *GV) {
1816 void* Ptr = GetPointerToGlobalIfAvailable(GV);
1817 if(Ptr)
1818 return Ptr;
1819
1820 if(GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) {
1821 /* If the global is external, just remember the address. */
1822 Ptr = GetPointerToNamedSymbol(GV->getName().str(), true);
1823 AddGlobalMapping(GV, Ptr);
1824 } else {
1825 /* If the global hasn't been emitted to memory yet,
1826 allocate space and emit it into memory. */
1827 Ptr = GetMemoryForGV(GV);
1828 AddGlobalMapping(GV, Ptr);
1829 EmitGlobalVariable(GV);
1830 }
1831
1832 return Ptr;
1833 }
1834
1835 /*
1836 * GetMemoryForGV - This method abstracts memory allocation of global
1837 * variable so that the JIT can allocate thread local variables depending
1838 * on the target.
1839 */
1840 void* GetMemoryForGV(const llvm::GlobalVariable* GV) {
1841 char* Ptr;
1842
1843 const llvm::Type* GlobalType = GV->getType()->getElementType();
1844 size_t S = mpTD->getTypeAllocSize(GlobalType);
1845 size_t A = mpTD->getPreferredAlignment(GV);
1846
1847 if(GV->isThreadLocal()) {
1848 /*
1849 * We can support TLS by
1850 *
1851 * Ptr = TJI.allocateThreadLocalMemory(S);
1852 *
1853 * But I tend not to .
1854 * (should we disable this in the front-end (i.e. slang)?).
1855 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001856 llvm::report_fatal_error
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001857 ("Compilation of Thread Local Storage (TLS) is disabled!");
1858
1859 } else if(mpTJI->allocateSeparateGVMemory()) {
1860 /*
1861 * On the Apple's ARM target (such as iPhone),
1862 * the global variable should be
1863 * placed in separately allocated heap memory rather than in the same
1864 * code memory.
1865 * The question is, how about the Android?
1866 */
1867 if(A <= 8) {
1868 Ptr = (char*) malloc(S);
1869 } else {
1870 /*
1871 * Allocate (S + A) bytes of memory,
1872 * then use an aligned pointer within that space.
1873 */
1874 Ptr = (char*) malloc(S + A);
1875 unsigned int MisAligned = ((intptr_t) Ptr & (A - 1));
1876 Ptr = Ptr + (MisAligned ? (A - MisAligned) : 0);
1877 }
1878 } else {
1879 Ptr = (char*) allocateGlobal(S, A);
1880 }
1881
1882 return Ptr;
1883 }
1884
1885 void EmitGlobalVariable(const llvm::GlobalVariable *GV) {
1886 void* GA = GetPointerToGlobalIfAvailable(GV);
1887
1888 if(GV->isThreadLocal())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001889 llvm::report_fatal_error
1890 ("We don't support Thread Local Storage (TLS)!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001891
1892 if(GA == NULL) {
1893 /* If it's not already specified, allocate memory for the global. */
1894 GA = GetMemoryForGV(GV);
1895 AddGlobalMapping(GV, GA);
1896 }
1897
1898 InitializeConstantToMemory(GV->getInitializer(), GA);
1899
1900 /* You can do some statistics on global variable here */
1901 return;
1902 }
1903
1904 typedef std::map<llvm::AssertingVH<llvm::GlobalValue>, void*
1905 > GlobalToIndirectSymMapTy;
1906 GlobalToIndirectSymMapTy GlobalToIndirectSymMap;
1907
1908 void* GetPointerToGVIndirectSym(llvm::GlobalValue *V, void *Reference) {
1909 /*
1910 * Make sure GV is emitted first, and create a stub containing the fully
1911 * resolved address.
1912 */
1913 void* GVAddress = GetPointerToGlobal(V, Reference, false);
1914
1915 /* If we already have a stub for this global variable, recycle it. */
1916 void*& IndirectSym = GlobalToIndirectSymMap[V];
1917 /* Otherwise, codegen a new indirect symbol. */
1918 if(!IndirectSym)
1919 IndirectSym = mpTJI->emitGlobalValueIndirectSym(V, GVAddress, *this);
1920
1921 return IndirectSym;
1922 }
1923
1924 /*
1925 * ExternalFnToStubMap - This is the equivalent of FunctionToLazyStubMap
1926 * for external functions.
1927 *
1928 * TODO: Of course, external functions don't need a lazy stub.
1929 * It's actually
1930 * here to make it more likely that far calls succeed, but no single
1931 * stub can guarantee that. I'll remove this in a subsequent checkin
1932 * when I actually fix far calls. (comment from LLVM source)
1933 */
1934 std::map<void*, void*> ExternalFnToStubMap;
1935
1936 /*
1937 * GetExternalFunctionStub - Return a stub for the function at the
1938 * specified address.
1939 */
1940 void* GetExternalFunctionStub(void* FnAddr) {
1941 void*& Stub = ExternalFnToStubMap[FnAddr];
1942 if(Stub)
1943 return Stub;
1944
1945 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
1946 startGVStub(0, SL.Size, SL.Alignment);
1947 Stub = mpTJI->emitFunctionStub(0, FnAddr, *this);
1948 finishGVStub();
1949
1950 return Stub;
1951 }
1952
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001953#if defined(USE_DISASSEMBLER)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001954 const llvm::MCAsmInfo* mpAsmInfo;
1955 const llvm::MCDisassembler* mpDisassmbler;
1956 llvm::MCInstPrinter* mpIP;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001957
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001958 class BufferMemoryObject : public llvm::MemoryObject {
1959 private:
1960 const uint8_t* mBytes;
1961 uint64_t mLength;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001962
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001963 public:
1964 BufferMemoryObject(const uint8_t *Bytes, uint64_t Length) :
1965 mBytes(Bytes), mLength(Length) { }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001966
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001967 uint64_t getBase() const { return 0; }
1968 uint64_t getExtent() const { return mLength; }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001969
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001970 int readByte(uint64_t Addr, uint8_t *Byte) const {
1971 if(Addr > getExtent())
1972 return -1;
1973 *Byte = mBytes[Addr];
1974 return 0;
1975 }
1976 };
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001977
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001978 void Disassemble(const llvm::StringRef& Name, uint8_t* Start,
1979 size_t Length, bool IsStub) {
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001980 llvm::raw_fd_ostream* OS;
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07001981#if defined(USE_DISASSEMBLER_FILE)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001982 std::string ErrorInfo;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001983 OS = new llvm::raw_fd_ostream(
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07001984 "/data/local/tmp/out.S", ErrorInfo, llvm::raw_fd_ostream::F_Append);
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001985 if(!ErrorInfo.empty()) { // some errors occurred
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07001986 //LOGE("Error in creating disassembly file");
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001987 delete OS;
1988 return;
1989 }
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001990#else
1991 OS = &llvm::outs();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001992#endif
1993
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001994
1995 *OS << "JIT: Disassembled code: " << Name
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001996 << ((IsStub) ? " (stub)" : "") << "\n";
1997
1998 if(mpAsmInfo == NULL)
1999 mpAsmInfo = mpTarget->createAsmInfo(Triple);
2000 if(mpDisassmbler == NULL)
2001 mpDisassmbler = mpTarget->createMCDisassembler();
2002 if(mpIP == NULL)
2003 mpIP = mpTarget->createMCInstPrinter(
2004 mpAsmInfo->getAssemblerDialect(), *mpAsmInfo);
2005
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002006 const BufferMemoryObject* BufferMObj =
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002007 new BufferMemoryObject(Start, Length);
2008 uint64_t Size;
2009 uint64_t Index;
2010
2011 for(Index=0;Index<Length;Index+=Size) {
2012 llvm::MCInst Inst;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002013
2014 if(mpDisassmbler->getInstruction(Inst, Size, *BufferMObj, Index,
2015 /* REMOVED */ llvm::nulls()))
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002016 {
2017 OS->indent(4).write("0x", 2).
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002018 write_hex((uint32_t) Start + Index).write(':');
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002019 mpIP->printInst(&Inst, *OS);
2020 *OS << "\n";
2021 } else {
2022 if (Size == 0)
2023 Size = 1; // skip illegible bytes
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002024 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002025 }
2026
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002027 *OS << "\n";
2028 delete BufferMObj;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002029
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002030#if defined(USE_DISASSEMBLER_FILE)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002031 /* If you want the disassemble results write to file, uncomment this */
2032 OS->close();
2033 delete OS;
2034#endif
2035
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002036 return;
2037 }
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002038#else
2039 void Disassemble(const std::string& Name, uint8_t* Start,
2040 size_t Length, bool IsStub) {
2041 return;
2042 }
2043#endif /* defined(USE_DISASSEMBLER) */
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002044
2045 public:
2046 /* Will take the ownership of @MemMgr */
2047 CodeEmitter(CodeMemoryManager* pMemMgr) :
2048 mpMemMgr(pMemMgr),
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002049 mpTarget(NULL),
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002050 mpTJI(NULL),
2051 mpTD(NULL),
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002052#if defined(USE_DISASSEMBLER)
2053 mpAsmInfo(NULL),
2054 mpDisassmbler(NULL),
2055 mpIP(NULL),
2056#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002057 mpCurEmitFunction(NULL),
2058 mpConstantPool(NULL),
2059 mpJumpTable(NULL),
2060 mpMMI(NULL),
2061 mpSymbolLookupFn(NULL),
2062 mpSymbolLookupContext(NULL)
2063 {
2064 return;
2065 }
2066
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002067 inline global_addresses_const_iterator global_address_begin() const {
2068 return mGlobalAddressMap.begin();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002069 }
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002070 inline global_addresses_const_iterator global_address_end() const {
2071 return mGlobalAddressMap.end();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002072 }
2073
2074 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid* pContext) {
2075 mpSymbolLookupFn = pFn;
2076 mpSymbolLookupContext = pContext;
2077 return;
2078 }
2079
2080 void setTargetMachine(llvm::TargetMachine& TM) {
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002081 /* set Target */
2082 mpTarget = &TM.getTarget();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002083 /* set TargetJITInfo */
2084 mpTJI = TM.getJITInfo();
2085 /* set TargetData */
2086 mpTD = TM.getTargetData();
2087
2088 /*
2089 if(mpTJI->needsGOT())
2090 mpMemMgr->AllocateGOT(); // however,
2091 // both X86 and ARM target don't need GOT
2092 // (mpTJI->needsGOT() always returns false)
2093 */
2094 assert(!mpTJI->needsGOT() && "We don't support GOT needed target!");
2095
2096 return;
2097 }
2098
2099 /*
2100 * startFunction - This callback is invoked when the specified function is
2101 * about to be code generated. This initializes the BufferBegin/End/Ptr
2102 * fields.
2103 */
2104 void startFunction(llvm::MachineFunction &F) {
2105 uintptr_t ActualSize = 0;
2106
2107 mpMemMgr->setMemoryWritable();
2108
2109 /*
2110 * BufferBegin, BufferEnd and CurBufferPtr
2111 * are all inherited from class MachineCodeEmitter,
2112 * which is the super class of the class JITCodeEmitter.
2113 *
2114 * BufferBegin/BufferEnd - Pointers to the start and end of the memory
2115 * allocated for this code buffer.
2116 *
2117 * CurBufferPtr - Pointer to the next byte of memory to fill when emitting
2118 * code.
2119 * This is guranteed to be in the range [BufferBegin,BufferEnd]. If
2120 * this pointer is at BufferEnd, it will never move due to code emission,
2121 * and
2122 * all code emission requests will be ignored (this is
2123 * the buffer overflow condition).
2124 */
2125 BufferBegin = CurBufferPtr = mpMemMgr
2126 ->startFunctionBody(F.getFunction(), ActualSize);
2127 BufferEnd = BufferBegin + ActualSize;
2128
2129 if(mpCurEmitFunction == NULL)
2130 mpCurEmitFunction = new EmittedFunctionCode();
2131 mpCurEmitFunction->FunctionBody = BufferBegin;
2132
2133 /* Ensure the constant pool/jump table info is at least 4-byte aligned. */
2134 emitAlignment(16);
2135
2136 emitConstantPool(F.getConstantPool());
2137 if(llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
2138 initJumpTableInfo(MJTI);
2139
2140 /* About to start emitting the machine code for the function. */
2141 emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
2142
2143 UpdateGlobalMapping(F.getFunction(), CurBufferPtr);
2144
2145 mpCurEmitFunction->Code = CurBufferPtr;
2146
2147 mMBBLocations.clear();
2148
2149 return;
2150 }
2151
2152 /*
2153 * finishFunction - This callback is invoked
2154 * when the specified function has
2155 * finished code generation.
2156 * If a buffer overflow has occurred, this method
2157 * returns true (the callee is required to try again), otherwise it returns
2158 * false.
2159 */
2160 bool finishFunction(llvm::MachineFunction &F) {
2161 if(CurBufferPtr == BufferEnd) {
2162 /* No enough memory */
2163 mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
2164 return false;
2165 }
2166
2167 if(llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
2168 emitJumpTableInfo(MJTI);
2169
2170 /*
2171 * FnStart is the start of the text,
2172 * not the start of the constant pool and other per-function data.
2173 */
2174 uint8_t* FnStart = (uint8_t*) GetPointerToGlobalIfAvailable
2175 (F.getFunction());
2176
2177 /* FnEnd is the end of the function's machine code. */
2178 uint8_t* FnEnd = CurBufferPtr;
2179
2180 if(!mRelocations.empty()) {
2181 /* Resolve the relocations to concrete pointers. */
2182 for(int i=0;i<mRelocations.size();i++) {
2183 llvm::MachineRelocation& MR = mRelocations[i];
2184 void* ResultPtr = NULL;
2185
2186 if(!MR.letTargetResolve()) {
2187 if(MR.isExternalSymbol()) {
2188 ResultPtr = GetPointerToNamedSymbol(MR.getExternalSymbol(), true);
2189 if(MR.mayNeedFarStub())
2190 ResultPtr = GetExternalFunctionStub(ResultPtr);
2191 } else if(MR.isGlobalValue()) {
2192 ResultPtr = GetPointerToGlobal(MR.getGlobalValue(),
2193 BufferBegin
2194 + MR.getMachineCodeOffset(),
2195 MR.mayNeedFarStub());
2196 } else if(MR.isIndirectSymbol()) {
2197 ResultPtr = GetPointerToGVIndirectSym
2198 (MR.getGlobalValue(),
2199 BufferBegin + MR.getMachineCodeOffset()
2200 );
2201 } else if(MR.isBasicBlock()) {
2202 ResultPtr =
2203 (void*) getMachineBasicBlockAddress(MR.getBasicBlock());
2204 } else if(MR.isConstantPoolIndex()) {
2205 ResultPtr =
2206 (void*) getConstantPoolEntryAddress
2207 (MR.getConstantPoolIndex());
2208 } else {
2209 assert(MR.isJumpTableIndex() && "Unknown type of relocation");
2210 ResultPtr =
2211 (void*) getJumpTableEntryAddress(MR.getJumpTableIndex());
2212 }
2213
2214 MR.setResultPointer(ResultPtr);
2215 }
2216 }
2217
2218 mpTJI->relocate(BufferBegin, &mRelocations[0], mRelocations.size(),
2219 mpMemMgr->getGOTBase());
2220 }
2221
2222 mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
2223 /*
2224 * CurBufferPtr may have moved beyond FnEnd, due to memory allocation for
2225 * global variables that were referenced in the relocations.
2226 */
2227 if(CurBufferPtr == BufferEnd)
2228 return false;
2229
2230 /* Now that we've succeeded in emitting the function */
2231 mpCurEmitFunction->Size = CurBufferPtr - BufferBegin;
2232 BufferBegin = CurBufferPtr = 0;
2233
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002234 if(F.getFunction()->hasName())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002235 mEmittedFunctions[F.getFunction()->getNameStr()] = mpCurEmitFunction;
2236 mpCurEmitFunction = NULL;
2237
2238 mRelocations.clear();
2239 mConstPoolAddresses.clear();
2240
2241 /* Mark code region readable and executable if it's not so already. */
2242 mpMemMgr->setMemoryExecutable();
2243
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002244 Disassemble(F.getFunction()->getName(), FnStart, FnEnd - FnStart, false);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002245
2246 if(mpMMI)
2247 mpMMI->EndFunction();
2248
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002249 updateFunctionStub(F.getFunction());
2250
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002251 return false;
2252 }
2253
2254 void startGVStub(const llvm::GlobalValue* GV, unsigned StubSize,
2255 unsigned Alignment) {
2256 mpSavedBufferBegin = BufferBegin;
2257 mpSavedBufferEnd = BufferEnd;
2258 mpSavedCurBufferPtr = CurBufferPtr;
2259
2260 BufferBegin = CurBufferPtr = mpMemMgr->allocateStub(GV, StubSize,
2261 Alignment);
2262 BufferEnd = BufferBegin + StubSize + 1;
2263
2264 return;
2265 }
2266
2267 void startGVStub(void* Buffer, unsigned StubSize) {
2268 mpSavedBufferBegin = BufferBegin;
2269 mpSavedBufferEnd = BufferEnd;
2270 mpSavedCurBufferPtr = CurBufferPtr;
2271
2272 BufferBegin = CurBufferPtr = (uint8_t *) Buffer;
2273 BufferEnd = BufferBegin + StubSize + 1;
2274
2275 return;
2276 }
2277
2278 void finishGVStub() {
2279 assert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space.");
2280
2281 /* restore */
2282 BufferBegin = mpSavedBufferBegin;
2283 BufferEnd = mpSavedBufferEnd;
2284 CurBufferPtr = mpSavedCurBufferPtr;
2285
2286 return;
2287 }
2288
2289 /*
2290 * allocIndirectGV - Allocates and fills storage for an indirect
2291 * GlobalValue, and returns the address.
2292 */
2293 void* allocIndirectGV(const llvm::GlobalValue *GV,
2294 const uint8_t *Buffer, size_t Size,
2295 unsigned Alignment) {
2296 uint8_t* IndGV = mpMemMgr->allocateStub(GV, Size, Alignment);
2297 memcpy(IndGV, Buffer, Size);
2298 return IndGV;
2299 }
2300
2301 /* emitLabel - Emits a label */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002302 void emitLabel(llvm::MCSymbol *Label) {
2303 mLabelLocations[Label] = getCurrentPCValue();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002304 return;
2305 }
2306
2307 /*
2308 * allocateGlobal - Allocate memory for a global. Unlike allocateSpace,
2309 * this method does not allocate memory in the current output buffer,
2310 * because a global may live longer than the current function.
2311 */
2312 void* allocateGlobal(uintptr_t Size, unsigned Alignment) {
2313 /* Delegate this call through the memory manager. */
2314 return mpMemMgr->allocateGlobal(Size, Alignment);
2315 }
2316
2317 /*
2318 * StartMachineBasicBlock - This should be called by the target when a new
2319 * basic block is about to be emitted. This way the MCE knows where the
2320 * start of the block is, and can implement getMachineBasicBlockAddress.
2321 */
2322 void StartMachineBasicBlock(llvm::MachineBasicBlock *MBB) {
2323 if(mMBBLocations.size() <= (unsigned) MBB->getNumber())
2324 mMBBLocations.resize((MBB->getNumber() + 1) * 2);
2325 mMBBLocations[MBB->getNumber()] = getCurrentPCValue();
2326 return;
2327 }
2328
2329 /*
2330 * addRelocation - Whenever a relocatable address is needed, it should be
2331 * noted with this interface.
2332 */
2333 void addRelocation(const llvm::MachineRelocation &MR) {
2334 mRelocations.push_back(MR);
2335 return;
2336 }
2337
2338 /*
2339 * getConstantPoolEntryAddress - Return the address of the 'Index' entry in
2340 * the constant pool that was last emitted with
2341 * the emitConstantPool method.
2342 */
2343 uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
2344 assert(Index < mpConstantPool->getConstants().size() &&
2345 "Invalid constant pool index!");
2346 return mConstPoolAddresses[Index];
2347 }
2348
2349 /*
2350 * getJumpTableEntryAddress - Return the address of the jump table
2351 * with index
2352 * 'Index' in the function that last called initJumpTableInfo.
2353 */
2354 uintptr_t getJumpTableEntryAddress(unsigned Index) const {
2355 const std::vector<llvm::MachineJumpTableEntry>& JT =
2356 mpJumpTable->getJumpTables();
2357
2358 assert(Index < JT.size() && "Invalid jump table index!");
2359
2360 unsigned int Offset = 0;
2361 unsigned int EntrySize = mpJumpTable->getEntrySize(*mpTD);
2362
2363 for(int i=0;i<Index;i++)
2364 Offset += JT[i].MBBs.size();
2365 Offset *= EntrySize;
2366
2367 return (uintptr_t)((char *) mpJumpTableBase + Offset);
2368 }
2369
2370 /*
2371 * getMachineBasicBlockAddress - Return the address of the specified
2372 * MachineBasicBlock, only usable after the label for the MBB has been
2373 * emitted.
2374 */
2375 uintptr_t getMachineBasicBlockAddress(llvm::MachineBasicBlock *MBB) const {
2376 assert(mMBBLocations.size() > (unsigned) MBB->getNumber() &&
2377 mMBBLocations[MBB->getNumber()] && "MBB not emitted!");
2378 return mMBBLocations[MBB->getNumber()];
2379 }
2380
2381 /*
2382 * getLabelAddress - Return the address of the specified LabelID,
2383 * only usable after the LabelID has been emitted.
2384 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002385 uintptr_t getLabelAddress(llvm::MCSymbol* Label) const {
2386 assert(mLabelLocations.count(Label) && "Label not emitted!");
2387 return mLabelLocations.find(Label)->second;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002388 }
2389
2390 /*
2391 * Specifies the MachineModuleInfo object.
2392 * This is used for exception handling
2393 * purposes.
2394 */
2395 void setModuleInfo(llvm::MachineModuleInfo* Info) {
2396 mpMMI = Info;
2397 return;
2398 }
2399
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002400 void updateFunctionStub(const llvm::Function* F) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002401 /* Get the empty stub we generated earlier. */
2402 void* Stub;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002403 std::set<const llvm::Function*>::iterator I = PendingFunctions.find(F);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002404 if(I != PendingFunctions.end())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002405 Stub = mFunctionToLazyStubMap[F];
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002406 else
2407 return;
2408
2409 void* Addr = GetPointerToGlobalIfAvailable(F);
2410
2411 assert(Addr != Stub &&
2412 "Function must have non-stub address to be updated.");
2413
2414 /*
2415 * Tell the target jit info to rewrite the stub at the specified address,
2416 * rather than creating a new one.
2417 */
2418 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
2419 startGVStub(Stub, SL.Size);
2420 mpTJI->emitFunctionStub(F, Addr, *this);
2421 finishGVStub();
2422
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002423 Disassemble(F->getName(), (uint8_t*) Stub, SL.Size, true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002424
2425 PendingFunctions.erase(I);
2426
2427 return;
2428 }
2429
2430 /*
2431 * Once you finish the compilation on a translation unit,
2432 * you can call this function to recycle the memory
2433 * (which is used at compilation time and not needed for runtime).
2434 *
2435 * NOTE: You should not call this funtion until the code-gen passes
2436 * for a given module is done.
2437 * Otherwise, the results is undefined and may cause the system crash!
2438 */
2439 void releaseUnnecessary() {
2440 mMBBLocations.clear();
2441 mLabelLocations.clear();
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002442 mGlobalAddressMap.clear();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002443 mFunctionToLazyStubMap.clear();
2444 GlobalToIndirectSymMap.clear();
2445 ExternalFnToStubMap.clear();
2446 PendingFunctions.clear();
2447
2448 return;
2449 }
2450
2451 void reset() {
2452 releaseUnnecessary();
2453
2454 mpSymbolLookupFn = NULL;
2455 mpSymbolLookupContext = NULL;
2456
2457 mpTJI = NULL;
2458 mpTD = NULL;
2459
2460 for(EmittedFunctionsMapTy::iterator I = mEmittedFunctions.begin();
2461 I != mEmittedFunctions.end();
2462 I++)
2463 if(I->second != NULL)
2464 delete I->second;
2465 mEmittedFunctions.clear();
2466
2467 mpMemMgr->reset();
2468
2469 return;
2470 }
2471
2472 void* lookup(const char* Name) {
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002473 return lookup( llvm::StringRef(Name) );
2474 }
2475
2476 void* lookup(const llvm::StringRef& Name) {
2477 EmittedFunctionsMapTy::const_iterator I = mEmittedFunctions.find(Name.str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002478 if(I == mEmittedFunctions.end())
2479 return NULL;
2480 else
2481 return I->second->Code;
2482 }
2483
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002484 void getFunctionNames(BCCsizei* actualFunctionCount,
2485 BCCsizei maxFunctionCount,
2486 BCCchar** functions) {
2487 int functionCount = mEmittedFunctions.size();
2488
2489 if(actualFunctionCount)
2490 *actualFunctionCount = functionCount;
2491 if(functionCount > maxFunctionCount)
2492 functionCount = maxFunctionCount;
2493 if(functions)
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002494 for(EmittedFunctionsMapTy::const_iterator it =
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002495 mEmittedFunctions.begin();
2496 functionCount > 0;
2497 functionCount--, it++)
2498 *functions++ = (BCCchar*) it->first.c_str();
2499
2500 return;
2501 }
2502
2503 void getFunctionBinary(BCCchar* label,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002504 BCCvoid** base,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002505 BCCsizei* length) {
2506 EmittedFunctionsMapTy::const_iterator I = mEmittedFunctions.find(label);
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002507 if(I == mEmittedFunctions.end()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002508 *base = NULL;
2509 *length = 0;
2510 } else {
2511 *base = I->second->Code;
2512 *length = I->second->Size;
2513 }
2514 return;
2515 }
2516
2517 ~CodeEmitter() {
2518 if(mpMemMgr)
2519 delete mpMemMgr;
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002520#if defined(USE_DISASSEMBLER)
2521 if(mpAsmInfo)
2522 delete mpAsmInfo;
2523 if(mpDisassmbler)
2524 delete mpDisassmbler;
2525 if(mpIP)
2526 delete mpIP;
2527#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002528 return;
2529 }
2530 /* }}} */
2531 }; /* End of Class CodeEmitter */
2532
2533 /* The CodeEmitter */
2534 llvm::OwningPtr<CodeEmitter> mCodeEmitter;
2535 CodeEmitter* createCodeEmitter() {
2536 mCodeEmitter.reset(new CodeEmitter(mCodeMemMgr.take()));
2537 return mCodeEmitter.get();
2538 }
2539
2540 BCCSymbolLookupFn mpSymbolLookupFn;
2541 void* mpSymbolLookupContext;
2542
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002543 llvm::LLVMContext* mContext;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002544 llvm::Module* mModule;
2545
2546 bool mTypeInformationPrepared;
2547 std::vector<const llvm::Type*> mTypes;
2548
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002549 public:
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002550 Compiler() :
2551 mpSymbolLookupFn(NULL),
2552 mpSymbolLookupContext(NULL),
2553 mContext(NULL),
2554 mModule(NULL)
2555 {
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002556 mContext = new llvm::LLVMContext();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002557 return;
2558 }
2559
2560 /* interface for BCCscript::registerSymbolCallback() */
2561 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid* pContext) {
2562 mpSymbolLookupFn = pFn;
2563 mpSymbolLookupContext = pContext;
2564 return;
2565 }
2566
2567 int loadModule(const char* bitcode, size_t bitcodeSize) {
2568 llvm::MemoryBuffer* SB = NULL;
2569
2570 if(bitcode == NULL || bitcodeSize <= 0)
2571 return 0;
Shih-wei Liaobe5c5312010-05-09 05:30:09 -07002572 LOGE("Before Init");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002573 GlobalInitialization();
2574
2575 /* Package input to object MemoryBuffer */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002576 SB = llvm::MemoryBuffer::getMemBuffer(
2577 llvm::StringRef(bitcode, bitcodeSize));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002578 if(SB == NULL) {
2579 setError("Error reading input Bitcode into memory");
2580 goto on_bcc_load_module_error;
2581 }
2582
2583 /* Read the input Bitcode as a Module */
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002584 mModule = llvm::ParseBitcodeFile(SB, *mContext, &mError);
Shih-wei Liaobe5c5312010-05-09 05:30:09 -07002585 LOGE("FINISH LOAD");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002586on_bcc_load_module_error:
2587 if (SB)
2588 delete SB;
2589
2590 return hasError();
2591 }
2592
2593 /* interace for bccCompileScript() */
2594 int compile() {
2595 llvm::TargetData* TD = NULL;
2596
2597 llvm::TargetMachine* TM = NULL;
2598 const llvm::Target* Target;
2599 std::string FeaturesStr;
2600
2601 llvm::FunctionPassManager* CodeGenPasses = NULL;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002602
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002603 const llvm::NamedMDNode* PragmaMetadata;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002604 const llvm::NamedMDNode* ExportVarMetadata;
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002605 const llvm::NamedMDNode* ExportFuncMetadata;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002606
Shih-wei Liaobe5c5312010-05-09 05:30:09 -07002607 LOGE("mModule=%x", mModule);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002608 if(mModule == NULL) /* No module was loaded */
2609 return 0;
2610
2611 /* Create TargetMachine */
2612 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
2613 if(hasError())
2614 goto on_bcc_compile_error;
2615
2616 if(!CPU.empty() || !Features.empty()) {
2617 llvm::SubtargetFeatures F;
2618 F.setCPU(CPU);
2619 for(std::vector<std::string>::const_iterator it = Features.begin();
2620 it != Features.end();
2621 it++)
2622 F.AddFeature(*it);
2623 FeaturesStr = F.getString();
2624 }
2625
2626 TM = Target->createTargetMachine(Triple, FeaturesStr);
2627 if(TM == NULL) {
2628 setError("Failed to create target machine implementation for the"
2629 " specified triple '" + Triple + "'");
2630 goto on_bcc_compile_error;
2631 }
2632
2633 /* Create memory manager for creation of code emitter later */
2634 if(!mCodeMemMgr.get() && !createCodeMemoryManager()) {
2635 setError("Failed to startup memory management for further compilation");
2636 goto on_bcc_compile_error;
2637 }
2638
2639 /* Create code emitter */
2640 if(!mCodeEmitter.get()) {
2641 if(!createCodeEmitter()) {
2642 setError("Failed to create machine code emitter to complete"
2643 " the compilation");
2644 goto on_bcc_compile_error;
2645 }
2646 } else {
2647 /* reuse the code emitter */
2648 mCodeEmitter->reset();
2649 }
2650
2651 mCodeEmitter->setTargetMachine(*TM);
2652 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
2653 mpSymbolLookupContext);
2654
2655 /* Get target data from Module */
2656 TD = new llvm::TargetData(mModule);
2657 /* Create code-gen pass to run the code emitter */
2658 CodeGenPasses = new llvm::FunctionPassManager(mModule);
2659 CodeGenPasses->add(TD); // Will take the ownership of TD
2660
2661 if(TM->addPassesToEmitMachineCode(*CodeGenPasses,
2662 *mCodeEmitter, CodeGenOptLevel)) {
2663 setError("The machine code emission is not supported by BCC on target '"
2664 + Triple + "'");
2665 goto on_bcc_compile_error;
2666 }
2667
2668 /*
2669 * Run the pass (the code emitter) on every non-declaration function
2670 * in the module
2671 */
2672 CodeGenPasses->doInitialization();
2673 for(llvm::Module::iterator I = mModule->begin();
2674 I != mModule->end();
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002675 I++)
2676 if(!I->isDeclaration())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002677 CodeGenPasses->run(*I);
2678
2679 CodeGenPasses->doFinalization();
2680
2681 /* Copy the global address mapping from code emitter and remapping */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002682 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
2683 if(ExportVarMetadata) {
2684 for(int i=0;i<ExportVarMetadata->getNumOperands();i++) {
2685 llvm::MDNode* ExportVar = ExportVarMetadata->getOperand(i);
2686 if(ExportVar != NULL && ExportVar->getNumOperands() > 1) {
2687 llvm::Value* ExportVarNameMDS = ExportVar->getOperand(0);
2688 if(ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
2689 llvm::StringRef ExportVarName =
2690 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
2691 CodeEmitter::global_addresses_const_iterator I;
2692 for(I = mCodeEmitter->global_address_begin();
2693 I != mCodeEmitter->global_address_end();
2694 I++)
2695 {
2696 if(I->first->getValueID() != llvm::Value::GlobalVariableVal)
2697 continue;
2698 if(ExportVarName == I->first->getName()) {
2699 mExportVars.push_back(I->second);
2700 break;
2701 }
2702 }
2703 if(I != mCodeEmitter->global_address_end())
2704 continue; // found
2705 }
2706 }
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002707 // if here, the global variable record in metadata is not
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002708 // found, make an empty slot
2709 mExportVars.push_back(NULL);
2710 }
2711 assert((mExportVars.size() == ExportVarMetadata->getNumOperands()) &&
2712 "Number of slots doesn't match the number of export variables!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002713 }
2714
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002715 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
2716 if(ExportFuncMetadata) {
2717 for(int i=0;i<ExportFuncMetadata->getNumOperands();i++) {
2718 llvm::MDNode* ExportFunc = ExportFuncMetadata->getOperand(i);
2719 if(ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
2720 llvm::Value* ExportFuncNameMDS = ExportFunc->getOperand(0);
2721 if(ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
2722 llvm::StringRef ExportFuncName =
2723 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
2724 mExportFuncs.push_back(mCodeEmitter->lookup(ExportFuncName));
2725 }
2726 }
2727 }
2728 }
2729
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002730 /*
2731 * Tell code emitter now can release the memory using
2732 * during the JIT since we have done the code emission
2733 */
2734 mCodeEmitter->releaseUnnecessary();
2735
2736 /*
2737 * Finally, read pragma information from the metadata node
2738 * of the @Module if any
2739 */
2740 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
2741 if(PragmaMetadata)
2742 for(int i=0;i<PragmaMetadata->getNumOperands();i++) {
2743 llvm::MDNode* Pragma = PragmaMetadata->getOperand(i);
2744 if(Pragma != NULL &&
2745 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
2746 llvm::Value* PragmaNameMDS = Pragma->getOperand(0);
2747 llvm::Value* PragmaValueMDS = Pragma->getOperand(1);
2748
2749 if((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
2750 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
2751 llvm::StringRef PragmaName =
2752 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
2753 llvm::StringRef PragmaValue =
2754 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
2755
2756 mPragmas.push_back( make_pair( std::string(PragmaName.data(),
2757 PragmaName.size()),
2758 std::string(PragmaValue.data(),
2759 PragmaValue.size())
2760 )
2761 );
2762 }
2763 }
2764 }
2765
2766 on_bcc_compile_error:
2767 if (CodeGenPasses) {
2768 delete CodeGenPasses;
2769 } else if (TD) {
2770 delete TD;
2771 }
2772 if (TM)
2773 delete TM;
2774
2775 return hasError();
2776 }
2777
2778 /* interface for bccGetScriptInfoLog() */
2779 char* getErrorMessage() {
2780 return const_cast<char*>(mError.c_str());
2781 }
2782
2783 /* interface for bccGetScriptLabel() */
2784 void* lookup(const char* name) {
2785 void* addr = NULL;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002786 if(mCodeEmitter.get())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002787 /* Find function pointer */
2788 addr = mCodeEmitter->lookup(name);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002789 return addr;
2790 }
2791
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002792 /* Interface for bccGetExportVars() */
2793 void getExportVars(BCCsizei* actualVarCount,
2794 BCCsizei maxVarCount,
2795 BCCvoid** vars) {
2796 int varCount = mExportVars.size();
2797
2798 if(actualVarCount)
2799 *actualVarCount = varCount;
2800 if(varCount > maxVarCount)
2801 varCount = maxVarCount;
2802 if(vars)
2803 for(ExportVarList::const_iterator it = mExportVars.begin();
2804 it != mExportVars.end();
2805 it++)
2806 {
2807 *vars++ = *it;
2808 }
2809
2810 return;
2811 }
2812
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002813 /* Interface for bccGetExportFuncs() */
2814 void getExportFuncs(BCCsizei* actualFuncCount,
2815 BCCsizei maxFuncCount,
2816 BCCvoid** funcs) {
2817 int funcCount = mExportFuncs.size();
2818
2819 if(actualFuncCount)
2820 *actualFuncCount = funcCount;
2821 if(funcCount > maxFuncCount)
2822 funcCount = maxFuncCount;
2823 if(funcs)
2824 for(ExportFuncList::const_iterator it = mExportFuncs.begin();
2825 it != mExportFuncs.end();
2826 it++)
2827 {
2828 *funcs++ = *it;
2829 }
2830
2831 return;
2832 }
2833
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002834 /* Interface for bccGetPragmas() */
2835 void getPragmas(BCCsizei* actualStringCount,
2836 BCCsizei maxStringCount,
2837 BCCchar** strings) {
2838 int stringCount = mPragmas.size() * 2;
2839
2840 if(actualStringCount)
2841 *actualStringCount = stringCount;
2842 if(stringCount > maxStringCount)
2843 stringCount = maxStringCount;
2844 if(strings)
2845 for(PragmaList::const_iterator it = mPragmas.begin();
2846 stringCount > 0;
2847 stringCount-=2, it++)
2848 {
2849 *strings++ = (BCCchar*) it->first.c_str();
2850 *strings++ = (BCCchar*) it->second.c_str();
2851 }
2852
2853 return;
2854 }
2855
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002856 /* Interface for bccGetFunctions() */
2857 void getFunctions(BCCsizei* actualFunctionCount,
2858 BCCsizei maxFunctionCount,
2859 BCCchar** functions) {
2860 if(mCodeEmitter.get())
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002861 mCodeEmitter->getFunctionNames(actualFunctionCount,
2862 maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002863 functions);
2864 else
2865 *actualFunctionCount = 0;
2866
2867 return;
2868 }
2869
2870 /* Interface for bccGetFunctionBinary() */
2871 void getFunctionBinary(BCCchar* function,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002872 BCCvoid** base,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002873 BCCsizei* length) {
2874 if(mCodeEmitter.get()) {
2875 mCodeEmitter->getFunctionBinary(function, base, length);
2876 } else {
2877 *base = NULL;
2878 *length = 0;
2879 }
2880 return;
2881 }
2882
2883 inline const llvm::Module* getModule() const {
2884 return mModule;
2885 }
2886
2887 inline const std::vector<const llvm::Type*>& getTypes() const {
2888 return mTypes;
2889 }
2890
2891 ~Compiler() {
2892 delete mModule;
Shih-wei Liaobe5c5312010-05-09 05:30:09 -07002893 //llvm::llvm_shutdown();
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002894 delete mContext;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002895 return;
2896 }
2897}; /* End of Class Compiler */
2898
2899bool Compiler::GlobalInitialized = false;
2900
2901/* Code generation optimization level for the compiler */
2902llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
2903
2904std::string Compiler::Triple;
2905
2906std::string Compiler::CPU;
2907
2908std::vector<std::string> Compiler::Features;
2909
Shih-wei Liaobe5c5312010-05-09 05:30:09 -07002910std::string Compiler::mError;
2911
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002912/*
2913 * The named of metadata node that pragma resides
2914 * (should be synced with slang.cpp)
2915 */
2916const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
2917
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002918/*
2919 * The named of metadata node that export variable name resides
2920 * (should be synced with slang.cpp)
2921 */
2922const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
2923
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002924/*
2925 * The named of metadata node that export function name resides
2926 * (should be synced with slang.cpp)
2927 */
2928const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
2929
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002930struct BCCscript {
2931 /*
2932 * Part I. Compiler
2933 */
2934
2935 Compiler compiler;
2936
2937 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid* pContext) {
2938 compiler.registerSymbolCallback(pFn, pContext);
2939 }
2940
2941 /*
2942 * Part II. Logistics & Error handling
2943 */
2944
2945 BCCscript() {
2946 bccError = BCC_NO_ERROR;
2947 }
2948
2949 ~BCCscript() {
2950 }
2951
2952 void setError(BCCenum error) {
2953 if (bccError == BCC_NO_ERROR && error != BCC_NO_ERROR) {
2954 bccError = error;
2955 }
2956 }
2957
2958 BCCenum getError() {
2959 BCCenum result = bccError;
2960 bccError = BCC_NO_ERROR;
2961 return result;
2962 }
2963
2964 BCCenum bccError;
2965};
2966
2967
2968extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002969BCCscript* bccCreateScript()
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002970{
2971 return new BCCscript();
2972}
2973
2974extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002975BCCenum bccGetError( BCCscript* script )
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002976{
2977 return script->getError();
2978}
2979
2980extern "C"
2981void bccDeleteScript(BCCscript* script) {
2982 delete script;
2983}
2984
2985extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002986void bccRegisterSymbolCallback(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002987 BCCSymbolLookupFn pFn,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002988 BCCvoid* pContext)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002989{
2990 script->registerSymbolCallback(pFn, pContext);
2991}
2992
2993extern "C"
2994void bccScriptBitcode(BCCscript* script,
2995 const BCCchar* bitcode,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002996 BCCint size)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002997{
2998 script->compiler.loadModule(bitcode, size);
2999}
3000
3001extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003002void bccCompileScript(BCCscript* script)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003003{
3004 int result = script->compiler.compile();
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003005 if (result)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003006 script->setError(BCC_INVALID_OPERATION);
3007}
3008
3009extern "C"
3010void bccGetScriptInfoLog(BCCscript* script,
3011 BCCsizei maxLength,
3012 BCCsizei* length,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003013 BCCchar* infoLog)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003014{
3015 char* message = script->compiler.getErrorMessage();
3016 int messageLength = strlen(message) + 1;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003017 if (length)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003018 *length = messageLength;
3019
3020 if (infoLog && maxLength > 0) {
3021 int trimmedLength = maxLength < messageLength ? maxLength : messageLength;
3022 memcpy(infoLog, message, trimmedLength);
3023 infoLog[trimmedLength] = 0;
3024 }
3025}
3026
3027extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003028void bccGetScriptLabel(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003029 const BCCchar * name,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003030 BCCvoid ** address)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003031{
3032 void* value = script->compiler.lookup(name);
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003033 if (value)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003034 *address = value;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003035 else
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003036 script->setError(BCC_INVALID_VALUE);
3037}
3038
3039extern "C"
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07003040void bccGetExportVars(BCCscript* script,
3041 BCCsizei* actualVarCount,
3042 BCCsizei maxVarCount,
3043 BCCvoid** vars)
3044{
3045 script->compiler.getExportVars(actualVarCount, maxVarCount, vars);
3046}
3047
3048extern "C"
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07003049void bccGetExportFuncs(BCCscript* script,
3050 BCCsizei* actualFuncCount,
3051 BCCsizei maxFuncCount,
3052 BCCvoid** funcs)
3053{
3054 script->compiler.getExportFuncs(actualFuncCount, maxFuncCount, funcs);
3055}
3056
3057extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003058void bccGetPragmas(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003059 BCCsizei* actualStringCount,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003060 BCCsizei maxStringCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003061 BCCchar** strings)
3062{
3063 script->compiler.getPragmas(actualStringCount, maxStringCount, strings);
3064}
3065
3066extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003067void bccGetFunctions(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003068 BCCsizei* actualFunctionCount,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003069 BCCsizei maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003070 BCCchar** functions)
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003071{
3072 script->compiler.getFunctions(actualFunctionCount,
3073 maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003074 functions);
3075}
3076
3077extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003078void bccGetFunctionBinary(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003079 BCCchar* function,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003080 BCCvoid** base,
3081 BCCsizei* length)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003082{
3083 script->compiler.getFunctionBinary(function, base, length);
3084}
3085
3086struct BCCtype {
3087 const Compiler* compiler;
3088 const llvm::Type* t;
3089};
3090
3091} /* End of namespace bcc */