annotate gcc/calls.c @ 127:4c56639505ff

fix function.c and add CbC-example Makefile
author mir3636
date Wed, 11 Apr 2018 18:46:58 +0900
parents 49957f95a4d1
children fe568345ddd5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* Convert function calls to rtl insns, for GNU C compiler.
111
kono
parents: 67
diff changeset
2 Copyright (C) 1989-2017 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify it under
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 the terms of the GNU General Public License as published by the Free
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 Software Foundation; either version 3, or (at your option) any later
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 #include "coretypes.h"
111
kono
parents: 67
diff changeset
23 #include "backend.h"
kono
parents: 67
diff changeset
24 #include "target.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 #include "rtl.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 #include "tree.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 #include "gimple.h"
111
kono
parents: 67
diff changeset
28 #include "predict.h"
kono
parents: 67
diff changeset
29 #include "memmodel.h"
kono
parents: 67
diff changeset
30 #include "tm_p.h"
kono
parents: 67
diff changeset
31 #include "stringpool.h"
kono
parents: 67
diff changeset
32 #include "expmed.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 #include "optabs.h"
111
kono
parents: 67
diff changeset
34 #include "emit-rtl.h"
kono
parents: 67
diff changeset
35 #include "cgraph.h"
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
36 #include "diagnostic-core.h"
111
kono
parents: 67
diff changeset
37 #include "fold-const.h"
kono
parents: 67
diff changeset
38 #include "stor-layout.h"
kono
parents: 67
diff changeset
39 #include "varasm.h"
kono
parents: 67
diff changeset
40 #include "internal-fn.h"
kono
parents: 67
diff changeset
41 #include "dojump.h"
kono
parents: 67
diff changeset
42 #include "explow.h"
kono
parents: 67
diff changeset
43 #include "calls.h"
kono
parents: 67
diff changeset
44 #include "expr.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 #include "output.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 #include "langhooks.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 #include "except.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 #include "dbgcnt.h"
111
kono
parents: 67
diff changeset
49 #include "rtl-iter.h"
kono
parents: 67
diff changeset
50 #include "tree-chkp.h"
kono
parents: 67
diff changeset
51 #include "tree-vrp.h"
kono
parents: 67
diff changeset
52 #include "tree-ssanames.h"
kono
parents: 67
diff changeset
53 #include "rtl-chkp.h"
kono
parents: 67
diff changeset
54 #include "intl.h"
kono
parents: 67
diff changeset
55 #include "stringpool.h"
kono
parents: 67
diff changeset
56 #include "attribs.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 /* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 #define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 /* Data structure and subroutines used within expand_call. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 struct arg_data
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 /* Tree node for this argument. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 tree tree_value;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 /* Mode for value; TYPE_MODE unless promoted. */
111
kono
parents: 67
diff changeset
68 machine_mode mode;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 /* Current RTL value for argument, or 0 if it isn't precomputed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 rtx value;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 /* Initially-compute RTL value for argument; only for const functions. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 rtx initial_value;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 /* Register to pass this argument in, 0 if passed on stack, or an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 PARALLEL if the arg is to be copied into multiple non-contiguous
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 registers. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 rtx reg;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 /* Register to pass this argument in when generating tail call sequence.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 This is not the same register as for normal calls on machines with
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 register windows. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 rtx tail_call_reg;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 /* If REG is a PARALLEL, this is a copy of VALUE pulled into the correct
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 form for emit_group_move. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 rtx parallel_value;
111
kono
parents: 67
diff changeset
84 /* If value is passed in neither reg nor stack, this field holds a number
kono
parents: 67
diff changeset
85 of a special slot to be used. */
kono
parents: 67
diff changeset
86 rtx special_slot;
kono
parents: 67
diff changeset
87 /* For pointer bounds hold an index of parm bounds are bound to. -1 if
kono
parents: 67
diff changeset
88 there is no such pointer. */
kono
parents: 67
diff changeset
89 int pointer_arg;
kono
parents: 67
diff changeset
90 /* If pointer_arg refers a structure, then pointer_offset holds an offset
kono
parents: 67
diff changeset
91 of a pointer in this structure. */
kono
parents: 67
diff changeset
92 int pointer_offset;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 /* If REG was promoted from the actual mode of the argument expression,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 indicates whether the promotion is sign- or zero-extended. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 int unsignedp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 /* Number of bytes to put in registers. 0 means put the whole arg
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 in registers. Also 0 if not passed in registers. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 int partial;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 /* Nonzero if argument must be passed on stack.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 Note that some arguments may be passed on the stack
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 even though pass_on_stack is zero, just because FUNCTION_ARG says so.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 pass_on_stack identifies arguments that *cannot* go in registers. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 int pass_on_stack;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 /* Some fields packaged up for locate_and_pad_parm. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 struct locate_and_pad_arg_data locate;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 /* Location on the stack at which parameter should be stored. The store
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 has already been done if STACK == VALUE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 rtx stack;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 /* Location on the stack of the start of this argument slot. This can
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 differ from STACK if this arg pads downward. This location is known
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
111 to be aligned to TARGET_FUNCTION_ARG_BOUNDARY. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 rtx stack_slot;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 /* Place that this stack area has been saved, if needed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 rtx save_area;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 /* If an argument's alignment does not permit direct copying into registers,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 copy in smaller-sized pieces into pseudos. These are stored in a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 block pointed to by this field. The next field says how many
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 word-sized pseudos we made. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 rtx *aligned_regs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 int n_aligned_regs;
73
ce75bd9117e4 merge calls.c, cfgexpand.c, gcc.c, gimple.c, gimple.h and gimplify.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 70
diff changeset
121 #ifndef noCbC
ce75bd9117e4 merge calls.c, cfgexpand.c, gcc.c, gimple.c, gimple.h and gimplify.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 70
diff changeset
122 rtx exprs;
ce75bd9117e4 merge calls.c, cfgexpand.c, gcc.c, gimple.c, gimple.h and gimplify.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 70
diff changeset
123 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 /* A vector of one char per byte of stack space. A byte if nonzero if
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 the corresponding stack location has been used.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 This vector is used to prevent a function call within an argument from
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 clobbering any stack already set up. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 static char *stack_usage_map;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 /* Size of STACK_USAGE_MAP. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 static int highest_outgoing_arg_in_use;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 /* A bitmap of virtual-incoming stack space. Bit is set if the corresponding
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 stack location's tail call argument has been already stored into the stack.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 This bitmap is used to prevent sibling call optimization if function tries
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 to use parent's incoming argument slots when they have been already
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 overwritten with tail call arguments. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 static sbitmap stored_args_map;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 /* stack_arg_under_construction is nonzero when an argument may be
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 initialized with a constructor call (including a C function that
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 returns a BLKmode struct) and expand_call must take special action
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 to make sure the object being constructed does not overlap the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 argument list for the constructor call. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 static int stack_arg_under_construction;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
148
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 static void emit_call_1 (rtx, tree, tree, tree, HOST_WIDE_INT, HOST_WIDE_INT,
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
150 HOST_WIDE_INT, rtx, rtx, int, rtx, int,
111
kono
parents: 67
diff changeset
151 cumulative_args_t);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 static void precompute_register_parameters (int, struct arg_data *, int *);
111
kono
parents: 67
diff changeset
153 static void store_bounds (struct arg_data *, struct arg_data *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 static int store_one_arg (struct arg_data *, rtx, int, int, int);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 static void store_unaligned_arguments_into_pseudos (struct arg_data *, int);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 static int finalize_must_preallocate (int, int, struct arg_data *,
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
157 struct args_size *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 static void precompute_arguments (int, struct arg_data *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 static int compute_argument_block_size (int, struct args_size *, tree, tree, int);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 static void initialize_argument_information (int, struct arg_data *,
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
161 struct args_size *, int,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
162 tree, tree,
111
kono
parents: 67
diff changeset
163 tree, tree, cumulative_args_t, int,
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
164 rtx *, int *, int *, int *,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
165 bool *, bool);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 static void compute_argument_addresses (struct arg_data *, rtx, int);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 static rtx rtx_for_function_call (tree, tree);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 static void load_register_parameters (struct arg_data *, int, rtx *, int,
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
169 int, int *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 static int special_function_p (const_tree, int);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
171 static int check_sibcall_argument_overlap_1 (rtx);
111
kono
parents: 67
diff changeset
172 static int check_sibcall_argument_overlap (rtx_insn *, struct arg_data *, int);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
173
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 static int combine_pending_stack_adjustment_and_call (int, struct args_size *,
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
175 unsigned int);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 static tree split_complex_types (tree);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
177
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
178 #ifdef REG_PARM_STACK_SPACE
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
179 static rtx save_fixed_argument_area (int, rtx, int *, int *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
180 static void restore_fixed_argument_area (rtx, rtx, int, int);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
181 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
182
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
183 /* Force FUNEXP into a form suitable for the address of a CALL,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 and return that as an rtx. Also load the static chain register
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 if FNDECL is a nested function.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
186
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 CALL_FUSAGE points to a variable holding the prospective
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
188 CALL_INSN_FUNCTION_USAGE information. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
189
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 rtx
111
kono
parents: 67
diff changeset
191 prepare_call_address (tree fndecl_or_type, rtx funexp, rtx static_chain_value,
kono
parents: 67
diff changeset
192 rtx *call_fusage, int reg_parm_seen, int flags)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 /* Make a valid memory address and copy constants through pseudo-regs,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 but not for a constant address if -fno-function-cse. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 if (GET_CODE (funexp) != SYMBOL_REF)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 {
111
kono
parents: 67
diff changeset
198 /* If it's an indirect call by descriptor, generate code to perform
kono
parents: 67
diff changeset
199 runtime identification of the pointer and load the descriptor. */
kono
parents: 67
diff changeset
200 if ((flags & ECF_BY_DESCRIPTOR) && !flag_trampolines)
kono
parents: 67
diff changeset
201 {
kono
parents: 67
diff changeset
202 const int bit_val = targetm.calls.custom_function_descriptors;
kono
parents: 67
diff changeset
203 rtx call_lab = gen_label_rtx ();
kono
parents: 67
diff changeset
204
kono
parents: 67
diff changeset
205 gcc_assert (fndecl_or_type && TYPE_P (fndecl_or_type));
kono
parents: 67
diff changeset
206 fndecl_or_type
kono
parents: 67
diff changeset
207 = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, NULL_TREE,
kono
parents: 67
diff changeset
208 fndecl_or_type);
kono
parents: 67
diff changeset
209 DECL_STATIC_CHAIN (fndecl_or_type) = 1;
kono
parents: 67
diff changeset
210 rtx chain = targetm.calls.static_chain (fndecl_or_type, false);
kono
parents: 67
diff changeset
211
kono
parents: 67
diff changeset
212 if (GET_MODE (funexp) != Pmode)
kono
parents: 67
diff changeset
213 funexp = convert_memory_address (Pmode, funexp);
kono
parents: 67
diff changeset
214
kono
parents: 67
diff changeset
215 /* Avoid long live ranges around function calls. */
kono
parents: 67
diff changeset
216 funexp = copy_to_mode_reg (Pmode, funexp);
kono
parents: 67
diff changeset
217
kono
parents: 67
diff changeset
218 if (REG_P (chain))
kono
parents: 67
diff changeset
219 emit_insn (gen_rtx_CLOBBER (VOIDmode, chain));
kono
parents: 67
diff changeset
220
kono
parents: 67
diff changeset
221 /* Emit the runtime identification pattern. */
kono
parents: 67
diff changeset
222 rtx mask = gen_rtx_AND (Pmode, funexp, GEN_INT (bit_val));
kono
parents: 67
diff changeset
223 emit_cmp_and_jump_insns (mask, const0_rtx, EQ, NULL_RTX, Pmode, 1,
kono
parents: 67
diff changeset
224 call_lab);
kono
parents: 67
diff changeset
225
kono
parents: 67
diff changeset
226 /* Statically predict the branch to very likely taken. */
kono
parents: 67
diff changeset
227 rtx_insn *insn = get_last_insn ();
kono
parents: 67
diff changeset
228 if (JUMP_P (insn))
kono
parents: 67
diff changeset
229 predict_insn_def (insn, PRED_BUILTIN_EXPECT, TAKEN);
kono
parents: 67
diff changeset
230
kono
parents: 67
diff changeset
231 /* Load the descriptor. */
kono
parents: 67
diff changeset
232 rtx mem = gen_rtx_MEM (ptr_mode,
kono
parents: 67
diff changeset
233 plus_constant (Pmode, funexp, - bit_val));
kono
parents: 67
diff changeset
234 MEM_NOTRAP_P (mem) = 1;
kono
parents: 67
diff changeset
235 mem = convert_memory_address (Pmode, mem);
kono
parents: 67
diff changeset
236 emit_move_insn (chain, mem);
kono
parents: 67
diff changeset
237
kono
parents: 67
diff changeset
238 mem = gen_rtx_MEM (ptr_mode,
kono
parents: 67
diff changeset
239 plus_constant (Pmode, funexp,
kono
parents: 67
diff changeset
240 POINTER_SIZE / BITS_PER_UNIT
kono
parents: 67
diff changeset
241 - bit_val));
kono
parents: 67
diff changeset
242 MEM_NOTRAP_P (mem) = 1;
kono
parents: 67
diff changeset
243 mem = convert_memory_address (Pmode, mem);
kono
parents: 67
diff changeset
244 emit_move_insn (funexp, mem);
kono
parents: 67
diff changeset
245
kono
parents: 67
diff changeset
246 emit_label (call_lab);
kono
parents: 67
diff changeset
247
kono
parents: 67
diff changeset
248 if (REG_P (chain))
kono
parents: 67
diff changeset
249 {
kono
parents: 67
diff changeset
250 use_reg (call_fusage, chain);
kono
parents: 67
diff changeset
251 STATIC_CHAIN_REG_P (chain) = 1;
kono
parents: 67
diff changeset
252 }
kono
parents: 67
diff changeset
253
kono
parents: 67
diff changeset
254 /* Make sure we're not going to be overwritten below. */
kono
parents: 67
diff changeset
255 gcc_assert (!static_chain_value);
kono
parents: 67
diff changeset
256 }
kono
parents: 67
diff changeset
257
kono
parents: 67
diff changeset
258 /* If we are using registers for parameters, force the
kono
parents: 67
diff changeset
259 function address into a register now. */
kono
parents: 67
diff changeset
260 funexp = ((reg_parm_seen
kono
parents: 67
diff changeset
261 && targetm.small_register_classes_for_mode_p (FUNCTION_MODE))
kono
parents: 67
diff changeset
262 ? force_not_mem (memory_address (FUNCTION_MODE, funexp))
kono
parents: 67
diff changeset
263 : memory_address (FUNCTION_MODE, funexp));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
264 }
111
kono
parents: 67
diff changeset
265 else
kono
parents: 67
diff changeset
266 {
kono
parents: 67
diff changeset
267 /* funexp could be a SYMBOL_REF represents a function pointer which is
kono
parents: 67
diff changeset
268 of ptr_mode. In this case, it should be converted into address mode
kono
parents: 67
diff changeset
269 to be a valid address for memory rtx pattern. See PR 64971. */
kono
parents: 67
diff changeset
270 if (GET_MODE (funexp) != Pmode)
kono
parents: 67
diff changeset
271 funexp = convert_memory_address (Pmode, funexp);
kono
parents: 67
diff changeset
272
kono
parents: 67
diff changeset
273 if (!(flags & ECF_SIBCALL))
kono
parents: 67
diff changeset
274 {
kono
parents: 67
diff changeset
275 if (!NO_FUNCTION_CSE && optimize && ! flag_no_function_cse)
kono
parents: 67
diff changeset
276 funexp = force_reg (Pmode, funexp);
kono
parents: 67
diff changeset
277 }
kono
parents: 67
diff changeset
278 }
kono
parents: 67
diff changeset
279
kono
parents: 67
diff changeset
280 if (static_chain_value != 0
kono
parents: 67
diff changeset
281 && (TREE_CODE (fndecl_or_type) != FUNCTION_DECL
kono
parents: 67
diff changeset
282 || DECL_STATIC_CHAIN (fndecl_or_type)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
283 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
284 rtx chain;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
285
111
kono
parents: 67
diff changeset
286 chain = targetm.calls.static_chain (fndecl_or_type, false);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
287 static_chain_value = convert_memory_address (Pmode, static_chain_value);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
288
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
289 emit_move_insn (chain, static_chain_value);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
290 if (REG_P (chain))
111
kono
parents: 67
diff changeset
291 {
kono
parents: 67
diff changeset
292 use_reg (call_fusage, chain);
kono
parents: 67
diff changeset
293 STATIC_CHAIN_REG_P (chain) = 1;
kono
parents: 67
diff changeset
294 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
296
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 return funexp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
299
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
300 /* Generate instructions to call function FUNEXP,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
301 and optionally pop the results.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
302 The CALL_INSN is the first insn generated.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
303
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
304 FNDECL is the declaration node of the function. This is given to the
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
305 hook TARGET_RETURN_POPS_ARGS to determine whether this function pops
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
306 its own args.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
307
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
308 FUNTYPE is the data type of the function. This is given to the hook
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
309 TARGET_RETURN_POPS_ARGS to determine whether this function pops its
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
310 own args. We used to allow an identifier for library functions, but
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
311 that doesn't work when the return type is an aggregate type and the
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
312 calling convention says that the pointer to this aggregate is to be
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
313 popped by the callee.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
314
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
315 STACK_SIZE is the number of bytes of arguments on the stack,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
316 ROUNDED_STACK_SIZE is that number rounded up to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
317 PREFERRED_STACK_BOUNDARY; zero if the size is variable. This is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
318 both to put into the call insn and to generate explicit popping
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
319 code if necessary.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
320
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
321 STRUCT_VALUE_SIZE is the number of bytes wanted in a structure value.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
322 It is zero if this call doesn't want a structure value.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
323
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 NEXT_ARG_REG is the rtx that results from executing
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
325 targetm.calls.function_arg (&args_so_far, VOIDmode, void_type_node, true)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
326 just after all the args have had their registers assigned.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
327 This could be whatever you like, but normally it is the first
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
328 arg-register beyond those used for args in this call,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
329 or 0 if all the arg-registers are used in this call.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
330 It is passed on to `gen_call' so you can put this info in the call insn.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
331
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
332 VALREG is a hard register in which a value is returned,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
333 or 0 if the call does not return a value.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
334
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
335 OLD_INHIBIT_DEFER_POP is the value that `inhibit_defer_pop' had before
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
336 the args to this call were processed.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
337 We restore `inhibit_defer_pop' to that value.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
338
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
339 CALL_FUSAGE is either empty or an EXPR_LIST of USE expressions that
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
340 denote registers used by the called function. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
341
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
342 static void
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
343 emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNUSED,
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
344 tree funtype ATTRIBUTE_UNUSED,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
345 HOST_WIDE_INT stack_size ATTRIBUTE_UNUSED,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
346 HOST_WIDE_INT rounded_stack_size,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
347 HOST_WIDE_INT struct_value_size ATTRIBUTE_UNUSED,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
348 rtx next_arg_reg ATTRIBUTE_UNUSED, rtx valreg,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
349 int old_inhibit_defer_pop, rtx call_fusage, int ecf_flags,
111
kono
parents: 67
diff changeset
350 cumulative_args_t args_so_far ATTRIBUTE_UNUSED)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
351 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 rtx rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
111
kono
parents: 67
diff changeset
353 rtx call, funmem, pat;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
354 int already_popped = 0;
111
kono
parents: 67
diff changeset
355 HOST_WIDE_INT n_popped = 0;
kono
parents: 67
diff changeset
356
kono
parents: 67
diff changeset
357 /* Sibling call patterns never pop arguments (no sibcall(_value)_pop
kono
parents: 67
diff changeset
358 patterns exist). Any popping that the callee does on return will
kono
parents: 67
diff changeset
359 be from our caller's frame rather than ours. */
kono
parents: 67
diff changeset
360 if (!(ecf_flags & ECF_SIBCALL))
kono
parents: 67
diff changeset
361 {
kono
parents: 67
diff changeset
362 n_popped += targetm.calls.return_pops_args (fndecl, funtype, stack_size);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
363
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
364 #ifdef CALL_POPS_ARGS
111
kono
parents: 67
diff changeset
365 n_popped += CALL_POPS_ARGS (*get_cumulative_args (args_so_far));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
366 #endif
111
kono
parents: 67
diff changeset
367 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
368
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
369 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
370 and we don't want to load it into a register as an optimization,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
371 because prepare_call_address already did it if it should be done. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
372 if (GET_CODE (funexp) != SYMBOL_REF)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
373 funexp = memory_address (FUNCTION_MODE, funexp);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
374
111
kono
parents: 67
diff changeset
375 funmem = gen_rtx_MEM (FUNCTION_MODE, funexp);
kono
parents: 67
diff changeset
376 if (fndecl && TREE_CODE (fndecl) == FUNCTION_DECL)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
377 {
111
kono
parents: 67
diff changeset
378 tree t = fndecl;
kono
parents: 67
diff changeset
379
kono
parents: 67
diff changeset
380 /* Although a built-in FUNCTION_DECL and its non-__builtin
kono
parents: 67
diff changeset
381 counterpart compare equal and get a shared mem_attrs, they
kono
parents: 67
diff changeset
382 produce different dump output in compare-debug compilations,
kono
parents: 67
diff changeset
383 if an entry gets garbage collected in one compilation, then
kono
parents: 67
diff changeset
384 adds a different (but equivalent) entry, while the other
kono
parents: 67
diff changeset
385 doesn't run the garbage collector at the same spot and then
kono
parents: 67
diff changeset
386 shares the mem_attr with the equivalent entry. */
kono
parents: 67
diff changeset
387 if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL)
kono
parents: 67
diff changeset
388 {
kono
parents: 67
diff changeset
389 tree t2 = builtin_decl_explicit (DECL_FUNCTION_CODE (t));
kono
parents: 67
diff changeset
390 if (t2)
kono
parents: 67
diff changeset
391 t = t2;
kono
parents: 67
diff changeset
392 }
kono
parents: 67
diff changeset
393
kono
parents: 67
diff changeset
394 set_mem_expr (funmem, t);
kono
parents: 67
diff changeset
395 }
kono
parents: 67
diff changeset
396 else if (fntree)
kono
parents: 67
diff changeset
397 set_mem_expr (funmem, build_simple_mem_ref (CALL_EXPR_FN (fntree)));
kono
parents: 67
diff changeset
398
kono
parents: 67
diff changeset
399 if (ecf_flags & ECF_SIBCALL)
kono
parents: 67
diff changeset
400 {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
401 if (valreg)
111
kono
parents: 67
diff changeset
402 pat = targetm.gen_sibcall_value (valreg, funmem,
kono
parents: 67
diff changeset
403 rounded_stack_size_rtx,
kono
parents: 67
diff changeset
404 next_arg_reg, NULL_RTX);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
405 else
111
kono
parents: 67
diff changeset
406 pat = targetm.gen_sibcall (funmem, rounded_stack_size_rtx,
kono
parents: 67
diff changeset
407 next_arg_reg, GEN_INT (struct_value_size));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
408 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
409 /* If the target has "call" or "call_value" insns, then prefer them
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
410 if no arguments are actually popped. If the target does not have
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
411 "call" or "call_value" insns, then we must use the popping versions
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
412 even if the call has no arguments to pop. */
111
kono
parents: 67
diff changeset
413 else if (n_popped > 0
kono
parents: 67
diff changeset
414 || !(valreg
kono
parents: 67
diff changeset
415 ? targetm.have_call_value ()
kono
parents: 67
diff changeset
416 : targetm.have_call ()))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
417 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
418 rtx n_pop = GEN_INT (n_popped);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
419
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
420 /* If this subroutine pops its own args, record that in the call insn
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
421 if possible, for the sake of frame pointer elimination. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
422
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
423 if (valreg)
111
kono
parents: 67
diff changeset
424 pat = targetm.gen_call_value_pop (valreg, funmem,
kono
parents: 67
diff changeset
425 rounded_stack_size_rtx,
kono
parents: 67
diff changeset
426 next_arg_reg, n_pop);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
427 else
111
kono
parents: 67
diff changeset
428 pat = targetm.gen_call_pop (funmem, rounded_stack_size_rtx,
kono
parents: 67
diff changeset
429 next_arg_reg, n_pop);
kono
parents: 67
diff changeset
430
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
431 already_popped = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
432 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
433 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
434 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
435 if (valreg)
111
kono
parents: 67
diff changeset
436 pat = targetm.gen_call_value (valreg, funmem, rounded_stack_size_rtx,
kono
parents: 67
diff changeset
437 next_arg_reg, NULL_RTX);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
438 else
111
kono
parents: 67
diff changeset
439 pat = targetm.gen_call (funmem, rounded_stack_size_rtx, next_arg_reg,
kono
parents: 67
diff changeset
440 GEN_INT (struct_value_size));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
441 }
111
kono
parents: 67
diff changeset
442 emit_insn (pat);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
443
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
444 /* Find the call we just emitted. */
111
kono
parents: 67
diff changeset
445 rtx_call_insn *call_insn = last_call_insn ();
kono
parents: 67
diff changeset
446
kono
parents: 67
diff changeset
447 /* Some target create a fresh MEM instead of reusing the one provided
kono
parents: 67
diff changeset
448 above. Set its MEM_EXPR. */
kono
parents: 67
diff changeset
449 call = get_call_rtx_from (call_insn);
kono
parents: 67
diff changeset
450 if (call
kono
parents: 67
diff changeset
451 && MEM_EXPR (XEXP (call, 0)) == NULL_TREE
kono
parents: 67
diff changeset
452 && MEM_EXPR (funmem) != NULL_TREE)
kono
parents: 67
diff changeset
453 set_mem_expr (XEXP (call, 0), MEM_EXPR (funmem));
kono
parents: 67
diff changeset
454
kono
parents: 67
diff changeset
455 /* Mark instrumented calls. */
kono
parents: 67
diff changeset
456 if (call && fntree)
kono
parents: 67
diff changeset
457 CALL_EXPR_WITH_BOUNDS_P (call) = CALL_WITH_BOUNDS_P (fntree);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
458
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
459 /* Put the register usage information there. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
460 add_function_usage_to (call_insn, call_fusage);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
461
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
462 /* If this is a const call, then set the insn's unchanging bit. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
463 if (ecf_flags & ECF_CONST)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
464 RTL_CONST_CALL_P (call_insn) = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
465
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
466 /* If this is a pure call, then set the insn's unchanging bit. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
467 if (ecf_flags & ECF_PURE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 RTL_PURE_CALL_P (call_insn) = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
469
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
470 /* If this is a const call, then set the insn's unchanging bit. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
471 if (ecf_flags & ECF_LOOPING_CONST_OR_PURE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
472 RTL_LOOPING_CONST_OR_PURE_CALL_P (call_insn) = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
473
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
474 /* Create a nothrow REG_EH_REGION note, if needed. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
475 make_reg_eh_region_note (call_insn, ecf_flags, 0);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
476
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
477 if (ecf_flags & ECF_NORETURN)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
478 add_reg_note (call_insn, REG_NORETURN, const0_rtx);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
479
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
480 if (ecf_flags & ECF_RETURNS_TWICE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
481 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
482 add_reg_note (call_insn, REG_SETJMP, const0_rtx);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
483 cfun->calls_setjmp = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
484 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
485
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
486 SIBLING_CALL_P (call_insn) = ((ecf_flags & ECF_SIBCALL) != 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
487
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
488 /* Restore this now, so that we do defer pops for this call's args
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
489 if the context of the call as a whole permits. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
490 inhibit_defer_pop = old_inhibit_defer_pop;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
491
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
492 if (n_popped > 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
493 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
494 if (!already_popped)
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
495 CALL_INSN_FUNCTION_USAGE (call_insn)
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
496 = gen_rtx_EXPR_LIST (VOIDmode,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
497 gen_rtx_CLOBBER (VOIDmode, stack_pointer_rtx),
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
498 CALL_INSN_FUNCTION_USAGE (call_insn));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
499 rounded_stack_size -= n_popped;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
500 rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
501 stack_pointer_delta -= n_popped;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
502
111
kono
parents: 67
diff changeset
503 add_reg_note (call_insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
kono
parents: 67
diff changeset
504
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
505 /* If popup is needed, stack realign must use DRAP */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
506 if (SUPPORTS_STACK_ALIGNMENT)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
507 crtl->need_drap = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
508 }
111
kono
parents: 67
diff changeset
509 /* For noreturn calls when not accumulating outgoing args force
kono
parents: 67
diff changeset
510 REG_ARGS_SIZE note to prevent crossjumping of calls with different
kono
parents: 67
diff changeset
511 args sizes. */
kono
parents: 67
diff changeset
512 else if (!ACCUMULATE_OUTGOING_ARGS && (ecf_flags & ECF_NORETURN) != 0)
kono
parents: 67
diff changeset
513 add_reg_note (call_insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
514
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
515 if (!ACCUMULATE_OUTGOING_ARGS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
516 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
517 /* If returning from the subroutine does not automatically pop the args,
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
518 we need an instruction to pop them sooner or later.
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
519 Perhaps do it now; perhaps just record how much space to pop later.
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
520
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
521 If returning from the subroutine does pop the args, indicate that the
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
522 stack pointer will be changed. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
523
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
524 if (rounded_stack_size != 0)
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
525 {
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
526 if (ecf_flags & ECF_NORETURN)
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
527 /* Just pretend we did the pop. */
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
528 stack_pointer_delta -= rounded_stack_size;
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
529 else if (flag_defer_pop && inhibit_defer_pop == 0
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
530 && ! (ecf_flags & (ECF_CONST | ECF_PURE)))
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
531 pending_stack_adjust += rounded_stack_size;
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
532 else
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
533 adjust_stack (rounded_stack_size_rtx);
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
534 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
535 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
536 /* When we accumulate outgoing args, we must avoid any stack manipulations.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
537 Restore the stack pointer to its original value now. Usually
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
538 ACCUMULATE_OUTGOING_ARGS targets don't get here, but there are exceptions.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
539 On i386 ACCUMULATE_OUTGOING_ARGS can be enabled on demand, and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
540 popping variants of functions exist as well.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
541
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
542 ??? We may optimize similar to defer_pop above, but it is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
543 probably not worthwhile.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
544
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
545 ??? It will be worthwhile to enable combine_stack_adjustments even for
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
546 such machines. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
547 else if (n_popped)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
548 anti_adjust_stack (GEN_INT (n_popped));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
549 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
550
111
kono
parents: 67
diff changeset
551 /* Determine if the function identified by FNDECL is one with
kono
parents: 67
diff changeset
552 special properties we wish to know about. Modify FLAGS accordingly.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
553
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
554 For example, if the function might return more than one time (setjmp), then
111
kono
parents: 67
diff changeset
555 set ECF_RETURNS_TWICE.
kono
parents: 67
diff changeset
556
kono
parents: 67
diff changeset
557 Set ECF_MAY_BE_ALLOCA for any memory allocation function that might allocate
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
558 space from the stack such as alloca. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
559
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
560 static int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
561 special_function_p (const_tree fndecl, int flags)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
562 {
111
kono
parents: 67
diff changeset
563 tree name_decl = DECL_NAME (fndecl);
kono
parents: 67
diff changeset
564
kono
parents: 67
diff changeset
565 /* For instrumentation clones we want to derive flags
kono
parents: 67
diff changeset
566 from the original name. */
kono
parents: 67
diff changeset
567 if (cgraph_node::get (fndecl)
kono
parents: 67
diff changeset
568 && cgraph_node::get (fndecl)->instrumentation_clone)
kono
parents: 67
diff changeset
569 name_decl = DECL_NAME (cgraph_node::get (fndecl)->orig_decl);
kono
parents: 67
diff changeset
570
kono
parents: 67
diff changeset
571 if (fndecl && name_decl
kono
parents: 67
diff changeset
572 && IDENTIFIER_LENGTH (name_decl) <= 11
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
573 /* Exclude functions not at the file scope, or not `extern',
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
574 since they are not the magic functions we would otherwise
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
575 think they are.
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
576 FIXME: this should be handled with attributes, not with this
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
577 hacky imitation of DECL_ASSEMBLER_NAME. It's (also) wrong
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
578 because you can declare fork() inside a function if you
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
579 wish. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
580 && (DECL_CONTEXT (fndecl) == NULL_TREE
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
581 || TREE_CODE (DECL_CONTEXT (fndecl)) == TRANSLATION_UNIT_DECL)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
582 && TREE_PUBLIC (fndecl))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
583 {
111
kono
parents: 67
diff changeset
584 const char *name = IDENTIFIER_POINTER (name_decl);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
585 const char *tname = name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
586
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
587 /* We assume that alloca will always be called by name. It
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
588 makes no sense to pass it as a pointer-to-function to
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
589 anything that does not understand its behavior. */
111
kono
parents: 67
diff changeset
590 if (IDENTIFIER_LENGTH (name_decl) == 6
kono
parents: 67
diff changeset
591 && name[0] == 'a'
kono
parents: 67
diff changeset
592 && ! strcmp (name, "alloca"))
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
593 flags |= ECF_MAY_BE_ALLOCA;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
594
111
kono
parents: 67
diff changeset
595 /* Disregard prefix _ or __. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
596 if (name[0] == '_')
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
597 {
111
kono
parents: 67
diff changeset
598 if (name[1] == '_')
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
599 tname += 2;
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
600 else
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
601 tname += 1;
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
602 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
603
111
kono
parents: 67
diff changeset
604 /* ECF_RETURNS_TWICE is safe even for -ffreestanding. */
kono
parents: 67
diff changeset
605 if (! strcmp (tname, "setjmp")
kono
parents: 67
diff changeset
606 || ! strcmp (tname, "sigsetjmp")
kono
parents: 67
diff changeset
607 || ! strcmp (name, "savectx")
kono
parents: 67
diff changeset
608 || ! strcmp (name, "vfork")
kono
parents: 67
diff changeset
609 || ! strcmp (name, "getcontext"))
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
610 flags |= ECF_RETURNS_TWICE;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
611 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
612
111
kono
parents: 67
diff changeset
613 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
kono
parents: 67
diff changeset
614 && ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (fndecl)))
kono
parents: 67
diff changeset
615 flags |= ECF_MAY_BE_ALLOCA;
kono
parents: 67
diff changeset
616
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
617 return flags;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
618 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
619
111
kono
parents: 67
diff changeset
620 /* Similar to special_function_p; return a set of ERF_ flags for the
kono
parents: 67
diff changeset
621 function FNDECL. */
kono
parents: 67
diff changeset
622 static int
kono
parents: 67
diff changeset
623 decl_return_flags (tree fndecl)
kono
parents: 67
diff changeset
624 {
kono
parents: 67
diff changeset
625 tree attr;
kono
parents: 67
diff changeset
626 tree type = TREE_TYPE (fndecl);
kono
parents: 67
diff changeset
627 if (!type)
kono
parents: 67
diff changeset
628 return 0;
kono
parents: 67
diff changeset
629
kono
parents: 67
diff changeset
630 attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type));
kono
parents: 67
diff changeset
631 if (!attr)
kono
parents: 67
diff changeset
632 return 0;
kono
parents: 67
diff changeset
633
kono
parents: 67
diff changeset
634 attr = TREE_VALUE (TREE_VALUE (attr));
kono
parents: 67
diff changeset
635 if (!attr || TREE_STRING_LENGTH (attr) < 1)
kono
parents: 67
diff changeset
636 return 0;
kono
parents: 67
diff changeset
637
kono
parents: 67
diff changeset
638 switch (TREE_STRING_POINTER (attr)[0])
kono
parents: 67
diff changeset
639 {
kono
parents: 67
diff changeset
640 case '1':
kono
parents: 67
diff changeset
641 case '2':
kono
parents: 67
diff changeset
642 case '3':
kono
parents: 67
diff changeset
643 case '4':
kono
parents: 67
diff changeset
644 return ERF_RETURNS_ARG | (TREE_STRING_POINTER (attr)[0] - '1');
kono
parents: 67
diff changeset
645
kono
parents: 67
diff changeset
646 case 'm':
kono
parents: 67
diff changeset
647 return ERF_NOALIAS;
kono
parents: 67
diff changeset
648
kono
parents: 67
diff changeset
649 case '.':
kono
parents: 67
diff changeset
650 default:
kono
parents: 67
diff changeset
651 return 0;
kono
parents: 67
diff changeset
652 }
kono
parents: 67
diff changeset
653 }
kono
parents: 67
diff changeset
654
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
655 /* Return nonzero when FNDECL represents a call to setjmp. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
656
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
657 int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
658 setjmp_call_p (const_tree fndecl)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
659 {
111
kono
parents: 67
diff changeset
660 if (DECL_IS_RETURNS_TWICE (fndecl))
kono
parents: 67
diff changeset
661 return ECF_RETURNS_TWICE;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
662 return special_function_p (fndecl, 0) & ECF_RETURNS_TWICE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
663 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
664
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
665
111
kono
parents: 67
diff changeset
666 /* Return true if STMT may be an alloca call. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
667
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
668 bool
111
kono
parents: 67
diff changeset
669 gimple_maybe_alloca_call_p (const gimple *stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
670 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
671 tree fndecl;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
672
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
673 if (!is_gimple_call (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
674 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
675
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
676 fndecl = gimple_call_fndecl (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
677 if (fndecl && (special_function_p (fndecl, 0) & ECF_MAY_BE_ALLOCA))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
678 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
679
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
680 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
681 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
682
111
kono
parents: 67
diff changeset
683 /* Return true if STMT is a builtin alloca call. */
kono
parents: 67
diff changeset
684
kono
parents: 67
diff changeset
685 bool
kono
parents: 67
diff changeset
686 gimple_alloca_call_p (const gimple *stmt)
kono
parents: 67
diff changeset
687 {
kono
parents: 67
diff changeset
688 tree fndecl;
kono
parents: 67
diff changeset
689
kono
parents: 67
diff changeset
690 if (!is_gimple_call (stmt))
kono
parents: 67
diff changeset
691 return false;
kono
parents: 67
diff changeset
692
kono
parents: 67
diff changeset
693 fndecl = gimple_call_fndecl (stmt);
kono
parents: 67
diff changeset
694 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
kono
parents: 67
diff changeset
695 switch (DECL_FUNCTION_CODE (fndecl))
kono
parents: 67
diff changeset
696 {
kono
parents: 67
diff changeset
697 CASE_BUILT_IN_ALLOCA:
kono
parents: 67
diff changeset
698 return true;
kono
parents: 67
diff changeset
699 default:
kono
parents: 67
diff changeset
700 break;
kono
parents: 67
diff changeset
701 }
kono
parents: 67
diff changeset
702
kono
parents: 67
diff changeset
703 return false;
kono
parents: 67
diff changeset
704 }
kono
parents: 67
diff changeset
705
kono
parents: 67
diff changeset
706 /* Return true when exp contains a builtin alloca call. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
707
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
708 bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
709 alloca_call_p (const_tree exp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
710 {
111
kono
parents: 67
diff changeset
711 tree fndecl;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
712 if (TREE_CODE (exp) == CALL_EXPR
111
kono
parents: 67
diff changeset
713 && (fndecl = get_callee_fndecl (exp))
kono
parents: 67
diff changeset
714 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
kono
parents: 67
diff changeset
715 switch (DECL_FUNCTION_CODE (fndecl))
kono
parents: 67
diff changeset
716 {
kono
parents: 67
diff changeset
717 CASE_BUILT_IN_ALLOCA:
kono
parents: 67
diff changeset
718 return true;
kono
parents: 67
diff changeset
719 default:
kono
parents: 67
diff changeset
720 break;
kono
parents: 67
diff changeset
721 }
kono
parents: 67
diff changeset
722
kono
parents: 67
diff changeset
723 return false;
kono
parents: 67
diff changeset
724 }
kono
parents: 67
diff changeset
725
kono
parents: 67
diff changeset
726 /* Return TRUE if FNDECL is either a TM builtin or a TM cloned
kono
parents: 67
diff changeset
727 function. Return FALSE otherwise. */
kono
parents: 67
diff changeset
728
kono
parents: 67
diff changeset
729 static bool
kono
parents: 67
diff changeset
730 is_tm_builtin (const_tree fndecl)
kono
parents: 67
diff changeset
731 {
kono
parents: 67
diff changeset
732 if (fndecl == NULL)
kono
parents: 67
diff changeset
733 return false;
kono
parents: 67
diff changeset
734
kono
parents: 67
diff changeset
735 if (decl_is_tm_clone (fndecl))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
736 return true;
111
kono
parents: 67
diff changeset
737
kono
parents: 67
diff changeset
738 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
kono
parents: 67
diff changeset
739 {
kono
parents: 67
diff changeset
740 switch (DECL_FUNCTION_CODE (fndecl))
kono
parents: 67
diff changeset
741 {
kono
parents: 67
diff changeset
742 case BUILT_IN_TM_COMMIT:
kono
parents: 67
diff changeset
743 case BUILT_IN_TM_COMMIT_EH:
kono
parents: 67
diff changeset
744 case BUILT_IN_TM_ABORT:
kono
parents: 67
diff changeset
745 case BUILT_IN_TM_IRREVOCABLE:
kono
parents: 67
diff changeset
746 case BUILT_IN_TM_GETTMCLONE_IRR:
kono
parents: 67
diff changeset
747 case BUILT_IN_TM_MEMCPY:
kono
parents: 67
diff changeset
748 case BUILT_IN_TM_MEMMOVE:
kono
parents: 67
diff changeset
749 case BUILT_IN_TM_MEMSET:
kono
parents: 67
diff changeset
750 CASE_BUILT_IN_TM_STORE (1):
kono
parents: 67
diff changeset
751 CASE_BUILT_IN_TM_STORE (2):
kono
parents: 67
diff changeset
752 CASE_BUILT_IN_TM_STORE (4):
kono
parents: 67
diff changeset
753 CASE_BUILT_IN_TM_STORE (8):
kono
parents: 67
diff changeset
754 CASE_BUILT_IN_TM_STORE (FLOAT):
kono
parents: 67
diff changeset
755 CASE_BUILT_IN_TM_STORE (DOUBLE):
kono
parents: 67
diff changeset
756 CASE_BUILT_IN_TM_STORE (LDOUBLE):
kono
parents: 67
diff changeset
757 CASE_BUILT_IN_TM_STORE (M64):
kono
parents: 67
diff changeset
758 CASE_BUILT_IN_TM_STORE (M128):
kono
parents: 67
diff changeset
759 CASE_BUILT_IN_TM_STORE (M256):
kono
parents: 67
diff changeset
760 CASE_BUILT_IN_TM_LOAD (1):
kono
parents: 67
diff changeset
761 CASE_BUILT_IN_TM_LOAD (2):
kono
parents: 67
diff changeset
762 CASE_BUILT_IN_TM_LOAD (4):
kono
parents: 67
diff changeset
763 CASE_BUILT_IN_TM_LOAD (8):
kono
parents: 67
diff changeset
764 CASE_BUILT_IN_TM_LOAD (FLOAT):
kono
parents: 67
diff changeset
765 CASE_BUILT_IN_TM_LOAD (DOUBLE):
kono
parents: 67
diff changeset
766 CASE_BUILT_IN_TM_LOAD (LDOUBLE):
kono
parents: 67
diff changeset
767 CASE_BUILT_IN_TM_LOAD (M64):
kono
parents: 67
diff changeset
768 CASE_BUILT_IN_TM_LOAD (M128):
kono
parents: 67
diff changeset
769 CASE_BUILT_IN_TM_LOAD (M256):
kono
parents: 67
diff changeset
770 case BUILT_IN_TM_LOG:
kono
parents: 67
diff changeset
771 case BUILT_IN_TM_LOG_1:
kono
parents: 67
diff changeset
772 case BUILT_IN_TM_LOG_2:
kono
parents: 67
diff changeset
773 case BUILT_IN_TM_LOG_4:
kono
parents: 67
diff changeset
774 case BUILT_IN_TM_LOG_8:
kono
parents: 67
diff changeset
775 case BUILT_IN_TM_LOG_FLOAT:
kono
parents: 67
diff changeset
776 case BUILT_IN_TM_LOG_DOUBLE:
kono
parents: 67
diff changeset
777 case BUILT_IN_TM_LOG_LDOUBLE:
kono
parents: 67
diff changeset
778 case BUILT_IN_TM_LOG_M64:
kono
parents: 67
diff changeset
779 case BUILT_IN_TM_LOG_M128:
kono
parents: 67
diff changeset
780 case BUILT_IN_TM_LOG_M256:
kono
parents: 67
diff changeset
781 return true;
kono
parents: 67
diff changeset
782 default:
kono
parents: 67
diff changeset
783 break;
kono
parents: 67
diff changeset
784 }
kono
parents: 67
diff changeset
785 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
786 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
787 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
788
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
789 /* Detect flags (function attributes) from the function decl or type node. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
790
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
791 int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
792 flags_from_decl_or_type (const_tree exp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
793 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
794 int flags = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
795
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
796 if (DECL_P (exp))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
797 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
798 /* The function exp may have the `malloc' attribute. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
799 if (DECL_IS_MALLOC (exp))
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
800 flags |= ECF_MALLOC;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
801
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
802 /* The function exp may have the `returns_twice' attribute. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
803 if (DECL_IS_RETURNS_TWICE (exp))
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
804 flags |= ECF_RETURNS_TWICE;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
805
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
806 /* Process the pure and const attributes. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
807 if (TREE_READONLY (exp))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
808 flags |= ECF_CONST;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
809 if (DECL_PURE_P (exp))
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
810 flags |= ECF_PURE;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
811 if (DECL_LOOPING_CONST_OR_PURE_P (exp))
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
812 flags |= ECF_LOOPING_CONST_OR_PURE;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
813
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
814 if (DECL_IS_NOVOPS (exp))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
815 flags |= ECF_NOVOPS;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
816 if (lookup_attribute ("leaf", DECL_ATTRIBUTES (exp)))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
817 flags |= ECF_LEAF;
111
kono
parents: 67
diff changeset
818 if (lookup_attribute ("cold", DECL_ATTRIBUTES (exp)))
kono
parents: 67
diff changeset
819 flags |= ECF_COLD;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
820
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
821 if (TREE_NOTHROW (exp))
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
822 flags |= ECF_NOTHROW;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
823
111
kono
parents: 67
diff changeset
824 if (flag_tm)
kono
parents: 67
diff changeset
825 {
kono
parents: 67
diff changeset
826 if (is_tm_builtin (exp))
kono
parents: 67
diff changeset
827 flags |= ECF_TM_BUILTIN;
kono
parents: 67
diff changeset
828 else if ((flags & (ECF_CONST|ECF_NOVOPS)) != 0
kono
parents: 67
diff changeset
829 || lookup_attribute ("transaction_pure",
kono
parents: 67
diff changeset
830 TYPE_ATTRIBUTES (TREE_TYPE (exp))))
kono
parents: 67
diff changeset
831 flags |= ECF_TM_PURE;
kono
parents: 67
diff changeset
832 }
kono
parents: 67
diff changeset
833
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
834 flags = special_function_p (exp, flags);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
835 }
111
kono
parents: 67
diff changeset
836 else if (TYPE_P (exp))
kono
parents: 67
diff changeset
837 {
kono
parents: 67
diff changeset
838 if (TYPE_READONLY (exp))
kono
parents: 67
diff changeset
839 flags |= ECF_CONST;
kono
parents: 67
diff changeset
840
kono
parents: 67
diff changeset
841 if (flag_tm
kono
parents: 67
diff changeset
842 && ((flags & ECF_CONST) != 0
kono
parents: 67
diff changeset
843 || lookup_attribute ("transaction_pure", TYPE_ATTRIBUTES (exp))))
kono
parents: 67
diff changeset
844 flags |= ECF_TM_PURE;
kono
parents: 67
diff changeset
845 }
kono
parents: 67
diff changeset
846 else
kono
parents: 67
diff changeset
847 gcc_unreachable ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
848
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
849 if (TREE_THIS_VOLATILE (exp))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
850 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
851 flags |= ECF_NORETURN;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
852 if (flags & (ECF_CONST|ECF_PURE))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
853 flags |= ECF_LOOPING_CONST_OR_PURE;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
854 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
855
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
856 return flags;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
857 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
858
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
859 /* Detect flags from a CALL_EXPR. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
860
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
861 int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
862 call_expr_flags (const_tree t)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
863 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
864 int flags;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
865 tree decl = get_callee_fndecl (t);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
866
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
867 if (decl)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
868 flags = flags_from_decl_or_type (decl);
111
kono
parents: 67
diff changeset
869 else if (CALL_EXPR_FN (t) == NULL_TREE)
kono
parents: 67
diff changeset
870 flags = internal_fn_flags (CALL_EXPR_IFN (t));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
871 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
872 {
111
kono
parents: 67
diff changeset
873 tree type = TREE_TYPE (CALL_EXPR_FN (t));
kono
parents: 67
diff changeset
874 if (type && TREE_CODE (type) == POINTER_TYPE)
kono
parents: 67
diff changeset
875 flags = flags_from_decl_or_type (TREE_TYPE (type));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
876 else
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
877 flags = 0;
111
kono
parents: 67
diff changeset
878 if (CALL_EXPR_BY_DESCRIPTOR (t))
kono
parents: 67
diff changeset
879 flags |= ECF_BY_DESCRIPTOR;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
880 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
881
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
882 return flags;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
883 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
884
111
kono
parents: 67
diff changeset
885 /* Return true if TYPE should be passed by invisible reference. */
kono
parents: 67
diff changeset
886
kono
parents: 67
diff changeset
887 bool
kono
parents: 67
diff changeset
888 pass_by_reference (CUMULATIVE_ARGS *ca, machine_mode mode,
kono
parents: 67
diff changeset
889 tree type, bool named_arg)
kono
parents: 67
diff changeset
890 {
kono
parents: 67
diff changeset
891 if (type)
kono
parents: 67
diff changeset
892 {
kono
parents: 67
diff changeset
893 /* If this type contains non-trivial constructors, then it is
kono
parents: 67
diff changeset
894 forbidden for the middle-end to create any new copies. */
kono
parents: 67
diff changeset
895 if (TREE_ADDRESSABLE (type))
kono
parents: 67
diff changeset
896 return true;
kono
parents: 67
diff changeset
897
kono
parents: 67
diff changeset
898 /* GCC post 3.4 passes *all* variable sized types by reference. */
kono
parents: 67
diff changeset
899 if (!TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
kono
parents: 67
diff changeset
900 return true;
kono
parents: 67
diff changeset
901
kono
parents: 67
diff changeset
902 /* If a record type should be passed the same as its first (and only)
kono
parents: 67
diff changeset
903 member, use the type and mode of that member. */
kono
parents: 67
diff changeset
904 if (TREE_CODE (type) == RECORD_TYPE && TYPE_TRANSPARENT_AGGR (type))
kono
parents: 67
diff changeset
905 {
kono
parents: 67
diff changeset
906 type = TREE_TYPE (first_field (type));
kono
parents: 67
diff changeset
907 mode = TYPE_MODE (type);
kono
parents: 67
diff changeset
908 }
kono
parents: 67
diff changeset
909 }
kono
parents: 67
diff changeset
910
kono
parents: 67
diff changeset
911 return targetm.calls.pass_by_reference (pack_cumulative_args (ca), mode,
kono
parents: 67
diff changeset
912 type, named_arg);
kono
parents: 67
diff changeset
913 }
kono
parents: 67
diff changeset
914
kono
parents: 67
diff changeset
915 /* Return true if TYPE, which is passed by reference, should be callee
kono
parents: 67
diff changeset
916 copied instead of caller copied. */
kono
parents: 67
diff changeset
917
kono
parents: 67
diff changeset
918 bool
kono
parents: 67
diff changeset
919 reference_callee_copied (CUMULATIVE_ARGS *ca, machine_mode mode,
kono
parents: 67
diff changeset
920 tree type, bool named_arg)
kono
parents: 67
diff changeset
921 {
kono
parents: 67
diff changeset
922 if (type && TREE_ADDRESSABLE (type))
kono
parents: 67
diff changeset
923 return false;
kono
parents: 67
diff changeset
924 return targetm.calls.callee_copies (pack_cumulative_args (ca), mode, type,
kono
parents: 67
diff changeset
925 named_arg);
kono
parents: 67
diff changeset
926 }
kono
parents: 67
diff changeset
927
kono
parents: 67
diff changeset
928
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
929 /* Precompute all register parameters as described by ARGS, storing values
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
930 into fields within the ARGS array.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
931
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
932 NUM_ACTUALS indicates the total number elements in the ARGS array.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
933
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
934 Set REG_PARM_SEEN if we encounter a register parameter. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
935
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
936 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
937 precompute_register_parameters (int num_actuals, struct arg_data *args,
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
938 int *reg_parm_seen)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
939 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
940 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
941
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
942 *reg_parm_seen = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
943
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
944 for (i = 0; i < num_actuals; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
945 if (args[i].reg != 0 && ! args[i].pass_on_stack)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
946 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
947 *reg_parm_seen = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
948
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
949 if (args[i].value == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
950 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
951 push_temp_slots ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
952 args[i].value = expand_normal (args[i].tree_value);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
953 preserve_temp_slots (args[i].value);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
954 pop_temp_slots ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
955 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
956
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
957 /* If we are to promote the function arg to a wider mode,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
958 do it now. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
959
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
960 if (args[i].mode != TYPE_MODE (TREE_TYPE (args[i].tree_value)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
961 args[i].value
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
962 = convert_modes (args[i].mode,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
963 TYPE_MODE (TREE_TYPE (args[i].tree_value)),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
964 args[i].value, args[i].unsignedp);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
965
111
kono
parents: 67
diff changeset
966 /* If the value is a non-legitimate constant, force it into a
kono
parents: 67
diff changeset
967 pseudo now. TLS symbols sometimes need a call to resolve. */
kono
parents: 67
diff changeset
968 if (CONSTANT_P (args[i].value)
kono
parents: 67
diff changeset
969 && !targetm.legitimate_constant_p (args[i].mode, args[i].value))
kono
parents: 67
diff changeset
970 args[i].value = force_reg (args[i].mode, args[i].value);
kono
parents: 67
diff changeset
971
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
972 /* If we're going to have to load the value by parts, pull the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
973 parts into pseudos. The part extraction process can involve
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
974 non-trivial computation. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
975 if (GET_CODE (args[i].reg) == PARALLEL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
976 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
977 tree type = TREE_TYPE (args[i].tree_value);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
978 args[i].parallel_value
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
979 = emit_group_load_into_temps (args[i].reg, args[i].value,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
980 type, int_size_in_bytes (type));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
981 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
982
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
983 /* If the value is expensive, and we are inside an appropriately
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
984 short loop, put the value into a pseudo and then put the pseudo
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
985 into the hard reg.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
986
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
987 For small register classes, also do this if this call uses
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
988 register parameters. This is to avoid reload conflicts while
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
989 loading the parameters registers. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
990
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
991 else if ((! (REG_P (args[i].value)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
992 || (GET_CODE (args[i].value) == SUBREG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
993 && REG_P (SUBREG_REG (args[i].value)))))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
994 && args[i].mode != BLKmode
111
kono
parents: 67
diff changeset
995 && (set_src_cost (args[i].value, args[i].mode,
kono
parents: 67
diff changeset
996 optimize_insn_for_speed_p ())
kono
parents: 67
diff changeset
997 > COSTS_N_INSNS (1))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
998 && ((*reg_parm_seen
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
999 && targetm.small_register_classes_for_mode_p (args[i].mode))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1000 || optimize))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1001 args[i].value = copy_to_mode_reg (args[i].mode, args[i].value);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1002 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1003 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1004
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1005 #ifdef REG_PARM_STACK_SPACE
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1006
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1007 /* The argument list is the property of the called routine and it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1008 may clobber it. If the fixed area has been used for previous
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1009 parameters, we must save and restore it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1010
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1011 static rtx
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1012 save_fixed_argument_area (int reg_parm_stack_space, rtx argblock, int *low_to_save, int *high_to_save)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1013 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1014 int low;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1015 int high;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1016
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1017 /* Compute the boundary of the area that needs to be saved, if any. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1018 high = reg_parm_stack_space;
111
kono
parents: 67
diff changeset
1019 if (ARGS_GROW_DOWNWARD)
kono
parents: 67
diff changeset
1020 high += 1;
kono
parents: 67
diff changeset
1021
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1022 if (high > highest_outgoing_arg_in_use)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1023 high = highest_outgoing_arg_in_use;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1024
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1025 for (low = 0; low < high; low++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1026 if (stack_usage_map[low] != 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1027 {
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1028 int num_to_save;
111
kono
parents: 67
diff changeset
1029 machine_mode save_mode;
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1030 int delta;
111
kono
parents: 67
diff changeset
1031 rtx addr;
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1032 rtx stack_area;
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1033 rtx save_area;
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1034
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1035 while (stack_usage_map[--high] == 0)
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1036 ;
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1037
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1038 *low_to_save = low;
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1039 *high_to_save = high;
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1040
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1041 num_to_save = high - low + 1;
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1042
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1043 /* If we don't have the required alignment, must do this
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1044 in BLKmode. */
111
kono
parents: 67
diff changeset
1045 scalar_int_mode imode;
kono
parents: 67
diff changeset
1046 if (int_mode_for_size (num_to_save * BITS_PER_UNIT, 1).exists (&imode)
kono
parents: 67
diff changeset
1047 && (low & (MIN (GET_MODE_SIZE (imode),
kono
parents: 67
diff changeset
1048 BIGGEST_ALIGNMENT / UNITS_PER_WORD) - 1)) == 0)
kono
parents: 67
diff changeset
1049 save_mode = imode;
kono
parents: 67
diff changeset
1050 else
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1051 save_mode = BLKmode;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1052
111
kono
parents: 67
diff changeset
1053 if (ARGS_GROW_DOWNWARD)
kono
parents: 67
diff changeset
1054 delta = -high;
kono
parents: 67
diff changeset
1055 else
kono
parents: 67
diff changeset
1056 delta = low;
kono
parents: 67
diff changeset
1057
kono
parents: 67
diff changeset
1058 addr = plus_constant (Pmode, argblock, delta);
kono
parents: 67
diff changeset
1059 stack_area = gen_rtx_MEM (save_mode, memory_address (save_mode, addr));
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1060
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1061 set_mem_align (stack_area, PARM_BOUNDARY);
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1062 if (save_mode == BLKmode)
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1063 {
111
kono
parents: 67
diff changeset
1064 save_area = assign_stack_temp (BLKmode, num_to_save);
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1065 emit_block_move (validize_mem (save_area), stack_area,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1066 GEN_INT (num_to_save), BLOCK_OP_CALL_PARM);
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1067 }
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1068 else
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1069 {
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1070 save_area = gen_reg_rtx (save_mode);
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1071 emit_move_insn (save_area, stack_area);
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1072 }
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1073
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1074 return save_area;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1075 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1076
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1077 return NULL_RTX;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1078 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1079
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1080 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1081 restore_fixed_argument_area (rtx save_area, rtx argblock, int high_to_save, int low_to_save)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1082 {
111
kono
parents: 67
diff changeset
1083 machine_mode save_mode = GET_MODE (save_area);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1084 int delta;
111
kono
parents: 67
diff changeset
1085 rtx addr, stack_area;
kono
parents: 67
diff changeset
1086
kono
parents: 67
diff changeset
1087 if (ARGS_GROW_DOWNWARD)
kono
parents: 67
diff changeset
1088 delta = -high_to_save;
kono
parents: 67
diff changeset
1089 else
kono
parents: 67
diff changeset
1090 delta = low_to_save;
kono
parents: 67
diff changeset
1091
kono
parents: 67
diff changeset
1092 addr = plus_constant (Pmode, argblock, delta);
kono
parents: 67
diff changeset
1093 stack_area = gen_rtx_MEM (save_mode, memory_address (save_mode, addr));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1094 set_mem_align (stack_area, PARM_BOUNDARY);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1095
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1096 if (save_mode != BLKmode)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1097 emit_move_insn (stack_area, save_area);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1098 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1099 emit_block_move (stack_area, validize_mem (save_area),
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1100 GEN_INT (high_to_save - low_to_save + 1),
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1101 BLOCK_OP_CALL_PARM);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1102 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1103 #endif /* REG_PARM_STACK_SPACE */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1104
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1105 /* If any elements in ARGS refer to parameters that are to be passed in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1106 registers, but not in memory, and whose alignment does not permit a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1107 direct copy into registers. Copy the values into a group of pseudos
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1108 which we will later copy into the appropriate hard registers.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1109
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1110 Pseudos for each unaligned argument will be stored into the array
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1111 args[argnum].aligned_regs. The caller is responsible for deallocating
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1112 the aligned_regs array if it is nonzero. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1113
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1114 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1115 store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1116 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1117 int i, j;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1118
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1119 for (i = 0; i < num_actuals; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1120 if (args[i].reg != 0 && ! args[i].pass_on_stack
111
kono
parents: 67
diff changeset
1121 && GET_CODE (args[i].reg) != PARALLEL
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1122 && args[i].mode == BLKmode
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1123 && MEM_P (args[i].value)
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1124 && (MEM_ALIGN (args[i].value)
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1125 < (unsigned int) MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1126 {
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1127 int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1128 int endian_correction = 0;
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1129
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1130 if (args[i].partial)
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1131 {
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1132 gcc_assert (args[i].partial % UNITS_PER_WORD == 0);
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1133 args[i].n_aligned_regs = args[i].partial / UNITS_PER_WORD;
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1134 }
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1135 else
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1136 {
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1137 args[i].n_aligned_regs
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1138 = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1139 }
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1140
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1141 args[i].aligned_regs = XNEWVEC (rtx, args[i].n_aligned_regs);
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1142
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1143 /* Structures smaller than a word are normally aligned to the
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1144 least significant byte. On a BYTES_BIG_ENDIAN machine,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1145 this means we must skip the empty high order bytes when
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1146 calculating the bit offset. */
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1147 if (bytes < UNITS_PER_WORD
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1148 #ifdef BLOCK_REG_PADDING
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1149 && (BLOCK_REG_PADDING (args[i].mode,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1150 TREE_TYPE (args[i].tree_value), 1)
111
kono
parents: 67
diff changeset
1151 == PAD_DOWNWARD)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1152 #else
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1153 && BYTES_BIG_ENDIAN
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1154 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1155 )
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1156 endian_correction = BITS_PER_WORD - bytes * BITS_PER_UNIT;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1157
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1158 for (j = 0; j < args[i].n_aligned_regs; j++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1159 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1160 rtx reg = gen_reg_rtx (word_mode);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1161 rtx word = operand_subword_force (args[i].value, j, BLKmode);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1162 int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1163
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1164 args[i].aligned_regs[j] = reg;
111
kono
parents: 67
diff changeset
1165 word = extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
kono
parents: 67
diff changeset
1166 word_mode, word_mode, false, NULL);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1167
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1168 /* There is no need to restrict this code to loading items
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1169 in TYPE_ALIGN sized hunks. The bitfield instructions can
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1170 load up entire word sized registers efficiently.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1171
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1172 ??? This may not be needed anymore.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1173 We use to emit a clobber here but that doesn't let later
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1174 passes optimize the instructions we emit. By storing 0 into
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1175 the register later passes know the first AND to zero out the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1176 bitfield being set in the register is unnecessary. The store
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1177 of 0 will be deleted as will at least the first AND. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1178
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1179 emit_move_insn (reg, const0_rtx);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1180
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1181 bytes -= bitsize / BITS_PER_UNIT;
111
kono
parents: 67
diff changeset
1182 store_bit_field (reg, bitsize, endian_correction, 0, 0,
kono
parents: 67
diff changeset
1183 word_mode, word, false);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1184 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1185 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1186 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1187
111
kono
parents: 67
diff changeset
1188 /* The limit set by -Walloc-larger-than=. */
kono
parents: 67
diff changeset
1189 static GTY(()) tree alloc_object_size_limit;
kono
parents: 67
diff changeset
1190
kono
parents: 67
diff changeset
1191 /* Initialize ALLOC_OBJECT_SIZE_LIMIT based on the -Walloc-size-larger-than=
kono
parents: 67
diff changeset
1192 setting if the option is specified, or to the maximum object size if it
kono
parents: 67
diff changeset
1193 is not. Return the initialized value. */
kono
parents: 67
diff changeset
1194
kono
parents: 67
diff changeset
1195 static tree
kono
parents: 67
diff changeset
1196 alloc_max_size (void)
kono
parents: 67
diff changeset
1197 {
kono
parents: 67
diff changeset
1198 if (!alloc_object_size_limit)
kono
parents: 67
diff changeset
1199 {
kono
parents: 67
diff changeset
1200 alloc_object_size_limit = TYPE_MAX_VALUE (ssizetype);
kono
parents: 67
diff changeset
1201
kono
parents: 67
diff changeset
1202 if (warn_alloc_size_limit)
kono
parents: 67
diff changeset
1203 {
kono
parents: 67
diff changeset
1204 char *end = NULL;
kono
parents: 67
diff changeset
1205 errno = 0;
kono
parents: 67
diff changeset
1206 unsigned HOST_WIDE_INT unit = 1;
kono
parents: 67
diff changeset
1207 unsigned HOST_WIDE_INT limit
kono
parents: 67
diff changeset
1208 = strtoull (warn_alloc_size_limit, &end, 10);
kono
parents: 67
diff changeset
1209
kono
parents: 67
diff changeset
1210 if (!errno)
kono
parents: 67
diff changeset
1211 {
kono
parents: 67
diff changeset
1212 if (end && *end)
kono
parents: 67
diff changeset
1213 {
kono
parents: 67
diff changeset
1214 /* Numeric option arguments are at most INT_MAX. Make it
kono
parents: 67
diff changeset
1215 possible to specify a larger value by accepting common
kono
parents: 67
diff changeset
1216 suffixes. */
kono
parents: 67
diff changeset
1217 if (!strcmp (end, "kB"))
kono
parents: 67
diff changeset
1218 unit = 1000;
kono
parents: 67
diff changeset
1219 else if (!strcasecmp (end, "KiB") || strcmp (end, "KB"))
kono
parents: 67
diff changeset
1220 unit = 1024;
kono
parents: 67
diff changeset
1221 else if (!strcmp (end, "MB"))
kono
parents: 67
diff changeset
1222 unit = HOST_WIDE_INT_UC (1000) * 1000;
kono
parents: 67
diff changeset
1223 else if (!strcasecmp (end, "MiB"))
kono
parents: 67
diff changeset
1224 unit = HOST_WIDE_INT_UC (1024) * 1024;
kono
parents: 67
diff changeset
1225 else if (!strcasecmp (end, "GB"))
kono
parents: 67
diff changeset
1226 unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000;
kono
parents: 67
diff changeset
1227 else if (!strcasecmp (end, "GiB"))
kono
parents: 67
diff changeset
1228 unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024;
kono
parents: 67
diff changeset
1229 else if (!strcasecmp (end, "TB"))
kono
parents: 67
diff changeset
1230 unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000;
kono
parents: 67
diff changeset
1231 else if (!strcasecmp (end, "TiB"))
kono
parents: 67
diff changeset
1232 unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024;
kono
parents: 67
diff changeset
1233 else if (!strcasecmp (end, "PB"))
kono
parents: 67
diff changeset
1234 unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000;
kono
parents: 67
diff changeset
1235 else if (!strcasecmp (end, "PiB"))
kono
parents: 67
diff changeset
1236 unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024;
kono
parents: 67
diff changeset
1237 else if (!strcasecmp (end, "EB"))
kono
parents: 67
diff changeset
1238 unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000
kono
parents: 67
diff changeset
1239 * 1000;
kono
parents: 67
diff changeset
1240 else if (!strcasecmp (end, "EiB"))
kono
parents: 67
diff changeset
1241 unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024
kono
parents: 67
diff changeset
1242 * 1024;
kono
parents: 67
diff changeset
1243 else
kono
parents: 67
diff changeset
1244 unit = 0;
kono
parents: 67
diff changeset
1245 }
kono
parents: 67
diff changeset
1246
kono
parents: 67
diff changeset
1247 if (unit)
kono
parents: 67
diff changeset
1248 {
kono
parents: 67
diff changeset
1249 widest_int w = wi::mul (limit, unit);
kono
parents: 67
diff changeset
1250 if (w < wi::to_widest (alloc_object_size_limit))
kono
parents: 67
diff changeset
1251 alloc_object_size_limit = wide_int_to_tree (ssizetype, w);
kono
parents: 67
diff changeset
1252 }
kono
parents: 67
diff changeset
1253 }
kono
parents: 67
diff changeset
1254 }
kono
parents: 67
diff changeset
1255 }
kono
parents: 67
diff changeset
1256 return alloc_object_size_limit;
kono
parents: 67
diff changeset
1257 }
kono
parents: 67
diff changeset
1258
kono
parents: 67
diff changeset
1259 /* Return true when EXP's range can be determined and set RANGE[] to it
kono
parents: 67
diff changeset
1260 after adjusting it if necessary to make EXP a valid size argument to
kono
parents: 67
diff changeset
1261 an allocation function declared with attribute alloc_size (whose
kono
parents: 67
diff changeset
1262 argument may be signed), or to a string manipulation function like
kono
parents: 67
diff changeset
1263 memset. */
kono
parents: 67
diff changeset
1264
kono
parents: 67
diff changeset
1265 bool
kono
parents: 67
diff changeset
1266 get_size_range (tree exp, tree range[2])
kono
parents: 67
diff changeset
1267 {
kono
parents: 67
diff changeset
1268 if (tree_fits_uhwi_p (exp))
kono
parents: 67
diff changeset
1269 {
kono
parents: 67
diff changeset
1270 /* EXP is a constant. */
kono
parents: 67
diff changeset
1271 range[0] = range[1] = exp;
kono
parents: 67
diff changeset
1272 return true;
kono
parents: 67
diff changeset
1273 }
kono
parents: 67
diff changeset
1274
kono
parents: 67
diff changeset
1275 wide_int min, max;
kono
parents: 67
diff changeset
1276 enum value_range_type range_type
kono
parents: 67
diff changeset
1277 = ((TREE_CODE (exp) == SSA_NAME && INTEGRAL_TYPE_P (TREE_TYPE (exp)))
kono
parents: 67
diff changeset
1278 ? get_range_info (exp, &min, &max) : VR_VARYING);
kono
parents: 67
diff changeset
1279
kono
parents: 67
diff changeset
1280 if (range_type == VR_VARYING)
kono
parents: 67
diff changeset
1281 {
kono
parents: 67
diff changeset
1282 /* No range information available. */
kono
parents: 67
diff changeset
1283 range[0] = NULL_TREE;
kono
parents: 67
diff changeset
1284 range[1] = NULL_TREE;
kono
parents: 67
diff changeset
1285 return false;
kono
parents: 67
diff changeset
1286 }
kono
parents: 67
diff changeset
1287
kono
parents: 67
diff changeset
1288 tree exptype = TREE_TYPE (exp);
kono
parents: 67
diff changeset
1289 unsigned expprec = TYPE_PRECISION (exptype);
kono
parents: 67
diff changeset
1290
kono
parents: 67
diff changeset
1291 bool signed_p = !TYPE_UNSIGNED (exptype);
kono
parents: 67
diff changeset
1292
kono
parents: 67
diff changeset
1293 if (range_type == VR_ANTI_RANGE)
kono
parents: 67
diff changeset
1294 {
kono
parents: 67
diff changeset
1295 if (signed_p)
kono
parents: 67
diff changeset
1296 {
kono
parents: 67
diff changeset
1297 if (wi::les_p (max, 0))
kono
parents: 67
diff changeset
1298 {
kono
parents: 67
diff changeset
1299 /* EXP is not in a strictly negative range. That means
kono
parents: 67
diff changeset
1300 it must be in some (not necessarily strictly) positive
kono
parents: 67
diff changeset
1301 range which includes zero. Since in signed to unsigned
kono
parents: 67
diff changeset
1302 conversions negative values end up converted to large
kono
parents: 67
diff changeset
1303 positive values, and otherwise they are not valid sizes,
kono
parents: 67
diff changeset
1304 the resulting range is in both cases [0, TYPE_MAX]. */
kono
parents: 67
diff changeset
1305 min = wi::zero (expprec);
kono
parents: 67
diff changeset
1306 max = wi::to_wide (TYPE_MAX_VALUE (exptype));
kono
parents: 67
diff changeset
1307 }
kono
parents: 67
diff changeset
1308 else if (wi::les_p (min - 1, 0))
kono
parents: 67
diff changeset
1309 {
kono
parents: 67
diff changeset
1310 /* EXP is not in a negative-positive range. That means EXP
kono
parents: 67
diff changeset
1311 is either negative, or greater than max. Since negative
kono
parents: 67
diff changeset
1312 sizes are invalid make the range [MAX + 1, TYPE_MAX]. */
kono
parents: 67
diff changeset
1313 min = max + 1;
kono
parents: 67
diff changeset
1314 max = wi::to_wide (TYPE_MAX_VALUE (exptype));
kono
parents: 67
diff changeset
1315 }
kono
parents: 67
diff changeset
1316 else
kono
parents: 67
diff changeset
1317 {
kono
parents: 67
diff changeset
1318 max = min - 1;
kono
parents: 67
diff changeset
1319 min = wi::zero (expprec);
kono
parents: 67
diff changeset
1320 }
kono
parents: 67
diff changeset
1321 }
kono
parents: 67
diff changeset
1322 else if (wi::eq_p (0, min - 1))
kono
parents: 67
diff changeset
1323 {
kono
parents: 67
diff changeset
1324 /* EXP is unsigned and not in the range [1, MAX]. That means
kono
parents: 67
diff changeset
1325 it's either zero or greater than MAX. Even though 0 would
kono
parents: 67
diff changeset
1326 normally be detected by -Walloc-zero set the range to
kono
parents: 67
diff changeset
1327 [MAX, TYPE_MAX] so that when MAX is greater than the limit
kono
parents: 67
diff changeset
1328 the whole range is diagnosed. */
kono
parents: 67
diff changeset
1329 min = max + 1;
kono
parents: 67
diff changeset
1330 max = wi::to_wide (TYPE_MAX_VALUE (exptype));
kono
parents: 67
diff changeset
1331 }
kono
parents: 67
diff changeset
1332 else
kono
parents: 67
diff changeset
1333 {
kono
parents: 67
diff changeset
1334 max = min - 1;
kono
parents: 67
diff changeset
1335 min = wi::zero (expprec);
kono
parents: 67
diff changeset
1336 }
kono
parents: 67
diff changeset
1337 }
kono
parents: 67
diff changeset
1338
kono
parents: 67
diff changeset
1339 range[0] = wide_int_to_tree (exptype, min);
kono
parents: 67
diff changeset
1340 range[1] = wide_int_to_tree (exptype, max);
kono
parents: 67
diff changeset
1341
kono
parents: 67
diff changeset
1342 return true;
kono
parents: 67
diff changeset
1343 }
kono
parents: 67
diff changeset
1344
kono
parents: 67
diff changeset
1345 /* Diagnose a call EXP to function FN decorated with attribute alloc_size
kono
parents: 67
diff changeset
1346 whose argument numbers given by IDX with values given by ARGS exceed
kono
parents: 67
diff changeset
1347 the maximum object size or cause an unsigned oveflow (wrapping) when
kono
parents: 67
diff changeset
1348 multiplied. When ARGS[0] is null the function does nothing. ARGS[1]
kono
parents: 67
diff changeset
1349 may be null for functions like malloc, and non-null for those like
kono
parents: 67
diff changeset
1350 calloc that are decorated with a two-argument attribute alloc_size. */
kono
parents: 67
diff changeset
1351
kono
parents: 67
diff changeset
1352 void
kono
parents: 67
diff changeset
1353 maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2])
kono
parents: 67
diff changeset
1354 {
kono
parents: 67
diff changeset
1355 /* The range each of the (up to) two arguments is known to be in. */
kono
parents: 67
diff changeset
1356 tree argrange[2][2] = { { NULL_TREE, NULL_TREE }, { NULL_TREE, NULL_TREE } };
kono
parents: 67
diff changeset
1357
kono
parents: 67
diff changeset
1358 /* Maximum object size set by -Walloc-size-larger-than= or SIZE_MAX / 2. */
kono
parents: 67
diff changeset
1359 tree maxobjsize = alloc_max_size ();
kono
parents: 67
diff changeset
1360
kono
parents: 67
diff changeset
1361 location_t loc = EXPR_LOCATION (exp);
kono
parents: 67
diff changeset
1362
kono
parents: 67
diff changeset
1363 bool warned = false;
kono
parents: 67
diff changeset
1364
kono
parents: 67
diff changeset
1365 /* Validate each argument individually. */
kono
parents: 67
diff changeset
1366 for (unsigned i = 0; i != 2 && args[i]; ++i)
kono
parents: 67
diff changeset
1367 {
kono
parents: 67
diff changeset
1368 if (TREE_CODE (args[i]) == INTEGER_CST)
kono
parents: 67
diff changeset
1369 {
kono
parents: 67
diff changeset
1370 argrange[i][0] = args[i];
kono
parents: 67
diff changeset
1371 argrange[i][1] = args[i];
kono
parents: 67
diff changeset
1372
kono
parents: 67
diff changeset
1373 if (tree_int_cst_lt (args[i], integer_zero_node))
kono
parents: 67
diff changeset
1374 {
kono
parents: 67
diff changeset
1375 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
kono
parents: 67
diff changeset
1376 "%Kargument %i value %qE is negative",
kono
parents: 67
diff changeset
1377 exp, idx[i] + 1, args[i]);
kono
parents: 67
diff changeset
1378 }
kono
parents: 67
diff changeset
1379 else if (integer_zerop (args[i]))
kono
parents: 67
diff changeset
1380 {
kono
parents: 67
diff changeset
1381 /* Avoid issuing -Walloc-zero for allocation functions other
kono
parents: 67
diff changeset
1382 than __builtin_alloca that are declared with attribute
kono
parents: 67
diff changeset
1383 returns_nonnull because there's no portability risk. This
kono
parents: 67
diff changeset
1384 avoids warning for such calls to libiberty's xmalloc and
kono
parents: 67
diff changeset
1385 friends.
kono
parents: 67
diff changeset
1386 Also avoid issuing the warning for calls to function named
kono
parents: 67
diff changeset
1387 "alloca". */
kono
parents: 67
diff changeset
1388 if ((DECL_FUNCTION_CODE (fn) == BUILT_IN_ALLOCA
kono
parents: 67
diff changeset
1389 && IDENTIFIER_LENGTH (DECL_NAME (fn)) != 6)
kono
parents: 67
diff changeset
1390 || (DECL_FUNCTION_CODE (fn) != BUILT_IN_ALLOCA
kono
parents: 67
diff changeset
1391 && !lookup_attribute ("returns_nonnull",
kono
parents: 67
diff changeset
1392 TYPE_ATTRIBUTES (TREE_TYPE (fn)))))
kono
parents: 67
diff changeset
1393 warned = warning_at (loc, OPT_Walloc_zero,
kono
parents: 67
diff changeset
1394 "%Kargument %i value is zero",
kono
parents: 67
diff changeset
1395 exp, idx[i] + 1);
kono
parents: 67
diff changeset
1396 }
kono
parents: 67
diff changeset
1397 else if (tree_int_cst_lt (maxobjsize, args[i]))
kono
parents: 67
diff changeset
1398 {
kono
parents: 67
diff changeset
1399 /* G++ emits calls to ::operator new[](SIZE_MAX) in C++98
kono
parents: 67
diff changeset
1400 mode and with -fno-exceptions as a way to indicate array
kono
parents: 67
diff changeset
1401 size overflow. There's no good way to detect C++98 here
kono
parents: 67
diff changeset
1402 so avoid diagnosing these calls for all C++ modes. */
kono
parents: 67
diff changeset
1403 if (i == 0
kono
parents: 67
diff changeset
1404 && !args[1]
kono
parents: 67
diff changeset
1405 && lang_GNU_CXX ()
kono
parents: 67
diff changeset
1406 && DECL_IS_OPERATOR_NEW (fn)
kono
parents: 67
diff changeset
1407 && integer_all_onesp (args[i]))
kono
parents: 67
diff changeset
1408 continue;
kono
parents: 67
diff changeset
1409
kono
parents: 67
diff changeset
1410 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
kono
parents: 67
diff changeset
1411 "%Kargument %i value %qE exceeds "
kono
parents: 67
diff changeset
1412 "maximum object size %E",
kono
parents: 67
diff changeset
1413 exp, idx[i] + 1, args[i], maxobjsize);
kono
parents: 67
diff changeset
1414 }
kono
parents: 67
diff changeset
1415 }
kono
parents: 67
diff changeset
1416 else if (TREE_CODE (args[i]) == SSA_NAME
kono
parents: 67
diff changeset
1417 && get_size_range (args[i], argrange[i]))
kono
parents: 67
diff changeset
1418 {
kono
parents: 67
diff changeset
1419 /* Verify that the argument's range is not negative (including
kono
parents: 67
diff changeset
1420 upper bound of zero). */
kono
parents: 67
diff changeset
1421 if (tree_int_cst_lt (argrange[i][0], integer_zero_node)
kono
parents: 67
diff changeset
1422 && tree_int_cst_le (argrange[i][1], integer_zero_node))
kono
parents: 67
diff changeset
1423 {
kono
parents: 67
diff changeset
1424 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
kono
parents: 67
diff changeset
1425 "%Kargument %i range [%E, %E] is negative",
kono
parents: 67
diff changeset
1426 exp, idx[i] + 1,
kono
parents: 67
diff changeset
1427 argrange[i][0], argrange[i][1]);
kono
parents: 67
diff changeset
1428 }
kono
parents: 67
diff changeset
1429 else if (tree_int_cst_lt (maxobjsize, argrange[i][0]))
kono
parents: 67
diff changeset
1430 {
kono
parents: 67
diff changeset
1431 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
kono
parents: 67
diff changeset
1432 "%Kargument %i range [%E, %E] exceeds "
kono
parents: 67
diff changeset
1433 "maximum object size %E",
kono
parents: 67
diff changeset
1434 exp, idx[i] + 1,
kono
parents: 67
diff changeset
1435 argrange[i][0], argrange[i][1],
kono
parents: 67
diff changeset
1436 maxobjsize);
kono
parents: 67
diff changeset
1437 }
kono
parents: 67
diff changeset
1438 }
kono
parents: 67
diff changeset
1439 }
kono
parents: 67
diff changeset
1440
kono
parents: 67
diff changeset
1441 if (!argrange[0])
kono
parents: 67
diff changeset
1442 return;
kono
parents: 67
diff changeset
1443
kono
parents: 67
diff changeset
1444 /* For a two-argument alloc_size, validate the product of the two
kono
parents: 67
diff changeset
1445 arguments if both of their values or ranges are known. */
kono
parents: 67
diff changeset
1446 if (!warned && tree_fits_uhwi_p (argrange[0][0])
kono
parents: 67
diff changeset
1447 && argrange[1][0] && tree_fits_uhwi_p (argrange[1][0])
kono
parents: 67
diff changeset
1448 && !integer_onep (argrange[0][0])
kono
parents: 67
diff changeset
1449 && !integer_onep (argrange[1][0]))
kono
parents: 67
diff changeset
1450 {
kono
parents: 67
diff changeset
1451 /* Check for overflow in the product of a function decorated with
kono
parents: 67
diff changeset
1452 attribute alloc_size (X, Y). */
kono
parents: 67
diff changeset
1453 unsigned szprec = TYPE_PRECISION (size_type_node);
kono
parents: 67
diff changeset
1454 wide_int x = wi::to_wide (argrange[0][0], szprec);
kono
parents: 67
diff changeset
1455 wide_int y = wi::to_wide (argrange[1][0], szprec);
kono
parents: 67
diff changeset
1456
kono
parents: 67
diff changeset
1457 bool vflow;
kono
parents: 67
diff changeset
1458 wide_int prod = wi::umul (x, y, &vflow);
kono
parents: 67
diff changeset
1459
kono
parents: 67
diff changeset
1460 if (vflow)
kono
parents: 67
diff changeset
1461 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
kono
parents: 67
diff changeset
1462 "%Kproduct %<%E * %E%> of arguments %i and %i "
kono
parents: 67
diff changeset
1463 "exceeds %<SIZE_MAX%>",
kono
parents: 67
diff changeset
1464 exp, argrange[0][0], argrange[1][0],
kono
parents: 67
diff changeset
1465 idx[0] + 1, idx[1] + 1);
kono
parents: 67
diff changeset
1466 else if (wi::ltu_p (wi::to_wide (maxobjsize, szprec), prod))
kono
parents: 67
diff changeset
1467 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
kono
parents: 67
diff changeset
1468 "%Kproduct %<%E * %E%> of arguments %i and %i "
kono
parents: 67
diff changeset
1469 "exceeds maximum object size %E",
kono
parents: 67
diff changeset
1470 exp, argrange[0][0], argrange[1][0],
kono
parents: 67
diff changeset
1471 idx[0] + 1, idx[1] + 1,
kono
parents: 67
diff changeset
1472 maxobjsize);
kono
parents: 67
diff changeset
1473
kono
parents: 67
diff changeset
1474 if (warned)
kono
parents: 67
diff changeset
1475 {
kono
parents: 67
diff changeset
1476 /* Print the full range of each of the two arguments to make
kono
parents: 67
diff changeset
1477 it clear when it is, in fact, in a range and not constant. */
kono
parents: 67
diff changeset
1478 if (argrange[0][0] != argrange [0][1])
kono
parents: 67
diff changeset
1479 inform (loc, "argument %i in the range [%E, %E]",
kono
parents: 67
diff changeset
1480 idx[0] + 1, argrange[0][0], argrange[0][1]);
kono
parents: 67
diff changeset
1481 if (argrange[1][0] != argrange [1][1])
kono
parents: 67
diff changeset
1482 inform (loc, "argument %i in the range [%E, %E]",
kono
parents: 67
diff changeset
1483 idx[1] + 1, argrange[1][0], argrange[1][1]);
kono
parents: 67
diff changeset
1484 }
kono
parents: 67
diff changeset
1485 }
kono
parents: 67
diff changeset
1486
kono
parents: 67
diff changeset
1487 if (warned)
kono
parents: 67
diff changeset
1488 {
kono
parents: 67
diff changeset
1489 location_t fnloc = DECL_SOURCE_LOCATION (fn);
kono
parents: 67
diff changeset
1490
kono
parents: 67
diff changeset
1491 if (DECL_IS_BUILTIN (fn))
kono
parents: 67
diff changeset
1492 inform (loc,
kono
parents: 67
diff changeset
1493 "in a call to built-in allocation function %qD", fn);
kono
parents: 67
diff changeset
1494 else
kono
parents: 67
diff changeset
1495 inform (fnloc,
kono
parents: 67
diff changeset
1496 "in a call to allocation function %qD declared here", fn);
kono
parents: 67
diff changeset
1497 }
kono
parents: 67
diff changeset
1498 }
kono
parents: 67
diff changeset
1499
kono
parents: 67
diff changeset
1500 /* Issue an error if CALL_EXPR was flagged as requiring
kono
parents: 67
diff changeset
1501 tall-call optimization. */
kono
parents: 67
diff changeset
1502
kono
parents: 67
diff changeset
1503 static void
kono
parents: 67
diff changeset
1504 maybe_complain_about_tail_call (tree call_expr, const char *reason)
kono
parents: 67
diff changeset
1505 {
kono
parents: 67
diff changeset
1506 gcc_assert (TREE_CODE (call_expr) == CALL_EXPR);
kono
parents: 67
diff changeset
1507 if (!CALL_EXPR_MUST_TAIL_CALL (call_expr))
kono
parents: 67
diff changeset
1508 return;
kono
parents: 67
diff changeset
1509
kono
parents: 67
diff changeset
1510 error_at (EXPR_LOCATION (call_expr), "cannot tail-call: %s", reason);
kono
parents: 67
diff changeset
1511 }
kono
parents: 67
diff changeset
1512
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1513 /* Fill in ARGS_SIZE and ARGS array based on the parameters found in
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1514 CALL_EXPR EXP.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1515
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1516 NUM_ACTUALS is the total number of parameters.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1517
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1518 N_NAMED_ARGS is the total number of named arguments.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1519
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1520 STRUCT_VALUE_ADDR_VALUE is the implicit argument for a struct return
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1521 value, or null.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1522
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1523 FNDECL is the tree code for the target of this call (if known)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1524
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1525 ARGS_SO_FAR holds state needed by the target to know where to place
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1526 the next argument.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1527
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1528 REG_PARM_STACK_SPACE is the number of bytes of stack space reserved
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1529 for arguments which are passed in registers.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1530
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1531 OLD_STACK_LEVEL is a pointer to an rtx which olds the old stack level
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1532 and may be modified by this routine.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1533
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1534 OLD_PENDING_ADJ, MUST_PREALLOCATE and FLAGS are pointers to integer
111
kono
parents: 67
diff changeset
1535 flags which may be modified by this routine.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1536
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1537 MAY_TAILCALL is cleared if we encounter an invisible pass-by-reference
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1538 that requires allocation of stack space.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1539
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1540 CALL_FROM_THUNK_P is true if this call is the jump from a thunk to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1541 the thunked-to function. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1542
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1543 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1544 initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1545 struct arg_data *args,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1546 struct args_size *args_size,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1547 int n_named_args ATTRIBUTE_UNUSED,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1548 tree exp, tree struct_value_addr_value,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1549 tree fndecl, tree fntype,
111
kono
parents: 67
diff changeset
1550 cumulative_args_t args_so_far,
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1551 int reg_parm_stack_space,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1552 rtx *old_stack_level, int *old_pending_adj,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1553 int *must_preallocate, int *ecf_flags,
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1554 bool *may_tailcall, bool call_from_thunk_p)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1555 {
111
kono
parents: 67
diff changeset
1556 CUMULATIVE_ARGS *args_so_far_pnt = get_cumulative_args (args_so_far);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1557 location_t loc = EXPR_LOCATION (exp);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1558
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1559 /* Count arg position in order args appear. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1560 int argpos;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1561
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1562 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1563
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1564 args_size->constant = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1565 args_size->var = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1566
111
kono
parents: 67
diff changeset
1567 bitmap_obstack_initialize (NULL);
kono
parents: 67
diff changeset
1568
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1569 /* In this loop, we consider args in the order they are written.
111
kono
parents: 67
diff changeset
1570 We fill up ARGS from the back. */
kono
parents: 67
diff changeset
1571
kono
parents: 67
diff changeset
1572 i = num_actuals - 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1573 {
111
kono
parents: 67
diff changeset
1574 int j = i, ptr_arg = -1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1575 call_expr_arg_iterator iter;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1576 tree arg;
111
kono
parents: 67
diff changeset
1577 bitmap slots = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1578
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1579 if (struct_value_addr_value)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1580 {
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1581 args[j].tree_value = struct_value_addr_value;
111
kono
parents: 67
diff changeset
1582 j--;
kono
parents: 67
diff changeset
1583
kono
parents: 67
diff changeset
1584 /* If we pass structure address then we need to
kono
parents: 67
diff changeset
1585 create bounds for it. Since created bounds is
kono
parents: 67
diff changeset
1586 a call statement, we expand it right here to avoid
kono
parents: 67
diff changeset
1587 fixing all other places where it may be expanded. */
kono
parents: 67
diff changeset
1588 if (CALL_WITH_BOUNDS_P (exp))
kono
parents: 67
diff changeset
1589 {
kono
parents: 67
diff changeset
1590 args[j].value = gen_reg_rtx (targetm.chkp_bound_mode ());
kono
parents: 67
diff changeset
1591 args[j].tree_value
kono
parents: 67
diff changeset
1592 = chkp_make_bounds_for_struct_addr (struct_value_addr_value);
kono
parents: 67
diff changeset
1593 expand_expr_real (args[j].tree_value, args[j].value, VOIDmode,
kono
parents: 67
diff changeset
1594 EXPAND_NORMAL, 0, false);
kono
parents: 67
diff changeset
1595 args[j].pointer_arg = j + 1;
kono
parents: 67
diff changeset
1596 j--;
kono
parents: 67
diff changeset
1597 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1598 }
111
kono
parents: 67
diff changeset
1599 argpos = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1600 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1601 {
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1602 tree argtype = TREE_TYPE (arg);
111
kono
parents: 67
diff changeset
1603
kono
parents: 67
diff changeset
1604 /* Remember last param with pointer and associate it
kono
parents: 67
diff changeset
1605 with following pointer bounds. */
kono
parents: 67
diff changeset
1606 if (CALL_WITH_BOUNDS_P (exp)
kono
parents: 67
diff changeset
1607 && chkp_type_has_pointer (argtype))
kono
parents: 67
diff changeset
1608 {
kono
parents: 67
diff changeset
1609 if (slots)
kono
parents: 67
diff changeset
1610 BITMAP_FREE (slots);
kono
parents: 67
diff changeset
1611 ptr_arg = j;
kono
parents: 67
diff changeset
1612 if (!BOUNDED_TYPE_P (argtype))
kono
parents: 67
diff changeset
1613 {
kono
parents: 67
diff changeset
1614 slots = BITMAP_ALLOC (NULL);
kono
parents: 67
diff changeset
1615 chkp_find_bound_slots (argtype, slots);
kono
parents: 67
diff changeset
1616 }
kono
parents: 67
diff changeset
1617 }
kono
parents: 67
diff changeset
1618 else if (CALL_WITH_BOUNDS_P (exp)
kono
parents: 67
diff changeset
1619 && pass_by_reference (NULL, TYPE_MODE (argtype), argtype,
kono
parents: 67
diff changeset
1620 argpos < n_named_args))
kono
parents: 67
diff changeset
1621 {
kono
parents: 67
diff changeset
1622 if (slots)
kono
parents: 67
diff changeset
1623 BITMAP_FREE (slots);
kono
parents: 67
diff changeset
1624 ptr_arg = j;
kono
parents: 67
diff changeset
1625 }
kono
parents: 67
diff changeset
1626 else if (POINTER_BOUNDS_TYPE_P (argtype))
kono
parents: 67
diff changeset
1627 {
kono
parents: 67
diff changeset
1628 /* We expect bounds in instrumented calls only.
kono
parents: 67
diff changeset
1629 Otherwise it is a sign we lost flag due to some optimization
kono
parents: 67
diff changeset
1630 and may emit call args incorrectly. */
kono
parents: 67
diff changeset
1631 gcc_assert (CALL_WITH_BOUNDS_P (exp));
kono
parents: 67
diff changeset
1632
kono
parents: 67
diff changeset
1633 /* For structures look for the next available pointer. */
kono
parents: 67
diff changeset
1634 if (ptr_arg != -1 && slots)
kono
parents: 67
diff changeset
1635 {
kono
parents: 67
diff changeset
1636 unsigned bnd_no = bitmap_first_set_bit (slots);
kono
parents: 67
diff changeset
1637 args[j].pointer_offset =
kono
parents: 67
diff changeset
1638 bnd_no * POINTER_SIZE / BITS_PER_UNIT;
kono
parents: 67
diff changeset
1639
kono
parents: 67
diff changeset
1640 bitmap_clear_bit (slots, bnd_no);
kono
parents: 67
diff changeset
1641
kono
parents: 67
diff changeset
1642 /* Check we have no more pointers in the structure. */
kono
parents: 67
diff changeset
1643 if (bitmap_empty_p (slots))
kono
parents: 67
diff changeset
1644 BITMAP_FREE (slots);
kono
parents: 67
diff changeset
1645 }
kono
parents: 67
diff changeset
1646 args[j].pointer_arg = ptr_arg;
kono
parents: 67
diff changeset
1647
kono
parents: 67
diff changeset
1648 /* Check we covered all pointers in the previous
kono
parents: 67
diff changeset
1649 non bounds arg. */
kono
parents: 67
diff changeset
1650 if (!slots)
kono
parents: 67
diff changeset
1651 ptr_arg = -1;
kono
parents: 67
diff changeset
1652 }
kono
parents: 67
diff changeset
1653 else
kono
parents: 67
diff changeset
1654 ptr_arg = -1;
kono
parents: 67
diff changeset
1655
70
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1656 if (targetm.calls.split_complex_arg
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1657 && argtype
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1658 && TREE_CODE (argtype) == COMPLEX_TYPE
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1659 && targetm.calls.split_complex_arg (argtype))
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1660 {
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1661 tree subtype = TREE_TYPE (argtype);
b81903832de2 merge c-decl.c
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 69
diff changeset
1662 args[j].tree_value = build1 (REALPART_EXPR, subtype, arg);
111
kono
parents: 67