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