OSDN Git Service

* mn10300/mn10300.c (expand_epilogue): Restore registers in the
[pf3gnuchains/gcc-fork.git] / gcc / config / mn10300 / mn10300.c
1 /* Subroutines for insn-output.c for Matsushita MN10300 series
2    Copyright (C) 1996 Free Software Foundation, Inc.
3    Contributed by Jeff Law (law@cygnus.com).
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 #include <stdio.h>
23 #include "config.h"
24 #include "rtl.h"
25 #include "regs.h"
26 #include "hard-reg-set.h"
27 #include "real.h"
28 #include "insn-config.h"
29 #include "conditions.h"
30 #include "insn-flags.h"
31 #include "output.h"
32 #include "insn-attr.h"
33 #include "flags.h"
34 #include "recog.h"
35 #include "expr.h"
36 #include "tree.h"
37 #include "obstack.h"
38
39 void
40 asm_file_start (file)
41      FILE *file;
42 {
43   fprintf (file, "#\tGCC For the Matsushita MN10300\n");
44   if (optimize)
45     fprintf (file, "# -O%d\n", optimize);
46   else
47     fprintf (file, "\n\n");
48   output_file_directive (file, main_input_filename);
49 }
50 \f
51
52 int
53 const_costs (r, c)
54      rtx r;
55      enum rtx_code c;
56 {
57   switch (c)
58     {
59     case CONST_INT:
60       if (INT_8_BITS (INTVAL (r)))
61         return 0;
62       else if (INT_16_BITS (INTVAL (r)))
63         return 1;
64       else
65         return 2;
66     case CONST_DOUBLE:
67       return 8;
68     default:
69       return 4;
70     }
71 }
72 \f
73 /* Print operand X using operand code CODE to assembly language output file
74    FILE.  */
75
76 void
77 print_operand (file, x, code)
78      FILE *file;
79      rtx x;
80      int code;
81 {
82   switch (code)
83     {
84       case 'b':
85       case 'B':
86         /* These are normal and reversed branches.  */
87         switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
88           {
89           case NE:
90             fprintf (file, "ne");
91             break;
92           case EQ:
93             fprintf (file, "eq");
94             break;
95           case GE:
96             fprintf (file, "ge");
97             break;
98           case GT:
99             fprintf (file, "gt");
100             break;
101           case LE:
102             fprintf (file, "le");
103             break;
104           case LT:
105             fprintf (file, "lt");
106             break;
107           case GEU:
108             fprintf (file, "cc");
109             break;
110           case GTU:
111             fprintf (file, "hi");
112             break;
113           case LEU:
114             fprintf (file, "ls");
115             break;
116           case LTU:
117             fprintf (file, "cs");
118             break;
119           default:
120             abort ();
121           }
122         break;
123       case 'C':
124         /* This is used for the operand to a call instruction;
125            if it's a REG, enclose it in parens, else output
126            the operand normally.  */
127         if (GET_CODE (x) == REG)
128           {
129             fputc ('(', file);
130             print_operand (file, x, 0);
131             fputc (')', file);
132           }
133         else
134           print_operand (file, x, 0);
135         break;
136      
137       default:
138         switch (GET_CODE (x))
139           {
140           case MEM:
141             fputc ('(', file);
142             output_address (XEXP (x, 0));
143             fputc (')', file);
144             break;
145
146           case REG:
147             fprintf (file, "%s", reg_names[REGNO (x)]);
148             break;
149
150           case SUBREG:
151             fprintf (file, "%s",
152                      reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)]);
153             break;
154
155           case CONST_INT:
156           case SYMBOL_REF:
157           case CONST:
158           case LABEL_REF:
159           case CODE_LABEL:
160             print_operand_address (file, x);
161             break;
162           default:
163             abort ();
164           }
165         break;
166    }
167 }
168
169 /* Output assembly language output for the address ADDR to FILE.  */
170
171 void
172 print_operand_address (file, addr)
173      FILE *file;
174      rtx addr;
175 {
176   switch (GET_CODE (addr))
177     {
178     case REG:
179       if (addr == stack_pointer_rtx)
180         print_operand_address (file, gen_rtx (PLUS, SImode,
181                                               stack_pointer_rtx,
182                                               GEN_INT (0)));
183       else
184         print_operand (file, addr, 0);
185       break;
186     case PLUS:
187       {
188         rtx base, index;
189         if (REG_P (XEXP (addr, 0))
190             && REG_OK_FOR_BASE_P (XEXP (addr, 0)))
191           base = XEXP (addr, 0), index = XEXP (addr, 1);
192         else if (REG_P (XEXP (addr, 1))
193             && REG_OK_FOR_BASE_P (XEXP (addr, 1)))
194           base = XEXP (addr, 1), index = XEXP (addr, 0);
195         else
196           abort ();
197         print_operand (file, index, 0);
198         fputc (',', file);
199         print_operand (file, base, 0);;
200         break;
201       }
202     case SYMBOL_REF:
203       output_addr_const (file, addr);
204       break;
205     default:
206       output_addr_const (file, addr);
207       break;
208     }
209 }
210
211 void
212 expand_prologue ()
213 {
214   unsigned int size = get_frame_size ();
215
216   /* For simplicity, we just movm all the callee saved registers to
217      the stack with one instruction, then set up the frame pointer
218      (if needed), and finally allocate the new stack.  */
219   emit_insn (gen_store_movm ());
220
221   if (frame_pointer_needed)
222     {
223       emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
224       emit_insn (gen_addsi3 (frame_pointer_rtx,
225                              frame_pointer_rtx,
226                              GEN_INT (20)));
227     }
228
229   if (size)
230     emit_insn (gen_addsi3 (stack_pointer_rtx,
231                            stack_pointer_rtx,
232                            GEN_INT (-size)));
233 }
234
235 void
236 expand_epilogue ()
237 {
238   unsigned int size = get_frame_size ();
239
240   /* Cut back the stack.  */
241   if (frame_pointer_needed)
242     {
243       emit_insn (gen_addsi3 (frame_pointer_rtx,
244                              frame_pointer_rtx,
245                              GEN_INT (-20)));
246       emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
247       size = 0;
248     }
249   else if (size > 255)
250     {
251       emit_insn (gen_addsi3 (stack_pointer_rtx,
252                              stack_pointer_rtx,
253                              GEN_INT (size)));
254       size = 0;
255     }
256
257   /* Deallocate remaining stack, restore registers and return.  And return.  */
258   emit_jump_insn (gen_return_internal (GEN_INT (size)));
259 }
260
261 /* Update the condition code from the insn.  */
262
263 void
264 notice_update_cc (body, insn)
265      rtx body;
266      rtx insn;
267 {
268 #if 0
269   switch (get_attr_cc (insn))
270     {
271     case CC_NONE:
272       /* Insn does not affect CC at all.  */
273       break;
274
275     case CC_NONE_0HIT:
276       /* Insn does not change CC, but the 0'th operand has been changed.  */
277       if (cc_status.value1 != 0
278           && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
279         cc_status.value1 = 0;
280       break;
281
282     case CC_SET_ZN_C0:
283       /* Insn sets the Z,N flags of CC to recog_operand[0].
284          V is always set to 0.  C may or may not be set to 0 but that's ok
285          because alter_cond will change tests to use EQ/NE.  */
286       CC_STATUS_INIT;
287       cc_status.flags |= CC_NO_OVERFLOW;
288       cc_status.value1 = recog_operand[0];
289       break;
290
291     case CC_SET:
292     case CC_COMPARE:
293       /* The insn is a compare instruction.  */
294       CC_STATUS_INIT;
295       cc_status.value1 = SET_SRC (body);
296       break;
297
298     case CC_CLOBBER:
299       /* Insn doesn't leave CC in a usable state.  */
300       CC_STATUS_INIT;
301       break;
302     }
303 #endif
304   CC_STATUS_INIT;
305 }
306
307 /* Return true if OP is a valid call operand.  */
308
309 int
310 call_address_operand (op, mode)
311      rtx op;
312      enum machine_mode mode;
313 {
314   return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);
315 }
316
317 /* What (if any) secondary registers are needed to move IN with mode
318    MODE into a register from in register class CLASS. 
319
320    We might be able to simplify this.  */
321 enum reg_class
322 secondary_reload_class (class, mode, in)
323      enum reg_class class;
324      enum machine_mode mode;
325      rtx in;
326 {
327   int regno;
328
329   /* Memory loads less than a full word wide can't have an
330      address or stack pointer destination.  They must use
331      a data register as an intermediate register.  */
332   if (GET_CODE (in) == MEM
333       && (mode == QImode || mode == HImode)
334       && (class == ADDRESS_REGS || class == SP_REGS))
335     return DATA_REGS;
336
337   /* We can't directly load sp + const_int into a data register;
338      we must use an address register as an intermediate.  */
339   if (class == DATA_REGS
340       && (in == stack_pointer_rtx
341           || (GET_CODE (in) == PLUS
342               && XEXP (in, 0) == stack_pointer_rtx)))
343     return ADDRESS_REGS;
344
345   /* Get the true register.  */
346   if (GET_CODE (in) == REG)
347     {
348       regno = REGNO (in);
349       if (regno >= FIRST_PSEUDO_REGISTER)
350         regno = true_regnum (in);
351     }
352
353   /* We can't copy directly from a data register into the stack
354      pointer.  */
355   if (class == SP_REGS
356       && GET_CODE (in) == REG
357       && regno < 4)
358     return ADDRESS_REGS;
359
360   /* Otherwise assume no secondary reloads are needed.  */
361   return NO_REGS;
362 }