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