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