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