static void donotoptimise_apply(compile_t* c, reach_type_t* t, reach_method_t* m) { const char* strtab_name = m->name; m->intrinsic = true; ast_t* typearg = ast_child(m->typeargs); reach_type_t* t_elem = reach_type(c->reach, typearg); LLVMTypeRef params[2]; params[0] = t->use_type; params[1] = t_elem->use_type; start_function(c, m, m->result->use_type, params, 2); LLVMValueRef obj = LLVMGetParam(m->func, 1); LLVMTypeRef void_fn = LLVMFunctionType(c->void_type, &t_elem->use_type, 1, false); LLVMValueRef asmstr = LLVMConstInlineAsm(void_fn, "", "imr,~{memory}", true, false); LLVMBuildCall(c->builder, asmstr, &obj, 1, ""); LLVMBuildRet(c->builder, m->result->instance); codegen_finishfun(c); BOX_FUNCTION(); }
LLVMValueRef build_utcb_get(struct llvm_ctx *ctx) { LLVMTypeRef fntype = LLVMFunctionType(ctx->wordt, NULL, 0, 0); LLVMValueRef func = LLVMConstInlineAsm(fntype, "movl %gs:0,$0\n", "=r,~{dirflag},~{fpsr},~{flags}", 0, 0); LLVMValueRef call = LLVMBuildCall(ctx->builder, func, NULL, 0, "utcbget"); LLVMSetTailCall(call, 1); return LLVMBuildIntToPtr(ctx->builder, call, LLVMPointerType(ctx->wordt, 0), "utcb.wordp"); }
static void donotoptimise_observe(compile_t* c, reach_type_t* t) { FIND_METHOD("observe"); start_function(c, m, m->result->use_type, &t->use_type, 1); LLVMTypeRef void_fn = LLVMFunctionType(c->void_type, NULL, 0, false); LLVMValueRef asmstr = LLVMConstInlineAsm(void_fn, "", "~{memory}", true, false); LLVMBuildCall(c->builder, asmstr, NULL, 0, ""); LLVMBuildRet(c->builder, m->result->instance); codegen_finishfun(c); BOX_FUNCTION(); }
LLVMValueRef build_l4_ipc_call( struct llvm_ctx *ctx, LLVMValueRef arg_to, LLVMValueRef arg_timeouts, LLVMValueRef arg_fromspec, LLVMValueRef arg_mr0, LLVMValueRef *from_p, LLVMValueRef *mr1_p, LLVMValueRef *mr2_p) { LLVMTypeRef params[5]; for(int i=0; i<5; i++) params[i] = ctx->wordt; LLVMTypeRef ipc_result_type = LLVMStructTypeInContext(ctx->ctx, params, 4, 0); LLVMTypeRef ipc_type = LLVMFunctionType(ipc_result_type, params, 5, 0); LLVMValueRef fn = LLVMConstInlineAsm(ipc_type, /* NOTE: this compensates against LLVM 3.3's inability to save %ebp * over an asm statement. clearly a bug, but w/e. * * it's been around since at least LLVM 3.2. */ " pushl %ebp\n" "\tcall __L4_Ipc\n" "\tmovl %ebp, %ecx\n" "\tpopl %ebp\n", "={ax},={si},={bx},={cx},{ax},{cx},{dx},{si},{di},~{dirflag},~{fpsr},~{flags}", 1, 0); LLVMValueRef args[5] = { arg_to, arg_timeouts, arg_fromspec, arg_mr0, LLVMBuildPtrToInt(ctx->builder, ctx->utcb, ctx->wordt, "l4ipc.utcb"), }; LLVMValueRef result = LLVMBuildCall(ctx->builder, fn, args, 5, "l4ipc"); LLVMSetTailCall(result, 1); if(from_p != NULL) { *from_p = LLVMBuildExtractValue(ctx->builder, result, 0, "from"); } if(mr1_p != NULL) { *mr1_p = LLVMBuildExtractValue(ctx->builder, result, 2, "mr1"); } if(mr2_p != NULL) { *mr2_p = LLVMBuildExtractValue(ctx->builder, result, 3, "mr2"); } return LLVMBuildExtractValue(ctx->builder, result, 1, "mr0"); }
static void make_cpuid(compile_t* c) { if(target_is_x86(c->opt->triple)) { LLVMTypeRef elems[4] = {c->i32, c->i32, c->i32, c->i32}; LLVMTypeRef r_type = LLVMStructTypeInContext(c->context, elems, 4, false); LLVMTypeRef f_type = LLVMFunctionType(r_type, &c->i32, 1, false); LLVMValueRef fun = codegen_addfun(c, "internal.x86.cpuid", f_type); LLVMSetFunctionCallConv(fun, LLVMCCallConv); codegen_startfun(c, fun, NULL, NULL); LLVMValueRef cpuid = LLVMConstInlineAsm(f_type, "cpuid", "={ax},={bx},={cx},={dx},{ax}", false, false); LLVMValueRef zero = LLVMConstInt(c->i32, 0, false); LLVMValueRef result = LLVMBuildCall(c->builder, cpuid, &zero, 1, ""); LLVMBuildRet(c->builder, result); codegen_finishfun(c); } else { (void)c; } }