Initial revision
[official-gcc.git] / gcc / config / mn10300 / mn10300.c
blob9218584baf0cf71889e11938244d96c6a8bc0a50
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).
5 This file is part of GNU CC.
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.
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.
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. */
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"
39 void
40 asm_file_start (file)
41 FILE *file;
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);
52 int
53 const_costs (r, c)
54 rtx r;
55 enum rtx_code c;
57 switch (c)
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;
73 /* Print operand X using operand code CODE to assembly language output file
74 FILE. */
76 void
77 print_operand (file, x, code)
78 FILE *file;
79 rtx x;
80 int code;
82 switch (code)
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)))
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 ();
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)
129 fputc ('(', file);
130 print_operand (file, x, 0);
131 fputc (')', file);
133 else
134 print_operand (file, x, 0);
135 break;
137 default:
138 switch (GET_CODE (x))
140 case MEM:
141 fputc ('(', file);
142 output_address (XEXP (x, 0));
143 fputc (')', file);
144 break;
146 case REG:
147 fprintf (file, "%s", reg_names[REGNO (x)]);
148 break;
150 case SUBREG:
151 fprintf (file, "%s",
152 reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)]);
153 break;
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 ();
165 break;
169 /* Output assembly language output for the address ADDR to FILE. */
171 void
172 print_operand_address (file, addr)
173 FILE *file;
174 rtx addr;
176 switch (GET_CODE (addr))
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:
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;
202 case SYMBOL_REF:
203 output_addr_const (file, addr);
204 break;
205 default:
206 output_addr_const (file, addr);
207 break;
211 void
212 expand_prologue ()
214 unsigned int size = get_frame_size ();
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 ());
221 if (frame_pointer_needed)
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)));
229 if (size)
230 emit_insn (gen_addsi3 (stack_pointer_rtx,
231 stack_pointer_rtx,
232 GEN_INT (-size)));
235 void
236 expand_epilogue ()
238 unsigned int size = get_frame_size ();
240 /* Cut back the stack. */
241 if (frame_pointer_needed)
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);
248 else if (size)
249 emit_insn (gen_addsi3 (stack_pointer_rtx,
250 stack_pointer_rtx,
251 GEN_INT (size)));
253 /* And restore the registers. */
254 emit_insn (gen_load_movm ());
256 /* And return. */
257 emit_jump_insn (gen_return_internal ());
260 /* Update the condition code from the insn. */
262 void
263 notice_update_cc (body, insn)
264 rtx body;
265 rtx insn;
267 #if 0
268 switch (get_attr_cc (insn))
270 case CC_NONE:
271 /* Insn does not affect CC at all. */
272 break;
274 case CC_NONE_0HIT:
275 /* Insn does not change CC, but the 0'th operand has been changed. */
276 if (cc_status.value1 != 0
277 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
278 cc_status.value1 = 0;
279 break;
281 case CC_SET_ZN_C0:
282 /* Insn sets the Z,N flags of CC to recog_operand[0].
283 V is always set to 0. C may or may not be set to 0 but that's ok
284 because alter_cond will change tests to use EQ/NE. */
285 CC_STATUS_INIT;
286 cc_status.flags |= CC_NO_OVERFLOW;
287 cc_status.value1 = recog_operand[0];
288 break;
290 case CC_SET:
291 case CC_COMPARE:
292 /* The insn is a compare instruction. */
293 CC_STATUS_INIT;
294 cc_status.value1 = SET_SRC (body);
295 break;
297 case CC_CLOBBER:
298 /* Insn doesn't leave CC in a usable state. */
299 CC_STATUS_INIT;
300 break;
302 #endif
303 CC_STATUS_INIT;
306 /* Return true if OP is a valid call operand. */
309 call_address_operand (op, mode)
310 rtx op;
311 enum machine_mode mode;
313 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);
316 /* What (if any) secondary registers are needed to move IN with mode
317 MODE into a register from in register class CLASS.
319 We might be able to simplify this. */
320 enum reg_class
321 secondary_reload_class (class, mode, in)
322 enum reg_class class;
323 enum machine_mode mode;
324 rtx in;
326 int regno;
328 /* Memory loads less than a full word wide can't have an
329 address or stack pointer destination. They must use
330 a data register as an intermediate register. */
331 if (GET_CODE (in) == MEM
332 && (mode == QImode || mode == HImode)
333 && (class == ADDRESS_REGS || class == SP_REGS))
334 return DATA_REGS;
336 /* We can't directly load sp + const_int into a data register;
337 we must use an address register as an intermediate. */
338 if (class == DATA_REGS
339 && (in == stack_pointer_rtx
340 || (GET_CODE (in) == PLUS
341 && XEXP (in, 0) == stack_pointer_rtx)))
342 return ADDRESS_REGS;
344 /* Get the true register. */
345 if (GET_CODE (in) == REG)
347 regno = REGNO (in);
348 if (regno >= FIRST_PSEUDO_REGISTER)
349 regno = true_regnum (in);
352 /* We can't copy directly from a data register into the stack
353 pointer. */
354 if (class == SP_REGS
355 && GET_CODE (in) == REG
356 && regno < 4)
357 return ADDRESS_REGS;
359 /* Otherwise assume no secondary reloads are needed. */
360 return NO_REGS;