]>
Commit | Line | Data |
---|---|---|
535825e6 | 1 | /* Register to Stack convert for GNU compiler. |
9daf6266 | 2 | Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, |
33181afc | 3 | 1999, 2000, 2001, 2002 Free Software Foundation, Inc. |
535825e6 | 4 | |
f12b58b3 | 5 | This file is part of GCC. |
535825e6 | 6 | |
f12b58b3 | 7 | GCC is free software; you can redistribute it and/or modify it |
8 | under the terms of the GNU General Public License as published by | |
f3d96a58 | 9 | the Free Software Foundation; either version 2, or (at your option) |
10 | any later version. | |
535825e6 | 11 | |
f12b58b3 | 12 | GCC is distributed in the hope that it will be useful, but WITHOUT |
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
14 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
15 | License for more details. | |
535825e6 | 16 | |
f3d96a58 | 17 | You should have received a copy of the GNU General Public License |
f12b58b3 | 18 | along with GCC; see the file COPYING. If not, write to the Free |
19 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |
20 | 02111-1307, USA. */ | |
535825e6 | 21 | |
22 | /* This pass converts stack-like registers from the "flat register | |
23 | file" model that gcc uses, to a stack convention that the 387 uses. | |
24 | ||
25 | * The form of the input: | |
26 | ||
27 | On input, the function consists of insn that have had their | |
28 | registers fully allocated to a set of "virtual" registers. Note that | |
29 | the word "virtual" is used differently here than elsewhere in gcc: for | |
30 | each virtual stack reg, there is a hard reg, but the mapping between | |
31 | them is not known until this pass is run. On output, hard register | |
32 | numbers have been substituted, and various pop and exchange insns have | |
33 | been emitted. The hard register numbers and the virtual register | |
34 | numbers completely overlap - before this pass, all stack register | |
bed3e6b4 | 35 | numbers are virtual, and afterward they are all hard. |
535825e6 | 36 | |
37 | The virtual registers can be manipulated normally by gcc, and their | |
38 | semantics are the same as for normal registers. After the hard | |
39 | register numbers are substituted, the semantics of an insn containing | |
40 | stack-like regs are not the same as for an insn with normal regs: for | |
41 | instance, it is not safe to delete an insn that appears to be a no-op | |
42 | move. In general, no insn containing hard regs should be changed | |
43 | after this pass is done. | |
44 | ||
45 | * The form of the output: | |
46 | ||
47 | After this pass, hard register numbers represent the distance from | |
48 | the current top of stack to the desired register. A reference to | |
49 | FIRST_STACK_REG references the top of stack, FIRST_STACK_REG + 1, | |
50 | represents the register just below that, and so forth. Also, REG_DEAD | |
51 | notes indicate whether or not a stack register should be popped. | |
52 | ||
53 | A "swap" insn looks like a parallel of two patterns, where each | |
54 | pattern is a SET: one sets A to B, the other B to A. | |
55 | ||
56 | A "push" or "load" insn is a SET whose SET_DEST is FIRST_STACK_REG | |
57 | and whose SET_DEST is REG or MEM. Any other SET_DEST, such as PLUS, | |
58 | will replace the existing stack top, not push a new value. | |
59 | ||
60 | A store insn is a SET whose SET_DEST is FIRST_STACK_REG, and whose | |
61 | SET_SRC is REG or MEM. | |
62 | ||
fc738e1d | 63 | The case where the SET_SRC and SET_DEST are both FIRST_STACK_REG |
535825e6 | 64 | appears ambiguous. As a special case, the presence of a REG_DEAD note |
65 | for FIRST_STACK_REG differentiates between a load insn and a pop. | |
66 | ||
67 | If a REG_DEAD is present, the insn represents a "pop" that discards | |
68 | the top of the register stack. If there is no REG_DEAD note, then the | |
69 | insn represents a "dup" or a push of the current top of stack onto the | |
70 | stack. | |
71 | ||
72 | * Methodology: | |
73 | ||
74 | Existing REG_DEAD and REG_UNUSED notes for stack registers are | |
75 | deleted and recreated from scratch. REG_DEAD is never created for a | |
76 | SET_DEST, only REG_UNUSED. | |
77 | ||
bed3e6b4 | 78 | * asm_operands: |
535825e6 | 79 | |
bed3e6b4 | 80 | There are several rules on the usage of stack-like regs in |
81 | asm_operands insns. These rules apply only to the operands that are | |
82 | stack-like regs: | |
83 | ||
84 | 1. Given a set of input regs that die in an asm_operands, it is | |
85 | necessary to know which are implicitly popped by the asm, and | |
86 | which must be explicitly popped by gcc. | |
87 | ||
88 | An input reg that is implicitly popped by the asm must be | |
89 | explicitly clobbered, unless it is constrained to match an | |
90 | output operand. | |
91 | ||
92 | 2. For any input reg that is implicitly popped by an asm, it is | |
93 | necessary to know how to adjust the stack to compensate for the pop. | |
94 | If any non-popped input is closer to the top of the reg-stack than | |
95 | the implicitly popped reg, it would not be possible to know what the | |
96 | stack looked like - it's not clear how the rest of the stack "slides | |
97 | up". | |
98 | ||
99 | All implicitly popped input regs must be closer to the top of | |
100 | the reg-stack than any input that is not implicitly popped. | |
101 | ||
102 | 3. It is possible that if an input dies in an insn, reload might | |
103 | use the input reg for an output reload. Consider this example: | |
104 | ||
105 | asm ("foo" : "=t" (a) : "f" (b)); | |
106 | ||
107 | This asm says that input B is not popped by the asm, and that | |
108 | the asm pushes a result onto the reg-stack, ie, the stack is one | |
109 | deeper after the asm than it was before. But, it is possible that | |
110 | reload will think that it can use the same reg for both the input and | |
111 | the output, if input B dies in this insn. | |
112 | ||
113 | If any input operand uses the "f" constraint, all output reg | |
114 | constraints must use the "&" earlyclobber. | |
115 | ||
116 | The asm above would be written as | |
117 | ||
118 | asm ("foo" : "=&t" (a) : "f" (b)); | |
119 | ||
120 | 4. Some operands need to be in particular places on the stack. All | |
121 | output operands fall in this category - there is no other way to | |
122 | know which regs the outputs appear in unless the user indicates | |
123 | this in the constraints. | |
124 | ||
125 | Output operands must specifically indicate which reg an output | |
126 | appears in after an asm. "=f" is not allowed: the operand | |
127 | constraints must select a class with a single reg. | |
128 | ||
129 | 5. Output operands may not be "inserted" between existing stack regs. | |
130 | Since no 387 opcode uses a read/write operand, all output operands | |
131 | are dead before the asm_operands, and are pushed by the asm_operands. | |
132 | It makes no sense to push anywhere but the top of the reg-stack. | |
133 | ||
134 | Output operands must start at the top of the reg-stack: output | |
135 | operands may not "skip" a reg. | |
136 | ||
137 | 6. Some asm statements may need extra stack space for internal | |
138 | calculations. This can be guaranteed by clobbering stack registers | |
139 | unrelated to the inputs and outputs. | |
140 | ||
141 | Here are a couple of reasonable asms to want to write. This asm | |
142 | takes one input, which is internally popped, and produces two outputs. | |
143 | ||
144 | asm ("fsincos" : "=t" (cos), "=u" (sin) : "0" (inp)); | |
145 | ||
146 | This asm takes two inputs, which are popped by the fyl2xp1 opcode, | |
147 | and replaces them with one output. The user must code the "st(1)" | |
148 | clobber for reg-stack.c to know that fyl2xp1 pops both inputs. | |
149 | ||
150 | asm ("fyl2xp1" : "=t" (result) : "0" (x), "u" (y) : "st(1)"); | |
151 | ||
f3d96a58 | 152 | */ |
535825e6 | 153 | \f |
535825e6 | 154 | #include "config.h" |
405711de | 155 | #include "system.h" |
535825e6 | 156 | #include "tree.h" |
157 | #include "rtl.h" | |
7953c610 | 158 | #include "tm_p.h" |
0a893c29 | 159 | #include "function.h" |
bed3e6b4 | 160 | #include "insn-config.h" |
535825e6 | 161 | #include "regs.h" |
162 | #include "hard-reg-set.h" | |
163 | #include "flags.h" | |
12874aaf | 164 | #include "toplev.h" |
ce71a9e6 | 165 | #include "recog.h" |
f3d96a58 | 166 | #include "output.h" |
167 | #include "basic-block.h" | |
b67ec609 | 168 | #include "varray.h" |
f388bf5f | 169 | #include "reload.h" |
1f3233d1 | 170 | #include "ggc.h" |
171 | ||
172 | /* We use this array to cache info about insns, because otherwise we | |
173 | spend too much time in stack_regs_mentioned_p. | |
174 | ||
175 | Indexed by insn UIDs. A value of zero is uninitialized, one indicates | |
176 | the insn uses stack registers, two indicates the insn does not use | |
177 | stack registers. */ | |
178 | static GTY(()) varray_type stack_regs_mentioned_data; | |
535825e6 | 179 | |
180 | #ifdef STACK_REGS | |
181 | ||
182 | #define REG_STACK_SIZE (LAST_STACK_REG - FIRST_STACK_REG + 1) | |
183 | ||
535825e6 | 184 | /* This is the basic stack record. TOP is an index into REG[] such |
185 | that REG[TOP] is the top of stack. If TOP is -1 the stack is empty. | |
186 | ||
5e7a3068 | 187 | If TOP is -2, REG[] is not yet initialized. Stack initialization |
188 | consists of placing each live reg in array `reg' and setting `top' | |
189 | appropriately. | |
190 | ||
191 | REG_SET indicates which registers are live. */ | |
535825e6 | 192 | |
193 | typedef struct stack_def | |
194 | { | |
195 | int top; /* index to top stack element */ | |
196 | HARD_REG_SET reg_set; /* set of live registers */ | |
32478e31 | 197 | unsigned char reg[REG_STACK_SIZE];/* register - stack mapping */ |
535825e6 | 198 | } *stack; |
199 | ||
2617fe26 | 200 | /* This is used to carry information about basic blocks. It is |
f3d96a58 | 201 | attached to the AUX field of the standard CFG block. */ |
535825e6 | 202 | |
f3d96a58 | 203 | typedef struct block_info_def |
204 | { | |
205 | struct stack_def stack_in; /* Input stack configuration. */ | |
ecb7b891 | 206 | struct stack_def stack_out; /* Output stack configuration. */ |
f3d96a58 | 207 | HARD_REG_SET out_reg_set; /* Stack regs live on output. */ |
208 | int done; /* True if block already converted. */ | |
4ad72a03 | 209 | int predecessors; /* Number of predecessors that needs |
ecb7b891 | 210 | to be visited. */ |
f3d96a58 | 211 | } *block_info; |
535825e6 | 212 | |
f3d96a58 | 213 | #define BLOCK_INFO(B) ((block_info) (B)->aux) |
535825e6 | 214 | |
f3d96a58 | 215 | /* Passed to change_stack to indicate where to emit insns. */ |
216 | enum emit_where | |
217 | { | |
218 | EMIT_AFTER, | |
219 | EMIT_BEFORE | |
220 | }; | |
535825e6 | 221 | |
f3d96a58 | 222 | /* The block we're currently working on. */ |
223 | static basic_block current_block; | |
224 | ||
535825e6 | 225 | /* This is the register file for all register after conversion */ |
a5dff55e | 226 | static rtx |
227 | FP_mode_reg[LAST_STACK_REG+1-FIRST_STACK_REG][(int) MAX_MACHINE_MODE]; | |
228 | ||
229 | #define FP_MODE_REG(regno,mode) \ | |
33181afc | 230 | (FP_mode_reg[(regno)-FIRST_STACK_REG][(int) (mode)]) |
535825e6 | 231 | |
f3d96a58 | 232 | /* Used to initialize uninitialized registers. */ |
233 | static rtx nan; | |
535825e6 | 234 | |
535825e6 | 235 | /* Forward declarations */ |
236 | ||
99c683ff | 237 | static int stack_regs_mentioned_p PARAMS ((rtx pat)); |
238 | static void straighten_stack PARAMS ((rtx, stack)); | |
239 | static void pop_stack PARAMS ((stack, int)); | |
240 | static rtx *get_true_reg PARAMS ((rtx *)); | |
241 | ||
242 | static int check_asm_stack_operands PARAMS ((rtx)); | |
243 | static int get_asm_operand_n_inputs PARAMS ((rtx)); | |
244 | static rtx stack_result PARAMS ((tree)); | |
245 | static void replace_reg PARAMS ((rtx *, int)); | |
32478e31 | 246 | static void remove_regno_note PARAMS ((rtx, enum reg_note, |
247 | unsigned int)); | |
99c683ff | 248 | static int get_hard_regnum PARAMS ((stack, rtx)); |
99c683ff | 249 | static rtx emit_pop_insn PARAMS ((rtx, stack, rtx, |
f3d96a58 | 250 | enum emit_where)); |
99c683ff | 251 | static void emit_swap_insn PARAMS ((rtx, stack, rtx)); |
252 | static void move_for_stack_reg PARAMS ((rtx, stack, rtx)); | |
253 | static int swap_rtx_condition_1 PARAMS ((rtx)); | |
254 | static int swap_rtx_condition PARAMS ((rtx)); | |
255 | static void compare_for_stack_reg PARAMS ((rtx, stack, rtx)); | |
256 | static void subst_stack_regs_pat PARAMS ((rtx, stack, rtx)); | |
257 | static void subst_asm_stack_regs PARAMS ((rtx, stack)); | |
258 | static void subst_stack_regs PARAMS ((rtx, stack)); | |
259 | static void change_stack PARAMS ((rtx, stack, stack, | |
f3d96a58 | 260 | enum emit_where)); |
99c683ff | 261 | static int convert_regs_entry PARAMS ((void)); |
262 | static void convert_regs_exit PARAMS ((void)); | |
263 | static int convert_regs_1 PARAMS ((FILE *, basic_block)); | |
264 | static int convert_regs_2 PARAMS ((FILE *, basic_block)); | |
265 | static int convert_regs PARAMS ((FILE *)); | |
266 | static void print_stack PARAMS ((FILE *, stack)); | |
74647769 | 267 | static rtx next_flags_user PARAMS ((rtx)); |
268 | static void record_label_references PARAMS ((rtx, rtx)); | |
ecb7b891 | 269 | static bool compensate_edge PARAMS ((edge, FILE *)); |
b67ec609 | 270 | \f |
ce71a9e6 | 271 | /* Return non-zero if any stack register is mentioned somewhere within PAT. */ |
b67ec609 | 272 | |
273 | static int | |
ce71a9e6 | 274 | stack_regs_mentioned_p (pat) |
275 | rtx pat; | |
b67ec609 | 276 | { |
19cb6b50 | 277 | const char *fmt; |
278 | int i; | |
ce71a9e6 | 279 | |
280 | if (STACK_REG_P (pat)) | |
281 | return 1; | |
282 | ||
283 | fmt = GET_RTX_FORMAT (GET_CODE (pat)); | |
284 | for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--) | |
b67ec609 | 285 | { |
ce71a9e6 | 286 | if (fmt[i] == 'E') |
287 | { | |
19cb6b50 | 288 | int j; |
ce71a9e6 | 289 | |
290 | for (j = XVECLEN (pat, i) - 1; j >= 0; j--) | |
291 | if (stack_regs_mentioned_p (XVECEXP (pat, i, j))) | |
292 | return 1; | |
293 | } | |
294 | else if (fmt[i] == 'e' && stack_regs_mentioned_p (XEXP (pat, i))) | |
295 | return 1; | |
b67ec609 | 296 | } |
ce71a9e6 | 297 | |
b67ec609 | 298 | return 0; |
299 | } | |
300 | ||
ce71a9e6 | 301 | /* Return nonzero if INSN mentions stacked registers, else return zero. */ |
b67ec609 | 302 | |
303 | int | |
304 | stack_regs_mentioned (insn) | |
305 | rtx insn; | |
306 | { | |
ce71a9e6 | 307 | unsigned int uid, max; |
308 | int test; | |
309 | ||
6d866f03 | 310 | if (! INSN_P (insn) || !stack_regs_mentioned_data) |
b67ec609 | 311 | return 0; |
ce71a9e6 | 312 | |
b67ec609 | 313 | uid = INSN_UID (insn); |
ce71a9e6 | 314 | max = VARRAY_SIZE (stack_regs_mentioned_data); |
315 | if (uid >= max) | |
316 | { | |
317 | /* Allocate some extra size to avoid too many reallocs, but | |
318 | do not grow too quickly. */ | |
319 | max = uid + uid / 20; | |
320 | VARRAY_GROW (stack_regs_mentioned_data, max); | |
321 | } | |
322 | ||
323 | test = VARRAY_CHAR (stack_regs_mentioned_data, uid); | |
324 | if (test == 0) | |
325 | { | |
326 | /* This insn has yet to be examined. Do so now. */ | |
327 | test = stack_regs_mentioned_p (PATTERN (insn)) ? 1 : 2; | |
328 | VARRAY_CHAR (stack_regs_mentioned_data, uid) = test; | |
329 | } | |
330 | ||
331 | return test == 1; | |
b67ec609 | 332 | } |
ce71a9e6 | 333 | \f |
334 | static rtx ix86_flags_rtx; | |
b67ec609 | 335 | |
ce71a9e6 | 336 | static rtx |
337 | next_flags_user (insn) | |
338 | rtx insn; | |
339 | { | |
2617fe26 | 340 | /* Search forward looking for the first use of this value. |
ce71a9e6 | 341 | Stop at block boundaries. */ |
ce71a9e6 | 342 | |
7ce6501c | 343 | while (insn != current_block->end) |
ce71a9e6 | 344 | { |
345 | insn = NEXT_INSN (insn); | |
ce71a9e6 | 346 | |
9204e736 | 347 | if (INSN_P (insn) && reg_mentioned_p (ix86_flags_rtx, PATTERN (insn))) |
2617fe26 | 348 | return insn; |
ce71a9e6 | 349 | |
7ce6501c | 350 | if (GET_CODE (insn) == CALL_INSN) |
ce71a9e6 | 351 | return NULL_RTX; |
352 | } | |
7ce6501c | 353 | return NULL_RTX; |
ce71a9e6 | 354 | } |
535825e6 | 355 | \f |
a5dff55e | 356 | /* Reorganise the stack into ascending numbers, |
357 | after this insn. */ | |
358 | ||
359 | static void | |
360 | straighten_stack (insn, regstack) | |
361 | rtx insn; | |
362 | stack regstack; | |
363 | { | |
364 | struct stack_def temp_stack; | |
365 | int top; | |
366 | ||
f43291cf | 367 | /* If there is only a single register on the stack, then the stack is |
368 | already in increasing order and no reorganization is needed. | |
369 | ||
370 | Similarly if the stack is empty. */ | |
371 | if (regstack->top <= 0) | |
372 | return; | |
373 | ||
58bf3e9d | 374 | COPY_HARD_REG_SET (temp_stack.reg_set, regstack->reg_set); |
a5dff55e | 375 | |
376 | for (top = temp_stack.top = regstack->top; top >= 0; top--) | |
ce71a9e6 | 377 | temp_stack.reg[top] = FIRST_STACK_REG + temp_stack.top - top; |
2617fe26 | 378 | |
f3d96a58 | 379 | change_stack (insn, regstack, &temp_stack, EMIT_AFTER); |
a5dff55e | 380 | } |
a97edd5b | 381 | |
382 | /* Pop a register from the stack */ | |
383 | ||
384 | static void | |
385 | pop_stack (regstack, regno) | |
386 | stack regstack; | |
387 | int regno; | |
388 | { | |
389 | int top = regstack->top; | |
390 | ||
391 | CLEAR_HARD_REG_BIT (regstack->reg_set, regno); | |
392 | regstack->top--; | |
393 | /* If regno was not at the top of stack then adjust stack */ | |
394 | if (regstack->reg [top] != regno) | |
395 | { | |
396 | int i; | |
397 | for (i = regstack->top; i >= 0; i--) | |
398 | if (regstack->reg [i] == regno) | |
399 | { | |
400 | int j; | |
401 | for (j = i; j < top; j++) | |
402 | regstack->reg [j] = regstack->reg [j + 1]; | |
403 | break; | |
404 | } | |
405 | } | |
406 | } | |
a5dff55e | 407 | \f |
535825e6 | 408 | /* Convert register usage from "flat" register file usage to a "stack |
409 | register file. FIRST is the first insn in the function, FILE is the | |
410 | dump file, if used. | |
411 | ||
2cbd13af | 412 | Construct a CFG and run life analysis. Then convert each insn one |
fc4eaab7 | 413 | by one. Run a last cleanup_cfg pass, if optimizing, to eliminate |
f3d96a58 | 414 | code duplication created when the converter inserts pop insns on |
415 | the edges. */ | |
535825e6 | 416 | |
417 | void | |
418 | reg_to_stack (first, file) | |
419 | rtx first; | |
420 | FILE *file; | |
421 | { | |
4c26117a | 422 | basic_block bb; |
b3d6de89 | 423 | int i; |
424 | int max_uid; | |
f3d96a58 | 425 | |
6d866f03 | 426 | /* Clean up previous run. */ |
1f3233d1 | 427 | stack_regs_mentioned_data = 0; |
6d866f03 | 428 | |
bf73fcf4 | 429 | if (!optimize) |
430 | split_all_insns (0); | |
431 | ||
f3d96a58 | 432 | /* See if there is something to do. Flow analysis is quite |
433 | expensive so we might save some compilation time. */ | |
434 | for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++) | |
435 | if (regs_ever_live[i]) | |
436 | break; | |
437 | if (i > LAST_STACK_REG) | |
438 | return; | |
a5dff55e | 439 | |
2617fe26 | 440 | /* Ok, floating point instructions exist. If not optimizing, |
2cbd13af | 441 | build the CFG and run life analysis. */ |
bf73fcf4 | 442 | if (!optimize) |
7fb47f9f | 443 | { |
444 | find_basic_blocks (first, max_reg_num (), file); | |
445 | count_or_remove_death_notes (NULL, 1); | |
446 | life_analysis (first, file, PROP_DEATH_NOTES); | |
447 | } | |
ecb7b891 | 448 | mark_dfs_back_edges (); |
535825e6 | 449 | |
f3d96a58 | 450 | /* Set up block info for each basic block. */ |
b36d64df | 451 | alloc_aux_for_blocks (sizeof (struct block_info_def)); |
4c26117a | 452 | FOR_EACH_BB_REVERSE (bb) |
ecb7b891 | 453 | { |
454 | edge e; | |
ecb7b891 | 455 | for (e = bb->pred; e; e=e->pred_next) |
456 | if (!(e->flags & EDGE_DFS_BACK) | |
457 | && e->src != ENTRY_BLOCK_PTR) | |
4ad72a03 | 458 | BLOCK_INFO (bb)->predecessors++; |
ecb7b891 | 459 | } |
535825e6 | 460 | |
f3d96a58 | 461 | /* Create the replacement registers up front. */ |
462 | for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++) | |
b67ec609 | 463 | { |
f3d96a58 | 464 | enum machine_mode mode; |
465 | for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); | |
466 | mode != VOIDmode; | |
467 | mode = GET_MODE_WIDER_MODE (mode)) | |
468 | FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i); | |
469 | for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT); | |
470 | mode != VOIDmode; | |
471 | mode = GET_MODE_WIDER_MODE (mode)) | |
472 | FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i); | |
b67ec609 | 473 | } |
535825e6 | 474 | |
f3d96a58 | 475 | ix86_flags_rtx = gen_rtx_REG (CCmode, FLAGS_REG); |
535825e6 | 476 | |
2617fe26 | 477 | /* A QNaN for initializing uninitialized variables. |
535825e6 | 478 | |
f3d96a58 | 479 | ??? We can't load from constant memory in PIC mode, because |
480 | we're insertting these instructions before the prologue and | |
481 | the PIC register hasn't been set up. In that case, fall back | |
482 | on zero, which we can get from `ldz'. */ | |
535825e6 | 483 | |
f3d96a58 | 484 | if (flag_pic) |
485 | nan = CONST0_RTX (SFmode); | |
486 | else | |
487 | { | |
488 | nan = gen_lowpart (SFmode, GEN_INT (0x7fc00000)); | |
489 | nan = force_const_mem (SFmode, nan); | |
490 | } | |
535825e6 | 491 | |
f3d96a58 | 492 | /* Allocate a cache for stack_regs_mentioned. */ |
493 | max_uid = get_max_uid (); | |
494 | VARRAY_CHAR_INIT (stack_regs_mentioned_data, max_uid + 1, | |
495 | "stack_regs_mentioned cache"); | |
535825e6 | 496 | |
6d866f03 | 497 | convert_regs (file); |
b67ec609 | 498 | |
b36d64df | 499 | free_aux_for_blocks (); |
535825e6 | 500 | } |
501 | \f | |
502 | /* Check PAT, which is in INSN, for LABEL_REFs. Add INSN to the | |
503 | label's chain of references, and note which insn contains each | |
a92771b8 | 504 | reference. */ |
535825e6 | 505 | |
506 | static void | |
507 | record_label_references (insn, pat) | |
508 | rtx insn, pat; | |
509 | { | |
19cb6b50 | 510 | enum rtx_code code = GET_CODE (pat); |
511 | int i; | |
512 | const char *fmt; | |
535825e6 | 513 | |
514 | if (code == LABEL_REF) | |
515 | { | |
19cb6b50 | 516 | rtx label = XEXP (pat, 0); |
517 | rtx ref; | |
535825e6 | 518 | |
519 | if (GET_CODE (label) != CODE_LABEL) | |
520 | abort (); | |
521 | ||
a92771b8 | 522 | /* If this is an undefined label, LABEL_REFS (label) contains |
523 | garbage. */ | |
db5348da | 524 | if (INSN_UID (label) == 0) |
525 | return; | |
526 | ||
a92771b8 | 527 | /* Don't make a duplicate in the code_label's chain. */ |
535825e6 | 528 | |
c2f3c84e | 529 | for (ref = LABEL_REFS (label); |
530 | ref && ref != label; | |
531 | ref = LABEL_NEXTREF (ref)) | |
535825e6 | 532 | if (CONTAINING_INSN (ref) == insn) |
533 | return; | |
534 | ||
535 | CONTAINING_INSN (pat) = insn; | |
536 | LABEL_NEXTREF (pat) = LABEL_REFS (label); | |
537 | LABEL_REFS (label) = pat; | |
538 | ||
539 | return; | |
540 | } | |
541 | ||
542 | fmt = GET_RTX_FORMAT (code); | |
543 | for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) | |
544 | { | |
545 | if (fmt[i] == 'e') | |
546 | record_label_references (insn, XEXP (pat, i)); | |
547 | if (fmt[i] == 'E') | |
548 | { | |
19cb6b50 | 549 | int j; |
535825e6 | 550 | for (j = 0; j < XVECLEN (pat, i); j++) |
551 | record_label_references (insn, XVECEXP (pat, i, j)); | |
552 | } | |
553 | } | |
554 | } | |
555 | \f | |
556 | /* Return a pointer to the REG expression within PAT. If PAT is not a | |
557 | REG, possible enclosed by a conversion rtx, return the inner part of | |
a92771b8 | 558 | PAT that stopped the search. */ |
535825e6 | 559 | |
560 | static rtx * | |
561 | get_true_reg (pat) | |
562 | rtx *pat; | |
563 | { | |
a5dff55e | 564 | for (;;) |
ce71a9e6 | 565 | switch (GET_CODE (*pat)) |
a5dff55e | 566 | { |
ce71a9e6 | 567 | case SUBREG: |
568 | /* Eliminate FP subregister accesses in favour of the | |
569 | actual FP register in use. */ | |
570 | { | |
571 | rtx subreg; | |
572 | if (FP_REG_P (subreg = SUBREG_REG (*pat))) | |
a5dff55e | 573 | { |
701e46d0 | 574 | int regno_off = subreg_regno_offset (REGNO (subreg), |
575 | GET_MODE (subreg), | |
576 | SUBREG_BYTE (*pat), | |
577 | GET_MODE (*pat)); | |
578 | *pat = FP_MODE_REG (REGNO (subreg) + regno_off, | |
a5dff55e | 579 | GET_MODE (subreg)); |
ce71a9e6 | 580 | default: |
a5dff55e | 581 | return pat; |
582 | } | |
ce71a9e6 | 583 | } |
584 | case FLOAT: | |
585 | case FIX: | |
586 | case FLOAT_EXTEND: | |
587 | pat = & XEXP (*pat, 0); | |
a5dff55e | 588 | } |
535825e6 | 589 | } |
535825e6 | 590 | \f |
f3d96a58 | 591 | /* There are many rules that an asm statement for stack-like regs must |
bed3e6b4 | 592 | follow. Those rules are explained at the top of this file: the rule |
a92771b8 | 593 | numbers below refer to that explanation. */ |
bed3e6b4 | 594 | |
f3d96a58 | 595 | static int |
596 | check_asm_stack_operands (insn) | |
bed3e6b4 | 597 | rtx insn; |
bed3e6b4 | 598 | { |
599 | int i; | |
bed3e6b4 | 600 | int n_clobbers; |
601 | int malformed_asm = 0; | |
602 | rtx body = PATTERN (insn); | |
603 | ||
f3d96a58 | 604 | char reg_used_as_output[FIRST_PSEUDO_REGISTER]; |
605 | char implicitly_dies[FIRST_PSEUDO_REGISTER]; | |
78e49515 | 606 | int alt; |
bed3e6b4 | 607 | |
ef2c4a29 | 608 | rtx *clobber_reg = 0; |
78e49515 | 609 | int n_inputs, n_outputs; |
bed3e6b4 | 610 | |
d315aa96 | 611 | /* Find out what the constraints require. If no constraint |
71ed03a4 | 612 | alternative matches, this asm is malformed. */ |
78e49515 | 613 | extract_insn (insn); |
614 | constrain_operands (1); | |
615 | alt = which_alternative; | |
616 | ||
617 | preprocess_constraints (); | |
618 | ||
619 | n_inputs = get_asm_operand_n_inputs (body); | |
ed420a25 | 620 | n_outputs = recog_data.n_operands - n_inputs; |
78e49515 | 621 | |
622 | if (alt < 0) | |
623 | { | |
624 | malformed_asm = 1; | |
625 | /* Avoid further trouble with this insn. */ | |
626 | PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx); | |
f3d96a58 | 627 | return 0; |
78e49515 | 628 | } |
bed3e6b4 | 629 | |
a92771b8 | 630 | /* Strip SUBREGs here to make the following code simpler. */ |
ed420a25 | 631 | for (i = 0; i < recog_data.n_operands; i++) |
632 | if (GET_CODE (recog_data.operand[i]) == SUBREG | |
633 | && GET_CODE (SUBREG_REG (recog_data.operand[i])) == REG) | |
634 | recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]); | |
bed3e6b4 | 635 | |
636 | /* Set up CLOBBER_REG. */ | |
637 | ||
638 | n_clobbers = 0; | |
bed3e6b4 | 639 | |
640 | if (GET_CODE (body) == PARALLEL) | |
fc738e1d | 641 | { |
7426c2df | 642 | clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx)); |
bed3e6b4 | 643 | |
fc738e1d | 644 | for (i = 0; i < XVECLEN (body, 0); i++) |
645 | if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER) | |
646 | { | |
647 | rtx clobber = XVECEXP (body, 0, i); | |
648 | rtx reg = XEXP (clobber, 0); | |
bed3e6b4 | 649 | |
fc738e1d | 650 | if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG) |
651 | reg = SUBREG_REG (reg); | |
652 | ||
653 | if (STACK_REG_P (reg)) | |
654 | { | |
655 | clobber_reg[n_clobbers] = reg; | |
656 | n_clobbers++; | |
657 | } | |
658 | } | |
659 | } | |
bed3e6b4 | 660 | |
661 | /* Enforce rule #4: Output operands must specifically indicate which | |
662 | reg an output appears in after an asm. "=f" is not allowed: the | |
663 | operand constraints must select a class with a single reg. | |
664 | ||
665 | Also enforce rule #5: Output operands must start at the top of | |
a92771b8 | 666 | the reg-stack: output operands may not "skip" a reg. */ |
bed3e6b4 | 667 | |
f3d96a58 | 668 | memset (reg_used_as_output, 0, sizeof (reg_used_as_output)); |
bed3e6b4 | 669 | for (i = 0; i < n_outputs; i++) |
ed420a25 | 670 | if (STACK_REG_P (recog_data.operand[i])) |
8ac2b0ed | 671 | { |
78e49515 | 672 | if (reg_class_size[(int) recog_op_alt[i][alt].class] != 1) |
8ac2b0ed | 673 | { |
cb8bacb6 | 674 | error_for_asm (insn, "output constraint %d must specify a single register", i); |
8ac2b0ed | 675 | malformed_asm = 1; |
676 | } | |
2617fe26 | 677 | else |
8be6418a | 678 | { |
679 | int j; | |
680 | ||
681 | for (j = 0; j < n_clobbers; j++) | |
682 | if (REGNO (recog_data.operand[i]) == REGNO (clobber_reg[j])) | |
683 | { | |
cb8bacb6 | 684 | error_for_asm (insn, "output constraint %d cannot be specified together with \"%s\" clobber", |
8be6418a | 685 | i, reg_names [REGNO (clobber_reg[j])]); |
686 | malformed_asm = 1; | |
687 | break; | |
688 | } | |
689 | if (j == n_clobbers) | |
690 | reg_used_as_output[REGNO (recog_data.operand[i])] = 1; | |
691 | } | |
8ac2b0ed | 692 | } |
bed3e6b4 | 693 | |
694 | ||
695 | /* Search for first non-popped reg. */ | |
696 | for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++) | |
697 | if (! reg_used_as_output[i]) | |
698 | break; | |
699 | ||
700 | /* If there are any other popped regs, that's an error. */ | |
701 | for (; i < LAST_STACK_REG + 1; i++) | |
702 | if (reg_used_as_output[i]) | |
703 | break; | |
704 | ||
705 | if (i != LAST_STACK_REG + 1) | |
706 | { | |
cb8bacb6 | 707 | error_for_asm (insn, "output regs must be grouped at top of stack"); |
bed3e6b4 | 708 | malformed_asm = 1; |
709 | } | |
710 | ||
711 | /* Enforce rule #2: All implicitly popped input regs must be closer | |
712 | to the top of the reg-stack than any input that is not implicitly | |
a92771b8 | 713 | popped. */ |
bed3e6b4 | 714 | |
f3d96a58 | 715 | memset (implicitly_dies, 0, sizeof (implicitly_dies)); |
78e49515 | 716 | for (i = n_outputs; i < n_outputs + n_inputs; i++) |
ed420a25 | 717 | if (STACK_REG_P (recog_data.operand[i])) |
bed3e6b4 | 718 | { |
719 | /* An input reg is implicitly popped if it is tied to an | |
a92771b8 | 720 | output, or if there is a CLOBBER for it. */ |
bed3e6b4 | 721 | int j; |
722 | ||
723 | for (j = 0; j < n_clobbers; j++) | |
ed420a25 | 724 | if (operands_match_p (clobber_reg[j], recog_data.operand[i])) |
bed3e6b4 | 725 | break; |
726 | ||
78e49515 | 727 | if (j < n_clobbers || recog_op_alt[i][alt].matches >= 0) |
ed420a25 | 728 | implicitly_dies[REGNO (recog_data.operand[i])] = 1; |
bed3e6b4 | 729 | } |
730 | ||
731 | /* Search for first non-popped reg. */ | |
732 | for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++) | |
733 | if (! implicitly_dies[i]) | |
734 | break; | |
735 | ||
736 | /* If there are any other popped regs, that's an error. */ | |
737 | for (; i < LAST_STACK_REG + 1; i++) | |
738 | if (implicitly_dies[i]) | |
739 | break; | |
740 | ||
741 | if (i != LAST_STACK_REG + 1) | |
742 | { | |
743 | error_for_asm (insn, | |
cb8bacb6 | 744 | "implicitly popped regs must be grouped at top of stack"); |
bed3e6b4 | 745 | malformed_asm = 1; |
746 | } | |
747 | ||
748 | /* Enfore rule #3: If any input operand uses the "f" constraint, all | |
749 | output constraints must use the "&" earlyclobber. | |
750 | ||
f3d96a58 | 751 | ??? Detect this more deterministically by having constrain_asm_operands |
a92771b8 | 752 | record any earlyclobber. */ |
bed3e6b4 | 753 | |
78e49515 | 754 | for (i = n_outputs; i < n_outputs + n_inputs; i++) |
755 | if (recog_op_alt[i][alt].matches == -1) | |
bed3e6b4 | 756 | { |
757 | int j; | |
758 | ||
759 | for (j = 0; j < n_outputs; j++) | |
ed420a25 | 760 | if (operands_match_p (recog_data.operand[j], recog_data.operand[i])) |
bed3e6b4 | 761 | { |
762 | error_for_asm (insn, | |
cb8bacb6 | 763 | "output operand %d must use `&' constraint", j); |
bed3e6b4 | 764 | malformed_asm = 1; |
765 | } | |
766 | } | |
767 | ||
768 | if (malformed_asm) | |
769 | { | |
770 | /* Avoid further trouble with this insn. */ | |
941522d6 | 771 | PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx); |
f3d96a58 | 772 | return 0; |
d315aa96 | 773 | } |
535825e6 | 774 | |
f3d96a58 | 775 | return 1; |
535825e6 | 776 | } |
777 | \f | |
bed3e6b4 | 778 | /* Calculate the number of inputs and outputs in BODY, an |
779 | asm_operands. N_OPERANDS is the total number of operands, and | |
780 | N_INPUTS and N_OUTPUTS are pointers to ints into which the results are | |
a92771b8 | 781 | placed. */ |
bed3e6b4 | 782 | |
78e49515 | 783 | static int |
784 | get_asm_operand_n_inputs (body) | |
bed3e6b4 | 785 | rtx body; |
bed3e6b4 | 786 | { |
787 | if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS) | |
78e49515 | 788 | return ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body)); |
bed3e6b4 | 789 | |
790 | else if (GET_CODE (body) == ASM_OPERANDS) | |
78e49515 | 791 | return ASM_OPERANDS_INPUT_LENGTH (body); |
bed3e6b4 | 792 | |
793 | else if (GET_CODE (body) == PARALLEL | |
794 | && GET_CODE (XVECEXP (body, 0, 0)) == SET) | |
78e49515 | 795 | return ASM_OPERANDS_INPUT_LENGTH (SET_SRC (XVECEXP (body, 0, 0))); |
bed3e6b4 | 796 | |
797 | else if (GET_CODE (body) == PARALLEL | |
798 | && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS) | |
78e49515 | 799 | return ASM_OPERANDS_INPUT_LENGTH (XVECEXP (body, 0, 0)); |
bed3e6b4 | 800 | |
78e49515 | 801 | abort (); |
bed3e6b4 | 802 | } |
869072dd | 803 | |
24084825 | 804 | /* If current function returns its result in an fp stack register, |
1166733c | 805 | return the REG. Otherwise, return 0. */ |
24084825 | 806 | |
a5dff55e | 807 | static rtx |
808 | stack_result (decl) | |
24084825 | 809 | tree decl; |
810 | { | |
f4b5ce94 | 811 | rtx result; |
24084825 | 812 | |
f4b5ce94 | 813 | /* If the value is supposed to be returned in memory, then clearly |
814 | it is not returned in a stack register. */ | |
815 | if (aggregate_value_p (DECL_RESULT (decl))) | |
816 | return 0; | |
817 | ||
0e8e37b2 | 818 | result = DECL_RTL_IF_SET (DECL_RESULT (decl)); |
6e5b5ba9 | 819 | if (result != 0) |
24084825 | 820 | { |
821 | #ifdef FUNCTION_OUTGOING_VALUE | |
822 | result | |
2617fe26 | 823 | = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (decl)), decl); |
24084825 | 824 | #else |
825 | result = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (decl)), decl); | |
826 | #endif | |
827 | } | |
828 | ||
1166733c | 829 | return result != 0 && STACK_REG_P (result) ? result : 0; |
24084825 | 830 | } |
535825e6 | 831 | \f |
535825e6 | 832 | |
ce71a9e6 | 833 | /* |
834 | * This section deals with stack register substitution, and forms the second | |
835 | * pass over the RTL. | |
836 | */ | |
535825e6 | 837 | |
838 | /* Replace REG, which is a pointer to a stack reg RTX, with an RTX for | |
a92771b8 | 839 | the desired hard REGNO. */ |
535825e6 | 840 | |
841 | static void | |
842 | replace_reg (reg, regno) | |
843 | rtx *reg; | |
844 | int regno; | |
845 | { | |
846 | if (regno < FIRST_STACK_REG || regno > LAST_STACK_REG | |
847 | || ! STACK_REG_P (*reg)) | |
848 | abort (); | |
849 | ||
a5dff55e | 850 | switch (GET_MODE_CLASS (GET_MODE (*reg))) |
ce71a9e6 | 851 | { |
852 | default: abort (); | |
853 | case MODE_FLOAT: | |
854 | case MODE_COMPLEX_FLOAT:; | |
855 | } | |
5d574ad0 | 856 | |
a5dff55e | 857 | *reg = FP_MODE_REG (regno, GET_MODE (*reg)); |
535825e6 | 858 | } |
859 | ||
860 | /* Remove a note of type NOTE, which must be found, for register | |
a92771b8 | 861 | number REGNO from INSN. Remove only one such note. */ |
535825e6 | 862 | |
863 | static void | |
864 | remove_regno_note (insn, note, regno) | |
865 | rtx insn; | |
866 | enum reg_note note; | |
32478e31 | 867 | unsigned int regno; |
535825e6 | 868 | { |
19cb6b50 | 869 | rtx *note_link, this; |
535825e6 | 870 | |
337d789b | 871 | note_link = ®_NOTES (insn); |
535825e6 | 872 | for (this = *note_link; this; this = XEXP (this, 1)) |
873 | if (REG_NOTE_KIND (this) == note | |
874 | && REG_P (XEXP (this, 0)) && REGNO (XEXP (this, 0)) == regno) | |
875 | { | |
876 | *note_link = XEXP (this, 1); | |
877 | return; | |
878 | } | |
879 | else | |
880 | note_link = &XEXP (this, 1); | |
881 | ||
882 | abort (); | |
883 | } | |
884 | ||
885 | /* Find the hard register number of virtual register REG in REGSTACK. | |
886 | The hard register number is relative to the top of the stack. -1 is | |
a92771b8 | 887 | returned if the register is not found. */ |
535825e6 | 888 | |
889 | static int | |
890 | get_hard_regnum (regstack, reg) | |
891 | stack regstack; | |
892 | rtx reg; | |
893 | { | |
894 | int i; | |
895 | ||
896 | if (! STACK_REG_P (reg)) | |
897 | abort (); | |
898 | ||
899 | for (i = regstack->top; i >= 0; i--) | |
900 | if (regstack->reg[i] == REGNO (reg)) | |
901 | break; | |
902 | ||
903 | return i >= 0 ? (FIRST_STACK_REG + regstack->top - i) : -1; | |
904 | } | |
535825e6 | 905 | \f |
906 | /* Emit an insn to pop virtual register REG before or after INSN. | |
907 | REGSTACK is the stack state after INSN and is updated to reflect this | |
ce71a9e6 | 908 | pop. WHEN is either emit_insn_before or emit_insn_after. A pop insn |
909 | is represented as a SET whose destination is the register to be popped | |
910 | and source is the top of stack. A death note for the top of stack | |
a92771b8 | 911 | cases the movdf pattern to pop. */ |
535825e6 | 912 | |
913 | static rtx | |
f3d96a58 | 914 | emit_pop_insn (insn, regstack, reg, where) |
535825e6 | 915 | rtx insn; |
916 | stack regstack; | |
917 | rtx reg; | |
f3d96a58 | 918 | enum emit_where where; |
535825e6 | 919 | { |
920 | rtx pop_insn, pop_rtx; | |
921 | int hard_regno; | |
922 | ||
5545a6c8 | 923 | /* For complex types take care to pop both halves. These may survive in |
924 | CLOBBER and USE expressions. */ | |
925 | if (COMPLEX_MODE_P (GET_MODE (reg))) | |
926 | { | |
927 | rtx reg1 = FP_MODE_REG (REGNO (reg), DFmode); | |
928 | rtx reg2 = FP_MODE_REG (REGNO (reg) + 1, DFmode); | |
929 | ||
930 | pop_insn = NULL_RTX; | |
931 | if (get_hard_regnum (regstack, reg1) >= 0) | |
2617fe26 | 932 | pop_insn = emit_pop_insn (insn, regstack, reg1, where); |
5545a6c8 | 933 | if (get_hard_regnum (regstack, reg2) >= 0) |
2617fe26 | 934 | pop_insn = emit_pop_insn (insn, regstack, reg2, where); |
5545a6c8 | 935 | if (!pop_insn) |
936 | abort (); | |
937 | return pop_insn; | |
938 | } | |
939 | ||
535825e6 | 940 | hard_regno = get_hard_regnum (regstack, reg); |
941 | ||
942 | if (hard_regno < FIRST_STACK_REG) | |
943 | abort (); | |
944 | ||
ce71a9e6 | 945 | pop_rtx = gen_rtx_SET (VOIDmode, FP_MODE_REG (hard_regno, DFmode), |
946 | FP_MODE_REG (FIRST_STACK_REG, DFmode)); | |
535825e6 | 947 | |
f3d96a58 | 948 | if (where == EMIT_AFTER) |
9dda7915 | 949 | pop_insn = emit_insn_after (pop_rtx, insn); |
f3d96a58 | 950 | else |
9dda7915 | 951 | pop_insn = emit_insn_before (pop_rtx, insn); |
535825e6 | 952 | |
7014838c | 953 | REG_NOTES (pop_insn) |
954 | = gen_rtx_EXPR_LIST (REG_DEAD, FP_MODE_REG (FIRST_STACK_REG, DFmode), | |
955 | REG_NOTES (pop_insn)); | |
535825e6 | 956 | |
957 | regstack->reg[regstack->top - (hard_regno - FIRST_STACK_REG)] | |
958 | = regstack->reg[regstack->top]; | |
959 | regstack->top -= 1; | |
960 | CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (reg)); | |
961 | ||
962 | return pop_insn; | |
963 | } | |
964 | \f | |
f3d96a58 | 965 | /* Emit an insn before or after INSN to swap virtual register REG with |
966 | the top of stack. REGSTACK is the stack state before the swap, and | |
967 | is updated to reflect the swap. A swap insn is represented as a | |
968 | PARALLEL of two patterns: each pattern moves one reg to the other. | |
535825e6 | 969 | |
a92771b8 | 970 | If REG is already at the top of the stack, no insn is emitted. */ |
535825e6 | 971 | |
972 | static void | |
5e7a3068 | 973 | emit_swap_insn (insn, regstack, reg) |
535825e6 | 974 | rtx insn; |
975 | stack regstack; | |
5e7a3068 | 976 | rtx reg; |
535825e6 | 977 | { |
5e7a3068 | 978 | int hard_regno; |
f3d96a58 | 979 | rtx swap_rtx; |
5e7a3068 | 980 | int tmp, other_reg; /* swap regno temps */ |
981 | rtx i1; /* the stack-reg insn prior to INSN */ | |
982 | rtx i1set = NULL_RTX; /* the SET rtx within I1 */ | |
535825e6 | 983 | |
5e7a3068 | 984 | hard_regno = get_hard_regnum (regstack, reg); |
985 | ||
986 | if (hard_regno < FIRST_STACK_REG) | |
987 | abort (); | |
535825e6 | 988 | if (hard_regno == FIRST_STACK_REG) |
989 | return; | |
990 | ||
5e7a3068 | 991 | other_reg = regstack->top - (hard_regno - FIRST_STACK_REG); |
535825e6 | 992 | |
5e7a3068 | 993 | tmp = regstack->reg[other_reg]; |
994 | regstack->reg[other_reg] = regstack->reg[regstack->top]; | |
535825e6 | 995 | regstack->reg[regstack->top] = tmp; |
535825e6 | 996 | |
f3d96a58 | 997 | /* Find the previous insn involving stack regs, but don't pass a |
998 | block boundary. */ | |
999 | i1 = NULL; | |
1000 | if (current_block && insn != current_block->head) | |
5e7a3068 | 1001 | { |
f3d96a58 | 1002 | rtx tmp = PREV_INSN (insn); |
281d2538 | 1003 | rtx limit = PREV_INSN (current_block->head); |
1004 | while (tmp != limit) | |
f3d96a58 | 1005 | { |
1006 | if (GET_CODE (tmp) == CODE_LABEL | |
ce2ed006 | 1007 | || GET_CODE (tmp) == CALL_INSN |
83458610 | 1008 | || NOTE_INSN_BASIC_BLOCK_P (tmp) |
f3d96a58 | 1009 | || (GET_CODE (tmp) == INSN |
1010 | && stack_regs_mentioned (tmp))) | |
1011 | { | |
1012 | i1 = tmp; | |
1013 | break; | |
1014 | } | |
1015 | tmp = PREV_INSN (tmp); | |
1016 | } | |
1017 | } | |
1018 | ||
1019 | if (i1 != NULL_RTX | |
1020 | && (i1set = single_set (i1)) != NULL_RTX) | |
1021 | { | |
1022 | rtx i1src = *get_true_reg (&SET_SRC (i1set)); | |
5e7a3068 | 1023 | rtx i1dest = *get_true_reg (&SET_DEST (i1set)); |
535825e6 | 1024 | |
5e7a3068 | 1025 | /* If the previous register stack push was from the reg we are to |
a92771b8 | 1026 | swap with, omit the swap. */ |
5e7a3068 | 1027 | |
1028 | if (GET_CODE (i1dest) == REG && REGNO (i1dest) == FIRST_STACK_REG | |
97b330ca | 1029 | && GET_CODE (i1src) == REG |
1030 | && REGNO (i1src) == (unsigned) hard_regno - 1 | |
5e7a3068 | 1031 | && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX) |
1032 | return; | |
1033 | ||
1034 | /* If the previous insn wrote to the reg we are to swap with, | |
1035 | omit the swap. */ | |
1036 | ||
97b330ca | 1037 | if (GET_CODE (i1dest) == REG && REGNO (i1dest) == (unsigned) hard_regno |
5e7a3068 | 1038 | && GET_CODE (i1src) == REG && REGNO (i1src) == FIRST_STACK_REG |
1039 | && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX) | |
1040 | return; | |
1041 | } | |
1042 | ||
ce71a9e6 | 1043 | swap_rtx = gen_swapxf (FP_MODE_REG (hard_regno, XFmode), |
1044 | FP_MODE_REG (FIRST_STACK_REG, XFmode)); | |
f3d96a58 | 1045 | |
1046 | if (i1) | |
9dda7915 | 1047 | emit_insn_after (swap_rtx, i1); |
f3d96a58 | 1048 | else if (current_block) |
9dda7915 | 1049 | emit_insn_before (swap_rtx, current_block->head); |
f3d96a58 | 1050 | else |
1051 | emit_insn_before (swap_rtx, insn); | |
535825e6 | 1052 | } |
1053 | \f | |
1054 | /* Handle a move to or from a stack register in PAT, which is in INSN. | |
a92771b8 | 1055 | REGSTACK is the current stack. */ |
535825e6 | 1056 | |
1057 | static void | |
1058 | move_for_stack_reg (insn, regstack, pat) | |
1059 | rtx insn; | |
1060 | stack regstack; | |
1061 | rtx pat; | |
1062 | { | |
a5dff55e | 1063 | rtx *psrc = get_true_reg (&SET_SRC (pat)); |
1064 | rtx *pdest = get_true_reg (&SET_DEST (pat)); | |
1065 | rtx src, dest; | |
535825e6 | 1066 | rtx note; |
1067 | ||
a5dff55e | 1068 | src = *psrc; dest = *pdest; |
1069 | ||
1070 | if (STACK_REG_P (src) && STACK_REG_P (dest)) | |
535825e6 | 1071 | { |
1072 | /* Write from one stack reg to another. If SRC dies here, then | |
a92771b8 | 1073 | just change the register mapping and delete the insn. */ |
535825e6 | 1074 | |
a5dff55e | 1075 | note = find_regno_note (insn, REG_DEAD, REGNO (src)); |
535825e6 | 1076 | if (note) |
1077 | { | |
1078 | int i; | |
1079 | ||
a92771b8 | 1080 | /* If this is a no-op move, there must not be a REG_DEAD note. */ |
a5dff55e | 1081 | if (REGNO (src) == REGNO (dest)) |
535825e6 | 1082 | abort (); |
1083 | ||
1084 | for (i = regstack->top; i >= 0; i--) | |
a5dff55e | 1085 | if (regstack->reg[i] == REGNO (src)) |
535825e6 | 1086 | break; |
1087 | ||
a92771b8 | 1088 | /* The source must be live, and the dest must be dead. */ |
a5dff55e | 1089 | if (i < 0 || get_hard_regnum (regstack, dest) >= FIRST_STACK_REG) |
535825e6 | 1090 | abort (); |
1091 | ||
1092 | /* It is possible that the dest is unused after this insn. | |
a92771b8 | 1093 | If so, just pop the src. */ |
535825e6 | 1094 | |
a5dff55e | 1095 | if (find_regno_note (insn, REG_UNUSED, REGNO (dest))) |
535825e6 | 1096 | { |
f3d96a58 | 1097 | emit_pop_insn (insn, regstack, src, EMIT_AFTER); |
535825e6 | 1098 | |
e4bf866d | 1099 | delete_insn (insn); |
535825e6 | 1100 | return; |
1101 | } | |
1102 | ||
a5dff55e | 1103 | regstack->reg[i] = REGNO (dest); |
535825e6 | 1104 | |
a5dff55e | 1105 | SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest)); |
1106 | CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src)); | |
535825e6 | 1107 | |
e4bf866d | 1108 | delete_insn (insn); |
535825e6 | 1109 | |
1110 | return; | |
1111 | } | |
1112 | ||
a92771b8 | 1113 | /* The source reg does not die. */ |
535825e6 | 1114 | |
1115 | /* If this appears to be a no-op move, delete it, or else it | |
1116 | will confuse the machine description output patterns. But if | |
1117 | it is REG_UNUSED, we must pop the reg now, as per-insn processing | |
a92771b8 | 1118 | for REG_UNUSED will not work for deleted insns. */ |
535825e6 | 1119 | |
a5dff55e | 1120 | if (REGNO (src) == REGNO (dest)) |
535825e6 | 1121 | { |
a5dff55e | 1122 | if (find_regno_note (insn, REG_UNUSED, REGNO (dest))) |
f3d96a58 | 1123 | emit_pop_insn (insn, regstack, dest, EMIT_AFTER); |
535825e6 | 1124 | |
e4bf866d | 1125 | delete_insn (insn); |
535825e6 | 1126 | return; |
1127 | } | |
1128 | ||
1129 | /* The destination ought to be dead */ | |
a5dff55e | 1130 | if (get_hard_regnum (regstack, dest) >= FIRST_STACK_REG) |
535825e6 | 1131 | abort (); |
1132 | ||
a5dff55e | 1133 | replace_reg (psrc, get_hard_regnum (regstack, src)); |
535825e6 | 1134 | |
a5dff55e | 1135 | regstack->reg[++regstack->top] = REGNO (dest); |
1136 | SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest)); | |
1137 | replace_reg (pdest, FIRST_STACK_REG); | |
535825e6 | 1138 | } |
a5dff55e | 1139 | else if (STACK_REG_P (src)) |
535825e6 | 1140 | { |
1141 | /* Save from a stack reg to MEM, or possibly integer reg. Since | |
1142 | only top of stack may be saved, emit an exchange first if | |
a92771b8 | 1143 | needs be. */ |
535825e6 | 1144 | |
a5dff55e | 1145 | emit_swap_insn (insn, regstack, src); |
535825e6 | 1146 | |
a5dff55e | 1147 | note = find_regno_note (insn, REG_DEAD, REGNO (src)); |
535825e6 | 1148 | if (note) |
1149 | { | |
1150 | replace_reg (&XEXP (note, 0), FIRST_STACK_REG); | |
1151 | regstack->top--; | |
a5dff55e | 1152 | CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src)); |
535825e6 | 1153 | } |
75ab846a | 1154 | else if ((GET_MODE (src) == XFmode || GET_MODE (src) == TFmode) |
1155 | && regstack->top < REG_STACK_SIZE - 1) | |
b6e49ac0 | 1156 | { |
1157 | /* A 387 cannot write an XFmode value to a MEM without | |
1158 | clobbering the source reg. The output code can handle | |
1159 | this by reading back the value from the MEM. | |
1160 | But it is more efficient to use a temp register if one is | |
1161 | available. Push the source value here if the register | |
1162 | stack is not full, and then write the value to memory via | |
1163 | a pop. */ | |
1164 | rtx push_rtx, push_insn; | |
5545a6c8 | 1165 | rtx top_stack_reg = FP_MODE_REG (FIRST_STACK_REG, GET_MODE (src)); |
b6e49ac0 | 1166 | |
5545a6c8 | 1167 | if (GET_MODE (src) == TFmode) |
1168 | push_rtx = gen_movtf (top_stack_reg, top_stack_reg); | |
1169 | else | |
1170 | push_rtx = gen_movxf (top_stack_reg, top_stack_reg); | |
b6e49ac0 | 1171 | push_insn = emit_insn_before (push_rtx, insn); |
941522d6 | 1172 | REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, top_stack_reg, |
1173 | REG_NOTES (insn)); | |
b6e49ac0 | 1174 | } |
535825e6 | 1175 | |
a5dff55e | 1176 | replace_reg (psrc, FIRST_STACK_REG); |
535825e6 | 1177 | } |
a5dff55e | 1178 | else if (STACK_REG_P (dest)) |
535825e6 | 1179 | { |
1180 | /* Load from MEM, or possibly integer REG or constant, into the | |
1181 | stack regs. The actual target is always the top of the | |
1182 | stack. The stack mapping is changed to reflect that DEST is | |
1183 | now at top of stack. */ | |
1184 | ||
1185 | /* The destination ought to be dead */ | |
a5dff55e | 1186 | if (get_hard_regnum (regstack, dest) >= FIRST_STACK_REG) |
535825e6 | 1187 | abort (); |
1188 | ||
1189 | if (regstack->top >= REG_STACK_SIZE) | |
1190 | abort (); | |
1191 | ||
a5dff55e | 1192 | regstack->reg[++regstack->top] = REGNO (dest); |
1193 | SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest)); | |
1194 | replace_reg (pdest, FIRST_STACK_REG); | |
535825e6 | 1195 | } |
1196 | else | |
1197 | abort (); | |
1198 | } | |
1199 | \f | |
ce71a9e6 | 1200 | /* Swap the condition on a branch, if there is one. Return true if we |
1201 | found a condition to swap. False if the condition was not used as | |
aa40f561 | 1202 | such. */ |
ce71a9e6 | 1203 | |
1204 | static int | |
1205 | swap_rtx_condition_1 (pat) | |
5e7a3068 | 1206 | rtx pat; |
1207 | { | |
19cb6b50 | 1208 | const char *fmt; |
1209 | int i, r = 0; | |
5e7a3068 | 1210 | |
1211 | if (GET_RTX_CLASS (GET_CODE (pat)) == '<') | |
1212 | { | |
1213 | PUT_CODE (pat, swap_condition (GET_CODE (pat))); | |
ce71a9e6 | 1214 | r = 1; |
5e7a3068 | 1215 | } |
ce71a9e6 | 1216 | else |
5e7a3068 | 1217 | { |
ce71a9e6 | 1218 | fmt = GET_RTX_FORMAT (GET_CODE (pat)); |
1219 | for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--) | |
5e7a3068 | 1220 | { |
ce71a9e6 | 1221 | if (fmt[i] == 'E') |
1222 | { | |
19cb6b50 | 1223 | int j; |
5e7a3068 | 1224 | |
ce71a9e6 | 1225 | for (j = XVECLEN (pat, i) - 1; j >= 0; j--) |
1226 | r |= swap_rtx_condition_1 (XVECEXP (pat, i, j)); | |
1227 | } | |
1228 | else if (fmt[i] == 'e') | |
1229 | r |= swap_rtx_condition_1 (XEXP (pat, i)); | |
5e7a3068 | 1230 | } |
5e7a3068 | 1231 | } |
ce71a9e6 | 1232 | |
1233 | return r; | |
1234 | } | |
1235 | ||
1236 | static int | |
1237 | swap_rtx_condition (insn) | |
1238 | rtx insn; | |
1239 | { | |
1240 | rtx pat = PATTERN (insn); | |
1241 | ||
1242 | /* We're looking for a single set to cc0 or an HImode temporary. */ | |
1243 | ||
1244 | if (GET_CODE (pat) == SET | |
1245 | && GET_CODE (SET_DEST (pat)) == REG | |
1246 | && REGNO (SET_DEST (pat)) == FLAGS_REG) | |
1247 | { | |
1248 | insn = next_flags_user (insn); | |
1249 | if (insn == NULL_RTX) | |
1250 | return 0; | |
1251 | pat = PATTERN (insn); | |
1252 | } | |
1253 | ||
1254 | /* See if this is, or ends in, a fnstsw, aka unspec 9. If so, we're | |
1255 | not doing anything with the cc value right now. We may be able to | |
1256 | search for one though. */ | |
1257 | ||
1258 | if (GET_CODE (pat) == SET | |
1259 | && GET_CODE (SET_SRC (pat)) == UNSPEC | |
372310d2 | 1260 | && XINT (SET_SRC (pat), 1) == UNSPEC_FNSTSW) |
ce71a9e6 | 1261 | { |
1262 | rtx dest = SET_DEST (pat); | |
1263 | ||
2617fe26 | 1264 | /* Search forward looking for the first use of this value. |
ce71a9e6 | 1265 | Stop at block boundaries. */ |
7ce6501c | 1266 | while (insn != current_block->end) |
ce71a9e6 | 1267 | { |
1268 | insn = NEXT_INSN (insn); | |
9204e736 | 1269 | if (INSN_P (insn) && reg_mentioned_p (dest, insn)) |
ce71a9e6 | 1270 | break; |
7ce6501c | 1271 | if (GET_CODE (insn) == CALL_INSN) |
ce71a9e6 | 1272 | return 0; |
1273 | } | |
1274 | ||
1275 | /* So we've found the insn using this value. If it is anything | |
1276 | other than sahf, aka unspec 10, or the value does not die | |
1277 | (meaning we'd have to search further), then we must give up. */ | |
1278 | pat = PATTERN (insn); | |
1279 | if (GET_CODE (pat) != SET | |
1280 | || GET_CODE (SET_SRC (pat)) != UNSPEC | |
372310d2 | 1281 | || XINT (SET_SRC (pat), 1) != UNSPEC_SAHF |
ce71a9e6 | 1282 | || ! dead_or_set_p (insn, dest)) |
1283 | return 0; | |
1284 | ||
1285 | /* Now we are prepared to handle this as a normal cc0 setter. */ | |
1286 | insn = next_flags_user (insn); | |
1287 | if (insn == NULL_RTX) | |
1288 | return 0; | |
1289 | pat = PATTERN (insn); | |
1290 | } | |
1291 | ||
5377f687 | 1292 | if (swap_rtx_condition_1 (pat)) |
1293 | { | |
7ce6501c | 1294 | int fail = 0; |
5377f687 | 1295 | INSN_CODE (insn) = -1; |
1296 | if (recog_memoized (insn) == -1) | |
7ce6501c | 1297 | fail = 1; |
1298 | /* In case the flags don't die here, recurse to try fix | |
1299 | following user too. */ | |
1300 | else if (! dead_or_set_p (insn, ix86_flags_rtx)) | |
1301 | { | |
1302 | insn = next_flags_user (insn); | |
1303 | if (!insn || !swap_rtx_condition (insn)) | |
1304 | fail = 1; | |
1305 | } | |
1306 | if (fail) | |
5377f687 | 1307 | { |
1308 | swap_rtx_condition_1 (pat); | |
1309 | return 0; | |
1310 | } | |
1311 | return 1; | |
1312 | } | |
1313 | return 0; | |
5e7a3068 | 1314 | } |
1315 | ||
535825e6 | 1316 | /* Handle a comparison. Special care needs to be taken to avoid |
1317 | causing comparisons that a 387 cannot do correctly, such as EQ. | |
1318 | ||
ce71a9e6 | 1319 | Also, a pop insn may need to be emitted. The 387 does have an |
535825e6 | 1320 | `fcompp' insn that can pop two regs, but it is sometimes too expensive |
1321 | to do this - a `fcomp' followed by a `fstpl %st(0)' may be easier to | |
ce71a9e6 | 1322 | set up. */ |
535825e6 | 1323 | |
1324 | static void | |
ce71a9e6 | 1325 | compare_for_stack_reg (insn, regstack, pat_src) |
535825e6 | 1326 | rtx insn; |
1327 | stack regstack; | |
ce71a9e6 | 1328 | rtx pat_src; |
535825e6 | 1329 | { |
1330 | rtx *src1, *src2; | |
1331 | rtx src1_note, src2_note; | |
ce71a9e6 | 1332 | rtx flags_user; |
3c8249d9 | 1333 | |
ce71a9e6 | 1334 | src1 = get_true_reg (&XEXP (pat_src, 0)); |
1335 | src2 = get_true_reg (&XEXP (pat_src, 1)); | |
1336 | flags_user = next_flags_user (insn); | |
535825e6 | 1337 | |
5e7a3068 | 1338 | /* ??? If fxch turns out to be cheaper than fstp, give priority to |
a92771b8 | 1339 | registers that die in this insn - move those to stack top first. */ |
ce71a9e6 | 1340 | if ((! STACK_REG_P (*src1) |
1341 | || (STACK_REG_P (*src2) | |
1342 | && get_hard_regnum (regstack, *src2) == FIRST_STACK_REG)) | |
1343 | && swap_rtx_condition (insn)) | |
5e7a3068 | 1344 | { |
ce71a9e6 | 1345 | rtx temp; |
1346 | temp = XEXP (pat_src, 0); | |
1347 | XEXP (pat_src, 0) = XEXP (pat_src, 1); | |
1348 | XEXP (pat_src, 1) = temp; | |
535825e6 | 1349 | |
ce71a9e6 | 1350 | src1 = get_true_reg (&XEXP (pat_src, 0)); |
1351 | src2 = get_true_reg (&XEXP (pat_src, 1)); | |
3f89e86c | 1352 | |
2f4ca440 | 1353 | INSN_CODE (insn) = -1; |
5e7a3068 | 1354 | } |
535825e6 | 1355 | |
a92771b8 | 1356 | /* We will fix any death note later. */ |
535825e6 | 1357 | |
1358 | src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1)); | |
1359 | ||
1360 | if (STACK_REG_P (*src2)) | |
1361 | src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2)); | |
1362 | else | |
5e7a3068 | 1363 | src2_note = NULL_RTX; |
535825e6 | 1364 | |
ce71a9e6 | 1365 | emit_swap_insn (insn, regstack, *src1); |
535825e6 | 1366 | |
1367 | replace_reg (src1, FIRST_STACK_REG); | |
1368 | ||
1369 | if (STACK_REG_P (*src2)) | |
ce71a9e6 | 1370 | replace_reg (src2, get_hard_regnum (regstack, *src2)); |
535825e6 | 1371 | |
1372 | if (src1_note) | |
1373 | { | |
a97edd5b | 1374 | pop_stack (regstack, REGNO (XEXP (src1_note, 0))); |
535825e6 | 1375 | replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG); |
535825e6 | 1376 | } |
1377 | ||
1378 | /* If the second operand dies, handle that. But if the operands are | |
1379 | the same stack register, don't bother, because only one death is | |
a92771b8 | 1380 | needed, and it was just handled. */ |
535825e6 | 1381 | |
1382 | if (src2_note | |
5e7a3068 | 1383 | && ! (STACK_REG_P (*src1) && STACK_REG_P (*src2) |
535825e6 | 1384 | && REGNO (*src1) == REGNO (*src2))) |
1385 | { | |
1386 | /* As a special case, two regs may die in this insn if src2 is | |
1387 | next to top of stack and the top of stack also dies. Since | |
1388 | we have already popped src1, "next to top of stack" is really | |
a92771b8 | 1389 | at top (FIRST_STACK_REG) now. */ |
535825e6 | 1390 | |
1391 | if (get_hard_regnum (regstack, XEXP (src2_note, 0)) == FIRST_STACK_REG | |
1392 | && src1_note) | |
1393 | { | |
a97edd5b | 1394 | pop_stack (regstack, REGNO (XEXP (src2_note, 0))); |
535825e6 | 1395 | replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG + 1); |
535825e6 | 1396 | } |
1397 | else | |
1398 | { | |
ce71a9e6 | 1399 | /* The 386 can only represent death of the first operand in |
1400 | the case handled above. In all other cases, emit a separate | |
1401 | pop and remove the death note from here. */ | |
1402 | ||
1403 | /* link_cc0_insns (insn); */ | |
1404 | ||
1405 | remove_regno_note (insn, REG_DEAD, REGNO (XEXP (src2_note, 0))); | |
535825e6 | 1406 | |
ce71a9e6 | 1407 | emit_pop_insn (insn, regstack, XEXP (src2_note, 0), |
f3d96a58 | 1408 | EMIT_AFTER); |
535825e6 | 1409 | } |
1410 | } | |
1411 | } | |
1412 | \f | |
1413 | /* Substitute new registers in PAT, which is part of INSN. REGSTACK | |
a92771b8 | 1414 | is the current register layout. */ |
535825e6 | 1415 | |
1416 | static void | |
1417 | subst_stack_regs_pat (insn, regstack, pat) | |
1418 | rtx insn; | |
1419 | stack regstack; | |
1420 | rtx pat; | |
1421 | { | |
1422 | rtx *dest, *src; | |
535825e6 | 1423 | |
f3d96a58 | 1424 | switch (GET_CODE (pat)) |
1425 | { | |
1426 | case USE: | |
1427 | /* Deaths in USE insns can happen in non optimizing compilation. | |
1428 | Handle them by popping the dying register. */ | |
1429 | src = get_true_reg (&XEXP (pat, 0)); | |
2617fe26 | 1430 | if (STACK_REG_P (*src) |
1431 | && find_regno_note (insn, REG_DEAD, REGNO (*src))) | |
1432 | { | |
1433 | emit_pop_insn (insn, regstack, *src, EMIT_AFTER); | |
1434 | return; | |
1435 | } | |
c95cfc31 | 1436 | /* ??? Uninitialized USE should not happen. */ |
f3d96a58 | 1437 | else if (get_hard_regnum (regstack, *src) == -1) |
33181afc | 1438 | abort (); |
f3d96a58 | 1439 | break; |
535825e6 | 1440 | |
f3d96a58 | 1441 | case CLOBBER: |
1442 | { | |
1443 | rtx note; | |
535825e6 | 1444 | |
f3d96a58 | 1445 | dest = get_true_reg (&XEXP (pat, 0)); |
1446 | if (STACK_REG_P (*dest)) | |
1447 | { | |
1448 | note = find_reg_note (insn, REG_DEAD, *dest); | |
631ef7ce | 1449 | |
1450 | if (pat != PATTERN (insn)) | |
1451 | { | |
1452 | /* The fix_truncdi_1 pattern wants to be able to allocate | |
1453 | it's own scratch register. It does this by clobbering | |
1454 | an fp reg so that it is assured of an empty reg-stack | |
2617fe26 | 1455 | register. If the register is live, kill it now. |
631ef7ce | 1456 | Remove the DEAD/UNUSED note so we don't try to kill it |
1457 | later too. */ | |
1458 | ||
1459 | if (note) | |
1460 | emit_pop_insn (insn, regstack, *dest, EMIT_BEFORE); | |
1461 | else | |
1462 | { | |
1463 | note = find_reg_note (insn, REG_UNUSED, *dest); | |
1464 | if (!note) | |
1465 | abort (); | |
1466 | } | |
1467 | remove_note (insn, note); | |
1468 | replace_reg (dest, LAST_STACK_REG); | |
1469 | } | |
f3d96a58 | 1470 | else |
1471 | { | |
631ef7ce | 1472 | /* A top-level clobber with no REG_DEAD, and no hard-regnum |
1473 | indicates an uninitialized value. Because reload removed | |
2617fe26 | 1474 | all other clobbers, this must be due to a function |
631ef7ce | 1475 | returning without a value. Load up a NaN. */ |
1476 | ||
1477 | if (! note | |
1478 | && get_hard_regnum (regstack, *dest) == -1) | |
1479 | { | |
1480 | pat = gen_rtx_SET (VOIDmode, | |
1481 | FP_MODE_REG (REGNO (*dest), SFmode), | |
1482 | nan); | |
1483 | PATTERN (insn) = pat; | |
1484 | move_for_stack_reg (insn, regstack, pat); | |
1485 | } | |
5545a6c8 | 1486 | if (! note && COMPLEX_MODE_P (GET_MODE (*dest)) |
1487 | && get_hard_regnum (regstack, FP_MODE_REG (REGNO (*dest), DFmode)) == -1) | |
1488 | { | |
1489 | pat = gen_rtx_SET (VOIDmode, | |
1490 | FP_MODE_REG (REGNO (*dest) + 1, SFmode), | |
1491 | nan); | |
1492 | PATTERN (insn) = pat; | |
1493 | move_for_stack_reg (insn, regstack, pat); | |
1494 | } | |
f3d96a58 | 1495 | } |
f3d96a58 | 1496 | } |
535825e6 | 1497 | break; |
f3d96a58 | 1498 | } |
535825e6 | 1499 | |
f3d96a58 | 1500 | case SET: |
1501 | { | |
d946ea19 | 1502 | rtx *src1 = (rtx *) 0, *src2; |
f3d96a58 | 1503 | rtx src1_note, src2_note; |
1504 | rtx pat_src; | |
1505 | ||
1506 | dest = get_true_reg (&SET_DEST (pat)); | |
1507 | src = get_true_reg (&SET_SRC (pat)); | |
1508 | pat_src = SET_SRC (pat); | |
1509 | ||
1510 | /* See if this is a `movM' pattern, and handle elsewhere if so. */ | |
1511 | if (STACK_REG_P (*src) | |
1512 | || (STACK_REG_P (*dest) | |
1513 | && (GET_CODE (*src) == REG || GET_CODE (*src) == MEM | |
1514 | || GET_CODE (*src) == CONST_DOUBLE))) | |
1515 | { | |
1516 | move_for_stack_reg (insn, regstack, pat); | |
1517 | break; | |
1518 | } | |
535825e6 | 1519 | |
f3d96a58 | 1520 | switch (GET_CODE (pat_src)) |
1521 | { | |
1522 | case COMPARE: | |
1523 | compare_for_stack_reg (insn, regstack, pat_src); | |
1524 | break; | |
535825e6 | 1525 | |
f3d96a58 | 1526 | case CALL: |
1527 | { | |
1528 | int count; | |
1529 | for (count = HARD_REGNO_NREGS (REGNO (*dest), GET_MODE (*dest)); | |
1530 | --count >= 0;) | |
1531 | { | |
1532 | regstack->reg[++regstack->top] = REGNO (*dest) + count; | |
1533 | SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest) + count); | |
1534 | } | |
1535 | } | |
1536 | replace_reg (dest, FIRST_STACK_REG); | |
1537 | break; | |
535825e6 | 1538 | |
f3d96a58 | 1539 | case REG: |
1540 | /* This is a `tstM2' case. */ | |
1541 | if (*dest != cc0_rtx) | |
1542 | abort (); | |
1543 | src1 = src; | |
535825e6 | 1544 | |
f3d96a58 | 1545 | /* Fall through. */ |
535825e6 | 1546 | |
f3d96a58 | 1547 | case FLOAT_TRUNCATE: |
1548 | case SQRT: | |
1549 | case ABS: | |
1550 | case NEG: | |
1551 | /* These insns only operate on the top of the stack. DEST might | |
1552 | be cc0_rtx if we're processing a tstM pattern. Also, it's | |
1553 | possible that the tstM case results in a REG_DEAD note on the | |
1554 | source. */ | |
535825e6 | 1555 | |
f3d96a58 | 1556 | if (src1 == 0) |
1557 | src1 = get_true_reg (&XEXP (pat_src, 0)); | |
535825e6 | 1558 | |
f3d96a58 | 1559 | emit_swap_insn (insn, regstack, *src1); |
535825e6 | 1560 | |
f3d96a58 | 1561 | src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1)); |
535825e6 | 1562 | |
f3d96a58 | 1563 | if (STACK_REG_P (*dest)) |
1564 | replace_reg (dest, FIRST_STACK_REG); | |
535825e6 | 1565 | |
f3d96a58 | 1566 | if (src1_note) |
1567 | { | |
1568 | replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG); | |
1569 | regstack->top--; | |
1570 | CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1)); | |
1571 | } | |
535825e6 | 1572 | |
f3d96a58 | 1573 | replace_reg (src1, FIRST_STACK_REG); |
1574 | break; | |
535825e6 | 1575 | |
f3d96a58 | 1576 | case MINUS: |
1577 | case DIV: | |
1578 | /* On i386, reversed forms of subM3 and divM3 exist for | |
1579 | MODE_FLOAT, so the same code that works for addM3 and mulM3 | |
1580 | can be used. */ | |
1581 | case MULT: | |
1582 | case PLUS: | |
1583 | /* These insns can accept the top of stack as a destination | |
1584 | from a stack reg or mem, or can use the top of stack as a | |
1585 | source and some other stack register (possibly top of stack) | |
1586 | as a destination. */ | |
1587 | ||
1588 | src1 = get_true_reg (&XEXP (pat_src, 0)); | |
1589 | src2 = get_true_reg (&XEXP (pat_src, 1)); | |
1590 | ||
1591 | /* We will fix any death note later. */ | |
1592 | ||
1593 | if (STACK_REG_P (*src1)) | |
1594 | src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1)); | |
1595 | else | |
1596 | src1_note = NULL_RTX; | |
1597 | if (STACK_REG_P (*src2)) | |
1598 | src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2)); | |
1599 | else | |
1600 | src2_note = NULL_RTX; | |
535825e6 | 1601 | |
f3d96a58 | 1602 | /* If either operand is not a stack register, then the dest |
1603 | must be top of stack. */ | |
535825e6 | 1604 | |
f3d96a58 | 1605 | if (! STACK_REG_P (*src1) || ! STACK_REG_P (*src2)) |
5e7a3068 | 1606 | emit_swap_insn (insn, regstack, *dest); |
f3d96a58 | 1607 | else |
1608 | { | |
1609 | /* Both operands are REG. If neither operand is already | |
1610 | at the top of stack, choose to make the one that is the dest | |
1611 | the new top of stack. */ | |
535825e6 | 1612 | |
f3d96a58 | 1613 | int src1_hard_regnum, src2_hard_regnum; |
535825e6 | 1614 | |
f3d96a58 | 1615 | src1_hard_regnum = get_hard_regnum (regstack, *src1); |
1616 | src2_hard_regnum = get_hard_regnum (regstack, *src2); | |
1617 | if (src1_hard_regnum == -1 || src2_hard_regnum == -1) | |
1618 | abort (); | |
535825e6 | 1619 | |
f3d96a58 | 1620 | if (src1_hard_regnum != FIRST_STACK_REG |
1621 | && src2_hard_regnum != FIRST_STACK_REG) | |
1622 | emit_swap_insn (insn, regstack, *dest); | |
535825e6 | 1623 | } |
f3d96a58 | 1624 | |
1625 | if (STACK_REG_P (*src1)) | |
1626 | replace_reg (src1, get_hard_regnum (regstack, *src1)); | |
1627 | if (STACK_REG_P (*src2)) | |
1628 | replace_reg (src2, get_hard_regnum (regstack, *src2)); | |
1629 | ||
1630 | if (src1_note) | |
535825e6 | 1631 | { |
f3d96a58 | 1632 | rtx src1_reg = XEXP (src1_note, 0); |
535825e6 | 1633 | |
f3d96a58 | 1634 | /* If the register that dies is at the top of stack, then |
1635 | the destination is somewhere else - merely substitute it. | |
1636 | But if the reg that dies is not at top of stack, then | |
1637 | move the top of stack to the dead reg, as though we had | |
1638 | done the insn and then a store-with-pop. */ | |
535825e6 | 1639 | |
f3d96a58 | 1640 | if (REGNO (src1_reg) == regstack->reg[regstack->top]) |
1641 | { | |
1642 | SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest)); | |
1643 | replace_reg (dest, get_hard_regnum (regstack, *dest)); | |
1644 | } | |
1645 | else | |
1646 | { | |
1647 | int regno = get_hard_regnum (regstack, src1_reg); | |
535825e6 | 1648 | |
f3d96a58 | 1649 | SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest)); |
1650 | replace_reg (dest, regno); | |
1651 | ||
1652 | regstack->reg[regstack->top - (regno - FIRST_STACK_REG)] | |
1653 | = regstack->reg[regstack->top]; | |
1654 | } | |
1655 | ||
1656 | CLEAR_HARD_REG_BIT (regstack->reg_set, | |
1657 | REGNO (XEXP (src1_note, 0))); | |
1658 | replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG); | |
1659 | regstack->top--; | |
1660 | } | |
1661 | else if (src2_note) | |
535825e6 | 1662 | { |
f3d96a58 | 1663 | rtx src2_reg = XEXP (src2_note, 0); |
1664 | if (REGNO (src2_reg) == regstack->reg[regstack->top]) | |
1665 | { | |
1666 | SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest)); | |
1667 | replace_reg (dest, get_hard_regnum (regstack, *dest)); | |
1668 | } | |
1669 | else | |
1670 | { | |
1671 | int regno = get_hard_regnum (regstack, src2_reg); | |
1672 | ||
1673 | SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest)); | |
1674 | replace_reg (dest, regno); | |
1675 | ||
1676 | regstack->reg[regstack->top - (regno - FIRST_STACK_REG)] | |
1677 | = regstack->reg[regstack->top]; | |
1678 | } | |
1679 | ||
1680 | CLEAR_HARD_REG_BIT (regstack->reg_set, | |
1681 | REGNO (XEXP (src2_note, 0))); | |
1682 | replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG); | |
1683 | regstack->top--; | |
535825e6 | 1684 | } |
1685 | else | |
1686 | { | |
535825e6 | 1687 | SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest)); |
f3d96a58 | 1688 | replace_reg (dest, get_hard_regnum (regstack, *dest)); |
535825e6 | 1689 | } |
2fa792d7 | 1690 | |
1691 | /* Keep operand 1 maching with destination. */ | |
1692 | if (GET_RTX_CLASS (GET_CODE (pat_src)) == 'c' | |
1693 | && REG_P (*src1) && REG_P (*src2) | |
1694 | && REGNO (*src1) != REGNO (*dest)) | |
1695 | { | |
73ca2d39 | 1696 | int tmp = REGNO (*src1); |
1697 | replace_reg (src1, REGNO (*src2)); | |
1698 | replace_reg (src2, tmp); | |
2fa792d7 | 1699 | } |
f3d96a58 | 1700 | break; |
535825e6 | 1701 | |
f3d96a58 | 1702 | case UNSPEC: |
1703 | switch (XINT (pat_src, 1)) | |
1704 | { | |
372310d2 | 1705 | case UNSPEC_SIN: |
1706 | case UNSPEC_COS: | |
f3d96a58 | 1707 | /* These insns only operate on the top of the stack. */ |
d315aa96 | 1708 | |
f3d96a58 | 1709 | src1 = get_true_reg (&XVECEXP (pat_src, 0, 0)); |
d315aa96 | 1710 | |
f3d96a58 | 1711 | emit_swap_insn (insn, regstack, *src1); |
d315aa96 | 1712 | |
f3d96a58 | 1713 | src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1)); |
d315aa96 | 1714 | |
f3d96a58 | 1715 | if (STACK_REG_P (*dest)) |
1716 | replace_reg (dest, FIRST_STACK_REG); | |
d315aa96 | 1717 | |
f3d96a58 | 1718 | if (src1_note) |
1719 | { | |
1720 | replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG); | |
1721 | regstack->top--; | |
1722 | CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1)); | |
1723 | } | |
d315aa96 | 1724 | |
f3d96a58 | 1725 | replace_reg (src1, FIRST_STACK_REG); |
1726 | break; | |
d315aa96 | 1727 | |
372310d2 | 1728 | case UNSPEC_SAHF: |
1729 | /* (unspec [(unspec [(compare)] UNSPEC_FNSTSW)] UNSPEC_SAHF) | |
1730 | The combination matches the PPRO fcomi instruction. */ | |
d315aa96 | 1731 | |
f3d96a58 | 1732 | pat_src = XVECEXP (pat_src, 0, 0); |
1733 | if (GET_CODE (pat_src) != UNSPEC | |
372310d2 | 1734 | || XINT (pat_src, 1) != UNSPEC_FNSTSW) |
f3d96a58 | 1735 | abort (); |
1736 | /* FALLTHRU */ | |
ce71a9e6 | 1737 | |
372310d2 | 1738 | case UNSPEC_FNSTSW: |
f3d96a58 | 1739 | /* Combined fcomp+fnstsw generated for doing well with |
1740 | CSE. When optimizing this would have been broken | |
1741 | up before now. */ | |
ce71a9e6 | 1742 | |
f3d96a58 | 1743 | pat_src = XVECEXP (pat_src, 0, 0); |
1744 | if (GET_CODE (pat_src) != COMPARE) | |
1745 | abort (); | |
ce71a9e6 | 1746 | |
f3d96a58 | 1747 | compare_for_stack_reg (insn, regstack, pat_src); |
1748 | break; | |
ce71a9e6 | 1749 | |
f3d96a58 | 1750 | default: |
1751 | abort (); | |
1752 | } | |
ce71a9e6 | 1753 | break; |
1754 | ||
f3d96a58 | 1755 | case IF_THEN_ELSE: |
aa40f561 | 1756 | /* This insn requires the top of stack to be the destination. */ |
d315aa96 | 1757 | |
ba126de4 | 1758 | src1 = get_true_reg (&XEXP (pat_src, 1)); |
1759 | src2 = get_true_reg (&XEXP (pat_src, 2)); | |
1760 | ||
1761 | src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1)); | |
1762 | src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2)); | |
1763 | ||
f3d96a58 | 1764 | /* If the comparison operator is an FP comparison operator, |
1765 | it is handled correctly by compare_for_stack_reg () who | |
1766 | will move the destination to the top of stack. But if the | |
1767 | comparison operator is not an FP comparison operator, we | |
aa40f561 | 1768 | have to handle it here. */ |
f3d96a58 | 1769 | if (get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG |
1770 | && REGNO (*dest) != regstack->reg[regstack->top]) | |
ba126de4 | 1771 | { |
1772 | /* In case one of operands is the top of stack and the operands | |
372310d2 | 1773 | dies, it is safe to make it the destination operand by |
1774 | reversing the direction of cmove and avoid fxch. */ | |
ba126de4 | 1775 | if ((REGNO (*src1) == regstack->reg[regstack->top] |
1776 | && src1_note) | |
1777 | || (REGNO (*src2) == regstack->reg[regstack->top] | |
1778 | && src2_note)) | |
1779 | { | |
33e1caad | 1780 | int idx1 = (get_hard_regnum (regstack, *src1) |
1781 | - FIRST_STACK_REG); | |
1782 | int idx2 = (get_hard_regnum (regstack, *src2) | |
1783 | - FIRST_STACK_REG); | |
1784 | ||
1785 | /* Make reg-stack believe that the operands are already | |
1786 | swapped on the stack */ | |
1787 | regstack->reg[regstack->top - idx1] = REGNO (*src2); | |
1788 | regstack->reg[regstack->top - idx2] = REGNO (*src1); | |
1789 | ||
1790 | /* Reverse condition to compensate the operand swap. | |
1791 | i386 do have comparison always reversible. */ | |
ba126de4 | 1792 | PUT_CODE (XEXP (pat_src, 0), |
1793 | reversed_comparison_code (XEXP (pat_src, 0), insn)); | |
1794 | } | |
1795 | else | |
2617fe26 | 1796 | emit_swap_insn (insn, regstack, *dest); |
ba126de4 | 1797 | } |
632c6b15 | 1798 | |
f3d96a58 | 1799 | { |
1800 | rtx src_note [3]; | |
1801 | int i; | |
632c6b15 | 1802 | |
f3d96a58 | 1803 | src_note[0] = 0; |
1804 | src_note[1] = src1_note; | |
1805 | src_note[2] = src2_note; | |
2ff2cb3c | 1806 | |
f3d96a58 | 1807 | if (STACK_REG_P (*src1)) |
1808 | replace_reg (src1, get_hard_regnum (regstack, *src1)); | |
1809 | if (STACK_REG_P (*src2)) | |
1810 | replace_reg (src2, get_hard_regnum (regstack, *src2)); | |
632c6b15 | 1811 | |
f3d96a58 | 1812 | for (i = 1; i <= 2; i++) |
1813 | if (src_note [i]) | |
632c6b15 | 1814 | { |
f3d96a58 | 1815 | int regno = REGNO (XEXP (src_note[i], 0)); |
1816 | ||
1817 | /* If the register that dies is not at the top of | |
1818 | stack, then move the top of stack to the dead reg */ | |
1819 | if (regno != regstack->reg[regstack->top]) | |
1820 | { | |
1821 | remove_regno_note (insn, REG_DEAD, regno); | |
1822 | emit_pop_insn (insn, regstack, XEXP (src_note[i], 0), | |
1823 | EMIT_AFTER); | |
1824 | } | |
1825 | else | |
33e1caad | 1826 | /* Top of stack never dies, as it is the |
1827 | destination. */ | |
1828 | abort (); | |
632c6b15 | 1829 | } |
f3d96a58 | 1830 | } |
632c6b15 | 1831 | |
f3d96a58 | 1832 | /* Make dest the top of stack. Add dest to regstack if |
aa40f561 | 1833 | not present. */ |
f3d96a58 | 1834 | if (get_hard_regnum (regstack, *dest) < FIRST_STACK_REG) |
2617fe26 | 1835 | regstack->reg[++regstack->top] = REGNO (*dest); |
f3d96a58 | 1836 | SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest)); |
1837 | replace_reg (dest, FIRST_STACK_REG); | |
1838 | break; | |
3c8249d9 | 1839 | |
f3d96a58 | 1840 | default: |
1841 | abort (); | |
1842 | } | |
632c6b15 | 1843 | break; |
535825e6 | 1844 | } |
f3d96a58 | 1845 | |
1846 | default: | |
1847 | break; | |
1848 | } | |
535825e6 | 1849 | } |
1850 | \f | |
bed3e6b4 | 1851 | /* Substitute hard regnums for any stack regs in INSN, which has |
1852 | N_INPUTS inputs and N_OUTPUTS outputs. REGSTACK is the stack info | |
78e49515 | 1853 | before the insn, and is updated with changes made here. |
bed3e6b4 | 1854 | |
1855 | There are several requirements and assumptions about the use of | |
1856 | stack-like regs in asm statements. These rules are enforced by | |
1857 | record_asm_stack_regs; see comments there for details. Any | |
1858 | asm_operands left in the RTL at this point may be assume to meet the | |
667a0198 | 1859 | requirements, since record_asm_stack_regs removes any problem asm. */ |
bed3e6b4 | 1860 | |
667a0198 | 1861 | static void |
78e49515 | 1862 | subst_asm_stack_regs (insn, regstack) |
bed3e6b4 | 1863 | rtx insn; |
1864 | stack regstack; | |
bed3e6b4 | 1865 | { |
bed3e6b4 | 1866 | rtx body = PATTERN (insn); |
78e49515 | 1867 | int alt; |
bed3e6b4 | 1868 | |
1869 | rtx *note_reg; /* Array of note contents */ | |
1870 | rtx **note_loc; /* Address of REG field of each note */ | |
1871 | enum reg_note *note_kind; /* The type of each note */ | |
1872 | ||
ef2c4a29 | 1873 | rtx *clobber_reg = 0; |
1874 | rtx **clobber_loc = 0; | |
bed3e6b4 | 1875 | |
1876 | struct stack_def temp_stack; | |
1877 | int n_notes; | |
1878 | int n_clobbers; | |
1879 | rtx note; | |
1880 | int i; | |
78e49515 | 1881 | int n_inputs, n_outputs; |
bed3e6b4 | 1882 | |
f3d96a58 | 1883 | if (! check_asm_stack_operands (insn)) |
1884 | return; | |
1885 | ||
bed3e6b4 | 1886 | /* Find out what the constraints required. If no constraint |
1887 | alternative matches, that is a compiler bug: we should have caught | |
f3d96a58 | 1888 | such an insn in check_asm_stack_operands. */ |
78e49515 | 1889 | extract_insn (insn); |
1890 | constrain_operands (1); | |
1891 | alt = which_alternative; | |
1892 | ||
1893 | preprocess_constraints (); | |
bed3e6b4 | 1894 | |
78e49515 | 1895 | n_inputs = get_asm_operand_n_inputs (body); |
ed420a25 | 1896 | n_outputs = recog_data.n_operands - n_inputs; |
2617fe26 | 1897 | |
78e49515 | 1898 | if (alt < 0) |
bed3e6b4 | 1899 | abort (); |
1900 | ||
a92771b8 | 1901 | /* Strip SUBREGs here to make the following code simpler. */ |
ed420a25 | 1902 | for (i = 0; i < recog_data.n_operands; i++) |
1903 | if (GET_CODE (recog_data.operand[i]) == SUBREG | |
1904 | && GET_CODE (SUBREG_REG (recog_data.operand[i])) == REG) | |
bed3e6b4 | 1905 | { |
ed420a25 | 1906 | recog_data.operand_loc[i] = & SUBREG_REG (recog_data.operand[i]); |
1907 | recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]); | |
bed3e6b4 | 1908 | } |
1909 | ||
1910 | /* Set up NOTE_REG, NOTE_LOC and NOTE_KIND. */ | |
1911 | ||
1912 | for (i = 0, note = REG_NOTES (insn); note; note = XEXP (note, 1)) | |
1913 | i++; | |
1914 | ||
1915 | note_reg = (rtx *) alloca (i * sizeof (rtx)); | |
1916 | note_loc = (rtx **) alloca (i * sizeof (rtx *)); | |
1917 | note_kind = (enum reg_note *) alloca (i * sizeof (enum reg_note)); | |
1918 | ||
1919 | n_notes = 0; | |
1920 | for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) | |
1921 | { | |
1922 | rtx reg = XEXP (note, 0); | |
1923 | rtx *loc = & XEXP (note, 0); | |
1924 | ||
1925 | if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG) | |
1926 | { | |
1927 | loc = & SUBREG_REG (reg); | |
1928 | reg = SUBREG_REG (reg); | |
1929 | } | |
1930 | ||
1931 | if (STACK_REG_P (reg) | |
1932 | && (REG_NOTE_KIND (note) == REG_DEAD | |
1933 | || REG_NOTE_KIND (note) == REG_UNUSED)) | |
1934 | { | |
1935 | note_reg[n_notes] = reg; | |
1936 | note_loc[n_notes] = loc; | |
1937 | note_kind[n_notes] = REG_NOTE_KIND (note); | |
1938 | n_notes++; | |
1939 | } | |
1940 | } | |
1941 | ||
1942 | /* Set up CLOBBER_REG and CLOBBER_LOC. */ | |
1943 | ||
1944 | n_clobbers = 0; | |
bed3e6b4 | 1945 | |
1946 | if (GET_CODE (body) == PARALLEL) | |
fc738e1d | 1947 | { |
7426c2df | 1948 | clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx)); |
1949 | clobber_loc = (rtx **) alloca (XVECLEN (body, 0) * sizeof (rtx *)); | |
bed3e6b4 | 1950 | |
fc738e1d | 1951 | for (i = 0; i < XVECLEN (body, 0); i++) |
1952 | if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER) | |
1953 | { | |
1954 | rtx clobber = XVECEXP (body, 0, i); | |
1955 | rtx reg = XEXP (clobber, 0); | |
1956 | rtx *loc = & XEXP (clobber, 0); | |
bed3e6b4 | 1957 | |
fc738e1d | 1958 | if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG) |
1959 | { | |
1960 | loc = & SUBREG_REG (reg); | |
1961 | reg = SUBREG_REG (reg); | |
1962 | } | |
1963 | ||
1964 | if (STACK_REG_P (reg)) | |
1965 | { | |
1966 | clobber_reg[n_clobbers] = reg; | |
1967 | clobber_loc[n_clobbers] = loc; | |
1968 | n_clobbers++; | |
1969 | } | |
1970 | } | |
1971 | } | |
bed3e6b4 | 1972 | |
f3d96a58 | 1973 | temp_stack = *regstack; |
bed3e6b4 | 1974 | |
1975 | /* Put the input regs into the desired place in TEMP_STACK. */ | |
1976 | ||
78e49515 | 1977 | for (i = n_outputs; i < n_outputs + n_inputs; i++) |
ed420a25 | 1978 | if (STACK_REG_P (recog_data.operand[i]) |
78e49515 | 1979 | && reg_class_subset_p (recog_op_alt[i][alt].class, |
1980 | FLOAT_REGS) | |
1981 | && recog_op_alt[i][alt].class != FLOAT_REGS) | |
bed3e6b4 | 1982 | { |
1983 | /* If an operand needs to be in a particular reg in | |
1984 | FLOAT_REGS, the constraint was either 't' or 'u'. Since | |
ed420a25 | 1985 | these constraints are for single register classes, and |
1986 | reload guaranteed that operand[i] is already in that class, | |
1987 | we can just use REGNO (recog_data.operand[i]) to know which | |
1988 | actual reg this operand needs to be in. */ | |
bed3e6b4 | 1989 | |
ed420a25 | 1990 | int regno = get_hard_regnum (&temp_stack, recog_data.operand[i]); |
bed3e6b4 | 1991 | |
1992 | if (regno < 0) | |
1993 | abort (); | |
1994 | ||
97b330ca | 1995 | if ((unsigned int) regno != REGNO (recog_data.operand[i])) |
bed3e6b4 | 1996 | { |
ed420a25 | 1997 | /* recog_data.operand[i] is not in the right place. Find |
1998 | it and swap it with whatever is already in I's place. | |
1999 | K is where recog_data.operand[i] is now. J is where it | |
2000 | should be. */ | |
bed3e6b4 | 2001 | int j, k, temp; |
2002 | ||
2003 | k = temp_stack.top - (regno - FIRST_STACK_REG); | |
2004 | j = (temp_stack.top | |
ed420a25 | 2005 | - (REGNO (recog_data.operand[i]) - FIRST_STACK_REG)); |
bed3e6b4 | 2006 | |
2007 | temp = temp_stack.reg[k]; | |
2008 | temp_stack.reg[k] = temp_stack.reg[j]; | |
2009 | temp_stack.reg[j] = temp; | |
2010 | } | |
2011 | } | |
2012 | ||
f3d96a58 | 2013 | /* Emit insns before INSN to make sure the reg-stack is in the right |
bed3e6b4 | 2014 | order. */ |
2015 | ||
f3d96a58 | 2016 | change_stack (insn, regstack, &temp_stack, EMIT_BEFORE); |
bed3e6b4 | 2017 | |
2018 | /* Make the needed input register substitutions. Do death notes and | |
a92771b8 | 2019 | clobbers too, because these are for inputs, not outputs. */ |
bed3e6b4 | 2020 | |
78e49515 | 2021 | for (i = n_outputs; i < n_outputs + n_inputs; i++) |
ed420a25 | 2022 | if (STACK_REG_P (recog_data.operand[i])) |
bed3e6b4 | 2023 | { |
ed420a25 | 2024 | int regnum = get_hard_regnum (regstack, recog_data.operand[i]); |
bed3e6b4 | 2025 | |
2026 | if (regnum < 0) | |
2027 | abort (); | |
2028 | ||
ed420a25 | 2029 | replace_reg (recog_data.operand_loc[i], regnum); |
bed3e6b4 | 2030 | } |
2031 | ||
2032 | for (i = 0; i < n_notes; i++) | |
2033 | if (note_kind[i] == REG_DEAD) | |
2034 | { | |
2035 | int regnum = get_hard_regnum (regstack, note_reg[i]); | |
2036 | ||
2037 | if (regnum < 0) | |
2038 | abort (); | |
2039 | ||
2040 | replace_reg (note_loc[i], regnum); | |
2041 | } | |
2042 | ||
2043 | for (i = 0; i < n_clobbers; i++) | |
2044 | { | |
2045 | /* It's OK for a CLOBBER to reference a reg that is not live. | |
2046 | Don't try to replace it in that case. */ | |
2047 | int regnum = get_hard_regnum (regstack, clobber_reg[i]); | |
2048 | ||
2049 | if (regnum >= 0) | |
2050 | { | |
2051 | /* Sigh - clobbers always have QImode. But replace_reg knows | |
2052 | that these regs can't be MODE_INT and will abort. Just put | |
2053 | the right reg there without calling replace_reg. */ | |
2054 | ||
a5dff55e | 2055 | *clobber_loc[i] = FP_MODE_REG (regnum, DFmode); |
bed3e6b4 | 2056 | } |
2057 | } | |
2058 | ||
a92771b8 | 2059 | /* Now remove from REGSTACK any inputs that the asm implicitly popped. */ |
bed3e6b4 | 2060 | |
78e49515 | 2061 | for (i = n_outputs; i < n_outputs + n_inputs; i++) |
ed420a25 | 2062 | if (STACK_REG_P (recog_data.operand[i])) |
bed3e6b4 | 2063 | { |
2064 | /* An input reg is implicitly popped if it is tied to an | |
a92771b8 | 2065 | output, or if there is a CLOBBER for it. */ |
bed3e6b4 | 2066 | int j; |
2067 | ||
2068 | for (j = 0; j < n_clobbers; j++) | |
ed420a25 | 2069 | if (operands_match_p (clobber_reg[j], recog_data.operand[i])) |
bed3e6b4 | 2070 | break; |
2071 | ||
78e49515 | 2072 | if (j < n_clobbers || recog_op_alt[i][alt].matches >= 0) |
bed3e6b4 | 2073 | { |
ed420a25 | 2074 | /* recog_data.operand[i] might not be at the top of stack. |
2075 | But that's OK, because all we need to do is pop the | |
2076 | right number of regs off of the top of the reg-stack. | |
2077 | record_asm_stack_regs guaranteed that all implicitly | |
2078 | popped regs were grouped at the top of the reg-stack. */ | |
bed3e6b4 | 2079 | |
2080 | CLEAR_HARD_REG_BIT (regstack->reg_set, | |
2081 | regstack->reg[regstack->top]); | |
2082 | regstack->top--; | |
2083 | } | |
2084 | } | |
2085 | ||
2086 | /* Now add to REGSTACK any outputs that the asm implicitly pushed. | |
2087 | Note that there isn't any need to substitute register numbers. | |
a92771b8 | 2088 | ??? Explain why this is true. */ |
bed3e6b4 | 2089 | |
2090 | for (i = LAST_STACK_REG; i >= FIRST_STACK_REG; i--) | |
2091 | { | |
2092 | /* See if there is an output for this hard reg. */ | |
2093 | int j; | |
2094 | ||
2095 | for (j = 0; j < n_outputs; j++) | |
ed420a25 | 2096 | if (STACK_REG_P (recog_data.operand[j]) |
97b330ca | 2097 | && REGNO (recog_data.operand[j]) == (unsigned) i) |
bed3e6b4 | 2098 | { |
2099 | regstack->reg[++regstack->top] = i; | |
2100 | SET_HARD_REG_BIT (regstack->reg_set, i); | |
2101 | break; | |
2102 | } | |
2103 | } | |
2104 | ||
2105 | /* Now emit a pop insn for any REG_UNUSED output, or any REG_DEAD | |
2106 | input that the asm didn't implicitly pop. If the asm didn't | |
fc738e1d | 2107 | implicitly pop an input reg, that reg will still be live. |
bed3e6b4 | 2108 | |
2109 | Note that we can't use find_regno_note here: the register numbers | |
2110 | in the death notes have already been substituted. */ | |
2111 | ||
fc738e1d | 2112 | for (i = 0; i < n_outputs; i++) |
ed420a25 | 2113 | if (STACK_REG_P (recog_data.operand[i])) |
fc738e1d | 2114 | { |
2115 | int j; | |
2116 | ||
2117 | for (j = 0; j < n_notes; j++) | |
ed420a25 | 2118 | if (REGNO (recog_data.operand[i]) == REGNO (note_reg[j]) |
fc738e1d | 2119 | && note_kind[j] == REG_UNUSED) |
2120 | { | |
ed420a25 | 2121 | insn = emit_pop_insn (insn, regstack, recog_data.operand[i], |
f3d96a58 | 2122 | EMIT_AFTER); |
fc738e1d | 2123 | break; |
2124 | } | |
2125 | } | |
2126 | ||
78e49515 | 2127 | for (i = n_outputs; i < n_outputs + n_inputs; i++) |
ed420a25 | 2128 | if (STACK_REG_P (recog_data.operand[i])) |
bed3e6b4 | 2129 | { |
2130 | int j; | |
2131 | ||
2132 | for (j = 0; j < n_notes; j++) | |
ed420a25 | 2133 | if (REGNO (recog_data.operand[i]) == REGNO (note_reg[j]) |
fc738e1d | 2134 | && note_kind[j] == REG_DEAD |
78e49515 | 2135 | && TEST_HARD_REG_BIT (regstack->reg_set, |
ed420a25 | 2136 | REGNO (recog_data.operand[i]))) |
bed3e6b4 | 2137 | { |
ed420a25 | 2138 | insn = emit_pop_insn (insn, regstack, recog_data.operand[i], |
f3d96a58 | 2139 | EMIT_AFTER); |
bed3e6b4 | 2140 | break; |
2141 | } | |
2142 | } | |
2143 | } | |
2144 | \f | |
535825e6 | 2145 | /* Substitute stack hard reg numbers for stack virtual registers in |
2146 | INSN. Non-stack register numbers are not changed. REGSTACK is the | |
2147 | current stack content. Insns may be emitted as needed to arrange the | |
667a0198 | 2148 | stack for the 387 based on the contents of the insn. */ |
6f3ee61d | 2149 | |
667a0198 | 2150 | static void |
535825e6 | 2151 | subst_stack_regs (insn, regstack) |
2152 | rtx insn; | |
2153 | stack regstack; | |
2154 | { | |
19cb6b50 | 2155 | rtx *note_link, note; |
2156 | int i; | |
535825e6 | 2157 | |
a5dff55e | 2158 | if (GET_CODE (insn) == CALL_INSN) |
ce71a9e6 | 2159 | { |
2160 | int top = regstack->top; | |
535825e6 | 2161 | |
ce71a9e6 | 2162 | /* If there are any floating point parameters to be passed in |
2163 | registers for this call, make sure they are in the right | |
2164 | order. */ | |
535825e6 | 2165 | |
ce71a9e6 | 2166 | if (top >= 0) |
2167 | { | |
2168 | straighten_stack (PREV_INSN (insn), regstack); | |
a5dff55e | 2169 | |
ce71a9e6 | 2170 | /* Now mark the arguments as dead after the call. */ |
a5dff55e | 2171 | |
ce71a9e6 | 2172 | while (regstack->top >= 0) |
2173 | { | |
2174 | CLEAR_HARD_REG_BIT (regstack->reg_set, FIRST_STACK_REG + regstack->top); | |
2175 | regstack->top--; | |
2176 | } | |
2177 | } | |
2178 | } | |
535825e6 | 2179 | |
2180 | /* Do the actual substitution if any stack regs are mentioned. | |
2181 | Since we only record whether entire insn mentions stack regs, and | |
2182 | subst_stack_regs_pat only works for patterns that contain stack regs, | |
2183 | we must check each pattern in a parallel here. A call_value_pop could | |
a92771b8 | 2184 | fail otherwise. */ |
535825e6 | 2185 | |
b67ec609 | 2186 | if (stack_regs_mentioned (insn)) |
535825e6 | 2187 | { |
78e49515 | 2188 | int n_operands = asm_noperands (PATTERN (insn)); |
bed3e6b4 | 2189 | if (n_operands >= 0) |
2190 | { | |
2191 | /* This insn is an `asm' with operands. Decode the operands, | |
2192 | decide how many are inputs, and do register substitution. | |
a92771b8 | 2193 | Any REG_UNUSED notes will be handled by subst_asm_stack_regs. */ |
bed3e6b4 | 2194 | |
78e49515 | 2195 | subst_asm_stack_regs (insn, regstack); |
667a0198 | 2196 | return; |
bed3e6b4 | 2197 | } |
2198 | ||
535825e6 | 2199 | if (GET_CODE (PATTERN (insn)) == PARALLEL) |
d3115c90 | 2200 | for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++) |
535825e6 | 2201 | { |
2202 | if (stack_regs_mentioned_p (XVECEXP (PATTERN (insn), 0, i))) | |
ce71a9e6 | 2203 | subst_stack_regs_pat (insn, regstack, |
2204 | XVECEXP (PATTERN (insn), 0, i)); | |
535825e6 | 2205 | } |
2206 | else | |
2207 | subst_stack_regs_pat (insn, regstack, PATTERN (insn)); | |
2208 | } | |
2209 | ||
2210 | /* subst_stack_regs_pat may have deleted a no-op insn. If so, any | |
a92771b8 | 2211 | REG_UNUSED will already have been dealt with, so just return. */ |
535825e6 | 2212 | |
5192f3ed | 2213 | if (GET_CODE (insn) == NOTE || INSN_DELETED_P (insn)) |
667a0198 | 2214 | return; |
535825e6 | 2215 | |
2216 | /* If there is a REG_UNUSED note on a stack register on this insn, | |
2217 | the indicated reg must be popped. The REG_UNUSED note is removed, | |
2218 | since the form of the newly emitted pop insn references the reg, | |
a92771b8 | 2219 | making it no longer `unset'. */ |
535825e6 | 2220 | |
337d789b | 2221 | note_link = ®_NOTES (insn); |
535825e6 | 2222 | for (note = *note_link; note; note = XEXP (note, 1)) |
2223 | if (REG_NOTE_KIND (note) == REG_UNUSED && STACK_REG_P (XEXP (note, 0))) | |
2224 | { | |
2225 | *note_link = XEXP (note, 1); | |
f3d96a58 | 2226 | insn = emit_pop_insn (insn, regstack, XEXP (note, 0), EMIT_AFTER); |
535825e6 | 2227 | } |
2228 | else | |
2229 | note_link = &XEXP (note, 1); | |
2230 | } | |
2231 | \f | |
2232 | /* Change the organization of the stack so that it fits a new basic | |
2233 | block. Some registers might have to be popped, but there can never be | |
2234 | a register live in the new block that is not now live. | |
2235 | ||
f3d96a58 | 2236 | Insert any needed insns before or after INSN, as indicated by |
2237 | WHERE. OLD is the original stack layout, and NEW is the desired | |
2238 | form. OLD is updated to reflect the code emitted, ie, it will be | |
2239 | the same as NEW upon return. | |
535825e6 | 2240 | |
2241 | This function will not preserve block_end[]. But that information | |
a92771b8 | 2242 | is no longer needed once this has executed. */ |
535825e6 | 2243 | |
2244 | static void | |
f3d96a58 | 2245 | change_stack (insn, old, new, where) |
535825e6 | 2246 | rtx insn; |
2247 | stack old; | |
2248 | stack new; | |
f3d96a58 | 2249 | enum emit_where where; |
535825e6 | 2250 | { |
2251 | int reg; | |
f3d96a58 | 2252 | int update_end = 0; |
535825e6 | 2253 | |
f3d96a58 | 2254 | /* We will be inserting new insns "backwards". If we are to insert |
2255 | after INSN, find the next insn, and insert before it. */ | |
535825e6 | 2256 | |
f3d96a58 | 2257 | if (where == EMIT_AFTER) |
2258 | { | |
2259 | if (current_block && current_block->end == insn) | |
2260 | update_end = 1; | |
2261 | insn = NEXT_INSN (insn); | |
2262 | } | |
535825e6 | 2263 | |
a92771b8 | 2264 | /* Pop any registers that are not needed in the new block. */ |
535825e6 | 2265 | |
2266 | for (reg = old->top; reg >= 0; reg--) | |
2267 | if (! TEST_HARD_REG_BIT (new->reg_set, old->reg[reg])) | |
a5dff55e | 2268 | emit_pop_insn (insn, old, FP_MODE_REG (old->reg[reg], DFmode), |
f3d96a58 | 2269 | EMIT_BEFORE); |
535825e6 | 2270 | |
2271 | if (new->top == -2) | |
2272 | { | |
2273 | /* If the new block has never been processed, then it can inherit | |
a92771b8 | 2274 | the old stack order. */ |
535825e6 | 2275 | |
2276 | new->top = old->top; | |
f3d96a58 | 2277 | memcpy (new->reg, old->reg, sizeof (new->reg)); |
535825e6 | 2278 | } |
2279 | else | |
2280 | { | |
2281 | /* This block has been entered before, and we must match the | |
a92771b8 | 2282 | previously selected stack order. */ |
535825e6 | 2283 | |
2284 | /* By now, the only difference should be the order of the stack, | |
a92771b8 | 2285 | not their depth or liveliness. */ |
535825e6 | 2286 | |
2287 | GO_IF_HARD_REG_EQUAL (old->reg_set, new->reg_set, win); | |
535825e6 | 2288 | abort (); |
535825e6 | 2289 | win: |
535825e6 | 2290 | if (old->top != new->top) |
2291 | abort (); | |
2292 | ||
ce531cb7 | 2293 | /* If the stack is not empty (new->top != -1), loop here emitting |
2617fe26 | 2294 | swaps until the stack is correct. |
ce531cb7 | 2295 | |
2296 | The worst case number of swaps emitted is N + 2, where N is the | |
535825e6 | 2297 | depth of the stack. In some cases, the reg at the top of |
2298 | stack may be correct, but swapped anyway in order to fix | |
2299 | other regs. But since we never swap any other reg away from | |
a92771b8 | 2300 | its correct slot, this algorithm will converge. */ |
535825e6 | 2301 | |
ce531cb7 | 2302 | if (new->top != -1) |
2303 | do | |
2304 | { | |
2305 | /* Swap the reg at top of stack into the position it is | |
2306 | supposed to be in, until the correct top of stack appears. */ | |
535825e6 | 2307 | |
ce531cb7 | 2308 | while (old->reg[old->top] != new->reg[new->top]) |
2309 | { | |
2310 | for (reg = new->top; reg >= 0; reg--) | |
2311 | if (new->reg[reg] == old->reg[old->top]) | |
2312 | break; | |
535825e6 | 2313 | |
ce531cb7 | 2314 | if (reg == -1) |
2315 | abort (); | |
535825e6 | 2316 | |
ce531cb7 | 2317 | emit_swap_insn (insn, old, |
2318 | FP_MODE_REG (old->reg[reg], DFmode)); | |
2319 | } | |
535825e6 | 2320 | |
ce531cb7 | 2321 | /* See if any regs remain incorrect. If so, bring an |
535825e6 | 2322 | incorrect reg to the top of stack, and let the while loop |
a92771b8 | 2323 | above fix it. */ |
535825e6 | 2324 | |
ce531cb7 | 2325 | for (reg = new->top; reg >= 0; reg--) |
2326 | if (new->reg[reg] != old->reg[reg]) | |
2327 | { | |
2328 | emit_swap_insn (insn, old, | |
2329 | FP_MODE_REG (old->reg[reg], DFmode)); | |
2330 | break; | |
2331 | } | |
2332 | } while (reg >= 0); | |
535825e6 | 2333 | |
a92771b8 | 2334 | /* At this point there must be no differences. */ |
535825e6 | 2335 | |
2336 | for (reg = old->top; reg >= 0; reg--) | |
2337 | if (old->reg[reg] != new->reg[reg]) | |
2338 | abort (); | |
2339 | } | |
f3d96a58 | 2340 | |
2341 | if (update_end) | |
2342 | current_block->end = PREV_INSN (insn); | |
535825e6 | 2343 | } |
2344 | \f | |
f3d96a58 | 2345 | /* Print stack configuration. */ |
535825e6 | 2346 | |
2347 | static void | |
f3d96a58 | 2348 | print_stack (file, s) |
2349 | FILE *file; | |
2350 | stack s; | |
535825e6 | 2351 | { |
f3d96a58 | 2352 | if (! file) |
2353 | return; | |
535825e6 | 2354 | |
f3d96a58 | 2355 | if (s->top == -2) |
2356 | fprintf (file, "uninitialized\n"); | |
2357 | else if (s->top == -1) | |
2358 | fprintf (file, "empty\n"); | |
2359 | else | |
ce71a9e6 | 2360 | { |
f3d96a58 | 2361 | int i; |
2362 | fputs ("[ ", file); | |
2363 | for (i = 0; i <= s->top; ++i) | |
2364 | fprintf (file, "%d ", s->reg[i]); | |
2365 | fputs ("]\n", file); | |
ce71a9e6 | 2366 | } |
f3d96a58 | 2367 | } |
2368 | \f | |
2369 | /* This function was doing life analysis. We now let the regular live | |
2617fe26 | 2370 | code do it's job, so we only need to check some extra invariants |
f3d96a58 | 2371 | that reg-stack expects. Primary among these being that all registers |
2372 | are initialized before use. | |
535825e6 | 2373 | |
f3d96a58 | 2374 | The function returns true when code was emitted to CFG edges and |
2375 | commit_edge_insertions needs to be called. */ | |
535825e6 | 2376 | |
f3d96a58 | 2377 | static int |
2378 | convert_regs_entry () | |
2379 | { | |
4c26117a | 2380 | int inserted = 0; |
f3d96a58 | 2381 | edge e; |
4c26117a | 2382 | basic_block block; |
535825e6 | 2383 | |
4c26117a | 2384 | FOR_EACH_BB_REVERSE (block) |
535825e6 | 2385 | { |
f3d96a58 | 2386 | block_info bi = BLOCK_INFO (block); |
2387 | int reg; | |
2617fe26 | 2388 | |
f3d96a58 | 2389 | /* Set current register status at last instruction `uninitialized'. */ |
2390 | bi->stack_in.top = -2; | |
2617fe26 | 2391 | |
f3d96a58 | 2392 | /* Copy live_at_end and live_at_start into temporaries. */ |
2393 | for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++) | |
535825e6 | 2394 | { |
f3d96a58 | 2395 | if (REGNO_REG_SET_P (block->global_live_at_end, reg)) |
2396 | SET_HARD_REG_BIT (bi->out_reg_set, reg); | |
2397 | if (REGNO_REG_SET_P (block->global_live_at_start, reg)) | |
2398 | SET_HARD_REG_BIT (bi->stack_in.reg_set, reg); | |
535825e6 | 2399 | } |
2400 | } | |
535825e6 | 2401 | |
2617fe26 | 2402 | /* Load something into each stack register live at function entry. |
f3d96a58 | 2403 | Such live registers can be caused by uninitialized variables or |
2617fe26 | 2404 | functions not returning values on all paths. In order to keep |
f3d96a58 | 2405 | the push/pop code happy, and to not scrog the register stack, we |
2617fe26 | 2406 | must put something in these registers. Use a QNaN. |
535825e6 | 2407 | |
f3d96a58 | 2408 | Note that we are insertting converted code here. This code is |
2409 | never seen by the convert_regs pass. */ | |
535825e6 | 2410 | |
f3d96a58 | 2411 | for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next) |
2412 | { | |
2413 | basic_block block = e->dest; | |
2414 | block_info bi = BLOCK_INFO (block); | |
2415 | int reg, top = -1; | |
535825e6 | 2416 | |
f3d96a58 | 2417 | for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg) |
2418 | if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg)) | |
2419 | { | |
2420 | rtx init; | |
535825e6 | 2421 | |
f3d96a58 | 2422 | bi->stack_in.reg[++top] = reg; |
535825e6 | 2423 | |
f3d96a58 | 2424 | init = gen_rtx_SET (VOIDmode, |
2425 | FP_MODE_REG (FIRST_STACK_REG, SFmode), | |
2426 | nan); | |
2427 | insert_insn_on_edge (init, e); | |
2428 | inserted = 1; | |
2429 | } | |
535825e6 | 2430 | |
f3d96a58 | 2431 | bi->stack_in.top = top; |
2432 | } | |
535825e6 | 2433 | |
f3d96a58 | 2434 | return inserted; |
2435 | } | |
535825e6 | 2436 | |
f3d96a58 | 2437 | /* Construct the desired stack for function exit. This will either |
2438 | be `empty', or the function return value at top-of-stack. */ | |
535825e6 | 2439 | |
f3d96a58 | 2440 | static void |
2441 | convert_regs_exit () | |
2442 | { | |
2443 | int value_reg_low, value_reg_high; | |
2444 | stack output_stack; | |
2445 | rtx retvalue; | |
535825e6 | 2446 | |
f3d96a58 | 2447 | retvalue = stack_result (current_function_decl); |
2448 | value_reg_low = value_reg_high = -1; | |
2449 | if (retvalue) | |
2450 | { | |
2451 | value_reg_low = REGNO (retvalue); | |
2452 | value_reg_high = value_reg_low | |
2453 | + HARD_REGNO_NREGS (value_reg_low, GET_MODE (retvalue)) - 1; | |
2454 | } | |
535825e6 | 2455 | |
f3d96a58 | 2456 | output_stack = &BLOCK_INFO (EXIT_BLOCK_PTR)->stack_in; |
2457 | if (value_reg_low == -1) | |
2458 | output_stack->top = -1; | |
2459 | else | |
2460 | { | |
2461 | int reg; | |
535825e6 | 2462 | |
f3d96a58 | 2463 | output_stack->top = value_reg_high - value_reg_low; |
2464 | for (reg = value_reg_low; reg <= value_reg_high; ++reg) | |
2465 | { | |
2466 | output_stack->reg[reg - value_reg_low] = reg; | |
2467 | SET_HARD_REG_BIT (output_stack->reg_set, reg); | |
2468 | } | |
2469 | } | |
535825e6 | 2470 | } |
535825e6 | 2471 | |
ecb7b891 | 2472 | /* Adjust the stack of this block on exit to match the stack of the |
2473 | target block, or copy stack info into the stack of the successor | |
2474 | of the successor hasn't been processed yet. */ | |
2475 | static bool | |
2476 | compensate_edge (e, file) | |
2477 | edge e; | |
2478 | FILE *file; | |
2479 | { | |
2480 | basic_block block = e->src, target = e->dest; | |
2481 | block_info bi = BLOCK_INFO (block); | |
2482 | struct stack_def regstack, tmpstack; | |
2483 | stack target_stack = &BLOCK_INFO (target)->stack_in; | |
2484 | int reg; | |
2485 | ||
2486 | current_block = block; | |
2487 | regstack = bi->stack_out; | |
2488 | if (file) | |
b3d6de89 | 2489 | fprintf (file, "Edge %d->%d: ", block->index, target->index); |
ecb7b891 | 2490 | |
2491 | if (target_stack->top == -2) | |
2492 | { | |
2493 | /* The target block hasn't had a stack order selected. | |
2494 | We need merely ensure that no pops are needed. */ | |
2495 | for (reg = regstack.top; reg >= 0; --reg) | |
2496 | if (!TEST_HARD_REG_BIT (target_stack->reg_set, regstack.reg[reg])) | |
2497 | break; | |
2498 | ||
2499 | if (reg == -1) | |
2500 | { | |
2501 | if (file) | |
2502 | fprintf (file, "new block; copying stack position\n"); | |
2503 | ||
2504 | /* change_stack kills values in regstack. */ | |
2505 | tmpstack = regstack; | |
2506 | ||
2507 | change_stack (block->end, &tmpstack, target_stack, EMIT_AFTER); | |
2617fe26 | 2508 | return false; |
ecb7b891 | 2509 | } |
2510 | ||
2511 | if (file) | |
2512 | fprintf (file, "new block; pops needed\n"); | |
2513 | } | |
2514 | else | |
2515 | { | |
2516 | if (target_stack->top == regstack.top) | |
2517 | { | |
2518 | for (reg = target_stack->top; reg >= 0; --reg) | |
2519 | if (target_stack->reg[reg] != regstack.reg[reg]) | |
2520 | break; | |
2521 | ||
2522 | if (reg == -1) | |
2523 | { | |
2524 | if (file) | |
2525 | fprintf (file, "no changes needed\n"); | |
2526 | return false; | |
2527 | } | |
2528 | } | |
2529 | ||
2530 | if (file) | |
2531 | { | |
2532 | fprintf (file, "correcting stack to "); | |
2533 | print_stack (file, target_stack); | |
2534 | } | |
2535 | } | |
2536 | ||
2537 | /* Care for non-call EH edges specially. The normal return path have | |
2538 | values in registers. These will be popped en masse by the unwind | |
2539 | library. */ | |
2540 | if ((e->flags & (EDGE_EH | EDGE_ABNORMAL_CALL)) == EDGE_EH) | |
2541 | target_stack->top = -1; | |
2542 | ||
2543 | /* Other calls may appear to have values live in st(0), but the | |
2544 | abnormal return path will not have actually loaded the values. */ | |
2545 | else if (e->flags & EDGE_ABNORMAL_CALL) | |
2546 | { | |
2547 | /* Assert that the lifetimes are as we expect -- one value | |
2548 | live at st(0) on the end of the source block, and no | |
2549 | values live at the beginning of the destination block. */ | |
2550 | HARD_REG_SET tmp; | |
2551 | ||
2552 | CLEAR_HARD_REG_SET (tmp); | |
2553 | GO_IF_HARD_REG_EQUAL (target_stack->reg_set, tmp, eh1); | |
2554 | abort (); | |
2555 | eh1: | |
2556 | ||
2557 | SET_HARD_REG_BIT (tmp, FIRST_STACK_REG); | |
2558 | GO_IF_HARD_REG_EQUAL (regstack.reg_set, tmp, eh2); | |
2559 | abort (); | |
2560 | eh2: | |
2561 | ||
2562 | target_stack->top = -1; | |
2563 | } | |
2564 | ||
2565 | /* It is better to output directly to the end of the block | |
2566 | instead of to the edge, because emit_swap can do minimal | |
2567 | insn scheduling. We can do this when there is only one | |
2568 | edge out, and it is not abnormal. */ | |
2569 | else if (block->succ->succ_next == NULL && !(e->flags & EDGE_ABNORMAL)) | |
2570 | { | |
2571 | /* change_stack kills values in regstack. */ | |
2572 | tmpstack = regstack; | |
2573 | ||
2574 | change_stack (block->end, &tmpstack, target_stack, | |
2575 | (GET_CODE (block->end) == JUMP_INSN | |
2576 | ? EMIT_BEFORE : EMIT_AFTER)); | |
2577 | } | |
2578 | else | |
2579 | { | |
2580 | rtx seq, after; | |
2581 | ||
2582 | /* We don't support abnormal edges. Global takes care to | |
2583 | avoid any live register across them, so we should never | |
2584 | have to insert instructions on such edges. */ | |
2585 | if (e->flags & EDGE_ABNORMAL) | |
2586 | abort (); | |
2587 | ||
2588 | current_block = NULL; | |
2589 | start_sequence (); | |
2590 | ||
2617fe26 | 2591 | /* ??? change_stack needs some point to emit insns after. |
2592 | Also needed to keep gen_sequence from returning a | |
ecb7b891 | 2593 | pattern as opposed to a sequence, which would lose |
2594 | REG_DEAD notes. */ | |
2595 | after = emit_note (NULL, NOTE_INSN_DELETED); | |
2596 | ||
2597 | tmpstack = regstack; | |
2598 | change_stack (after, &tmpstack, target_stack, EMIT_BEFORE); | |
2599 | ||
2600 | seq = gen_sequence (); | |
2601 | end_sequence (); | |
2602 | ||
2603 | insert_insn_on_edge (seq, e); | |
2604 | return true; | |
2605 | } | |
2606 | return false; | |
2607 | } | |
2608 | ||
f3d96a58 | 2609 | /* Convert stack register references in one block. */ |
2610 | ||
2611 | static int | |
2612 | convert_regs_1 (file, block) | |
2613 | FILE *file; | |
2614 | basic_block block; | |
535825e6 | 2615 | { |
ecb7b891 | 2616 | struct stack_def regstack; |
f3d96a58 | 2617 | block_info bi = BLOCK_INFO (block); |
2618 | int inserted, reg; | |
2619 | rtx insn, next; | |
ecb7b891 | 2620 | edge e, beste = NULL; |
535825e6 | 2621 | |
ecb7b891 | 2622 | inserted = 0; |
2623 | ||
2624 | /* Find the edge we will copy stack from. It should be the most frequent | |
2625 | one as it will get cheapest after compensation code is generated, | |
424da949 | 2626 | if multiple such exists, take one with largest count, prefer critical |
ecb7b891 | 2627 | one (as splitting critical edges is more expensive), or one with lowest |
2628 | index, to avoid random changes with different orders of the edges. */ | |
2629 | for (e = block->pred; e ; e = e->pred_next) | |
2630 | { | |
2631 | if (e->flags & EDGE_DFS_BACK) | |
2632 | ; | |
2633 | else if (! beste) | |
2634 | beste = e; | |
2635 | else if (EDGE_FREQUENCY (beste) < EDGE_FREQUENCY (e)) | |
2636 | beste = e; | |
4f3ad672 | 2637 | else if (EDGE_FREQUENCY (beste) > EDGE_FREQUENCY (e)) |
2638 | ; | |
ecb7b891 | 2639 | else if (beste->count < e->count) |
2640 | beste = e; | |
2641 | else if (beste->count > e->count) | |
2642 | ; | |
e76f35e8 | 2643 | else if ((EDGE_CRITICAL_P (e) != 0) |
2644 | != (EDGE_CRITICAL_P (beste) != 0)) | |
ecb7b891 | 2645 | { |
e76f35e8 | 2646 | if (EDGE_CRITICAL_P (e)) |
ecb7b891 | 2647 | beste = e; |
2648 | } | |
b3d6de89 | 2649 | else if (e->src->index < beste->src->index) |
ecb7b891 | 2650 | beste = e; |
2651 | } | |
2652 | ||
2653 | /* Entry block does have stack already initialized. */ | |
2654 | if (bi->stack_in.top == -2) | |
2655 | inserted |= compensate_edge (beste, file); | |
2656 | else | |
2657 | beste = NULL; | |
2617fe26 | 2658 | |
ecb7b891 | 2659 | current_block = block; |
2660 | ||
f3d96a58 | 2661 | if (file) |
535825e6 | 2662 | { |
b3d6de89 | 2663 | fprintf (file, "\nBasic block %d\nInput stack: ", block->index); |
f3d96a58 | 2664 | print_stack (file, &bi->stack_in); |
2665 | } | |
535825e6 | 2666 | |
f3d96a58 | 2667 | /* Process all insns in this block. Keep track of NEXT so that we |
2668 | don't process insns emitted while substituting in INSN. */ | |
2669 | next = block->head; | |
2670 | regstack = bi->stack_in; | |
2671 | do | |
2672 | { | |
2673 | insn = next; | |
2674 | next = NEXT_INSN (insn); | |
535825e6 | 2675 | |
f3d96a58 | 2676 | /* Ensure we have not missed a block boundary. */ |
2677 | if (next == NULL) | |
2678 | abort (); | |
2679 | if (insn == block->end) | |
2680 | next = NULL; | |
2681 | ||
2682 | /* Don't bother processing unless there is a stack reg | |
2683 | mentioned or if it's a CALL_INSN. */ | |
2684 | if (stack_regs_mentioned (insn) | |
2685 | || GET_CODE (insn) == CALL_INSN) | |
2686 | { | |
2687 | if (file) | |
2688 | { | |
2689 | fprintf (file, " insn %d input stack: ", | |
2690 | INSN_UID (insn)); | |
2691 | print_stack (file, ®stack); | |
2692 | } | |
2693 | subst_stack_regs (insn, ®stack); | |
535825e6 | 2694 | } |
f3d96a58 | 2695 | } |
2696 | while (next); | |
535825e6 | 2697 | |
f3d96a58 | 2698 | if (file) |
2699 | { | |
2700 | fprintf (file, "Expected live registers ["); | |
2701 | for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; ++reg) | |
2702 | if (TEST_HARD_REG_BIT (bi->out_reg_set, reg)) | |
2703 | fprintf (file, " %d", reg); | |
2704 | fprintf (file, " ]\nOutput stack: "); | |
2705 | print_stack (file, ®stack); | |
2706 | } | |
535825e6 | 2707 | |
f3d96a58 | 2708 | insn = block->end; |
2709 | if (GET_CODE (insn) == JUMP_INSN) | |
2710 | insn = PREV_INSN (insn); | |
2711 | ||
2712 | /* If the function is declared to return a value, but it returns one | |
2713 | in only some cases, some registers might come live here. Emit | |
2714 | necessary moves for them. */ | |
2715 | ||
2716 | for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; ++reg) | |
2717 | { | |
2718 | if (TEST_HARD_REG_BIT (bi->out_reg_set, reg) | |
2719 | && ! TEST_HARD_REG_BIT (regstack.reg_set, reg)) | |
535825e6 | 2720 | { |
f3d96a58 | 2721 | rtx set; |
535825e6 | 2722 | |
f3d96a58 | 2723 | if (file) |
2724 | { | |
2725 | fprintf (file, "Emitting insn initializing reg %d\n", | |
2726 | reg); | |
2727 | } | |
535825e6 | 2728 | |
f3d96a58 | 2729 | set = gen_rtx_SET (VOIDmode, FP_MODE_REG (reg, SFmode), |
2730 | nan); | |
9dda7915 | 2731 | insn = emit_insn_after (set, insn); |
f3d96a58 | 2732 | subst_stack_regs (insn, ®stack); |
2733 | } | |
2734 | } | |
535825e6 | 2735 | |
f3d96a58 | 2736 | /* Something failed if the stack lives don't match. */ |
2737 | GO_IF_HARD_REG_EQUAL (regstack.reg_set, bi->out_reg_set, win); | |
2738 | abort (); | |
2739 | win: | |
ecb7b891 | 2740 | bi->stack_out = regstack; |
535825e6 | 2741 | |
ecb7b891 | 2742 | /* Compensate the back edges, as those wasn't visited yet. */ |
f3d96a58 | 2743 | for (e = block->succ; e ; e = e->succ_next) |
2744 | { | |
ecb7b891 | 2745 | if (e->flags & EDGE_DFS_BACK |
2746 | || (e->dest == EXIT_BLOCK_PTR)) | |
f3d96a58 | 2747 | { |
ecb7b891 | 2748 | if (!BLOCK_INFO (e->dest)->done |
2749 | && e->dest != block) | |
2750 | abort (); | |
2617fe26 | 2751 | inserted |= compensate_edge (e, file); |
ce71a9e6 | 2752 | } |
ecb7b891 | 2753 | } |
2754 | for (e = block->pred; e ; e = e->pred_next) | |
2755 | { | |
2756 | if (e != beste && !(e->flags & EDGE_DFS_BACK) | |
2757 | && e->src != ENTRY_BLOCK_PTR) | |
f3d96a58 | 2758 | { |
ecb7b891 | 2759 | if (!BLOCK_INFO (e->src)->done) |
f3d96a58 | 2760 | abort (); |
2617fe26 | 2761 | inserted |= compensate_edge (e, file); |
f3d96a58 | 2762 | } |
ce71a9e6 | 2763 | } |
f3d96a58 | 2764 | |
2765 | return inserted; | |
535825e6 | 2766 | } |
535825e6 | 2767 | |
f3d96a58 | 2768 | /* Convert registers in all blocks reachable from BLOCK. */ |
2769 | ||
2770 | static int | |
2771 | convert_regs_2 (file, block) | |
535825e6 | 2772 | FILE *file; |
f3d96a58 | 2773 | basic_block block; |
535825e6 | 2774 | { |
f3d96a58 | 2775 | basic_block *stack, *sp; |
2776 | int inserted; | |
535825e6 | 2777 | |
b3d6de89 | 2778 | stack = (basic_block *) xmalloc (sizeof (*stack) * n_basic_blocks); |
f3d96a58 | 2779 | sp = stack; |
535825e6 | 2780 | |
f3d96a58 | 2781 | *sp++ = block; |
535825e6 | 2782 | |
f3d96a58 | 2783 | inserted = 0; |
2784 | do | |
2785 | { | |
2786 | edge e; | |
535825e6 | 2787 | |
f3d96a58 | 2788 | block = *--sp; |
2789 | inserted |= convert_regs_1 (file, block); | |
ecb7b891 | 2790 | BLOCK_INFO (block)->done = 1; |
535825e6 | 2791 | |
f3d96a58 | 2792 | for (e = block->succ; e ; e = e->succ_next) |
ecb7b891 | 2793 | if (! (e->flags & EDGE_DFS_BACK)) |
f3d96a58 | 2794 | { |
4ad72a03 | 2795 | BLOCK_INFO (e->dest)->predecessors--; |
2796 | if (!BLOCK_INFO (e->dest)->predecessors) | |
ecb7b891 | 2797 | *sp++ = e->dest; |
f3d96a58 | 2798 | } |
535825e6 | 2799 | } |
f3d96a58 | 2800 | while (sp != stack); |
2801 | ||
2802 | return inserted; | |
535825e6 | 2803 | } |
c5b9f902 | 2804 | |
f3d96a58 | 2805 | /* Traverse all basic blocks in a function, converting the register |
2806 | references in each insn from the "flat" register file that gcc uses, | |
2807 | to the stack-like registers the 387 uses. */ | |
2808 | ||
2809 | static int | |
2810 | convert_regs (file) | |
535825e6 | 2811 | FILE *file; |
2812 | { | |
4c26117a | 2813 | int inserted; |
2814 | basic_block b; | |
f3d96a58 | 2815 | edge e; |
535825e6 | 2816 | |
f3d96a58 | 2817 | /* Initialize uninitialized registers on function entry. */ |
2818 | inserted = convert_regs_entry (); | |
535825e6 | 2819 | |
f3d96a58 | 2820 | /* Construct the desired stack for function exit. */ |
2821 | convert_regs_exit (); | |
2822 | BLOCK_INFO (EXIT_BLOCK_PTR)->done = 1; | |
535825e6 | 2823 | |
f3d96a58 | 2824 | /* ??? Future: process inner loops first, and give them arbitrary |
2825 | initial stacks which emit_swap_insn can modify. This ought to | |
2826 | prevent double fxch that aften appears at the head of a loop. */ | |
535825e6 | 2827 | |
f3d96a58 | 2828 | /* Process all blocks reachable from all entry points. */ |
2829 | for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next) | |
2830 | inserted |= convert_regs_2 (file, e->dest); | |
2617fe26 | 2831 | |
2832 | /* ??? Process all unreachable blocks. Though there's no excuse | |
f3d96a58 | 2833 | for keeping these even when not optimizing. */ |
4c26117a | 2834 | FOR_EACH_BB (b) |
f3d96a58 | 2835 | { |
f3d96a58 | 2836 | block_info bi = BLOCK_INFO (b); |
535825e6 | 2837 | |
f3d96a58 | 2838 | if (! bi->done) |
535825e6 | 2839 | { |
f3d96a58 | 2840 | int reg; |
535825e6 | 2841 | |
f3d96a58 | 2842 | /* Create an arbitrary input stack. */ |
2843 | bi->stack_in.top = -1; | |
2844 | for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg) | |
2845 | if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg)) | |
2846 | bi->stack_in.reg[++bi->stack_in.top] = reg; | |
535825e6 | 2847 | |
f3d96a58 | 2848 | inserted |= convert_regs_2 (file, b); |
2849 | } | |
2850 | } | |
535825e6 | 2851 | |
17a54dac | 2852 | fixup_abnormal_edges (); |
f3d96a58 | 2853 | if (inserted) |
2854 | commit_edge_insertions (); | |
535825e6 | 2855 | |
f3d96a58 | 2856 | if (file) |
2857 | fputc ('\n', file); | |
535825e6 | 2858 | |
f3d96a58 | 2859 | return inserted; |
535825e6 | 2860 | } |
535825e6 | 2861 | #endif /* STACK_REGS */ |
1f3233d1 | 2862 | |
2863 | #include "gt-reg-stack.h" |