]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/h8300/h8300.c
toplev.c (output_clean_symbol_name): 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
7948a9ea
KH
1809/* Return the length of mov instruction. */
1810
1811unsigned int
1812compute_mov_length (rtx *operands)
1813{
1814 /* If the mov instruction involves a memory operand, we compute the
1815 length, assuming the largest addressing mode is used, and then
1816 adjust later in the function. Otherwise, we compute and return
1817 the exact length in one step. */
1818 enum machine_mode mode = GET_MODE (operands[0]);
1819 rtx dest = operands[0];
1820 rtx src = operands[1];
1821 rtx addr;
1822
1823 if (GET_CODE (src) == MEM)
1824 addr = XEXP (src, 0);
1825 else if (GET_CODE (dest) == MEM)
1826 addr = XEXP (dest, 0);
1827 else
1828 addr = NULL_RTX;
1829
1830 if (TARGET_H8300)
1831 {
1832 unsigned int base_length;
1833
1834 switch (mode)
1835 {
1836 case QImode:
1837 if (addr == NULL_RTX)
1838 return 2;
1839
1840 /* The eightbit addressing is available only in QImode, so
1841 go ahead and take care of it. */
1842 if (h8300_eightbit_constant_address_p (addr))
1843 return 2;
1844
1845 base_length = 4;
1846 break;
1847
1848 case HImode:
1849 if (addr == NULL_RTX)
1850 {
1851 if (REG_P (src))
1852 return 2;
1853
1854 if (src == const0_rtx)
1855 return 2;
1856
1857 return 4;
1858 }
1859
1860 base_length = 4;
1861 break;
1862
1863 case SImode:
1864 if (addr == NULL_RTX)
1865 {
1866 if (REG_P (src))
1867 return 4;
1868
1869 if (GET_CODE (src) == CONST_INT)
1870 {
1871 if (src == const0_rtx)
1872 return 4;
1873
1874 if ((INTVAL (src) & 0xffff) == 0)
1875 return 6;
1876
1877 if ((INTVAL (src) & 0xffff) == 0)
1878 return 6;
f5139cc5
KH
1879
1880 if ((INTVAL (src) & 0xffff)
1881 == ((INTVAL (src) >> 16) & 0xffff))
1882 return 6;
7948a9ea
KH
1883 }
1884 return 8;
1885 }
1886
1887 base_length = 8;
1888 break;
1889
1890 case SFmode:
1891 if (addr == NULL_RTX)
1892 {
1893 if (REG_P (src))
1894 return 4;
1895
81983b04 1896 return 8;
7948a9ea
KH
1897 }
1898
1899 base_length = 8;
1900 break;
1901
1902 default:
1903 abort ();
1904 }
1905
1906 /* Adjust the length based on the addressing mode used.
1907 Specifically, we subtract the difference between the actual
1908 length and the longest one, which is @(d:16,Rs). For SImode
1909 and SFmode, we double the adjustment because two mov.w are
1910 used to do the job. */
1911
1912 /* @Rs+ and @-Rd are 2 bytes shorter than the longest. */
1913 if (GET_CODE (addr) == PRE_DEC
1914 || GET_CODE (addr) == POST_INC)
1915 {
1916 if (mode == QImode || mode == HImode)
1917 return base_length - 2;
1918 else
1919 /* In SImode and SFmode, we use two mov.w instructions, so
1920 double the adustment. */
1921 return base_length - 4;
1922 }
1923
1924 /* @Rs and @Rd are 2 bytes shorter than the longest. Note that
1925 in SImode and SFmode, the second mov.w involves an address
1926 with displacement, namely @(2,Rs) or @(2,Rd), so we subtract
1927 only 2 bytes. */
1928 if (GET_CODE (addr) == REG)
1929 return base_length - 2;
1930
1931 return base_length;
1932 }
1933 else
1934 {
1935 unsigned int base_length;
1936
1937 switch (mode)
1938 {
1939 case QImode:
1940 if (addr == NULL_RTX)
1941 return 2;
1942
1943 /* The eightbit addressing is available only in QImode, so
1944 go ahead and take care of it. */
1945 if (h8300_eightbit_constant_address_p (addr))
1946 return 2;
1947
1948 base_length = 8;
1949 break;
1950
1951 case HImode:
1952 if (addr == NULL_RTX)
1953 {
1954 if (REG_P (src))
1955 return 2;
1956
1957 if (src == const0_rtx)
1958 return 2;
1959
1960 return 4;
1961 }
1962
1963 base_length = 8;
1964 break;
1965
1966 case SImode:
1967 if (addr == NULL_RTX)
1968 {
1969 if (REG_P (src))
1970 {
1971 if (REGNO (src) == MAC_REG || REGNO (dest) == MAC_REG)
1972 return 4;
1973 else
1974 return 2;
1975 }
1976
1977 if (GET_CODE (src) == CONST_INT)
1978 {
1979 int val = INTVAL (src);
1980
1981 if (val == 0)
1982 return 2;
1983
1984 if (val == (val & 0x00ff) || val == (val & 0xff00))
1985 return 4;
1986
1987 switch (val & 0xffffffff)
1988 {
1989 case 0xffffffff:
1990 case 0xfffffffe:
1991 case 0xfffffffc:
1992 case 0x0000ffff:
1993 case 0x0000fffe:
1994 case 0xffff0000:
1995 case 0xfffe0000:
1996 case 0x00010000:
1997 case 0x00020000:
1998 return 4;
1999 }
2000 }
2001 return 6;
2002 }
2003
2004 base_length = 10;
2005 break;
2006
2007 case SFmode:
2008 if (addr == NULL_RTX)
2009 {
2010 if (REG_P (src))
2011 return 2;
2012
fad37371 2013 if (CONST_DOUBLE_OK_FOR_LETTER_P (src, 'G'))
7948a9ea
KH
2014 return 2;
2015 return 6;
2016 }
2017
2018 base_length = 10;
2019 break;
2020
2021 default:
2022 abort ();
2023 }
2024
2025 /* Adjust the length based on the addressing mode used.
2026 Specifically, we subtract the difference between the actual
2027 length and the longest one, which is @(d:24,ERs). */
2028
2029 /* @ERs+ and @-ERd are 6 bytes shorter than the longest. */
2030 if (GET_CODE (addr) == PRE_DEC
2031 || GET_CODE (addr) == POST_INC)
2032 return base_length - 6;
2033
2034 /* @ERs and @ERd are 6 bytes shorter than the longest. */
2035 if (GET_CODE (addr) == REG)
2036 return base_length - 6;
2037
2038 /* @(d:16,ERs) and @(d:16,ERd) are 4 bytes shorter than the
2039 longest. */
2040 if (GET_CODE (addr) == PLUS
2041 && GET_CODE (XEXP (addr, 0)) == REG
2042 && GET_CODE (XEXP (addr, 1)) == CONST_INT
2043 && INTVAL (XEXP (addr, 1)) > -32768
2044 && INTVAL (XEXP (addr, 1)) < 32767)
2045 return base_length - 4;
2046
2047 /* @aa:16 is 4 bytes shorter than the longest. */
2048 if (h8300_tiny_constant_address_p (addr))
2049 return base_length - 4;
2050
2051 /* @aa:24 is 2 bytes shorter than the longest. */
2052 if (CONSTANT_P (addr))
2053 return base_length - 2;
2054
2055 return base_length;
2056 }
2057}
2058\f
366a7b27 2059const char *
cb713a8d 2060output_plussi (rtx *operands)
7d6ac401
KH
2061{
2062 enum machine_mode mode = GET_MODE (operands[0]);
2063
2064 if (mode != SImode)
2065 abort ();
2066
2067 if (TARGET_H8300)
2068 {
cfedf91b
KH
2069 if (GET_CODE (operands[2]) == REG)
2070 return "add.w\t%f2,%f0\n\taddx\t%y2,%y0\n\taddx\t%z2,%z0";
2071
2072 if (GET_CODE (operands[2]) == CONST_INT)
2073 {
2074 HOST_WIDE_INT n = INTVAL (operands[2]);
2075
2076 if ((n & 0xffffff) == 0)
2077 return "add\t%z2,%z0";
2078 if ((n & 0xffff) == 0)
2079 return "add\t%y2,%y0\n\taddx\t%z2,%z0";
2080 if ((n & 0xff) == 0)
2081 return "add\t%x2,%x0\n\taddx\t%y2,%y0\n\taddx\t%z2,%z0";
2082 }
2083
2084 return "add\t%w2,%w0\n\taddx\t%x2,%x0\n\taddx\t%y2,%y0\n\taddx\t%z2,%z0";
7d6ac401
KH
2085 }
2086 else
2087 {
2088 if (GET_CODE (operands[2]) == REG)
2089 return "add.l\t%S2,%S0";
2090
2091 if (GET_CODE (operands[2]) == CONST_INT)
2092 {
2093 HOST_WIDE_INT intval = INTVAL (operands[2]);
2094
2095 /* See if we can finish with 2 bytes. */
2096
9ac7ebba 2097 switch ((unsigned int) intval & 0xffffffff)
7d6ac401
KH
2098 {
2099 case 0x00000001:
2100 case 0x00000002:
2101 case 0x00000004:
2102 return "adds\t%2,%S0";
2103
2104 case 0xffffffff:
2105 case 0xfffffffe:
2106 case 0xfffffffc:
2107 return "subs\t%G2,%S0";
2108
2109 case 0x00010000:
2110 case 0x00020000:
2111 operands[2] = GEN_INT (intval >> 16);
2112 return "inc.w\t%2,%e0";
2113
2114 case 0xffff0000:
2115 case 0xfffe0000:
2116 operands[2] = GEN_INT (intval >> 16);
2117 return "dec.w\t%G2,%e0";
2118 }
2119
2120 /* See if we can finish with 4 bytes. */
2121 if ((intval & 0xffff) == 0)
2122 {
2123 operands[2] = GEN_INT (intval >> 16);
2124 return "add.w\t%2,%e0";
2125 }
2126 }
2127
2128 return "add.l\t%S2,%S0";
2129 }
2130}
2131
2132unsigned int
cb713a8d 2133compute_plussi_length (rtx *operands)
7d6ac401
KH
2134{
2135 enum machine_mode mode = GET_MODE (operands[0]);
2136
2137 if (mode != SImode)
2138 abort ();
2139
2140 if (TARGET_H8300)
2141 {
cfedf91b
KH
2142 if (GET_CODE (operands[2]) == REG)
2143 return 6;
2144
2145 if (GET_CODE (operands[2]) == CONST_INT)
2146 {
2147 HOST_WIDE_INT n = INTVAL (operands[2]);
2148
2149 if ((n & 0xffffff) == 0)
2150 return 2;
2151 if ((n & 0xffff) == 0)
2152 return 4;
2153 if ((n & 0xff) == 0)
2154 return 6;
2155 }
2156
2157 return 8;
7d6ac401
KH
2158 }
2159 else
2160 {
2161 if (GET_CODE (operands[2]) == REG)
2162 return 2;
2163
2164 if (GET_CODE (operands[2]) == CONST_INT)
2165 {
2166 HOST_WIDE_INT intval = INTVAL (operands[2]);
2167
2168 /* See if we can finish with 2 bytes. */
2169
9ac7ebba 2170 switch ((unsigned int) intval & 0xffffffff)
7d6ac401
KH
2171 {
2172 case 0x00000001:
2173 case 0x00000002:
2174 case 0x00000004:
2175 return 2;
2176
2177 case 0xffffffff:
2178 case 0xfffffffe:
2179 case 0xfffffffc:
2180 return 2;
2181
2182 case 0x00010000:
2183 case 0x00020000:
2184 return 2;
2185
2186 case 0xffff0000:
2187 case 0xfffe0000:
2188 return 2;
2189 }
2190
2191 /* See if we can finish with 4 bytes. */
2192 if ((intval & 0xffff) == 0)
2193 return 4;
2194 }
2195
2196 return 6;
2197 }
2198}
2199
87a902e4 2200int
cb713a8d 2201compute_plussi_cc (rtx *operands)
7d6ac401
KH
2202{
2203 enum machine_mode mode = GET_MODE (operands[0]);
2204
2205 if (mode != SImode)
2206 abort ();
2207
2208 if (TARGET_H8300)
2209 {
cfedf91b 2210 return CC_CLOBBER;
7d6ac401
KH
2211 }
2212 else
2213 {
2214 if (GET_CODE (operands[2]) == REG)
2215 return CC_SET_ZN;
2216
2217 if (GET_CODE (operands[2]) == CONST_INT)
2218 {
2219 HOST_WIDE_INT intval = INTVAL (operands[2]);
2220
2221 /* See if we can finish with 2 bytes. */
2222
9ac7ebba 2223 switch ((unsigned int) intval & 0xffffffff)
7d6ac401
KH
2224 {
2225 case 0x00000001:
2226 case 0x00000002:
2227 case 0x00000004:
2228 return CC_NONE_0HIT;
2229
2230 case 0xffffffff:
2231 case 0xfffffffe:
2232 case 0xfffffffc:
2233 return CC_NONE_0HIT;
2234
2235 case 0x00010000:
2236 case 0x00020000:
2237 return CC_CLOBBER;
2238
2239 case 0xffff0000:
2240 case 0xfffe0000:
2241 return CC_CLOBBER;
2242 }
2243
2244 /* See if we can finish with 4 bytes. */
2245 if ((intval & 0xffff) == 0)
2246 return CC_CLOBBER;
2247 }
2248
2249 return CC_SET_ZN;
2250 }
2251}
2252\f
2253const char *
cb713a8d 2254output_logical_op (enum machine_mode mode, rtx *operands)
366a7b27 2255{
b42cff6b
KH
2256 /* Figure out the logical op that we need to perform. */
2257 enum rtx_code code = GET_CODE (operands[3]);
366a7b27 2258 /* Pretend that every byte is affected if both operands are registers. */
7798db98 2259 const unsigned HOST_WIDE_INT intval =
366a7b27
KH
2260 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
2261 ? INTVAL (operands[2]) : 0x55555555);
2262 /* The determinant of the algorithm. If we perform an AND, 0
2263 affects a bit. Otherwise, 1 affects a bit. */
7798db98 2264 const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
f9ac2f95
KH
2265 /* Break up DET into pieces. */
2266 const unsigned HOST_WIDE_INT b0 = (det >> 0) & 0xff;
2267 const unsigned HOST_WIDE_INT b1 = (det >> 8) & 0xff;
c5e7ce43
KH
2268 const unsigned HOST_WIDE_INT b2 = (det >> 16) & 0xff;
2269 const unsigned HOST_WIDE_INT b3 = (det >> 24) & 0xff;
f9ac2f95
KH
2270 const unsigned HOST_WIDE_INT w0 = (det >> 0) & 0xffff;
2271 const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff;
2272 int lower_half_easy_p = 0;
2273 int upper_half_easy_p = 0;
366a7b27
KH
2274 /* The name of an insn. */
2275 const char *opname;
2276 char insn_buf[100];
2277
2278 switch (code)
2279 {
2280 case AND:
2281 opname = "and";
2282 break;
2283 case IOR:
2284 opname = "or";
2285 break;
2286 case XOR:
2287 opname = "xor";
2288 break;
2289 default:
2290 abort ();
2291 }
2292
2293 switch (mode)
2294 {
2295 case HImode:
2296 /* First, see if we can finish with one insn. */
2297 if ((TARGET_H8300H || TARGET_H8300S)
c5e7ce43
KH
2298 && b0 != 0
2299 && b1 != 0)
366a7b27
KH
2300 {
2301 sprintf (insn_buf, "%s.w\t%%T2,%%T0", opname);
2302 output_asm_insn (insn_buf, operands);
2303 }
2304 else
2305 {
2306 /* Take care of the lower byte. */
c5e7ce43 2307 if (b0 != 0)
366a7b27
KH
2308 {
2309 sprintf (insn_buf, "%s\t%%s2,%%s0", opname);
2310 output_asm_insn (insn_buf, operands);
2311 }
2312 /* Take care of the upper byte. */
c5e7ce43 2313 if (b1 != 0)
366a7b27
KH
2314 {
2315 sprintf (insn_buf, "%s\t%%t2,%%t0", opname);
2316 output_asm_insn (insn_buf, operands);
2317 }
2318 }
2319 break;
2320 case SImode:
f9ac2f95
KH
2321 if (TARGET_H8300H || TARGET_H8300S)
2322 {
2323 /* Determine if the lower half can be taken care of in no more
2324 than two bytes. */
2325 lower_half_easy_p = (b0 == 0
2326 || b1 == 0
2327 || (code != IOR && w0 == 0xffff));
2328
2329 /* Determine if the upper half can be taken care of in no more
2330 than two bytes. */
2331 upper_half_easy_p = ((code != IOR && w1 == 0xffff)
2332 || (code == AND && w1 == 0xff00));
2333 }
366a7b27 2334
f9ac2f95
KH
2335 /* Check if doing everything with one insn is no worse than
2336 using multiple insns. */
366a7b27 2337 if ((TARGET_H8300H || TARGET_H8300S)
f9ac2f95 2338 && w0 != 0 && w1 != 0
472f2723
KH
2339 && !(lower_half_easy_p && upper_half_easy_p)
2340 && !(code == IOR && w1 == 0xffff
2341 && (w0 & 0x8000) != 0 && lower_half_easy_p))
366a7b27
KH
2342 {
2343 sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname);
2344 output_asm_insn (insn_buf, operands);
2345 }
2346 else
2347 {
2348 /* Take care of the lower and upper words individually. For
2349 each word, we try different methods in the order of
2350
2351 1) the special insn (in case of AND or XOR),
2352 2) the word-wise insn, and
2353 3) The byte-wise insn. */
c5e7ce43 2354 if (w0 == 0xffff
6dfa4005 2355 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
366a7b27 2356 output_asm_insn ((code == AND)
187462ac 2357 ? "sub.w\t%f0,%f0" : "not.w\t%f0",
366a7b27
KH
2358 operands);
2359 else if ((TARGET_H8300H || TARGET_H8300S)
c5e7ce43
KH
2360 && (b0 != 0)
2361 && (b1 != 0))
366a7b27
KH
2362 {
2363 sprintf (insn_buf, "%s.w\t%%f2,%%f0", opname);
2364 output_asm_insn (insn_buf, operands);
2365 }
2366 else
2367 {
c5e7ce43 2368 if (b0 != 0)
366a7b27
KH
2369 {
2370 sprintf (insn_buf, "%s\t%%w2,%%w0", opname);
2371 output_asm_insn (insn_buf, operands);
2372 }
c5e7ce43 2373 if (b1 != 0)
366a7b27
KH
2374 {
2375 sprintf (insn_buf, "%s\t%%x2,%%x0", opname);
2376 output_asm_insn (insn_buf, operands);
2377 }
2378 }
2379
c5e7ce43 2380 if ((w1 == 0xffff)
6dfa4005 2381 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
366a7b27 2382 output_asm_insn ((code == AND)
187462ac 2383 ? "sub.w\t%e0,%e0" : "not.w\t%e0",
366a7b27 2384 operands);
472f2723
KH
2385 else if ((TARGET_H8300H || TARGET_H8300S)
2386 && code == IOR
2387 && w1 == 0xffff
2388 && (w0 & 0x8000) != 0)
2389 {
2390 output_asm_insn ("exts.l\t%S0", operands);
2391 }
a6e8d113
KH
2392 else if ((TARGET_H8300H || TARGET_H8300S)
2393 && code == AND
c5e7ce43 2394 && w1 == 0xff00)
a6e8d113 2395 {
dc5f17ec 2396 output_asm_insn ("extu.w\t%e0", operands);
a6e8d113 2397 }
366a7b27
KH
2398 else if (TARGET_H8300H || TARGET_H8300S)
2399 {
c5e7ce43 2400 if (w1 != 0)
366a7b27
KH
2401 {
2402 sprintf (insn_buf, "%s.w\t%%e2,%%e0", opname);
2403 output_asm_insn (insn_buf, operands);
2404 }
2405 }
2406 else
2407 {
c5e7ce43 2408 if (b2 != 0)
366a7b27
KH
2409 {
2410 sprintf (insn_buf, "%s\t%%y2,%%y0", opname);
2411 output_asm_insn (insn_buf, operands);
2412 }
c5e7ce43 2413 if (b3 != 0)
366a7b27
KH
2414 {
2415 sprintf (insn_buf, "%s\t%%z2,%%z0", opname);
2416 output_asm_insn (insn_buf, operands);
2417 }
2418 }
2419 }
2420 break;
2421 default:
2422 abort ();
2423 }
2424 return "";
2425}
40367e2d
KH
2426
2427unsigned int
cb713a8d 2428compute_logical_op_length (enum machine_mode mode, rtx *operands)
40367e2d 2429{
b42cff6b
KH
2430 /* Figure out the logical op that we need to perform. */
2431 enum rtx_code code = GET_CODE (operands[3]);
40367e2d 2432 /* Pretend that every byte is affected if both operands are registers. */
7798db98 2433 const unsigned HOST_WIDE_INT intval =
40367e2d
KH
2434 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
2435 ? INTVAL (operands[2]) : 0x55555555);
2436 /* The determinant of the algorithm. If we perform an AND, 0
2437 affects a bit. Otherwise, 1 affects a bit. */
7798db98 2438 const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
f9ac2f95
KH
2439 /* Break up DET into pieces. */
2440 const unsigned HOST_WIDE_INT b0 = (det >> 0) & 0xff;
2441 const unsigned HOST_WIDE_INT b1 = (det >> 8) & 0xff;
c5e7ce43
KH
2442 const unsigned HOST_WIDE_INT b2 = (det >> 16) & 0xff;
2443 const unsigned HOST_WIDE_INT b3 = (det >> 24) & 0xff;
f9ac2f95
KH
2444 const unsigned HOST_WIDE_INT w0 = (det >> 0) & 0xffff;
2445 const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff;
2446 int lower_half_easy_p = 0;
2447 int upper_half_easy_p = 0;
40367e2d
KH
2448 /* Insn length. */
2449 unsigned int length = 0;
2450
2451 switch (mode)
2452 {
2453 case HImode:
2454 /* First, see if we can finish with one insn. */
2455 if ((TARGET_H8300H || TARGET_H8300S)
c5e7ce43
KH
2456 && b0 != 0
2457 && b1 != 0)
40367e2d
KH
2458 {
2459 if (REG_P (operands[2]))
2460 length += 2;
2461 else
2462 length += 4;
2463 }
2464 else
2465 {
2466 /* Take care of the lower byte. */
c5e7ce43 2467 if (b0 != 0)
40367e2d
KH
2468 length += 2;
2469
2470 /* Take care of the upper byte. */
c5e7ce43 2471 if (b1 != 0)
40367e2d
KH
2472 length += 2;
2473 }
2474 break;
2475 case SImode:
f9ac2f95
KH
2476 if (TARGET_H8300H || TARGET_H8300S)
2477 {
2478 /* Determine if the lower half can be taken care of in no more
2479 than two bytes. */
2480 lower_half_easy_p = (b0 == 0
2481 || b1 == 0
2482 || (code != IOR && w0 == 0xffff));
2483
2484 /* Determine if the upper half can be taken care of in no more
2485 than two bytes. */
2486 upper_half_easy_p = ((code != IOR && w1 == 0xffff)
2487 || (code == AND && w1 == 0xff00));
2488 }
40367e2d 2489
f9ac2f95
KH
2490 /* Check if doing everything with one insn is no worse than
2491 using multiple insns. */
40367e2d 2492 if ((TARGET_H8300H || TARGET_H8300S)
f9ac2f95 2493 && w0 != 0 && w1 != 0
472f2723
KH
2494 && !(lower_half_easy_p && upper_half_easy_p)
2495 && !(code == IOR && w1 == 0xffff
2496 && (w0 & 0x8000) != 0 && lower_half_easy_p))
40367e2d
KH
2497 {
2498 if (REG_P (operands[2]))
2499 length += 4;
2500 else
2501 length += 6;
2502 }
2503 else
2504 {
2505 /* Take care of the lower and upper words individually. For
2506 each word, we try different methods in the order of
2507
2508 1) the special insn (in case of AND or XOR),
2509 2) the word-wise insn, and
2510 3) The byte-wise insn. */
c5e7ce43 2511 if (w0 == 0xffff
40367e2d
KH
2512 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
2513 {
2514 length += 2;
2515 }
2516 else if ((TARGET_H8300H || TARGET_H8300S)
c5e7ce43
KH
2517 && (b0 != 0)
2518 && (b1 != 0))
40367e2d
KH
2519 {
2520 length += 4;
2521 }
2522 else
2523 {
c5e7ce43 2524 if (b0 != 0)
40367e2d
KH
2525 length += 2;
2526
c5e7ce43 2527 if (b1 != 0)
40367e2d
KH
2528 length += 2;
2529 }
2530
c5e7ce43 2531 if (w1 == 0xffff
40367e2d
KH
2532 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
2533 {
2534 length += 2;
2535 }
472f2723
KH
2536 else if ((TARGET_H8300H || TARGET_H8300S)
2537 && code == IOR
2538 && w1 == 0xffff
2539 && (w0 & 0x8000) != 0)
2540 {
2541 length += 2;
2542 }
a6e8d113
KH
2543 else if ((TARGET_H8300H || TARGET_H8300S)
2544 && code == AND
c5e7ce43 2545 && w1 == 0xff00)
a6e8d113
KH
2546 {
2547 length += 2;
2548 }
40367e2d
KH
2549 else if (TARGET_H8300H || TARGET_H8300S)
2550 {
c5e7ce43 2551 if (w1 != 0)
40367e2d
KH
2552 length += 4;
2553 }
2554 else
2555 {
c5e7ce43 2556 if (b2 != 0)
40367e2d
KH
2557 length += 2;
2558
c5e7ce43 2559 if (b3 != 0)
40367e2d
KH
2560 length += 2;
2561 }
2562 }
2563 break;
2564 default:
2565 abort ();
2566 }
2567 return length;
2568}
b42cff6b
KH
2569
2570int
cb713a8d 2571compute_logical_op_cc (enum machine_mode mode, rtx *operands)
b42cff6b
KH
2572{
2573 /* Figure out the logical op that we need to perform. */
2574 enum rtx_code code = GET_CODE (operands[3]);
2575 /* Pretend that every byte is affected if both operands are registers. */
7798db98 2576 const unsigned HOST_WIDE_INT intval =
b42cff6b
KH
2577 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
2578 ? INTVAL (operands[2]) : 0x55555555);
2579 /* The determinant of the algorithm. If we perform an AND, 0
2580 affects a bit. Otherwise, 1 affects a bit. */
7798db98 2581 const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
f9ac2f95
KH
2582 /* Break up DET into pieces. */
2583 const unsigned HOST_WIDE_INT b0 = (det >> 0) & 0xff;
2584 const unsigned HOST_WIDE_INT b1 = (det >> 8) & 0xff;
2585 const unsigned HOST_WIDE_INT w0 = (det >> 0) & 0xffff;
2586 const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff;
2587 int lower_half_easy_p = 0;
2588 int upper_half_easy_p = 0;
b42cff6b
KH
2589 /* Condition code. */
2590 enum attr_cc cc = CC_CLOBBER;
2591
2592 switch (mode)
2593 {
2594 case HImode:
2595 /* First, see if we can finish with one insn. */
2596 if ((TARGET_H8300H || TARGET_H8300S)
c5e7ce43
KH
2597 && b0 != 0
2598 && b1 != 0)
b42cff6b
KH
2599 {
2600 cc = CC_SET_ZNV;
2601 }
2602 break;
2603 case SImode:
f9ac2f95
KH
2604 if (TARGET_H8300H || TARGET_H8300S)
2605 {
2606 /* Determine if the lower half can be taken care of in no more
2607 than two bytes. */
2608 lower_half_easy_p = (b0 == 0
2609 || b1 == 0
2610 || (code != IOR && w0 == 0xffff));
2611
2612 /* Determine if the upper half can be taken care of in no more
2613 than two bytes. */
2614 upper_half_easy_p = ((code != IOR && w1 == 0xffff)
2615 || (code == AND && w1 == 0xff00));
2616 }
b42cff6b 2617
f9ac2f95
KH
2618 /* Check if doing everything with one insn is no worse than
2619 using multiple insns. */
b42cff6b 2620 if ((TARGET_H8300H || TARGET_H8300S)
f9ac2f95 2621 && w0 != 0 && w1 != 0
472f2723
KH
2622 && !(lower_half_easy_p && upper_half_easy_p)
2623 && !(code == IOR && w1 == 0xffff
2624 && (w0 & 0x8000) != 0 && lower_half_easy_p))
b42cff6b
KH
2625 {
2626 cc = CC_SET_ZNV;
2627 }
472f2723
KH
2628 else
2629 {
2630 if ((TARGET_H8300H || TARGET_H8300S)
2631 && code == IOR
2632 && w1 == 0xffff
2633 && (w0 & 0x8000) != 0)
2634 {
2635 cc = CC_SET_ZNV;
2636 }
2637 }
b42cff6b
KH
2638 break;
2639 default:
2640 abort ();
2641 }
2642 return cc;
2643}
366a7b27 2644\f
48837e29
DE
2645/* Shifts.
2646
005e3e05
KH
2647 We devote a fair bit of code to getting efficient shifts since we
2648 can only shift one bit at a time on the H8/300 and H8/300H and only
3db11b5c 2649 one or two bits at a time on the H8S.
005e3e05
KH
2650
2651 All shift code falls into one of the following ways of
2652 implementation:
2653
2654 o SHIFT_INLINE: Emit straight line code for the shift; this is used
2655 when a straight line shift is about the same size or smaller than
2656 a loop.
2657
2658 o SHIFT_ROT_AND: Rotate the value the opposite direction, then mask
2659 off the bits we don't need. This is used when only a few of the
2660 bits in the original value will survive in the shifted value.
2661
2662 o SHIFT_SPECIAL: Often it's possible to move a byte or a word to
2663 simulate a shift by 8, 16, or 24 bits. Once moved, a few inline
2664 shifts can be added if the shift count is slightly more than 8 or
2665 16. This case also includes other oddballs that are not worth
f411c849 2666 explaining here.
005e3e05 2667
3db11b5c 2668 o SHIFT_LOOP: Emit a loop using one (or two on H8S) bit shifts.
005e3e05 2669
5ec0b66e
KH
2670 For each shift count, we try to use code that has no trade-off
2671 between code size and speed whenever possible.
2672
2673 If the trade-off is unavoidable, we try to be reasonable.
2674 Specifically, the fastest version is one instruction longer than
2675 the shortest version, we take the fastest version. We also provide
2676 the use a way to switch back to the shortest version with -Os.
2677
2678 For the details of the shift algorithms for various shift counts,
2679 refer to shift_alg_[qhs]i. */
07aae5c2
SC
2680
2681int
cb713a8d 2682nshift_operator (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
48837e29
DE
2683{
2684 switch (GET_CODE (x))
2685 {
2686 case ASHIFTRT:
2687 case LSHIFTRT:
2688 case ASHIFT:
2689 return 1;
2690
2691 default:
2692 return 0;
2693 }
2694}
2695
317d21e9 2696/* Emit code to do shifts. */
48837e29 2697
317d21e9 2698void
cb713a8d 2699expand_a_shift (enum machine_mode mode, int code, rtx operands[])
07aae5c2 2700{
07aae5c2
SC
2701 emit_move_insn (operands[0], operands[1]);
2702
07e4d94e
KH
2703 /* Need a loop to get all the bits we want - we generate the
2704 code at emit time, but need to allocate a scratch reg now. */
48837e29 2705
c5c76735
JL
2706 emit_insn (gen_rtx_PARALLEL
2707 (VOIDmode,
48837e29 2708 gen_rtvec (2,
c5c76735
JL
2709 gen_rtx_SET (VOIDmode, operands[0],
2710 gen_rtx (code, mode, operands[0],
2711 operands[2])),
2712 gen_rtx_CLOBBER (VOIDmode,
2713 gen_rtx_SCRATCH (QImode)))));
48837e29
DE
2714}
2715
48837e29
DE
2716/* Symbols of the various modes which can be used as indices. */
2717
2718enum shift_mode
1a63219b
KH
2719{
2720 QIshift, HIshift, SIshift
2721};
48837e29 2722
269c14e1
DE
2723/* For single bit shift insns, record assembler and what bits of the
2724 condition code are valid afterwards (represented as various CC_FOO
2725 bits, 0 means CC isn't left in a usable state). */
48837e29
DE
2726
2727struct shift_insn
2728{
8b60264b
KG
2729 const char *const assembler;
2730 const int cc_valid;
48837e29
DE
2731};
2732
2733/* Assembler instruction shift table.
2734
2735 These tables are used to look up the basic shifts.
07e4d94e 2736 They are indexed by cpu, shift_type, and mode. */
07aae5c2 2737
48837e29
DE
2738static const struct shift_insn shift_one[2][3][3] =
2739{
2740/* H8/300 */
2741 {
2742/* SHIFT_ASHIFT */
2743 {
45ca2106
KH
2744 { "shll\t%X0", CC_SET_ZNV },
2745 { "add.w\t%T0,%T0", CC_SET_ZN },
2746 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", CC_CLOBBER }
48837e29
DE
2747 },
2748/* SHIFT_LSHIFTRT */
2749 {
45ca2106
KH
2750 { "shlr\t%X0", CC_SET_ZNV },
2751 { "shlr\t%t0\n\trotxr\t%s0", CC_CLOBBER },
2752 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", CC_CLOBBER }
48837e29
DE
2753 },
2754/* SHIFT_ASHIFTRT */
2755 {
45ca2106
KH
2756 { "shar\t%X0", CC_SET_ZNV },
2757 { "shar\t%t0\n\trotxr\t%s0", CC_CLOBBER },
2758 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", CC_CLOBBER }
48837e29
DE
2759 }
2760 },
2761/* H8/300H */
2762 {
2763/* SHIFT_ASHIFT */
2764 {
45ca2106
KH
2765 { "shll.b\t%X0", CC_SET_ZNV },
2766 { "shll.w\t%T0", CC_SET_ZNV },
2767 { "shll.l\t%S0", CC_SET_ZNV }
48837e29
DE
2768 },
2769/* SHIFT_LSHIFTRT */
2770 {
45ca2106
KH
2771 { "shlr.b\t%X0", CC_SET_ZNV },
2772 { "shlr.w\t%T0", CC_SET_ZNV },
2773 { "shlr.l\t%S0", CC_SET_ZNV }
48837e29
DE
2774 },
2775/* SHIFT_ASHIFTRT */
2776 {
45ca2106
KH
2777 { "shar.b\t%X0", CC_SET_ZNV },
2778 { "shar.w\t%T0", CC_SET_ZNV },
2779 { "shar.l\t%S0", CC_SET_ZNV }
48837e29
DE
2780 }
2781 }
2782};
07aae5c2 2783
51c0c1d7
JL
2784static const struct shift_insn shift_two[3][3] =
2785{
2786/* SHIFT_ASHIFT */
2787 {
45ca2106
KH
2788 { "shll.b\t#2,%X0", CC_SET_ZNV },
2789 { "shll.w\t#2,%T0", CC_SET_ZNV },
2790 { "shll.l\t#2,%S0", CC_SET_ZNV }
51c0c1d7
JL
2791 },
2792/* SHIFT_LSHIFTRT */
2793 {
45ca2106
KH
2794 { "shlr.b\t#2,%X0", CC_SET_ZNV },
2795 { "shlr.w\t#2,%T0", CC_SET_ZNV },
2796 { "shlr.l\t#2,%S0", CC_SET_ZNV }
51c0c1d7
JL
2797 },
2798/* SHIFT_ASHIFTRT */
2799 {
45ca2106
KH
2800 { "shar.b\t#2,%X0", CC_SET_ZNV },
2801 { "shar.w\t#2,%T0", CC_SET_ZNV },
2802 { "shar.l\t#2,%S0", CC_SET_ZNV }
51c0c1d7
JL
2803 }
2804};
2805
48837e29
DE
2806/* Rotates are organized by which shift they'll be used in implementing.
2807 There's no need to record whether the cc is valid afterwards because
2808 it is the AND insn that will decide this. */
07aae5c2 2809
48837e29
DE
2810static const char *const rotate_one[2][3][3] =
2811{
2812/* H8/300 */
2813 {
2814/* SHIFT_ASHIFT */
2815 {
51c0c1d7
JL
2816 "rotr\t%X0",
2817 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
48837e29
DE
2818 0
2819 },
2820/* SHIFT_LSHIFTRT */
2821 {
51c0c1d7
JL
2822 "rotl\t%X0",
2823 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
48837e29
DE
2824 0
2825 },
2826/* SHIFT_ASHIFTRT */
2827 {
51c0c1d7
JL
2828 "rotl\t%X0",
2829 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
48837e29 2830 0
07aae5c2 2831 }
48837e29
DE
2832 },
2833/* H8/300H */
2834 {
2835/* SHIFT_ASHIFT */
2836 {
51c0c1d7
JL
2837 "rotr.b\t%X0",
2838 "rotr.w\t%T0",
2839 "rotr.l\t%S0"
48837e29
DE
2840 },
2841/* SHIFT_LSHIFTRT */
07aae5c2 2842 {
51c0c1d7
JL
2843 "rotl.b\t%X0",
2844 "rotl.w\t%T0",
2845 "rotl.l\t%S0"
48837e29
DE
2846 },
2847/* SHIFT_ASHIFTRT */
2848 {
51c0c1d7
JL
2849 "rotl.b\t%X0",
2850 "rotl.w\t%T0",
2851 "rotl.l\t%S0"
48837e29
DE
2852 }
2853 }
2854};
2855
51c0c1d7
JL
2856static const char *const rotate_two[3][3] =
2857{
2858/* SHIFT_ASHIFT */
2859 {
2860 "rotr.b\t#2,%X0",
2861 "rotr.w\t#2,%T0",
2862 "rotr.l\t#2,%S0"
2863 },
2864/* SHIFT_LSHIFTRT */
2865 {
2866 "rotl.b\t#2,%X0",
2867 "rotl.w\t#2,%T0",
2868 "rotl.l\t#2,%S0"
2869 },
2870/* SHIFT_ASHIFTRT */
2871 {
2872 "rotl.b\t#2,%X0",
2873 "rotl.w\t#2,%T0",
2874 "rotl.l\t#2,%S0"
2875 }
2876};
2877
35fb3d1f
KH
2878struct shift_info {
2879 /* Shift algorithm. */
2880 enum shift_alg alg;
2881
2882 /* The number of bits to be shifted by shift1 and shift2. Valid
2883 when ALG is SHIFT_SPECIAL. */
2884 unsigned int remainder;
2885
2886 /* Special insn for a shift. Valid when ALG is SHIFT_SPECIAL. */
2887 const char *special;
2888
2889 /* Insn for a one-bit shift. Valid when ALG is either SHIFT_INLINE
9cd10576 2890 or SHIFT_SPECIAL, and REMAINDER is nonzero. */
35fb3d1f
KH
2891 const char *shift1;
2892
2893 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
9cd10576 2894 or SHIFT_SPECIAL, and REMAINDER is nonzero. */
35fb3d1f
KH
2895 const char *shift2;
2896
45ca2106
KH
2897 /* CC status for SHIFT_INLINE. */
2898 int cc_inline;
2899
2900 /* CC status for SHIFT_SPECIAL. */
2901 int cc_special;
35fb3d1f
KH
2902};
2903
cb713a8d
KH
2904static void get_shift_alg (enum shift_type,
2905 enum shift_mode, unsigned int,
2906 struct shift_info *);
441d04c6 2907
c009a745
KH
2908/* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
2909 best algorithm for doing the shift. The assembler code is stored
5ec0b66e
KH
2910 in the pointers in INFO. We achieve the maximum efficiency in most
2911 cases when !TARGET_H8300. In case of TARGET_H8300, shifts in
2912 SImode in particular have a lot of room to optimize.
2913
2914 We first determine the strategy of the shift algorithm by a table
2915 lookup. If that tells us to use a hand crafted assembly code, we
2916 go into the big switch statement to find what that is. Otherwise,
2917 we resort to a generic way, such as inlining. In either case, the
2918 result is returned through INFO. */
48837e29 2919
cb33eb17 2920static void
cb713a8d
KH
2921get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
2922 unsigned int count, struct shift_info *info)
48837e29 2923{
b9b575e6 2924 enum h8_cpu cpu;
769828ab
KH
2925
2926 /* Find the target CPU. */
2927 if (TARGET_H8300)
b9b575e6 2928 cpu = H8_300;
769828ab 2929 else if (TARGET_H8300H)
b9b575e6 2930 cpu = H8_300H;
769828ab 2931 else
b9b575e6 2932 cpu = H8_S;
769828ab 2933
96eaf358 2934 /* Find the shift algorithm. */
b9b575e6 2935 info->alg = SHIFT_LOOP;
48837e29
DE
2936 switch (shift_mode)
2937 {
2938 case QIshift:
b9b575e6 2939 if (count < GET_MODE_BITSIZE (QImode))
96eaf358
KH
2940 info->alg = shift_alg_qi[cpu][shift_type][count];
2941 break;
769828ab 2942
96eaf358 2943 case HIshift:
b9b575e6 2944 if (count < GET_MODE_BITSIZE (HImode))
96eaf358
KH
2945 info->alg = shift_alg_hi[cpu][shift_type][count];
2946 break;
2947
2948 case SIshift:
b9b575e6 2949 if (count < GET_MODE_BITSIZE (SImode))
96eaf358
KH
2950 info->alg = shift_alg_si[cpu][shift_type][count];
2951 break;
2952
2953 default:
2954 abort ();
2955 }
2956
2957 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
2958 switch (info->alg)
2959 {
2960 case SHIFT_INLINE:
2961 info->remainder = count;
2962 /* Fall through. */
2963
2964 case SHIFT_LOOP:
2965 /* It is up to the caller to know that looping clobbers cc. */
2966 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2967 info->shift2 = shift_two[shift_type][shift_mode].assembler;
45ca2106 2968 info->cc_inline = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
96eaf358
KH
2969 goto end;
2970
2971 case SHIFT_ROT_AND:
2972 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
2973 info->shift2 = rotate_two[shift_type][shift_mode];
45ca2106 2974 info->cc_inline = CC_CLOBBER;
96eaf358
KH
2975 goto end;
2976
2977 case SHIFT_SPECIAL:
2978 /* REMAINDER is 0 for most cases, so initialize it to 0. */
2979 info->remainder = 0;
2980 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2981 info->shift2 = shift_two[shift_type][shift_mode].assembler;
45ca2106
KH
2982 info->cc_inline = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
2983 info->cc_special = CC_CLOBBER;
96eaf358
KH
2984 break;
2985 }
51c0c1d7 2986
96eaf358
KH
2987 /* Here we only deal with SHIFT_SPECIAL. */
2988 switch (shift_mode)
2989 {
2990 case QIshift:
769828ab
KH
2991 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2992 through the entire value. */
2993 if (shift_type == SHIFT_ASHIFTRT && count == 7)
2994 {
2995 info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
692b7eb3 2996 goto end;
769828ab
KH
2997 }
2998 abort ();
2999
3000 case HIshift:
769828ab 3001 if (count == 7)
51c0c1d7 3002 {
a77b1dbc 3003 switch (shift_type)
51c0c1d7 3004 {
a77b1dbc
KH
3005 case SHIFT_ASHIFT:
3006 if (TARGET_H8300)
3007 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";
3008 else
3009 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
692b7eb3 3010 goto end;
a77b1dbc
KH
3011 case SHIFT_LSHIFTRT:
3012 if (TARGET_H8300)
3013 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";
3014 else
3015 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
692b7eb3 3016 goto end;
a77b1dbc 3017 case SHIFT_ASHIFTRT:
35fb3d1f 3018 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
692b7eb3 3019 goto end;
48837e29 3020 }
07aae5c2 3021 }
b30686ec 3022 else if ((8 <= count && count <= 13)
a38b3eea 3023 || (TARGET_H8300S && count == 14))
07aae5c2 3024 {
a7812c0b
KH
3025 info->remainder = count - 8;
3026
51c0c1d7 3027 switch (shift_type)
48837e29 3028 {
51c0c1d7 3029 case SHIFT_ASHIFT:
35fb3d1f 3030 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
692b7eb3 3031 goto end;
51c0c1d7 3032 case SHIFT_LSHIFTRT:
a7612343
KH
3033 if (TARGET_H8300)
3034 {
3035 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
3036 info->shift1 = "shlr.b\t%s0";
45ca2106 3037 info->cc_inline = CC_SET_ZNV;
a7612343
KH
3038 }
3039 else
3040 {
3041 info->special = "mov.b\t%t0,%s0\n\textu.w\t%T0";
45ca2106 3042 info->cc_special = CC_SET_ZNV;
a7612343 3043 }
692b7eb3 3044 goto end;
51c0c1d7
JL
3045 case SHIFT_ASHIFTRT:
3046 if (TARGET_H8300)
a7612343
KH
3047 {
3048 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
3049 info->shift1 = "shar.b\t%s0";
a7612343 3050 }
51c0c1d7 3051 else
a7612343
KH
3052 {
3053 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
45ca2106 3054 info->cc_special = CC_SET_ZNV;
a7612343 3055 }
692b7eb3 3056 goto end;
51c0c1d7
JL
3057 }
3058 }
5e98fba2
DD
3059 else if (count == 14)
3060 {
3061 switch (shift_type)
3062 {
3063 case SHIFT_ASHIFT:
3064 if (TARGET_H8300)
3065 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";
3066 goto end;
3067 case SHIFT_LSHIFTRT:
3068 if (TARGET_H8300)
3069 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";
3070 goto end;
3071 case SHIFT_ASHIFTRT:
3072 if (TARGET_H8300)
3073 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";
3074 else if (TARGET_H8300H)
45ca2106
KH
3075 {
3076 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";
3077 info->cc_special = CC_SET_ZNV;
3078 }
5e98fba2 3079 else /* TARGET_H8300S */
b30686ec 3080 abort ();
5e98fba2
DD
3081 goto end;
3082 }
3083 }
1e41e866 3084 else if (count == 15)
51c0c1d7 3085 {
1e41e866
KH
3086 switch (shift_type)
3087 {
3088 case SHIFT_ASHIFT:
3089 info->special = "bld\t#0,%s0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#7,%t0";
3090 goto end;
3091 case SHIFT_LSHIFTRT:
3092 info->special = "bld\t#7,%t0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#0,%s0";
3093 goto end;
3094 case SHIFT_ASHIFTRT:
3095 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
3096 goto end;
3097 }
07aae5c2 3098 }
769828ab 3099 abort ();
51c0c1d7 3100
48837e29 3101 case SIshift:
1e41e866 3102 if (TARGET_H8300 && 8 <= count && count <= 9)
48837e29 3103 {
1e41e866
KH
3104 info->remainder = count - 8;
3105
51c0c1d7 3106 switch (shift_type)
48837e29 3107 {
51c0c1d7 3108 case SHIFT_ASHIFT:
35fb3d1f 3109 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 3110 goto end;
51c0c1d7 3111 case SHIFT_LSHIFTRT:
35fb3d1f 3112 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 3113 info->shift1 = "shlr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0";
692b7eb3 3114 goto end;
51c0c1d7 3115 case SHIFT_ASHIFTRT:
35fb3d1f 3116 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 3117 goto end;
48837e29 3118 }
48837e29 3119 }
e6bcfef9
JS
3120 else if (count == 8 && !TARGET_H8300)
3121 {
3122 switch (shift_type)
3123 {
3124 case SHIFT_ASHIFT:
35fb3d1f 3125 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 3126 goto end;
e6bcfef9 3127 case SHIFT_LSHIFTRT:
35fb3d1f 3128 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 3129 goto end;
e6bcfef9 3130 case SHIFT_ASHIFTRT:
35fb3d1f 3131 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 3132 goto end;
e6bcfef9
JS
3133 }
3134 }
1e41e866
KH
3135 else if (count == 15 && TARGET_H8300)
3136 {
3137 switch (shift_type)
3138 {
3139 case SHIFT_ASHIFT:
3140 abort ();
3141 case SHIFT_LSHIFTRT:
a35abc3c 3142 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
3143 goto end;
3144 case SHIFT_ASHIFTRT:
a35abc3c 3145 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
3146 goto end;
3147 }
3148 }
dd69e230
KH
3149 else if (count == 15 && !TARGET_H8300)
3150 {
3151 switch (shift_type)
3152 {
3153 case SHIFT_ASHIFT:
3154 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
45ca2106 3155 info->cc_special = CC_SET_ZNV;
dd69e230
KH
3156 goto end;
3157 case SHIFT_LSHIFTRT:
18cf8dda 3158 info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
45ca2106 3159 info->cc_special = CC_SET_ZNV;
dd69e230 3160 goto end;
aefc5826
KH
3161 case SHIFT_ASHIFTRT:
3162 abort ();
dd69e230
KH
3163 }
3164 }
1e41e866 3165 else if ((TARGET_H8300 && 16 <= count && count <= 20)
a7812c0b 3166 || (TARGET_H8300H && 16 <= count && count <= 19)
e0f19bd0 3167 || (TARGET_H8300S && 16 <= count && count <= 21))
48837e29 3168 {
a7812c0b
KH
3169 info->remainder = count - 16;
3170
48837e29
DE
3171 switch (shift_type)
3172 {
3173 case SHIFT_ASHIFT:
35fb3d1f 3174 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
1e41e866 3175 if (TARGET_H8300)
b30686ec 3176 info->shift1 = "add.w\t%e0,%e0";
692b7eb3 3177 goto end;
51c0c1d7 3178 case SHIFT_LSHIFTRT:
1e41e866
KH
3179 if (TARGET_H8300)
3180 {
a7612343
KH
3181 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
3182 info->shift1 = "shlr\t%x0\n\trotxr\t%w0";
1e41e866
KH
3183 }
3184 else
3185 {
a7612343 3186 info->special = "mov.w\t%e0,%f0\n\textu.l\t%S0";
45ca2106 3187 info->cc_special = CC_SET_ZNV;
1e41e866 3188 }
692b7eb3 3189 goto end;
51c0c1d7
JL
3190 case SHIFT_ASHIFTRT:
3191 if (TARGET_H8300)
1e41e866
KH
3192 {
3193 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
3194 info->shift1 = "shar\t%x0\n\trotxr\t%w0";
3195 }
51c0c1d7 3196 else
1e41e866
KH
3197 {
3198 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
45ca2106 3199 info->cc_special = CC_SET_ZNV;
1e41e866 3200 }
692b7eb3 3201 goto end;
51c0c1d7
JL
3202 }
3203 }
1e41e866 3204 else if (TARGET_H8300 && 24 <= count && count <= 28)
f9477efd
KH
3205 {
3206 info->remainder = count - 24;
f0b6f9a6 3207
f9477efd
KH
3208 switch (shift_type)
3209 {
3210 case SHIFT_ASHIFT:
3211 info->special = "mov.b\t%w0,%z0\n\tsub.b\t%y0,%y0\n\tsub.w\t%f0,%f0";
3212 info->shift1 = "shll.b\t%z0";
45ca2106 3213 info->cc_inline = CC_SET_ZNV;
f9477efd
KH
3214 goto end;
3215 case SHIFT_LSHIFTRT:
3216 info->special = "mov.b\t%z0,%w0\n\tsub.b\t%x0,%x0\n\tsub.w\t%e0,%e0";
3217 info->shift1 = "shlr.b\t%w0";
45ca2106 3218 info->cc_inline = CC_SET_ZNV;
f9477efd
KH
3219 goto end;
3220 case SHIFT_ASHIFTRT:
3221 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";
3222 info->shift1 = "shar.b\t%w0";
45ca2106 3223 info->cc_inline = CC_SET_ZNV;
7f473594
KH
3224 goto end;
3225 }
3226 }
4a4ae922
KH
3227 else if ((TARGET_H8300H && count == 24)
3228 || (TARGET_H8300S && 24 <= count && count <= 25))
e6bcfef9 3229 {
4a4ae922
KH
3230 info->remainder = count - 24;
3231
e6bcfef9
JS
3232 switch (shift_type)
3233 {
3234 case SHIFT_ASHIFT:
35fb3d1f 3235 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 3236 goto end;
e6bcfef9 3237 case SHIFT_LSHIFTRT:
35fb3d1f 3238 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
45ca2106 3239 info->cc_special = CC_SET_ZNV;
692b7eb3 3240 goto end;
e6bcfef9 3241 case SHIFT_ASHIFTRT:
35fb3d1f 3242 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
45ca2106 3243 info->cc_special = CC_SET_ZNV;
692b7eb3 3244 goto end;
e6bcfef9
JS
3245 }
3246 }
1e5bdc40
KH
3247 else if (!TARGET_H8300 && count == 28)
3248 {
3249 switch (shift_type)
3250 {
3251 case SHIFT_ASHIFT:
3252 if (TARGET_H8300H)
3253 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";
3254 else
3255 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
3256 goto end;
3257 case SHIFT_LSHIFTRT:
3258 if (TARGET_H8300H)
45ca2106
KH
3259 {
3260 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";
3261 info->cc_special = CC_SET_ZNV;
3262 }
1e5bdc40 3263 else
a7612343 3264 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
3265 goto end;
3266 case SHIFT_ASHIFTRT:
3267 abort ();
3268 }
3269 }
3270 else if (!TARGET_H8300 && count == 29)
3271 {
3272 switch (shift_type)
3273 {
3274 case SHIFT_ASHIFT:
3275 if (TARGET_H8300H)
3276 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";
3277 else
3278 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
3279 goto end;
3280 case SHIFT_LSHIFTRT:
3281 if (TARGET_H8300H)
45ca2106
KH
3282 {
3283 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";
3284 info->cc_special = CC_SET_ZNV;
3285 }
1e5bdc40 3286 else
45ca2106
KH
3287 {
3288 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t%S0\n\textu.l\t%S0";
3289 info->cc_special = CC_SET_ZNV;
3290 }
1e5bdc40
KH
3291 goto end;
3292 case SHIFT_ASHIFTRT:
3293 abort ();
3294 }
3295 }
3296 else if (!TARGET_H8300 && count == 30)
3297 {
3298 switch (shift_type)
3299 {
3300 case SHIFT_ASHIFT:
3301 if (TARGET_H8300H)
3302 info->special = "sub.w\t%e0,%e0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0";
3303 else
3304 info->special = "sub.w\t%e0,%e0\n\trotr.l\t#2,%S0\n\tsub.w\t%f0,%f0";
1e5bdc40
KH
3305 goto end;
3306 case SHIFT_LSHIFTRT:
3307 if (TARGET_H8300H)
a7612343 3308 info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0";
1e5bdc40 3309 else
a7612343 3310 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\textu.l\t%S0";
1e5bdc40
KH
3311 goto end;
3312 case SHIFT_ASHIFTRT:
3313 abort ();
3314 }
3315 }
48837e29
DE
3316 else if (count == 31)
3317 {
dd69e230 3318 if (TARGET_H8300)
48837e29 3319 {
dd69e230
KH
3320 switch (shift_type)
3321 {
3322 case SHIFT_ASHIFT:
3323 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
3324 goto end;
3325 case SHIFT_LSHIFTRT:
3326 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
3327 goto end;
3328 case SHIFT_ASHIFTRT:
3329 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
3330 goto end;
3331 }
48837e29
DE
3332 }
3333 else
3334 {
dd69e230 3335 switch (shift_type)
48837e29 3336 {
dd69e230
KH
3337 case SHIFT_ASHIFT:
3338 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
45ca2106 3339 info->cc_special = CC_SET_ZNV;
dd69e230
KH
3340 goto end;
3341 case SHIFT_LSHIFTRT:
3342 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
45ca2106 3343 info->cc_special = CC_SET_ZNV;
dd69e230
KH
3344 goto end;
3345 case SHIFT_ASHIFTRT:
a7612343 3346 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\texts.w\t%T0\n\texts.l\t%S0";
45ca2106 3347 info->cc_special = CC_SET_ZNV;
692b7eb3 3348 goto end;
48837e29 3349 }
48837e29
DE
3350 }
3351 }
769828ab 3352 abort ();
51c0c1d7 3353
48837e29
DE
3354 default:
3355 abort ();
07aae5c2 3356 }
48837e29 3357
cb33eb17
KH
3358 end:
3359 if (!TARGET_H8300S)
3360 info->shift2 = NULL;
07aae5c2
SC
3361}
3362
be1e06df
KH
3363/* Given COUNT and MODE of a shift, return 1 if a scratch reg may be
3364 needed for some shift with COUNT and MODE. Return 0 otherwise. */
3365
3366int
cb713a8d 3367h8300_shift_needs_scratch_p (int count, enum machine_mode mode)
be1e06df 3368{
b9b575e6 3369 enum h8_cpu cpu;
be1e06df
KH
3370 int a, lr, ar;
3371
3372 if (GET_MODE_BITSIZE (mode) <= count)
3373 return 1;
3374
3375 /* Find out the target CPU. */
3376 if (TARGET_H8300)
b9b575e6 3377 cpu = H8_300;
be1e06df 3378 else if (TARGET_H8300H)
b9b575e6 3379 cpu = H8_300H;
be1e06df 3380 else
b9b575e6 3381 cpu = H8_S;
be1e06df
KH
3382
3383 /* Find the shift algorithm. */
3384 switch (mode)
3385 {
3386 case QImode:
3387 a = shift_alg_qi[cpu][SHIFT_ASHIFT][count];
3388 lr = shift_alg_qi[cpu][SHIFT_LSHIFTRT][count];
3389 ar = shift_alg_qi[cpu][SHIFT_ASHIFTRT][count];
3390 break;
3391
3392 case HImode:
3393 a = shift_alg_hi[cpu][SHIFT_ASHIFT][count];
3394 lr = shift_alg_hi[cpu][SHIFT_LSHIFTRT][count];
3395 ar = shift_alg_hi[cpu][SHIFT_ASHIFTRT][count];
3396 break;
3397
3398 case SImode:
3399 a = shift_alg_si[cpu][SHIFT_ASHIFT][count];
3400 lr = shift_alg_si[cpu][SHIFT_LSHIFTRT][count];
3401 ar = shift_alg_si[cpu][SHIFT_ASHIFTRT][count];
3402 break;
3403
3404 default:
3405 abort ();
3406 }
3407
aa2fb4dd 3408 /* On H8/300H, count == 8 uses a scratch register. */
be1e06df 3409 return (a == SHIFT_LOOP || lr == SHIFT_LOOP || ar == SHIFT_LOOP
75a3503b 3410 || (TARGET_H8300H && mode == SImode && count == 8));
be1e06df
KH
3411}
3412
48837e29
DE
3413/* Emit the assembler code for doing shifts. */
3414
441d04c6 3415const char *
cb713a8d 3416output_a_shift (rtx *operands)
07aae5c2 3417{
48837e29 3418 static int loopend_lab;
48837e29
DE
3419 rtx shift = operands[3];
3420 enum machine_mode mode = GET_MODE (shift);
3421 enum rtx_code code = GET_CODE (shift);
3422 enum shift_type shift_type;
3423 enum shift_mode shift_mode;
35fb3d1f 3424 struct shift_info info;
48837e29
DE
3425
3426 loopend_lab++;
3427
3428 switch (mode)
3429 {
3430 case QImode:
3431 shift_mode = QIshift;
3432 break;
3433 case HImode:
3434 shift_mode = HIshift;
3435 break;
3436 case SImode:
3437 shift_mode = SIshift;
3438 break;
3439 default:
3440 abort ();
3441 }
07aae5c2 3442
48837e29 3443 switch (code)
07aae5c2 3444 {
48837e29
DE
3445 case ASHIFTRT:
3446 shift_type = SHIFT_ASHIFTRT;
3447 break;
3448 case LSHIFTRT:
3449 shift_type = SHIFT_LSHIFTRT;
3450 break;
3451 case ASHIFT:
3452 shift_type = SHIFT_ASHIFT;
3453 break;
3454 default:
3455 abort ();
3456 }
07aae5c2 3457
48837e29
DE
3458 if (GET_CODE (operands[2]) != CONST_INT)
3459 {
cd9b5ca8
KH
3460 /* This case must be taken care of by one of the two splitters
3461 that convert a variable shift into a loop. */
3462 abort ();
48837e29
DE
3463 }
3464 else
3465 {
3466 int n = INTVAL (operands[2]);
48837e29
DE
3467
3468 /* If the count is negative, make it 0. */
3469 if (n < 0)
3470 n = 0;
3471 /* If the count is too big, truncate it.
3472 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
3473 do the intuitive thing. */
64530b82 3474 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
48837e29
DE
3475 n = GET_MODE_BITSIZE (mode);
3476
cb33eb17 3477 get_shift_alg (shift_type, shift_mode, n, &info);
48837e29 3478
cb33eb17 3479 switch (info.alg)
48837e29 3480 {
cb33eb17
KH
3481 case SHIFT_SPECIAL:
3482 output_asm_insn (info.special, operands);
3483 /* Fall through. */
3484
48837e29 3485 case SHIFT_INLINE:
cb33eb17
KH
3486 n = info.remainder;
3487
51c0c1d7 3488 /* Emit two bit shifts first. */
1a275226 3489 if (info.shift2 != NULL)
51c0c1d7 3490 {
1a275226
KH
3491 for (; n > 1; n -= 2)
3492 output_asm_insn (info.shift2, operands);
51c0c1d7
JL
3493 }
3494
3495 /* Now emit one bit shifts for any residual. */
1a275226
KH
3496 for (; n > 0; n--)
3497 output_asm_insn (info.shift1, operands);
48837e29 3498 return "";
51c0c1d7 3499
48837e29
DE
3500 case SHIFT_ROT_AND:
3501 {
3502 int m = GET_MODE_BITSIZE (mode) - n;
7798db98
KH
3503 const int mask = (shift_type == SHIFT_ASHIFT
3504 ? ((1 << m) - 1) << n
3505 : (1 << m) - 1);
48837e29 3506 char insn_buf[200];
b5eaf9ba 3507
48837e29
DE
3508 /* Not all possibilities of rotate are supported. They shouldn't
3509 be generated, but let's watch for 'em. */
35fb3d1f 3510 if (info.shift1 == 0)
48837e29 3511 abort ();
51c0c1d7
JL
3512
3513 /* Emit two bit rotates first. */
1a275226 3514 if (info.shift2 != NULL)
51c0c1d7 3515 {
1a275226
KH
3516 for (; m > 1; m -= 2)
3517 output_asm_insn (info.shift2, operands);
51c0c1d7
JL
3518 }
3519
3520 /* Now single bit rotates for any residual. */
1a275226
KH
3521 for (; m > 0; m--)
3522 output_asm_insn (info.shift1, operands);
51c0c1d7
JL
3523
3524 /* Now mask off the high bits. */
ade53a50
KH
3525 if (mode == QImode)
3526 sprintf (insn_buf, "and\t#%d,%%X0", mask);
3527 else if (mode == HImode && (TARGET_H8300H || TARGET_H8300S))
3528 sprintf (insn_buf, "and.w\t#%d,%%T0", mask);
3529 else
3530 abort ();
3531
48837e29
DE
3532 output_asm_insn (insn_buf, operands);
3533 return "";
3534 }
b5eaf9ba 3535
b5eaf9ba
KH
3536 case SHIFT_LOOP:
3537 /* A loop to shift by a "large" constant value.
3538 If we have shift-by-2 insns, use them. */
35fb3d1f 3539 if (info.shift2 != NULL)
b5eaf9ba
KH
3540 {
3541 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
3542 names_big[REGNO (operands[4])]);
3543 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 3544 output_asm_insn (info.shift2, operands);
b5eaf9ba
KH
3545 output_asm_insn ("add #0xff,%X4", operands);
3546 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
3547 if (n % 2)
35fb3d1f 3548 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
3549 }
3550 else
3551 {
3552 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
3553 names_big[REGNO (operands[4])]);
3554 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
35fb3d1f 3555 output_asm_insn (info.shift1, operands);
b5eaf9ba
KH
3556 output_asm_insn ("add #0xff,%X4", operands);
3557 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
3558 }
51c0c1d7 3559 return "";
b5eaf9ba
KH
3560
3561 default:
3562 abort ();
51c0c1d7 3563 }
07aae5c2 3564 }
07aae5c2 3565}
86855e8c
KH
3566
3567static unsigned int
cb713a8d 3568h8300_asm_insn_count (const char *template)
86855e8c
KH
3569{
3570 unsigned int count = 1;
3571
3572 for (; *template; template++)
3573 if (*template == '\n')
3574 count++;
3575
3576 return count;
3577}
3578
3579unsigned int
cb713a8d 3580compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
86855e8c
KH
3581{
3582 rtx shift = operands[3];
3583 enum machine_mode mode = GET_MODE (shift);
3584 enum rtx_code code = GET_CODE (shift);
3585 enum shift_type shift_type;
3586 enum shift_mode shift_mode;
3587 struct shift_info info;
3588 unsigned int wlength = 0;
3589
3590 switch (mode)
3591 {
3592 case QImode:
3593 shift_mode = QIshift;
3594 break;
3595 case HImode:
3596 shift_mode = HIshift;
3597 break;
3598 case SImode:
3599 shift_mode = SIshift;
3600 break;
3601 default:
3602 abort ();
3603 }
3604
3605 switch (code)
3606 {
3607 case ASHIFTRT:
3608 shift_type = SHIFT_ASHIFTRT;
3609 break;
3610 case LSHIFTRT:
3611 shift_type = SHIFT_LSHIFTRT;
3612 break;
3613 case ASHIFT:
3614 shift_type = SHIFT_ASHIFT;
3615 break;
3616 default:
3617 abort ();
3618 }
3619
3620 if (GET_CODE (operands[2]) != CONST_INT)
3621 {
3622 /* Get the assembler code to do one shift. */
3623 get_shift_alg (shift_type, shift_mode, 1, &info);
3624
3625 return (4 + h8300_asm_insn_count (info.shift1)) * 2;
3626 }
3627 else
3628 {
3629 int n = INTVAL (operands[2]);
3630
3631 /* If the count is negative, make it 0. */
3632 if (n < 0)
3633 n = 0;
3634 /* If the count is too big, truncate it.
3635 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
3636 do the intuitive thing. */
3637 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
3638 n = GET_MODE_BITSIZE (mode);
3639
3640 get_shift_alg (shift_type, shift_mode, n, &info);
3641
3642 switch (info.alg)
3643 {
3644 case SHIFT_SPECIAL:
3645 wlength += h8300_asm_insn_count (info.special);
41c3eb5d
KH
3646
3647 /* Every assembly instruction used in SHIFT_SPECIAL case
3648 takes 2 bytes except xor.l, which takes 4 bytes, so if we
3649 see xor.l, we just pretend that xor.l counts as two insns
3650 so that the insn length will be computed correctly. */
3651 if (strstr (info.special, "xor.l") != NULL)
3652 wlength++;
3653
86855e8c
KH
3654 /* Fall through. */
3655
3656 case SHIFT_INLINE:
3657 n = info.remainder;
3658
3659 if (info.shift2 != NULL)
3660 {
3661 wlength += h8300_asm_insn_count (info.shift2) * (n / 2);
3662 n = n % 2;
3663 }
3664
3665 wlength += h8300_asm_insn_count (info.shift1) * n;
6b148bd9 3666
86855e8c
KH
3667 return 2 * wlength;
3668
3669 case SHIFT_ROT_AND:
3670 {
3671 int m = GET_MODE_BITSIZE (mode) - n;
3672
3673 /* Not all possibilities of rotate are supported. They shouldn't
3674 be generated, but let's watch for 'em. */
3675 if (info.shift1 == 0)
3676 abort ();
3677
3678 if (info.shift2 != NULL)
3679 {
3680 wlength += h8300_asm_insn_count (info.shift2) * (m / 2);
3681 m = m % 2;
3682 }
3683
3684 wlength += h8300_asm_insn_count (info.shift1) * m;
6b148bd9 3685
86855e8c
KH
3686 /* Now mask off the high bits. */
3687 switch (mode)
3688 {
3689 case QImode:
3690 wlength += 1;
3691 break;
3692 case HImode:
3693 wlength += 2;
3694 break;
3695 case SImode:
3696 if (TARGET_H8300)
3697 abort ();
3698 wlength += 3;
3699 break;
3700 default:
3701 abort ();
3702 }
3703 return 2 * wlength;
3704 }
3705
3706 case SHIFT_LOOP:
3707 /* A loop to shift by a "large" constant value.
3708 If we have shift-by-2 insns, use them. */
3709 if (info.shift2 != NULL)
3710 {
3711 wlength += 3 + h8300_asm_insn_count (info.shift2);
3712 if (n % 2)
3713 wlength += h8300_asm_insn_count (info.shift1);
3714 }
3715 else
3716 {
3717 wlength += 3 + h8300_asm_insn_count (info.shift1);
3718 }
3719 return 2 * wlength;
3720
3721 default:
3722 abort ();
3723 }
3724 }
3725}
45ca2106
KH
3726
3727int
cb713a8d 3728compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
45ca2106
KH
3729{
3730 rtx shift = operands[3];
3731 enum machine_mode mode = GET_MODE (shift);
3732 enum rtx_code code = GET_CODE (shift);
3733 enum shift_type shift_type;
3734 enum shift_mode shift_mode;
3735 struct shift_info info;
3736
3737 switch (mode)
3738 {
3739 case QImode:
3740 shift_mode = QIshift;
3741 break;
3742 case HImode:
3743 shift_mode = HIshift;
3744 break;
3745 case SImode:
3746 shift_mode = SIshift;
3747 break;
3748 default:
3749 abort ();
3750 }
3751
3752 switch (code)
3753 {
3754 case ASHIFTRT:
3755 shift_type = SHIFT_ASHIFTRT;
3756 break;
3757 case LSHIFTRT:
3758 shift_type = SHIFT_LSHIFTRT;
3759 break;
3760 case ASHIFT:
3761 shift_type = SHIFT_ASHIFT;
3762 break;
3763 default:
3764 abort ();
3765 }
3766
3767 if (GET_CODE (operands[2]) != CONST_INT)
3768 {
3769 /* This case must be taken care of by one of the two splitters
3770 that convert a variable shift into a loop. */
3771 abort ();
3772 }
3773 else
3774 {
3775 int n = INTVAL (operands[2]);
3776
3777 /* If the count is negative, make it 0. */
3778 if (n < 0)
3779 n = 0;
3780 /* If the count is too big, truncate it.
3781 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
3782 do the intuitive thing. */
3783 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
3784 n = GET_MODE_BITSIZE (mode);
3785
3786 get_shift_alg (shift_type, shift_mode, n, &info);
3787
3788 switch (info.alg)
3789 {
3790 case SHIFT_SPECIAL:
3791 if (info.remainder == 0)
3792 return info.cc_special;
3793
3794 /* Fall through. */
3795
3796 case SHIFT_INLINE:
3797 return info.cc_inline;
3798
3799 case SHIFT_ROT_AND:
3800 /* This case always ends with an and instruction. */
3801 return CC_SET_ZNV;
3802
3803 case SHIFT_LOOP:
3804 /* A loop to shift by a "large" constant value.
3805 If we have shift-by-2 insns, use them. */
3806 if (info.shift2 != NULL)
3807 {
3808 if (n % 2)
3809 return info.cc_inline;
3810 }
3811 return CC_CLOBBER;
3812
3813 default:
3814 abort ();
3815 }
3816 }
3817}
48837e29 3818\f
edd71f0f
KH
3819/* A rotation by a non-constant will cause a loop to be generated, in
3820 which a rotation by one bit is used. A rotation by a constant,
3821 including the one in the loop, will be taken care of by
caf7f21a 3822 output_a_rotate () at the insn emit time. */
edd71f0f
KH
3823
3824int
cb713a8d 3825expand_a_rotate (enum rtx_code code, rtx operands[])
edd71f0f
KH
3826{
3827 rtx dst = operands[0];
3828 rtx src = operands[1];
3829 rtx rotate_amount = operands[2];
3830 enum machine_mode mode = GET_MODE (dst);
3831 rtx tmp;
3832
3833 /* We rotate in place. */
3834 emit_move_insn (dst, src);
3835
3836 if (GET_CODE (rotate_amount) != CONST_INT)
3837 {
3838 rtx counter = gen_reg_rtx (QImode);
3839 rtx start_label = gen_label_rtx ();
3840 rtx end_label = gen_label_rtx ();
3841
3842 /* If the rotate amount is less than or equal to 0,
3843 we go out of the loop. */
d43e0b7d
RK
3844 emit_cmp_and_jump_insns (rotate_amount, GEN_INT (0), LE, NULL_RTX,
3845 QImode, 0, end_label);
edd71f0f
KH
3846
3847 /* Initialize the loop counter. */
3848 emit_move_insn (counter, rotate_amount);
3849
3850 emit_label (start_label);
3851
3852 /* Rotate by one bit. */
3853 tmp = gen_rtx (code, mode, dst, GEN_INT (1));
3854 emit_insn (gen_rtx_SET (mode, dst, tmp));
3855
3856 /* Decrement the counter by 1. */
3857 tmp = gen_rtx_PLUS (QImode, counter, GEN_INT (-1));
3858 emit_insn (gen_rtx_SET (VOIDmode, counter, tmp));
3859
9cd10576 3860 /* If the loop counter is nonzero, we go back to the beginning
edd71f0f 3861 of the loop. */
d43e0b7d
RK
3862 emit_cmp_and_jump_insns (counter, GEN_INT (0), NE, NULL_RTX, QImode, 1,
3863 start_label);
edd71f0f
KH
3864
3865 emit_label (end_label);
3866 }
3867 else
3868 {
3869 /* Rotate by AMOUNT bits. */
3870 tmp = gen_rtx (code, mode, dst, rotate_amount);
3871 emit_insn (gen_rtx_SET (mode, dst, tmp));
3872 }
3873
3874 return 1;
3875}
3876
caf7f21a 3877/* Output rotate insns. */
edd71f0f
KH
3878
3879const char *
caf7f21a 3880output_a_rotate (enum rtx_code code, rtx *operands)
edd71f0f
KH
3881{
3882 rtx dst = operands[0];
3883 rtx rotate_amount = operands[2];
3884 enum shift_mode rotate_mode;
3885 enum shift_type rotate_type;
3886 const char *insn_buf;
3887 int bits;
3888 int amount;
3889 enum machine_mode mode = GET_MODE (dst);
3890
3891 if (GET_CODE (rotate_amount) != CONST_INT)
3892 abort ();
3893
3894 switch (mode)
3895 {
3896 case QImode:
3897 rotate_mode = QIshift;
3898 break;
3899 case HImode:
3900 rotate_mode = HIshift;
3901 break;
3902 case SImode:
3903 rotate_mode = SIshift;
3904 break;
3905 default:
3906 abort ();
3907 }
3908
3909 switch (code)
3910 {
3911 case ROTATERT:
3912 rotate_type = SHIFT_ASHIFT;
3913 break;
3914 case ROTATE:
3915 rotate_type = SHIFT_LSHIFTRT;
3916 break;
3917 default:
3918 abort ();
3919 }
3920
3921 amount = INTVAL (rotate_amount);
3922
3923 /* Clean up AMOUNT. */
3924 if (amount < 0)
3925 amount = 0;
3926 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3927 amount = GET_MODE_BITSIZE (mode);
3928
3929 /* Determine the faster direction. After this phase, amount will be
3930 at most a half of GET_MODE_BITSIZE (mode). */
e0c32c62 3931 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
edd71f0f
KH
3932 {
3933 /* Flip the direction. */
3934 amount = GET_MODE_BITSIZE (mode) - amount;
3935 rotate_type =
3936 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
3937 }
3938
3939 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3940 boost up the rotation. */
3941 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3942 || (mode == HImode && TARGET_H8300H && amount >= 6)
3943 || (mode == HImode && TARGET_H8300S && amount == 8)
3944 || (mode == SImode && TARGET_H8300H && amount >= 10)
3945 || (mode == SImode && TARGET_H8300S && amount >= 13))
3946 {
3947 switch (mode)
3948 {
3949 case HImode:
3950 /* This code works on any family. */
3951 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
3952 output_asm_insn (insn_buf, operands);
3953 break;
3954
3955 case SImode:
3db11b5c 3956 /* This code works on the H8/300H and H8S. */
edd71f0f
KH
3957 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
3958 output_asm_insn (insn_buf, operands);
3959 break;
3960
3961 default:
3962 abort ();
3963 }
3964
3965 /* Adjust AMOUNT and flip the direction. */
3966 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3967 rotate_type =
3968 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
3969 }
3970
3971 /* Emit rotate insns. */
3972 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2)
3973 {
3974 if (bits == 2)
3975 insn_buf = rotate_two[rotate_type][rotate_mode];
3976 else
3977 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode];
2c54abce 3978
edd71f0f
KH
3979 for (; amount >= bits; amount -= bits)
3980 output_asm_insn (insn_buf, operands);
3981 }
3982
3983 return "";
3984}
caf7f21a
KH
3985
3986unsigned int
3987compute_a_rotate_length (rtx *operands)
3988{
3989 rtx src = operands[1];
343fd2c7 3990 rtx amount_rtx = operands[2];
caf7f21a
KH
3991 enum machine_mode mode = GET_MODE (src);
3992 int amount;
3993 unsigned int length = 0;
3994
343fd2c7
KH
3995 if (GET_CODE (amount_rtx) != CONST_INT)
3996 abort ();
caf7f21a 3997
343fd2c7 3998 amount = INTVAL (amount_rtx);
caf7f21a
KH
3999
4000 /* Clean up AMOUNT. */
4001 if (amount < 0)
4002 amount = 0;
4003 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
4004 amount = GET_MODE_BITSIZE (mode);
4005
4006 /* Determine the faster direction. After this phase, amount
4007 will be at most a half of GET_MODE_BITSIZE (mode). */
4008 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
4009 /* Flip the direction. */
4010 amount = GET_MODE_BITSIZE (mode) - amount;
4011
4012 /* See if a byte swap (in HImode) or a word swap (in SImode) can
4013 boost up the rotation. */
4014 if ((mode == HImode && TARGET_H8300 && amount >= 5)
4015 || (mode == HImode && TARGET_H8300H && amount >= 6)
4016 || (mode == HImode && TARGET_H8300S && amount == 8)
4017 || (mode == SImode && TARGET_H8300H && amount >= 10)
4018 || (mode == SImode && TARGET_H8300S && amount >= 13))
4019 {
4020 /* Adjust AMOUNT and flip the direction. */
4021 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
4022 length += 6;
4023 }
4024
4025 /* We use 2-bit rotations on the H8S. */
4026 if (TARGET_H8300S)
4027 amount = amount / 2 + amount % 2;
4028
4029 /* The H8/300 uses three insns to rotate one bit, taking 6
4030 length. */
4031 length += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2);
4032
4033 return length;
4034}
edd71f0f 4035\f
48837e29 4036/* Fix the operands of a gen_xxx so that it could become a bit
2c54abce 4037 operating insn. */
07aae5c2
SC
4038
4039int
cb713a8d 4040fix_bit_operand (rtx *operands, int what, enum rtx_code type)
07aae5c2 4041{
abc95ed3 4042 /* The bit_operand predicate accepts any memory during RTL generation, but
48837e29
DE
4043 only 'U' memory afterwards, so if this is a MEM operand, we must force
4044 it to be valid for 'U' by reloading the address. */
07aae5c2 4045
2e760b15
KH
4046 if ((what == 0 && single_zero_operand (operands[2], QImode))
4047 || (what == 1 && single_one_operand (operands[2], QImode)))
07aae5c2 4048 {
2e760b15
KH
4049 /* OK to have a memory dest. */
4050 if (GET_CODE (operands[0]) == MEM
4051 && !EXTRA_CONSTRAINT (operands[0], 'U'))
48837e29 4052 {
2e760b15
KH
4053 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
4054 copy_to_mode_reg (Pmode,
4055 XEXP (operands[0], 0)));
4056 MEM_COPY_ATTRIBUTES (mem, operands[0]);
4057 operands[0] = mem;
4058 }
48837e29 4059
2e760b15
KH
4060 if (GET_CODE (operands[1]) == MEM
4061 && !EXTRA_CONSTRAINT (operands[1], 'U'))
4062 {
4063 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
4064 copy_to_mode_reg (Pmode,
4065 XEXP (operands[1], 0)));
4066 MEM_COPY_ATTRIBUTES (mem, operands[0]);
4067 operands[1] = mem;
48837e29 4068 }
2e760b15 4069 return 0;
48837e29 4070 }
07aae5c2 4071
48837e29 4072 /* Dest and src op must be register. */
07aae5c2 4073
48837e29
DE
4074 operands[1] = force_reg (QImode, operands[1]);
4075 {
4076 rtx res = gen_reg_rtx (QImode);
c5c76735
JL
4077 emit_insn (gen_rtx_SET (VOIDmode, res,
4078 gen_rtx (type, QImode, operands[1], operands[2])));
4079 emit_insn (gen_rtx_SET (VOIDmode, operands[0], res));
48837e29
DE
4080 }
4081 return 1;
07aae5c2 4082}
f5b65a56 4083
f5b65a56
JL
4084/* Return nonzero if FUNC is an interrupt function as specified
4085 by the "interrupt" attribute. */
4086
4087static int
cb713a8d 4088h8300_interrupt_function_p (tree func)
f5b65a56
JL
4089{
4090 tree a;
4091
4092 if (TREE_CODE (func) != FUNCTION_DECL)
4093 return 0;
4094
91d231cb 4095 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
f5b65a56
JL
4096 return a != NULL_TREE;
4097}
4098
fabe72bb
JL
4099/* Return nonzero if FUNC is an OS_Task function as specified
4100 by the "OS_Task" attribute. */
4101
4102static int
cb713a8d 4103h8300_os_task_function_p (tree func)
fabe72bb
JL
4104{
4105 tree a;
4106
4107 if (TREE_CODE (func) != FUNCTION_DECL)
4108 return 0;
4109
91d231cb 4110 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func));
fabe72bb
JL
4111 return a != NULL_TREE;
4112}
4113
4114/* Return nonzero if FUNC is a monitor function as specified
4115 by the "monitor" attribute. */
4116
4117static int
cb713a8d 4118h8300_monitor_function_p (tree func)
fabe72bb
JL
4119{
4120 tree a;
4121
4122 if (TREE_CODE (func) != FUNCTION_DECL)
4123 return 0;
4124
91d231cb 4125 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func));
fabe72bb
JL
4126 return a != NULL_TREE;
4127}
4128
f5b65a56
JL
4129/* Return nonzero if FUNC is a function that should be called
4130 through the function vector. */
4131
4132int
cb713a8d 4133h8300_funcvec_function_p (tree func)
f5b65a56
JL
4134{
4135 tree a;
4136
4137 if (TREE_CODE (func) != FUNCTION_DECL)
4138 return 0;
4139
91d231cb 4140 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func));
f5b65a56
JL
4141 return a != NULL_TREE;
4142}
4143
887a8bd9 4144/* Return nonzero if DECL is a variable that's in the eight bit
15dc331e
JL
4145 data area. */
4146
4147int
cb713a8d 4148h8300_eightbit_data_p (tree decl)
15dc331e
JL
4149{
4150 tree a;
4151
4152 if (TREE_CODE (decl) != VAR_DECL)
4153 return 0;
4154
91d231cb 4155 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl));
15dc331e
JL
4156 return a != NULL_TREE;
4157}
4158
887a8bd9
JL
4159/* Return nonzero if DECL is a variable that's in the tiny
4160 data area. */
4161
4162int
cb713a8d 4163h8300_tiny_data_p (tree decl)
887a8bd9
JL
4164{
4165 tree a;
4166
4167 if (TREE_CODE (decl) != VAR_DECL)
4168 return 0;
4169
91d231cb 4170 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl));
887a8bd9
JL
4171 return a != NULL_TREE;
4172}
4173
2c1d2fcb
DD
4174/* Generate an 'interrupt_handler' attribute for decls. */
4175
4176static void
cb713a8d 4177h8300_insert_attributes (tree node, tree *attributes)
2c1d2fcb 4178{
e392d367 4179 if (!pragma_interrupt
2c1d2fcb
DD
4180 || TREE_CODE (node) != FUNCTION_DECL)
4181 return;
4182
e392d367
KH
4183 pragma_interrupt = 0;
4184
2c1d2fcb
DD
4185 /* Add an 'interrupt_handler' attribute. */
4186 *attributes = tree_cons (get_identifier ("interrupt_handler"),
4187 NULL, *attributes);
4188}
4189
91d231cb 4190/* Supported attributes:
f5b65a56 4191
97c5ec1d 4192 interrupt_handler: output a prologue and epilogue suitable for an
f5b65a56
JL
4193 interrupt handler.
4194
97c5ec1d 4195 function_vector: This function should be called through the
887a8bd9
JL
4196 function vector.
4197
4198 eightbit_data: This variable lives in the 8-bit data area and can
4199 be referenced with 8-bit absolute memory addresses.
4200
4201 tiny_data: This variable lives in the tiny data area and can be
4202 referenced with 16-bit absolute memory references. */
f5b65a56 4203
91d231cb 4204const struct attribute_spec h8300_attribute_table[] =
f5b65a56 4205{
91d231cb
JM
4206 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4207 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
4208 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
4209 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
4210 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
4211 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute },
4212 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute },
4213 { NULL, 0, 0, false, false, false, NULL }
4214};
f5b65a56 4215
15dc331e 4216
91d231cb
JM
4217/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4218 struct attribute_spec.handler. */
4219static tree
cb713a8d
KH
4220h8300_handle_fndecl_attribute (tree *node, tree name,
4221 tree args ATTRIBUTE_UNUSED,
4222 int flags ATTRIBUTE_UNUSED,
4223 bool *no_add_attrs)
91d231cb
JM
4224{
4225 if (TREE_CODE (*node) != FUNCTION_DECL)
4226 {
4227 warning ("`%s' attribute only applies to functions",
4228 IDENTIFIER_POINTER (name));
4229 *no_add_attrs = true;
4230 }
4231
4232 return NULL_TREE;
4233}
4234
4235/* Handle an "eightbit_data" attribute; arguments as in
4236 struct attribute_spec.handler. */
4237static tree
cb713a8d
KH
4238h8300_handle_eightbit_data_attribute (tree *node, tree name,
4239 tree args ATTRIBUTE_UNUSED,
4240 int flags ATTRIBUTE_UNUSED,
4241 bool *no_add_attrs)
91d231cb
JM
4242{
4243 tree decl = *node;
4244
4245 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
15dc331e 4246 {
64378c91 4247 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
91d231cb
JM
4248 }
4249 else
4250 {
4251 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4252 *no_add_attrs = true;
887a8bd9
JL
4253 }
4254
91d231cb
JM
4255 return NULL_TREE;
4256}
4257
4258/* Handle an "tiny_data" attribute; arguments as in
4259 struct attribute_spec.handler. */
4260static tree
cb713a8d
KH
4261h8300_handle_tiny_data_attribute (tree *node, tree name,
4262 tree args ATTRIBUTE_UNUSED,
4263 int flags ATTRIBUTE_UNUSED,
4264 bool *no_add_attrs)
91d231cb
JM
4265{
4266 tree decl = *node;
4267
4268 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
887a8bd9 4269 {
64378c91 4270 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
91d231cb
JM
4271 }
4272 else
4273 {
4274 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4275 *no_add_attrs = true;
15dc331e 4276 }
07e4d94e 4277
91d231cb 4278 return NULL_TREE;
f5b65a56
JL
4279}
4280
dc66a1c4 4281/* Mark function vectors, and various small data objects. */
fb49053f
RH
4282
4283static void
cb713a8d 4284h8300_encode_section_info (tree decl, rtx rtl, int first)
fb49053f 4285{
dc66a1c4
RH
4286 int extra_flags = 0;
4287
c6a2438a 4288 default_encode_section_info (decl, rtl, first);
dc66a1c4 4289
fb49053f
RH
4290 if (TREE_CODE (decl) == FUNCTION_DECL
4291 && h8300_funcvec_function_p (decl))
dc66a1c4 4292 extra_flags = SYMBOL_FLAG_FUNCVEC_FUNCTION;
fb49053f
RH
4293 else if (TREE_CODE (decl) == VAR_DECL
4294 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
4295 {
4296 if (h8300_eightbit_data_p (decl))
dc66a1c4 4297 extra_flags = SYMBOL_FLAG_EIGHTBIT_DATA;
fb49053f 4298 else if (first && h8300_tiny_data_p (decl))
dc66a1c4 4299 extra_flags = SYMBOL_FLAG_TINY_DATA;
fb49053f 4300 }
772c5265 4301
dc66a1c4 4302 if (extra_flags)
c6a2438a 4303 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= extra_flags;
772c5265
RH
4304}
4305
441d04c6 4306const char *
cb713a8d 4307output_simode_bld (int bild, rtx operands[])
bd93f126 4308{
6be580c7
KH
4309 if (TARGET_H8300)
4310 {
4311 /* Clear the destination register. */
4312 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
4313
4314 /* Now output the bit load or bit inverse load, and store it in
4315 the destination. */
4316 if (bild)
4317 output_asm_insn ("bild\t%Z2,%Y1", operands);
4318 else
4319 output_asm_insn ("bld\t%Z2,%Y1", operands);
bd93f126 4320
6be580c7
KH
4321 output_asm_insn ("bst\t#0,%w0", operands);
4322 }
bd93f126 4323 else
6be580c7 4324 {
0eb933a0
KH
4325 /* Determine if we can clear the destination first. */
4326 int clear_first = (REG_P (operands[0]) && REG_P (operands[1])
4327 && REGNO (operands[0]) != REGNO (operands[1]));
4328
4329 if (clear_first)
4330 output_asm_insn ("sub.l\t%S0,%S0", operands);
4331
6be580c7
KH
4332 /* Output the bit load or bit inverse load. */
4333 if (bild)
4334 output_asm_insn ("bild\t%Z2,%Y1", operands);
4335 else
4336 output_asm_insn ("bld\t%Z2,%Y1", operands);
4337
0eb933a0
KH
4338 if (!clear_first)
4339 output_asm_insn ("xor.l\t%S0,%S0", operands);
4340
4341 /* Perform the bit store. */
802a9907 4342 output_asm_insn ("rotxl.l\t%S0", operands);
6be580c7 4343 }
bd93f126
JL
4344
4345 /* All done. */
4346 return "";
4347}
e6219736 4348
ede75ee8 4349#ifndef OBJECT_FORMAT_ELF
7c262518 4350static void
cb713a8d 4351h8300_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
7c262518
RH
4352{
4353 /* ??? Perhaps we should be using default_coff_asm_named_section. */
4354 fprintf (asm_out_file, "\t.section %s\n", name);
4355}
ede75ee8 4356#endif /* ! OBJECT_FORMAT_ELF */
803d56f5 4357
7c143ed2
KH
4358/* Nonzero if X is a constant address suitable as an 8-bit absolute,
4359 which is a special case of the 'R' operand. */
4360
803d56f5 4361int
cb713a8d 4362h8300_eightbit_constant_address_p (rtx x)
803d56f5 4363{
3f7211f1 4364 /* The ranges of the 8-bit area. */
d2d199a3
KH
4365 const unsigned HOST_WIDE_INT n1 = trunc_int_for_mode (0xff00, HImode);
4366 const unsigned HOST_WIDE_INT n2 = trunc_int_for_mode (0xffff, HImode);
803d56f5
KH
4367 const unsigned HOST_WIDE_INT h1 = trunc_int_for_mode (0x00ffff00, SImode);
4368 const unsigned HOST_WIDE_INT h2 = trunc_int_for_mode (0x00ffffff, SImode);
4369 const unsigned HOST_WIDE_INT s1 = trunc_int_for_mode (0xffffff00, SImode);
4370 const unsigned HOST_WIDE_INT s2 = trunc_int_for_mode (0xffffffff, SImode);
4371
4372 unsigned HOST_WIDE_INT addr;
4373
9675a91e 4374 /* We accept symbols declared with eightbit_data. */
dc66a1c4
RH
4375 if (GET_CODE (x) == SYMBOL_REF)
4376 return (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_EIGHTBIT_DATA) != 0;
9675a91e 4377
803d56f5
KH
4378 if (GET_CODE (x) != CONST_INT)
4379 return 0;
4380
4381 addr = INTVAL (x);
4382
4383 return (0
39ba95b5 4384 || ((TARGET_H8300 || TARGET_NORMAL_MODE) && IN_RANGE (addr, n1, n2))
803d56f5
KH
4385 || (TARGET_H8300H && IN_RANGE (addr, h1, h2))
4386 || (TARGET_H8300S && IN_RANGE (addr, s1, s2)));
4387}
4388
7c143ed2
KH
4389/* Nonzero if X is a constant address suitable as an 16-bit absolute
4390 on H8/300H and H8S. */
4391
803d56f5 4392int
cb713a8d 4393h8300_tiny_constant_address_p (rtx x)
803d56f5 4394{
3f7211f1 4395 /* The ranges of the 16-bit area. */
803d56f5
KH
4396 const unsigned HOST_WIDE_INT h1 = trunc_int_for_mode (0x00000000, SImode);
4397 const unsigned HOST_WIDE_INT h2 = trunc_int_for_mode (0x00007fff, SImode);
4398 const unsigned HOST_WIDE_INT h3 = trunc_int_for_mode (0x00ff8000, SImode);
4399 const unsigned HOST_WIDE_INT h4 = trunc_int_for_mode (0x00ffffff, SImode);
4400 const unsigned HOST_WIDE_INT s1 = trunc_int_for_mode (0x00000000, SImode);
4401 const unsigned HOST_WIDE_INT s2 = trunc_int_for_mode (0x00007fff, SImode);
4402 const unsigned HOST_WIDE_INT s3 = trunc_int_for_mode (0xffff8000, SImode);
4403 const unsigned HOST_WIDE_INT s4 = trunc_int_for_mode (0xffffffff, SImode);
4404
4405 unsigned HOST_WIDE_INT addr;
4406
56b8e164 4407 /* We accept symbols declared with tiny_data. */
dc66a1c4
RH
4408 if (GET_CODE (x) == SYMBOL_REF)
4409 return (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_TINY_DATA) != 0;
56b8e164 4410
803d56f5
KH
4411 if (GET_CODE (x) != CONST_INT)
4412 return 0;
4413
4414 addr = INTVAL (x);
4415
4416 return (0
6d7d3112
DD
4417 || TARGET_NORMAL_MODE
4418 || (TARGET_H8300H
94aec8dd 4419 && (IN_RANGE (addr, h1, h2) || IN_RANGE (addr, h3, h4)))
6d7d3112 4420 || (TARGET_H8300S
94aec8dd 4421 && (IN_RANGE (addr, s1, s2) || IN_RANGE (addr, s3, s4))));
803d56f5 4422}
9b98dc74
KH
4423
4424int
cb713a8d 4425byte_accesses_mergeable_p (rtx addr1, rtx addr2)
9b98dc74
KH
4426{
4427 HOST_WIDE_INT offset1, offset2;
4428 rtx reg1, reg2;
4429
4430 if (REG_P (addr1))
4431 {
4432 reg1 = addr1;
4433 offset1 = 0;
4434 }
4435 else if (GET_CODE (addr1) == PLUS
4436 && REG_P (XEXP (addr1, 0))
4437 && GET_CODE (XEXP (addr1, 1)) == CONST_INT)
4438 {
4439 reg1 = XEXP (addr1, 0);
4440 offset1 = INTVAL (XEXP (addr1, 1));
4441 }
4442 else
4443 return 0;
4444
4445 if (REG_P (addr2))
4446 {
4447 reg2 = addr2;
4448 offset2 = 0;
4449 }
4450 else if (GET_CODE (addr2) == PLUS
4451 && REG_P (XEXP (addr2, 0))
4452 && GET_CODE (XEXP (addr2, 1)) == CONST_INT)
4453 {
4454 reg2 = XEXP (addr2, 0);
4455 offset2 = INTVAL (XEXP (addr2, 1));
4456 }
4457 else
4458 return 0;
4459
4460 if (((reg1 == stack_pointer_rtx && reg2 == stack_pointer_rtx)
4461 || (reg1 == frame_pointer_rtx && reg2 == frame_pointer_rtx))
4462 && offset1 % 2 == 0
4463 && offset1 + 1 == offset2)
4464 return 1;
4465
4466 return 0;
4467}
02529902
KH
4468
4469/* Return nonzero if we have the same comparison insn as I3 two insns
19cff4db 4470 before I3. I3 is assumed to be a comparison insn. */
02529902
KH
4471
4472int
4473same_cmp_preceding_p (rtx i3)
4474{
4475 rtx i1, i2;
4476
4477 /* Make sure we have a sequence of three insns. */
4478 i2 = prev_nonnote_insn (i3);
4479 if (i2 == NULL_RTX)
4480 return 0;
4481 i1 = prev_nonnote_insn (i2);
4482 if (i1 == NULL_RTX)
4483 return 0;
4484
4485 return (INSN_P (i1) && rtx_equal_p (PATTERN (i1), PATTERN (i3))
4486 && any_condjump_p (i2) && onlyjump_p (i2));
4487}
6e014ef3
KH
4488\f
4489/* Initialize the GCC target structure. */
4490#undef TARGET_ATTRIBUTE_TABLE
4491#define TARGET_ATTRIBUTE_TABLE h8300_attribute_table
4492
4493#undef TARGET_ASM_ALIGNED_HI_OP
4494#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
4495
4496#undef TARGET_ASM_FUNCTION_EPILOGUE
4497#define TARGET_ASM_FUNCTION_EPILOGUE h8300_output_function_epilogue
4498
1bc7c5b6
ZW
4499#undef TARGET_ASM_FILE_START
4500#define TARGET_ASM_FILE_START h8300_file_start
4501#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
4502#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
4503
6e014ef3
KH
4504#undef TARGET_ASM_FILE_END
4505#define TARGET_ASM_FILE_END h8300_file_end
4506
4507#undef TARGET_ENCODE_SECTION_INFO
4508#define TARGET_ENCODE_SECTION_INFO h8300_encode_section_info
4509
4510#undef TARGET_INSERT_ATTRIBUTES
4511#define TARGET_INSERT_ATTRIBUTES h8300_insert_attributes
4512
4513#undef TARGET_RTX_COSTS
4514#define TARGET_RTX_COSTS h8300_rtx_costs
4515
4516struct gcc_target targetm = TARGET_INITIALIZER;