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