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