]>
Commit | Line | Data |
---|---|---|
29a404f9 | 1 | /* Subroutines for insn-output.c for Matsushita MN10300 series |
6e90c6cd | 2 | Copyright (C) 1996, 1997 Free Software Foundation, Inc. |
29a404f9 | 3 | Contributed by Jeff Law (law@cygnus.com). |
4 | ||
5 | This file is part of GNU CC. | |
6 | ||
7 | GNU CC is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 2, or (at your option) | |
10 | any later version. | |
11 | ||
12 | GNU CC is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with GNU CC; see the file COPYING. If not, write to | |
19 | the Free Software Foundation, 59 Temple Place - Suite 330, | |
20 | Boston, MA 02111-1307, USA. */ | |
21 | ||
29a404f9 | 22 | #include "config.h" |
0dbd1c74 | 23 | #include <stdio.h> |
29a404f9 | 24 | #include "rtl.h" |
25 | #include "regs.h" | |
26 | #include "hard-reg-set.h" | |
27 | #include "real.h" | |
28 | #include "insn-config.h" | |
29 | #include "conditions.h" | |
30 | #include "insn-flags.h" | |
31 | #include "output.h" | |
32 | #include "insn-attr.h" | |
33 | #include "flags.h" | |
34 | #include "recog.h" | |
35 | #include "expr.h" | |
36 | #include "tree.h" | |
37 | #include "obstack.h" | |
38 | ||
6e90c6cd | 39 | /* Global registers known to hold the value zero. |
40 | ||
41 | Normally we'd depend on CSE and combine to put zero into a | |
42 | register and re-use it. | |
43 | ||
44 | However, on the mn10x00 processors we implicitly use the constant | |
45 | zero in tst instructions, so we might be able to do better by | |
46 | loading the value into a register in the prologue, then re-useing | |
47 | that register throughout the function. | |
48 | ||
49 | We could perform similar optimizations for other constants, but with | |
50 | gcse due soon, it doesn't seem worth the effort. | |
51 | ||
52 | These variables hold a rtx for a register known to hold the value | |
53 | zero throughout the entire function, or NULL if no register of | |
54 | the appropriate class has such a value throughout the life of the | |
55 | function. */ | |
56 | rtx zero_dreg; | |
57 | rtx zero_areg; | |
58 | ||
29a404f9 | 59 | void |
60 | asm_file_start (file) | |
61 | FILE *file; | |
62 | { | |
63 | fprintf (file, "#\tGCC For the Matsushita MN10300\n"); | |
64 | if (optimize) | |
65 | fprintf (file, "# -O%d\n", optimize); | |
66 | else | |
67 | fprintf (file, "\n\n"); | |
68 | output_file_directive (file, main_input_filename); | |
69 | } | |
70 | \f | |
71 | ||
29a404f9 | 72 | /* Print operand X using operand code CODE to assembly language output file |
73 | FILE. */ | |
74 | ||
75 | void | |
76 | print_operand (file, x, code) | |
77 | FILE *file; | |
78 | rtx x; | |
79 | int code; | |
80 | { | |
81 | switch (code) | |
82 | { | |
83 | case 'b': | |
84 | case 'B': | |
85 | /* These are normal and reversed branches. */ | |
86 | switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x))) | |
87 | { | |
88 | case NE: | |
89 | fprintf (file, "ne"); | |
90 | break; | |
91 | case EQ: | |
92 | fprintf (file, "eq"); | |
93 | break; | |
94 | case GE: | |
95 | fprintf (file, "ge"); | |
96 | break; | |
97 | case GT: | |
98 | fprintf (file, "gt"); | |
99 | break; | |
100 | case LE: | |
101 | fprintf (file, "le"); | |
102 | break; | |
103 | case LT: | |
104 | fprintf (file, "lt"); | |
105 | break; | |
106 | case GEU: | |
107 | fprintf (file, "cc"); | |
108 | break; | |
109 | case GTU: | |
110 | fprintf (file, "hi"); | |
111 | break; | |
112 | case LEU: | |
113 | fprintf (file, "ls"); | |
114 | break; | |
115 | case LTU: | |
116 | fprintf (file, "cs"); | |
117 | break; | |
118 | default: | |
119 | abort (); | |
120 | } | |
121 | break; | |
122 | case 'C': | |
123 | /* This is used for the operand to a call instruction; | |
124 | if it's a REG, enclose it in parens, else output | |
125 | the operand normally. */ | |
126 | if (GET_CODE (x) == REG) | |
127 | { | |
128 | fputc ('(', file); | |
129 | print_operand (file, x, 0); | |
130 | fputc (')', file); | |
131 | } | |
132 | else | |
133 | print_operand (file, x, 0); | |
134 | break; | |
135 | ||
6ce19398 | 136 | /* These are the least significant word in a 64bit value. */ |
137 | case 'L': | |
138 | switch (GET_CODE (x)) | |
139 | { | |
140 | case MEM: | |
141 | fputc ('(', file); | |
142 | output_address (XEXP (x, 0)); | |
143 | fputc (')', file); | |
144 | break; | |
145 | ||
146 | case REG: | |
147 | fprintf (file, "%s", reg_names[REGNO (x)]); | |
148 | break; | |
149 | ||
150 | case SUBREG: | |
151 | fprintf (file, "%s", | |
152 | reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)]); | |
153 | break; | |
154 | ||
155 | case CONST_DOUBLE: | |
156 | { | |
157 | long val[2]; | |
158 | REAL_VALUE_TYPE rv; | |
159 | ||
160 | switch (GET_MODE (x)) | |
161 | { | |
162 | case DFmode: | |
163 | REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
164 | REAL_VALUE_TO_TARGET_DOUBLE (rv, val); | |
165 | print_operand_address (file, GEN_INT (val[0])); | |
166 | break;; | |
167 | case SFmode: | |
168 | REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
169 | REAL_VALUE_TO_TARGET_SINGLE (rv, val[0]); | |
170 | print_operand_address (file, GEN_INT (val[0])); | |
171 | break;; | |
172 | case VOIDmode: | |
173 | case DImode: | |
174 | print_operand_address (file, | |
175 | GEN_INT (CONST_DOUBLE_LOW (x))); | |
176 | break; | |
177 | } | |
178 | break; | |
179 | } | |
180 | ||
181 | case CONST_INT: | |
182 | print_operand_address (file, x); | |
183 | break; | |
184 | ||
185 | default: | |
186 | abort (); | |
187 | } | |
188 | break; | |
189 | ||
190 | /* Similarly, but for the most significant word. */ | |
191 | case 'H': | |
192 | switch (GET_CODE (x)) | |
193 | { | |
194 | case MEM: | |
195 | fputc ('(', file); | |
196 | x = adj_offsettable_operand (x, 4); | |
197 | output_address (XEXP (x, 0)); | |
198 | fputc (')', file); | |
199 | break; | |
200 | ||
201 | case REG: | |
202 | fprintf (file, "%s", reg_names[REGNO (x) + 1]); | |
203 | break; | |
204 | ||
205 | case SUBREG: | |
206 | fprintf (file, "%s", | |
207 | reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)] + 1); | |
208 | break; | |
209 | ||
210 | case CONST_DOUBLE: | |
211 | { | |
212 | long val[2]; | |
213 | REAL_VALUE_TYPE rv; | |
214 | ||
215 | switch (GET_MODE (x)) | |
216 | { | |
217 | case DFmode: | |
218 | REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
219 | REAL_VALUE_TO_TARGET_DOUBLE (rv, val); | |
220 | print_operand_address (file, GEN_INT (val[1])); | |
221 | break;; | |
222 | case SFmode: | |
223 | abort (); | |
224 | case VOIDmode: | |
225 | case DImode: | |
226 | print_operand_address (file, | |
227 | GEN_INT (CONST_DOUBLE_HIGH (x))); | |
228 | break; | |
229 | } | |
230 | break; | |
231 | } | |
232 | ||
233 | case CONST_INT: | |
234 | if (INTVAL (x) < 0) | |
235 | print_operand_address (file, GEN_INT (-1)); | |
236 | else | |
237 | print_operand_address (file, GEN_INT (0)); | |
238 | break; | |
239 | default: | |
240 | abort (); | |
241 | } | |
242 | break; | |
243 | ||
244 | case 'A': | |
245 | fputc ('(', file); | |
246 | if (GET_CODE (XEXP (x, 0)) == REG) | |
247 | output_address (gen_rtx (PLUS, SImode, XEXP (x, 0), GEN_INT (0))); | |
248 | else | |
249 | output_address (XEXP (x, 0)); | |
250 | fputc (')', file); | |
251 | break; | |
252 | ||
167fa942 | 253 | case 'N': |
254 | output_address (GEN_INT ((~INTVAL (x)) & 0xff)); | |
255 | break; | |
256 | ||
63e678f2 | 257 | /* For shift counts. The hardware ignores the upper bits of |
258 | any immediate, but the assembler will flag an out of range | |
259 | shift count as an error. So we mask off the high bits | |
260 | of the immediate here. */ | |
261 | case 'S': | |
262 | if (GET_CODE (x) == CONST_INT) | |
263 | { | |
264 | fprintf (file, "%d", INTVAL (x) & 0x1f); | |
265 | break; | |
266 | } | |
267 | /* FALL THROUGH */ | |
268 | ||
29a404f9 | 269 | default: |
270 | switch (GET_CODE (x)) | |
271 | { | |
272 | case MEM: | |
273 | fputc ('(', file); | |
274 | output_address (XEXP (x, 0)); | |
275 | fputc (')', file); | |
276 | break; | |
277 | ||
6ce19398 | 278 | case PLUS: |
279 | output_address (x); | |
280 | break; | |
281 | ||
29a404f9 | 282 | case REG: |
283 | fprintf (file, "%s", reg_names[REGNO (x)]); | |
284 | break; | |
285 | ||
286 | case SUBREG: | |
287 | fprintf (file, "%s", | |
288 | reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)]); | |
289 | break; | |
290 | ||
6ce19398 | 291 | /* This will only be single precision.... */ |
292 | case CONST_DOUBLE: | |
293 | { | |
294 | unsigned long val; | |
295 | REAL_VALUE_TYPE rv; | |
296 | ||
297 | REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
298 | REAL_VALUE_TO_TARGET_SINGLE (rv, val); | |
299 | print_operand_address (file, GEN_INT (val)); | |
300 | break; | |
301 | } | |
302 | ||
29a404f9 | 303 | case CONST_INT: |
304 | case SYMBOL_REF: | |
305 | case CONST: | |
306 | case LABEL_REF: | |
307 | case CODE_LABEL: | |
308 | print_operand_address (file, x); | |
309 | break; | |
310 | default: | |
311 | abort (); | |
312 | } | |
313 | break; | |
314 | } | |
315 | } | |
316 | ||
317 | /* Output assembly language output for the address ADDR to FILE. */ | |
318 | ||
319 | void | |
320 | print_operand_address (file, addr) | |
321 | FILE *file; | |
322 | rtx addr; | |
323 | { | |
324 | switch (GET_CODE (addr)) | |
325 | { | |
326 | case REG: | |
327 | if (addr == stack_pointer_rtx) | |
328 | print_operand_address (file, gen_rtx (PLUS, SImode, | |
329 | stack_pointer_rtx, | |
330 | GEN_INT (0))); | |
331 | else | |
332 | print_operand (file, addr, 0); | |
333 | break; | |
334 | case PLUS: | |
335 | { | |
336 | rtx base, index; | |
337 | if (REG_P (XEXP (addr, 0)) | |
338 | && REG_OK_FOR_BASE_P (XEXP (addr, 0))) | |
339 | base = XEXP (addr, 0), index = XEXP (addr, 1); | |
340 | else if (REG_P (XEXP (addr, 1)) | |
341 | && REG_OK_FOR_BASE_P (XEXP (addr, 1))) | |
342 | base = XEXP (addr, 1), index = XEXP (addr, 0); | |
343 | else | |
344 | abort (); | |
345 | print_operand (file, index, 0); | |
346 | fputc (',', file); | |
347 | print_operand (file, base, 0);; | |
348 | break; | |
349 | } | |
350 | case SYMBOL_REF: | |
351 | output_addr_const (file, addr); | |
352 | break; | |
353 | default: | |
354 | output_addr_const (file, addr); | |
355 | break; | |
356 | } | |
357 | } | |
358 | ||
6ce19398 | 359 | int |
360 | can_use_return_insn () | |
361 | { | |
36ed4406 | 362 | /* size includes the fixed stack space needed for function calls. */ |
363 | int size = get_frame_size () + current_function_outgoing_args_size; | |
364 | ||
365 | /* And space for the return pointer. */ | |
366 | size += current_function_outgoing_args_size ? 4 : 0; | |
6ce19398 | 367 | |
368 | return (reload_completed | |
369 | && size == 0 | |
370 | && !regs_ever_live[2] | |
371 | && !regs_ever_live[3] | |
372 | && !regs_ever_live[6] | |
373 | && !regs_ever_live[7] | |
374 | && !frame_pointer_needed); | |
375 | } | |
376 | ||
6e90c6cd | 377 | /* Count the number of tst insns which compare a data or address |
378 | register with zero. */ | |
379 | static void | |
380 | count_tst_insns (dreg_countp, areg_countp) | |
381 | int *dreg_countp; | |
382 | int *areg_countp; | |
383 | { | |
384 | rtx insn; | |
385 | ||
386 | /* Assume no tst insns exist. */ | |
387 | *dreg_countp = 0; | |
388 | *areg_countp = 0; | |
389 | ||
390 | /* If not optimizing, then quit now. */ | |
391 | if (!optimize) | |
392 | return; | |
393 | ||
394 | /* Walk through all the insns. */ | |
395 | for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) | |
396 | { | |
397 | rtx pat; | |
398 | ||
399 | /* Ignore anything that is not a normal INSN. */ | |
400 | if (GET_CODE (insn) != INSN) | |
401 | continue; | |
402 | ||
403 | /* Ignore anything that isn't a SET. */ | |
404 | pat = PATTERN (insn); | |
405 | if (GET_CODE (pat) != SET) | |
406 | continue; | |
407 | ||
408 | /* Check for a tst insn. */ | |
409 | if (SET_DEST (pat) == cc0_rtx | |
410 | && GET_CODE (SET_SRC (pat)) == REG) | |
411 | { | |
412 | if (REGNO_REG_CLASS (REGNO (SET_SRC (pat))) == DATA_REGS) | |
413 | (*dreg_countp)++; | |
414 | ||
415 | if (REGNO_REG_CLASS (REGNO (SET_SRC (pat))) == ADDRESS_REGS) | |
416 | (*areg_countp)++; | |
417 | } | |
418 | ||
419 | /* Setting an address register to zero can also be optimized, | |
420 | so count it just like a tst insn. */ | |
421 | if (GET_CODE (SET_DEST (pat)) == REG | |
422 | && GET_CODE (SET_SRC (pat)) == CONST_INT | |
423 | && INTVAL (SET_SRC (pat)) == 0 | |
424 | && REGNO_REG_CLASS (REGNO (SET_DEST (pat))) == ADDRESS_REGS) | |
425 | (*areg_countp)++; | |
426 | } | |
427 | } | |
428 | ||
29a404f9 | 429 | void |
430 | expand_prologue () | |
431 | { | |
f1899bff | 432 | unsigned int size; |
433 | ||
be989dda | 434 | /* We need to end the current sequence so that count_tst_insns can |
435 | look at all the insns in this function. Normally this would be | |
436 | unsafe, but it's OK in the prologue/epilogue expanders. */ | |
437 | end_sequence (); | |
438 | ||
6e90c6cd | 439 | /* Determine if it is profitable to put the value zero into a register |
440 | for the entire function. If so, set ZERO_DREG and ZERO_AREG. */ | |
441 | if (regs_ever_live[2] || regs_ever_live[3] | |
442 | || regs_ever_live[6] || regs_ever_live[7] | |
443 | || frame_pointer_needed) | |
444 | { | |
445 | int dreg_count, areg_count; | |
446 | ||
447 | /* Get a count of the number of tst insns which use address and | |
448 | data registers. */ | |
449 | count_tst_insns (&dreg_count, &areg_count); | |
450 | ||
451 | /* If there's more than one tst insn using a data register, then | |
452 | this optimization is a win. */ | |
453 | if (dreg_count > 1 | |
454 | && (!regs_ever_live[2] || !regs_ever_live[3])) | |
455 | { | |
456 | if (!regs_ever_live[2]) | |
457 | { | |
458 | regs_ever_live[2] = 1; | |
459 | zero_dreg = gen_rtx (REG, SImode, 2); | |
460 | } | |
461 | else | |
462 | { | |
463 | regs_ever_live[3] = 1; | |
464 | zero_dreg = gen_rtx (REG, SImode, 3); | |
465 | } | |
466 | } | |
467 | else | |
468 | zero_dreg = NULL_RTX; | |
469 | ||
470 | /* If there's more than two tst insns using an address register, | |
471 | then this optimization is a win. */ | |
472 | if (areg_count > 2 | |
473 | && (!regs_ever_live[6] || !regs_ever_live[7])) | |
474 | { | |
475 | if (!regs_ever_live[6]) | |
476 | { | |
477 | regs_ever_live[6] = 1; | |
478 | zero_areg = gen_rtx (REG, SImode, 6); | |
479 | } | |
480 | else | |
481 | { | |
482 | regs_ever_live[7] = 1; | |
483 | zero_areg = gen_rtx (REG, SImode, 7); | |
484 | } | |
485 | } | |
486 | else | |
487 | zero_areg = NULL_RTX; | |
488 | } | |
489 | else | |
490 | { | |
491 | zero_dreg = NULL_RTX; | |
492 | zero_areg = NULL_RTX; | |
493 | } | |
494 | ||
be989dda | 495 | /* Start a new sequence. */ |
496 | start_sequence (); | |
497 | ||
f1899bff | 498 | /* SIZE includes the fixed stack space needed for function calls. */ |
36ed4406 | 499 | size = get_frame_size () + current_function_outgoing_args_size; |
500 | size += (current_function_outgoing_args_size ? 4 : 0); | |
29a404f9 | 501 | |
bb4959a8 | 502 | /* If this is an old-style varargs function, then its arguments |
503 | need to be flushed back to the stack. */ | |
504 | if (current_function_varargs) | |
505 | { | |
506 | emit_move_insn (gen_rtx (MEM, SImode, | |
507 | gen_rtx (PLUS, Pmode, stack_pointer_rtx, | |
508 | GEN_INT (4))), | |
509 | gen_rtx (REG, SImode, 0)); | |
510 | emit_move_insn (gen_rtx (MEM, SImode, | |
511 | gen_rtx (PLUS, Pmode, stack_pointer_rtx, | |
512 | GEN_INT (8))), | |
513 | gen_rtx (REG, SImode, 1)); | |
514 | } | |
515 | ||
48cb86e3 | 516 | /* And now store all the registers onto the stack with a |
517 | single two byte instruction. */ | |
518 | if (regs_ever_live[2] || regs_ever_live[3] | |
519 | || regs_ever_live[6] || regs_ever_live[7] | |
520 | || frame_pointer_needed) | |
521 | emit_insn (gen_store_movm ()); | |
522 | ||
523 | /* Now put the frame pointer into the frame pointer register. */ | |
29a404f9 | 524 | if (frame_pointer_needed) |
014546df | 525 | emit_move_insn (frame_pointer_rtx, stack_pointer_rtx); |
29a404f9 | 526 | |
48cb86e3 | 527 | /* Allocate stack for this frame. */ |
29a404f9 | 528 | if (size) |
529 | emit_insn (gen_addsi3 (stack_pointer_rtx, | |
530 | stack_pointer_rtx, | |
531 | GEN_INT (-size))); | |
6e90c6cd | 532 | |
533 | /* Load zeros into registers as needed. */ | |
534 | if (zero_dreg) | |
535 | emit_move_insn (zero_dreg, const0_rtx); | |
536 | ||
537 | if (zero_areg) | |
538 | emit_move_insn (zero_areg, const0_rtx); | |
29a404f9 | 539 | } |
540 | ||
541 | void | |
542 | expand_epilogue () | |
543 | { | |
f1899bff | 544 | unsigned int size; |
545 | ||
f1899bff | 546 | /* SIZE includes the fixed stack space needed for function calls. */ |
36ed4406 | 547 | size = get_frame_size () + current_function_outgoing_args_size; |
548 | size += (current_function_outgoing_args_size ? 4 : 0); | |
29a404f9 | 549 | |
461cabcc | 550 | /* Maybe cut back the stack, except for the register save area. |
551 | ||
552 | If the frame pointer exists, then use the frame pointer to | |
553 | cut back the stack. | |
554 | ||
555 | If the stack size + register save area is more than 255 bytes, | |
556 | then the stack must be cut back here since the size + register | |
557 | save size is too big for a ret/retf instruction. | |
558 | ||
559 | Else leave it alone, it will be cut back as part of the | |
560 | ret/retf instruction, or there wasn't any stack to begin with. | |
561 | ||
562 | Under no circumstanes should the register save area be | |
563 | deallocated here, that would leave a window where an interrupt | |
564 | could occur and trash the register save area. */ | |
29a404f9 | 565 | if (frame_pointer_needed) |
566 | { | |
29a404f9 | 567 | emit_move_insn (stack_pointer_rtx, frame_pointer_rtx); |
b21218d6 | 568 | size = 0; |
569 | } | |
167fa942 | 570 | else if ((regs_ever_live[2] || regs_ever_live[3] |
571 | || regs_ever_live[6] || regs_ever_live[7]) | |
461cabcc | 572 | && size + 16 > 255) |
b21218d6 | 573 | { |
574 | emit_insn (gen_addsi3 (stack_pointer_rtx, | |
575 | stack_pointer_rtx, | |
576 | GEN_INT (size))); | |
577 | size = 0; | |
29a404f9 | 578 | } |
29a404f9 | 579 | |
48cb86e3 | 580 | /* For simplicity, we just movm all the callee saved registers to |
581 | the stack with one instruction. | |
582 | ||
583 | ?!? Only save registers which are actually used. Reduces | |
ad87de1e | 584 | stack requirements and is faster. */ |
48cb86e3 | 585 | if (regs_ever_live[2] || regs_ever_live[3] |
586 | || regs_ever_live[6] || regs_ever_live[7] | |
587 | || frame_pointer_needed) | |
461cabcc | 588 | emit_jump_insn (gen_return_internal_regs (GEN_INT (size + 16))); |
48cb86e3 | 589 | else |
590 | { | |
591 | if (size) | |
6ce19398 | 592 | { |
593 | emit_insn (gen_addsi3 (stack_pointer_rtx, | |
594 | stack_pointer_rtx, | |
595 | GEN_INT (size))); | |
596 | emit_jump_insn (gen_return_internal ()); | |
597 | } | |
598 | else | |
599 | { | |
600 | emit_jump_insn (gen_return ()); | |
601 | } | |
48cb86e3 | 602 | } |
29a404f9 | 603 | } |
604 | ||
605 | /* Update the condition code from the insn. */ | |
606 | ||
607 | void | |
608 | notice_update_cc (body, insn) | |
609 | rtx body; | |
610 | rtx insn; | |
611 | { | |
29a404f9 | 612 | switch (get_attr_cc (insn)) |
613 | { | |
614 | case CC_NONE: | |
615 | /* Insn does not affect CC at all. */ | |
616 | break; | |
617 | ||
618 | case CC_NONE_0HIT: | |
619 | /* Insn does not change CC, but the 0'th operand has been changed. */ | |
620 | if (cc_status.value1 != 0 | |
621 | && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1)) | |
622 | cc_status.value1 = 0; | |
623 | break; | |
624 | ||
14058057 | 625 | case CC_SET_ZN: |
29a404f9 | 626 | /* Insn sets the Z,N flags of CC to recog_operand[0]. |
14058057 | 627 | V,C are unusable. */ |
29a404f9 | 628 | CC_STATUS_INIT; |
14058057 | 629 | cc_status.flags |= CC_NO_CARRY | CC_OVERFLOW_UNUSABLE; |
29a404f9 | 630 | cc_status.value1 = recog_operand[0]; |
631 | break; | |
632 | ||
14058057 | 633 | case CC_SET_ZNV: |
634 | /* Insn sets the Z,N,V flags of CC to recog_operand[0]. | |
635 | C is unusable. */ | |
45e3d109 | 636 | CC_STATUS_INIT; |
14058057 | 637 | cc_status.flags |= CC_NO_CARRY; |
45e3d109 | 638 | cc_status.value1 = recog_operand[0]; |
639 | break; | |
640 | ||
29a404f9 | 641 | case CC_COMPARE: |
642 | /* The insn is a compare instruction. */ | |
643 | CC_STATUS_INIT; | |
644 | cc_status.value1 = SET_SRC (body); | |
645 | break; | |
646 | ||
952e42d8 | 647 | case CC_INVERT: |
648 | /* The insn is a compare instruction. */ | |
649 | CC_STATUS_INIT; | |
650 | cc_status.value1 = SET_SRC (body); | |
651 | cc_status.flags |= CC_INVERTED; | |
652 | break; | |
653 | ||
29a404f9 | 654 | case CC_CLOBBER: |
655 | /* Insn doesn't leave CC in a usable state. */ | |
656 | CC_STATUS_INIT; | |
657 | break; | |
45e3d109 | 658 | |
659 | default: | |
660 | abort (); | |
29a404f9 | 661 | } |
29a404f9 | 662 | } |
663 | ||
664 | /* Return true if OP is a valid call operand. */ | |
665 | ||
666 | int | |
667 | call_address_operand (op, mode) | |
668 | rtx op; | |
669 | enum machine_mode mode; | |
670 | { | |
671 | return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG); | |
672 | } | |
673 | ||
674 | /* What (if any) secondary registers are needed to move IN with mode | |
675 | MODE into a register from in register class CLASS. | |
676 | ||
677 | We might be able to simplify this. */ | |
678 | enum reg_class | |
679 | secondary_reload_class (class, mode, in) | |
680 | enum reg_class class; | |
681 | enum machine_mode mode; | |
682 | rtx in; | |
683 | { | |
684 | int regno; | |
685 | ||
686 | /* Memory loads less than a full word wide can't have an | |
687 | address or stack pointer destination. They must use | |
688 | a data register as an intermediate register. */ | |
689 | if (GET_CODE (in) == MEM | |
690 | && (mode == QImode || mode == HImode) | |
691 | && (class == ADDRESS_REGS || class == SP_REGS)) | |
692 | return DATA_REGS; | |
693 | ||
694 | /* We can't directly load sp + const_int into a data register; | |
695 | we must use an address register as an intermediate. */ | |
48cb86e3 | 696 | if (class != SP_REGS |
697 | && class != ADDRESS_REGS | |
698 | && class != SP_OR_ADDRESS_REGS | |
29a404f9 | 699 | && (in == stack_pointer_rtx |
700 | || (GET_CODE (in) == PLUS | |
48cb86e3 | 701 | && (XEXP (in, 0) == stack_pointer_rtx |
702 | || XEXP (in, 1) == stack_pointer_rtx)))) | |
29a404f9 | 703 | return ADDRESS_REGS; |
704 | ||
19de5de1 | 705 | if (GET_CODE (in) == PLUS |
706 | && (XEXP (in, 0) == stack_pointer_rtx | |
707 | || XEXP (in, 1) == stack_pointer_rtx)) | |
708 | return DATA_REGS; | |
709 | ||
710 | ||
48cb86e3 | 711 | /* Otherwise assume no secondary reloads are needed. */ |
712 | return NO_REGS; | |
713 | } | |
714 | ||
715 | int | |
716 | initial_offset (from, to) | |
717 | int from, to; | |
718 | { | |
f1899bff | 719 | /* The difference between the argument pointer and the frame pointer |
720 | is the size of the callee register save area. */ | |
48cb86e3 | 721 | if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM) |
29a404f9 | 722 | { |
48cb86e3 | 723 | if (regs_ever_live[2] || regs_ever_live[3] |
724 | || regs_ever_live[6] || regs_ever_live[7] | |
725 | || frame_pointer_needed) | |
bb4959a8 | 726 | return 16; |
48cb86e3 | 727 | else |
bb4959a8 | 728 | return 0; |
29a404f9 | 729 | } |
730 | ||
f1899bff | 731 | /* The difference between the argument pointer and the stack pointer is |
732 | the sum of the size of this function's frame, the callee register save | |
733 | area, and the fixed stack space needed for function calls (if any). */ | |
48cb86e3 | 734 | if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM) |
735 | { | |
736 | if (regs_ever_live[2] || regs_ever_live[3] | |
737 | || regs_ever_live[6] || regs_ever_live[7] | |
738 | || frame_pointer_needed) | |
36ed4406 | 739 | return (get_frame_size () + 16 |
740 | + (current_function_outgoing_args_size | |
741 | ? current_function_outgoing_args_size + 4 : 0)); | |
48cb86e3 | 742 | else |
36ed4406 | 743 | return (get_frame_size () |
744 | + (current_function_outgoing_args_size | |
745 | ? current_function_outgoing_args_size + 4 : 0)); | |
48cb86e3 | 746 | } |
29a404f9 | 747 | |
f1899bff | 748 | /* The difference between the frame pointer and stack pointer is the sum |
749 | of the size of this function's frame and the fixed stack space needed | |
750 | for function calls (if any). */ | |
48cb86e3 | 751 | if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM) |
36ed4406 | 752 | return (get_frame_size () |
753 | + (current_function_outgoing_args_size | |
754 | ? current_function_outgoing_args_size + 4 : 0)); | |
48cb86e3 | 755 | |
756 | abort (); | |
29a404f9 | 757 | } |
bb4959a8 | 758 | |
759 | /* Flush the argument registers to the stack for a stdarg function; | |
760 | return the new argument pointer. */ | |
761 | rtx | |
762 | mn10300_builtin_saveregs (arglist) | |
763 | tree arglist; | |
764 | { | |
765 | rtx offset; | |
766 | tree fntype = TREE_TYPE (current_function_decl); | |
767 | int argadj = ((!(TYPE_ARG_TYPES (fntype) != 0 | |
768 | && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) | |
769 | != void_type_node))) | |
770 | ? UNITS_PER_WORD : 0); | |
771 | ||
772 | if (argadj) | |
773 | offset = plus_constant (current_function_arg_offset_rtx, argadj); | |
774 | else | |
775 | offset = current_function_arg_offset_rtx; | |
776 | ||
777 | emit_move_insn (gen_rtx (MEM, SImode, current_function_internal_arg_pointer), | |
778 | gen_rtx (REG, SImode, 0)); | |
779 | emit_move_insn (gen_rtx (MEM, SImode, | |
780 | plus_constant | |
781 | (current_function_internal_arg_pointer, 4)), | |
782 | gen_rtx (REG, SImode, 1)); | |
783 | return copy_to_reg (expand_binop (Pmode, add_optab, | |
784 | current_function_internal_arg_pointer, | |
785 | offset, 0, 0, OPTAB_LIB_WIDEN)); | |
786 | } | |
787 | ||
788 | /* Return an RTX to represent where a value with mode MODE will be returned | |
789 | from a function. If the result is 0, the argument is pushed. */ | |
790 | ||
791 | rtx | |
792 | function_arg (cum, mode, type, named) | |
793 | CUMULATIVE_ARGS *cum; | |
794 | enum machine_mode mode; | |
795 | tree type; | |
796 | int named; | |
797 | { | |
798 | rtx result = 0; | |
799 | int size, align; | |
800 | ||
801 | /* We only support using 2 data registers as argument registers. */ | |
802 | int nregs = 2; | |
803 | ||
804 | /* Figure out the size of the object to be passed. */ | |
805 | if (mode == BLKmode) | |
806 | size = int_size_in_bytes (type); | |
807 | else | |
808 | size = GET_MODE_SIZE (mode); | |
809 | ||
810 | /* Figure out the alignment of the object to be passed. */ | |
811 | align = size; | |
812 | ||
813 | cum->nbytes = (cum->nbytes + 3) & ~3; | |
814 | ||
815 | /* Don't pass this arg via a register if all the argument registers | |
816 | are used up. */ | |
817 | if (cum->nbytes > nregs * UNITS_PER_WORD) | |
818 | return 0; | |
819 | ||
820 | /* Don't pass this arg via a register if it would be split between | |
821 | registers and memory. */ | |
822 | if (type == NULL_TREE | |
823 | && cum->nbytes + size > nregs * UNITS_PER_WORD) | |
824 | return 0; | |
825 | ||
826 | switch (cum->nbytes / UNITS_PER_WORD) | |
827 | { | |
828 | case 0: | |
829 | result = gen_rtx (REG, mode, 0); | |
830 | break; | |
831 | case 1: | |
832 | result = gen_rtx (REG, mode, 1); | |
833 | break; | |
834 | default: | |
835 | result = 0; | |
836 | } | |
837 | ||
838 | return result; | |
839 | } | |
840 | ||
841 | /* Return the number of registers to use for an argument passed partially | |
842 | in registers and partially in memory. */ | |
843 | ||
844 | int | |
845 | function_arg_partial_nregs (cum, mode, type, named) | |
846 | CUMULATIVE_ARGS *cum; | |
847 | enum machine_mode mode; | |
848 | tree type; | |
849 | int named; | |
850 | { | |
851 | int size, align; | |
852 | ||
853 | /* We only support using 2 data registers as argument registers. */ | |
854 | int nregs = 2; | |
855 | ||
856 | /* Figure out the size of the object to be passed. */ | |
857 | if (mode == BLKmode) | |
858 | size = int_size_in_bytes (type); | |
859 | else | |
860 | size = GET_MODE_SIZE (mode); | |
861 | ||
862 | /* Figure out the alignment of the object to be passed. */ | |
863 | align = size; | |
864 | ||
865 | cum->nbytes = (cum->nbytes + 3) & ~3; | |
866 | ||
867 | /* Don't pass this arg via a register if all the argument registers | |
868 | are used up. */ | |
869 | if (cum->nbytes > nregs * UNITS_PER_WORD) | |
870 | return 0; | |
871 | ||
872 | if (cum->nbytes + size <= nregs * UNITS_PER_WORD) | |
873 | return 0; | |
874 | ||
875 | /* Don't pass this arg via a register if it would be split between | |
876 | registers and memory. */ | |
877 | if (type == NULL_TREE | |
878 | && cum->nbytes + size > nregs * UNITS_PER_WORD) | |
879 | return 0; | |
880 | ||
881 | return (nregs * UNITS_PER_WORD - cum->nbytes) / UNITS_PER_WORD; | |
882 | } | |
883 | ||
884 | /* Output a tst insn. */ | |
885 | char * | |
886 | output_tst (operand, insn) | |
887 | rtx operand, insn; | |
888 | { | |
bb4959a8 | 889 | rtx temp; |
890 | int past_call = 0; | |
891 | ||
6e90c6cd | 892 | /* If we have a data register which is known to be zero throughout |
893 | the function, then use it instead of doing a search. */ | |
894 | if (zero_dreg && REGNO_REG_CLASS (REGNO (operand)) == DATA_REGS) | |
895 | { | |
896 | rtx xoperands[2]; | |
897 | xoperands[0] = operand; | |
898 | xoperands[1] = zero_dreg; | |
899 | ||
900 | output_asm_insn ("cmp %1,%0", xoperands); | |
901 | return ""; | |
902 | } | |
903 | ||
904 | /* Similarly for address registers. */ | |
905 | if (zero_areg && REGNO_REG_CLASS (REGNO (operand)) == ADDRESS_REGS) | |
906 | { | |
907 | rtx xoperands[2]; | |
908 | xoperands[0] = operand; | |
909 | xoperands[1] = zero_areg; | |
910 | ||
911 | output_asm_insn ("cmp %1,%0", xoperands); | |
912 | return ""; | |
913 | } | |
914 | ||
bb4959a8 | 915 | /* We can save a byte if we can find a register which has the value |
916 | zero in it. */ | |
917 | temp = PREV_INSN (insn); | |
6e90c6cd | 918 | while (optimize && temp) |
bb4959a8 | 919 | { |
920 | rtx set; | |
921 | ||
922 | /* We allow the search to go through call insns. We record | |
923 | the fact that we've past a CALL_INSN and reject matches which | |
924 | use call clobbered registers. */ | |
925 | if (GET_CODE (temp) == CODE_LABEL | |
926 | || GET_CODE (temp) == JUMP_INSN | |
927 | || GET_CODE (temp) == BARRIER) | |
928 | break; | |
929 | ||
930 | if (GET_CODE (temp) == CALL_INSN) | |
931 | past_call = 1; | |
932 | ||
933 | if (GET_CODE (temp) == NOTE) | |
934 | { | |
935 | temp = PREV_INSN (temp); | |
936 | continue; | |
937 | } | |
938 | ||
939 | /* It must be an insn, see if it is a simple set. */ | |
940 | set = single_set (temp); | |
941 | if (!set) | |
942 | { | |
943 | temp = PREV_INSN (temp); | |
944 | continue; | |
945 | } | |
946 | ||
947 | /* Are we setting a data register to zero (this does not win for | |
948 | address registers)? | |
949 | ||
950 | If it's a call clobbered register, have we past a call? | |
951 | ||
952 | Make sure the register we find isn't the same as ourself; | |
953 | the mn10300 can't encode that. */ | |
954 | if (REG_P (SET_DEST (set)) | |
955 | && SET_SRC (set) == CONST0_RTX (GET_MODE (SET_DEST (set))) | |
956 | && !reg_set_between_p (SET_DEST (set), temp, insn) | |
6e90c6cd | 957 | && (REGNO_REG_CLASS (REGNO (SET_DEST (set))) |
958 | == REGNO_REG_CLASS (REGNO (operand))) | |
bb4959a8 | 959 | && REGNO (SET_DEST (set)) != REGNO (operand) |
960 | && (!past_call | |
961 | || !call_used_regs[REGNO (SET_DEST (set))])) | |
962 | { | |
963 | rtx xoperands[2]; | |
964 | xoperands[0] = operand; | |
965 | xoperands[1] = SET_DEST (set); | |
966 | ||
967 | output_asm_insn ("cmp %1,%0", xoperands); | |
968 | return ""; | |
969 | } | |
970 | temp = PREV_INSN (temp); | |
971 | } | |
972 | return "cmp 0,%0"; | |
973 | } | |
36ed4406 | 974 | |
975 | int | |
976 | impossible_plus_operand (op, mode) | |
977 | rtx op; | |
978 | enum machine_mode mode; | |
979 | { | |
980 | extern rtx *reg_equiv_mem; | |
981 | rtx reg1, reg2; | |
982 | ||
983 | if (GET_CODE (op) != PLUS) | |
984 | return 0; | |
985 | ||
19de5de1 | 986 | if (XEXP (op, 0) == stack_pointer_rtx |
987 | || XEXP (op, 1) == stack_pointer_rtx) | |
36ed4406 | 988 | return 1; |
989 | ||
36ed4406 | 990 | return 0; |
991 | } | |
c4cd8f6a | 992 | |
9d3b5b5e | 993 | /* Return 1 if X is a CONST_INT that is only 8 bits wide. This is used |
994 | for the btst insn which may examine memory or a register (the memory | |
995 | variant only allows an unsigned 8 bit integer). */ | |
996 | int | |
997 | const_8bit_operand (op, mode) | |
998 | register rtx op; | |
999 | enum machine_mode mode; | |
1000 | { | |
1001 | return (GET_CODE (op) == CONST_INT | |
1002 | && INTVAL (op) >= 0 | |
1003 | && INTVAL (op) < 256); | |
1004 | } | |
1005 | ||
1006 | /* Similarly, but when using a zero_extract pattern for a btst where | |
1007 | the source operand might end up in memory. */ | |
1008 | int | |
1009 | mask_ok_for_mem_btst (len, bit) | |
1010 | int len; | |
1011 | int bit; | |
1012 | { | |
1013 | int mask = 0; | |
1014 | ||
1015 | while (len > 0) | |
1016 | { | |
1017 | mask |= (1 << bit); | |
1018 | bit++; | |
1019 | len--; | |
1020 | } | |
1021 | ||
1022 | /* MASK must bit into an 8bit value. */ | |
1023 | return (((mask & 0xff) == mask) | |
1024 | || ((mask & 0xff00) == mask) | |
1025 | || ((mask & 0xff0000) == mask) | |
1026 | || ((mask & 0xff000000) == mask)); | |
1027 | } | |
1028 | ||
c4cd8f6a | 1029 | /* Return 1 if X contains a symbolic expression. We know these |
1030 | expressions will have one of a few well defined forms, so | |
1031 | we need only check those forms. */ | |
1032 | int | |
1033 | symbolic_operand (op, mode) | |
1034 | register rtx op; | |
1035 | enum machine_mode mode; | |
1036 | { | |
1037 | switch (GET_CODE (op)) | |
1038 | { | |
1039 | case SYMBOL_REF: | |
1040 | case LABEL_REF: | |
1041 | return 1; | |
1042 | case CONST: | |
1043 | op = XEXP (op, 0); | |
1044 | return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF | |
1045 | || GET_CODE (XEXP (op, 0)) == LABEL_REF) | |
1046 | && GET_CODE (XEXP (op, 1)) == CONST_INT); | |
1047 | default: | |
1048 | return 0; | |
1049 | } | |
1050 | } | |
1051 | ||
1052 | /* Try machine dependent ways of modifying an illegitimate address | |
1053 | to be legitimate. If we find one, return the new valid address. | |
1054 | This macro is used in only one place: `memory_address' in explow.c. | |
1055 | ||
1056 | OLDX is the address as it was before break_out_memory_refs was called. | |
1057 | In some cases it is useful to look at this to decide what needs to be done. | |
1058 | ||
1059 | MODE and WIN are passed so that this macro can use | |
1060 | GO_IF_LEGITIMATE_ADDRESS. | |
1061 | ||
1062 | Normally it is always safe for this macro to do nothing. It exists to | |
1063 | recognize opportunities to optimize the output. | |
1064 | ||
1065 | But on a few ports with segmented architectures and indexed addressing | |
1066 | (mn10300, hppa) it is used to rewrite certain problematical addresses. */ | |
1067 | rtx | |
1068 | legitimize_address (x, oldx, mode) | |
1069 | rtx x; | |
1070 | rtx oldx; | |
1071 | enum machine_mode mode; | |
1072 | { | |
1073 | /* Uh-oh. We might have an address for x[n-100000]. This needs | |
1074 | special handling to avoid creating an indexed memory address | |
1075 | with x-100000 as the base. */ | |
1076 | if (GET_CODE (x) == PLUS | |
1077 | && symbolic_operand (XEXP (x, 1), VOIDmode)) | |
1078 | { | |
1079 | /* Ugly. We modify things here so that the address offset specified | |
1080 | by the index expression is computed first, then added to x to form | |
1081 | the entire address. */ | |
1082 | ||
1083 | rtx regx1, regx2, regy1, regy2, y; | |
1084 | ||
1085 | /* Strip off any CONST. */ | |
1086 | y = XEXP (x, 1); | |
1087 | if (GET_CODE (y) == CONST) | |
1088 | y = XEXP (y, 0); | |
1089 | ||
c927a8ab | 1090 | if (GET_CODE (y) == PLUS || GET_CODE (y) == MINUS) |
1091 | { | |
1092 | regx1 = force_reg (Pmode, force_operand (XEXP (x, 0), 0)); | |
1093 | regy1 = force_reg (Pmode, force_operand (XEXP (y, 0), 0)); | |
1094 | regy2 = force_reg (Pmode, force_operand (XEXP (y, 1), 0)); | |
1095 | regx1 = force_reg (Pmode, | |
1096 | gen_rtx (GET_CODE (y), Pmode, regx1, regy2)); | |
1097 | return force_reg (Pmode, gen_rtx (PLUS, Pmode, regx1, regy1)); | |
1098 | } | |
c4cd8f6a | 1099 | } |
11b4605c | 1100 | return x; |
c4cd8f6a | 1101 | } |