2015-05-14 3 views
5

Sto imparando LLVM. Capisco che ci sono un certo numero di utili funzioni C fornite in LLVM già come intrinseche. Quindi sto provando a chiamare la funzione @printf dal mio codice.Come chiamare @printf in LLVM tramite il sistema di creazione moduli

ho trovato le rispettive parti del manuale di riferimento LLVM che descrivono il codice IR per farlo, che è relativo chiara:

declare i32 @printf(i8* noalias nocapture, ...) 
call i32 (i8*, ...)* @printf(i8* %msg, i32 12, i8 42) 

ecc, ma io non sono in grado di trovare il modo di farlo utilizzando il IRBuilder <> classe. Ho controllato la classe di builder ma non sono riuscito a capire nulla.

Non voglio passare qualsiasi variabile di fantasia, fondamentalmente solo qualcosa come

printf("%lu", variable_64_bit); 

in C o qualcosa del genere.

Qualcuno potrebbe darmi un'idea di cosa devo fare per chiamare la funzione printf attraverso il builder.

Grazie in anticipo

+0

Vuoi dire il 'IRBuilder'? –

+0

Sì, mi dispiace, ho corretto le mie domande su questo –

risposta

2

ho trovato un answer to this problem altrove. In realtà va un po 'al di là della mia domanda iniziale, ma è stato utile per me e spero che possa aiutare qualcun altro.

2
void kprintf(Module *mod, BasicBlock *bb, const char *format, ...) 
{ 
    Function *func_printf = mod->getFunction("printf"); 
    if (!func_printf) { 
     PointerType *Pty = PointerType::get(IntegerType::get(mod->getContext(), 8), 0); 
     FunctionType *FuncTy9 = FunctionType::get(IntegerType::get(mod->getContext(), 32), true); 

     func_printf = Function::Create(FuncTy9, GlobalValue::ExternalLinkage, "printf", mod); 
     func_printf->setCallingConv(CallingConv::C); 

     AttrListPtr func_printf_PAL; 
     func_printf->setAttributes(func_printf_PAL); 
    } 

    IRBuilder <> builder(mod->getContext()); 
    builder.SetInsertPoint(bb); 

    Value *str = builder.CreateGlobalStringPtr(format); 
    std::vector <Value *> int32_call_params; 
    int32_call_params.push_back(str); 

    va_list ap; 
    va_start(ap, format); 

    char *str_ptr = va_arg(ap, char*); 
    Value *format_ptr = builder.CreateGlobalStringPtr(str_ptr); 
    int32_call_params.push_back(format_ptr); 

    std::vector<llvm::Value*> extra; 
    do { 
     llvm::Value *op = va_arg(ap, llvm::Value*); 
     if (op) { 
      int32_call_params.push_back(op); 
     } else { 
      break; 
     } 
    } while (1); 
    va_end(ap); 

    CallInst * int32_call = CallInst::Create(func_printf, int32_call_params, "call", bb); 
} 
#define oprintf(...) kprintf(__VA_ARGS__) 
#define llvm_printf(...) oprintf(mod, bb, __VA_ARGS__, NULL) 

llvm_printf("Output: 0x%08X %f %d\n", 0x12345678, 3.1415926, 12345); 

spero di essere di aiuto a voi

+0

L'aggiunta di comandi di compilazione e di compilazione sarebbe super-utile. – jbcoe