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