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