OSDN Git Service

7276d813e2744b0e394736fbf050cc32a661a184
[pf3gnuchains/gcc-fork.git] / gcc / config / mcore / mcore.c
1 /* Output routines for Motorola MCore processor
2    Copyright (C) 1993, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "rtl.h"
24 #include "tree.h"
25 #include "tm_p.h"
26 #include "assert.h"
27 #include "mcore.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "output.h"
34 #include "insn-attr.h"
35 #include "flags.h"
36 #include "obstack.h"
37 #include "expr.h"
38 #include "reload.h"
39 #include "recog.h"
40 #include "function.h"
41 #include "ggc.h"
42 #include "toplev.h"
43 #include "target.h"
44 #include "target-def.h"
45
46 /* Maximum size we are allowed to grow the stack in a single operation.
47    If we want more, we must do it in increments of at most this size.
48    If this value is 0, we don't check at all.  */
49 const char * mcore_stack_increment_string = 0;
50 int          mcore_stack_increment = STACK_UNITS_MAXSTEP;
51
52 /* For dumping information about frame sizes.  */
53 char * mcore_current_function_name = 0;
54 long   mcore_current_compilation_timestamp = 0;
55
56 /* Global variables for machine-dependent things.  */
57
58 /* Saved operands from the last compare to use when we generate an scc
59   or bcc insn.  */
60 rtx arch_compare_op0;
61 rtx arch_compare_op1;
62
63 /* Provides the class number of the smallest class containing
64    reg number.  */
65 const int regno_reg_class[FIRST_PSEUDO_REGISTER] =
66 {
67   GENERAL_REGS, ONLYR1_REGS,  LRW_REGS,     LRW_REGS,
68   LRW_REGS,     LRW_REGS,     LRW_REGS,     LRW_REGS,
69   LRW_REGS,     LRW_REGS,     LRW_REGS,     LRW_REGS,
70   LRW_REGS,     LRW_REGS,     LRW_REGS,     GENERAL_REGS,
71   GENERAL_REGS, C_REGS,       NO_REGS,      NO_REGS,
72 };
73
74 /* Provide reg_class from a letter such as appears in the machine
75    description.  */
76 const enum reg_class reg_class_from_letter[] =
77 {
78   /* a */ LRW_REGS, /* b */ ONLYR1_REGS, /* c */ C_REGS,  /* d */ NO_REGS,
79   /* e */ NO_REGS, /* f */ NO_REGS, /* g */ NO_REGS, /* h */ NO_REGS,
80   /* i */ NO_REGS, /* j */ NO_REGS, /* k */ NO_REGS, /* l */ NO_REGS,
81   /* m */ NO_REGS, /* n */ NO_REGS, /* o */ NO_REGS, /* p */ NO_REGS,
82   /* q */ NO_REGS, /* r */ GENERAL_REGS, /* s */ NO_REGS, /* t */ NO_REGS,
83   /* u */ NO_REGS, /* v */ NO_REGS, /* w */ NO_REGS, /* x */ ALL_REGS,
84   /* y */ NO_REGS, /* z */ NO_REGS
85 };
86
87 struct mcore_frame
88 {
89   int arg_size;                 /* stdarg spills (bytes) */
90   int reg_size;                 /* non-volatile reg saves (bytes) */
91   int reg_mask;                 /* non-volatile reg saves */
92   int local_size;               /* locals */
93   int outbound_size;            /* arg overflow on calls out */
94   int pad_outbound;
95   int pad_local;
96   int pad_reg;
97   /* Describe the steps we'll use to grow it.  */
98 #define MAX_STACK_GROWS 4       /* gives us some spare space */
99   int growth[MAX_STACK_GROWS];
100   int arg_offset;
101   int reg_offset;
102   int reg_growth;
103   int local_growth;
104 };
105
106 typedef enum
107 {
108   COND_NO,
109   COND_MOV_INSN,
110   COND_CLR_INSN,
111   COND_INC_INSN,
112   COND_DEC_INSN,
113   COND_BRANCH_INSN
114 }
115 cond_type;
116
117 static void       output_stack_adjust          PARAMS ((int, int));
118 static int        calc_live_regs               PARAMS ((int *));
119 static int        const_ok_for_mcore           PARAMS ((int));
120 static int        try_constant_tricks          PARAMS ((long, int *, int *));
121 static const char *     output_inline_const          PARAMS ((enum machine_mode, rtx *));
122 static void       block_move_sequence          PARAMS ((rtx, rtx, rtx, rtx, int, int, int));
123 static void       layout_mcore_frame           PARAMS ((struct mcore_frame *));
124 static cond_type  is_cond_candidate            PARAMS ((rtx));
125 static rtx        emit_new_cond_insn           PARAMS ((rtx, int));
126 static rtx        conditionalize_block         PARAMS ((rtx));
127 static void       conditionalize_optimization  PARAMS ((rtx));
128 static void       mcore_add_gc_roots           PARAMS ((void));
129 static rtx        handle_structs_in_regs       PARAMS ((enum machine_mode, tree, int));
130 static void       mcore_mark_dllexport         PARAMS ((tree));
131 static void       mcore_mark_dllimport         PARAMS ((tree));
132 static int        mcore_dllexport_p            PARAMS ((tree));
133 static int        mcore_dllimport_p            PARAMS ((tree));
134 const struct attribute_spec mcore_attribute_table[];
135 static tree       mcore_handle_naked_attribute PARAMS ((tree *, tree, tree, int, bool *));
136 #ifdef OBJECT_FORMAT_ELF
137 static void       mcore_asm_named_section      PARAMS ((const char *,
138                                                         unsigned int));
139 #endif
140 static void       mcore_unique_section         PARAMS ((tree, int));
141 static void mcore_encode_section_info           PARAMS ((tree, int));
142 static const char *mcore_strip_name_encoding    PARAMS ((const char *));
143 \f
144 /* Initialize the GCC target structure.  */
145 #ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
146 #undef TARGET_MERGE_DECL_ATTRIBUTES
147 #define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
148 #endif
149
150 #ifdef OBJECT_FORMAT_ELF
151 #undef TARGET_ASM_UNALIGNED_HI_OP
152 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
153 #undef TARGET_ASM_UNALIGNED_SI_OP
154 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
155 #endif
156
157 #undef TARGET_ATTRIBUTE_TABLE
158 #define TARGET_ATTRIBUTE_TABLE mcore_attribute_table
159 #undef TARGET_ASM_UNIQUE_SECTION
160 #define TARGET_ASM_UNIQUE_SECTION mcore_unique_section
161 #undef TARGET_ENCODE_SECTION_INFO
162 #define TARGET_ENCODE_SECTION_INFO mcore_encode_section_info
163 #undef TARGET_STRIP_NAME_ENCODING
164 #define TARGET_STRIP_NAME_ENCODING mcore_strip_name_encoding
165
166 struct gcc_target targetm = TARGET_INITIALIZER;
167 \f
168 /* Adjust the stack and return the number of bytes taken to do it.  */
169 static void
170 output_stack_adjust (direction, size)
171      int direction;
172      int size;
173 {
174   /* If extending stack a lot, we do it incrementally.  */
175   if (direction < 0 && size > mcore_stack_increment && mcore_stack_increment > 0)
176     {
177       rtx tmp = gen_rtx (REG, SImode, 1);
178       rtx memref;
179       emit_insn (gen_movsi (tmp, GEN_INT (mcore_stack_increment)));
180       do
181         {
182           emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
183           memref = gen_rtx (MEM, SImode, stack_pointer_rtx);
184           MEM_VOLATILE_P (memref) = 1;
185           emit_insn (gen_movsi (memref, stack_pointer_rtx));
186           size -= mcore_stack_increment;
187         }
188       while (size > mcore_stack_increment);
189
190       /* SIZE is now the residual for the last adjustment,
191          which doesn't require a probe.  */
192     }
193
194   if (size)
195     {
196       rtx insn;
197       rtx val = GEN_INT (size);
198
199       if (size > 32)
200         {
201           rtx nval = gen_rtx (REG, SImode, 1);
202           emit_insn (gen_movsi (nval, val));
203           val = nval;
204         }
205       
206       if (direction > 0)
207         insn = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, val);
208       else
209         insn = gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, val);
210       
211       emit_insn (insn);
212     }
213 }
214
215 /* Work out the registers which need to be saved,
216    both as a mask and a count.  */
217
218 static int
219 calc_live_regs (count)
220      int * count;
221 {
222   int reg;
223   int live_regs_mask = 0;
224   
225   * count = 0;
226
227   for (reg = 0; reg < FIRST_PSEUDO_REGISTER; reg++)
228     {
229       if (regs_ever_live[reg] && !call_used_regs[reg])
230         {
231           (*count)++;
232           live_regs_mask |= (1 << reg);
233         }
234     }
235
236   return live_regs_mask;
237 }
238
239 /* Print the operand address in x to the stream.  */
240
241 void
242 mcore_print_operand_address (stream, x)
243      FILE * stream;
244      rtx x;
245 {
246   switch (GET_CODE (x))
247     {
248     case REG:
249       fprintf (stream, "(%s)", reg_names[REGNO (x)]);
250       break;
251       
252     case PLUS:
253       {
254         rtx base = XEXP (x, 0);
255         rtx index = XEXP (x, 1);
256
257         if (GET_CODE (base) != REG)
258           {
259             /* Ensure that BASE is a register (one of them must be).  */
260             rtx temp = base;
261             base = index;
262             index = temp;
263           }
264
265         switch (GET_CODE (index))
266           {
267           case CONST_INT:
268             fprintf (stream, "(%s,%d)", reg_names[REGNO(base)],
269                      INTVAL (index));
270             break;
271
272           default:
273             debug_rtx (x);
274
275             abort ();
276           }
277       }
278
279       break;
280
281     default:
282       output_addr_const (stream, x);
283       break;
284     }
285 }
286
287 /* Print operand x (an rtx) in assembler syntax to file stream
288    according to modifier code.
289
290    'R'  print the next register or memory location along, ie the lsw in
291         a double word value
292    'O'  print a constant without the #
293    'M'  print a constant as its negative
294    'P'  print log2 of a power of two
295    'Q'  print log2 of an inverse of a power of two
296    'U'  print register for ldm/stm instruction
297    'X'  print byte number for xtrbN instruction.  */
298
299 void
300 mcore_print_operand (stream, x, code)
301      FILE * stream;
302      rtx x;
303      int code;
304 {
305   switch (code)
306     {
307     case 'N':
308       if (INTVAL(x) == -1)
309         fprintf (asm_out_file, "32");
310       else
311         fprintf (asm_out_file, "%d", exact_log2 (INTVAL (x) + 1));
312       break;
313     case 'P':
314       fprintf (asm_out_file, "%d", exact_log2 (INTVAL (x)));
315       break;
316     case 'Q':
317       fprintf (asm_out_file, "%d", exact_log2 (~INTVAL (x)));
318       break;
319     case 'O':
320       fprintf (asm_out_file, "%d", INTVAL (x));
321       break;
322     case 'M':
323       fprintf (asm_out_file, "%d", - INTVAL (x));
324       break;
325     case 'R':
326       /* Next location along in memory or register.  */
327       switch (GET_CODE (x))
328         {
329         case REG:
330           fputs (reg_names[REGNO (x) + 1], (stream));
331           break;
332         case MEM:
333           mcore_print_operand_address
334             (stream, XEXP (adjust_address (x, SImode, 4), 0));
335           break;
336         default:
337           abort ();
338         }
339       break;
340     case 'U':
341       fprintf (asm_out_file, "%s-%s", reg_names[REGNO (x)],
342                reg_names[REGNO (x) + 3]);
343       break;
344     case 'x':
345       fprintf (asm_out_file, "0x%x", INTVAL (x));
346       break;
347     case 'X':
348       fprintf (asm_out_file, "%d", 3 - INTVAL (x) / 8);
349       break;
350
351     default:
352       switch (GET_CODE (x))
353         {
354         case REG:
355           fputs (reg_names[REGNO (x)], (stream));
356           break;
357         case MEM:
358           output_address (XEXP (x, 0));
359           break;
360         default:
361           output_addr_const (stream, x);
362           break;
363         }
364       break;
365     }
366 }
367
368 /* What does a constant cost ?  */
369
370 int
371 mcore_const_costs (exp, code)
372      rtx exp;
373      enum rtx_code code;
374 {
375
376   int val = INTVAL (exp);
377
378   /* Easy constants.  */
379   if (   CONST_OK_FOR_I (val)   
380       || CONST_OK_FOR_M (val)   
381       || CONST_OK_FOR_N (val)   
382       || (code == PLUS && CONST_OK_FOR_L (val)))
383     return 1;                                   
384   else if (code == AND
385            && (   CONST_OK_FOR_M (~val)
386                || CONST_OK_FOR_N (~val)))
387     return 2;
388   else if (code == PLUS                 
389            && (   CONST_OK_FOR_I (-val) 
390                || CONST_OK_FOR_M (-val) 
391                || CONST_OK_FOR_N (-val)))       
392     return 2;                                           
393
394   return 5;                                     
395 }
396
397 /* What does an and instruction cost - we do this b/c immediates may 
398    have been relaxed.   We want to ensure that cse will cse relaxed immeds
399    out.  Otherwise we'll get bad code (multiple reloads of the same const).  */
400
401 int
402 mcore_and_cost (x)
403      rtx x;
404 {
405   int val;
406
407   if (GET_CODE (XEXP (x, 1)) != CONST_INT)
408     return 2;
409
410   val = INTVAL (XEXP (x, 1));
411    
412   /* Do it directly.  */
413   if (CONST_OK_FOR_K (val) || CONST_OK_FOR_M (~val))
414     return 2;
415   /* Takes one instruction to load.  */
416   else if (const_ok_for_mcore (val))
417     return 3;
418   /* Takes two instructions to load.  */
419   else if (TARGET_HARDLIT && mcore_const_ok_for_inline (val))
420     return 4;
421
422   /* Takes a lrw to load.  */
423   return 5;
424 }
425
426 /* What does an or cost - see and_cost().  */
427
428 int
429 mcore_ior_cost (x)
430      rtx x;
431 {
432   int val;
433
434   if (GET_CODE (XEXP (x, 1)) != CONST_INT)
435     return 2;
436
437   val = INTVAL (XEXP (x, 1));
438
439   /* Do it directly with bclri.  */
440   if (CONST_OK_FOR_M (val))
441     return 2;
442   /* Takes one instruction to load.  */
443   else if (const_ok_for_mcore (val))
444     return 3;
445   /* Takes two instructions to load.  */
446   else if (TARGET_HARDLIT && mcore_const_ok_for_inline (val))
447     return 4;
448   
449   /* Takes a lrw to load.  */
450   return 5;
451 }
452
453 /* Check to see if a comparison against a constant can be made more efficient
454    by incrementing/decrementing the constant to get one that is more efficient
455    to load.  */
456
457 int
458 mcore_modify_comparison (code)
459      enum rtx_code code;
460 {
461   rtx op1   = arch_compare_op1;
462   
463   if (GET_CODE (op1) == CONST_INT)
464     {
465       int val = INTVAL (op1);
466       
467       switch (code)
468         {
469         case LE:
470           if (CONST_OK_FOR_J (val + 1))
471             {
472               arch_compare_op1 = GEN_INT (val + 1);
473               return 1;
474             }
475           break;
476           
477         default:
478           break;
479         }
480     }
481   
482   return 0;
483 }
484
485 /* Prepare the operands for a comparison.  */
486
487 rtx
488 mcore_gen_compare_reg (code)
489      enum rtx_code code;
490 {
491   rtx op0 = arch_compare_op0;
492   rtx op1 = arch_compare_op1;
493   rtx cc_reg = gen_rtx (REG, CCmode, CC_REG);
494
495   if (CONSTANT_P (op1) && GET_CODE (op1) != CONST_INT)
496     op1 = force_reg (SImode, op1);
497
498   /* cmpnei: 0-31 (K immediate)
499      cmplti: 1-32 (J immediate, 0 using btsti x,31).  */
500   switch (code)
501     {
502     case EQ:    /* Use inverted condition, cmpne.  */
503       code = NE;
504       /* drop through */
505       
506     case NE:    /* Use normal condition, cmpne.  */
507       if (GET_CODE (op1) == CONST_INT && ! CONST_OK_FOR_K (INTVAL (op1)))
508         op1 = force_reg (SImode, op1);
509       break;
510
511     case LE:    /* Use inverted condition, reversed cmplt.  */
512       code = GT;
513       /* drop through */
514       
515     case GT:    /* Use normal condition, reversed cmplt.  */
516       if (GET_CODE (op1) == CONST_INT)
517         op1 = force_reg (SImode, op1);
518       break;
519
520     case GE:    /* Use inverted condition, cmplt.  */
521       code = LT;
522       /* drop through */
523       
524     case LT:    /* Use normal condition, cmplt.  */
525       if (GET_CODE (op1) == CONST_INT && 
526           /* covered by btsti x,31 */
527           INTVAL (op1) != 0 &&
528           ! CONST_OK_FOR_J (INTVAL (op1)))
529         op1 = force_reg (SImode, op1);
530       break;
531
532     case GTU:   /* Use inverted condition, cmple.  */
533       if (GET_CODE (op1) == CONST_INT && INTVAL (op1) == 0)
534         {
535           /* Unsigned > 0 is the same as != 0, but we need
536              to invert the condition, so we want to set
537              code = EQ.  This cannot be done however, as the
538              mcore does not support such a test.  Instead we
539              cope with this case in the "bgtu" pattern itself
540              so we should never reach this point.  */
541           /* code = EQ; */
542           abort ();
543           break;
544         }
545       code = LEU;
546       /* drop through */
547       
548     case LEU:   /* Use normal condition, reversed cmphs. */
549       if (GET_CODE (op1) == CONST_INT && INTVAL (op1) != 0)
550         op1 = force_reg (SImode, op1);
551       break;
552
553     case LTU:   /* Use inverted condition, cmphs.  */
554       code = GEU;
555       /* drop through */
556       
557     case GEU:   /* Use normal condition, cmphs.  */
558       if (GET_CODE (op1) == CONST_INT && INTVAL (op1) != 0)
559         op1 = force_reg (SImode, op1);
560       break;
561
562     default:
563       break;
564     }
565
566   emit_insn (gen_rtx (SET, VOIDmode, cc_reg, gen_rtx (code, CCmode, op0, op1)));
567   
568   return cc_reg;
569 }
570
571
572 int
573 mcore_symbolic_address_p (x)
574      rtx x;
575 {
576   switch (GET_CODE (x))
577     {
578     case SYMBOL_REF:
579     case LABEL_REF:
580       return 1;
581     case CONST:
582       x = XEXP (x, 0);
583       return (   (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
584                || GET_CODE (XEXP (x, 0)) == LABEL_REF)
585               && GET_CODE (XEXP (x, 1)) == CONST_INT);
586     default:
587       return 0;
588     }
589 }
590
591 int
592 mcore_call_address_operand (x, mode)
593      rtx x;
594      enum machine_mode mode;
595 {
596   return register_operand (x, mode) || CONSTANT_P (x);
597 }
598
599 /* Functions to output assembly code for a function call.  */
600
601 char *
602 mcore_output_call (operands, index)
603      rtx operands[];
604      int index;
605 {
606   static char buffer[20];
607   rtx addr = operands [index];
608   
609   if (REG_P (addr))
610     {
611       if (TARGET_CG_DATA)
612         {
613           if (mcore_current_function_name == 0)
614             abort ();
615           
616           ASM_OUTPUT_CG_EDGE (asm_out_file, mcore_current_function_name,
617                               "unknown", 1);
618         }
619
620       sprintf (buffer, "jsr\t%%%d", index);
621     }
622   else
623     {
624       if (TARGET_CG_DATA)
625         {
626           if (mcore_current_function_name == 0)
627             abort ();
628           
629           if (GET_CODE (addr) != SYMBOL_REF)
630             abort ();
631           
632           ASM_OUTPUT_CG_EDGE (asm_out_file, mcore_current_function_name, XSTR (addr, 0), 0);
633         }
634       
635       sprintf (buffer, "jbsr\t%%%d", index);
636     }
637
638   return buffer;
639 }
640
641 /* Can we load a constant with a single instruction ?  */
642
643 static int
644 const_ok_for_mcore (value)
645      int value;
646 {
647   if (value >= 0 && value <= 127)
648     return 1;
649   
650   /* Try exact power of two.  */
651   if ((value & (value - 1)) == 0)
652     return 1;
653   
654   /* Try exact power of two - 1. */
655   if ((value & (value + 1)) == 0)
656     return 1;
657   
658   return 0;
659 }
660
661 /* Can we load a constant inline with up to 2 instructions ?  */
662
663 int
664 mcore_const_ok_for_inline (value)
665      long value;
666 {
667   int x, y;
668    
669   return try_constant_tricks (value, & x, & y) > 0;
670 }
671
672 /* Are we loading the constant using a not ?  */
673
674 int
675 mcore_const_trick_uses_not (value)
676      long value;
677 {
678   int x, y;
679
680   return try_constant_tricks (value, & x, & y) == 2; 
681 }       
682
683 /* Try tricks to load a constant inline and return the trick number if
684    success (0 is non-inlinable).
685   
686    0: not inlinable
687    1: single instruction (do the usual thing)
688    2: single insn followed by a 'not'
689    3: single insn followed by a subi
690    4: single insn followed by an addi
691    5: single insn followed by rsubi
692    6: single insn followed by bseti
693    7: single insn followed by bclri
694    8: single insn followed by rotli
695    9: single insn followed by lsli
696    10: single insn followed by ixh
697    11: single insn followed by ixw.  */
698
699 static int
700 try_constant_tricks (value, x, y)
701      long value;
702      int * x;
703      int * y;
704 {
705   int i;
706   unsigned bit, shf, rot;
707
708   if (const_ok_for_mcore (value))
709     return 1;   /* Do the usual thing.  */
710   
711   if (TARGET_HARDLIT) 
712     {
713       if (const_ok_for_mcore (~value))
714         {
715           *x = ~value;
716           return 2;
717         }
718       
719       for (i = 1; i <= 32; i++)
720         {
721           if (const_ok_for_mcore (value - i))
722             {
723               *x = value - i;
724               *y = i;
725               
726               return 3;
727             }
728           
729           if (const_ok_for_mcore (value + i))
730             {
731               *x = value + i;
732               *y = i;
733               
734               return 4;
735             }
736         }
737       
738       bit = 0x80000000L;
739       
740       for (i = 0; i <= 31; i++)
741         {
742           if (const_ok_for_mcore (i - value))
743             {
744               *x = i - value;
745               *y = i;
746               
747               return 5;
748             }
749           
750           if (const_ok_for_mcore (value & ~bit))
751             {
752               *y = bit;
753               *x = value & ~bit;
754               
755               return 6;
756             }
757           
758           if (const_ok_for_mcore (value | bit))
759             {
760               *y = ~bit;
761               *x = value | bit;
762               
763               return 7;
764             }
765           
766           bit >>= 1;
767         }
768       
769       shf = value;
770       rot = value;
771       
772       for (i = 1; i < 31; i++)
773         {
774           int c;
775           
776           /* MCore has rotate left.  */
777           c = rot << 31;
778           rot >>= 1;
779           rot &= 0x7FFFFFFF;
780           rot |= c;   /* Simulate rotate.  */
781           
782           if (const_ok_for_mcore (rot))
783             {
784               *y = i;
785               *x = rot;
786               
787               return 8;
788             }
789           
790           if (shf & 1)
791             shf = 0;    /* Can't use logical shift, low order bit is one.  */
792           
793           shf >>= 1;
794           
795           if (shf != 0 && const_ok_for_mcore (shf))
796             {
797               *y = i;
798               *x = shf;
799               
800               return 9;
801             }
802         }
803       
804       if ((value % 3) == 0 && const_ok_for_mcore (value / 3))
805         {
806           *x = value / 3;
807           
808           return 10;
809         }
810       
811       if ((value % 5) == 0 && const_ok_for_mcore (value / 5))
812         {
813           *x = value / 5;
814           
815           return 11;
816         }
817     }
818   
819   return 0;
820 }
821
822
823 /* Check whether reg is dead at first.  This is done by searching ahead
824    for either the next use (i.e., reg is live), a death note, or a set of
825    reg.  Don't just use dead_or_set_p() since reload does not always mark 
826    deaths (especially if PRESERVE_DEATH_NOTES_REGNO_P is not defined). We
827    can ignore subregs by extracting the actual register.  BRC  */
828
829 int
830 mcore_is_dead (first, reg)
831      rtx first;
832      rtx reg;
833 {
834   rtx insn;
835
836   /* For mcore, subregs can't live independently of their parent regs.  */
837   if (GET_CODE (reg) == SUBREG)
838     reg = SUBREG_REG (reg);
839
840   /* Dies immediately.  */
841   if (dead_or_set_p (first, reg))
842     return 1;
843
844   /* Look for conclusive evidence of live/death, otherwise we have
845      to assume that it is live.  */
846   for (insn = NEXT_INSN (first); insn; insn = NEXT_INSN (insn))
847     {
848       if (GET_CODE (insn) == JUMP_INSN)
849         return 0;       /* We lose track, assume it is alive.  */
850
851       else if (GET_CODE(insn) == CALL_INSN)
852         {
853           /* Call's might use it for target or register parms.  */
854           if (reg_referenced_p (reg, PATTERN (insn))
855               || find_reg_fusage (insn, USE, reg))
856             return 0;
857           else if (dead_or_set_p (insn, reg))
858             return 1;
859         }
860       else if (GET_CODE (insn) == INSN)
861         {
862           if (reg_referenced_p (reg, PATTERN (insn)))
863             return 0;
864           else if (dead_or_set_p (insn, reg))
865             return 1;
866         }
867     }
868
869   /* No conclusive evidence either way, we can not take the chance
870      that control flow hid the use from us -- "I'm not dead yet".  */
871   return 0;
872 }
873
874
875 /* Count the number of ones in mask.  */
876
877 int
878 mcore_num_ones (mask)
879      int mask;
880 {
881   /* A trick to count set bits recently posted on comp.compilers.  */
882   mask =  (mask >> 1  & 0x55555555) + (mask & 0x55555555);
883   mask = ((mask >> 2) & 0x33333333) + (mask & 0x33333333);
884   mask = ((mask >> 4) + mask) & 0x0f0f0f0f;
885   mask = ((mask >> 8) + mask);
886
887   return (mask + (mask >> 16)) & 0xff;
888 }
889
890 /* Count the number of zeros in mask.  */
891
892 int
893 mcore_num_zeros (mask)
894      int mask;
895 {
896   return 32 - mcore_num_ones (mask);
897 }
898
899 /* Determine byte being masked.  */
900
901 int
902 mcore_byte_offset (mask)
903      unsigned int mask;
904 {
905   if (mask == 0x00ffffffL)
906     return 0;
907   else if (mask == 0xff00ffffL)
908     return 1;
909   else if (mask == 0xffff00ffL)
910     return 2;
911   else if (mask == 0xffffff00L)
912     return 3;
913
914   return -1;
915 }
916
917 /* Determine halfword being masked.  */
918
919 int
920 mcore_halfword_offset (mask)
921      unsigned int mask;
922 {
923   if (mask == 0x0000ffffL)
924     return 0;
925   else if (mask == 0xffff0000L)
926     return 1;
927
928   return -1;
929 }
930
931 /* Output a series of bseti's corresponding to mask.  */
932
933 const char *
934 mcore_output_bseti (dst, mask)
935      rtx dst;
936      int mask;
937 {
938   rtx out_operands[2];
939   int bit;
940
941   out_operands[0] = dst;
942
943   for (bit = 0; bit < 32; bit++)
944     {
945       if ((mask & 0x1) == 0x1)
946         {
947           out_operands[1] = GEN_INT (bit);
948           
949           output_asm_insn ("bseti\t%0,%1", out_operands);
950         }
951       mask >>= 1;
952     }  
953
954   return "";
955 }
956
957 /* Output a series of bclri's corresponding to mask.  */
958
959 const char *
960 mcore_output_bclri (dst, mask)
961      rtx dst;
962      int mask;
963 {
964   rtx out_operands[2];
965   int bit;
966
967   out_operands[0] = dst;
968
969   for (bit = 0; bit < 32; bit++)
970     {
971       if ((mask & 0x1) == 0x0)
972         {
973           out_operands[1] = GEN_INT (bit);
974           
975           output_asm_insn ("bclri\t%0,%1", out_operands);
976         }
977       
978       mask >>= 1;
979     }  
980
981   return "";
982 }
983
984 /* Output a conditional move of two constants that are +/- 1 within each
985    other.  See the "movtK" patterns in mcore.md.   I'm not sure this is
986    really worth the effort.  */
987
988 const char *
989 mcore_output_cmov (operands, cmp_t, test)
990      rtx operands[];
991      int cmp_t;
992      const char * test;
993 {
994   int load_value;
995   int adjust_value;
996   rtx out_operands[4];
997
998   out_operands[0] = operands[0];
999
1000   /* Check to see which constant is loadable.  */
1001   if (const_ok_for_mcore (INTVAL (operands[1])))
1002     {
1003       out_operands[1] = operands[1];
1004       out_operands[2] = operands[2];
1005     }
1006   else if (const_ok_for_mcore (INTVAL (operands[2])))
1007     {
1008       out_operands[1] = operands[2];
1009       out_operands[2] = operands[1];
1010
1011       /* Complement test since constants are swapped.  */
1012       cmp_t = (cmp_t == 0);
1013     }
1014   load_value   = INTVAL (out_operands[1]);
1015   adjust_value = INTVAL (out_operands[2]);
1016
1017   /* First output the test if folded into the pattern.  */
1018
1019   if (test) 
1020     output_asm_insn (test, operands);
1021
1022   /* Load the constant - for now, only support constants that can be
1023      generated with a single instruction.  maybe add general inlinable
1024      constants later (this will increase the # of patterns since the
1025      instruction sequence has a different length attribute).  */
1026   if (load_value >= 0 && load_value <= 127)
1027     output_asm_insn ("movi\t%0,%1", out_operands);
1028   else if ((load_value & (load_value - 1)) == 0)
1029     output_asm_insn ("bgeni\t%0,%P1", out_operands);
1030   else if ((load_value & (load_value + 1)) == 0)
1031     output_asm_insn ("bmaski\t%0,%N1", out_operands);
1032    
1033   /* Output the constant adjustment.  */
1034   if (load_value > adjust_value)
1035     {
1036       if (cmp_t)
1037         output_asm_insn ("decf\t%0", out_operands);
1038       else
1039         output_asm_insn ("dect\t%0", out_operands);
1040     }
1041   else
1042     {
1043       if (cmp_t)
1044         output_asm_insn ("incf\t%0", out_operands);
1045       else
1046         output_asm_insn ("inct\t%0", out_operands);
1047     }
1048
1049   return "";
1050 }
1051
1052 /* Outputs the peephole for moving a constant that gets not'ed followed 
1053    by an and (i.e. combine the not and the and into andn). BRC  */
1054
1055 const char *
1056 mcore_output_andn (insn, operands)
1057      rtx insn ATTRIBUTE_UNUSED;
1058      rtx operands[];
1059 {
1060   int x, y;
1061   rtx out_operands[3];
1062   const char * load_op;
1063   char buf[256];
1064
1065   if (try_constant_tricks (INTVAL (operands[1]), &x, &y) != 2)
1066     abort ();
1067
1068   out_operands[0] = operands[0];
1069   out_operands[1] = GEN_INT(x);
1070   out_operands[2] = operands[2];
1071
1072   if (x >= 0 && x <= 127)
1073     load_op = "movi\t%0,%1";
1074   
1075   /* Try exact power of two.  */
1076   else if ((x & (x - 1)) == 0)
1077     load_op = "bgeni\t%0,%P1";
1078   
1079   /* Try exact power of two - 1.  */
1080   else if ((x & (x + 1)) == 0)
1081     load_op = "bmaski\t%0,%N1";
1082   
1083   else 
1084     load_op = "BADMOVI\t%0,%1";
1085
1086   sprintf (buf, "%s\n\tandn\t%%2,%%0", load_op);
1087   output_asm_insn (buf, out_operands);
1088
1089   return "";
1090 }
1091
1092 /* Output an inline constant.  */
1093
1094 static const char *
1095 output_inline_const (mode, operands)
1096      enum machine_mode mode;
1097      rtx operands[];
1098 {
1099   int x = 0, y = 0;
1100   int trick_no;
1101   rtx out_operands[3];
1102   char buf[256];
1103   char load_op[256];
1104   const char *dst_fmt;
1105   int value;
1106
1107   value = INTVAL (operands[1]);
1108    
1109   if ((trick_no = try_constant_tricks (value, &x, &y)) == 0)
1110     {
1111       /* lrw's are handled separately:  Large inlinable constants
1112          never get turned into lrw's.  Our caller uses try_constant_tricks
1113          to back off to an lrw rather than calling this routine.  */
1114       abort ();
1115     }
1116
1117   if (trick_no == 1)
1118     x = value;
1119
1120   /* operands: 0 = dst, 1 = load immed., 2 = immed. adjustment.  */
1121   out_operands[0] = operands[0];
1122   out_operands[1] = GEN_INT (x);
1123   
1124   if (trick_no > 2)
1125     out_operands[2] = GEN_INT (y);
1126
1127   /* Select dst format based on mode.  */
1128   if (mode == DImode && (! TARGET_LITTLE_END))
1129     dst_fmt = "%R0";
1130   else
1131     dst_fmt = "%0";
1132
1133   if (x >= 0 && x <= 127)
1134     sprintf (load_op, "movi\t%s,%%1", dst_fmt);
1135   
1136   /* Try exact power of two.  */
1137   else if ((x & (x - 1)) == 0)
1138     sprintf (load_op, "bgeni\t%s,%%P1", dst_fmt);
1139   
1140   /* Try exact power of two - 1.  */
1141   else if ((x & (x + 1)) == 0)
1142     sprintf (load_op, "bmaski\t%s,%%N1", dst_fmt);
1143   
1144   else 
1145     sprintf (load_op, "BADMOVI\t%s,%%1", dst_fmt);
1146
1147   switch (trick_no)
1148     {
1149     case 1:
1150       strcpy (buf, load_op);
1151       break;
1152     case 2:   /* not */
1153       sprintf (buf, "%s\n\tnot\t%s\t// %d 0x%x", load_op, dst_fmt, value, value);
1154       break;
1155     case 3:   /* add */
1156       sprintf (buf, "%s\n\taddi\t%s,%%2\t// %d 0x%x", load_op, dst_fmt, value, value);
1157       break;
1158     case 4:   /* sub */
1159       sprintf (buf, "%s\n\tsubi\t%s,%%2\t// %d 0x%x", load_op, dst_fmt, value, value);
1160       break;
1161     case 5:   /* rsub */
1162       /* Never happens unless -mrsubi, see try_constant_tricks().  */
1163       sprintf (buf, "%s\n\trsubi\t%s,%%2\t// %d 0x%x", load_op, dst_fmt, value, value);
1164       break;
1165     case 6:   /* bset */
1166       sprintf (buf, "%s\n\tbseti\t%s,%%P2\t// %d 0x%x", load_op, dst_fmt, value, value);
1167       break;
1168     case 7:   /* bclr */
1169       sprintf (buf, "%s\n\tbclri\t%s,%%Q2\t// %d 0x%x", load_op, dst_fmt, value, value);
1170       break;
1171     case 8:   /* rotl */
1172       sprintf (buf, "%s\n\trotli\t%s,%%2\t// %d 0x%x", load_op, dst_fmt, value, value);
1173       break;
1174     case 9:   /* lsl */
1175       sprintf (buf, "%s\n\tlsli\t%s,%%2\t// %d 0x%x", load_op, dst_fmt, value, value);
1176       break;
1177     case 10:  /* ixh */
1178       sprintf (buf, "%s\n\tixh\t%s,%s\t// %d 0x%x", load_op, dst_fmt, dst_fmt, value, value);
1179       break;
1180     case 11:  /* ixw */
1181       sprintf (buf, "%s\n\tixw\t%s,%s\t// %d 0x%x", load_op, dst_fmt, dst_fmt, value, value);
1182       break;
1183     default:
1184       return "";
1185     }
1186   
1187   output_asm_insn (buf, out_operands);
1188
1189   return "";
1190 }
1191
1192 /* Output a move of a word or less value.  */
1193
1194 const char *
1195 mcore_output_move (insn, operands, mode)
1196      rtx insn ATTRIBUTE_UNUSED;
1197      rtx operands[];
1198      enum machine_mode mode ATTRIBUTE_UNUSED;
1199 {
1200   rtx dst = operands[0];
1201   rtx src = operands[1];
1202
1203   if (GET_CODE (dst) == REG)
1204     {
1205       if (GET_CODE (src) == REG)
1206         {               
1207           if (REGNO (src) == CC_REG)            /* r-c */
1208             return "mvc\t%0"; 
1209           else 
1210             return "mov\t%0,%1";                /* r-r*/
1211         }
1212       else if (GET_CODE (src) == MEM)
1213         {
1214           if (GET_CODE (XEXP (src, 0)) == LABEL_REF) 
1215             return "lrw\t%0,[%1]";              /* a-R */
1216           else
1217             return "ldw\t%0,%1";                 /* r-m */
1218         }
1219       else if (GET_CODE (src) == CONST_INT)
1220         {
1221           int x, y;
1222           
1223           if (CONST_OK_FOR_I (INTVAL (src)))       /* r-I */
1224             return "movi\t%0,%1";
1225           else if (CONST_OK_FOR_M (INTVAL (src)))  /* r-M */
1226             return "bgeni\t%0,%P1\t// %1 %x1";
1227           else if (CONST_OK_FOR_N (INTVAL (src)))  /* r-N */
1228             return "bmaski\t%0,%N1\t// %1 %x1";
1229           else if (try_constant_tricks (INTVAL (src), &x, &y))     /* R-P */
1230             return output_inline_const (SImode, operands);  /* 1-2 insns */
1231           else 
1232             return "lrw\t%0,%x1\t// %1";        /* Get it from literal pool.  */
1233         }
1234       else
1235         return "lrw\t%0, %1";                /* Into the literal pool.  */
1236     }
1237   else if (GET_CODE (dst) == MEM)               /* m-r */
1238     return "stw\t%1,%0";
1239
1240   abort ();
1241 }
1242
1243 /* Outputs a constant inline -- regardless of the cost.
1244    Useful for things where we've gotten into trouble and think we'd
1245    be doing an lrw into r15 (forbidden). This lets us get out of
1246    that pickle even after register allocation.  */
1247
1248 const char *
1249 mcore_output_inline_const_forced (insn, operands, mode)
1250      rtx insn ATTRIBUTE_UNUSED;
1251      rtx operands[];
1252      enum machine_mode mode ATTRIBUTE_UNUSED;
1253 {
1254   unsigned long value = INTVAL (operands[1]);
1255   unsigned long ovalue = value;
1256   struct piece
1257   {
1258     int low;
1259     int shift;
1260   }
1261   part[6];
1262   int i;
1263
1264   if (mcore_const_ok_for_inline (value))
1265     return output_inline_const (SImode, operands);
1266
1267   for (i = 0; (unsigned) i < ARRAY_SIZE (part); i++)
1268     {
1269       part[i].shift = 0;
1270       part[i].low = (value & 0x1F);
1271       value -= part[i].low;
1272       
1273       if (mcore_const_ok_for_inline (value))
1274         break;
1275       else
1276         {
1277           value >>= 5;
1278           part[i].shift = 5;
1279           
1280           while ((value & 1) == 0)
1281             {
1282               part[i].shift++;
1283               value >>= 1;
1284             }
1285           
1286           if (mcore_const_ok_for_inline (value))
1287             break;
1288         }
1289     }
1290   
1291   /* 5 bits per iteration, a maximum of 5 times == 25 bits and leaves
1292      7 bits left in the constant -- which we know we can cover with
1293      a movi.  The final value can't be zero otherwise we'd have stopped
1294      in the previous iteration.   */
1295   if (value == 0 || ! mcore_const_ok_for_inline (value))
1296     abort ();
1297
1298   /* Now, work our way backwards emitting the constant.  */
1299
1300   /* Emit the value that remains -- it will be non-zero.  */
1301   operands[1] = GEN_INT (value);
1302   output_asm_insn (output_inline_const (SImode, operands), operands);
1303  
1304   while (i >= 0)
1305     {
1306       /* Shift anything we've already loaded.  */
1307       if (part[i].shift)
1308         {
1309           operands[2] = GEN_INT (part[i].shift);
1310           output_asm_insn ("lsli       %0,%2", operands);
1311           value <<= part[i].shift;
1312         }
1313       
1314       /* Add anything we need into the low 5 bits.  */
1315       if (part[i].low != 0)
1316         {
1317           operands[2] = GEN_INT (part[i].low);
1318           output_asm_insn ("addi      %0,%2", operands);
1319           value += part[i].low;
1320         }
1321       
1322       i--;
1323     }
1324   
1325   if (value != ovalue)          /* sanity */
1326     abort ();
1327  
1328   /* We've output all the instructions.  */
1329   return "";
1330 }
1331
1332 /* Return a sequence of instructions to perform DI or DF move.
1333    Since the MCORE cannot move a DI or DF in one instruction, we have
1334    to take care when we see overlapping source and dest registers.  */
1335
1336 const char *
1337 mcore_output_movedouble (operands, mode)
1338      rtx operands[];
1339      enum machine_mode mode ATTRIBUTE_UNUSED;
1340 {
1341   rtx dst = operands[0];
1342   rtx src = operands[1];
1343
1344   if (GET_CODE (dst) == REG)
1345     {
1346       if (GET_CODE (src) == REG)
1347         {
1348           int dstreg = REGNO (dst);
1349           int srcreg = REGNO (src);
1350           
1351           /* Ensure the second source not overwritten.  */
1352           if (srcreg + 1 == dstreg)
1353             return "mov %R0,%R1\n\tmov  %0,%1";
1354           else
1355             return "mov %0,%1\n\tmov    %R0,%R1";
1356         }
1357       else if (GET_CODE (src) == MEM)
1358         {
1359           rtx memexp = memexp = XEXP (src, 0);
1360           int dstreg = REGNO (dst);
1361           int basereg = -1;
1362           
1363           if (GET_CODE (memexp) == LABEL_REF)
1364             return "lrw\t%0,[%1]\n\tlrw\t%R0,[%R1]";
1365           else if (GET_CODE (memexp) == REG) 
1366             basereg = REGNO (memexp);
1367           else if (GET_CODE (memexp) == PLUS)
1368             {
1369               if (GET_CODE (XEXP (memexp, 0)) == REG)
1370                 basereg = REGNO (XEXP (memexp, 0));
1371               else if (GET_CODE (XEXP (memexp, 1)) == REG)
1372                 basereg = REGNO (XEXP (memexp, 1));
1373               else
1374                 abort ();
1375             }
1376           else
1377             abort ();
1378
1379           /* ??? length attribute is wrong here.  */
1380           if (dstreg == basereg)
1381             {
1382               /* Just load them in reverse order.  */
1383               return "ldw\t%R0,%R1\n\tldw\t%0,%1";
1384               
1385               /* XXX: alternative: move basereg to basereg+1
1386                  and then fall through.  */
1387             }
1388           else
1389             return "ldw\t%0,%1\n\tldw\t%R0,%R1";
1390         }
1391       else if (GET_CODE (src) == CONST_INT)
1392         {
1393           if (TARGET_LITTLE_END)
1394             {
1395               if (CONST_OK_FOR_I (INTVAL (src)))
1396                 output_asm_insn ("movi  %0,%1", operands);
1397               else if (CONST_OK_FOR_M (INTVAL (src)))
1398                 output_asm_insn ("bgeni %0,%P1", operands);
1399               else if (INTVAL (src) == -1)
1400                 output_asm_insn ("bmaski        %0,32", operands);
1401               else if (CONST_OK_FOR_N (INTVAL (src)))
1402                 output_asm_insn ("bmaski        %0,%N1", operands);
1403               else
1404                 abort ();
1405
1406               if (INTVAL (src) < 0)
1407                 return "bmaski  %R0,32";
1408               else
1409                 return "movi    %R0,0";
1410             }
1411           else
1412             {
1413               if (CONST_OK_FOR_I (INTVAL (src)))
1414                 output_asm_insn ("movi  %R0,%1", operands);
1415               else if (CONST_OK_FOR_M (INTVAL (src)))
1416                 output_asm_insn ("bgeni %R0,%P1", operands);
1417               else if (INTVAL (src) == -1)
1418                 output_asm_insn ("bmaski        %R0,32", operands);
1419               else if (CONST_OK_FOR_N (INTVAL (src)))
1420                 output_asm_insn ("bmaski        %R0,%N1", operands);
1421               else
1422                 abort ();
1423               
1424               if (INTVAL (src) < 0)
1425                 return "bmaski  %0,32";
1426               else
1427                 return "movi    %0,0";
1428             }
1429         }
1430       else
1431         abort ();
1432     }
1433   else if (GET_CODE (dst) == MEM && GET_CODE (src) == REG)
1434     return "stw\t%1,%0\n\tstw\t%R1,%R0";
1435   else
1436     abort ();
1437 }
1438
1439 /* Predicates used by the templates.  */
1440
1441 /* Non zero if OP can be source of a simple move operation.  */
1442
1443 int
1444 mcore_general_movsrc_operand (op, mode)
1445      rtx op;
1446      enum machine_mode mode;
1447 {
1448   /* Any (MEM LABEL_REF) is OK.  That is a pc-relative load.  */
1449   if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == LABEL_REF)
1450     return 1;
1451
1452   return general_operand (op, mode);
1453 }
1454
1455 /* Non zero if OP can be destination of a simple move operation. */
1456
1457 int
1458 mcore_general_movdst_operand (op, mode)
1459      rtx op;
1460      enum machine_mode mode;
1461 {
1462   if (GET_CODE (op) == REG && REGNO (op) == CC_REG)
1463     return 0;
1464   
1465   return general_operand (op, mode);
1466 }
1467
1468 /* Nonzero if OP is a normal arithmetic register.  */
1469
1470 int
1471 mcore_arith_reg_operand (op, mode)
1472      rtx op;
1473      enum machine_mode mode;
1474 {
1475   if (! register_operand (op, mode))
1476     return 0;
1477
1478   if (GET_CODE (op) == SUBREG)
1479     op = SUBREG_REG (op);
1480
1481   if (GET_CODE (op) == REG)
1482     return REGNO (op) != CC_REG;
1483
1484   return 1;
1485 }
1486
1487 /* Non zero if OP should be recognized during reload for an ixh/ixw
1488    operand.  See the ixh/ixw patterns.  */
1489
1490 int
1491 mcore_reload_operand (op, mode)
1492      rtx op;
1493      enum machine_mode mode;
1494 {
1495   if (mcore_arith_reg_operand (op, mode))
1496     return 1;
1497
1498   if (! reload_in_progress)
1499     return 0;
1500
1501   return GET_CODE (op) == MEM;
1502 }
1503
1504 /* Nonzero if OP is a valid source operand for an arithmetic insn.  */
1505
1506 int
1507 mcore_arith_J_operand (op, mode)
1508      rtx op;
1509      enum machine_mode mode;
1510 {
1511   if (register_operand (op, mode))
1512     return 1;
1513
1514   if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_J (INTVAL (op)))
1515     return 1;
1516   
1517   return 0;
1518 }
1519
1520 /* Nonzero if OP is a valid source operand for an arithmetic insn.  */
1521
1522 int
1523 mcore_arith_K_operand (op, mode)
1524      rtx op;
1525      enum machine_mode mode;
1526 {
1527   if (register_operand (op, mode))
1528     return 1;
1529
1530   if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op)))
1531     return 1;
1532
1533   return 0;
1534 }
1535
1536 /* Nonzero if OP is a valid source operand for a shift or rotate insn.  */
1537
1538 int
1539 mcore_arith_K_operand_not_0 (op, mode)
1540      rtx op;
1541      enum machine_mode mode;
1542 {
1543   if (register_operand (op, mode))
1544     return 1;
1545
1546   if (   GET_CODE (op) == CONST_INT
1547       && CONST_OK_FOR_K (INTVAL (op))
1548       && INTVAL (op) != 0)
1549     return 1;
1550
1551   return 0;
1552 }
1553
1554 int
1555 mcore_arith_K_S_operand (op, mode)
1556      rtx op;
1557      enum machine_mode mode;
1558 {
1559   if (register_operand (op, mode))
1560     return 1;
1561
1562   if (GET_CODE (op) == CONST_INT)
1563     {
1564       if (CONST_OK_FOR_K (INTVAL (op)) || CONST_OK_FOR_M (~INTVAL (op)))
1565         return 1;
1566     }
1567   
1568   return 0;
1569 }
1570
1571 int
1572 mcore_arith_S_operand (op)
1573      rtx op;
1574 {
1575   if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_M (~INTVAL (op)))
1576     return 1;
1577   
1578   return 0;
1579 }
1580
1581 int
1582 mcore_arith_M_operand (op, mode)
1583      rtx op;
1584      enum machine_mode mode;
1585 {
1586   if (register_operand (op, mode))
1587     return 1;
1588
1589   if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_M (INTVAL (op)))
1590     return 1;
1591
1592   return 0;
1593 }
1594
1595 /* Nonzero if OP is a valid source operand for loading.  */
1596
1597 int
1598 mcore_arith_imm_operand (op, mode)
1599      rtx op;
1600      enum machine_mode mode;
1601 {
1602   if (register_operand (op, mode))
1603     return 1;
1604
1605   if (GET_CODE (op) == CONST_INT && const_ok_for_mcore (INTVAL (op)))
1606     return 1;
1607
1608   return 0;
1609 }
1610
1611 int
1612 mcore_arith_any_imm_operand (op, mode)
1613      rtx op;
1614      enum machine_mode mode;
1615 {
1616   if (register_operand (op, mode))
1617     return 1;
1618
1619   if (GET_CODE (op) == CONST_INT)
1620     return 1;
1621
1622   return 0;
1623 }
1624
1625 /* Nonzero if OP is a valid source operand for a cmov with two consts +/- 1.  */
1626
1627 int
1628 mcore_arith_O_operand (op, mode)
1629      rtx op;
1630      enum machine_mode mode;
1631 {
1632   if (register_operand (op, mode))
1633     return 1;
1634
1635   if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_O (INTVAL (op)))
1636     return 1;
1637   
1638   return 0;
1639 }
1640
1641 /* Nonzero if OP is a valid source operand for a btsti.  */
1642
1643 int
1644 mcore_literal_K_operand (op, mode)
1645      rtx op;
1646      enum machine_mode mode ATTRIBUTE_UNUSED;
1647 {
1648   if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op)))
1649     return 1;
1650
1651   return 0;
1652 }
1653
1654 /* Nonzero if OP is a valid source operand for an add/sub insn.  */
1655
1656 int
1657 mcore_addsub_operand (op, mode)
1658      rtx op;
1659      enum machine_mode mode;
1660 {
1661   if (register_operand (op, mode))
1662     return 1;
1663
1664   if (GET_CODE (op) == CONST_INT)
1665     {
1666       return 1;
1667       
1668       /* The following is removed because it precludes large constants from being
1669          returned as valid source operands for and add/sub insn.  While large 
1670          constants may not directly be used in an add/sub, they may if first loaded
1671          into a register.  Thus, this predicate should indicate that they are valid,
1672          and the constraint in mcore.md should control whether an additional load to
1673          register is needed. (see mcore.md, addsi). -- DAC 4/2/1998  */
1674       /*
1675         if (CONST_OK_FOR_J(INTVAL(op)) || CONST_OK_FOR_L(INTVAL(op)))
1676           return 1;
1677       */
1678     }
1679   
1680   return 0;
1681 }
1682
1683 /* Nonzero if OP is a valid source operand for a compare operation.  */
1684
1685 int
1686 mcore_compare_operand (op, mode)
1687      rtx op;
1688      enum machine_mode mode;
1689 {
1690   if (register_operand (op, mode))
1691     return 1;
1692
1693   if (GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
1694     return 1;
1695   
1696   return 0;
1697 }
1698
1699 /* Expand insert bit field.  BRC  */
1700
1701 int
1702 mcore_expand_insv (operands)
1703      rtx operands[];
1704 {
1705   int width = INTVAL (operands[1]);
1706   int posn = INTVAL (operands[2]);
1707   int mask;
1708   rtx mreg, sreg, ereg;
1709
1710   /* To get width 1 insv, the test in store_bit_field() (expmed.c, line 191)
1711      for width==1 must be removed.  Look around line 368.  This is something
1712      we really want the md part to do.  */
1713   if (width == 1 && GET_CODE (operands[3]) == CONST_INT)
1714     {
1715       /* Do directly with bseti or bclri.  */
1716       /* RBE: 2/97 consider only low bit of constant.  */
1717       if ((INTVAL(operands[3])&1) == 0)
1718         {
1719           mask = ~(1 << posn);
1720           emit_insn (gen_rtx (SET, SImode, operands[0],
1721                               gen_rtx (AND, SImode, operands[0], GEN_INT (mask))));
1722         }
1723       else
1724         {
1725           mask = 1 << posn;
1726           emit_insn (gen_rtx (SET, SImode, operands[0],
1727                             gen_rtx (IOR, SImode, operands[0], GEN_INT (mask))));
1728         }
1729       
1730       return 1;
1731     }
1732
1733   /* Look at some bitfield placements that we aren't interested
1734      in handling ourselves, unless specifically directed to do so.  */
1735   if (! TARGET_W_FIELD)
1736     return 0;           /* Generally, give up about now.  */
1737
1738   if (width == 8 && posn % 8 == 0)
1739     /* Byte sized and aligned; let caller break it up.  */
1740     return 0;
1741   
1742   if (width == 16 && posn % 16 == 0)
1743     /* Short sized and aligned; let caller break it up.  */
1744     return 0;
1745
1746   /* The general case - we can do this a little bit better than what the
1747      machine independent part tries.  This will get rid of all the subregs
1748      that mess up constant folding in combine when working with relaxed
1749      immediates.  */
1750
1751   /* If setting the entire field, do it directly.  */
1752   if (GET_CODE (operands[3]) == CONST_INT && 
1753       INTVAL (operands[3]) == ((1 << width) - 1))
1754     {
1755       mreg = force_reg (SImode, GEN_INT (INTVAL (operands[3]) << posn));
1756       emit_insn (gen_rtx (SET, SImode, operands[0],
1757                          gen_rtx (IOR, SImode, operands[0], mreg)));
1758       return 1;
1759     }
1760
1761   /* Generate the clear mask.  */
1762   mreg = force_reg (SImode, GEN_INT (~(((1 << width) - 1) << posn)));
1763
1764   /* Clear the field, to overlay it later with the source.  */
1765   emit_insn (gen_rtx (SET, SImode, operands[0], 
1766                       gen_rtx (AND, SImode, operands[0], mreg)));
1767
1768   /* If the source is constant 0, we've nothing to add back.  */
1769   if (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) == 0)
1770     return 1;
1771
1772   /* XXX: Should we worry about more games with constant values?
1773      We've covered the high profile: set/clear single-bit and many-bit
1774      fields. How often do we see "arbitrary bit pattern" constants?  */
1775   sreg = copy_to_mode_reg (SImode, operands[3]);
1776
1777   /* Extract src as same width as dst (needed for signed values).  We
1778      always have to do this since we widen everything to SImode.
1779      We don't have to mask if we're shifting this up against the
1780      MSB of the register (e.g., the shift will push out any hi-order
1781      bits.  */
1782   if (width + posn != (int) GET_MODE_SIZE (SImode))
1783     {
1784       ereg = force_reg (SImode, GEN_INT ((1 << width) - 1));      
1785       emit_insn (gen_rtx (SET, SImode, sreg,
1786                           gen_rtx (AND, SImode, sreg, ereg)));
1787     }
1788
1789   /* Insert source value in dest.  */
1790   if (posn != 0)
1791     emit_insn (gen_rtx (SET, SImode, sreg,
1792                         gen_rtx (ASHIFT, SImode, sreg, GEN_INT (posn))));
1793   
1794   emit_insn (gen_rtx (SET, SImode, operands[0],
1795                       gen_rtx (IOR, SImode, operands[0], sreg)));
1796
1797   return 1;
1798 }
1799
1800 /* Return 1 if OP is a load multiple operation.  It is known to be a
1801    PARALLEL and the first section will be tested.  */
1802 int
1803 mcore_load_multiple_operation (op, mode)
1804      rtx op;
1805      enum machine_mode mode ATTRIBUTE_UNUSED;
1806 {
1807   int count = XVECLEN (op, 0);
1808   int dest_regno;
1809   rtx src_addr;
1810   int i;
1811
1812   /* Perform a quick check so we don't blow up below.  */
1813   if (count <= 1
1814       || GET_CODE (XVECEXP (op, 0, 0)) != SET
1815       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
1816       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
1817     return 0;
1818
1819   dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
1820   src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
1821
1822   for (i = 1; i < count; i++)
1823     {
1824       rtx elt = XVECEXP (op, 0, i);
1825
1826       if (GET_CODE (elt) != SET
1827           || GET_CODE (SET_DEST (elt)) != REG
1828           || GET_MODE (SET_DEST (elt)) != SImode
1829           || REGNO (SET_DEST (elt))    != (unsigned) (dest_regno + i)
1830           || GET_CODE (SET_SRC (elt))  != MEM
1831           || GET_MODE (SET_SRC (elt))  != SImode
1832           || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
1833           || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
1834           || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
1835           || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
1836         return 0;
1837     }
1838
1839   return 1;
1840 }
1841
1842 /* Similar, but tests for store multiple.  */
1843
1844 int
1845 mcore_store_multiple_operation (op, mode)
1846      rtx op;
1847      enum machine_mode mode ATTRIBUTE_UNUSED;
1848 {
1849   int count = XVECLEN (op, 0);
1850   int src_regno;
1851   rtx dest_addr;
1852   int i;
1853
1854   /* Perform a quick check so we don't blow up below.  */
1855   if (count <= 1
1856       || GET_CODE (XVECEXP (op, 0, 0)) != SET
1857       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
1858       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
1859     return 0;
1860
1861   src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
1862   dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
1863
1864   for (i = 1; i < count; i++)
1865     {
1866       rtx elt = XVECEXP (op, 0, i);
1867
1868       if (GET_CODE (elt) != SET
1869           || GET_CODE (SET_SRC (elt)) != REG
1870           || GET_MODE (SET_SRC (elt)) != SImode
1871           || REGNO (SET_SRC (elt)) != (unsigned) (src_regno + i)
1872           || GET_CODE (SET_DEST (elt)) != MEM
1873           || GET_MODE (SET_DEST (elt)) != SImode
1874           || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
1875           || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
1876           || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
1877           || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
1878         return 0;
1879     }
1880
1881   return 1;
1882 }
1883 \f
1884 /* ??? Block move stuff stolen from m88k.  This code has not been
1885    verified for correctness.  */
1886
1887 /* Emit code to perform a block move.  Choose the best method.
1888
1889    OPERANDS[0] is the destination.
1890    OPERANDS[1] is the source.
1891    OPERANDS[2] is the size.
1892    OPERANDS[3] is the alignment safe to use.  */
1893
1894 /* Emit code to perform a block move with an offset sequence of ldw/st
1895    instructions (..., ldw 0, stw 1, ldw 1, stw 0, ...).  SIZE and ALIGN are
1896    known constants.  DEST and SRC are registers.  OFFSET is the known
1897    starting point for the output pattern.  */
1898
1899 static const enum machine_mode mode_from_align[] =
1900 {
1901   VOIDmode, QImode, HImode, VOIDmode, SImode,
1902   VOIDmode, VOIDmode, VOIDmode, DImode
1903 };
1904
1905 static void
1906 block_move_sequence (dest, dst_mem, src, src_mem, size, align, offset)
1907      rtx dest, dst_mem;
1908      rtx src, src_mem;
1909      int size;
1910      int align;
1911      int offset;
1912 {
1913   rtx temp[2];
1914   enum machine_mode mode[2];
1915   int amount[2];
1916   int active[2];
1917   int phase = 0;
1918   int next;
1919   int offset_ld = offset;
1920   int offset_st = offset;
1921
1922   active[0] = active[1] = FALSE;
1923
1924   /* Establish parameters for the first load and for the second load if
1925      it is known to be the same mode as the first.  */
1926   amount[0] = amount[1] = align;
1927
1928   mode[0] = mode_from_align[align];
1929
1930   temp[0] = gen_reg_rtx (mode[0]);
1931   
1932   if (size >= 2 * align)
1933     {
1934       mode[1] = mode[0];
1935       temp[1] = gen_reg_rtx (mode[1]);
1936     }
1937
1938   do
1939     {
1940       rtx srcp, dstp;
1941       
1942       next = phase;
1943       phase = !phase;
1944
1945       if (size > 0)
1946         {
1947           /* Change modes as the sequence tails off.  */
1948           if (size < amount[next])
1949             {
1950               amount[next] = (size >= 4 ? 4 : (size >= 2 ? 2 : 1));
1951               mode[next] = mode_from_align[amount[next]];
1952               temp[next] = gen_reg_rtx (mode[next]);
1953             }
1954           
1955           size -= amount[next];
1956           srcp = gen_rtx (MEM,
1957 #if 0
1958                           MEM_IN_STRUCT_P (src_mem) ? mode[next] : BLKmode,
1959 #else
1960                           mode[next],
1961 #endif
1962                           gen_rtx (PLUS, Pmode, src,
1963                                    gen_rtx (CONST_INT, SImode, offset_ld)));
1964           
1965           RTX_UNCHANGING_P (srcp) = RTX_UNCHANGING_P (src_mem);
1966           MEM_VOLATILE_P (srcp) = MEM_VOLATILE_P (src_mem);
1967           MEM_IN_STRUCT_P (srcp) = 1;
1968           emit_insn (gen_rtx (SET, VOIDmode, temp[next], srcp));
1969           offset_ld += amount[next];
1970           active[next] = TRUE;
1971         }
1972
1973       if (active[phase])
1974         {
1975           active[phase] = FALSE;
1976           
1977           dstp = gen_rtx (MEM,
1978 #if 0
1979                           MEM_IN_STRUCT_P (dst_mem) ? mode[phase] : BLKmode,
1980 #else
1981                           mode[phase],
1982 #endif
1983                           gen_rtx (PLUS, Pmode, dest,
1984                                    gen_rtx (CONST_INT, SImode, offset_st)));
1985           
1986           RTX_UNCHANGING_P (dstp) = RTX_UNCHANGING_P (dst_mem);
1987           MEM_VOLATILE_P (dstp) = MEM_VOLATILE_P (dst_mem);
1988           MEM_IN_STRUCT_P (dstp) = 1;
1989           emit_insn (gen_rtx (SET, VOIDmode, dstp, temp[phase]));
1990           offset_st += amount[phase];
1991         }
1992     }
1993   while (active[next]);
1994 }
1995
1996 void
1997 mcore_expand_block_move (dst_mem, src_mem, operands)
1998      rtx dst_mem;
1999      rtx src_mem;
2000      rtx * operands;
2001 {
2002   int align = INTVAL (operands[3]);
2003   int bytes;
2004
2005   if (GET_CODE (operands[2]) == CONST_INT)
2006     {
2007       bytes = INTVAL (operands[2]);
2008       
2009       if (bytes <= 0)
2010         return;
2011       if (align > 4)
2012         align = 4;
2013       
2014       /* RBE: bumped 1 and 2 byte align from 1 and 2 to 4 and 8 bytes before
2015          we give up and go to memcpy.  */
2016       if ((align == 4 && (bytes <= 4*4
2017                           || ((bytes & 01) == 0 && bytes <= 8*4)
2018                           || ((bytes & 03) == 0 && bytes <= 16*4)))
2019           || (align == 2 && bytes <= 4*2)
2020           || (align == 1 && bytes <= 4*1))
2021         {
2022           block_move_sequence (operands[0], dst_mem, operands[1], src_mem,
2023                                bytes, align, 0);
2024           return;
2025         }
2026     }
2027
2028   /* If we get here, just use the library routine.  */
2029   emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcpy"), 0, VOIDmode, 3,
2030                      operands[0], Pmode, operands[1], Pmode, operands[2],
2031                      SImode);
2032 }
2033 \f
2034
2035 /* Code to generate prologue and epilogue sequences.  */
2036 static int number_of_regs_before_varargs;
2037
2038 /* Set by SETUP_INCOMING_VARARGS to indicate to prolog that this is
2039    for a varargs function.  */
2040 static int current_function_anonymous_args;
2041
2042 #define STACK_BYTES (STACK_BOUNDARY/BITS_PER_UNIT)
2043 #define STORE_REACH (64)        /* Maximum displace of word store + 4.  */
2044 #define ADDI_REACH (32)         /* Maximum addi operand.  */
2045
2046 static void
2047 layout_mcore_frame (infp)
2048      struct mcore_frame * infp;
2049 {
2050   int n;
2051   unsigned int i;
2052   int nbytes;
2053   int regarg;
2054   int localregarg;
2055   int localreg;
2056   int outbounds;
2057   unsigned int growths;
2058   int step;
2059
2060   /* Might have to spill bytes to re-assemble a big argument that
2061      was passed partially in registers and partially on the stack.  */
2062   nbytes = current_function_pretend_args_size;
2063   
2064   /* Determine how much space for spilled anonymous args (e.g., stdarg).  */
2065   if (current_function_anonymous_args)
2066     nbytes += (NPARM_REGS - number_of_regs_before_varargs) * UNITS_PER_WORD;
2067   
2068   infp->arg_size = nbytes;
2069
2070   /* How much space to save non-volatile registers we stomp.  */
2071   infp->reg_mask = calc_live_regs (& n);
2072   infp->reg_size = n * 4;
2073
2074   /* And the rest of it... locals and space for overflowed outbounds. */
2075   infp->local_size = get_frame_size ();
2076   infp->outbound_size = current_function_outgoing_args_size;
2077
2078   /* Make sure we have a whole number of words for the locals.  */
2079   if (infp->local_size % STACK_BYTES)
2080     infp->local_size = (infp->local_size + STACK_BYTES - 1) & ~ (STACK_BYTES -1);
2081   
2082   /* Only thing we know we have to pad is the outbound space, since
2083      we've aligned our locals assuming that base of locals is aligned.  */
2084   infp->pad_local = 0;
2085   infp->pad_reg = 0;
2086   infp->pad_outbound = 0;
2087   if (infp->outbound_size % STACK_BYTES)
2088     infp->pad_outbound = STACK_BYTES - (infp->outbound_size % STACK_BYTES);
2089
2090   /* Now we see how we want to stage the prologue so that it does
2091      the most appropriate stack growth and register saves to either:
2092      (1) run fast,
2093      (2) reduce instruction space, or
2094      (3) reduce stack space.  */
2095   for (i = 0; i < ARRAY_SIZE (infp->growth); i++)
2096     infp->growth[i] = 0;
2097
2098   regarg      = infp->reg_size + infp->arg_size;
2099   localregarg = infp->local_size + regarg;
2100   localreg    = infp->local_size + infp->reg_size;
2101   outbounds   = infp->outbound_size + infp->pad_outbound;
2102   growths     = 0;
2103
2104   /* XXX: Consider one where we consider localregarg + outbound too! */
2105
2106   /* Frame of <= 32 bytes and using stm would get <= 2 registers.
2107      use stw's with offsets and buy the frame in one shot.  */
2108   if (localregarg <= ADDI_REACH
2109       && (infp->reg_size <= 8 || (infp->reg_mask & 0xc000) != 0xc000))
2110     {
2111       /* Make sure we'll be aligned.  */
2112       if (localregarg % STACK_BYTES)
2113         infp->pad_reg = STACK_BYTES - (localregarg % STACK_BYTES);
2114
2115       step = localregarg + infp->pad_reg;
2116       infp->reg_offset = infp->local_size;
2117       
2118       if (outbounds + step <= ADDI_REACH && !frame_pointer_needed)
2119         {
2120           step += outbounds;
2121           infp->reg_offset += outbounds;
2122           outbounds = 0;
2123         }
2124       
2125       infp->arg_offset = step - 4;
2126       infp->growth[growths++] = step;
2127       infp->reg_growth = growths;
2128       infp->local_growth = growths;
2129       
2130       /* If we haven't already folded it in.  */
2131       if (outbounds)
2132         infp->growth[growths++] = outbounds;
2133       
2134       goto finish;
2135     }
2136
2137   /* Frame can't be done with a single subi, but can be done with 2
2138      insns.  If the 'stm' is getting <= 2 registers, we use stw's and
2139      shift some of the stack purchase into the first subi, so both are
2140      single instructions.  */
2141   if (localregarg <= STORE_REACH
2142       && (infp->local_size > ADDI_REACH)
2143       && (infp->reg_size <= 8 || (infp->reg_mask & 0xc000) != 0xc000))
2144     {
2145       int all;
2146
2147       /* Make sure we'll be aligned; use either pad_reg or pad_local.  */
2148       if (localregarg % STACK_BYTES)
2149         infp->pad_reg = STACK_BYTES - (localregarg % STACK_BYTES);
2150
2151       all = localregarg + infp->pad_reg + infp->pad_local;
2152       step = ADDI_REACH;        /* As much up front as we can.  */
2153       if (step > all)
2154         step = all;
2155       
2156       /* XXX: Consider whether step will still be aligned; we believe so.  */
2157       infp->arg_offset = step - 4;
2158       infp->growth[growths++] = step;
2159       infp->reg_growth = growths;
2160       infp->reg_offset = step - infp->pad_reg - infp->reg_size;
2161       all -= step;
2162
2163       /* Can we fold in any space required for outbounds?  */
2164       if (outbounds + all <= ADDI_REACH && !frame_pointer_needed)
2165         {
2166           all += outbounds;
2167           outbounds = 0;
2168         }
2169
2170       /* Get the rest of the locals in place.  */
2171       step = all;
2172       infp->growth[growths++] = step;
2173       infp->local_growth = growths;
2174       all -= step;
2175
2176       assert (all == 0);
2177
2178       /* Finish off if we need to do so.  */
2179       if (outbounds)
2180         infp->growth[growths++] = outbounds;
2181       
2182       goto finish;
2183     }
2184
2185   /* Registers + args is nicely aligned, so we'll buy that in one shot.
2186      Then we buy the rest of the frame in 1 or 2 steps depending on
2187      whether we need a frame pointer.  */
2188   if ((regarg % STACK_BYTES) == 0)
2189     {
2190       infp->growth[growths++] = regarg;
2191       infp->reg_growth = growths;
2192       infp->arg_offset = regarg - 4;
2193       infp->reg_offset = 0;
2194
2195       if (infp->local_size % STACK_BYTES)
2196         infp->pad_local = STACK_BYTES - (infp->local_size % STACK_BYTES);
2197       
2198       step = infp->local_size + infp->pad_local;
2199       
2200       if (!frame_pointer_needed)
2201         {
2202           step += outbounds;
2203           outbounds = 0;
2204         }
2205       
2206       infp->growth[growths++] = step;
2207       infp->local_growth = growths;
2208
2209       /* If there's any left to be done.  */
2210       if (outbounds)
2211         infp->growth[growths++] = outbounds;
2212       
2213       goto finish;
2214     }
2215
2216   /* XXX: optimizations that we'll want to play with....
2217      -- regarg is not aligned, but it's a small number of registers;
2218         use some of localsize so that regarg is aligned and then 
2219         save the registers.  */
2220
2221   /* Simple encoding; plods down the stack buying the pieces as it goes.
2222      -- does not optimize space consumption.
2223      -- does not attempt to optimize instruction counts.
2224      -- but it is safe for all alignments.  */
2225   if (regarg % STACK_BYTES != 0)
2226     infp->pad_reg = STACK_BYTES - (regarg % STACK_BYTES);
2227   
2228   infp->growth[growths++] = infp->arg_size + infp->reg_size + infp->pad_reg;
2229   infp->reg_growth = growths;
2230   infp->arg_offset = infp->growth[0] - 4;
2231   infp->reg_offset = 0;
2232   
2233   if (frame_pointer_needed)
2234     {
2235       if (infp->local_size % STACK_BYTES != 0)
2236         infp->pad_local = STACK_BYTES - (infp->local_size % STACK_BYTES);
2237       
2238       infp->growth[growths++] = infp->local_size + infp->pad_local;
2239       infp->local_growth = growths;
2240       
2241       infp->growth[growths++] = outbounds;
2242     }
2243   else
2244     {
2245       if ((infp->local_size + outbounds) % STACK_BYTES != 0)
2246         infp->pad_local = STACK_BYTES - ((infp->local_size + outbounds) % STACK_BYTES);
2247       
2248       infp->growth[growths++] = infp->local_size + infp->pad_local + outbounds;
2249       infp->local_growth = growths;
2250     }
2251
2252   /* Anything else that we've forgotten?, plus a few consistency checks.  */
2253  finish:
2254   assert (infp->reg_offset >= 0);
2255   assert (growths <= MAX_STACK_GROWS);
2256   
2257   for (i = 0; i < growths; i++)
2258     {
2259       if (infp->growth[i] % STACK_BYTES)
2260         {
2261           fprintf (stderr,"stack growth of %d is not %d aligned\n",
2262                    infp->growth[i], STACK_BYTES);
2263           abort ();
2264         }
2265     }
2266 }
2267
2268 /* Define the offset between two registers, one to be eliminated, and
2269    the other its replacement, at the start of a routine.  */
2270
2271 int
2272 mcore_initial_elimination_offset (from, to)
2273      int from;
2274      int to;
2275 {
2276   int above_frame;
2277   int below_frame;
2278   struct mcore_frame fi;
2279
2280   layout_mcore_frame (& fi);
2281
2282   /* fp to ap */
2283   above_frame = fi.local_size + fi.pad_local + fi.reg_size + fi.pad_reg;
2284   /* sp to fp */
2285   below_frame = fi.outbound_size + fi.pad_outbound;
2286
2287   if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
2288     return above_frame;
2289
2290   if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
2291     return above_frame + below_frame;
2292
2293   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
2294     return below_frame;
2295
2296   abort ();
2297
2298   return 0;
2299 }
2300
2301 /* Keep track of some information about varargs for the prolog.  */
2302
2303 void
2304 mcore_setup_incoming_varargs (args_so_far, mode, type, ptr_pretend_size)
2305      CUMULATIVE_ARGS args_so_far;
2306      enum machine_mode mode;
2307      tree type;
2308      int * ptr_pretend_size ATTRIBUTE_UNUSED;
2309 {
2310   current_function_anonymous_args = 1;
2311
2312   /* We need to know how many argument registers are used before
2313      the varargs start, so that we can push the remaining argument
2314      registers during the prologue.  */
2315   number_of_regs_before_varargs = args_so_far + mcore_num_arg_regs (mode, type);
2316   
2317   /* There is a bug somwehere in the arg handling code.
2318      Until I can find it this workaround always pushes the
2319      last named argument onto the stack.  */
2320   number_of_regs_before_varargs = args_so_far;
2321   
2322   /* The last named argument may be split between argument registers
2323      and the stack.  Allow for this here.  */
2324   if (number_of_regs_before_varargs > NPARM_REGS)
2325     number_of_regs_before_varargs = NPARM_REGS;
2326 }
2327
2328 void
2329 mcore_expand_prolog ()
2330 {
2331   struct mcore_frame fi;
2332   int space_allocated = 0;
2333   int growth = 0;
2334
2335   /* Find out what we're doing.  */
2336   layout_mcore_frame (&fi);
2337   
2338   space_allocated = fi.arg_size + fi.reg_size + fi.local_size +
2339     fi.outbound_size + fi.pad_outbound + fi.pad_local + fi.pad_reg;
2340
2341   if (TARGET_CG_DATA)
2342     {
2343       /* Emit a symbol for this routine's frame size.  */
2344       rtx x;
2345       int len;
2346
2347       x = DECL_RTL (current_function_decl);
2348       
2349       if (GET_CODE (x) != MEM)
2350         abort ();
2351       
2352       x = XEXP (x, 0);
2353       
2354       if (GET_CODE (x) != SYMBOL_REF)
2355         abort ();
2356       
2357       if (mcore_current_function_name)
2358         free (mcore_current_function_name);
2359       
2360       len = strlen (XSTR (x, 0)) + 1;
2361       mcore_current_function_name = (char *) xmalloc (len);
2362       
2363       memcpy (mcore_current_function_name, XSTR (x, 0), len);
2364       
2365       ASM_OUTPUT_CG_NODE (asm_out_file, mcore_current_function_name, space_allocated);
2366
2367       if (current_function_calls_alloca)
2368         ASM_OUTPUT_CG_EDGE (asm_out_file, mcore_current_function_name, "alloca", 1);
2369
2370       /* 970425: RBE:
2371          We're looking at how the 8byte alignment affects stack layout
2372          and where we had to pad things. This emits information we can
2373          extract which tells us about frame sizes and the like.  */
2374       fprintf (asm_out_file,
2375                "\t.equ\t__$frame$info$_%s_$_%d_%d_x%x_%d_%d_%d,0\n",
2376                mcore_current_function_name,
2377                fi.arg_size, fi.reg_size, fi.reg_mask,
2378                fi.local_size, fi.outbound_size,
2379                frame_pointer_needed);
2380     }
2381
2382   if (mcore_naked_function_p ())
2383     return;
2384   
2385   /* Handle stdarg+regsaves in one shot: can't be more than 64 bytes.  */
2386   output_stack_adjust (-1, fi.growth[growth++]);        /* grows it */
2387
2388   /* If we have a parameter passed partially in regs and partially in memory,
2389      the registers will have been stored to memory already in function.c.  So
2390      we only need to do something here for varargs functions.  */
2391   if (fi.arg_size != 0 && current_function_pretend_args_size == 0)
2392     {
2393       int offset;
2394       int rn = FIRST_PARM_REG + NPARM_REGS - 1;
2395       int remaining = fi.arg_size;
2396
2397       for (offset = fi.arg_offset; remaining >= 4; offset -= 4, rn--, remaining -= 4)
2398         {
2399           emit_insn (gen_movsi
2400                      (gen_rtx (MEM, SImode,
2401                                plus_constant (stack_pointer_rtx, offset)),
2402                       gen_rtx (REG, SImode, rn)));
2403         }
2404     }
2405
2406   /* Do we need another stack adjustment before we do the register saves?  */
2407   if (growth < fi.reg_growth)
2408     output_stack_adjust (-1, fi.growth[growth++]);              /* grows it */
2409
2410   if (fi.reg_size != 0)
2411     {
2412       int i;
2413       int offs = fi.reg_offset;
2414       
2415       for (i = 15; i >= 0; i--)
2416         {
2417           if (offs == 0 && i == 15 && ((fi.reg_mask & 0xc000) == 0xc000))
2418             {
2419               int first_reg = 15;
2420
2421               while (fi.reg_mask & (1 << first_reg))
2422                 first_reg--;
2423               first_reg++;
2424
2425               emit_insn (gen_store_multiple (gen_rtx (MEM, SImode, stack_pointer_rtx),
2426                                              gen_rtx (REG, SImode, first_reg),
2427                                              GEN_INT (16 - first_reg)));
2428
2429               i -= (15 - first_reg);
2430               offs += (16 - first_reg) * 4;
2431             }
2432           else if (fi.reg_mask & (1 << i))
2433             {
2434               emit_insn (gen_movsi
2435                          (gen_rtx (MEM, SImode,
2436                                    plus_constant (stack_pointer_rtx, offs)),
2437                           gen_rtx (REG, SImode, i)));
2438               offs += 4;
2439             }
2440         }
2441     }
2442
2443   /* Figure the locals + outbounds.  */
2444   if (frame_pointer_needed)
2445     {
2446       /* If we haven't already purchased to 'fp'.  */
2447       if (growth < fi.local_growth)
2448         output_stack_adjust (-1, fi.growth[growth++]);          /* grows it */
2449       
2450       emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
2451
2452       /* ... and then go any remaining distance for outbounds, etc.  */
2453       if (fi.growth[growth])
2454         output_stack_adjust (-1, fi.growth[growth++]);
2455     }
2456   else
2457     {
2458       if (growth < fi.local_growth)
2459         output_stack_adjust (-1, fi.growth[growth++]);          /* grows it */
2460       if (fi.growth[growth])
2461         output_stack_adjust (-1, fi.growth[growth++]);
2462     }
2463 }
2464
2465 void
2466 mcore_expand_epilog ()
2467 {
2468   struct mcore_frame fi;
2469   int i;
2470   int offs;
2471   int growth = MAX_STACK_GROWS - 1 ;
2472
2473     
2474   /* Find out what we're doing.  */
2475   layout_mcore_frame(&fi);
2476
2477   if (mcore_naked_function_p ())
2478     return;
2479
2480   /* If we had a frame pointer, restore the sp from that.  */
2481   if (frame_pointer_needed)
2482     {
2483       emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx));
2484       growth = fi.local_growth - 1;
2485     }
2486   else
2487     {
2488       /* XXX: while loop should accumulate and do a single sell.  */
2489       while (growth >= fi.local_growth)
2490         {
2491           if (fi.growth[growth] != 0)
2492             output_stack_adjust (1, fi.growth[growth]);
2493           growth--;
2494         }
2495     }
2496
2497   /* Make sure we've shrunk stack back to the point where the registers
2498      were laid down. This is typically 0/1 iterations.  Then pull the
2499      register save information back off the stack.  */
2500   while (growth >= fi.reg_growth)
2501     output_stack_adjust ( 1, fi.growth[growth--]);
2502   
2503   offs = fi.reg_offset;
2504   
2505   for (i = 15; i >= 0; i--)
2506     {
2507       if (offs == 0 && i == 15 && ((fi.reg_mask & 0xc000) == 0xc000))
2508         {
2509           int first_reg;
2510
2511           /* Find the starting register.  */
2512           first_reg = 15;
2513           
2514           while (fi.reg_mask & (1 << first_reg))
2515             first_reg--;
2516           
2517           first_reg++;
2518
2519           emit_insn (gen_load_multiple (gen_rtx (REG, SImode, first_reg),
2520                                         gen_rtx (MEM, SImode, stack_pointer_rtx),
2521                                         GEN_INT (16 - first_reg)));
2522
2523           i -= (15 - first_reg);
2524           offs += (16 - first_reg) * 4;
2525         }
2526       else if (fi.reg_mask & (1 << i))
2527         {
2528           emit_insn (gen_movsi
2529                      (gen_rtx (REG, SImode, i),
2530                       gen_rtx (MEM, SImode,
2531                                plus_constant (stack_pointer_rtx, offs))));
2532           offs += 4;
2533         }
2534     }
2535
2536   /* Give back anything else.  */
2537   /* XXX: Should accumuate total and then give it back.  */
2538   while (growth >= 0)
2539     output_stack_adjust ( 1, fi.growth[growth--]);
2540 }
2541 \f
2542 /* This code is borrowed from the SH port.  */
2543
2544 /* The MCORE cannot load a large constant into a register, constants have to
2545    come from a pc relative load.  The reference of a pc relative load
2546    instruction must be less than 1k infront of the instruction.  This
2547    means that we often have to dump a constant inside a function, and
2548    generate code to branch around it.
2549
2550    It is important to minimize this, since the branches will slow things
2551    down and make things bigger.
2552
2553    Worst case code looks like:
2554
2555    lrw   L1,r0
2556    br    L2
2557    align
2558    L1:   .long value
2559    L2:
2560    ..
2561
2562    lrw   L3,r0
2563    br    L4
2564    align
2565    L3:   .long value
2566    L4:
2567    ..
2568
2569    We fix this by performing a scan before scheduling, which notices which
2570    instructions need to have their operands fetched from the constant table
2571    and builds the table.
2572
2573    The algorithm is:
2574
2575    scan, find an instruction which needs a pcrel move.  Look forward, find the
2576    last barrier which is within MAX_COUNT bytes of the requirement.
2577    If there isn't one, make one.  Process all the instructions between
2578    the find and the barrier.
2579
2580    In the above example, we can tell that L3 is within 1k of L1, so
2581    the first move can be shrunk from the 2 insn+constant sequence into
2582    just 1 insn, and the constant moved to L3 to make:
2583
2584    lrw          L1,r0
2585    ..
2586    lrw          L3,r0
2587    bra          L4
2588    align
2589    L3:.long value
2590    L4:.long value
2591
2592    Then the second move becomes the target for the shortening process.  */
2593
2594 typedef struct
2595 {
2596   rtx value;                    /* Value in table.  */
2597   rtx label;                    /* Label of value.  */
2598 } pool_node;
2599
2600 /* The maximum number of constants that can fit into one pool, since
2601    the pc relative range is 0...1020 bytes and constants are at least 4
2602    bytes long.  We subtact 4 from the range to allow for the case where
2603    we need to add a branch/align before the constant pool.  */
2604
2605 #define MAX_COUNT 1016
2606 #define MAX_POOL_SIZE (MAX_COUNT/4)
2607 static pool_node pool_vector[MAX_POOL_SIZE];
2608 static int pool_size;
2609
2610 /* Dump out any constants accumulated in the final pass.  These
2611    will only be labels.  */
2612
2613 const char *
2614 mcore_output_jump_label_table ()
2615 {
2616   int i;
2617
2618   if (pool_size)
2619     {
2620       fprintf (asm_out_file, "\t.align 2\n");
2621       
2622       for (i = 0; i < pool_size; i++)
2623         {
2624           pool_node * p = pool_vector + i;
2625
2626           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (p->label));
2627           
2628           output_asm_insn (".long       %0", &p->value);
2629         }
2630       
2631       pool_size = 0;
2632     }
2633
2634   return "";
2635 }
2636
2637 /* Check whether insn is a candidate for a conditional.  */
2638
2639 static cond_type
2640 is_cond_candidate (insn)
2641      rtx insn;
2642 {
2643   /* The only things we conditionalize are those that can be directly
2644      changed into a conditional.  Only bother with SImode items.  If 
2645      we wanted to be a little more aggressive, we could also do other
2646      modes such as DImode with reg-reg move or load 0.  */
2647   if (GET_CODE (insn) == INSN)
2648     {
2649       rtx pat = PATTERN (insn);
2650       rtx src, dst;
2651
2652       if (GET_CODE (pat) != SET)
2653         return COND_NO;
2654
2655       dst = XEXP (pat, 0);
2656
2657       if ((GET_CODE (dst) != REG &&
2658            GET_CODE (dst) != SUBREG) ||
2659           GET_MODE (dst) != SImode)
2660         return COND_NO;
2661   
2662       src = XEXP (pat, 1);
2663
2664       if ((GET_CODE (src) == REG ||
2665            (GET_CODE (src) == SUBREG &&
2666             GET_CODE (SUBREG_REG (src)) == REG)) &&
2667           GET_MODE (src) == SImode)
2668         return COND_MOV_INSN;
2669       else if (GET_CODE (src) == CONST_INT && 
2670                INTVAL (src) == 0)
2671         return COND_CLR_INSN;
2672       else if (GET_CODE (src) == PLUS &&
2673                (GET_CODE (XEXP (src, 0)) == REG ||
2674                 (GET_CODE (XEXP (src, 0)) == SUBREG &&
2675                  GET_CODE (SUBREG_REG (XEXP (src, 0))) == REG)) &&
2676                GET_MODE (XEXP (src, 0)) == SImode &&
2677                GET_CODE (XEXP (src, 1)) == CONST_INT &&
2678                INTVAL (XEXP (src, 1)) == 1)
2679         return COND_INC_INSN;
2680       else if (((GET_CODE (src) == MINUS &&
2681                  GET_CODE (XEXP (src, 1)) == CONST_INT &&
2682                  INTVAL( XEXP (src, 1)) == 1) ||
2683                 (GET_CODE (src) == PLUS &&
2684                  GET_CODE (XEXP (src, 1)) == CONST_INT &&
2685                  INTVAL (XEXP (src, 1)) == -1)) &&
2686                (GET_CODE (XEXP (src, 0)) == REG ||
2687                 (GET_CODE (XEXP (src, 0)) == SUBREG &&
2688                  GET_CODE (SUBREG_REG (XEXP (src, 0))) == REG)) &&
2689                GET_MODE (XEXP (src, 0)) == SImode)
2690         return COND_DEC_INSN;
2691
2692       /* some insns that we don't bother with:
2693          (set (rx:DI) (ry:DI))
2694          (set (rx:DI) (const_int 0))
2695       */            
2696
2697     }
2698   else if (GET_CODE (insn) == JUMP_INSN &&
2699            GET_CODE (PATTERN (insn)) == SET &&
2700            GET_CODE (XEXP (PATTERN (insn), 1)) == LABEL_REF)
2701     return COND_BRANCH_INSN;
2702
2703   return COND_NO;
2704 }
2705
2706 /* Emit a conditional version of insn and replace the old insn with the
2707    new one.  Return the new insn if emitted.  */
2708
2709 static rtx
2710 emit_new_cond_insn (insn, cond)
2711      rtx insn;
2712      int cond;
2713 {
2714   rtx c_insn = 0;
2715   rtx pat, dst, src;
2716   cond_type num;
2717
2718   if ((num = is_cond_candidate (insn)) == COND_NO)
2719     return NULL;
2720
2721   pat = PATTERN (insn);
2722
2723   if (GET_CODE (insn) == INSN)
2724     {
2725       dst = SET_DEST (pat);
2726       src = SET_SRC (pat);
2727     }
2728   else
2729     {
2730       dst = JUMP_LABEL (insn);
2731       src = NULL_RTX;
2732     }
2733
2734   switch (num)
2735     {
2736     case COND_MOV_INSN: 
2737     case COND_CLR_INSN:
2738       if (cond)
2739         c_insn = gen_movt0 (dst, src, dst);
2740       else
2741         c_insn = gen_movt0 (dst, dst, src);
2742       break;
2743
2744     case COND_INC_INSN:
2745       if (cond)
2746         c_insn = gen_incscc (dst, dst);
2747       else
2748         c_insn = gen_incscc_false (dst, dst);
2749       break;
2750   
2751     case COND_DEC_INSN:
2752       if (cond)
2753         c_insn = gen_decscc (dst, dst);
2754       else
2755         c_insn = gen_decscc_false (dst, dst);
2756       break;
2757
2758     case COND_BRANCH_INSN:
2759       if (cond)
2760         c_insn = gen_branch_true (dst);
2761       else
2762         c_insn = gen_branch_false (dst);
2763       break;
2764
2765     default:
2766       return NULL;
2767     }
2768
2769   /* Only copy the notes if they exist.  */
2770   if (rtx_length [GET_CODE (c_insn)] >= 7 && rtx_length [GET_CODE (insn)] >= 7)
2771     {
2772       /* We really don't need to bother with the notes and links at this
2773          point, but go ahead and save the notes.  This will help is_dead()
2774          when applying peepholes (links don't matter since they are not
2775          used any more beyond this point for the mcore).  */
2776       REG_NOTES (c_insn) = REG_NOTES (insn);
2777     }
2778   
2779   if (num == COND_BRANCH_INSN)
2780     {
2781       /* For jumps, we need to be a little bit careful and emit the new jump
2782          before the old one and to update the use count for the target label.
2783          This way, the barrier following the old (uncond) jump will get
2784          deleted, but the label won't.  */
2785       c_insn = emit_jump_insn_before (c_insn, insn);
2786       
2787       ++ LABEL_NUSES (dst);
2788       
2789       JUMP_LABEL (c_insn) = dst;
2790     }
2791   else
2792     c_insn = emit_insn_after (c_insn, insn);
2793
2794   delete_insn (insn);
2795   
2796   return c_insn;
2797 }
2798
2799 /* Attempt to change a basic block into a series of conditional insns.  This
2800    works by taking the branch at the end of the 1st block and scanning for the 
2801    end of the 2nd block.  If all instructions in the 2nd block have cond.
2802    versions and the label at the start of block 3 is the same as the target
2803    from the branch at block 1, then conditionalize all insn in block 2 using
2804    the inverse condition of the branch at block 1.  (Note I'm bending the
2805    definition of basic block here.)
2806
2807    e.g., change:   
2808
2809                 bt      L2             <-- end of block 1 (delete)
2810                 mov     r7,r8          
2811                 addu    r7,1           
2812                 br      L3             <-- end of block 2
2813
2814         L2:     ...                    <-- start of block 3 (NUSES==1)
2815         L3:     ...
2816
2817    to:
2818
2819                 movf    r7,r8
2820                 incf    r7
2821                 bf      L3
2822
2823         L3:     ...
2824
2825    we can delete the L2 label if NUSES==1 and re-apply the optimization
2826    starting at the last instruction of block 2.  This may allow an entire
2827    if-then-else statement to be conditionalized.  BRC  */
2828 static rtx
2829 conditionalize_block (first)
2830      rtx first;
2831 {
2832   rtx insn;
2833   rtx br_pat;
2834   rtx end_blk_1_br = 0;
2835   rtx end_blk_2_insn = 0;
2836   rtx start_blk_3_lab = 0;
2837   int cond;
2838   int br_lab_num;
2839   int blk_size = 0;
2840
2841     
2842   /* Check that the first insn is a candidate conditional jump.  This is
2843      the one that we'll eliminate.  If not, advance to the next insn to
2844      try.  */
2845   if (GET_CODE (first) != JUMP_INSN ||
2846       GET_CODE (PATTERN (first)) != SET ||
2847       GET_CODE (XEXP (PATTERN (first), 1)) != IF_THEN_ELSE)
2848     return NEXT_INSN (first);
2849
2850   /* Extract some information we need.  */
2851   end_blk_1_br = first;
2852   br_pat = PATTERN (end_blk_1_br);
2853
2854   /* Complement the condition since we use the reverse cond. for the insns.  */
2855   cond = (GET_CODE (XEXP (XEXP (br_pat, 1), 0)) == EQ);
2856
2857   /* Determine what kind of branch we have.  */
2858   if (GET_CODE (XEXP (XEXP (br_pat, 1), 1)) == LABEL_REF)
2859     {
2860       /* A normal branch, so extract label out of first arm.  */
2861       br_lab_num = CODE_LABEL_NUMBER (XEXP (XEXP (XEXP (br_pat, 1), 1), 0));
2862     }
2863   else
2864     {
2865       /* An inverse branch, so extract the label out of the 2nd arm
2866          and complement the condition.  */
2867       cond = (cond == 0);
2868       br_lab_num = CODE_LABEL_NUMBER (XEXP (XEXP (XEXP (br_pat, 1), 2), 0));
2869     }
2870
2871   /* Scan forward for the start of block 2: it must start with a
2872      label and that label must be the same as the branch target
2873      label from block 1.  We don't care about whether block 2 actually
2874      ends with a branch or a label (an uncond. branch is 
2875      conditionalizable).  */
2876   for (insn = NEXT_INSN (first); insn; insn = NEXT_INSN (insn))
2877     {
2878       enum rtx_code code;
2879       
2880       code = GET_CODE (insn);
2881
2882       /* Look for the label at the start of block 3. */
2883       if (code == CODE_LABEL && CODE_LABEL_NUMBER (insn) == br_lab_num)
2884         break;
2885
2886       /* Skip barriers, notes, and conditionalizable insns.  If the
2887          insn is not conditionalizable or makes this optimization fail,
2888          just return the next insn so we can start over from that point.  */
2889       if (code != BARRIER && code != NOTE && !is_cond_candidate (insn))
2890         return NEXT_INSN (insn);
2891      
2892       /* Remember the last real insn before the label (ie end of block 2).  */
2893       if (code == JUMP_INSN || code == INSN)
2894         {
2895           blk_size ++;
2896           end_blk_2_insn = insn;
2897         }
2898     }
2899
2900   if (!insn)
2901     return insn;
2902  
2903   /* It is possible for this optimization to slow performance if the blocks 
2904      are long.  This really depends upon whether the branch is likely taken 
2905      or not.  If the branch is taken, we slow performance in many cases.  But,
2906      if the branch is not taken, we always help performance (for a single 
2907      block, but for a double block (i.e. when the optimization is re-applied) 
2908      this is not true since the 'right thing' depends on the overall length of
2909      the collapsed block).  As a compromise, don't apply this optimization on 
2910      blocks larger than size 2 (unlikely for the mcore) when speed is important.
2911      the best threshold depends on the latencies of the instructions (i.e., 
2912      the branch penalty).  */
2913   if (optimize > 1 && blk_size > 2)
2914     return insn;
2915
2916   /* At this point, we've found the start of block 3 and we know that
2917      it is the destination of the branch from block 1.   Also, all
2918      instructions in the block 2 are conditionalizable.  So, apply the
2919      conditionalization and delete the branch.  */
2920   start_blk_3_lab = insn;   
2921    
2922   for (insn = NEXT_INSN (end_blk_1_br); insn != start_blk_3_lab; 
2923        insn = NEXT_INSN (insn))
2924     {
2925       rtx newinsn;
2926
2927       if (INSN_DELETED_P (insn))
2928         continue;
2929       
2930       /* Try to form a conditional variant of the instruction and emit it. */
2931       if ((newinsn = emit_new_cond_insn (insn, cond)))
2932         {
2933           if (end_blk_2_insn == insn)
2934             end_blk_2_insn = newinsn;
2935
2936           insn = newinsn;
2937         }
2938     }
2939
2940   /* Note whether we will delete the label starting blk 3 when the jump
2941      gets deleted.  If so, we want to re-apply this optimization at the 
2942      last real instruction right before the label.  */
2943   if (LABEL_NUSES (start_blk_3_lab) == 1)
2944     {
2945       start_blk_3_lab = 0;
2946     }
2947
2948   /* ??? we probably should redistribute the death notes for this insn, esp.
2949      the death of cc, but it doesn't really matter this late in the game.
2950      The peepholes all use is_dead() which will find the correct death
2951      regardless of whether there is a note.  */
2952   delete_insn (end_blk_1_br);
2953
2954   if (! start_blk_3_lab)
2955     return end_blk_2_insn;
2956   
2957   /* Return the insn right after the label at the start of block 3.  */
2958   return NEXT_INSN (start_blk_3_lab);
2959 }
2960
2961 /* Apply the conditionalization of blocks optimization.  This is the
2962    outer loop that traverses through the insns scanning for a branch
2963    that signifies an opportunity to apply the optimization.  Note that
2964    this optimization is applied late.  If we could apply it earlier,
2965    say before cse 2, it may expose more optimization opportunities.  
2966    but, the pay back probably isn't really worth the effort (we'd have 
2967    to update all reg/flow/notes/links/etc to make it work - and stick it
2968    in before cse 2).  */
2969
2970 static void
2971 conditionalize_optimization (first)
2972      rtx first;
2973 {
2974   rtx insn;
2975
2976   for (insn = first; insn; insn = conditionalize_block (insn))
2977     continue;
2978 }
2979
2980 static int saved_warn_return_type = -1;
2981 static int saved_warn_return_type_count = 0;
2982
2983 /* This function is called from toplev.c before reorg.  */
2984
2985 void
2986 mcore_dependent_reorg (first)
2987      rtx first;
2988 {
2989   /* Reset this variable.  */
2990   current_function_anonymous_args = 0;
2991   
2992   /* Restore the warn_return_type if it has been altered.  */
2993   if (saved_warn_return_type != -1)
2994     {
2995       /* Only restore the value if we have reached another function.
2996          The test of warn_return_type occurs in final_function () in
2997          c-decl.c a long time after the code for the function is generated,
2998          so we need a counter to tell us when we have finished parsing that
2999          function and can restore the flag.  */
3000       if (--saved_warn_return_type_count == 0)
3001         {
3002           warn_return_type = saved_warn_return_type;
3003           saved_warn_return_type = -1;
3004         }
3005     }
3006   
3007   if (optimize == 0)
3008     return;
3009   
3010   /* Conditionalize blocks where we can.  */
3011   conditionalize_optimization (first);
3012
3013   /* Literal pool generation is now pushed off until the assembler.  */
3014 }
3015
3016 \f
3017 /* Return the reg_class to use when reloading the rtx X into the class
3018    CLASS.  */
3019
3020 /* If the input is (PLUS REG CONSTANT) representing a stack slot address,
3021    then we want to restrict the class to LRW_REGS since that ensures that
3022    will be able to safely load the constant.
3023
3024    If the input is a constant that should be loaded with mvir1, then use
3025    ONLYR1_REGS.
3026
3027    ??? We don't handle the case where we have (PLUS REG CONSTANT) and
3028    the constant should be loaded with mvir1, because that can lead to cases
3029    where an instruction needs two ONLYR1_REGS reloads.  */
3030 enum reg_class
3031 mcore_reload_class (x, class)
3032      rtx x;
3033      enum reg_class class;
3034 {
3035   enum reg_class new_class;
3036
3037   if (class == GENERAL_REGS && CONSTANT_P (x)
3038       && (GET_CODE (x) != CONST_INT
3039           || (   ! CONST_OK_FOR_I (INTVAL (x))
3040               && ! CONST_OK_FOR_M (INTVAL (x))
3041               && ! CONST_OK_FOR_N (INTVAL (x)))))
3042     new_class = LRW_REGS;
3043   else
3044     new_class = class;
3045
3046   return new_class;
3047 }
3048
3049 /* Tell me if a pair of reg/subreg rtx's actually refer to the same
3050    register.  Note that the current version doesn't worry about whether
3051    they are the same mode or note (e.g., a QImode in r2 matches an HImode
3052    in r2 matches an SImode in r2. Might think in the future about whether
3053    we want to be able to say something about modes.  */
3054 int
3055 mcore_is_same_reg (x, y)
3056      rtx x;
3057      rtx y;
3058 {
3059   /* Strip any and all of the subreg wrappers. */
3060   while (GET_CODE (x) == SUBREG)
3061     x = SUBREG_REG (x);
3062   
3063   while (GET_CODE (y) == SUBREG)
3064     y = SUBREG_REG (y);
3065
3066   if (GET_CODE(x) == REG && GET_CODE(y) == REG && REGNO(x) == REGNO(y))
3067     return 1;
3068
3069   return 0;
3070 }
3071
3072 /* Called to register all of our global variables with the garbage
3073    collector.  */
3074 static void
3075 mcore_add_gc_roots ()
3076 {
3077   ggc_add_rtx_root (&arch_compare_op0, 1);
3078   ggc_add_rtx_root (&arch_compare_op1, 1);
3079 }
3080
3081 void
3082 mcore_override_options ()
3083 {
3084   if (mcore_stack_increment_string)
3085     {
3086       mcore_stack_increment = atoi (mcore_stack_increment_string);
3087       
3088       if (mcore_stack_increment < 0
3089           || (mcore_stack_increment == 0
3090               && (mcore_stack_increment_string[0] != '0'
3091                   || mcore_stack_increment_string[1] != 0)))
3092         error ("invalid option `-mstack-increment=%s'",
3093                mcore_stack_increment_string);   
3094     }
3095   
3096   /* Only the m340 supports little endian code.  */
3097   if (TARGET_LITTLE_END && ! TARGET_M340)
3098     target_flags |= M340_BIT;
3099
3100   mcore_add_gc_roots ();
3101 }
3102 \f
3103 int
3104 mcore_must_pass_on_stack (mode, type)
3105      enum machine_mode mode ATTRIBUTE_UNUSED;
3106      tree type;
3107 {
3108   if (type == NULL)
3109     return 0;
3110
3111   /* If the argugment can have its address taken, it must
3112      be placed on the stack.  */
3113   if (TREE_ADDRESSABLE (type))
3114     return 1;
3115
3116   return 0;
3117 }
3118
3119 /* Compute the number of word sized registers needed to 
3120    hold a function argument of mode MODE and type TYPE.  */
3121 int
3122 mcore_num_arg_regs (mode, type)
3123      enum machine_mode mode;
3124      tree type;
3125 {
3126   int size;
3127
3128   if (MUST_PASS_IN_STACK (mode, type))
3129     return 0;
3130
3131   if (type && mode == BLKmode)
3132     size = int_size_in_bytes (type);
3133   else
3134     size = GET_MODE_SIZE (mode);
3135
3136   return ROUND_ADVANCE (size);
3137 }
3138
3139 static rtx
3140 handle_structs_in_regs (mode, type, reg)
3141      enum machine_mode mode;
3142      tree type;
3143      int  reg;
3144 {
3145   int size;
3146
3147   /* The MCore ABI defines that a structure whoes size is not a whole multiple
3148      of bytes is passed packed into registers (or spilled onto the stack if
3149      not enough registers are available) with the last few bytes of the
3150      structure being packed, left-justified, into the last register/stack slot.
3151      GCC handles this correctly if the last word is in a stack slot, but we
3152      have to generate a special, PARALLEL RTX if the last word is in an
3153      argument register.  */
3154   if (type
3155       && TYPE_MODE (type) == BLKmode
3156       && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
3157       && (size = int_size_in_bytes (type)) > UNITS_PER_WORD
3158       && (size % UNITS_PER_WORD != 0)
3159       && (reg + mcore_num_arg_regs (mode, type) <= (FIRST_PARM_REG + NPARM_REGS)))
3160     {
3161       rtx    arg_regs [NPARM_REGS]; 
3162       int    nregs;
3163       rtx    result;
3164       rtvec  rtvec;
3165                      
3166       for (nregs = 0; size > 0; size -= UNITS_PER_WORD)
3167         {
3168           arg_regs [nregs] =
3169             gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, reg ++),
3170                                GEN_INT (nregs * UNITS_PER_WORD));
3171           nregs ++;
3172         }
3173
3174       /* We assume here that NPARM_REGS == 6.  The assert checks this.  */
3175       assert (ARRAY_SIZE (arg_regs) == 6);
3176       rtvec = gen_rtvec (nregs, arg_regs[0], arg_regs[1], arg_regs[2],
3177                           arg_regs[3], arg_regs[4], arg_regs[5]);
3178       
3179       result = gen_rtx_PARALLEL (mode, rtvec);
3180       return result;
3181     }
3182   
3183   return gen_rtx_REG (mode, reg);
3184 }
3185
3186 rtx
3187 mcore_function_value (valtype, func)
3188      tree valtype;
3189      tree func ATTRIBUTE_UNUSED;
3190 {
3191   enum machine_mode mode;
3192   int unsigned_p;
3193   
3194   mode = TYPE_MODE (valtype);
3195
3196   PROMOTE_MODE (mode, unsigned_p, NULL);
3197   
3198   return handle_structs_in_regs (mode, valtype, FIRST_RET_REG);
3199 }
3200
3201 /* Define where to put the arguments to a function.
3202    Value is zero to push the argument on the stack,
3203    or a hard register in which to store the argument.
3204
3205    MODE is the argument's machine mode.
3206    TYPE is the data type of the argument (as a tree).
3207     This is null for libcalls where that information may
3208     not be available.
3209    CUM is a variable of type CUMULATIVE_ARGS which gives info about
3210     the preceding args and about the function being called.
3211    NAMED is nonzero if this argument is a named parameter
3212     (otherwise it is an extra parameter matching an ellipsis).
3213
3214    On MCore the first args are normally in registers
3215    and the rest are pushed.  Any arg that starts within the first
3216    NPARM_REGS words is at least partially passed in a register unless
3217    its data type forbids.  */
3218 rtx
3219 mcore_function_arg (cum, mode, type, named)
3220      CUMULATIVE_ARGS   cum;
3221      enum machine_mode mode;
3222      tree              type;
3223      int               named;
3224 {
3225   int arg_reg;
3226   
3227   if (! named)
3228     return 0;
3229
3230   if (MUST_PASS_IN_STACK (mode, type))
3231     return 0;
3232
3233   arg_reg = ROUND_REG (cum, mode);
3234   
3235   if (arg_reg < NPARM_REGS)
3236     return handle_structs_in_regs (mode, type, FIRST_PARM_REG + arg_reg);
3237
3238   return 0;
3239 }
3240
3241 /* Implements the FUNCTION_ARG_PARTIAL_NREGS macro.
3242    Returns the number of argument registers required to hold *part* of
3243    a parameter of machine mode MODE and type TYPE (which may be NULL if
3244    the type is not known).  If the argument fits entirly in the argument
3245    registers, or entirely on the stack, then 0 is returned.  CUM is the
3246    number of argument registers already used by earlier parameters to
3247    the function.  */
3248 int
3249 mcore_function_arg_partial_nregs (cum, mode, type, named)
3250      CUMULATIVE_ARGS   cum;
3251      enum machine_mode mode;
3252      tree              type;
3253      int               named;
3254 {
3255   int reg = ROUND_REG (cum, mode);
3256
3257   if (named == 0)
3258     return 0;
3259
3260   if (MUST_PASS_IN_STACK (mode, type))
3261     return 0;
3262       
3263   /* REG is not the *hardware* register number of the register that holds
3264      the argument, it is the *argument* register number.  So for example,
3265      the first argument to a function goes in argument register 0, which
3266      translates (for the MCore) into hardware register 2.  The second
3267      argument goes into argument register 1, which translates into hardware
3268      register 3, and so on.  NPARM_REGS is the number of argument registers
3269      supported by the target, not the maximum hardware register number of
3270      the target.  */
3271   if (reg >= NPARM_REGS)
3272     return 0;
3273
3274   /* If the argument fits entirely in registers, return 0.  */
3275   if (reg + mcore_num_arg_regs (mode, type) <= NPARM_REGS)
3276     return 0;
3277
3278   /* The argument overflows the number of available argument registers.
3279      Compute how many argument registers have not yet been assigned to
3280      hold an argument.  */
3281   reg = NPARM_REGS - reg;
3282
3283   /* Return partially in registers and partially on the stack.  */
3284   return reg;
3285 }
3286 \f
3287 /* Return non-zero if SYMBOL is marked as being dllexport'd.  */
3288 int
3289 mcore_dllexport_name_p (symbol)
3290      const char * symbol;
3291 {
3292   return symbol[0] == '@' && symbol[1] == 'e' && symbol[2] == '.';
3293 }
3294
3295 /* Return non-zero if SYMBOL is marked as being dllimport'd.  */
3296 int
3297 mcore_dllimport_name_p (symbol)
3298      const char * symbol;
3299 {
3300   return symbol[0] == '@' && symbol[1] == 'i' && symbol[2] == '.';
3301 }
3302
3303 /* Mark a DECL as being dllexport'd.  */
3304 static void
3305 mcore_mark_dllexport (decl)
3306      tree decl;
3307 {
3308   const char * oldname;
3309   char * newname;
3310   rtx    rtlname;
3311   tree   idp;
3312
3313   rtlname = XEXP (DECL_RTL (decl), 0);
3314   
3315   if (GET_CODE (rtlname) == SYMBOL_REF)
3316     oldname = XSTR (rtlname, 0);
3317   else if (   GET_CODE (rtlname) == MEM
3318            && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
3319     oldname = XSTR (XEXP (rtlname, 0), 0);
3320   else
3321     abort ();
3322   
3323   if (mcore_dllexport_name_p (oldname))
3324     return;  /* Already done.  */
3325
3326   newname = alloca (strlen (oldname) + 4);
3327   sprintf (newname, "@e.%s", oldname);
3328
3329   /* We pass newname through get_identifier to ensure it has a unique
3330      address.  RTL processing can sometimes peek inside the symbol ref
3331      and compare the string's addresses to see if two symbols are
3332      identical.  */
3333   /* ??? At least I think that's why we do this.  */
3334   idp = get_identifier (newname);
3335
3336   XEXP (DECL_RTL (decl), 0) =
3337     gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (idp));
3338 }
3339
3340 /* Mark a DECL as being dllimport'd.  */
3341 static void
3342 mcore_mark_dllimport (decl)
3343      tree decl;
3344 {
3345   const char * oldname;
3346   char * newname;
3347   tree   idp;
3348   rtx    rtlname;
3349   rtx    newrtl;
3350
3351   rtlname = XEXP (DECL_RTL (decl), 0);
3352   
3353   if (GET_CODE (rtlname) == SYMBOL_REF)
3354     oldname = XSTR (rtlname, 0);
3355   else if (   GET_CODE (rtlname) == MEM
3356            && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
3357     oldname = XSTR (XEXP (rtlname, 0), 0);
3358   else
3359     abort ();
3360   
3361   if (mcore_dllexport_name_p (oldname))
3362     abort (); /* This shouldn't happen.  */
3363   else if (mcore_dllimport_name_p (oldname))
3364     return; /* Already done.  */
3365
3366   /* ??? One can well ask why we're making these checks here,
3367      and that would be a good question.  */
3368
3369   /* Imported variables can't be initialized.  */
3370   if (TREE_CODE (decl) == VAR_DECL
3371       && !DECL_VIRTUAL_P (decl)
3372       && DECL_INITIAL (decl))
3373     {
3374       error_with_decl (decl, "initialized variable `%s' is marked dllimport");
3375       return;
3376     }
3377   
3378   /* `extern' needn't be specified with dllimport.
3379      Specify `extern' now and hope for the best.  Sigh.  */
3380   if (TREE_CODE (decl) == VAR_DECL
3381       /* ??? Is this test for vtables needed?  */
3382       && !DECL_VIRTUAL_P (decl))
3383     {
3384       DECL_EXTERNAL (decl) = 1;
3385       TREE_PUBLIC (decl) = 1;
3386     }
3387
3388   newname = alloca (strlen (oldname) + 11);
3389   sprintf (newname, "@i.__imp_%s", oldname);
3390
3391   /* We pass newname through get_identifier to ensure it has a unique
3392      address.  RTL processing can sometimes peek inside the symbol ref
3393      and compare the string's addresses to see if two symbols are
3394      identical.  */
3395   /* ??? At least I think that's why we do this.  */
3396   idp = get_identifier (newname);
3397
3398   newrtl = gen_rtx (MEM, Pmode,
3399                     gen_rtx (SYMBOL_REF, Pmode,
3400                              IDENTIFIER_POINTER (idp)));
3401   XEXP (DECL_RTL (decl), 0) = newrtl;
3402 }
3403
3404 static int
3405 mcore_dllexport_p (decl)
3406      tree decl;
3407 {
3408   if (   TREE_CODE (decl) != VAR_DECL
3409       && TREE_CODE (decl) != FUNCTION_DECL)
3410     return 0;
3411
3412   return lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)) != 0;
3413 }
3414
3415 static int
3416 mcore_dllimport_p (decl)
3417      tree decl;
3418 {
3419   if (   TREE_CODE (decl) != VAR_DECL
3420       && TREE_CODE (decl) != FUNCTION_DECL)
3421     return 0;
3422
3423   return lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl)) != 0;
3424 }
3425
3426 /* We must mark dll symbols specially.  Definitions of dllexport'd objects
3427    install some info in the .drective (PE) or .exports (ELF) sections.   */
3428
3429 static void
3430 mcore_encode_section_info (decl, first)
3431      tree decl;
3432      int first ATTRIBUTE_UNUSED;
3433 {
3434   /* This bit is copied from arm.h.  */
3435   if (optimize > 0
3436       && TREE_CONSTANT (decl)
3437       && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
3438     {
3439       rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
3440                  ? TREE_CST_RTL (decl) : DECL_RTL (decl));
3441       SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
3442     }
3443
3444   /* Mark the decl so we can tell from the rtl whether the object is
3445      dllexport'd or dllimport'd.  */
3446   if (mcore_dllexport_p (decl))
3447     mcore_mark_dllexport (decl);
3448   else if (mcore_dllimport_p (decl))
3449     mcore_mark_dllimport (decl);
3450   
3451   /* It might be that DECL has already been marked as dllimport, but
3452      a subsequent definition nullified that.  The attribute is gone
3453      but DECL_RTL still has @i.__imp_foo.  We need to remove that.  */
3454   else if ((TREE_CODE (decl) == FUNCTION_DECL
3455             || TREE_CODE (decl) == VAR_DECL)
3456            && DECL_RTL (decl) != NULL_RTX
3457            && GET_CODE (DECL_RTL (decl)) == MEM
3458            && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
3459            && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
3460            && mcore_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
3461     {
3462       const char * oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
3463       tree idp = get_identifier (oldname + 9);
3464       rtx newrtl = gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (idp));
3465
3466       XEXP (DECL_RTL (decl), 0) = newrtl;
3467
3468       /* We previously set TREE_PUBLIC and DECL_EXTERNAL.
3469          ??? We leave these alone for now.  */
3470     }
3471 }
3472
3473 /* Undo the effects of the above.  */
3474
3475 static const char *
3476 mcore_strip_name_encoding (str)
3477      const char *str;
3478 {
3479   return str + (str[0] == '@' ? 3 : 0);
3480 }
3481
3482 /* MCore specific attribute support.
3483    dllexport - for exporting a function/variable that will live in a dll
3484    dllimport - for importing a function/variable from a dll
3485    naked     - do not create a function prologue/epilogue.  */
3486
3487 const struct attribute_spec mcore_attribute_table[] =
3488 {
3489   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
3490   { "dllexport", 0, 0, true,  false, false, NULL },
3491   { "dllimport", 0, 0, true,  false, false, NULL },
3492   { "naked",     0, 0, true,  false, false, mcore_handle_naked_attribute },
3493   { NULL,        0, 0, false, false, false, NULL }
3494 };
3495
3496 /* Handle a "naked" attribute; arguments as in
3497    struct attribute_spec.handler.  */
3498 static tree
3499 mcore_handle_naked_attribute (node, name, args, flags, no_add_attrs)
3500      tree *node;
3501      tree name;
3502      tree args ATTRIBUTE_UNUSED;
3503      int flags ATTRIBUTE_UNUSED;
3504      bool *no_add_attrs;
3505 {
3506   if (TREE_CODE (*node) == FUNCTION_DECL)
3507     {
3508       /* PR14310 - don't complain about lack of return statement
3509          in naked functions.  The solution here is a gross hack
3510          but this is the only way to solve the problem without
3511          adding a new feature to GCC.  I did try submitting a patch
3512          that would add such a new feature, but it was (rightfully)
3513          rejected on the grounds that it was creeping featurism,
3514          so hence this code.  */
3515       if (warn_return_type)
3516         {
3517           saved_warn_return_type = warn_return_type;
3518           warn_return_type = 0;
3519           saved_warn_return_type_count = 2;
3520         }
3521       else if (saved_warn_return_type_count)
3522         saved_warn_return_type_count = 2;
3523     }
3524   else
3525     {
3526       warning ("`%s' attribute only applies to functions",
3527                IDENTIFIER_POINTER (name));
3528       *no_add_attrs = true;
3529     }
3530
3531   return NULL_TREE;
3532 }
3533
3534 /* ??? It looks like this is PE specific?  Oh well, this is what the
3535    old code did as well.  */
3536
3537 static void
3538 mcore_unique_section (decl, reloc)
3539      tree decl;
3540      int reloc ATTRIBUTE_UNUSED;
3541 {
3542   int len;
3543   const char * name;
3544   char * string;
3545   const char * prefix;
3546
3547   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
3548   
3549   /* Strip off any encoding in name.  */
3550   name = (* targetm.strip_name_encoding) (name);
3551
3552   /* The object is put in, for example, section .text$foo.
3553      The linker will then ultimately place them in .text
3554      (everything from the $ on is stripped).  */
3555   if (TREE_CODE (decl) == FUNCTION_DECL)
3556     prefix = ".text$";
3557   /* For compatibility with EPOC, we ignore the fact that the
3558      section might have relocs against it.  */
3559   else if (DECL_READONLY_SECTION (decl, 0))
3560     prefix = ".rdata$";
3561   else
3562     prefix = ".data$";
3563   
3564   len = strlen (name) + strlen (prefix);
3565   string = alloca (len + 1);
3566   
3567   sprintf (string, "%s%s", prefix, name);
3568
3569   DECL_SECTION_NAME (decl) = build_string (len, string);
3570 }
3571
3572 int
3573 mcore_naked_function_p ()
3574 {
3575   return lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE;
3576 }
3577
3578 #ifdef OBJECT_FORMAT_ELF
3579 static void
3580 mcore_asm_named_section (name, flags)
3581      const char *name;
3582      unsigned int flags ATTRIBUTE_UNUSED;
3583 {
3584   fprintf (asm_out_file, "\t.section %s\n", name);
3585 }
3586 #endif /* OBJECT_FORMAT_ELF */