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