]>
Commit | Line | Data |
---|---|---|
c418d182 | 1 | /* Subroutines for insn-output.c for Matsushita MN10200 series |
ebb11c7b | 2 | Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 |
3 | Free Software Foundation, Inc. | |
c418d182 | 4 | Contributed by Jeff Law (law@cygnus.com). |
5 | ||
6 | This file is part of GNU CC. | |
7 | ||
8 | GNU CC is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 2, or (at your option) | |
11 | any later version. | |
12 | ||
13 | GNU CC is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with GNU CC; see the file COPYING. If not, write to | |
20 | the Free Software Foundation, 59 Temple Place - Suite 330, | |
21 | Boston, MA 02111-1307, USA. */ | |
22 | ||
c418d182 | 23 | #include "config.h" |
7014838c | 24 | #include "system.h" |
805e22b2 | 25 | #include "coretypes.h" |
26 | #include "tm.h" | |
c418d182 | 27 | #include "rtl.h" |
4faf81b8 | 28 | #include "tree.h" |
c418d182 | 29 | #include "regs.h" |
30 | #include "hard-reg-set.h" | |
31 | #include "real.h" | |
32 | #include "insn-config.h" | |
33 | #include "conditions.h" | |
c418d182 | 34 | #include "output.h" |
35 | #include "insn-attr.h" | |
36 | #include "flags.h" | |
37 | #include "recog.h" | |
38 | #include "expr.h" | |
4faf81b8 | 39 | #include "function.h" |
c418d182 | 40 | #include "obstack.h" |
f3a9b67f | 41 | #include "ggc.h" |
aebc2c24 | 42 | #include "toplev.h" |
43 | #include "tm_p.h" | |
a767736d | 44 | #include "target.h" |
45 | #include "target-def.h" | |
c418d182 | 46 | |
47 | /* Global registers known to hold the value zero. | |
48 | ||
49 | Normally we'd depend on CSE and combine to put zero into a | |
50 | register and re-use it. | |
51 | ||
52 | However, on the mn10x00 processors we implicitly use the constant | |
53 | zero in tst instructions, so we might be able to do better by | |
54 | loading the value into a register in the prologue, then re-useing | |
55 | that register throughout the function. | |
56 | ||
57 | We could perform similar optimizations for other constants, but with | |
58 | gcse due soon, it doesn't seem worth the effort. | |
59 | ||
60 | These variables hold a rtx for a register known to hold the value | |
61 | zero throughout the entire function, or NULL if no register of | |
62 | the appropriate class has such a value throughout the life of the | |
63 | function. */ | |
64 | rtx zero_dreg; | |
65 | rtx zero_areg; | |
66 | ||
aebc2c24 | 67 | static void count_tst_insns PARAMS ((int *)); |
68 | ||
c418d182 | 69 | /* Note whether or not we need an out of line epilogue. */ |
70 | static int out_of_line_epilogue; | |
a767736d | 71 | \f |
72 | /* Initialize the GCC target structure. */ | |
58356836 | 73 | #undef TARGET_ASM_ALIGNED_HI_OP |
74 | #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t" | |
c418d182 | 75 | |
57e4bbfb | 76 | struct gcc_target targetm = TARGET_INITIALIZER; |
a767736d | 77 | \f |
c418d182 | 78 | /* Indicate this file was compiled by gcc and what optimization |
79 | level was used. */ | |
80 | void | |
81 | asm_file_start (file) | |
82 | FILE *file; | |
83 | { | |
84 | fprintf (file, "#\tGCC For the Matsushita MN10200\n"); | |
85 | if (optimize) | |
86 | fprintf (file, "# -O%d\n", optimize); | |
87 | else | |
88 | fprintf (file, "\n\n"); | |
89 | output_file_directive (file, main_input_filename); | |
90 | } | |
91 | ||
92 | /* Print operand X using operand code CODE to assembly language output file | |
93 | FILE. */ | |
94 | ||
95 | void | |
96 | print_operand (file, x, code) | |
97 | FILE *file; | |
98 | rtx x; | |
99 | int code; | |
100 | { | |
101 | switch (code) | |
102 | { | |
103 | case 'b': | |
104 | case 'B': | |
105 | /* These are normal and reversed branches. */ | |
106 | switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x))) | |
107 | { | |
108 | case NE: | |
109 | fprintf (file, "ne"); | |
110 | break; | |
111 | case EQ: | |
112 | fprintf (file, "eq"); | |
113 | break; | |
114 | case GE: | |
115 | fprintf (file, "ge"); | |
116 | break; | |
117 | case GT: | |
118 | fprintf (file, "gt"); | |
119 | break; | |
120 | case LE: | |
121 | fprintf (file, "le"); | |
122 | break; | |
123 | case LT: | |
124 | fprintf (file, "lt"); | |
125 | break; | |
126 | case GEU: | |
127 | fprintf (file, "cc"); | |
128 | break; | |
129 | case GTU: | |
130 | fprintf (file, "hi"); | |
131 | break; | |
132 | case LEU: | |
133 | fprintf (file, "ls"); | |
134 | break; | |
135 | case LTU: | |
136 | fprintf (file, "cs"); | |
137 | break; | |
138 | default: | |
139 | abort (); | |
140 | } | |
141 | break; | |
142 | case 'C': | |
143 | /* This is used for the operand to a call instruction; | |
144 | if it's a REG, enclose it in parens, else output | |
145 | the operand normally. */ | |
146 | if (GET_CODE (x) == REG) | |
147 | { | |
148 | fputc ('(', file); | |
149 | print_operand (file, x, 0); | |
150 | fputc (')', file); | |
151 | } | |
152 | else | |
153 | print_operand (file, x, 0); | |
154 | break; | |
155 | ||
156 | /* These are the least significant word in a 32bit value. | |
157 | 'o' allows us to sign extend a constant if doing so | |
158 | makes for more compact code. */ | |
159 | case 'L': | |
160 | case 'o': | |
161 | switch (GET_CODE (x)) | |
162 | { | |
163 | case MEM: | |
164 | fputc ('(', file); | |
165 | output_address (XEXP (x, 0)); | |
166 | fputc (')', file); | |
167 | break; | |
168 | ||
169 | case REG: | |
170 | fprintf (file, "%s", reg_names[REGNO (x)]); | |
171 | break; | |
172 | ||
173 | case SUBREG: | |
701e46d0 | 174 | fprintf (file, "%s", reg_names[subreg_regno (x)]); |
c418d182 | 175 | break; |
176 | ||
177 | case CONST_DOUBLE: | |
178 | if (code == 'L') | |
179 | { | |
180 | long val; | |
181 | REAL_VALUE_TYPE rv; | |
182 | ||
183 | REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
184 | REAL_VALUE_TO_TARGET_SINGLE (rv, val); | |
185 | print_operand_address (file, GEN_INT (val & 0xffff)); | |
186 | } | |
187 | else | |
188 | { | |
189 | long val; | |
190 | REAL_VALUE_TYPE rv; | |
191 | ||
192 | REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
193 | REAL_VALUE_TO_TARGET_SINGLE (rv, val); | |
194 | ||
195 | val &= 0xffff; | |
196 | val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000; | |
197 | print_operand_address (file, GEN_INT (val)); | |
198 | } | |
199 | break; | |
200 | ||
201 | case CONST_INT: | |
202 | if (code == 'L') | |
203 | print_operand_address (file, GEN_INT ((INTVAL (x) & 0xffff))); | |
204 | else | |
205 | { | |
206 | unsigned int val = INTVAL (x) & 0xffff; | |
207 | val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000; | |
208 | print_operand_address (file, GEN_INT (val)); | |
209 | } | |
210 | break; | |
211 | default: | |
212 | abort (); | |
213 | } | |
214 | break; | |
215 | ||
216 | /* Similarly, but for the most significant word. */ | |
217 | case 'H': | |
218 | case 'h': | |
219 | switch (GET_CODE (x)) | |
220 | { | |
221 | case MEM: | |
222 | fputc ('(', file); | |
eafc6604 | 223 | x = adjust_address (x, HImode, 2); |
c418d182 | 224 | output_address (XEXP (x, 0)); |
225 | fputc (')', file); | |
226 | break; | |
227 | ||
228 | case REG: | |
229 | fprintf (file, "%s", reg_names[REGNO (x) + 1]); | |
230 | break; | |
231 | ||
232 | case SUBREG: | |
701e46d0 | 233 | fprintf (file, "%s", reg_names[subreg_regno (x) + 1]); |
c418d182 | 234 | break; |
235 | ||
236 | case CONST_DOUBLE: | |
237 | if (code == 'H') | |
238 | { | |
239 | long val; | |
240 | REAL_VALUE_TYPE rv; | |
241 | ||
242 | REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
243 | REAL_VALUE_TO_TARGET_SINGLE (rv, val); | |
244 | ||
245 | print_operand_address (file, GEN_INT ((val >> 16) & 0xffff)); | |
246 | } | |
247 | else | |
248 | { | |
249 | long val; | |
250 | REAL_VALUE_TYPE rv; | |
251 | ||
252 | REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
253 | REAL_VALUE_TO_TARGET_SINGLE (rv, val); | |
254 | ||
255 | val = (val >> 16) & 0xffff; | |
256 | val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000; | |
257 | ||
258 | print_operand_address (file, GEN_INT (val)); | |
259 | } | |
260 | break; | |
261 | ||
262 | case CONST_INT: | |
263 | if (code == 'H') | |
264 | print_operand_address (file, | |
265 | GEN_INT ((INTVAL (x) >> 16) & 0xffff)); | |
266 | else | |
267 | { | |
268 | unsigned int val = (INTVAL (x) >> 16) & 0xffff; | |
269 | val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000; | |
270 | ||
271 | print_operand_address (file, GEN_INT (val)); | |
272 | } | |
273 | break; | |
274 | default: | |
275 | abort (); | |
276 | } | |
277 | break; | |
278 | ||
279 | /* Output ~CONST_INT. */ | |
280 | case 'N': | |
281 | if (GET_CODE (x) != CONST_INT) | |
282 | abort (); | |
283 | fprintf (file, "%d", ~INTVAL (x)); | |
284 | break; | |
285 | ||
286 | /* An address which can not be register indirect, if it is | |
287 | register indirect, then turn it into reg + disp. */ | |
288 | case 'A': | |
289 | if (GET_CODE (x) != MEM) | |
290 | abort (); | |
291 | if (GET_CODE (XEXP (x, 0)) == REG) | |
7014838c | 292 | x = gen_rtx_PLUS (PSImode, XEXP (x, 0), GEN_INT (0)); |
c418d182 | 293 | else |
294 | x = XEXP (x, 0); | |
295 | fputc ('(', file); | |
296 | output_address (x); | |
297 | fputc (')', file); | |
298 | break; | |
299 | ||
300 | case 'Z': | |
301 | print_operand (file, XEXP (x, 1), 0); | |
302 | break; | |
303 | ||
304 | /* More cases where we can sign-extend a CONST_INT if it | |
305 | results in more compact code. */ | |
306 | case 's': | |
307 | case 'S': | |
308 | if (GET_CODE (x) == CONST_INT) | |
309 | { | |
310 | int val = INTVAL (x); | |
311 | ||
312 | if (code == 's') | |
313 | x = GEN_INT (((val & 0xffff) ^ (~0x7fff)) + 0x8000); | |
314 | else | |
315 | x = GEN_INT (((val & 0xff) ^ (~0x7f)) + 0x80); | |
316 | } | |
317 | /* FALL THROUGH */ | |
318 | default: | |
319 | switch (GET_CODE (x)) | |
320 | { | |
321 | case MEM: | |
322 | fputc ('(', file); | |
323 | output_address (XEXP (x, 0)); | |
324 | fputc (')', file); | |
325 | break; | |
326 | ||
327 | case REG: | |
328 | fprintf (file, "%s", reg_names[REGNO (x)]); | |
329 | break; | |
330 | ||
331 | case SUBREG: | |
701e46d0 | 332 | fprintf (file, "%s", reg_names[subreg_regno (x)]); |
c418d182 | 333 | break; |
334 | ||
335 | case CONST_INT: | |
336 | case CONST_DOUBLE: | |
337 | case SYMBOL_REF: | |
338 | case CONST: | |
339 | case LABEL_REF: | |
340 | case CODE_LABEL: | |
341 | print_operand_address (file, x); | |
342 | break; | |
343 | default: | |
344 | abort (); | |
345 | } | |
346 | break; | |
347 | } | |
348 | } | |
349 | ||
350 | /* Output assembly language output for the address ADDR to FILE. */ | |
351 | ||
352 | void | |
353 | print_operand_address (file, addr) | |
354 | FILE *file; | |
355 | rtx addr; | |
356 | { | |
357 | switch (GET_CODE (addr)) | |
358 | { | |
359 | case REG: | |
360 | print_operand (file, addr, 0); | |
361 | break; | |
362 | case PLUS: | |
363 | { | |
364 | rtx base, index; | |
365 | /* The base and index could be in any order, so we have | |
366 | to figure out which is the base and which is the index. | |
367 | Uses the same code as GO_IF_LEGITIMATE_ADDRESS. */ | |
368 | if (REG_P (XEXP (addr, 0)) | |
369 | && REG_OK_FOR_BASE_P (XEXP (addr, 0))) | |
370 | base = XEXP (addr, 0), index = XEXP (addr, 1); | |
371 | else if (REG_P (XEXP (addr, 1)) | |
372 | && REG_OK_FOR_BASE_P (XEXP (addr, 1))) | |
373 | base = XEXP (addr, 1), index = XEXP (addr, 0); | |
374 | else | |
375 | abort (); | |
376 | print_operand (file, index, 0); | |
377 | fputc (',', file); | |
378 | print_operand (file, base, 0);; | |
379 | break; | |
380 | } | |
381 | case SYMBOL_REF: | |
382 | output_addr_const (file, addr); | |
383 | break; | |
384 | default: | |
385 | output_addr_const (file, addr); | |
386 | break; | |
387 | } | |
388 | } | |
389 | ||
390 | /* Count the number of tst insns which compare an address register | |
391 | with zero. */ | |
392 | static void | |
393 | count_tst_insns (areg_countp) | |
394 | int *areg_countp; | |
395 | { | |
396 | rtx insn; | |
397 | ||
398 | /* Assume no tst insns exist. */ | |
399 | *areg_countp = 0; | |
400 | ||
401 | /* If not optimizing, then quit now. */ | |
402 | if (!optimize) | |
403 | return; | |
404 | ||
405 | /* Walk through all the insns. */ | |
406 | for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) | |
407 | { | |
408 | rtx pat; | |
409 | ||
410 | /* Ignore anything that is not a normal INSN. */ | |
411 | if (GET_CODE (insn) != INSN) | |
412 | continue; | |
413 | ||
414 | /* Ignore anything that isn't a SET. */ | |
415 | pat = PATTERN (insn); | |
416 | if (GET_CODE (pat) != SET) | |
417 | continue; | |
418 | ||
419 | /* Check for a tst insn. */ | |
420 | if (SET_DEST (pat) == cc0_rtx | |
421 | && GET_CODE (SET_SRC (pat)) == REG | |
422 | && REGNO_REG_CLASS (REGNO (SET_SRC (pat))) == ADDRESS_REGS) | |
423 | (*areg_countp)++; | |
424 | } | |
425 | } | |
426 | ||
427 | /* Return the total size (in bytes) of the current function's frame. | |
428 | This is the size of the register save area + the size of locals, | |
429 | spills, etc. */ | |
430 | int | |
431 | total_frame_size () | |
432 | { | |
433 | unsigned int size = get_frame_size (); | |
434 | unsigned int outgoing_args_size = current_function_outgoing_args_size; | |
435 | int i; | |
436 | ||
437 | /* First figure out if we're going to use an out of line | |
438 | prologue, if so we have to make space for all the | |
439 | registers, even if we don't use them. */ | |
440 | if (optimize && !current_function_needs_context && !frame_pointer_needed) | |
441 | { | |
442 | int inline_count, outline_count; | |
443 | ||
444 | /* Compute how many bytes an inline prologue would take. | |
445 | ||
446 | Each address register store takes two bytes, each data register | |
447 | store takes three bytes. */ | |
448 | inline_count = 0; | |
449 | if (regs_ever_live[5]) | |
450 | inline_count += 2; | |
451 | if (regs_ever_live[6]) | |
452 | inline_count += 2; | |
453 | if (regs_ever_live[2]) | |
454 | inline_count += 3; | |
455 | if (regs_ever_live[3]) | |
456 | inline_count += 3; | |
457 | ||
458 | /* If this function has any stack, then the stack adjustment | |
459 | will take two (or more) bytes. */ | |
460 | if (size || outgoing_args_size | |
461 | || regs_ever_live[5] || regs_ever_live[6] | |
462 | || regs_ever_live[2] || regs_ever_live[3]) | |
463 | inline_count += 2; | |
464 | ||
465 | /* Multiply the current count by two and add one to account for the | |
466 | epilogue insns. */ | |
467 | inline_count = inline_count * 2 + 1; | |
468 | ||
469 | /* Now compute how many bytes an out of line sequence would take. */ | |
470 | /* A relaxed jsr will be three bytes. */ | |
471 | outline_count = 3; | |
472 | ||
473 | /* If there are outgoing arguments, then we will need a stack | |
474 | pointer adjustment after the call to the prologue, two | |
475 | more bytes. */ | |
476 | outline_count += (outgoing_args_size == 0 ? 0 : 2); | |
477 | ||
478 | /* If there is some local frame to allocate, it will need to be | |
479 | done before the call to the prologue, two more bytes. */ | |
480 | if (get_frame_size () != 0) | |
481 | outline_count += 2; | |
482 | ||
483 | /* Now account for the epilogue, multiply the base count by two, | |
484 | then deal with optimizing away the rts instruction. */ | |
485 | outline_count = outline_count * 2 + 1; | |
486 | ||
487 | if (get_frame_size () == 0 && outgoing_args_size == 0) | |
488 | outline_count -= 1; | |
489 | ||
490 | /* If an out of line prologue is smaller, use it. */ | |
491 | if (inline_count > outline_count) | |
492 | return size + outgoing_args_size + 16; | |
493 | } | |
494 | ||
495 | ||
496 | for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
497 | { | |
aebc2c24 | 498 | if ((regs_ever_live[i] && !call_used_regs[i] && ! fixed_regs[i]) |
c418d182 | 499 | || (i == FRAME_POINTER_REGNUM && frame_pointer_needed)) |
500 | size += 4; | |
501 | } | |
502 | ||
503 | return (size + outgoing_args_size); | |
504 | } | |
505 | ||
506 | /* Expand the prologue into RTL. */ | |
507 | void | |
508 | expand_prologue () | |
509 | { | |
510 | unsigned int size = total_frame_size (); | |
511 | unsigned int outgoing_args_size = current_function_outgoing_args_size; | |
512 | int offset, i; | |
513 | ||
514 | zero_areg = NULL_RTX; | |
515 | zero_dreg = NULL_RTX; | |
516 | ||
517 | /* If optimizing, see if we should do an out of line prologue/epilogue | |
518 | sequence. | |
519 | ||
520 | We don't support out of line prologues if the current function | |
521 | needs a context or frame pointer. */ | |
522 | if (optimize && !current_function_needs_context && !frame_pointer_needed) | |
523 | { | |
524 | int inline_count, outline_count, areg_count; | |
525 | ||
526 | /* We need to end the current sequence so that count_tst_insns can | |
527 | look at all the insns in this function. Normally this would be | |
528 | unsafe, but it's OK in the prologue/epilogue expanders. */ | |
529 | end_sequence (); | |
530 | ||
531 | /* Get a count of the number of tst insns which use address | |
532 | registers (it's not profitable to try and improve tst insns | |
533 | which use data registers). */ | |
534 | count_tst_insns (&areg_count); | |
535 | ||
536 | /* Now start a new sequence. */ | |
537 | start_sequence (); | |
538 | ||
539 | /* Compute how many bytes an inline prologue would take. | |
540 | ||
541 | Each address register store takes two bytes, each data register | |
542 | store takes three bytes. */ | |
543 | inline_count = 0; | |
544 | if (regs_ever_live[5]) | |
545 | inline_count += 2; | |
546 | if (regs_ever_live[6]) | |
547 | inline_count += 2; | |
548 | if (regs_ever_live[2]) | |
549 | inline_count += 3; | |
550 | if (regs_ever_live[3]) | |
551 | inline_count += 3; | |
552 | ||
553 | /* If this function has any stack, then the stack adjustment | |
554 | will take two (or more) bytes. */ | |
555 | if (size || outgoing_args_size | |
556 | || regs_ever_live[5] || regs_ever_live[6] | |
557 | || regs_ever_live[2] || regs_ever_live[3]) | |
558 | inline_count += 2; | |
559 | ||
560 | /* Multiply the current count by two and add one to account for the | |
561 | epilogue insns. */ | |
562 | inline_count = inline_count * 2 + 1; | |
563 | ||
564 | /* Now compute how many bytes an out of line sequence would take. */ | |
565 | /* A relaxed jsr will be three bytes. */ | |
566 | outline_count = 3; | |
567 | ||
568 | /* If there are outgoing arguments, then we will need a stack | |
569 | pointer adjustment after the call to the prologue, two | |
570 | more bytes. */ | |
571 | outline_count += (outgoing_args_size == 0 ? 0 : 2); | |
572 | ||
573 | /* If there is some local frame to allocate, it will need to be | |
574 | done before the call to the prologue, two more bytes. */ | |
575 | if (get_frame_size () != 0) | |
576 | outline_count += 2; | |
577 | ||
578 | /* Now account for the epilogue, multiply the base count by two, | |
579 | then deal with optimizing away the rts instruction. */ | |
580 | outline_count = outline_count * 2 + 1; | |
581 | ||
582 | if (get_frame_size () == 0 && outgoing_args_size == 0) | |
583 | outline_count -= 1; | |
584 | ||
585 | /* If an out of line prologue is smaller, use it. */ | |
586 | if (inline_count > outline_count) | |
587 | { | |
588 | if (get_frame_size () != 0) | |
589 | emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx, | |
590 | GEN_INT (-size + outgoing_args_size + 16))); | |
591 | emit_insn (gen_outline_prologue_call ()); | |
592 | ||
593 | if (outgoing_args_size) | |
594 | emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx, | |
595 | GEN_INT (-outgoing_args_size))); | |
596 | ||
597 | out_of_line_epilogue = 1; | |
598 | ||
599 | /* Determine if it is profitable to put the value zero into a register | |
600 | for the entire function. If so, set ZERO_DREG and ZERO_AREG. */ | |
601 | ||
602 | /* First see if we could load the value into a data register | |
603 | since that's the most efficient way. */ | |
604 | if (areg_count > 1 | |
605 | && (!regs_ever_live[2] || !regs_ever_live[3])) | |
606 | { | |
607 | if (!regs_ever_live[2]) | |
608 | { | |
609 | regs_ever_live[2] = 1; | |
7014838c | 610 | zero_dreg = gen_rtx_REG (HImode, 2); |
c418d182 | 611 | } |
612 | if (!regs_ever_live[3]) | |
613 | { | |
614 | regs_ever_live[3] = 1; | |
7014838c | 615 | zero_dreg = gen_rtx_REG (HImode, 3); |
c418d182 | 616 | } |
617 | } | |
618 | ||
ebb11c7b | 619 | /* Now see if we could load the value into an address register. */ |
c418d182 | 620 | if (zero_dreg == NULL_RTX |
621 | && areg_count > 2 | |
622 | && (!regs_ever_live[5] || !regs_ever_live[6])) | |
623 | { | |
624 | if (!regs_ever_live[5]) | |
625 | { | |
626 | regs_ever_live[5] = 1; | |
7014838c | 627 | zero_areg = gen_rtx_REG (HImode, 5); |
c418d182 | 628 | } |
629 | if (!regs_ever_live[6]) | |
630 | { | |
631 | regs_ever_live[6] = 1; | |
7014838c | 632 | zero_areg = gen_rtx_REG (HImode, 6); |
c418d182 | 633 | } |
634 | } | |
635 | ||
636 | if (zero_dreg) | |
637 | emit_move_insn (zero_dreg, const0_rtx); | |
638 | ||
639 | if (zero_areg) | |
640 | emit_move_insn (zero_areg, const0_rtx); | |
641 | ||
642 | return; | |
643 | } | |
644 | } | |
645 | ||
646 | out_of_line_epilogue = 0; | |
647 | ||
648 | /* Temporarily stuff the static chain onto the stack so we can | |
649 | use a0 as a scratch register during the prologue. */ | |
650 | if (current_function_needs_context) | |
651 | { | |
652 | emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx, | |
653 | GEN_INT (-4))); | |
7014838c | 654 | emit_move_insn (gen_rtx_MEM (PSImode, stack_pointer_rtx), |
655 | gen_rtx_REG (PSImode, STATIC_CHAIN_REGNUM)); | |
c418d182 | 656 | } |
657 | ||
658 | if (frame_pointer_needed) | |
659 | { | |
660 | /* Store a2 into a0 temporarily. */ | |
7014838c | 661 | emit_move_insn (gen_rtx_REG (PSImode, 4), frame_pointer_rtx); |
c418d182 | 662 | |
663 | /* Set up the frame pointer. */ | |
664 | emit_move_insn (frame_pointer_rtx, stack_pointer_rtx); | |
665 | } | |
666 | ||
667 | /* Make any necessary space for the saved registers and local frame. */ | |
668 | if (size) | |
669 | emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx, | |
670 | GEN_INT (-size))); | |
671 | ||
672 | /* Save the callee saved registers. They're saved into the top | |
673 | of the frame, using the stack pointer. */ | |
674 | for (i = 0, offset = outgoing_args_size; | |
675 | i < FIRST_PSEUDO_REGISTER; i++) | |
676 | { | |
aebc2c24 | 677 | if ((regs_ever_live[i] && !call_used_regs[i] && ! fixed_regs[i]) |
c418d182 | 678 | || (i == FRAME_POINTER_REGNUM && frame_pointer_needed)) |
679 | { | |
680 | int regno; | |
681 | ||
682 | /* If we're saving the frame pointer, then it will be found in | |
683 | register 4 (a0). */ | |
684 | regno = (i == FRAME_POINTER_REGNUM && frame_pointer_needed) ? 4 : i; | |
685 | ||
7014838c | 686 | emit_move_insn (gen_rtx_MEM (PSImode, |
687 | plus_constant (stack_pointer_rtx, | |
688 | offset)), | |
689 | gen_rtx_REG (PSImode, regno)); | |
c418d182 | 690 | offset += 4; |
691 | } | |
692 | } | |
693 | ||
694 | /* Now put the static chain back where the rest of the function | |
4ff5402e | 695 | expects to find it. |
696 | ||
697 | Note that we may eliminate all references to this later, so we | |
698 | mark the static chain as maybe dead. */ | |
c418d182 | 699 | if (current_function_needs_context) |
700 | { | |
4ff5402e | 701 | rtx insn; |
702 | ||
703 | insn = emit_move_insn (gen_rtx_REG (PSImode, STATIC_CHAIN_REGNUM), | |
704 | gen_rtx (MEM, PSImode, | |
705 | gen_rtx_PLUS (PSImode, | |
706 | stack_pointer_rtx, | |
707 | GEN_INT (size)))); | |
708 | REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, | |
709 | const0_rtx, | |
710 | REG_NOTES (insn)); | |
711 | ||
c418d182 | 712 | } |
713 | } | |
714 | ||
715 | /* Expand the epilogue into RTL. */ | |
716 | void | |
717 | expand_epilogue () | |
718 | { | |
719 | unsigned int size; | |
720 | unsigned int outgoing_args_size = current_function_outgoing_args_size; | |
721 | int offset, i, temp_regno; | |
722 | rtx basereg; | |
723 | ||
724 | size = total_frame_size (); | |
725 | ||
726 | if (DECL_RESULT (current_function_decl) | |
c2effb6d | 727 | && POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl)))) |
728 | temp_regno = 0; | |
c418d182 | 729 | else |
730 | temp_regno = 4; | |
731 | ||
732 | /* Emit an out of line epilogue sequence if it's profitable to do so. */ | |
733 | if (out_of_line_epilogue) | |
734 | { | |
735 | /* If there were no outgoing arguments and no local frame, then | |
736 | we will be able to omit the rts at the end of this function, | |
737 | so just jump to the epilogue_noreturn routine. */ | |
738 | if (get_frame_size () == 0 && outgoing_args_size == 0) | |
739 | { | |
740 | emit_jump_insn (gen_outline_epilogue_jump ()); | |
741 | return; | |
742 | } | |
743 | ||
744 | if (outgoing_args_size) | |
745 | emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx, | |
746 | GEN_INT (outgoing_args_size))); | |
747 | ||
748 | if (temp_regno == 0) | |
749 | emit_insn (gen_outline_epilogue_call_d0 ()); | |
750 | else if (temp_regno == 4) | |
751 | emit_insn (gen_outline_epilogue_call_a0 ()); | |
752 | ||
753 | if (get_frame_size () != 0) | |
754 | emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx, | |
755 | GEN_INT (size - outgoing_args_size - 16))); | |
756 | emit_jump_insn (gen_return_internal ()); | |
757 | return; | |
758 | } | |
759 | ||
760 | /* Registers are restored from the frame pointer if we have one, | |
761 | else they're restored from the stack pointer. Figure out | |
762 | the appropriate offset to the register save area for both cases. */ | |
763 | if (frame_pointer_needed) | |
764 | { | |
765 | basereg = frame_pointer_rtx; | |
766 | offset = -(size - outgoing_args_size); | |
767 | } | |
768 | else | |
769 | { | |
770 | basereg = stack_pointer_rtx; | |
771 | offset = outgoing_args_size; | |
772 | } | |
773 | ||
774 | /* Restore each register. */ | |
775 | for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
776 | { | |
aebc2c24 | 777 | if ((regs_ever_live[i] && !call_used_regs[i] && ! fixed_regs[i]) |
c418d182 | 778 | || (i == FRAME_POINTER_REGNUM && frame_pointer_needed)) |
779 | { | |
780 | int regno; | |
781 | ||
782 | /* Restore the frame pointer (if it exists) into a temporary | |
783 | register. */ | |
784 | regno = ((i == FRAME_POINTER_REGNUM && frame_pointer_needed) | |
785 | ? temp_regno : i); | |
786 | ||
7014838c | 787 | emit_move_insn (gen_rtx_REG (PSImode, regno), |
788 | gen_rtx_MEM (PSImode, | |
789 | plus_constant (basereg, offset))); | |
c418d182 | 790 | offset += 4; |
791 | } | |
792 | } | |
793 | ||
794 | if (frame_pointer_needed) | |
795 | { | |
796 | /* Deallocate this frame's stack. */ | |
797 | emit_move_insn (stack_pointer_rtx, frame_pointer_rtx); | |
798 | /* Restore the old frame pointer. */ | |
7014838c | 799 | emit_move_insn (frame_pointer_rtx, gen_rtx_REG (PSImode, temp_regno)); |
c418d182 | 800 | } |
801 | else if (size) | |
802 | { | |
803 | /* Deallocate this function's stack. */ | |
804 | emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx, | |
805 | GEN_INT (size))); | |
806 | } | |
807 | ||
808 | /* If we had to allocate a slot to save the context pointer, | |
809 | then it must be deallocated here. */ | |
810 | if (current_function_needs_context) | |
811 | emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (4))); | |
812 | ||
813 | /* Emit the return insn, if this function had no stack, then we | |
814 | can use the standard return (which allows more optimizations), | |
815 | else we have to use the special one which inhibits optimizations. */ | |
816 | if (size == 0 && !current_function_needs_context) | |
817 | emit_jump_insn (gen_return ()); | |
818 | else | |
819 | emit_jump_insn (gen_return_internal ()); | |
820 | } | |
821 | ||
822 | /* Update the condition code from the insn. */ | |
823 | ||
824 | void | |
825 | notice_update_cc (body, insn) | |
826 | rtx body; | |
827 | rtx insn; | |
828 | { | |
829 | switch (get_attr_cc (insn)) | |
830 | { | |
831 | case CC_NONE: | |
832 | /* Insn does not affect CC at all. */ | |
833 | break; | |
834 | ||
835 | case CC_NONE_0HIT: | |
836 | /* Insn does not change CC, but the 0'th operand has been changed. */ | |
837 | if (cc_status.value1 != 0 | |
ed420a25 | 838 | && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1)) |
c418d182 | 839 | cc_status.value1 = 0; |
840 | break; | |
841 | ||
842 | case CC_SET_ZN: | |
ed420a25 | 843 | /* Insn sets the Z,N flags of CC to recog_data.operand[0]. |
c418d182 | 844 | V,C is in an unusable state. */ |
845 | CC_STATUS_INIT; | |
846 | cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY; | |
ed420a25 | 847 | cc_status.value1 = recog_data.operand[0]; |
c418d182 | 848 | break; |
849 | ||
850 | case CC_SET_ZNV: | |
ed420a25 | 851 | /* Insn sets the Z,N,V flags of CC to recog_data.operand[0]. |
c418d182 | 852 | C is in an unusable state. */ |
853 | CC_STATUS_INIT; | |
854 | cc_status.flags |= CC_NO_CARRY; | |
ed420a25 | 855 | cc_status.value1 = recog_data.operand[0]; |
c418d182 | 856 | break; |
857 | ||
858 | case CC_COMPARE: | |
859 | /* The insn is a compare instruction. */ | |
860 | CC_STATUS_INIT; | |
861 | cc_status.value1 = SET_SRC (body); | |
862 | break; | |
863 | ||
864 | case CC_CLOBBER: | |
865 | /* Insn doesn't leave CC in a usable state. */ | |
866 | CC_STATUS_INIT; | |
867 | break; | |
868 | ||
869 | default: | |
870 | CC_STATUS_INIT; | |
871 | break; | |
872 | } | |
873 | } | |
874 | ||
875 | /* Return true if OP is a valid call operand. Valid call operands | |
876 | are SYMBOL_REFs and REGs. */ | |
877 | int | |
878 | call_address_operand (op, mode) | |
879 | rtx op; | |
aebc2c24 | 880 | enum machine_mode mode ATTRIBUTE_UNUSED; |
c418d182 | 881 | { |
882 | return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG); | |
c418d182 | 883 | } |
884 | ||
885 | /* Return true if OP is a memory operand with a constant address. | |
886 | A special PSImode move pattern uses this predicate. */ | |
887 | int | |
888 | constant_memory_operand (op, mode) | |
889 | rtx op; | |
aebc2c24 | 890 | enum machine_mode mode ATTRIBUTE_UNUSED; |
c418d182 | 891 | { |
892 | return GET_CODE (op) == MEM && CONSTANT_ADDRESS_P (XEXP (op, 0)); | |
893 | } | |
894 | ||
6a7c9c13 | 895 | /* Return true if OP is valid for a psi mode truncation operand. |
896 | It must either be a memory operand which is valid for a PSImode | |
897 | address, or if it is not a memory operand at all. */ | |
898 | int | |
899 | psimode_truncation_operand (op, mode) | |
900 | rtx op; | |
901 | enum machine_mode mode; | |
902 | { | |
903 | return (general_operand (op, mode) | |
904 | && (GET_CODE (op) != MEM | |
905 | || memory_address_p (PSImode, XEXP (op, 0)))); | |
906 | } | |
907 | ||
c418d182 | 908 | /* What (if any) secondary registers are needed to move IN with mode |
909 | MODE into a register from in register class CLASS. | |
910 | ||
911 | We might be able to simplify this. */ | |
912 | enum reg_class | |
913 | secondary_reload_class (class, mode, in, input) | |
914 | enum reg_class class; | |
915 | enum machine_mode mode; | |
916 | rtx in; | |
917 | int input; | |
918 | { | |
c418d182 | 919 | /* Memory loads less than a full word wide can't have an |
920 | address or stack pointer destination. They must use | |
921 | a data register as an intermediate register. */ | |
922 | if (input | |
923 | && GET_CODE (in) == MEM | |
924 | && (mode == QImode) | |
925 | && class == ADDRESS_REGS) | |
926 | return DATA_REGS; | |
927 | ||
ad87de1e | 928 | /* Address register stores which are not PSImode need a scratch register. */ |
c418d182 | 929 | if (! input |
930 | && GET_CODE (in) == MEM | |
931 | && (mode != PSImode) | |
932 | && class == ADDRESS_REGS) | |
933 | return DATA_REGS; | |
934 | ||
935 | /* Otherwise assume no secondary reloads are needed. */ | |
936 | return NO_REGS; | |
937 | } | |
938 | ||
939 | \f | |
940 | /* Shifts. | |
941 | ||
942 | We devote a fair bit of code to getting efficient shifts since we can only | |
943 | shift one bit at a time, and each single bit shift may take multiple | |
944 | instructions. | |
945 | ||
946 | The basic shift methods: | |
947 | ||
e911aedf | 948 | * loop shifts -- emit a loop using one (or two on H8S) bit shifts; |
c418d182 | 949 | this is the default. SHIFT_LOOP |
950 | ||
951 | * inlined shifts -- emit straight line code for the shift; this is | |
952 | used when a straight line shift is about the same size or smaller | |
953 | than a loop. We allow the inline version to be slightly longer in | |
954 | some cases as it saves a register. SHIFT_INLINE | |
955 | ||
956 | * There other oddballs. Not worth explaining. SHIFT_SPECIAL | |
957 | ||
958 | ||
959 | HImode shifts: | |
960 | ||
961 | 1-4 do them inline | |
962 | ||
963 | 5-7 If ashift, then multiply, else loop. | |
964 | ||
965 | 8-14 - If ashift, then multiply, if lshiftrt, then divide, else loop. | |
966 | 15 - rotate the bit we want into the carry, clear the destination, | |
967 | (use mov 0,dst, not sub as sub will clobber the carry), then | |
968 | move bit into place. | |
969 | ||
970 | Don't Panic, it's not nearly as bad as the H8 shifting code!!! */ | |
971 | ||
972 | int | |
973 | nshift_operator (x, mode) | |
974 | rtx x; | |
aebc2c24 | 975 | enum machine_mode mode ATTRIBUTE_UNUSED; |
c418d182 | 976 | { |
977 | switch (GET_CODE (x)) | |
978 | { | |
979 | case ASHIFTRT: | |
980 | case LSHIFTRT: | |
981 | case ASHIFT: | |
982 | return 1; | |
983 | ||
984 | default: | |
985 | return 0; | |
986 | } | |
987 | } | |
988 | ||
989 | /* Called from the .md file to emit code to do shifts. | |
990 | Returns a boolean indicating success | |
991 | (currently this is always TRUE). */ | |
992 | ||
993 | int | |
994 | expand_a_shift (mode, code, operands) | |
995 | enum machine_mode mode; | |
996 | int code; | |
997 | rtx operands[]; | |
998 | { | |
999 | emit_move_insn (operands[0], operands[1]); | |
1000 | ||
1001 | /* need a loop to get all the bits we want - we generate the | |
1002 | code at emit time, but need to allocate a scratch reg now */ | |
1003 | ||
7014838c | 1004 | emit_insn (gen_rtx_PARALLEL |
1005 | (VOIDmode, | |
c418d182 | 1006 | gen_rtvec (2, |
7014838c | 1007 | gen_rtx_SET (VOIDmode, operands[0], |
1008 | gen_rtx (code, mode, | |
1009 | operands[0], operands[2])), | |
1010 | gen_rtx_CLOBBER (VOIDmode, | |
1011 | gen_rtx_SCRATCH (HImode))))); | |
c418d182 | 1012 | |
1013 | return 1; | |
1014 | } | |
1015 | ||
1016 | /* Shift algorithm determination. | |
1017 | ||
1018 | There are various ways of doing a shift: | |
1019 | SHIFT_INLINE: If the amount is small enough, just generate as many one-bit | |
1020 | shifts as we need. | |
1021 | SHIFT_SPECIAL: Hand crafted assembler. | |
1022 | SHIFT_LOOP: If the above methods fail, just loop. */ | |
1023 | ||
1024 | enum shift_alg | |
1025 | { | |
1026 | SHIFT_INLINE, | |
1027 | SHIFT_SPECIAL, | |
1028 | SHIFT_LOOP, | |
1029 | SHIFT_MAX | |
1030 | }; | |
1031 | ||
1032 | /* Symbols of the various shifts which can be used as indices. */ | |
1033 | ||
1034 | enum shift_type | |
1035 | { | |
1036 | SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT | |
1037 | }; | |
1038 | ||
1039 | /* Symbols of the various modes which can be used as indices. */ | |
1040 | ||
1041 | enum shift_mode | |
1042 | { | |
feb9af9f | 1043 | HIshift |
c418d182 | 1044 | }; |
1045 | ||
1046 | /* For single bit shift insns, record assembler and what bits of the | |
1047 | condition code are valid afterwards (represented as various CC_FOO | |
1048 | bits, 0 means CC isn't left in a usable state). */ | |
1049 | ||
1050 | struct shift_insn | |
1051 | { | |
aebc2c24 | 1052 | const char *assembler; |
c418d182 | 1053 | int cc_valid; |
1054 | }; | |
1055 | ||
1056 | /* Assembler instruction shift table. | |
1057 | ||
1058 | These tables are used to look up the basic shifts. | |
1059 | They are indexed by cpu, shift_type, and mode. | |
1060 | */ | |
1061 | ||
1062 | static const struct shift_insn shift_one[3][3] = | |
1063 | { | |
1064 | { | |
1065 | /* SHIFT_ASHIFT */ | |
1066 | { "add\t%0,%0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }, | |
1067 | }, | |
1068 | /* SHIFT_LSHIFTRT */ | |
1069 | { | |
1070 | { "lsr\t%0", CC_NO_CARRY }, | |
1071 | }, | |
1072 | /* SHIFT_ASHIFTRT */ | |
1073 | { | |
1074 | { "asr\t%0", CC_NO_CARRY }, | |
1075 | }, | |
1076 | }; | |
1077 | ||
aebc2c24 | 1078 | static enum shift_alg get_shift_alg PARAMS ((enum shift_type, |
1079 | enum machine_mode, int, | |
1080 | const char **, int *)); | |
1081 | ||
c418d182 | 1082 | /* Given CPU, MODE, SHIFT_TYPE, and shift count COUNT, determine the best |
1083 | algorithm for doing the shift. The assembler code is stored in ASSEMBLER. | |
1084 | We don't achieve maximum efficiency in all cases, but the hooks are here | |
1085 | to do so. | |
1086 | ||
1087 | For now we just use lots of switch statements. Since we don't even come | |
1088 | close to supporting all the cases, this is simplest. If this function ever | |
1089 | gets too big, perhaps resort to a more table based lookup. Of course, | |
1090 | at this point you may just wish to do it all in rtl. */ | |
1091 | ||
1092 | static enum shift_alg | |
1093 | get_shift_alg (shift_type, mode, count, assembler_p, cc_valid_p) | |
1094 | enum shift_type shift_type; | |
1095 | enum machine_mode mode; | |
1096 | int count; | |
1097 | const char **assembler_p; | |
1098 | int *cc_valid_p; | |
1099 | { | |
1100 | /* The default is to loop. */ | |
1101 | enum shift_alg alg = SHIFT_LOOP; | |
1102 | enum shift_mode shift_mode; | |
1103 | ||
1104 | /* We don't handle negative shifts or shifts greater than the word size, | |
1105 | they should have been handled already. */ | |
1106 | ||
1107 | if (count < 0 || count > GET_MODE_BITSIZE (mode)) | |
1108 | abort (); | |
1109 | ||
1110 | switch (mode) | |
1111 | { | |
1112 | case HImode: | |
1113 | shift_mode = HIshift; | |
1114 | break; | |
1115 | default: | |
1116 | abort (); | |
1117 | } | |
1118 | ||
1119 | /* Assume either SHIFT_LOOP or SHIFT_INLINE. | |
1120 | It is up to the caller to know that looping clobbers cc. */ | |
1121 | *assembler_p = shift_one[shift_type][shift_mode].assembler; | |
1122 | *cc_valid_p = shift_one[shift_type][shift_mode].cc_valid; | |
1123 | ||
1124 | /* Now look for cases we want to optimize. */ | |
1125 | ||
1126 | switch (shift_mode) | |
1127 | { | |
1128 | case HIshift: | |
1129 | if (count <= 4) | |
1130 | return SHIFT_INLINE; | |
1131 | else if (count < 15 && shift_type != SHIFT_ASHIFTRT) | |
1132 | { | |
1133 | switch (count) | |
1134 | { | |
1135 | case 5: | |
1136 | if (shift_type == SHIFT_ASHIFT) | |
1137 | *assembler_p = "mov 32,%4\n\tmul %4,%0"; | |
1138 | else if (shift_type == SHIFT_LSHIFTRT) | |
1139 | *assembler_p | |
1140 | = "sub %4,%4\n\tmov %4,mdr\n\tmov 32,%4\n\tdivu %4,%0"; | |
1141 | *cc_valid_p = CC_NO_CARRY; | |
1142 | return SHIFT_SPECIAL; | |
1143 | case 6: | |
1144 | if (shift_type == SHIFT_ASHIFT) | |
1145 | *assembler_p = "mov 64,%4\n\tmul %4,%0"; | |
1146 | else if (shift_type == SHIFT_LSHIFTRT) | |
1147 | *assembler_p | |
1148 | = "sub %4,%4\n\tmov %4,mdr\n\tmov 64,%4\n\tdivu %4,%0"; | |
1149 | *cc_valid_p = CC_NO_CARRY; | |
1150 | return SHIFT_SPECIAL; | |
1151 | case 7: | |
1152 | if (shift_type == SHIFT_ASHIFT) | |
1153 | *assembler_p = "mov 128,%4\n\tmul %4,%0"; | |
1154 | else if (shift_type == SHIFT_LSHIFTRT) | |
1155 | *assembler_p | |
1156 | = "sub %4,%4\n\tmov %4,mdr\n\tmov 128,%4\n\tdivu %4,%0"; | |
1157 | *cc_valid_p = CC_NO_CARRY; | |
1158 | return SHIFT_SPECIAL; | |
1159 | case 8: | |
1160 | if (shift_type == SHIFT_ASHIFT) | |
1161 | *assembler_p = "mov 256,%4\n\tmul %4,%0"; | |
1162 | else if (shift_type == SHIFT_LSHIFTRT) | |
1163 | *assembler_p | |
1164 | = "sub %4,%4\n\tmov %4,mdr\n\tmov 256,%4\n\tdivu %4,%0"; | |
1165 | *cc_valid_p = CC_NO_CARRY; | |
1166 | return SHIFT_SPECIAL; | |
1167 | case 9: | |
1168 | if (shift_type == SHIFT_ASHIFT) | |
1169 | *assembler_p = "mov 512,%4\n\tmul %4,%0"; | |
1170 | else if (shift_type == SHIFT_LSHIFTRT) | |
1171 | *assembler_p | |
1172 | = "sub %4,%4\n\tmov %4,mdr\n\tmov 512,%4\n\tdivu %4,%0"; | |
1173 | *cc_valid_p = CC_NO_CARRY; | |
1174 | return SHIFT_SPECIAL; | |
1175 | case 10: | |
1176 | if (shift_type == SHIFT_ASHIFT) | |
1177 | *assembler_p = "mov 1024,%4\n\tmul %4,%0"; | |
1178 | else if (shift_type == SHIFT_LSHIFTRT) | |
1179 | *assembler_p | |
1180 | = "sub %4,%4\n\tmov %4,mdr\n\tmov 1024,%4\n\tdivu %4,%0"; | |
1181 | *cc_valid_p = CC_NO_CARRY; | |
1182 | return SHIFT_SPECIAL; | |
1183 | case 11: | |
1184 | if (shift_type == SHIFT_ASHIFT) | |
1185 | *assembler_p = "mov 2048,%4\n\tmul %4,%0"; | |
1186 | else if (shift_type == SHIFT_LSHIFTRT) | |
1187 | *assembler_p | |
1188 | = "sub %4,%4\n\tmov %4,mdr\n\tmov 2048,%4\n\tdivu %4,%0"; | |
1189 | *cc_valid_p = CC_NO_CARRY; | |
1190 | return SHIFT_SPECIAL; | |
1191 | case 12: | |
1192 | if (shift_type == SHIFT_ASHIFT) | |
1193 | *assembler_p = "mov 4096,%4\n\tmul %4,%0"; | |
1194 | else if (shift_type == SHIFT_LSHIFTRT) | |
1195 | *assembler_p | |
1196 | = "sub %4,%4\n\tmov %4,mdr\n\tmov 4096,%4\n\tdivu %4,%0"; | |
1197 | *cc_valid_p = CC_NO_CARRY; | |
1198 | return SHIFT_SPECIAL; | |
1199 | case 13: | |
1200 | if (shift_type == SHIFT_ASHIFT) | |
1201 | *assembler_p = "mov 8192,%4\n\tmul %4,%0"; | |
1202 | else if (shift_type == SHIFT_LSHIFTRT) | |
1203 | *assembler_p | |
1204 | = "sub %4,%4\n\tmov %4,mdr\n\tmov 8192,%4\n\tdivu %4,%0"; | |
1205 | *cc_valid_p = CC_NO_CARRY; | |
1206 | return SHIFT_SPECIAL; | |
1207 | case 14: | |
1208 | if (shift_type == SHIFT_ASHIFT) | |
1209 | *assembler_p = "mov 16384,%4\n\tmul %4,%0"; | |
1210 | else if (shift_type == SHIFT_LSHIFTRT) | |
1211 | *assembler_p | |
1212 | = "sub %4,%4\n\tmov %4,mdr\n\tmov 16384,%4\n\tdivu %4,%0"; | |
1213 | *cc_valid_p = CC_NO_CARRY; | |
1214 | return SHIFT_SPECIAL; | |
1215 | } | |
1216 | } | |
1217 | else if (count == 15) | |
1218 | { | |
1219 | if (shift_type == SHIFT_ASHIFTRT) | |
1220 | { | |
1221 | *assembler_p = "add\t%0,%0\n\tsubc\t%0,%0\n"; | |
1222 | *cc_valid_p = CC_NO_CARRY; | |
1223 | return SHIFT_SPECIAL; | |
1224 | } | |
1225 | if (shift_type == SHIFT_LSHIFTRT) | |
1226 | { | |
1227 | *assembler_p = "add\t%0,%0\n\tmov 0,%0\n\trol %0\n"; | |
1228 | *cc_valid_p = CC_NO_CARRY; | |
1229 | return SHIFT_SPECIAL; | |
1230 | } | |
1231 | if (shift_type == SHIFT_ASHIFT) | |
1232 | { | |
1233 | *assembler_p = "ror\t%0\n\tmov 0,%0\n\tror %0\n"; | |
1234 | *cc_valid_p = CC_NO_CARRY; | |
1235 | return SHIFT_SPECIAL; | |
1236 | } | |
1237 | } | |
1238 | break; | |
1239 | ||
1240 | default: | |
1241 | abort (); | |
1242 | } | |
1243 | ||
1244 | return alg; | |
1245 | } | |
1246 | ||
1247 | /* Emit the assembler code for doing shifts. */ | |
1248 | ||
aebc2c24 | 1249 | const char * |
c418d182 | 1250 | emit_a_shift (insn, operands) |
aebc2c24 | 1251 | rtx insn ATTRIBUTE_UNUSED; |
c418d182 | 1252 | rtx *operands; |
1253 | { | |
1254 | static int loopend_lab; | |
aebc2c24 | 1255 | const char *assembler; |
c418d182 | 1256 | int cc_valid; |
c418d182 | 1257 | rtx shift = operands[3]; |
1258 | enum machine_mode mode = GET_MODE (shift); | |
1259 | enum rtx_code code = GET_CODE (shift); | |
1260 | enum shift_type shift_type; | |
1261 | enum shift_mode shift_mode; | |
1262 | ||
1263 | loopend_lab++; | |
1264 | ||
1265 | switch (mode) | |
1266 | { | |
1267 | case HImode: | |
1268 | shift_mode = HIshift; | |
1269 | break; | |
1270 | default: | |
1271 | abort (); | |
1272 | } | |
1273 | ||
1274 | switch (code) | |
1275 | { | |
1276 | case ASHIFTRT: | |
1277 | shift_type = SHIFT_ASHIFTRT; | |
1278 | break; | |
1279 | case LSHIFTRT: | |
1280 | shift_type = SHIFT_LSHIFTRT; | |
1281 | break; | |
1282 | case ASHIFT: | |
1283 | shift_type = SHIFT_ASHIFT; | |
1284 | break; | |
1285 | default: | |
1286 | abort (); | |
1287 | } | |
1288 | ||
1289 | if (GET_CODE (operands[2]) != CONST_INT) | |
1290 | { | |
1291 | /* Indexing by reg, so have to loop and test at top */ | |
1292 | output_asm_insn ("mov %2,%4", operands); | |
1293 | output_asm_insn ("cmp 0,%4", operands); | |
1294 | fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab); | |
1295 | ||
1296 | /* Get the assembler code to do one shift. */ | |
1297 | get_shift_alg (shift_type, mode, 1, &assembler, &cc_valid); | |
1298 | } | |
1299 | else | |
1300 | { | |
1301 | int n = INTVAL (operands[2]); | |
1302 | enum shift_alg alg; | |
1303 | ||
1304 | /* If the count is negative, make it 0. */ | |
1305 | if (n < 0) | |
1306 | n = 0; | |
1307 | /* If the count is too big, truncate it. | |
1308 | ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to | |
1309 | do the intuitive thing. */ | |
1310 | else if (n > GET_MODE_BITSIZE (mode)) | |
1311 | n = GET_MODE_BITSIZE (mode); | |
1312 | ||
1313 | alg = get_shift_alg (shift_type, mode, n, &assembler, &cc_valid); | |
1314 | ||
1315 | ||
1316 | switch (alg) | |
1317 | { | |
1318 | case SHIFT_INLINE: | |
1319 | /* Emit one bit shifts. */ | |
1320 | while (n > 0) | |
1321 | { | |
1322 | output_asm_insn (assembler, operands); | |
1323 | n -= 1; | |
1324 | } | |
1325 | ||
1326 | /* Keep track of CC. */ | |
1327 | if (cc_valid) | |
1328 | { | |
1329 | cc_status.value1 = operands[0]; | |
1330 | cc_status.flags |= cc_valid; | |
1331 | } | |
1332 | return ""; | |
1333 | ||
1334 | case SHIFT_SPECIAL: | |
1335 | output_asm_insn (assembler, operands); | |
1336 | ||
1337 | /* Keep track of CC. */ | |
1338 | if (cc_valid) | |
1339 | { | |
1340 | cc_status.value1 = operands[0]; | |
1341 | cc_status.flags |= cc_valid; | |
1342 | } | |
1343 | return ""; | |
1344 | } | |
1345 | ||
1346 | { | |
1347 | fprintf (asm_out_file, "\tmov %d,%s\n", n, | |
1348 | reg_names[REGNO (operands[4])]); | |
1349 | fprintf (asm_out_file, ".Llt%d:\n", loopend_lab); | |
1350 | output_asm_insn (assembler, operands); | |
1351 | output_asm_insn ("add -1,%4", operands); | |
1352 | fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab); | |
1353 | return ""; | |
1354 | } | |
1355 | } | |
1356 | ||
1357 | fprintf (asm_out_file, ".Llt%d:\n", loopend_lab); | |
1358 | output_asm_insn (assembler, operands); | |
1359 | output_asm_insn ("add -1,%4", operands); | |
1360 | fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab); | |
1361 | fprintf (asm_out_file, ".Lle%d:\n", loopend_lab); | |
1362 | ||
1363 | return ""; | |
1364 | } | |
1365 | ||
1366 | /* Return an RTX to represent where a value with mode MODE will be returned | |
1367 | from a function. If the result is 0, the argument is pushed. */ | |
1368 | ||
1369 | rtx | |
1370 | function_arg (cum, mode, type, named) | |
1371 | CUMULATIVE_ARGS *cum; | |
1372 | enum machine_mode mode; | |
1373 | tree type; | |
1374 | int named; | |
1375 | { | |
1376 | rtx result = 0; | |
1377 | int size, align; | |
1378 | ||
1379 | /* We only support using 2 data registers as argument registers. */ | |
1380 | int nregs = 2; | |
1381 | ||
1382 | /* Only pass named arguments in registers. */ | |
1383 | if (!named) | |
1384 | return NULL_RTX; | |
1385 | ||
1386 | /* Figure out the size of the object to be passed. We lie and claim | |
1387 | PSImode values are only two bytes since they fit in a single | |
1388 | register. */ | |
1389 | if (mode == BLKmode) | |
1390 | size = int_size_in_bytes (type); | |
1391 | else if (mode == PSImode) | |
1392 | size = 2; | |
1393 | else | |
1394 | size = GET_MODE_SIZE (mode); | |
1395 | ||
1396 | /* Figure out the alignment of the object to be passed. */ | |
1397 | align = size; | |
1398 | ||
1399 | cum->nbytes = (cum->nbytes + 1) & ~1; | |
1400 | ||
1401 | /* Don't pass this arg via a register if all the argument registers | |
1402 | are used up. */ | |
1403 | if (cum->nbytes + size > nregs * UNITS_PER_WORD) | |
1404 | return 0; | |
1405 | ||
1406 | switch (cum->nbytes / UNITS_PER_WORD) | |
1407 | { | |
1408 | case 0: | |
7014838c | 1409 | result = gen_rtx_REG (mode, 0); |
c418d182 | 1410 | break; |
1411 | case 1: | |
7014838c | 1412 | result = gen_rtx_REG (mode, 1); |
c418d182 | 1413 | break; |
1414 | default: | |
1415 | result = 0; | |
1416 | } | |
1417 | ||
1418 | return result; | |
1419 | } | |
1420 | ||
1421 | /* Return the number of registers to use for an argument passed partially | |
1422 | in registers and partially in memory. */ | |
1423 | ||
1424 | int | |
1425 | function_arg_partial_nregs (cum, mode, type, named) | |
1426 | CUMULATIVE_ARGS *cum; | |
1427 | enum machine_mode mode; | |
1428 | tree type; | |
1429 | int named; | |
1430 | { | |
1431 | int size, align; | |
1432 | ||
1433 | /* We only support using 2 data registers as argument registers. */ | |
1434 | int nregs = 2; | |
1435 | ||
1436 | return 0; | |
1437 | /* Only pass named arguments in registers. */ | |
1438 | if (!named) | |
1439 | return 0; | |
1440 | ||
1441 | /* Figure out the size of the object to be passed. */ | |
1442 | if (mode == BLKmode) | |
1443 | size = int_size_in_bytes (type); | |
1444 | else if (mode == PSImode) | |
1445 | size = 2; | |
1446 | else | |
1447 | size = GET_MODE_SIZE (mode); | |
1448 | ||
1449 | /* Figure out the alignment of the object to be passed. */ | |
1450 | align = size; | |
1451 | ||
1452 | cum->nbytes = (cum->nbytes + 1) & ~1; | |
1453 | ||
1454 | /* Don't pass this arg via a register if all the argument registers | |
1455 | are used up. */ | |
1456 | if (cum->nbytes > nregs * UNITS_PER_WORD) | |
1457 | return 0; | |
1458 | ||
1459 | if (cum->nbytes + size <= nregs * UNITS_PER_WORD) | |
1460 | return 0; | |
1461 | ||
1462 | /* Don't pass this arg via a register if it would be split between | |
1463 | registers and memory. */ | |
1464 | if (type == NULL_TREE | |
1465 | && cum->nbytes + size > nregs * UNITS_PER_WORD) | |
1466 | return 0; | |
1467 | ||
1468 | return (nregs * UNITS_PER_WORD - cum->nbytes) / UNITS_PER_WORD; | |
1469 | } | |
1470 | ||
1e77b0ba | 1471 | rtx |
1472 | mn10200_va_arg (valist, type) | |
1473 | tree valist, type; | |
1474 | { | |
1475 | HOST_WIDE_INT align, rsize; | |
1476 | tree t, ptr, pptr; | |
1477 | ||
1478 | /* Compute the rounded size of the type. */ | |
1479 | align = PARM_BOUNDARY / BITS_PER_UNIT; | |
1480 | rsize = (((int_size_in_bytes (type) + align - 1) / align) * align); | |
1481 | ||
1482 | t = build (POSTINCREMENT_EXPR, TREE_TYPE (valist), valist, | |
1483 | build_int_2 ((rsize > 8 ? 4 : rsize), 0)); | |
1484 | TREE_SIDE_EFFECTS (t) = 1; | |
1485 | ||
1486 | ptr = build_pointer_type (type); | |
1487 | ||
1488 | /* "Large" types are passed by reference. */ | |
1489 | if (rsize > 8) | |
1490 | { | |
1491 | pptr = build_pointer_type (ptr); | |
1492 | t = build1 (NOP_EXPR, pptr, t); | |
1493 | TREE_SIDE_EFFECTS (t) = 1; | |
1494 | ||
1495 | t = build1 (INDIRECT_REF, ptr, t); | |
1496 | TREE_SIDE_EFFECTS (t) = 1; | |
1497 | } | |
1498 | else | |
1499 | { | |
1500 | t = build1 (NOP_EXPR, ptr, t); | |
1501 | TREE_SIDE_EFFECTS (t) = 1; | |
1502 | } | |
1503 | ||
1504 | /* Calculate! */ | |
760f82b7 | 1505 | return force_reg (Pmode, expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL)); |
1e77b0ba | 1506 | } |
1507 | ||
aebc2c24 | 1508 | const char * |
c418d182 | 1509 | output_tst (operand, insn) |
1510 | rtx operand, insn; | |
1511 | { | |
1512 | ||
1513 | rtx temp; | |
1514 | int past_call = 0; | |
1515 | ||
1516 | /* Only tst insns using address registers can be optimized. */ | |
1517 | if (REGNO_REG_CLASS (REGNO (operand)) != ADDRESS_REGS) | |
1518 | return "cmp 0,%0"; | |
1519 | ||
1520 | /* If testing an address register against zero, we can do better if | |
1521 | we know there's a register already holding the value zero. First | |
1522 | see if a global register has been set to zero, else we do a search | |
1523 | for a register holding zero, if both of those fail, then we use a | |
1524 | compare against zero. */ | |
1525 | if (zero_dreg || zero_areg) | |
1526 | { | |
1527 | rtx xoperands[2]; | |
1528 | xoperands[0] = operand; | |
1529 | xoperands[1] = zero_dreg ? zero_dreg : zero_areg; | |
1530 | ||
1531 | output_asm_insn ("cmp %1,%0", xoperands); | |
1532 | return ""; | |
1533 | } | |
1534 | ||
1535 | /* We can save a byte if we can find a register which has the value | |
1536 | zero in it. */ | |
1537 | temp = PREV_INSN (insn); | |
1538 | while (temp) | |
1539 | { | |
1540 | rtx set; | |
1541 | ||
1542 | /* We allow the search to go through call insns. We record | |
1543 | the fact that we've past a CALL_INSN and reject matches which | |
1544 | use call clobbered registers. */ | |
1545 | if (GET_CODE (temp) == CODE_LABEL | |
1546 | || GET_CODE (temp) == JUMP_INSN | |
1547 | || GET_CODE (temp) == BARRIER) | |
1548 | break; | |
1549 | ||
1550 | if (GET_CODE (temp) == CALL_INSN) | |
1551 | past_call = 1; | |
1552 | ||
1553 | if (GET_CODE (temp) == NOTE) | |
1554 | { | |
1555 | temp = PREV_INSN (temp); | |
1556 | continue; | |
1557 | } | |
1558 | ||
1559 | /* It must be an insn, see if it is a simple set. */ | |
1560 | set = single_set (temp); | |
1561 | if (!set) | |
1562 | { | |
1563 | temp = PREV_INSN (temp); | |
1564 | continue; | |
1565 | } | |
1566 | ||
1567 | /* Are we setting a register to zero? | |
1568 | ||
1569 | If it's a call clobbered register, have we past a call? */ | |
1570 | if (REG_P (SET_DEST (set)) | |
1571 | && SET_SRC (set) == CONST0_RTX (GET_MODE (SET_DEST (set))) | |
1572 | && !reg_set_between_p (SET_DEST (set), temp, insn) | |
1573 | && (!past_call | |
1574 | || !call_used_regs[REGNO (SET_DEST (set))])) | |
1575 | { | |
1576 | rtx xoperands[2]; | |
1577 | xoperands[0] = operand; | |
1578 | xoperands[1] = SET_DEST (set); | |
1579 | ||
1580 | output_asm_insn ("cmp %1,%0", xoperands); | |
1581 | return ""; | |
1582 | } | |
1583 | temp = PREV_INSN (temp); | |
1584 | } | |
1585 | return "cmp 0,%0"; | |
1586 | } | |
1587 | ||
1588 | /* Return nonzero if OP is a valid operand for a {zero,sign}_extendpsisi | |
1589 | instruction. | |
1590 | ||
1591 | It accepts anything that is a general operand or the sum of the | |
1592 | stack pointer and a general operand. */ | |
aebc2c24 | 1593 | int |
c418d182 | 1594 | extendpsi_operand (op, mode) |
1595 | rtx op; | |
1596 | enum machine_mode mode; | |
1597 | { | |
1598 | return (general_operand (op, mode) | |
1599 | || (GET_CODE (op) == PLUS | |
1600 | && XEXP (op, 0) == stack_pointer_rtx | |
1601 | && general_operand (XEXP (op, 1), VOIDmode))); | |
1602 | } |