static void Init(rtems_task_argument arg) { test_context *self = &test_instance; int i; int j; int k; TEST_BEGIN(); test_context_is_executing(); for (i = 0; i < 2; ++i) { for (j = 0; j < 2; ++j) { for (k = 0; k < 2; ++k) { printf("Test configuration %s %s %s... ", desc(i), desc(j), desc(k)); test(self, is_fp(i), is_fp(j), is_fp(k)); printf("done\n"); } } } TEST_END(); rtems_test_exit(0); }
static LLVMValueRef make_binop(compile_t* c, ast_t* left, ast_t* right, const_binop const_f, const_binop const_i, build_binop build_f, build_binop build_i) { 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)) { if(is_fp(l_value)) return const_f(l_value, r_value); return const_i(l_value, r_value); } if(is_fp(l_value)) { LLVMValueRef result = build_f(c->builder, l_value, r_value, ""); if(!c->opt->ieee_math) LLVMSetUnsafeAlgebra(result); return result; } return build_i(c->builder, l_value, r_value, ""); }
static LLVMValueRef make_cmp_value(compile_t* c, bool sign, LLVMValueRef l_value, LLVMValueRef r_value, LLVMRealPredicate cmp_f, LLVMIntPredicate cmp_si, LLVMIntPredicate cmp_ui) { if((l_value == NULL) || (r_value == NULL)) return NULL; if(LLVMIsConstant(l_value) && LLVMIsConstant(r_value)) { if(is_fp(l_value)) return LLVMConstFCmp(cmp_f, l_value, r_value); if(sign) return LLVMConstICmp(cmp_si, l_value, r_value); return LLVMConstICmp(cmp_ui, l_value, r_value); } if(is_fp(l_value)) return LLVMBuildFCmp(c->builder, cmp_f, l_value, r_value, ""); if(sign) return LLVMBuildICmp(c->builder, cmp_si, l_value, r_value, ""); return LLVMBuildICmp(c->builder, cmp_ui, l_value, r_value, ""); }
Z3_ast Z3_API Z3_mk_fpa_eq(Z3_context c, Z3_ast t1, Z3_ast t2) { Z3_TRY; LOG_Z3_mk_fpa_eq(c, t1, t2); RESET_ERROR_CODE(); if (!is_fp(c, t1) || !is_fp(c, t2)) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(nullptr); } api::context * ctx = mk_c(c); expr * a = ctx->fpautil().mk_float_eq(to_expr(t1), to_expr(t2)); ctx->save_ast_trail(a); RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(nullptr); }
Z3_ast Z3_API Z3_mk_fpa_fma(Z3_context c, Z3_ast rm, Z3_ast t1, Z3_ast t2, Z3_ast t3) { Z3_TRY; LOG_Z3_mk_fpa_fma(c, rm, t1, t2, t3); RESET_ERROR_CODE(); if (!is_rm(c, rm) || !is_fp(c, t1) || !is_fp(c, t2) || !is_fp(c, t3)) { SET_ERROR_CODE(Z3_INVALID_ARG, "rm and fp sorts expected"); RETURN_Z3(nullptr); } api::context * ctx = mk_c(c); expr * a = ctx->fpautil().mk_fma(to_expr(rm), to_expr(t1), to_expr(t2), to_expr(t3)); ctx->save_ast_trail(a); RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(nullptr); }
Z3_bool Z3_API Z3_fpa_get_numeral_sign(Z3_context c, Z3_ast t, int * sgn) { Z3_TRY; LOG_Z3_fpa_get_numeral_sign(c, t, sgn); RESET_ERROR_CODE(); CHECK_NON_NULL(t, 0); CHECK_VALID_AST(t, 0); if (sgn == nullptr) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } scoped_mpf val(mpfm); bool r = plugin->is_numeral(to_expr(t), val); if (!r || mpfm.is_nan(val)) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } *sgn = mpfm.sgn(val); return r; Z3_CATCH_RETURN(0); }
Z3_string Z3_API Z3_fpa_get_numeral_significand_string(Z3_context c, Z3_ast t) { Z3_TRY; LOG_Z3_fpa_get_numeral_significand_string(c, t); RESET_ERROR_CODE(); CHECK_NON_NULL(t, nullptr); CHECK_VALID_AST(t, nullptr); ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid); SASSERT(plugin != 0); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); return ""; } scoped_mpf val(mpfm); bool r = plugin->is_numeral(e, val); if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) { SET_ERROR_CODE(Z3_INVALID_ARG); return ""; } unsigned sbits = val.get().get_sbits(); scoped_mpq q(mpqm); mpqm.set(q, mpfm.sig(val)); if (!mpfm.is_denormal(val)) mpqm.add(q, mpfm.m_powers2(sbits - 1), q); mpqm.div(q, mpfm.m_powers2(sbits - 1), q); if (mpfm.is_inf(val)) mpqm.set(q, 0); std::stringstream ss; mpqm.display_decimal(ss, q, sbits); return mk_c(c)->mk_external_string(ss.str()); Z3_CATCH_RETURN(""); }
Z3_ast Z3_API Z3_fpa_get_numeral_sign_bv(Z3_context c, Z3_ast t) { Z3_TRY; LOG_Z3_fpa_get_numeral_sign_bv(c, t); RESET_ERROR_CODE(); CHECK_NON_NULL(t, nullptr); CHECK_VALID_AST(t, nullptr); ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid); api::context * ctx = mk_c(c); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(nullptr); } scoped_mpf val(mpfm); bool r = plugin->is_numeral(to_expr(t), val); if (!r || mpfm.is_nan(val)) { SET_ERROR_CODE(Z3_INVALID_ARG); return nullptr; } app * a; if (mpfm.is_pos(val)) a = ctx->bvutil().mk_numeral(0, 1); else a = ctx->bvutil().mk_numeral(1, 1); mk_c(c)->save_ast_trail(a); RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(nullptr); }
Z3_ast Z3_API Z3_fpa_get_numeral_significand_bv(Z3_context c, Z3_ast t) { Z3_TRY; LOG_Z3_fpa_get_numeral_significand_bv(c, t); RESET_ERROR_CODE(); CHECK_NON_NULL(t, nullptr); CHECK_VALID_AST(t, nullptr); ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid); SASSERT(plugin != 0); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(nullptr); } scoped_mpf val(mpfm); bool r = plugin->is_numeral(e, val); if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(nullptr); } unsigned sbits = val.get().get_sbits(); scoped_mpq q(mpqm); mpqm.set(q, mpfm.sig(val)); if (mpfm.is_inf(val)) mpqm.set(q, 0); app * a = mk_c(c)->bvutil().mk_numeral(q.get(), sbits-1); mk_c(c)->save_ast_trail(a); RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(nullptr); }
Z3_ast Z3_API Z3_mk_fpa_to_real(Z3_context c, Z3_ast t) { Z3_TRY; LOG_Z3_mk_fpa_to_real(c, t); RESET_ERROR_CODE(); if (!is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(nullptr); } api::context * ctx = mk_c(c); expr * a = ctx->fpautil().mk_to_real(to_expr(t)); ctx->save_ast_trail(a); RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(nullptr); }
Z3_ast Z3_API Z3_mk_fpa_to_sbv(Z3_context c, Z3_ast rm, Z3_ast t, unsigned sz) { Z3_TRY; LOG_Z3_mk_fpa_to_sbv(c, rm, t, sz); RESET_ERROR_CODE(); if (!is_rm(c, rm) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(nullptr); } api::context * ctx = mk_c(c); expr * a = ctx->fpautil().mk_to_sbv(to_expr(rm), to_expr(t), sz); ctx->save_ast_trail(a); RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(nullptr); }
Z3_ast Z3_API Z3_mk_fpa_to_ieee_bv(Z3_context c, Z3_ast t) { Z3_TRY; LOG_Z3_mk_fpa_to_ieee_bv(c, t); RESET_ERROR_CODE(); CHECK_NON_NULL(t, nullptr); CHECK_VALID_AST(t, nullptr); if (!is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(nullptr); } api::context * ctx = mk_c(c); Z3_ast r = of_ast(ctx->fpautil().mk_to_ieee_bv(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(nullptr); }
LLVMValueRef gen_neg(compile_t* c, ast_t* ast) { LLVMValueRef value = gen_expr(c, ast); if(value == NULL) return NULL; if(LLVMIsAConstantFP(value)) return LLVMConstFNeg(value); if(LLVMIsAConstantInt(value)) return LLVMConstNeg(value); if(is_fp(value)) return LLVMBuildFNeg(c->builder, value, ""); return LLVMBuildNeg(c->builder, value, ""); }
Z3_bool Z3_API Z3_fpa_get_numeral_exponent_int64(Z3_context c, Z3_ast t, int64_t * n, Z3_bool biased) { Z3_TRY; LOG_Z3_fpa_get_numeral_exponent_int64(c, t, n, biased); RESET_ERROR_CODE(); CHECK_NON_NULL(t, 0); CHECK_VALID_AST(t, 0); if (n == nullptr) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); SASSERT(plugin != 0); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); *n = 0; return 0; } scoped_mpf val(mpfm); bool r = plugin->is_numeral(e, val); if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) { SET_ERROR_CODE(Z3_INVALID_ARG); *n = 0; return 0; } unsigned ebits = val.get().get_ebits(); if (biased) { *n = mpfm.is_zero(val) ? 0 : mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) : mpfm.bias_exp(ebits, mpfm.exp(val)); } else { *n = mpfm.is_zero(val) ? 0 : mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) : mpfm.is_denormal(val) ? mpfm.mk_min_exp(ebits) : mpfm.exp(val); } return 1; Z3_CATCH_RETURN(0); }
Z3_string Z3_API Z3_fpa_get_numeral_exponent_string(Z3_context c, Z3_ast t, Z3_bool biased) { Z3_TRY; LOG_Z3_fpa_get_numeral_exponent_string(c, t, biased); RESET_ERROR_CODE(); CHECK_NON_NULL(t, nullptr); CHECK_VALID_AST(t, nullptr); ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); SASSERT(plugin != 0); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); return ""; } scoped_mpf val(mpfm); bool r = plugin->is_numeral(e, val); if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) { SET_ERROR_CODE(Z3_INVALID_ARG); return ""; } unsigned ebits = val.get().get_ebits(); mpf_exp_t exp; if (biased) { exp = mpfm.is_zero(val) ? 0 : mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) : mpfm.bias_exp(ebits, mpfm.exp(val)); } else { exp = mpfm.is_zero(val) ? 0 : mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) : mpfm.is_denormal(val) ? mpfm.mk_min_exp(ebits) : mpfm.exp(val); } std::stringstream ss; ss << exp; return mk_c(c)->mk_external_string(ss.str()); Z3_CATCH_RETURN(""); }
Z3_ast Z3_API Z3_fpa_get_numeral_exponent_bv(Z3_context c, Z3_ast t, Z3_bool biased) { Z3_TRY; LOG_Z3_fpa_get_numeral_exponent_bv(c, t, biased); RESET_ERROR_CODE(); CHECK_NON_NULL(t, nullptr); CHECK_VALID_AST(t, nullptr); ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(nullptr); } scoped_mpf val(mpfm); bool r = plugin->is_numeral(e, val); if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(nullptr); } unsigned ebits = val.get().get_ebits(); mpf_exp_t exp; if (biased) { exp = mpfm.is_zero(val) ? 0 : mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) : mpfm.bias_exp(ebits, mpfm.exp(val)); } else { exp = mpfm.is_zero(val) ? 0 : mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) : mpfm.is_denormal(val) ? mpfm.mk_min_exp(ebits) : mpfm.exp(val); } app * a = mk_c(c)->bvutil().mk_numeral(exp, ebits); mk_c(c)->save_ast_trail(a); RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(nullptr); }
Z3_bool Z3_API Z3_fpa_get_numeral_significand_uint64(Z3_context c, Z3_ast t, uint64_t * n) { Z3_TRY; LOG_Z3_fpa_get_numeral_significand_uint64(c, t, n); RESET_ERROR_CODE(); CHECK_NON_NULL(t, 0); CHECK_VALID_AST(t, 0); if (n == nullptr) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); unsynch_mpz_manager & mpzm = mpfm.mpz_manager(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid); SASSERT(plugin != 0); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); *n = 0; return 0; } scoped_mpf val(mpfm); bool r = plugin->is_numeral(e, val); const mpz & z = mpfm.sig(val); if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val)) || !mpzm.is_uint64(z)) { SET_ERROR_CODE(Z3_INVALID_ARG); *n = 0; return 0; } *n = mpzm.get_uint64(z); return 1; Z3_CATCH_RETURN(0); }
static const char *desc(int i) { return is_fp(i) ? "F" : "N"; }
LLVMValueRef make_divmod(compile_t* c, ast_t* left, ast_t* right, const_binop const_f, const_binop const_ui, const_binop const_si, build_binop build_f, build_binop build_ui, build_binop build_si) { ast_t* type = ast_type(left); bool sign = is_signed(c->opt, type); LLVMValueRef l_value = gen_expr(c, left); LLVMValueRef r_value = gen_expr(c, right); if((l_value == NULL) || (r_value == NULL)) return NULL; if(!is_fp(r_value) && LLVMIsConstant(r_value) && (LLVMConstIntGetSExtValue(r_value) == 0) ) { ast_error(right, "constant divide or mod by zero"); return NULL; } if(LLVMIsConstant(l_value) && LLVMIsConstant(r_value)) { if(is_fp(l_value)) return const_f(l_value, r_value); if(sign) return const_si(l_value, r_value); return const_ui(l_value, r_value); } if(is_fp(l_value)) return build_f(c->builder, l_value, r_value, ""); // Setup additional blocks. LLVMBasicBlockRef insert = LLVMGetInsertBlock(c->builder); LLVMBasicBlockRef then_block = codegen_block(c, "div_then"); LLVMBasicBlockRef post_block = codegen_block(c, "div_post"); // Check for div by zero. LLVMTypeRef r_type = LLVMTypeOf(r_value); LLVMValueRef zero = LLVMConstInt(r_type, 0, false); LLVMValueRef cmp = LLVMBuildICmp(c->builder, LLVMIntNE, r_value, zero, ""); LLVMBuildCondBr(c->builder, cmp, then_block, post_block); // Divisor is not zero. LLVMPositionBuilderAtEnd(c->builder, then_block); LLVMValueRef result; if(sign) result = build_si(c->builder, l_value, r_value, ""); else result = build_ui(c->builder, l_value, r_value, ""); LLVMBuildBr(c->builder, post_block); // Phi node. LLVMPositionBuilderAtEnd(c->builder, post_block); LLVMValueRef phi = LLVMBuildPhi(c->builder, r_type, ""); LLVMAddIncoming(phi, &zero, &insert, 1); LLVMAddIncoming(phi, &result, &then_block, 1); return phi; }