]> gcc.gnu.org Git - gcc.git/blame - gcc/config/h8300/h8300.c
Daily bump.
[gcc.git] / gcc / config / h8300 / h8300.c
CommitLineData
07aae5c2 1/* Subroutines for insn-output.c for Hitachi H8/300.
aefc5826
KH
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002 Free Software Foundation, Inc.
48837e29
DE
4 Contributed by Steve Chamberlain (sac@cygnus.com),
5 Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
07aae5c2
SC
6
7This file is part of GNU CC.
8
9GNU CC is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2, or (at your option)
12any later version.
13
14GNU CC is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with GNU CC; see the file COPYING. If not, write to
97aadbb9
RK
21the Free Software Foundation, 59 Temple Place - Suite 330,
22Boston, MA 02111-1307, USA. */
07aae5c2 23
07aae5c2 24#include "config.h"
c5c76735 25#include "system.h"
4977bab6
ZW
26#include "coretypes.h"
27#include "tm.h"
07aae5c2 28#include "rtl.h"
bf6bb899 29#include "tree.h"
07aae5c2
SC
30#include "regs.h"
31#include "hard-reg-set.h"
32#include "real.h"
33#include "insn-config.h"
34#include "conditions.h"
07aae5c2
SC
35#include "output.h"
36#include "insn-attr.h"
37#include "flags.h"
38#include "recog.h"
39#include "expr.h"
bf6bb899 40#include "function.h"
441d04c6 41#include "toplev.h"
8b97c5f8 42#include "c-pragma.h"
441d04c6 43#include "tm_p.h"
f2a9645f 44#include "ggc.h"
672a6f42
NB
45#include "target.h"
46#include "target-def.h"
07aae5c2
SC
47
48/* Forward declarations. */
9c188705 49static const char *byte_reg PARAMS ((rtx, int));
f6da8bc3
KG
50static int h8300_interrupt_function_p PARAMS ((tree));
51static int h8300_monitor_function_p PARAMS ((tree));
52static int h8300_os_task_function_p PARAMS ((tree));
e8a68017 53static void dosize PARAMS ((FILE *, int, unsigned int));
8682223f
KH
54static int round_frame_size PARAMS ((int));
55static unsigned int compute_saved_regs PARAMS ((void));
56static void push PARAMS ((FILE *, int));
57static void pop PARAMS ((FILE *, int));
f6da8bc3 58static const char *cond_string PARAMS ((enum rtx_code));
86855e8c 59static unsigned int h8300_asm_insn_count PARAMS ((const char *));
91d231cb
JM
60const struct attribute_spec h8300_attribute_table[];
61static tree h8300_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
62static tree h8300_handle_eightbit_data_attribute PARAMS ((tree *, tree, tree, int, bool *));
63static tree h8300_handle_tiny_data_attribute PARAMS ((tree *, tree, tree, int, bool *));
08c148a8
NB
64static void h8300_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
65static void h8300_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
2c1d2fcb 66static void h8300_insert_attributes PARAMS ((tree, tree *));
ede75ee8 67#ifndef OBJECT_FORMAT_ELF
715bdd29 68static void h8300_asm_named_section PARAMS ((const char *, unsigned int));
ede75ee8 69#endif
fb49053f
RH
70static void h8300_encode_label PARAMS ((tree));
71static void h8300_encode_section_info PARAMS ((tree, int));
772c5265 72static const char *h8300_strip_name_encoding PARAMS ((const char *));
f5b65a56 73
48837e29
DE
74/* CPU_TYPE, says what cpu we're compiling for. */
75int cpu_type;
76
f5b65a56
JL
77/* True if the current function is an interrupt handler
78 (either via #pragma or an attribute specification). */
0869f126 79static int interrupt_handler;
f5b65a56 80
808fbfac 81/* True if the current function is an OS Task
fabe72bb 82 (via an attribute specification). */
0869f126 83static int os_task;
fabe72bb
JL
84
85/* True if the current function is a monitor
86 (via an attribute specification). */
0869f126 87static int monitor;
07aae5c2
SC
88
89/* True if a #pragma saveall has been seen for the current function. */
0869f126 90static int pragma_saveall;
07aae5c2 91
441d04c6 92static const char *const names_big[] =
07e4d94e 93{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" };
48837e29 94
441d04c6 95static const char *const names_extended[] =
07e4d94e 96{ "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" };
48837e29 97
441d04c6 98static const char *const names_upper_extended[] =
07e4d94e 99{ "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7" };
48837e29
DE
100
101/* Points to one of the above. */
102/* ??? The above could be put in an array indexed by CPU_TYPE. */
441d04c6 103const char * const *h8_reg_names;
48837e29
DE
104
105/* Various operations needed by the following, indexed by CPU_TYPE. */
48837e29 106
441d04c6 107const char *h8_push_op, *h8_pop_op, *h8_mov_op;
672a6f42
NB
108\f
109/* Initialize the GCC target structure. */
91d231cb
JM
110#undef TARGET_ATTRIBUTE_TABLE
111#define TARGET_ATTRIBUTE_TABLE h8300_attribute_table
48837e29 112
301d03af
RS
113#undef TARGET_ASM_ALIGNED_HI_OP
114#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
115
08c148a8
NB
116#undef TARGET_ASM_FUNCTION_PROLOGUE
117#define TARGET_ASM_FUNCTION_PROLOGUE h8300_output_function_prologue
118#undef TARGET_ASM_FUNCTION_EPILOGUE
119#define TARGET_ASM_FUNCTION_EPILOGUE h8300_output_function_epilogue
fb49053f
RH
120#undef TARGET_ENCODE_SECTION_INFO
121#define TARGET_ENCODE_SECTION_INFO h8300_encode_section_info
772c5265
RH
122#undef TARGET_STRIP_NAME_ENCODING
123#define TARGET_STRIP_NAME_ENCODING h8300_strip_name_encoding
08c148a8 124
2c1d2fcb
DD
125#undef TARGET_INSERT_ATTRIBUTES
126#define TARGET_INSERT_ATTRIBUTES h8300_insert_attributes
127
f6897b10 128struct gcc_target targetm = TARGET_INITIALIZER;
672a6f42 129\f
c4dfc70c
DD
130/* See below where shifts are handled for explanation of this enum. */
131
132enum shift_alg
133{
134 SHIFT_INLINE,
135 SHIFT_ROT_AND,
136 SHIFT_SPECIAL,
137 SHIFT_LOOP
138};
139
140/* Symbols of the various shifts which can be used as indices. */
141
142enum shift_type
143{
144 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
145};
146
147/* Macros to keep the shift algorithm tables small. */
148#define INL SHIFT_INLINE
149#define ROT SHIFT_ROT_AND
150#define LOP SHIFT_LOOP
151#define SPC SHIFT_SPECIAL
152
153/* The shift algorithms for each machine, mode, shift type, and shift
154 count are defined below. The three tables below correspond to
155 QImode, HImode, and SImode, respectively. Each table is organized
156 by, in the order of indecies, machine, shift type, and shift count. */
157
158static enum shift_alg shift_alg_qi[3][3][8] = {
159 {
160 /* TARGET_H8300 */
161 /* 0 1 2 3 4 5 6 7 */
162 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
163 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
164 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
165 },
166 {
167 /* TARGET_H8300H */
168 /* 0 1 2 3 4 5 6 7 */
169 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
170 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
171 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
172 },
173 {
174 /* TARGET_H8300S */
175 /* 0 1 2 3 4 5 6 7 */
176 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_ASHIFT */
177 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_LSHIFTRT */
178 { INL, INL, INL, INL, INL, INL, INL, SPC } /* SHIFT_ASHIFTRT */
179 }
180};
181
182static enum shift_alg shift_alg_hi[3][3][16] = {
183 {
184 /* TARGET_H8300 */
185 /* 0 1 2 3 4 5 6 7 */
186 /* 8 9 10 11 12 13 14 15 */
187 { INL, INL, INL, INL, INL, INL, INL, SPC,
188 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */
189 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
190 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */
191 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
192 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
193 },
194 {
195 /* TARGET_H8300H */
196 /* 0 1 2 3 4 5 6 7 */
197 /* 8 9 10 11 12 13 14 15 */
198 { INL, INL, INL, INL, INL, INL, INL, SPC,
199 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
200 { INL, INL, INL, INL, INL, INL, INL, SPC,
201 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
202 { INL, INL, INL, INL, INL, INL, INL, SPC,
203 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
204 },
205 {
206 /* TARGET_H8300S */
207 /* 0 1 2 3 4 5 6 7 */
208 /* 8 9 10 11 12 13 14 15 */
209 { INL, INL, INL, INL, INL, INL, INL, INL,
210 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
211 { INL, INL, INL, INL, INL, INL, INL, INL,
212 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
213 { INL, INL, INL, INL, INL, INL, INL, INL,
214 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
215 }
216};
217
218static enum shift_alg shift_alg_si[3][3][32] = {
219 {
220 /* TARGET_H8300 */
221 /* 0 1 2 3 4 5 6 7 */
222 /* 8 9 10 11 12 13 14 15 */
223 /* 16 17 18 19 20 21 22 23 */
224 /* 24 25 26 27 28 29 30 31 */
225 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
226 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
227 SPC, SPC, SPC, SPC, SPC, LOP, LOP, LOP,
228 SPC, SPC, SPC, SPC, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
229 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
230 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC,
231 SPC, SPC, SPC, LOP, LOP, LOP, LOP, LOP,
232 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
233 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
234 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
235 SPC, SPC, LOP, LOP, LOP, LOP, LOP, LOP,
236 SPC, SPC, SPC, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
237 },
238 {
239 /* TARGET_H8300H */
240 /* 0 1 2 3 4 5 6 7 */
241 /* 8 9 10 11 12 13 14 15 */
242 /* 16 17 18 19 20 21 22 23 */
243 /* 24 25 26 27 28 29 30 31 */
244 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
245 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
246 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
1e5bdc40 247 SPC, LOP, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */
c4dfc70c
DD
248 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
249 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
250 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
1e5bdc40 251 SPC, LOP, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */
c4dfc70c
DD
252 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
253 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
254 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
255 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
256 },
257 {
258 /* TARGET_H8300S */
259 /* 0 1 2 3 4 5 6 7 */
260 /* 8 9 10 11 12 13 14 15 */
261 /* 16 17 18 19 20 21 22 23 */
262 /* 24 25 26 27 28 29 30 31 */
263 { INL, INL, INL, INL, INL, INL, INL, INL,
264 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
265 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
1e5bdc40 266 SPC, SPC, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */
c4dfc70c
DD
267 { INL, INL, INL, INL, INL, INL, INL, INL,
268 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
269 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
1e5bdc40 270 SPC, SPC, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */
c4dfc70c
DD
271 { INL, INL, INL, INL, INL, INL, INL, INL,
272 INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
273 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
274 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
275 }
276};
277
278#undef INL
279#undef ROT
280#undef LOP
281#undef SPC
282
283enum h8_cpu
284{
285 H8_300,
286 H8_300H,
287 H8_S
288};
289
48837e29
DE
290/* Initialize various cpu specific globals at start up. */
291
292void
293h8300_init_once ()
294{
cbf1b2da
KH
295 static const char *const h8_push_ops[2] = { "push" , "push.l" };
296 static const char *const h8_pop_ops[2] = { "pop" , "pop.l" };
297 static const char *const h8_mov_ops[2] = { "mov.w", "mov.l" };
298
48837e29
DE
299 if (TARGET_H8300)
300 {
301 cpu_type = (int) CPU_H8300;
302 h8_reg_names = names_big;
303 }
304 else
305 {
3db11b5c 306 /* For this we treat the H8/300H and H8S the same. */
48837e29
DE
307 cpu_type = (int) CPU_H8300H;
308 h8_reg_names = names_extended;
309 }
310 h8_push_op = h8_push_ops[cpu_type];
311 h8_pop_op = h8_pop_ops[cpu_type];
312 h8_mov_op = h8_mov_ops[cpu_type];
17f0f8fa
KH
313
314 if (!TARGET_H8300S && TARGET_MAC)
400500c4 315 {
c725bd79 316 error ("-ms2600 is used without -ms");
ec5b0c68 317 target_flags |= MASK_H8300S;
400500c4 318 }
920e86b8 319
39ba95b5
VK
320 if (TARGET_H8300 && TARGET_NORMAL_MODE)
321 {
92d4b8a0 322 error ("-mn is used without -mh or -ms");
39ba95b5
VK
323 target_flags ^= MASK_NORMAL_MODE;
324 }
c4dfc70c 325
8bd06267 326 /* Some of the shifts are optimized for speed by default.
c4dfc70c 327 See http://gcc.gnu.org/ml/gcc-patches/2002-07/msg01858.html
8bd06267 328 If optimizing for size, change shift_alg for those shift to
c4dfc70c 329 SHIFT_LOOP. */
b6894857 330 if (optimize_size)
c4dfc70c 331 {
b6894857
KH
332 /* H8/300 */
333 shift_alg_hi[H8_300][SHIFT_ASHIFT][5] = SHIFT_LOOP;
334 shift_alg_hi[H8_300][SHIFT_ASHIFT][6] = SHIFT_LOOP;
335 shift_alg_hi[H8_300][SHIFT_ASHIFT][13] = SHIFT_LOOP;
336 shift_alg_hi[H8_300][SHIFT_ASHIFT][14] = SHIFT_LOOP;
c4dfc70c 337
b6894857
KH
338 shift_alg_hi[H8_300][SHIFT_LSHIFTRT][13] = SHIFT_LOOP;
339 shift_alg_hi[H8_300][SHIFT_LSHIFTRT][14] = SHIFT_LOOP;
c4dfc70c 340
b6894857
KH
341 shift_alg_hi[H8_300][SHIFT_ASHIFTRT][13] = SHIFT_LOOP;
342 shift_alg_hi[H8_300][SHIFT_ASHIFTRT][14] = SHIFT_LOOP;
c4dfc70c 343
b6894857
KH
344 /* H8/300H */
345 shift_alg_hi[H8_300H][SHIFT_ASHIFT][5] = SHIFT_LOOP;
346 shift_alg_hi[H8_300H][SHIFT_ASHIFT][6] = SHIFT_LOOP;
c4dfc70c 347
b6894857
KH
348 shift_alg_hi[H8_300H][SHIFT_LSHIFTRT][5] = SHIFT_LOOP;
349 shift_alg_hi[H8_300H][SHIFT_LSHIFTRT][6] = SHIFT_LOOP;
c4dfc70c 350
b6894857
KH
351 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][5] = SHIFT_LOOP;
352 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][6] = SHIFT_LOOP;
353 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][13] = SHIFT_LOOP;
354 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][14] = SHIFT_LOOP;
c4dfc70c
DD
355
356 /* H8S */
b6894857 357 shift_alg_hi[H8_S][SHIFT_ASHIFTRT][14] = SHIFT_LOOP;
c4dfc70c 358 }
48837e29 359}
07aae5c2 360
9c188705 361static const char *
07aae5c2
SC
362byte_reg (x, b)
363 rtx x;
364 int b;
365{
9cbcd983
KH
366 static const char *const names_small[] = {
367 "r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
368 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h"
369 };
07aae5c2
SC
370
371 return names_small[REGNO (x) * 2 + b];
372}
373
374/* REGNO must be saved/restored across calls if this macro is true. */
48837e29 375
9cbcd983
KH
376#define WORD_REG_USED(regno) \
377 (regno < 7 \
378 /* No need to save registers if this function will not return. */ \
379 && ! TREE_THIS_VOLATILE (current_function_decl) \
380 && (pragma_saveall \
381 /* Save any call saved register that was used. */ \
382 || (regs_ever_live[regno] && !call_used_regs[regno]) \
383 /* Save the frame pointer if it was used. */ \
384 || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno]) \
385 /* Save any register used in an interrupt handler. */ \
386 || (interrupt_handler && regs_ever_live[regno]) \
387 /* Save call clobbered registers in non-leaf interrupt \
388 handlers. */ \
389 || (interrupt_handler \
390 && call_used_regs[regno] \
fc80ea73 391 && !current_function_is_leaf)))
07aae5c2
SC
392
393/* Output assembly language to FILE for the operation OP with operand size
48837e29 394 SIZE to adjust the stack pointer. */
48837e29 395
07aae5c2 396static void
e8a68017 397dosize (file, sign, size)
07aae5c2 398 FILE *file;
e8a68017 399 int sign;
07aae5c2 400 unsigned int size;
07aae5c2 401{
3db11b5c 402 /* On the H8/300H and H8S, for sizes <= 8 bytes, it is as good or
7b3d4613
KH
403 better to use adds/subs insns rather than add.l/sub.l with an
404 immediate value.
405
406 Also, on the H8/300, if we don't have a temporary to hold the
407 size of the frame in the prologue, we simply emit a sequence of
408 subs since this shouldn't happen often. */
409 if ((TARGET_H8300 && size <= 4)
410 || ((TARGET_H8300H || TARGET_H8300S) && size <= 8)
768caa28 411 || (TARGET_H8300 && interrupt_handler)
7b3d4613 412 || (TARGET_H8300 && current_function_needs_context
e8a68017 413 && sign < 0))
f8f26adc 414 {
e8a68017 415 const char *op = (sign > 0) ? "add" : "sub";
b47900aa 416 unsigned int amount;
f8f26adc 417
7b3d4613
KH
418 /* Try different amounts in descending order. */
419 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
420 amount > 0;
421 amount /= 2)
82fa9209 422 {
513f31eb
KH
423 char insn[100];
424
425 sprintf (insn, "\t%ss\t#%d,%s\n", op, amount,
426 TARGET_H8300 ? "r7" : "er7");
1a63219b 427 for (; size >= amount; size -= amount)
513f31eb 428 fputs (insn, file);
82fa9209 429 }
7b3d4613
KH
430 }
431 else
432 {
48837e29 433 if (TARGET_H8300)
e8a68017
KH
434 {
435 fprintf (file, "\tmov.w\t#%d,r3\n\tadd.w\tr3,r7\n", sign * size);
436 }
48837e29 437 else
e8a68017
KH
438 {
439 fprintf (file, "\tadd.l\t#%d,er7\n", sign * size);
440 }
07aae5c2
SC
441 }
442}
443
8682223f
KH
444/* Round up frame size SIZE. */
445
446static int
447round_frame_size (size)
448 int size;
449{
489eda65
KH
450 return ((size + STACK_BOUNDARY / BITS_PER_UNIT - 1)
451 & -STACK_BOUNDARY / BITS_PER_UNIT);
8682223f
KH
452}
453
454/* Compute which registers to push/pop.
455 Return a bit vector of registers. */
456
457static unsigned int
458compute_saved_regs ()
459{
460 unsigned int saved_regs = 0;
461 int regno;
462
463 /* Construct a bit vector of registers to be pushed/popped. */
b9b575e6 464 for (regno = 0; regno <= FRAME_POINTER_REGNUM; regno++)
8682223f
KH
465 {
466 if (WORD_REG_USED (regno))
467 saved_regs |= 1 << regno;
468 }
469
470 /* Don't push/pop the frame pointer as it is treated separately. */
471 if (frame_pointer_needed)
472 saved_regs &= ~(1 << FRAME_POINTER_REGNUM);
473
474 return saved_regs;
475}
476
477/* Output assembly language code to push register RN. */
478
479static void
480push (file, rn)
481 FILE *file;
482 int rn;
483{
513f31eb
KH
484 if (TARGET_H8300)
485 fprintf (file, "\t%s\t%s,@-r7\n", h8_mov_op, h8_reg_names[rn]);
486 else
487 fprintf (file, "\t%s\t%s,@-er7\n", h8_mov_op, h8_reg_names[rn]);
8682223f
KH
488}
489
490/* Output assembly language code to pop register RN. */
491
492static void
493pop (file, rn)
494 FILE *file;
495 int rn;
496{
513f31eb
KH
497 if (TARGET_H8300)
498 fprintf (file, "\t%s\t@r7+,%s\n", h8_mov_op, h8_reg_names[rn]);
499 else
500 fprintf (file, "\t%s\t@er7+,%s\n", h8_mov_op, h8_reg_names[rn]);
8682223f 501}
07aae5c2 502
f0b6f9a6 503/* This is what the stack looks like after the prolog of
07aae5c2
SC
504 a function with a frame has been set up:
505
48837e29
DE
506 <args>
507 PC
508 FP <- fp
509 <locals>
8bd06267 510 <saved registers> <- sp
07aae5c2
SC
511
512 This is what the stack looks like after the prolog of
513 a function which doesn't have a frame:
514
48837e29
DE
515 <args>
516 PC
517 <locals>
8bd06267 518 <saved registers> <- sp
07aae5c2
SC
519*/
520
8682223f
KH
521/* Output assembly language code for the function prologue. */
522
08c148a8
NB
523static void
524h8300_output_function_prologue (file, size)
07aae5c2 525 FILE *file;
08c148a8 526 HOST_WIDE_INT size;
07aae5c2 527{
8682223f 528 int fsize = round_frame_size (size);
e651d484 529 int regno;
8682223f 530 int saved_regs;
cda4bd43 531 int n_regs;
07aae5c2 532
dd07092e
JL
533 /* Note a function with the interrupt attribute and set interrupt_handler
534 accordingly. */
f5b65a56
JL
535 if (h8300_interrupt_function_p (current_function_decl))
536 interrupt_handler = 1;
537
fabe72bb
JL
538 /* If the current function has the OS_Task attribute set, then
539 we have a naked prologue. */
540 if (h8300_os_task_function_p (current_function_decl))
541 {
542 fprintf (file, ";OS_Task prologue\n");
543 os_task = 1;
544 return;
545 }
546
547 if (h8300_monitor_function_p (current_function_decl))
548 {
549 /* My understanding of monitor functions is they act just
550 like interrupt functions, except the prologue must
551 mask interrupts. */
552 fprintf (file, ";monitor prologue\n");
553 interrupt_handler = 1;
554 monitor = 1;
ea3a7ffa
JL
555 if (TARGET_H8300)
556 {
557 fprintf (file, "\tsubs\t#2,sp\n");
8682223f 558 push (file, 0);
ea3a7ffa 559 fprintf (file, "\tstc\tccr,r0l\n");
46d00fef
KH
560 fprintf (file, "\tmov.b\tr0l,@(2,sp)\n");
561 pop (file, 0);
ea3a7ffa 562 fprintf (file, "\torc\t#128,ccr\n");
46d00fef
KH
563 }
564 else if (TARGET_H8300H)
565 {
566 push (file, 0);
567 fprintf (file, "\tstc\tccr,r0l\n");
ea3a7ffa 568 fprintf (file, "\tmov.b\tr0l,@(4,sp)\n");
46d00fef
KH
569 pop (file, 0);
570 fprintf (file, "\torc\t#128,ccr\n");
ea3a7ffa 571 }
46d00fef 572 else if (TARGET_H8300S)
ea3a7ffa 573 {
46d00fef 574 fprintf (file, "\tstc\texr,@-sp\n");
8682223f 575 push (file, 0);
ea3a7ffa 576 fprintf (file, "\tstc\tccr,r0l\n");
46d00fef
KH
577 fprintf (file, "\tmov.b\tr0l,@(6,sp)\n");
578 pop (file, 0);
ea3a7ffa 579 fprintf (file, "\torc\t#128,ccr\n");
ea3a7ffa 580 }
46d00fef
KH
581 else
582 abort ();
fabe72bb
JL
583 }
584
48837e29
DE
585 if (frame_pointer_needed)
586 {
07e4d94e 587 /* Push fp. */
8682223f 588 push (file, FRAME_POINTER_REGNUM);
48837e29
DE
589 fprintf (file, "\t%s\t%s,%s\n", h8_mov_op,
590 h8_reg_names[STACK_POINTER_REGNUM],
591 h8_reg_names[FRAME_POINTER_REGNUM]);
a1616dd9 592 }
48837e29 593
07e4d94e 594 /* Leave room for locals. */
e8a68017 595 dosize (file, -1, fsize);
07aae5c2 596
8682223f
KH
597 /* Push the rest of the registers in ascending order. */
598 saved_regs = compute_saved_regs ();
e651d484 599 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno += n_regs)
cda4bd43 600 {
cda4bd43 601 n_regs = 1;
8682223f 602 if (saved_regs & (1 << regno))
a1616dd9
JL
603 {
604 if (TARGET_H8300S)
605 {
cda4bd43
KH
606 /* See how many registers we can push at the same time. */
607 if ((regno == 0 || regno == 4)
8682223f 608 && ((saved_regs >> regno) & 0x0f) == 0x0f)
cda4bd43
KH
609 n_regs = 4;
610
611 else if ((regno == 0 || regno == 4)
8682223f 612 && ((saved_regs >> regno) & 0x07) == 0x07)
cda4bd43
KH
613 n_regs = 3;
614
615 else if ((regno == 0 || regno == 2 || regno == 4 || regno == 6)
8682223f 616 && ((saved_regs >> regno) & 0x03) == 0x03)
cda4bd43 617 n_regs = 2;
a1616dd9 618 }
cda4bd43 619
e8a68017
KH
620 switch (n_regs)
621 {
622 case 1:
623 push (file, regno);
624 break;
625 case 2:
626 fprintf (file, "\tstm.l\t%s-%s,@-er7\n",
627 h8_reg_names[regno],
628 h8_reg_names[regno + 1]);
629 break;
630 case 3:
631 fprintf (file, "\tstm.l\t%s-%s,@-er7\n",
632 h8_reg_names[regno],
633 h8_reg_names[regno + 2]);
634 break;
635 case 4:
636 fprintf (file, "\tstm.l\t%s-%s,@-er7\n",
637 h8_reg_names[regno],
638 h8_reg_names[regno + 3]);
639 break;
640 default:
641 abort ();
642 }
07aae5c2
SC
643 }
644 }
645}
646
647/* Output assembly language code for the function epilogue. */
648
08c148a8
NB
649static void
650h8300_output_function_epilogue (file, size)
07aae5c2 651 FILE *file;
08c148a8 652 HOST_WIDE_INT size;
07aae5c2 653{
8682223f 654 int fsize = round_frame_size (size);
e651d484 655 int regno;
07aae5c2 656 rtx insn = get_last_insn ();
8682223f 657 int saved_regs;
cda4bd43 658 int n_regs;
07aae5c2 659
fabe72bb
JL
660 if (os_task)
661 {
662 /* OS_Task epilogues are nearly naked -- they just have an
663 rts instruction. */
664 fprintf (file, ";OS_task epilogue\n");
665 fprintf (file, "\trts\n");
666 goto out;
667 }
668
07e4d94e 669 /* Monitor epilogues are the same as interrupt function epilogues.
5bdc5878 670 Just make a note that we're in a monitor epilogue. */
fabe72bb 671 if (monitor)
07e4d94e 672 fprintf (file, ";monitor epilogue\n");
fabe72bb 673
07aae5c2
SC
674 /* If the last insn was a BARRIER, we don't have to write any code. */
675 if (GET_CODE (insn) == NOTE)
676 insn = prev_nonnote_insn (insn);
677 if (insn && GET_CODE (insn) == BARRIER)
f40a8c03 678 goto out;
07aae5c2 679
8682223f
KH
680 /* Pop the saved registers in descending order. */
681 saved_regs = compute_saved_regs ();
e651d484 682 for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno -= n_regs)
cda4bd43 683 {
cda4bd43 684 n_regs = 1;
8682223f 685 if (saved_regs & (1 << regno))
07aae5c2 686 {
a1616dd9
JL
687 if (TARGET_H8300S)
688 {
cda4bd43
KH
689 /* See how many registers we can pop at the same time. */
690 if ((regno == 7 || regno == 3)
8682223f 691 && ((saved_regs >> (regno - 3)) & 0x0f) == 0x0f)
cda4bd43
KH
692 n_regs = 4;
693
694 else if ((regno == 6 || regno == 2)
8682223f 695 && ((saved_regs >> (regno - 2)) & 0x07) == 0x07)
cda4bd43
KH
696 n_regs = 3;
697
698 else if ((regno == 7 || regno == 5 || regno == 3 || regno == 1)
8682223f 699 && ((saved_regs >> (regno - 1)) & 0x03) == 0x03)
cda4bd43 700 n_regs = 2;
a1616dd9 701 }
cda4bd43 702
e8a68017
KH
703 switch (n_regs)
704 {
705 case 1:
706 pop (file, regno);
707 break;
708 case 2:
709 fprintf (file, "\tldm.l\t@er7+,%s-%s\n",
710 h8_reg_names[regno - 1],
711 h8_reg_names[regno]);
712 break;
713 case 3:
714 fprintf (file, "\tldm.l\t@er7+,%s-%s\n",
715 h8_reg_names[regno - 2],
716 h8_reg_names[regno]);
717 break;
718 case 4:
719 fprintf (file, "\tldm.l\t@er7+,%s-%s\n",
720 h8_reg_names[regno - 3],
721 h8_reg_names[regno]);
722 break;
723 default:
724 abort ();
725 }
07aae5c2 726 }
07aae5c2 727 }
48837e29 728
07e4d94e 729 /* Deallocate locals. */
e8a68017 730 dosize (file, 1, fsize);
a1616dd9 731
07e4d94e 732 /* Pop frame pointer if we had one. */
a1616dd9 733 if (frame_pointer_needed)
8682223f 734 pop (file, FRAME_POINTER_REGNUM);
a1616dd9 735
dd07092e
JL
736 if (interrupt_handler)
737 fprintf (file, "\trte\n");
07aae5c2 738 else
dd07092e 739 fprintf (file, "\trts\n");
07aae5c2 740
07e4d94e 741 out:
f5b65a56 742 interrupt_handler = 0;
fabe72bb
JL
743 os_task = 0;
744 monitor = 0;
07aae5c2 745 pragma_saveall = 0;
48837e29
DE
746}
747
748/* Output assembly code for the start of the file. */
749
441d04c6 750void
48837e29
DE
751asm_file_start (file)
752 FILE *file;
753{
754 fprintf (file, ";\tGCC For the Hitachi H8/300\n");
755 fprintf (file, ";\tBy Hitachi America Ltd and Cygnus Support\n");
8bd06267 756
ff970081 757 if (optimize_size)
f8cb5851 758 fprintf (file, "; -Os\n");
ff970081 759 else if (optimize)
48837e29
DE
760 fprintf (file, "; -O%d\n", optimize);
761 if (TARGET_H8300H)
762 fprintf (file, "\n\t.h8300h\n");
a1616dd9
JL
763 else if (TARGET_H8300S)
764 fprintf (file, "\n\t.h8300s\n");
48837e29
DE
765 else
766 fprintf (file, "\n\n");
767 output_file_directive (file, main_input_filename);
768}
769
770/* Output assembly language code for the end of file. */
771
772void
773asm_file_end (file)
774 FILE *file;
775{
776 fprintf (file, "\t.end\n");
07aae5c2
SC
777}
778\f
68560db3 779/* Return true if OP is a valid source operand for an integer move
07aae5c2 780 instruction. */
48837e29 781
07aae5c2
SC
782int
783general_operand_src (op, mode)
784 rtx op;
785 enum machine_mode mode;
786{
48837e29
DE
787 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
788 return 1;
07aae5c2
SC
789 return general_operand (op, mode);
790}
791
792/* Return true if OP is a valid destination operand for an integer move
5660465a 793 instruction. */
48837e29 794
07aae5c2
SC
795int
796general_operand_dst (op, mode)
797 rtx op;
798 enum machine_mode mode;
799{
48837e29
DE
800 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == PRE_DEC)
801 return 1;
07aae5c2
SC
802 return general_operand (op, mode);
803}
48837e29 804
4d4d89e2
KH
805/* Return true if OP is a constant that contains only one 1 in its
806 binary representation. */
48837e29
DE
807
808int
4d4d89e2 809single_one_operand (operand, mode)
48837e29 810 rtx operand;
441d04c6 811 enum machine_mode mode ATTRIBUTE_UNUSED;
48837e29 812{
4d4d89e2
KH
813 if (GET_CODE (operand) == CONST_INT)
814 {
815 /* We really need to do this masking because 0x80 in QImode is
816 represented as -128 for example. */
817 unsigned HOST_WIDE_INT mask =
e27051f7
KH
818 (GET_MODE_BITSIZE (mode) < HOST_BITS_PER_WIDE_INT)
819 ? ((unsigned HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (mode)) - 1
491a9777 820 : ~(unsigned HOST_WIDE_INT) 0;
4d4d89e2
KH
821 unsigned HOST_WIDE_INT value = INTVAL (operand);
822
823 if (exact_log2 (value & mask) >= 0)
824 return 1;
825 }
826
827 return 0;
828}
829
830/* Return true if OP is a constant that contains only one 0 in its
831 binary representation. */
832
833int
834single_zero_operand (operand, mode)
835 rtx operand;
836 enum machine_mode mode ATTRIBUTE_UNUSED;
837{
838 if (GET_CODE (operand) == CONST_INT)
839 {
840 /* We really need to do this masking because 0x80 in QImode is
841 represented as -128 for example. */
842 unsigned HOST_WIDE_INT mask =
e27051f7
KH
843 (GET_MODE_BITSIZE (mode) < HOST_BITS_PER_WIDE_INT)
844 ? ((unsigned HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (mode)) - 1
491a9777 845 : ~(unsigned HOST_WIDE_INT) 0;
4d4d89e2
KH
846 unsigned HOST_WIDE_INT value = INTVAL (operand);
847
848 if (exact_log2 (~value & mask) >= 0)
849 return 1;
850 }
851
852 return 0;
48837e29
DE
853}
854
48837e29
DE
855/* Return true if OP is a valid call operand. */
856
857int
858call_insn_operand (op, mode)
859 rtx op;
441d04c6 860 enum machine_mode mode ATTRIBUTE_UNUSED;
48837e29
DE
861{
862 if (GET_CODE (op) == MEM)
863 {
864 rtx inside = XEXP (op, 0);
865 if (register_operand (inside, Pmode))
866 return 1;
867 if (CONSTANT_ADDRESS_P (inside))
868 return 1;
869 }
870 return 0;
871}
872
22c9a795 873/* Return 1 if an addition/subtraction of a constant integer can be
997e5af8 874 transformed into two consecutive adds/subs that are faster than the
22c9a795 875 straightforward way. Otherwise, return 0. */
997e5af8 876
3b7d443c 877int
009ac3d3 878two_insn_adds_subs_operand (op, mode)
3b7d443c 879 rtx op;
997e5af8 880 enum machine_mode mode;
3b7d443c
JL
881{
882 if (GET_CODE (op) == CONST_INT)
883 {
009ac3d3 884 HOST_WIDE_INT value = INTVAL (op);
3b7d443c 885
997e5af8
KH
886 /* Force VALUE to be positive so that we do not have to consider
887 the negative case. */
888 if (value < 0)
889 value = -value;
009ac3d3
RH
890 if (TARGET_H8300H || TARGET_H8300S)
891 {
997e5af8
KH
892 /* A constant addition/subtraction takes 2 states in QImode,
893 4 states in HImode, and 6 states in SImode. Thus, the
894 only case we can win is when SImode is used, in which
c59ff527 895 case, two adds/subs are used, taking 4 states. */
997e5af8
KH
896 if (mode == SImode
897 && (value == 2 + 1
898 || value == 4 + 1
899 || value == 4 + 2
900 || value == 4 + 4))
22c9a795 901 return 1;
009ac3d3
RH
902 }
903 else
904 {
ae19f5ef
KH
905 /* We do not profit directly by splitting addition or
906 subtraction of 3 and 4. However, since these are
907 implemented as a sequence of adds or subs, they do not
908 clobber (cc0) unlike a sequence of add.b and add.x. */
909 if (mode == HImode
997e5af8
KH
910 && (value == 2 + 1
911 || value == 2 + 2))
009ac3d3
RH
912 return 1;
913 }
914 }
e6219736 915
e6219736
JL
916 return 0;
917}
918
009ac3d3
RH
919/* Split an add of a small constant into two adds/subs insns. */
920
921void
922split_adds_subs (mode, operands)
923 enum machine_mode mode;
3b7d443c
JL
924 rtx *operands;
925{
009ac3d3
RH
926 HOST_WIDE_INT val = INTVAL (operands[1]);
927 rtx reg = operands[0];
9492393e
KH
928 HOST_WIDE_INT sign = 1;
929 HOST_WIDE_INT amount;
3b7d443c 930
9492393e
KH
931 /* Force VAL to be positive so that we do not have to consider the
932 sign. */
933 if (val < 0)
3b7d443c 934 {
9492393e
KH
935 val = -val;
936 sign = -1;
937 }
3b7d443c 938
9492393e
KH
939 /* Try different amounts in descending order. */
940 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
941 amount > 0;
942 amount /= 2)
943 {
1a63219b 944 for (; val >= amount; val -= amount)
009ac3d3 945 {
9492393e 946 rtx tmp = gen_rtx_PLUS (mode, reg, GEN_INT (sign * amount));
009ac3d3 947 emit_insn (gen_rtx_SET (VOIDmode, reg, tmp));
009ac3d3 948 }
3b7d443c
JL
949 }
950
9492393e 951 return;
3b7d443c
JL
952}
953
f5b65a56
JL
954/* Return true if OP is a valid call operand, and OP represents
955 an operand for a small call (4 bytes instead of 6 bytes). */
956
957int
958small_call_insn_operand (op, mode)
959 rtx op;
441d04c6 960 enum machine_mode mode ATTRIBUTE_UNUSED;
f5b65a56
JL
961{
962 if (GET_CODE (op) == MEM)
963 {
964 rtx inside = XEXP (op, 0);
965
966 /* Register indirect is a small call. */
967 if (register_operand (inside, Pmode))
968 return 1;
969
970 /* A call through the function vector is a small
971 call too. */
972 if (GET_CODE (inside) == SYMBOL_REF
973 && SYMBOL_REF_FLAG (inside))
974 return 1;
975 }
976 /* Otherwise it's a large call. */
977 return 0;
978}
979
48837e29
DE
980/* Return true if OP is a valid jump operand. */
981
982int
983jump_address_operand (op, mode)
984 rtx op;
985 enum machine_mode mode;
986{
987 if (GET_CODE (op) == REG)
988 return mode == Pmode;
989
990 if (GET_CODE (op) == MEM)
991 {
992 rtx inside = XEXP (op, 0);
993 if (register_operand (inside, Pmode))
994 return 1;
995 if (CONSTANT_ADDRESS_P (inside))
996 return 1;
997 }
998 return 0;
999}
1000
43a88a8c 1001/* Recognize valid operands for bit-field instructions. */
48837e29
DE
1002
1003extern int rtx_equal_function_value_matters;
1004
1005int
1006bit_operand (op, mode)
1007 rtx op;
1008 enum machine_mode mode;
1009{
1010 /* We can except any general operand, expept that MEM operands must
1011 be limited to those that use addresses valid for the 'U' constraint. */
1012 if (!general_operand (op, mode))
1013 return 0;
1014
1015 /* Accept any mem during RTL generation. Otherwise, the code that does
1016 insv and extzv will think that we can not handle memory. However,
1017 to avoid reload problems, we only accept 'U' MEM operands after RTL
1018 generation. This means that any named pattern which uses this predicate
1019 must force its operands to match 'U' before emitting RTL. */
1020
1021 if (GET_CODE (op) == REG)
1022 return 1;
1023 if (GET_CODE (op) == SUBREG)
1024 return 1;
1025 if (!rtx_equal_function_value_matters)
07e4d94e
KH
1026 /* We're building rtl. */
1027 return GET_CODE (op) == MEM;
48837e29 1028 else
07e4d94e
KH
1029 return (GET_CODE (op) == MEM
1030 && EXTRA_CONSTRAINT (op, 'U'));
48837e29
DE
1031}
1032
887a8bd9
JL
1033int
1034bit_memory_operand (op, mode)
1035 rtx op;
441d04c6 1036 enum machine_mode mode ATTRIBUTE_UNUSED;
887a8bd9
JL
1037{
1038 return (GET_CODE (op) == MEM
1039 && EXTRA_CONSTRAINT (op, 'U'));
1040}
1041
07aae5c2 1042/* Handle machine specific pragmas for compatibility with existing
48837e29 1043 compilers for the H8/300.
07aae5c2
SC
1044
1045 pragma saveall generates prolog/epilog code which saves and
1046 restores all the registers on function entry.
48837e29 1047
07aae5c2
SC
1048 pragma interrupt saves and restores all registers, and exits with
1049 an rte instruction rather than an rts. A pointer to a function
1050 with this attribute may be safely used in an interrupt vector. */
48837e29 1051
8b97c5f8
ZW
1052void
1053h8300_pr_interrupt (pfile)
1054 cpp_reader *pfile ATTRIBUTE_UNUSED;
07aae5c2 1055{
8b97c5f8
ZW
1056 interrupt_handler = 1;
1057}
05a81fe5 1058
8b97c5f8
ZW
1059void
1060h8300_pr_saveall (pfile)
1061 cpp_reader *pfile ATTRIBUTE_UNUSED;
1062{
1063 pragma_saveall = 1;
07aae5c2 1064}
8b97c5f8 1065
64bead4c
KH
1066/* If the next function argument with MODE and TYPE is to be passed in
1067 a register, return a reg RTX for the hard register in which to pass
1068 the argument. CUM represents the state after the last argument.
1069 If the argument is to be pushed, NULL_RTX is returned. */
48837e29 1070
07aae5c2
SC
1071rtx
1072function_arg (cum, mode, type, named)
1073 CUMULATIVE_ARGS *cum;
1074 enum machine_mode mode;
1075 tree type;
1076 int named;
1077{
0ea6f6a0
KH
1078 static const char *const hand_list[] = {
1079 "__main",
1080 "__cmpsi2",
1081 "__divhi3",
1082 "__modhi3",
1083 "__udivhi3",
1084 "__umodhi3",
1085 "__divsi3",
1086 "__modsi3",
1087 "__udivsi3",
1088 "__umodsi3",
1089 "__mulhi3",
1090 "__mulsi3",
1091 "__reg_memcpy",
1092 "__reg_memset",
1093 "__ucmpsi2",
1094 0,
1095 };
1096
7192cbf1 1097 rtx result = NULL_RTX;
441d04c6 1098 const char *fname;
48837e29
DE
1099 int regpass = 0;
1100
dd07092e
JL
1101 /* Never pass unnamed arguments in registers. */
1102 if (!named)
7192cbf1 1103 return NULL_RTX;
dd07092e 1104
48837e29
DE
1105 /* Pass 3 regs worth of data in regs when user asked on the command line. */
1106 if (TARGET_QUICKCALL)
1107 regpass = 3;
1108
1109 /* If calling hand written assembler, use 4 regs of args. */
48837e29
DE
1110 if (cum->libcall)
1111 {
441d04c6 1112 const char * const *p;
48837e29
DE
1113
1114 fname = XSTR (cum->libcall, 0);
1115
1116 /* See if this libcall is one of the hand coded ones. */
48837e29
DE
1117 for (p = hand_list; *p && strcmp (*p, fname) != 0; p++)
1118 ;
07aae5c2 1119
48837e29
DE
1120 if (*p)
1121 regpass = 4;
1122 }
1123
1124 if (regpass)
1125 {
1126 int size;
1127
1128 if (mode == BLKmode)
1129 size = int_size_in_bytes (type);
1130 else
1131 size = GET_MODE_SIZE (mode);
1132
15e0e275
KH
1133 if (size + cum->nbytes <= regpass * UNITS_PER_WORD
1134 && cum->nbytes / UNITS_PER_WORD <= 3)
1135 result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
48837e29 1136 }
07aae5c2 1137
48837e29
DE
1138 return result;
1139}
1140\f
1141/* Return the cost of the rtx R with code CODE. */
07aae5c2 1142
48837e29 1143int
037f11ef 1144const_costs (r, c, outer_code)
48837e29
DE
1145 rtx r;
1146 enum rtx_code c;
037f11ef 1147 enum rtx_code outer_code;
48837e29
DE
1148{
1149 switch (c)
07aae5c2 1150 {
48837e29
DE
1151 case CONST_INT:
1152 switch (INTVAL (r))
07aae5c2
SC
1153 {
1154 case 0:
037f11ef 1155 return 0;
48837e29 1156 case 1:
07aae5c2 1157 case 2:
48837e29
DE
1158 case -1:
1159 case -2:
037f11ef 1160 return 0 + (outer_code == SET);
5ae5999c
JL
1161 case 4:
1162 case -4:
a1616dd9 1163 if (TARGET_H8300H || TARGET_H8300S)
037f11ef 1164 return 0 + (outer_code == SET);
5ae5999c
JL
1165 else
1166 return 1;
48837e29
DE
1167 default:
1168 return 1;
07aae5c2 1169 }
48837e29
DE
1170
1171 case CONST:
1172 case LABEL_REF:
1173 case SYMBOL_REF:
1174 return 3;
1175
1176 case CONST_DOUBLE:
1177 return 20;
1178
1179 default:
1180 return 4;
07aae5c2 1181 }
07aae5c2 1182}
ae557002 1183
73cc75e9
KH
1184int
1185h8300_and_costs (x)
1186 rtx x;
1187{
1188 rtx operands[4];
1189
1190 if (GET_MODE (x) == QImode)
1191 return 1;
1192
1193 if (GET_MODE (x) != HImode
1194 && GET_MODE (x) != SImode)
1195 return 100;
1196
1197 operands[0] = NULL;
1198 operands[1] = NULL;
1199 operands[2] = XEXP (x, 1);
1200 operands[3] = x;
1201 return compute_logical_op_length (GET_MODE (x), operands);
1202}
1203
ae557002
KH
1204int
1205h8300_shift_costs (x)
1206 rtx x;
1207{
1208 rtx operands[4];
1209
1210 if (GET_MODE (x) != QImode
1211 && GET_MODE (x) != HImode
1212 && GET_MODE (x) != SImode)
1213 return 100;
1214
1215 operands[0] = NULL;
1216 operands[1] = NULL;
1217 operands[2] = XEXP (x, 1);
1218 operands[3] = x;
1219 return compute_a_shift_length (NULL, operands);
1220}
48837e29 1221\f
07aae5c2
SC
1222/* Documentation for the machine specific operand escapes:
1223
48837e29
DE
1224 'E' like s but negative.
1225 'F' like t but negative.
1226 'G' constant just the negative
15dc331e
JL
1227 'R' print operand as a byte:8 address if appropriate, else fall back to
1228 'X' handling.
48837e29 1229 'S' print operand as a long word
07aae5c2 1230 'T' print operand as a word
48837e29
DE
1231 'V' find the set bit, and print its number.
1232 'W' find the clear bit, and print its number.
1233 'X' print operand as a byte
07aae5c2 1234 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
15dc331e 1235 If this operand isn't a register, fall back to 'R' handling.
48837e29
DE
1236 'Z' print int & 7.
1237 'b' print the bit opcode
48837e29
DE
1238 'e' first word of 32 bit value - if reg, then least reg. if mem
1239 then least. if const then most sig word
1240 'f' second word of 32 bit value - if reg, then biggest reg. if mem
1241 then +2. if const then least sig word
07aae5c2
SC
1242 'j' print operand as condition code.
1243 'k' print operand as reverse condition code.
48837e29
DE
1244 's' print as low byte of 16 bit value
1245 't' print as high byte of 16 bit value
1246 'w' print as low byte of 32 bit value
1247 'x' print as 2nd byte of 32 bit value
1248 'y' print as 3rd byte of 32 bit value
1249 'z' print as msb of 32 bit value
1250*/
07aae5c2
SC
1251
1252/* Return assembly language string which identifies a comparison type. */
1253
441d04c6 1254static const char *
07aae5c2
SC
1255cond_string (code)
1256 enum rtx_code code;
1257{
1258 switch (code)
1259 {
1260 case NE:
1261 return "ne";
1262 case EQ:
1263 return "eq";
1264 case GE:
1265 return "ge";
1266 case GT:
1267 return "gt";
1268 case LE:
1269 return "le";
1270 case LT:
1271 return "lt";
1272 case GEU:
1273 return "hs";
1274 case GTU:
1275 return "hi";
1276 case LEU:
1277 return "ls";
1278 case LTU:
1279 return "lo";
1280 default:
1281 abort ();
1282 }
1283}
1284
1285/* Print operand X using operand code CODE to assembly language output file
1286 FILE. */
1287
1288void
1289print_operand (file, x, code)
1290 FILE *file;
1291 rtx x;
1292 int code;
1293{
269c14e1 1294 /* This is used for communication between codes V,W,Z and Y. */
07aae5c2
SC
1295 static int bitint;
1296
1297 switch (code)
1298 {
48837e29
DE
1299 case 'E':
1300 switch (GET_CODE (x))
1301 {
1302 case REG:
1303 fprintf (file, "%sl", names_big[REGNO (x)]);
1304 break;
1305 case CONST_INT:
b47900aa 1306 fprintf (file, "#%ld", (-INTVAL (x)) & 0xff);
48837e29
DE
1307 break;
1308 default:
1309 abort ();
1310 }
1311 break;
1312 case 'F':
1313 switch (GET_CODE (x))
1314 {
1315 case REG:
1316 fprintf (file, "%sh", names_big[REGNO (x)]);
1317 break;
1318 case CONST_INT:
b47900aa 1319 fprintf (file, "#%ld", ((-INTVAL (x)) & 0xff00) >> 8);
48837e29
DE
1320 break;
1321 default:
1322 abort ();
1323 }
1324 break;
07aae5c2
SC
1325 case 'G':
1326 if (GET_CODE (x) != CONST_INT)
1327 abort ();
b47900aa 1328 fprintf (file, "#%ld", 0xff & (-INTVAL (x)));
07aae5c2 1329 break;
48837e29
DE
1330 case 'S':
1331 if (GET_CODE (x) == REG)
1332 fprintf (file, "%s", names_extended[REGNO (x)]);
07aae5c2 1333 else
48837e29 1334 goto def;
07aae5c2 1335 break;
48837e29
DE
1336 case 'T':
1337 if (GET_CODE (x) == REG)
1338 fprintf (file, "%s", names_big[REGNO (x)]);
07aae5c2 1339 else
48837e29 1340 goto def;
07aae5c2 1341 break;
48837e29 1342 case 'V':
4d4d89e2 1343 bitint = exact_log2 (INTVAL (x) & 0xff);
48837e29 1344 if (bitint == -1)
07aae5c2 1345 abort ();
4d4d89e2 1346 fprintf (file, "#%d", bitint);
07aae5c2 1347 break;
48837e29 1348 case 'W':
07aae5c2
SC
1349 bitint = exact_log2 ((~INTVAL (x)) & 0xff);
1350 if (bitint == -1)
1351 abort ();
4d4d89e2 1352 fprintf (file, "#%d", bitint);
07aae5c2 1353 break;
15dc331e 1354 case 'R':
48837e29
DE
1355 case 'X':
1356 if (GET_CODE (x) == REG)
1357 fprintf (file, "%s", byte_reg (x, 0));
1358 else
1359 goto def;
1360 break;
1361 case 'Y':
07aae5c2
SC
1362 if (bitint == -1)
1363 abort ();
48837e29
DE
1364 if (GET_CODE (x) == REG)
1365 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
1366 else
15dc331e 1367 print_operand (file, x, 'R');
48837e29
DE
1368 bitint = -1;
1369 break;
1370 case 'Z':
1371 bitint = INTVAL (x);
07aae5c2
SC
1372 fprintf (file, "#%d", bitint & 7);
1373 break;
48837e29
DE
1374 case 'b':
1375 switch (GET_CODE (x))
07aae5c2 1376 {
48837e29
DE
1377 case IOR:
1378 fprintf (file, "bor");
1379 break;
1380 case XOR:
1381 fprintf (file, "bxor");
1382 break;
1383 case AND:
1384 fprintf (file, "band");
1385 break;
441d04c6
KG
1386 default:
1387 break;
07aae5c2 1388 }
48837e29 1389 break;
07aae5c2
SC
1390 case 'e':
1391 switch (GET_CODE (x))
1392 {
1393 case REG:
48837e29
DE
1394 if (TARGET_H8300)
1395 fprintf (file, "%s", names_big[REGNO (x)]);
1396 else
1397 fprintf (file, "%s", names_upper_extended[REGNO (x)]);
07aae5c2
SC
1398 break;
1399 case MEM:
07aae5c2
SC
1400 print_operand (file, x, 0);
1401 break;
1402 case CONST_INT:
b47900aa 1403 fprintf (file, "#%ld", ((INTVAL (x) >> 16) & 0xffff));
07aae5c2 1404 break;
808fbfac
JL
1405 case CONST_DOUBLE:
1406 {
1407 long val;
1408 REAL_VALUE_TYPE rv;
1409 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1410 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
441d04c6 1411 fprintf (file, "#%ld", ((val >> 16) & 0xffff));
808fbfac
JL
1412 break;
1413 }
07aae5c2
SC
1414 default:
1415 abort ();
1416 break;
1417 }
1418 break;
07aae5c2
SC
1419 case 'f':
1420 switch (GET_CODE (x))
1421 {
1422 case REG:
48837e29
DE
1423 if (TARGET_H8300)
1424 fprintf (file, "%s", names_big[REGNO (x) + 1]);
1425 else
1426 fprintf (file, "%s", names_big[REGNO (x)]);
07aae5c2 1427 break;
07aae5c2 1428 case MEM:
b72f00af 1429 x = adjust_address (x, HImode, 2);
07aae5c2
SC
1430 print_operand (file, x, 0);
1431 break;
07aae5c2 1432 case CONST_INT:
b47900aa 1433 fprintf (file, "#%ld", INTVAL (x) & 0xffff);
07aae5c2 1434 break;
808fbfac
JL
1435 case CONST_DOUBLE:
1436 {
1437 long val;
1438 REAL_VALUE_TYPE rv;
1439 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1440 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
441d04c6 1441 fprintf (file, "#%ld", (val & 0xffff));
808fbfac
JL
1442 break;
1443 }
07aae5c2
SC
1444 default:
1445 abort ();
1446 }
1447 break;
07aae5c2 1448 case 'j':
761c70aa 1449 fputs (cond_string (GET_CODE (x)), file);
07aae5c2 1450 break;
07aae5c2 1451 case 'k':
761c70aa 1452 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
07aae5c2 1453 break;
48837e29
DE
1454 case 's':
1455 if (GET_CODE (x) == CONST_INT)
b47900aa 1456 fprintf (file, "#%ld", (INTVAL (x)) & 0xff);
48837e29
DE
1457 else
1458 fprintf (file, "%s", byte_reg (x, 0));
1459 break;
1460 case 't':
1461 if (GET_CODE (x) == CONST_INT)
b47900aa 1462 fprintf (file, "#%ld", (INTVAL (x) >> 8) & 0xff);
48837e29
DE
1463 else
1464 fprintf (file, "%s", byte_reg (x, 1));
1465 break;
1466 case 'u':
1467 if (GET_CODE (x) != CONST_INT)
1468 abort ();
b47900aa 1469 fprintf (file, "%ld", INTVAL (x));
48837e29
DE
1470 break;
1471 case 'w':
1472 if (GET_CODE (x) == CONST_INT)
b47900aa 1473 fprintf (file, "#%ld", INTVAL (x) & 0xff);
48837e29 1474 else
a1616dd9
JL
1475 fprintf (file, "%s",
1476 byte_reg (x, TARGET_H8300 ? 2 : 0));
48837e29
DE
1477 break;
1478 case 'x':
1479 if (GET_CODE (x) == CONST_INT)
b47900aa 1480 fprintf (file, "#%ld", (INTVAL (x) >> 8) & 0xff);
48837e29 1481 else
a1616dd9
JL
1482 fprintf (file, "%s",
1483 byte_reg (x, TARGET_H8300 ? 3 : 1));
48837e29
DE
1484 break;
1485 case 'y':
1486 if (GET_CODE (x) == CONST_INT)
b47900aa 1487 fprintf (file, "#%ld", (INTVAL (x) >> 16) & 0xff);
48837e29
DE
1488 else
1489 fprintf (file, "%s", byte_reg (x, 0));
1490 break;
1491 case 'z':
1492 if (GET_CODE (x) == CONST_INT)
b47900aa 1493 fprintf (file, "#%ld", (INTVAL (x) >> 24) & 0xff);
48837e29
DE
1494 else
1495 fprintf (file, "%s", byte_reg (x, 1));
1496 break;
1497
07aae5c2 1498 default:
48837e29 1499 def:
07aae5c2
SC
1500 switch (GET_CODE (x))
1501 {
1502 case REG:
48837e29
DE
1503 switch (GET_MODE (x))
1504 {
1505 case QImode:
269c14e1 1506#if 0 /* Is it asm ("mov.b %0,r2l", ...) */
48837e29
DE
1507 fprintf (file, "%s", byte_reg (x, 0));
1508#else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1509 fprintf (file, "%s", names_big[REGNO (x)]);
1510#endif
1511 break;
1512 case HImode:
1513 fprintf (file, "%s", names_big[REGNO (x)]);
1514 break;
1515 case SImode:
8977e8a7 1516 case SFmode:
48837e29
DE
1517 fprintf (file, "%s", names_extended[REGNO (x)]);
1518 break;
1519 default:
1520 abort ();
1521 }
07aae5c2
SC
1522 break;
1523
1524 case MEM:
87e4ee91
KH
1525 {
1526 rtx addr = XEXP (x, 0);
1527
1528 fprintf (file, "@");
1529 output_address (addr);
1530
bc8db8a1
KH
1531 /* We fall back from smaller addressing to larger
1532 addressing in various ways depending on CODE. */
1533 switch (code)
1534 {
1535 case 'R':
1536 /* Used for mov.b and bit operations. */
7c143ed2 1537 if (h8300_eightbit_constant_address_p (addr))
bc8db8a1
KH
1538 {
1539 fprintf (file, ":8");
1540 break;
1541 }
1542
1543 /* Fall through. We should not get here if we are
1544 processing bit operations on H8/300 or H8/300H
1545 because 'U' constraint does not allow bit
1546 operations on the tiny area on these machines. */
1547
1548 case 'T':
1549 case 'S':
1550 /* Used for mov.w and mov.l. */
56b8e164 1551 if (h8300_tiny_constant_address_p (addr))
bc8db8a1
KH
1552 fprintf (file, ":16");
1553 break;
1554 default:
1555 break;
1556 }
87e4ee91 1557 }
07aae5c2
SC
1558 break;
1559
1560 case CONST_INT:
1561 case SYMBOL_REF:
1562 case CONST:
1563 case LABEL_REF:
1564 fprintf (file, "#");
1565 print_operand_address (file, x);
1566 break;
808fbfac
JL
1567 case CONST_DOUBLE:
1568 {
1569 long val;
1570 REAL_VALUE_TYPE rv;
1571 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1572 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
441d04c6 1573 fprintf (file, "#%ld", val);
808fbfac
JL
1574 break;
1575 }
441d04c6
KG
1576 default:
1577 break;
07aae5c2
SC
1578 }
1579 }
1580}
1581
1582/* Output assembly language output for the address ADDR to FILE. */
1583
1584void
1585print_operand_address (file, addr)
1586 FILE *file;
1587 rtx addr;
1588{
1589 switch (GET_CODE (addr))
1590 {
1591 case REG:
48837e29 1592 fprintf (file, "%s", h8_reg_names[REGNO (addr)]);
07aae5c2
SC
1593 break;
1594
1595 case PRE_DEC:
48837e29 1596 fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
07aae5c2
SC
1597 break;
1598
1599 case POST_INC:
48837e29 1600 fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);
07aae5c2
SC
1601 break;
1602
1603 case PLUS:
1604 fprintf (file, "(");
1605 if (GET_CODE (XEXP (addr, 0)) == REG)
1606 {
1607 /* reg,foo */
1608 print_operand_address (file, XEXP (addr, 1));
1609 fprintf (file, ",");
1610 print_operand_address (file, XEXP (addr, 0));
1611 }
1612 else
1613 {
1614 /* foo+k */
1615 print_operand_address (file, XEXP (addr, 0));
1616 fprintf (file, "+");
1617 print_operand_address (file, XEXP (addr, 1));
1618 }
1619 fprintf (file, ")");
1620 break;
1621
1622 case CONST_INT:
48837e29 1623 {
64530b82 1624 /* Since the H8/300 only has 16 bit pointers, negative values are also
48837e29
DE
1625 those >= 32768. This happens for example with pointer minus a
1626 constant. We don't want to turn (char *p - 2) into
1627 (char *p + 65534) because loop unrolling can build upon this
1628 (IE: char *p + 131068). */
1629 int n = INTVAL (addr);
1630 if (TARGET_H8300)
1631 n = (int) (short) n;
1632 if (n < 0)
07e4d94e 1633 /* ??? Why the special case for -ve values? */
48837e29
DE
1634 fprintf (file, "-%d", -n);
1635 else
1636 fprintf (file, "%d", n);
1637 break;
1638 }
07aae5c2
SC
1639
1640 default:
1641 output_addr_const (file, addr);
1642 break;
1643 }
1644}
1645\f
07aae5c2
SC
1646/* Output all insn addresses and their sizes into the assembly language
1647 output file. This is helpful for debugging whether the length attributes
1648 in the md file are correct. This is not meant to be a user selectable
1649 option. */
1650
1651void
1652final_prescan_insn (insn, operand, num_operands)
441d04c6
KG
1653 rtx insn, *operand ATTRIBUTE_UNUSED;
1654 int num_operands ATTRIBUTE_UNUSED;
07aae5c2
SC
1655{
1656 /* This holds the last insn address. */
1657 static int last_insn_address = 0;
1658
1659 int uid = INSN_UID (insn);
1660
48837e29
DE
1661 if (TARGET_RTL_DUMP)
1662 {
1663 fprintf (asm_out_file, "\n****************");
1664 print_rtl (asm_out_file, PATTERN (insn));
1665 fprintf (asm_out_file, "\n");
1666 }
1667
07aae5c2
SC
1668 if (TARGET_ADDRESSES)
1669 {
9d98a694
AO
1670 fprintf (asm_out_file, "; 0x%x %d\n", INSN_ADDRESSES (uid),
1671 INSN_ADDRESSES (uid) - last_insn_address);
1672 last_insn_address = INSN_ADDRESSES (uid);
07aae5c2
SC
1673 }
1674}
1675
48837e29
DE
1676/* Prepare for an SI sized move. */
1677
1678int
1679do_movsi (operands)
1680 rtx operands[];
07aae5c2 1681{
48837e29
DE
1682 rtx src = operands[1];
1683 rtx dst = operands[0];
1684 if (!reload_in_progress && !reload_completed)
1685 {
1686 if (!register_operand (dst, GET_MODE (dst)))
1687 {
1688 rtx tmp = gen_reg_rtx (GET_MODE (dst));
1689 emit_move_insn (tmp, src);
1690 operands[1] = tmp;
1691 }
1692 }
1693 return 0;
1694}
1695
1696/* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
07e4d94e
KH
1697 Define the offset between two registers, one to be eliminated, and
1698 the other its replacement, at the start of a routine. */
07aae5c2 1699
48837e29 1700int
d7af42bc 1701h8300_initial_elimination_offset (from, to)
441d04c6 1702 int from, to;
48837e29
DE
1703{
1704 int offset = 0;
1705
1706 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1707 offset = UNITS_PER_WORD + frame_pointer_needed * UNITS_PER_WORD;
1aae372e
JL
1708 else if (from == RETURN_ADDRESS_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1709 offset = frame_pointer_needed * UNITS_PER_WORD;
48837e29 1710 else
07aae5c2 1711 {
48837e29
DE
1712 int regno;
1713
1714 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
d01d2903 1715 if (WORD_REG_USED (regno))
48837e29
DE
1716 offset += UNITS_PER_WORD;
1717
1718 /* See the comments for get_frame_size. We need to round it up to
1719 STACK_BOUNDARY. */
1720
1a86c850 1721 offset += round_frame_size (get_frame_size ());
48837e29
DE
1722
1723 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1724 offset += UNITS_PER_WORD; /* Skip saved PC */
1725 }
39ba95b5
VK
1726
1727 if ((TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE)
1728 offset -= 2;
1729
48837e29
DE
1730 return offset;
1731}
1732
1aae372e
JL
1733rtx
1734h8300_return_addr_rtx (count, frame)
1735 int count;
1736 rtx frame;
1737{
1738 rtx ret;
1739
1740 if (count == 0)
1741 ret = gen_rtx_MEM (Pmode,
1742 gen_rtx_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM));
1743 else if (flag_omit_frame_pointer)
1744 return (rtx) 0;
1745 else
1746 ret = gen_rtx_MEM (Pmode,
1747 memory_address (Pmode,
1748 plus_constant (frame, UNITS_PER_WORD)));
1749 set_mem_alias_set (ret, get_frame_alias_set ());
1750 return ret;
1751}
1752
48837e29
DE
1753/* Update the condition code from the insn. */
1754
441d04c6 1755void
48837e29
DE
1756notice_update_cc (body, insn)
1757 rtx body;
1758 rtx insn;
1759{
1760 switch (get_attr_cc (insn))
1761 {
1762 case CC_NONE:
269c14e1 1763 /* Insn does not affect CC at all. */
48837e29
DE
1764 break;
1765
1766 case CC_NONE_0HIT:
269c14e1 1767 /* Insn does not change CC, but the 0'th operand has been changed. */
48837e29 1768 if (cc_status.value1 != 0
1ccbefce 1769 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
48837e29 1770 cc_status.value1 = 0;
d4d6d0ce
KH
1771 if (cc_status.value2 != 0
1772 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value2))
1773 cc_status.value2 = 0;
48837e29
DE
1774 break;
1775
065bbfe6 1776 case CC_SET_ZN:
1ccbefce 1777 /* Insn sets the Z,N flags of CC to recog_data.operand[0].
269c14e1
DE
1778 The V flag is unusable. The C flag may or may not be known but
1779 that's ok because alter_cond will change tests to use EQ/NE. */
48837e29 1780 CC_STATUS_INIT;
269c14e1 1781 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
1ccbefce 1782 cc_status.value1 = recog_data.operand[0];
48837e29
DE
1783 break;
1784
065bbfe6 1785 case CC_SET_ZNV:
1ccbefce 1786 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
065bbfe6
JL
1787 The C flag may or may not be known but that's ok because
1788 alter_cond will change tests to use EQ/NE. */
1789 CC_STATUS_INIT;
1790 cc_status.flags |= CC_NO_CARRY;
1ccbefce 1791 cc_status.value1 = recog_data.operand[0];
d4d6d0ce
KH
1792 if (GET_CODE (body) == SET && REG_P (SET_SRC (body)))
1793 cc_status.value2 = SET_SRC (body);
065bbfe6
JL
1794 break;
1795
269c14e1
DE
1796 case CC_COMPARE:
1797 /* The insn is a compare instruction. */
48837e29 1798 CC_STATUS_INIT;
269c14e1 1799 cc_status.value1 = SET_SRC (body);
48837e29
DE
1800 break;
1801
48837e29 1802 case CC_CLOBBER:
269c14e1 1803 /* Insn doesn't leave CC in a usable state. */
48837e29
DE
1804 CC_STATUS_INIT;
1805 break;
07aae5c2 1806 }
48837e29
DE
1807}
1808
f9d2de4d
KH
1809/* Return nonzero if X is a constant suitable for inc/dec. */
1810
1811int
1812incdec_operand (x, mode)
1813 rtx x;
1814 enum machine_mode mode ATTRIBUTE_UNUSED;
1815{
1816 return (GET_CODE (x) == CONST_INT
1817 && (CONST_OK_FOR_M (INTVAL (x))
1818 || CONST_OK_FOR_O (INTVAL (x))));
1819}
1820
1821/* Return nonzero if X is either EQ or NE. */
1822
1823int
1824eqne_operator (x, mode)
1825 rtx x;
1826 enum machine_mode mode ATTRIBUTE_UNUSED;
1827{
1828 enum rtx_code code = GET_CODE (x);
1829
1830 return (code == EQ || code == NE);
1831}
1832
07e4d94e 1833/* Recognize valid operators for bit instructions. */
48837e29
DE
1834
1835int
1836bit_operator (x, mode)
1837 rtx x;
441d04c6 1838 enum machine_mode mode ATTRIBUTE_UNUSED;
48837e29
DE
1839{
1840 enum rtx_code code = GET_CODE (x);
07aae5c2 1841
48837e29
DE
1842 return (code == XOR
1843 || code == AND
1844 || code == IOR);
07aae5c2 1845}
48837e29 1846\f
366a7b27 1847const char *
b42cff6b 1848output_logical_op (mode, operands)
366a7b27 1849 enum machine_mode mode;
366a7b27
KH
1850 rtx *operands;
1851{
b42cff6b
KH
1852 /* Figure out the logical op that we need to perform. */
1853 enum rtx_code code = GET_CODE (operands[3]);
366a7b27
KH
1854 /* Pretend that every byte is affected if both operands are registers. */
1855 unsigned HOST_WIDE_INT intval =
1856 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
1857 ? INTVAL (operands[2]) : 0x55555555);
1858 /* The determinant of the algorithm. If we perform an AND, 0
1859 affects a bit. Otherwise, 1 affects a bit. */
1860 unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
1861 /* The name of an insn. */
1862 const char *opname;
1863 char insn_buf[100];
1864
1865 switch (code)
1866 {
1867 case AND:
1868 opname = "and";
1869 break;
1870 case IOR:
1871 opname = "or";
1872 break;
1873 case XOR:
1874 opname = "xor";
1875 break;
1876 default:
1877 abort ();
1878 }
1879
1880 switch (mode)
1881 {
1882 case HImode:
1883 /* First, see if we can finish with one insn. */
1884 if ((TARGET_H8300H || TARGET_H8300S)
1885 && ((det & 0x00ff) != 0)
1886 && ((det & 0xff00) != 0))
1887 {
1888 sprintf (insn_buf, "%s.w\t%%T2,%%T0", opname);
1889 output_asm_insn (insn_buf, operands);
1890 }
1891 else
1892 {
1893 /* Take care of the lower byte. */
1894 if ((det & 0x00ff) != 0)
1895 {
1896 sprintf (insn_buf, "%s\t%%s2,%%s0", opname);
1897 output_asm_insn (insn_buf, operands);
1898 }
1899 /* Take care of the upper byte. */
1900 if ((det & 0xff00) != 0)
1901 {
1902 sprintf (insn_buf, "%s\t%%t2,%%t0", opname);
1903 output_asm_insn (insn_buf, operands);
1904 }
1905 }
1906 break;
1907 case SImode:
1908 /* First, see if we can finish with one insn.
1909
1910 If code is either AND or XOR, we exclude two special cases,
187462ac 1911 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
366a7b27
KH
1912 can do a better job. */
1913 if ((TARGET_H8300H || TARGET_H8300S)
1914 && ((det & 0x0000ffff) != 0)
1915 && ((det & 0xffff0000) != 0)
1916 && (code == IOR || det != 0xffffff00)
1917 && (code == IOR || det != 0xffff00ff))
1918 {
1919 sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname);
1920 output_asm_insn (insn_buf, operands);
1921 }
1922 else
1923 {
1924 /* Take care of the lower and upper words individually. For
1925 each word, we try different methods in the order of
1926
1927 1) the special insn (in case of AND or XOR),
1928 2) the word-wise insn, and
1929 3) The byte-wise insn. */
6dfa4005
KH
1930 if ((det & 0x0000ffff) == 0x0000ffff
1931 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
366a7b27 1932 output_asm_insn ((code == AND)
187462ac 1933 ? "sub.w\t%f0,%f0" : "not.w\t%f0",
366a7b27
KH
1934 operands);
1935 else if ((TARGET_H8300H || TARGET_H8300S)
1936 && ((det & 0x000000ff) != 0)
1937 && ((det & 0x0000ff00) != 0))
1938 {
1939 sprintf (insn_buf, "%s.w\t%%f2,%%f0", opname);
1940 output_asm_insn (insn_buf, operands);
1941 }
1942 else
1943 {
1944 if ((det & 0x000000ff) != 0)
1945 {
1946 sprintf (insn_buf, "%s\t%%w2,%%w0", opname);
1947 output_asm_insn (insn_buf, operands);
1948 }
1949 if ((det & 0x0000ff00) != 0)
1950 {
1951 sprintf (insn_buf, "%s\t%%x2,%%x0", opname);
1952 output_asm_insn (insn_buf, operands);
1953 }
1954 }
1955
6dfa4005
KH
1956 if ((det & 0xffff0000) == 0xffff0000
1957 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
366a7b27 1958 output_asm_insn ((code == AND)
187462ac 1959 ? "sub.w\t%e0,%e0" : "not.w\t%e0",
366a7b27
KH
1960 operands);
1961 else if (TARGET_H8300H || TARGET_H8300S)
1962 {
1963 if ((det & 0xffff0000) != 0)
1964 {
1965 sprintf (insn_buf, "%s.w\t%%e2,%%e0", opname);
1966 output_asm_insn (insn_buf, operands);
1967 }
1968 }
1969 else
1970 {
1971 if ((det & 0x00ff0000) != 0)
1972 {
1973 sprintf (insn_buf, "%s\t%%y2,%%y0", opname);
1974 output_asm_insn (insn_buf, operands);
1975 }
1976 if ((det & 0xff000000) != 0)
1977 {
1978 sprintf (insn_buf, "%s\t%%z2,%%z0", opname);
1979 output_asm_insn (insn_buf, operands);
1980 }
1981 }
1982 }
1983 break;
1984 default:
1985 abort ();
1986 }
1987 return "";
1988}
40367e2d
KH
1989
1990unsigned int
b42cff6b 1991compute_logical_op_length (mode, operands)
40367e2d 1992 enum machine_mode mode;
40367e2d
KH
1993 rtx *operands;
1994{
b42cff6b
KH
1995 /* Figure out the logical op that we need to perform. */
1996 enum rtx_code code = GET_CODE (operands[3]);
40367e2d
KH
1997 /* Pretend that every byte is affected if both operands are registers. */
1998 unsigned HOST_WIDE_INT intval =
1999 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
2000 ? INTVAL (operands[2]) : 0x55555555);
2001 /* The determinant of the algorithm. If we perform an AND, 0
2002 affects a bit. Otherwise, 1 affects a bit. */
2003 unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
2004 /* Insn length. */
2005 unsigned int length = 0;
2006
2007 switch (mode)
2008 {
2009 case HImode:
2010 /* First, see if we can finish with one insn. */
2011 if ((TARGET_H8300H || TARGET_H8300S)
2012 && ((det & 0x00ff) != 0)
2013 && ((det & 0xff00) != 0))
2014 {
2015 if (REG_P (operands[2]))
2016 length += 2;
2017 else
2018 length += 4;
2019 }
2020 else
2021 {
2022 /* Take care of the lower byte. */
2023 if ((det & 0x00ff) != 0)
2024 length += 2;
2025
2026 /* Take care of the upper byte. */
2027 if ((det & 0xff00) != 0)
2028 length += 2;
2029 }
2030 break;
2031 case SImode:
2032 /* First, see if we can finish with one insn.
2033
2034 If code is either AND or XOR, we exclude two special cases,
2035 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
2036 can do a better job. */
2037 if ((TARGET_H8300H || TARGET_H8300S)
2038 && ((det & 0x0000ffff) != 0)
2039 && ((det & 0xffff0000) != 0)
2040 && (code == IOR || det != 0xffffff00)
2041 && (code == IOR || det != 0xffff00ff))
2042 {
2043 if (REG_P (operands[2]))
2044 length += 4;
2045 else
2046 length += 6;
2047 }
2048 else
2049 {
2050 /* Take care of the lower and upper words individually. For
2051 each word, we try different methods in the order of
2052
2053 1) the special insn (in case of AND or XOR),
2054 2) the word-wise insn, and
2055 3) The byte-wise insn. */
2056 if ((det & 0x0000ffff) == 0x0000ffff
2057 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
2058 {
2059 length += 2;
2060 }
2061 else if ((TARGET_H8300H || TARGET_H8300S)
2062 && ((det & 0x000000ff) != 0)
2063 && ((det & 0x0000ff00) != 0))
2064 {
2065 length += 4;
2066 }
2067 else
2068 {
2069 if ((det & 0x000000ff) != 0)
2070 length += 2;
2071
2072 if ((det & 0x0000ff00) != 0)
2073 length += 2;
2074 }
2075
2076 if ((det & 0xffff0000) == 0xffff0000
2077 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
2078 {
2079 length += 2;
2080 }
2081 else if (TARGET_H8300H || TARGET_H8300S)
2082 {
2083 if ((det & 0xffff0000) != 0)
2084 length += 4;
2085 }
2086 else
2087 {
2088 if ((det & 0x00ff0000) != 0)
2089 length += 2;
2090
2091 if ((det & 0xff000000) != 0)
2092 length += 2;
2093 }
2094 }
2095 break;
2096 default:
2097 abort ();
2098 }
2099 return length;
2100}
b42cff6b
KH
2101
2102int
2103compute_logical_op_cc (mode, operands)
2104 enum machine_mode mode;
2105 rtx *operands;
2106{
2107 /* Figure out the logical op that we need to perform. */
2108 enum rtx_code code = GET_CODE (operands[3]);
2109 /* Pretend that every byte is affected if both operands are registers. */
2110 unsigned HOST_WIDE_INT intval =
2111 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
2112 ? INTVAL (operands[2]) : 0x55555555);
2113 /* The determinant of the algorithm. If we perform an AND, 0
2114 affects a bit. Otherwise, 1 affects a bit. */
2115 unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
2116 /* Condition code. */
2117 enum attr_cc cc = CC_CLOBBER;
2118
2119 switch (mode)
2120 {
2121 case HImode:
2122 /* First, see if we can finish with one insn. */
2123 if ((TARGET_H8300H || TARGET_H8300S)
2124 && ((det & 0x00ff) != 0)
2125 && ((det & 0xff00) != 0))
2126 {
2127 cc = CC_SET_ZNV;
2128 }
2129 break;
2130 case SImode:
2131 /* First, see if we can finish with one insn.
2132
2133 If code is either AND or XOR, we exclude two special cases,
2134 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
2135 can do a better job. */
2136 if ((TARGET_H8300H || TARGET_H8300S)
2137 && ((det & 0x0000ffff) != 0)
2138 && ((det & 0xffff0000) != 0)
2139 && (code == IOR || det != 0xffffff00)
2140 && (code == IOR || det != 0xffff00ff))
2141 {
2142 cc = CC_SET_ZNV;
2143 }
2144 break;
2145 default:
2146 abort ();
2147 }
2148 return cc;
2149}
366a7b27 2150\f
48837e29
DE
2151/* Shifts.
2152
005e3e05
KH
2153 We devote a fair bit of code to getting efficient shifts since we
2154 can only shift one bit at a time on the H8/300 and H8/300H and only
3db11b5c 2155 one or two bits at a time on the H8S.
005e3e05
KH
2156
2157 All shift code falls into one of the following ways of
2158 implementation:
2159
2160 o SHIFT_INLINE: Emit straight line code for the shift; this is used
2161 when a straight line shift is about the same size or smaller than
2162 a loop.
2163
2164 o SHIFT_ROT_AND: Rotate the value the opposite direction, then mask
2165 off the bits we don't need. This is used when only a few of the
2166 bits in the original value will survive in the shifted value.
2167
2168 o SHIFT_SPECIAL: Often it's possible to move a byte or a word to
2169 simulate a shift by 8, 16, or 24 bits. Once moved, a few inline
2170 shifts can be added if the shift count is slightly more than 8 or
2171 16. This case also includes other oddballs that are not worth
2172 explaning here.
2173
3db11b5c 2174 o SHIFT_LOOP: Emit a loop using one (or two on H8S) bit shifts.
005e3e05 2175
5ec0b66e
KH
2176 For each shift count, we try to use code that has no trade-off
2177 between code size and speed whenever possible.
2178
2179 If the trade-off is unavoidable, we try to be reasonable.
2180 Specifically, the fastest version is one instruction longer than
2181 the shortest version, we take the fastest version. We also provide
2182 the use a way to switch back to the shortest version with -Os.
2183
2184 For the details of the shift algorithms for various shift counts,
2185 refer to shift_alg_[qhs]i. */
07aae5c2
SC
2186
2187int
48837e29
DE
2188nshift_operator (x, mode)
2189 rtx x;
441d04c6 2190 enum machine_mode mode ATTRIBUTE_UNUSED;
48837e29
DE
2191{
2192 switch (GET_CODE (x))
2193 {
2194 case ASHIFTRT:
2195 case LSHIFTRT:
2196 case ASHIFT:
2197 return 1;
2198
2199 default:
2200 return 0;
2201 }
2202}
2203
2204/* Called from the .md file to emit code to do shifts.
64530b82
KH
2205 Return a boolean indicating success.
2206 (Currently this is always TRUE). */
48837e29
DE
2207
2208int
2209expand_a_shift (mode, code, operands)
2210 enum machine_mode mode;
07aae5c2
SC
2211 int code;
2212 rtx operands[];
07aae5c2 2213{
07aae5c2
SC
2214 emit_move_insn (operands[0], operands[1]);
2215
07e4d94e
KH
2216 /* Need a loop to get all the bits we want - we generate the
2217 code at emit time, but need to allocate a scratch reg now. */
48837e29 2218
c5c76735
JL
2219 emit_insn (gen_rtx_PARALLEL
2220 (VOIDmode,
48837e29 2221 gen_rtvec (2,
c5c76735
JL
2222 gen_rtx_SET (VOIDmode, operands[0],
2223 gen_rtx (code, mode, operands[0],
2224 operands[2])),
2225 gen_rtx_CLOBBER (VOIDmode,
2226 gen_rtx_SCRATCH (QImode)))));
48837e29
DE
2227
2228 return 1;
2229}
2230
48837e29
DE
2231/* Symbols of the various modes which can be used as indices. */
2232
2233enum shift_mode
1a63219b
KH
2234{
2235 QIshift, HIshift, SIshift
2236};
48837e29 2237
269c14e1
DE
2238/* For single bit shift insns, record assembler and what bits of the
2239 condition code are valid afterwards (represented as various CC_FOO
2240 bits, 0 means CC isn't left in a usable state). */
48837e29
DE
2241
2242struct shift_insn
2243{
8b60264b
KG
2244 const char *const assembler;
2245 const int cc_valid;
48837e29
DE
2246};
2247
2248/* Assembler instruction shift table.
2249
2250 These tables are used to look up the basic shifts.
07e4d94e 2251 They are indexed by cpu, shift_type, and mode. */
07aae5c2 2252
48837e29
DE
2253static const struct shift_insn shift_one[2][3][3] =
2254{
2255/* H8/300 */
2256 {
2257/* SHIFT_ASHIFT */
2258 {
065bbfe6 2259 { "shll\t%X0", CC_NO_CARRY },
51c0c1d7
JL
2260 { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2261 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }
48837e29
DE
2262 },
2263/* SHIFT_LSHIFTRT */
2264 {
065bbfe6 2265 { "shlr\t%X0", CC_NO_CARRY },
51c0c1d7
JL
2266 { "shlr\t%t0\n\trotxr\t%s0", 0 },
2267 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
48837e29
DE
2268 },
2269/* SHIFT_ASHIFTRT */
2270 {
51c0c1d7
JL
2271 { "shar\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2272 { "shar\t%t0\n\trotxr\t%s0", 0 },
2273 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
48837e29
DE
2274 }
2275 },
2276/* H8/300H */
2277 {
2278/* SHIFT_ASHIFT */
2279 {
065bbfe6
JL
2280 { "shll.b\t%X0", CC_NO_CARRY },
2281 { "shll.w\t%T0", CC_NO_CARRY },
2282 { "shll.l\t%S0", CC_NO_CARRY }
48837e29
DE
2283 },
2284/* SHIFT_LSHIFTRT */
2285 {
065bbfe6
JL
2286 { "shlr.b\t%X0", CC_NO_CARRY },
2287 { "shlr.w\t%T0", CC_NO_CARRY },
2288 { "shlr.l\t%S0", CC_NO_CARRY }
48837e29
DE
2289 },
2290/* SHIFT_ASHIFTRT */
2291 {
51c0c1d7
JL
2292 { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2293 { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2294 { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
48837e29
DE
2295 }
2296 }
2297};
07aae5c2 2298
51c0c1d7
JL
2299static const struct shift_insn shift_two[3][3] =
2300{
2301/* SHIFT_ASHIFT */
2302 {
065bbfe6
JL
2303 { "shll.b\t#2,%X0", CC_NO_CARRY },
2304 { "shll.w\t#2,%T0", CC_NO_CARRY },
2305 { "shll.l\t#2,%S0", CC_NO_CARRY }
51c0c1d7
JL
2306 },
2307/* SHIFT_LSHIFTRT */
2308 {
065bbfe6
JL
2309 { "shlr.b\t#2,%X0", CC_NO_CARRY },
2310 { "shlr.w\t#2,%T0", CC_NO_CARRY },
2311 { "shlr.l\t#2,%S0", CC_NO_CARRY }
51c0c1d7
JL
2312 },
2313/* SHIFT_ASHIFTRT */
2314 {
2315 { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2316 { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2317 { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
2318 }
2319};
2320
48837e29
DE
2321/* Rotates are organized by which shift they'll be used in implementing.
2322 There's no need to record whether the cc is valid afterwards because
2323 it is the AND insn that will decide this. */
07aae5c2 2324
48837e29
DE
2325static const char *const rotate_one[2][3][3] =
2326{
2327/* H8/300 */
2328 {
2329/* SHIFT_ASHIFT */
2330 {
51c0c1d7
JL
2331 "rotr\t%X0",
2332 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
48837e29
DE
2333 0
2334 },
2335/* SHIFT_LSHIFTRT */
2336 {
51c0c1d7
JL
2337 "rotl\t%X0",
2338 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
48837e29
DE
2339 0
2340 },
2341/* SHIFT_ASHIFTRT */
2342 {
51c0c1d7
JL
2343 "rotl\t%X0",
2344 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
48837e29 2345 0
07aae5c2 2346 }
48837e29
DE
2347 },
2348/* H8/300H */
2349 {
2350/* SHIFT_ASHIFT */
2351 {
51c0c1d7
JL
2352 "rotr.b\t%X0",
2353 "rotr.w\t%T0",
2354 "rotr.l\t%S0"
48837e29
DE
2355 },
2356/* SHIFT_LSHIFTRT */
07aae5c2 2357 {
51c0c1d7
JL
2358 "rotl.b\t%X0",
2359 "rotl.w\t%T0",
2360 "rotl.l\t%S0"
48837e29
DE
2361 },
2362/* SHIFT_ASHIFTRT */
2363 {
51c0c1d7
JL
2364 "rotl.b\t%X0",
2365 "rotl.w\t%T0",
2366 "rotl.l\t%S0"
48837e29
DE
2367 }
2368 }
2369};
2370
51c0c1d7
JL
2371static const char *const rotate_two[3][3] =
2372{
2373/* SHIFT_ASHIFT */
2374 {
2375 "rotr.b\t#2,%X0",
2376 "rotr.w\t#2,%T0",
2377 "rotr.l\t#2,%S0"
2378 },
2379/* SHIFT_LSHIFTRT */
2380 {
2381 "rotl.b\t#2,%X0",
2382 "rotl.w\t#2,%T0",
2383 "rotl.l\t#2,%S0"
2384 },
2385/* SHIFT_ASHIFTRT */
2386 {
2387 "rotl.b\t#2,%X0",
2388 "rotl.w\t#2,%T0",
2389 "rotl.l\t#2,%S0"
2390 }
2391};
2392
35fb3d1f
KH
2393struct shift_info {
2394 /* Shift algorithm. */
2395 enum shift_alg alg;
2396
2397 /* The number of bits to be shifted by shift1 and shift2. Valid
2398 when ALG is SHIFT_SPECIAL. */
2399 unsigned int remainder;
2400
2401 /* Special insn for a shift. Valid when ALG is SHIFT_SPECIAL. */
2402 const char *special;
2403
2404 /* Insn for a one-bit shift. Valid when ALG is either SHIFT_INLINE
9cd10576 2405 or SHIFT_SPECIAL, and REMAINDER is nonzero. */
35fb3d1f
KH
2406 const char *shift1;
2407
2408 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
9cd10576 2409 or SHIFT_SPECIAL, and REMAINDER is nonzero. */
35fb3d1f
KH
2410 const char *shift2;
2411
2412 /* Valid CC flags. */
2413 int cc_valid_p;
2414};
2415
cb33eb17 2416static void get_shift_alg PARAMS ((enum shift_type,
769828ab 2417 enum shift_mode, unsigned int,
cb33eb17 2418 struct shift_info *));
441d04c6 2419
c009a745
KH
2420/* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
2421 best algorithm for doing the shift. The assembler code is stored
5ec0b66e
KH
2422 in the pointers in INFO. We achieve the maximum efficiency in most
2423 cases when !TARGET_H8300. In case of TARGET_H8300, shifts in
2424 SImode in particular have a lot of room to optimize.
2425
2426 We first determine the strategy of the shift algorithm by a table
2427 lookup. If that tells us to use a hand crafted assembly code, we
2428 go into the big switch statement to find what that is. Otherwise,
2429 we resort to a generic way, such as inlining. In either case, the
2430 result is returned through INFO. */
48837e29 2431
cb33eb17 2432static void
35fb3d1f 2433get_shift_alg (shift_type, shift_mode, count, info)
48837e29 2434 enum shift_type shift_type;
9789584b 2435 enum shift_mode shift_mode;
769828ab 2436 unsigned int count;
35fb3d1f 2437 struct shift_info *info;
48837e29 2438{
b9b575e6 2439 enum h8_cpu cpu;
769828ab
KH
2440
2441 /* Find the target CPU. */
2442 if (TARGET_H8300)
b9b575e6 2443 cpu = H8_300;
769828ab 2444 else if (TARGET_H8300H)
b9b575e6 2445 cpu = H8_300H;
769828ab 2446 else
b9b575e6 2447 cpu = H8_S;
769828ab 2448
96eaf358 2449 /* Find the shift algorithm. */
b9b575e6 2450 info->alg = SHIFT_LOOP;
48837e29
DE
2451 switch (shift_mode)
2452 {
2453 case QIshift:
b9b575e6 2454 if (count < GET_MODE_BITSIZE (QImode))
96eaf358
KH
2455 info->alg = shift_alg_qi[cpu][shift_type][count];
2456 break;
769828ab 2457
96eaf358 2458 case HIshift:
b9b575e6 2459 if (count < GET_MODE_BITSIZE (HImode))
96eaf358
KH
2460 info->alg = shift_alg_hi[cpu][shift_type][count];
2461 break;
2462
2463 case SIshift:
b9b575e6 2464 if (count < GET_MODE_BITSIZE (SImode))
96eaf358
KH
2465 info->alg = shift_alg_si[cpu][shift_type][count];
2466 break;
2467
2468 default:
2469 abort ();
2470 }
2471
2472 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
2473 switch (info->alg)
2474 {
2475 case SHIFT_INLINE:
2476 info->remainder = count;
2477 /* Fall through. */
2478
2479 case SHIFT_LOOP:
2480 /* It is up to the caller to know that looping clobbers cc. */
2481 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2482 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2483 info->cc_valid_p = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
2484 goto end;
2485
2486 case SHIFT_ROT_AND:
2487 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
2488 info->shift2 = rotate_two[shift_type][shift_mode];
2489 info->cc_valid_p = 0;
2490 goto end;
2491
2492 case SHIFT_SPECIAL:
2493 /* REMAINDER is 0 for most cases, so initialize it to 0. */
2494 info->remainder = 0;
2495 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2496 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2497 info->cc_valid_p = 0;
2498 break;
2499 }
51c0c1d7 2500
96eaf358
KH
2501 /* Here we only deal with SHIFT_SPECIAL. */
2502 switch (shift_mode)
2503 {
2504 case QIshift:
769828ab
KH
2505 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2506 through the entire value. */
2507 if (shift_type == SHIFT_ASHIFTRT && count == 7)
2508 {
2509 info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
692b7eb3 2510 goto end;
769828ab
KH
2511 }
2512 abort ();
2513
2514 case HIshift:
769828ab 2515 if (count == 7)
51c0c1d7 2516 {
a77b1dbc 2517 switch (shift_type)
51c0c1d7 2518 {
a77b1dbc
KH
2519 case SHIFT_ASHIFT:
2520 if (TARGET_H8300)
2521 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";
2522 else
2523 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
692b7eb3 2524 goto end;
a77b1dbc
KH
2525 case SHIFT_LSHIFTRT:
2526 if (TARGET_H8300)
2527 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";
2528 else
2529 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
692b7eb3 2530 goto end;
a77b1dbc 2531 case SHIFT_ASHIFTRT:
35fb3d1f 2532 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
692b7eb3 2533 goto end;
48837e29 2534 }
07aae5c2 2535 }
5e98fba2 2536 else if (8 <= count && count <= 13)
07aae5c2 2537 {
a7812c0b
KH
2538 info->remainder = count - 8;
2539
51c0c1d7 2540 switch (shift_type)
48837e29 2541 {
51c0c1d7 2542 case SHIFT_ASHIFT:
35fb3d1f 2543 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
a7812c0b
KH
2544 info->shift1 = "shal.b\t%t0";
2545 info->shift2 = "shal.b\t#2,%t0";
692b7eb3 2546 goto end;
51c0c1d7 2547 case SHIFT_LSHIFTRT:
35fb3d1f 2548 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
a7812c0b
KH
2549 info->shift1 = "shlr.b\t%s0";
2550 info->shift2 = "shlr.b\t#2,%s0";
692b7eb3 2551 goto end;
51c0c1d7
JL
2552 case SHIFT_ASHIFTRT:
2553 if (TARGET_H8300)
a7812c0b 2554 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
51c0c1d7 2555 else
35fb3d1f 2556 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
a7812c0b
KH
2557 info->shift1 = "shar.b\t%s0";
2558 info->shift2 = "shar.b\t#2,%s0";
692b7eb3 2559 goto end;
51c0c1d7
JL
2560 }
2561 }
5e98fba2
DD
2562 else if (count == 14)
2563 {
2564 switch (shift_type)
2565 {
2566 case SHIFT_ASHIFT:
2567 if (TARGET_H8300)
2568 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";
2569 goto end;
2570 case SHIFT_LSHIFTRT:
2571 if (TARGET_H8300)
2572 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";
2573 goto end;
2574 case SHIFT_ASHIFTRT:
2575 if (TARGET_H8300)
2576 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";
2577 else if (TARGET_H8300H)
2578 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";
2579 else /* TARGET_H8300S */
2580 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.w\t#2,%T0\n\tshar.w\t#2,%T0\n\tshar.w\t#2,%T0";
2581 goto end;
2582 }
2583 }
1e41e866 2584 else if (count == 15)
51c0c1d7 2585 {
1e41e866
KH
2586 switch (shift_type)
2587 {
2588 case SHIFT_ASHIFT:
2589 info->special = "bld\t#0,%s0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#7,%t0";
2590 goto end;
2591 case SHIFT_LSHIFTRT:
2592 info->special = "bld\t#7,%t0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#0,%s0";
2593 goto end;
2594 case SHIFT_ASHIFTRT:
2595 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
2596 goto end;
2597 }
07aae5c2 2598 }
769828ab 2599 abort ();
51c0c1d7 2600
48837e29 2601 case SIshift:
1e41e866 2602 if (TARGET_H8300 && 8 <= count && count <= 9)
48837e29 2603 {
1e41e866
KH
2604 info->remainder = count - 8;
2605
51c0c1d7 2606 switch (shift_type)
48837e29 2607 {
51c0c1d7 2608 case SHIFT_ASHIFT:
35fb3d1f 2609 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";
692b7eb3 2610 goto end;
51c0c1d7 2611 case SHIFT_LSHIFTRT:
35fb3d1f 2612 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";
1e41e866 2613 info->shift1 = "shlr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0";
692b7eb3 2614 goto end;
51c0c1d7 2615 case SHIFT_ASHIFTRT:
35fb3d1f 2616 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";
692b7eb3 2617 goto end;
48837e29 2618 }
48837e29 2619 }
e6bcfef9
JS
2620 else if (count == 8 && !TARGET_H8300)
2621 {
2622 switch (shift_type)
2623 {
2624 case SHIFT_ASHIFT:
35fb3d1f 2625 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";
692b7eb3 2626 goto end;
e6bcfef9 2627 case SHIFT_LSHIFTRT:
35fb3d1f 2628 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";
692b7eb3 2629 goto end;
e6bcfef9 2630 case SHIFT_ASHIFTRT:
35fb3d1f 2631 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";
692b7eb3 2632 goto end;
e6bcfef9
JS
2633 }
2634 }
1e41e866
KH
2635 else if (count == 15 && TARGET_H8300)
2636 {
2637 switch (shift_type)
2638 {
2639 case SHIFT_ASHIFT:
2640 abort ();
2641 case SHIFT_LSHIFTRT:
2642 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,%w0\n\trotxl\t%x0,%x0\n\trotxl\t%y0,%y0";
2643 goto end;
2644 case SHIFT_ASHIFTRT:
2645 info->special = "bld\t#7,%z0\n\tmov.w\t%e0,%f0\n\trotxl\t%w0,%w0\n\trotxl\t%x0,%x0\n\tsubx\t%y0,%y0\n\tsubx\t%z0,%z0";
2646 goto end;
2647 }
2648 }
dd69e230
KH
2649 else if (count == 15 && !TARGET_H8300)
2650 {
2651 switch (shift_type)
2652 {
2653 case SHIFT_ASHIFT:
2654 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
2655 goto end;
2656 case SHIFT_LSHIFTRT:
18cf8dda 2657 info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
dd69e230 2658 goto end;
aefc5826
KH
2659 case SHIFT_ASHIFTRT:
2660 abort ();
dd69e230
KH
2661 }
2662 }
1e41e866 2663 else if ((TARGET_H8300 && 16 <= count && count <= 20)
a7812c0b 2664 || (TARGET_H8300H && 16 <= count && count <= 19)
e0f19bd0 2665 || (TARGET_H8300S && 16 <= count && count <= 21))
48837e29 2666 {
a7812c0b
KH
2667 info->remainder = count - 16;
2668
48837e29
DE
2669 switch (shift_type)
2670 {
2671 case SHIFT_ASHIFT:
35fb3d1f 2672 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
1e41e866
KH
2673 if (TARGET_H8300)
2674 {
2675 info->shift1 = "add.w\t%e0,%e0";
2676 }
2677 else
2678 {
2679 info->shift1 = "shll.l\t%S0";
2680 info->shift2 = "shll.l\t#2,%S0";
2681 }
692b7eb3 2682 goto end;
51c0c1d7 2683 case SHIFT_LSHIFTRT:
35fb3d1f 2684 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
1e41e866
KH
2685 if (TARGET_H8300)
2686 {
2687 info->shift1 = "shlr\t%x0\n\trotxr\t%w0";
2688 }
2689 else
2690 {
2691 info->shift1 = "shlr.l\t%S0";
2692 info->shift2 = "shlr.l\t#2,%S0";
2693 }
692b7eb3 2694 goto end;
51c0c1d7
JL
2695 case SHIFT_ASHIFTRT:
2696 if (TARGET_H8300)
1e41e866
KH
2697 {
2698 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2699 info->shift1 = "shar\t%x0\n\trotxr\t%w0";
2700 }
51c0c1d7 2701 else
1e41e866
KH
2702 {
2703 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
2704 info->shift1 = "shar.l\t%S0";
2705 info->shift2 = "shar.l\t#2,%S0";
2706 }
692b7eb3 2707 goto end;
51c0c1d7
JL
2708 }
2709 }
1e41e866 2710 else if (TARGET_H8300 && 24 <= count && count <= 28)
f9477efd
KH
2711 {
2712 info->remainder = count - 24;
f0b6f9a6 2713
f9477efd
KH
2714 switch (shift_type)
2715 {
2716 case SHIFT_ASHIFT:
2717 info->special = "mov.b\t%w0,%z0\n\tsub.b\t%y0,%y0\n\tsub.w\t%f0,%f0";
2718 info->shift1 = "shll.b\t%z0";
2719 goto end;
2720 case SHIFT_LSHIFTRT:
2721 info->special = "mov.b\t%z0,%w0\n\tsub.b\t%x0,%x0\n\tsub.w\t%e0,%e0";
2722 info->shift1 = "shlr.b\t%w0";
2723 goto end;
2724 case SHIFT_ASHIFTRT:
2725 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";
2726 info->shift1 = "shar.b\t%w0";
7f473594
KH
2727 goto end;
2728 }
2729 }
4a4ae922
KH
2730 else if ((TARGET_H8300H && count == 24)
2731 || (TARGET_H8300S && 24 <= count && count <= 25))
e6bcfef9 2732 {
4a4ae922
KH
2733 info->remainder = count - 24;
2734
e6bcfef9
JS
2735 switch (shift_type)
2736 {
2737 case SHIFT_ASHIFT:
35fb3d1f 2738 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";
4a4ae922
KH
2739 info->shift1 = "shll.l\t%S0";
2740 info->shift2 = "shll.l\t#2,%S0";
692b7eb3 2741 goto end;
e6bcfef9 2742 case SHIFT_LSHIFTRT:
35fb3d1f 2743 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
4a4ae922
KH
2744 info->shift1 = "shlr.l\t%S0";
2745 info->shift2 = "shlr.l\t#2,%S0";
692b7eb3 2746 goto end;
e6bcfef9 2747 case SHIFT_ASHIFTRT:
35fb3d1f 2748 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
4a4ae922
KH
2749 info->shift1 = "shar.l\t%S0";
2750 info->shift2 = "shar.l\t#2,%S0";
692b7eb3 2751 goto end;
e6bcfef9
JS
2752 }
2753 }
1e5bdc40
KH
2754 else if (!TARGET_H8300 && count == 28)
2755 {
2756 switch (shift_type)
2757 {
2758 case SHIFT_ASHIFT:
2759 if (TARGET_H8300H)
2760 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";
2761 else
2762 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";
2763 info->shift1 = "";
2764 info->shift2 = "";
2765 goto end;
2766 case SHIFT_LSHIFTRT:
2767 if (TARGET_H8300H)
2768 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\tsub.w\t%e0,%e0";
2769 else
2770 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t#2,%S0\n\tsub.w\t%e0,%e0";
2771 info->shift1 = "";
2772 info->shift2 = "";
2773 goto end;
2774 case SHIFT_ASHIFTRT:
2775 abort ();
2776 }
2777 }
2778 else if (!TARGET_H8300 && count == 29)
2779 {
2780 switch (shift_type)
2781 {
2782 case SHIFT_ASHIFT:
2783 if (TARGET_H8300H)
2784 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";
2785 else
2786 info->special = "sub.w\t%e0,%e0\n\trotr.l\t#2,%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0";
2787 info->shift1 = "";
2788 info->shift2 = "";
2789 goto end;
2790 case SHIFT_LSHIFTRT:
2791 if (TARGET_H8300H)
2792 info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\tsub.w\t%e0,%e0";
2793 else
2794 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t%S0\n\tsub.w\t%e0,%e0";
2795 info->shift1 = "";
2796 info->shift2 = "";
2797 goto end;
2798 case SHIFT_ASHIFTRT:
2799 abort ();
2800 }
2801 }
2802 else if (!TARGET_H8300 && count == 30)
2803 {
2804 switch (shift_type)
2805 {
2806 case SHIFT_ASHIFT:
2807 if (TARGET_H8300H)
2808 info->special = "sub.w\t%e0,%e0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0";
2809 else
2810 info->special = "sub.w\t%e0,%e0\n\trotr.l\t#2,%S0\n\tsub.w\t%f0,%f0";
2811 info->shift1 = "";
2812 info->shift2 = "";
2813 goto end;
2814 case SHIFT_LSHIFTRT:
2815 if (TARGET_H8300H)
2816 info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\tsub.w\t%e0,%e0";
2817 else
2818 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\tsub.w\t%e0,%e0";
2819 info->shift1 = "";
2820 info->shift2 = "";
2821 goto end;
2822 case SHIFT_ASHIFTRT:
2823 abort ();
2824 }
2825 }
48837e29
DE
2826 else if (count == 31)
2827 {
dd69e230 2828 if (TARGET_H8300)
48837e29 2829 {
dd69e230
KH
2830 switch (shift_type)
2831 {
2832 case SHIFT_ASHIFT:
2833 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2834 goto end;
2835 case SHIFT_LSHIFTRT:
2836 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2837 goto end;
2838 case SHIFT_ASHIFTRT:
2839 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2840 goto end;
2841 }
48837e29
DE
2842 }
2843 else
2844 {
dd69e230 2845 switch (shift_type)
48837e29 2846 {
dd69e230
KH
2847 case SHIFT_ASHIFT:
2848 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
2849 goto end;
2850 case SHIFT_LSHIFTRT:
2851 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
2852 goto end;
2853 case SHIFT_ASHIFTRT:
2854 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
692b7eb3 2855 goto end;
48837e29 2856 }
48837e29
DE
2857 }
2858 }
769828ab 2859 abort ();
51c0c1d7 2860
48837e29
DE
2861 default:
2862 abort ();
07aae5c2 2863 }
48837e29 2864
cb33eb17
KH
2865 end:
2866 if (!TARGET_H8300S)
2867 info->shift2 = NULL;
07aae5c2
SC
2868}
2869
be1e06df
KH
2870/* Given COUNT and MODE of a shift, return 1 if a scratch reg may be
2871 needed for some shift with COUNT and MODE. Return 0 otherwise. */
2872
2873int
2874h8300_shift_needs_scratch_p (count, mode)
2875 int count;
2876 enum machine_mode mode;
2877{
b9b575e6 2878 enum h8_cpu cpu;
be1e06df
KH
2879 int a, lr, ar;
2880
2881 if (GET_MODE_BITSIZE (mode) <= count)
2882 return 1;
2883
2884 /* Find out the target CPU. */
2885 if (TARGET_H8300)
b9b575e6 2886 cpu = H8_300;
be1e06df 2887 else if (TARGET_H8300H)
b9b575e6 2888 cpu = H8_300H;
be1e06df 2889 else
b9b575e6 2890 cpu = H8_S;
be1e06df
KH
2891
2892 /* Find the shift algorithm. */
2893 switch (mode)
2894 {
2895 case QImode:
2896 a = shift_alg_qi[cpu][SHIFT_ASHIFT][count];
2897 lr = shift_alg_qi[cpu][SHIFT_LSHIFTRT][count];
2898 ar = shift_alg_qi[cpu][SHIFT_ASHIFTRT][count];
2899 break;
2900
2901 case HImode:
2902 a = shift_alg_hi[cpu][SHIFT_ASHIFT][count];
2903 lr = shift_alg_hi[cpu][SHIFT_LSHIFTRT][count];
2904 ar = shift_alg_hi[cpu][SHIFT_ASHIFTRT][count];
2905 break;
2906
2907 case SImode:
2908 a = shift_alg_si[cpu][SHIFT_ASHIFT][count];
2909 lr = shift_alg_si[cpu][SHIFT_LSHIFTRT][count];
2910 ar = shift_alg_si[cpu][SHIFT_ASHIFTRT][count];
2911 break;
2912
2913 default:
2914 abort ();
2915 }
2916
3db11b5c 2917 /* On H8/300H and H8S, count == 8 uses the scratch register. */
be1e06df
KH
2918 return (a == SHIFT_LOOP || lr == SHIFT_LOOP || ar == SHIFT_LOOP
2919 || (!TARGET_H8300 && mode == SImode && count == 8));
2920}
2921
48837e29
DE
2922/* Emit the assembler code for doing shifts. */
2923
441d04c6 2924const char *
1a275226 2925output_a_shift (operands)
48837e29 2926 rtx *operands;
07aae5c2 2927{
48837e29 2928 static int loopend_lab;
48837e29
DE
2929 rtx shift = operands[3];
2930 enum machine_mode mode = GET_MODE (shift);
2931 enum rtx_code code = GET_CODE (shift);
2932 enum shift_type shift_type;
2933 enum shift_mode shift_mode;
35fb3d1f 2934 struct shift_info info;
48837e29
DE
2935
2936 loopend_lab++;
2937
2938 switch (mode)
2939 {
2940 case QImode:
2941 shift_mode = QIshift;
2942 break;
2943 case HImode:
2944 shift_mode = HIshift;
2945 break;
2946 case SImode:
2947 shift_mode = SIshift;
2948 break;
2949 default:
2950 abort ();
2951 }
07aae5c2 2952
48837e29 2953 switch (code)
07aae5c2 2954 {
48837e29
DE
2955 case ASHIFTRT:
2956 shift_type = SHIFT_ASHIFTRT;
2957 break;
2958 case LSHIFTRT:
2959 shift_type = SHIFT_LSHIFTRT;
2960 break;
2961 case ASHIFT:
2962 shift_type = SHIFT_ASHIFT;
2963 break;
2964 default:
2965 abort ();
2966 }
07aae5c2 2967
48837e29
DE
2968 if (GET_CODE (operands[2]) != CONST_INT)
2969 {
07e4d94e 2970 /* Indexing by reg, so have to loop and test at top. */
48837e29
DE
2971 output_asm_insn ("mov.b %X2,%X4", operands);
2972 fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab);
2973
2974 /* Get the assembler code to do one shift. */
35fb3d1f 2975 get_shift_alg (shift_type, shift_mode, 1, &info);
b5eaf9ba
KH
2976
2977 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 2978 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
2979 output_asm_insn ("add #0xff,%X4", operands);
2980 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2981 fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
2982
2983 return "";
48837e29
DE
2984 }
2985 else
2986 {
2987 int n = INTVAL (operands[2]);
48837e29
DE
2988
2989 /* If the count is negative, make it 0. */
2990 if (n < 0)
2991 n = 0;
2992 /* If the count is too big, truncate it.
2993 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2994 do the intuitive thing. */
64530b82 2995 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
48837e29
DE
2996 n = GET_MODE_BITSIZE (mode);
2997
cb33eb17 2998 get_shift_alg (shift_type, shift_mode, n, &info);
48837e29 2999
cb33eb17 3000 switch (info.alg)
48837e29 3001 {
cb33eb17
KH
3002 case SHIFT_SPECIAL:
3003 output_asm_insn (info.special, operands);
3004 /* Fall through. */
3005
48837e29 3006 case SHIFT_INLINE:
cb33eb17
KH
3007 n = info.remainder;
3008
51c0c1d7 3009 /* Emit two bit shifts first. */
1a275226 3010 if (info.shift2 != NULL)
51c0c1d7 3011 {
1a275226
KH
3012 for (; n > 1; n -= 2)
3013 output_asm_insn (info.shift2, operands);
51c0c1d7
JL
3014 }
3015
3016 /* Now emit one bit shifts for any residual. */
1a275226
KH
3017 for (; n > 0; n--)
3018 output_asm_insn (info.shift1, operands);
51c0c1d7
JL
3019
3020 /* Keep track of CC. */
35fb3d1f 3021 if (info.cc_valid_p)
269c14e1
DE
3022 {
3023 cc_status.value1 = operands[0];
35fb3d1f 3024 cc_status.flags |= info.cc_valid_p;
269c14e1 3025 }
48837e29 3026 return "";
51c0c1d7 3027
48837e29
DE
3028 case SHIFT_ROT_AND:
3029 {
3030 int m = GET_MODE_BITSIZE (mode) - n;
3031 int mask = (shift_type == SHIFT_ASHIFT
1a275226
KH
3032 ? ((1 << m) - 1) << n
3033 : (1 << m) - 1);
48837e29 3034 char insn_buf[200];
b5eaf9ba 3035
48837e29
DE
3036 /* Not all possibilities of rotate are supported. They shouldn't
3037 be generated, but let's watch for 'em. */
35fb3d1f 3038 if (info.shift1 == 0)
48837e29 3039 abort ();
51c0c1d7
JL
3040
3041 /* Emit two bit rotates first. */
1a275226 3042 if (info.shift2 != NULL)
51c0c1d7 3043 {
1a275226
KH
3044 for (; m > 1; m -= 2)
3045 output_asm_insn (info.shift2, operands);
51c0c1d7
JL
3046 }
3047
3048 /* Now single bit rotates for any residual. */
1a275226
KH
3049 for (; m > 0; m--)
3050 output_asm_insn (info.shift1, operands);
51c0c1d7
JL
3051
3052 /* Now mask off the high bits. */
539dbd15 3053 switch (mode)
48837e29 3054 {
539dbd15
KH
3055 case QImode:
3056 sprintf (insn_buf, "and\t#%d,%%X0", mask);
3057 cc_status.value1 = operands[0];
3058 cc_status.flags |= CC_NO_CARRY;
3059 break;
3060 case HImode:
3061 if (TARGET_H8300)
48837e29 3062 {
3e39bdb9 3063 sprintf (insn_buf, "and\t#%d,%%s0\n\tand\t#%d,%%t0",
441d04c6 3064 mask & 255, mask >> 8);
48837e29 3065 }
539dbd15
KH
3066 else
3067 {
3068 sprintf (insn_buf, "and.w\t#%d,%%T0", mask);
3069 cc_status.value1 = operands[0];
3070 cc_status.flags |= CC_NO_CARRY;
3071 }
3072 break;
3073 default:
3074 abort ();
48837e29
DE
3075 }
3076 output_asm_insn (insn_buf, operands);
3077 return "";
3078 }
b5eaf9ba 3079
b5eaf9ba
KH
3080 case SHIFT_LOOP:
3081 /* A loop to shift by a "large" constant value.
3082 If we have shift-by-2 insns, use them. */
35fb3d1f 3083 if (info.shift2 != NULL)
b5eaf9ba
KH
3084 {
3085 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
3086 names_big[REGNO (operands[4])]);
3087 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 3088 output_asm_insn (info.shift2, operands);
b5eaf9ba
KH
3089 output_asm_insn ("add #0xff,%X4", operands);
3090 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
3091 if (n % 2)
35fb3d1f 3092 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
3093 }
3094 else
3095 {
3096 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
3097 names_big[REGNO (operands[4])]);
3098 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 3099 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
3100 output_asm_insn ("add #0xff,%X4", operands);
3101 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
3102 }
51c0c1d7 3103 return "";
b5eaf9ba
KH
3104
3105 default:
3106 abort ();
51c0c1d7 3107 }
07aae5c2 3108 }
07aae5c2 3109}
86855e8c
KH
3110
3111static unsigned int
ab2877a3
KG
3112h8300_asm_insn_count (template)
3113 const char *template;
86855e8c
KH
3114{
3115 unsigned int count = 1;
3116
3117 for (; *template; template++)
3118 if (*template == '\n')
3119 count++;
3120
3121 return count;
3122}
3123
3124unsigned int
3125compute_a_shift_length (insn, operands)
3126 rtx insn ATTRIBUTE_UNUSED;
3127 rtx *operands;
3128{
3129 rtx shift = operands[3];
3130 enum machine_mode mode = GET_MODE (shift);
3131 enum rtx_code code = GET_CODE (shift);
3132 enum shift_type shift_type;
3133 enum shift_mode shift_mode;
3134 struct shift_info info;
3135 unsigned int wlength = 0;
3136
3137 switch (mode)
3138 {
3139 case QImode:
3140 shift_mode = QIshift;
3141 break;
3142 case HImode:
3143 shift_mode = HIshift;
3144 break;
3145 case SImode:
3146 shift_mode = SIshift;
3147 break;
3148 default:
3149 abort ();
3150 }
3151
3152 switch (code)
3153 {
3154 case ASHIFTRT:
3155 shift_type = SHIFT_ASHIFTRT;
3156 break;
3157 case LSHIFTRT:
3158 shift_type = SHIFT_LSHIFTRT;
3159 break;
3160 case ASHIFT:
3161 shift_type = SHIFT_ASHIFT;
3162 break;
3163 default:
3164 abort ();
3165 }
3166
3167 if (GET_CODE (operands[2]) != CONST_INT)
3168 {
3169 /* Get the assembler code to do one shift. */
3170 get_shift_alg (shift_type, shift_mode, 1, &info);
3171
3172 return (4 + h8300_asm_insn_count (info.shift1)) * 2;
3173 }
3174 else
3175 {
3176 int n = INTVAL (operands[2]);
3177
3178 /* If the count is negative, make it 0. */
3179 if (n < 0)
3180 n = 0;
3181 /* If the count is too big, truncate it.
3182 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
3183 do the intuitive thing. */
3184 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
3185 n = GET_MODE_BITSIZE (mode);
3186
3187 get_shift_alg (shift_type, shift_mode, n, &info);
3188
3189 switch (info.alg)
3190 {
3191 case SHIFT_SPECIAL:
3192 wlength += h8300_asm_insn_count (info.special);
41c3eb5d
KH
3193
3194 /* Every assembly instruction used in SHIFT_SPECIAL case
3195 takes 2 bytes except xor.l, which takes 4 bytes, so if we
3196 see xor.l, we just pretend that xor.l counts as two insns
3197 so that the insn length will be computed correctly. */
3198 if (strstr (info.special, "xor.l") != NULL)
3199 wlength++;
3200
86855e8c
KH
3201 /* Fall through. */
3202
3203 case SHIFT_INLINE:
3204 n = info.remainder;
3205
3206 if (info.shift2 != NULL)
3207 {
3208 wlength += h8300_asm_insn_count (info.shift2) * (n / 2);
3209 n = n % 2;
3210 }
3211
3212 wlength += h8300_asm_insn_count (info.shift1) * n;
6b148bd9 3213
86855e8c
KH
3214 return 2 * wlength;
3215
3216 case SHIFT_ROT_AND:
3217 {
3218 int m = GET_MODE_BITSIZE (mode) - n;
3219
3220 /* Not all possibilities of rotate are supported. They shouldn't
3221 be generated, but let's watch for 'em. */
3222 if (info.shift1 == 0)
3223 abort ();
3224
3225 if (info.shift2 != NULL)
3226 {
3227 wlength += h8300_asm_insn_count (info.shift2) * (m / 2);
3228 m = m % 2;
3229 }
3230
3231 wlength += h8300_asm_insn_count (info.shift1) * m;
6b148bd9 3232
86855e8c
KH
3233 /* Now mask off the high bits. */
3234 switch (mode)
3235 {
3236 case QImode:
3237 wlength += 1;
3238 break;
3239 case HImode:
3240 wlength += 2;
3241 break;
3242 case SImode:
3243 if (TARGET_H8300)
3244 abort ();
3245 wlength += 3;
3246 break;
3247 default:
3248 abort ();
3249 }
3250 return 2 * wlength;
3251 }
3252
3253 case SHIFT_LOOP:
3254 /* A loop to shift by a "large" constant value.
3255 If we have shift-by-2 insns, use them. */
3256 if (info.shift2 != NULL)
3257 {
3258 wlength += 3 + h8300_asm_insn_count (info.shift2);
3259 if (n % 2)
3260 wlength += h8300_asm_insn_count (info.shift1);
3261 }
3262 else
3263 {
3264 wlength += 3 + h8300_asm_insn_count (info.shift1);
3265 }
3266 return 2 * wlength;
3267
3268 default:
3269 abort ();
3270 }
3271 }
3272}
48837e29 3273\f
edd71f0f
KH
3274/* A rotation by a non-constant will cause a loop to be generated, in
3275 which a rotation by one bit is used. A rotation by a constant,
3276 including the one in the loop, will be taken care of by
3277 emit_a_rotate () at the insn emit time. */
3278
3279int
3280expand_a_rotate (code, operands)
a11d9dfc 3281 enum rtx_code code;
edd71f0f
KH
3282 rtx operands[];
3283{
3284 rtx dst = operands[0];
3285 rtx src = operands[1];
3286 rtx rotate_amount = operands[2];
3287 enum machine_mode mode = GET_MODE (dst);
3288 rtx tmp;
3289
3290 /* We rotate in place. */
3291 emit_move_insn (dst, src);
3292
3293 if (GET_CODE (rotate_amount) != CONST_INT)
3294 {
3295 rtx counter = gen_reg_rtx (QImode);
3296 rtx start_label = gen_label_rtx ();
3297 rtx end_label = gen_label_rtx ();
3298
3299 /* If the rotate amount is less than or equal to 0,
3300 we go out of the loop. */
d43e0b7d
RK
3301 emit_cmp_and_jump_insns (rotate_amount, GEN_INT (0), LE, NULL_RTX,
3302 QImode, 0, end_label);
edd71f0f
KH
3303
3304 /* Initialize the loop counter. */
3305 emit_move_insn (counter, rotate_amount);
3306
3307 emit_label (start_label);
3308
3309 /* Rotate by one bit. */
3310 tmp = gen_rtx (code, mode, dst, GEN_INT (1));
3311 emit_insn (gen_rtx_SET (mode, dst, tmp));
3312
3313 /* Decrement the counter by 1. */
3314 tmp = gen_rtx_PLUS (QImode, counter, GEN_INT (-1));
3315 emit_insn (gen_rtx_SET (VOIDmode, counter, tmp));
3316
9cd10576 3317 /* If the loop counter is nonzero, we go back to the beginning
edd71f0f 3318 of the loop. */
d43e0b7d
RK
3319 emit_cmp_and_jump_insns (counter, GEN_INT (0), NE, NULL_RTX, QImode, 1,
3320 start_label);
edd71f0f
KH
3321
3322 emit_label (end_label);
3323 }
3324 else
3325 {
3326 /* Rotate by AMOUNT bits. */
3327 tmp = gen_rtx (code, mode, dst, rotate_amount);
3328 emit_insn (gen_rtx_SET (mode, dst, tmp));
3329 }
3330
3331 return 1;
3332}
3333
3334/* Emit rotate insns. */
3335
3336const char *
3337emit_a_rotate (code, operands)
a11d9dfc 3338 enum rtx_code code;
edd71f0f
KH
3339 rtx *operands;
3340{
3341 rtx dst = operands[0];
3342 rtx rotate_amount = operands[2];
3343 enum shift_mode rotate_mode;
3344 enum shift_type rotate_type;
3345 const char *insn_buf;
3346 int bits;
3347 int amount;
3348 enum machine_mode mode = GET_MODE (dst);
3349
3350 if (GET_CODE (rotate_amount) != CONST_INT)
3351 abort ();
3352
3353 switch (mode)
3354 {
3355 case QImode:
3356 rotate_mode = QIshift;
3357 break;
3358 case HImode:
3359 rotate_mode = HIshift;
3360 break;
3361 case SImode:
3362 rotate_mode = SIshift;
3363 break;
3364 default:
3365 abort ();
3366 }
3367
3368 switch (code)
3369 {
3370 case ROTATERT:
3371 rotate_type = SHIFT_ASHIFT;
3372 break;
3373 case ROTATE:
3374 rotate_type = SHIFT_LSHIFTRT;
3375 break;
3376 default:
3377 abort ();
3378 }
3379
3380 amount = INTVAL (rotate_amount);
3381
3382 /* Clean up AMOUNT. */
3383 if (amount < 0)
3384 amount = 0;
3385 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3386 amount = GET_MODE_BITSIZE (mode);
3387
3388 /* Determine the faster direction. After this phase, amount will be
3389 at most a half of GET_MODE_BITSIZE (mode). */
e0c32c62 3390 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
edd71f0f
KH
3391 {
3392 /* Flip the direction. */
3393 amount = GET_MODE_BITSIZE (mode) - amount;
3394 rotate_type =
3395 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
3396 }
3397
3398 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3399 boost up the rotation. */
3400 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3401 || (mode == HImode && TARGET_H8300H && amount >= 6)
3402 || (mode == HImode && TARGET_H8300S && amount == 8)
3403 || (mode == SImode && TARGET_H8300H && amount >= 10)
3404 || (mode == SImode && TARGET_H8300S && amount >= 13))
3405 {
3406 switch (mode)
3407 {
3408 case HImode:
3409 /* This code works on any family. */
3410 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
3411 output_asm_insn (insn_buf, operands);
3412 break;
3413
3414 case SImode:
3db11b5c 3415 /* This code works on the H8/300H and H8S. */
edd71f0f
KH
3416 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
3417 output_asm_insn (insn_buf, operands);
3418 break;
3419
3420 default:
3421 abort ();
3422 }
3423
3424 /* Adjust AMOUNT and flip the direction. */
3425 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3426 rotate_type =
3427 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
3428 }
3429
3430 /* Emit rotate insns. */
3431 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2)
3432 {
3433 if (bits == 2)
3434 insn_buf = rotate_two[rotate_type][rotate_mode];
3435 else
3436 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode];
2c54abce 3437
edd71f0f
KH
3438 for (; amount >= bits; amount -= bits)
3439 output_asm_insn (insn_buf, operands);
3440 }
3441
3442 return "";
3443}
3444\f
48837e29 3445/* Fix the operands of a gen_xxx so that it could become a bit
2c54abce 3446 operating insn. */
07aae5c2
SC
3447
3448int
48837e29
DE
3449fix_bit_operand (operands, what, type)
3450 rtx *operands;
441d04c6 3451 int what;
48837e29 3452 enum rtx_code type;
07aae5c2 3453{
abc95ed3 3454 /* The bit_operand predicate accepts any memory during RTL generation, but
48837e29
DE
3455 only 'U' memory afterwards, so if this is a MEM operand, we must force
3456 it to be valid for 'U' by reloading the address. */
07aae5c2 3457
2e760b15
KH
3458 if ((what == 0 && single_zero_operand (operands[2], QImode))
3459 || (what == 1 && single_one_operand (operands[2], QImode)))
07aae5c2 3460 {
2e760b15
KH
3461 /* OK to have a memory dest. */
3462 if (GET_CODE (operands[0]) == MEM
3463 && !EXTRA_CONSTRAINT (operands[0], 'U'))
48837e29 3464 {
2e760b15
KH
3465 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
3466 copy_to_mode_reg (Pmode,
3467 XEXP (operands[0], 0)));
3468 MEM_COPY_ATTRIBUTES (mem, operands[0]);
3469 operands[0] = mem;
3470 }
48837e29 3471
2e760b15
KH
3472 if (GET_CODE (operands[1]) == MEM
3473 && !EXTRA_CONSTRAINT (operands[1], 'U'))
3474 {
3475 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
3476 copy_to_mode_reg (Pmode,
3477 XEXP (operands[1], 0)));
3478 MEM_COPY_ATTRIBUTES (mem, operands[0]);
3479 operands[1] = mem;
48837e29 3480 }
2e760b15 3481 return 0;
48837e29 3482 }
07aae5c2 3483
48837e29 3484 /* Dest and src op must be register. */
07aae5c2 3485
48837e29
DE
3486 operands[1] = force_reg (QImode, operands[1]);
3487 {
3488 rtx res = gen_reg_rtx (QImode);
c5c76735
JL
3489 emit_insn (gen_rtx_SET (VOIDmode, res,
3490 gen_rtx (type, QImode, operands[1], operands[2])));
3491 emit_insn (gen_rtx_SET (VOIDmode, operands[0], res));
48837e29
DE
3492 }
3493 return 1;
07aae5c2 3494}
f5b65a56 3495
f5b65a56
JL
3496/* Return nonzero if FUNC is an interrupt function as specified
3497 by the "interrupt" attribute. */
3498
3499static int
3500h8300_interrupt_function_p (func)
3501 tree func;
3502{
3503 tree a;
3504
3505 if (TREE_CODE (func) != FUNCTION_DECL)
3506 return 0;
3507
91d231cb 3508 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
f5b65a56
JL
3509 return a != NULL_TREE;
3510}
3511
fabe72bb
JL
3512/* Return nonzero if FUNC is an OS_Task function as specified
3513 by the "OS_Task" attribute. */
3514
3515static int
3516h8300_os_task_function_p (func)
3517 tree func;
3518{
3519 tree a;
3520
3521 if (TREE_CODE (func) != FUNCTION_DECL)
3522 return 0;
3523
91d231cb 3524 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func));
fabe72bb
JL
3525 return a != NULL_TREE;
3526}
3527
3528/* Return nonzero if FUNC is a monitor function as specified
3529 by the "monitor" attribute. */
3530
3531static int
3532h8300_monitor_function_p (func)
3533 tree func;
3534{
3535 tree a;
3536
3537 if (TREE_CODE (func) != FUNCTION_DECL)
3538 return 0;
3539
91d231cb 3540 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func));
fabe72bb
JL
3541 return a != NULL_TREE;
3542}
3543
f5b65a56
JL
3544/* Return nonzero if FUNC is a function that should be called
3545 through the function vector. */
3546
3547int
3548h8300_funcvec_function_p (func)
3549 tree func;
3550{
3551 tree a;
3552
3553 if (TREE_CODE (func) != FUNCTION_DECL)
3554 return 0;
3555
91d231cb 3556 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func));
f5b65a56
JL
3557 return a != NULL_TREE;
3558}
3559
887a8bd9 3560/* Return nonzero if DECL is a variable that's in the eight bit
15dc331e
JL
3561 data area. */
3562
3563int
fabdc32d 3564h8300_eightbit_data_p (decl)
15dc331e
JL
3565 tree decl;
3566{
3567 tree a;
3568
3569 if (TREE_CODE (decl) != VAR_DECL)
3570 return 0;
3571
91d231cb 3572 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl));
15dc331e
JL
3573 return a != NULL_TREE;
3574}
3575
887a8bd9
JL
3576/* Return nonzero if DECL is a variable that's in the tiny
3577 data area. */
3578
3579int
3580h8300_tiny_data_p (decl)
3581 tree decl;
3582{
3583 tree a;
3584
3585 if (TREE_CODE (decl) != VAR_DECL)
3586 return 0;
3587
91d231cb 3588 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl));
887a8bd9
JL
3589 return a != NULL_TREE;
3590}
3591
2c1d2fcb
DD
3592/* Generate an 'interrupt_handler' attribute for decls. */
3593
3594static void
3595h8300_insert_attributes (node, attributes)
3596 tree node;
3597 tree *attributes;
3598{
3599 if (!interrupt_handler
3600 || TREE_CODE (node) != FUNCTION_DECL)
3601 return;
3602
3603 /* Add an 'interrupt_handler' attribute. */
3604 *attributes = tree_cons (get_identifier ("interrupt_handler"),
3605 NULL, *attributes);
3606}
3607
91d231cb 3608/* Supported attributes:
f5b65a56 3609
97c5ec1d 3610 interrupt_handler: output a prologue and epilogue suitable for an
f5b65a56
JL
3611 interrupt handler.
3612
97c5ec1d 3613 function_vector: This function should be called through the
887a8bd9
JL
3614 function vector.
3615
3616 eightbit_data: This variable lives in the 8-bit data area and can
3617 be referenced with 8-bit absolute memory addresses.
3618
3619 tiny_data: This variable lives in the tiny data area and can be
3620 referenced with 16-bit absolute memory references. */
f5b65a56 3621
91d231cb 3622const struct attribute_spec h8300_attribute_table[] =
f5b65a56 3623{
91d231cb
JM
3624 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
3625 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3626 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3627 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3628 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3629 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute },
3630 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute },
3631 { NULL, 0, 0, false, false, false, NULL }
3632};
f5b65a56 3633
15dc331e 3634
91d231cb
JM
3635/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
3636 struct attribute_spec.handler. */
3637static tree
3638h8300_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
3639 tree *node;
3640 tree name;
3641 tree args ATTRIBUTE_UNUSED;
3642 int flags ATTRIBUTE_UNUSED;
3643 bool *no_add_attrs;
3644{
3645 if (TREE_CODE (*node) != FUNCTION_DECL)
3646 {
3647 warning ("`%s' attribute only applies to functions",
3648 IDENTIFIER_POINTER (name));
3649 *no_add_attrs = true;
3650 }
3651
3652 return NULL_TREE;
3653}
3654
3655/* Handle an "eightbit_data" attribute; arguments as in
3656 struct attribute_spec.handler. */
3657static tree
3658h8300_handle_eightbit_data_attribute (node, name, args, flags, no_add_attrs)
3659 tree *node;
3660 tree name;
3661 tree args ATTRIBUTE_UNUSED;
3662 int flags ATTRIBUTE_UNUSED;
3663 bool *no_add_attrs;
3664{
3665 tree decl = *node;
3666
3667 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
15dc331e 3668 {
64378c91 3669 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
91d231cb
JM
3670 }
3671 else
3672 {
3673 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3674 *no_add_attrs = true;
887a8bd9
JL
3675 }
3676
91d231cb
JM
3677 return NULL_TREE;
3678}
3679
3680/* Handle an "tiny_data" attribute; arguments as in
3681 struct attribute_spec.handler. */
3682static tree
3683h8300_handle_tiny_data_attribute (node, name, args, flags, no_add_attrs)
3684 tree *node;
3685 tree name;
3686 tree args ATTRIBUTE_UNUSED;
3687 int flags ATTRIBUTE_UNUSED;
3688 bool *no_add_attrs;
3689{
3690 tree decl = *node;
3691
3692 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
887a8bd9 3693 {
64378c91 3694 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
91d231cb
JM
3695 }
3696 else
3697 {
3698 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3699 *no_add_attrs = true;
15dc331e 3700 }
07e4d94e 3701
91d231cb 3702 return NULL_TREE;
f5b65a56
JL
3703}
3704
fb49053f 3705static void
887a8bd9
JL
3706h8300_encode_label (decl)
3707 tree decl;
3708{
441d04c6 3709 const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
887a8bd9 3710 int len = strlen (str);
93cacb72 3711 char *newstr = alloca (len + 2);
887a8bd9 3712
93cacb72
KH
3713 newstr[0] = '&';
3714 strcpy (&newstr[1], str);
887a8bd9 3715
93cacb72
KH
3716 XSTR (XEXP (DECL_RTL (decl), 0), 0) =
3717 ggc_alloc_string (newstr, len + 1);
887a8bd9
JL
3718}
3719
fb49053f
RH
3720/* If we are referencing a function that is supposed to be called
3721 through the function vector, the SYMBOL_REF_FLAG in the rtl
3722 so the call patterns can generate the correct code. */
3723
3724static void
3725h8300_encode_section_info (decl, first)
3726 tree decl;
3727 int first;
3728{
3729 if (TREE_CODE (decl) == FUNCTION_DECL
3730 && h8300_funcvec_function_p (decl))
3731 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
3732 else if (TREE_CODE (decl) == VAR_DECL
3733 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
3734 {
3735 if (h8300_eightbit_data_p (decl))
3736 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
3737 else if (first && h8300_tiny_data_p (decl))
3738 h8300_encode_label (decl);
3739 }
3740}
3741
772c5265
RH
3742/* Undo the effects of the above. */
3743
3744static const char *
3745h8300_strip_name_encoding (str)
3746 const char *str;
3747{
3748 return str + (*str == '*' || *str == '@' || *str == '&');
3749}
3750
441d04c6 3751const char *
871f73e3 3752output_simode_bld (bild, operands)
bd93f126 3753 int bild;
bd93f126
JL
3754 rtx operands[];
3755{
6be580c7
KH
3756 if (TARGET_H8300)
3757 {
3758 /* Clear the destination register. */
3759 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
3760
3761 /* Now output the bit load or bit inverse load, and store it in
3762 the destination. */
3763 if (bild)
3764 output_asm_insn ("bild\t%Z2,%Y1", operands);
3765 else
3766 output_asm_insn ("bld\t%Z2,%Y1", operands);
bd93f126 3767
6be580c7
KH
3768 output_asm_insn ("bst\t#0,%w0", operands);
3769 }
bd93f126 3770 else
6be580c7
KH
3771 {
3772 /* Output the bit load or bit inverse load. */
3773 if (bild)
3774 output_asm_insn ("bild\t%Z2,%Y1", operands);
3775 else
3776 output_asm_insn ("bld\t%Z2,%Y1", operands);
3777
3778 /* Clear the destination register and perform the bit store. */
3779 output_asm_insn ("xor.l\t%S0,%S0\n\tbst\t#0,%w0", operands);
3780 }
bd93f126
JL
3781
3782 /* All done. */
3783 return "";
3784}
e6219736 3785
9ec36da5 3786/* Given INSN and its current length LENGTH, return the adjustment
e6219736
JL
3787 (in bytes) to correctly compute INSN's length.
3788
3789 We use this to get the lengths of various memory references correct. */
3790
441d04c6 3791int
e6219736
JL
3792h8300_adjust_insn_length (insn, length)
3793 rtx insn;
441d04c6 3794 int length ATTRIBUTE_UNUSED;
e6219736 3795{
5fc4b751 3796 rtx pat = PATTERN (insn);
04b6000c 3797
e32815aa 3798 /* We must filter these out before calling get_attr_adjust_length. */
5fc4b751
KH
3799 if (GET_CODE (pat) == USE
3800 || GET_CODE (pat) == CLOBBER
3801 || GET_CODE (pat) == SEQUENCE
3802 || GET_CODE (pat) == ADDR_VEC
3803 || GET_CODE (pat) == ADDR_DIFF_VEC)
47cf37f9
JL
3804 return 0;
3805
04b6000c
VM
3806 if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO)
3807 return 0;
3808
e6219736
JL
3809 /* Adjust length for reg->mem and mem->reg copies. */
3810 if (GET_CODE (pat) == SET
3811 && (GET_CODE (SET_SRC (pat)) == MEM
3812 || GET_CODE (SET_DEST (pat)) == MEM))
3813 {
3814 /* This insn might need a length adjustment. */
3815 rtx addr;
3816
3817 if (GET_CODE (SET_SRC (pat)) == MEM)
3818 addr = XEXP (SET_SRC (pat), 0);
3819 else
3820 addr = XEXP (SET_DEST (pat), 0);
3821
fbf0fe41
KH
3822 if (TARGET_H8300)
3823 {
3824 /* On the H8/300, we subtract the difference between the
3825 actual length and the longest one, which is @(d:16,ERs). */
e6219736 3826
fbf0fe41
KH
3827 /* @Rs is 2 bytes shorter than the longest. */
3828 if (GET_CODE (addr) == REG)
3829 return -2;
d56c04ce
DD
3830
3831 /* @aa:8 is 2 bytes shorter than the longest. */
3832 if (GET_MODE (SET_SRC (pat)) == QImode
7c143ed2 3833 && h8300_eightbit_constant_address_p (addr))
d56c04ce 3834 return -2;
fbf0fe41
KH
3835 }
3836 else
3837 {
3db11b5c 3838 /* On the H8/300H and H8S, we subtract the difference
fbf0fe41
KH
3839 between the actual length and the longest one, which is
3840 @(d:24,ERs). */
3841
3842 /* @ERs is 6 bytes shorter than the longest. */
3843 if (GET_CODE (addr) == REG)
3844 return -6;
3845
3846 /* @(d:16,ERs) is 6 bytes shorter than the longest. */
3847 if (GET_CODE (addr) == PLUS
3848 && GET_CODE (XEXP (addr, 0)) == REG
3849 && GET_CODE (XEXP (addr, 1)) == CONST_INT
3850 && INTVAL (XEXP (addr, 1)) > -32768
3851 && INTVAL (XEXP (addr, 1)) < 32767)
3852 return -4;
3853
054ef905
KH
3854 /* @aa:8 is 6 bytes shorter than the longest. */
3855 if (GET_MODE (SET_SRC (pat)) == QImode
7c143ed2 3856 && h8300_eightbit_constant_address_p (addr))
054ef905
KH
3857 return -6;
3858
3859 /* @aa:16 is 4 bytes shorter than the longest. */
56b8e164 3860 if (h8300_tiny_constant_address_p (addr))
054ef905
KH
3861 return -4;
3862
3863 /* @aa:24 is 2 bytes shorter than the longest. */
3864 if (GET_CODE (addr) == CONST_INT)
fbf0fe41
KH
3865 return -2;
3866 }
e6219736
JL
3867 }
3868
3869 /* Loading some constants needs adjustment. */
3870 if (GET_CODE (pat) == SET
3871 && GET_CODE (SET_SRC (pat)) == CONST_INT
3872 && GET_MODE (SET_DEST (pat)) == SImode
3873 && INTVAL (SET_SRC (pat)) != 0)
3874 {
64530b82
KH
3875 int val = INTVAL (SET_SRC (pat));
3876
e6219736 3877 if (TARGET_H8300
64530b82
KH
3878 && ((val & 0xffff) == 0
3879 || ((val >> 16) & 0xffff) == 0))
e6219736
JL
3880 return -2;
3881
a1616dd9 3882 if (TARGET_H8300H || TARGET_H8300S)
e6219736 3883 {
e6219736
JL
3884 if (val == (val & 0xff)
3885 || val == (val & 0xff00))
86039100 3886 return 4 - 6;
e6219736 3887
86039100
KH
3888 switch (val & 0xffffffff)
3889 {
3890 case 0xffffffff:
3891 case 0xfffffffe:
3892 case 0xfffffffc:
3893 case 0x0000ffff:
3894 case 0x0000fffe:
3895 case 0xffff0000:
3896 case 0xfffe0000:
3897 case 0x00010000:
3898 case 0x00020000:
3899 return 4 - 6;
3900 }
e6219736
JL
3901 }
3902 }
3903
edd71f0f
KH
3904 /* Rotations need various adjustments. */
3905 if (GET_CODE (pat) == SET
3906 && (GET_CODE (SET_SRC (pat)) == ROTATE
3907 || GET_CODE (SET_SRC (pat)) == ROTATERT))
3908 {
3909 rtx src = SET_SRC (pat);
3910 enum machine_mode mode = GET_MODE (src);
3911 int amount;
3912 int states = 0;
3913
3914 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3915 return 0;
3916
3917 amount = INTVAL (XEXP (src, 1));
3918
3919 /* Clean up AMOUNT. */
3920 if (amount < 0)
3921 amount = 0;
3922 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3923 amount = GET_MODE_BITSIZE (mode);
3924
3925 /* Determine the faster direction. After this phase, amount
3926 will be at most a half of GET_MODE_BITSIZE (mode). */
e0c32c62 3927 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
edd71f0f
KH
3928 /* Flip the direction. */
3929 amount = GET_MODE_BITSIZE (mode) - amount;
3930
3931 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3932 boost up the rotation. */
3933 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3934 || (mode == HImode && TARGET_H8300H && amount >= 6)
3935 || (mode == HImode && TARGET_H8300S && amount == 8)
3936 || (mode == SImode && TARGET_H8300H && amount >= 10)
3937 || (mode == SImode && TARGET_H8300S && amount >= 13))
3938 {
3939 /* Adjust AMOUNT and flip the direction. */
3940 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3941 states += 6;
3942 }
3943
3db11b5c 3944 /* We use 2-bit rotatations on the H8S. */
edd71f0f
KH
3945 if (TARGET_H8300S)
3946 amount = amount / 2 + amount % 2;
3947
3948 /* The H8/300 uses three insns to rotate one bit, taking 6
3949 states. */
3950 states += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2);
3951
3952 return -(20 - states);
3953 }
3954
e6219736
JL
3955 return 0;
3956}
7c262518 3957
ede75ee8 3958#ifndef OBJECT_FORMAT_ELF
7c262518 3959static void
715bdd29 3960h8300_asm_named_section (name, flags)
7c262518
RH
3961 const char *name;
3962 unsigned int flags ATTRIBUTE_UNUSED;
7c262518
RH
3963{
3964 /* ??? Perhaps we should be using default_coff_asm_named_section. */
3965 fprintf (asm_out_file, "\t.section %s\n", name);
3966}
ede75ee8 3967#endif /* ! OBJECT_FORMAT_ELF */
803d56f5 3968
7c143ed2
KH
3969/* Nonzero if X is a constant address suitable as an 8-bit absolute,
3970 which is a special case of the 'R' operand. */
3971
803d56f5
KH
3972int
3973h8300_eightbit_constant_address_p (x)
3974 rtx x;
3975{
3f7211f1 3976 /* The ranges of the 8-bit area. */
d2d199a3
KH
3977 const unsigned HOST_WIDE_INT n1 = trunc_int_for_mode (0xff00, HImode);
3978 const unsigned HOST_WIDE_INT n2 = trunc_int_for_mode (0xffff, HImode);
803d56f5
KH
3979 const unsigned HOST_WIDE_INT h1 = trunc_int_for_mode (0x00ffff00, SImode);
3980 const unsigned HOST_WIDE_INT h2 = trunc_int_for_mode (0x00ffffff, SImode);
3981 const unsigned HOST_WIDE_INT s1 = trunc_int_for_mode (0xffffff00, SImode);
3982 const unsigned HOST_WIDE_INT s2 = trunc_int_for_mode (0xffffffff, SImode);
3983
3984 unsigned HOST_WIDE_INT addr;
3985
9675a91e
KH
3986 /* We accept symbols declared with eightbit_data. */
3987 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FLAG (x))
3988 return 1;
3989
803d56f5
KH
3990 if (GET_CODE (x) != CONST_INT)
3991 return 0;
3992
3993 addr = INTVAL (x);
3994
3995 return (0
39ba95b5 3996 || ((TARGET_H8300 || TARGET_NORMAL_MODE) && IN_RANGE (addr, n1, n2))
803d56f5
KH
3997 || (TARGET_H8300H && IN_RANGE (addr, h1, h2))
3998 || (TARGET_H8300S && IN_RANGE (addr, s1, s2)));
3999}
4000
7c143ed2
KH
4001/* Nonzero if X is a constant address suitable as an 16-bit absolute
4002 on H8/300H and H8S. */
4003
803d56f5
KH
4004int
4005h8300_tiny_constant_address_p (x)
4006 rtx x;
4007{
3f7211f1 4008 /* The ranges of the 16-bit area. */
803d56f5
KH
4009 const unsigned HOST_WIDE_INT h1 = trunc_int_for_mode (0x00000000, SImode);
4010 const unsigned HOST_WIDE_INT h2 = trunc_int_for_mode (0x00007fff, SImode);
4011 const unsigned HOST_WIDE_INT h3 = trunc_int_for_mode (0x00ff8000, SImode);
4012 const unsigned HOST_WIDE_INT h4 = trunc_int_for_mode (0x00ffffff, SImode);
4013 const unsigned HOST_WIDE_INT s1 = trunc_int_for_mode (0x00000000, SImode);
4014 const unsigned HOST_WIDE_INT s2 = trunc_int_for_mode (0x00007fff, SImode);
4015 const unsigned HOST_WIDE_INT s3 = trunc_int_for_mode (0xffff8000, SImode);
4016 const unsigned HOST_WIDE_INT s4 = trunc_int_for_mode (0xffffffff, SImode);
4017
4018 unsigned HOST_WIDE_INT addr;
4019
56b8e164
KH
4020 /* We accept symbols declared with tiny_data. */
4021 if (GET_CODE (x) == SYMBOL_REF && TINY_DATA_NAME_P (XSTR (x, 0)))
4022 return 1;
4023
803d56f5
KH
4024 if (GET_CODE (x) != CONST_INT)
4025 return 0;
4026
4027 addr = INTVAL (x);
4028
4029 return (0
39ba95b5 4030 || ((TARGET_H8300H && !TARGET_NORMAL_MODE)
94aec8dd 4031 && (IN_RANGE (addr, h1, h2) || IN_RANGE (addr, h3, h4)))
39ba95b5 4032 || ((TARGET_H8300S && !TARGET_NORMAL_MODE)
94aec8dd 4033 && (IN_RANGE (addr, s1, s2) || IN_RANGE (addr, s3, s4))));
803d56f5 4034}
This page took 1.771549 seconds and 5 git commands to generate.