LLVM ã®ããã¯ã¨ã³ãã«ã¯ã½ã¼ã¹ã³ã¼ããçæã§ãããã®ãããã
% llc --help : (snip) : -march - Architecture to generate code for: =x86 - 32-bit X86: Pentium-Pro and above =x86-64 - 64-bit X86: EM64T and AMD64 =sparc - SPARC =ppc32 - PowerPC 32 =ppc64 - PowerPC 64 =alpha - Alpha (incomplete) =ia64 - IA-64 (Itanium) =arm - ARM =thumb - Thumb =mips - Mips =cellspu - STI CBEA Cell SPU =c - C backend =msil - MSIL backend =cpp - C++ backend :
ããã§åç´ãª C ã®ã½ã¼ã¹ã³ã¼ãããããã³ã¼ãã«å¤æããå¾ã§ C è¨èªããã¯ã¨ã³ã㧠C ã®ã½ã¼ã¹ã³ã¼ãã«æ»ãã¦ã¿ãã
#include <stdio.h> int main(int argc, char** argv) { printf("Hello, World!\n"); return 0; }
ããã printf.c ã¨ãããã¡ã¤ã«ã«ä¿åãã¦ãllvm ã§ãã«ããã«ãããã
% llvm-gcc -emit-llvm printf.c -c # printf.o (bitcode) ãçæãããã % llc -march=c printf.o -f # printf.o.cbe.c ãçæãããã
çæããã printf.o.cbe.c ã¯ä»¥ä¸ã®ã¨ããã*1
/* Provide Declarations */ #include <stdarg.h> #include <setjmp.h> /* get a declaration for alloca */ #if defined(__CYGWIN__) || defined(__MINGW32__) #define alloca(x) __builtin_alloca((x)) #define _alloca(x) __builtin_alloca((x)) #elif defined(__APPLE__) extern void *__builtin_alloca(unsigned long); #define alloca(x) __builtin_alloca(x) #define longjmp _longjmp #define setjmp _setjmp #elif defined(__sun__) #if defined(__sparcv9) extern void *__builtin_alloca(unsigned long); #else extern void *__builtin_alloca(unsigned int); #endif #define alloca(x) __builtin_alloca(x) #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #define alloca(x) __builtin_alloca(x) #elif defined(_MSC_VER) #define inline _inline #define alloca(x) _alloca(x) #else #include <alloca.h> #endif #ifndef __GNUC__ /* Can only support "linkonce" vars with GCC */ #define __attribute__(X) #endif #if defined(__GNUC__) && defined(__APPLE_CC__) #define __EXTERNAL_WEAK__ __attribute__((weak_import)) #elif defined(__GNUC__) #define __EXTERNAL_WEAK__ __attribute__((weak)) #else #define __EXTERNAL_WEAK__ #endif #if defined(__GNUC__) && defined(__APPLE_CC__) #define __ATTRIBUTE_WEAK__ #elif defined(__GNUC__) #define __ATTRIBUTE_WEAK__ __attribute__((weak)) #else #define __ATTRIBUTE_WEAK__ #endif #if defined(__GNUC__) #define __HIDDEN__ __attribute__((visibility("hidden"))) #endif #ifdef __GNUC__ #define LLVM_NAN(NanStr) __builtin_nan(NanStr) /* Double */ #define LLVM_NANF(NanStr) __builtin_nanf(NanStr) /* Float */ #define LLVM_NANS(NanStr) __builtin_nans(NanStr) /* Double */ #define LLVM_NANSF(NanStr) __builtin_nansf(NanStr) /* Float */ #define LLVM_INF __builtin_inf() /* Double */ #define LLVM_INFF __builtin_inff() /* Float */ #define LLVM_PREFETCH(addr,rw,locality) __builtin_prefetch(addr,rw,locality) #define __ATTRIBUTE_CTOR__ __attribute__((constructor)) #define __ATTRIBUTE_DTOR__ __attribute__((destructor)) #define LLVM_ASM __asm__ #else #define LLVM_NAN(NanStr) ((double)0.0) /* Double */ #define LLVM_NANF(NanStr) 0.0F /* Float */ #define LLVM_NANS(NanStr) ((double)0.0) /* Double */ #define LLVM_NANSF(NanStr) 0.0F /* Float */ #define LLVM_INF ((double)0.0) /* Double */ #define LLVM_INFF 0.0F /* Float */ #define LLVM_PREFETCH(addr,rw,locality) /* PREFETCH */ #define __ATTRIBUTE_CTOR__ #define __ATTRIBUTE_DTOR__ #define LLVM_ASM(X) #endif #if __GNUC__ < 4 /* Old GCC's, or compilers not GCC */ #define __builtin_stack_save() 0 /* not implemented */ #define __builtin_stack_restore(X) /* noop */ #endif #define CODE_FOR_MAIN() /* Any target-specific code for main()*/ #ifndef __cplusplus typedef unsigned char bool; #endif /* Support for floating point constants */ typedef unsigned long long ConstantDoubleTy; typedef unsigned int ConstantFloatTy; typedef struct { unsigned long long f1; unsigned short f2; unsigned short pad[3]; } ConstantFP80Ty; typedef struct { unsigned long long f1; unsigned long long f2; } ConstantFP128Ty; /* Global Declarations */ /* Helper union for bitcasts */ typedef union { unsigned int Int32; unsigned long long Int64; float Float; double Double; } llvmBitCastUnion; /* External Global Variable Declarations */ /* Function Declarations */ double fmod(double, double); float fmodf(float, float); long double fmodl(long double, long double); unsigned int main(unsigned int llvm_cbe_argc, unsigned char **llvm_cbe_argv); unsigned int puts(unsigned char *); unsigned char *malloc(); void free(unsigned char *); void abort(void); /* Global Variable Declarations */ static unsigned char _2E_str[14]; /* Global Variable Definitions and Initialization */ static unsigned char _2E_str[14] = "Hello, World!"; /* Function Bodies */ static inline int llvm_fcmp_ord(double X, double Y) { return X == X && Y == Y; } static inline int llvm_fcmp_uno(double X, double Y) { return X != X || Y != Y; } static inline int llvm_fcmp_ueq(double X, double Y) { return X == Y || llvm_fcmp_uno(X, Y); } static inline int llvm_fcmp_une(double X, double Y) { return X != Y; } static inline int llvm_fcmp_ult(double X, double Y) { return X < Y || llvm_fcmp_uno(X, Y); } static inline int llvm_fcmp_ugt(double X, double Y) { return X > Y || llvm_fcmp_uno(X, Y); } static inline int llvm_fcmp_ule(double X, double Y) { return X <= Y || llvm_fcmp_uno(X, Y); } static inline int llvm_fcmp_uge(double X, double Y) { return X >= Y || llvm_fcmp_uno(X, Y); } static inline int llvm_fcmp_oeq(double X, double Y) { return X == Y ; } static inline int llvm_fcmp_one(double X, double Y) { return X != Y && llvm_fcmp_ord(X, Y); } static inline int llvm_fcmp_olt(double X, double Y) { return X < Y ; } static inline int llvm_fcmp_ogt(double X, double Y) { return X > Y ; } static inline int llvm_fcmp_ole(double X, double Y) { return X <= Y ; } static inline int llvm_fcmp_oge(double X, double Y) { return X >= Y ; } unsigned int main(unsigned int llvm_cbe_argc, unsigned char **llvm_cbe_argv) { unsigned int llvm_cbe_argc_addr; /* Address-exposed local */ unsigned char **llvm_cbe_argv_addr; /* Address-exposed local */ unsigned int llvm_cbe_retval; /* Address-exposed local */ unsigned int llvm_cbe_tmp; /* Address-exposed local */ unsigned int llvm_cbe_alloca_20_point; unsigned int llvm_cbe_tmp1; unsigned int llvm_cbe_tmp2; unsigned int llvm_cbe_retval3; CODE_FOR_MAIN(); llvm_cbe_alloca_20_point = ((unsigned int )0u); *(&llvm_cbe_argc_addr) = llvm_cbe_argc; *(&llvm_cbe_argv_addr) = llvm_cbe_argv; llvm_cbe_tmp1 = puts(((&_2E_str[((signed int )0u)]))); *(&llvm_cbe_tmp) = 0u; llvm_cbe_tmp2 = *(&llvm_cbe_tmp); *(&llvm_cbe_retval) = llvm_cbe_tmp2; llvm_cbe_retval3 = *(&llvm_cbe_retval); return llvm_cbe_retval3; }
ãã©ãããã©ã¼ã æ¯ã®ãã¯ãã®å®ç¾©ã®å¾ã«ã¯ LLVM_ æ¥é è¾ãæã¤ãã¯ãã®å®ç¾©ãç¶ãã*2
- #if defined(__CYGWIN__) ã¨ãã表è¨ããããã¨ãããcygwin ã®ãã¨ãèãããã¦ããªãããã§ã¯ãªããããã
- ã ãã© __attribute__ 㯠__GNUC__ ãªãå¿ ãå®ç¾©ããã¦ãã¾ãã¿ãããªã¨ãããèããã¨ãã¨ããããã³ã³ãã¤ã«ã§ããç¨åº¦ã®èããããªãããã
- llvm_fcmp_* ãã¯ã㧠double åã®æ¯è¼æ¼ç®ãã©ãããã¦ãããå®éã«å ã® C ã½ã¼ã¹ã³ã¼ãã«ãã®ãããªæ¼ç®ãããå ´åã¯ãã®ãã¯ãã使ç¨ãããã以ä¸ã«ãã®ä¾ã示ãã
double func(double a, double b) { return (a >= b) ? a + b : a - b; }
double func(double llvm_cbe_a, double llvm_cbe_b) { double llvm_cbe_a_addr; /* Address-exposed local */ double llvm_cbe_b_addr; /* Address-exposed local */ double llvm_cbe_retval; /* Address-exposed local */ double llvm_cbe_iftmp_2e_0; /* Address-exposed local */ double llvm_cbe_tmp; /* Address-exposed local */ unsigned int llvm_cbe_alloca_20_point; double llvm_cbe_tmp1; double llvm_cbe_tmp2; double llvm_cbe_tmp5; double llvm_cbe_tmp6; double llvm_cbe_tmp13; double llvm_cbe_tmp14; double llvm_cbe_retval15; llvm_cbe_alloca_20_point = ((unsigned int )0u); *(&llvm_cbe_a_addr) = llvm_cbe_a; *(&llvm_cbe_b_addr) = llvm_cbe_b; llvm_cbe_tmp1 = *(&llvm_cbe_a_addr); llvm_cbe_tmp2 = *(&llvm_cbe_b_addr); llvm_cbe_tmp5 = *(&llvm_cbe_a_addr); llvm_cbe_tmp6 = *(&llvm_cbe_b_addr); if (((((unsigned char )(bool )(llvm_fcmp_oge(llvm_cbe_tmp1, llvm_cbe_tmp2)))) != ((unsigned char )0))) { goto llvm_cbe_bb; } else { goto llvm_cbe_bb8; } llvm_cbe_bb: *(&llvm_cbe_iftmp_2e_0) = (llvm_cbe_tmp5 + llvm_cbe_tmp6); goto llvm_cbe_bb12; llvm_cbe_bb8: *(&llvm_cbe_iftmp_2e_0) = (llvm_cbe_tmp5 - llvm_cbe_tmp6); goto llvm_cbe_bb12; llvm_cbe_bb12: llvm_cbe_tmp13 = *(&llvm_cbe_iftmp_2e_0); *(&llvm_cbe_tmp) = llvm_cbe_tmp13; llvm_cbe_tmp14 = *(&llvm_cbe_tmp); *(&llvm_cbe_retval) = llvm_cbe_tmp14; llvm_cbe_retval15 = *(&llvm_cbe_retval); return llvm_cbe_retval15; }
C++ 㨠MSIL ã«ã¤ãã¦ã¯æ°ãåãããæãä¸ããã