LLVMValueRef gen_int(compile_t* c, ast_t* ast) { ast_t* type = ast_type(ast); gentype_t g; if(!gentype(c, type, &g)) return NULL; __uint128_t value = ast_int(ast); uint64_t low, high; #if !defined(HAVE_STRUCT_INT128) low = (uint64_t)value; high = (uint64_t)(value >> 64); #else low = value.low; high = value.high; #endif LLVMValueRef vlow = LLVMConstInt(c->i128, low, false); LLVMValueRef vhigh = LLVMConstInt(c->i128, high, false); LLVMValueRef shift = LLVMConstInt(c->i128, 64, false); vhigh = LLVMConstShl(vhigh, shift); vhigh = LLVMConstAdd(vhigh, vlow); if(g.primitive == c->i128) return vhigh; if((g.primitive == c->f32) || (g.primitive == c->f64)) return LLVMConstUIToFP(vhigh, g.primitive); return LLVMConstTrunc(vhigh, g.primitive); }
/** * Generate a + b */ LLVMValueRef lp_build_add(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) { const struct lp_type type = bld->type; LLVMValueRef res; if(a == bld->zero) return b; if(b == bld->zero) return a; if(a == bld->undef || b == bld->undef) return bld->undef; if(bld->type.norm) { const char *intrinsic = NULL; if(a == bld->one || b == bld->one) return bld->one; if(util_cpu_caps.has_sse2 && type.width * type.length == 128 && !type.floating && !type.fixed) { if(type.width == 8) intrinsic = type.sign ? "llvm.x86.sse2.padds.b" : "llvm.x86.sse2.paddus.b"; if(type.width == 16) intrinsic = type.sign ? "llvm.x86.sse2.padds.w" : "llvm.x86.sse2.paddus.w"; } if(intrinsic) return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b); } if(LLVMIsConstant(a) && LLVMIsConstant(b)) res = LLVMConstAdd(a, b); else res = LLVMBuildAdd(bld->builder, a, b, ""); /* clamp to ceiling of 1.0 */ if(bld->type.norm && (bld->type.floating || bld->type.fixed)) res = lp_build_min_simple(bld, res, bld->one); /* XXX clamp to floor of -1 or 0??? */ return res; }
LLVMValueRef gen_int(compile_t* c, ast_t* ast) { ast_t* type = ast_type(ast); reach_type_t* t = reach_type(c->reach, 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(t->primitive == c->i128) return vhigh; if((t->primitive == c->f32) || (t->primitive == c->f64)) return LLVMConstUIToFP(vhigh, t->primitive); return LLVMConstTrunc(vhigh, t->primitive); }
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); }