]>
Commit | Line | Data |
---|---|---|
16bea517 | 1 | /* Output routines for GCC for Hitachi Super-H. |
8aa2a305 | 2 | Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. |
bc45ade3 | 3 | |
c15c9075 RK |
4 | This file is part of GNU CC. |
5 | ||
6 | GNU CC is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 2, or (at your option) | |
9 | any later version. | |
10 | ||
11 | GNU CC is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with GNU CC; see the file COPYING. If not, write to | |
18 | the Free Software Foundation, 59 Temple Place - Suite 330, | |
19 | Boston, MA 02111-1307, USA. */ | |
bc45ade3 | 20 | |
8aa2a305 JW |
21 | /* Contributed by Steve Chamberlain (sac@cygnus.com). |
22 | Improved by Jim Wilson (wilson@cygnus.com). */ | |
bc45ade3 | 23 | |
bc45ade3 | 24 | #include "config.h" |
8aa2a305 JW |
25 | |
26 | #include <stdio.h> | |
27 | ||
bc45ade3 | 28 | #include "rtl.h" |
bc45ade3 | 29 | #include "tree.h" |
bc45ade3 | 30 | #include "flags.h" |
8aa2a305 | 31 | #include "insn-flags.h" |
bc45ade3 | 32 | #include "expr.h" |
8aa2a305 JW |
33 | #include "regs.h" |
34 | #include "hard-reg-set.h" | |
35 | #include "output.h" | |
956a5206 | 36 | #include "insn-attr.h" |
bc45ade3 | 37 | |
00f8ff66 SC |
38 | #define MSW (TARGET_LITTLE_ENDIAN ? 1 : 0) |
39 | #define LSW (TARGET_LITTLE_ENDIAN ? 0 : 1) | |
40 | ||
20b04867 | 41 | /* ??? The pragma interrupt support will not work for SH3. */ |
8aa2a305 JW |
42 | /* This is set by #pragma interrupt and #pragma trapa, and causes gcc to |
43 | output code for the next function appropriate for an interrupt handler. */ | |
0d7e008e | 44 | int pragma_interrupt; |
bc45ade3 | 45 | |
8aa2a305 JW |
46 | /* This is set by #pragma trapa, and is similar to the above, except that |
47 | the compiler doesn't emit code to preserve all registers. */ | |
48 | static int pragma_trapa; | |
49 | ||
956a5206 JW |
50 | /* This is set by #pragma nosave_low_regs. This is useful on the SH3, |
51 | which has a separate set of low regs for User and Supervisor modes. | |
52 | This should only be used for the lowest level of interrupts. Higher levels | |
53 | of interrupts must save the registers in case they themselves are | |
54 | interrupted. */ | |
55 | int pragma_nosave_low_regs; | |
56 | ||
8aa2a305 JW |
57 | /* This is used for communication between SETUP_INCOMING_VARARGS and |
58 | sh_expand_prologue. */ | |
bc45ade3 | 59 | int current_function_anonymous_args; |
16bea517 | 60 | |
8aa2a305 JW |
61 | /* Global variables from toplev.c and final.c that are used within, but |
62 | not declared in any header file. */ | |
b9654711 | 63 | extern char *version_string; |
8aa2a305 | 64 | extern int *insn_addresses; |
00f8ff66 | 65 | |
bc45ade3 SC |
66 | /* Global variables for machine-dependent things. */ |
67 | ||
16bea517 JW |
68 | /* Which cpu are we scheduling for. */ |
69 | enum processor_type sh_cpu; | |
70 | ||
bc45ade3 | 71 | /* Saved operands from the last compare to use when we generate an scc |
16bea517 | 72 | or bcc insn. */ |
bc45ade3 SC |
73 | |
74 | rtx sh_compare_op0; | |
75 | rtx sh_compare_op1; | |
76 | ||
77 | /* Provides the class number of the smallest class containing | |
16bea517 | 78 | reg number. */ |
bc45ade3 SC |
79 | |
80 | int regno_reg_class[FIRST_PSEUDO_REGISTER] = | |
81 | { | |
8e87e161 | 82 | R0_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, |
bc45ade3 SC |
83 | GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, |
84 | GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, | |
85 | GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, | |
8e87e161 SC |
86 | GENERAL_REGS, PR_REGS, T_REGS, NO_REGS, |
87 | MAC_REGS, MAC_REGS, | |
bc45ade3 SC |
88 | }; |
89 | ||
90 | /* Provide reg_class from a letter such as appears in the machine | |
16bea517 | 91 | description. */ |
bc45ade3 SC |
92 | |
93 | enum reg_class reg_class_from_letter[] = | |
94 | { | |
95 | /* a */ NO_REGS, /* b */ NO_REGS, /* c */ NO_REGS, /* d */ NO_REGS, | |
96 | /* e */ NO_REGS, /* f */ NO_REGS, /* g */ NO_REGS, /* h */ NO_REGS, | |
97 | /* i */ NO_REGS, /* j */ NO_REGS, /* k */ NO_REGS, /* l */ PR_REGS, | |
98 | /* m */ NO_REGS, /* n */ NO_REGS, /* o */ NO_REGS, /* p */ NO_REGS, | |
99 | /* q */ NO_REGS, /* r */ NO_REGS, /* s */ NO_REGS, /* t */ T_REGS, | |
100 | /* u */ NO_REGS, /* v */ NO_REGS, /* w */ NO_REGS, /* x */ MAC_REGS, | |
101 | /* y */ NO_REGS, /* z */ R0_REGS | |
102 | }; | |
b9654711 | 103 | \f |
16bea517 | 104 | /* Print the operand address in x to the stream. */ |
bc45ade3 SC |
105 | |
106 | void | |
107 | print_operand_address (stream, x) | |
108 | FILE *stream; | |
109 | rtx x; | |
110 | { | |
111 | switch (GET_CODE (x)) | |
112 | { | |
113 | case REG: | |
114 | fprintf (stream, "@%s", reg_names[REGNO (x)]); | |
115 | break; | |
8aa2a305 | 116 | |
bc45ade3 SC |
117 | case PLUS: |
118 | { | |
119 | rtx base = XEXP (x, 0); | |
120 | rtx index = XEXP (x, 1); | |
121 | ||
bc45ade3 SC |
122 | switch (GET_CODE (index)) |
123 | { | |
124 | case CONST_INT: | |
8aa2a305 | 125 | fprintf (stream, "@(%d,%s)", INTVAL (index), |
bc45ade3 SC |
126 | reg_names[REGNO (base)]); |
127 | break; | |
128 | ||
129 | case REG: | |
b9654711 SC |
130 | fprintf (stream, "@(r0,%s)", |
131 | reg_names[MAX (REGNO (base), REGNO (index))]); | |
bc45ade3 SC |
132 | break; |
133 | ||
134 | default: | |
b9654711 | 135 | debug_rtx (x); |
bc45ade3 SC |
136 | abort (); |
137 | } | |
138 | } | |
bc45ade3 | 139 | break; |
8aa2a305 | 140 | |
bc45ade3 SC |
141 | case PRE_DEC: |
142 | fprintf (stream, "@-%s", reg_names[REGNO (XEXP (x, 0))]); | |
143 | break; | |
144 | ||
145 | case POST_INC: | |
146 | fprintf (stream, "@%s+", reg_names[REGNO (XEXP (x, 0))]); | |
147 | break; | |
148 | ||
149 | default: | |
150 | output_addr_const (stream, x); | |
151 | break; | |
152 | } | |
153 | } | |
154 | ||
155 | /* Print operand x (an rtx) in assembler syntax to file stream | |
156 | according to modifier code. | |
157 | ||
b9654711 | 158 | '.' print a .s if insn needs delay slot |
d3ae8277 | 159 | '@' print rte or rts depending upon pragma interruptness |
8aa2a305 JW |
160 | '#' output a nop if there is nothing to put in the delay slot |
161 | 'O' print a constant without the # | |
00f8ff66 | 162 | 'R' print the LSW of a dp value - changes if in little endian |
00f8ff66 | 163 | 'S' print the MSW of a dp value - changes if in little endian |
8aa2a305 | 164 | 'T' print the next word of a dp value - same as 'R' in big endian mode. */ |
bc45ade3 SC |
165 | |
166 | void | |
167 | print_operand (stream, x, code) | |
168 | FILE *stream; | |
169 | rtx x; | |
170 | int code; | |
171 | { | |
172 | switch (code) | |
173 | { | |
b9654711 | 174 | case '.': |
79b2746a JW |
175 | if (final_sequence |
176 | && ! INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0))) | |
b9654711 SC |
177 | fprintf (stream, ".s"); |
178 | break; | |
d3ae8277 SC |
179 | case '@': |
180 | if (pragma_interrupt) | |
8e87e161 | 181 | fprintf (stream, "rte"); |
d3ae8277 | 182 | else |
8e87e161 | 183 | fprintf (stream, "rts"); |
d3ae8277 | 184 | break; |
bc45ade3 | 185 | case '#': |
16bea517 | 186 | /* Output a nop if there's nothing in the delay slot. */ |
bc45ade3 | 187 | if (dbr_sequence_length () == 0) |
8aa2a305 | 188 | fprintf (stream, "\n\tnop"); |
bc45ade3 | 189 | break; |
b9654711 | 190 | case 'O': |
0d7e008e | 191 | output_addr_const (stream, x); |
bc45ade3 | 192 | break; |
bc45ade3 | 193 | case 'R': |
8aa2a305 JW |
194 | fputs (reg_names[REGNO (x) + LSW], (stream)); |
195 | break; | |
196 | case 'S': | |
197 | fputs (reg_names[REGNO (x) + MSW], (stream)); | |
00f8ff66 SC |
198 | break; |
199 | case 'T': | |
16bea517 | 200 | /* Next word of a double. */ |
bc45ade3 SC |
201 | switch (GET_CODE (x)) |
202 | { | |
203 | case REG: | |
204 | fputs (reg_names[REGNO (x) + 1], (stream)); | |
205 | break; | |
206 | case MEM: | |
8aa2a305 JW |
207 | print_operand_address (stream, |
208 | XEXP (adj_offsettable_operand (x, 4), 0)); | |
bc45ade3 SC |
209 | break; |
210 | } | |
211 | break; | |
bc45ade3 SC |
212 | default: |
213 | switch (GET_CODE (x)) | |
214 | { | |
215 | case REG: | |
216 | fputs (reg_names[REGNO (x)], (stream)); | |
217 | break; | |
218 | case MEM: | |
219 | output_address (XEXP (x, 0)); | |
220 | break; | |
221 | default: | |
222 | fputc ('#', stream); | |
223 | output_addr_const (stream, x); | |
224 | break; | |
bc45ade3 SC |
225 | } |
226 | break; | |
227 | } | |
228 | } | |
bc45ade3 | 229 | \f |
0d7e008e SC |
230 | /* Emit code to perform a block move. Choose the best method. |
231 | ||
232 | OPERANDS[0] is the destination. | |
233 | OPERANDS[1] is the source. | |
234 | OPERANDS[2] is the size. | |
235 | OPERANDS[3] is the alignment safe to use. */ | |
236 | ||
0d7e008e SC |
237 | int |
238 | expand_block_move (operands) | |
239 | rtx *operands; | |
240 | { | |
241 | int align = INTVAL (operands[3]); | |
242 | int constp = (GET_CODE (operands[2]) == CONST_INT); | |
243 | int bytes = (constp ? INTVAL (operands[2]) : 0); | |
0d7e008e | 244 | |
8aa2a305 JW |
245 | /* If it isn't a constant number of bytes, or if it doesn't have 4 byte |
246 | alignment, or if it isn't a multiple of 4 bytes, then fail. */ | |
247 | if (! constp || align < 4 || (bytes % 4 != 0)) | |
d3ae8277 SC |
248 | return 0; |
249 | ||
8aa2a305 | 250 | if (bytes < 64) |
0d7e008e SC |
251 | { |
252 | char entry[30]; | |
253 | tree entry_name; | |
254 | rtx func_addr_rtx; | |
255 | rtx r4 = gen_rtx (REG, SImode, 4); | |
256 | rtx r5 = gen_rtx (REG, SImode, 5); | |
8aa2a305 JW |
257 | |
258 | sprintf (entry, "__movstrSI%d", bytes); | |
0d7e008e SC |
259 | entry_name = get_identifier (entry); |
260 | ||
8aa2a305 JW |
261 | func_addr_rtx |
262 | = copy_to_mode_reg (Pmode, | |
263 | gen_rtx (SYMBOL_REF, Pmode, | |
264 | IDENTIFIER_POINTER (entry_name))); | |
0d7e008e SC |
265 | emit_insn (gen_move_insn (r4, XEXP (operands[0], 0))); |
266 | emit_insn (gen_move_insn (r5, XEXP (operands[1], 0))); | |
267 | emit_insn (gen_block_move_real (func_addr_rtx)); | |
268 | return 1; | |
269 | } | |
8aa2a305 JW |
270 | |
271 | /* This is the same number of bytes as a memcpy call, but to a different | |
272 | less common function name, so this will occasionally use more space. */ | |
273 | if (! TARGET_SMALLCODE) | |
0d7e008e | 274 | { |
0d7e008e SC |
275 | tree entry_name; |
276 | rtx func_addr_rtx; | |
8aa2a305 | 277 | int final_switch, while_loop; |
0d7e008e SC |
278 | rtx r4 = gen_rtx (REG, SImode, 4); |
279 | rtx r5 = gen_rtx (REG, SImode, 5); | |
280 | rtx r6 = gen_rtx (REG, SImode, 6); | |
0d7e008e | 281 | |
8aa2a305 JW |
282 | entry_name = get_identifier ("__movstr"); |
283 | func_addr_rtx | |
284 | = copy_to_mode_reg (Pmode, | |
285 | gen_rtx (SYMBOL_REF, Pmode, | |
286 | IDENTIFIER_POINTER (entry_name))); | |
0d7e008e SC |
287 | emit_insn (gen_move_insn (r4, XEXP (operands[0], 0))); |
288 | emit_insn (gen_move_insn (r5, XEXP (operands[1], 0))); | |
289 | ||
8aa2a305 JW |
290 | /* r6 controls the size of the move. 16 is decremented from it |
291 | for each 64 bytes moved. Then the negative bit left over is used | |
292 | as an index into a list of move instructions. e.g., a 72 byte move | |
293 | would be set up with size(r6) = 14, for one iteration through the | |
294 | big while loop, and a switch of -2 for the last part. */ | |
0d7e008e | 295 | |
8aa2a305 JW |
296 | final_switch = 16 - ((bytes / 4) % 16); |
297 | while_loop = ((bytes / 4) / 16 - 1) * 16; | |
298 | emit_insn (gen_move_insn (r6, GEN_INT (while_loop + final_switch))); | |
299 | emit_insn (gen_block_lump_real (func_addr_rtx)); | |
300 | return 1; | |
0d7e008e | 301 | } |
0d7e008e | 302 | |
d3ae8277 | 303 | return 0; |
0d7e008e SC |
304 | } |
305 | ||
bc45ade3 | 306 | /* Prepare operands for a move define_expand; specifically, one of the |
8aa2a305 | 307 | operands must be in a register. */ |
bc45ade3 | 308 | |
b9654711 | 309 | int |
bc45ade3 SC |
310 | prepare_move_operands (operands, mode) |
311 | rtx operands[]; | |
312 | enum machine_mode mode; | |
313 | { | |
8aa2a305 JW |
314 | /* Copy the source to a register if both operands aren't registers. */ |
315 | if (! reload_in_progress && ! reload_completed | |
316 | && ! register_operand (operands[0], mode) | |
317 | && ! register_operand (operands[1], mode)) | |
318 | operands[1] = copy_to_mode_reg (mode, operands[1]); | |
319 | ||
320 | return 0; | |
321 | } | |
322 | ||
323 | /* Prepare the operands for an scc instruction; make sure that the | |
324 | compare has been done. */ | |
325 | rtx | |
326 | prepare_scc_operands (code) | |
327 | enum rtx_code code; | |
328 | { | |
329 | rtx t_reg = gen_rtx (REG, SImode, T_REG); | |
330 | enum rtx_code oldcode = code; | |
9374bd85 | 331 | enum machine_mode mode; |
8aa2a305 JW |
332 | |
333 | /* First need a compare insn. */ | |
334 | switch (code) | |
bc45ade3 | 335 | { |
8aa2a305 JW |
336 | case NE: |
337 | /* It isn't possible to handle this case. */ | |
338 | abort (); | |
339 | case LT: | |
340 | code = GT; | |
341 | break; | |
342 | case LE: | |
343 | code = GE; | |
344 | break; | |
345 | case LTU: | |
346 | code = GTU; | |
347 | break; | |
348 | case LEU: | |
349 | code = GEU; | |
350 | break; | |
bc45ade3 | 351 | } |
8aa2a305 | 352 | if (code != oldcode) |
b9654711 | 353 | { |
8aa2a305 JW |
354 | rtx tmp = sh_compare_op0; |
355 | sh_compare_op0 = sh_compare_op1; | |
356 | sh_compare_op1 = tmp; | |
0d7e008e | 357 | } |
b9654711 | 358 | |
9374bd85 RK |
359 | mode = GET_MODE (sh_compare_op0); |
360 | if (mode == VOIDmode) | |
361 | mode = GET_MODE (sh_compare_op1); | |
362 | ||
363 | sh_compare_op0 = force_reg (mode, sh_compare_op0); | |
8aa2a305 JW |
364 | if (code != EQ && code != NE |
365 | && (sh_compare_op1 != const0_rtx | |
366 | || code == GTU || code == GEU || code == LTU || code == LEU)) | |
9374bd85 | 367 | sh_compare_op1 = force_reg (mode, sh_compare_op1); |
0d7e008e | 368 | |
8aa2a305 JW |
369 | emit_insn (gen_rtx (SET, VOIDmode, t_reg, |
370 | gen_rtx (code, SImode, sh_compare_op0, | |
371 | sh_compare_op1))); | |
0d7e008e | 372 | |
8aa2a305 | 373 | return t_reg; |
bc45ade3 SC |
374 | } |
375 | ||
8aa2a305 JW |
376 | /* Called from the md file, set up the operands of a compare instruction. */ |
377 | ||
378 | void | |
379 | from_compare (operands, code) | |
380 | rtx *operands; | |
8e87e161 | 381 | int code; |
bc45ade3 | 382 | { |
8aa2a305 | 383 | if (code != EQ && code != NE) |
bc45ade3 | 384 | { |
24a25d45 JW |
385 | enum machine_mode mode = GET_MODE (sh_compare_op0); |
386 | if (mode == VOIDmode) | |
387 | mode = GET_MODE (sh_compare_op1); | |
388 | ||
8aa2a305 | 389 | /* Force args into regs, since we can't use constants here. */ |
24a25d45 | 390 | sh_compare_op0 = force_reg (mode, sh_compare_op0); |
8aa2a305 JW |
391 | if (sh_compare_op1 != const0_rtx |
392 | || code == GTU || code == GEU || code == LTU || code == LEU) | |
24a25d45 | 393 | sh_compare_op1 = force_reg (mode, sh_compare_op1); |
bc45ade3 | 394 | } |
8aa2a305 JW |
395 | operands[1] = sh_compare_op0; |
396 | operands[2] = sh_compare_op1; | |
bc45ade3 SC |
397 | } |
398 | \f | |
16bea517 | 399 | /* Functions to output assembly code. */ |
bc45ade3 | 400 | |
b9654711 | 401 | /* Return a sequence of instructions to perform DI or DF move. |
bc45ade3 | 402 | |
b9654711 | 403 | Since the SH cannot move a DI or DF in one instruction, we have |
16bea517 | 404 | to take care when we see overlapping source and dest registers. */ |
0d7e008e | 405 | |
bc45ade3 | 406 | char * |
0d7e008e SC |
407 | output_movedouble (insn, operands, mode) |
408 | rtx insn; | |
bc45ade3 SC |
409 | rtx operands[]; |
410 | enum machine_mode mode; | |
411 | { | |
b9654711 SC |
412 | rtx dst = operands[0]; |
413 | rtx src = operands[1]; | |
b9654711 | 414 | |
0d7e008e | 415 | if (GET_CODE (dst) == MEM |
16bea517 | 416 | && GET_CODE (XEXP (dst, 0)) == PRE_DEC) |
8aa2a305 JW |
417 | return "mov.l %T1,%0\n\tmov.l %1,%0"; |
418 | ||
b9654711 SC |
419 | if (register_operand (dst, mode) |
420 | && register_operand (src, mode)) | |
bc45ade3 | 421 | { |
b9654711 | 422 | if (REGNO (src) == MACH_REG) |
00f8ff66 | 423 | return "sts mach,%S0\n\tsts macl,%R0"; |
bc45ade3 | 424 | |
8aa2a305 JW |
425 | /* When mov.d r1,r2 do r2->r3 then r1->r2; |
426 | when mov.d r1,r0 do r1->r0 then r2->r1. */ | |
b9654711 SC |
427 | |
428 | if (REGNO (src) + 1 == REGNO (dst)) | |
5325c0fa | 429 | return "mov %T1,%T0\n\tmov %1,%0"; |
b9654711 | 430 | else |
5325c0fa | 431 | return "mov %1,%0\n\tmov %T1,%T0"; |
b9654711 SC |
432 | } |
433 | else if (GET_CODE (src) == CONST_INT) | |
bc45ade3 | 434 | { |
8aa2a305 JW |
435 | if (INTVAL (src) < 0) |
436 | output_asm_insn ("mov #-1,%S0", operands); | |
bc45ade3 | 437 | else |
8aa2a305 | 438 | output_asm_insn ("mov #0,%S0", operands); |
bc45ade3 | 439 | |
8aa2a305 | 440 | return "mov %1,%R0"; |
0d7e008e | 441 | } |
b9654711 | 442 | else if (GET_CODE (src) == MEM) |
bc45ade3 | 443 | { |
8aa2a305 | 444 | int ptrreg = -1; |
b9654711 SC |
445 | int dreg = REGNO (dst); |
446 | rtx inside = XEXP (src, 0); | |
bc45ade3 SC |
447 | |
448 | if (GET_CODE (inside) == REG) | |
8aa2a305 | 449 | ptrreg = REGNO (inside); |
79b2746a JW |
450 | else if (GET_CODE (inside) == SUBREG) |
451 | ptrreg = REGNO (SUBREG_REG (inside)) + SUBREG_WORD (inside); | |
bc45ade3 SC |
452 | else if (GET_CODE (inside) == PLUS) |
453 | { | |
8aa2a305 JW |
454 | ptrreg = REGNO (XEXP (inside, 0)); |
455 | /* ??? A r0+REG address shouldn't be possible here, because it isn't | |
456 | an offsettable address. Unfortunately, offsettable addresses use | |
457 | QImode to check the offset, and a QImode offsettable address | |
458 | requires r0 for the other operand, which is not currently | |
459 | supported, so we can't use the 'o' constraint. | |
460 | Thus we must check for and handle r0+REG addresses here. | |
461 | We punt for now, since this is likely very rare. */ | |
462 | if (GET_CODE (XEXP (inside, 1)) == REG) | |
463 | abort (); | |
bc45ade3 | 464 | } |
0d7e008e | 465 | else if (GET_CODE (inside) == LABEL_REF) |
8aa2a305 | 466 | return "mov.l %1,%0\n\tmov.l %1+4,%T0"; |
8e87e161 | 467 | else if (GET_CODE (inside) == POST_INC) |
8aa2a305 | 468 | return "mov.l %1,%0\n\tmov.l %1,%T0"; |
bc45ade3 SC |
469 | else |
470 | abort (); | |
471 | ||
8aa2a305 JW |
472 | /* Work out the safe way to copy. Copy into the second half first. */ |
473 | if (dreg == ptrreg) | |
474 | return "mov.l %T1,%T0\n\tmov.l %1,%0"; | |
bc45ade3 SC |
475 | } |
476 | ||
00f8ff66 | 477 | return "mov.l %1,%0\n\tmov.l %T1,%T0"; |
bc45ade3 SC |
478 | } |
479 | ||
8aa2a305 JW |
480 | /* Print an instruction which would have gone into a delay slot after |
481 | another instruction, but couldn't because the other instruction expanded | |
482 | into a sequence where putting the slot insn at the end wouldn't work. */ | |
0d7e008e | 483 | |
8aa2a305 JW |
484 | static void |
485 | print_slot (insn) | |
486 | rtx insn; | |
487 | { | |
488 | final_scan_insn (XVECEXP (insn, 0, 1), asm_out_file, optimize, 0, 1); | |
b9654711 | 489 | |
8aa2a305 JW |
490 | INSN_DELETED_P (XVECEXP (insn, 0, 1)) = 1; |
491 | } | |
0d7e008e | 492 | |
8aa2a305 JW |
493 | /* We can't tell if we need a register as a scratch for the jump |
494 | until after branch shortening, and then it's too late to allocate a | |
495 | register the 'proper' way. These instruction sequences are rare | |
496 | anyway, so to avoid always using a reg up from our limited set, we'll | |
497 | grab one when we need one on output. */ | |
0d7e008e | 498 | |
8aa2a305 JW |
499 | /* ??? Should fix compiler so that using a clobber scratch in jump |
500 | instructions works, and then this will be unnecessary. */ | |
0d7e008e SC |
501 | |
502 | char * | |
503 | output_far_jump (insn, op) | |
504 | rtx insn; | |
505 | rtx op; | |
506 | { | |
507 | rtx thislab = gen_label_rtx (); | |
508 | ||
8aa2a305 | 509 | /* Output the delay slot insn first if any. */ |
0d7e008e | 510 | if (dbr_sequence_length ()) |
8aa2a305 | 511 | print_slot (final_sequence); |
b9654711 | 512 | |
8aa2a305 JW |
513 | output_asm_insn ("mov.l r13,@-r15", 0); |
514 | output_asm_insn ("mov.l %O0,r13", &thislab); | |
515 | output_asm_insn ("jmp @r13", 0); | |
516 | output_asm_insn ("mov.l @r15+,r13", 0); | |
0d7e008e | 517 | output_asm_insn (".align 2", 0); |
d3ae8277 | 518 | ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (thislab)); |
0d7e008e SC |
519 | output_asm_insn (".long %O0", &op); |
520 | return ""; | |
521 | } | |
bc45ade3 | 522 | |
8aa2a305 JW |
523 | /* Local label counter, used for constants in the pool and inside |
524 | pattern branches. */ | |
525 | ||
526 | static int lf = 100; | |
527 | ||
528 | /* Output code for ordinary branches. */ | |
529 | ||
bc45ade3 | 530 | char * |
8aa2a305 | 531 | output_branch (logic, insn, operands) |
bc45ade3 | 532 | int logic; |
b9654711 | 533 | rtx insn; |
8aa2a305 | 534 | rtx *operands; |
bc45ade3 | 535 | { |
bc45ade3 | 536 | int label = lf++; |
8e87e161 | 537 | |
bc45ade3 SC |
538 | switch (get_attr_length (insn)) |
539 | { | |
540 | case 2: | |
22e1ebf1 JW |
541 | /* A branch with an unfilled delay slot. */ |
542 | case 4: | |
543 | /* Simple branch in range -252..+258 bytes */ | |
b9654711 | 544 | return logic ? "bt%. %l0" : "bf%. %l0"; |
bc45ade3 SC |
545 | |
546 | case 6: | |
22e1ebf1 JW |
547 | /* A branch with an unfilled delay slot. */ |
548 | case 8: | |
16bea517 | 549 | /* Branch in range -4092..+4098 bytes. */ |
b9654711 | 550 | { |
8aa2a305 JW |
551 | /* The call to print_slot will clobber the operands. */ |
552 | rtx op0 = operands[0]; | |
b9654711 | 553 | |
79b2746a JW |
554 | /* If the instruction in the delay slot is annulled (true), then |
555 | there is no delay slot where we can put it now. The only safe | |
556 | place for it is after the label. */ | |
557 | ||
16bea517 | 558 | if (final_sequence) |
b9654711 | 559 | { |
79b2746a JW |
560 | fprintf (asm_out_file, "\tb%c%s\tLF%d\n", logic ? 'f' : 't', |
561 | INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0)) | |
562 | ? "" : ".s", label); | |
563 | if (! INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0))) | |
564 | print_slot (final_sequence); | |
b9654711 | 565 | } |
b9654711 | 566 | else |
8aa2a305 | 567 | fprintf (asm_out_file, "\tb%c\tLF%d\n", logic ? 'f' : 't', label); |
b9654711 | 568 | |
8aa2a305 JW |
569 | output_asm_insn ("bra %l0", &op0); |
570 | fprintf (asm_out_file, "\tnop\n"); | |
b9654711 | 571 | fprintf (asm_out_file, "LF%d:\n", label); |
79b2746a JW |
572 | |
573 | if (final_sequence | |
574 | && INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0))) | |
575 | print_slot (final_sequence); | |
b9654711 | 576 | } |
bc45ade3 SC |
577 | return ""; |
578 | ||
8aa2a305 JW |
579 | case 16: |
580 | /* A branch with an unfilled delay slot. */ | |
581 | case 18: | |
582 | /* Branches a long way away. */ | |
583 | { | |
584 | /* The call to print_slot will clobber the operands. */ | |
585 | rtx op0 = operands[0]; | |
bc45ade3 | 586 | |
79b2746a JW |
587 | /* If the instruction in the delay slot is annulled (true), then |
588 | there is no delay slot where we can put it now. The only safe | |
589 | place for it is after the label. */ | |
590 | ||
8aa2a305 JW |
591 | if (final_sequence) |
592 | { | |
79b2746a JW |
593 | fprintf (asm_out_file, "\tb%c%s\tLF%d\n", logic ? 'f' : 't', |
594 | INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0)) | |
595 | ? "" : ".s", label); | |
596 | if (! INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0))) | |
597 | print_slot (final_sequence); | |
8aa2a305 JW |
598 | } |
599 | else | |
600 | fprintf (asm_out_file, "\tb%c\tLF%d\n", logic ? 'f' : 't', label); | |
bc45ade3 | 601 | |
8aa2a305 JW |
602 | output_far_jump (insn, op0); |
603 | fprintf (asm_out_file, "LF%d:\n", label); | |
79b2746a JW |
604 | |
605 | if (final_sequence | |
606 | && INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0))) | |
607 | print_slot (final_sequence); | |
8aa2a305 | 608 | } |
79b2746a | 609 | return ""; |
bc45ade3 | 610 | } |
8aa2a305 | 611 | return "bad"; |
bc45ade3 | 612 | } |
8e87e161 | 613 | \f |
8aa2a305 | 614 | /* A copy of the option structure defined in toplev.c. */ |
bc45ade3 | 615 | |
0d7e008e | 616 | struct option |
bc45ade3 | 617 | { |
0d7e008e SC |
618 | char *string; |
619 | int *variable; | |
620 | int on_value; | |
621 | }; | |
b9654711 | 622 | |
8aa2a305 JW |
623 | /* Output a single output option string NAME to FILE, without generating |
624 | lines longer than MAX. */ | |
625 | ||
0d7e008e SC |
626 | static int |
627 | output_option (file, sep, type, name, indent, pos, max) | |
628 | FILE *file; | |
629 | char *sep; | |
630 | char *type; | |
631 | char *name; | |
632 | char *indent; | |
633 | int pos; | |
634 | int max; | |
635 | { | |
636 | if (strlen (sep) + strlen (type) + strlen (name) + pos > max) | |
bc45ade3 | 637 | { |
0d7e008e SC |
638 | fprintf (file, indent); |
639 | return fprintf (file, "%s%s", type, name); | |
b9654711 | 640 | } |
0d7e008e SC |
641 | return pos + fprintf (file, "%s%s%s", sep, type, name); |
642 | } | |
bc45ade3 | 643 | |
8aa2a305 JW |
644 | /* A copy of the target_switches variable in toplev.c. */ |
645 | ||
0d7e008e SC |
646 | static struct |
647 | { | |
648 | char *name; | |
649 | int value; | |
8aa2a305 | 650 | } m_options[] = TARGET_SWITCHES; |
bc45ade3 | 651 | |
8aa2a305 | 652 | /* Output all options to the assembly language file. */ |
bc45ade3 | 653 | |
0d7e008e SC |
654 | static void |
655 | output_options (file, f_options, f_len, W_options, W_len, | |
656 | pos, max, sep, indent, term) | |
657 | FILE *file; | |
658 | struct option *f_options; | |
659 | struct option *W_options; | |
660 | int f_len, W_len; | |
661 | int pos; | |
662 | int max; | |
663 | char *sep; | |
664 | char *indent; | |
665 | char *term; | |
666 | { | |
667 | register int j; | |
bc45ade3 | 668 | |
0d7e008e SC |
669 | if (optimize) |
670 | pos = output_option (file, sep, "-O", "", indent, pos, max); | |
671 | if (write_symbols != NO_DEBUG) | |
672 | pos = output_option (file, sep, "-g", "", indent, pos, max); | |
0d7e008e SC |
673 | if (profile_flag) |
674 | pos = output_option (file, sep, "-p", "", indent, pos, max); | |
675 | if (profile_block_flag) | |
676 | pos = output_option (file, sep, "-a", "", indent, pos, max); | |
bc45ade3 | 677 | |
0d7e008e SC |
678 | for (j = 0; j < f_len; j++) |
679 | if (*f_options[j].variable == f_options[j].on_value) | |
680 | pos = output_option (file, sep, "-f", f_options[j].string, | |
681 | indent, pos, max); | |
bc45ade3 | 682 | |
0d7e008e SC |
683 | for (j = 0; j < W_len; j++) |
684 | if (*W_options[j].variable == W_options[j].on_value) | |
685 | pos = output_option (file, sep, "-W", W_options[j].string, | |
686 | indent, pos, max); | |
bc45ade3 | 687 | |
0d7e008e SC |
688 | for (j = 0; j < sizeof m_options / sizeof m_options[0]; j++) |
689 | if (m_options[j].name[0] != '\0' | |
690 | && m_options[j].value > 0 | |
691 | && ((m_options[j].value & target_flags) | |
692 | == m_options[j].value)) | |
693 | pos = output_option (file, sep, "-m", m_options[j].name, | |
694 | indent, pos, max); | |
bc45ade3 | 695 | |
0d7e008e | 696 | fprintf (file, term); |
0d7e008e | 697 | } |
b9654711 | 698 | |
8aa2a305 JW |
699 | /* Output to FILE the start of the assembler file. */ |
700 | ||
0d7e008e SC |
701 | void |
702 | output_file_start (file, f_options, f_len, W_options, W_len) | |
703 | FILE *file; | |
704 | struct option *f_options; | |
705 | struct option *W_options; | |
706 | int f_len, W_len; | |
bc45ade3 | 707 | { |
0d7e008e | 708 | register int pos; |
b9654711 | 709 | |
0d7e008e | 710 | output_file_directive (file, main_input_filename); |
b9654711 | 711 | |
0d7e008e SC |
712 | /* Switch to the data section so that the coffsem symbol and the |
713 | gcc2_compiled. symbol aren't in the text section. */ | |
714 | data_section (); | |
b9654711 | 715 | |
00f8ff66 | 716 | pos = fprintf (file, "\n! Hitachi SH cc1 (%s) arguments:", version_string); |
0d7e008e SC |
717 | output_options (file, f_options, f_len, W_options, W_len, |
718 | pos, 75, " ", "\n! ", "\n\n"); | |
8aa2a305 JW |
719 | |
720 | if (TARGET_LITTLE_ENDIAN) | |
721 | fprintf (file, "\t.little\n"); | |
bc45ade3 | 722 | } |
0d7e008e | 723 | \f |
16bea517 | 724 | /* Actual number of instructions used to make a shift by N. */ |
8aa2a305 | 725 | static char ashiftrt_insns[] = |
16bea517 JW |
726 | { 0,1,2,3,4,5,8,8,8,8,8,8,8,8,8,8,2,3,4,5,8,8,8,8,8,8,8,8,8,8,8,2}; |
727 | ||
728 | /* Left shift and logical right shift are the same. */ | |
8aa2a305 | 729 | static char shift_insns[] = |
16bea517 | 730 | { 0,1,1,2,2,3,3,4,1,2,2,3,3,4,3,3,1,2,2,3,3,4,3,3,2,3,3,4,4,4,3,3}; |
8aa2a305 | 731 | |
16bea517 JW |
732 | /* Individual shift amounts needed to get the above length sequences. |
733 | One bit right shifts clobber the T bit, so when possible, put one bit | |
734 | shifts in the middle of the sequence, so the ends are eligible for | |
735 | branch delay slots. */ | |
8aa2a305 | 736 | static short shift_amounts[32][5] = { |
16bea517 JW |
737 | {0}, {1}, {2}, {2, 1}, |
738 | {2, 2}, {2, 1, 2}, {2, 2, 2}, {2, 2, 1, 2}, | |
739 | {8}, {8, 1}, {8, 2}, {8, 1, 2}, | |
740 | {8, 2, 2}, {8, 2, 1, 2}, {8, -2, 8}, {8, -1, 8}, | |
741 | {16}, {16, 1}, {16, 2}, {16, 1, 2}, | |
742 | {16, 2, 2}, {16, 2, 1, 2}, {16, -2, 8}, {16, -1, 8}, | |
743 | {16, 8}, {16, 1, 8}, {16, 8, 2}, {16, 8, 1, 2}, | |
1d3534c0 | 744 | {16, 8, 2, 2}, {16, -1, -2, 16}, {16, -2, 16}, {16, -1, 16}}; |
16bea517 JW |
745 | |
746 | /* This is used in length attributes in sh.md to help compute the length | |
747 | of arbitrary constant shift instructions. */ | |
bc45ade3 | 748 | |
16bea517 JW |
749 | int |
750 | shift_insns_rtx (insn) | |
751 | rtx insn; | |
752 | { | |
753 | rtx set_src = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); | |
754 | int shift_count = INTVAL (XEXP (set_src, 1)); | |
755 | enum rtx_code shift_code = GET_CODE (set_src); | |
00f8ff66 | 756 | |
16bea517 JW |
757 | switch (shift_code) |
758 | { | |
759 | case ASHIFTRT: | |
760 | return ashiftrt_insns[shift_count]; | |
761 | case LSHIFTRT: | |
762 | case ASHIFT: | |
763 | return shift_insns[shift_count]; | |
764 | default: | |
765 | abort(); | |
766 | } | |
767 | } | |
768 | ||
16bea517 | 769 | /* Return the cost of a shift. */ |
bc45ade3 | 770 | |
0d7e008e | 771 | int |
8aa2a305 JW |
772 | shiftcosts (x) |
773 | rtx x; | |
bc45ade3 | 774 | { |
8aa2a305 JW |
775 | int value = INTVAL (XEXP (x, 1)); |
776 | ||
16bea517 | 777 | /* If shift by a non constant, then this will be expensive. */ |
8aa2a305 | 778 | if (GET_CODE (XEXP (x, 1)) != CONST_INT) |
00f8ff66 | 779 | { |
20b04867 JW |
780 | if (TARGET_SH3) |
781 | return 2; | |
782 | /* If not an sh3 then we don't even have an instruction for it. */ | |
00f8ff66 SC |
783 | return 20; |
784 | } | |
bc45ade3 | 785 | |
16bea517 | 786 | /* Otherwise, return the true cost in instructions. */ |
8aa2a305 | 787 | if (GET_CODE (x) == ASHIFTRT) |
49b6d06b JW |
788 | { |
789 | int cost = ashiftrt_insns[value]; | |
790 | /* If SH3, then we put the constant in a reg and use shad. */ | |
791 | if (TARGET_SH3 && cost > 3) | |
792 | cost = 3; | |
793 | return cost; | |
794 | } | |
8aa2a305 JW |
795 | else |
796 | return shift_insns[value]; | |
0d7e008e | 797 | } |
b9654711 | 798 | |
8aa2a305 JW |
799 | /* Return the cost of an AND operation. */ |
800 | ||
8e87e161 | 801 | int |
8aa2a305 JW |
802 | andcosts (x) |
803 | rtx x; | |
0d7e008e SC |
804 | { |
805 | int i; | |
8aa2a305 | 806 | |
a6f71af5 | 807 | /* Anding with a register is a single cycle and instruction. */ |
8aa2a305 | 808 | if (GET_CODE (XEXP (x, 1)) != CONST_INT) |
a6f71af5 | 809 | return 1; |
8aa2a305 JW |
810 | |
811 | i = INTVAL (XEXP (x, 1)); | |
a6f71af5 | 812 | /* These constants are single cycle extu.[bw] instructions. */ |
0d7e008e | 813 | if (i == 0xff || i == 0xffff) |
a6f71af5 JW |
814 | return 1; |
815 | /* Constants that can be used in an and immediate instruction is a single | |
816 | cycle, but this requires r0, so make it a little more expensive. */ | |
817 | if (CONST_OK_FOR_L (i)) | |
0d7e008e | 818 | return 2; |
a6f71af5 JW |
819 | /* Constants that can be loaded with a mov immediate and an and. |
820 | This case is probably unnecessary. */ | |
0d7e008e | 821 | if (CONST_OK_FOR_I (i)) |
a6f71af5 JW |
822 | return 2; |
823 | /* Any other constants requires a 2 cycle pc-relative load plus an and. | |
824 | This case is probably unnecessary. */ | |
825 | return 3; | |
0d7e008e | 826 | } |
d3ae8277 | 827 | |
16bea517 | 828 | /* Return the cost of a multiply. */ |
0d7e008e | 829 | int |
8aa2a305 JW |
830 | multcosts (x) |
831 | rtx x; | |
0d7e008e SC |
832 | { |
833 | if (TARGET_SH2) | |
d3ae8277 SC |
834 | { |
835 | /* We have a mul insn, so we can never take more than the mul and the | |
a7771f78 | 836 | read of the mac reg, but count more because of the latency and extra |
16bea517 | 837 | reg usage. */ |
d3ae8277 | 838 | if (TARGET_SMALLCODE) |
8e87e161 | 839 | return 2; |
a7771f78 | 840 | return 3; |
d3ae8277 SC |
841 | } |
842 | ||
a7771f78 | 843 | /* If we're aiming at small code, then just count the number of |
16bea517 | 844 | insns in a multiply call sequence. */ |
8e87e161 | 845 | if (TARGET_SMALLCODE) |
8aa2a305 | 846 | return 5; |
d3ae8277 | 847 | |
16bea517 | 848 | /* Otherwise count all the insns in the routine we'd be calling too. */ |
d3ae8277 | 849 | return 20; |
0d7e008e | 850 | } |
b9654711 | 851 | |
16bea517 | 852 | /* Code to expand a shift. */ |
b9654711 | 853 | |
0d7e008e SC |
854 | void |
855 | gen_ashift (type, n, reg) | |
856 | int type; | |
857 | int n; | |
858 | rtx reg; | |
859 | { | |
16bea517 JW |
860 | /* Negative values here come from the shift_amounts array. */ |
861 | if (n < 0) | |
862 | { | |
863 | if (type == ASHIFT) | |
864 | type = LSHIFTRT; | |
865 | else | |
866 | type = ASHIFT; | |
867 | n = -n; | |
868 | } | |
869 | ||
0d7e008e | 870 | switch (type) |
bc45ade3 | 871 | { |
0d7e008e SC |
872 | case ASHIFTRT: |
873 | emit_insn (gen_ashrsi3_k (reg, reg, GEN_INT (n))); | |
874 | break; | |
875 | case LSHIFTRT: | |
16bea517 JW |
876 | if (n == 1) |
877 | emit_insn (gen_lshrsi3_m (reg, reg, GEN_INT (n))); | |
878 | else | |
879 | emit_insn (gen_lshrsi3_k (reg, reg, GEN_INT (n))); | |
0d7e008e SC |
880 | break; |
881 | case ASHIFT: | |
5325c0fa | 882 | emit_insn (gen_ashlsi3_k (reg, reg, GEN_INT (n))); |
0d7e008e | 883 | break; |
bc45ade3 | 884 | } |
bc45ade3 | 885 | } |
bc45ade3 | 886 | |
8aa2a305 JW |
887 | /* Output RTL to split a constant shift into its component SH constant |
888 | shift instructions. */ | |
889 | ||
0d7e008e SC |
890 | int |
891 | gen_shifty_op (code, operands) | |
892 | int code; | |
893 | rtx *operands; | |
bc45ade3 | 894 | { |
16bea517 | 895 | int value = INTVAL (operands[2]); |
8aa2a305 | 896 | int max, i; |
00f8ff66 | 897 | |
8aa2a305 | 898 | if (value == 31) |
16bea517 | 899 | { |
8aa2a305 | 900 | if (code == LSHIFTRT) |
0d7e008e | 901 | { |
8aa2a305 JW |
902 | emit_insn (gen_rotlsi3_1 (operands[0], operands[0])); |
903 | emit_insn (gen_movt (operands[0])); | |
904 | return; | |
16bea517 | 905 | } |
8aa2a305 | 906 | else if (code == ASHIFT) |
16bea517 | 907 | { |
8aa2a305 JW |
908 | /* There is a two instruction sequence for 31 bit left shifts, |
909 | but it requires r0. */ | |
910 | if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 0) | |
0d7e008e | 911 | { |
8aa2a305 JW |
912 | emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx)); |
913 | emit_insn (gen_rotlsi3_31 (operands[0], operands[0])); | |
914 | return; | |
0d7e008e | 915 | } |
16bea517 | 916 | } |
8aa2a305 | 917 | } |
c17f53a8 JW |
918 | else if (value == 0) |
919 | { | |
920 | /* This can happen when not optimizing. We must output something here | |
921 | to prevent the compiler from aborting in final.c after the try_split | |
922 | call. */ | |
923 | emit_insn (gen_nop ()); | |
924 | return; | |
925 | } | |
a9f71ad8 | 926 | |
8aa2a305 JW |
927 | max = shift_insns[value]; |
928 | for (i = 0; i < max; i++) | |
929 | gen_ashift (code, shift_amounts[value][i], operands[0]); | |
930 | } | |
931 | ||
932 | /* Output RTL for an arithmetic right shift. */ | |
933 | ||
934 | /* ??? Rewrite to use super-optimizer sequences. */ | |
935 | ||
936 | int | |
937 | expand_ashiftrt (operands) | |
938 | rtx *operands; | |
939 | { | |
940 | rtx wrk; | |
941 | char func[18]; | |
942 | tree func_name; | |
943 | int value; | |
944 | ||
49b6d06b | 945 | if (TARGET_SH3) |
20b04867 | 946 | { |
49b6d06b JW |
947 | if (GET_CODE (operands[2]) != CONST_INT) |
948 | { | |
949 | rtx count = copy_to_mode_reg (SImode, operands[2]); | |
950 | emit_insn (gen_negsi2 (count, count)); | |
951 | emit_insn (gen_ashrsi3_d (operands[0], operands[1], count)); | |
952 | return 1; | |
953 | } | |
954 | else if (ashiftrt_insns[INTVAL (operands[2])] > 3) | |
955 | { | |
956 | rtx count = force_reg (SImode, GEN_INT (- INTVAL (operands[2]))); | |
957 | emit_insn (gen_ashrsi3_d (operands[0], operands[1], count)); | |
958 | return 1; | |
959 | } | |
20b04867 | 960 | } |
8aa2a305 JW |
961 | if (GET_CODE (operands[2]) != CONST_INT) |
962 | return 0; | |
963 | ||
964 | value = INTVAL (operands[2]); | |
965 | ||
966 | if (value == 31) | |
967 | { | |
968 | emit_insn (gen_ashrsi2_31 (operands[0], operands[1])); | |
969 | return 1; | |
970 | } | |
971 | else if (value >= 16 && value <= 19) | |
972 | { | |
973 | wrk = gen_reg_rtx (SImode); | |
974 | emit_insn (gen_ashrsi2_16 (wrk, operands[1])); | |
975 | value -= 16; | |
976 | while (value--) | |
977 | gen_ashift (ASHIFTRT, 1, wrk); | |
978 | emit_move_insn (operands[0], wrk); | |
979 | return 1; | |
a9f71ad8 | 980 | } |
8aa2a305 JW |
981 | /* Expand a short sequence inline, longer call a magic routine. */ |
982 | else if (value <= 5) | |
983 | { | |
984 | wrk = gen_reg_rtx (SImode); | |
985 | emit_move_insn (wrk, operands[1]); | |
986 | while (value--) | |
987 | gen_ashift (ASHIFTRT, 1, wrk); | |
988 | emit_move_insn (operands[0], wrk); | |
989 | return 1; | |
990 | } | |
991 | ||
992 | wrk = gen_reg_rtx (Pmode); | |
993 | ||
994 | /* Load the value into an arg reg and call a helper. */ | |
995 | emit_move_insn (gen_rtx (REG, SImode, 4), operands[1]); | |
996 | sprintf (func, "__ashiftrt_r4_%d", value); | |
997 | func_name = get_identifier (func); | |
998 | emit_move_insn (wrk, gen_rtx (SYMBOL_REF, Pmode, | |
999 | IDENTIFIER_POINTER (func_name))); | |
1000 | emit_insn (gen_ashrsi3_n (GEN_INT (value), wrk)); | |
1001 | emit_move_insn (operands[0], gen_rtx (REG, SImode, 4)); | |
1002 | return 1; | |
bc45ade3 | 1003 | } |
8aa2a305 JW |
1004 | \f |
1005 | /* The SH cannot load a large constant into a register, constants have to | |
1006 | come from a pc relative load. The reference of a pc relative load | |
1007 | instruction must be less than 1k infront of the instruction. This | |
1008 | means that we often have to dump a constant inside a function, and | |
1009 | generate code to branch around it. | |
bc45ade3 | 1010 | |
8aa2a305 JW |
1011 | It is important to minimize this, since the branches will slow things |
1012 | down and make things bigger. | |
1013 | ||
1014 | Worst case code looks like: | |
1015 | ||
1016 | mov.l L1,rn | |
1017 | bra L2 | |
1018 | nop | |
1019 | align | |
1020 | L1: .long value | |
1021 | L2: | |
1022 | .. | |
1023 | ||
1024 | mov.l L3,rn | |
1025 | bra L4 | |
1026 | nop | |
1027 | align | |
1028 | L3: .long value | |
1029 | L4: | |
1030 | .. | |
1031 | ||
1032 | We fix this by performing a scan before scheduling, which notices which | |
1033 | instructions need to have their operands fetched from the constant table | |
1034 | and builds the table. | |
1035 | ||
1036 | The algorithm is: | |
1037 | ||
1038 | scan, find an instruction which needs a pcrel move. Look forward, find the | |
1039 | last barrier which is within MAX_COUNT bytes of the requirement. | |
1040 | If there isn't one, make one. Process all the instructions between | |
1041 | the find and the barrier. | |
1042 | ||
1043 | In the above example, we can tell that L3 is within 1k of L1, so | |
1044 | the first move can be shrunk from the 3 insn+constant sequence into | |
1045 | just 1 insn, and the constant moved to L3 to make: | |
1046 | ||
1047 | mov.l L1,rn | |
1048 | .. | |
1049 | mov.l L3,rn | |
1050 | bra L4 | |
1051 | nop | |
1052 | align | |
1053 | L3:.long value | |
1054 | L4:.long value | |
1055 | ||
1056 | Then the second move becomes the target for the shortening process. */ | |
1057 | ||
1058 | typedef struct | |
1059 | { | |
1060 | rtx value; /* Value in table. */ | |
1061 | rtx label; /* Label of value. */ | |
1062 | enum machine_mode mode; /* Mode of value. */ | |
1063 | } pool_node; | |
1064 | ||
1065 | /* The maximum number of constants that can fit into one pool, since | |
1066 | the pc relative range is 0...1020 bytes and constants are at least 4 | |
1067 | bytes long. */ | |
1068 | ||
1069 | #define MAX_POOL_SIZE (1020/4) | |
1070 | static pool_node pool_vector[MAX_POOL_SIZE]; | |
1071 | static int pool_size; | |
1072 | ||
1073 | /* ??? If we need a constant in HImode which is the truncated value of a | |
1074 | constant we need in SImode, we could combine the two entries thus saving | |
1075 | two bytes. Is this common enough to be worth the effort of implementing | |
1076 | it? */ | |
1077 | ||
1078 | /* ??? This stuff should be done at the same time that we shorten branches. | |
1079 | As it is now, we must assume that all branches are the maximum size, and | |
1080 | this causes us to almost always output constant pools sooner than | |
1081 | necessary. */ | |
1082 | ||
1083 | /* Add a constant to the pool and return its label. */ | |
1084 | ||
1085 | static rtx | |
1086 | add_constant (x, mode) | |
1087 | rtx x; | |
1088 | enum machine_mode mode; | |
0d7e008e SC |
1089 | { |
1090 | int i; | |
8aa2a305 JW |
1091 | rtx lab; |
1092 | ||
1093 | /* First see if we've already got it. */ | |
1094 | for (i = 0; i < pool_size; i++) | |
0d7e008e | 1095 | { |
8aa2a305 JW |
1096 | if (x->code == pool_vector[i].value->code |
1097 | && mode == pool_vector[i].mode) | |
0d7e008e | 1098 | { |
8aa2a305 JW |
1099 | if (x->code == CODE_LABEL) |
1100 | { | |
1101 | if (XINT (x, 3) != XINT (pool_vector[i].value, 3)) | |
1102 | continue; | |
1103 | } | |
1104 | if (rtx_equal_p (x, pool_vector[i].value)) | |
1105 | return pool_vector[i].label; | |
0d7e008e | 1106 | } |
0d7e008e | 1107 | } |
b9654711 | 1108 | |
8aa2a305 JW |
1109 | /* Need a new one. */ |
1110 | pool_vector[pool_size].value = x; | |
1111 | lab = gen_label_rtx (); | |
1112 | pool_vector[pool_size].mode = mode; | |
1113 | pool_vector[pool_size].label = lab; | |
1114 | pool_size++; | |
1115 | return lab; | |
0d7e008e | 1116 | } |
16bea517 JW |
1117 | |
1118 | /* Output the literal table. */ | |
b9654711 | 1119 | |
b9654711 | 1120 | static void |
0d7e008e SC |
1121 | dump_table (scan) |
1122 | rtx scan; | |
b9654711 | 1123 | { |
0d7e008e | 1124 | int i; |
0d7e008e | 1125 | int need_align = 1; |
b9654711 | 1126 | |
16bea517 | 1127 | /* Do two passes, first time dump out the HI sized constants. */ |
b9654711 | 1128 | |
0d7e008e | 1129 | for (i = 0; i < pool_size; i++) |
b9654711 | 1130 | { |
8aa2a305 JW |
1131 | pool_node *p = &pool_vector[i]; |
1132 | ||
0d7e008e SC |
1133 | if (p->mode == HImode) |
1134 | { | |
1135 | if (need_align) | |
1136 | { | |
1137 | scan = emit_insn_after (gen_align_2 (), scan); | |
1138 | need_align = 0; | |
1139 | } | |
1140 | scan = emit_label_after (p->label, scan); | |
1141 | scan = emit_insn_after (gen_consttable_2 (p->value), scan); | |
1142 | } | |
b9654711 | 1143 | } |
8aa2a305 | 1144 | |
0d7e008e | 1145 | need_align = 1; |
b9654711 | 1146 | |
0d7e008e | 1147 | for (i = 0; i < pool_size; i++) |
b9654711 | 1148 | { |
8aa2a305 | 1149 | pool_node *p = &pool_vector[i]; |
b9654711 | 1150 | |
0d7e008e | 1151 | switch (p->mode) |
b9654711 | 1152 | { |
0d7e008e SC |
1153 | case HImode: |
1154 | break; | |
1155 | case SImode: | |
1156 | if (need_align) | |
b9654711 | 1157 | { |
0d7e008e | 1158 | need_align = 0; |
d3ae8277 | 1159 | scan = emit_label_after (gen_label_rtx (), scan); |
0d7e008e | 1160 | scan = emit_insn_after (gen_align_4 (), scan); |
b9654711 | 1161 | } |
0d7e008e SC |
1162 | scan = emit_label_after (p->label, scan); |
1163 | scan = emit_insn_after (gen_consttable_4 (p->value), scan); | |
1164 | break; | |
1165 | case DImode: | |
1166 | if (need_align) | |
1167 | { | |
1168 | need_align = 0; | |
d3ae8277 | 1169 | scan = emit_label_after (gen_label_rtx (), scan); |
0d7e008e SC |
1170 | scan = emit_insn_after (gen_align_4 (), scan); |
1171 | } | |
1172 | scan = emit_label_after (p->label, scan); | |
1173 | scan = emit_insn_after (gen_consttable_8 (p->value), scan); | |
1174 | break; | |
1175 | default: | |
1176 | abort (); | |
1177 | break; | |
b9654711 SC |
1178 | } |
1179 | } | |
b9654711 | 1180 | |
0d7e008e SC |
1181 | scan = emit_insn_after (gen_consttable_end (), scan); |
1182 | scan = emit_barrier_after (scan); | |
1183 | pool_size = 0; | |
1184 | } | |
b9654711 | 1185 | |
8aa2a305 JW |
1186 | /* Return non-zero if constant would be an ok source for a |
1187 | mov.w instead of a mov.l. */ | |
b9654711 | 1188 | |
16bea517 | 1189 | static int |
8aa2a305 | 1190 | hi_const (src) |
0d7e008e | 1191 | rtx src; |
0d7e008e | 1192 | { |
8aa2a305 JW |
1193 | return (GET_CODE (src) == CONST_INT |
1194 | && INTVAL (src) >= -32768 | |
1195 | && INTVAL (src) <= 32767); | |
b9654711 SC |
1196 | } |
1197 | ||
8aa2a305 JW |
1198 | /* Non-zero if the insn is a move instruction which needs to be fixed. */ |
1199 | ||
1200 | /* ??? For a DImode/DFmode moves, we don't need to fix it if each half of the | |
1201 | CONST_DOUBLE input value is CONST_OK_FOR_I. For a SFmode move, we don't | |
1202 | need to fix it if the input value is CONST_OK_FOR_I. */ | |
1203 | ||
1204 | static int | |
1205 | broken_move (insn) | |
1206 | rtx insn; | |
b9654711 | 1207 | { |
8aa2a305 JW |
1208 | if (GET_CODE (insn) == INSN |
1209 | && GET_CODE (PATTERN (insn)) == SET | |
1210 | /* We can load any 8 bit value if we don't care what the high | |
1211 | order bits end up as. */ | |
1212 | && GET_MODE (SET_DEST (PATTERN (insn))) != QImode | |
1213 | && CONSTANT_P (SET_SRC (PATTERN (insn))) | |
1214 | && (GET_CODE (SET_SRC (PATTERN (insn))) != CONST_INT | |
1215 | || ! CONST_OK_FOR_I (INTVAL (SET_SRC (PATTERN (insn)))))) | |
d3ae8277 SC |
1216 | return 1; |
1217 | ||
8aa2a305 | 1218 | return 0; |
b9654711 | 1219 | } |
b9654711 | 1220 | |
8aa2a305 JW |
1221 | /* Find the last barrier from insn FROM which is close enough to hold the |
1222 | constant pool. If we can't find one, then create one near the end of | |
1223 | the range. */ | |
b9654711 | 1224 | |
5325c0fa JW |
1225 | /* ??? It would be good to put constant pool tables between a case jump and |
1226 | the jump table. This fails for two reasons. First, there is no | |
1227 | barrier after the case jump. This is a bug in the casesi pattern. | |
1228 | Second, inserting the table here may break the mova instruction that | |
1229 | loads the jump table address, by moving the jump table too far away. | |
1230 | We fix that problem by never outputting the constant pool between a mova | |
1231 | and its label. */ | |
1232 | ||
8aa2a305 | 1233 | static rtx |
06c386ea SC |
1234 | find_barrier (from) |
1235 | rtx from; | |
b9654711 | 1236 | { |
0d7e008e SC |
1237 | int count_si = 0; |
1238 | int count_hi = 0; | |
1239 | int found_hi = 0; | |
1240 | int found_si = 0; | |
1241 | rtx found_barrier = 0; | |
5325c0fa | 1242 | rtx found_mova = 0; |
c17f53a8 JW |
1243 | int si_limit; |
1244 | int hi_limit; | |
8aa2a305 JW |
1245 | |
1246 | /* For HImode: range is 510, add 4 because pc counts from address of | |
1247 | second instruction after this one, subtract 2 for the jump instruction | |
1248 | that we may need to emit before the table. This gives 512. | |
1249 | For SImode: range is 1020, add 4 because pc counts from address of | |
1250 | second instruction after this one, subtract 2 in case pc is 2 byte | |
1251 | aligned, subtract 2 for the jump instruction that we may need to emit | |
1252 | before the table. This gives 1020. */ | |
c17f53a8 JW |
1253 | |
1254 | /* If not optimizing, then it is possible that the jump instruction we add | |
1255 | won't be shortened, and thus will have a length of 14 instead of 2. | |
1256 | We must adjust the limits downwards to account for this, giving a limit | |
1257 | of 1008 for SImode and 500 for HImode. */ | |
1258 | ||
1259 | if (optimize) | |
1260 | { | |
1261 | si_limit = 1020; | |
1262 | hi_limit = 512; | |
1263 | } | |
1264 | else | |
1265 | { | |
1266 | si_limit = 1008; | |
1267 | hi_limit = 500; | |
1268 | } | |
1269 | ||
1270 | while (from && count_si < si_limit && count_hi < hi_limit) | |
0d7e008e | 1271 | { |
5dbcc9c0 | 1272 | int inc = get_attr_length (from); |
8aa2a305 | 1273 | |
0d7e008e | 1274 | if (GET_CODE (from) == BARRIER) |
8aa2a305 JW |
1275 | found_barrier = from; |
1276 | ||
8aa2a305 | 1277 | if (broken_move (from)) |
0d7e008e | 1278 | { |
c17f53a8 JW |
1279 | rtx pat = PATTERN (from); |
1280 | rtx src = SET_SRC (pat); | |
1281 | rtx dst = SET_DEST (pat); | |
1282 | enum machine_mode mode = GET_MODE (dst); | |
1283 | ||
1284 | /* We must explicitly check the mode, because sometimes the | |
1285 | front end will generate code to load unsigned constants into | |
1286 | HImode targets without properly sign extending them. */ | |
1287 | if (mode == HImode || (mode == SImode && hi_const (src))) | |
00e94d65 RK |
1288 | { |
1289 | found_hi = 1; | |
1290 | /* We put the short constants before the long constants, so | |
1291 | we must count the length of short constants in the range | |
1292 | for the long constants. */ | |
1293 | /* ??? This isn't optimal, but is easy to do. */ | |
1294 | if (found_si) | |
1295 | count_si += 2; | |
1296 | } | |
0d7e008e SC |
1297 | else |
1298 | found_si = 1; | |
0d7e008e | 1299 | } |
5325c0fa | 1300 | |
5325c0fa JW |
1301 | if (GET_CODE (from) == INSN |
1302 | && GET_CODE (PATTERN (from)) == SET | |
16bea517 JW |
1303 | && GET_CODE (SET_SRC (PATTERN (from))) == UNSPEC |
1304 | && XINT (SET_SRC (PATTERN (from)), 1) == 1) | |
5325c0fa JW |
1305 | found_mova = from; |
1306 | else if (GET_CODE (from) == JUMP_INSN | |
1307 | && (GET_CODE (PATTERN (from)) == ADDR_VEC | |
1308 | || GET_CODE (PATTERN (from)) == ADDR_DIFF_VEC)) | |
1309 | found_mova = 0; | |
1310 | ||
0d7e008e SC |
1311 | if (found_si) |
1312 | count_si += inc; | |
1313 | if (found_hi) | |
1314 | count_hi += inc; | |
1315 | from = NEXT_INSN (from); | |
1316 | } | |
1317 | ||
5325c0fa JW |
1318 | /* Insert the constant pool table before the mova instruction, to prevent |
1319 | the mova label reference from going out of range. */ | |
1320 | if (found_mova) | |
1321 | from = found_mova; | |
1322 | ||
8aa2a305 | 1323 | if (! found_barrier) |
b9654711 | 1324 | { |
8aa2a305 JW |
1325 | /* We didn't find a barrier in time to dump our stuff, |
1326 | so we'll make one. */ | |
0d7e008e | 1327 | rtx label = gen_label_rtx (); |
8aa2a305 | 1328 | |
5dbcc9c0 RK |
1329 | /* If we exceeded the range, then we must back up over the last |
1330 | instruction we looked at. Otherwise, we just need to undo the | |
1331 | NEXT_INSN at the end of the loop. */ | |
c17f53a8 | 1332 | if (count_hi > hi_limit || count_si > si_limit) |
5dbcc9c0 RK |
1333 | from = PREV_INSN (PREV_INSN (from)); |
1334 | else | |
1335 | from = PREV_INSN (from); | |
1336 | ||
8aa2a305 JW |
1337 | /* Walk back to be just before any jump or label. |
1338 | Putting it before a label reduces the number of times the branch | |
1339 | around the constant pool table will be hit. Putting it before | |
1340 | a jump makes it more likely that the bra delay slot will be | |
1341 | filled. */ | |
1342 | while (GET_CODE (from) == JUMP_INSN || GET_CODE (from) == NOTE | |
8e87e161 | 1343 | || GET_CODE (from) == CODE_LABEL) |
8aa2a305 JW |
1344 | from = PREV_INSN (from); |
1345 | ||
0d7e008e SC |
1346 | from = emit_jump_insn_after (gen_jump (label), from); |
1347 | JUMP_LABEL (from) = label; | |
e081ed26 | 1348 | LABEL_NUSES (label) = 1; |
0d7e008e SC |
1349 | found_barrier = emit_barrier_after (from); |
1350 | emit_label_after (label, found_barrier); | |
b9654711 | 1351 | } |
b9654711 | 1352 | |
8aa2a305 | 1353 | return found_barrier; |
0d7e008e | 1354 | } |
b9654711 | 1355 | |
933c3ba3 JW |
1356 | /* See if the only way in which INSN uses REG is by calling it, or by |
1357 | setting it while calling it. Set *SET to a SET rtx if the register | |
1358 | is set by INSN. */ | |
1359 | ||
1360 | static int | |
1361 | noncall_uses_reg (reg, insn, set) | |
1362 | rtx reg; | |
1363 | rtx insn; | |
1364 | rtx *set; | |
1365 | { | |
1366 | rtx pattern; | |
1367 | ||
1368 | *set = NULL_RTX; | |
1369 | ||
1370 | if (GET_CODE (insn) != CALL_INSN) | |
1371 | { | |
1372 | /* We don't use rtx_equal_p because we don't care if the mode is | |
1373 | different. */ | |
1374 | pattern = single_set (insn); | |
1375 | if (pattern | |
1376 | && GET_CODE (SET_DEST (pattern)) == REG | |
1377 | && REGNO (reg) == REGNO (SET_DEST (pattern))) | |
1378 | { | |
1379 | *set = pattern; | |
1380 | return 0; | |
1381 | } | |
1382 | ||
1383 | return 1; | |
1384 | } | |
1385 | ||
1386 | pattern = PATTERN (insn); | |
1387 | ||
1388 | if (GET_CODE (pattern) == PARALLEL) | |
1389 | { | |
1390 | int i; | |
1391 | ||
1392 | for (i = XVECLEN (pattern, 0) - 1; i >= 1; i--) | |
1393 | if (reg_mentioned_p (reg, XVECEXP (pattern, 0, i))) | |
1394 | return 1; | |
1395 | pattern = XVECEXP (pattern, 0, 0); | |
1396 | } | |
1397 | ||
1398 | if (GET_CODE (pattern) == SET) | |
1399 | { | |
1400 | if (reg_mentioned_p (reg, SET_DEST (pattern))) | |
1401 | { | |
1402 | /* We don't use rtx_equal_p, because we don't care if the | |
1403 | mode is different. */ | |
1404 | if (GET_CODE (SET_DEST (pattern)) != REG | |
1405 | || REGNO (reg) != REGNO (SET_DEST (pattern))) | |
1406 | return 1; | |
1407 | ||
1408 | *set = pattern; | |
1409 | } | |
1410 | ||
1411 | pattern = SET_SRC (pattern); | |
1412 | } | |
1413 | ||
1414 | if (GET_CODE (pattern) != CALL | |
1415 | || GET_CODE (XEXP (pattern, 0)) != MEM | |
1416 | || ! rtx_equal_p (reg, XEXP (XEXP (pattern, 0), 0))) | |
1417 | return 1; | |
1418 | ||
1419 | return 0; | |
1420 | } | |
1421 | ||
8aa2a305 | 1422 | /* Exported to toplev.c. |
b9654711 | 1423 | |
933c3ba3 JW |
1424 | Do a final pass over the function, just before delayed branch |
1425 | scheduling. */ | |
b9654711 | 1426 | |
0d7e008e SC |
1427 | void |
1428 | machine_dependent_reorg (first) | |
1429 | rtx first; | |
1430 | { | |
1431 | rtx insn; | |
8aa2a305 | 1432 | |
933c3ba3 JW |
1433 | /* If relaxing, generate pseudo-ops to associate function calls with |
1434 | the symbols they call. It does no harm to not generate these | |
1435 | pseudo-ops. However, when we can generate them, it enables to | |
1436 | linker to potentially relax the jsr to a bsr, and eliminate the | |
1437 | register load and, possibly, the constant pool entry. */ | |
1438 | ||
1439 | if (TARGET_RELAX) | |
1440 | { | |
1441 | /* Remove all REG_LABEL notes. We want to use them for our own | |
1442 | purposes. This works because none of the remaining passes | |
1443 | need to look at them. | |
1444 | ||
1445 | ??? But it may break in the future. We should use a machine | |
1446 | dependent REG_NOTE, or some other approach entirely. */ | |
1447 | for (insn = first; insn; insn = NEXT_INSN (insn)) | |
1448 | { | |
1449 | if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') | |
1450 | { | |
1451 | rtx note; | |
1452 | ||
1453 | while ((note = find_reg_note (insn, REG_LABEL, NULL_RTX)) != 0) | |
1454 | remove_note (insn, note); | |
1455 | } | |
1456 | } | |
1457 | ||
1458 | for (insn = first; insn; insn = NEXT_INSN (insn)) | |
1459 | { | |
1460 | rtx pattern, reg, link, set, scan, dies, label; | |
1461 | int rescan = 0, foundinsn = 0; | |
1462 | ||
1463 | if (GET_CODE (insn) != CALL_INSN) | |
1464 | continue; | |
1465 | ||
1466 | pattern = PATTERN (insn); | |
1467 | ||
1468 | if (GET_CODE (pattern) == PARALLEL) | |
1469 | pattern = XVECEXP (pattern, 0, 0); | |
1470 | if (GET_CODE (pattern) == SET) | |
1471 | pattern = SET_SRC (pattern); | |
1472 | ||
1473 | if (GET_CODE (pattern) != CALL | |
1474 | || GET_CODE (XEXP (pattern, 0)) != MEM) | |
1475 | continue; | |
1476 | ||
1477 | reg = XEXP (XEXP (pattern, 0), 0); | |
1478 | if (GET_CODE (reg) != REG) | |
1479 | continue; | |
1480 | ||
1481 | /* This is a function call via REG. If the only uses of REG | |
1482 | between the time that it is set and the time that it dies | |
1483 | are in function calls, then we can associate all the | |
1484 | function calls with the setting of REG. */ | |
1485 | ||
1486 | for (link = LOG_LINKS (insn); link; link = XEXP (link, 1)) | |
1487 | { | |
1488 | set = single_set (XEXP (link, 0)); | |
1489 | if (set && rtx_equal_p (reg, SET_DEST (set))) | |
1490 | { | |
1491 | link = XEXP (link, 0); | |
1492 | break; | |
1493 | } | |
1494 | } | |
1495 | ||
1496 | if (! link) | |
1497 | { | |
1498 | /* ??? Sometimes global register allocation will have | |
1499 | deleted the insn pointed to by LOG_LINKS. Try | |
1500 | scanning backward to find where the register is set. */ | |
1501 | for (scan = PREV_INSN (insn); | |
1502 | scan && GET_CODE (scan) != CODE_LABEL; | |
1503 | scan = PREV_INSN (scan)) | |
1504 | { | |
1505 | if (GET_RTX_CLASS (GET_CODE (scan)) != 'i') | |
1506 | continue; | |
1507 | ||
1508 | if (! reg_mentioned_p (reg, scan)) | |
1509 | continue; | |
1510 | ||
1511 | if (noncall_uses_reg (reg, scan, &set)) | |
1512 | break; | |
1513 | ||
1514 | if (set) | |
1515 | { | |
1516 | link = scan; | |
1517 | break; | |
1518 | } | |
1519 | } | |
1520 | } | |
1521 | ||
1522 | if (! link) | |
1523 | continue; | |
1524 | ||
1525 | /* The register is set at LINK. */ | |
1526 | ||
1527 | /* We can only optimize the function call if the register is | |
1528 | being set to a symbol. In theory, we could sometimes | |
1529 | optimize calls to a constant location, but the assembler | |
1530 | and linker do not support that at present. */ | |
1531 | if (GET_CODE (SET_SRC (set)) != SYMBOL_REF | |
1532 | && GET_CODE (SET_SRC (set)) != LABEL_REF) | |
1533 | continue; | |
1534 | ||
1535 | /* Scan forward from LINK to the place where REG dies, and | |
1536 | make sure that the only insns which use REG are | |
1537 | themselves function calls. */ | |
1538 | ||
1539 | dies = NULL_RTX; | |
1540 | for (scan = NEXT_INSN (link); scan; scan = NEXT_INSN (scan)) | |
1541 | { | |
1542 | rtx scanset; | |
1543 | ||
1544 | if (GET_RTX_CLASS (GET_CODE (scan)) != 'i') | |
1545 | continue; | |
1546 | ||
1547 | /* Don't try to trace forward past a JUMP. To optimize | |
1548 | safely, we would have to check that all the | |
1549 | instructions at the jump destination did not use REG. | |
1550 | It should be safe to trace past a CODE_LABEL, because | |
1551 | we will only find the setting insn in LOG_LINKS if it | |
1552 | is in the same basic block (so probably we should | |
1553 | never find a CODE_LABEL anyhow). */ | |
1554 | ||
1555 | if (GET_CODE (insn) == JUMP_INSN) | |
1556 | break; | |
1557 | ||
1558 | if (! reg_mentioned_p (reg, scan)) | |
1559 | continue; | |
1560 | ||
1561 | if (noncall_uses_reg (reg, scan, &scanset)) | |
1562 | break; | |
1563 | ||
1564 | if (scan == insn) | |
1565 | foundinsn = 1; | |
1566 | ||
1567 | if (scan != insn && GET_CODE (scan) == CALL_INSN) | |
1568 | { | |
1569 | /* There is a function call to this register other | |
1570 | than the one we are checking. If we optimize | |
1571 | this call, we need to rescan again below. */ | |
1572 | rescan = 1; | |
1573 | } | |
1574 | ||
1575 | /* ??? We shouldn't have to worry about SCANSET here. | |
1576 | We should just be able to check for a REG_DEAD note | |
1577 | on a function call. However, the REG_DEAD notes are | |
1578 | apparently not dependable around libcalls; c-torture | |
1579 | execute/920501-2 is a test case. If SCANSET is set, | |
1580 | then this insn sets the register, so it must have | |
1581 | died earlier. Unfortunately, this will only handle | |
1582 | the cases in which the register is, in fact, set in a | |
1583 | later insn. */ | |
1584 | ||
1585 | /* ??? We shouldn't have to use FOUNDINSN here. | |
1586 | However, the LOG_LINKS fields are apparently not | |
1587 | entirely reliable around libcalls; | |
1588 | newlib/libm/math/e_pow.c is a test case. Sometimes | |
1589 | an insn will appear in LOG_LINKS even though it is | |
1590 | not the most recent insn which sets the register. */ | |
1591 | ||
1592 | if (foundinsn | |
1593 | && (scanset | |
1594 | || find_reg_note (scan, REG_DEAD, reg))) | |
1595 | { | |
1596 | dies = scan; | |
1597 | break; | |
1598 | } | |
1599 | } | |
1600 | ||
1601 | if (! dies) | |
1602 | { | |
1603 | /* Either there was a branch, or some insn used REG | |
1604 | other than as a function call address. */ | |
1605 | continue; | |
1606 | } | |
1607 | ||
1608 | /* Create a code label, and put it in a REG_LABEL note on | |
1609 | the insn which sets the register, and on each call insn | |
1610 | which uses the register. In final_prescan_insn we look | |
1611 | for the REG_LABEL notes, and output the appropriate label | |
1612 | or pseudo-op. */ | |
1613 | ||
1614 | label = gen_label_rtx (); | |
1615 | REG_NOTES (link) = gen_rtx (EXPR_LIST, REG_LABEL, label, | |
1616 | REG_NOTES (link)); | |
1617 | REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_LABEL, label, | |
1618 | REG_NOTES (insn)); | |
1619 | if (rescan) | |
1620 | { | |
1621 | scan = link; | |
1622 | do | |
1623 | { | |
1624 | scan = NEXT_INSN (scan); | |
1625 | if (scan != insn | |
1626 | && GET_CODE (scan) == CALL_INSN | |
1627 | && reg_mentioned_p (reg, scan)) | |
1628 | REG_NOTES (scan) = gen_rtx (EXPR_LIST, REG_LABEL, | |
1629 | label, REG_NOTES (scan)); | |
1630 | } | |
1631 | while (scan != dies); | |
1632 | } | |
1633 | } | |
1634 | } | |
1635 | ||
1636 | /* Scan the function looking for move instructions which have to be | |
1637 | changed to pc-relative loads and insert the literal tables. */ | |
1638 | ||
0d7e008e SC |
1639 | for (insn = first; insn; insn = NEXT_INSN (insn)) |
1640 | { | |
1641 | if (broken_move (insn)) | |
1642 | { | |
0d7e008e | 1643 | rtx scan; |
8aa2a305 JW |
1644 | /* Scan ahead looking for a barrier to stick the constant table |
1645 | behind. */ | |
0d7e008e | 1646 | rtx barrier = find_barrier (insn); |
b9654711 | 1647 | |
16bea517 | 1648 | /* Now find all the moves between the points and modify them. */ |
0d7e008e SC |
1649 | for (scan = insn; scan != barrier; scan = NEXT_INSN (scan)) |
1650 | { | |
1651 | if (broken_move (scan)) | |
1652 | { | |
1653 | rtx pat = PATTERN (scan); | |
1654 | rtx src = SET_SRC (pat); | |
1655 | rtx dst = SET_DEST (pat); | |
1656 | enum machine_mode mode = GET_MODE (dst); | |
1657 | rtx lab; | |
1658 | rtx newinsn; | |
1659 | rtx newsrc; | |
0d7e008e SC |
1660 | |
1661 | if (mode == SImode && hi_const (src)) | |
1662 | { | |
23ed92ca | 1663 | int offset = 0; |
8aa2a305 | 1664 | |
0d7e008e | 1665 | mode = HImode; |
d3ae8277 | 1666 | while (GET_CODE (dst) == SUBREG) |
23ed92ca JW |
1667 | { |
1668 | offset += SUBREG_WORD (dst); | |
1669 | dst = SUBREG_REG (dst); | |
1670 | } | |
1671 | dst = gen_rtx (REG, HImode, REGNO (dst) + offset); | |
0d7e008e | 1672 | } |
8aa2a305 | 1673 | |
0d7e008e SC |
1674 | lab = add_constant (src, mode); |
1675 | newsrc = gen_rtx (MEM, mode, | |
1676 | gen_rtx (LABEL_REF, VOIDmode, lab)); | |
8aa2a305 JW |
1677 | RTX_UNCHANGING_P (newsrc) = 1; |
1678 | newinsn = emit_insn_after (gen_rtx (SET, VOIDmode, | |
1679 | dst, newsrc), scan); | |
933c3ba3 JW |
1680 | REG_NOTES (newinsn) = REG_NOTES (scan); |
1681 | REG_NOTES (scan) = NULL_RTX; | |
c17f53a8 JW |
1682 | /* If not optimizing, then delete_insn doesn't remove the |
1683 | insn from the chain, and hence is not useful. We | |
1684 | convert the instruction to a NOTE in that case. */ | |
1685 | if (optimize) | |
1686 | delete_insn (scan); | |
1687 | else | |
1688 | { | |
1689 | PUT_CODE (scan, NOTE); | |
1690 | NOTE_LINE_NUMBER (scan) = NOTE_INSN_DELETED; | |
1691 | NOTE_SOURCE_FILE (insn) = 0; | |
1692 | } | |
0d7e008e SC |
1693 | scan = newinsn; |
1694 | } | |
1695 | } | |
1696 | dump_table (barrier); | |
1697 | } | |
1698 | } | |
b9654711 SC |
1699 | } |
1700 | ||
8aa2a305 | 1701 | /* Dump out instruction addresses, which is useful for debugging the |
933c3ba3 JW |
1702 | constant pool table stuff. |
1703 | ||
1704 | If relaxing, output the label and pseudo-ops used to link together | |
1705 | calls and the instruction which set the registers. */ | |
8aa2a305 JW |
1706 | |
1707 | /* ??? This is unnecessary, and probably should be deleted. This makes | |
1708 | the insn_addresses declaration above unnecessary. */ | |
1709 | ||
1710 | /* ??? The addresses printed by this routine for insns are nonsense for | |
1711 | insns which are inside of a sequence where none of the inner insns have | |
1712 | variable length. This is because the second pass of shorten_branches | |
1713 | does not bother to update them. */ | |
0d7e008e | 1714 | |
8e87e161 | 1715 | void |
8aa2a305 JW |
1716 | final_prescan_insn (insn, opvec, noperands) |
1717 | rtx insn; | |
1718 | rtx *opvec; | |
1719 | int noperands; | |
b9654711 | 1720 | { |
8aa2a305 JW |
1721 | if (TARGET_DUMPISIZE) |
1722 | fprintf (asm_out_file, "\n! at %04x\n", insn_addresses[INSN_UID (insn)]); | |
933c3ba3 JW |
1723 | |
1724 | if (TARGET_RELAX) | |
1725 | { | |
1726 | rtx note; | |
1727 | ||
1728 | note = find_reg_note (insn, REG_LABEL, NULL_RTX); | |
1729 | if (note) | |
1730 | { | |
1731 | rtx pattern; | |
1732 | ||
1733 | pattern = PATTERN (insn); | |
1734 | if (GET_CODE (pattern) == PARALLEL) | |
1735 | pattern = XVECEXP (pattern, 0, 0); | |
1736 | if (GET_CODE (pattern) == CALL | |
1737 | || (GET_CODE (pattern) == SET | |
1738 | && GET_CODE (SET_SRC (pattern)) == CALL)) | |
1739 | fprintf (asm_out_file, "\t.uses L%d\n", | |
1740 | CODE_LABEL_NUMBER (XEXP (note, 0))); | |
1741 | else if (GET_CODE (pattern) == SET) | |
1742 | ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", | |
1743 | CODE_LABEL_NUMBER (XEXP (note, 0))); | |
1744 | else | |
1745 | abort (); | |
1746 | } | |
1747 | } | |
0d7e008e | 1748 | } |
b9654711 | 1749 | |
8aa2a305 JW |
1750 | /* Dump out any constants accumulated in the final pass. These will |
1751 | will only be labels. */ | |
b9654711 | 1752 | |
8aa2a305 JW |
1753 | char * |
1754 | output_jump_label_table () | |
0d7e008e | 1755 | { |
8aa2a305 JW |
1756 | int i; |
1757 | ||
1758 | if (pool_size) | |
1759 | { | |
1760 | fprintf (asm_out_file, "\t.align 2\n"); | |
1761 | for (i = 0; i < pool_size; i++) | |
1762 | { | |
1763 | pool_node *p = &pool_vector[i]; | |
1764 | ||
1765 | ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", | |
1766 | CODE_LABEL_NUMBER (p->label)); | |
1767 | output_asm_insn (".long %O0", &p->value); | |
1768 | } | |
1769 | pool_size = 0; | |
1770 | } | |
b9654711 | 1771 | |
8aa2a305 JW |
1772 | return ""; |
1773 | } | |
1774 | \f | |
1775 | /* A full frame looks like: | |
16bea517 JW |
1776 | |
1777 | arg-5 | |
1778 | arg-4 | |
1779 | [ if current_function_anonymous_args | |
1780 | arg-3 | |
1781 | arg-2 | |
1782 | arg-1 | |
1783 | arg-0 ] | |
1784 | saved-fp | |
1785 | saved-r10 | |
1786 | saved-r11 | |
1787 | saved-r12 | |
1788 | saved-pr | |
1789 | local-n | |
1790 | .. | |
1791 | local-1 | |
1792 | local-0 <- fp points here. */ | |
8e87e161 | 1793 | |
8aa2a305 JW |
1794 | /* Number of bytes pushed for anonymous args, used to pass information |
1795 | between expand_prologue and expand_epilogue. */ | |
1796 | ||
1797 | static int extra_push; | |
1798 | ||
1799 | /* Adjust the stack and return the number of bytes taken to do it. */ | |
1800 | ||
1801 | static void | |
46d81ffa | 1802 | output_stack_adjust (size, reg) |
8aa2a305 | 1803 | int size; |
46d81ffa | 1804 | rtx reg; |
8aa2a305 JW |
1805 | { |
1806 | if (size) | |
1807 | { | |
1808 | rtx val = GEN_INT (size); | |
1809 | rtx insn; | |
1810 | ||
1811 | if (! CONST_OK_FOR_I (size)) | |
1812 | { | |
1813 | rtx reg = gen_rtx (REG, SImode, 3); | |
1814 | emit_insn (gen_movsi (reg, val)); | |
1815 | val = reg; | |
1816 | } | |
1817 | ||
46d81ffa | 1818 | insn = gen_addsi3 (reg, reg, val); |
8aa2a305 JW |
1819 | emit_insn (insn); |
1820 | } | |
1821 | } | |
1822 | ||
1823 | /* Output RTL to push register RN onto the stack. */ | |
1824 | ||
1825 | static void | |
1826 | push (rn) | |
1827 | int rn; | |
1828 | { | |
1829 | rtx x; | |
1830 | x = emit_insn (gen_push (gen_rtx (REG, SImode, rn))); | |
1831 | REG_NOTES (x) = gen_rtx (EXPR_LIST, REG_INC, | |
1832 | gen_rtx(REG, SImode, STACK_POINTER_REGNUM), 0); | |
1833 | } | |
1834 | ||
1835 | /* Output RTL to pop register RN from the stack. */ | |
1836 | ||
1837 | static void | |
1838 | pop (rn) | |
1839 | int rn; | |
1840 | { | |
1841 | rtx x; | |
1842 | x = emit_insn (gen_pop (gen_rtx (REG, SImode, rn))); | |
1843 | REG_NOTES (x) = gen_rtx (EXPR_LIST, REG_INC, | |
1844 | gen_rtx(REG, SImode, STACK_POINTER_REGNUM), 0); | |
1845 | } | |
1846 | ||
1847 | /* Generate code to push the regs specified in the mask, and return | |
1848 | the number of bytes the insns take. */ | |
1849 | ||
1850 | static void | |
1851 | push_regs (mask) | |
1852 | int mask; | |
1853 | { | |
1854 | int i; | |
1855 | ||
1856 | for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
1857 | if (mask & (1 << i)) | |
1858 | push (i); | |
1859 | } | |
1860 | ||
1861 | /* Work out the registers which need to be saved, both as a mask and a | |
1862 | count. | |
1863 | ||
1864 | If doing a pragma interrupt function, then push all regs used by the | |
1865 | function, and if we call another function (we can tell by looking at PR), | |
1866 | make sure that all the regs it clobbers are safe too. */ | |
1867 | ||
1868 | static int | |
1869 | calc_live_regs (count_ptr) | |
1870 | int *count_ptr; | |
1871 | { | |
1872 | int reg; | |
1873 | int live_regs_mask = 0; | |
1874 | int count = 0; | |
1875 | ||
1876 | for (reg = 0; reg < FIRST_PSEUDO_REGISTER; reg++) | |
1877 | { | |
1878 | if (pragma_interrupt && ! pragma_trapa) | |
1879 | { | |
956a5206 JW |
1880 | /* Normally, we must save all the regs ever live. |
1881 | If pragma_nosave_low_regs, then don't save any of the | |
1882 | registers which are banked on the SH3. */ | |
8aa2a305 JW |
1883 | if ((regs_ever_live[reg] |
1884 | || (call_used_regs[reg] && regs_ever_live[PR_REG])) | |
1885 | && reg != STACK_POINTER_REGNUM && reg != ARG_POINTER_REGNUM | |
956a5206 JW |
1886 | && reg != T_REG && reg != GBR_REG |
1887 | && ! (sh_cpu == CPU_SH3 && pragma_nosave_low_regs && reg < 8)) | |
8aa2a305 JW |
1888 | { |
1889 | live_regs_mask |= 1 << reg; | |
1890 | count++; | |
1891 | } | |
1892 | } | |
1893 | else | |
1894 | { | |
1895 | /* Only push those regs which are used and need to be saved. */ | |
1896 | if (regs_ever_live[reg] && ! call_used_regs[reg]) | |
1897 | { | |
1898 | live_regs_mask |= (1 << reg); | |
1899 | count++; | |
1900 | } | |
1901 | } | |
1902 | } | |
1903 | ||
1904 | *count_ptr = count; | |
1905 | return live_regs_mask; | |
1906 | } | |
1907 | ||
1908 | /* Code to generate prologue and epilogue sequences */ | |
b9654711 SC |
1909 | |
1910 | void | |
1911 | sh_expand_prologue () | |
1912 | { | |
1913 | int live_regs_mask; | |
40d2032b | 1914 | int d, i; |
b9654711 SC |
1915 | live_regs_mask = calc_live_regs (&d); |
1916 | ||
0d7e008e | 1917 | /* We have pretend args if we had an object sent partially in registers |
8aa2a305 | 1918 | and partially on the stack, e.g. a large structure. */ |
46d81ffa | 1919 | output_stack_adjust (-current_function_pretend_args_size, stack_pointer_rtx); |
b9654711 | 1920 | |
40d2032b JW |
1921 | extra_push = 0; |
1922 | ||
1923 | /* This is set by SETUP_VARARGS to indicate that this is a varargs | |
1924 | routine. Clear it here so that the next function isn't affected. */ | |
b9654711 SC |
1925 | if (current_function_anonymous_args) |
1926 | { | |
40d2032b JW |
1927 | current_function_anonymous_args = 0; |
1928 | ||
16bea517 | 1929 | /* Push arg regs as if they'd been provided by caller in stack. */ |
b9654711 SC |
1930 | for (i = 0; i < NPARM_REGS; i++) |
1931 | { | |
1932 | int rn = NPARM_REGS + FIRST_PARM_REG - i - 1; | |
79b2746a JW |
1933 | if (i > (NPARM_REGS - current_function_args_info |
1934 | - current_function_varargs)) | |
b9654711 SC |
1935 | break; |
1936 | push (rn); | |
b9654711 SC |
1937 | extra_push += 4; |
1938 | } | |
1939 | } | |
0d7e008e | 1940 | push_regs (live_regs_mask); |
46d81ffa | 1941 | output_stack_adjust (-get_frame_size (), stack_pointer_rtx); |
b9654711 SC |
1942 | |
1943 | if (frame_pointer_needed) | |
8aa2a305 | 1944 | emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx)); |
b9654711 SC |
1945 | } |
1946 | ||
1947 | void | |
1948 | sh_expand_epilogue () | |
1949 | { | |
1950 | int live_regs_mask; | |
40d2032b | 1951 | int d, i; |
b9654711 SC |
1952 | |
1953 | live_regs_mask = calc_live_regs (&d); | |
16bea517 | 1954 | |
b9654711 | 1955 | if (frame_pointer_needed) |
46d81ffa RK |
1956 | { |
1957 | /* We deliberately make the add dependent on the frame_pointer, | |
1958 | to ensure that instruction scheduling won't move the stack pointer | |
1959 | adjust before instructions reading from the frame. This can fail | |
1960 | if there is an interrupt which then writes to the stack. */ | |
1961 | output_stack_adjust (get_frame_size (), frame_pointer_rtx); | |
1962 | emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx)); | |
1963 | } | |
1964 | else | |
1965 | output_stack_adjust (get_frame_size (), stack_pointer_rtx); | |
b9654711 | 1966 | |
16bea517 | 1967 | /* Pop all the registers. */ |
0d7e008e | 1968 | |
b9654711 SC |
1969 | for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) |
1970 | { | |
1971 | int j = (FIRST_PSEUDO_REGISTER - 1) - i; | |
1972 | if (live_regs_mask & (1 << j)) | |
8aa2a305 | 1973 | pop (j); |
b9654711 | 1974 | } |
b9654711 | 1975 | |
46d81ffa RK |
1976 | output_stack_adjust (extra_push + current_function_pretend_args_size, |
1977 | stack_pointer_rtx); | |
b9654711 SC |
1978 | } |
1979 | ||
8aa2a305 JW |
1980 | /* Clear variables at function end. */ |
1981 | ||
1982 | void | |
1983 | function_epilogue (stream, size) | |
1984 | FILE *stream; | |
1985 | int size; | |
1986 | { | |
956a5206 | 1987 | pragma_interrupt = pragma_trapa = pragma_nosave_low_regs = 0; |
8aa2a305 JW |
1988 | } |
1989 | ||
0d7e008e SC |
1990 | /* Define the offset between two registers, one to be eliminated, and |
1991 | the other its replacement, at the start of a routine. */ | |
1992 | ||
1993 | int | |
1994 | initial_elimination_offset (from, to) | |
8e87e161 SC |
1995 | int from; |
1996 | int to; | |
0d7e008e SC |
1997 | { |
1998 | int regs_saved; | |
0d7e008e SC |
1999 | int total_saved_regs_space; |
2000 | int total_auto_space = get_frame_size (); | |
8e87e161 SC |
2001 | |
2002 | calc_live_regs (®s_saved); | |
0d7e008e | 2003 | total_saved_regs_space = (regs_saved) * 4; |
b9654711 | 2004 | |
0d7e008e | 2005 | if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM) |
8aa2a305 JW |
2006 | return total_saved_regs_space + total_auto_space; |
2007 | ||
0d7e008e | 2008 | if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM) |
8aa2a305 JW |
2009 | return total_saved_regs_space + total_auto_space; |
2010 | ||
2011 | /* Initial gap between fp and sp is 0. */ | |
0d7e008e | 2012 | if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM) |
8aa2a305 JW |
2013 | return 0; |
2014 | ||
0d7e008e SC |
2015 | abort (); |
2016 | } | |
8aa2a305 | 2017 | \f |
0d7e008e | 2018 | /* Handle machine specific pragmas to be semi-compatible with Hitachi |
16bea517 | 2019 | compiler. */ |
b9654711 SC |
2020 | |
2021 | int | |
0d7e008e SC |
2022 | handle_pragma (file) |
2023 | FILE *file; | |
b9654711 | 2024 | { |
0d7e008e SC |
2025 | int c; |
2026 | char pbuf[200]; | |
2027 | int psize = 0; | |
b9654711 | 2028 | |
0d7e008e SC |
2029 | c = getc (file); |
2030 | while (c == ' ' || c == '\t') | |
2031 | c = getc (file); | |
2032 | ||
2033 | if (c == '\n' || c == EOF) | |
2034 | return c; | |
2035 | ||
2036 | while (psize < sizeof (pbuf) - 1 && c != '\n') | |
2037 | { | |
2038 | pbuf[psize++] = c; | |
2039 | if (psize == 9 && strncmp (pbuf, "interrupt", 9) == 0) | |
2040 | { | |
2041 | pragma_interrupt = 1; | |
06c386ea | 2042 | return ' '; |
0d7e008e SC |
2043 | } |
2044 | if (psize == 5 && strncmp (pbuf, "trapa", 5) == 0) | |
2045 | { | |
2046 | pragma_interrupt = pragma_trapa = 1; | |
06c386ea | 2047 | return ' '; |
0d7e008e | 2048 | } |
956a5206 JW |
2049 | if (psize == 15 && strncmp (pbuf, "nosave_low_regs", 15) == 0) |
2050 | { | |
2051 | pragma_nosave_low_regs = 1; | |
2052 | return ' '; | |
2053 | } | |
0d7e008e SC |
2054 | c = getc (file); |
2055 | } | |
2056 | return c; | |
2057 | } | |
2058 | \f | |
8aa2a305 | 2059 | /* Predicates used by the templates. */ |
0d7e008e | 2060 | |
8aa2a305 JW |
2061 | /* Returns 1 if OP is MACL, MACH or PR. The input must be a REG rtx. |
2062 | Used only in general_movsrc_operand. */ | |
0d7e008e | 2063 | |
8aa2a305 JW |
2064 | int |
2065 | system_reg_operand (op, mode) | |
2066 | rtx op; | |
2067 | enum machine_mode mode; | |
0d7e008e | 2068 | { |
8aa2a305 | 2069 | switch (REGNO (op)) |
0d7e008e | 2070 | { |
8aa2a305 JW |
2071 | case PR_REG: |
2072 | case MACL_REG: | |
2073 | case MACH_REG: | |
2074 | return 1; | |
0d7e008e | 2075 | } |
8aa2a305 | 2076 | return 0; |
0d7e008e | 2077 | } |
0d7e008e SC |
2078 | |
2079 | /* Returns 1 if OP can be source of a simple move operation. | |
2080 | Same as general_operand, but a LABEL_REF is valid, PRE_DEC is | |
16bea517 | 2081 | invalid as are subregs of system registers. */ |
0d7e008e SC |
2082 | |
2083 | int | |
2084 | general_movsrc_operand (op, mode) | |
2085 | rtx op; | |
2086 | enum machine_mode mode; | |
2087 | { | |
06c386ea SC |
2088 | if (GET_CODE (op) == MEM) |
2089 | { | |
2090 | rtx inside = XEXP (op, 0); | |
2091 | if (GET_CODE (inside) == CONST) | |
2092 | inside = XEXP (inside, 0); | |
0d7e008e | 2093 | |
06c386ea SC |
2094 | if (GET_CODE (inside) == LABEL_REF) |
2095 | return 1; | |
8e87e161 | 2096 | |
06c386ea | 2097 | if (GET_CODE (inside) == PLUS |
8aa2a305 JW |
2098 | && GET_CODE (XEXP (inside, 0)) == LABEL_REF |
2099 | && GET_CODE (XEXP (inside, 1)) == CONST_INT) | |
06c386ea | 2100 | return 1; |
16bea517 JW |
2101 | |
2102 | /* Only post inc allowed. */ | |
97f8690b | 2103 | if (GET_CODE (inside) == PRE_DEC) |
06c386ea | 2104 | return 0; |
06c386ea | 2105 | } |
0d7e008e SC |
2106 | |
2107 | if ((mode == QImode || mode == HImode) | |
2108 | && (GET_CODE (op) == SUBREG | |
2109 | && GET_CODE (XEXP (op, 0)) == REG | |
2110 | && system_reg_operand (XEXP (op, 0), mode))) | |
2111 | return 0; | |
2112 | ||
0d7e008e | 2113 | return general_operand (op, mode); |
b9654711 SC |
2114 | } |
2115 | ||
0d7e008e SC |
2116 | /* Returns 1 if OP can be a destination of a move. |
2117 | Same as general_operand, but no preinc allowed. */ | |
2118 | ||
b9654711 | 2119 | int |
0d7e008e SC |
2120 | general_movdst_operand (op, mode) |
2121 | rtx op; | |
2122 | enum machine_mode mode; | |
b9654711 | 2123 | { |
16bea517 | 2124 | /* Only pre dec allowed. */ |
97f8690b | 2125 | if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC) |
0d7e008e | 2126 | return 0; |
d3ae8277 | 2127 | |
0d7e008e SC |
2128 | return general_operand (op, mode); |
2129 | } | |
2130 | ||
0d7e008e SC |
2131 | /* Returns 1 if OP is a normal arithmetic register. */ |
2132 | ||
2133 | int | |
2134 | arith_reg_operand (op, mode) | |
2135 | rtx op; | |
2136 | enum machine_mode mode; | |
2137 | { | |
2138 | if (register_operand (op, mode)) | |
2139 | { | |
2140 | if (GET_CODE (op) == REG) | |
2141 | return (REGNO (op) != T_REG | |
07c109c8 JW |
2142 | && REGNO (op) != PR_REG |
2143 | && REGNO (op) != MACH_REG | |
2144 | && REGNO (op) != MACL_REG); | |
0d7e008e SC |
2145 | return 1; |
2146 | } | |
2147 | return 0; | |
2148 | } | |
2149 | ||
0d7e008e SC |
2150 | /* Returns 1 if OP is a valid source operand for an arithmetic insn. */ |
2151 | ||
2152 | int | |
2153 | arith_operand (op, mode) | |
2154 | rtx op; | |
2155 | enum machine_mode mode; | |
2156 | { | |
2157 | if (arith_reg_operand (op, mode)) | |
2158 | return 1; | |
2159 | ||
8aa2a305 JW |
2160 | if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_I (INTVAL (op))) |
2161 | return 1; | |
2162 | ||
0d7e008e SC |
2163 | return 0; |
2164 | } | |
2165 | ||
22e1ebf1 JW |
2166 | /* Returns 1 if OP is a valid source operand for a compare insn. */ |
2167 | ||
2168 | int | |
2169 | arith_reg_or_0_operand (op, mode) | |
2170 | rtx op; | |
2171 | enum machine_mode mode; | |
2172 | { | |
2173 | if (arith_reg_operand (op, mode)) | |
2174 | return 1; | |
2175 | ||
8aa2a305 JW |
2176 | if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_N (INTVAL (op))) |
2177 | return 1; | |
2178 | ||
22e1ebf1 JW |
2179 | return 0; |
2180 | } | |
2181 | ||
16bea517 | 2182 | /* Returns 1 if OP is a valid source operand for a logical operation. */ |
0d7e008e SC |
2183 | |
2184 | int | |
2185 | logical_operand (op, mode) | |
2186 | rtx op; | |
2187 | enum machine_mode mode; | |
2188 | { | |
2189 | if (arith_reg_operand (op, mode)) | |
2190 | return 1; | |
2191 | ||
8aa2a305 JW |
2192 | if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_L (INTVAL (op))) |
2193 | return 1; | |
2194 | ||
0d7e008e | 2195 | return 0; |
b9654711 | 2196 | } |
8aa2a305 | 2197 | \f |
d3ae8277 SC |
2198 | /* Determine where to put an argument to a function. |
2199 | Value is zero to push the argument on the stack, | |
2200 | or a hard register in which to store the argument. | |
2201 | ||
2202 | MODE is the argument's machine mode. | |
2203 | TYPE is the data type of the argument (as a tree). | |
2204 | This is null for libcalls where that information may | |
2205 | not be available. | |
2206 | CUM is a variable of type CUMULATIVE_ARGS which gives info about | |
2207 | the preceding args and about the function being called. | |
2208 | NAMED is nonzero if this argument is a named parameter | |
2209 | (otherwise it is an extra parameter matching an ellipsis). */ | |
2210 | ||
8e87e161 | 2211 | rtx |
d3ae8277 | 2212 | sh_function_arg (cum, mode, type, named) |
8e87e161 SC |
2213 | CUMULATIVE_ARGS cum; |
2214 | enum machine_mode mode; | |
2215 | tree type; | |
2216 | int named; | |
d3ae8277 SC |
2217 | { |
2218 | if (named) | |
2219 | { | |
8aa2a305 | 2220 | int rr = (ROUND_REG (cum, mode)); |
d3ae8277 SC |
2221 | |
2222 | if (rr < NPARM_REGS) | |
8aa2a305 JW |
2223 | return ((type == 0 || ! TREE_ADDRESSABLE (type)) |
2224 | ? gen_rtx (REG, mode, FIRST_PARM_REG + rr) : 0); | |
d3ae8277 SC |
2225 | } |
2226 | return 0; | |
2227 | } | |
2228 | ||
2229 | /* For an arg passed partly in registers and partly in memory, | |
2230 | this is the number of registers used. | |
2231 | For args passed entirely in registers or entirely in memory, zero. | |
2232 | Any arg that starts in the first 4 regs but won't entirely fit in them | |
2233 | needs partial registers on the SH. */ | |
2234 | ||
2235 | int | |
8aa2a305 JW |
2236 | sh_function_arg_partial_nregs (cum, mode, type, named) |
2237 | CUMULATIVE_ARGS cum; | |
2238 | enum machine_mode mode; | |
2239 | tree type; | |
2240 | int named; | |
d3ae8277 | 2241 | { |
8aa2a305 | 2242 | if (cum < NPARM_REGS) |
8e87e161 | 2243 | { |
8aa2a305 JW |
2244 | if ((type == 0 || ! TREE_ADDRESSABLE (type)) |
2245 | && (cum + (mode == BLKmode | |
2246 | ? ROUND_ADVANCE (int_size_in_bytes (type)) | |
2247 | : ROUND_ADVANCE (GET_MODE_SIZE (mode))) - NPARM_REGS > 0)) | |
2248 | return NPARM_REGS - cum; | |
d3ae8277 SC |
2249 | } |
2250 | return 0; | |
2251 | } | |
a55e9d2b RK |
2252 | \f |
2253 | /* Return non-zero if REG is not used after INSN. | |
2254 | We assume REG is a reload reg, and therefore does | |
2255 | not live past labels or calls or jumps. */ | |
2256 | int | |
2257 | reg_unused_after (reg, insn) | |
2258 | rtx reg; | |
2259 | rtx insn; | |
2260 | { | |
8783b15e | 2261 | enum rtx_code code; |
a55e9d2b RK |
2262 | rtx set; |
2263 | ||
2264 | /* If the reg is set by this instruction, then it is safe for our | |
2265 | case. Disregard the case where this is a store to memory, since | |
2266 | we are checking a register used in the store address. */ | |
2267 | set = single_set (insn); | |
2268 | if (set && GET_CODE (SET_DEST (set)) != MEM | |
2269 | && reg_overlap_mentioned_p (reg, SET_DEST (set))) | |
2270 | return 1; | |
2271 | ||
2272 | while (insn = NEXT_INSN (insn)) | |
2273 | { | |
a55e9d2b | 2274 | code = GET_CODE (insn); |
8783b15e | 2275 | |
c8f6f18d RK |
2276 | #if 0 |
2277 | /* If this is a label that existed before reload, then the register | |
2278 | if dead here. However, if this is a label added by reorg, then | |
2279 | the register may still be live here. We can't tell the difference, | |
2280 | so we just ignore labels completely. */ | |
8783b15e | 2281 | if (code == CODE_LABEL) |
a55e9d2b | 2282 | return 1; |
c8f6f18d RK |
2283 | /* else */ |
2284 | #endif | |
a55e9d2b | 2285 | |
8783b15e RK |
2286 | /* If this is a sequence, we must handle them all at once. |
2287 | We could have for instance a call that sets the target register, | |
2288 | and a insn in a delay slot that uses the register. In this case, | |
2289 | we must return 0. */ | |
c8f6f18d | 2290 | if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE) |
a55e9d2b | 2291 | { |
8783b15e RK |
2292 | int i; |
2293 | int retval = 0; | |
2294 | ||
2295 | for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++) | |
2296 | { | |
2297 | rtx this_insn = XVECEXP (PATTERN (insn), 0, i); | |
2298 | rtx set = single_set (this_insn); | |
2299 | ||
2300 | if (GET_CODE (this_insn) == CALL_INSN) | |
2301 | code = CALL_INSN; | |
a55e9d2b | 2302 | |
8783b15e RK |
2303 | if (set && reg_overlap_mentioned_p (reg, SET_SRC (set))) |
2304 | return 0; | |
2305 | if (set && reg_overlap_mentioned_p (reg, SET_DEST (set))) | |
2306 | { | |
2307 | if (GET_CODE (SET_DEST (set)) != MEM) | |
2308 | retval = 1; | |
2309 | else | |
2310 | return 0; | |
2311 | } | |
2312 | if (set == 0 | |
2313 | && reg_overlap_mentioned_p (reg, PATTERN (this_insn))) | |
2314 | return 0; | |
2315 | } | |
2316 | if (retval == 1) | |
2317 | return 1; | |
2318 | } | |
2319 | else if (GET_RTX_CLASS (code) == 'i') | |
a55e9d2b RK |
2320 | { |
2321 | rtx set = single_set (insn); | |
2322 | ||
2323 | if (set && reg_overlap_mentioned_p (reg, SET_SRC (set))) | |
2324 | return 0; | |
2325 | if (set && reg_overlap_mentioned_p (reg, SET_DEST (set))) | |
2326 | return GET_CODE (SET_DEST (set)) != MEM; | |
2327 | if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn))) | |
2328 | return 0; | |
2329 | } | |
8783b15e RK |
2330 | |
2331 | if (code == CALL_INSN && call_used_regs[REGNO (reg)]) | |
2332 | return 1; | |
a55e9d2b RK |
2333 | } |
2334 | return 1; | |
2335 | } |