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