LLVMValueRef lp_build_const_aos(struct gallivm_state *gallivm, struct lp_type type, double r, double g, double b, double a, const unsigned char *swizzle) { const unsigned char default_swizzle[4] = {0, 1, 2, 3}; LLVMTypeRef elem_type; LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; unsigned i; assert(type.length % 4 == 0); assert(type.length <= LP_MAX_VECTOR_LENGTH); elem_type = lp_build_elem_type(gallivm, type); if(swizzle == NULL) swizzle = default_swizzle; if(type.floating) { elems[swizzle[0]] = LLVMConstReal(elem_type, r); elems[swizzle[1]] = LLVMConstReal(elem_type, g); elems[swizzle[2]] = LLVMConstReal(elem_type, b); elems[swizzle[3]] = LLVMConstReal(elem_type, a); } else { double dscale = lp_const_scale(type); elems[swizzle[0]] = LLVMConstInt(elem_type, r*dscale + 0.5, 0); elems[swizzle[1]] = LLVMConstInt(elem_type, g*dscale + 0.5, 0); elems[swizzle[2]] = LLVMConstInt(elem_type, b*dscale + 0.5, 0); elems[swizzle[3]] = LLVMConstInt(elem_type, a*dscale + 0.5, 0); } for(i = 4; i < type.length; ++i) elems[i] = elems[i % 4]; return LLVMConstVector(elems, type.length); }
LLVMValueRef gen_int(compile_t* c, ast_t* ast) { ast_t* type = deferred_reify(c->frame->reify, ast_type(ast), c->opt); reach_type_t* t = reach_type(c->reach, type); ast_free_unattached(type); compile_type_t* c_t = (compile_type_t*)t->c_type; lexint_t* value = ast_int(ast); LLVMValueRef vlow = LLVMConstInt(c->i128, value->low, false); LLVMValueRef vhigh = LLVMConstInt(c->i128, value->high, false); LLVMValueRef shift = LLVMConstInt(c->i128, 64, false); vhigh = LLVMConstShl(vhigh, shift); vhigh = LLVMConstAdd(vhigh, vlow); if(c_t->primitive == c->i128) return vhigh; if((c_t->primitive == c->f32) || (c_t->primitive == c->f64)) return LLVMConstUIToFP(vhigh, c_t->primitive); return LLVMConstTrunc(vhigh, c_t->primitive); }
static LLVMValueRef scm_to_llvm_value(int type, SCM scm_value) { switch (type) { case SCM_FOREIGN_TYPE_FLOAT: case SCM_FOREIGN_TYPE_DOUBLE: return LLVMConstReal(llvm_type(type), scm_to_double(scm_value)); case SCM_FOREIGN_TYPE_BOOL: return LLVMConstInt(llvm_type(type), scm_is_true(scm_value), 0); case SCM_FOREIGN_TYPE_UINT8: case SCM_FOREIGN_TYPE_UINT16: case SCM_FOREIGN_TYPE_UINT32: case SCM_FOREIGN_TYPE_UINT64: return LLVMConstInt(llvm_type(type), scm_to_uint64(scm_value), 0); case SCM_FOREIGN_TYPE_INT8: case SCM_FOREIGN_TYPE_INT16: case SCM_FOREIGN_TYPE_INT32: case SCM_FOREIGN_TYPE_INT64: return LLVMConstInt(llvm_type(type), scm_to_int64(scm_value), 1); default: return NULL; }; }
static void trace_known(compile_t* c, LLVMValueRef ctx, LLVMValueRef object, ast_t* type, int mutability) { reach_type_t* t = reach_type(c->reach, type); LLVMValueRef args[4]; args[0] = ctx; args[1] = LLVMBuildBitCast(c->builder, object, c->object_ptr, ""); args[2] = LLVMBuildBitCast(c->builder, t->desc, c->descriptor_ptr, ""); args[3] = LLVMConstInt(c->i32, mutability, false); gencall_runtime(c, "pony_traceknown", args, 4, ""); }
LLVMValueRef gen_string(compile_t* c, ast_t* ast) { const char* name = ast_name(ast); genned_string_t k; k.string = name; size_t index = HASHMAP_UNKNOWN; genned_string_t* string = genned_strings_get(&c->strings, &k, &index); if(string != NULL) return string->global; ast_t* type = ast_type(ast); pony_assert(is_literal(type, "String")); reach_type_t* t = reach_type(c->reach, type); compile_type_t* c_t = (compile_type_t*)t->c_type; size_t len = ast_name_len(ast); LLVMValueRef args[4]; args[0] = c_t->desc; args[1] = LLVMConstInt(c->intptr, len, false); args[2] = LLVMConstInt(c->intptr, len + 1, false); args[3] = codegen_string(c, name, len); LLVMValueRef inst = LLVMConstNamedStruct(c_t->structure, args, 4); LLVMValueRef g_inst = LLVMAddGlobal(c->module, c_t->structure, ""); LLVMSetInitializer(g_inst, inst); LLVMSetGlobalConstant(g_inst, true); LLVMSetLinkage(g_inst, LLVMPrivateLinkage); LLVMSetUnnamedAddr(g_inst, true); string = POOL_ALLOC(genned_string_t); string->string = name; string->global = g_inst; genned_strings_putindex(&c->strings, string, index); return g_inst; }
static LLVMValueRef emit_swizzle( struct lp_build_tgsi_context * bld_base, LLVMValueRef value, unsigned swizzle_x, unsigned swizzle_y, unsigned swizzle_z, unsigned swizzle_w) { LLVMValueRef swizzles[4]; LLVMTypeRef i32t = LLVMInt32TypeInContext(bld_base->base.gallivm->context); swizzles[0] = LLVMConstInt(i32t, swizzle_x, 0); swizzles[1] = LLVMConstInt(i32t, swizzle_y, 0); swizzles[2] = LLVMConstInt(i32t, swizzle_z, 0); swizzles[3] = LLVMConstInt(i32t, swizzle_w, 0); return LLVMBuildShuffleVector(bld_base->base.gallivm->builder, value, LLVMGetUndef(LLVMTypeOf(value)), LLVMConstVector(swizzles, 4), ""); }
/** * Return mask ? a : b; * * mask is a TGSI_WRITEMASK_xxx. */ LLVMValueRef lp_build_select_aos(struct lp_build_context *bld, unsigned mask, LLVMValueRef a, LLVMValueRef b) { LLVMBuilderRef builder = bld->gallivm->builder; const struct lp_type type = bld->type; const unsigned n = type.length; unsigned i, j; assert((mask & ~0xf) == 0); assert(lp_check_value(type, a)); assert(lp_check_value(type, b)); if(a == b) return a; if((mask & 0xf) == 0xf) return a; if((mask & 0xf) == 0x0) return b; if(a == bld->undef || b == bld->undef) return bld->undef; /* * There are two major ways of accomplishing this: * - with a shuffle * - with a select * * The flip between these is empirical and might need to be adjusted. */ if (n <= 4) { /* * Shuffle. */ LLVMTypeRef elem_type = LLVMInt32TypeInContext(bld->gallivm->context); LLVMValueRef shuffles[LP_MAX_VECTOR_LENGTH]; for(j = 0; j < n; j += 4) for(i = 0; i < 4; ++i) shuffles[j + i] = LLVMConstInt(elem_type, (mask & (1 << i) ? 0 : n) + j + i, 0); return LLVMBuildShuffleVector(builder, a, b, LLVMConstVector(shuffles, n), ""); } else { LLVMValueRef mask_vec = lp_build_const_mask_aos(bld->gallivm, type, mask); return lp_build_select(bld, mask_vec, a, b); } }
static LLVMValueRef make_field_list(compile_t* c, reach_type_t* t) { // The list is an array of field descriptors. uint32_t count; if(t->underlying == TK_TUPLETYPE) count = t->field_count; else count = 0; LLVMTypeRef field_type = LLVMArrayType(c->field_descriptor, count); // If we aren't a tuple, return a null pointer to a list. if(count == 0) return LLVMConstNull(LLVMPointerType(field_type, 0)); // Create a constant array of field descriptors. size_t buf_size = count * sizeof(LLVMValueRef); LLVMValueRef* list = (LLVMValueRef*)ponyint_pool_alloc_size(buf_size); for(uint32_t i = 0; i < count; i++) { LLVMValueRef fdesc[2]; fdesc[0] = LLVMConstInt(c->i32, LLVMOffsetOfElement(c->target_data, t->primitive, i), false); if(t->fields[i].type->desc != NULL) { // We are a concrete type. fdesc[1] = LLVMConstBitCast(t->fields[i].type->desc, c->descriptor_ptr); } else { // We aren't a concrete type. fdesc[1] = LLVMConstNull(c->descriptor_ptr); } list[i] = LLVMConstStructInContext(c->context, fdesc, 2, false); } LLVMValueRef field_array = LLVMConstArray(c->field_descriptor, list, count); // Create a global to hold the array. const char* name = genname_fieldlist(t->name); LLVMValueRef global = LLVMAddGlobal(c->module, field_type, name); LLVMSetGlobalConstant(global, true); LLVMSetLinkage(global, LLVMPrivateLinkage); LLVMSetInitializer(global, field_array); ponyint_pool_free_size(buf_size, list); return global; }
LLVMValueRef lp_build_zero(struct gallivm_state *gallivm, struct lp_type type) { if (type.length == 1) { if (type.floating) return lp_build_const_float(gallivm, 0.0); else return LLVMConstInt(LLVMIntTypeInContext(gallivm->context, type.width), 0, 0); } else { LLVMTypeRef vec_type = lp_build_vec_type(gallivm, type); return LLVMConstNull(vec_type); } }
LLVMValueRef ac_build_buffer_load_format(struct ac_llvm_context *ctx, LLVMValueRef rsrc, LLVMValueRef vindex, LLVMValueRef voffset, bool can_speculate) { LLVMValueRef args [] = { LLVMBuildBitCast(ctx->builder, rsrc, ctx->v4i32, ""), vindex, voffset, LLVMConstInt(ctx->i1, 0, 0), /* glc */ LLVMConstInt(ctx->i1, 0, 0), /* slc */ }; return ac_build_intrinsic(ctx, "llvm.amdgcn.buffer.load.format.v4f32", ctx->v4f32, args, ARRAY_SIZE(args), /* READNONE means writes can't affect it, while * READONLY means that writes can affect it. */ can_speculate && HAVE_LLVM >= 0x0400 ? AC_FUNC_ATTR_READNONE : AC_FUNC_ATTR_READONLY); }
static LLVMValueRef special_case_platform(compile_t* c, ast_t* ast) { AST_GET_CHILDREN(ast, positional, named, postfix); AST_GET_CHILDREN(postfix, receiver, method); const char* method_name = ast_name(method); bool is_target; if(os_is_target(method_name, c->opt->release, &is_target, c->opt)) return LLVMConstInt(c->ibool, is_target ? 1 : 0, false); ast_error(c->opt->check.errors, ast, "unknown Platform setting"); return NULL; }
int llvm_set_metadata(void) { LLVMBuilderRef b = LLVMCreateBuilder(); LLVMValueRef values[] = { LLVMConstInt(LLVMInt32Type(), 0, 0) }; // This used to trigger an assertion LLVMSetMetadata( LLVMBuildRetVoid(b), LLVMGetMDKindID("kind", 4), LLVMMDNode(values, 1)); LLVMDisposeBuilder(b); return 0; }
LLVMValueRef lp_build_zero(struct lp_type type) { if (type.length == 1) { if (type.floating) return LLVMConstReal(LLVMFloatType(), 0.0); else return LLVMConstInt(LLVMIntType(type.width), 0, 0); } else { LLVMTypeRef vec_type = lp_build_vec_type(type); return LLVMConstNull(vec_type); } }
static void emit_declaration( struct lp_build_tgsi_aos_context *bld, const struct tgsi_full_declaration *decl) { LLVMTypeRef vec_type = lp_build_vec_type(bld->base.type); unsigned first = decl->Range.First; unsigned last = decl->Range.Last; unsigned idx; for (idx = first; idx <= last; ++idx) { switch (decl->Declaration.File) { case TGSI_FILE_TEMPORARY: assert(idx < LP_MAX_TGSI_TEMPS); if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) { LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(), last + 1, 0); bld->temps_array = lp_build_array_alloca(bld->base.builder, vec_type, array_size, ""); } else { bld->temps[idx] = lp_build_alloca(bld->base.builder, vec_type, ""); } break; case TGSI_FILE_OUTPUT: bld->outputs[idx] = lp_build_alloca(bld->base.builder, vec_type, ""); break; case TGSI_FILE_ADDRESS: assert(idx < LP_MAX_TGSI_ADDRS); bld->addr[idx] = lp_build_alloca(bld->base.builder, vec_type, ""); break; case TGSI_FILE_PREDICATE: assert(idx < LP_MAX_TGSI_PREDS); bld->preds[idx] = lp_build_alloca(bld->base.builder, vec_type, ""); break; default: /* don't need to declare other vars */ break; } } }
static LLVMValueRef gen_identity_from_value(compile_t* c, LLVMValueRef value) { LLVMTypeRef type = LLVMTypeOf(value); switch(LLVMGetTypeKind(type)) { case LLVMFloatTypeKind: value = LLVMBuildBitCast(c->builder, value, c->i32, ""); return LLVMBuildZExt(c->builder, value, c->i64, ""); case LLVMDoubleTypeKind: return LLVMBuildBitCast(c->builder, value, c->i64, ""); case LLVMIntegerTypeKind: { uint32_t width = LLVMGetIntTypeWidth(type); if(width < 64) value = LLVMBuildZExt(c->builder, value, c->i64, ""); else if(width > 64) value = LLVMBuildTrunc(c->builder, value, c->i64, ""); return value; } case LLVMStructTypeKind: { uint32_t count = LLVMCountStructElementTypes(type); LLVMValueRef result = LLVMConstInt(c->i64, 0, false); for(uint32_t i = 0; i < count; i++) { LLVMValueRef elem = LLVMBuildExtractValue(c->builder, value, i, ""); elem = gen_identity_from_value(c, elem); result = LLVMBuildXor(c->builder, result, elem, ""); } return result; } case LLVMPointerTypeKind: return LLVMBuildPtrToInt(c->builder, value, c->i64, ""); default: {} } assert(0); return NULL; }
static void add_dispatch_case(compile_t* c, gentype_t* g, ast_t* fun, uint32_t index, LLVMValueRef handler, LLVMTypeRef type) { // Add a case to the dispatch function to handle this message. codegen_startfun(c, g->dispatch_fn, false); LLVMBasicBlockRef block = codegen_block(c, "handler"); LLVMValueRef id = LLVMConstInt(c->i32, index, false); LLVMAddCase(g->dispatch_switch, id, block); // Destructure the message. LLVMPositionBuilderAtEnd(c->builder, block); LLVMValueRef ctx = LLVMGetParam(g->dispatch_fn, 0); LLVMValueRef this_ptr = LLVMGetParam(g->dispatch_fn, 1); LLVMValueRef msg = LLVMBuildBitCast(c->builder, LLVMGetParam(g->dispatch_fn, 2), type, ""); int count = LLVMCountParams(handler); size_t buf_size = count * sizeof(LLVMValueRef); LLVMValueRef* args = (LLVMValueRef*)pool_alloc_size(buf_size); args[0] = LLVMBuildBitCast(c->builder, this_ptr, g->use_type, ""); // Trace the message. LLVMValueRef start_trace = gencall_runtime(c, "pony_gc_recv", &ctx, 1, ""); ast_t* params = ast_childidx(fun, 3); ast_t* param = ast_child(params); bool need_trace = false; for(int i = 1; i < count; i++) { LLVMValueRef field = LLVMBuildStructGEP(c->builder, msg, i + 2, ""); args[i] = LLVMBuildLoad(c->builder, field, ""); need_trace |= gentrace(c, ctx, args[i], ast_type(param)); param = ast_sibling(param); } if(need_trace) { gencall_runtime(c, "pony_recv_done", &ctx, 1, ""); } else { LLVMInstructionEraseFromParent(start_trace); } // Call the handler. codegen_call(c, handler, args, count); LLVMBuildRetVoid(c->builder); codegen_finishfun(c); pool_free_size(buf_size, args); }
void gendesc_init(compile_t* c, gentype_t* g) { // Initialise the global descriptor. uint32_t size = (uint32_t)LLVMABISizeOfType(c->target_data, g->structure); uint32_t trait_count = 0; LLVMValueRef trait_list = make_trait_list(c, g, &trait_count); // Generate a separate type ID for every type. LLVMValueRef args[DESC_LENGTH]; reachable_type_t* t = reach_type(c->reachable, g->type_name); args[DESC_ID] = LLVMConstInt(c->i32, t->type_id, false); args[DESC_SIZE] = LLVMConstInt(c->i32, size, false); args[DESC_TRAIT_COUNT] = LLVMConstInt(c->i32, trait_count, false); args[DESC_FIELD_COUNT] = make_field_count(c, g); args[DESC_FIELD_OFFSET] = make_field_offset(c, g); args[DESC_TRACE] = make_function_ptr(c, genname_trace(g->type_name), c->trace_fn); args[DESC_SERIALISE] = make_function_ptr(c, genname_serialise(g->type_name), c->trace_fn); args[DESC_DESERIALISE] = make_function_ptr(c, genname_deserialise(g->type_name), c->trace_fn); args[DESC_DISPATCH] = make_function_ptr(c, genname_dispatch(g->type_name), c->dispatch_fn); args[DESC_FINALISE] = make_function_ptr(c, genname_finalise(g->type_name), c->final_fn); args[DESC_EVENT_NOTIFY] = LLVMConstInt(c->i32, genfun_vtable_index(c, g, stringtab("_event_notify"), NULL), false); args[DESC_TRAITS] = trait_list; args[DESC_FIELDS] = make_field_list(c, g); args[DESC_VTABLE] = make_vtable(c, g); LLVMValueRef desc = LLVMConstNamedStruct(g->desc_type, args, DESC_LENGTH); LLVMSetInitializer(g->desc, desc); LLVMSetGlobalConstant(g->desc, true); }
LLVMValueRef gen_string(compile_t* c, ast_t* ast) { ast_t* type = ast_type(ast); const char* name = ast_name(ast); size_t len = strlen(name); LLVMValueRef args[4]; args[0] = LLVMConstInt(c->i32, 0, false); args[1] = LLVMConstInt(c->i32, 0, false); LLVMValueRef str = LLVMConstStringInContext(c->context, name, (int)len, false); LLVMValueRef g_str = LLVMAddGlobal(c->module, LLVMTypeOf(str), "$strval"); LLVMSetLinkage(g_str, LLVMInternalLinkage); LLVMSetInitializer(g_str, str); LLVMSetGlobalConstant(g_str, true); LLVMValueRef str_ptr = LLVMConstInBoundsGEP(g_str, args, 2); gentype_t g; if(!gentype(c, type, &g)) return NULL; args[0] = g.desc; args[1] = LLVMConstInt(c->i64, len, false); args[2] = LLVMConstInt(c->i64, 0, false); args[3] = str_ptr; LLVMValueRef inst = LLVMConstNamedStruct(g.structure, args, 4); LLVMValueRef g_inst = LLVMAddGlobal(c->module, g.structure, "$string"); LLVMSetInitializer(g_inst, inst); LLVMSetGlobalConstant(g_inst, true); LLVMSetLinkage(g_inst, LLVMInternalLinkage); return g_inst; }
/** * Perform the occlusion test and increase the counter. * Test the depth mask. Add the number of channel which has none zero mask * into the occlusion counter. e.g. maskvalue is {-1, -1, -1, -1}. * The counter will add 4. * * \param type holds element type of the mask vector. * \param maskvalue is the depth test mask. * \param counter is a pointer of the uint32 counter. */ static void lp_build_occlusion_count(LLVMBuilderRef builder, struct lp_type type, LLVMValueRef maskvalue, LLVMValueRef counter) { LLVMValueRef countmask = lp_build_const_int_vec(type, 1); LLVMValueRef countv = LLVMBuildAnd(builder, maskvalue, countmask, "countv"); LLVMTypeRef i8v16 = LLVMVectorType(LLVMInt8Type(), 16); LLVMValueRef counti = LLVMBuildBitCast(builder, countv, i8v16, "counti"); LLVMValueRef maskarray[4] = { LLVMConstInt(LLVMInt32Type(), 0, 0), LLVMConstInt(LLVMInt32Type(), 4, 0), LLVMConstInt(LLVMInt32Type(), 8, 0), LLVMConstInt(LLVMInt32Type(), 12, 0), }; LLVMValueRef shufflemask = LLVMConstVector(maskarray, 4); LLVMValueRef shufflev = LLVMBuildShuffleVector(builder, counti, LLVMGetUndef(i8v16), shufflemask, "shufflev"); LLVMValueRef shuffle = LLVMBuildBitCast(builder, shufflev, LLVMInt32Type(), "shuffle"); LLVMValueRef count = lp_build_intrinsic_unary(builder, "llvm.ctpop.i32", LLVMInt32Type(), shuffle); LLVMValueRef orig = LLVMBuildLoad(builder, counter, "orig"); LLVMValueRef incr = LLVMBuildAdd(builder, orig, count, "incr"); LLVMBuildStore(builder, incr, counter); }
static LLVMValueRef gen_digestof_int64(compile_t* c, LLVMValueRef value) { pony_assert(LLVMTypeOf(value) == c->i64); if(target_is_ilp32(c->opt->triple)) { LLVMValueRef shift = LLVMConstInt(c->i64, 32, false); LLVMValueRef high = LLVMBuildLShr(c->builder, value, shift, ""); high = LLVMBuildTrunc(c->builder, high, c->i32, ""); value = LLVMBuildTrunc(c->builder, value, c->i32, ""); value = LLVMBuildXor(c->builder, value, high, ""); } return value; }
LLVMValueRef ac_build_umsb(struct ac_llvm_context *ctx, LLVMValueRef arg, LLVMTypeRef dst_type) { LLVMValueRef args[2] = { arg, LLVMConstInt(ctx->i1, 1, 0), }; LLVMValueRef msb = ac_build_intrinsic(ctx, "llvm.ctlz.i32", dst_type, args, ARRAY_SIZE(args), AC_FUNC_ATTR_READNONE); /* The HW returns the last bit index from MSB, but TGSI/NIR wants * the index from LSB. Invert it by doing "31 - msb". */ msb = LLVMBuildSub(ctx->builder, LLVMConstInt(ctx->i32, 31, false), msb, ""); /* check for zero */ return LLVMBuildSelect(ctx->builder, LLVMBuildICmp(ctx->builder, LLVMIntEQ, arg, LLVMConstInt(ctx->i32, 0, 0), ""), LLVMConstInt(ctx->i32, -1, true), msb, ""); }
static LLVMValueRef make_trait_list(compile_t* c, gentype_t* g) { // The list is an array of integers. uint32_t count = trait_count(c, g); // If we have no traits, return a null pointer to a list. if(count == 0) return LLVMConstNull(LLVMPointerType(LLVMArrayType(c->i32, 0), 0)); // Sort the trait identifiers. size_t tid_size = count * sizeof(uint32_t); uint32_t* tid = (uint32_t*)pool_alloc_size(tid_size); reachable_type_t* t = reach_type(c->reachable, g->type_name); assert(t != NULL); size_t i = HASHMAP_BEGIN; size_t index = 0; reachable_type_t* provide; while((provide = reachable_type_cache_next(&t->subtypes, &i)) != NULL) tid[index++] = provide->type_id; qsort(tid, index, sizeof(uint32_t), cmp_uint32); index = unique_uint32(tid, index); // Create a constant array of trait identifiers. size_t list_size = index * sizeof(LLVMValueRef); LLVMValueRef* list = (LLVMValueRef*)pool_alloc_size(list_size); for(i = 0; i < index; i++) list[i] = LLVMConstInt(c->i32, tid[i], false); count = (uint32_t)index; LLVMValueRef trait_array = LLVMConstArray(c->i32, list, count); // Create a global to hold the array. const char* name = genname_traitlist(g->type_name); LLVMTypeRef type = LLVMArrayType(c->i32, count); LLVMValueRef global = LLVMAddGlobal(c->module, type, name); LLVMSetGlobalConstant(global, true); LLVMSetLinkage(global, LLVMInternalLinkage); LLVMSetInitializer(global, trait_array); pool_free_size(tid_size, tid); pool_free_size(list_size, list); return global; }
LLVMValueRef gen_or(compile_t* c, ast_t* left, ast_t* right) { LLVMValueRef l_value = gen_expr(c, left); LLVMValueRef r_value = gen_expr(c, right); if((l_value == NULL) || (r_value == NULL)) return NULL; if(LLVMIsConstant(l_value) && LLVMIsConstant(r_value)) return LLVMConstOr(l_value, r_value); if(is_always_true(c, l_value) || is_always_true(c, r_value)) return LLVMConstInt(c->i1, 1, false); return LLVMBuildOr(c->builder, l_value, r_value, ""); }
static LLVMValueRef llvm_load_const_buffer( struct lp_build_tgsi_context * bld_base, LLVMValueRef OffsetValue, unsigned ConstantAddressSpace) { LLVMValueRef offset[2] = { LLVMConstInt(LLVMInt64TypeInContext(bld_base->base.gallivm->context), 0, false), OffsetValue }; LLVMTypeRef const_ptr_type = LLVMPointerType(LLVMArrayType(LLVMVectorType(bld_base->base.elem_type, 4), 1024), ConstantAddressSpace); LLVMValueRef const_ptr = LLVMBuildIntToPtr(bld_base->base.gallivm->builder, lp_build_const_int32(bld_base->base.gallivm, 0), const_ptr_type, ""); LLVMValueRef ptr = LLVMBuildGEP(bld_base->base.gallivm->builder, const_ptr, offset, 2, ""); return LLVMBuildLoad(bld_base->base.gallivm->builder, ptr, ""); }
static LLVMValueRef translateStringBinOp(NodeKind Op, LLVMValueRef ValueE1, LLVMValueRef ValueE2) { LLVMValueRef StrCmpFn = LLVMGetNamedFunction(Module, "strcmp"); LLVMValueRef CmpArgs[] = { ValueE1, ValueE2 }, CallStrCmp = LLVMBuildCall(Builder, StrCmpFn, CmpArgs, 2, ""), ZeroConst = LLVMConstInt(LLVMInt32Type(), 0, 1); switch (Op) { case LtOp: return LLVMBuildICmp(Builder, LLVMIntSLT, CallStrCmp, ZeroConst, ""); case LeOp: return LLVMBuildICmp(Builder, LLVMIntSLE, CallStrCmp, ZeroConst, ""); case GtOp: return LLVMBuildICmp(Builder, LLVMIntSGT, CallStrCmp, ZeroConst, ""); case GeOp: return LLVMBuildICmp(Builder, LLVMIntSGE, CallStrCmp, ZeroConst, ""); case EqOp: return LLVMBuildICmp(Builder, LLVMIntEQ, CallStrCmp, ZeroConst, ""); case DiffOp: return LLVMBuildICmp(Builder, LLVMIntNE, CallStrCmp, ZeroConst, ""); default: return NULL; } }
struct vm_value * vm_value_new_from_int_constant(int int_constant) { struct vm_value *vmval; vmval = calloc(1, sizeof(struct vm_value)); if (!vmval) { fprintf(stderr, "Memory allocation request failed.\n"); exit(EXIT_FAILURE); } vmval->type_specifier = TYPE_INT; vmval->llvm_type = get_llvm_type(TYPE_INT); vmval->llvm_value = LLVMConstInt(vmval->llvm_type, int_constant, 0); return vmval; }
LLVMValueRef ett_default_value(EagleComplexType *type) { switch(type->type) { case ETInt1: case ETInt8: case ETUInt8: case ETInt16: case ETUInt16: case ETInt32: case ETUInt32: case ETInt64: case ETUInt64: case ETEnum: return LLVMConstInt(ett_llvm_type(type), 0, 0); case ETFloat: case ETDouble: return LLVMConstReal(ett_llvm_type(type), 0.0); case ETPointer: return LLVMConstPointerNull(ett_llvm_type(type)); case ETStruct: { Arraylist *types; ty_struct_get_members(type, NULL, &types); LLVMValueRef vals[types->count]; for(int i = 0; i < types->count; i++) vals[i] = ett_default_value(types->items[i]); return LLVMConstNamedStruct(ett_llvm_type(type), vals, types->count); } case ETArray: { EagleArrayType *at = (EagleArrayType *)type; LLVMValueRef val = ett_default_value(at->of); LLVMValueRef vals[at->ct]; for(int i = 0; i < at->ct; i++) vals[i] = val; return LLVMConstArray(ett_llvm_type(at->of), vals, at->ct); } default: return NULL; } }
static inline LLVMValueRef LLVM_visit(ASTNode *node, LLVMBuilderRef builder) { switch(node->type) { case AST_BINARY_OP: { ASTBinaryOp *binary_op = (ASTBinaryOp*)node; LLVMValueRef a = LLVM_visit(binary_op->lhs, builder); LLVMValueRef b = LLVM_visit(binary_op->rhs, builder); switch(binary_op->op) { case '+': return LLVMBuildAdd(builder, a, b, "a + b"); case '-': return LLVMBuildSub(builder, a, b, "a - b"); case '*': return LLVMBuildMul(builder, a, b, "a * b"); case '/': return LLVMBuildSDiv(builder, a, b, "a / b"); } } case AST_INT: { return LLVMConstInt(LLVMInt32Type(), ((ASTInt*)node)->value, 0); } } }
LLVMValueRef lp_build_const_int_vec(struct lp_type type, long long val) { LLVMTypeRef elem_type = lp_build_int_elem_type(type); LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; unsigned i; assert(type.length <= LP_MAX_VECTOR_LENGTH); for(i = 0; i < type.length; ++i) elems[i] = LLVMConstInt(elem_type, val, type.sign ? 1 : 0); if (type.length == 1) return elems[0]; return LLVMConstVector(elems, type.length); }
/** * Build constant-valued element from a scalar value. */ LLVMValueRef lp_build_const_elem(struct lp_type type, double val) { LLVMTypeRef elem_type = lp_build_elem_type(type); LLVMValueRef elem; if(type.floating) { elem = LLVMConstReal(elem_type, val); } else { double dscale = lp_const_scale(type); elem = LLVMConstInt(elem_type, val*dscale + 0.5, 0); } return elem; }