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