END_TEST START_TEST(test_case) { const error_t expect[] = { { 13, "missing choice C in case statement" }, { 19, "missing choice B in case statement" }, { 30, "10 to 19" }, { 36, "4 to 2147483647" }, { 44, "2147483647" }, { 51, "value 50 is already covered" }, { 53, "range 60 to 64 is already covered" }, { 59, "value -1 outside STD.STANDARD.NATURAL bounds" }, { 58, "0 to 2147483647" }, { 79, "choices cover only 2 of 8 possible values" }, { 84, "expected 3 elements in aggregate but have 2" }, { 86, "expected 3 elements in aggregate but have 4" }, { 88, "expected 3 elements in string literal but have 2" }, { 90, "expected 3 elements in string literal but have 4" }, { 95, "choices do not cover all possible values" }, { 101, "choices cover only 2 of 100 possible values" }, { -1, NULL } }; expect_errors(expect); input_from_file(TESTDIR "/bounds/case.vhd"); tree_t a = parse_and_check(T_ENTITY, T_ARCH); fail_unless(sem_errors() == 0); simplify(a); bounds_check(a); fail_unless(bounds_errors() == (sizeof(expect) / sizeof(error_t)) - 1); }
/* API: Aligned complex-complex */ int convolve_complex(float *x, int x_len, float *h, int h_len, float *y, int y_len, int start, int len, int step, int offset) { void (*conv_func)(float *, float *, float *, int, int) = NULL; if (bounds_check(x_len, h_len, y_len, start, len, step) < 0) return -1; memset(y, 0, len * 2 * sizeof(float)); #ifdef HAVE_NEON if (step <= 4 && !(h_len % 4)) conv_func = neon_conv_cmplx_4n; #endif if (conv_func) { conv_func(&x[2 * (-(h_len - 1) + start)], h, y, h_len, len); } else { _base_convolve_complex(x, x_len, h, h_len, y, y_len, start, len, step, offset); } return len; }
size_t chck_buffer_fill_from_file(FILE *src, size_t size, size_t memb, struct chck_buffer *buf) { assert(src && buf); if (!bounds_check(buf, size, memb) || !buf->curpos || !src) return 0; return fread(buf->curpos, size, memb, src); }
size_t chck_buffer_fill(const void *src, size_t size, size_t memb, struct chck_buffer *buf) { assert(src && buf); if (!bounds_check(buf, size, memb) || !buf->curpos || !src) return 0; memcpy(buf->curpos, src, size * memb); return memb; }
size_t chck_buffer_fill_from_fd(int fd, size_t size, size_t memb, struct chck_buffer *buf) { assert(fd && buf); if (!bounds_check(buf, size, memb) || !buf->curpos) return 0; ssize_t ret = read(fd, buf->curpos, size * memb); if (unlikely(ret == -1 || ret == 0)) return 0; return (size_t)ret / size; }
END_TEST START_TEST(test_issue36) { input_from_file(TESTDIR "/bounds/issue36.vhd"); tree_t e = parse_and_check(T_ENTITY); fail_unless(sem_errors() == 0); simplify(e); bounds_check(e); fail_unless(bounds_errors() == 0); }
END_TEST START_TEST(test_issue200) { input_from_file(TESTDIR "/bounds/issue200.vhd"); tree_t a = parse_and_check(T_ENTITY, T_ARCH); fail_unless(sem_errors() == 0); simplify(a); bounds_check(a); fail_unless(bounds_errors() == 0); }
/* API: Non-aligned (no SSE) complex-complex */ int base_convolve_complex(float *x, int x_len, float *h, int h_len, float *y, int y_len, int start, int len, int step, int offset) { if (bounds_check(x_len, h_len, y_len, start, len, step) < 0) return -1; memset(y, 0, len * 2 * sizeof(float)); return _base_convolve_complex(x, x_len, h, h_len, y, y_len, start, len, step, offset); }
/* API: Aligned complex-real */ int convolve_real(float *x, int x_len, float *h, int h_len, float *y, int y_len, int start, int len, int step, int offset) { void (*conv_func)(float *, float *, float *, int) = NULL; if (bounds_check(x_len, h_len, y_len, start, len, step) < 0) return -1; memset(y, 0, len * 2 * sizeof(float)); #ifdef HAVE_NEON if (step <= 4) { switch (h_len) { case 4: conv_func = neon_conv_real4; break; case 8: conv_func = neon_conv_real8; break; case 12: conv_func = neon_conv_real12; break; case 16: conv_func = neon_conv_real16; break; case 20: conv_func = neon_conv_real20; break; } } #endif if (conv_func) { conv_func(&x[2 * (-(h_len - 1) + start)], h, y, len); } else { _base_convolve_real(x, x_len, h, h_len, y, y_len, start, len, step, offset); } return len; }
END_TEST START_TEST(test_issue208) { const error_t expect[] = { { 20, "case choices do not cover the following values of " }, { -1, NULL } }; expect_errors(expect); input_from_file(TESTDIR "/bounds/issue208.vhd"); tree_t a = parse_and_check(T_ENTITY, T_ARCH); fail_unless(sem_errors() == 0); simplify(a); bounds_check(a); fail_unless(bounds_errors() == ARRAY_LEN(expect) - 1); }
END_TEST START_TEST(test_issue150) { const error_t expect[] = { { 10, "expected 8 elements in aggregate but have 6" }, { -1, NULL } }; expect_errors(expect); input_from_file(TESTDIR "/bounds/issue150.vhd"); tree_t a = parse_and_check(T_ENTITY, T_ARCH); fail_unless(sem_errors() == 0); simplify(a); bounds_check(a); fail_unless(bounds_errors() == (sizeof(expect) / sizeof(error_t)) - 1); }
END_TEST START_TEST(test_issue99) { const error_t expect[] = { { 7, "type conversion argument -1.5 out of bounds 0 to 2147483647" }, { 8, "type conversion argument -1 out of bounds 1 to 5" }, { -1, NULL } }; expect_errors(expect); input_from_file(TESTDIR "/bounds/issue99.vhd"); tree_t a = parse_and_check(T_ENTITY, T_ARCH); fail_unless(sem_errors() == 0); simplify(a); bounds_check(a); fail_unless(bounds_errors() == (sizeof(expect) / sizeof(error_t)) - 1); }
END_TEST START_TEST(test_issue54) { const error_t expect[] = { { 12, "aggregate index 3 out of bounds 7 downto 4" }, { 12, "aggregate index 0 out of bounds 7 downto 4" }, { -1, NULL } }; expect_errors(expect); input_from_file(TESTDIR "/bounds/issue54.vhd"); tree_t a = parse_and_check(T_ENTITY, T_ARCH); fail_unless(sem_errors() == 0); simplify(a); bounds_check(a); fail_unless(bounds_errors() == (sizeof(expect) / sizeof(error_t)) - 1); }
void iTensor2::set(int n1, int n2, int value) { int k = (n1-1)*columns + (n2-1); bounds_check(); vec[k] = value; }
const int& iTensor2::get(int n1, int n2) const { int k = (n1-1)*columns + (n2-1); bounds_check(); return vec[k]; }
void dTensor2d::set(int n1,int n2,double value) { int k = getidx(n1,n2); bounds_check(); vec[k] = value; }
double& dTensor2d::fetch(int n1,int n2) { int k = getidx(n1,n2); bounds_check(); return vec[k]; }
const double& dTensor2d::get(int n1,int n2) const { int k = getidx(n1,n2); bounds_check(); return vec[k]; }
void dTensor4d::set(int n1,int n2,int n3,int n4,double value) { int k = getidx(n1,n2,n3,n4); bounds_check(); vec[k] = value; }
double& dTensor4d::fetch(int n1,int n2,int n3,int n4) { int k = getidx(n1,n2,n3,n4); bounds_check(); return vec[k]; }
const double& dTensor4d::get(int n1,int n2,int n3,int n4) const { int k = getidx(n1,n2,n3,n4); bounds_check(); return vec[k]; }
static int check_all_bounds(struct device *dev, const struct smiapp_pll_limits *limits, const struct smiapp_pll_branch_limits *op_limits, struct smiapp_pll *pll, struct smiapp_pll_branch *op_pll) { int rval; rval = bounds_check(dev, pll->pll_ip_clk_freq_hz, limits->min_pll_ip_freq_hz, limits->max_pll_ip_freq_hz, "pll_ip_clk_freq_hz"); if (!rval) rval = bounds_check( dev, pll->pll_multiplier, limits->min_pll_multiplier, limits->max_pll_multiplier, "pll_multiplier"); if (!rval) rval = bounds_check( dev, pll->pll_op_clk_freq_hz, limits->min_pll_op_freq_hz, limits->max_pll_op_freq_hz, "pll_op_clk_freq_hz"); if (!rval) rval = bounds_check( dev, op_pll->sys_clk_div, op_limits->min_sys_clk_div, op_limits->max_sys_clk_div, "op_sys_clk_div"); if (!rval) rval = bounds_check( dev, op_pll->sys_clk_freq_hz, op_limits->min_sys_clk_freq_hz, op_limits->max_sys_clk_freq_hz, "op_sys_clk_freq_hz"); if (!rval) rval = bounds_check( dev, op_pll->pix_clk_freq_hz, op_limits->min_pix_clk_freq_hz, op_limits->max_pix_clk_freq_hz, "op_pix_clk_freq_hz"); /* * If there are no OP clocks, the VT clocks are contained in * the OP clock struct. */ if (pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS) return rval; if (!rval) rval = bounds_check( dev, pll->vt.sys_clk_freq_hz, limits->vt.min_sys_clk_freq_hz, limits->vt.max_sys_clk_freq_hz, "vt_sys_clk_freq_hz"); if (!rval) rval = bounds_check( dev, pll->vt.pix_clk_freq_hz, limits->vt.min_pix_clk_freq_hz, limits->vt.max_pix_clk_freq_hz, "vt_pix_clk_freq_hz"); return rval; }
value_set_dereferencet::valuet value_set_dereferencet::build_reference_to( const exprt &what, const modet mode, const exprt &pointer_expr, const guardt &guard) { const typet &dereference_type= ns.follow(pointer_expr.type()).subtype(); if(what.id()==ID_unknown || what.id()==ID_invalid) { invalid_pointer(pointer_expr, guard); return valuet(); } if(what.id()!=ID_object_descriptor) throw "unknown points-to: "+what.id_string(); const object_descriptor_exprt &o=to_object_descriptor_expr(what); const exprt &root_object=o.root_object(); const exprt &object=o.object(); #if 0 std::cout << "O: " << from_expr(ns, "", root_object) << '\n'; #endif valuet result; if(root_object.id()=="NULL-object") { if(options.get_bool_option("pointer-check")) { guardt tmp_guard(guard); if(o.offset().is_zero()) { tmp_guard.add(null_pointer(pointer_expr)); dereference_callback.dereference_failure( "pointer dereference", "NULL pointer", tmp_guard); } else { tmp_guard.add(null_object(pointer_expr)); dereference_callback.dereference_failure( "pointer dereference", "NULL plus offset pointer", tmp_guard); } } } else if(root_object.id()==ID_dynamic_object) { // const dynamic_object_exprt &dynamic_object= // to_dynamic_object_expr(root_object); // the object produced by malloc exprt malloc_object= ns.lookup(CPROVER_PREFIX "malloc_object").symbol_expr(); exprt is_malloc_object=same_object(pointer_expr, malloc_object); // constraint that it actually is a dynamic object exprt dynamic_object_expr(ID_dynamic_object, bool_typet()); dynamic_object_expr.copy_to_operands(pointer_expr); // this is also our guard result.pointer_guard=dynamic_object_expr; // can't remove here, turn into *p result.value=dereference_exprt(pointer_expr, dereference_type); if(options.get_bool_option("pointer-check")) { // if(!dynamic_object.valid().is_true()) { // check if it is still alive guardt tmp_guard(guard); tmp_guard.add(deallocated(pointer_expr, ns)); dereference_callback.dereference_failure( "pointer dereference", "dynamic object deallocated", tmp_guard); } if(options.get_bool_option("bounds-check")) { if(!o.offset().is_zero()) { // check lower bound guardt tmp_guard(guard); tmp_guard.add(is_malloc_object); tmp_guard.add( dynamic_object_lower_bound( pointer_expr, ns, nil_exprt())); dereference_callback.dereference_failure( "pointer dereference", "dynamic object lower bound", tmp_guard); } { // check upper bound // we check SAME_OBJECT(__CPROVER_malloc_object, p) && // POINTER_OFFSET(p)+size>__CPROVER_malloc_size guardt tmp_guard(guard); tmp_guard.add(is_malloc_object); tmp_guard.add( dynamic_object_upper_bound( pointer_expr, dereference_type, ns, size_of_expr(dereference_type, ns))); dereference_callback.dereference_failure( "pointer dereference", "dynamic object upper bound", tmp_guard); } } } } else if(root_object.id()==ID_integer_address) { // This is stuff like *((char *)5). // This is turned into an access to __CPROVER_memory[...]. if(language_mode==ID_java) { result.value=nil_exprt(); return result; } const symbolt &memory_symbol=ns.lookup(CPROVER_PREFIX "memory"); exprt symbol_expr=symbol_exprt(memory_symbol.name, memory_symbol.type); if(base_type_eq( ns.follow(memory_symbol.type).subtype(), dereference_type, ns)) { // Types match already, what a coincidence! // We can use an index expression. exprt index_expr=index_exprt(symbol_expr, pointer_offset(pointer_expr)); index_expr.type()=ns.follow(memory_symbol.type).subtype(); result.value=index_expr; } else if(dereference_type_compare( ns.follow(memory_symbol.type).subtype(), dereference_type)) { exprt index_expr=index_exprt(symbol_expr, pointer_offset(pointer_expr)); index_expr.type()=ns.follow(memory_symbol.type).subtype(); result.value=typecast_exprt(index_expr, dereference_type); } else { // We need to use byte_extract. // Won't do this without a commitment to an endianness. if(config.ansi_c.endianness==configt::ansi_ct::endiannesst::NO_ENDIANNESS) { } else { exprt byte_extract(byte_extract_id(), dereference_type); byte_extract.copy_to_operands( symbol_expr, pointer_offset(pointer_expr)); result.value=byte_extract; } } } else { // something generic -- really has to be a symbol address_of_exprt object_pointer(object); if(o.offset().is_zero()) { equal_exprt equality(pointer_expr, object_pointer); if(ns.follow(equality.lhs().type())!=ns.follow(equality.rhs().type())) equality.lhs().make_typecast(equality.rhs().type()); result.pointer_guard=equality; } else { result.pointer_guard=same_object(pointer_expr, object_pointer); } guardt tmp_guard(guard); tmp_guard.add(result.pointer_guard); valid_check(object, tmp_guard, mode); const typet &object_type=ns.follow(object.type()); const exprt &root_object=o.root_object(); const typet &root_object_type=ns.follow(root_object.type()); exprt root_object_subexpression=root_object; if(dereference_type_compare(object_type, dereference_type) && o.offset().is_zero()) { // The simplest case: types match, and offset is zero! // This is great, we are almost done. result.value=object; if(object_type!=ns.follow(dereference_type)) result.value.make_typecast(dereference_type); } else if(root_object_type.id()==ID_array && dereference_type_compare( root_object_type.subtype(), dereference_type)) { // We have an array with a subtype that matches // the dereferencing type. // We will require well-alignedness! exprt offset; // this should work as the object is essentially the root object if(o.offset().is_constant()) offset=o.offset(); else offset=pointer_offset(pointer_expr); exprt adjusted_offset; // are we doing a byte? mp_integer element_size= dereference_type.id()==ID_empty? pointer_offset_size(char_type(), ns): pointer_offset_size(dereference_type, ns); if(element_size==1) { // no need to adjust offset adjusted_offset=offset; } else if(element_size<=0) { throw "unknown or invalid type size of:\n"+dereference_type.pretty(); } else { exprt element_size_expr= from_integer(element_size, offset.type()); adjusted_offset=binary_exprt( offset, ID_div, element_size_expr, offset.type()); // TODO: need to assert well-alignedness } index_exprt index_expr= index_exprt(root_object, adjusted_offset, root_object_type.subtype()); bounds_check(index_expr, tmp_guard); result.value=index_expr; if(ns.follow(result.value.type())!=ns.follow(dereference_type)) result.value.make_typecast(dereference_type); } else if(get_subexpression_at_offset( root_object_subexpression, o.offset(), dereference_type, ns)) { // Successfully found a member, array index, or combination thereof // that matches the desired type and offset: result.value=root_object_subexpression; } else { // we extract something from the root object result.value=o.root_object(); // this is relative to the root object const exprt offset=pointer_offset(pointer_expr); if(memory_model(result.value, dereference_type, tmp_guard, offset)) { // ok, done } else { if(options.get_bool_option("pointer-check")) { std::string msg="memory model not applicable (got `"; msg+=from_type(ns, "", result.value.type()); msg+="', expected `"; msg+=from_type(ns, "", dereference_type); msg+="')"; dereference_callback.dereference_failure( "pointer dereference", msg, tmp_guard); } return valuet(); // give up, no way that this is ok } } } return result; }
static int analyse(int argc, char **argv) { set_work_lib(); static struct option long_options[] = { { "bootstrap", no_argument, 0, 'b' }, { "dump-llvm", no_argument, 0, 'd' }, { "dump-vcode", optional_argument, 0, 'v' }, { "prefer-explicit", no_argument, 0, 'p' }, // DEPRECATED { "relax", required_argument, 0, 'r' }, { 0, 0, 0, 0 } }; int c, index = 0; const char *spec = ""; optind = 1; while ((c = getopt_long(argc, argv, spec, long_options, &index)) != -1) { switch (c) { case 0: // Set a flag break; case '?': fatal("unrecognised analyse option %s", argv[optind - 1]); case 'b': opt_set_int("bootstrap", 1); break; case 'd': opt_set_int("dump-llvm", 1); break; case 'v': opt_set_str("dump-vcode", optarg ?: ""); break; case 'p': warnf("the --prefer-explict option is deprecated: use " "--relax=prefer-explict instead"); opt_set_int("relax", RELAX_PREFER_EXPLICT); break; case 'r': opt_set_int("relax", parse_relax(optarg)); break; default: abort(); } } size_t unit_list_sz = 32; tree_t *units LOCAL = xmalloc(sizeof(tree_t) * unit_list_sz); int n_units = 0; for (int i = optind; i < argc; i++) { input_from_file(argv[i]); tree_t unit; while ((unit = parse()) && sem_check(unit)) ARRAY_APPEND(units, unit, n_units, unit_list_sz); } for (int i = 0; i < n_units; i++) { simplify(units[i]); bounds_check(units[i]); } if (parse_errors() + sem_errors() + bounds_errors() > 0) return EXIT_FAILURE; for (int i = 0; i < n_units; i++) { tree_kind_t kind = tree_kind(units[i]); const bool need_cgen = (kind == T_PACK_BODY) || ((kind == T_PACKAGE) && pack_needs_cgen(units[i])); if (need_cgen) opt(units[i]); else units[i] = NULL; } lib_save(lib_work()); for (int i = 0; i < n_units; i++) { if (units[i] != NULL) { lower_unit(units[i]); cgen(units[i]); } } return EXIT_SUCCESS; }
void goto_checkt::check_rec(const exprt &expr, guardt &guard, bool address) { if (address) { if (expr.id() == "dereference") { assert(expr.operands().size() == 1); check_rec(expr.op0(), guard, false); } else if (expr.id() == "index") { assert(expr.operands().size() == 2); check_rec(expr.op0(), guard, true); check_rec(expr.op1(), guard, false); } else { forall_operands(it, expr) check_rec(*it, guard, true); } return; } if (expr.is_address_of()) { assert(expr.operands().size() == 1); check_rec(expr.op0(), guard, true); return; } else if (expr.is_and() || expr.id() == "or") { if (!expr.is_boolean()) throw expr.id_string() + " must be Boolean, but got " + expr.pretty(); unsigned old_guards = guard.size(); for (unsigned i = 0; i < expr.operands().size(); i++) { const exprt &op = expr.operands()[i]; if (!op.is_boolean()) throw expr.id_string() + " takes Boolean operands only, but got " + op.pretty(); check_rec(op, guard, false); if (expr.id() == "or") { exprt tmp(op); tmp.make_not(); expr2tc tmp_expr; migrate_expr(tmp, tmp_expr); guard.move(tmp_expr); } else { expr2tc tmp; migrate_expr(op, tmp); guard.add(tmp); } } guard.resize(old_guards); return; } else if (expr.id() == "if") { if (expr.operands().size() != 3) throw "if takes three arguments"; if (!expr.op0().is_boolean()) { std::string msg = "first argument of if must be boolean, but got " + expr.op0().to_string(); throw msg; } check_rec(expr.op0(), guard, false); { unsigned old_guard = guard.size(); expr2tc tmp; migrate_expr(expr.op0(), tmp); guard.add(tmp); check_rec(expr.op1(), guard, false); guard.resize(old_guard); } { unsigned old_guard = guard.size(); exprt tmp(expr.op0()); tmp.make_not(); expr2tc tmp_expr; migrate_expr(tmp, tmp_expr); guard.move(tmp_expr); check_rec(expr.op2(), guard, false); guard.resize(old_guard); } return; } forall_operands(it, expr) check_rec(*it, guard, false); if (expr.id() == "index") { bounds_check(expr, guard); } else if (expr.id() == "/") { div_by_zero_check(expr, guard); if (expr.type().id() == "signedbv") { overflow_check(expr, guard); } else if (expr.type().id() == "floatbv") { nan_check(expr, guard); } } else if (expr.id() == "+" || expr.id() == "-" || expr.id() == "*" || expr.id() == "unary-" || expr.id() == "typecast") { if (expr.type().id() == "signedbv") { overflow_check(expr, guard); } else if (expr.type().id() == "floatbv") { nan_check(expr, guard); } } else if (expr.id() == "<=" || expr.id() == "<" || expr.id() == ">=" || expr.id() == ">") { pointer_rel_check(expr, guard); } else if (expr.id() == "mod") { div_by_zero_check(expr, guard); if (expr.type().id() == "signedbv") { overflow_check(expr, guard); } else if (expr.type().id() == "floatbv") { nan_check(expr, guard); } } }
/* * Heuristically guess the PLL tree for a given common multiplier and * divisor. Begin with the operational timing and continue to video * timing once operational timing has been verified. * * @mul is the PLL multiplier and @div is the common divisor * (pre_pll_clk_div and op_sys_clk_div combined). The final PLL * multiplier will be a multiple of @mul. * * @return Zero on success, error code on error. */ static int __smiapp_pll_calculate(struct device *dev, const struct smiapp_pll_limits *limits, struct smiapp_pll *pll, uint32_t mul, uint32_t div, uint32_t lane_op_clock_ratio, uint32_t lane_vt_clock_ratio) { uint32_t sys_div; uint32_t best_pix_div = INT_MAX >> 1; uint32_t vt_op_binning_div; /* * Higher multipliers (and divisors) are often required than * necessitated by the external clock and the output clocks. * There are limits for all values in the clock tree. These * are the minimum and maximum multiplier for mul. */ uint32_t more_mul_min, more_mul_max; uint32_t more_mul_factor; uint32_t min_vt_div, max_vt_div, vt_div; uint32_t min_sys_div, max_sys_div; unsigned int i; int rval; /* * Get pre_pll_clk_div so that our pll_op_clk_freq_hz won't be * too high. */ dev_dbg(dev, "pre_pll_clk_div %u\n", pll->pre_pll_clk_div); /* Don't go above max pll multiplier. */ more_mul_max = limits->max_pll_multiplier / mul; dev_dbg(dev, "more_mul_max: max_pll_multiplier check: %u\n", more_mul_max); /* Don't go above max pll op frequency. */ more_mul_max = min_t(uint64_t, more_mul_max, div_u64(limits->max_pll_op_freq_hz, (pll->ext_clk_freq_hz / pll->pre_pll_clk_div * mul))); dev_dbg(dev, "more_mul_max: max_pll_op_freq_hz check: %u\n", more_mul_max); /* Don't go above the division capability of op sys clock divider. */ more_mul_max = min(more_mul_max, limits->op.max_sys_clk_div * pll->pre_pll_clk_div / div); dev_dbg(dev, "more_mul_max: max_op_sys_clk_div check: %u\n", more_mul_max); /* Ensure we won't go above min_pll_multiplier. */ more_mul_max = min(more_mul_max, DIV_ROUND_UP(limits->max_pll_multiplier, mul)); dev_dbg(dev, "more_mul_max: min_pll_multiplier check: %u\n", more_mul_max); /* Ensure we won't go below min_pll_op_freq_hz. */ more_mul_min = div_u64_round_up( limits->min_pll_op_freq_hz, pll->ext_clk_freq_hz / pll->pre_pll_clk_div * mul); dev_dbg(dev, "more_mul_min: min_pll_op_freq_hz check: %u\n", more_mul_min); /* Ensure we won't go below min_pll_multiplier. */ more_mul_min = max(more_mul_min, DIV_ROUND_UP(limits->min_pll_multiplier, mul)); dev_dbg(dev, "more_mul_min: min_pll_multiplier check: %u\n", more_mul_min); if (more_mul_min > more_mul_max) { dev_dbg(dev, "unable to compute more_mul_min and more_mul_max\n"); return -EINVAL; } more_mul_factor = lcm(div, pll->pre_pll_clk_div) / div; dev_dbg(dev, "more_mul_factor: %u\n", more_mul_factor); more_mul_factor = lcm(more_mul_factor, limits->op.min_sys_clk_div); dev_dbg(dev, "more_mul_factor: min_op_sys_clk_div: %u\n", more_mul_factor); i = roundup(more_mul_min, more_mul_factor); if (!is_one_or_even(i)) i <<= 1; dev_dbg(dev, "final more_mul: %u\n", i); if (i > more_mul_max) { dev_dbg(dev, "final more_mul is bad, max %u\n", more_mul_max); return -EINVAL; } pll->pll_multiplier = mul * i; pll->op_sys_clk_div = div * i / pll->pre_pll_clk_div; dev_dbg(dev, "op_sys_clk_div: %u\n", pll->op_sys_clk_div); pll->pll_ip_clk_freq_hz = pll->ext_clk_freq_hz / pll->pre_pll_clk_div; pll->pll_op_clk_freq_hz = pll->pll_ip_clk_freq_hz * pll->pll_multiplier; /* Derive pll_op_clk_freq_hz. */ pll->op_sys_clk_freq_hz = div_u64(pll->pll_op_clk_freq_hz, pll->op_sys_clk_div); pll->op_pix_clk_div = pll->bits_per_pixel; if (pll->flags & SMIAPP_PLL_FLAG_OP_PIX_DIV_HALF) pll->op_pix_clk_div /= 2; dev_dbg(dev, "op_pix_clk_div: %u\n", pll->op_pix_clk_div); pll->op_pix_clk_freq_hz = div_u64(pll->op_sys_clk_freq_hz, pll->op_pix_clk_div); /* * Some sensors perform analogue binning and some do this * digitally. The ones doing this digitally can be roughly be * found out using this formula. The ones doing this digitally * should run at higher clock rate, so smaller divisor is used * on video timing side. */ if (limits->min_line_length_pck_bin > limits->min_line_length_pck / pll->binning_horizontal) vt_op_binning_div = pll->binning_horizontal; else vt_op_binning_div = 1; dev_dbg(dev, "vt_op_binning_div: %u\n", vt_op_binning_div); /* * Profile 2 supports vt_pix_clk_div E [4, 10] * * Horizontal binning can be used as a base for difference in * divisors. One must make sure that horizontal blanking is * enough to accommodate the CSI-2 sync codes. * * Take scaling factor into account as well. * * Find absolute limits for the factor of vt divider. */ dev_dbg(dev, "scale_m: %u\n", pll->scale_m); min_vt_div = DIV_ROUND_UP(pll->op_pix_clk_div * pll->op_sys_clk_div * pll->scale_n * lane_vt_clock_ratio, lane_op_clock_ratio * vt_op_binning_div * pll->scale_m); /* Find smallest and biggest allowed vt divisor. */ dev_dbg(dev, "min_vt_div: %u\n", min_vt_div); min_vt_div = max_t(uint32_t, min_vt_div, div_u64_round_up(pll->pll_op_clk_freq_hz, limits->vt.max_pix_clk_freq_hz)); dev_dbg(dev, "min_vt_div: max_vt_pix_clk_freq_hz: %u\n", min_vt_div); min_vt_div = max_t(uint32_t, min_vt_div, limits->vt.min_pix_clk_div * limits->vt.min_sys_clk_div); dev_dbg(dev, "min_vt_div: min_vt_clk_div: %u\n", min_vt_div); max_vt_div = limits->vt.max_sys_clk_div * limits->vt.max_pix_clk_div; dev_dbg(dev, "max_vt_div: %u\n", max_vt_div); max_vt_div = min_t(uint32_t, max_vt_div, div_u64_round_up(pll->pll_op_clk_freq_hz, limits->vt.min_pix_clk_freq_hz)); dev_dbg(dev, "max_vt_div: min_vt_pix_clk_freq_hz: %u\n", max_vt_div); /* * Find limitsits for sys_clk_div. Not all values are possible * with all values of pix_clk_div. */ min_sys_div = limits->vt.min_sys_clk_div; dev_dbg(dev, "min_sys_div: %u\n", min_sys_div); min_sys_div = max(min_sys_div, DIV_ROUND_UP(min_vt_div, limits->vt.max_pix_clk_div)); dev_dbg(dev, "min_sys_div: max_vt_pix_clk_div: %d\n", min_sys_div); min_sys_div = max_t(uint32_t, min_sys_div, pll->pll_op_clk_freq_hz / limits->vt.max_sys_clk_freq_hz); dev_dbg(dev, "min_sys_div: max_pll_op_clk_freq_hz: %d\n", min_sys_div); min_sys_div = clk_div_up(min_sys_div, 0); dev_dbg(dev, "min_sys_div: one or even: %d\n", min_sys_div); max_sys_div = limits->vt.max_sys_clk_div; dev_dbg(dev, "max_sys_div: %u\n", max_sys_div); max_sys_div = min(max_sys_div, DIV_ROUND_UP(max_vt_div, limits->vt.min_pix_clk_div)); dev_dbg(dev, "max_sys_div: min_vt_pix_clk_div: %u\n", max_sys_div); max_sys_div = min_t(uint32_t, max_sys_div, div_u64_round_up(pll->pll_op_clk_freq_hz, limits->vt.min_pix_clk_freq_hz)); dev_dbg(dev, "max_sys_div: min_vt_pix_clk_freq_hz: %u\n", max_sys_div); /* * Find pix_div such that a legal pix_div * sys_div results * into a value which is not smaller than div, the desired * divisor. */ for (vt_div = min_vt_div; vt_div <= max_vt_div; vt_div += 2 - (vt_div & 1)) { for (sys_div = min_sys_div; sys_div <= max_sys_div; sys_div += 2 - (sys_div & 1)) { uint16_t pix_div = DIV_ROUND_UP(vt_div, sys_div); if (pix_div < limits->vt.min_pix_clk_div || pix_div > limits->vt.max_pix_clk_div) { dev_dbg(dev, "pix_div %u too small or too big (%u--%u)\n", pix_div, limits->vt.min_pix_clk_div, limits->vt.max_pix_clk_div); continue; } /* Check if this one is better. */ if (pix_div * sys_div <= roundup(min_vt_div, best_pix_div)) best_pix_div = pix_div; } if (best_pix_div < INT_MAX >> 1) break; } pll->vt_sys_clk_div = DIV_ROUND_UP(min_vt_div, best_pix_div); pll->vt_pix_clk_div = best_pix_div; pll->vt_sys_clk_freq_hz = div_u64(pll->pll_op_clk_freq_hz, pll->vt_sys_clk_div); pll->vt_pix_clk_freq_hz = div_u64(pll->vt_sys_clk_freq_hz, pll->vt_pix_clk_div); pll->pixel_rate_csi = pll->op_pix_clk_freq_hz * lane_op_clock_ratio; pll->pixel_rate_pixel_array = pll->vt_pix_clk_freq_hz * lane_vt_clock_ratio; if (pll->flags & SMIAPP_PLL_FLAG_PIX_CLOCK_DOUBLE) { pll->pixel_rate_csi *= 2; pll->pixel_rate_pixel_array *= 2; } rval = bounds_check(dev, pll->pll_ip_clk_freq_hz, limits->min_pll_ip_freq_hz, limits->max_pll_ip_freq_hz, "pll_ip_clk_freq_hz"); if (!rval) rval = bounds_check( dev, pll->pll_multiplier, limits->min_pll_multiplier, limits->max_pll_multiplier, "pll_multiplier"); if (!rval) rval = bounds_check( dev, pll->pll_op_clk_freq_hz, limits->min_pll_op_freq_hz, limits->max_pll_op_freq_hz, "pll_op_clk_freq_hz"); if (!rval) rval = bounds_check( dev, pll->op_sys_clk_div, limits->op.min_sys_clk_div, limits->op.max_sys_clk_div, "op_sys_clk_div"); if (!rval) rval = bounds_check( dev, pll->op_sys_clk_freq_hz, limits->op.min_sys_clk_freq_hz, limits->op.max_sys_clk_freq_hz, "op_sys_clk_freq_hz"); if (!rval) rval = bounds_check( dev, pll->op_pix_clk_freq_hz, limits->op.min_pix_clk_freq_hz, limits->op.max_pix_clk_freq_hz, "op_pix_clk_freq_hz"); if (!rval) rval = bounds_check( dev, pll->vt_sys_clk_freq_hz, limits->vt.min_sys_clk_freq_hz, limits->vt.max_sys_clk_freq_hz, "vt_sys_clk_freq_hz"); if (!rval) rval = bounds_check( dev, pll->vt_pix_clk_freq_hz, limits->vt.min_pix_clk_freq_hz, limits->vt.max_pix_clk_freq_hz, "vt_pix_clk_freq_hz"); return rval; }
static int analyse(int argc, char **argv) { set_work_lib(); static struct option long_options[] = { { "bootstrap", no_argument, 0, 'b' }, { "dump-llvm", no_argument, 0, 'd' }, { "prefer-explicit", no_argument, 0, 'p' }, { 0, 0, 0, 0 } }; int c, index = 0; const char *spec = ""; optind = 1; while ((c = getopt_long(argc, argv, spec, long_options, &index)) != -1) { switch (c) { case 0: // Set a flag break; case '?': // getopt_long already printed an error message exit(EXIT_FAILURE); case 'b': opt_set_int("bootstrap", 1); break; case 'd': opt_set_int("dump-llvm", 1); break; case 'p': opt_set_int("prefer-explicit", 1); break; default: abort(); } } size_t unit_list_sz = 32; tree_t *units LOCAL = xmalloc(sizeof(tree_t) * unit_list_sz); int n_units = 0; for (int i = optind; i < argc; i++) { input_from_file(argv[i]); tree_t unit; while ((unit = parse()) && sem_check(unit)) ARRAY_APPEND(units, unit, n_units, unit_list_sz); } for (int i = 0; i < n_units; i++) { simplify(units[i]); bounds_check(units[i]); } if (parse_errors() + sem_errors() + bounds_errors() > 0) return EXIT_FAILURE; for (int i = 0; i < n_units; i++) { tree_kind_t kind = tree_kind(units[i]); const bool need_cgen = (kind == T_PACK_BODY) || ((kind == T_PACKAGE) && pack_needs_cgen(units[i])); if (need_cgen) opt(units[i]); else units[i] = NULL; } lib_save(lib_work()); for (int i = 0; i < n_units; i++) { if (units[i] != NULL) cgen(units[i]); } return EXIT_SUCCESS; }
void iTensor3::set(int n1, int n2, int n3, int value) { int k = ((n1-1)*numElem2 + (n2-1))*numElem3 + (n3-1); bounds_check(); vec[k] = value; }
void goto_checkt::check_rec( const exprt &expr, guardt &guard, bool address) { // we don't look into quantifiers if(expr.id()==ID_exists || expr.id()==ID_forall) return; if(address) { if(expr.id()==ID_dereference) { assert(expr.operands().size()==1); check_rec(expr.op0(), guard, false); } else if(expr.id()==ID_index) { assert(expr.operands().size()==2); check_rec(expr.op0(), guard, true); check_rec(expr.op1(), guard, false); } else { forall_operands(it, expr) check_rec(*it, guard, true); } return; } if(expr.id()==ID_address_of) { assert(expr.operands().size()==1); check_rec(expr.op0(), guard, true); return; } else if(expr.id()==ID_and || expr.id()==ID_or) { if(!expr.is_boolean()) throw "`"+expr.id_string()+"' must be Boolean, but got "+ expr.pretty(); guardt old_guard=guard; for(unsigned i=0; i<expr.operands().size(); i++) { const exprt &op=expr.operands()[i]; if(!op.is_boolean()) throw "`"+expr.id_string()+"' takes Boolean operands only, but got "+ op.pretty(); check_rec(op, guard, false); if(expr.id()==ID_or) guard.add(not_exprt(op)); else guard.add(op); } guard.swap(old_guard); return; } else if(expr.id()==ID_if) { if(expr.operands().size()!=3) throw "if takes three arguments"; if(!expr.op0().is_boolean()) { std::string msg= "first argument of if must be boolean, but got " +expr.op0().pretty(); throw msg; } check_rec(expr.op0(), guard, false); { guardt old_guard=guard; guard.add(expr.op0()); check_rec(expr.op1(), guard, false); guard.swap(old_guard); } { guardt old_guard=guard; guard.add(not_exprt(expr.op0())); check_rec(expr.op2(), guard, false); guard.swap(old_guard); } return; } forall_operands(it, expr) check_rec(*it, guard, false); if(expr.id()==ID_index) { bounds_check(to_index_expr(expr), guard); } else if(expr.id()==ID_div) { div_by_zero_check(to_div_expr(expr), guard); if(expr.type().id()==ID_signedbv) integer_overflow_check(expr, guard); else if(expr.type().id()==ID_floatbv) { nan_check(expr, guard); float_overflow_check(expr, guard); } } else if(expr.id()==ID_shl || expr.id()==ID_ashr || expr.id()==ID_lshr) { undefined_shift_check(to_shift_expr(expr), guard); } else if(expr.id()==ID_mod) { mod_by_zero_check(to_mod_expr(expr), guard); } else if(expr.id()==ID_plus || expr.id()==ID_minus || expr.id()==ID_mult || expr.id()==ID_unary_minus) { if(expr.type().id()==ID_signedbv || expr.type().id()==ID_unsignedbv) { if(expr.operands().size()==2 && expr.op0().type().id()==ID_pointer) pointer_overflow_check(expr, guard); else integer_overflow_check(expr, guard); } else if(expr.type().id()==ID_floatbv) { nan_check(expr, guard); float_overflow_check(expr, guard); } else if(expr.type().id()==ID_pointer) { pointer_overflow_check(expr, guard); } } else if(expr.id()==ID_typecast) conversion_check(expr, guard); else if(expr.id()==ID_le || expr.id()==ID_lt || expr.id()==ID_ge || expr.id()==ID_gt) pointer_rel_check(expr, guard); else if(expr.id()==ID_dereference) pointer_validity_check(to_dereference_expr(expr), guard); }
const int& iTensor3::get(int n1, int n2, int n3) const { int k = ((n1-1)*numElem2 + (n2-1))*numElem3 + (n3-1); bounds_check(); return vec[k]; }