static void number_conversion(compile_t* c, num_conv_t* from, num_conv_t* to, bool native128) { if(!native128 && ((from->is_float && (to->size > 64)) || (to->is_float && (from->size > 64))) ) { return; } reach_type_t* t = reach_type_name(c->reach, from->type_name); if(t == NULL) return; FIND_METHOD(to->fun_name); start_function(c, m, to->type, &from->type, 1); LLVMValueRef arg = LLVMGetParam(m->func, 0); LLVMValueRef result; if(from->is_float) { if(to->is_float) { if(from->size < to->size) result = LLVMBuildFPExt(c->builder, arg, to->type, ""); else if(from->size > to->size) result = LLVMBuildFPTrunc(c->builder, arg, to->type, ""); else result = arg; } else if(to->is_signed) { result = LLVMBuildFPToSI(c->builder, arg, to->type, ""); } else { result = LLVMBuildFPToUI(c->builder, arg, to->type, ""); } } else if(to->is_float) { if(from->is_signed) result = LLVMBuildSIToFP(c->builder, arg, to->type, ""); else result = LLVMBuildUIToFP(c->builder, arg, to->type, ""); } else if(from->size > to->size) { result = LLVMBuildTrunc(c->builder, arg, to->type, ""); } else if(from->size < to->size) { if(from->is_signed) result = LLVMBuildSExt(c->builder, arg, to->type, ""); else result = LLVMBuildZExt(c->builder, arg, to->type, ""); } else { result = arg; } LLVMBuildRet(c->builder, result); codegen_finishfun(c); BOX_FUNCTION(); }
static void platform_debug(compile_t* c, reach_type_t* t) { FIND_METHOD("debug"); start_function(c, m, c->ibool, &t->use_type, 1); LLVMValueRef result = LLVMConstInt(c->ibool, !c->opt->release, false); LLVMBuildRet(c->builder, result); codegen_finishfun(c); BOX_FUNCTION(); }
static void platform_x86(compile_t* c, reach_type_t* t) { FIND_METHOD("x86"); start_function(c, m, c->ibool, &t->use_type, 1); LLVMValueRef result = LLVMConstInt(c->ibool, target_is_x86(c->opt->triple), false); LLVMBuildRet(c->builder, result); codegen_finishfun(c); BOX_FUNCTION(); }
static void f64_bits(compile_t* c, reach_type_t* t) { FIND_METHOD("bits"); start_function(c, m, c->i64, &c->f64, 1); LLVMValueRef result = LLVMBuildBitCast(c->builder, LLVMGetParam(m->func, 0), c->i64, ""); LLVMBuildRet(c->builder, result); codegen_finishfun(c); BOX_FUNCTION(); }
static void maybe_is_none(compile_t* c, reach_type_t* t) { // Returns true if the receiver is null. FIND_METHOD("is_none"); start_function(c, m, c->ibool, &t->use_type, 1); LLVMValueRef receiver = LLVMGetParam(m->func, 0); LLVMValueRef test = LLVMBuildIsNull(c->builder, receiver, ""); LLVMValueRef value = LLVMBuildZExt(c->builder, test, c->ibool, ""); LLVMBuildRet(c->builder, value); codegen_finishfun(c); BOX_FUNCTION(); }
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(); }
static void pointer_copy_to(compile_t* c, reach_type_t* t, reach_type_t* t_elem) { FIND_METHOD("_copy_to"); LLVMTypeRef params[3]; params[0] = t->use_type; params[1] = t->use_type; params[2] = c->intptr; start_function(c, m, t->use_type, params, 3); // Set up a constant integer for the allocation size. size_t size = (size_t)LLVMABISizeOfType(c->target_data, t_elem->use_type); LLVMValueRef l_size = LLVMConstInt(c->intptr, size, false); LLVMValueRef ptr = LLVMGetParam(m->func, 0); LLVMValueRef ptr2 = LLVMGetParam(m->func, 1); LLVMValueRef n = LLVMGetParam(m->func, 2); LLVMValueRef elen = LLVMBuildMul(c->builder, n, l_size, ""); LLVMValueRef args[5]; args[0] = LLVMBuildBitCast(c->builder, ptr2, c->void_ptr, ""); args[1] = LLVMBuildBitCast(c->builder, ptr, c->void_ptr, ""); args[2] = elen; args[3] = LLVMConstInt(c->i32, 1, false); args[4] = LLVMConstInt(c->i1, 0, false); // llvm.memcpy.*(ptr2, ptr, n * sizeof(elem), 1, 0) if(target_is_ilp32(c->opt->triple)) { gencall_runtime(c, "llvm.memcpy.p0i8.p0i8.i32", args, 5, ""); } else { gencall_runtime(c, "llvm.memcpy.p0i8.p0i8.i64", args, 5, ""); } LLVMBuildRet(c->builder, ptr); codegen_finishfun(c); BOX_FUNCTION(); }
static void pointer_apply(compile_t* c, reach_type_t* t, reach_type_t* t_elem) { FIND_METHOD("_apply"); LLVMTypeRef params[2]; params[0] = t->use_type; params[1] = c->intptr; start_function(c, m, t_elem->use_type, params, 2); LLVMValueRef ptr = LLVMGetParam(m->func, 0); LLVMValueRef index = LLVMGetParam(m->func, 1); LLVMValueRef elem_ptr = LLVMBuildBitCast(c->builder, ptr, LLVMPointerType(t_elem->use_type, 0), ""); LLVMValueRef loc = LLVMBuildGEP(c->builder, elem_ptr, &index, 1, ""); LLVMValueRef result = LLVMBuildLoad(c->builder, loc, ""); LLVMBuildRet(c->builder, result); codegen_finishfun(c); BOX_FUNCTION(); }
static void maybe_apply(compile_t* c, reach_type_t* t, reach_type_t* t_elem) { // Returns the receiver if it isn't null. FIND_METHOD("apply"); start_function(c, m, t_elem->use_type, &t->use_type, 1); LLVMValueRef result = LLVMGetParam(m->func, 0); LLVMValueRef test = LLVMBuildIsNull(c->builder, result, ""); LLVMBasicBlockRef is_false = codegen_block(c, ""); LLVMBasicBlockRef is_true = codegen_block(c, ""); LLVMBuildCondBr(c->builder, test, is_true, is_false); LLVMPositionBuilderAtEnd(c->builder, is_false); result = LLVMBuildBitCast(c->builder, result, t_elem->use_type, ""); LLVMBuildRet(c->builder, result); LLVMPositionBuilderAtEnd(c->builder, is_true); gencall_throw(c); codegen_finishfun(c); BOX_FUNCTION(); }