int main(int argc, char *argv[]) { double a, b; double numbers[6][2] = { {5.3, 6.01}, {5.00000001, 5.00000003}, {5.00000005, 5.00000001}, {-0.0000007, 0.00000007}, {-4.999999, -4.999998}, {4.999999, 4.999998} }; int i; for (i = 0; i < 6; i++) { a = numbers[i][0]; b = numbers[i][1]; printf( "Number a = %f\tNumber b = %f\tEquals = %s\n", a, b, float_compare(a, b) ? "true" : "false"); } return 0; }
OrcTestResult orc_test_compare_output_full (OrcProgram *program, int flags) { OrcExecutor *ex; int n; int m; OrcArray *dest_exec[4] = { NULL, NULL, NULL, NULL }; OrcArray *dest_emul[4] = { NULL, NULL, NULL, NULL }; OrcArray *src[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; int i; int j; int k; int have_dest = FALSE; OrcCompileResult result; int have_acc = FALSE; int acc_exec = 0, acc_emul = 0; int ret = ORC_TEST_OK; int bad = 0; int misalignment; ORC_DEBUG ("got here"); { OrcTarget *target; unsigned int flags; target = orc_target_get_default (); flags = orc_target_get_default_flags (target); result = orc_program_compile_full (program, target, flags); if (ORC_COMPILE_RESULT_IS_FATAL(result)) { ret = ORC_TEST_FAILED; goto out; } if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL(result)) { ret = ORC_TEST_INDETERMINATE; goto out; } } if (program->constant_n > 0) { n = program->constant_n; } else { n = 64 + (orc_random(&rand_context)&0xf); } ex = orc_executor_new (program); orc_executor_set_n (ex, n); if (program->is_2d) { if (program->constant_m > 0) { m = program->constant_m; } else { m = 8 + (orc_random(&rand_context)&0xf); } } else { m = 1; } orc_executor_set_m (ex, m); ORC_DEBUG("size %d %d", ex->n, ex->params[ORC_VAR_A1]); misalignment = 0; for(i=0;i<ORC_N_VARIABLES;i++){ if (program->vars[i].name == NULL) continue; if (program->vars[i].vartype == ORC_VAR_TYPE_SRC) { src[i-ORC_VAR_S1] = orc_array_new (n, m, program->vars[i].size, misalignment); orc_array_set_random (src[i-ORC_VAR_S1], &rand_context); misalignment++; } else if (program->vars[i].vartype == ORC_VAR_TYPE_DEST) { dest_exec[i-ORC_VAR_D1] = orc_array_new (n, m, program->vars[i].size, misalignment); orc_array_set_pattern (dest_exec[i], ORC_OOB_VALUE); dest_emul[i-ORC_VAR_D1] = orc_array_new (n, m, program->vars[i].size, misalignment); orc_array_set_pattern (dest_emul[i], ORC_OOB_VALUE); misalignment++; } else if (program->vars[i].vartype == ORC_VAR_TYPE_PARAM) { switch (program->vars[i].param_type) { case ORC_PARAM_TYPE_INT: orc_executor_set_param (ex, i, 2); break; case ORC_PARAM_TYPE_FLOAT: orc_executor_set_param_float (ex, i, 2.0); break; case ORC_PARAM_TYPE_INT64: orc_executor_set_param_int64 (ex, i, 2); break; case ORC_PARAM_TYPE_DOUBLE: orc_executor_set_param_double (ex, i, 2.0); break; } } } for(i=0;i<ORC_N_VARIABLES;i++){ if (program->vars[i].vartype == ORC_VAR_TYPE_DEST) { orc_executor_set_array (ex, i, dest_exec[i-ORC_VAR_D1]->data); orc_executor_set_stride (ex, i, dest_exec[i-ORC_VAR_D1]->stride); have_dest = TRUE; } if (program->vars[i].vartype == ORC_VAR_TYPE_SRC) { orc_executor_set_array (ex, i, src[i-ORC_VAR_S1]->data); orc_executor_set_stride (ex, i, src[i-ORC_VAR_S1]->stride); } } ORC_DEBUG ("running"); if (flags & ORC_TEST_FLAGS_BACKUP) { orc_executor_run_backup (ex); } else { orc_executor_run (ex); } ORC_DEBUG ("done running"); for(i=0;i<ORC_N_VARIABLES;i++){ if (program->vars[i].vartype == ORC_VAR_TYPE_ACCUMULATOR) { acc_exec = ex->accumulators[0]; have_acc = TRUE; } } for(i=0;i<ORC_N_VARIABLES;i++){ if (program->vars[i].vartype == ORC_VAR_TYPE_DEST) { orc_executor_set_array (ex, i, dest_emul[i]->data); orc_executor_set_stride (ex, i, dest_emul[i]->stride); } if (program->vars[i].vartype == ORC_VAR_TYPE_SRC) { ORC_DEBUG("setting array %p", src[i-ORC_VAR_S1]->data); orc_executor_set_array (ex, i, src[i-ORC_VAR_S1]->data); orc_executor_set_stride (ex, i, src[i-ORC_VAR_S1]->stride); } } orc_executor_emulate (ex); for(i=0;i<ORC_N_VARIABLES;i++){ if (program->vars[i].vartype == ORC_VAR_TYPE_ACCUMULATOR) { acc_emul = ex->accumulators[0]; } } for(k=ORC_VAR_D1;k<ORC_VAR_D1+4;k++){ if (program->vars[k].size > 0) { if (!orc_array_compare (dest_exec[k-ORC_VAR_D1], dest_emul[k-ORC_VAR_D1], flags)) { printf("dest array %d bad\n", k); bad = TRUE; } if (!orc_array_check_out_of_bounds (dest_exec[k-ORC_VAR_D1])) { printf("out of bounds failure\n"); ret = ORC_TEST_FAILED; } } } if (bad) { for(j=0;j<m;j++){ for(i=0;i<n;i++){ orc_uint64 a,b; int l; int line_bad = 0; printf("%2d %2d:", i, j); for(l=ORC_VAR_S1;l<ORC_VAR_S1+8;l++){ if (program->vars[l].size > 0) { if (flags & ORC_TEST_FLAGS_FLOAT) { print_array_val_float (src[l-ORC_VAR_S1], i, j); } else { print_array_val_hex (src[l-ORC_VAR_S1], i, j); } } } printf(" ->"); for(l=ORC_VAR_D1;l<ORC_VAR_D1+4;l++){ if (program->vars[l].size > 0) { if (flags & ORC_TEST_FLAGS_FLOAT) { a = print_array_val_float (dest_emul[l-ORC_VAR_D1], i, j); b = print_array_val_float (dest_exec[l-ORC_VAR_D1], i, j); if (!float_compare (dest_emul[l-ORC_VAR_D1], dest_exec[l-ORC_VAR_D1], i, j) != 0) { line_bad = TRUE; } } else { a = print_array_val_hex (dest_emul[l-ORC_VAR_D1], i, j); b = print_array_val_hex (dest_exec[l-ORC_VAR_D1], i, j); if (a != b) { line_bad = TRUE; } } } } if (line_bad) { printf(" *"); } printf("\n"); } } ret = ORC_TEST_FAILED; } if (have_acc) { if (acc_emul != acc_exec) { for(j=0;j<m;j++){ for(i=0;i<n;i++){ printf("%2d %2d:", i, j); for(k=0;k<ORC_N_VARIABLES;k++){ if (program->vars[k].name == NULL) continue; if (program->vars[k].vartype == ORC_VAR_TYPE_SRC && program->vars[k].size > 0) { if (flags & ORC_TEST_FLAGS_FLOAT) { print_array_val_float (src[k-ORC_VAR_S1], i, j); } else { print_array_val_signed (src[k-ORC_VAR_S1], i, j); } } } printf(" -> acc\n"); } } printf("acc %d %d\n", acc_emul, acc_exec); ret = ORC_TEST_FAILED; } } if (ret == ORC_TEST_FAILED) { printf("%s", orc_program_get_asm_code (program)); } for(i=0;i<4;i++){ if (dest_exec[i]) orc_array_free (dest_exec[i]); if (dest_emul[i]) orc_array_free (dest_emul[i]); } for(i=0;i<8;i++){ if (src[i]) orc_array_free (src[i]); } orc_executor_free (ex); out: orc_program_reset (program); return ret; }
static int float_compare2(const void *i, const void *j) { return float_compare((float*) i, (float*) j); }
bool Inliner::inline_primitive(Class* klass, CompiledMethod* cm, executor prim) { const char* inlined_prim = 0; if(prim == Primitives::tuple_at && count_ == 1) { inlined_prim = "tuple_at"; call_tuple_at(ops_, *this); } else if(prim == Primitives::tuple_put && count_ == 2) { inlined_prim = "tuple_put"; call_tuple_put(ops_, *this); } else if(prim == Primitives::fixnum_and && count_ == 1) { inlined_prim = "fixnum_and"; fixnum_and(ops_, *this); } else if(prim == Primitives::fixnum_or && count_ == 1) { inlined_prim = "fixnum_or"; fixnum_or(ops_, *this); } else if(prim == Primitives::fixnum_neg && count_ == 0) { inlined_prim = "fixnum_neg"; fixnum_neg(ops_, *this); } else if(prim == Primitives::fixnum_equal && count_ == 1) { inlined_prim = "fixnum_eq"; fixnum_compare(cEqual, ops_, *this); } else if(prim == Primitives::fixnum_lt && count_ == 1) { inlined_prim = "fixnum_lt"; fixnum_compare(cLessThan, ops_, *this); } else if(prim == Primitives::fixnum_le && count_ == 1) { inlined_prim = "fixnum_le"; fixnum_compare(cLessThanEqual, ops_, *this); } else if(prim == Primitives::fixnum_gt && count_ == 1) { inlined_prim = "fixnum_gt"; fixnum_compare(cGreaterThan, ops_, *this); } else if(prim == Primitives::fixnum_ge && count_ == 1) { inlined_prim = "fixnum_ge"; fixnum_compare(cGreaterThanEqual, ops_, *this); } else if(prim == Primitives::object_equal && count_ == 1) { inlined_prim = "object_equal"; object_equal(klass, ops_, *this); } else if(prim == Primitives::float_add && count_ == 1) { inlined_prim = "float_add"; float_op(cAdd, klass, ops_, *this); } else if(prim == Primitives::float_sub && count_ == 1) { inlined_prim = "float_sub"; float_op(cSub, klass, ops_, *this); } else if(prim == Primitives::float_mul && count_ == 1) { inlined_prim = "float_mul"; float_op(cMultiply, klass, ops_, *this); } else if(prim == Primitives::float_div && count_ == 1) { inlined_prim = "float_div"; float_op(cDivide, klass, ops_, *this); } else if(prim == Primitives::float_mod && count_ == 1) { inlined_prim = "float_mod"; float_op(cMod, klass, ops_, *this); } else if(prim == Primitives::float_equal && count_ == 1) { inlined_prim = "float_equal"; float_compare(cEqual, klass, ops_, *this); } else if(prim == Primitives::float_lt && count_ == 1) { inlined_prim = "float_lt"; float_compare(cLessThan, klass, ops_, *this); } else if(prim == Primitives::float_le && count_ == 1) { inlined_prim = "float_le"; float_compare(cLessThanEqual, klass, ops_, *this); } else if(prim == Primitives::float_gt && count_ == 1) { inlined_prim = "float_gt"; float_compare(cGreaterThan, klass, ops_, *this); } else if(prim == Primitives::float_ge && count_ == 1) { inlined_prim = "float_ge"; float_compare(cGreaterThanEqual, klass, ops_, *this); } else if(prim == Primitives::fixnum_s_eqq && count_ == 1) { inlined_prim = "fixnum_s_eqq"; fixnum_s_eqq(ops_, *this); } else if(prim == Primitives::symbol_s_eqq && count_ == 1) { inlined_prim = "symbol_s_eqq"; symbol_s_eqq(ops_, *this); } else { JITStubResults stub_res; if(Primitives::get_jit_stub(cm->prim_index(), stub_res)) { if(stub_res.arg_count() == count_) { Value* self = recv(); ops_.check_class(self, klass, failure()); std::vector<Value*> call_args; Signature sig(ops_.state(), "Object"); sig << "VM"; call_args.push_back(ops_.vm()); if(stub_res.pass_callframe()) { sig << "CallFrame"; call_args.push_back(ops_.call_frame()); } sig << "Object"; call_args.push_back(self); for(int i = 0; i < stub_res.arg_count(); i++) { sig << "Object"; call_args.push_back(arg(i)); } Function* func = sig.function(stub_res.name()); func->setDoesNotCapture(1, true); if(stub_res.pass_callframe()) { func->setDoesNotCapture(2, true); } Value* res = sig.call(stub_res.name(), call_args, "prim_value", ops_.b()); // Only doing this when stub_res.can_fail() causes an exception // to be thrown when running the ci specs, need to investigate. BasicBlock* cont = ops_.new_block("continue"); Value* as_i = ops_.ptrtoint(res); Value* icmp = ops_.b().CreateICmpEQ(as_i, ConstantInt::get(ops_.state()->IntPtrTy, reinterpret_cast<intptr_t>(Qundef))); use_send_for_failure(); ops_.b().CreateCondBr(icmp, failure(), cont); ops_.set_block(cont); set_result(res); if(ops_.state()->config().jit_inline_debug) { context_.inline_log("inlining") << ops_.state()->symbol_cstr(cm->scope()->module()->name()) << "#" << ops_.state()->symbol_cstr(cm->name()) << " into " << ops_.state()->symbol_cstr(ops_.method_name()) << ". generic primitive: " << stub_res.name() << "\n"; } return true; } } } if(inlined_prim) { if(ops_.state()->config().jit_inline_debug) { context_.inline_log("inlining") << ops_.state()->symbol_cstr(cm->scope()->module()->name()) << "#" << ops_.state()->symbol_cstr(cm->name()) << " into " << ops_.state()->symbol_cstr(ops_.method_name()) << ". primitive " << inlined_prim << "\n"; } return true; } // Add more primitive inlining! if(ops_.state()->config().jit_inline_debug) { context_.inline_log("NOT inlining") << ops_.state()->symbol_cstr(cm->scope()->module()->name()) << "#" << ops_.state()->symbol_cstr(cm->name()) << " into " << ops_.state()->symbol_cstr(ops_.method_name()) << ". primitive: " << ops_.state()->symbol_cstr(cm->primitive()) << "\n"; } return false; }
int8_t obj_compare(pPmObj_t pobj1, pPmObj_t pobj2) { #ifdef HAVE_BYTEARRAY PmReturn_t retval; pPmObj_t pobj; #endif /* HAVE_BYTEARRAY */ C_ASSERT(pobj1 != C_NULL); C_ASSERT(pobj2 != C_NULL); /* Check if pointers are same */ if (pobj1 == pobj2) { return C_SAME; } /* If types are different, objs must differ */ if (OBJ_GET_TYPE(pobj1) != OBJ_GET_TYPE(pobj2)) { return C_DIFFER; } #ifdef HAVE_BYTEARRAY /* If object is an instance, get the thing it contains */ if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_CLI) { retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj1)->cli_attrs, PM_NONE, &pobj); PM_RETURN_IF_ERROR(retval); pobj1 = pobj; } if (OBJ_GET_TYPE(pobj2) == OBJ_TYPE_CLI) { retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj2)->cli_attrs, PM_NONE, &pobj); PM_RETURN_IF_ERROR(retval); pobj2 = pobj; } /* If types are different, objs must differ */ if (OBJ_GET_TYPE(pobj1) != OBJ_GET_TYPE(pobj2)) { return C_DIFFER; } #endif /* HAVE_BYTEARRAY */ /* Otherwise handle types individually */ switch (OBJ_GET_TYPE(pobj1)) { case OBJ_TYPE_NON: return C_SAME; case OBJ_TYPE_INT: return ((pPmInt_t)pobj1)->val == ((pPmInt_t)pobj2)->val ? C_SAME : C_DIFFER; #ifdef HAVE_FLOAT case OBJ_TYPE_FLT: { pPmObj_t r_pobj; float_compare(pobj1, pobj2, &r_pobj, COMP_EQ); return (r_pobj == PM_TRUE) ? C_SAME : C_DIFFER; } #endif /* HAVE_FLOAT */ case OBJ_TYPE_STR: return string_compare((pPmString_t)pobj1, (pPmString_t)pobj2); case OBJ_TYPE_TUP: case OBJ_TYPE_LST: #ifdef HAVE_BYTEARRAY case OBJ_TYPE_BYA: #endif /* HAVE_BYTEARRAY */ return seq_compare(pobj1, pobj2); case OBJ_TYPE_DIC: return dict_compare(pobj1, pobj2); default: break; } /* All other types would need same pointer to be true */ return C_DIFFER; }