Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/mn10300/mn10300.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Subroutines for insn-output.c for Matsushita MN10300 series | 1 /* Subroutines for insn-output.c for Matsushita MN10300 series |
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | 2 Copyright (C) 1996-2017 Free Software Foundation, Inc. |
3 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. | |
4 Contributed by Jeff Law (law@cygnus.com). | 3 Contributed by Jeff Law (law@cygnus.com). |
5 | 4 |
6 This file is part of GCC. | 5 This file is part of GCC. |
7 | 6 |
8 GCC is free software; you can redistribute it and/or modify | 7 GCC is free software; you can redistribute it and/or modify |
20 <http://www.gnu.org/licenses/>. */ | 19 <http://www.gnu.org/licenses/>. */ |
21 | 20 |
22 #include "config.h" | 21 #include "config.h" |
23 #include "system.h" | 22 #include "system.h" |
24 #include "coretypes.h" | 23 #include "coretypes.h" |
25 #include "tm.h" | 24 #include "backend.h" |
25 #include "target.h" | |
26 #include "rtl.h" | 26 #include "rtl.h" |
27 #include "tree.h" | 27 #include "tree.h" |
28 #include "stringpool.h" | |
29 #include "attribs.h" | |
30 #include "cfghooks.h" | |
31 #include "cfgloop.h" | |
32 #include "df.h" | |
33 #include "memmodel.h" | |
34 #include "tm_p.h" | |
35 #include "optabs.h" | |
28 #include "regs.h" | 36 #include "regs.h" |
29 #include "hard-reg-set.h" | 37 #include "emit-rtl.h" |
30 #include "insn-config.h" | 38 #include "recog.h" |
31 #include "conditions.h" | 39 #include "diagnostic-core.h" |
40 #include "alias.h" | |
41 #include "stor-layout.h" | |
42 #include "varasm.h" | |
43 #include "calls.h" | |
32 #include "output.h" | 44 #include "output.h" |
33 #include "insn-attr.h" | 45 #include "insn-attr.h" |
34 #include "flags.h" | |
35 #include "recog.h" | |
36 #include "reload.h" | 46 #include "reload.h" |
47 #include "explow.h" | |
37 #include "expr.h" | 48 #include "expr.h" |
38 #include "optabs.h" | |
39 #include "function.h" | |
40 #include "obstack.h" | |
41 #include "diagnostic-core.h" | |
42 #include "tm_p.h" | |
43 #include "tm-constrs.h" | 49 #include "tm-constrs.h" |
44 #include "target.h" | 50 #include "cfgrtl.h" |
51 #include "dumpfile.h" | |
52 #include "builtins.h" | |
53 | |
54 /* This file should be included last. */ | |
45 #include "target-def.h" | 55 #include "target-def.h" |
46 #include "df.h" | |
47 | 56 |
48 /* This is used in the am33_2.0-linux-gnu port, in which global symbol | 57 /* This is used in the am33_2.0-linux-gnu port, in which global symbol |
49 names are not prefixed by underscores, to tell whether to prefix a | 58 names are not prefixed by underscores, to tell whether to prefix a |
50 label with a plus sign or not, so that the assembler can tell | 59 label with a plus sign or not, so that the assembler can tell |
51 symbol names from register names. */ | 60 symbol names from register names. */ |
52 int mn10300_protect_label; | 61 int mn10300_protect_label; |
53 | 62 |
54 /* The selected processor. */ | |
55 enum processor_type mn10300_processor = PROCESSOR_DEFAULT; | |
56 | |
57 /* Processor type to select for tuning. */ | |
58 static const char * mn10300_tune_string = NULL; | |
59 | |
60 /* Selected processor type for tuning. */ | 63 /* Selected processor type for tuning. */ |
61 enum processor_type mn10300_tune_cpu = PROCESSOR_DEFAULT; | 64 enum processor_type mn10300_tune_cpu = PROCESSOR_DEFAULT; |
62 | |
63 /* The size of the callee register save area. Right now we save everything | |
64 on entry since it costs us nothing in code size. It does cost us from a | |
65 speed standpoint, so we want to optimize this sooner or later. */ | |
66 #define REG_SAVE_BYTES (4 * df_regs_ever_live_p (2) \ | |
67 + 4 * df_regs_ever_live_p (3) \ | |
68 + 4 * df_regs_ever_live_p (6) \ | |
69 + 4 * df_regs_ever_live_p (7) \ | |
70 + 16 * (df_regs_ever_live_p (14) \ | |
71 || df_regs_ever_live_p (15) \ | |
72 || df_regs_ever_live_p (16) \ | |
73 || df_regs_ever_live_p (17))) | |
74 | |
75 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ | |
76 static const struct default_options mn10300_option_optimization_table[] = | |
77 { | |
78 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, | |
79 { OPT_LEVELS_NONE, 0, NULL, 0 } | |
80 }; | |
81 | 65 |
82 #define CC_FLAG_Z 1 | 66 #define CC_FLAG_Z 1 |
83 #define CC_FLAG_N 2 | 67 #define CC_FLAG_N 2 |
84 #define CC_FLAG_C 4 | 68 #define CC_FLAG_C 4 |
85 #define CC_FLAG_V 8 | 69 #define CC_FLAG_V 8 |
86 | 70 |
87 static int cc_flags_for_mode(enum machine_mode); | 71 static int cc_flags_for_mode(machine_mode); |
88 static int cc_flags_for_code(enum rtx_code); | 72 static int cc_flags_for_code(enum rtx_code); |
89 | 73 |
90 /* Implement TARGET_HANDLE_OPTION. */ | |
91 | |
92 static bool | |
93 mn10300_handle_option (size_t code, | |
94 const char *arg ATTRIBUTE_UNUSED, | |
95 int value) | |
96 { | |
97 switch (code) | |
98 { | |
99 case OPT_mam33: | |
100 mn10300_processor = value ? PROCESSOR_AM33 : PROCESSOR_MN10300; | |
101 return true; | |
102 | |
103 case OPT_mam33_2: | |
104 mn10300_processor = (value | |
105 ? PROCESSOR_AM33_2 | |
106 : MIN (PROCESSOR_AM33, PROCESSOR_DEFAULT)); | |
107 return true; | |
108 | |
109 case OPT_mam34: | |
110 mn10300_processor = (value ? PROCESSOR_AM34 : PROCESSOR_DEFAULT); | |
111 return true; | |
112 | |
113 case OPT_mtune_: | |
114 mn10300_tune_string = arg; | |
115 return true; | |
116 | |
117 default: | |
118 return true; | |
119 } | |
120 } | |
121 | |
122 /* Implement TARGET_OPTION_OVERRIDE. */ | 74 /* Implement TARGET_OPTION_OVERRIDE. */ |
123 | |
124 static void | 75 static void |
125 mn10300_option_override (void) | 76 mn10300_option_override (void) |
126 { | 77 { |
127 if (TARGET_AM33) | 78 if (TARGET_AM33) |
128 target_flags &= ~MASK_MULT_BUG; | 79 target_flags &= ~MASK_MULT_BUG; |
196 | 147 |
197 case 'b': | 148 case 'b': |
198 case 'B': | 149 case 'B': |
199 { | 150 { |
200 enum rtx_code cmp = GET_CODE (x); | 151 enum rtx_code cmp = GET_CODE (x); |
201 enum machine_mode mode = GET_MODE (XEXP (x, 0)); | 152 machine_mode mode = GET_MODE (XEXP (x, 0)); |
202 const char *str; | 153 const char *str; |
203 int have_flags; | 154 int have_flags; |
204 | 155 |
205 if (code == 'B') | 156 if (code == 'B') |
206 cmp = reverse_condition (cmp); | 157 cmp = reverse_condition (cmp); |
289 case 'D': | 240 case 'D': |
290 switch (GET_CODE (x)) | 241 switch (GET_CODE (x)) |
291 { | 242 { |
292 case MEM: | 243 case MEM: |
293 fputc ('(', file); | 244 fputc ('(', file); |
294 output_address (XEXP (x, 0)); | 245 output_address (GET_MODE (x), XEXP (x, 0)); |
295 fputc (')', file); | 246 fputc (')', file); |
296 break; | 247 break; |
297 | 248 |
298 case REG: | 249 case REG: |
299 fprintf (file, "fd%d", REGNO (x) - 18); | 250 fprintf (file, "fd%d", REGNO (x) - 18); |
308 case 'L': | 259 case 'L': |
309 switch (GET_CODE (x)) | 260 switch (GET_CODE (x)) |
310 { | 261 { |
311 case MEM: | 262 case MEM: |
312 fputc ('(', file); | 263 fputc ('(', file); |
313 output_address (XEXP (x, 0)); | 264 output_address (GET_MODE (x), XEXP (x, 0)); |
314 fputc (')', file); | 265 fputc (')', file); |
315 break; | 266 break; |
316 | 267 |
317 case REG: | 268 case REG: |
318 fprintf (file, "%s", reg_names[REGNO (x)]); | 269 fprintf (file, "%s", reg_names[REGNO (x)]); |
323 break; | 274 break; |
324 | 275 |
325 case CONST_DOUBLE: | 276 case CONST_DOUBLE: |
326 { | 277 { |
327 long val[2]; | 278 long val[2]; |
328 REAL_VALUE_TYPE rv; | |
329 | 279 |
330 switch (GET_MODE (x)) | 280 switch (GET_MODE (x)) |
331 { | 281 { |
332 case DFmode: | 282 case E_DFmode: |
333 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | 283 REAL_VALUE_TO_TARGET_DOUBLE |
334 REAL_VALUE_TO_TARGET_DOUBLE (rv, val); | 284 (*CONST_DOUBLE_REAL_VALUE (x), val); |
335 fprintf (file, "0x%lx", val[0]); | 285 fprintf (file, "0x%lx", val[0]); |
336 break;; | 286 break;; |
337 case SFmode: | 287 case E_SFmode: |
338 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | 288 REAL_VALUE_TO_TARGET_SINGLE |
339 REAL_VALUE_TO_TARGET_SINGLE (rv, val[0]); | 289 (*CONST_DOUBLE_REAL_VALUE (x), val[0]); |
340 fprintf (file, "0x%lx", val[0]); | 290 fprintf (file, "0x%lx", val[0]); |
341 break;; | 291 break;; |
342 case VOIDmode: | 292 case E_VOIDmode: |
343 case DImode: | 293 case E_DImode: |
344 mn10300_print_operand_address (file, | 294 mn10300_print_operand_address (file, |
345 GEN_INT (CONST_DOUBLE_LOW (x))); | 295 GEN_INT (CONST_DOUBLE_LOW (x))); |
346 break; | 296 break; |
347 default: | 297 default: |
348 break; | 298 break; |
368 switch (GET_CODE (x)) | 318 switch (GET_CODE (x)) |
369 { | 319 { |
370 case MEM: | 320 case MEM: |
371 fputc ('(', file); | 321 fputc ('(', file); |
372 x = adjust_address (x, SImode, 4); | 322 x = adjust_address (x, SImode, 4); |
373 output_address (XEXP (x, 0)); | 323 output_address (GET_MODE (x), XEXP (x, 0)); |
374 fputc (')', file); | 324 fputc (')', file); |
375 break; | 325 break; |
376 | 326 |
377 case REG: | 327 case REG: |
378 fprintf (file, "%s", reg_names[REGNO (x) + 1]); | 328 fprintf (file, "%s", reg_names[REGNO (x) + 1]); |
383 break; | 333 break; |
384 | 334 |
385 case CONST_DOUBLE: | 335 case CONST_DOUBLE: |
386 { | 336 { |
387 long val[2]; | 337 long val[2]; |
388 REAL_VALUE_TYPE rv; | |
389 | 338 |
390 switch (GET_MODE (x)) | 339 switch (GET_MODE (x)) |
391 { | 340 { |
392 case DFmode: | 341 case E_DFmode: |
393 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | 342 REAL_VALUE_TO_TARGET_DOUBLE |
394 REAL_VALUE_TO_TARGET_DOUBLE (rv, val); | 343 (*CONST_DOUBLE_REAL_VALUE (x), val); |
395 fprintf (file, "0x%lx", val[1]); | 344 fprintf (file, "0x%lx", val[1]); |
396 break;; | 345 break;; |
397 case SFmode: | 346 case E_SFmode: |
398 gcc_unreachable (); | 347 gcc_unreachable (); |
399 case VOIDmode: | 348 case E_VOIDmode: |
400 case DImode: | 349 case E_DImode: |
401 mn10300_print_operand_address (file, | 350 mn10300_print_operand_address (file, |
402 GEN_INT (CONST_DOUBLE_HIGH (x))); | 351 GEN_INT (CONST_DOUBLE_HIGH (x))); |
403 break; | 352 break; |
404 default: | 353 default: |
405 break; | 354 break; |
421 break; | 370 break; |
422 | 371 |
423 case 'A': | 372 case 'A': |
424 fputc ('(', file); | 373 fputc ('(', file); |
425 if (REG_P (XEXP (x, 0))) | 374 if (REG_P (XEXP (x, 0))) |
426 output_address (gen_rtx_PLUS (SImode, XEXP (x, 0), const0_rtx)); | 375 output_address (VOIDmode, gen_rtx_PLUS (SImode, |
376 XEXP (x, 0), const0_rtx)); | |
427 else | 377 else |
428 output_address (XEXP (x, 0)); | 378 output_address (VOIDmode, XEXP (x, 0)); |
429 fputc (')', file); | 379 fputc (')', file); |
430 break; | 380 break; |
431 | 381 |
432 case 'N': | 382 case 'N': |
433 gcc_assert (INTVAL (x) >= -128 && INTVAL (x) <= 255); | 383 gcc_assert (INTVAL (x) >= -128 && INTVAL (x) <= 255); |
454 default: | 404 default: |
455 switch (GET_CODE (x)) | 405 switch (GET_CODE (x)) |
456 { | 406 { |
457 case MEM: | 407 case MEM: |
458 fputc ('(', file); | 408 fputc ('(', file); |
459 output_address (XEXP (x, 0)); | 409 output_address (GET_MODE (x), XEXP (x, 0)); |
460 fputc (')', file); | 410 fputc (')', file); |
461 break; | 411 break; |
462 | 412 |
463 case PLUS: | 413 case PLUS: |
464 output_address (x); | 414 output_address (VOIDmode, x); |
465 break; | 415 break; |
466 | 416 |
467 case REG: | 417 case REG: |
468 fprintf (file, "%s", reg_names[REGNO (x)]); | 418 fprintf (file, "%s", reg_names[REGNO (x)]); |
469 break; | 419 break; |
474 | 424 |
475 /* This will only be single precision.... */ | 425 /* This will only be single precision.... */ |
476 case CONST_DOUBLE: | 426 case CONST_DOUBLE: |
477 { | 427 { |
478 unsigned long val; | 428 unsigned long val; |
479 REAL_VALUE_TYPE rv; | 429 |
480 | 430 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val); |
481 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
482 REAL_VALUE_TO_TARGET_SINGLE (rv, val); | |
483 fprintf (file, "0x%lx", val); | 431 fprintf (file, "0x%lx", val); |
484 break; | 432 break; |
485 } | 433 } |
486 | 434 |
487 case CONST_INT: | 435 case CONST_INT: |
675 return !mn10300_initial_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM); | 623 return !mn10300_initial_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM); |
676 } | 624 } |
677 | 625 |
678 /* Returns the set of live, callee-saved registers as a bitmask. The | 626 /* Returns the set of live, callee-saved registers as a bitmask. The |
679 callee-saved extended registers cannot be stored individually, so | 627 callee-saved extended registers cannot be stored individually, so |
680 all of them will be included in the mask if any one of them is used. */ | 628 all of them will be included in the mask if any one of them is used. |
681 | 629 Also returns the number of bytes in the registers in the mask if |
682 int | 630 BYTES_SAVED is not NULL. */ |
683 mn10300_get_live_callee_saved_regs (void) | 631 |
632 unsigned int | |
633 mn10300_get_live_callee_saved_regs (unsigned int * bytes_saved) | |
684 { | 634 { |
685 int mask; | 635 int mask; |
686 int i; | 636 int i; |
687 | 637 unsigned int count; |
688 mask = 0; | 638 |
639 count = mask = 0; | |
689 for (i = 0; i <= LAST_EXTENDED_REGNUM; i++) | 640 for (i = 0; i <= LAST_EXTENDED_REGNUM; i++) |
690 if (df_regs_ever_live_p (i) && ! call_really_used_regs[i]) | 641 if (df_regs_ever_live_p (i) && ! call_really_used_regs[i]) |
691 mask |= (1 << i); | 642 { |
643 mask |= (1 << i); | |
644 ++ count; | |
645 } | |
646 | |
692 if ((mask & 0x3c000) != 0) | 647 if ((mask & 0x3c000) != 0) |
693 mask |= 0x3c000; | 648 { |
649 for (i = 0x04000; i < 0x40000; i <<= 1) | |
650 if ((mask & i) == 0) | |
651 ++ count; | |
652 | |
653 mask |= 0x3c000; | |
654 } | |
655 | |
656 if (bytes_saved) | |
657 * bytes_saved = count * UNITS_PER_WORD; | |
694 | 658 |
695 return mask; | 659 return mask; |
696 } | 660 } |
697 | 661 |
698 static rtx | 662 static rtx |
752 | 716 |
753 if (((mask >> regno) & 1) == 0) | 717 if (((mask >> regno) & 1) == 0) |
754 continue; | 718 continue; |
755 | 719 |
756 ++count; | 720 ++count; |
757 x = plus_constant (stack_pointer_rtx, count * -4); | 721 x = plus_constant (Pmode, stack_pointer_rtx, count * -4); |
758 x = gen_frame_mem (SImode, x); | 722 x = gen_frame_mem (SImode, x); |
759 x = gen_rtx_SET (VOIDmode, x, gen_rtx_REG (SImode, regno)); | 723 x = gen_rtx_SET (x, gen_rtx_REG (SImode, regno)); |
760 elts[count] = F(x); | 724 elts[count] = F(x); |
761 | 725 |
762 /* Remove the register from the mask so that... */ | 726 /* Remove the register from the mask so that... */ |
763 mask &= ~(1u << regno); | 727 mask &= ~(1u << regno); |
764 } | 728 } |
766 /* ... we can make sure that we didn't try to use a register | 730 /* ... we can make sure that we didn't try to use a register |
767 not listed in the store order. */ | 731 not listed in the store order. */ |
768 gcc_assert (mask == 0); | 732 gcc_assert (mask == 0); |
769 | 733 |
770 /* Create the instruction that updates the stack pointer. */ | 734 /* Create the instruction that updates the stack pointer. */ |
771 x = plus_constant (stack_pointer_rtx, count * -4); | 735 x = plus_constant (Pmode, stack_pointer_rtx, count * -4); |
772 x = gen_rtx_SET (VOIDmode, stack_pointer_rtx, x); | 736 x = gen_rtx_SET (stack_pointer_rtx, x); |
773 elts[0] = F(x); | 737 elts[0] = F(x); |
774 | 738 |
775 /* We need one PARALLEL element to update the stack pointer and | 739 /* We need one PARALLEL element to update the stack pointer and |
776 an additional element for each register that is stored. */ | 740 an additional element for each register that is stored. */ |
777 x = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (count + 1, elts)); | 741 x = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (count + 1, elts)); |
778 F (emit_insn (x)); | 742 F (emit_insn (x)); |
779 } | 743 } |
780 | 744 |
745 static inline unsigned int | |
746 popcount (unsigned int mask) | |
747 { | |
748 unsigned int count = 0; | |
749 | |
750 while (mask) | |
751 { | |
752 ++ count; | |
753 mask &= ~ (mask & - mask); | |
754 } | |
755 return count; | |
756 } | |
757 | |
781 void | 758 void |
782 mn10300_expand_prologue (void) | 759 mn10300_expand_prologue (void) |
783 { | 760 { |
784 HOST_WIDE_INT size = mn10300_frame_size (); | 761 HOST_WIDE_INT size = mn10300_frame_size (); |
785 | 762 unsigned int mask; |
763 | |
764 mask = mn10300_get_live_callee_saved_regs (NULL); | |
786 /* If we use any of the callee-saved registers, save them now. */ | 765 /* If we use any of the callee-saved registers, save them now. */ |
787 mn10300_gen_multiple_store (mn10300_get_live_callee_saved_regs ()); | 766 mn10300_gen_multiple_store (mask); |
767 | |
768 if (flag_stack_usage_info) | |
769 current_function_static_stack_size = size + popcount (mask) * 4; | |
788 | 770 |
789 if (TARGET_AM33_2 && fp_regs_to_save ()) | 771 if (TARGET_AM33_2 && fp_regs_to_save ()) |
790 { | 772 { |
791 int num_regs_to_save = fp_regs_to_save (), i; | 773 int num_regs_to_save = fp_regs_to_save (), i; |
792 HOST_WIDE_INT xsize; | 774 HOST_WIDE_INT xsize; |
798 save_a0_merge, | 780 save_a0_merge, |
799 save_a0_no_merge | 781 save_a0_no_merge |
800 } strategy; | 782 } strategy; |
801 unsigned int strategy_size = (unsigned)-1, this_strategy_size; | 783 unsigned int strategy_size = (unsigned)-1, this_strategy_size; |
802 rtx reg; | 784 rtx reg; |
785 | |
786 if (flag_stack_usage_info) | |
787 current_function_static_stack_size += num_regs_to_save * 4; | |
803 | 788 |
804 /* We have several different strategies to save FP registers. | 789 /* We have several different strategies to save FP registers. |
805 We can store them using SP offsets, which is beneficial if | 790 We can store them using SP offsets, which is beneficial if |
806 there are just a few registers to save, or we can use `a0' in | 791 there are just a few registers to save, or we can use `a0' in |
807 post-increment mode (`a0' is the only call-clobbered address | 792 post-increment mode (`a0' is the only call-clobbered address |
1039 | 1024 |
1040 void | 1025 void |
1041 mn10300_expand_epilogue (void) | 1026 mn10300_expand_epilogue (void) |
1042 { | 1027 { |
1043 HOST_WIDE_INT size = mn10300_frame_size (); | 1028 HOST_WIDE_INT size = mn10300_frame_size (); |
1044 int reg_save_bytes = REG_SAVE_BYTES; | 1029 unsigned int reg_save_bytes; |
1045 | 1030 |
1031 mn10300_get_live_callee_saved_regs (& reg_save_bytes); | |
1032 | |
1046 if (TARGET_AM33_2 && fp_regs_to_save ()) | 1033 if (TARGET_AM33_2 && fp_regs_to_save ()) |
1047 { | 1034 { |
1048 int num_regs_to_save = fp_regs_to_save (), i; | 1035 int num_regs_to_save = fp_regs_to_save (), i; |
1049 rtx reg = 0; | 1036 rtx reg = 0; |
1050 | 1037 |
1110 if (size + 4 * num_regs_to_save + reg_save_bytes > 255) | 1097 if (size + 4 * num_regs_to_save + reg_save_bytes > 255) |
1111 { | 1098 { |
1112 /* Insn: add size + 4 * num_regs_to_save | 1099 /* Insn: add size + 4 * num_regs_to_save |
1113 + reg_save_bytes - 252,sp. */ | 1100 + reg_save_bytes - 252,sp. */ |
1114 this_strategy_size = SIZE_ADD_SP (size + 4 * num_regs_to_save | 1101 this_strategy_size = SIZE_ADD_SP (size + 4 * num_regs_to_save |
1115 + reg_save_bytes - 252); | 1102 + (int) reg_save_bytes - 252); |
1116 /* Insn: fmov (##,sp),fs#, fo each fs# to be restored. */ | 1103 /* Insn: fmov (##,sp),fs#, fo each fs# to be restored. */ |
1117 this_strategy_size += SIZE_FMOV_SP (252 - reg_save_bytes | 1104 this_strategy_size += SIZE_FMOV_SP (252 - reg_save_bytes |
1118 - 4 * num_regs_to_save, | 1105 - 4 * num_regs_to_save, |
1119 num_regs_to_save); | 1106 num_regs_to_save); |
1120 /* We're going to use ret to release the FP registers | 1107 /* We're going to use ret to release the FP registers |
1258 size = 0; | 1245 size = 0; |
1259 } | 1246 } |
1260 | 1247 |
1261 /* Adjust the stack and restore callee-saved registers, if any. */ | 1248 /* Adjust the stack and restore callee-saved registers, if any. */ |
1262 if (mn10300_can_use_rets_insn ()) | 1249 if (mn10300_can_use_rets_insn ()) |
1263 emit_jump_insn (gen_rtx_RETURN (VOIDmode)); | 1250 emit_jump_insn (ret_rtx); |
1264 else | 1251 else |
1265 emit_jump_insn (gen_return_ret (GEN_INT (size + REG_SAVE_BYTES))); | 1252 emit_jump_insn (gen_return_ret (GEN_INT (size + reg_save_bytes))); |
1266 } | 1253 } |
1267 | 1254 |
1268 /* Recognize the PARALLEL rtx generated by mn10300_gen_multiple_store(). | 1255 /* Recognize the PARALLEL rtx generated by mn10300_gen_multiple_store(). |
1269 This function is for MATCH_PARALLEL and so assumes OP is known to be | 1256 This function is for MATCH_PARALLEL and so assumes OP is known to be |
1270 parallel. If OP is a multiple store, return a mask indicating which | 1257 parallel. If OP is a multiple store, return a mask indicating which |
1271 registers it saves. Return 0 otherwise. */ | 1258 registers it saves. Return 0 otherwise. */ |
1272 | 1259 |
1273 int | 1260 unsigned int |
1274 mn10300_store_multiple_operation (rtx op, | 1261 mn10300_store_multiple_regs (rtx op) |
1275 enum machine_mode mode ATTRIBUTE_UNUSED) | |
1276 { | 1262 { |
1277 int count; | 1263 int count; |
1278 int mask; | 1264 int mask; |
1279 int i; | 1265 int i; |
1280 unsigned int last; | 1266 unsigned int last; |
1367 | 1353 |
1368 /* Implement TARGET_SECONDARY_RELOAD. */ | 1354 /* Implement TARGET_SECONDARY_RELOAD. */ |
1369 | 1355 |
1370 static reg_class_t | 1356 static reg_class_t |
1371 mn10300_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i, | 1357 mn10300_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i, |
1372 enum machine_mode mode, secondary_reload_info *sri) | 1358 machine_mode mode, secondary_reload_info *sri) |
1373 { | 1359 { |
1374 enum reg_class rclass = (enum reg_class) rclass_i; | 1360 enum reg_class rclass = (enum reg_class) rclass_i; |
1375 enum reg_class xclass = NO_REGS; | 1361 enum reg_class xclass = NO_REGS; |
1376 unsigned int xregno = INVALID_REGNUM; | 1362 unsigned int xregno = INVALID_REGNUM; |
1377 | 1363 |
1433 { | 1419 { |
1434 rtx addr = NULL; | 1420 rtx addr = NULL; |
1435 | 1421 |
1436 if (xregno >= FIRST_PSEUDO_REGISTER && xregno != INVALID_REGNUM) | 1422 if (xregno >= FIRST_PSEUDO_REGISTER && xregno != INVALID_REGNUM) |
1437 { | 1423 { |
1438 addr = reg_equiv_mem [xregno]; | 1424 addr = reg_equiv_mem (xregno); |
1439 if (addr) | 1425 if (addr) |
1440 addr = XEXP (addr, 0); | 1426 addr = XEXP (addr, 0); |
1441 } | 1427 } |
1442 else if (MEM_P (x)) | 1428 else if (MEM_P (x)) |
1443 addr = XEXP (x, 0); | 1429 addr = XEXP (x, 0); |
1444 | 1430 |
1445 if (addr && CONSTANT_ADDRESS_P (addr)) | 1431 if (addr && CONSTANT_ADDRESS_P (addr)) |
1446 return GENERAL_REGS; | 1432 return GENERAL_REGS; |
1447 } | 1433 } |
1448 | |
1449 /* Otherwise assume no secondary reloads are needed. */ | 1434 /* Otherwise assume no secondary reloads are needed. */ |
1450 return NO_REGS; | 1435 return NO_REGS; |
1451 } | 1436 } |
1452 | 1437 |
1453 int | 1438 int |
1475 | 1460 |
1476 /* The difference between the argument pointer and the frame pointer | 1461 /* The difference between the argument pointer and the frame pointer |
1477 is the size of the callee register save area. */ | 1462 is the size of the callee register save area. */ |
1478 if (from == ARG_POINTER_REGNUM) | 1463 if (from == ARG_POINTER_REGNUM) |
1479 { | 1464 { |
1480 diff += REG_SAVE_BYTES; | 1465 unsigned int reg_save_bytes; |
1466 | |
1467 mn10300_get_live_callee_saved_regs (& reg_save_bytes); | |
1468 diff += reg_save_bytes; | |
1481 diff += 4 * fp_regs_to_save (); | 1469 diff += 4 * fp_regs_to_save (); |
1482 } | 1470 } |
1483 | 1471 |
1484 return diff; | 1472 return diff; |
1485 } | 1473 } |
1505 int argadj = ((!stdarg_p (fntype)) | 1493 int argadj = ((!stdarg_p (fntype)) |
1506 ? UNITS_PER_WORD : 0); | 1494 ? UNITS_PER_WORD : 0); |
1507 alias_set_type set = get_varargs_alias_set (); | 1495 alias_set_type set = get_varargs_alias_set (); |
1508 | 1496 |
1509 if (argadj) | 1497 if (argadj) |
1510 offset = plus_constant (crtl->args.arg_offset_rtx, argadj); | 1498 offset = plus_constant (Pmode, crtl->args.arg_offset_rtx, argadj); |
1511 else | 1499 else |
1512 offset = crtl->args.arg_offset_rtx; | 1500 offset = crtl->args.arg_offset_rtx; |
1513 | 1501 |
1514 mem = gen_rtx_MEM (SImode, crtl->args.internal_arg_pointer); | 1502 mem = gen_rtx_MEM (SImode, crtl->args.internal_arg_pointer); |
1515 set_mem_alias_set (mem, set); | 1503 set_mem_alias_set (mem, set); |
1516 emit_move_insn (mem, gen_rtx_REG (SImode, 0)); | 1504 emit_move_insn (mem, gen_rtx_REG (SImode, 0)); |
1517 | 1505 |
1518 mem = gen_rtx_MEM (SImode, | 1506 mem = gen_rtx_MEM (SImode, |
1519 plus_constant (crtl->args.internal_arg_pointer, 4)); | 1507 plus_constant (Pmode, |
1508 crtl->args.internal_arg_pointer, 4)); | |
1520 set_mem_alias_set (mem, set); | 1509 set_mem_alias_set (mem, set); |
1521 emit_move_insn (mem, gen_rtx_REG (SImode, 1)); | 1510 emit_move_insn (mem, gen_rtx_REG (SImode, 1)); |
1522 | 1511 |
1523 return copy_to_reg (expand_binop (Pmode, add_optab, | 1512 return copy_to_reg (expand_binop (Pmode, add_optab, |
1524 crtl->args.internal_arg_pointer, | 1513 crtl->args.internal_arg_pointer, |
1533 } | 1522 } |
1534 | 1523 |
1535 /* Return true when a parameter should be passed by reference. */ | 1524 /* Return true when a parameter should be passed by reference. */ |
1536 | 1525 |
1537 static bool | 1526 static bool |
1538 mn10300_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, | 1527 mn10300_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, |
1539 enum machine_mode mode, const_tree type, | 1528 machine_mode mode, const_tree type, |
1540 bool named ATTRIBUTE_UNUSED) | 1529 bool named ATTRIBUTE_UNUSED) |
1541 { | 1530 { |
1542 unsigned HOST_WIDE_INT size; | 1531 unsigned HOST_WIDE_INT size; |
1543 | 1532 |
1544 if (type) | 1533 if (type) |
1551 | 1540 |
1552 /* Return an RTX to represent where a value with mode MODE will be returned | 1541 /* Return an RTX to represent where a value with mode MODE will be returned |
1553 from a function. If the result is NULL_RTX, the argument is pushed. */ | 1542 from a function. If the result is NULL_RTX, the argument is pushed. */ |
1554 | 1543 |
1555 static rtx | 1544 static rtx |
1556 mn10300_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, | 1545 mn10300_function_arg (cumulative_args_t cum_v, machine_mode mode, |
1557 const_tree type, bool named ATTRIBUTE_UNUSED) | 1546 const_tree type, bool named ATTRIBUTE_UNUSED) |
1558 { | 1547 { |
1548 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); | |
1559 rtx result = NULL_RTX; | 1549 rtx result = NULL_RTX; |
1560 int size; | 1550 int size; |
1561 | 1551 |
1562 /* We only support using 2 data registers as argument registers. */ | 1552 /* We only support using 2 data registers as argument registers. */ |
1563 int nregs = 2; | 1553 int nregs = 2; |
1599 /* Update the data in CUM to advance over an argument | 1589 /* Update the data in CUM to advance over an argument |
1600 of mode MODE and data type TYPE. | 1590 of mode MODE and data type TYPE. |
1601 (TYPE is null for libcalls where that information may not be available.) */ | 1591 (TYPE is null for libcalls where that information may not be available.) */ |
1602 | 1592 |
1603 static void | 1593 static void |
1604 mn10300_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, | 1594 mn10300_function_arg_advance (cumulative_args_t cum_v, machine_mode mode, |
1605 const_tree type, bool named ATTRIBUTE_UNUSED) | 1595 const_tree type, bool named ATTRIBUTE_UNUSED) |
1606 { | 1596 { |
1597 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); | |
1598 | |
1607 cum->nbytes += (mode != BLKmode | 1599 cum->nbytes += (mode != BLKmode |
1608 ? (GET_MODE_SIZE (mode) + 3) & ~3 | 1600 ? (GET_MODE_SIZE (mode) + 3) & ~3 |
1609 : (int_size_in_bytes (type) + 3) & ~3); | 1601 : (int_size_in_bytes (type) + 3) & ~3); |
1610 } | 1602 } |
1611 | 1603 |
1612 /* Return the number of bytes of registers to use for an argument passed | 1604 /* Return the number of bytes of registers to use for an argument passed |
1613 partially in registers and partially in memory. */ | 1605 partially in registers and partially in memory. */ |
1614 | 1606 |
1615 static int | 1607 static int |
1616 mn10300_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, | 1608 mn10300_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode, |
1617 tree type, bool named ATTRIBUTE_UNUSED) | 1609 tree type, bool named ATTRIBUTE_UNUSED) |
1618 { | 1610 { |
1611 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); | |
1619 int size; | 1612 int size; |
1620 | 1613 |
1621 /* We only support using 2 data registers as argument registers. */ | 1614 /* We only support using 2 data registers as argument registers. */ |
1622 int nregs = 2; | 1615 int nregs = 2; |
1623 | 1616 |
1656 mn10300_function_value (const_tree valtype, | 1649 mn10300_function_value (const_tree valtype, |
1657 const_tree fn_decl_or_type ATTRIBUTE_UNUSED, | 1650 const_tree fn_decl_or_type ATTRIBUTE_UNUSED, |
1658 bool outgoing) | 1651 bool outgoing) |
1659 { | 1652 { |
1660 rtx rv; | 1653 rtx rv; |
1661 enum machine_mode mode = TYPE_MODE (valtype); | 1654 machine_mode mode = TYPE_MODE (valtype); |
1662 | 1655 |
1663 if (! POINTER_TYPE_P (valtype)) | 1656 if (! POINTER_TYPE_P (valtype)) |
1664 return gen_rtx_REG (mode, FIRST_DATA_REGNUM); | 1657 return gen_rtx_REG (mode, FIRST_DATA_REGNUM); |
1665 else if (! TARGET_PTR_A0D0 || ! outgoing | 1658 else if (! TARGET_PTR_A0D0 || ! outgoing |
1666 || cfun->returns_struct) | 1659 || cfun->returns_struct) |
1680 } | 1673 } |
1681 | 1674 |
1682 /* Implements TARGET_LIBCALL_VALUE. */ | 1675 /* Implements TARGET_LIBCALL_VALUE. */ |
1683 | 1676 |
1684 static rtx | 1677 static rtx |
1685 mn10300_libcall_value (enum machine_mode mode, | 1678 mn10300_libcall_value (machine_mode mode, |
1686 const_rtx fun ATTRIBUTE_UNUSED) | 1679 const_rtx fun ATTRIBUTE_UNUSED) |
1687 { | 1680 { |
1688 return gen_rtx_REG (mode, FIRST_DATA_REGNUM); | 1681 return gen_rtx_REG (mode, FIRST_DATA_REGNUM); |
1689 } | 1682 } |
1690 | 1683 |
1792 expressions will have one of a few well defined forms, so | 1785 expressions will have one of a few well defined forms, so |
1793 we need only check those forms. */ | 1786 we need only check those forms. */ |
1794 | 1787 |
1795 int | 1788 int |
1796 mn10300_symbolic_operand (rtx op, | 1789 mn10300_symbolic_operand (rtx op, |
1797 enum machine_mode mode ATTRIBUTE_UNUSED) | 1790 machine_mode mode ATTRIBUTE_UNUSED) |
1798 { | 1791 { |
1799 switch (GET_CODE (op)) | 1792 switch (GET_CODE (op)) |
1800 { | 1793 { |
1801 case SYMBOL_REF: | 1794 case SYMBOL_REF: |
1802 case LABEL_REF: | 1795 case LABEL_REF: |
1824 But on a few ports with segmented architectures and indexed addressing | 1817 But on a few ports with segmented architectures and indexed addressing |
1825 (mn10300, hppa) it is used to rewrite certain problematical addresses. */ | 1818 (mn10300, hppa) it is used to rewrite certain problematical addresses. */ |
1826 | 1819 |
1827 static rtx | 1820 static rtx |
1828 mn10300_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, | 1821 mn10300_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, |
1829 enum machine_mode mode ATTRIBUTE_UNUSED) | 1822 machine_mode mode ATTRIBUTE_UNUSED) |
1830 { | 1823 { |
1831 if (flag_pic && ! mn10300_legitimate_pic_operand_p (x)) | 1824 if (flag_pic && ! mn10300_legitimate_pic_operand_p (x)) |
1832 x = mn10300_legitimize_pic_address (oldx, NULL_RTX); | 1825 x = mn10300_legitimize_pic_address (oldx, NULL_RTX); |
1833 | 1826 |
1834 /* Uh-oh. We might have an address for x[n-100000]. This needs | 1827 /* Uh-oh. We might have an address for x[n-100000]. This needs |
1867 | 1860 |
1868 rtx | 1861 rtx |
1869 mn10300_legitimize_pic_address (rtx orig, rtx reg) | 1862 mn10300_legitimize_pic_address (rtx orig, rtx reg) |
1870 { | 1863 { |
1871 rtx x; | 1864 rtx x; |
1865 rtx_insn *insn; | |
1872 | 1866 |
1873 if (GET_CODE (orig) == LABEL_REF | 1867 if (GET_CODE (orig) == LABEL_REF |
1874 || (GET_CODE (orig) == SYMBOL_REF | 1868 || (GET_CODE (orig) == SYMBOL_REF |
1875 && (CONSTANT_POOL_ADDRESS_P (orig) | 1869 && (CONSTANT_POOL_ADDRESS_P (orig) |
1876 || ! MN10300_GLOBAL_P (orig)))) | 1870 || ! MN10300_GLOBAL_P (orig)))) |
1880 | 1874 |
1881 x = gen_rtx_UNSPEC (SImode, gen_rtvec (1, orig), UNSPEC_GOTOFF); | 1875 x = gen_rtx_UNSPEC (SImode, gen_rtvec (1, orig), UNSPEC_GOTOFF); |
1882 x = gen_rtx_CONST (SImode, x); | 1876 x = gen_rtx_CONST (SImode, x); |
1883 emit_move_insn (reg, x); | 1877 emit_move_insn (reg, x); |
1884 | 1878 |
1885 x = emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx)); | 1879 insn = emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx)); |
1886 } | 1880 } |
1887 else if (GET_CODE (orig) == SYMBOL_REF) | 1881 else if (GET_CODE (orig) == SYMBOL_REF) |
1888 { | 1882 { |
1889 if (reg == NULL) | 1883 if (reg == NULL) |
1890 reg = gen_reg_rtx (Pmode); | 1884 reg = gen_reg_rtx (Pmode); |
1892 x = gen_rtx_UNSPEC (SImode, gen_rtvec (1, orig), UNSPEC_GOT); | 1886 x = gen_rtx_UNSPEC (SImode, gen_rtvec (1, orig), UNSPEC_GOT); |
1893 x = gen_rtx_CONST (SImode, x); | 1887 x = gen_rtx_CONST (SImode, x); |
1894 x = gen_rtx_PLUS (SImode, pic_offset_table_rtx, x); | 1888 x = gen_rtx_PLUS (SImode, pic_offset_table_rtx, x); |
1895 x = gen_const_mem (SImode, x); | 1889 x = gen_const_mem (SImode, x); |
1896 | 1890 |
1897 x = emit_move_insn (reg, x); | 1891 insn = emit_move_insn (reg, x); |
1898 } | 1892 } |
1899 else | 1893 else |
1900 return orig; | 1894 return orig; |
1901 | 1895 |
1902 set_unique_reg_note (x, REG_EQUAL, orig); | 1896 set_unique_reg_note (insn, REG_EQUAL, orig); |
1903 return reg; | 1897 return reg; |
1904 } | 1898 } |
1905 | 1899 |
1906 /* Return zero if X references a SYMBOL_REF or LABEL_REF whose symbol | 1900 /* Return zero if X references a SYMBOL_REF or LABEL_REF whose symbol |
1907 isn't protected by a PIC unspec; nonzero otherwise. */ | 1901 isn't protected by a PIC unspec; nonzero otherwise. */ |
1955 it's just much more difficult. For a discussion of a possible | 1949 it's just much more difficult. For a discussion of a possible |
1956 workaround and solution, see the comments in pa.c before the | 1950 workaround and solution, see the comments in pa.c before the |
1957 function record_unscaled_index_insn_codes. */ | 1951 function record_unscaled_index_insn_codes. */ |
1958 | 1952 |
1959 static bool | 1953 static bool |
1960 mn10300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) | 1954 mn10300_legitimate_address_p (machine_mode mode, rtx x, bool strict) |
1961 { | 1955 { |
1962 rtx base, index; | 1956 rtx base, index; |
1963 | 1957 |
1964 if (CONSTANT_ADDRESS_P (x)) | 1958 if (CONSTANT_ADDRESS_P (x)) |
1965 return !flag_pic || mn10300_legitimate_pic_operand_p (x); | 1959 return !flag_pic || mn10300_legitimate_pic_operand_p (x); |
2023 return TEST_HARD_REG_BIT (reg_class_contents[rclass], regno); | 2017 return TEST_HARD_REG_BIT (reg_class_contents[rclass], regno); |
2024 } | 2018 } |
2025 | 2019 |
2026 rtx | 2020 rtx |
2027 mn10300_legitimize_reload_address (rtx x, | 2021 mn10300_legitimize_reload_address (rtx x, |
2028 enum machine_mode mode ATTRIBUTE_UNUSED, | 2022 machine_mode mode ATTRIBUTE_UNUSED, |
2029 int opnum, int type, | 2023 int opnum, int type, |
2030 int ind_levels ATTRIBUTE_UNUSED) | 2024 int ind_levels ATTRIBUTE_UNUSED) |
2031 { | 2025 { |
2032 bool any_change = false; | 2026 bool any_change = false; |
2033 | 2027 |
2054 } | 2048 } |
2055 | 2049 |
2056 return any_change ? x : NULL_RTX; | 2050 return any_change ? x : NULL_RTX; |
2057 } | 2051 } |
2058 | 2052 |
2059 /* Used by LEGITIMATE_CONSTANT_P(). Returns TRUE if X is a valid | 2053 /* Implement TARGET_LEGITIMATE_CONSTANT_P. Returns TRUE if X is a valid |
2060 constant. Note that some "constants" aren't valid, such as TLS | 2054 constant. Note that some "constants" aren't valid, such as TLS |
2061 symbols and unconverted GOT-based references, so we eliminate | 2055 symbols and unconverted GOT-based references, so we eliminate |
2062 those here. */ | 2056 those here. */ |
2063 | 2057 |
2064 bool | 2058 static bool |
2065 mn10300_legitimate_constant_p (rtx x) | 2059 mn10300_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x) |
2066 { | 2060 { |
2067 switch (GET_CODE (x)) | 2061 switch (GET_CODE (x)) |
2068 { | 2062 { |
2069 case CONST: | 2063 case CONST: |
2070 x = XEXP (x, 0); | 2064 x = XEXP (x, 0); |
2166 /* For addresses, costs are relative to "MOV (Rm),Rn". For AM33 this is | 2160 /* For addresses, costs are relative to "MOV (Rm),Rn". For AM33 this is |
2167 the 3-byte fully general instruction; for MN103 this is the 2-byte form | 2161 the 3-byte fully general instruction; for MN103 this is the 2-byte form |
2168 with an address register. */ | 2162 with an address register. */ |
2169 | 2163 |
2170 static int | 2164 static int |
2171 mn10300_address_cost (rtx x, bool speed) | 2165 mn10300_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED, |
2166 addr_space_t as ATTRIBUTE_UNUSED, bool speed) | |
2172 { | 2167 { |
2173 HOST_WIDE_INT i; | 2168 HOST_WIDE_INT i; |
2174 rtx base, index; | 2169 rtx base, index; |
2175 | 2170 |
2176 switch (GET_CODE (x)) | 2171 switch (GET_CODE (x)) |
2219 if (IN_RANGE (i, -32768, 32767)) | 2214 if (IN_RANGE (i, -32768, 32767)) |
2220 return speed ? 0 : 2; | 2215 return speed ? 0 : 2; |
2221 return speed ? 2 : 6; | 2216 return speed ? 2 : 6; |
2222 | 2217 |
2223 default: | 2218 default: |
2224 return rtx_cost (x, MEM, speed); | 2219 return rtx_cost (x, Pmode, MEM, 0, speed); |
2225 } | 2220 } |
2226 } | 2221 } |
2227 | 2222 |
2228 /* Implement the TARGET_REGISTER_MOVE_COST hook. | 2223 /* Implement the TARGET_REGISTER_MOVE_COST hook. |
2229 | 2224 |
2230 Recall that the base value of 2 is required by assumptions elsewhere | 2225 Recall that the base value of 2 is required by assumptions elsewhere |
2231 in the body of the compiler, and that cost 2 is special-cased as an | 2226 in the body of the compiler, and that cost 2 is special-cased as an |
2232 early exit from reload meaning no work is required. */ | 2227 early exit from reload meaning no work is required. */ |
2233 | 2228 |
2234 static int | 2229 static int |
2235 mn10300_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, | 2230 mn10300_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED, |
2236 reg_class_t ifrom, reg_class_t ito) | 2231 reg_class_t ifrom, reg_class_t ito) |
2237 { | 2232 { |
2238 enum reg_class from = (enum reg_class) ifrom; | 2233 enum reg_class from = (enum reg_class) ifrom; |
2239 enum reg_class to = (enum reg_class) ito; | 2234 enum reg_class to = (enum reg_class) ito; |
2240 enum reg_class scratch, test; | 2235 enum reg_class scratch, test; |
2317 Given lack of the form of the address, this must be speed-relative, | 2312 Given lack of the form of the address, this must be speed-relative, |
2318 though we should never be less expensive than a size-relative register | 2313 though we should never be less expensive than a size-relative register |
2319 move cost above. This is not a problem. */ | 2314 move cost above. This is not a problem. */ |
2320 | 2315 |
2321 static int | 2316 static int |
2322 mn10300_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, | 2317 mn10300_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED, |
2323 reg_class_t iclass, bool in ATTRIBUTE_UNUSED) | 2318 reg_class_t iclass, bool in ATTRIBUTE_UNUSED) |
2324 { | 2319 { |
2325 enum reg_class rclass = (enum reg_class) iclass; | 2320 enum reg_class rclass = (enum reg_class) iclass; |
2326 | 2321 |
2327 if (rclass == FP_REGS) | 2322 if (rclass == FP_REGS) |
2333 | 2328 |
2334 Speed-relative costs are relative to COSTS_N_INSNS, which is intended | 2329 Speed-relative costs are relative to COSTS_N_INSNS, which is intended |
2335 to represent cycles. Size-relative costs are in bytes. */ | 2330 to represent cycles. Size-relative costs are in bytes. */ |
2336 | 2331 |
2337 static bool | 2332 static bool |
2338 mn10300_rtx_costs (rtx x, int code, int outer_code, int *ptotal, bool speed) | 2333 mn10300_rtx_costs (rtx x, machine_mode mode, int outer_code, |
2334 int opno ATTRIBUTE_UNUSED, int *ptotal, bool speed) | |
2339 { | 2335 { |
2340 /* This value is used for SYMBOL_REF etc where we want to pretend | 2336 /* This value is used for SYMBOL_REF etc where we want to pretend |
2341 we have a full 32-bit constant. */ | 2337 we have a full 32-bit constant. */ |
2342 HOST_WIDE_INT i = 0x12345678; | 2338 HOST_WIDE_INT i = 0x12345678; |
2343 int total; | 2339 int total; |
2340 int code = GET_CODE (x); | |
2344 | 2341 |
2345 switch (code) | 2342 switch (code) |
2346 { | 2343 { |
2347 case CONST_INT: | 2344 case CONST_INT: |
2348 i = INTVAL (x); | 2345 i = INTVAL (x); |
2424 if (!speed && outer_code == SET && CONST_INT_P (XEXP (x, 1))) | 2421 if (!speed && outer_code == SET && CONST_INT_P (XEXP (x, 1))) |
2425 { | 2422 { |
2426 i = INTVAL (XEXP (x, 1)); | 2423 i = INTVAL (XEXP (x, 1)); |
2427 if (i == 1 || i == 4) | 2424 if (i == 1 || i == 4) |
2428 { | 2425 { |
2429 total = 1 + rtx_cost (XEXP (x, 0), PLUS, speed); | 2426 total = 1 + rtx_cost (XEXP (x, 0), mode, PLUS, 0, speed); |
2430 goto alldone; | 2427 goto alldone; |
2431 } | 2428 } |
2432 } | 2429 } |
2433 goto do_arith_costs; | 2430 goto do_arith_costs; |
2434 | 2431 |
2480 /* Include space to load+retrieve MDR. */ | 2477 /* Include space to load+retrieve MDR. */ |
2481 : code == MOD || code == UMOD ? 6 : 4); | 2478 : code == MOD || code == UMOD ? 6 : 4); |
2482 break; | 2479 break; |
2483 | 2480 |
2484 case MEM: | 2481 case MEM: |
2485 total = mn10300_address_cost (XEXP (x, 0), speed); | 2482 total = mn10300_address_cost (XEXP (x, 0), mode, |
2483 MEM_ADDR_SPACE (x), speed); | |
2486 if (speed) | 2484 if (speed) |
2487 total = COSTS_N_INSNS (2 + total); | 2485 total = COSTS_N_INSNS (2 + total); |
2488 goto alldone; | 2486 goto alldone; |
2489 | 2487 |
2490 default: | 2488 default: |
2503 | 2501 |
2504 /* If using PIC, mark a SYMBOL_REF for a non-global symbol so that we | 2502 /* If using PIC, mark a SYMBOL_REF for a non-global symbol so that we |
2505 may access it using GOTOFF instead of GOT. */ | 2503 may access it using GOTOFF instead of GOT. */ |
2506 | 2504 |
2507 static void | 2505 static void |
2508 mn10300_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED) | 2506 mn10300_encode_section_info (tree decl, rtx rtl, int first) |
2509 { | 2507 { |
2510 rtx symbol; | 2508 rtx symbol; |
2509 | |
2510 default_encode_section_info (decl, rtl, first); | |
2511 | 2511 |
2512 if (! MEM_P (rtl)) | 2512 if (! MEM_P (rtl)) |
2513 return; | 2513 return; |
2514 | |
2514 symbol = XEXP (rtl, 0); | 2515 symbol = XEXP (rtl, 0); |
2515 if (GET_CODE (symbol) != SYMBOL_REF) | 2516 if (GET_CODE (symbol) != SYMBOL_REF) |
2516 return; | 2517 return; |
2517 | 2518 |
2518 if (flag_pic) | 2519 if (flag_pic) |
2552 | 2553 |
2553 Note that the two extra insns are effectively nops; they | 2554 Note that the two extra insns are effectively nops; they |
2554 clobber the flags but do not affect the contents of D0 or D1. */ | 2555 clobber the flags but do not affect the contents of D0 or D1. */ |
2555 | 2556 |
2556 disp = expand_binop (SImode, sub_optab, fnaddr, | 2557 disp = expand_binop (SImode, sub_optab, fnaddr, |
2557 plus_constant (XEXP (m_tramp, 0), 11), | 2558 plus_constant (Pmode, XEXP (m_tramp, 0), 11), |
2558 NULL_RTX, 1, OPTAB_DIRECT); | 2559 NULL_RTX, 1, OPTAB_DIRECT); |
2559 | 2560 |
2560 mem = adjust_address (m_tramp, SImode, 0); | 2561 mem = adjust_address (m_tramp, SImode, 0); |
2561 emit_move_insn (mem, gen_int_mode (0xddfc0028, SImode)); | 2562 emit_move_insn (mem, gen_int_mode (0xddfc0028, SImode)); |
2562 mem = adjust_address (m_tramp, SImode, 4); | 2563 mem = adjust_address (m_tramp, SImode, 4); |
2623 const_tree function ATTRIBUTE_UNUSED) | 2624 const_tree function ATTRIBUTE_UNUSED) |
2624 { | 2625 { |
2625 return true; | 2626 return true; |
2626 } | 2627 } |
2627 | 2628 |
2628 bool | 2629 /* Implement TARGET_HARD_REGNO_MODE_OK. */ |
2629 mn10300_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode) | 2630 |
2631 static bool | |
2632 mn10300_hard_regno_mode_ok (unsigned int regno, machine_mode mode) | |
2630 { | 2633 { |
2631 if (REGNO_REG_CLASS (regno) == FP_REGS | 2634 if (REGNO_REG_CLASS (regno) == FP_REGS |
2632 || REGNO_REG_CLASS (regno) == FP_ACC_REGS) | 2635 || REGNO_REG_CLASS (regno) == FP_ACC_REGS) |
2633 /* Do not store integer values in FP registers. */ | 2636 /* Do not store integer values in FP registers. */ |
2634 return GET_MODE_CLASS (mode) == MODE_FLOAT && ((regno & 1) == 0); | 2637 return GET_MODE_CLASS (mode) == MODE_FLOAT && ((regno & 1) == 0); |
2635 | 2638 |
2639 if (! TARGET_AM33 && REGNO_REG_CLASS (regno) == EXTENDED_REGS) | |
2640 return false; | |
2641 | |
2636 if (((regno) & 1) == 0 || GET_MODE_SIZE (mode) == 4) | 2642 if (((regno) & 1) == 0 || GET_MODE_SIZE (mode) == 4) |
2637 return true; | 2643 return true; |
2638 | 2644 |
2639 if (REGNO_REG_CLASS (regno) == DATA_REGS | 2645 if (REGNO_REG_CLASS (regno) == DATA_REGS |
2640 || (TARGET_AM33 && REGNO_REG_CLASS (regno) == ADDRESS_REGS) | 2646 || (TARGET_AM33 && REGNO_REG_CLASS (regno) == ADDRESS_REGS) |
2642 return GET_MODE_SIZE (mode) <= 4; | 2648 return GET_MODE_SIZE (mode) <= 4; |
2643 | 2649 |
2644 return false; | 2650 return false; |
2645 } | 2651 } |
2646 | 2652 |
2647 bool | 2653 /* Implement TARGET_MODES_TIEABLE_P. */ |
2648 mn10300_modes_tieable (enum machine_mode mode1, enum machine_mode mode2) | 2654 |
2655 static bool | |
2656 mn10300_modes_tieable_p (machine_mode mode1, machine_mode mode2) | |
2649 { | 2657 { |
2650 if (GET_MODE_CLASS (mode1) == MODE_FLOAT | 2658 if (GET_MODE_CLASS (mode1) == MODE_FLOAT |
2651 && GET_MODE_CLASS (mode2) != MODE_FLOAT) | 2659 && GET_MODE_CLASS (mode2) != MODE_FLOAT) |
2652 return false; | 2660 return false; |
2653 | 2661 |
2662 | 2670 |
2663 return false; | 2671 return false; |
2664 } | 2672 } |
2665 | 2673 |
2666 static int | 2674 static int |
2667 cc_flags_for_mode (enum machine_mode mode) | 2675 cc_flags_for_mode (machine_mode mode) |
2668 { | 2676 { |
2669 switch (mode) | 2677 switch (mode) |
2670 { | 2678 { |
2671 case CCmode: | 2679 case E_CCmode: |
2672 return CC_FLAG_Z | CC_FLAG_N | CC_FLAG_C | CC_FLAG_V; | 2680 return CC_FLAG_Z | CC_FLAG_N | CC_FLAG_C | CC_FLAG_V; |
2673 case CCZNCmode: | 2681 case E_CCZNCmode: |
2674 return CC_FLAG_Z | CC_FLAG_N | CC_FLAG_C; | 2682 return CC_FLAG_Z | CC_FLAG_N | CC_FLAG_C; |
2675 case CCZNmode: | 2683 case E_CCZNmode: |
2676 return CC_FLAG_Z | CC_FLAG_N; | 2684 return CC_FLAG_Z | CC_FLAG_N; |
2677 case CC_FLOATmode: | 2685 case E_CC_FLOATmode: |
2678 return -1; | 2686 return -1; |
2679 default: | 2687 default: |
2680 gcc_unreachable (); | 2688 gcc_unreachable (); |
2681 } | 2689 } |
2682 } | 2690 } |
2691 return CC_FLAG_Z; | 2699 return CC_FLAG_Z; |
2692 | 2700 |
2693 case LT: /* N */ | 2701 case LT: /* N */ |
2694 case GE: /* ~N */ | 2702 case GE: /* ~N */ |
2695 return CC_FLAG_N; | 2703 return CC_FLAG_N; |
2696 break; | |
2697 | 2704 |
2698 case GT: /* ~(Z|(N^V)) */ | 2705 case GT: /* ~(Z|(N^V)) */ |
2699 case LE: /* Z|(N^V) */ | 2706 case LE: /* Z|(N^V) */ |
2700 return CC_FLAG_Z | CC_FLAG_N | CC_FLAG_V; | 2707 return CC_FLAG_Z | CC_FLAG_N | CC_FLAG_V; |
2701 | 2708 |
2720 default: | 2727 default: |
2721 gcc_unreachable (); | 2728 gcc_unreachable (); |
2722 } | 2729 } |
2723 } | 2730 } |
2724 | 2731 |
2725 enum machine_mode | 2732 machine_mode |
2726 mn10300_select_cc_mode (enum rtx_code code, rtx x, rtx y ATTRIBUTE_UNUSED) | 2733 mn10300_select_cc_mode (enum rtx_code code, rtx x, rtx y ATTRIBUTE_UNUSED) |
2727 { | 2734 { |
2728 int req; | 2735 int req; |
2729 | 2736 |
2730 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) | 2737 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) |
2738 return CCZNCmode; | 2745 return CCZNCmode; |
2739 return CCZNmode; | 2746 return CCZNmode; |
2740 } | 2747 } |
2741 | 2748 |
2742 static inline bool | 2749 static inline bool |
2743 is_load_insn (rtx insn) | 2750 set_is_load_p (rtx set) |
2744 { | 2751 { |
2745 if (GET_CODE (PATTERN (insn)) != SET) | 2752 return MEM_P (SET_SRC (set)); |
2746 return false; | |
2747 | |
2748 return MEM_P (SET_SRC (PATTERN (insn))); | |
2749 } | 2753 } |
2750 | 2754 |
2751 static inline bool | 2755 static inline bool |
2752 is_store_insn (rtx insn) | 2756 set_is_store_p (rtx set) |
2753 { | 2757 { |
2754 if (GET_CODE (PATTERN (insn)) != SET) | 2758 return MEM_P (SET_DEST (set)); |
2755 return false; | |
2756 | |
2757 return MEM_P (SET_DEST (PATTERN (insn))); | |
2758 } | 2759 } |
2759 | 2760 |
2760 /* Update scheduling costs for situations that cannot be | 2761 /* Update scheduling costs for situations that cannot be |
2761 described using the attributes and DFA machinery. | 2762 described using the attributes and DFA machinery. |
2762 DEP is the insn being scheduled. | 2763 DEP is the insn being scheduled. |
2763 INSN is the previous insn. | 2764 INSN is the previous insn. |
2764 COST is the current cycle cost for DEP. */ | 2765 COST is the current cycle cost for DEP. */ |
2765 | 2766 |
2766 static int | 2767 static int |
2767 mn10300_adjust_sched_cost (rtx insn, rtx link, rtx dep, int cost) | 2768 mn10300_adjust_sched_cost (rtx_insn *insn, int dep_type, rtx_insn *dep, |
2768 { | 2769 int cost, unsigned int) |
2769 int timings = get_attr_timings (insn); | 2770 { |
2771 rtx insn_set; | |
2772 rtx dep_set; | |
2773 int timings; | |
2770 | 2774 |
2771 if (!TARGET_AM33) | 2775 if (!TARGET_AM33) |
2772 return 1; | 2776 return 1; |
2773 | 2777 |
2774 if (GET_CODE (insn) == PARALLEL) | 2778 /* We are only interested in pairs of SET. */ |
2775 insn = XVECEXP (insn, 0, 0); | 2779 insn_set = single_set (insn); |
2776 | 2780 if (!insn_set) |
2777 if (GET_CODE (dep) == PARALLEL) | 2781 return cost; |
2778 dep = XVECEXP (dep, 0, 0); | 2782 |
2783 dep_set = single_set (dep); | |
2784 if (!dep_set) | |
2785 return cost; | |
2779 | 2786 |
2780 /* For the AM34 a load instruction that follows a | 2787 /* For the AM34 a load instruction that follows a |
2781 store instruction incurs an extra cycle of delay. */ | 2788 store instruction incurs an extra cycle of delay. */ |
2782 if (mn10300_tune_cpu == PROCESSOR_AM34 | 2789 if (mn10300_tune_cpu == PROCESSOR_AM34 |
2783 && is_load_insn (dep) | 2790 && set_is_load_p (dep_set) |
2784 && is_store_insn (insn)) | 2791 && set_is_store_p (insn_set)) |
2785 cost += 1; | 2792 cost += 1; |
2786 | 2793 |
2787 /* For the AM34 a non-store, non-branch FPU insn that follows | 2794 /* For the AM34 a non-store, non-branch FPU insn that follows |
2788 another FPU insn incurs a one cycle throughput increase. */ | 2795 another FPU insn incurs a one cycle throughput increase. */ |
2789 else if (mn10300_tune_cpu == PROCESSOR_AM34 | 2796 else if (mn10300_tune_cpu == PROCESSOR_AM34 |
2790 && ! is_store_insn (insn) | 2797 && ! set_is_store_p (insn_set) |
2791 && ! JUMP_P (insn) | 2798 && ! JUMP_P (insn) |
2792 && GET_CODE (PATTERN (dep)) == SET | 2799 && GET_MODE_CLASS (GET_MODE (SET_SRC (dep_set))) == MODE_FLOAT |
2793 && GET_CODE (PATTERN (insn)) == SET | 2800 && GET_MODE_CLASS (GET_MODE (SET_SRC (insn_set))) == MODE_FLOAT) |
2794 && GET_MODE_CLASS (GET_MODE (SET_SRC (PATTERN (dep)))) == MODE_FLOAT | |
2795 && GET_MODE_CLASS (GET_MODE (SET_SRC (PATTERN (insn)))) == MODE_FLOAT) | |
2796 cost += 1; | 2801 cost += 1; |
2797 | 2802 |
2798 /* Resolve the conflict described in section 1-7-4 of | 2803 /* Resolve the conflict described in section 1-7-4 of |
2799 Chapter 3 of the MN103E Series Instruction Manual | 2804 Chapter 3 of the MN103E Series Instruction Manual |
2800 where it says: | 2805 where it says: |
2801 | 2806 |
2802 "When the preceeding instruction is a CPU load or | 2807 "When the preceding instruction is a CPU load or |
2803 store instruction, a following FPU instruction | 2808 store instruction, a following FPU instruction |
2804 cannot be executed until the CPU completes the | 2809 cannot be executed until the CPU completes the |
2805 latency period even though there are no register | 2810 latency period even though there are no register |
2806 or flag dependencies between them." */ | 2811 or flag dependencies between them." */ |
2807 | 2812 |
2808 /* Only the AM33-2 (and later) CPUs have FPU instructions. */ | 2813 /* Only the AM33-2 (and later) CPUs have FPU instructions. */ |
2809 if (! TARGET_AM33_2) | 2814 if (! TARGET_AM33_2) |
2810 return cost; | 2815 return cost; |
2811 | 2816 |
2812 /* If a data dependence already exists then the cost is correct. */ | 2817 /* If a data dependence already exists then the cost is correct. */ |
2813 if (REG_NOTE_KIND (link) == 0) | 2818 if (dep_type == 0) |
2814 return cost; | 2819 return cost; |
2815 | 2820 |
2816 /* Check that the instruction about to scheduled is an FPU instruction. */ | 2821 /* Check that the instruction about to scheduled is an FPU instruction. */ |
2817 if (GET_CODE (PATTERN (dep)) != SET) | 2822 if (GET_MODE_CLASS (GET_MODE (SET_SRC (dep_set))) != MODE_FLOAT) |
2818 return cost; | 2823 return cost; |
2819 | 2824 |
2820 if (GET_MODE_CLASS (GET_MODE (SET_SRC (PATTERN (dep)))) != MODE_FLOAT) | 2825 /* Now check to see if the previous instruction is a load or store. */ |
2826 if (! set_is_load_p (insn_set) && ! set_is_store_p (insn_set)) | |
2821 return cost; | 2827 return cost; |
2822 | 2828 |
2823 /* Now check to see if the previous instruction is a load or store. */ | 2829 /* XXX: Verify: The text of 1-7-4 implies that the restriction |
2824 if (! is_load_insn (insn) && ! is_store_insn (insn)) | 2830 only applies when an INTEGER load/store precedes an FPU |
2831 instruction, but is this true ? For now we assume that it is. */ | |
2832 if (GET_MODE_CLASS (GET_MODE (SET_SRC (insn_set))) != MODE_INT) | |
2825 return cost; | 2833 return cost; |
2826 | 2834 |
2827 /* XXX: Verify: The text of 1-7-4 implies that the restriction | |
2828 only applies when an INTEGER load/store preceeds an FPU | |
2829 instruction, but is this true ? For now we assume that it is. */ | |
2830 if (GET_MODE_CLASS (GET_MODE (SET_SRC (PATTERN (insn)))) != MODE_INT) | |
2831 return cost; | |
2832 | |
2833 /* Extract the latency value from the timings attribute. */ | 2835 /* Extract the latency value from the timings attribute. */ |
2836 timings = get_attr_timings (insn); | |
2834 return timings < 100 ? (timings % 10) : (timings % 100); | 2837 return timings < 100 ? (timings % 10) : (timings % 100); |
2835 } | 2838 } |
2836 | 2839 |
2837 static void | 2840 static void |
2838 mn10300_conditional_register_usage (void) | 2841 mn10300_conditional_register_usage (void) |
2854 if (flag_pic) | 2857 if (flag_pic) |
2855 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = | 2858 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = |
2856 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; | 2859 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; |
2857 } | 2860 } |
2858 | 2861 |
2859 /* Worker function for TARGET_MD_ASM_CLOBBERS. | 2862 /* Worker function for TARGET_MD_ASM_ADJUST. |
2860 We do this in the mn10300 backend to maintain source compatibility | 2863 We do this in the mn10300 backend to maintain source compatibility |
2861 with the old cc0-based compiler. */ | 2864 with the old cc0-based compiler. */ |
2862 | 2865 |
2863 static tree | 2866 static rtx_insn * |
2864 mn10300_md_asm_clobbers (tree outputs ATTRIBUTE_UNUSED, | 2867 mn10300_md_asm_adjust (vec<rtx> &/*outputs*/, vec<rtx> &/*inputs*/, |
2865 tree inputs ATTRIBUTE_UNUSED, | 2868 vec<const char *> &/*constraints*/, |
2866 tree clobbers) | 2869 vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs) |
2867 { | 2870 { |
2868 clobbers = tree_cons (NULL_TREE, build_string (5, "EPSW"), | 2871 clobbers.safe_push (gen_rtx_REG (CCmode, CC_REG)); |
2869 clobbers); | 2872 SET_HARD_REG_BIT (clobbered_regs, CC_REG); |
2870 return clobbers; | 2873 return NULL; |
2871 } | 2874 } |
2872 | 2875 |
2873 /* A helper function for splitting cbranch patterns after reload. */ | 2876 /* A helper function for splitting cbranch patterns after reload. */ |
2874 | 2877 |
2875 void | 2878 void |
2876 mn10300_split_cbranch (enum machine_mode cmp_mode, rtx cmp_op, rtx label_ref) | 2879 mn10300_split_cbranch (machine_mode cmp_mode, rtx cmp_op, rtx label_ref) |
2877 { | 2880 { |
2878 rtx flags, x; | 2881 rtx flags, x; |
2879 | 2882 |
2880 flags = gen_rtx_REG (cmp_mode, CC_REG); | 2883 flags = gen_rtx_REG (cmp_mode, CC_REG); |
2881 x = gen_rtx_COMPARE (cmp_mode, XEXP (cmp_op, 0), XEXP (cmp_op, 1)); | 2884 x = gen_rtx_COMPARE (cmp_mode, XEXP (cmp_op, 0), XEXP (cmp_op, 1)); |
2882 x = gen_rtx_SET (VOIDmode, flags, x); | 2885 x = gen_rtx_SET (flags, x); |
2883 emit_insn (x); | 2886 emit_insn (x); |
2884 | 2887 |
2885 x = gen_rtx_fmt_ee (GET_CODE (cmp_op), VOIDmode, flags, const0_rtx); | 2888 x = gen_rtx_fmt_ee (GET_CODE (cmp_op), VOIDmode, flags, const0_rtx); |
2886 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, label_ref, pc_rtx); | 2889 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, label_ref, pc_rtx); |
2887 x = gen_rtx_SET (VOIDmode, pc_rtx, x); | 2890 x = gen_rtx_SET (pc_rtx, x); |
2888 emit_jump_insn (x); | 2891 emit_jump_insn (x); |
2889 } | 2892 } |
2890 | 2893 |
2891 /* A helper function for matching parallels that set the flags. */ | 2894 /* A helper function for matching parallels that set the flags. */ |
2892 | 2895 |
2893 bool | 2896 bool |
2894 mn10300_match_ccmode (rtx insn, enum machine_mode cc_mode) | 2897 mn10300_match_ccmode (rtx insn, machine_mode cc_mode) |
2895 { | 2898 { |
2896 rtx op1, flags; | 2899 rtx op1, flags; |
2897 enum machine_mode flags_mode; | 2900 machine_mode flags_mode; |
2898 | 2901 |
2899 gcc_checking_assert (XVECLEN (PATTERN (insn), 0) == 2); | 2902 gcc_checking_assert (XVECLEN (PATTERN (insn), 0) == 2); |
2900 | 2903 |
2901 op1 = XVECEXP (PATTERN (insn), 0, 1); | 2904 op1 = XVECEXP (PATTERN (insn), 0, 0); |
2902 gcc_checking_assert (GET_CODE (SET_SRC (op1)) == COMPARE); | 2905 gcc_checking_assert (GET_CODE (SET_SRC (op1)) == COMPARE); |
2903 | 2906 |
2904 flags = SET_DEST (op1); | 2907 flags = SET_DEST (op1); |
2905 flags_mode = GET_MODE (flags); | 2908 flags_mode = GET_MODE (flags); |
2906 | 2909 |
2913 if (cc_flags_for_mode (flags_mode) & ~cc_flags_for_mode (cc_mode)) | 2916 if (cc_flags_for_mode (flags_mode) & ~cc_flags_for_mode (cc_mode)) |
2914 return false; | 2917 return false; |
2915 | 2918 |
2916 return true; | 2919 return true; |
2917 } | 2920 } |
2921 | |
2922 /* This function is used to help split: | |
2923 | |
2924 (set (reg) (and (reg) (int))) | |
2925 | |
2926 into: | |
2927 | |
2928 (set (reg) (shift (reg) (int)) | |
2929 (set (reg) (shift (reg) (int)) | |
2930 | |
2931 where the shitfs will be shorter than the "and" insn. | |
2932 | |
2933 It returns the number of bits that should be shifted. A positive | |
2934 values means that the low bits are to be cleared (and hence the | |
2935 shifts should be right followed by left) whereas a negative value | |
2936 means that the high bits are to be cleared (left followed by right). | |
2937 Zero is returned when it would not be economical to split the AND. */ | |
2918 | 2938 |
2919 int | 2939 int |
2920 mn10300_split_and_operand_count (rtx op) | 2940 mn10300_split_and_operand_count (rtx op) |
2921 { | 2941 { |
2922 HOST_WIDE_INT val = INTVAL (op); | 2942 HOST_WIDE_INT val = INTVAL (op); |
2930 return 0; | 2950 return 0; |
2931 /* This is only size win if we can use the asl2 insn. Otherwise we | 2951 /* This is only size win if we can use the asl2 insn. Otherwise we |
2932 would be replacing 1 6-byte insn with 2 3-byte insns. */ | 2952 would be replacing 1 6-byte insn with 2 3-byte insns. */ |
2933 if (count > (optimize_insn_for_speed_p () ? 2 : 4)) | 2953 if (count > (optimize_insn_for_speed_p () ? 2 : 4)) |
2934 return 0; | 2954 return 0; |
2935 return -count; | 2955 return count; |
2936 } | 2956 } |
2937 else | 2957 else |
2938 { | 2958 { |
2939 /* High bit is clear, look for bits set at the bottom. */ | 2959 /* High bit is clear, look for bits set at the bottom. */ |
2940 count = exact_log2 (val + 1); | 2960 count = exact_log2 (val + 1); |
2958 extract the operands and LIW attributes from the insn and use them to fill | 2978 extract the operands and LIW attributes from the insn and use them to fill |
2959 in the liw_data structure. Return true upon success or false if the insn | 2979 in the liw_data structure. Return true upon success or false if the insn |
2960 cannot be bundled. */ | 2980 cannot be bundled. */ |
2961 | 2981 |
2962 static bool | 2982 static bool |
2963 extract_bundle (rtx insn, struct liw_data * pdata) | 2983 extract_bundle (rtx_insn *insn, struct liw_data * pdata) |
2964 { | 2984 { |
2965 bool allow_consts = true; | 2985 bool allow_consts = true; |
2966 rtx p,s; | 2986 rtx p; |
2967 | 2987 |
2968 gcc_assert (pdata != NULL); | 2988 gcc_assert (pdata != NULL); |
2969 | 2989 |
2970 if (insn == NULL_RTX) | 2990 if (insn == NULL) |
2971 return false; | 2991 return false; |
2972 /* Make sure that we are dealing with a simple SET insn. */ | 2992 /* Make sure that we are dealing with a simple SET insn. */ |
2973 p = single_set (insn); | 2993 p = single_set (insn); |
2974 if (p == NULL_RTX) | 2994 if (p == NULL_RTX) |
2975 return false; | 2995 return false; |
2978 pdata->slot = get_attr_liw (insn); | 2998 pdata->slot = get_attr_liw (insn); |
2979 if (pdata->slot == LIW_BOTH) | 2999 if (pdata->slot == LIW_BOTH) |
2980 return false; | 3000 return false; |
2981 | 3001 |
2982 pdata->op = get_attr_liw_op (insn); | 3002 pdata->op = get_attr_liw_op (insn); |
2983 | |
2984 s = SET_SRC (p); | |
2985 | 3003 |
2986 switch (pdata->op) | 3004 switch (pdata->op) |
2987 { | 3005 { |
2988 case LIW_OP_MOV: | 3006 case LIW_OP_MOV: |
2989 pdata->dest = SET_DEST (p); | 3007 pdata->dest = SET_DEST (p); |
3086 /* Combine pairs of insns into LIW bundles. */ | 3104 /* Combine pairs of insns into LIW bundles. */ |
3087 | 3105 |
3088 static void | 3106 static void |
3089 mn10300_bundle_liw (void) | 3107 mn10300_bundle_liw (void) |
3090 { | 3108 { |
3091 rtx r; | 3109 rtx_insn *r; |
3092 | 3110 |
3093 for (r = get_insns (); r != NULL_RTX; r = next_nonnote_nondebug_insn (r)) | 3111 for (r = get_insns (); r != NULL; r = next_nonnote_nondebug_insn (r)) |
3094 { | 3112 { |
3095 rtx insn1, insn2; | 3113 rtx_insn *insn1, *insn2; |
3096 struct liw_data liw1, liw2; | 3114 struct liw_data liw1, liw2; |
3097 | 3115 |
3098 insn1 = r; | 3116 insn1 = r; |
3099 if (! extract_bundle (insn1, & liw1)) | 3117 if (! extract_bundle (insn1, & liw1)) |
3100 continue; | 3118 continue; |
3116 liw2 = temp; | 3134 liw2 = temp; |
3117 } | 3135 } |
3118 | 3136 |
3119 delete_insn (insn2); | 3137 delete_insn (insn2); |
3120 | 3138 |
3139 rtx insn2_pat; | |
3121 if (liw1.op == LIW_OP_CMP) | 3140 if (liw1.op == LIW_OP_CMP) |
3122 insn2 = gen_cmp_liw (liw2.dest, liw2.src, liw1.dest, liw1.src, | 3141 insn2_pat = gen_cmp_liw (liw2.dest, liw2.src, liw1.dest, liw1.src, |
3123 GEN_INT (liw2.op)); | 3142 GEN_INT (liw2.op)); |
3124 else if (liw2.op == LIW_OP_CMP) | 3143 else if (liw2.op == LIW_OP_CMP) |
3125 insn2 = gen_liw_cmp (liw1.dest, liw1.src, liw2.dest, liw2.src, | 3144 insn2_pat = gen_liw_cmp (liw1.dest, liw1.src, liw2.dest, liw2.src, |
3126 GEN_INT (liw1.op)); | 3145 GEN_INT (liw1.op)); |
3127 else | 3146 else |
3128 insn2 = gen_liw (liw1.dest, liw2.dest, liw1.src, liw2.src, | 3147 insn2_pat = gen_liw (liw1.dest, liw2.dest, liw1.src, liw2.src, |
3129 GEN_INT (liw1.op), GEN_INT (liw2.op)); | 3148 GEN_INT (liw1.op), GEN_INT (liw2.op)); |
3130 | 3149 |
3131 insn2 = emit_insn_after (insn2, insn1); | 3150 insn2 = emit_insn_after (insn2_pat, insn1); |
3132 delete_insn (insn1); | 3151 delete_insn (insn1); |
3133 r = insn2; | 3152 r = insn2; |
3134 } | 3153 } |
3135 } | 3154 } |
3136 | 3155 |
3156 #define DUMP(reason, insn) \ | |
3157 do \ | |
3158 { \ | |
3159 if (dump_file) \ | |
3160 { \ | |
3161 fprintf (dump_file, reason "\n"); \ | |
3162 if (insn != NULL_RTX) \ | |
3163 print_rtl_single (dump_file, insn); \ | |
3164 fprintf(dump_file, "\n"); \ | |
3165 } \ | |
3166 } \ | |
3167 while (0) | |
3168 | |
3169 /* Replace the BRANCH insn with a Lcc insn that goes to LABEL. | |
3170 Insert a SETLB insn just before LABEL. */ | |
3171 | |
3172 static void | |
3173 mn10300_insert_setlb_lcc (rtx_insn *label, rtx_insn *branch) | |
3174 { | |
3175 rtx lcc, comparison, cmp_reg; | |
3176 | |
3177 if (LABEL_NUSES (label) > 1) | |
3178 { | |
3179 rtx_insn *insn; | |
3180 | |
3181 /* This label is used both as an entry point to the loop | |
3182 and as a loop-back point for the loop. We need to separate | |
3183 these two functions so that the SETLB happens upon entry, | |
3184 but the loop-back does not go to the SETLB instruction. */ | |
3185 DUMP ("Inserting SETLB insn after:", label); | |
3186 insn = emit_insn_after (gen_setlb (), label); | |
3187 label = gen_label_rtx (); | |
3188 emit_label_after (label, insn); | |
3189 DUMP ("Created new loop-back label:", label); | |
3190 } | |
3191 else | |
3192 { | |
3193 DUMP ("Inserting SETLB insn before:", label); | |
3194 emit_insn_before (gen_setlb (), label); | |
3195 } | |
3196 | |
3197 comparison = XEXP (SET_SRC (PATTERN (branch)), 0); | |
3198 cmp_reg = XEXP (comparison, 0); | |
3199 gcc_assert (REG_P (cmp_reg)); | |
3200 | |
3201 /* If the comparison has not already been split out of the branch | |
3202 then do so now. */ | |
3203 gcc_assert (REGNO (cmp_reg) == CC_REG); | |
3204 | |
3205 if (GET_MODE (cmp_reg) == CC_FLOATmode) | |
3206 lcc = gen_FLcc (comparison, label); | |
3207 else | |
3208 lcc = gen_Lcc (comparison, label); | |
3209 | |
3210 rtx_insn *jump = emit_jump_insn_before (lcc, branch); | |
3211 mark_jump_label (XVECEXP (lcc, 0, 0), jump, 0); | |
3212 JUMP_LABEL (jump) = label; | |
3213 DUMP ("Replacing branch insn...", branch); | |
3214 DUMP ("... with Lcc insn:", jump); | |
3215 delete_insn (branch); | |
3216 } | |
3217 | |
3218 static bool | |
3219 mn10300_block_contains_call (basic_block block) | |
3220 { | |
3221 rtx_insn *insn; | |
3222 | |
3223 FOR_BB_INSNS (block, insn) | |
3224 if (CALL_P (insn)) | |
3225 return true; | |
3226 | |
3227 return false; | |
3228 } | |
3229 | |
3230 static bool | |
3231 mn10300_loop_contains_call_insn (loop_p loop) | |
3232 { | |
3233 basic_block * bbs; | |
3234 bool result = false; | |
3235 unsigned int i; | |
3236 | |
3237 bbs = get_loop_body (loop); | |
3238 | |
3239 for (i = 0; i < loop->num_nodes; i++) | |
3240 if (mn10300_block_contains_call (bbs[i])) | |
3241 { | |
3242 result = true; | |
3243 break; | |
3244 } | |
3245 | |
3246 free (bbs); | |
3247 return result; | |
3248 } | |
3249 | |
3250 static void | |
3251 mn10300_scan_for_setlb_lcc (void) | |
3252 { | |
3253 loop_p loop; | |
3254 | |
3255 DUMP ("Looking for loops that can use the SETLB insn", NULL_RTX); | |
3256 | |
3257 df_analyze (); | |
3258 compute_bb_for_insn (); | |
3259 | |
3260 /* Find the loops. */ | |
3261 loop_optimizer_init (AVOID_CFG_MODIFICATIONS); | |
3262 | |
3263 /* FIXME: For now we only investigate innermost loops. In practice however | |
3264 if an inner loop is not suitable for use with the SETLB/Lcc insns, it may | |
3265 be the case that its parent loop is suitable. Thus we should check all | |
3266 loops, but work from the innermost outwards. */ | |
3267 FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST) | |
3268 { | |
3269 const char * reason = NULL; | |
3270 | |
3271 /* Check to see if we can modify this loop. If we cannot | |
3272 then set 'reason' to describe why it could not be done. */ | |
3273 if (loop->latch == NULL) | |
3274 reason = "it contains multiple latches"; | |
3275 else if (loop->header != loop->latch) | |
3276 /* FIXME: We could handle loops that span multiple blocks, | |
3277 but this requires a lot more work tracking down the branches | |
3278 that need altering, so for now keep things simple. */ | |
3279 reason = "the loop spans multiple blocks"; | |
3280 else if (mn10300_loop_contains_call_insn (loop)) | |
3281 reason = "it contains CALL insns"; | |
3282 else | |
3283 { | |
3284 rtx_insn *branch = BB_END (loop->latch); | |
3285 | |
3286 gcc_assert (JUMP_P (branch)); | |
3287 if (single_set (branch) == NULL_RTX || ! any_condjump_p (branch)) | |
3288 /* We cannot optimize tablejumps and the like. */ | |
3289 /* FIXME: We could handle unconditional jumps. */ | |
3290 reason = "it is not a simple loop"; | |
3291 else | |
3292 { | |
3293 rtx_insn *label; | |
3294 | |
3295 if (dump_file) | |
3296 flow_loop_dump (loop, dump_file, NULL, 0); | |
3297 | |
3298 label = BB_HEAD (loop->header); | |
3299 gcc_assert (LABEL_P (label)); | |
3300 | |
3301 mn10300_insert_setlb_lcc (label, branch); | |
3302 } | |
3303 } | |
3304 | |
3305 if (dump_file && reason != NULL) | |
3306 fprintf (dump_file, "Loop starting with insn %d is not suitable because %s\n", | |
3307 INSN_UID (BB_HEAD (loop->header)), | |
3308 reason); | |
3309 } | |
3310 | |
3311 loop_optimizer_finalize (); | |
3312 | |
3313 df_finish_pass (false); | |
3314 | |
3315 DUMP ("SETLB scan complete", NULL_RTX); | |
3316 } | |
3317 | |
3137 static void | 3318 static void |
3138 mn10300_reorg (void) | 3319 mn10300_reorg (void) |
3139 { | 3320 { |
3140 if (TARGET_AM33) | 3321 /* These are optimizations, so only run them if optimizing. */ |
3141 { | 3322 if (TARGET_AM33 && (optimize > 0 || optimize_size)) |
3323 { | |
3324 if (TARGET_ALLOW_SETLB) | |
3325 mn10300_scan_for_setlb_lcc (); | |
3326 | |
3142 if (TARGET_ALLOW_LIW) | 3327 if (TARGET_ALLOW_LIW) |
3143 mn10300_bundle_liw (); | 3328 mn10300_bundle_liw (); |
3144 } | 3329 } |
3145 } | 3330 } |
3146 | 3331 |
3147 /* Initialize the GCC target structure. */ | 3332 /* Initialize the GCC target structure. */ |
3148 | 3333 |
3149 #undef TARGET_MACHINE_DEPENDENT_REORG | 3334 #undef TARGET_MACHINE_DEPENDENT_REORG |
3150 #define TARGET_MACHINE_DEPENDENT_REORG mn10300_reorg | 3335 #define TARGET_MACHINE_DEPENDENT_REORG mn10300_reorg |
3151 | |
3152 #undef TARGET_EXCEPT_UNWIND_INFO | |
3153 #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info | |
3154 | 3336 |
3155 #undef TARGET_ASM_ALIGNED_HI_OP | 3337 #undef TARGET_ASM_ALIGNED_HI_OP |
3156 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t" | 3338 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t" |
3157 | 3339 |
3158 #undef TARGET_LEGITIMIZE_ADDRESS | 3340 #undef TARGET_LEGITIMIZE_ADDRESS |
3173 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true | 3355 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true |
3174 | 3356 |
3175 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA | 3357 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA |
3176 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA mn10300_asm_output_addr_const_extra | 3358 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA mn10300_asm_output_addr_const_extra |
3177 | 3359 |
3178 #undef TARGET_DEFAULT_TARGET_FLAGS | |
3179 #define TARGET_DEFAULT_TARGET_FLAGS MASK_MULT_BUG | MASK_PTR_A0D0 | MASK_ALLOW_LIW | |
3180 #undef TARGET_HANDLE_OPTION | |
3181 #define TARGET_HANDLE_OPTION mn10300_handle_option | |
3182 #undef TARGET_OPTION_OVERRIDE | 3360 #undef TARGET_OPTION_OVERRIDE |
3183 #define TARGET_OPTION_OVERRIDE mn10300_option_override | 3361 #define TARGET_OPTION_OVERRIDE mn10300_option_override |
3184 #undef TARGET_OPTION_OPTIMIZATION_TABLE | |
3185 #define TARGET_OPTION_OPTIMIZATION_TABLE mn10300_option_optimization_table | |
3186 | 3362 |
3187 #undef TARGET_ENCODE_SECTION_INFO | 3363 #undef TARGET_ENCODE_SECTION_INFO |
3188 #define TARGET_ENCODE_SECTION_INFO mn10300_encode_section_info | 3364 #define TARGET_ENCODE_SECTION_INFO mn10300_encode_section_info |
3189 | 3365 |
3190 #undef TARGET_PROMOTE_PROTOTYPES | 3366 #undef TARGET_PROMOTE_PROTOTYPES |
3208 #define TARGET_EXPAND_BUILTIN_VA_START mn10300_va_start | 3384 #define TARGET_EXPAND_BUILTIN_VA_START mn10300_va_start |
3209 | 3385 |
3210 #undef TARGET_CASE_VALUES_THRESHOLD | 3386 #undef TARGET_CASE_VALUES_THRESHOLD |
3211 #define TARGET_CASE_VALUES_THRESHOLD mn10300_case_values_threshold | 3387 #define TARGET_CASE_VALUES_THRESHOLD mn10300_case_values_threshold |
3212 | 3388 |
3389 #undef TARGET_LRA_P | |
3390 #define TARGET_LRA_P hook_bool_void_false | |
3391 | |
3213 #undef TARGET_LEGITIMATE_ADDRESS_P | 3392 #undef TARGET_LEGITIMATE_ADDRESS_P |
3214 #define TARGET_LEGITIMATE_ADDRESS_P mn10300_legitimate_address_p | 3393 #define TARGET_LEGITIMATE_ADDRESS_P mn10300_legitimate_address_p |
3215 #undef TARGET_DELEGITIMIZE_ADDRESS | 3394 #undef TARGET_DELEGITIMIZE_ADDRESS |
3216 #define TARGET_DELEGITIMIZE_ADDRESS mn10300_delegitimize_address | 3395 #define TARGET_DELEGITIMIZE_ADDRESS mn10300_delegitimize_address |
3396 #undef TARGET_LEGITIMATE_CONSTANT_P | |
3397 #define TARGET_LEGITIMATE_CONSTANT_P mn10300_legitimate_constant_p | |
3217 | 3398 |
3218 #undef TARGET_PREFERRED_RELOAD_CLASS | 3399 #undef TARGET_PREFERRED_RELOAD_CLASS |
3219 #define TARGET_PREFERRED_RELOAD_CLASS mn10300_preferred_reload_class | 3400 #define TARGET_PREFERRED_RELOAD_CLASS mn10300_preferred_reload_class |
3220 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS | 3401 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS |
3221 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS \ | 3402 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS \ |
3240 #define TARGET_SCHED_ADJUST_COST mn10300_adjust_sched_cost | 3421 #define TARGET_SCHED_ADJUST_COST mn10300_adjust_sched_cost |
3241 | 3422 |
3242 #undef TARGET_CONDITIONAL_REGISTER_USAGE | 3423 #undef TARGET_CONDITIONAL_REGISTER_USAGE |
3243 #define TARGET_CONDITIONAL_REGISTER_USAGE mn10300_conditional_register_usage | 3424 #define TARGET_CONDITIONAL_REGISTER_USAGE mn10300_conditional_register_usage |
3244 | 3425 |
3245 #undef TARGET_MD_ASM_CLOBBERS | 3426 #undef TARGET_MD_ASM_ADJUST |
3246 #define TARGET_MD_ASM_CLOBBERS mn10300_md_asm_clobbers | 3427 #define TARGET_MD_ASM_ADJUST mn10300_md_asm_adjust |
3247 | 3428 |
3248 #undef TARGET_FLAGS_REGNUM | 3429 #undef TARGET_FLAGS_REGNUM |
3249 #define TARGET_FLAGS_REGNUM CC_REG | 3430 #define TARGET_FLAGS_REGNUM CC_REG |
3250 | 3431 |
3432 #undef TARGET_HARD_REGNO_MODE_OK | |
3433 #define TARGET_HARD_REGNO_MODE_OK mn10300_hard_regno_mode_ok | |
3434 | |
3435 #undef TARGET_MODES_TIEABLE_P | |
3436 #define TARGET_MODES_TIEABLE_P mn10300_modes_tieable_p | |
3437 | |
3251 struct gcc_target targetm = TARGET_INITIALIZER; | 3438 struct gcc_target targetm = TARGET_INITIALIZER; |