Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/h8300/h8300.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 77e2b8dfacca |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* Subroutines for insn-output.c for Renesas H8/300. | |
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, | |
3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 | |
4 Free Software Foundation, Inc. | |
5 Contributed by Steve Chamberlain (sac@cygnus.com), | |
6 Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com). | |
7 | |
8 This file is part of GCC. | |
9 | |
10 GCC is free software; you can redistribute it and/or modify | |
11 it under the terms of the GNU General Public License as published by | |
12 the Free Software Foundation; either version 3, or (at your option) | |
13 any later version. | |
14 | |
15 GCC is distributed in the hope that it will be useful, | |
16 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 GNU General Public License for more details. | |
19 | |
20 You should have received a copy of the GNU General Public License | |
21 along with GCC; see the file COPYING3. If not see | |
22 <http://www.gnu.org/licenses/>. */ | |
23 | |
24 #include "config.h" | |
25 #include "system.h" | |
26 #include "coretypes.h" | |
27 #include "tm.h" | |
28 #include "rtl.h" | |
29 #include "tree.h" | |
30 #include "regs.h" | |
31 #include "hard-reg-set.h" | |
32 #include "real.h" | |
33 #include "insn-config.h" | |
34 #include "conditions.h" | |
35 #include "output.h" | |
36 #include "insn-attr.h" | |
37 #include "flags.h" | |
38 #include "recog.h" | |
39 #include "expr.h" | |
40 #include "function.h" | |
41 #include "optabs.h" | |
42 #include "toplev.h" | |
43 #include "c-pragma.h" | |
44 #include "tm_p.h" | |
45 #include "ggc.h" | |
46 #include "target.h" | |
47 #include "target-def.h" | |
48 | |
49 /* Classifies a h8300_src_operand or h8300_dst_operand. | |
50 | |
51 H8OP_IMMEDIATE | |
52 A constant operand of some sort. | |
53 | |
54 H8OP_REGISTER | |
55 An ordinary register. | |
56 | |
57 H8OP_MEM_ABSOLUTE | |
58 A memory reference with a constant address. | |
59 | |
60 H8OP_MEM_BASE | |
61 A memory reference with a register as its address. | |
62 | |
63 H8OP_MEM_COMPLEX | |
64 Some other kind of memory reference. */ | |
65 enum h8300_operand_class | |
66 { | |
67 H8OP_IMMEDIATE, | |
68 H8OP_REGISTER, | |
69 H8OP_MEM_ABSOLUTE, | |
70 H8OP_MEM_BASE, | |
71 H8OP_MEM_COMPLEX, | |
72 NUM_H8OPS | |
73 }; | |
74 | |
75 /* For a general two-operand instruction, element [X][Y] gives | |
76 the length of the opcode fields when the first operand has class | |
77 (X + 1) and the second has class Y. */ | |
78 typedef unsigned char h8300_length_table[NUM_H8OPS - 1][NUM_H8OPS]; | |
79 | |
80 /* Forward declarations. */ | |
81 static const char *byte_reg (rtx, int); | |
82 static int h8300_interrupt_function_p (tree); | |
83 static int h8300_saveall_function_p (tree); | |
84 static int h8300_monitor_function_p (tree); | |
85 static int h8300_os_task_function_p (tree); | |
86 static void h8300_emit_stack_adjustment (int, HOST_WIDE_INT); | |
87 static HOST_WIDE_INT round_frame_size (HOST_WIDE_INT); | |
88 static unsigned int compute_saved_regs (void); | |
89 static void push (int); | |
90 static void pop (int); | |
91 static const char *cond_string (enum rtx_code); | |
92 static unsigned int h8300_asm_insn_count (const char *); | |
93 static tree h8300_handle_fndecl_attribute (tree *, tree, tree, int, bool *); | |
94 static tree h8300_handle_eightbit_data_attribute (tree *, tree, tree, int, bool *); | |
95 static tree h8300_handle_tiny_data_attribute (tree *, tree, tree, int, bool *); | |
96 #ifndef OBJECT_FORMAT_ELF | |
97 static void h8300_asm_named_section (const char *, unsigned int, tree); | |
98 #endif | |
99 static int h8300_and_costs (rtx); | |
100 static int h8300_shift_costs (rtx); | |
101 static void h8300_push_pop (int, int, int, int); | |
102 static int h8300_stack_offset_p (rtx, int); | |
103 static int h8300_ldm_stm_regno (rtx, int, int, int); | |
104 static void h8300_reorg (void); | |
105 static unsigned int h8300_constant_length (rtx); | |
106 static unsigned int h8300_displacement_length (rtx, int); | |
107 static unsigned int h8300_classify_operand (rtx, int, enum h8300_operand_class *); | |
108 static unsigned int h8300_length_from_table (rtx, rtx, const h8300_length_table *); | |
109 static unsigned int h8300_unary_length (rtx); | |
110 static unsigned int h8300_short_immediate_length (rtx); | |
111 static unsigned int h8300_bitfield_length (rtx, rtx); | |
112 static unsigned int h8300_binary_length (rtx, const h8300_length_table *); | |
113 static bool h8300_short_move_mem_p (rtx, enum rtx_code); | |
114 static unsigned int h8300_move_length (rtx *, const h8300_length_table *); | |
115 static bool h8300_hard_regno_scratch_ok (unsigned int); | |
116 | |
117 /* CPU_TYPE, says what cpu we're compiling for. */ | |
118 int cpu_type; | |
119 | |
120 /* True if a #pragma interrupt has been seen for the current function. */ | |
121 static int pragma_interrupt; | |
122 | |
123 /* True if a #pragma saveall has been seen for the current function. */ | |
124 static int pragma_saveall; | |
125 | |
126 static const char *const names_big[] = | |
127 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" }; | |
128 | |
129 static const char *const names_extended[] = | |
130 { "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" }; | |
131 | |
132 static const char *const names_upper_extended[] = | |
133 { "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7" }; | |
134 | |
135 /* Points to one of the above. */ | |
136 /* ??? The above could be put in an array indexed by CPU_TYPE. */ | |
137 const char * const *h8_reg_names; | |
138 | |
139 /* Various operations needed by the following, indexed by CPU_TYPE. */ | |
140 | |
141 const char *h8_push_op, *h8_pop_op, *h8_mov_op; | |
142 | |
143 /* Value of MOVE_RATIO. */ | |
144 int h8300_move_ratio; | |
145 | |
146 /* See below where shifts are handled for explanation of this enum. */ | |
147 | |
148 enum shift_alg | |
149 { | |
150 SHIFT_INLINE, | |
151 SHIFT_ROT_AND, | |
152 SHIFT_SPECIAL, | |
153 SHIFT_LOOP | |
154 }; | |
155 | |
156 /* Symbols of the various shifts which can be used as indices. */ | |
157 | |
158 enum shift_type | |
159 { | |
160 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT | |
161 }; | |
162 | |
163 /* Macros to keep the shift algorithm tables small. */ | |
164 #define INL SHIFT_INLINE | |
165 #define ROT SHIFT_ROT_AND | |
166 #define LOP SHIFT_LOOP | |
167 #define SPC SHIFT_SPECIAL | |
168 | |
169 /* The shift algorithms for each machine, mode, shift type, and shift | |
170 count are defined below. The three tables below correspond to | |
171 QImode, HImode, and SImode, respectively. Each table is organized | |
172 by, in the order of indices, machine, shift type, and shift count. */ | |
173 | |
174 static enum shift_alg shift_alg_qi[3][3][8] = { | |
175 { | |
176 /* TARGET_H8300 */ | |
177 /* 0 1 2 3 4 5 6 7 */ | |
178 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */ | |
179 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */ | |
180 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */ | |
181 }, | |
182 { | |
183 /* TARGET_H8300H */ | |
184 /* 0 1 2 3 4 5 6 7 */ | |
185 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */ | |
186 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */ | |
187 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */ | |
188 }, | |
189 { | |
190 /* TARGET_H8300S */ | |
191 /* 0 1 2 3 4 5 6 7 */ | |
192 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_ASHIFT */ | |
193 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_LSHIFTRT */ | |
194 { INL, INL, INL, INL, INL, INL, INL, SPC } /* SHIFT_ASHIFTRT */ | |
195 } | |
196 }; | |
197 | |
198 static enum shift_alg shift_alg_hi[3][3][16] = { | |
199 { | |
200 /* TARGET_H8300 */ | |
201 /* 0 1 2 3 4 5 6 7 */ | |
202 /* 8 9 10 11 12 13 14 15 */ | |
203 { INL, INL, INL, INL, INL, INL, INL, SPC, | |
204 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */ | |
205 { INL, INL, INL, INL, INL, LOP, LOP, SPC, | |
206 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */ | |
207 { INL, INL, INL, INL, INL, LOP, LOP, SPC, | |
208 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */ | |
209 }, | |
210 { | |
211 /* TARGET_H8300H */ | |
212 /* 0 1 2 3 4 5 6 7 */ | |
213 /* 8 9 10 11 12 13 14 15 */ | |
214 { INL, INL, INL, INL, INL, INL, INL, SPC, | |
215 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */ | |
216 { INL, INL, INL, INL, INL, INL, INL, SPC, | |
217 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */ | |
218 { INL, INL, INL, INL, INL, INL, INL, SPC, | |
219 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */ | |
220 }, | |
221 { | |
222 /* TARGET_H8300S */ | |
223 /* 0 1 2 3 4 5 6 7 */ | |
224 /* 8 9 10 11 12 13 14 15 */ | |
225 { INL, INL, INL, INL, INL, INL, INL, INL, | |
226 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */ | |
227 { INL, INL, INL, INL, INL, INL, INL, INL, | |
228 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */ | |
229 { INL, INL, INL, INL, INL, INL, INL, INL, | |
230 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */ | |
231 } | |
232 }; | |
233 | |
234 static enum shift_alg shift_alg_si[3][3][32] = { | |
235 { | |
236 /* TARGET_H8300 */ | |
237 /* 0 1 2 3 4 5 6 7 */ | |
238 /* 8 9 10 11 12 13 14 15 */ | |
239 /* 16 17 18 19 20 21 22 23 */ | |
240 /* 24 25 26 27 28 29 30 31 */ | |
241 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP, | |
242 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP, | |
243 SPC, SPC, SPC, SPC, SPC, LOP, LOP, LOP, | |
244 SPC, SPC, SPC, SPC, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFT */ | |
245 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP, | |
246 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC, | |
247 SPC, SPC, SPC, LOP, LOP, LOP, LOP, LOP, | |
248 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */ | |
249 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP, | |
250 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC, | |
251 SPC, SPC, LOP, LOP, LOP, LOP, LOP, LOP, | |
252 SPC, SPC, SPC, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */ | |
253 }, | |
254 { | |
255 /* TARGET_H8300H */ | |
256 /* 0 1 2 3 4 5 6 7 */ | |
257 /* 8 9 10 11 12 13 14 15 */ | |
258 /* 16 17 18 19 20 21 22 23 */ | |
259 /* 24 25 26 27 28 29 30 31 */ | |
260 { INL, INL, INL, INL, INL, LOP, LOP, LOP, | |
261 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC, | |
262 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP, | |
263 SPC, LOP, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */ | |
264 { INL, INL, INL, INL, INL, LOP, LOP, LOP, | |
265 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC, | |
266 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP, | |
267 SPC, LOP, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */ | |
268 { INL, INL, INL, INL, INL, LOP, LOP, LOP, | |
269 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP, | |
270 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP, | |
271 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */ | |
272 }, | |
273 { | |
274 /* TARGET_H8300S */ | |
275 /* 0 1 2 3 4 5 6 7 */ | |
276 /* 8 9 10 11 12 13 14 15 */ | |
277 /* 16 17 18 19 20 21 22 23 */ | |
278 /* 24 25 26 27 28 29 30 31 */ | |
279 { INL, INL, INL, INL, INL, INL, INL, INL, | |
280 INL, INL, INL, LOP, LOP, LOP, LOP, SPC, | |
281 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP, | |
282 SPC, SPC, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */ | |
283 { INL, INL, INL, INL, INL, INL, INL, INL, | |
284 INL, INL, INL, LOP, LOP, LOP, LOP, SPC, | |
285 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP, | |
286 SPC, SPC, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */ | |
287 { INL, INL, INL, INL, INL, INL, INL, INL, | |
288 INL, INL, INL, LOP, LOP, LOP, LOP, LOP, | |
289 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP, | |
290 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */ | |
291 } | |
292 }; | |
293 | |
294 #undef INL | |
295 #undef ROT | |
296 #undef LOP | |
297 #undef SPC | |
298 | |
299 enum h8_cpu | |
300 { | |
301 H8_300, | |
302 H8_300H, | |
303 H8_S | |
304 }; | |
305 | |
306 /* Initialize various cpu specific globals at start up. */ | |
307 | |
308 void | |
309 h8300_init_once (void) | |
310 { | |
311 static const char *const h8_push_ops[2] = { "push" , "push.l" }; | |
312 static const char *const h8_pop_ops[2] = { "pop" , "pop.l" }; | |
313 static const char *const h8_mov_ops[2] = { "mov.w", "mov.l" }; | |
314 | |
315 if (TARGET_H8300) | |
316 { | |
317 cpu_type = (int) CPU_H8300; | |
318 h8_reg_names = names_big; | |
319 } | |
320 else | |
321 { | |
322 /* For this we treat the H8/300H and H8S the same. */ | |
323 cpu_type = (int) CPU_H8300H; | |
324 h8_reg_names = names_extended; | |
325 } | |
326 h8_push_op = h8_push_ops[cpu_type]; | |
327 h8_pop_op = h8_pop_ops[cpu_type]; | |
328 h8_mov_op = h8_mov_ops[cpu_type]; | |
329 | |
330 if (!TARGET_H8300S && TARGET_MAC) | |
331 { | |
332 error ("-ms2600 is used without -ms"); | |
333 target_flags |= MASK_H8300S_1; | |
334 } | |
335 | |
336 if (TARGET_H8300 && TARGET_NORMAL_MODE) | |
337 { | |
338 error ("-mn is used without -mh or -ms"); | |
339 target_flags ^= MASK_NORMAL_MODE; | |
340 } | |
341 | |
342 /* Some of the shifts are optimized for speed by default. | |
343 See http://gcc.gnu.org/ml/gcc-patches/2002-07/msg01858.html | |
344 If optimizing for size, change shift_alg for those shift to | |
345 SHIFT_LOOP. */ | |
346 if (optimize_size) | |
347 { | |
348 /* H8/300 */ | |
349 shift_alg_hi[H8_300][SHIFT_ASHIFT][5] = SHIFT_LOOP; | |
350 shift_alg_hi[H8_300][SHIFT_ASHIFT][6] = SHIFT_LOOP; | |
351 shift_alg_hi[H8_300][SHIFT_ASHIFT][13] = SHIFT_LOOP; | |
352 shift_alg_hi[H8_300][SHIFT_ASHIFT][14] = SHIFT_LOOP; | |
353 | |
354 shift_alg_hi[H8_300][SHIFT_LSHIFTRT][13] = SHIFT_LOOP; | |
355 shift_alg_hi[H8_300][SHIFT_LSHIFTRT][14] = SHIFT_LOOP; | |
356 | |
357 shift_alg_hi[H8_300][SHIFT_ASHIFTRT][13] = SHIFT_LOOP; | |
358 shift_alg_hi[H8_300][SHIFT_ASHIFTRT][14] = SHIFT_LOOP; | |
359 | |
360 /* H8/300H */ | |
361 shift_alg_hi[H8_300H][SHIFT_ASHIFT][5] = SHIFT_LOOP; | |
362 shift_alg_hi[H8_300H][SHIFT_ASHIFT][6] = SHIFT_LOOP; | |
363 | |
364 shift_alg_hi[H8_300H][SHIFT_LSHIFTRT][5] = SHIFT_LOOP; | |
365 shift_alg_hi[H8_300H][SHIFT_LSHIFTRT][6] = SHIFT_LOOP; | |
366 | |
367 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][5] = SHIFT_LOOP; | |
368 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][6] = SHIFT_LOOP; | |
369 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][13] = SHIFT_LOOP; | |
370 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][14] = SHIFT_LOOP; | |
371 | |
372 /* H8S */ | |
373 shift_alg_hi[H8_S][SHIFT_ASHIFTRT][14] = SHIFT_LOOP; | |
374 } | |
375 | |
376 /* Work out a value for MOVE_RATIO. */ | |
377 if (!TARGET_H8300SX) | |
378 { | |
379 /* Memory-memory moves are quite expensive without the | |
380 h8sx instructions. */ | |
381 h8300_move_ratio = 3; | |
382 } | |
383 else if (flag_omit_frame_pointer) | |
384 { | |
385 /* movmd sequences are fairly cheap when er6 isn't fixed. They can | |
386 sometimes be as short as two individual memory-to-memory moves, | |
387 but since they use all the call-saved registers, it seems better | |
388 to allow up to three moves here. */ | |
389 h8300_move_ratio = 4; | |
390 } | |
391 else if (optimize_size) | |
392 { | |
393 /* In this case we don't use movmd sequences since they tend | |
394 to be longer than calls to memcpy(). Memory-to-memory | |
395 moves are cheaper than for !TARGET_H8300SX, so it makes | |
396 sense to have a slightly higher threshold. */ | |
397 h8300_move_ratio = 4; | |
398 } | |
399 else | |
400 { | |
401 /* We use movmd sequences for some moves since it can be quicker | |
402 than calling memcpy(). The sequences will need to save and | |
403 restore er6 though, so bump up the cost. */ | |
404 h8300_move_ratio = 6; | |
405 } | |
406 } | |
407 | |
408 /* Implement REG_CLASS_FROM_LETTER. | |
409 | |
410 Some patterns need to use er6 as a scratch register. This is | |
411 difficult to arrange since er6 is the frame pointer and usually | |
412 can't be spilled. | |
413 | |
414 Such patterns should define two alternatives, one which allows only | |
415 er6 and one which allows any general register. The former alternative | |
416 should have a 'd' constraint while the latter should be disparaged and | |
417 use 'D'. | |
418 | |
419 Normally, 'd' maps to DESTINATION_REGS and 'D' maps to GENERAL_REGS. | |
420 However, there are cases where they should be NO_REGS: | |
421 | |
422 - 'd' should be NO_REGS when reloading a function that uses the | |
423 frame pointer. In this case, DESTINATION_REGS won't contain any | |
424 spillable registers, so the first alternative can't be used. | |
425 | |
426 - -fno-omit-frame-pointer means that the frame pointer will | |
427 always be in use. It's therefore better to map 'd' to NO_REGS | |
428 before reload so that register allocator will pick the second | |
429 alternative. | |
430 | |
431 - we would like 'D' to be be NO_REGS when the frame pointer isn't | |
432 live, but we the frame pointer may turn out to be needed after | |
433 we start reload, and then we may have already decided we don't | |
434 have a choice, so we can't do that. Forcing the register | |
435 allocator to use er6 if possible might produce better code for | |
436 small functions: it's more efficient to save and restore er6 in | |
437 the prologue & epilogue than to do it in a define_split. | |
438 Hopefully disparaging 'D' will have a similar effect, without | |
439 forcing a reload failure if the frame pointer is found to be | |
440 needed too late. */ | |
441 | |
442 enum reg_class | |
443 h8300_reg_class_from_letter (int c) | |
444 { | |
445 switch (c) | |
446 { | |
447 case 'a': | |
448 return MAC_REGS; | |
449 | |
450 case 'c': | |
451 return COUNTER_REGS; | |
452 | |
453 case 'd': | |
454 if (!flag_omit_frame_pointer && !reload_completed) | |
455 return NO_REGS; | |
456 if (frame_pointer_needed && reload_in_progress) | |
457 return NO_REGS; | |
458 return DESTINATION_REGS; | |
459 | |
460 case 'D': | |
461 /* The meaning of a constraint shouldn't change dynamically, so | |
462 we can't make this NO_REGS. */ | |
463 return GENERAL_REGS; | |
464 | |
465 case 'f': | |
466 return SOURCE_REGS; | |
467 | |
468 default: | |
469 return NO_REGS; | |
470 } | |
471 } | |
472 | |
473 /* Return the byte register name for a register rtx X. B should be 0 | |
474 if you want a lower byte register. B should be 1 if you want an | |
475 upper byte register. */ | |
476 | |
477 static const char * | |
478 byte_reg (rtx x, int b) | |
479 { | |
480 static const char *const names_small[] = { | |
481 "r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h", | |
482 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h" | |
483 }; | |
484 | |
485 gcc_assert (REG_P (x)); | |
486 | |
487 return names_small[REGNO (x) * 2 + b]; | |
488 } | |
489 | |
490 /* REGNO must be saved/restored across calls if this macro is true. */ | |
491 | |
492 #define WORD_REG_USED(regno) \ | |
493 (regno < SP_REG \ | |
494 /* No need to save registers if this function will not return. */ \ | |
495 && ! TREE_THIS_VOLATILE (current_function_decl) \ | |
496 && (h8300_saveall_function_p (current_function_decl) \ | |
497 /* Save any call saved register that was used. */ \ | |
498 || (df_regs_ever_live_p (regno) && !call_used_regs[regno]) \ | |
499 /* Save the frame pointer if it was used. */ \ | |
500 || (regno == HARD_FRAME_POINTER_REGNUM && df_regs_ever_live_p (regno)) \ | |
501 /* Save any register used in an interrupt handler. */ \ | |
502 || (h8300_current_function_interrupt_function_p () \ | |
503 && df_regs_ever_live_p (regno)) \ | |
504 /* Save call clobbered registers in non-leaf interrupt \ | |
505 handlers. */ \ | |
506 || (h8300_current_function_interrupt_function_p () \ | |
507 && call_used_regs[regno] \ | |
508 && !current_function_is_leaf))) | |
509 | |
510 /* Output assembly language to FILE for the operation OP with operand size | |
511 SIZE to adjust the stack pointer. */ | |
512 | |
513 static void | |
514 h8300_emit_stack_adjustment (int sign, HOST_WIDE_INT size) | |
515 { | |
516 /* If the frame size is 0, we don't have anything to do. */ | |
517 if (size == 0) | |
518 return; | |
519 | |
520 /* H8/300 cannot add/subtract a large constant with a single | |
521 instruction. If a temporary register is available, load the | |
522 constant to it and then do the addition. */ | |
523 if (TARGET_H8300 | |
524 && size > 4 | |
525 && !h8300_current_function_interrupt_function_p () | |
526 && !(cfun->static_chain_decl != NULL && sign < 0)) | |
527 { | |
528 rtx r3 = gen_rtx_REG (Pmode, 3); | |
529 emit_insn (gen_movhi (r3, GEN_INT (sign * size))); | |
530 emit_insn (gen_addhi3 (stack_pointer_rtx, | |
531 stack_pointer_rtx, r3)); | |
532 } | |
533 else | |
534 { | |
535 /* The stack adjustment made here is further optimized by the | |
536 splitter. In case of H8/300, the splitter always splits the | |
537 addition emitted here to make the adjustment | |
538 interrupt-safe. */ | |
539 if (Pmode == HImode) | |
540 emit_insn (gen_addhi3 (stack_pointer_rtx, | |
541 stack_pointer_rtx, GEN_INT (sign * size))); | |
542 else | |
543 emit_insn (gen_addsi3 (stack_pointer_rtx, | |
544 stack_pointer_rtx, GEN_INT (sign * size))); | |
545 } | |
546 } | |
547 | |
548 /* Round up frame size SIZE. */ | |
549 | |
550 static HOST_WIDE_INT | |
551 round_frame_size (HOST_WIDE_INT size) | |
552 { | |
553 return ((size + STACK_BOUNDARY / BITS_PER_UNIT - 1) | |
554 & -STACK_BOUNDARY / BITS_PER_UNIT); | |
555 } | |
556 | |
557 /* Compute which registers to push/pop. | |
558 Return a bit vector of registers. */ | |
559 | |
560 static unsigned int | |
561 compute_saved_regs (void) | |
562 { | |
563 unsigned int saved_regs = 0; | |
564 int regno; | |
565 | |
566 /* Construct a bit vector of registers to be pushed/popped. */ | |
567 for (regno = 0; regno <= HARD_FRAME_POINTER_REGNUM; regno++) | |
568 { | |
569 if (WORD_REG_USED (regno)) | |
570 saved_regs |= 1 << regno; | |
571 } | |
572 | |
573 /* Don't push/pop the frame pointer as it is treated separately. */ | |
574 if (frame_pointer_needed) | |
575 saved_regs &= ~(1 << HARD_FRAME_POINTER_REGNUM); | |
576 | |
577 return saved_regs; | |
578 } | |
579 | |
580 /* Emit an insn to push register RN. */ | |
581 | |
582 static void | |
583 push (int rn) | |
584 { | |
585 rtx reg = gen_rtx_REG (word_mode, rn); | |
586 rtx x; | |
587 | |
588 if (TARGET_H8300) | |
589 x = gen_push_h8300 (reg); | |
590 else if (!TARGET_NORMAL_MODE) | |
591 x = gen_push_h8300hs_advanced (reg); | |
592 else | |
593 x = gen_push_h8300hs_normal (reg); | |
594 x = emit_insn (x); | |
595 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, 0); | |
596 } | |
597 | |
598 /* Emit an insn to pop register RN. */ | |
599 | |
600 static void | |
601 pop (int rn) | |
602 { | |
603 rtx reg = gen_rtx_REG (word_mode, rn); | |
604 rtx x; | |
605 | |
606 if (TARGET_H8300) | |
607 x = gen_pop_h8300 (reg); | |
608 else if (!TARGET_NORMAL_MODE) | |
609 x = gen_pop_h8300hs_advanced (reg); | |
610 else | |
611 x = gen_pop_h8300hs_normal (reg); | |
612 x = emit_insn (x); | |
613 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, 0); | |
614 } | |
615 | |
616 /* Emit an instruction to push or pop NREGS consecutive registers | |
617 starting at register REGNO. POP_P selects a pop rather than a | |
618 push and RETURN_P is true if the instruction should return. | |
619 | |
620 It must be possible to do the requested operation in a single | |
621 instruction. If NREGS == 1 && !RETURN_P, use a normal push | |
622 or pop insn. Otherwise emit a parallel of the form: | |
623 | |
624 (parallel | |
625 [(return) ;; if RETURN_P | |
626 (save or restore REGNO) | |
627 (save or restore REGNO + 1) | |
628 ... | |
629 (save or restore REGNO + NREGS - 1) | |
630 (set sp (plus sp (const_int adjust)))] */ | |
631 | |
632 static void | |
633 h8300_push_pop (int regno, int nregs, int pop_p, int return_p) | |
634 { | |
635 int i, j; | |
636 rtvec vec; | |
637 rtx sp, offset; | |
638 | |
639 /* See whether we can use a simple push or pop. */ | |
640 if (!return_p && nregs == 1) | |
641 { | |
642 if (pop_p) | |
643 pop (regno); | |
644 else | |
645 push (regno); | |
646 return; | |
647 } | |
648 | |
649 /* We need one element for the return insn, if present, one for each | |
650 register, and one for stack adjustment. */ | |
651 vec = rtvec_alloc ((return_p != 0) + nregs + 1); | |
652 sp = stack_pointer_rtx; | |
653 i = 0; | |
654 | |
655 /* Add the return instruction. */ | |
656 if (return_p) | |
657 { | |
658 RTVEC_ELT (vec, i) = gen_rtx_RETURN (VOIDmode); | |
659 i++; | |
660 } | |
661 | |
662 /* Add the register moves. */ | |
663 for (j = 0; j < nregs; j++) | |
664 { | |
665 rtx lhs, rhs; | |
666 | |
667 if (pop_p) | |
668 { | |
669 /* Register REGNO + NREGS - 1 is popped first. Before the | |
670 stack adjustment, its slot is at address @sp. */ | |
671 lhs = gen_rtx_REG (SImode, regno + j); | |
672 rhs = gen_rtx_MEM (SImode, plus_constant (sp, (nregs - j - 1) * 4)); | |
673 } | |
674 else | |
675 { | |
676 /* Register REGNO is pushed first and will be stored at @(-4,sp). */ | |
677 lhs = gen_rtx_MEM (SImode, plus_constant (sp, (j + 1) * -4)); | |
678 rhs = gen_rtx_REG (SImode, regno + j); | |
679 } | |
680 RTVEC_ELT (vec, i + j) = gen_rtx_SET (VOIDmode, lhs, rhs); | |
681 } | |
682 | |
683 /* Add the stack adjustment. */ | |
684 offset = GEN_INT ((pop_p ? nregs : -nregs) * 4); | |
685 RTVEC_ELT (vec, i + j) = gen_rtx_SET (VOIDmode, sp, | |
686 gen_rtx_PLUS (Pmode, sp, offset)); | |
687 | |
688 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec)); | |
689 } | |
690 | |
691 /* Return true if X has the value sp + OFFSET. */ | |
692 | |
693 static int | |
694 h8300_stack_offset_p (rtx x, int offset) | |
695 { | |
696 if (offset == 0) | |
697 return x == stack_pointer_rtx; | |
698 | |
699 return (GET_CODE (x) == PLUS | |
700 && XEXP (x, 0) == stack_pointer_rtx | |
701 && GET_CODE (XEXP (x, 1)) == CONST_INT | |
702 && INTVAL (XEXP (x, 1)) == offset); | |
703 } | |
704 | |
705 /* A subroutine of h8300_ldm_stm_parallel. X is one pattern in | |
706 something that may be an ldm or stm instruction. If it fits | |
707 the required template, return the register it loads or stores, | |
708 otherwise return -1. | |
709 | |
710 LOAD_P is true if X should be a load, false if it should be a store. | |
711 NREGS is the number of registers that the whole instruction is expected | |
712 to load or store. INDEX is the index of the register that X should | |
713 load or store, relative to the lowest-numbered register. */ | |
714 | |
715 static int | |
716 h8300_ldm_stm_regno (rtx x, int load_p, int index, int nregs) | |
717 { | |
718 int regindex, memindex, offset; | |
719 | |
720 if (load_p) | |
721 regindex = 0, memindex = 1, offset = (nregs - index - 1) * 4; | |
722 else | |
723 memindex = 0, regindex = 1, offset = (index + 1) * -4; | |
724 | |
725 if (GET_CODE (x) == SET | |
726 && GET_CODE (XEXP (x, regindex)) == REG | |
727 && GET_CODE (XEXP (x, memindex)) == MEM | |
728 && h8300_stack_offset_p (XEXP (XEXP (x, memindex), 0), offset)) | |
729 return REGNO (XEXP (x, regindex)); | |
730 | |
731 return -1; | |
732 } | |
733 | |
734 /* Return true if the elements of VEC starting at FIRST describe an | |
735 ldm or stm instruction (LOAD_P says which). */ | |
736 | |
737 int | |
738 h8300_ldm_stm_parallel (rtvec vec, int load_p, int first) | |
739 { | |
740 rtx last; | |
741 int nregs, i, regno, adjust; | |
742 | |
743 /* There must be a stack adjustment, a register move, and at least one | |
744 other operation (a return or another register move). */ | |
745 if (GET_NUM_ELEM (vec) < 3) | |
746 return false; | |
747 | |
748 /* Get the range of registers to be pushed or popped. */ | |
749 nregs = GET_NUM_ELEM (vec) - first - 1; | |
750 regno = h8300_ldm_stm_regno (RTVEC_ELT (vec, first), load_p, 0, nregs); | |
751 | |
752 /* Check that the call to h8300_ldm_stm_regno succeeded and | |
753 that we're only dealing with GPRs. */ | |
754 if (regno < 0 || regno + nregs > 8) | |
755 return false; | |
756 | |
757 /* 2-register h8s instructions must start with an even-numbered register. | |
758 3- and 4-register instructions must start with er0 or er4. */ | |
759 if (!TARGET_H8300SX) | |
760 { | |
761 if ((regno & 1) != 0) | |
762 return false; | |
763 if (nregs > 2 && (regno & 3) != 0) | |
764 return false; | |
765 } | |
766 | |
767 /* Check the other loads or stores. */ | |
768 for (i = 1; i < nregs; i++) | |
769 if (h8300_ldm_stm_regno (RTVEC_ELT (vec, first + i), load_p, i, nregs) | |
770 != regno + i) | |
771 return false; | |
772 | |
773 /* Check the stack adjustment. */ | |
774 last = RTVEC_ELT (vec, first + nregs); | |
775 adjust = (load_p ? nregs : -nregs) * 4; | |
776 return (GET_CODE (last) == SET | |
777 && SET_DEST (last) == stack_pointer_rtx | |
778 && h8300_stack_offset_p (SET_SRC (last), adjust)); | |
779 } | |
780 | |
781 /* This is what the stack looks like after the prolog of | |
782 a function with a frame has been set up: | |
783 | |
784 <args> | |
785 PC | |
786 FP <- fp | |
787 <locals> | |
788 <saved registers> <- sp | |
789 | |
790 This is what the stack looks like after the prolog of | |
791 a function which doesn't have a frame: | |
792 | |
793 <args> | |
794 PC | |
795 <locals> | |
796 <saved registers> <- sp | |
797 */ | |
798 | |
799 /* Generate RTL code for the function prologue. */ | |
800 | |
801 void | |
802 h8300_expand_prologue (void) | |
803 { | |
804 int regno; | |
805 int saved_regs; | |
806 int n_regs; | |
807 | |
808 /* If the current function has the OS_Task attribute set, then | |
809 we have a naked prologue. */ | |
810 if (h8300_os_task_function_p (current_function_decl)) | |
811 return; | |
812 | |
813 if (h8300_monitor_function_p (current_function_decl)) | |
814 /* My understanding of monitor functions is they act just like | |
815 interrupt functions, except the prologue must mask | |
816 interrupts. */ | |
817 emit_insn (gen_monitor_prologue ()); | |
818 | |
819 if (frame_pointer_needed) | |
820 { | |
821 /* Push fp. */ | |
822 push (HARD_FRAME_POINTER_REGNUM); | |
823 emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx); | |
824 } | |
825 | |
826 /* Push the rest of the registers in ascending order. */ | |
827 saved_regs = compute_saved_regs (); | |
828 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno += n_regs) | |
829 { | |
830 n_regs = 1; | |
831 if (saved_regs & (1 << regno)) | |
832 { | |
833 if (TARGET_H8300S) | |
834 { | |
835 /* See how many registers we can push at the same time. */ | |
836 if ((!TARGET_H8300SX || (regno & 3) == 0) | |
837 && ((saved_regs >> regno) & 0x0f) == 0x0f) | |
838 n_regs = 4; | |
839 | |
840 else if ((!TARGET_H8300SX || (regno & 3) == 0) | |
841 && ((saved_regs >> regno) & 0x07) == 0x07) | |
842 n_regs = 3; | |
843 | |
844 else if ((!TARGET_H8300SX || (regno & 1) == 0) | |
845 && ((saved_regs >> regno) & 0x03) == 0x03) | |
846 n_regs = 2; | |
847 } | |
848 | |
849 h8300_push_pop (regno, n_regs, 0, 0); | |
850 } | |
851 } | |
852 | |
853 /* Leave room for locals. */ | |
854 h8300_emit_stack_adjustment (-1, round_frame_size (get_frame_size ())); | |
855 } | |
856 | |
857 /* Return nonzero if we can use "rts" for the function currently being | |
858 compiled. */ | |
859 | |
860 int | |
861 h8300_can_use_return_insn_p (void) | |
862 { | |
863 return (reload_completed | |
864 && !frame_pointer_needed | |
865 && get_frame_size () == 0 | |
866 && compute_saved_regs () == 0); | |
867 } | |
868 | |
869 /* Generate RTL code for the function epilogue. */ | |
870 | |
871 void | |
872 h8300_expand_epilogue (void) | |
873 { | |
874 int regno; | |
875 int saved_regs; | |
876 int n_regs; | |
877 HOST_WIDE_INT frame_size; | |
878 bool returned_p; | |
879 | |
880 if (h8300_os_task_function_p (current_function_decl)) | |
881 /* OS_Task epilogues are nearly naked -- they just have an | |
882 rts instruction. */ | |
883 return; | |
884 | |
885 frame_size = round_frame_size (get_frame_size ()); | |
886 returned_p = false; | |
887 | |
888 /* Deallocate locals. */ | |
889 h8300_emit_stack_adjustment (1, frame_size); | |
890 | |
891 /* Pop the saved registers in descending order. */ | |
892 saved_regs = compute_saved_regs (); | |
893 for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno -= n_regs) | |
894 { | |
895 n_regs = 1; | |
896 if (saved_regs & (1 << regno)) | |
897 { | |
898 if (TARGET_H8300S) | |
899 { | |
900 /* See how many registers we can pop at the same time. */ | |
901 if ((TARGET_H8300SX || (regno & 3) == 3) | |
902 && ((saved_regs << 3 >> regno) & 0x0f) == 0x0f) | |
903 n_regs = 4; | |
904 | |
905 else if ((TARGET_H8300SX || (regno & 3) == 2) | |
906 && ((saved_regs << 2 >> regno) & 0x07) == 0x07) | |
907 n_regs = 3; | |
908 | |
909 else if ((TARGET_H8300SX || (regno & 1) == 1) | |
910 && ((saved_regs << 1 >> regno) & 0x03) == 0x03) | |
911 n_regs = 2; | |
912 } | |
913 | |
914 /* See if this pop would be the last insn before the return. | |
915 If so, use rte/l or rts/l instead of pop or ldm.l. */ | |
916 if (TARGET_H8300SX | |
917 && !frame_pointer_needed | |
918 && frame_size == 0 | |
919 && (saved_regs & ((1 << (regno - n_regs + 1)) - 1)) == 0) | |
920 returned_p = true; | |
921 | |
922 h8300_push_pop (regno - n_regs + 1, n_regs, 1, returned_p); | |
923 } | |
924 } | |
925 | |
926 /* Pop frame pointer if we had one. */ | |
927 if (frame_pointer_needed) | |
928 { | |
929 if (TARGET_H8300SX) | |
930 returned_p = true; | |
931 h8300_push_pop (HARD_FRAME_POINTER_REGNUM, 1, 1, returned_p); | |
932 } | |
933 | |
934 if (!returned_p) | |
935 emit_jump_insn (gen_rtx_RETURN (VOIDmode)); | |
936 } | |
937 | |
938 /* Return nonzero if the current function is an interrupt | |
939 function. */ | |
940 | |
941 int | |
942 h8300_current_function_interrupt_function_p (void) | |
943 { | |
944 return (h8300_interrupt_function_p (current_function_decl) | |
945 || h8300_monitor_function_p (current_function_decl)); | |
946 } | |
947 | |
948 /* Output assembly code for the start of the file. */ | |
949 | |
950 static void | |
951 h8300_file_start (void) | |
952 { | |
953 default_file_start (); | |
954 | |
955 if (TARGET_H8300H) | |
956 fputs (TARGET_NORMAL_MODE ? "\t.h8300hn\n" : "\t.h8300h\n", asm_out_file); | |
957 else if (TARGET_H8300SX) | |
958 fputs (TARGET_NORMAL_MODE ? "\t.h8300sxn\n" : "\t.h8300sx\n", asm_out_file); | |
959 else if (TARGET_H8300S) | |
960 fputs (TARGET_NORMAL_MODE ? "\t.h8300sn\n" : "\t.h8300s\n", asm_out_file); | |
961 } | |
962 | |
963 /* Output assembly language code for the end of file. */ | |
964 | |
965 static void | |
966 h8300_file_end (void) | |
967 { | |
968 fputs ("\t.end\n", asm_out_file); | |
969 } | |
970 | |
971 /* Split an add of a small constant into two adds/subs insns. | |
972 | |
973 If USE_INCDEC_P is nonzero, we generate the last insn using inc/dec | |
974 instead of adds/subs. */ | |
975 | |
976 void | |
977 split_adds_subs (enum machine_mode mode, rtx *operands) | |
978 { | |
979 HOST_WIDE_INT val = INTVAL (operands[1]); | |
980 rtx reg = operands[0]; | |
981 HOST_WIDE_INT sign = 1; | |
982 HOST_WIDE_INT amount; | |
983 rtx (*gen_add) (rtx, rtx, rtx); | |
984 | |
985 /* Force VAL to be positive so that we do not have to consider the | |
986 sign. */ | |
987 if (val < 0) | |
988 { | |
989 val = -val; | |
990 sign = -1; | |
991 } | |
992 | |
993 switch (mode) | |
994 { | |
995 case HImode: | |
996 gen_add = gen_addhi3; | |
997 break; | |
998 | |
999 case SImode: | |
1000 gen_add = gen_addsi3; | |
1001 break; | |
1002 | |
1003 default: | |
1004 gcc_unreachable (); | |
1005 } | |
1006 | |
1007 /* Try different amounts in descending order. */ | |
1008 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2; | |
1009 amount > 0; | |
1010 amount /= 2) | |
1011 { | |
1012 for (; val >= amount; val -= amount) | |
1013 emit_insn (gen_add (reg, reg, GEN_INT (sign * amount))); | |
1014 } | |
1015 | |
1016 return; | |
1017 } | |
1018 | |
1019 /* Handle machine specific pragmas for compatibility with existing | |
1020 compilers for the H8/300. | |
1021 | |
1022 pragma saveall generates prologue/epilogue code which saves and | |
1023 restores all the registers on function entry. | |
1024 | |
1025 pragma interrupt saves and restores all registers, and exits with | |
1026 an rte instruction rather than an rts. A pointer to a function | |
1027 with this attribute may be safely used in an interrupt vector. */ | |
1028 | |
1029 void | |
1030 h8300_pr_interrupt (struct cpp_reader *pfile ATTRIBUTE_UNUSED) | |
1031 { | |
1032 pragma_interrupt = 1; | |
1033 } | |
1034 | |
1035 void | |
1036 h8300_pr_saveall (struct cpp_reader *pfile ATTRIBUTE_UNUSED) | |
1037 { | |
1038 pragma_saveall = 1; | |
1039 } | |
1040 | |
1041 /* If the next function argument with MODE and TYPE is to be passed in | |
1042 a register, return a reg RTX for the hard register in which to pass | |
1043 the argument. CUM represents the state after the last argument. | |
1044 If the argument is to be pushed, NULL_RTX is returned. */ | |
1045 | |
1046 rtx | |
1047 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, | |
1048 tree type, int named) | |
1049 { | |
1050 static const char *const hand_list[] = { | |
1051 "__main", | |
1052 "__cmpsi2", | |
1053 "__divhi3", | |
1054 "__modhi3", | |
1055 "__udivhi3", | |
1056 "__umodhi3", | |
1057 "__divsi3", | |
1058 "__modsi3", | |
1059 "__udivsi3", | |
1060 "__umodsi3", | |
1061 "__mulhi3", | |
1062 "__mulsi3", | |
1063 "__reg_memcpy", | |
1064 "__reg_memset", | |
1065 "__ucmpsi2", | |
1066 0, | |
1067 }; | |
1068 | |
1069 rtx result = NULL_RTX; | |
1070 const char *fname; | |
1071 int regpass = 0; | |
1072 | |
1073 /* Never pass unnamed arguments in registers. */ | |
1074 if (!named) | |
1075 return NULL_RTX; | |
1076 | |
1077 /* Pass 3 regs worth of data in regs when user asked on the command line. */ | |
1078 if (TARGET_QUICKCALL) | |
1079 regpass = 3; | |
1080 | |
1081 /* If calling hand written assembler, use 4 regs of args. */ | |
1082 if (cum->libcall) | |
1083 { | |
1084 const char * const *p; | |
1085 | |
1086 fname = XSTR (cum->libcall, 0); | |
1087 | |
1088 /* See if this libcall is one of the hand coded ones. */ | |
1089 for (p = hand_list; *p && strcmp (*p, fname) != 0; p++) | |
1090 ; | |
1091 | |
1092 if (*p) | |
1093 regpass = 4; | |
1094 } | |
1095 | |
1096 if (regpass) | |
1097 { | |
1098 int size; | |
1099 | |
1100 if (mode == BLKmode) | |
1101 size = int_size_in_bytes (type); | |
1102 else | |
1103 size = GET_MODE_SIZE (mode); | |
1104 | |
1105 if (size + cum->nbytes <= regpass * UNITS_PER_WORD | |
1106 && cum->nbytes / UNITS_PER_WORD <= 3) | |
1107 result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD); | |
1108 } | |
1109 | |
1110 return result; | |
1111 } | |
1112 | |
1113 /* Compute the cost of an and insn. */ | |
1114 | |
1115 static int | |
1116 h8300_and_costs (rtx x) | |
1117 { | |
1118 rtx operands[4]; | |
1119 | |
1120 if (GET_MODE (x) == QImode) | |
1121 return 1; | |
1122 | |
1123 if (GET_MODE (x) != HImode | |
1124 && GET_MODE (x) != SImode) | |
1125 return 100; | |
1126 | |
1127 operands[0] = NULL; | |
1128 operands[1] = XEXP (x, 0); | |
1129 operands[2] = XEXP (x, 1); | |
1130 operands[3] = x; | |
1131 return compute_logical_op_length (GET_MODE (x), operands) / 2; | |
1132 } | |
1133 | |
1134 /* Compute the cost of a shift insn. */ | |
1135 | |
1136 static int | |
1137 h8300_shift_costs (rtx x) | |
1138 { | |
1139 rtx operands[4]; | |
1140 | |
1141 if (GET_MODE (x) != QImode | |
1142 && GET_MODE (x) != HImode | |
1143 && GET_MODE (x) != SImode) | |
1144 return 100; | |
1145 | |
1146 operands[0] = NULL; | |
1147 operands[1] = NULL; | |
1148 operands[2] = XEXP (x, 1); | |
1149 operands[3] = x; | |
1150 return compute_a_shift_length (NULL, operands) / 2; | |
1151 } | |
1152 | |
1153 /* Worker function for TARGET_RTX_COSTS. */ | |
1154 | |
1155 static bool | |
1156 h8300_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed) | |
1157 { | |
1158 if (TARGET_H8300SX && outer_code == MEM) | |
1159 { | |
1160 /* Estimate the number of execution states needed to calculate | |
1161 the address. */ | |
1162 if (register_operand (x, VOIDmode) | |
1163 || GET_CODE (x) == POST_INC | |
1164 || GET_CODE (x) == POST_DEC | |
1165 || CONSTANT_P (x)) | |
1166 *total = 0; | |
1167 else | |
1168 *total = COSTS_N_INSNS (1); | |
1169 return true; | |
1170 } | |
1171 | |
1172 switch (code) | |
1173 { | |
1174 case CONST_INT: | |
1175 { | |
1176 HOST_WIDE_INT n = INTVAL (x); | |
1177 | |
1178 if (TARGET_H8300SX) | |
1179 { | |
1180 /* Constant operands need the same number of processor | |
1181 states as register operands. Although we could try to | |
1182 use a size-based cost for !speed, the lack of | |
1183 of a mode makes the results very unpredictable. */ | |
1184 *total = 0; | |
1185 return true; | |
1186 } | |
1187 if (-4 <= n || n <= 4) | |
1188 { | |
1189 switch ((int) n) | |
1190 { | |
1191 case 0: | |
1192 *total = 0; | |
1193 return true; | |
1194 case 1: | |
1195 case 2: | |
1196 case -1: | |
1197 case -2: | |
1198 *total = 0 + (outer_code == SET); | |
1199 return true; | |
1200 case 4: | |
1201 case -4: | |
1202 if (TARGET_H8300H || TARGET_H8300S) | |
1203 *total = 0 + (outer_code == SET); | |
1204 else | |
1205 *total = 1; | |
1206 return true; | |
1207 } | |
1208 } | |
1209 *total = 1; | |
1210 return true; | |
1211 } | |
1212 | |
1213 case CONST: | |
1214 case LABEL_REF: | |
1215 case SYMBOL_REF: | |
1216 if (TARGET_H8300SX) | |
1217 { | |
1218 /* See comment for CONST_INT. */ | |
1219 *total = 0; | |
1220 return true; | |
1221 } | |
1222 *total = 3; | |
1223 return true; | |
1224 | |
1225 case CONST_DOUBLE: | |
1226 *total = 20; | |
1227 return true; | |
1228 | |
1229 case AND: | |
1230 if (!h8300_dst_operand (XEXP (x, 0), VOIDmode) | |
1231 || !h8300_src_operand (XEXP (x, 1), VOIDmode)) | |
1232 return false; | |
1233 *total = COSTS_N_INSNS (h8300_and_costs (x)); | |
1234 return true; | |
1235 | |
1236 /* We say that MOD and DIV are so expensive because otherwise we'll | |
1237 generate some really horrible code for division of a power of two. */ | |
1238 case MOD: | |
1239 case DIV: | |
1240 case UMOD: | |
1241 case UDIV: | |
1242 if (TARGET_H8300SX) | |
1243 switch (GET_MODE (x)) | |
1244 { | |
1245 case QImode: | |
1246 case HImode: | |
1247 *total = COSTS_N_INSNS (!speed ? 4 : 10); | |
1248 return false; | |
1249 | |
1250 case SImode: | |
1251 *total = COSTS_N_INSNS (!speed ? 4 : 18); | |
1252 return false; | |
1253 | |
1254 default: | |
1255 break; | |
1256 } | |
1257 *total = COSTS_N_INSNS (12); | |
1258 return true; | |
1259 | |
1260 case MULT: | |
1261 if (TARGET_H8300SX) | |
1262 switch (GET_MODE (x)) | |
1263 { | |
1264 case QImode: | |
1265 case HImode: | |
1266 *total = COSTS_N_INSNS (2); | |
1267 return false; | |
1268 | |
1269 case SImode: | |
1270 *total = COSTS_N_INSNS (5); | |
1271 return false; | |
1272 | |
1273 default: | |
1274 break; | |
1275 } | |
1276 *total = COSTS_N_INSNS (4); | |
1277 return true; | |
1278 | |
1279 case ASHIFT: | |
1280 case ASHIFTRT: | |
1281 case LSHIFTRT: | |
1282 if (h8sx_binary_shift_operator (x, VOIDmode)) | |
1283 { | |
1284 *total = COSTS_N_INSNS (2); | |
1285 return false; | |
1286 } | |
1287 else if (h8sx_unary_shift_operator (x, VOIDmode)) | |
1288 { | |
1289 *total = COSTS_N_INSNS (1); | |
1290 return false; | |
1291 } | |
1292 *total = COSTS_N_INSNS (h8300_shift_costs (x)); | |
1293 return true; | |
1294 | |
1295 case ROTATE: | |
1296 case ROTATERT: | |
1297 if (GET_MODE (x) == HImode) | |
1298 *total = 2; | |
1299 else | |
1300 *total = 8; | |
1301 return true; | |
1302 | |
1303 default: | |
1304 *total = COSTS_N_INSNS (1); | |
1305 return false; | |
1306 } | |
1307 } | |
1308 | |
1309 /* Documentation for the machine specific operand escapes: | |
1310 | |
1311 'E' like s but negative. | |
1312 'F' like t but negative. | |
1313 'G' constant just the negative | |
1314 'R' print operand as a byte:8 address if appropriate, else fall back to | |
1315 'X' handling. | |
1316 'S' print operand as a long word | |
1317 'T' print operand as a word | |
1318 'V' find the set bit, and print its number. | |
1319 'W' find the clear bit, and print its number. | |
1320 'X' print operand as a byte | |
1321 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8. | |
1322 If this operand isn't a register, fall back to 'R' handling. | |
1323 'Z' print int & 7. | |
1324 'c' print the opcode corresponding to rtl | |
1325 'e' first word of 32-bit value - if reg, then least reg. if mem | |
1326 then least. if const then most sig word | |
1327 'f' second word of 32-bit value - if reg, then biggest reg. if mem | |
1328 then +2. if const then least sig word | |
1329 'j' print operand as condition code. | |
1330 'k' print operand as reverse condition code. | |
1331 'm' convert an integer operand to a size suffix (.b, .w or .l) | |
1332 'o' print an integer without a leading '#' | |
1333 's' print as low byte of 16-bit value | |
1334 't' print as high byte of 16-bit value | |
1335 'w' print as low byte of 32-bit value | |
1336 'x' print as 2nd byte of 32-bit value | |
1337 'y' print as 3rd byte of 32-bit value | |
1338 'z' print as msb of 32-bit value | |
1339 */ | |
1340 | |
1341 /* Return assembly language string which identifies a comparison type. */ | |
1342 | |
1343 static const char * | |
1344 cond_string (enum rtx_code code) | |
1345 { | |
1346 switch (code) | |
1347 { | |
1348 case NE: | |
1349 return "ne"; | |
1350 case EQ: | |
1351 return "eq"; | |
1352 case GE: | |
1353 return "ge"; | |
1354 case GT: | |
1355 return "gt"; | |
1356 case LE: | |
1357 return "le"; | |
1358 case LT: | |
1359 return "lt"; | |
1360 case GEU: | |
1361 return "hs"; | |
1362 case GTU: | |
1363 return "hi"; | |
1364 case LEU: | |
1365 return "ls"; | |
1366 case LTU: | |
1367 return "lo"; | |
1368 default: | |
1369 gcc_unreachable (); | |
1370 } | |
1371 } | |
1372 | |
1373 /* Print operand X using operand code CODE to assembly language output file | |
1374 FILE. */ | |
1375 | |
1376 void | |
1377 print_operand (FILE *file, rtx x, int code) | |
1378 { | |
1379 /* This is used for communication between codes V,W,Z and Y. */ | |
1380 static int bitint; | |
1381 | |
1382 switch (code) | |
1383 { | |
1384 case 'E': | |
1385 switch (GET_CODE (x)) | |
1386 { | |
1387 case REG: | |
1388 fprintf (file, "%sl", names_big[REGNO (x)]); | |
1389 break; | |
1390 case CONST_INT: | |
1391 fprintf (file, "#%ld", (-INTVAL (x)) & 0xff); | |
1392 break; | |
1393 default: | |
1394 gcc_unreachable (); | |
1395 } | |
1396 break; | |
1397 case 'F': | |
1398 switch (GET_CODE (x)) | |
1399 { | |
1400 case REG: | |
1401 fprintf (file, "%sh", names_big[REGNO (x)]); | |
1402 break; | |
1403 case CONST_INT: | |
1404 fprintf (file, "#%ld", ((-INTVAL (x)) & 0xff00) >> 8); | |
1405 break; | |
1406 default: | |
1407 gcc_unreachable (); | |
1408 } | |
1409 break; | |
1410 case 'G': | |
1411 gcc_assert (GET_CODE (x) == CONST_INT); | |
1412 fprintf (file, "#%ld", 0xff & (-INTVAL (x))); | |
1413 break; | |
1414 case 'S': | |
1415 if (GET_CODE (x) == REG) | |
1416 fprintf (file, "%s", names_extended[REGNO (x)]); | |
1417 else | |
1418 goto def; | |
1419 break; | |
1420 case 'T': | |
1421 if (GET_CODE (x) == REG) | |
1422 fprintf (file, "%s", names_big[REGNO (x)]); | |
1423 else | |
1424 goto def; | |
1425 break; | |
1426 case 'V': | |
1427 bitint = exact_log2 (INTVAL (x) & 0xff); | |
1428 gcc_assert (bitint >= 0); | |
1429 fprintf (file, "#%d", bitint); | |
1430 break; | |
1431 case 'W': | |
1432 bitint = exact_log2 ((~INTVAL (x)) & 0xff); | |
1433 gcc_assert (bitint >= 0); | |
1434 fprintf (file, "#%d", bitint); | |
1435 break; | |
1436 case 'R': | |
1437 case 'X': | |
1438 if (GET_CODE (x) == REG) | |
1439 fprintf (file, "%s", byte_reg (x, 0)); | |
1440 else | |
1441 goto def; | |
1442 break; | |
1443 case 'Y': | |
1444 gcc_assert (bitint >= 0); | |
1445 if (GET_CODE (x) == REG) | |
1446 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l'); | |
1447 else | |
1448 print_operand (file, x, 'R'); | |
1449 bitint = -1; | |
1450 break; | |
1451 case 'Z': | |
1452 bitint = INTVAL (x); | |
1453 fprintf (file, "#%d", bitint & 7); | |
1454 break; | |
1455 case 'c': | |
1456 switch (GET_CODE (x)) | |
1457 { | |
1458 case IOR: | |
1459 fprintf (file, "or"); | |
1460 break; | |
1461 case XOR: | |
1462 fprintf (file, "xor"); | |
1463 break; | |
1464 case AND: | |
1465 fprintf (file, "and"); | |
1466 break; | |
1467 default: | |
1468 break; | |
1469 } | |
1470 break; | |
1471 case 'e': | |
1472 switch (GET_CODE (x)) | |
1473 { | |
1474 case REG: | |
1475 if (TARGET_H8300) | |
1476 fprintf (file, "%s", names_big[REGNO (x)]); | |
1477 else | |
1478 fprintf (file, "%s", names_upper_extended[REGNO (x)]); | |
1479 break; | |
1480 case MEM: | |
1481 print_operand (file, x, 0); | |
1482 break; | |
1483 case CONST_INT: | |
1484 fprintf (file, "#%ld", ((INTVAL (x) >> 16) & 0xffff)); | |
1485 break; | |
1486 case CONST_DOUBLE: | |
1487 { | |
1488 long val; | |
1489 REAL_VALUE_TYPE rv; | |
1490 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
1491 REAL_VALUE_TO_TARGET_SINGLE (rv, val); | |
1492 fprintf (file, "#%ld", ((val >> 16) & 0xffff)); | |
1493 break; | |
1494 } | |
1495 default: | |
1496 gcc_unreachable (); | |
1497 break; | |
1498 } | |
1499 break; | |
1500 case 'f': | |
1501 switch (GET_CODE (x)) | |
1502 { | |
1503 case REG: | |
1504 if (TARGET_H8300) | |
1505 fprintf (file, "%s", names_big[REGNO (x) + 1]); | |
1506 else | |
1507 fprintf (file, "%s", names_big[REGNO (x)]); | |
1508 break; | |
1509 case MEM: | |
1510 x = adjust_address (x, HImode, 2); | |
1511 print_operand (file, x, 0); | |
1512 break; | |
1513 case CONST_INT: | |
1514 fprintf (file, "#%ld", INTVAL (x) & 0xffff); | |
1515 break; | |
1516 case CONST_DOUBLE: | |
1517 { | |
1518 long val; | |
1519 REAL_VALUE_TYPE rv; | |
1520 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
1521 REAL_VALUE_TO_TARGET_SINGLE (rv, val); | |
1522 fprintf (file, "#%ld", (val & 0xffff)); | |
1523 break; | |
1524 } | |
1525 default: | |
1526 gcc_unreachable (); | |
1527 } | |
1528 break; | |
1529 case 'j': | |
1530 fputs (cond_string (GET_CODE (x)), file); | |
1531 break; | |
1532 case 'k': | |
1533 fputs (cond_string (reverse_condition (GET_CODE (x))), file); | |
1534 break; | |
1535 case 'm': | |
1536 gcc_assert (GET_CODE (x) == CONST_INT); | |
1537 switch (INTVAL (x)) | |
1538 { | |
1539 case 1: | |
1540 fputs (".b", file); | |
1541 break; | |
1542 | |
1543 case 2: | |
1544 fputs (".w", file); | |
1545 break; | |
1546 | |
1547 case 4: | |
1548 fputs (".l", file); | |
1549 break; | |
1550 | |
1551 default: | |
1552 gcc_unreachable (); | |
1553 } | |
1554 break; | |
1555 case 'o': | |
1556 print_operand_address (file, x); | |
1557 break; | |
1558 case 's': | |
1559 if (GET_CODE (x) == CONST_INT) | |
1560 fprintf (file, "#%ld", (INTVAL (x)) & 0xff); | |
1561 else | |
1562 fprintf (file, "%s", byte_reg (x, 0)); | |
1563 break; | |
1564 case 't': | |
1565 if (GET_CODE (x) == CONST_INT) | |
1566 fprintf (file, "#%ld", (INTVAL (x) >> 8) & 0xff); | |
1567 else | |
1568 fprintf (file, "%s", byte_reg (x, 1)); | |
1569 break; | |
1570 case 'w': | |
1571 if (GET_CODE (x) == CONST_INT) | |
1572 fprintf (file, "#%ld", INTVAL (x) & 0xff); | |
1573 else | |
1574 fprintf (file, "%s", | |
1575 byte_reg (x, TARGET_H8300 ? 2 : 0)); | |
1576 break; | |
1577 case 'x': | |
1578 if (GET_CODE (x) == CONST_INT) | |
1579 fprintf (file, "#%ld", (INTVAL (x) >> 8) & 0xff); | |
1580 else | |
1581 fprintf (file, "%s", | |
1582 byte_reg (x, TARGET_H8300 ? 3 : 1)); | |
1583 break; | |
1584 case 'y': | |
1585 if (GET_CODE (x) == CONST_INT) | |
1586 fprintf (file, "#%ld", (INTVAL (x) >> 16) & 0xff); | |
1587 else | |
1588 fprintf (file, "%s", byte_reg (x, 0)); | |
1589 break; | |
1590 case 'z': | |
1591 if (GET_CODE (x) == CONST_INT) | |
1592 fprintf (file, "#%ld", (INTVAL (x) >> 24) & 0xff); | |
1593 else | |
1594 fprintf (file, "%s", byte_reg (x, 1)); | |
1595 break; | |
1596 | |
1597 default: | |
1598 def: | |
1599 switch (GET_CODE (x)) | |
1600 { | |
1601 case REG: | |
1602 switch (GET_MODE (x)) | |
1603 { | |
1604 case QImode: | |
1605 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */ | |
1606 fprintf (file, "%s", byte_reg (x, 0)); | |
1607 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */ | |
1608 fprintf (file, "%s", names_big[REGNO (x)]); | |
1609 #endif | |
1610 break; | |
1611 case HImode: | |
1612 fprintf (file, "%s", names_big[REGNO (x)]); | |
1613 break; | |
1614 case SImode: | |
1615 case SFmode: | |
1616 fprintf (file, "%s", names_extended[REGNO (x)]); | |
1617 break; | |
1618 default: | |
1619 gcc_unreachable (); | |
1620 } | |
1621 break; | |
1622 | |
1623 case MEM: | |
1624 { | |
1625 rtx addr = XEXP (x, 0); | |
1626 | |
1627 fprintf (file, "@"); | |
1628 output_address (addr); | |
1629 | |
1630 /* Add a length suffix to constant addresses. Although this | |
1631 is often unnecessary, it helps to avoid ambiguity in the | |
1632 syntax of mova. If we wrote an insn like: | |
1633 | |
1634 mova/w.l @(1,@foo.b),er0 | |
1635 | |
1636 then .b would be considered part of the symbol name. | |
1637 Adding a length after foo will avoid this. */ | |
1638 if (CONSTANT_P (addr)) | |
1639 switch (code) | |
1640 { | |
1641 case 'R': | |
1642 /* Used for mov.b and bit operations. */ | |
1643 if (h8300_eightbit_constant_address_p (addr)) | |
1644 { | |
1645 fprintf (file, ":8"); | |
1646 break; | |
1647 } | |
1648 | |
1649 /* Fall through. We should not get here if we are | |
1650 processing bit operations on H8/300 or H8/300H | |
1651 because 'U' constraint does not allow bit | |
1652 operations on the tiny area on these machines. */ | |
1653 | |
1654 case 'X': | |
1655 case 'T': | |
1656 case 'S': | |
1657 if (h8300_constant_length (addr) == 2) | |
1658 fprintf (file, ":16"); | |
1659 else | |
1660 fprintf (file, ":32"); | |
1661 break; | |
1662 default: | |
1663 break; | |
1664 } | |
1665 } | |
1666 break; | |
1667 | |
1668 case CONST_INT: | |
1669 case SYMBOL_REF: | |
1670 case CONST: | |
1671 case LABEL_REF: | |
1672 fprintf (file, "#"); | |
1673 print_operand_address (file, x); | |
1674 break; | |
1675 case CONST_DOUBLE: | |
1676 { | |
1677 long val; | |
1678 REAL_VALUE_TYPE rv; | |
1679 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
1680 REAL_VALUE_TO_TARGET_SINGLE (rv, val); | |
1681 fprintf (file, "#%ld", val); | |
1682 break; | |
1683 } | |
1684 default: | |
1685 break; | |
1686 } | |
1687 } | |
1688 } | |
1689 | |
1690 /* Output assembly language output for the address ADDR to FILE. */ | |
1691 | |
1692 void | |
1693 print_operand_address (FILE *file, rtx addr) | |
1694 { | |
1695 rtx index; | |
1696 int size; | |
1697 | |
1698 switch (GET_CODE (addr)) | |
1699 { | |
1700 case REG: | |
1701 fprintf (file, "%s", h8_reg_names[REGNO (addr)]); | |
1702 break; | |
1703 | |
1704 case PRE_DEC: | |
1705 fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]); | |
1706 break; | |
1707 | |
1708 case POST_INC: | |
1709 fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]); | |
1710 break; | |
1711 | |
1712 case PRE_INC: | |
1713 fprintf (file, "+%s", h8_reg_names[REGNO (XEXP (addr, 0))]); | |
1714 break; | |
1715 | |
1716 case POST_DEC: | |
1717 fprintf (file, "%s-", h8_reg_names[REGNO (XEXP (addr, 0))]); | |
1718 break; | |
1719 | |
1720 case PLUS: | |
1721 fprintf (file, "("); | |
1722 | |
1723 index = h8300_get_index (XEXP (addr, 0), VOIDmode, &size); | |
1724 if (GET_CODE (index) == REG) | |
1725 { | |
1726 /* reg,foo */ | |
1727 print_operand_address (file, XEXP (addr, 1)); | |
1728 fprintf (file, ","); | |
1729 switch (size) | |
1730 { | |
1731 case 0: | |
1732 print_operand_address (file, index); | |
1733 break; | |
1734 | |
1735 case 1: | |
1736 print_operand (file, index, 'X'); | |
1737 fputs (".b", file); | |
1738 break; | |
1739 | |
1740 case 2: | |
1741 print_operand (file, index, 'T'); | |
1742 fputs (".w", file); | |
1743 break; | |
1744 | |
1745 case 4: | |
1746 print_operand (file, index, 'S'); | |
1747 fputs (".l", file); | |
1748 break; | |
1749 } | |
1750 /* print_operand_address (file, XEXP (addr, 0)); */ | |
1751 } | |
1752 else | |
1753 { | |
1754 /* foo+k */ | |
1755 print_operand_address (file, XEXP (addr, 0)); | |
1756 fprintf (file, "+"); | |
1757 print_operand_address (file, XEXP (addr, 1)); | |
1758 } | |
1759 fprintf (file, ")"); | |
1760 break; | |
1761 | |
1762 case CONST_INT: | |
1763 { | |
1764 /* Since the H8/300 only has 16-bit pointers, negative values are also | |
1765 those >= 32768. This happens for example with pointer minus a | |
1766 constant. We don't want to turn (char *p - 2) into | |
1767 (char *p + 65534) because loop unrolling can build upon this | |
1768 (IE: char *p + 131068). */ | |
1769 int n = INTVAL (addr); | |
1770 if (TARGET_H8300) | |
1771 n = (int) (short) n; | |
1772 fprintf (file, "%d", n); | |
1773 break; | |
1774 } | |
1775 | |
1776 default: | |
1777 output_addr_const (file, addr); | |
1778 break; | |
1779 } | |
1780 } | |
1781 | |
1782 /* Output all insn addresses and their sizes into the assembly language | |
1783 output file. This is helpful for debugging whether the length attributes | |
1784 in the md file are correct. This is not meant to be a user selectable | |
1785 option. */ | |
1786 | |
1787 void | |
1788 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED, | |
1789 int num_operands ATTRIBUTE_UNUSED) | |
1790 { | |
1791 /* This holds the last insn address. */ | |
1792 static int last_insn_address = 0; | |
1793 | |
1794 const int uid = INSN_UID (insn); | |
1795 | |
1796 if (TARGET_ADDRESSES) | |
1797 { | |
1798 fprintf (asm_out_file, "; 0x%x %d\n", INSN_ADDRESSES (uid), | |
1799 INSN_ADDRESSES (uid) - last_insn_address); | |
1800 last_insn_address = INSN_ADDRESSES (uid); | |
1801 } | |
1802 } | |
1803 | |
1804 /* Prepare for an SI sized move. */ | |
1805 | |
1806 int | |
1807 h8300_expand_movsi (rtx operands[]) | |
1808 { | |
1809 rtx src = operands[1]; | |
1810 rtx dst = operands[0]; | |
1811 if (!reload_in_progress && !reload_completed) | |
1812 { | |
1813 if (!register_operand (dst, GET_MODE (dst))) | |
1814 { | |
1815 rtx tmp = gen_reg_rtx (GET_MODE (dst)); | |
1816 emit_move_insn (tmp, src); | |
1817 operands[1] = tmp; | |
1818 } | |
1819 } | |
1820 return 0; | |
1821 } | |
1822 | |
1823 /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET). | |
1824 Define the offset between two registers, one to be eliminated, and | |
1825 the other its replacement, at the start of a routine. */ | |
1826 | |
1827 int | |
1828 h8300_initial_elimination_offset (int from, int to) | |
1829 { | |
1830 /* The number of bytes that the return address takes on the stack. */ | |
1831 int pc_size = POINTER_SIZE / BITS_PER_UNIT; | |
1832 | |
1833 /* The number of bytes that the saved frame pointer takes on the stack. */ | |
1834 int fp_size = frame_pointer_needed * UNITS_PER_WORD; | |
1835 | |
1836 /* The number of bytes that the saved registers, excluding the frame | |
1837 pointer, take on the stack. */ | |
1838 int saved_regs_size = 0; | |
1839 | |
1840 /* The number of bytes that the locals takes on the stack. */ | |
1841 int frame_size = round_frame_size (get_frame_size ()); | |
1842 | |
1843 int regno; | |
1844 | |
1845 for (regno = 0; regno <= HARD_FRAME_POINTER_REGNUM; regno++) | |
1846 if (WORD_REG_USED (regno)) | |
1847 saved_regs_size += UNITS_PER_WORD; | |
1848 | |
1849 /* Adjust saved_regs_size because the above loop took the frame | |
1850 pointer int account. */ | |
1851 saved_regs_size -= fp_size; | |
1852 | |
1853 switch (to) | |
1854 { | |
1855 case HARD_FRAME_POINTER_REGNUM: | |
1856 switch (from) | |
1857 { | |
1858 case ARG_POINTER_REGNUM: | |
1859 return pc_size + fp_size; | |
1860 case RETURN_ADDRESS_POINTER_REGNUM: | |
1861 return fp_size; | |
1862 case FRAME_POINTER_REGNUM: | |
1863 return -saved_regs_size; | |
1864 default: | |
1865 gcc_unreachable (); | |
1866 } | |
1867 break; | |
1868 case STACK_POINTER_REGNUM: | |
1869 switch (from) | |
1870 { | |
1871 case ARG_POINTER_REGNUM: | |
1872 return pc_size + saved_regs_size + frame_size; | |
1873 case RETURN_ADDRESS_POINTER_REGNUM: | |
1874 return saved_regs_size + frame_size; | |
1875 case FRAME_POINTER_REGNUM: | |
1876 return frame_size; | |
1877 default: | |
1878 gcc_unreachable (); | |
1879 } | |
1880 break; | |
1881 default: | |
1882 gcc_unreachable (); | |
1883 } | |
1884 gcc_unreachable (); | |
1885 } | |
1886 | |
1887 /* Worker function for RETURN_ADDR_RTX. */ | |
1888 | |
1889 rtx | |
1890 h8300_return_addr_rtx (int count, rtx frame) | |
1891 { | |
1892 rtx ret; | |
1893 | |
1894 if (count == 0) | |
1895 ret = gen_rtx_MEM (Pmode, | |
1896 gen_rtx_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM)); | |
1897 else if (flag_omit_frame_pointer) | |
1898 return (rtx) 0; | |
1899 else | |
1900 ret = gen_rtx_MEM (Pmode, | |
1901 memory_address (Pmode, | |
1902 plus_constant (frame, UNITS_PER_WORD))); | |
1903 set_mem_alias_set (ret, get_frame_alias_set ()); | |
1904 return ret; | |
1905 } | |
1906 | |
1907 /* Update the condition code from the insn. */ | |
1908 | |
1909 void | |
1910 notice_update_cc (rtx body, rtx insn) | |
1911 { | |
1912 rtx set; | |
1913 | |
1914 switch (get_attr_cc (insn)) | |
1915 { | |
1916 case CC_NONE: | |
1917 /* Insn does not affect CC at all. */ | |
1918 break; | |
1919 | |
1920 case CC_NONE_0HIT: | |
1921 /* Insn does not change CC, but the 0'th operand has been changed. */ | |
1922 if (cc_status.value1 != 0 | |
1923 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1)) | |
1924 cc_status.value1 = 0; | |
1925 if (cc_status.value2 != 0 | |
1926 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value2)) | |
1927 cc_status.value2 = 0; | |
1928 break; | |
1929 | |
1930 case CC_SET_ZN: | |
1931 /* Insn sets the Z,N flags of CC to recog_data.operand[0]. | |
1932 The V flag is unusable. The C flag may or may not be known but | |
1933 that's ok because alter_cond will change tests to use EQ/NE. */ | |
1934 CC_STATUS_INIT; | |
1935 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY; | |
1936 set = single_set (insn); | |
1937 cc_status.value1 = SET_SRC (set); | |
1938 if (SET_DEST (set) != cc0_rtx) | |
1939 cc_status.value2 = SET_DEST (set); | |
1940 break; | |
1941 | |
1942 case CC_SET_ZNV: | |
1943 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0]. | |
1944 The C flag may or may not be known but that's ok because | |
1945 alter_cond will change tests to use EQ/NE. */ | |
1946 CC_STATUS_INIT; | |
1947 cc_status.flags |= CC_NO_CARRY; | |
1948 set = single_set (insn); | |
1949 cc_status.value1 = SET_SRC (set); | |
1950 if (SET_DEST (set) != cc0_rtx) | |
1951 { | |
1952 /* If the destination is STRICT_LOW_PART, strip off | |
1953 STRICT_LOW_PART. */ | |
1954 if (GET_CODE (SET_DEST (set)) == STRICT_LOW_PART) | |
1955 cc_status.value2 = XEXP (SET_DEST (set), 0); | |
1956 else | |
1957 cc_status.value2 = SET_DEST (set); | |
1958 } | |
1959 break; | |
1960 | |
1961 case CC_COMPARE: | |
1962 /* The insn is a compare instruction. */ | |
1963 CC_STATUS_INIT; | |
1964 cc_status.value1 = SET_SRC (body); | |
1965 break; | |
1966 | |
1967 case CC_CLOBBER: | |
1968 /* Insn doesn't leave CC in a usable state. */ | |
1969 CC_STATUS_INIT; | |
1970 break; | |
1971 } | |
1972 } | |
1973 | |
1974 /* Given that X occurs in an address of the form (plus X constant), | |
1975 return the part of X that is expected to be a register. There are | |
1976 four kinds of addressing mode to recognize: | |
1977 | |
1978 @(dd,Rn) | |
1979 @(dd,RnL.b) | |
1980 @(dd,Rn.w) | |
1981 @(dd,ERn.l) | |
1982 | |
1983 If SIZE is nonnull, and the address is one of the last three forms, | |
1984 set *SIZE to the index multiplication factor. Set it to 0 for | |
1985 plain @(dd,Rn) addresses. | |
1986 | |
1987 MODE is the mode of the value being accessed. It can be VOIDmode | |
1988 if the address is known to be valid, but its mode is unknown. */ | |
1989 | |
1990 rtx | |
1991 h8300_get_index (rtx x, enum machine_mode mode, int *size) | |
1992 { | |
1993 int dummy, factor; | |
1994 | |
1995 if (size == 0) | |
1996 size = &dummy; | |
1997 | |
1998 factor = (mode == VOIDmode ? 0 : GET_MODE_SIZE (mode)); | |
1999 if (TARGET_H8300SX | |
2000 && factor <= 4 | |
2001 && (mode == VOIDmode | |
2002 || GET_MODE_CLASS (mode) == MODE_INT | |
2003 || GET_MODE_CLASS (mode) == MODE_FLOAT)) | |
2004 { | |
2005 if (factor <= 1 && GET_CODE (x) == ZERO_EXTEND) | |
2006 { | |
2007 /* When accessing byte-sized values, the index can be | |
2008 a zero-extended QImode or HImode register. */ | |
2009 *size = GET_MODE_SIZE (GET_MODE (XEXP (x, 0))); | |
2010 return XEXP (x, 0); | |
2011 } | |
2012 else | |
2013 { | |
2014 /* We're looking for addresses of the form: | |
2015 | |
2016 (mult X I) | |
2017 or (mult (zero_extend X) I) | |
2018 | |
2019 where I is the size of the operand being accessed. | |
2020 The canonical form of the second expression is: | |
2021 | |
2022 (and (mult (subreg X) I) J) | |
2023 | |
2024 where J == GET_MODE_MASK (GET_MODE (X)) * I. */ | |
2025 rtx index; | |
2026 | |
2027 if (GET_CODE (x) == AND | |
2028 && GET_CODE (XEXP (x, 1)) == CONST_INT | |
2029 && (factor == 0 | |
2030 || INTVAL (XEXP (x, 1)) == 0xff * factor | |
2031 || INTVAL (XEXP (x, 1)) == 0xffff * factor)) | |
2032 { | |
2033 index = XEXP (x, 0); | |
2034 *size = (INTVAL (XEXP (x, 1)) >= 0xffff ? 2 : 1); | |
2035 } | |
2036 else | |
2037 { | |
2038 index = x; | |
2039 *size = 4; | |
2040 } | |
2041 | |
2042 if (GET_CODE (index) == MULT | |
2043 && GET_CODE (XEXP (index, 1)) == CONST_INT | |
2044 && (factor == 0 || factor == INTVAL (XEXP (index, 1)))) | |
2045 return XEXP (index, 0); | |
2046 } | |
2047 } | |
2048 *size = 0; | |
2049 return x; | |
2050 } | |
2051 | |
2052 static const h8300_length_table addb_length_table = | |
2053 { | |
2054 /* #xx Rs @aa @Rs @xx */ | |
2055 { 2, 2, 4, 4, 4 }, /* add.b xx,Rd */ | |
2056 { 4, 4, 4, 4, 6 }, /* add.b xx,@aa */ | |
2057 { 4, 4, 4, 4, 6 }, /* add.b xx,@Rd */ | |
2058 { 6, 4, 4, 4, 6 } /* add.b xx,@xx */ | |
2059 }; | |
2060 | |
2061 static const h8300_length_table addw_length_table = | |
2062 { | |
2063 /* #xx Rs @aa @Rs @xx */ | |
2064 { 2, 2, 4, 4, 4 }, /* add.w xx,Rd */ | |
2065 { 4, 4, 4, 4, 6 }, /* add.w xx,@aa */ | |
2066 { 4, 4, 4, 4, 6 }, /* add.w xx,@Rd */ | |
2067 { 4, 4, 4, 4, 6 } /* add.w xx,@xx */ | |
2068 }; | |
2069 | |
2070 static const h8300_length_table addl_length_table = | |
2071 { | |
2072 /* #xx Rs @aa @Rs @xx */ | |
2073 { 2, 2, 4, 4, 4 }, /* add.l xx,Rd */ | |
2074 { 4, 4, 6, 6, 6 }, /* add.l xx,@aa */ | |
2075 { 4, 4, 6, 6, 6 }, /* add.l xx,@Rd */ | |
2076 { 4, 4, 6, 6, 6 } /* add.l xx,@xx */ | |
2077 }; | |
2078 | |
2079 #define logicb_length_table addb_length_table | |
2080 #define logicw_length_table addw_length_table | |
2081 | |
2082 static const h8300_length_table logicl_length_table = | |
2083 { | |
2084 /* #xx Rs @aa @Rs @xx */ | |
2085 { 2, 4, 4, 4, 4 }, /* and.l xx,Rd */ | |
2086 { 4, 4, 6, 6, 6 }, /* and.l xx,@aa */ | |
2087 { 4, 4, 6, 6, 6 }, /* and.l xx,@Rd */ | |
2088 { 4, 4, 6, 6, 6 } /* and.l xx,@xx */ | |
2089 }; | |
2090 | |
2091 static const h8300_length_table movb_length_table = | |
2092 { | |
2093 /* #xx Rs @aa @Rs @xx */ | |
2094 { 2, 2, 2, 2, 4 }, /* mov.b xx,Rd */ | |
2095 { 4, 2, 4, 4, 4 }, /* mov.b xx,@aa */ | |
2096 { 4, 2, 4, 4, 4 }, /* mov.b xx,@Rd */ | |
2097 { 4, 4, 4, 4, 4 } /* mov.b xx,@xx */ | |
2098 }; | |
2099 | |
2100 #define movw_length_table movb_length_table | |
2101 | |
2102 static const h8300_length_table movl_length_table = | |
2103 { | |
2104 /* #xx Rs @aa @Rs @xx */ | |
2105 { 2, 2, 4, 4, 4 }, /* mov.l xx,Rd */ | |
2106 { 4, 4, 4, 4, 4 }, /* mov.l xx,@aa */ | |
2107 { 4, 4, 4, 4, 4 }, /* mov.l xx,@Rd */ | |
2108 { 4, 4, 4, 4, 4 } /* mov.l xx,@xx */ | |
2109 }; | |
2110 | |
2111 /* Return the size of the given address or displacement constant. */ | |
2112 | |
2113 static unsigned int | |
2114 h8300_constant_length (rtx constant) | |
2115 { | |
2116 /* Check for (@d:16,Reg). */ | |
2117 if (GET_CODE (constant) == CONST_INT | |
2118 && IN_RANGE (INTVAL (constant), -0x8000, 0x7fff)) | |
2119 return 2; | |
2120 | |
2121 /* Check for (@d:16,Reg) in cases where the displacement is | |
2122 an absolute address. */ | |
2123 if (Pmode == HImode || h8300_tiny_constant_address_p (constant)) | |
2124 return 2; | |
2125 | |
2126 return 4; | |
2127 } | |
2128 | |
2129 /* Return the size of a displacement field in address ADDR, which should | |
2130 have the form (plus X constant). SIZE is the number of bytes being | |
2131 accessed. */ | |
2132 | |
2133 static unsigned int | |
2134 h8300_displacement_length (rtx addr, int size) | |
2135 { | |
2136 rtx offset; | |
2137 | |
2138 offset = XEXP (addr, 1); | |
2139 | |
2140 /* Check for @(d:2,Reg). */ | |
2141 if (register_operand (XEXP (addr, 0), VOIDmode) | |
2142 && GET_CODE (offset) == CONST_INT | |
2143 && (INTVAL (offset) == size | |
2144 || INTVAL (offset) == size * 2 | |
2145 || INTVAL (offset) == size * 3)) | |
2146 return 0; | |
2147 | |
2148 return h8300_constant_length (offset); | |
2149 } | |
2150 | |
2151 /* Store the class of operand OP in *OPCLASS and return the length of any | |
2152 extra operand fields. SIZE is the number of bytes in OP. OPCLASS | |
2153 can be null if only the length is needed. */ | |
2154 | |
2155 static unsigned int | |
2156 h8300_classify_operand (rtx op, int size, enum h8300_operand_class *opclass) | |
2157 { | |
2158 enum h8300_operand_class dummy; | |
2159 | |
2160 if (opclass == 0) | |
2161 opclass = &dummy; | |
2162 | |
2163 if (CONSTANT_P (op)) | |
2164 { | |
2165 *opclass = H8OP_IMMEDIATE; | |
2166 | |
2167 /* Byte-sized immediates are stored in the opcode fields. */ | |
2168 if (size == 1) | |
2169 return 0; | |
2170 | |
2171 /* If this is a 32-bit instruction, see whether the constant | |
2172 will fit into a 16-bit immediate field. */ | |
2173 if (TARGET_H8300SX | |
2174 && size == 4 | |
2175 && GET_CODE (op) == CONST_INT | |
2176 && IN_RANGE (INTVAL (op), 0, 0xffff)) | |
2177 return 2; | |
2178 | |
2179 return size; | |
2180 } | |
2181 else if (GET_CODE (op) == MEM) | |
2182 { | |
2183 op = XEXP (op, 0); | |
2184 if (CONSTANT_P (op)) | |
2185 { | |
2186 *opclass = H8OP_MEM_ABSOLUTE; | |
2187 return h8300_constant_length (op); | |
2188 } | |
2189 else if (GET_CODE (op) == PLUS && CONSTANT_P (XEXP (op, 1))) | |
2190 { | |
2191 *opclass = H8OP_MEM_COMPLEX; | |
2192 return h8300_displacement_length (op, size); | |
2193 } | |
2194 else if (GET_RTX_CLASS (GET_CODE (op)) == RTX_AUTOINC) | |
2195 { | |
2196 *opclass = H8OP_MEM_COMPLEX; | |
2197 return 0; | |
2198 } | |
2199 else if (register_operand (op, VOIDmode)) | |
2200 { | |
2201 *opclass = H8OP_MEM_BASE; | |
2202 return 0; | |
2203 } | |
2204 } | |
2205 gcc_assert (register_operand (op, VOIDmode)); | |
2206 *opclass = H8OP_REGISTER; | |
2207 return 0; | |
2208 } | |
2209 | |
2210 /* Return the length of the instruction described by TABLE given that | |
2211 its operands are OP1 and OP2. OP1 must be an h8300_dst_operand | |
2212 and OP2 must be an h8300_src_operand. */ | |
2213 | |
2214 static unsigned int | |
2215 h8300_length_from_table (rtx op1, rtx op2, const h8300_length_table *table) | |
2216 { | |
2217 enum h8300_operand_class op1_class, op2_class; | |
2218 unsigned int size, immediate_length; | |
2219 | |
2220 size = GET_MODE_SIZE (GET_MODE (op1)); | |
2221 immediate_length = (h8300_classify_operand (op1, size, &op1_class) | |
2222 + h8300_classify_operand (op2, size, &op2_class)); | |
2223 return immediate_length + (*table)[op1_class - 1][op2_class]; | |
2224 } | |
2225 | |
2226 /* Return the length of a unary instruction such as neg or not given that | |
2227 its operand is OP. */ | |
2228 | |
2229 unsigned int | |
2230 h8300_unary_length (rtx op) | |
2231 { | |
2232 enum h8300_operand_class opclass; | |
2233 unsigned int size, operand_length; | |
2234 | |
2235 size = GET_MODE_SIZE (GET_MODE (op)); | |
2236 operand_length = h8300_classify_operand (op, size, &opclass); | |
2237 switch (opclass) | |
2238 { | |
2239 case H8OP_REGISTER: | |
2240 return 2; | |
2241 | |
2242 case H8OP_MEM_BASE: | |
2243 return (size == 4 ? 6 : 4); | |
2244 | |
2245 case H8OP_MEM_ABSOLUTE: | |
2246 return operand_length + (size == 4 ? 6 : 4); | |
2247 | |
2248 case H8OP_MEM_COMPLEX: | |
2249 return operand_length + 6; | |
2250 | |
2251 default: | |
2252 gcc_unreachable (); | |
2253 } | |
2254 } | |
2255 | |
2256 /* Likewise short immediate instructions such as add.w #xx:3,OP. */ | |
2257 | |
2258 static unsigned int | |
2259 h8300_short_immediate_length (rtx op) | |
2260 { | |
2261 enum h8300_operand_class opclass; | |
2262 unsigned int size, operand_length; | |
2263 | |
2264 size = GET_MODE_SIZE (GET_MODE (op)); | |
2265 operand_length = h8300_classify_operand (op, size, &opclass); | |
2266 | |
2267 switch (opclass) | |
2268 { | |
2269 case H8OP_REGISTER: | |
2270 return 2; | |
2271 | |
2272 case H8OP_MEM_BASE: | |
2273 case H8OP_MEM_ABSOLUTE: | |
2274 case H8OP_MEM_COMPLEX: | |
2275 return 4 + operand_length; | |
2276 | |
2277 default: | |
2278 gcc_unreachable (); | |
2279 } | |
2280 } | |
2281 | |
2282 /* Likewise bitfield load and store instructions. */ | |
2283 | |
2284 static unsigned int | |
2285 h8300_bitfield_length (rtx op, rtx op2) | |
2286 { | |
2287 enum h8300_operand_class opclass; | |
2288 unsigned int size, operand_length; | |
2289 | |
2290 if (GET_CODE (op) == REG) | |
2291 op = op2; | |
2292 gcc_assert (GET_CODE (op) != REG); | |
2293 | |
2294 size = GET_MODE_SIZE (GET_MODE (op)); | |
2295 operand_length = h8300_classify_operand (op, size, &opclass); | |
2296 | |
2297 switch (opclass) | |
2298 { | |
2299 case H8OP_MEM_BASE: | |
2300 case H8OP_MEM_ABSOLUTE: | |
2301 case H8OP_MEM_COMPLEX: | |
2302 return 4 + operand_length; | |
2303 | |
2304 default: | |
2305 gcc_unreachable (); | |
2306 } | |
2307 } | |
2308 | |
2309 /* Calculate the length of general binary instruction INSN using TABLE. */ | |
2310 | |
2311 static unsigned int | |
2312 h8300_binary_length (rtx insn, const h8300_length_table *table) | |
2313 { | |
2314 rtx set; | |
2315 | |
2316 set = single_set (insn); | |
2317 gcc_assert (set); | |
2318 | |
2319 if (BINARY_P (SET_SRC (set))) | |
2320 return h8300_length_from_table (XEXP (SET_SRC (set), 0), | |
2321 XEXP (SET_SRC (set), 1), table); | |
2322 else | |
2323 { | |
2324 gcc_assert (GET_RTX_CLASS (GET_CODE (SET_SRC (set))) == RTX_TERNARY); | |
2325 return h8300_length_from_table (XEXP (XEXP (SET_SRC (set), 1), 0), | |
2326 XEXP (XEXP (SET_SRC (set), 1), 1), | |
2327 table); | |
2328 } | |
2329 } | |
2330 | |
2331 /* Subroutine of h8300_move_length. Return true if OP is 1- or 2-byte | |
2332 memory reference and either (1) it has the form @(d:16,Rn) or | |
2333 (2) its address has the code given by INC_CODE. */ | |
2334 | |
2335 static bool | |
2336 h8300_short_move_mem_p (rtx op, enum rtx_code inc_code) | |
2337 { | |
2338 rtx addr; | |
2339 unsigned int size; | |
2340 | |
2341 if (GET_CODE (op) != MEM) | |
2342 return false; | |
2343 | |
2344 addr = XEXP (op, 0); | |
2345 size = GET_MODE_SIZE (GET_MODE (op)); | |
2346 if (size != 1 && size != 2) | |
2347 return false; | |
2348 | |
2349 return (GET_CODE (addr) == inc_code | |
2350 || (GET_CODE (addr) == PLUS | |
2351 && GET_CODE (XEXP (addr, 0)) == REG | |
2352 && h8300_displacement_length (addr, size) == 2)); | |
2353 } | |
2354 | |
2355 /* Calculate the length of move instruction INSN using the given length | |
2356 table. Although the tables are correct for most cases, there is some | |
2357 irregularity in the length of mov.b and mov.w. The following forms: | |
2358 | |
2359 mov @ERs+, Rd | |
2360 mov @(d:16,ERs), Rd | |
2361 mov Rs, @-ERd | |
2362 mov Rs, @(d:16,ERd) | |
2363 | |
2364 are two bytes shorter than most other "mov Rs, @complex" or | |
2365 "mov @complex,Rd" combinations. */ | |
2366 | |
2367 static unsigned int | |
2368 h8300_move_length (rtx *operands, const h8300_length_table *table) | |
2369 { | |
2370 unsigned int size; | |
2371 | |
2372 size = h8300_length_from_table (operands[0], operands[1], table); | |
2373 if (REG_P (operands[0]) && h8300_short_move_mem_p (operands[1], POST_INC)) | |
2374 size -= 2; | |
2375 if (REG_P (operands[1]) && h8300_short_move_mem_p (operands[0], PRE_DEC)) | |
2376 size -= 2; | |
2377 return size; | |
2378 } | |
2379 | |
2380 /* Return the length of a mova instruction with the given operands. | |
2381 DEST is the register destination, SRC is the source address and | |
2382 OFFSET is the 16-bit or 32-bit displacement. */ | |
2383 | |
2384 static unsigned int | |
2385 h8300_mova_length (rtx dest, rtx src, rtx offset) | |
2386 { | |
2387 unsigned int size; | |
2388 | |
2389 size = (2 | |
2390 + h8300_constant_length (offset) | |
2391 + h8300_classify_operand (src, GET_MODE_SIZE (GET_MODE (src)), 0)); | |
2392 if (!REG_P (dest) || !REG_P (src) || REGNO (src) != REGNO (dest)) | |
2393 size += 2; | |
2394 return size; | |
2395 } | |
2396 | |
2397 /* Compute the length of INSN based on its length_table attribute. | |
2398 OPERANDS is the array of its operands. */ | |
2399 | |
2400 unsigned int | |
2401 h8300_insn_length_from_table (rtx insn, rtx * operands) | |
2402 { | |
2403 switch (get_attr_length_table (insn)) | |
2404 { | |
2405 case LENGTH_TABLE_NONE: | |
2406 gcc_unreachable (); | |
2407 | |
2408 case LENGTH_TABLE_ADDB: | |
2409 return h8300_binary_length (insn, &addb_length_table); | |
2410 | |
2411 case LENGTH_TABLE_ADDW: | |
2412 return h8300_binary_length (insn, &addw_length_table); | |
2413 | |
2414 case LENGTH_TABLE_ADDL: | |
2415 return h8300_binary_length (insn, &addl_length_table); | |
2416 | |
2417 case LENGTH_TABLE_LOGICB: | |
2418 return h8300_binary_length (insn, &logicb_length_table); | |
2419 | |
2420 case LENGTH_TABLE_MOVB: | |
2421 return h8300_move_length (operands, &movb_length_table); | |
2422 | |
2423 case LENGTH_TABLE_MOVW: | |
2424 return h8300_move_length (operands, &movw_length_table); | |
2425 | |
2426 case LENGTH_TABLE_MOVL: | |
2427 return h8300_move_length (operands, &movl_length_table); | |
2428 | |
2429 case LENGTH_TABLE_MOVA: | |
2430 return h8300_mova_length (operands[0], operands[1], operands[2]); | |
2431 | |
2432 case LENGTH_TABLE_MOVA_ZERO: | |
2433 return h8300_mova_length (operands[0], operands[1], const0_rtx); | |
2434 | |
2435 case LENGTH_TABLE_UNARY: | |
2436 return h8300_unary_length (operands[0]); | |
2437 | |
2438 case LENGTH_TABLE_MOV_IMM4: | |
2439 return 2 + h8300_classify_operand (operands[0], 0, 0); | |
2440 | |
2441 case LENGTH_TABLE_SHORT_IMMEDIATE: | |
2442 return h8300_short_immediate_length (operands[0]); | |
2443 | |
2444 case LENGTH_TABLE_BITFIELD: | |
2445 return h8300_bitfield_length (operands[0], operands[1]); | |
2446 | |
2447 case LENGTH_TABLE_BITBRANCH: | |
2448 return h8300_bitfield_length (operands[1], operands[2]) - 2; | |
2449 | |
2450 default: | |
2451 gcc_unreachable (); | |
2452 } | |
2453 } | |
2454 | |
2455 /* Return true if LHS and RHS are memory references that can be mapped | |
2456 to the same h8sx assembly operand. LHS appears as the destination of | |
2457 an instruction and RHS appears as a source. | |
2458 | |
2459 Three cases are allowed: | |
2460 | |
2461 - RHS is @+Rn or @-Rn, LHS is @Rn | |
2462 - RHS is @Rn, LHS is @Rn+ or @Rn- | |
2463 - RHS and LHS have the same address and neither has side effects. */ | |
2464 | |
2465 bool | |
2466 h8sx_mergeable_memrefs_p (rtx lhs, rtx rhs) | |
2467 { | |
2468 if (GET_CODE (rhs) == MEM && GET_CODE (lhs) == MEM) | |
2469 { | |
2470 rhs = XEXP (rhs, 0); | |
2471 lhs = XEXP (lhs, 0); | |
2472 | |
2473 if (GET_CODE (rhs) == PRE_INC || GET_CODE (rhs) == PRE_DEC) | |
2474 return rtx_equal_p (XEXP (rhs, 0), lhs); | |
2475 | |
2476 if (GET_CODE (lhs) == POST_INC || GET_CODE (lhs) == POST_DEC) | |
2477 return rtx_equal_p (rhs, XEXP (lhs, 0)); | |
2478 | |
2479 if (rtx_equal_p (rhs, lhs)) | |
2480 return true; | |
2481 } | |
2482 return false; | |
2483 } | |
2484 | |
2485 /* Return true if OPERANDS[1] can be mapped to the same assembly | |
2486 operand as OPERANDS[0]. */ | |
2487 | |
2488 bool | |
2489 h8300_operands_match_p (rtx *operands) | |
2490 { | |
2491 if (register_operand (operands[0], VOIDmode) | |
2492 && register_operand (operands[1], VOIDmode)) | |
2493 return true; | |
2494 | |
2495 if (h8sx_mergeable_memrefs_p (operands[0], operands[1])) | |
2496 return true; | |
2497 | |
2498 return false; | |
2499 } | |
2500 | |
2501 /* Try using movmd to move LENGTH bytes from memory region SRC to memory | |
2502 region DEST. The two regions do not overlap and have the common | |
2503 alignment given by ALIGNMENT. Return true on success. | |
2504 | |
2505 Using movmd for variable-length moves seems to involve some | |
2506 complex trade-offs. For instance: | |
2507 | |
2508 - Preparing for a movmd instruction is similar to preparing | |
2509 for a memcpy. The main difference is that the arguments | |
2510 are moved into er4, er5 and er6 rather than er0, er1 and er2. | |
2511 | |
2512 - Since movmd clobbers the frame pointer, we need to save | |
2513 and restore it somehow when frame_pointer_needed. This can | |
2514 sometimes make movmd sequences longer than calls to memcpy(). | |
2515 | |
2516 - The counter register is 16 bits, so the instruction is only | |
2517 suitable for variable-length moves when sizeof (size_t) == 2. | |
2518 That's only true in normal mode. | |
2519 | |
2520 - We will often lack static alignment information. Falling back | |
2521 on movmd.b would likely be slower than calling memcpy(), at least | |
2522 for big moves. | |
2523 | |
2524 This function therefore only uses movmd when the length is a | |
2525 known constant, and only then if -fomit-frame-pointer is in | |
2526 effect or if we're not optimizing for size. | |
2527 | |
2528 At the moment the function uses movmd for all in-range constants, | |
2529 but it might be better to fall back on memcpy() for large moves | |
2530 if ALIGNMENT == 1. */ | |
2531 | |
2532 bool | |
2533 h8sx_emit_movmd (rtx dest, rtx src, rtx length, | |
2534 HOST_WIDE_INT alignment) | |
2535 { | |
2536 if (!flag_omit_frame_pointer && optimize_size) | |
2537 return false; | |
2538 | |
2539 if (GET_CODE (length) == CONST_INT) | |
2540 { | |
2541 rtx dest_reg, src_reg, first_dest, first_src; | |
2542 HOST_WIDE_INT n; | |
2543 int factor; | |
2544 | |
2545 /* Use movmd.l if the alignment allows it, otherwise fall back | |
2546 on movmd.b. */ | |
2547 factor = (alignment >= 2 ? 4 : 1); | |
2548 | |
2549 /* Make sure the length is within range. We can handle counter | |
2550 values up to 65536, although HImode truncation will make | |
2551 the count appear negative in rtl dumps. */ | |
2552 n = INTVAL (length); | |
2553 if (n <= 0 || n / factor > 65536) | |
2554 return false; | |
2555 | |
2556 /* Create temporary registers for the source and destination | |
2557 pointers. Initialize them to the start of each region. */ | |
2558 dest_reg = copy_addr_to_reg (XEXP (dest, 0)); | |
2559 src_reg = copy_addr_to_reg (XEXP (src, 0)); | |
2560 | |
2561 /* Create references to the movmd source and destination blocks. */ | |
2562 first_dest = replace_equiv_address (dest, dest_reg); | |
2563 first_src = replace_equiv_address (src, src_reg); | |
2564 | |
2565 set_mem_size (first_dest, GEN_INT (n & -factor)); | |
2566 set_mem_size (first_src, GEN_INT (n & -factor)); | |
2567 | |
2568 length = copy_to_mode_reg (HImode, gen_int_mode (n / factor, HImode)); | |
2569 emit_insn (gen_movmd (first_dest, first_src, length, GEN_INT (factor))); | |
2570 | |
2571 if ((n & -factor) != n) | |
2572 { | |
2573 /* Move SRC and DEST past the region we just copied. | |
2574 This is done to update the memory attributes. */ | |
2575 dest = adjust_address (dest, BLKmode, n & -factor); | |
2576 src = adjust_address (src, BLKmode, n & -factor); | |
2577 | |
2578 /* Replace the addresses with the source and destination | |
2579 registers, which movmd has left with the right values. */ | |
2580 dest = replace_equiv_address (dest, dest_reg); | |
2581 src = replace_equiv_address (src, src_reg); | |
2582 | |
2583 /* Mop up the left-over bytes. */ | |
2584 if (n & 2) | |
2585 emit_move_insn (adjust_address (dest, HImode, 0), | |
2586 adjust_address (src, HImode, 0)); | |
2587 if (n & 1) | |
2588 emit_move_insn (adjust_address (dest, QImode, n & 2), | |
2589 adjust_address (src, QImode, n & 2)); | |
2590 } | |
2591 return true; | |
2592 } | |
2593 return false; | |
2594 } | |
2595 | |
2596 /* Move ADDR into er6 after pushing its old value onto the stack. */ | |
2597 | |
2598 void | |
2599 h8300_swap_into_er6 (rtx addr) | |
2600 { | |
2601 push (HARD_FRAME_POINTER_REGNUM); | |
2602 emit_move_insn (hard_frame_pointer_rtx, addr); | |
2603 if (REGNO (addr) == SP_REG) | |
2604 emit_move_insn (hard_frame_pointer_rtx, | |
2605 plus_constant (hard_frame_pointer_rtx, | |
2606 GET_MODE_SIZE (word_mode))); | |
2607 } | |
2608 | |
2609 /* Move the current value of er6 into ADDR and pop its old value | |
2610 from the stack. */ | |
2611 | |
2612 void | |
2613 h8300_swap_out_of_er6 (rtx addr) | |
2614 { | |
2615 if (REGNO (addr) != SP_REG) | |
2616 emit_move_insn (addr, hard_frame_pointer_rtx); | |
2617 pop (HARD_FRAME_POINTER_REGNUM); | |
2618 } | |
2619 | |
2620 /* Return the length of mov instruction. */ | |
2621 | |
2622 unsigned int | |
2623 compute_mov_length (rtx *operands) | |
2624 { | |
2625 /* If the mov instruction involves a memory operand, we compute the | |
2626 length, assuming the largest addressing mode is used, and then | |
2627 adjust later in the function. Otherwise, we compute and return | |
2628 the exact length in one step. */ | |
2629 enum machine_mode mode = GET_MODE (operands[0]); | |
2630 rtx dest = operands[0]; | |
2631 rtx src = operands[1]; | |
2632 rtx addr; | |
2633 | |
2634 if (GET_CODE (src) == MEM) | |
2635 addr = XEXP (src, 0); | |
2636 else if (GET_CODE (dest) == MEM) | |
2637 addr = XEXP (dest, 0); | |
2638 else | |
2639 addr = NULL_RTX; | |
2640 | |
2641 if (TARGET_H8300) | |
2642 { | |
2643 unsigned int base_length; | |
2644 | |
2645 switch (mode) | |
2646 { | |
2647 case QImode: | |
2648 if (addr == NULL_RTX) | |
2649 return 2; | |
2650 | |
2651 /* The eightbit addressing is available only in QImode, so | |
2652 go ahead and take care of it. */ | |
2653 if (h8300_eightbit_constant_address_p (addr)) | |
2654 return 2; | |
2655 | |
2656 base_length = 4; | |
2657 break; | |
2658 | |
2659 case HImode: | |
2660 if (addr == NULL_RTX) | |
2661 { | |
2662 if (REG_P (src)) | |
2663 return 2; | |
2664 | |
2665 if (src == const0_rtx) | |
2666 return 2; | |
2667 | |
2668 return 4; | |
2669 } | |
2670 | |
2671 base_length = 4; | |
2672 break; | |
2673 | |
2674 case SImode: | |
2675 if (addr == NULL_RTX) | |
2676 { | |
2677 if (REG_P (src)) | |
2678 return 4; | |
2679 | |
2680 if (GET_CODE (src) == CONST_INT) | |
2681 { | |
2682 if (src == const0_rtx) | |
2683 return 4; | |
2684 | |
2685 if ((INTVAL (src) & 0xffff) == 0) | |
2686 return 6; | |
2687 | |
2688 if ((INTVAL (src) & 0xffff) == 0) | |
2689 return 6; | |
2690 | |
2691 if ((INTVAL (src) & 0xffff) | |
2692 == ((INTVAL (src) >> 16) & 0xffff)) | |
2693 return 6; | |
2694 } | |
2695 return 8; | |
2696 } | |
2697 | |
2698 base_length = 8; | |
2699 break; | |
2700 | |
2701 case SFmode: | |
2702 if (addr == NULL_RTX) | |
2703 { | |
2704 if (REG_P (src)) | |
2705 return 4; | |
2706 | |
2707 if (CONST_DOUBLE_OK_FOR_LETTER_P (src, 'G')) | |
2708 return 4; | |
2709 | |
2710 return 8; | |
2711 } | |
2712 | |
2713 base_length = 8; | |
2714 break; | |
2715 | |
2716 default: | |
2717 gcc_unreachable (); | |
2718 } | |
2719 | |
2720 /* Adjust the length based on the addressing mode used. | |
2721 Specifically, we subtract the difference between the actual | |
2722 length and the longest one, which is @(d:16,Rs). For SImode | |
2723 and SFmode, we double the adjustment because two mov.w are | |
2724 used to do the job. */ | |
2725 | |
2726 /* @Rs+ and @-Rd are 2 bytes shorter than the longest. */ | |
2727 if (GET_CODE (addr) == PRE_DEC | |
2728 || GET_CODE (addr) == POST_INC) | |
2729 { | |
2730 if (mode == QImode || mode == HImode) | |
2731 return base_length - 2; | |
2732 else | |
2733 /* In SImode and SFmode, we use two mov.w instructions, so | |
2734 double the adjustment. */ | |
2735 return base_length - 4; | |
2736 } | |
2737 | |
2738 /* @Rs and @Rd are 2 bytes shorter than the longest. Note that | |
2739 in SImode and SFmode, the second mov.w involves an address | |
2740 with displacement, namely @(2,Rs) or @(2,Rd), so we subtract | |
2741 only 2 bytes. */ | |
2742 if (GET_CODE (addr) == REG) | |
2743 return base_length - 2; | |
2744 | |
2745 return base_length; | |
2746 } | |
2747 else | |
2748 { | |
2749 unsigned int base_length; | |
2750 | |
2751 switch (mode) | |
2752 { | |
2753 case QImode: | |
2754 if (addr == NULL_RTX) | |
2755 return 2; | |
2756 | |
2757 /* The eightbit addressing is available only in QImode, so | |
2758 go ahead and take care of it. */ | |
2759 if (h8300_eightbit_constant_address_p (addr)) | |
2760 return 2; | |
2761 | |
2762 base_length = 8; | |
2763 break; | |
2764 | |
2765 case HImode: | |
2766 if (addr == NULL_RTX) | |
2767 { | |
2768 if (REG_P (src)) | |
2769 return 2; | |
2770 | |
2771 if (src == const0_rtx) | |
2772 return 2; | |
2773 | |
2774 return 4; | |
2775 } | |
2776 | |
2777 base_length = 8; | |
2778 break; | |
2779 | |
2780 case SImode: | |
2781 if (addr == NULL_RTX) | |
2782 { | |
2783 if (REG_P (src)) | |
2784 { | |
2785 if (REGNO (src) == MAC_REG || REGNO (dest) == MAC_REG) | |
2786 return 4; | |
2787 else | |
2788 return 2; | |
2789 } | |
2790 | |
2791 if (GET_CODE (src) == CONST_INT) | |
2792 { | |
2793 int val = INTVAL (src); | |
2794 | |
2795 if (val == 0) | |
2796 return 2; | |
2797 | |
2798 if (val == (val & 0x00ff) || val == (val & 0xff00)) | |
2799 return 4; | |
2800 | |
2801 switch (val & 0xffffffff) | |
2802 { | |
2803 case 0xffffffff: | |
2804 case 0xfffffffe: | |
2805 case 0xfffffffc: | |
2806 case 0x0000ffff: | |
2807 case 0x0000fffe: | |
2808 case 0xffff0000: | |
2809 case 0xfffe0000: | |
2810 case 0x00010000: | |
2811 case 0x00020000: | |
2812 return 4; | |
2813 } | |
2814 } | |
2815 return 6; | |
2816 } | |
2817 | |
2818 base_length = 10; | |
2819 break; | |
2820 | |
2821 case SFmode: | |
2822 if (addr == NULL_RTX) | |
2823 { | |
2824 if (REG_P (src)) | |
2825 return 2; | |
2826 | |
2827 if (CONST_DOUBLE_OK_FOR_LETTER_P (src, 'G')) | |
2828 return 2; | |
2829 | |
2830 return 6; | |
2831 } | |
2832 | |
2833 base_length = 10; | |
2834 break; | |
2835 | |
2836 default: | |
2837 gcc_unreachable (); | |
2838 } | |
2839 | |
2840 /* Adjust the length based on the addressing mode used. | |
2841 Specifically, we subtract the difference between the actual | |
2842 length and the longest one, which is @(d:24,ERs). */ | |
2843 | |
2844 /* @ERs+ and @-ERd are 6 bytes shorter than the longest. */ | |
2845 if (GET_CODE (addr) == PRE_DEC | |
2846 || GET_CODE (addr) == POST_INC) | |
2847 return base_length - 6; | |
2848 | |
2849 /* @ERs and @ERd are 6 bytes shorter than the longest. */ | |
2850 if (GET_CODE (addr) == REG) | |
2851 return base_length - 6; | |
2852 | |
2853 /* @(d:16,ERs) and @(d:16,ERd) are 4 bytes shorter than the | |
2854 longest. */ | |
2855 if (GET_CODE (addr) == PLUS | |
2856 && GET_CODE (XEXP (addr, 0)) == REG | |
2857 && GET_CODE (XEXP (addr, 1)) == CONST_INT | |
2858 && INTVAL (XEXP (addr, 1)) > -32768 | |
2859 && INTVAL (XEXP (addr, 1)) < 32767) | |
2860 return base_length - 4; | |
2861 | |
2862 /* @aa:16 is 4 bytes shorter than the longest. */ | |
2863 if (h8300_tiny_constant_address_p (addr)) | |
2864 return base_length - 4; | |
2865 | |
2866 /* @aa:24 is 2 bytes shorter than the longest. */ | |
2867 if (CONSTANT_P (addr)) | |
2868 return base_length - 2; | |
2869 | |
2870 return base_length; | |
2871 } | |
2872 } | |
2873 | |
2874 /* Output an addition insn. */ | |
2875 | |
2876 const char * | |
2877 output_plussi (rtx *operands) | |
2878 { | |
2879 enum machine_mode mode = GET_MODE (operands[0]); | |
2880 | |
2881 gcc_assert (mode == SImode); | |
2882 | |
2883 if (TARGET_H8300) | |
2884 { | |
2885 if (GET_CODE (operands[2]) == REG) | |
2886 return "add.w\t%f2,%f0\n\taddx\t%y2,%y0\n\taddx\t%z2,%z0"; | |
2887 | |
2888 if (GET_CODE (operands[2]) == CONST_INT) | |
2889 { | |
2890 HOST_WIDE_INT n = INTVAL (operands[2]); | |
2891 | |
2892 if ((n & 0xffffff) == 0) | |
2893 return "add\t%z2,%z0"; | |
2894 if ((n & 0xffff) == 0) | |
2895 return "add\t%y2,%y0\n\taddx\t%z2,%z0"; | |
2896 if ((n & 0xff) == 0) | |
2897 return "add\t%x2,%x0\n\taddx\t%y2,%y0\n\taddx\t%z2,%z0"; | |
2898 } | |
2899 | |
2900 return "add\t%w2,%w0\n\taddx\t%x2,%x0\n\taddx\t%y2,%y0\n\taddx\t%z2,%z0"; | |
2901 } | |
2902 else | |
2903 { | |
2904 if (GET_CODE (operands[2]) == CONST_INT | |
2905 && register_operand (operands[1], VOIDmode)) | |
2906 { | |
2907 HOST_WIDE_INT intval = INTVAL (operands[2]); | |
2908 | |
2909 if (TARGET_H8300SX && (intval >= 1 && intval <= 7)) | |
2910 return "add.l\t%S2,%S0"; | |
2911 if (TARGET_H8300SX && (intval >= -7 && intval <= -1)) | |
2912 return "sub.l\t%G2,%S0"; | |
2913 | |
2914 /* See if we can finish with 2 bytes. */ | |
2915 | |
2916 switch ((unsigned int) intval & 0xffffffff) | |
2917 { | |
2918 case 0x00000001: | |
2919 case 0x00000002: | |
2920 case 0x00000004: | |
2921 return "adds\t%2,%S0"; | |
2922 | |
2923 case 0xffffffff: | |
2924 case 0xfffffffe: | |
2925 case 0xfffffffc: | |
2926 return "subs\t%G2,%S0"; | |
2927 | |
2928 case 0x00010000: | |
2929 case 0x00020000: | |
2930 operands[2] = GEN_INT (intval >> 16); | |
2931 return "inc.w\t%2,%e0"; | |
2932 | |
2933 case 0xffff0000: | |
2934 case 0xfffe0000: | |
2935 operands[2] = GEN_INT (intval >> 16); | |
2936 return "dec.w\t%G2,%e0"; | |
2937 } | |
2938 | |
2939 /* See if we can finish with 4 bytes. */ | |
2940 if ((intval & 0xffff) == 0) | |
2941 { | |
2942 operands[2] = GEN_INT (intval >> 16); | |
2943 return "add.w\t%2,%e0"; | |
2944 } | |
2945 } | |
2946 | |
2947 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) | |
2948 { | |
2949 operands[2] = GEN_INT (-INTVAL (operands[2])); | |
2950 return "sub.l\t%S2,%S0"; | |
2951 } | |
2952 return "add.l\t%S2,%S0"; | |
2953 } | |
2954 } | |
2955 | |
2956 /* ??? It would be much easier to add the h8sx stuff if a single function | |
2957 classified the addition as either inc/dec, adds/subs, add.w or add.l. */ | |
2958 /* Compute the length of an addition insn. */ | |
2959 | |
2960 unsigned int | |
2961 compute_plussi_length (rtx *operands) | |
2962 { | |
2963 enum machine_mode mode = GET_MODE (operands[0]); | |
2964 | |
2965 gcc_assert (mode == SImode); | |
2966 | |
2967 if (TARGET_H8300) | |
2968 { | |
2969 if (GET_CODE (operands[2]) == REG) | |
2970 return 6; | |
2971 | |
2972 if (GET_CODE (operands[2]) == CONST_INT) | |
2973 { | |
2974 HOST_WIDE_INT n = INTVAL (operands[2]); | |
2975 | |
2976 if ((n & 0xffffff) == 0) | |
2977 return 2; | |
2978 if ((n & 0xffff) == 0) | |
2979 return 4; | |
2980 if ((n & 0xff) == 0) | |
2981 return 6; | |
2982 } | |
2983 | |
2984 return 8; | |
2985 } | |
2986 else | |
2987 { | |
2988 if (GET_CODE (operands[2]) == CONST_INT | |
2989 && register_operand (operands[1], VOIDmode)) | |
2990 { | |
2991 HOST_WIDE_INT intval = INTVAL (operands[2]); | |
2992 | |
2993 if (TARGET_H8300SX && (intval >= 1 && intval <= 7)) | |
2994 return 2; | |
2995 if (TARGET_H8300SX && (intval >= -7 && intval <= -1)) | |
2996 return 2; | |
2997 | |
2998 /* See if we can finish with 2 bytes. */ | |
2999 | |
3000 switch ((unsigned int) intval & 0xffffffff) | |
3001 { | |
3002 case 0x00000001: | |
3003 case 0x00000002: | |
3004 case 0x00000004: | |
3005 return 2; | |
3006 | |
3007 case 0xffffffff: | |
3008 case 0xfffffffe: | |
3009 case 0xfffffffc: | |
3010 return 2; | |
3011 | |
3012 case 0x00010000: | |
3013 case 0x00020000: | |
3014 return 2; | |
3015 | |
3016 case 0xffff0000: | |
3017 case 0xfffe0000: | |
3018 return 2; | |
3019 } | |
3020 | |
3021 /* See if we can finish with 4 bytes. */ | |
3022 if ((intval & 0xffff) == 0) | |
3023 return 4; | |
3024 } | |
3025 | |
3026 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) | |
3027 return h8300_length_from_table (operands[0], | |
3028 GEN_INT (-INTVAL (operands[2])), | |
3029 &addl_length_table); | |
3030 else | |
3031 return h8300_length_from_table (operands[0], operands[2], | |
3032 &addl_length_table); | |
3033 return 6; | |
3034 } | |
3035 } | |
3036 | |
3037 /* Compute which flag bits are valid after an addition insn. */ | |
3038 | |
3039 int | |
3040 compute_plussi_cc (rtx *operands) | |
3041 { | |
3042 enum machine_mode mode = GET_MODE (operands[0]); | |
3043 | |
3044 gcc_assert (mode == SImode); | |
3045 | |
3046 if (TARGET_H8300) | |
3047 { | |
3048 return CC_CLOBBER; | |
3049 } | |
3050 else | |
3051 { | |
3052 if (GET_CODE (operands[2]) == CONST_INT | |
3053 && register_operand (operands[1], VOIDmode)) | |
3054 { | |
3055 HOST_WIDE_INT intval = INTVAL (operands[2]); | |
3056 | |
3057 if (TARGET_H8300SX && (intval >= 1 && intval <= 7)) | |
3058 return CC_SET_ZN; | |
3059 if (TARGET_H8300SX && (intval >= -7 && intval <= -1)) | |
3060 return CC_SET_ZN; | |
3061 | |
3062 /* See if we can finish with 2 bytes. */ | |
3063 | |
3064 switch ((unsigned int) intval & 0xffffffff) | |
3065 { | |
3066 case 0x00000001: | |
3067 case 0x00000002: | |
3068 case 0x00000004: | |
3069 return CC_NONE_0HIT; | |
3070 | |
3071 case 0xffffffff: | |
3072 case 0xfffffffe: | |
3073 case 0xfffffffc: | |
3074 return CC_NONE_0HIT; | |
3075 | |
3076 case 0x00010000: | |
3077 case 0x00020000: | |
3078 return CC_CLOBBER; | |
3079 | |
3080 case 0xffff0000: | |
3081 case 0xfffe0000: | |
3082 return CC_CLOBBER; | |
3083 } | |
3084 | |
3085 /* See if we can finish with 4 bytes. */ | |
3086 if ((intval & 0xffff) == 0) | |
3087 return CC_CLOBBER; | |
3088 } | |
3089 | |
3090 return CC_SET_ZN; | |
3091 } | |
3092 } | |
3093 | |
3094 /* Output a logical insn. */ | |
3095 | |
3096 const char * | |
3097 output_logical_op (enum machine_mode mode, rtx *operands) | |
3098 { | |
3099 /* Figure out the logical op that we need to perform. */ | |
3100 enum rtx_code code = GET_CODE (operands[3]); | |
3101 /* Pretend that every byte is affected if both operands are registers. */ | |
3102 const unsigned HOST_WIDE_INT intval = | |
3103 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT) | |
3104 /* Always use the full instruction if the | |
3105 first operand is in memory. It is better | |
3106 to use define_splits to generate the shorter | |
3107 sequence where valid. */ | |
3108 && register_operand (operands[1], VOIDmode) | |
3109 ? INTVAL (operands[2]) : 0x55555555); | |
3110 /* The determinant of the algorithm. If we perform an AND, 0 | |
3111 affects a bit. Otherwise, 1 affects a bit. */ | |
3112 const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval; | |
3113 /* Break up DET into pieces. */ | |
3114 const unsigned HOST_WIDE_INT b0 = (det >> 0) & 0xff; | |
3115 const unsigned HOST_WIDE_INT b1 = (det >> 8) & 0xff; | |
3116 const unsigned HOST_WIDE_INT b2 = (det >> 16) & 0xff; | |
3117 const unsigned HOST_WIDE_INT b3 = (det >> 24) & 0xff; | |
3118 const unsigned HOST_WIDE_INT w0 = (det >> 0) & 0xffff; | |
3119 const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff; | |
3120 int lower_half_easy_p = 0; | |
3121 int upper_half_easy_p = 0; | |
3122 /* The name of an insn. */ | |
3123 const char *opname; | |
3124 char insn_buf[100]; | |
3125 | |
3126 switch (code) | |
3127 { | |
3128 case AND: | |
3129 opname = "and"; | |
3130 break; | |
3131 case IOR: | |
3132 opname = "or"; | |
3133 break; | |
3134 case XOR: | |
3135 opname = "xor"; | |
3136 break; | |
3137 default: | |
3138 gcc_unreachable (); | |
3139 } | |
3140 | |
3141 switch (mode) | |
3142 { | |
3143 case HImode: | |
3144 /* First, see if we can finish with one insn. */ | |
3145 if ((TARGET_H8300H || TARGET_H8300S) | |
3146 && b0 != 0 | |
3147 && b1 != 0) | |
3148 { | |
3149 sprintf (insn_buf, "%s.w\t%%T2,%%T0", opname); | |
3150 output_asm_insn (insn_buf, operands); | |
3151 } | |
3152 else | |
3153 { | |
3154 /* Take care of the lower byte. */ | |
3155 if (b0 != 0) | |
3156 { | |
3157 sprintf (insn_buf, "%s\t%%s2,%%s0", opname); | |
3158 output_asm_insn (insn_buf, operands); | |
3159 } | |
3160 /* Take care of the upper byte. */ | |
3161 if (b1 != 0) | |
3162 { | |
3163 sprintf (insn_buf, "%s\t%%t2,%%t0", opname); | |
3164 output_asm_insn (insn_buf, operands); | |
3165 } | |
3166 } | |
3167 break; | |
3168 case SImode: | |
3169 if (TARGET_H8300H || TARGET_H8300S) | |
3170 { | |
3171 /* Determine if the lower half can be taken care of in no more | |
3172 than two bytes. */ | |
3173 lower_half_easy_p = (b0 == 0 | |
3174 || b1 == 0 | |
3175 || (code != IOR && w0 == 0xffff)); | |
3176 | |
3177 /* Determine if the upper half can be taken care of in no more | |
3178 than two bytes. */ | |
3179 upper_half_easy_p = ((code != IOR && w1 == 0xffff) | |
3180 || (code == AND && w1 == 0xff00)); | |
3181 } | |
3182 | |
3183 /* Check if doing everything with one insn is no worse than | |
3184 using multiple insns. */ | |
3185 if ((TARGET_H8300H || TARGET_H8300S) | |
3186 && w0 != 0 && w1 != 0 | |
3187 && !(lower_half_easy_p && upper_half_easy_p) | |
3188 && !(code == IOR && w1 == 0xffff | |
3189 && (w0 & 0x8000) != 0 && lower_half_easy_p)) | |
3190 { | |
3191 sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname); | |
3192 output_asm_insn (insn_buf, operands); | |
3193 } | |
3194 else | |
3195 { | |
3196 /* Take care of the lower and upper words individually. For | |
3197 each word, we try different methods in the order of | |
3198 | |
3199 1) the special insn (in case of AND or XOR), | |
3200 2) the word-wise insn, and | |
3201 3) The byte-wise insn. */ | |
3202 if (w0 == 0xffff | |
3203 && (TARGET_H8300 ? (code == AND) : (code != IOR))) | |
3204 output_asm_insn ((code == AND) | |
3205 ? "sub.w\t%f0,%f0" : "not.w\t%f0", | |
3206 operands); | |
3207 else if ((TARGET_H8300H || TARGET_H8300S) | |
3208 && (b0 != 0) | |
3209 && (b1 != 0)) | |
3210 { | |
3211 sprintf (insn_buf, "%s.w\t%%f2,%%f0", opname); | |
3212 output_asm_insn (insn_buf, operands); | |
3213 } | |
3214 else | |
3215 { | |
3216 if (b0 != 0) | |
3217 { | |
3218 sprintf (insn_buf, "%s\t%%w2,%%w0", opname); | |
3219 output_asm_insn (insn_buf, operands); | |
3220 } | |
3221 if (b1 != 0) | |
3222 { | |
3223 sprintf (insn_buf, "%s\t%%x2,%%x0", opname); | |
3224 output_asm_insn (insn_buf, operands); | |
3225 } | |
3226 } | |
3227 | |
3228 if ((w1 == 0xffff) | |
3229 && (TARGET_H8300 ? (code == AND) : (code != IOR))) | |
3230 output_asm_insn ((code == AND) | |
3231 ? "sub.w\t%e0,%e0" : "not.w\t%e0", | |
3232 operands); | |
3233 else if ((TARGET_H8300H || TARGET_H8300S) | |
3234 && code == IOR | |
3235 && w1 == 0xffff | |
3236 && (w0 & 0x8000) != 0) | |
3237 { | |
3238 output_asm_insn ("exts.l\t%S0", operands); | |
3239 } | |
3240 else if ((TARGET_H8300H || TARGET_H8300S) | |
3241 && code == AND | |
3242 && w1 == 0xff00) | |
3243 { | |
3244 output_asm_insn ("extu.w\t%e0", operands); | |
3245 } | |
3246 else if (TARGET_H8300H || TARGET_H8300S) | |
3247 { | |
3248 if (w1 != 0) | |
3249 { | |
3250 sprintf (insn_buf, "%s.w\t%%e2,%%e0", opname); | |
3251 output_asm_insn (insn_buf, operands); | |
3252 } | |
3253 } | |
3254 else | |
3255 { | |
3256 if (b2 != 0) | |
3257 { | |
3258 sprintf (insn_buf, "%s\t%%y2,%%y0", opname); | |
3259 output_asm_insn (insn_buf, operands); | |
3260 } | |
3261 if (b3 != 0) | |
3262 { | |
3263 sprintf (insn_buf, "%s\t%%z2,%%z0", opname); | |
3264 output_asm_insn (insn_buf, operands); | |
3265 } | |
3266 } | |
3267 } | |
3268 break; | |
3269 default: | |
3270 gcc_unreachable (); | |
3271 } | |
3272 return ""; | |
3273 } | |
3274 | |
3275 /* Compute the length of a logical insn. */ | |
3276 | |
3277 unsigned int | |
3278 compute_logical_op_length (enum machine_mode mode, rtx *operands) | |
3279 { | |
3280 /* Figure out the logical op that we need to perform. */ | |
3281 enum rtx_code code = GET_CODE (operands[3]); | |
3282 /* Pretend that every byte is affected if both operands are registers. */ | |
3283 const unsigned HOST_WIDE_INT intval = | |
3284 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT) | |
3285 /* Always use the full instruction if the | |
3286 first operand is in memory. It is better | |
3287 to use define_splits to generate the shorter | |
3288 sequence where valid. */ | |
3289 && register_operand (operands[1], VOIDmode) | |
3290 ? INTVAL (operands[2]) : 0x55555555); | |
3291 /* The determinant of the algorithm. If we perform an AND, 0 | |
3292 affects a bit. Otherwise, 1 affects a bit. */ | |
3293 const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval; | |
3294 /* Break up DET into pieces. */ | |
3295 const unsigned HOST_WIDE_INT b0 = (det >> 0) & 0xff; | |
3296 const unsigned HOST_WIDE_INT b1 = (det >> 8) & 0xff; | |
3297 const unsigned HOST_WIDE_INT b2 = (det >> 16) & 0xff; | |
3298 const unsigned HOST_WIDE_INT b3 = (det >> 24) & 0xff; | |
3299 const unsigned HOST_WIDE_INT w0 = (det >> 0) & 0xffff; | |
3300 const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff; | |
3301 int lower_half_easy_p = 0; | |
3302 int upper_half_easy_p = 0; | |
3303 /* Insn length. */ | |
3304 unsigned int length = 0; | |
3305 | |
3306 switch (mode) | |
3307 { | |
3308 case HImode: | |
3309 /* First, see if we can finish with one insn. */ | |
3310 if ((TARGET_H8300H || TARGET_H8300S) | |
3311 && b0 != 0 | |
3312 && b1 != 0) | |
3313 { | |
3314 length = h8300_length_from_table (operands[1], operands[2], | |
3315 &logicw_length_table); | |
3316 } | |
3317 else | |
3318 { | |
3319 /* Take care of the lower byte. */ | |
3320 if (b0 != 0) | |
3321 length += 2; | |
3322 | |
3323 /* Take care of the upper byte. */ | |
3324 if (b1 != 0) | |
3325 length += 2; | |
3326 } | |
3327 break; | |
3328 case SImode: | |
3329 if (TARGET_H8300H || TARGET_H8300S) | |
3330 { | |
3331 /* Determine if the lower half can be taken care of in no more | |
3332 than two bytes. */ | |
3333 lower_half_easy_p = (b0 == 0 | |
3334 || b1 == 0 | |
3335 || (code != IOR && w0 == 0xffff)); | |
3336 | |
3337 /* Determine if the upper half can be taken care of in no more | |
3338 than two bytes. */ | |
3339 upper_half_easy_p = ((code != IOR && w1 == 0xffff) | |
3340 || (code == AND && w1 == 0xff00)); | |
3341 } | |
3342 | |
3343 /* Check if doing everything with one insn is no worse than | |
3344 using multiple insns. */ | |
3345 if ((TARGET_H8300H || TARGET_H8300S) | |
3346 && w0 != 0 && w1 != 0 | |
3347 && !(lower_half_easy_p && upper_half_easy_p) | |
3348 && !(code == IOR && w1 == 0xffff | |
3349 && (w0 & 0x8000) != 0 && lower_half_easy_p)) | |
3350 { | |
3351 length = h8300_length_from_table (operands[1], operands[2], | |
3352 &logicl_length_table); | |
3353 } | |
3354 else | |
3355 { | |
3356 /* Take care of the lower and upper words individually. For | |
3357 each word, we try different methods in the order of | |
3358 | |
3359 1) the special insn (in case of AND or XOR), | |
3360 2) the word-wise insn, and | |
3361 3) The byte-wise insn. */ | |
3362 if (w0 == 0xffff | |
3363 && (TARGET_H8300 ? (code == AND) : (code != IOR))) | |
3364 { | |
3365 length += 2; | |
3366 } | |
3367 else if ((TARGET_H8300H || TARGET_H8300S) | |
3368 && (b0 != 0) | |
3369 && (b1 != 0)) | |
3370 { | |
3371 length += 4; | |
3372 } | |
3373 else | |
3374 { | |
3375 if (b0 != 0) | |
3376 length += 2; | |
3377 | |
3378 if (b1 != 0) | |
3379 length += 2; | |
3380 } | |
3381 | |
3382 if (w1 == 0xffff | |
3383 && (TARGET_H8300 ? (code == AND) : (code != IOR))) | |
3384 { | |
3385 length += 2; | |
3386 } | |
3387 else if ((TARGET_H8300H || TARGET_H8300S) | |
3388 && code == IOR | |
3389 && w1 == 0xffff | |
3390 && (w0 & 0x8000) != 0) | |
3391 { | |
3392 length += 2; | |
3393 } | |
3394 else if ((TARGET_H8300H || TARGET_H8300S) | |
3395 && code == AND | |
3396 && w1 == 0xff00) | |
3397 { | |
3398 length += 2; | |
3399 } | |
3400 else if (TARGET_H8300H || TARGET_H8300S) | |
3401 { | |
3402 if (w1 != 0) | |
3403 length += 4; | |
3404 } | |
3405 else | |
3406 { | |
3407 if (b2 != 0) | |
3408 length += 2; | |
3409 | |
3410 if (b3 != 0) | |
3411 length += 2; | |
3412 } | |
3413 } | |
3414 break; | |
3415 default: | |
3416 gcc_unreachable (); | |
3417 } | |
3418 return length; | |
3419 } | |
3420 | |
3421 /* Compute which flag bits are valid after a logical insn. */ | |
3422 | |
3423 int | |
3424 compute_logical_op_cc (enum machine_mode mode, rtx *operands) | |
3425 { | |
3426 /* Figure out the logical op that we need to perform. */ | |
3427 enum rtx_code code = GET_CODE (operands[3]); | |
3428 /* Pretend that every byte is affected if both operands are registers. */ | |
3429 const unsigned HOST_WIDE_INT intval = | |
3430 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT) | |
3431 /* Always use the full instruction if the | |
3432 first operand is in memory. It is better | |
3433 to use define_splits to generate the shorter | |
3434 sequence where valid. */ | |
3435 && register_operand (operands[1], VOIDmode) | |
3436 ? INTVAL (operands[2]) : 0x55555555); | |
3437 /* The determinant of the algorithm. If we perform an AND, 0 | |
3438 affects a bit. Otherwise, 1 affects a bit. */ | |
3439 const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval; | |
3440 /* Break up DET into pieces. */ | |
3441 const unsigned HOST_WIDE_INT b0 = (det >> 0) & 0xff; | |
3442 const unsigned HOST_WIDE_INT b1 = (det >> 8) & 0xff; | |
3443 const unsigned HOST_WIDE_INT w0 = (det >> 0) & 0xffff; | |
3444 const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff; | |
3445 int lower_half_easy_p = 0; | |
3446 int upper_half_easy_p = 0; | |
3447 /* Condition code. */ | |
3448 enum attr_cc cc = CC_CLOBBER; | |
3449 | |
3450 switch (mode) | |
3451 { | |
3452 case HImode: | |
3453 /* First, see if we can finish with one insn. */ | |
3454 if ((TARGET_H8300H || TARGET_H8300S) | |
3455 && b0 != 0 | |
3456 && b1 != 0) | |
3457 { | |
3458 cc = CC_SET_ZNV; | |
3459 } | |
3460 break; | |
3461 case SImode: | |
3462 if (TARGET_H8300H || TARGET_H8300S) | |
3463 { | |
3464 /* Determine if the lower half can be taken care of in no more | |
3465 than two bytes. */ | |
3466 lower_half_easy_p = (b0 == 0 | |
3467 || b1 == 0 | |
3468 || (code != IOR && w0 == 0xffff)); | |
3469 | |
3470 /* Determine if the upper half can be taken care of in no more | |
3471 than two bytes. */ | |
3472 upper_half_easy_p = ((code != IOR && w1 == 0xffff) | |
3473 || (code == AND && w1 == 0xff00)); | |
3474 } | |
3475 | |
3476 /* Check if doing everything with one insn is no worse than | |
3477 using multiple insns. */ | |
3478 if ((TARGET_H8300H || TARGET_H8300S) | |
3479 && w0 != 0 && w1 != 0 | |
3480 && !(lower_half_easy_p && upper_half_easy_p) | |
3481 && !(code == IOR && w1 == 0xffff | |
3482 && (w0 & 0x8000) != 0 && lower_half_easy_p)) | |
3483 { | |
3484 cc = CC_SET_ZNV; | |
3485 } | |
3486 else | |
3487 { | |
3488 if ((TARGET_H8300H || TARGET_H8300S) | |
3489 && code == IOR | |
3490 && w1 == 0xffff | |
3491 && (w0 & 0x8000) != 0) | |
3492 { | |
3493 cc = CC_SET_ZNV; | |
3494 } | |
3495 } | |
3496 break; | |
3497 default: | |
3498 gcc_unreachable (); | |
3499 } | |
3500 return cc; | |
3501 } | |
3502 | |
3503 /* Expand a conditional branch. */ | |
3504 | |
3505 void | |
3506 h8300_expand_branch (enum rtx_code code, rtx label) | |
3507 { | |
3508 rtx tmp; | |
3509 | |
3510 tmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx); | |
3511 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, | |
3512 gen_rtx_LABEL_REF (VOIDmode, label), | |
3513 pc_rtx); | |
3514 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); | |
3515 } | |
3516 | |
3517 /* Shifts. | |
3518 | |
3519 We devote a fair bit of code to getting efficient shifts since we | |
3520 can only shift one bit at a time on the H8/300 and H8/300H and only | |
3521 one or two bits at a time on the H8S. | |
3522 | |
3523 All shift code falls into one of the following ways of | |
3524 implementation: | |
3525 | |
3526 o SHIFT_INLINE: Emit straight line code for the shift; this is used | |
3527 when a straight line shift is about the same size or smaller than | |
3528 a loop. | |
3529 | |
3530 o SHIFT_ROT_AND: Rotate the value the opposite direction, then mask | |
3531 off the bits we don't need. This is used when only a few of the | |
3532 bits in the original value will survive in the shifted value. | |
3533 | |
3534 o SHIFT_SPECIAL: Often it's possible to move a byte or a word to | |
3535 simulate a shift by 8, 16, or 24 bits. Once moved, a few inline | |
3536 shifts can be added if the shift count is slightly more than 8 or | |
3537 16. This case also includes other oddballs that are not worth | |
3538 explaining here. | |
3539 | |
3540 o SHIFT_LOOP: Emit a loop using one (or two on H8S) bit shifts. | |
3541 | |
3542 For each shift count, we try to use code that has no trade-off | |
3543 between code size and speed whenever possible. | |
3544 | |
3545 If the trade-off is unavoidable, we try to be reasonable. | |
3546 Specifically, the fastest version is one instruction longer than | |
3547 the shortest version, we take the fastest version. We also provide | |
3548 the use a way to switch back to the shortest version with -Os. | |
3549 | |
3550 For the details of the shift algorithms for various shift counts, | |
3551 refer to shift_alg_[qhs]i. */ | |
3552 | |
3553 /* Classify a shift with the given mode and code. OP is the shift amount. */ | |
3554 | |
3555 enum h8sx_shift_type | |
3556 h8sx_classify_shift (enum machine_mode mode, enum rtx_code code, rtx op) | |
3557 { | |
3558 if (!TARGET_H8300SX) | |
3559 return H8SX_SHIFT_NONE; | |
3560 | |
3561 switch (code) | |
3562 { | |
3563 case ASHIFT: | |
3564 case LSHIFTRT: | |
3565 /* Check for variable shifts (shll Rs,Rd and shlr Rs,Rd). */ | |
3566 if (GET_CODE (op) != CONST_INT) | |
3567 return H8SX_SHIFT_BINARY; | |
3568 | |
3569 /* Reject out-of-range shift amounts. */ | |
3570 if (INTVAL (op) <= 0 || INTVAL (op) >= GET_MODE_BITSIZE (mode)) | |
3571 return H8SX_SHIFT_NONE; | |
3572 | |
3573 /* Power-of-2 shifts are effectively unary operations. */ | |
3574 if (exact_log2 (INTVAL (op)) >= 0) | |
3575 return H8SX_SHIFT_UNARY; | |
3576 | |
3577 return H8SX_SHIFT_BINARY; | |
3578 | |
3579 case ASHIFTRT: | |
3580 if (op == const1_rtx || op == const2_rtx) | |
3581 return H8SX_SHIFT_UNARY; | |
3582 return H8SX_SHIFT_NONE; | |
3583 | |
3584 case ROTATE: | |
3585 if (GET_CODE (op) == CONST_INT | |
3586 && (INTVAL (op) == 1 | |
3587 || INTVAL (op) == 2 | |
3588 || INTVAL (op) == GET_MODE_BITSIZE (mode) - 2 | |
3589 || INTVAL (op) == GET_MODE_BITSIZE (mode) - 1)) | |
3590 return H8SX_SHIFT_UNARY; | |
3591 return H8SX_SHIFT_NONE; | |
3592 | |
3593 default: | |
3594 return H8SX_SHIFT_NONE; | |
3595 } | |
3596 } | |
3597 | |
3598 /* Return the asm template for a single h8sx shift instruction. | |
3599 OPERANDS[0] and OPERANDS[1] are the destination, OPERANDS[2] | |
3600 is the source and OPERANDS[3] is the shift. SUFFIX is the | |
3601 size suffix ('b', 'w' or 'l') and OPTYPE is the print_operand | |
3602 prefix for the destination operand. */ | |
3603 | |
3604 const char * | |
3605 output_h8sx_shift (rtx *operands, int suffix, int optype) | |
3606 { | |
3607 static char buffer[16]; | |
3608 const char *stem; | |
3609 | |
3610 switch (GET_CODE (operands[3])) | |
3611 { | |
3612 case ASHIFT: | |
3613 stem = "shll"; | |
3614 break; | |
3615 | |
3616 case ASHIFTRT: | |
3617 stem = "shar"; | |
3618 break; | |
3619 | |
3620 case LSHIFTRT: | |
3621 stem = "shlr"; | |
3622 break; | |
3623 | |
3624 case ROTATE: | |
3625 stem = "rotl"; | |
3626 if (INTVAL (operands[2]) > 2) | |
3627 { | |
3628 /* This is really a right rotate. */ | |
3629 operands[2] = GEN_INT (GET_MODE_BITSIZE (GET_MODE (operands[0])) | |
3630 - INTVAL (operands[2])); | |
3631 stem = "rotr"; | |
3632 } | |
3633 break; | |
3634 | |
3635 default: | |
3636 gcc_unreachable (); | |
3637 } | |
3638 if (operands[2] == const1_rtx) | |
3639 sprintf (buffer, "%s.%c\t%%%c0", stem, suffix, optype); | |
3640 else | |
3641 sprintf (buffer, "%s.%c\t%%X2,%%%c0", stem, suffix, optype); | |
3642 return buffer; | |
3643 } | |
3644 | |
3645 /* Emit code to do shifts. */ | |
3646 | |
3647 bool | |
3648 expand_a_shift (enum machine_mode mode, int code, rtx operands[]) | |
3649 { | |
3650 switch (h8sx_classify_shift (mode, code, operands[2])) | |
3651 { | |
3652 case H8SX_SHIFT_BINARY: | |
3653 operands[1] = force_reg (mode, operands[1]); | |
3654 return false; | |
3655 | |
3656 case H8SX_SHIFT_UNARY: | |
3657 return false; | |
3658 | |
3659 case H8SX_SHIFT_NONE: | |
3660 break; | |
3661 } | |
3662 | |
3663 emit_move_insn (copy_rtx (operands[0]), operands[1]); | |
3664 | |
3665 /* Need a loop to get all the bits we want - we generate the | |
3666 code at emit time, but need to allocate a scratch reg now. */ | |
3667 | |
3668 emit_insn (gen_rtx_PARALLEL | |
3669 (VOIDmode, | |
3670 gen_rtvec (2, | |
3671 gen_rtx_SET (VOIDmode, copy_rtx (operands[0]), | |
3672 gen_rtx_fmt_ee (code, mode, | |
3673 copy_rtx (operands[0]), operands[2])), | |
3674 gen_rtx_CLOBBER (VOIDmode, | |
3675 gen_rtx_SCRATCH (QImode))))); | |
3676 return true; | |
3677 } | |
3678 | |
3679 /* Symbols of the various modes which can be used as indices. */ | |
3680 | |
3681 enum shift_mode | |
3682 { | |
3683 QIshift, HIshift, SIshift | |
3684 }; | |
3685 | |
3686 /* For single bit shift insns, record assembler and what bits of the | |
3687 condition code are valid afterwards (represented as various CC_FOO | |
3688 bits, 0 means CC isn't left in a usable state). */ | |
3689 | |
3690 struct shift_insn | |
3691 { | |
3692 const char *const assembler; | |
3693 const int cc_valid; | |
3694 }; | |
3695 | |
3696 /* Assembler instruction shift table. | |
3697 | |
3698 These tables are used to look up the basic shifts. | |
3699 They are indexed by cpu, shift_type, and mode. */ | |
3700 | |
3701 static const struct shift_insn shift_one[2][3][3] = | |
3702 { | |
3703 /* H8/300 */ | |
3704 { | |
3705 /* SHIFT_ASHIFT */ | |
3706 { | |
3707 { "shll\t%X0", CC_SET_ZNV }, | |
3708 { "add.w\t%T0,%T0", CC_SET_ZN }, | |
3709 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", CC_CLOBBER } | |
3710 }, | |
3711 /* SHIFT_LSHIFTRT */ | |
3712 { | |
3713 { "shlr\t%X0", CC_SET_ZNV }, | |
3714 { "shlr\t%t0\n\trotxr\t%s0", CC_CLOBBER }, | |
3715 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", CC_CLOBBER } | |
3716 }, | |
3717 /* SHIFT_ASHIFTRT */ | |
3718 { | |
3719 { "shar\t%X0", CC_SET_ZNV }, | |
3720 { "shar\t%t0\n\trotxr\t%s0", CC_CLOBBER }, | |
3721 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", CC_CLOBBER } | |
3722 } | |
3723 }, | |
3724 /* H8/300H */ | |
3725 { | |
3726 /* SHIFT_ASHIFT */ | |
3727 { | |
3728 { "shll.b\t%X0", CC_SET_ZNV }, | |
3729 { "shll.w\t%T0", CC_SET_ZNV }, | |
3730 { "shll.l\t%S0", CC_SET_ZNV } | |
3731 }, | |
3732 /* SHIFT_LSHIFTRT */ | |
3733 { | |
3734 { "shlr.b\t%X0", CC_SET_ZNV }, | |
3735 { "shlr.w\t%T0", CC_SET_ZNV }, | |
3736 { "shlr.l\t%S0", CC_SET_ZNV } | |
3737 }, | |
3738 /* SHIFT_ASHIFTRT */ | |
3739 { | |
3740 { "shar.b\t%X0", CC_SET_ZNV }, | |
3741 { "shar.w\t%T0", CC_SET_ZNV }, | |
3742 { "shar.l\t%S0", CC_SET_ZNV } | |
3743 } | |
3744 } | |
3745 }; | |
3746 | |
3747 static const struct shift_insn shift_two[3][3] = | |
3748 { | |
3749 /* SHIFT_ASHIFT */ | |
3750 { | |
3751 { "shll.b\t#2,%X0", CC_SET_ZNV }, | |
3752 { "shll.w\t#2,%T0", CC_SET_ZNV }, | |
3753 { "shll.l\t#2,%S0", CC_SET_ZNV } | |
3754 }, | |
3755 /* SHIFT_LSHIFTRT */ | |
3756 { | |
3757 { "shlr.b\t#2,%X0", CC_SET_ZNV }, | |
3758 { "shlr.w\t#2,%T0", CC_SET_ZNV }, | |
3759 { "shlr.l\t#2,%S0", CC_SET_ZNV } | |
3760 }, | |
3761 /* SHIFT_ASHIFTRT */ | |
3762 { | |
3763 { "shar.b\t#2,%X0", CC_SET_ZNV }, | |
3764 { "shar.w\t#2,%T0", CC_SET_ZNV }, | |
3765 { "shar.l\t#2,%S0", CC_SET_ZNV } | |
3766 } | |
3767 }; | |
3768 | |
3769 /* Rotates are organized by which shift they'll be used in implementing. | |
3770 There's no need to record whether the cc is valid afterwards because | |
3771 it is the AND insn that will decide this. */ | |
3772 | |
3773 static const char *const rotate_one[2][3][3] = | |
3774 { | |
3775 /* H8/300 */ | |
3776 { | |
3777 /* SHIFT_ASHIFT */ | |
3778 { | |
3779 "rotr\t%X0", | |
3780 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0", | |
3781 0 | |
3782 }, | |
3783 /* SHIFT_LSHIFTRT */ | |
3784 { | |
3785 "rotl\t%X0", | |
3786 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0", | |
3787 0 | |
3788 }, | |
3789 /* SHIFT_ASHIFTRT */ | |
3790 { | |
3791 "rotl\t%X0", | |
3792 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0", | |
3793 0 | |
3794 } | |
3795 }, | |
3796 /* H8/300H */ | |
3797 { | |
3798 /* SHIFT_ASHIFT */ | |
3799 { | |
3800 "rotr.b\t%X0", | |
3801 "rotr.w\t%T0", | |
3802 "rotr.l\t%S0" | |
3803 }, | |
3804 /* SHIFT_LSHIFTRT */ | |
3805 { | |
3806 "rotl.b\t%X0", | |
3807 "rotl.w\t%T0", | |
3808 "rotl.l\t%S0" | |
3809 }, | |
3810 /* SHIFT_ASHIFTRT */ | |
3811 { | |
3812 "rotl.b\t%X0", | |
3813 "rotl.w\t%T0", | |
3814 "rotl.l\t%S0" | |
3815 } | |
3816 } | |
3817 }; | |
3818 | |
3819 static const char *const rotate_two[3][3] = | |
3820 { | |
3821 /* SHIFT_ASHIFT */ | |
3822 { | |
3823 "rotr.b\t#2,%X0", | |
3824 "rotr.w\t#2,%T0", | |
3825 "rotr.l\t#2,%S0" | |
3826 }, | |
3827 /* SHIFT_LSHIFTRT */ | |
3828 { | |
3829 "rotl.b\t#2,%X0", | |
3830 "rotl.w\t#2,%T0", | |
3831 "rotl.l\t#2,%S0" | |
3832 }, | |
3833 /* SHIFT_ASHIFTRT */ | |
3834 { | |
3835 "rotl.b\t#2,%X0", | |
3836 "rotl.w\t#2,%T0", | |
3837 "rotl.l\t#2,%S0" | |
3838 } | |
3839 }; | |
3840 | |
3841 struct shift_info { | |
3842 /* Shift algorithm. */ | |
3843 enum shift_alg alg; | |
3844 | |
3845 /* The number of bits to be shifted by shift1 and shift2. Valid | |
3846 when ALG is SHIFT_SPECIAL. */ | |
3847 unsigned int remainder; | |
3848 | |
3849 /* Special insn for a shift. Valid when ALG is SHIFT_SPECIAL. */ | |
3850 const char *special; | |
3851 | |
3852 /* Insn for a one-bit shift. Valid when ALG is either SHIFT_INLINE | |
3853 or SHIFT_SPECIAL, and REMAINDER is nonzero. */ | |
3854 const char *shift1; | |
3855 | |
3856 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE | |
3857 or SHIFT_SPECIAL, and REMAINDER is nonzero. */ | |
3858 const char *shift2; | |
3859 | |
3860 /* CC status for SHIFT_INLINE. */ | |
3861 int cc_inline; | |
3862 | |
3863 /* CC status for SHIFT_SPECIAL. */ | |
3864 int cc_special; | |
3865 }; | |
3866 | |
3867 static void get_shift_alg (enum shift_type, | |
3868 enum shift_mode, unsigned int, | |
3869 struct shift_info *); | |
3870 | |
3871 /* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the | |
3872 best algorithm for doing the shift. The assembler code is stored | |
3873 in the pointers in INFO. We achieve the maximum efficiency in most | |
3874 cases when !TARGET_H8300. In case of TARGET_H8300, shifts in | |
3875 SImode in particular have a lot of room to optimize. | |
3876 | |
3877 We first determine the strategy of the shift algorithm by a table | |
3878 lookup. If that tells us to use a hand crafted assembly code, we | |
3879 go into the big switch statement to find what that is. Otherwise, | |
3880 we resort to a generic way, such as inlining. In either case, the | |
3881 result is returned through INFO. */ | |
3882 | |
3883 static void | |
3884 get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode, | |
3885 unsigned int count, struct shift_info *info) | |
3886 { | |
3887 enum h8_cpu cpu; | |
3888 | |
3889 /* Find the target CPU. */ | |
3890 if (TARGET_H8300) | |
3891 cpu = H8_300; | |
3892 else if (TARGET_H8300H) | |
3893 cpu = H8_300H; | |
3894 else | |
3895 cpu = H8_S; | |
3896 | |
3897 /* Find the shift algorithm. */ | |
3898 info->alg = SHIFT_LOOP; | |
3899 switch (shift_mode) | |
3900 { | |
3901 case QIshift: | |
3902 if (count < GET_MODE_BITSIZE (QImode)) | |
3903 info->alg = shift_alg_qi[cpu][shift_type][count]; | |
3904 break; | |
3905 | |
3906 case HIshift: | |
3907 if (count < GET_MODE_BITSIZE (HImode)) | |
3908 info->alg = shift_alg_hi[cpu][shift_type][count]; | |
3909 break; | |
3910 | |
3911 case SIshift: | |
3912 if (count < GET_MODE_BITSIZE (SImode)) | |
3913 info->alg = shift_alg_si[cpu][shift_type][count]; | |
3914 break; | |
3915 | |
3916 default: | |
3917 gcc_unreachable (); | |
3918 } | |
3919 | |
3920 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */ | |
3921 switch (info->alg) | |
3922 { | |
3923 case SHIFT_INLINE: | |
3924 info->remainder = count; | |
3925 /* Fall through. */ | |
3926 | |
3927 case SHIFT_LOOP: | |
3928 /* It is up to the caller to know that looping clobbers cc. */ | |
3929 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler; | |
3930 info->shift2 = shift_two[shift_type][shift_mode].assembler; | |
3931 info->cc_inline = shift_one[cpu_type][shift_type][shift_mode].cc_valid; | |
3932 goto end; | |
3933 | |
3934 case SHIFT_ROT_AND: | |
3935 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode]; | |
3936 info->shift2 = rotate_two[shift_type][shift_mode]; | |
3937 info->cc_inline = CC_CLOBBER; | |
3938 goto end; | |
3939 | |
3940 case SHIFT_SPECIAL: | |
3941 /* REMAINDER is 0 for most cases, so initialize it to 0. */ | |
3942 info->remainder = 0; | |
3943 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler; | |
3944 info->shift2 = shift_two[shift_type][shift_mode].assembler; | |
3945 info->cc_inline = shift_one[cpu_type][shift_type][shift_mode].cc_valid; | |
3946 info->cc_special = CC_CLOBBER; | |
3947 break; | |
3948 } | |
3949 | |
3950 /* Here we only deal with SHIFT_SPECIAL. */ | |
3951 switch (shift_mode) | |
3952 { | |
3953 case QIshift: | |
3954 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated | |
3955 through the entire value. */ | |
3956 gcc_assert (shift_type == SHIFT_ASHIFTRT && count == 7); | |
3957 info->special = "shll\t%X0\n\tsubx\t%X0,%X0"; | |
3958 goto end; | |
3959 | |
3960 case HIshift: | |
3961 if (count == 7) | |
3962 { | |
3963 switch (shift_type) | |
3964 { | |
3965 case SHIFT_ASHIFT: | |
3966 if (TARGET_H8300) | |
3967 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.b\t%t0\n\trotr.b\t%s0\n\tand.b\t#0x80,%s0"; | |
3968 else | |
3969 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0"; | |
3970 goto end; | |
3971 case SHIFT_LSHIFTRT: | |
3972 if (TARGET_H8300) | |
3973 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\trotl.b\t%t0\n\tand.b\t#0x01,%t0"; | |
3974 else | |
3975 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0"; | |
3976 goto end; | |
3977 case SHIFT_ASHIFTRT: | |
3978 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0"; | |
3979 goto end; | |
3980 } | |
3981 } | |
3982 else if ((8 <= count && count <= 13) | |
3983 || (TARGET_H8300S && count == 14)) | |
3984 { | |
3985 info->remainder = count - 8; | |
3986 | |
3987 switch (shift_type) | |
3988 { | |
3989 case SHIFT_ASHIFT: | |
3990 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0"; | |
3991 goto end; | |
3992 case SHIFT_LSHIFTRT: | |
3993 if (TARGET_H8300) | |
3994 { | |
3995 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0"; | |
3996 info->shift1 = "shlr.b\t%s0"; | |
3997 info->cc_inline = CC_SET_ZNV; | |
3998 } | |
3999 else | |
4000 { | |
4001 info->special = "mov.b\t%t0,%s0\n\textu.w\t%T0"; | |
4002 info->cc_special = CC_SET_ZNV; | |
4003 } | |
4004 goto end; | |
4005 case SHIFT_ASHIFTRT: | |
4006 if (TARGET_H8300) | |
4007 { | |
4008 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0"; | |
4009 info->shift1 = "shar.b\t%s0"; | |
4010 } | |
4011 else | |
4012 { | |
4013 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0"; | |
4014 info->cc_special = CC_SET_ZNV; | |
4015 } | |
4016 goto end; | |
4017 } | |
4018 } | |
4019 else if (count == 14) | |
4020 { | |
4021 switch (shift_type) | |
4022 { | |
4023 case SHIFT_ASHIFT: | |
4024 if (TARGET_H8300) | |
4025 info->special = "mov.b\t%s0,%t0\n\trotr.b\t%t0\n\trotr.b\t%t0\n\tand.b\t#0xC0,%t0\n\tsub.b\t%s0,%s0"; | |
4026 goto end; | |
4027 case SHIFT_LSHIFTRT: | |
4028 if (TARGET_H8300) | |
4029 info->special = "mov.b\t%t0,%s0\n\trotl.b\t%s0\n\trotl.b\t%s0\n\tand.b\t#3,%s0\n\tsub.b\t%t0,%t0"; | |
4030 goto end; | |
4031 case SHIFT_ASHIFTRT: | |
4032 if (TARGET_H8300) | |
4033 info->special = "mov.b\t%t0,%s0\n\tshll.b\t%s0\n\tsubx.b\t%t0,%t0\n\tshll.b\t%s0\n\tmov.b\t%t0,%s0\n\tbst.b\t#0,%s0"; | |
4034 else if (TARGET_H8300H) | |
4035 { | |
4036 info->special = "shll.b\t%t0\n\tsubx.b\t%s0,%s0\n\tshll.b\t%t0\n\trotxl.b\t%s0\n\texts.w\t%T0"; | |
4037 info->cc_special = CC_SET_ZNV; | |
4038 } | |
4039 else /* TARGET_H8300S */ | |
4040 gcc_unreachable (); | |
4041 goto end; | |
4042 } | |
4043 } | |
4044 else if (count == 15) | |
4045 { | |
4046 switch (shift_type) | |
4047 { | |
4048 case SHIFT_ASHIFT: | |
4049 info->special = "bld\t#0,%s0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#7,%t0"; | |
4050 goto end; | |
4051 case SHIFT_LSHIFTRT: | |
4052 info->special = "bld\t#7,%t0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#0,%s0"; | |
4053 goto end; | |
4054 case SHIFT_ASHIFTRT: | |
4055 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0"; | |
4056 goto end; | |
4057 } | |
4058 } | |
4059 gcc_unreachable (); | |
4060 | |
4061 case SIshift: | |
4062 if (TARGET_H8300 && 8 <= count && count <= 9) | |
4063 { | |
4064 info->remainder = count - 8; | |
4065 | |
4066 switch (shift_type) | |
4067 { | |
4068 case SHIFT_ASHIFT: | |
4069 info->special = "mov.b\t%y0,%z0\n\tmov.b\t%x0,%y0\n\tmov.b\t%w0,%x0\n\tsub.b\t%w0,%w0"; | |
4070 goto end; | |
4071 case SHIFT_LSHIFTRT: | |
4072 info->special = "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tsub.b\t%z0,%z0"; | |
4073 info->shift1 = "shlr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0"; | |
4074 goto end; | |
4075 case SHIFT_ASHIFTRT: | |
4076 info->special = "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tshll\t%z0\n\tsubx\t%z0,%z0"; | |
4077 goto end; | |
4078 } | |
4079 } | |
4080 else if (count == 8 && !TARGET_H8300) | |
4081 { | |
4082 switch (shift_type) | |
4083 { | |
4084 case SHIFT_ASHIFT: | |
4085 info->special = "mov.w\t%e0,%f4\n\tmov.b\t%s4,%t4\n\tmov.b\t%t0,%s4\n\tmov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f4,%e0"; | |
4086 goto end; | |
4087 case SHIFT_LSHIFTRT: | |
4088 info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\textu.w\t%f4\n\tmov.w\t%f4,%e0"; | |
4089 goto end; | |
4090 case SHIFT_ASHIFTRT: | |
4091 info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\texts.w\t%f4\n\tmov.w\t%f4,%e0"; | |
4092 goto end; | |
4093 } | |
4094 } | |
4095 else if (count == 15 && TARGET_H8300) | |
4096 { | |
4097 switch (shift_type) | |
4098 { | |
4099 case SHIFT_ASHIFT: | |
4100 gcc_unreachable (); | |
4101 case SHIFT_LSHIFTRT: | |
4102 info->special = "bld\t#7,%z0\n\tmov.w\t%e0,%f0\n\txor\t%y0,%y0\n\txor\t%z0,%z0\n\trotxl\t%w0\n\trotxl\t%x0\n\trotxl\t%y0"; | |
4103 goto end; | |
4104 case SHIFT_ASHIFTRT: | |
4105 info->special = "bld\t#7,%z0\n\tmov.w\t%e0,%f0\n\trotxl\t%w0\n\trotxl\t%x0\n\tsubx\t%y0,%y0\n\tsubx\t%z0,%z0"; | |
4106 goto end; | |
4107 } | |
4108 } | |
4109 else if (count == 15 && !TARGET_H8300) | |
4110 { | |
4111 switch (shift_type) | |
4112 { | |
4113 case SHIFT_ASHIFT: | |
4114 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0"; | |
4115 info->cc_special = CC_SET_ZNV; | |
4116 goto end; | |
4117 case SHIFT_LSHIFTRT: | |
4118 info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0"; | |
4119 info->cc_special = CC_SET_ZNV; | |
4120 goto end; | |
4121 case SHIFT_ASHIFTRT: | |
4122 gcc_unreachable (); | |
4123 } | |
4124 } | |
4125 else if ((TARGET_H8300 && 16 <= count && count <= 20) | |
4126 || (TARGET_H8300H && 16 <= count && count <= 19) | |
4127 || (TARGET_H8300S && 16 <= count && count <= 21)) | |
4128 { | |
4129 info->remainder = count - 16; | |
4130 | |
4131 switch (shift_type) | |
4132 { | |
4133 case SHIFT_ASHIFT: | |
4134 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0"; | |
4135 if (TARGET_H8300) | |
4136 info->shift1 = "add.w\t%e0,%e0"; | |
4137 goto end; | |
4138 case SHIFT_LSHIFTRT: | |
4139 if (TARGET_H8300) | |
4140 { | |
4141 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0"; | |
4142 info->shift1 = "shlr\t%x0\n\trotxr\t%w0"; | |
4143 } | |
4144 else | |
4145 { | |
4146 info->special = "mov.w\t%e0,%f0\n\textu.l\t%S0"; | |
4147 info->cc_special = CC_SET_ZNV; | |
4148 } | |
4149 goto end; | |
4150 case SHIFT_ASHIFTRT: | |
4151 if (TARGET_H8300) | |
4152 { | |
4153 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0"; | |
4154 info->shift1 = "shar\t%x0\n\trotxr\t%w0"; | |
4155 } | |
4156 else | |
4157 { | |
4158 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0"; | |
4159 info->cc_special = CC_SET_ZNV; | |
4160 } | |
4161 goto end; | |
4162 } | |
4163 } | |
4164 else if (TARGET_H8300 && 24 <= count && count <= 28) | |
4165 { | |
4166 info->remainder = count - 24; | |
4167 | |
4168 switch (shift_type) | |
4169 { | |
4170 case SHIFT_ASHIFT: | |
4171 info->special = "mov.b\t%w0,%z0\n\tsub.b\t%y0,%y0\n\tsub.w\t%f0,%f0"; | |
4172 info->shift1 = "shll.b\t%z0"; | |
4173 info->cc_inline = CC_SET_ZNV; | |
4174 goto end; | |
4175 case SHIFT_LSHIFTRT: | |
4176 info->special = "mov.b\t%z0,%w0\n\tsub.b\t%x0,%x0\n\tsub.w\t%e0,%e0"; | |
4177 info->shift1 = "shlr.b\t%w0"; | |
4178 info->cc_inline = CC_SET_ZNV; | |
4179 goto end; | |
4180 case SHIFT_ASHIFTRT: | |
4181 info->special = "mov.b\t%z0,%w0\n\tbld\t#7,%w0\n\tsubx\t%x0,%x0\n\tsubx\t%x0,%x0\n\tsubx\t%x0,%x0"; | |
4182 info->shift1 = "shar.b\t%w0"; | |
4183 info->cc_inline = CC_SET_ZNV; | |
4184 goto end; | |
4185 } | |
4186 } | |
4187 else if ((TARGET_H8300H && count == 24) | |
4188 || (TARGET_H8300S && 24 <= count && count <= 25)) | |
4189 { | |
4190 info->remainder = count - 24; | |
4191 | |
4192 switch (shift_type) | |
4193 { | |
4194 case SHIFT_ASHIFT: | |
4195 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f0,%e0\n\tsub.w\t%f0,%f0"; | |
4196 goto end; | |
4197 case SHIFT_LSHIFTRT: | |
4198 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0"; | |
4199 info->cc_special = CC_SET_ZNV; | |
4200 goto end; | |
4201 case SHIFT_ASHIFTRT: | |
4202 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0"; | |
4203 info->cc_special = CC_SET_ZNV; | |
4204 goto end; | |
4205 } | |
4206 } | |
4207 else if (!TARGET_H8300 && count == 28) | |
4208 { | |
4209 switch (shift_type) | |
4210 { | |
4211 case SHIFT_ASHIFT: | |
4212 if (TARGET_H8300H) | |
4213 info->special = "sub.w\t%e0,%e0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0"; | |
4214 else | |
4215 info->special = "sub.w\t%e0,%e0\n\trotr.l\t#2,%S0\n\trotr.l\t#2,%S0\n\tsub.w\t%f0,%f0"; | |
4216 goto end; | |
4217 case SHIFT_LSHIFTRT: | |
4218 if (TARGET_H8300H) | |
4219 { | |
4220 info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0"; | |
4221 info->cc_special = CC_SET_ZNV; | |
4222 } | |
4223 else | |
4224 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t#2,%S0\n\textu.l\t%S0"; | |
4225 goto end; | |
4226 case SHIFT_ASHIFTRT: | |
4227 gcc_unreachable (); | |
4228 } | |
4229 } | |
4230 else if (!TARGET_H8300 && count == 29) | |
4231 { | |
4232 switch (shift_type) | |
4233 { | |
4234 case SHIFT_ASHIFT: | |
4235 if (TARGET_H8300H) | |
4236 info->special = "sub.w\t%e0,%e0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0"; | |
4237 else | |
4238 info->special = "sub.w\t%e0,%e0\n\trotr.l\t#2,%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0"; | |
4239 goto end; | |
4240 case SHIFT_LSHIFTRT: | |
4241 if (TARGET_H8300H) | |
4242 { | |
4243 info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0"; | |
4244 info->cc_special = CC_SET_ZNV; | |
4245 } | |
4246 else | |
4247 { | |
4248 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t%S0\n\textu.l\t%S0"; | |
4249 info->cc_special = CC_SET_ZNV; | |
4250 } | |
4251 goto end; | |
4252 case SHIFT_ASHIFTRT: | |
4253 gcc_unreachable (); | |
4254 } | |
4255 } | |
4256 else if (!TARGET_H8300 && count == 30) | |
4257 { | |
4258 switch (shift_type) | |
4259 { | |
4260 case SHIFT_ASHIFT: | |
4261 if (TARGET_H8300H) | |
4262 info->special = "sub.w\t%e0,%e0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0"; | |
4263 else | |
4264 info->special = "sub.w\t%e0,%e0\n\trotr.l\t#2,%S0\n\tsub.w\t%f0,%f0"; | |
4265 goto end; | |
4266 case SHIFT_LSHIFTRT: | |
4267 if (TARGET_H8300H) | |
4268 info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0"; | |
4269 else | |
4270 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\textu.l\t%S0"; | |
4271 goto end; | |
4272 case SHIFT_ASHIFTRT: | |
4273 gcc_unreachable (); | |
4274 } | |
4275 } | |
4276 else if (count == 31) | |
4277 { | |
4278 if (TARGET_H8300) | |
4279 { | |
4280 switch (shift_type) | |
4281 { | |
4282 case SHIFT_ASHIFT: | |
4283 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0"; | |
4284 goto end; | |
4285 case SHIFT_LSHIFTRT: | |
4286 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0"; | |
4287 goto end; | |
4288 case SHIFT_ASHIFTRT: | |
4289 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0"; | |
4290 goto end; | |
4291 } | |
4292 } | |
4293 else | |
4294 { | |
4295 switch (shift_type) | |
4296 { | |
4297 case SHIFT_ASHIFT: | |
4298 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0"; | |
4299 info->cc_special = CC_SET_ZNV; | |
4300 goto end; | |
4301 case SHIFT_LSHIFTRT: | |
4302 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0"; | |
4303 info->cc_special = CC_SET_ZNV; | |
4304 goto end; | |
4305 case SHIFT_ASHIFTRT: | |
4306 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\texts.w\t%T0\n\texts.l\t%S0"; | |
4307 info->cc_special = CC_SET_ZNV; | |
4308 goto end; | |
4309 } | |
4310 } | |
4311 } | |
4312 gcc_unreachable (); | |
4313 | |
4314 default: | |
4315 gcc_unreachable (); | |
4316 } | |
4317 | |
4318 end: | |
4319 if (!TARGET_H8300S) | |
4320 info->shift2 = NULL; | |
4321 } | |
4322 | |
4323 /* Given COUNT and MODE of a shift, return 1 if a scratch reg may be | |
4324 needed for some shift with COUNT and MODE. Return 0 otherwise. */ | |
4325 | |
4326 int | |
4327 h8300_shift_needs_scratch_p (int count, enum machine_mode mode) | |
4328 { | |
4329 enum h8_cpu cpu; | |
4330 int a, lr, ar; | |
4331 | |
4332 if (GET_MODE_BITSIZE (mode) <= count) | |
4333 return 1; | |
4334 | |
4335 /* Find out the target CPU. */ | |
4336 if (TARGET_H8300) | |
4337 cpu = H8_300; | |
4338 else if (TARGET_H8300H) | |
4339 cpu = H8_300H; | |
4340 else | |
4341 cpu = H8_S; | |
4342 | |
4343 /* Find the shift algorithm. */ | |
4344 switch (mode) | |
4345 { | |
4346 case QImode: | |
4347 a = shift_alg_qi[cpu][SHIFT_ASHIFT][count]; | |
4348 lr = shift_alg_qi[cpu][SHIFT_LSHIFTRT][count]; | |
4349 ar = shift_alg_qi[cpu][SHIFT_ASHIFTRT][count]; | |
4350 break; | |
4351 | |
4352 case HImode: | |
4353 a = shift_alg_hi[cpu][SHIFT_ASHIFT][count]; | |
4354 lr = shift_alg_hi[cpu][SHIFT_LSHIFTRT][count]; | |
4355 ar = shift_alg_hi[cpu][SHIFT_ASHIFTRT][count]; | |
4356 break; | |
4357 | |
4358 case SImode: | |
4359 a = shift_alg_si[cpu][SHIFT_ASHIFT][count]; | |
4360 lr = shift_alg_si[cpu][SHIFT_LSHIFTRT][count]; | |
4361 ar = shift_alg_si[cpu][SHIFT_ASHIFTRT][count]; | |
4362 break; | |
4363 | |
4364 default: | |
4365 gcc_unreachable (); | |
4366 } | |
4367 | |
4368 /* On H8/300H, count == 8 uses a scratch register. */ | |
4369 return (a == SHIFT_LOOP || lr == SHIFT_LOOP || ar == SHIFT_LOOP | |
4370 || (TARGET_H8300H && mode == SImode && count == 8)); | |
4371 } | |
4372 | |
4373 /* Output the assembler code for doing shifts. */ | |
4374 | |
4375 const char * | |
4376 output_a_shift (rtx *operands) | |
4377 { | |
4378 static int loopend_lab; | |
4379 rtx shift = operands[3]; | |
4380 enum machine_mode mode = GET_MODE (shift); | |
4381 enum rtx_code code = GET_CODE (shift); | |
4382 enum shift_type shift_type; | |
4383 enum shift_mode shift_mode; | |
4384 struct shift_info info; | |
4385 int n; | |
4386 | |
4387 loopend_lab++; | |
4388 | |
4389 switch (mode) | |
4390 { | |
4391 case QImode: | |
4392 shift_mode = QIshift; | |
4393 break; | |
4394 case HImode: | |
4395 shift_mode = HIshift; | |
4396 break; | |
4397 case SImode: | |
4398 shift_mode = SIshift; | |
4399 break; | |
4400 default: | |
4401 gcc_unreachable (); | |
4402 } | |
4403 | |
4404 switch (code) | |
4405 { | |
4406 case ASHIFTRT: | |
4407 shift_type = SHIFT_ASHIFTRT; | |
4408 break; | |
4409 case LSHIFTRT: | |
4410 shift_type = SHIFT_LSHIFTRT; | |
4411 break; | |
4412 case ASHIFT: | |
4413 shift_type = SHIFT_ASHIFT; | |
4414 break; | |
4415 default: | |
4416 gcc_unreachable (); | |
4417 } | |
4418 | |
4419 /* This case must be taken care of by one of the two splitters | |
4420 that convert a variable shift into a loop. */ | |
4421 gcc_assert (GET_CODE (operands[2]) == CONST_INT); | |
4422 | |
4423 n = INTVAL (operands[2]); | |
4424 | |
4425 /* If the count is negative, make it 0. */ | |
4426 if (n < 0) | |
4427 n = 0; | |
4428 /* If the count is too big, truncate it. | |
4429 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to | |
4430 do the intuitive thing. */ | |
4431 else if ((unsigned int) n > GET_MODE_BITSIZE (mode)) | |
4432 n = GET_MODE_BITSIZE (mode); | |
4433 | |
4434 get_shift_alg (shift_type, shift_mode, n, &info); | |
4435 | |
4436 switch (info.alg) | |
4437 { | |
4438 case SHIFT_SPECIAL: | |
4439 output_asm_insn (info.special, operands); | |
4440 /* Fall through. */ | |
4441 | |
4442 case SHIFT_INLINE: | |
4443 n = info.remainder; | |
4444 | |
4445 /* Emit two bit shifts first. */ | |
4446 if (info.shift2 != NULL) | |
4447 { | |
4448 for (; n > 1; n -= 2) | |
4449 output_asm_insn (info.shift2, operands); | |
4450 } | |
4451 | |
4452 /* Now emit one bit shifts for any residual. */ | |
4453 for (; n > 0; n--) | |
4454 output_asm_insn (info.shift1, operands); | |
4455 return ""; | |
4456 | |
4457 case SHIFT_ROT_AND: | |
4458 { | |
4459 int m = GET_MODE_BITSIZE (mode) - n; | |
4460 const int mask = (shift_type == SHIFT_ASHIFT | |
4461 ? ((1 << m) - 1) << n | |
4462 : (1 << m) - 1); | |
4463 char insn_buf[200]; | |
4464 | |
4465 /* Not all possibilities of rotate are supported. They shouldn't | |
4466 be generated, but let's watch for 'em. */ | |
4467 gcc_assert (info.shift1); | |
4468 | |
4469 /* Emit two bit rotates first. */ | |
4470 if (info.shift2 != NULL) | |
4471 { | |
4472 for (; m > 1; m -= 2) | |
4473 output_asm_insn (info.shift2, operands); | |
4474 } | |
4475 | |
4476 /* Now single bit rotates for any residual. */ | |
4477 for (; m > 0; m--) | |
4478 output_asm_insn (info.shift1, operands); | |
4479 | |
4480 /* Now mask off the high bits. */ | |
4481 switch (mode) | |
4482 { | |
4483 case QImode: | |
4484 sprintf (insn_buf, "and\t#%d,%%X0", mask); | |
4485 break; | |
4486 | |
4487 case HImode: | |
4488 gcc_assert (TARGET_H8300H || TARGET_H8300S); | |
4489 sprintf (insn_buf, "and.w\t#%d,%%T0", mask); | |
4490 break; | |
4491 | |
4492 default: | |
4493 gcc_unreachable (); | |
4494 } | |
4495 | |
4496 output_asm_insn (insn_buf, operands); | |
4497 return ""; | |
4498 } | |
4499 | |
4500 case SHIFT_LOOP: | |
4501 /* A loop to shift by a "large" constant value. | |
4502 If we have shift-by-2 insns, use them. */ | |
4503 if (info.shift2 != NULL) | |
4504 { | |
4505 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2, | |
4506 names_big[REGNO (operands[4])]); | |
4507 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab); | |
4508 output_asm_insn (info.shift2, operands); | |
4509 output_asm_insn ("add #0xff,%X4", operands); | |
4510 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab); | |
4511 if (n % 2) | |
4512 output_asm_insn (info.shift1, operands); | |
4513 } | |
4514 else | |
4515 { | |
4516 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n, | |
4517 names_big[REGNO (operands[4])]); | |
4518 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab); | |
4519 output_asm_insn (info.shift1, operands); | |
4520 output_asm_insn ("add #0xff,%X4", operands); | |
4521 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab); | |
4522 } | |
4523 return ""; | |
4524 | |
4525 default: | |
4526 gcc_unreachable (); | |
4527 } | |
4528 } | |
4529 | |
4530 /* Count the number of assembly instructions in a string TEMPL. */ | |
4531 | |
4532 static unsigned int | |
4533 h8300_asm_insn_count (const char *templ) | |
4534 { | |
4535 unsigned int count = 1; | |
4536 | |
4537 for (; *templ; templ++) | |
4538 if (*templ == '\n') | |
4539 count++; | |
4540 | |
4541 return count; | |
4542 } | |
4543 | |
4544 /* Compute the length of a shift insn. */ | |
4545 | |
4546 unsigned int | |
4547 compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands) | |
4548 { | |
4549 rtx shift = operands[3]; | |
4550 enum machine_mode mode = GET_MODE (shift); | |
4551 enum rtx_code code = GET_CODE (shift); | |
4552 enum shift_type shift_type; | |
4553 enum shift_mode shift_mode; | |
4554 struct shift_info info; | |
4555 unsigned int wlength = 0; | |
4556 | |
4557 switch (mode) | |
4558 { | |
4559 case QImode: | |
4560 shift_mode = QIshift; | |
4561 break; | |
4562 case HImode: | |
4563 shift_mode = HIshift; | |
4564 break; | |
4565 case SImode: | |
4566 shift_mode = SIshift; | |
4567 break; | |
4568 default: | |
4569 gcc_unreachable (); | |
4570 } | |
4571 | |
4572 switch (code) | |
4573 { | |
4574 case ASHIFTRT: | |
4575 shift_type = SHIFT_ASHIFTRT; | |
4576 break; | |
4577 case LSHIFTRT: | |
4578 shift_type = SHIFT_LSHIFTRT; | |
4579 break; | |
4580 case ASHIFT: | |
4581 shift_type = SHIFT_ASHIFT; | |
4582 break; | |
4583 default: | |
4584 gcc_unreachable (); | |
4585 } | |
4586 | |
4587 if (GET_CODE (operands[2]) != CONST_INT) | |
4588 { | |
4589 /* Get the assembler code to do one shift. */ | |
4590 get_shift_alg (shift_type, shift_mode, 1, &info); | |
4591 | |
4592 return (4 + h8300_asm_insn_count (info.shift1)) * 2; | |
4593 } | |
4594 else | |
4595 { | |
4596 int n = INTVAL (operands[2]); | |
4597 | |
4598 /* If the count is negative, make it 0. */ | |
4599 if (n < 0) | |
4600 n = 0; | |
4601 /* If the count is too big, truncate it. | |
4602 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to | |
4603 do the intuitive thing. */ | |
4604 else if ((unsigned int) n > GET_MODE_BITSIZE (mode)) | |
4605 n = GET_MODE_BITSIZE (mode); | |
4606 | |
4607 get_shift_alg (shift_type, shift_mode, n, &info); | |
4608 | |
4609 switch (info.alg) | |
4610 { | |
4611 case SHIFT_SPECIAL: | |
4612 wlength += h8300_asm_insn_count (info.special); | |
4613 | |
4614 /* Every assembly instruction used in SHIFT_SPECIAL case | |
4615 takes 2 bytes except xor.l, which takes 4 bytes, so if we | |
4616 see xor.l, we just pretend that xor.l counts as two insns | |
4617 so that the insn length will be computed correctly. */ | |
4618 if (strstr (info.special, "xor.l") != NULL) | |
4619 wlength++; | |
4620 | |
4621 /* Fall through. */ | |
4622 | |
4623 case SHIFT_INLINE: | |
4624 n = info.remainder; | |
4625 | |
4626 if (info.shift2 != NULL) | |
4627 { | |
4628 wlength += h8300_asm_insn_count (info.shift2) * (n / 2); | |
4629 n = n % 2; | |
4630 } | |
4631 | |
4632 wlength += h8300_asm_insn_count (info.shift1) * n; | |
4633 | |
4634 return 2 * wlength; | |
4635 | |
4636 case SHIFT_ROT_AND: | |
4637 { | |
4638 int m = GET_MODE_BITSIZE (mode) - n; | |
4639 | |
4640 /* Not all possibilities of rotate are supported. They shouldn't | |
4641 be generated, but let's watch for 'em. */ | |
4642 gcc_assert (info.shift1); | |
4643 | |
4644 if (info.shift2 != NULL) | |
4645 { | |
4646 wlength += h8300_asm_insn_count (info.shift2) * (m / 2); | |
4647 m = m % 2; | |
4648 } | |
4649 | |
4650 wlength += h8300_asm_insn_count (info.shift1) * m; | |
4651 | |
4652 /* Now mask off the high bits. */ | |
4653 switch (mode) | |
4654 { | |
4655 case QImode: | |
4656 wlength += 1; | |
4657 break; | |
4658 case HImode: | |
4659 wlength += 2; | |
4660 break; | |
4661 case SImode: | |
4662 gcc_assert (!TARGET_H8300); | |
4663 wlength += 3; | |
4664 break; | |
4665 default: | |
4666 gcc_unreachable (); | |
4667 } | |
4668 return 2 * wlength; | |
4669 } | |
4670 | |
4671 case SHIFT_LOOP: | |
4672 /* A loop to shift by a "large" constant value. | |
4673 If we have shift-by-2 insns, use them. */ | |
4674 if (info.shift2 != NULL) | |
4675 { | |
4676 wlength += 3 + h8300_asm_insn_count (info.shift2); | |
4677 if (n % 2) | |
4678 wlength += h8300_asm_insn_count (info.shift1); | |
4679 } | |
4680 else | |
4681 { | |
4682 wlength += 3 + h8300_asm_insn_count (info.shift1); | |
4683 } | |
4684 return 2 * wlength; | |
4685 | |
4686 default: | |
4687 gcc_unreachable (); | |
4688 } | |
4689 } | |
4690 } | |
4691 | |
4692 /* Compute which flag bits are valid after a shift insn. */ | |
4693 | |
4694 int | |
4695 compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands) | |
4696 { | |
4697 rtx shift = operands[3]; | |
4698 enum machine_mode mode = GET_MODE (shift); | |
4699 enum rtx_code code = GET_CODE (shift); | |
4700 enum shift_type shift_type; | |
4701 enum shift_mode shift_mode; | |
4702 struct shift_info info; | |
4703 int n; | |
4704 | |
4705 switch (mode) | |
4706 { | |
4707 case QImode: | |
4708 shift_mode = QIshift; | |
4709 break; | |
4710 case HImode: | |
4711 shift_mode = HIshift; | |
4712 break; | |
4713 case SImode: | |
4714 shift_mode = SIshift; | |
4715 break; | |
4716 default: | |
4717 gcc_unreachable (); | |
4718 } | |
4719 | |
4720 switch (code) | |
4721 { | |
4722 case ASHIFTRT: | |
4723 shift_type = SHIFT_ASHIFTRT; | |
4724 break; | |
4725 case LSHIFTRT: | |
4726 shift_type = SHIFT_LSHIFTRT; | |
4727 break; | |
4728 case ASHIFT: | |
4729 shift_type = SHIFT_ASHIFT; | |
4730 break; | |
4731 default: | |
4732 gcc_unreachable (); | |
4733 } | |
4734 | |
4735 /* This case must be taken care of by one of the two splitters | |
4736 that convert a variable shift into a loop. */ | |
4737 gcc_assert (GET_CODE (operands[2]) == CONST_INT); | |
4738 | |
4739 n = INTVAL (operands[2]); | |
4740 | |
4741 /* If the count is negative, make it 0. */ | |
4742 if (n < 0) | |
4743 n = 0; | |
4744 /* If the count is too big, truncate it. | |
4745 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to | |
4746 do the intuitive thing. */ | |
4747 else if ((unsigned int) n > GET_MODE_BITSIZE (mode)) | |
4748 n = GET_MODE_BITSIZE (mode); | |
4749 | |
4750 get_shift_alg (shift_type, shift_mode, n, &info); | |
4751 | |
4752 switch (info.alg) | |
4753 { | |
4754 case SHIFT_SPECIAL: | |
4755 if (info.remainder == 0) | |
4756 return info.cc_special; | |
4757 | |
4758 /* Fall through. */ | |
4759 | |
4760 case SHIFT_INLINE: | |
4761 return info.cc_inline; | |
4762 | |
4763 case SHIFT_ROT_AND: | |
4764 /* This case always ends with an and instruction. */ | |
4765 return CC_SET_ZNV; | |
4766 | |
4767 case SHIFT_LOOP: | |
4768 /* A loop to shift by a "large" constant value. | |
4769 If we have shift-by-2 insns, use them. */ | |
4770 if (info.shift2 != NULL) | |
4771 { | |
4772 if (n % 2) | |
4773 return info.cc_inline; | |
4774 } | |
4775 return CC_CLOBBER; | |
4776 | |
4777 default: | |
4778 gcc_unreachable (); | |
4779 } | |
4780 } | |
4781 | |
4782 /* A rotation by a non-constant will cause a loop to be generated, in | |
4783 which a rotation by one bit is used. A rotation by a constant, | |
4784 including the one in the loop, will be taken care of by | |
4785 output_a_rotate () at the insn emit time. */ | |
4786 | |
4787 int | |
4788 expand_a_rotate (rtx operands[]) | |
4789 { | |
4790 rtx dst = operands[0]; | |
4791 rtx src = operands[1]; | |
4792 rtx rotate_amount = operands[2]; | |
4793 enum machine_mode mode = GET_MODE (dst); | |
4794 | |
4795 if (h8sx_classify_shift (mode, ROTATE, rotate_amount) == H8SX_SHIFT_UNARY) | |
4796 return false; | |
4797 | |
4798 /* We rotate in place. */ | |
4799 emit_move_insn (dst, src); | |
4800 | |
4801 if (GET_CODE (rotate_amount) != CONST_INT) | |
4802 { | |
4803 rtx counter = gen_reg_rtx (QImode); | |
4804 rtx start_label = gen_label_rtx (); | |
4805 rtx end_label = gen_label_rtx (); | |
4806 | |
4807 /* If the rotate amount is less than or equal to 0, | |
4808 we go out of the loop. */ | |
4809 emit_cmp_and_jump_insns (rotate_amount, const0_rtx, LE, NULL_RTX, | |
4810 QImode, 0, end_label); | |
4811 | |
4812 /* Initialize the loop counter. */ | |
4813 emit_move_insn (counter, rotate_amount); | |
4814 | |
4815 emit_label (start_label); | |
4816 | |
4817 /* Rotate by one bit. */ | |
4818 switch (mode) | |
4819 { | |
4820 case QImode: | |
4821 emit_insn (gen_rotlqi3_1 (dst, dst, const1_rtx)); | |
4822 break; | |
4823 case HImode: | |
4824 emit_insn (gen_rotlhi3_1 (dst, dst, const1_rtx)); | |
4825 break; | |
4826 case SImode: | |
4827 emit_insn (gen_rotlsi3_1 (dst, dst, const1_rtx)); | |
4828 break; | |
4829 default: | |
4830 gcc_unreachable (); | |
4831 } | |
4832 | |
4833 /* Decrement the counter by 1. */ | |
4834 emit_insn (gen_addqi3 (counter, counter, constm1_rtx)); | |
4835 | |
4836 /* If the loop counter is nonzero, we go back to the beginning | |
4837 of the loop. */ | |
4838 emit_cmp_and_jump_insns (counter, const0_rtx, NE, NULL_RTX, QImode, 1, | |
4839 start_label); | |
4840 | |
4841 emit_label (end_label); | |
4842 } | |
4843 else | |
4844 { | |
4845 /* Rotate by AMOUNT bits. */ | |
4846 switch (mode) | |
4847 { | |
4848 case QImode: | |
4849 emit_insn (gen_rotlqi3_1 (dst, dst, rotate_amount)); | |
4850 break; | |
4851 case HImode: | |
4852 emit_insn (gen_rotlhi3_1 (dst, dst, rotate_amount)); | |
4853 break; | |
4854 case SImode: | |
4855 emit_insn (gen_rotlsi3_1 (dst, dst, rotate_amount)); | |
4856 break; | |
4857 default: | |
4858 gcc_unreachable (); | |
4859 } | |
4860 } | |
4861 | |
4862 return 1; | |
4863 } | |
4864 | |
4865 /* Output a rotate insn. */ | |
4866 | |
4867 const char * | |
4868 output_a_rotate (enum rtx_code code, rtx *operands) | |
4869 { | |
4870 rtx dst = operands[0]; | |
4871 rtx rotate_amount = operands[2]; | |
4872 enum shift_mode rotate_mode; | |
4873 enum shift_type rotate_type; | |
4874 const char *insn_buf; | |
4875 int bits; | |
4876 int amount; | |
4877 enum machine_mode mode = GET_MODE (dst); | |
4878 | |
4879 gcc_assert (GET_CODE (rotate_amount) == CONST_INT); | |
4880 | |
4881 switch (mode) | |
4882 { | |
4883 case QImode: | |
4884 rotate_mode = QIshift; | |
4885 break; | |
4886 case HImode: | |
4887 rotate_mode = HIshift; | |
4888 break; | |
4889 case SImode: | |
4890 rotate_mode = SIshift; | |
4891 break; | |
4892 default: | |
4893 gcc_unreachable (); | |
4894 } | |
4895 | |
4896 switch (code) | |
4897 { | |
4898 case ROTATERT: | |
4899 rotate_type = SHIFT_ASHIFT; | |
4900 break; | |
4901 case ROTATE: | |
4902 rotate_type = SHIFT_LSHIFTRT; | |
4903 break; | |
4904 default: | |
4905 gcc_unreachable (); | |
4906 } | |
4907 | |
4908 amount = INTVAL (rotate_amount); | |
4909 | |
4910 /* Clean up AMOUNT. */ | |
4911 if (amount < 0) | |
4912 amount = 0; | |
4913 if ((unsigned int) amount > GET_MODE_BITSIZE (mode)) | |
4914 amount = GET_MODE_BITSIZE (mode); | |
4915 | |
4916 /* Determine the faster direction. After this phase, amount will be | |
4917 at most a half of GET_MODE_BITSIZE (mode). */ | |
4918 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2) | |
4919 { | |
4920 /* Flip the direction. */ | |
4921 amount = GET_MODE_BITSIZE (mode) - amount; | |
4922 rotate_type = | |
4923 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT; | |
4924 } | |
4925 | |
4926 /* See if a byte swap (in HImode) or a word swap (in SImode) can | |
4927 boost up the rotation. */ | |
4928 if ((mode == HImode && TARGET_H8300 && amount >= 5) | |
4929 || (mode == HImode && TARGET_H8300H && amount >= 6) | |
4930 || (mode == HImode && TARGET_H8300S && amount == 8) | |
4931 || (mode == SImode && TARGET_H8300H && amount >= 10) | |
4932 || (mode == SImode && TARGET_H8300S && amount >= 13)) | |
4933 { | |
4934 switch (mode) | |
4935 { | |
4936 case HImode: | |
4937 /* This code works on any family. */ | |
4938 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0"; | |
4939 output_asm_insn (insn_buf, operands); | |
4940 break; | |
4941 | |
4942 case SImode: | |
4943 /* This code works on the H8/300H and H8S. */ | |
4944 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0"; | |
4945 output_asm_insn (insn_buf, operands); | |
4946 break; | |
4947 | |
4948 default: | |
4949 gcc_unreachable (); | |
4950 } | |
4951 | |
4952 /* Adjust AMOUNT and flip the direction. */ | |
4953 amount = GET_MODE_BITSIZE (mode) / 2 - amount; | |
4954 rotate_type = | |
4955 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT; | |
4956 } | |
4957 | |
4958 /* Output rotate insns. */ | |
4959 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2) | |
4960 { | |
4961 if (bits == 2) | |
4962 insn_buf = rotate_two[rotate_type][rotate_mode]; | |
4963 else | |
4964 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode]; | |
4965 | |
4966 for (; amount >= bits; amount -= bits) | |
4967 output_asm_insn (insn_buf, operands); | |
4968 } | |
4969 | |
4970 return ""; | |
4971 } | |
4972 | |
4973 /* Compute the length of a rotate insn. */ | |
4974 | |
4975 unsigned int | |
4976 compute_a_rotate_length (rtx *operands) | |
4977 { | |
4978 rtx src = operands[1]; | |
4979 rtx amount_rtx = operands[2]; | |
4980 enum machine_mode mode = GET_MODE (src); | |
4981 int amount; | |
4982 unsigned int length = 0; | |
4983 | |
4984 gcc_assert (GET_CODE (amount_rtx) == CONST_INT); | |
4985 | |
4986 amount = INTVAL (amount_rtx); | |
4987 | |
4988 /* Clean up AMOUNT. */ | |
4989 if (amount < 0) | |
4990 amount = 0; | |
4991 if ((unsigned int) amount > GET_MODE_BITSIZE (mode)) | |
4992 amount = GET_MODE_BITSIZE (mode); | |
4993 | |
4994 /* Determine the faster direction. After this phase, amount | |
4995 will be at most a half of GET_MODE_BITSIZE (mode). */ | |
4996 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2) | |
4997 /* Flip the direction. */ | |
4998 amount = GET_MODE_BITSIZE (mode) - amount; | |
4999 | |
5000 /* See if a byte swap (in HImode) or a word swap (in SImode) can | |
5001 boost up the rotation. */ | |
5002 if ((mode == HImode && TARGET_H8300 && amount >= 5) | |
5003 || (mode == HImode && TARGET_H8300H && amount >= 6) | |
5004 || (mode == HImode && TARGET_H8300S && amount == 8) | |
5005 || (mode == SImode && TARGET_H8300H && amount >= 10) | |
5006 || (mode == SImode && TARGET_H8300S && amount >= 13)) | |
5007 { | |
5008 /* Adjust AMOUNT and flip the direction. */ | |
5009 amount = GET_MODE_BITSIZE (mode) / 2 - amount; | |
5010 length += 6; | |
5011 } | |
5012 | |
5013 /* We use 2-bit rotations on the H8S. */ | |
5014 if (TARGET_H8300S) | |
5015 amount = amount / 2 + amount % 2; | |
5016 | |
5017 /* The H8/300 uses three insns to rotate one bit, taking 6 | |
5018 length. */ | |
5019 length += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2); | |
5020 | |
5021 return length; | |
5022 } | |
5023 | |
5024 /* Fix the operands of a gen_xxx so that it could become a bit | |
5025 operating insn. */ | |
5026 | |
5027 int | |
5028 fix_bit_operand (rtx *operands, enum rtx_code code) | |
5029 { | |
5030 /* The bit_operand predicate accepts any memory during RTL generation, but | |
5031 only 'U' memory afterwards, so if this is a MEM operand, we must force | |
5032 it to be valid for 'U' by reloading the address. */ | |
5033 | |
5034 if (code == AND | |
5035 ? single_zero_operand (operands[2], QImode) | |
5036 : single_one_operand (operands[2], QImode)) | |
5037 { | |
5038 /* OK to have a memory dest. */ | |
5039 if (GET_CODE (operands[0]) == MEM | |
5040 && !OK_FOR_U (operands[0])) | |
5041 { | |
5042 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]), | |
5043 copy_to_mode_reg (Pmode, | |
5044 XEXP (operands[0], 0))); | |
5045 MEM_COPY_ATTRIBUTES (mem, operands[0]); | |
5046 operands[0] = mem; | |
5047 } | |
5048 | |
5049 if (GET_CODE (operands[1]) == MEM | |
5050 && !OK_FOR_U (operands[1])) | |
5051 { | |
5052 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]), | |
5053 copy_to_mode_reg (Pmode, | |
5054 XEXP (operands[1], 0))); | |
5055 MEM_COPY_ATTRIBUTES (mem, operands[0]); | |
5056 operands[1] = mem; | |
5057 } | |
5058 return 0; | |
5059 } | |
5060 | |
5061 /* Dest and src op must be register. */ | |
5062 | |
5063 operands[1] = force_reg (QImode, operands[1]); | |
5064 { | |
5065 rtx res = gen_reg_rtx (QImode); | |
5066 switch (code) | |
5067 { | |
5068 case AND: | |
5069 emit_insn (gen_andqi3_1 (res, operands[1], operands[2])); | |
5070 break; | |
5071 case IOR: | |
5072 emit_insn (gen_iorqi3_1 (res, operands[1], operands[2])); | |
5073 break; | |
5074 case XOR: | |
5075 emit_insn (gen_xorqi3_1 (res, operands[1], operands[2])); | |
5076 break; | |
5077 default: | |
5078 gcc_unreachable (); | |
5079 } | |
5080 emit_insn (gen_movqi (operands[0], res)); | |
5081 } | |
5082 return 1; | |
5083 } | |
5084 | |
5085 /* Return nonzero if FUNC is an interrupt function as specified | |
5086 by the "interrupt" attribute. */ | |
5087 | |
5088 static int | |
5089 h8300_interrupt_function_p (tree func) | |
5090 { | |
5091 tree a; | |
5092 | |
5093 if (TREE_CODE (func) != FUNCTION_DECL) | |
5094 return 0; | |
5095 | |
5096 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func)); | |
5097 return a != NULL_TREE; | |
5098 } | |
5099 | |
5100 /* Return nonzero if FUNC is a saveall function as specified by the | |
5101 "saveall" attribute. */ | |
5102 | |
5103 static int | |
5104 h8300_saveall_function_p (tree func) | |
5105 { | |
5106 tree a; | |
5107 | |
5108 if (TREE_CODE (func) != FUNCTION_DECL) | |
5109 return 0; | |
5110 | |
5111 a = lookup_attribute ("saveall", DECL_ATTRIBUTES (func)); | |
5112 return a != NULL_TREE; | |
5113 } | |
5114 | |
5115 /* Return nonzero if FUNC is an OS_Task function as specified | |
5116 by the "OS_Task" attribute. */ | |
5117 | |
5118 static int | |
5119 h8300_os_task_function_p (tree func) | |
5120 { | |
5121 tree a; | |
5122 | |
5123 if (TREE_CODE (func) != FUNCTION_DECL) | |
5124 return 0; | |
5125 | |
5126 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func)); | |
5127 return a != NULL_TREE; | |
5128 } | |
5129 | |
5130 /* Return nonzero if FUNC is a monitor function as specified | |
5131 by the "monitor" attribute. */ | |
5132 | |
5133 static int | |
5134 h8300_monitor_function_p (tree func) | |
5135 { | |
5136 tree a; | |
5137 | |
5138 if (TREE_CODE (func) != FUNCTION_DECL) | |
5139 return 0; | |
5140 | |
5141 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func)); | |
5142 return a != NULL_TREE; | |
5143 } | |
5144 | |
5145 /* Return nonzero if FUNC is a function that should be called | |
5146 through the function vector. */ | |
5147 | |
5148 int | |
5149 h8300_funcvec_function_p (tree func) | |
5150 { | |
5151 tree a; | |
5152 | |
5153 if (TREE_CODE (func) != FUNCTION_DECL) | |
5154 return 0; | |
5155 | |
5156 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func)); | |
5157 return a != NULL_TREE; | |
5158 } | |
5159 | |
5160 /* Return nonzero if DECL is a variable that's in the eight bit | |
5161 data area. */ | |
5162 | |
5163 int | |
5164 h8300_eightbit_data_p (tree decl) | |
5165 { | |
5166 tree a; | |
5167 | |
5168 if (TREE_CODE (decl) != VAR_DECL) | |
5169 return 0; | |
5170 | |
5171 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl)); | |
5172 return a != NULL_TREE; | |
5173 } | |
5174 | |
5175 /* Return nonzero if DECL is a variable that's in the tiny | |
5176 data area. */ | |
5177 | |
5178 int | |
5179 h8300_tiny_data_p (tree decl) | |
5180 { | |
5181 tree a; | |
5182 | |
5183 if (TREE_CODE (decl) != VAR_DECL) | |
5184 return 0; | |
5185 | |
5186 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl)); | |
5187 return a != NULL_TREE; | |
5188 } | |
5189 | |
5190 /* Generate an 'interrupt_handler' attribute for decls. We convert | |
5191 all the pragmas to corresponding attributes. */ | |
5192 | |
5193 static void | |
5194 h8300_insert_attributes (tree node, tree *attributes) | |
5195 { | |
5196 if (TREE_CODE (node) == FUNCTION_DECL) | |
5197 { | |
5198 if (pragma_interrupt) | |
5199 { | |
5200 pragma_interrupt = 0; | |
5201 | |
5202 /* Add an 'interrupt_handler' attribute. */ | |
5203 *attributes = tree_cons (get_identifier ("interrupt_handler"), | |
5204 NULL, *attributes); | |
5205 } | |
5206 | |
5207 if (pragma_saveall) | |
5208 { | |
5209 pragma_saveall = 0; | |
5210 | |
5211 /* Add an 'saveall' attribute. */ | |
5212 *attributes = tree_cons (get_identifier ("saveall"), | |
5213 NULL, *attributes); | |
5214 } | |
5215 } | |
5216 } | |
5217 | |
5218 /* Supported attributes: | |
5219 | |
5220 interrupt_handler: output a prologue and epilogue suitable for an | |
5221 interrupt handler. | |
5222 | |
5223 saveall: output a prologue and epilogue that saves and restores | |
5224 all registers except the stack pointer. | |
5225 | |
5226 function_vector: This function should be called through the | |
5227 function vector. | |
5228 | |
5229 eightbit_data: This variable lives in the 8-bit data area and can | |
5230 be referenced with 8-bit absolute memory addresses. | |
5231 | |
5232 tiny_data: This variable lives in the tiny data area and can be | |
5233 referenced with 16-bit absolute memory references. */ | |
5234 | |
5235 const struct attribute_spec h8300_attribute_table[] = | |
5236 { | |
5237 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ | |
5238 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute }, | |
5239 { "saveall", 0, 0, true, false, false, h8300_handle_fndecl_attribute }, | |
5240 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute }, | |
5241 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute }, | |
5242 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute }, | |
5243 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute }, | |
5244 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute }, | |
5245 { NULL, 0, 0, false, false, false, NULL } | |
5246 }; | |
5247 | |
5248 | |
5249 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in | |
5250 struct attribute_spec.handler. */ | |
5251 static tree | |
5252 h8300_handle_fndecl_attribute (tree *node, tree name, | |
5253 tree args ATTRIBUTE_UNUSED, | |
5254 int flags ATTRIBUTE_UNUSED, | |
5255 bool *no_add_attrs) | |
5256 { | |
5257 if (TREE_CODE (*node) != FUNCTION_DECL) | |
5258 { | |
5259 warning (OPT_Wattributes, "%qs attribute only applies to functions", | |
5260 IDENTIFIER_POINTER (name)); | |
5261 *no_add_attrs = true; | |
5262 } | |
5263 | |
5264 return NULL_TREE; | |
5265 } | |
5266 | |
5267 /* Handle an "eightbit_data" attribute; arguments as in | |
5268 struct attribute_spec.handler. */ | |
5269 static tree | |
5270 h8300_handle_eightbit_data_attribute (tree *node, tree name, | |
5271 tree args ATTRIBUTE_UNUSED, | |
5272 int flags ATTRIBUTE_UNUSED, | |
5273 bool *no_add_attrs) | |
5274 { | |
5275 tree decl = *node; | |
5276 | |
5277 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) | |
5278 { | |
5279 DECL_SECTION_NAME (decl) = build_string (7, ".eight"); | |
5280 } | |
5281 else | |
5282 { | |
5283 warning (OPT_Wattributes, "%qs attribute ignored", | |
5284 IDENTIFIER_POINTER (name)); | |
5285 *no_add_attrs = true; | |
5286 } | |
5287 | |
5288 return NULL_TREE; | |
5289 } | |
5290 | |
5291 /* Handle an "tiny_data" attribute; arguments as in | |
5292 struct attribute_spec.handler. */ | |
5293 static tree | |
5294 h8300_handle_tiny_data_attribute (tree *node, tree name, | |
5295 tree args ATTRIBUTE_UNUSED, | |
5296 int flags ATTRIBUTE_UNUSED, | |
5297 bool *no_add_attrs) | |
5298 { | |
5299 tree decl = *node; | |
5300 | |
5301 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) | |
5302 { | |
5303 DECL_SECTION_NAME (decl) = build_string (6, ".tiny"); | |
5304 } | |
5305 else | |
5306 { | |
5307 warning (OPT_Wattributes, "%qs attribute ignored", | |
5308 IDENTIFIER_POINTER (name)); | |
5309 *no_add_attrs = true; | |
5310 } | |
5311 | |
5312 return NULL_TREE; | |
5313 } | |
5314 | |
5315 /* Mark function vectors, and various small data objects. */ | |
5316 | |
5317 static void | |
5318 h8300_encode_section_info (tree decl, rtx rtl, int first) | |
5319 { | |
5320 int extra_flags = 0; | |
5321 | |
5322 default_encode_section_info (decl, rtl, first); | |
5323 | |
5324 if (TREE_CODE (decl) == FUNCTION_DECL | |
5325 && h8300_funcvec_function_p (decl)) | |
5326 extra_flags = SYMBOL_FLAG_FUNCVEC_FUNCTION; | |
5327 else if (TREE_CODE (decl) == VAR_DECL | |
5328 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) | |
5329 { | |
5330 if (h8300_eightbit_data_p (decl)) | |
5331 extra_flags = SYMBOL_FLAG_EIGHTBIT_DATA; | |
5332 else if (first && h8300_tiny_data_p (decl)) | |
5333 extra_flags = SYMBOL_FLAG_TINY_DATA; | |
5334 } | |
5335 | |
5336 if (extra_flags) | |
5337 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= extra_flags; | |
5338 } | |
5339 | |
5340 /* Output a single-bit extraction. */ | |
5341 | |
5342 const char * | |
5343 output_simode_bld (int bild, rtx operands[]) | |
5344 { | |
5345 if (TARGET_H8300) | |
5346 { | |
5347 /* Clear the destination register. */ | |
5348 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands); | |
5349 | |
5350 /* Now output the bit load or bit inverse load, and store it in | |
5351 the destination. */ | |
5352 if (bild) | |
5353 output_asm_insn ("bild\t%Z2,%Y1", operands); | |
5354 else | |
5355 output_asm_insn ("bld\t%Z2,%Y1", operands); | |
5356 | |
5357 output_asm_insn ("bst\t#0,%w0", operands); | |
5358 } | |
5359 else | |
5360 { | |
5361 /* Determine if we can clear the destination first. */ | |
5362 int clear_first = (REG_P (operands[0]) && REG_P (operands[1]) | |
5363 && REGNO (operands[0]) != REGNO (operands[1])); | |
5364 | |
5365 if (clear_first) | |
5366 output_asm_insn ("sub.l\t%S0,%S0", operands); | |
5367 | |
5368 /* Output the bit load or bit inverse load. */ | |
5369 if (bild) | |
5370 output_asm_insn ("bild\t%Z2,%Y1", operands); | |
5371 else | |
5372 output_asm_insn ("bld\t%Z2,%Y1", operands); | |
5373 | |
5374 if (!clear_first) | |
5375 output_asm_insn ("xor.l\t%S0,%S0", operands); | |
5376 | |
5377 /* Perform the bit store. */ | |
5378 output_asm_insn ("rotxl.l\t%S0", operands); | |
5379 } | |
5380 | |
5381 /* All done. */ | |
5382 return ""; | |
5383 } | |
5384 | |
5385 /* Delayed-branch scheduling is more effective if we have some idea | |
5386 how long each instruction will be. Use a shorten_branches pass | |
5387 to get an initial estimate. */ | |
5388 | |
5389 static void | |
5390 h8300_reorg (void) | |
5391 { | |
5392 if (flag_delayed_branch) | |
5393 shorten_branches (get_insns ()); | |
5394 } | |
5395 | |
5396 #ifndef OBJECT_FORMAT_ELF | |
5397 static void | |
5398 h8300_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED, | |
5399 tree decl) | |
5400 { | |
5401 /* ??? Perhaps we should be using default_coff_asm_named_section. */ | |
5402 fprintf (asm_out_file, "\t.section %s\n", name); | |
5403 } | |
5404 #endif /* ! OBJECT_FORMAT_ELF */ | |
5405 | |
5406 /* Nonzero if X is a constant address suitable as an 8-bit absolute, | |
5407 which is a special case of the 'R' operand. */ | |
5408 | |
5409 int | |
5410 h8300_eightbit_constant_address_p (rtx x) | |
5411 { | |
5412 /* The ranges of the 8-bit area. */ | |
5413 const unsigned HOST_WIDE_INT n1 = trunc_int_for_mode (0xff00, HImode); | |
5414 const unsigned HOST_WIDE_INT n2 = trunc_int_for_mode (0xffff, HImode); | |
5415 const unsigned HOST_WIDE_INT h1 = trunc_int_for_mode (0x00ffff00, SImode); | |
5416 const unsigned HOST_WIDE_INT h2 = trunc_int_for_mode (0x00ffffff, SImode); | |
5417 const unsigned HOST_WIDE_INT s1 = trunc_int_for_mode (0xffffff00, SImode); | |
5418 const unsigned HOST_WIDE_INT s2 = trunc_int_for_mode (0xffffffff, SImode); | |
5419 | |
5420 unsigned HOST_WIDE_INT addr; | |
5421 | |
5422 /* We accept symbols declared with eightbit_data. */ | |
5423 if (GET_CODE (x) == SYMBOL_REF) | |
5424 return (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_EIGHTBIT_DATA) != 0; | |
5425 | |
5426 if (GET_CODE (x) != CONST_INT) | |
5427 return 0; | |
5428 | |
5429 addr = INTVAL (x); | |
5430 | |
5431 return (0 | |
5432 || ((TARGET_H8300 || TARGET_NORMAL_MODE) && IN_RANGE (addr, n1, n2)) | |
5433 || (TARGET_H8300H && IN_RANGE (addr, h1, h2)) | |
5434 || (TARGET_H8300S && IN_RANGE (addr, s1, s2))); | |
5435 } | |
5436 | |
5437 /* Nonzero if X is a constant address suitable as an 16-bit absolute | |
5438 on H8/300H and H8S. */ | |
5439 | |
5440 int | |
5441 h8300_tiny_constant_address_p (rtx x) | |
5442 { | |
5443 /* The ranges of the 16-bit area. */ | |
5444 const unsigned HOST_WIDE_INT h1 = trunc_int_for_mode (0x00000000, SImode); | |
5445 const unsigned HOST_WIDE_INT h2 = trunc_int_for_mode (0x00007fff, SImode); | |
5446 const unsigned HOST_WIDE_INT h3 = trunc_int_for_mode (0x00ff8000, SImode); | |
5447 const unsigned HOST_WIDE_INT h4 = trunc_int_for_mode (0x00ffffff, SImode); | |
5448 const unsigned HOST_WIDE_INT s1 = trunc_int_for_mode (0x00000000, SImode); | |
5449 const unsigned HOST_WIDE_INT s2 = trunc_int_for_mode (0x00007fff, SImode); | |
5450 const unsigned HOST_WIDE_INT s3 = trunc_int_for_mode (0xffff8000, SImode); | |
5451 const unsigned HOST_WIDE_INT s4 = trunc_int_for_mode (0xffffffff, SImode); | |
5452 | |
5453 unsigned HOST_WIDE_INT addr; | |
5454 | |
5455 switch (GET_CODE (x)) | |
5456 { | |
5457 case SYMBOL_REF: | |
5458 /* In the normal mode, any symbol fits in the 16-bit absolute | |
5459 address range. We also accept symbols declared with | |
5460 tiny_data. */ | |
5461 return (TARGET_NORMAL_MODE | |
5462 || (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_TINY_DATA) != 0); | |
5463 | |
5464 case CONST_INT: | |
5465 addr = INTVAL (x); | |
5466 return (TARGET_NORMAL_MODE | |
5467 || (TARGET_H8300H | |
5468 && (IN_RANGE (addr, h1, h2) || IN_RANGE (addr, h3, h4))) | |
5469 || (TARGET_H8300S | |
5470 && (IN_RANGE (addr, s1, s2) || IN_RANGE (addr, s3, s4)))); | |
5471 | |
5472 case CONST: | |
5473 return TARGET_NORMAL_MODE; | |
5474 | |
5475 default: | |
5476 return 0; | |
5477 } | |
5478 | |
5479 } | |
5480 | |
5481 /* Return nonzero if ADDR1 and ADDR2 point to consecutive memory | |
5482 locations that can be accessed as a 16-bit word. */ | |
5483 | |
5484 int | |
5485 byte_accesses_mergeable_p (rtx addr1, rtx addr2) | |
5486 { | |
5487 HOST_WIDE_INT offset1, offset2; | |
5488 rtx reg1, reg2; | |
5489 | |
5490 if (REG_P (addr1)) | |
5491 { | |
5492 reg1 = addr1; | |
5493 offset1 = 0; | |
5494 } | |
5495 else if (GET_CODE (addr1) == PLUS | |
5496 && REG_P (XEXP (addr1, 0)) | |
5497 && GET_CODE (XEXP (addr1, 1)) == CONST_INT) | |
5498 { | |
5499 reg1 = XEXP (addr1, 0); | |
5500 offset1 = INTVAL (XEXP (addr1, 1)); | |
5501 } | |
5502 else | |
5503 return 0; | |
5504 | |
5505 if (REG_P (addr2)) | |
5506 { | |
5507 reg2 = addr2; | |
5508 offset2 = 0; | |
5509 } | |
5510 else if (GET_CODE (addr2) == PLUS | |
5511 && REG_P (XEXP (addr2, 0)) | |
5512 && GET_CODE (XEXP (addr2, 1)) == CONST_INT) | |
5513 { | |
5514 reg2 = XEXP (addr2, 0); | |
5515 offset2 = INTVAL (XEXP (addr2, 1)); | |
5516 } | |
5517 else | |
5518 return 0; | |
5519 | |
5520 if (((reg1 == stack_pointer_rtx && reg2 == stack_pointer_rtx) | |
5521 || (reg1 == frame_pointer_rtx && reg2 == frame_pointer_rtx)) | |
5522 && offset1 % 2 == 0 | |
5523 && offset1 + 1 == offset2) | |
5524 return 1; | |
5525 | |
5526 return 0; | |
5527 } | |
5528 | |
5529 /* Return nonzero if we have the same comparison insn as I3 two insns | |
5530 before I3. I3 is assumed to be a comparison insn. */ | |
5531 | |
5532 int | |
5533 same_cmp_preceding_p (rtx i3) | |
5534 { | |
5535 rtx i1, i2; | |
5536 | |
5537 /* Make sure we have a sequence of three insns. */ | |
5538 i2 = prev_nonnote_insn (i3); | |
5539 if (i2 == NULL_RTX) | |
5540 return 0; | |
5541 i1 = prev_nonnote_insn (i2); | |
5542 if (i1 == NULL_RTX) | |
5543 return 0; | |
5544 | |
5545 return (INSN_P (i1) && rtx_equal_p (PATTERN (i1), PATTERN (i3)) | |
5546 && any_condjump_p (i2) && onlyjump_p (i2)); | |
5547 } | |
5548 | |
5549 /* Return nonzero if we have the same comparison insn as I1 two insns | |
5550 after I1. I1 is assumed to be a comparison insn. */ | |
5551 | |
5552 int | |
5553 same_cmp_following_p (rtx i1) | |
5554 { | |
5555 rtx i2, i3; | |
5556 | |
5557 /* Make sure we have a sequence of three insns. */ | |
5558 i2 = next_nonnote_insn (i1); | |
5559 if (i2 == NULL_RTX) | |
5560 return 0; | |
5561 i3 = next_nonnote_insn (i2); | |
5562 if (i3 == NULL_RTX) | |
5563 return 0; | |
5564 | |
5565 return (INSN_P (i3) && rtx_equal_p (PATTERN (i1), PATTERN (i3)) | |
5566 && any_condjump_p (i2) && onlyjump_p (i2)); | |
5567 } | |
5568 | |
5569 /* Return nonzero if OPERANDS are valid for stm (or ldm) that pushes | |
5570 (or pops) N registers. OPERANDS are assumed to be an array of | |
5571 registers. */ | |
5572 | |
5573 int | |
5574 h8300_regs_ok_for_stm (int n, rtx operands[]) | |
5575 { | |
5576 switch (n) | |
5577 { | |
5578 case 2: | |
5579 return ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1) | |
5580 || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3) | |
5581 || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5)); | |
5582 case 3: | |
5583 return ((REGNO (operands[0]) == 0 | |
5584 && REGNO (operands[1]) == 1 | |
5585 && REGNO (operands[2]) == 2) | |
5586 || (REGNO (operands[0]) == 4 | |
5587 && REGNO (operands[1]) == 5 | |
5588 && REGNO (operands[2]) == 6)); | |
5589 | |
5590 case 4: | |
5591 return (REGNO (operands[0]) == 0 | |
5592 && REGNO (operands[1]) == 1 | |
5593 && REGNO (operands[2]) == 2 | |
5594 && REGNO (operands[3]) == 3); | |
5595 default: | |
5596 gcc_unreachable (); | |
5597 } | |
5598 } | |
5599 | |
5600 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */ | |
5601 | |
5602 int | |
5603 h8300_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED, | |
5604 unsigned int new_reg) | |
5605 { | |
5606 /* Interrupt functions can only use registers that have already been | |
5607 saved by the prologue, even if they would normally be | |
5608 call-clobbered. */ | |
5609 | |
5610 if (h8300_current_function_interrupt_function_p () | |
5611 && !df_regs_ever_live_p (new_reg)) | |
5612 return 0; | |
5613 | |
5614 return 1; | |
5615 } | |
5616 | |
5617 /* Returns true if register REGNO is safe to be allocated as a scratch | |
5618 register in the current function. */ | |
5619 | |
5620 static bool | |
5621 h8300_hard_regno_scratch_ok (unsigned int regno) | |
5622 { | |
5623 if (h8300_current_function_interrupt_function_p () | |
5624 && ! WORD_REG_USED (regno)) | |
5625 return false; | |
5626 | |
5627 return true; | |
5628 } | |
5629 | |
5630 | |
5631 /* Return nonzero if X is a legitimate constant. */ | |
5632 | |
5633 int | |
5634 h8300_legitimate_constant_p (rtx x ATTRIBUTE_UNUSED) | |
5635 { | |
5636 return 1; | |
5637 } | |
5638 | |
5639 /* Return nonzero if X is a REG or SUBREG suitable as a base register. */ | |
5640 | |
5641 static int | |
5642 h8300_rtx_ok_for_base_p (rtx x, int strict) | |
5643 { | |
5644 /* Strip off SUBREG if any. */ | |
5645 if (GET_CODE (x) == SUBREG) | |
5646 x = SUBREG_REG (x); | |
5647 | |
5648 return (REG_P (x) | |
5649 && (strict | |
5650 ? REG_OK_FOR_BASE_STRICT_P (x) | |
5651 : REG_OK_FOR_BASE_NONSTRICT_P (x))); | |
5652 } | |
5653 | |
5654 /* Return nozero if X is a legitimate address. On the H8/300, a | |
5655 legitimate address has the form REG, REG+CONSTANT_ADDRESS or | |
5656 CONSTANT_ADDRESS. */ | |
5657 | |
5658 int | |
5659 h8300_legitimate_address_p (enum machine_mode mode, rtx x, int strict) | |
5660 { | |
5661 /* The register indirect addresses like @er0 is always valid. */ | |
5662 if (h8300_rtx_ok_for_base_p (x, strict)) | |
5663 return 1; | |
5664 | |
5665 if (CONSTANT_ADDRESS_P (x)) | |
5666 return 1; | |
5667 | |
5668 if (TARGET_H8300SX | |
5669 && ( GET_CODE (x) == PRE_INC | |
5670 || GET_CODE (x) == PRE_DEC | |
5671 || GET_CODE (x) == POST_INC | |
5672 || GET_CODE (x) == POST_DEC) | |
5673 && h8300_rtx_ok_for_base_p (XEXP (x, 0), strict)) | |
5674 return 1; | |
5675 | |
5676 if (GET_CODE (x) == PLUS | |
5677 && CONSTANT_ADDRESS_P (XEXP (x, 1)) | |
5678 && h8300_rtx_ok_for_base_p (h8300_get_index (XEXP (x, 0), | |
5679 mode, 0), strict)) | |
5680 return 1; | |
5681 | |
5682 return 0; | |
5683 } | |
5684 | |
5685 /* Worker function for HARD_REGNO_NREGS. | |
5686 | |
5687 We pretend the MAC register is 32bits -- we don't have any data | |
5688 types on the H8 series to handle more than 32bits. */ | |
5689 | |
5690 int | |
5691 h8300_hard_regno_nregs (int regno ATTRIBUTE_UNUSED, enum machine_mode mode) | |
5692 { | |
5693 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; | |
5694 } | |
5695 | |
5696 /* Worker function for HARD_REGNO_MODE_OK. */ | |
5697 | |
5698 int | |
5699 h8300_hard_regno_mode_ok (int regno, enum machine_mode mode) | |
5700 { | |
5701 if (TARGET_H8300) | |
5702 /* If an even reg, then anything goes. Otherwise the mode must be | |
5703 QI or HI. */ | |
5704 return ((regno & 1) == 0) || (mode == HImode) || (mode == QImode); | |
5705 else | |
5706 /* MAC register can only be of SImode. Otherwise, anything | |
5707 goes. */ | |
5708 return regno == MAC_REG ? mode == SImode : 1; | |
5709 } | |
5710 | |
5711 /* Perform target dependent optabs initialization. */ | |
5712 static void | |
5713 h8300_init_libfuncs (void) | |
5714 { | |
5715 set_optab_libfunc (smul_optab, HImode, "__mulhi3"); | |
5716 set_optab_libfunc (sdiv_optab, HImode, "__divhi3"); | |
5717 set_optab_libfunc (udiv_optab, HImode, "__udivhi3"); | |
5718 set_optab_libfunc (smod_optab, HImode, "__modhi3"); | |
5719 set_optab_libfunc (umod_optab, HImode, "__umodhi3"); | |
5720 } | |
5721 | |
5722 /* Worker function for TARGET_RETURN_IN_MEMORY. */ | |
5723 | |
5724 static bool | |
5725 h8300_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) | |
5726 { | |
5727 return (TYPE_MODE (type) == BLKmode | |
5728 || GET_MODE_SIZE (TYPE_MODE (type)) > (TARGET_H8300 ? 4 : 8)); | |
5729 } | |
5730 | |
5731 /* Initialize the GCC target structure. */ | |
5732 #undef TARGET_ATTRIBUTE_TABLE | |
5733 #define TARGET_ATTRIBUTE_TABLE h8300_attribute_table | |
5734 | |
5735 #undef TARGET_ASM_ALIGNED_HI_OP | |
5736 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t" | |
5737 | |
5738 #undef TARGET_ASM_FILE_START | |
5739 #define TARGET_ASM_FILE_START h8300_file_start | |
5740 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE | |
5741 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true | |
5742 | |
5743 #undef TARGET_ASM_FILE_END | |
5744 #define TARGET_ASM_FILE_END h8300_file_end | |
5745 | |
5746 #undef TARGET_ENCODE_SECTION_INFO | |
5747 #define TARGET_ENCODE_SECTION_INFO h8300_encode_section_info | |
5748 | |
5749 #undef TARGET_INSERT_ATTRIBUTES | |
5750 #define TARGET_INSERT_ATTRIBUTES h8300_insert_attributes | |
5751 | |
5752 #undef TARGET_RTX_COSTS | |
5753 #define TARGET_RTX_COSTS h8300_rtx_costs | |
5754 | |
5755 #undef TARGET_INIT_LIBFUNCS | |
5756 #define TARGET_INIT_LIBFUNCS h8300_init_libfuncs | |
5757 | |
5758 #undef TARGET_RETURN_IN_MEMORY | |
5759 #define TARGET_RETURN_IN_MEMORY h8300_return_in_memory | |
5760 | |
5761 #undef TARGET_MACHINE_DEPENDENT_REORG | |
5762 #define TARGET_MACHINE_DEPENDENT_REORG h8300_reorg | |
5763 | |
5764 #undef TARGET_HARD_REGNO_SCRATCH_OK | |
5765 #define TARGET_HARD_REGNO_SCRATCH_OK h8300_hard_regno_scratch_ok | |
5766 | |
5767 #undef TARGET_DEFAULT_TARGET_FLAGS | |
5768 #define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT | |
5769 | |
5770 struct gcc_target targetm = TARGET_INITIALIZER; |