static void lm32_block_move_inline (rtx dest, rtx src, HOST_WIDE_INT length, HOST_WIDE_INT alignment) { HOST_WIDE_INT offset, delta; unsigned HOST_WIDE_INT bits; int i; machine_mode mode; rtx *regs; /* Work out how many bits to move at a time. */ switch (alignment) { case 1: bits = 8; break; case 2: bits = 16; break; default: bits = 32; break; } mode = mode_for_size (bits, MODE_INT, 0); delta = bits / BITS_PER_UNIT; /* Allocate a buffer for the temporary registers. */ regs = XALLOCAVEC (rtx, length / delta); /* Load as many BITS-sized chunks as possible. */ for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++) { regs[i] = gen_reg_rtx (mode); emit_move_insn (regs[i], adjust_address (src, mode, offset)); } /* Copy the chunks to the destination. */ for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++) emit_move_insn (adjust_address (dest, mode, offset), regs[i]); /* Mop up any left-over bytes. */ if (offset < length) { src = adjust_address (src, BLKmode, offset); dest = adjust_address (dest, BLKmode, offset); move_by_pieces (dest, src, length - offset, MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), 0); } }
static tree trans_runtime_error_vararg (bool error, locus* where, const char* msgid, va_list ap) { stmtblock_t block; tree tmp; tree arg, arg2; tree *argarray; tree fntype; char *message; const char *p; int line, nargs, i; location_t loc; /* Compute the number of extra arguments from the format string. */ for (p = msgid, nargs = 0; *p; p++) if (*p == '%') { p++; if (*p != '%') nargs++; } /* The code to generate the error. */ gfc_start_block (&block); if (where) { line = LOCATION_LINE (where->lb->location); asprintf (&message, "At line %d of file %s", line, where->lb->file->filename); } else asprintf (&message, "In file '%s', around line %d", gfc_source_file, input_line + 1); arg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const (message)); free (message); asprintf (&message, "%s", _(msgid)); arg2 = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const (message)); free (message); /* Build the argument array. */ argarray = XALLOCAVEC (tree, nargs + 2); argarray[0] = arg; argarray[1] = arg2; for (i = 0; i < nargs; i++) argarray[2 + i] = va_arg (ap, tree); /* Build the function call to runtime_(warning,error)_at; because of the variable number of arguments, we can't use build_call_expr_loc dinput_location, irectly. */ if (error) fntype = TREE_TYPE (gfor_fndecl_runtime_error_at); else fntype = TREE_TYPE (gfor_fndecl_runtime_warning_at); loc = where ? where->lb->location : input_location; tmp = fold_builtin_call_array (loc, TREE_TYPE (fntype), fold_build1_loc (loc, ADDR_EXPR, build_pointer_type (fntype), error ? gfor_fndecl_runtime_error_at : gfor_fndecl_runtime_warning_at), nargs + 2, argarray); gfc_add_expr_to_block (&block, tmp); return gfc_finish_block (&block); }
static tree cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2) { tree defparm, parm, t; int i = 0; int nargs; tree *argarray; if (fn == NULL) return NULL; nargs = list_length (DECL_ARGUMENTS (fn)); argarray = XALLOCAVEC (tree, nargs); defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn))); if (arg2) defparm = TREE_CHAIN (defparm); if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE) { tree inner_type = TREE_TYPE (arg1); tree start1, end1, p1; tree start2 = NULL, p2 = NULL; tree ret = NULL, lab; start1 = arg1; start2 = arg2; do { inner_type = TREE_TYPE (inner_type); start1 = build4 (ARRAY_REF, inner_type, start1, size_zero_node, NULL, NULL); if (arg2) start2 = build4 (ARRAY_REF, inner_type, start2, size_zero_node, NULL, NULL); } while (TREE_CODE (inner_type) == ARRAY_TYPE); start1 = build_fold_addr_expr_loc (input_location, start1); if (arg2) start2 = build_fold_addr_expr_loc (input_location, start2); end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1)); end1 = fold_build_pointer_plus (start1, end1); p1 = create_tmp_var (TREE_TYPE (start1), NULL); t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1); append_to_statement_list (t, &ret); if (arg2) { p2 = create_tmp_var (TREE_TYPE (start2), NULL); t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2); append_to_statement_list (t, &ret); } lab = create_artificial_label (input_location); t = build1 (LABEL_EXPR, void_type_node, lab); append_to_statement_list (t, &ret); argarray[i++] = p1; if (arg2) argarray[i++] = p2; /* Handle default arguments. */ for (parm = defparm; parm && parm != void_list_node; parm = TREE_CHAIN (parm), i++) argarray[i] = convert_default_arg (TREE_VALUE (parm), TREE_PURPOSE (parm), fn, i, tf_warning_or_error); t = build_call_a (fn, i, argarray); t = fold_convert (void_type_node, t); t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); append_to_statement_list (t, &ret); t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type)); t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t); append_to_statement_list (t, &ret); if (arg2) { t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type)); t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t); append_to_statement_list (t, &ret); } t = build2 (NE_EXPR, boolean_type_node, p1, end1); t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL); append_to_statement_list (t, &ret); return ret; } else { argarray[i++] = build_fold_addr_expr_loc (input_location, arg1); if (arg2) argarray[i++] = build_fold_addr_expr_loc (input_location, arg2); /* Handle default arguments. */ for (parm = defparm; parm && parm != void_list_node; parm = TREE_CHAIN (parm), i++) argarray[i] = convert_default_arg (TREE_VALUE (parm), TREE_PURPOSE (parm), fn, i, tf_warning_or_error); t = build_call_a (fn, i, argarray); t = fold_convert (void_type_node, t); return fold_build_cleanup_point_expr (TREE_TYPE (t), t); } }