annotate gcc/cbc-goto.h @ 21:959d4c8c8abc

add conv.c conv1.c
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Tue, 29 Sep 2009 20:15:16 +0900
parents 7ff9aed93de8
children 2476ed92181e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 static void
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 preexpand_argument_expr (struct arg_data *, int);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 static void
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 determine_order(int *, int);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 static int
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 expand_one_arg_push (struct arg_data *, rtx, int, int, int);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 static void
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 push_overlaps(struct arg_data *, int);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 static int
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 check_frame_offset(rtx);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 static rtx
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 expand_cbc_goto (tree exp, rtx target, tree fndecl, tree funtype, tree fntype,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 tree addr,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 int ignore,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 int flags,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 int num_actuals,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 struct arg_data *args,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 struct args_size *args_size,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 CUMULATIVE_ARGS args_so_far,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 rtx old_stack_level,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 int reg_parm_stack_space,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 int old_pending_adj,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 unsigned HOST_WIDE_INT preferred_stack_boundary,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 unsigned HOST_WIDE_INT preferred_unit_stack_boundary,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 rtx structure_value_addr,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 //int structure_value_addr_parm,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 int old_inhibit_defer_pop
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 )
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 /* folowing variables is just copied from expand_call. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 int pass = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 int i;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 #ifdef REG_PARM_STACK_SPACE
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 /* Define the boundary of the register parm stack space that needs to be
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 saved, if any. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 #endif
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 rtx funexp;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 rtx valreg;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 struct args_size adjusted_args_size;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 int unadjusted_args_size;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 int reg_parm_seen;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 rtx static_chain_value;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 int old_stack_allocated;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 int old_stack_pointer_delta = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 int old_stack_arg_under_construction = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 rtx call_fusage;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 char *stack_usage_map_buf = NULL;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 rtx argblock = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 HOST_WIDE_INT struct_value_size = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 int pcc_struct_value = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 int initial_highest_arg_in_use = highest_outgoing_arg_in_use;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 char *initial_stack_usage_map = stack_usage_map;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 rtx tail_call_insns = NULL_RTX;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 int *store_order;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 int sibcall_failure = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 /* We want to emit any pending stack adjustments before the tail
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 recursion "call". That way we know any adjustment after the tail
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 recursion call can be ignored if we indeed use the tail
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 call expansion. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 int save_pending_stack_adjust = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 int save_stack_pointer_delta = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 rtx insns;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 rtx before_call, next_arg_reg;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 /* State variables we need to save and restore between
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 iterations. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 save_pending_stack_adjust = pending_stack_adjust;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 save_stack_pointer_delta = stack_pointer_delta;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 flags |= ECF_SIBCALL;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 /* Other state variables that we must reinitialize each time
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 through the loop (that are not initialized by the loop itself). */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 argblock = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 call_fusage = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 /* Start a new sequence for the normal call case.
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 From this point on, if the sibling call fails, we want to set
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 sibcall_failure instead of continuing the loop. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 start_sequence ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 /* Don't let pending stack adjusts add up to too much.
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 Also, do all pending adjustments now if there is any chance
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 this might be a call to alloca or if we are expanding a sibling
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 call sequence or if we are calling a function that is to return
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 with stack pointer depressed.
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 Also do the adjustments before a throwing call, otherwise
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 exception handling can fail; PR 19225. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 if (pending_stack_adjust >= 32
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 || (pending_stack_adjust > 0
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 && (flags & ECF_MAY_BE_ALLOCA))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 || (pending_stack_adjust > 0
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 && flag_exceptions && !(flags & ECF_NOTHROW))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 || pass == 0)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 do_pending_stack_adjust ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 if (pass == 0 && crtl->stack_protect_guard)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 stack_protect_epilogue ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 adjusted_args_size = *args_size;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 /* Compute the actual size of the argument block required. The variable
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 and constant sizes must be combined, the size may have to be rounded,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 and there may be a minimum required size. When generating a sibcall
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 pattern, do not round up, since we'll be re-using whatever space our
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 caller provided. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 unadjusted_args_size
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 = compute_argument_block_size (reg_parm_stack_space,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 &adjusted_args_size,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 fndecl, fntype,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 (pass == 0 ? 0
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 : preferred_stack_boundary));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 old_stack_allocated = stack_pointer_delta - pending_stack_adjust;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 argblock = crtl->args.internal_arg_pointer;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 argblock
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 #ifdef STACK_GROWS_DOWNWARD
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 = plus_constant (argblock, crtl->args.pretend_args_size);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 #else
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 = plus_constant (argblock, -crtl->args.pretend_args_size);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 #endif
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 stored_args_map = sbitmap_alloc (args_size->constant);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 sbitmap_zero (stored_args_map);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 if (ACCUMULATE_OUTGOING_ARGS)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 /* The save/restore code in store_one_arg handles all
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 cases except one: a constructor call (including a C
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 function returning a BLKmode struct) to initialize
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 an argument. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 if (stack_arg_under_construction)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 rtx push_size
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 = GEN_INT (adjusted_args_size.constant
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 + (OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 : TREE_TYPE (fndecl))) ? 0
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 : reg_parm_stack_space));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 if (old_stack_level == 0)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 emit_stack_save (SAVE_BLOCK, &old_stack_level,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 NULL_RTX);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 old_stack_pointer_delta = stack_pointer_delta;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 old_pending_adj = pending_stack_adjust;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
162 pending_stack_adjust = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 /* stack_arg_under_construction says whether a stack
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
164 arg is being constructed at the old stack level.
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 Pushing the stack gets a clean outgoing argument
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 block. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 old_stack_arg_under_construction
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 = stack_arg_under_construction;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
169 stack_arg_under_construction = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 /* Make a new map for the new argument list. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
171 if (stack_usage_map_buf)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 free (stack_usage_map_buf);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
173 stack_usage_map_buf = XNEWVEC (char, highest_outgoing_arg_in_use);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 stack_usage_map = stack_usage_map_buf;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 memset (stack_usage_map, 0, highest_outgoing_arg_in_use);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 highest_outgoing_arg_in_use = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
178 allocate_dynamic_stack_space (push_size, NULL_RTX,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
179 BITS_PER_UNIT);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
180 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
181
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 /* If argument evaluation might modify the stack pointer,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
183 copy the address of the argument list to a register. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 for (i = 0; i < num_actuals; i++)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 if (args[i].pass_on_stack)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 argblock = copy_addr_to_reg (argblock);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
188 break;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
191
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
192 compute_argument_addresses (args, argblock, num_actuals);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 /* in the case that
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 a function goto codesegment.
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 adjust stack space. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 if ( !CbC_IS_CODE_SEGMENT(TREE_TYPE(current_function_decl)) )
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
198 //if ( !(current_function_decl&&CbC_IS_CODE_SEGMENT(current_function_decl)) )
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 HOST_WIDE_INT padding;
21
959d4c8c8abc add conv.c conv1.c
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents: 7
diff changeset
201 padding = CbC_PRETENDED_STACK_SIZE -
3
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
202 (crtl->args.size - crtl->args.pretend_args_size);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 if (0&&padding > 0)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 anti_adjust_stack (GEN_INT (padding));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
206
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
207 /* Now that the stack is properly aligned, pops can't safely
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 be deferred during the evaluation of the arguments. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 NO_DEFER_POP;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
210
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 funexp = rtx_for_function_call (fndecl, addr);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 /* Figure out the register where the value, if any, will come back. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
214 valreg = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
215
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
216
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 /* Precompute all register parameters. It isn't safe to compute anything
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
218 once we have started filling any specific hard regs. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
219 precompute_register_parameters (num_actuals, args, &reg_parm_seen);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
220
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 /* operand[2] is environment. */
7
7ff9aed93de8 partially written goto with env...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
222 if (TREE_OPERAND (exp, 2))
7ff9aed93de8 partially written goto with env...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
223 static_chain_value = expand_normal (TREE_OPERAND (exp, 2));
7ff9aed93de8 partially written goto with env...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
224 else
3
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 static_chain_value = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
226
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
227
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
228 /* parallel assignment */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
229 store_order = alloca (num_actuals * sizeof (int));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 memset (store_order, 0, num_actuals * sizeof (int));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
231
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
232 /* fill the arg[i]->exprs. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 for (i = 0; i < num_actuals; i++)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
235 if (args[i].reg == 0 || args[i].pass_on_stack)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
236 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
237 preexpand_argument_expr (&args[i],
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 adjusted_args_size.var != 0);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
240 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
241
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
242
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 /* push overlapped argument to stack. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
244 push_overlaps(args, num_actuals);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
245
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 /* determine ordering to store arguments.
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 and generate RTL that store some variable temporary, if it needed.*/
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 /* now... this function do nothing. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
249 determine_order(store_order, num_actuals);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
250
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
251 /* push arguments in the order . */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
252 for (i = 0; i < num_actuals; i++)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 if (args[store_order[i]].reg == 0
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 || args[store_order[i]].pass_on_stack
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 || args[store_order[i]].partial!=0 )
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
258 expand_one_arg_push (&args[store_order[i]], argblock, flags,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
259 adjusted_args_size.var != 0,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
260 reg_parm_stack_space);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
261 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
262 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
263
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
264
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
265 /* If register arguments require space on the stack and stack space
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
266 was not preallocated, allocate stack space here for arguments
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
267 passed in registers. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
268 #ifdef OUTGOING_REG_PARM_STACK_SPACE
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
269 //if (!ACCUMULATE_OUTGOING_ARGS
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
270 //&& must_preallocate == 0 && reg_parm_stack_space > 0)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
271 //anti_adjust_stack (GEN_INT (reg_parm_stack_space));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
272 #endif
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
273
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
274 /* */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
275 funexp = prepare_call_address (funexp, static_chain_value,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
276 &call_fusage, reg_parm_seen, pass == 0);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
277
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
278 /* store args into register. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
279 load_register_parameters (args, num_actuals, &call_fusage, flags,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
280 //pass == 0, &sibcall_failure);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
281 0, NULL);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
282
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
283 /* Save a pointer to the last insn before the call, so that we can
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
284 later safely search backwards to find the CALL_INSN. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
285 before_call = get_last_insn ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
286
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
287 /* Set up next argument register. For sibling calls on machines
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
288 with register windows this should be the incoming register. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
289 #ifdef FUNCTION_INCOMING_ARG
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
290 if (pass == 0)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 next_arg_reg = FUNCTION_INCOMING_ARG (args_so_far, VOIDmode,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
292 void_type_node, 1);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
293 else
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
294 #endif
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
296 void_type_node, 1);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 /* All arguments and registers used for the call must be set up by
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 now! */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
300
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
301 /* Stack must be properly aligned now. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
302 gcc_assert (!pass
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
303 || !(stack_pointer_delta % preferred_unit_stack_boundary));
7
7ff9aed93de8 partially written goto with env...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
304 #if 0
3
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
305 /* store environment. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
306 if ( env_tree!=NULL )
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
307 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
308 emit_insn (gen_rtx_CLOBBER (VOIDmode,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
309 gen_rtx_MEM (BLKmode,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
310 hard_frame_pointer_rtx)));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
311 emit_move_insn (hard_frame_pointer_rtx, env_rtx);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
312 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
313 //pop_temp_slots ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
314
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
315 emit_indirect_jump (funexp);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
316 }
7
7ff9aed93de8 partially written goto with env...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 6
diff changeset
317 #endif
3
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
318
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
319 /* Generate the actual call instruction. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
320 emit_call_1 (funexp, exp, fndecl, funtype, unadjusted_args_size,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
321 adjusted_args_size.constant, struct_value_size,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
322 //next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
323 next_arg_reg, valreg, 0, call_fusage,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 flags, & args_so_far);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
325
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
326 /* If a non-BLKmode value is returned at the most significant end
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
327 of a register, shift the register right by the appropriate amount
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
328 and update VALREG accordingly. BLKmode values are handled by the
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
329 group load/store machinery below. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
330 if (!structure_value_addr
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
331 && !pcc_struct_value
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
332 && TYPE_MODE (TREE_TYPE (exp)) != BLKmode
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
333 && targetm.calls.return_in_msb (TREE_TYPE (exp)))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
334 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
335 if (shift_return_value (TYPE_MODE (TREE_TYPE (exp)), false, valreg))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
336 sibcall_failure = 1;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
337 valreg = gen_rtx_REG (TYPE_MODE (TREE_TYPE (exp)), REGNO (valreg));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
338 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
339
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
340
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
341 /* For calls to `setjmp', etc., inform flow.c it should complain
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
342 if nonvolatile values are live. For functions that cannot return,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
343 inform flow that control does not fall through. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
344
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
345 if ((flags & ECF_NORETURN) || pass == 0)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
346 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
347 /* The barrier must be emitted
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
348 immediately after the CALL_INSN. Some ports emit more
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
349 than just a CALL_INSN above, so we must search for it here. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
350
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
351 rtx last = get_last_insn ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 while (!CALL_P (last))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
353 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
354 last = PREV_INSN (last);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
355 /* There was no CALL_INSN? */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
356 gcc_assert (last != before_call);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
357 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
358
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
359 emit_barrier_after (last);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
360
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
361 /* Stack adjustments after a noreturn call are dead code.
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
362 However when NO_DEFER_POP is in effect, we must preserve
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
363 stack_pointer_delta. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
364 if (inhibit_defer_pop == 0)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
365 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
366 stack_pointer_delta = old_stack_allocated;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
367 pending_stack_adjust = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
368 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
369 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
370
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
371 /* If value type not void, return an rtx for the value. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
372
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
373 if (TYPE_MODE (TREE_TYPE (exp)) == VOIDmode
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
374 || ignore)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
375 target = const0_rtx;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
376
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
377 if (targetm.calls.promote_function_return(funtype))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
378 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
379 /* If we promoted this return value, make the proper SUBREG.
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
380 TARGET might be const0_rtx here, so be careful. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
381 if (REG_P (target)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
382 && TYPE_MODE (TREE_TYPE (exp)) != BLKmode
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
383 && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
384 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
385 tree type = TREE_TYPE (exp);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
386 int unsignedp = TYPE_UNSIGNED (type);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
387 int offset = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
388 enum machine_mode pmode;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
389
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
390 pmode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
391 /* If we don't promote as expected, something is wrong. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
392 gcc_assert (GET_MODE (target) == pmode);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
393
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
394 if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
395 && (GET_MODE_SIZE (GET_MODE (target))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
396 > GET_MODE_SIZE (TYPE_MODE (type))))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
397 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
398 offset = GET_MODE_SIZE (GET_MODE (target))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
399 - GET_MODE_SIZE (TYPE_MODE (type));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
400 if (! BYTES_BIG_ENDIAN)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
401 offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
402 else if (! WORDS_BIG_ENDIAN)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
403 offset %= UNITS_PER_WORD;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
404 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
405 target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
406 SUBREG_PROMOTED_VAR_P (target) = 1;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
407 SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
408 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
409 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
410
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
411 /* If size of args is variable or this was a constructor call for a stack
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
412 argument, restore saved stack-pointer value. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
413
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
414 if (old_stack_level)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
415 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
416 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
417 stack_pointer_delta = old_stack_pointer_delta;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
418 pending_stack_adjust = old_pending_adj;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
419 old_stack_allocated = stack_pointer_delta - pending_stack_adjust;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
420 stack_arg_under_construction = old_stack_arg_under_construction;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
421 highest_outgoing_arg_in_use = initial_highest_arg_in_use;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 stack_usage_map = initial_stack_usage_map;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
423 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
424
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
425 /* If this was alloca, record the new stack level for nonlocal gotos.
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
426 Check for the handler slots since we might not have a save area
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
427 for non-local gotos. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
428
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
429 if ((flags & ECF_MAY_BE_ALLOCA) && cfun->nonlocal_goto_save_area != 0)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
430 update_nonlocal_goto_save_area ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
431
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
432 /* Free up storage we no longer need. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
433 for (i = 0; i < num_actuals; ++i)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
434 if (args[i].aligned_regs)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
435 free (args[i].aligned_regs);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
436
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
437 insns = get_insns ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
438 end_sequence ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
439
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
440 tail_call_insns = insns;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
441
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
442 /* Restore the pending stack adjustment now that we have
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
443 finished generating the sibling call sequence. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
444
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
445 pending_stack_adjust = save_pending_stack_adjust;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
446 stack_pointer_delta = save_stack_pointer_delta;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
447
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
448 /* Prepare arg structure for next iteration. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
449 for (i = 0; i < num_actuals; i++)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
450 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
451 args[i].value = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
452 args[i].aligned_regs = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
453 args[i].stack = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
454 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
455
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
456 sbitmap_free (stored_args_map);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
457
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
458
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
459 emit_insn(tail_call_insns);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
460 crtl->tail_call_emit = true;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
461
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
462 return target;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
463 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
464
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
465
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
466 static void
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
467 preexpand_argument_expr (struct arg_data *arg,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 int variable_size ATTRIBUTE_UNUSED)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
469 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
470 tree pval = arg->tree_value;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
471 rtx reg = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
472 int partial = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
473
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
474 if (TREE_CODE (pval) == ERROR_MARK)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
475 return;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
476
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
477 /* Push a new temporary level for any temporaries we make for
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
478 this argument. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
479 push_temp_slots ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
480
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
481
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
482 /* If this isn't going to be placed on both the stack and in registers,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
483 set up the register and number of words. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
484 if (! arg->pass_on_stack)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
485 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
486 //if (flags & ECF_SIBCALL)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
487 reg = arg->tail_call_reg;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
488 //else
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
489 //reg = arg->reg;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
490 partial = arg->partial;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
491 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
492
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
493 /* Being passed entirely in a register. We shouldn't be called in
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
494 this case. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
495 gcc_assert (reg == 0 || partial != 0);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
496
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
497 /* If this arg needs special alignment, don't load the registers
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
498 here. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
499 if (arg->n_aligned_regs != 0)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
500 reg = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
501
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
502 /* Start a new sequence for the arg->exprs. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
503 start_sequence ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
504
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
505
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
506 if (arg->pass_on_stack)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
507 stack_arg_under_construction++;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
508
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
509 arg->value = expand_expr (pval,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
510 (partial
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
511 || TYPE_MODE (TREE_TYPE (pval)) != arg->mode)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
512 ? NULL_RTX : arg->stack,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
513 VOIDmode, EXPAND_STACK_PARM);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
514
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
515 /* If we are promoting object (or for any other reason) the mode
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
516 doesn't agree, convert the mode. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
517
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
518 if (arg->mode != TYPE_MODE (TREE_TYPE (pval)))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
519 arg->value = convert_modes (arg->mode, TYPE_MODE (TREE_TYPE (pval)),
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
520 arg->value, arg->unsignedp);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
521
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
522 if (arg->pass_on_stack)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
523 stack_arg_under_construction--;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
524
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
525 arg->exprs = get_insns ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
526 end_sequence ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
527
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
528 if (arg->exprs) emit_insn(arg->exprs);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
529
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
530 preserve_temp_slots (arg->value);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
531 pop_temp_slots ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
532
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
533 return ;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
534 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
535
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
536 static int
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
537 expand_one_arg_push (struct arg_data *arg, rtx argblock, int flags,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
538 int variable_size ATTRIBUTE_UNUSED, int reg_parm_stack_space)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
539 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
540 tree pval = arg->tree_value;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
541 int used = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
542 int i, lower_bound = 0, upper_bound = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
543 rtx reg = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
544 int partial = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
545
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
546 /* Push a new temporary level for any temporaries we make for
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
547 this argument. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
548 push_temp_slots ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
549
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
550
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
551 /* copy from store_one_arg. modify here after.*/
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
552 /* If this isn't going to be placed on both the stack and in registers,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
553 set up the register and number of words. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
554 if (! arg->pass_on_stack)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
555 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
556 //if (flags & ECF_SIBCALL)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
557 reg = arg->tail_call_reg;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
558 //else
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
559 //reg = arg->reg;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
560 partial = arg->partial;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
561 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
562 /* Being passed entirely in a register. We shouldn't be called in
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
563 this case. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
564 gcc_assert (reg == 0 || partial != 0);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
565 /* If this arg needs special alignment, don't load the registers
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
566 here. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
567 if (arg->n_aligned_regs != 0)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
568 reg = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
569
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
570
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
571
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
572
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
573 if (arg->value == arg->stack)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
574 /* If the value is already in the stack slot, we are done. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
575 ;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
576 else if (arg->mode != BLKmode)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
577 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
578 int size;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
579
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
580 /* Argument is a scalar, not entirely passed in registers.
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
581 (If part is passed in registers, arg->partial says how much
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
582 and emit_push_insn will take care of putting it there.)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
583
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
584 Push it, and if its size is less than the
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
585 amount of space allocated to it,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
586 also bump stack pointer by the additional space.
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
587 Note that in C the default argument promotions
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
588 will prevent such mismatches. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
589
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
590 size = GET_MODE_SIZE (arg->mode);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
591 /* Compute how much space the push instruction will push.
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
592 On many machines, pushing a byte will advance the stack
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
593 pointer by a halfword. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
594 #ifdef PUSH_ROUNDING
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
595 size = PUSH_ROUNDING (size);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
596 #endif
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
597 used = size;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
598
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
599 /* Compute how much space the argument should get:
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
600 round up to a multiple of the alignment for arguments. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
601 if (none != FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
602 used = (((size + PARM_BOUNDARY / BITS_PER_UNIT - 1)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
603 / (PARM_BOUNDARY / BITS_PER_UNIT))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
604 * (PARM_BOUNDARY / BITS_PER_UNIT));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
605
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
606 /* This isn't already where we want it on the stack, so put it there.
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
607 This can either be done with push or copy insns. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
608 emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
609 PARM_BOUNDARY, partial, reg, used - size, argblock,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
610 ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
611 ARGS_SIZE_RTX (arg->locate.alignment_pad));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
612
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
613 /* Unless this is a partially-in-register argument, the argument is now
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
614 in the stack. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
615 if (partial == 0)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
616 arg->value = arg->stack;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
617 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
618 else
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
619 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
620 /* BLKmode, at least partly to be pushed. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
621
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
622 unsigned int parm_align;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
623 int excess;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
624 rtx size_rtx;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
625
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
626 /* Pushing a nonscalar.
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
627 If part is passed in registers, PARTIAL says how much
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
628 and emit_push_insn will take care of putting it there. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
629
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
630 /* Round its size up to a multiple
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
631 of the allocation unit for arguments. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
632
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
633 if (arg->locate.size.var != 0)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
634 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
635 excess = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
636 size_rtx = ARGS_SIZE_RTX (arg->locate.size);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
637 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
638 else
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
639 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
640 /* PUSH_ROUNDING has no effect on us, because emit_push_insn
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
641 for BLKmode is careful to avoid it. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
642 excess = (arg->locate.size.constant
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
643 - int_size_in_bytes (TREE_TYPE (pval))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
644 + partial);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
645 size_rtx = expand_expr (size_in_bytes (TREE_TYPE (pval)),
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
646 NULL_RTX, TYPE_MODE (sizetype), 0);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
647 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
648
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
649 parm_align = arg->locate.boundary;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
650
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
651 /* When an argument is padded down, the block is aligned to
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
652 PARM_BOUNDARY, but the actual argument isn't. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
653 if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
654 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
655 if (arg->locate.size.var)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
656 parm_align = BITS_PER_UNIT;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
657 else if (excess)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
658 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
659 unsigned int excess_align = (excess & -excess) * BITS_PER_UNIT;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
660 parm_align = MIN (parm_align, excess_align);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
661 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
662 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
663
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
664 if ((flags & ECF_SIBCALL) && MEM_P (arg->value))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
665 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
666 /* emit_push_insn might not work properly if arg->value and
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
667 argblock + arg->locate.offset areas overlap. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
668 rtx x = arg->value;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
669 int i = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
670
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
671 if (XEXP (x, 0) == crtl->args.internal_arg_pointer
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
672 || (GET_CODE (XEXP (x, 0)) == PLUS
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
673 && XEXP (XEXP (x, 0), 0) ==
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
674 crtl->args.internal_arg_pointer
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
675 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
676 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
677 if (XEXP (x, 0) != crtl->args.internal_arg_pointer)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
678 i = INTVAL (XEXP (XEXP (x, 0), 1));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
679
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
680 /* expand_call should ensure this. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
681 gcc_assert (!arg->locate.offset.var
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
682 && GET_CODE (size_rtx) == CONST_INT);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
683 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
684 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
685
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
686 emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
687 parm_align, partial, reg, excess, argblock,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
688 ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
689 ARGS_SIZE_RTX (arg->locate.alignment_pad));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
690
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
691 /* Unless this is a partially-in-register argument, the argument is now
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
692 in the stack.
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
693
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
694 ??? Unlike the case above, in which we want the actual
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
695 address of the data, so that we can load it directly into a
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
696 register, here we want the address of the stack slot, so that
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
697 it's properly aligned for word-by-word copying or something
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
698 like that. It's not clear that this is always correct. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
699 if (partial == 0)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
700 arg->value = arg->stack_slot;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
701 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
702
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
703 if (arg->reg && GET_CODE (arg->reg) == PARALLEL)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
704 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
705 tree type = TREE_TYPE (arg->tree_value);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
706 arg->parallel_value
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
707 = emit_group_load_into_temps (arg->reg, arg->value, type,
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
708 int_size_in_bytes (type));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
709 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
710
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
711 /* Mark all slots this store used. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
712 if (ACCUMULATE_OUTGOING_ARGS && !(flags & ECF_SIBCALL)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
713 && argblock && ! variable_size && arg->stack)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
714 for (i = lower_bound; i < upper_bound; i++)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
715 stack_usage_map[i] = 1;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
716
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
717 /* Once we have pushed something, pops can't safely
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
718 be deferred during the rest of the arguments. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
719 NO_DEFER_POP;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
720
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
721 /* Free any temporary slots made in processing this argument. Show
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
722 that we might have taken the address of something and pushed that
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
723 as an operand. */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
724 preserve_temp_slots (NULL_RTX);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
725 free_temp_slots ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
726 pop_temp_slots ();
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
727
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
728 return 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
729 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
730
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
731 static void
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
732 determine_order(int *order, int num_actuals)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
733 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
734 int i;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
735 for (i=0; i<num_actuals; i++)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
736 order[i] = num_actuals-i-1;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
737 return;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
738 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
739
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
740 static void
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
741 push_overlaps(struct arg_data *args, int num_actuals)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
742 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
743 int i;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
744
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
745 for (i=0; i<num_actuals; i++)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
746 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
747 int dst_offset; /* */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
748 int src_offset; /* */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
749 rtx temp;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
750 if ( (dst_offset=check_frame_offset(args[i].stack)) < 0 ) continue;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
751 if ( (src_offset=check_frame_offset(args[i].value)) < 0 ) continue;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
752
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
753 /* 退避 */
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
754 temp = assign_temp(args[i].tree_value, 1, 0, 0);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
755 if ( args[i].mode==BLKmode )
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
756 emit_block_move ( temp, args[i].value, ARGS_SIZE_RTX(args[i].locate.size), 0 );
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
757 else
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
758 emit_move_insn ( temp, args[i].value );
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
759 args[i].value = temp;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
760
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
761 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
762 return;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
763 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
764
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
765 static int
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
766 check_frame_offset(rtx x)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
767 {
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
768 int i;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
769 rtx addr;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
770 if ( !x || !MEM_P(x))
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
771 return -1;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
772
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
773 addr = XEXP(x, 0);
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
774 if (addr == crtl->args.internal_arg_pointer)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
775 i = 0;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
776 else if (GET_CODE (addr) == PLUS
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
777 && XEXP (addr, 0) == crtl->args.internal_arg_pointer
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
778 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
779 i = INTVAL (XEXP (addr, 1));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
780 else if (GET_CODE (addr) == PLUS
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
781 && GET_CODE (XEXP (addr, 0)) == CONST_INT
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
782 && XEXP (addr, 1) == crtl->args.internal_arg_pointer )
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
783 i = INTVAL (XEXP (addr, 0));
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
784 else
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
785 return -1;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
786
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
787 return i;
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
788 }
d43292db8c8c finished merging
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
789