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