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