]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/h8300/h8300.c
* Make-lang.in: Change copyright header to refer to version 3 of the GNU General
[thirdparty/gcc.git] / gcc / config / h8300 / h8300.c
CommitLineData
716085c2 1/* Subroutines for insn-output.c for Renesas H8/300.
7913b5f4 2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3072d30e 3 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
b839e0b4 4 Contributed by Steve Chamberlain (sac@cygnus.com),
5 Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
e1629549 6
dbbae424 7This file is part of GCC.
e1629549 8
dbbae424 9GCC is free software; you can redistribute it and/or modify
e1629549 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
dbbae424 14GCC is distributed in the hope that it will be useful,
e1629549 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
dbbae424 20along with GCC; see the file COPYING. If not, write to
dbddc6c4 21the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22Boston, MA 02110-1301, USA. */
e1629549 23
e1629549 24#include "config.h"
7014838c 25#include "system.h"
805e22b2 26#include "coretypes.h"
27#include "tm.h"
e1629549 28#include "rtl.h"
4faf81b8 29#include "tree.h"
e1629549 30#include "regs.h"
31#include "hard-reg-set.h"
32#include "real.h"
33#include "insn-config.h"
34#include "conditions.h"
e1629549 35#include "output.h"
36#include "insn-attr.h"
37#include "flags.h"
38#include "recog.h"
39#include "expr.h"
4faf81b8 40#include "function.h"
f2f543a3 41#include "optabs.h"
9305fe33 42#include "toplev.h"
1fcd08b1 43#include "c-pragma.h"
9305fe33 44#include "tm_p.h"
f8870f17 45#include "ggc.h"
a767736d 46#include "target.h"
47#include "target-def.h"
e1629549 48
727c62dd 49/* Classifies a h8300_src_operand or h8300_dst_operand.
50
51 H8OP_IMMEDIATE
52 A constant operand of some sort.
53
54 H8OP_REGISTER
55 An ordinary register.
56
57 H8OP_MEM_ABSOLUTE
58 A memory reference with a constant address.
59
60 H8OP_MEM_BASE
61 A memory reference with a register as its address.
62
63 H8OP_MEM_COMPLEX
64 Some other kind of memory reference. */
65enum h8300_operand_class
66{
67 H8OP_IMMEDIATE,
68 H8OP_REGISTER,
69 H8OP_MEM_ABSOLUTE,
70 H8OP_MEM_BASE,
71 H8OP_MEM_COMPLEX,
72 NUM_H8OPS
73};
74
727c62dd 75/* For a general two-operand instruction, element [X][Y] gives
76 the length of the opcode fields when the first operand has class
77 (X + 1) and the second has class Y. */
78typedef unsigned char h8300_length_table[NUM_H8OPS - 1][NUM_H8OPS];
79
e1629549 80/* Forward declarations. */
230002f2 81static const char *byte_reg (rtx, int);
82static int h8300_interrupt_function_p (tree);
5344805f 83static int h8300_saveall_function_p (tree);
230002f2 84static int h8300_monitor_function_p (tree);
85static int h8300_os_task_function_p (tree);
959e2f12 86static void h8300_emit_stack_adjustment (int, HOST_WIDE_INT);
87static HOST_WIDE_INT round_frame_size (HOST_WIDE_INT);
230002f2 88static unsigned int compute_saved_regs (void);
89static void push (int);
90static void pop (int);
91static const char *cond_string (enum rtx_code);
92static unsigned int h8300_asm_insn_count (const char *);
230002f2 93static tree h8300_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
94static tree h8300_handle_eightbit_data_attribute (tree *, tree, tree, int, bool *);
95static tree h8300_handle_tiny_data_attribute (tree *, tree, tree, int, bool *);
6e4758ce 96#ifndef OBJECT_FORMAT_ELF
537cd941 97static void h8300_asm_named_section (const char *, unsigned int, tree);
6e4758ce 98#endif
230002f2 99static int h8300_and_costs (rtx);
100static int h8300_shift_costs (rtx);
727c62dd 101static void h8300_push_pop (int, int, int, int);
102static int h8300_stack_offset_p (rtx, int);
103static int h8300_ldm_stm_regno (rtx, int, int, int);
727c62dd 104static void h8300_reorg (void);
105static unsigned int h8300_constant_length (rtx);
106static unsigned int h8300_displacement_length (rtx, int);
107static unsigned int h8300_classify_operand (rtx, int, enum h8300_operand_class *);
108static unsigned int h8300_length_from_table (rtx, rtx, const h8300_length_table *);
109static unsigned int h8300_unary_length (rtx);
110static unsigned int h8300_short_immediate_length (rtx);
111static unsigned int h8300_bitfield_length (rtx, rtx);
112static unsigned int h8300_binary_length (rtx, const h8300_length_table *);
113static bool h8300_short_move_mem_p (rtx, enum rtx_code);
114static unsigned int h8300_move_length (rtx *, const h8300_length_table *);
b11bfc61 115
b839e0b4 116/* CPU_TYPE, says what cpu we're compiling for. */
117int cpu_type;
118
41ed3bcd 119/* True if a #pragma interrupt has been seen for the current function. */
120static int pragma_interrupt;
e1629549 121
122/* True if a #pragma saveall has been seen for the current function. */
8ba450ad 123static int pragma_saveall;
e1629549 124
9305fe33 125static const char *const names_big[] =
eb2aa24e 126{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" };
b839e0b4 127
9305fe33 128static const char *const names_extended[] =
eb2aa24e 129{ "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" };
b839e0b4 130
9305fe33 131static const char *const names_upper_extended[] =
eb2aa24e 132{ "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7" };
b839e0b4 133
134/* Points to one of the above. */
135/* ??? The above could be put in an array indexed by CPU_TYPE. */
9305fe33 136const char * const *h8_reg_names;
b839e0b4 137
138/* Various operations needed by the following, indexed by CPU_TYPE. */
b839e0b4 139
9305fe33 140const char *h8_push_op, *h8_pop_op, *h8_mov_op;
d37aaac2 141
727c62dd 142/* Value of MOVE_RATIO. */
143int h8300_move_ratio;
a767736d 144\f
0650a2e5 145/* See below where shifts are handled for explanation of this enum. */
146
147enum shift_alg
148{
149 SHIFT_INLINE,
150 SHIFT_ROT_AND,
151 SHIFT_SPECIAL,
152 SHIFT_LOOP
153};
154
155/* Symbols of the various shifts which can be used as indices. */
156
157enum shift_type
158{
159 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
160};
161
162/* Macros to keep the shift algorithm tables small. */
163#define INL SHIFT_INLINE
164#define ROT SHIFT_ROT_AND
165#define LOP SHIFT_LOOP
166#define SPC SHIFT_SPECIAL
167
168/* The shift algorithms for each machine, mode, shift type, and shift
169 count are defined below. The three tables below correspond to
170 QImode, HImode, and SImode, respectively. Each table is organized
cc72e60a 171 by, in the order of indices, machine, shift type, and shift count. */
0650a2e5 172
173static enum shift_alg shift_alg_qi[3][3][8] = {
174 {
175 /* TARGET_H8300 */
176 /* 0 1 2 3 4 5 6 7 */
177 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
178 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
179 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
180 },
181 {
182 /* TARGET_H8300H */
183 /* 0 1 2 3 4 5 6 7 */
184 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
185 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
186 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
187 },
188 {
189 /* TARGET_H8300S */
190 /* 0 1 2 3 4 5 6 7 */
191 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_ASHIFT */
192 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_LSHIFTRT */
193 { INL, INL, INL, INL, INL, INL, INL, SPC } /* SHIFT_ASHIFTRT */
194 }
195};
196
197static enum shift_alg shift_alg_hi[3][3][16] = {
198 {
199 /* TARGET_H8300 */
200 /* 0 1 2 3 4 5 6 7 */
201 /* 8 9 10 11 12 13 14 15 */
202 { INL, INL, INL, INL, INL, INL, INL, SPC,
203 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */
204 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
205 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */
206 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
207 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
208 },
209 {
210 /* TARGET_H8300H */
211 /* 0 1 2 3 4 5 6 7 */
212 /* 8 9 10 11 12 13 14 15 */
213 { INL, INL, INL, INL, INL, INL, INL, SPC,
214 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
215 { INL, INL, INL, INL, INL, INL, INL, SPC,
216 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
217 { INL, INL, INL, INL, INL, INL, INL, SPC,
218 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
219 },
220 {
221 /* TARGET_H8300S */
222 /* 0 1 2 3 4 5 6 7 */
223 /* 8 9 10 11 12 13 14 15 */
224 { INL, INL, INL, INL, INL, INL, INL, INL,
225 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
226 { INL, INL, INL, INL, INL, INL, INL, INL,
227 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
228 { INL, INL, INL, INL, INL, INL, INL, INL,
229 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
230 }
231};
232
233static enum shift_alg shift_alg_si[3][3][32] = {
234 {
235 /* TARGET_H8300 */
236 /* 0 1 2 3 4 5 6 7 */
237 /* 8 9 10 11 12 13 14 15 */
238 /* 16 17 18 19 20 21 22 23 */
239 /* 24 25 26 27 28 29 30 31 */
240 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
241 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
242 SPC, SPC, SPC, SPC, SPC, LOP, LOP, LOP,
243 SPC, SPC, SPC, SPC, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
244 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
245 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC,
246 SPC, SPC, SPC, LOP, LOP, LOP, LOP, LOP,
247 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
248 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
249 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
250 SPC, SPC, LOP, LOP, LOP, LOP, LOP, LOP,
251 SPC, SPC, SPC, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
252 },
253 {
254 /* TARGET_H8300H */
255 /* 0 1 2 3 4 5 6 7 */
256 /* 8 9 10 11 12 13 14 15 */
257 /* 16 17 18 19 20 21 22 23 */
258 /* 24 25 26 27 28 29 30 31 */
259 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
260 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
261 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
567c4b66 262 SPC, LOP, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */
0650a2e5 263 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
264 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
265 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
567c4b66 266 SPC, LOP, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */
0650a2e5 267 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
268 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
269 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
270 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
271 },
272 {
273 /* TARGET_H8300S */
274 /* 0 1 2 3 4 5 6 7 */
275 /* 8 9 10 11 12 13 14 15 */
276 /* 16 17 18 19 20 21 22 23 */
277 /* 24 25 26 27 28 29 30 31 */
278 { INL, INL, INL, INL, INL, INL, INL, INL,
279 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
280 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
567c4b66 281 SPC, SPC, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */
0650a2e5 282 { INL, INL, INL, INL, INL, INL, INL, INL,
283 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
284 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
567c4b66 285 SPC, SPC, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */
0650a2e5 286 { INL, INL, INL, INL, INL, INL, INL, INL,
287 INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
288 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
289 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
290 }
291};
292
293#undef INL
294#undef ROT
295#undef LOP
296#undef SPC
297
298enum h8_cpu
299{
300 H8_300,
301 H8_300H,
302 H8_S
303};
304
b839e0b4 305/* Initialize various cpu specific globals at start up. */
306
307void
230002f2 308h8300_init_once (void)
b839e0b4 309{
1592a00c 310 static const char *const h8_push_ops[2] = { "push" , "push.l" };
311 static const char *const h8_pop_ops[2] = { "pop" , "pop.l" };
312 static const char *const h8_mov_ops[2] = { "mov.w", "mov.l" };
313
b839e0b4 314 if (TARGET_H8300)
315 {
316 cpu_type = (int) CPU_H8300;
317 h8_reg_names = names_big;
318 }
319 else
320 {
11f95d7c 321 /* For this we treat the H8/300H and H8S the same. */
b839e0b4 322 cpu_type = (int) CPU_H8300H;
323 h8_reg_names = names_extended;
324 }
325 h8_push_op = h8_push_ops[cpu_type];
326 h8_pop_op = h8_pop_ops[cpu_type];
327 h8_mov_op = h8_mov_ops[cpu_type];
92d7ef92 328
329 if (!TARGET_H8300S && TARGET_MAC)
f060a027 330 {
68435912 331 error ("-ms2600 is used without -ms");
3f21adc8 332 target_flags |= MASK_H8300S_1;
f060a027 333 }
16b503e9 334
35a462ce 335 if (TARGET_H8300 && TARGET_NORMAL_MODE)
336 {
5d4af384 337 error ("-mn is used without -mh or -ms");
35a462ce 338 target_flags ^= MASK_NORMAL_MODE;
339 }
0650a2e5 340
9f56f86b 341 /* Some of the shifts are optimized for speed by default.
0650a2e5 342 See http://gcc.gnu.org/ml/gcc-patches/2002-07/msg01858.html
9f56f86b 343 If optimizing for size, change shift_alg for those shift to
0650a2e5 344 SHIFT_LOOP. */
3a599070 345 if (optimize_size)
0650a2e5 346 {
3a599070 347 /* H8/300 */
348 shift_alg_hi[H8_300][SHIFT_ASHIFT][5] = SHIFT_LOOP;
349 shift_alg_hi[H8_300][SHIFT_ASHIFT][6] = SHIFT_LOOP;
350 shift_alg_hi[H8_300][SHIFT_ASHIFT][13] = SHIFT_LOOP;
351 shift_alg_hi[H8_300][SHIFT_ASHIFT][14] = SHIFT_LOOP;
0650a2e5 352
3a599070 353 shift_alg_hi[H8_300][SHIFT_LSHIFTRT][13] = SHIFT_LOOP;
354 shift_alg_hi[H8_300][SHIFT_LSHIFTRT][14] = SHIFT_LOOP;
0650a2e5 355
3a599070 356 shift_alg_hi[H8_300][SHIFT_ASHIFTRT][13] = SHIFT_LOOP;
357 shift_alg_hi[H8_300][SHIFT_ASHIFTRT][14] = SHIFT_LOOP;
0650a2e5 358
3a599070 359 /* H8/300H */
360 shift_alg_hi[H8_300H][SHIFT_ASHIFT][5] = SHIFT_LOOP;
361 shift_alg_hi[H8_300H][SHIFT_ASHIFT][6] = SHIFT_LOOP;
0650a2e5 362
3a599070 363 shift_alg_hi[H8_300H][SHIFT_LSHIFTRT][5] = SHIFT_LOOP;
364 shift_alg_hi[H8_300H][SHIFT_LSHIFTRT][6] = SHIFT_LOOP;
0650a2e5 365
3a599070 366 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][5] = SHIFT_LOOP;
367 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][6] = SHIFT_LOOP;
368 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][13] = SHIFT_LOOP;
369 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][14] = SHIFT_LOOP;
0650a2e5 370
371 /* H8S */
3a599070 372 shift_alg_hi[H8_S][SHIFT_ASHIFTRT][14] = SHIFT_LOOP;
0650a2e5 373 }
727c62dd 374
375 /* Work out a value for MOVE_RATIO. */
376 if (!TARGET_H8300SX)
377 {
378 /* Memory-memory moves are quite expensive without the
379 h8sx instructions. */
380 h8300_move_ratio = 3;
381 }
382 else if (flag_omit_frame_pointer)
383 {
384 /* movmd sequences are fairly cheap when er6 isn't fixed. They can
385 sometimes be as short as two individual memory-to-memory moves,
386 but since they use all the call-saved registers, it seems better
387 to allow up to three moves here. */
388 h8300_move_ratio = 4;
389 }
390 else if (optimize_size)
391 {
392 /* In this case we don't use movmd sequences since they tend
393 to be longer than calls to memcpy(). Memory-to-memory
394 moves are cheaper than for !TARGET_H8300SX, so it makes
395 sense to have a slightly higher threshold. */
396 h8300_move_ratio = 4;
397 }
398 else
399 {
400 /* We use movmd sequences for some moves since it can be quicker
401 than calling memcpy(). The sequences will need to save and
402 restore er6 though, so bump up the cost. */
403 h8300_move_ratio = 6;
404 }
405}
406
407/* Implement REG_CLASS_FROM_LETTER.
408
409 Some patterns need to use er6 as a scratch register. This is
410 difficult to arrange since er6 is the frame pointer and usually
411 can't be spilled.
412
413 Such patterns should define two alternatives, one which allows only
414 er6 and one which allows any general register. The former alternative
415 should have a 'd' constraint while the latter should be disparaged and
416 use 'D'.
417
418 Normally, 'd' maps to DESTINATION_REGS and 'D' maps to GENERAL_REGS.
419 However, there are cases where they should be NO_REGS:
420
421 - 'd' should be NO_REGS when reloading a function that uses the
422 frame pointer. In this case, DESTINATION_REGS won't contain any
423 spillable registers, so the first alternative can't be used.
424
425 - -fno-omit-frame-pointer means that the frame pointer will
426 always be in use. It's therefore better to map 'd' to NO_REGS
427 before reload so that register allocator will pick the second
428 alternative.
429
430 - we would like 'D' to be be NO_REGS when the frame pointer isn't
431 live, but we the frame pointer may turn out to be needed after
432 we start reload, and then we may have already decided we don't
433 have a choice, so we can't do that. Forcing the register
434 allocator to use er6 if possible might produce better code for
435 small functions: it's more efficient to save and restore er6 in
436 the prologue & epilogue than to do it in a define_split.
437 Hopefully disparaging 'D' will have a similar effect, without
438 forcing a reload failure if the frame pointer is found to be
439 needed too late. */
440
441enum reg_class
442h8300_reg_class_from_letter (int c)
443{
444 switch (c)
445 {
446 case 'a':
447 return MAC_REGS;
448
449 case 'c':
450 return COUNTER_REGS;
451
452 case 'd':
453 if (!flag_omit_frame_pointer && !reload_completed)
454 return NO_REGS;
455 if (frame_pointer_needed && reload_in_progress)
456 return NO_REGS;
457 return DESTINATION_REGS;
458
459 case 'D':
460 /* The meaning of a constraint shouldn't change dynamically, so
461 we can't make this NO_REGS. */
462 return GENERAL_REGS;
463
464 case 'f':
465 return SOURCE_REGS;
466
467 default:
468 return NO_REGS;
469 }
b839e0b4 470}
e1629549 471
cdfb02e8 472/* Return the byte register name for a register rtx X. B should be 0
473 if you want a lower byte register. B should be 1 if you want an
474 upper byte register. */
475
7198848c 476static const char *
230002f2 477byte_reg (rtx x, int b)
e1629549 478{
ded3e58c 479 static const char *const names_small[] = {
480 "r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
481 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h"
482 };
e1629549 483
3afe906b 484 gcc_assert (REG_P (x));
589b6991 485
e1629549 486 return names_small[REGNO (x) * 2 + b];
487}
488
489/* REGNO must be saved/restored across calls if this macro is true. */
b839e0b4 490
ded3e58c 491#define WORD_REG_USED(regno) \
b91522ff 492 (regno < SP_REG \
ded3e58c 493 /* No need to save registers if this function will not return. */ \
494 && ! TREE_THIS_VOLATILE (current_function_decl) \
5344805f 495 && (h8300_saveall_function_p (current_function_decl) \
ded3e58c 496 /* Save any call saved register that was used. */ \
3072d30e 497 || (df_regs_ever_live_p (regno) && !call_used_regs[regno]) \
ded3e58c 498 /* Save the frame pointer if it was used. */ \
3072d30e 499 || (regno == HARD_FRAME_POINTER_REGNUM && df_regs_ever_live_p (regno)) \
ded3e58c 500 /* Save any register used in an interrupt handler. */ \
41ed3bcd 501 || (h8300_current_function_interrupt_function_p () \
3072d30e 502 && df_regs_ever_live_p (regno)) \
ded3e58c 503 /* Save call clobbered registers in non-leaf interrupt \
504 handlers. */ \
41ed3bcd 505 || (h8300_current_function_interrupt_function_p () \
ded3e58c 506 && call_used_regs[regno] \
3754a8bb 507 && !current_function_is_leaf)))
e1629549 508
509/* Output assembly language to FILE for the operation OP with operand size
b839e0b4 510 SIZE to adjust the stack pointer. */
b839e0b4 511
e1629549 512static void
959e2f12 513h8300_emit_stack_adjustment (int sign, HOST_WIDE_INT size)
e1629549 514{
921a6571 515 /* If the frame size is 0, we don't have anything to do. */
516 if (size == 0)
a3dedda8 517 return;
921a6571 518
8f260b97 519 /* H8/300 cannot add/subtract a large constant with a single
520 instruction. If a temporary register is available, load the
521 constant to it and then do the addition. */
522 if (TARGET_H8300
523 && size > 4
524 && !h8300_current_function_interrupt_function_p ()
4ee9c684 525 && !(cfun->static_chain_decl != NULL && sign < 0))
b9393aaf 526 {
8f260b97 527 rtx r3 = gen_rtx_REG (Pmode, 3);
921a6571 528 emit_insn (gen_movhi (r3, GEN_INT (sign * size)));
529 emit_insn (gen_addhi3 (stack_pointer_rtx,
530 stack_pointer_rtx, r3));
bfc1492f 531 }
532 else
533 {
8f260b97 534 /* The stack adjustment made here is further optimized by the
535 splitter. In case of H8/300, the splitter always splits the
536 addition emitted here to make the adjustment
537 interrupt-safe. */
921a6571 538 if (Pmode == HImode)
539 emit_insn (gen_addhi3 (stack_pointer_rtx,
540 stack_pointer_rtx, GEN_INT (sign * size)));
541 else
542 emit_insn (gen_addsi3 (stack_pointer_rtx,
543 stack_pointer_rtx, GEN_INT (sign * size)));
e1629549 544 }
545}
546
b1292c73 547/* Round up frame size SIZE. */
548
959e2f12 549static HOST_WIDE_INT
550round_frame_size (HOST_WIDE_INT size)
b1292c73 551{
b25ffd74 552 return ((size + STACK_BOUNDARY / BITS_PER_UNIT - 1)
553 & -STACK_BOUNDARY / BITS_PER_UNIT);
b1292c73 554}
555
556/* Compute which registers to push/pop.
557 Return a bit vector of registers. */
558
559static unsigned int
230002f2 560compute_saved_regs (void)
b1292c73 561{
562 unsigned int saved_regs = 0;
563 int regno;
564
565 /* Construct a bit vector of registers to be pushed/popped. */
f4ac50fb 566 for (regno = 0; regno <= HARD_FRAME_POINTER_REGNUM; regno++)
b1292c73 567 {
568 if (WORD_REG_USED (regno))
569 saved_regs |= 1 << regno;
570 }
571
572 /* Don't push/pop the frame pointer as it is treated separately. */
573 if (frame_pointer_needed)
f4ac50fb 574 saved_regs &= ~(1 << HARD_FRAME_POINTER_REGNUM);
b1292c73 575
576 return saved_regs;
577}
578
8f260b97 579/* Emit an insn to push register RN. */
b1292c73 580
581static void
230002f2 582push (int rn)
b1292c73 583{
8f260b97 584 rtx reg = gen_rtx_REG (word_mode, rn);
585 rtx x;
586
4081a531 587 if (TARGET_H8300)
8f260b97 588 x = gen_push_h8300 (reg);
c99597ba 589 else if (!TARGET_NORMAL_MODE)
34712114 590 x = gen_push_h8300hs_advanced (reg);
c99597ba 591 else
592 x = gen_push_h8300hs_normal (reg);
8f260b97 593 x = emit_insn (x);
594 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, 0);
b1292c73 595}
596
8f260b97 597/* Emit an insn to pop register RN. */
b1292c73 598
599static void
230002f2 600pop (int rn)
b1292c73 601{
8f260b97 602 rtx reg = gen_rtx_REG (word_mode, rn);
603 rtx x;
604
4081a531 605 if (TARGET_H8300)
8f260b97 606 x = gen_pop_h8300 (reg);
c99597ba 607 else if (!TARGET_NORMAL_MODE)
34712114 608 x = gen_pop_h8300hs_advanced (reg);
c99597ba 609 else
610 x = gen_pop_h8300hs_normal (reg);
8f260b97 611 x = emit_insn (x);
612 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, 0);
b1292c73 613}
e1629549 614
727c62dd 615/* Emit an instruction to push or pop NREGS consecutive registers
616 starting at register REGNO. POP_P selects a pop rather than a
617 push and RETURN_P is true if the instruction should return.
618
619 It must be possible to do the requested operation in a single
620 instruction. If NREGS == 1 && !RETURN_P, use a normal push
621 or pop insn. Otherwise emit a parallel of the form:
622
623 (parallel
624 [(return) ;; if RETURN_P
625 (save or restore REGNO)
626 (save or restore REGNO + 1)
627 ...
628 (save or restore REGNO + NREGS - 1)
629 (set sp (plus sp (const_int adjust)))] */
630
631static void
632h8300_push_pop (int regno, int nregs, int pop_p, int return_p)
633{
634 int i, j;
635 rtvec vec;
636 rtx sp, offset;
637
638 /* See whether we can use a simple push or pop. */
639 if (!return_p && nregs == 1)
640 {
641 if (pop_p)
642 pop (regno);
643 else
644 push (regno);
645 return;
646 }
647
648 /* We need one element for the return insn, if present, one for each
649 register, and one for stack adjustment. */
650 vec = rtvec_alloc ((return_p != 0) + nregs + 1);
651 sp = stack_pointer_rtx;
652 i = 0;
653
654 /* Add the return instruction. */
655 if (return_p)
656 {
657 RTVEC_ELT (vec, i) = gen_rtx_RETURN (VOIDmode);
658 i++;
659 }
660
661 /* Add the register moves. */
662 for (j = 0; j < nregs; j++)
663 {
664 rtx lhs, rhs;
665
666 if (pop_p)
667 {
668 /* Register REGNO + NREGS - 1 is popped first. Before the
669 stack adjustment, its slot is at address @sp. */
670 lhs = gen_rtx_REG (SImode, regno + j);
671 rhs = gen_rtx_MEM (SImode, plus_constant (sp, (nregs - j - 1) * 4));
672 }
673 else
674 {
675 /* Register REGNO is pushed first and will be stored at @(-4,sp). */
676 lhs = gen_rtx_MEM (SImode, plus_constant (sp, (j + 1) * -4));
677 rhs = gen_rtx_REG (SImode, regno + j);
678 }
679 RTVEC_ELT (vec, i + j) = gen_rtx_SET (VOIDmode, lhs, rhs);
680 }
681
682 /* Add the stack adjustment. */
683 offset = GEN_INT ((pop_p ? nregs : -nregs) * 4);
684 RTVEC_ELT (vec, i + j) = gen_rtx_SET (VOIDmode, sp,
685 gen_rtx_PLUS (Pmode, sp, offset));
686
687 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
688}
689
690/* Return true if X has the value sp + OFFSET. */
691
692static int
693h8300_stack_offset_p (rtx x, int offset)
694{
695 if (offset == 0)
696 return x == stack_pointer_rtx;
697
698 return (GET_CODE (x) == PLUS
699 && XEXP (x, 0) == stack_pointer_rtx
700 && GET_CODE (XEXP (x, 1)) == CONST_INT
701 && INTVAL (XEXP (x, 1)) == offset);
702}
703
704/* A subroutine of h8300_ldm_stm_parallel. X is one pattern in
705 something that may be an ldm or stm instruction. If it fits
706 the required template, return the register it loads or stores,
707 otherwise return -1.
708
709 LOAD_P is true if X should be a load, false if it should be a store.
710 NREGS is the number of registers that the whole instruction is expected
711 to load or store. INDEX is the index of the register that X should
712 load or store, relative to the lowest-numbered register. */
713
714static int
715h8300_ldm_stm_regno (rtx x, int load_p, int index, int nregs)
716{
717 int regindex, memindex, offset;
718
719 if (load_p)
720 regindex = 0, memindex = 1, offset = (nregs - index - 1) * 4;
721 else
722 memindex = 0, regindex = 1, offset = (index + 1) * -4;
723
724 if (GET_CODE (x) == SET
725 && GET_CODE (XEXP (x, regindex)) == REG
726 && GET_CODE (XEXP (x, memindex)) == MEM
727 && h8300_stack_offset_p (XEXP (XEXP (x, memindex), 0), offset))
728 return REGNO (XEXP (x, regindex));
729
730 return -1;
731}
732
733/* Return true if the elements of VEC starting at FIRST describe an
734 ldm or stm instruction (LOAD_P says which). */
735
d255713c 736int
727c62dd 737h8300_ldm_stm_parallel (rtvec vec, int load_p, int first)
738{
739 rtx last;
740 int nregs, i, regno, adjust;
741
742 /* There must be a stack adjustment, a register move, and at least one
743 other operation (a return or another register move). */
744 if (GET_NUM_ELEM (vec) < 3)
745 return false;
746
747 /* Get the range of registers to be pushed or popped. */
748 nregs = GET_NUM_ELEM (vec) - first - 1;
749 regno = h8300_ldm_stm_regno (RTVEC_ELT (vec, first), load_p, 0, nregs);
750
751 /* Check that the call to h8300_ldm_stm_regno succeeded and
752 that we're only dealing with GPRs. */
753 if (regno < 0 || regno + nregs > 8)
754 return false;
755
756 /* 2-register h8s instructions must start with an even-numbered register.
757 3- and 4-register instructions must start with er0 or er4. */
758 if (!TARGET_H8300SX)
759 {
760 if ((regno & 1) != 0)
761 return false;
762 if (nregs > 2 && (regno & 3) != 0)
763 return false;
764 }
765
766 /* Check the other loads or stores. */
767 for (i = 1; i < nregs; i++)
768 if (h8300_ldm_stm_regno (RTVEC_ELT (vec, first + i), load_p, i, nregs)
769 != regno + i)
770 return false;
771
772 /* Check the stack adjustment. */
773 last = RTVEC_ELT (vec, first + nregs);
774 adjust = (load_p ? nregs : -nregs) * 4;
775 return (GET_CODE (last) == SET
776 && SET_DEST (last) == stack_pointer_rtx
777 && h8300_stack_offset_p (SET_SRC (last), adjust));
778}
779
f2702e8a 780/* This is what the stack looks like after the prolog of
e1629549 781 a function with a frame has been set up:
782
b839e0b4 783 <args>
784 PC
785 FP <- fp
786 <locals>
9f56f86b 787 <saved registers> <- sp
e1629549 788
789 This is what the stack looks like after the prolog of
790 a function which doesn't have a frame:
791
b839e0b4 792 <args>
793 PC
794 <locals>
9f56f86b 795 <saved registers> <- sp
e1629549 796*/
797
8f260b97 798/* Generate RTL code for the function prologue. */
b1292c73 799
8f260b97 800void
230002f2 801h8300_expand_prologue (void)
e1629549 802{
b2adb3e0 803 int regno;
b1292c73 804 int saved_regs;
97709d8d 805 int n_regs;
e1629549 806
09c48b9c 807 /* If the current function has the OS_Task attribute set, then
808 we have a naked prologue. */
809 if (h8300_os_task_function_p (current_function_decl))
8f260b97 810 return;
09c48b9c 811
812 if (h8300_monitor_function_p (current_function_decl))
8f260b97 813 /* My understanding of monitor functions is they act just like
814 interrupt functions, except the prologue must mask
815 interrupts. */
816 emit_insn (gen_monitor_prologue ());
09c48b9c 817
b839e0b4 818 if (frame_pointer_needed)
819 {
eb2aa24e 820 /* Push fp. */
f4ac50fb 821 push (HARD_FRAME_POINTER_REGNUM);
2a8d3d1b 822 emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
69b4e418 823 }
b839e0b4 824
b1292c73 825 /* Push the rest of the registers in ascending order. */
826 saved_regs = compute_saved_regs ();
b2adb3e0 827 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno += n_regs)
97709d8d 828 {
97709d8d 829 n_regs = 1;
b1292c73 830 if (saved_regs & (1 << regno))
69b4e418 831 {
832 if (TARGET_H8300S)
833 {
97709d8d 834 /* See how many registers we can push at the same time. */
727c62dd 835 if ((!TARGET_H8300SX || (regno & 3) == 0)
b1292c73 836 && ((saved_regs >> regno) & 0x0f) == 0x0f)
97709d8d 837 n_regs = 4;
838
727c62dd 839 else if ((!TARGET_H8300SX || (regno & 3) == 0)
b1292c73 840 && ((saved_regs >> regno) & 0x07) == 0x07)
97709d8d 841 n_regs = 3;
842
727c62dd 843 else if ((!TARGET_H8300SX || (regno & 1) == 0)
b1292c73 844 && ((saved_regs >> regno) & 0x03) == 0x03)
97709d8d 845 n_regs = 2;
69b4e418 846 }
97709d8d 847
727c62dd 848 h8300_push_pop (regno, n_regs, 0, 0);
e1629549 849 }
850 }
f4ac50fb 851
852 /* Leave room for locals. */
853 h8300_emit_stack_adjustment (-1, round_frame_size (get_frame_size ()));
e1629549 854}
855
cdfb02e8 856/* Return nonzero if we can use "rts" for the function currently being
857 compiled. */
858
8f260b97 859int
230002f2 860h8300_can_use_return_insn_p (void)
8f260b97 861{
862 return (reload_completed
863 && !frame_pointer_needed
864 && get_frame_size () == 0
865 && compute_saved_regs () == 0);
866}
e1629549 867
8f260b97 868/* Generate RTL code for the function epilogue. */
869
870void
230002f2 871h8300_expand_epilogue (void)
e1629549 872{
b2adb3e0 873 int regno;
b1292c73 874 int saved_regs;
97709d8d 875 int n_regs;
727c62dd 876 HOST_WIDE_INT frame_size;
877 bool returned_p;
e1629549 878
41ed3bcd 879 if (h8300_os_task_function_p (current_function_decl))
8f260b97 880 /* OS_Task epilogues are nearly naked -- they just have an
881 rts instruction. */
882 return;
e1629549 883
727c62dd 884 frame_size = round_frame_size (get_frame_size ());
885 returned_p = false;
886
f4ac50fb 887 /* Deallocate locals. */
727c62dd 888 h8300_emit_stack_adjustment (1, frame_size);
f4ac50fb 889
b1292c73 890 /* Pop the saved registers in descending order. */
891 saved_regs = compute_saved_regs ();
b2adb3e0 892 for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno -= n_regs)
97709d8d 893 {
97709d8d 894 n_regs = 1;
b1292c73 895 if (saved_regs & (1 << regno))
e1629549 896 {
69b4e418 897 if (TARGET_H8300S)
898 {
97709d8d 899 /* See how many registers we can pop at the same time. */
727c62dd 900 if ((TARGET_H8300SX || (regno & 3) == 3)
901 && ((saved_regs << 3 >> regno) & 0x0f) == 0x0f)
97709d8d 902 n_regs = 4;
903
727c62dd 904 else if ((TARGET_H8300SX || (regno & 3) == 2)
905 && ((saved_regs << 2 >> regno) & 0x07) == 0x07)
97709d8d 906 n_regs = 3;
907
727c62dd 908 else if ((TARGET_H8300SX || (regno & 1) == 1)
909 && ((saved_regs << 1 >> regno) & 0x03) == 0x03)
97709d8d 910 n_regs = 2;
69b4e418 911 }
97709d8d 912
727c62dd 913 /* See if this pop would be the last insn before the return.
914 If so, use rte/l or rts/l instead of pop or ldm.l. */
915 if (TARGET_H8300SX
916 && !frame_pointer_needed
917 && frame_size == 0
918 && (saved_regs & ((1 << (regno - n_regs + 1)) - 1)) == 0)
919 returned_p = true;
920
921 h8300_push_pop (regno - n_regs + 1, n_regs, 1, returned_p);
e1629549 922 }
e1629549 923 }
b839e0b4 924
eb2aa24e 925 /* Pop frame pointer if we had one. */
69b4e418 926 if (frame_pointer_needed)
727c62dd 927 {
928 if (TARGET_H8300SX)
929 returned_p = true;
930 h8300_push_pop (HARD_FRAME_POINTER_REGNUM, 1, 1, returned_p);
931 }
932
933 if (!returned_p)
934 emit_insn (gen_rtx_RETURN (VOIDmode));
8f260b97 935}
69b4e418 936
41ed3bcd 937/* Return nonzero if the current function is an interrupt
938 function. */
939
940int
230002f2 941h8300_current_function_interrupt_function_p (void)
41ed3bcd 942{
943 return (h8300_interrupt_function_p (current_function_decl)
944 || h8300_monitor_function_p (current_function_decl));
945}
946
b839e0b4 947/* Output assembly code for the start of the file. */
948
92c473b8 949static void
950h8300_file_start (void)
b839e0b4 951{
92c473b8 952 default_file_start ();
9f56f86b 953
b839e0b4 954 if (TARGET_H8300H)
92c473b8 955 fputs (TARGET_NORMAL_MODE ? "\t.h8300hn\n" : "\t.h8300h\n", asm_out_file);
727c62dd 956 else if (TARGET_H8300SX)
957 fputs (TARGET_NORMAL_MODE ? "\t.h8300sxn\n" : "\t.h8300sx\n", asm_out_file);
69b4e418 958 else if (TARGET_H8300S)
92c473b8 959 fputs (TARGET_NORMAL_MODE ? "\t.h8300sn\n" : "\t.h8300s\n", asm_out_file);
b839e0b4 960}
961
962/* Output assembly language code for the end of file. */
963
f6940372 964static void
230002f2 965h8300_file_end (void)
b839e0b4 966{
f6940372 967 fputs ("\t.end\n", asm_out_file);
e1629549 968}
969\f
c5673261 970/* Split an add of a small constant into two adds/subs insns.
971
972 If USE_INCDEC_P is nonzero, we generate the last insn using inc/dec
973 instead of adds/subs. */
8e7d5182 974
975void
230002f2 976split_adds_subs (enum machine_mode mode, rtx *operands)
0a56558f 977{
8e7d5182 978 HOST_WIDE_INT val = INTVAL (operands[1]);
979 rtx reg = operands[0];
d8afbfc6 980 HOST_WIDE_INT sign = 1;
981 HOST_WIDE_INT amount;
90b024e5 982 rtx (*gen_add) (rtx, rtx, rtx);
0a56558f 983
d8afbfc6 984 /* Force VAL to be positive so that we do not have to consider the
985 sign. */
986 if (val < 0)
0a56558f 987 {
d8afbfc6 988 val = -val;
989 sign = -1;
990 }
0a56558f 991
c5673261 992 switch (mode)
993 {
994 case HImode:
90b024e5 995 gen_add = gen_addhi3;
c5673261 996 break;
997
998 case SImode:
90b024e5 999 gen_add = gen_addsi3;
c5673261 1000 break;
1001
1002 default:
3afe906b 1003 gcc_unreachable ();
c5673261 1004 }
1005
d8afbfc6 1006 /* Try different amounts in descending order. */
1007 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
1008 amount > 0;
1009 amount /= 2)
1010 {
27276a3b 1011 for (; val >= amount; val -= amount)
90b024e5 1012 emit_insn (gen_add (reg, reg, GEN_INT (sign * amount)));
0a56558f 1013 }
1014
d8afbfc6 1015 return;
0a56558f 1016}
1017
e1629549 1018/* Handle machine specific pragmas for compatibility with existing
b839e0b4 1019 compilers for the H8/300.
e1629549 1020
cc72e60a 1021 pragma saveall generates prologue/epilogue code which saves and
e1629549 1022 restores all the registers on function entry.
b839e0b4 1023
e1629549 1024 pragma interrupt saves and restores all registers, and exits with
1025 an rte instruction rather than an rts. A pointer to a function
1026 with this attribute may be safely used in an interrupt vector. */
b839e0b4 1027
1fcd08b1 1028void
230002f2 1029h8300_pr_interrupt (struct cpp_reader *pfile ATTRIBUTE_UNUSED)
e1629549 1030{
41ed3bcd 1031 pragma_interrupt = 1;
1fcd08b1 1032}
b97b38c0 1033
1fcd08b1 1034void
230002f2 1035h8300_pr_saveall (struct cpp_reader *pfile ATTRIBUTE_UNUSED)
1fcd08b1 1036{
1037 pragma_saveall = 1;
e1629549 1038}
1fcd08b1 1039
c738c371 1040/* If the next function argument with MODE and TYPE is to be passed in
1041 a register, return a reg RTX for the hard register in which to pass
1042 the argument. CUM represents the state after the last argument.
1043 If the argument is to be pushed, NULL_RTX is returned. */
b839e0b4 1044
e1629549 1045rtx
230002f2 1046function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1047 tree type, int named)
e1629549 1048{
70a21926 1049 static const char *const hand_list[] = {
1050 "__main",
1051 "__cmpsi2",
1052 "__divhi3",
1053 "__modhi3",
1054 "__udivhi3",
1055 "__umodhi3",
1056 "__divsi3",
1057 "__modsi3",
1058 "__udivsi3",
1059 "__umodsi3",
1060 "__mulhi3",
1061 "__mulsi3",
1062 "__reg_memcpy",
1063 "__reg_memset",
1064 "__ucmpsi2",
1065 0,
1066 };
1067
6996dd46 1068 rtx result = NULL_RTX;
9305fe33 1069 const char *fname;
b839e0b4 1070 int regpass = 0;
1071
0d37f3a1 1072 /* Never pass unnamed arguments in registers. */
1073 if (!named)
6996dd46 1074 return NULL_RTX;
0d37f3a1 1075
b839e0b4 1076 /* Pass 3 regs worth of data in regs when user asked on the command line. */
1077 if (TARGET_QUICKCALL)
1078 regpass = 3;
1079
1080 /* If calling hand written assembler, use 4 regs of args. */
b839e0b4 1081 if (cum->libcall)
1082 {
9305fe33 1083 const char * const *p;
b839e0b4 1084
1085 fname = XSTR (cum->libcall, 0);
1086
1087 /* See if this libcall is one of the hand coded ones. */
b839e0b4 1088 for (p = hand_list; *p && strcmp (*p, fname) != 0; p++)
1089 ;
e1629549 1090
b839e0b4 1091 if (*p)
1092 regpass = 4;
1093 }
1094
1095 if (regpass)
1096 {
1097 int size;
1098
1099 if (mode == BLKmode)
1100 size = int_size_in_bytes (type);
1101 else
1102 size = GET_MODE_SIZE (mode);
1103
60ff2ea8 1104 if (size + cum->nbytes <= regpass * UNITS_PER_WORD
1105 && cum->nbytes / UNITS_PER_WORD <= 3)
1106 result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
b839e0b4 1107 }
e1629549 1108
b839e0b4 1109 return result;
1110}
1111\f
cdfb02e8 1112/* Compute the cost of an and insn. */
1113
fab7adbf 1114static int
230002f2 1115h8300_and_costs (rtx x)
b785ceb4 1116{
1117 rtx operands[4];
1118
1119 if (GET_MODE (x) == QImode)
1120 return 1;
1121
1122 if (GET_MODE (x) != HImode
1123 && GET_MODE (x) != SImode)
1124 return 100;
1125
1126 operands[0] = NULL;
727c62dd 1127 operands[1] = XEXP (x, 0);
b785ceb4 1128 operands[2] = XEXP (x, 1);
1129 operands[3] = x;
5a622ac3 1130 return compute_logical_op_length (GET_MODE (x), operands) / 2;
b785ceb4 1131}
1132
cdfb02e8 1133/* Compute the cost of a shift insn. */
1134
fab7adbf 1135static int
230002f2 1136h8300_shift_costs (rtx x)
c033ada4 1137{
1138 rtx operands[4];
1139
1140 if (GET_MODE (x) != QImode
1141 && GET_MODE (x) != HImode
1142 && GET_MODE (x) != SImode)
1143 return 100;
1144
1145 operands[0] = NULL;
1146 operands[1] = NULL;
1147 operands[2] = XEXP (x, 1);
1148 operands[3] = x;
5a622ac3 1149 return compute_a_shift_length (NULL, operands) / 2;
c033ada4 1150}
fab7adbf 1151
cdfb02e8 1152/* Worker function for TARGET_RTX_COSTS. */
1153
fab7adbf 1154static bool
230002f2 1155h8300_rtx_costs (rtx x, int code, int outer_code, int *total)
fab7adbf 1156{
727c62dd 1157 if (TARGET_H8300SX && outer_code == MEM)
1158 {
1159 /* Estimate the number of execution states needed to calculate
1160 the address. */
1161 if (register_operand (x, VOIDmode)
1162 || GET_CODE (x) == POST_INC
1163 || GET_CODE (x) == POST_DEC
1164 || CONSTANT_P (x))
1165 *total = 0;
1166 else
1167 *total = COSTS_N_INSNS (1);
1168 return true;
1169 }
1170
fab7adbf 1171 switch (code)
1172 {
1d6dae88 1173 case CONST_INT:
1174 {
1175 HOST_WIDE_INT n = INTVAL (x);
1176
727c62dd 1177 if (TARGET_H8300SX)
1178 {
1179 /* Constant operands need the same number of processor
1180 states as register operands. Although we could try to
1181 use a size-based cost for optimize_size, the lack of
1182 of a mode makes the results very unpredictable. */
1183 *total = 0;
1184 return true;
1185 }
1d6dae88 1186 if (-4 <= n || n <= 4)
1187 {
1188 switch ((int) n)
1189 {
1190 case 0:
1191 *total = 0;
1192 return true;
1193 case 1:
1194 case 2:
1195 case -1:
1196 case -2:
1197 *total = 0 + (outer_code == SET);
1198 return true;
1199 case 4:
1200 case -4:
1201 if (TARGET_H8300H || TARGET_H8300S)
1202 *total = 0 + (outer_code == SET);
1203 else
1204 *total = 1;
1205 return true;
1206 }
1207 }
1208 *total = 1;
1209 return true;
1210 }
1211
1212 case CONST:
1213 case LABEL_REF:
1214 case SYMBOL_REF:
727c62dd 1215 if (TARGET_H8300SX)
1216 {
1217 /* See comment for CONST_INT. */
1218 *total = 0;
1219 return true;
1220 }
1d6dae88 1221 *total = 3;
1222 return true;
1223
1224 case CONST_DOUBLE:
1225 *total = 20;
1226 return true;
1227
fab7adbf 1228 case AND:
727c62dd 1229 if (!h8300_dst_operand (XEXP (x, 0), VOIDmode)
1230 || !h8300_src_operand (XEXP (x, 1), VOIDmode))
1231 return false;
fab7adbf 1232 *total = COSTS_N_INSNS (h8300_and_costs (x));
1233 return true;
1234
1235 /* We say that MOD and DIV are so expensive because otherwise we'll
1236 generate some really horrible code for division of a power of two. */
1237 case MOD:
1238 case DIV:
727c62dd 1239 case UMOD:
1240 case UDIV:
1241 if (TARGET_H8300SX)
1242 switch (GET_MODE (x))
1243 {
1244 case QImode:
1245 case HImode:
1246 *total = COSTS_N_INSNS (optimize_size ? 4 : 10);
1247 return false;
1248
1249 case SImode:
1250 *total = COSTS_N_INSNS (optimize_size ? 4 : 18);
1251 return false;
1252
1253 default:
1254 break;
1255 }
1256 *total = COSTS_N_INSNS (12);
fab7adbf 1257 return true;
1258
1259 case MULT:
727c62dd 1260 if (TARGET_H8300SX)
1261 switch (GET_MODE (x))
1262 {
1263 case QImode:
1264 case HImode:
1265 *total = COSTS_N_INSNS (2);
1266 return false;
1267
1268 case SImode:
1269 *total = COSTS_N_INSNS (5);
1270 return false;
1271
1272 default:
1273 break;
1274 }
1275 *total = COSTS_N_INSNS (4);
fab7adbf 1276 return true;
1277
1278 case ASHIFT:
1279 case ASHIFTRT:
1280 case LSHIFTRT:
727c62dd 1281 if (h8sx_binary_shift_operator (x, VOIDmode))
1282 {
1283 *total = COSTS_N_INSNS (2);
1284 return false;
1285 }
1286 else if (h8sx_unary_shift_operator (x, VOIDmode))
1287 {
1288 *total = COSTS_N_INSNS (1);
1289 return false;
1290 }
fab7adbf 1291 *total = COSTS_N_INSNS (h8300_shift_costs (x));
1292 return true;
1293
1294 case ROTATE:
1295 case ROTATERT:
1296 if (GET_MODE (x) == HImode)
1297 *total = 2;
1298 else
1299 *total = 8;
1300 return true;
1301
1302 default:
727c62dd 1303 *total = COSTS_N_INSNS (1);
1304 return false;
fab7adbf 1305 }
1306}
b839e0b4 1307\f
e1629549 1308/* Documentation for the machine specific operand escapes:
1309
b839e0b4 1310 'E' like s but negative.
1311 'F' like t but negative.
1312 'G' constant just the negative
2c7be643 1313 'R' print operand as a byte:8 address if appropriate, else fall back to
1314 'X' handling.
b839e0b4 1315 'S' print operand as a long word
e1629549 1316 'T' print operand as a word
b839e0b4 1317 'V' find the set bit, and print its number.
1318 'W' find the clear bit, and print its number.
1319 'X' print operand as a byte
e1629549 1320 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
2c7be643 1321 If this operand isn't a register, fall back to 'R' handling.
b839e0b4 1322 'Z' print int & 7.
4c924258 1323 'c' print the opcode corresponding to rtl
03fb0c81 1324 'e' first word of 32-bit value - if reg, then least reg. if mem
b839e0b4 1325 then least. if const then most sig word
03fb0c81 1326 'f' second word of 32-bit value - if reg, then biggest reg. if mem
b839e0b4 1327 then +2. if const then least sig word
e1629549 1328 'j' print operand as condition code.
1329 'k' print operand as reverse condition code.
727c62dd 1330 'm' convert an integer operand to a size suffix (.b, .w or .l)
1331 'o' print an integer without a leading '#'
03fb0c81 1332 's' print as low byte of 16-bit value
1333 't' print as high byte of 16-bit value
1334 'w' print as low byte of 32-bit value
1335 'x' print as 2nd byte of 32-bit value
1336 'y' print as 3rd byte of 32-bit value
1337 'z' print as msb of 32-bit value
b839e0b4 1338*/
e1629549 1339
1340/* Return assembly language string which identifies a comparison type. */
1341
9305fe33 1342static const char *
230002f2 1343cond_string (enum rtx_code code)
e1629549 1344{
1345 switch (code)
1346 {
1347 case NE:
1348 return "ne";
1349 case EQ:
1350 return "eq";
1351 case GE:
1352 return "ge";
1353 case GT:
1354 return "gt";
1355 case LE:
1356 return "le";
1357 case LT:
1358 return "lt";
1359 case GEU:
1360 return "hs";
1361 case GTU:
1362 return "hi";
1363 case LEU:
1364 return "ls";
1365 case LTU:
1366 return "lo";
1367 default:
3afe906b 1368 gcc_unreachable ();
e1629549 1369 }
1370}
1371
1372/* Print operand X using operand code CODE to assembly language output file
1373 FILE. */
1374
1375void
230002f2 1376print_operand (FILE *file, rtx x, int code)
e1629549 1377{
30c992ef 1378 /* This is used for communication between codes V,W,Z and Y. */
e1629549 1379 static int bitint;
1380
1381 switch (code)
1382 {
b839e0b4 1383 case 'E':
1384 switch (GET_CODE (x))
1385 {
1386 case REG:
1387 fprintf (file, "%sl", names_big[REGNO (x)]);
1388 break;
1389 case CONST_INT:
21650cc9 1390 fprintf (file, "#%ld", (-INTVAL (x)) & 0xff);
b839e0b4 1391 break;
1392 default:
3afe906b 1393 gcc_unreachable ();
b839e0b4 1394 }
1395 break;
1396 case 'F':
1397 switch (GET_CODE (x))
1398 {
1399 case REG:
1400 fprintf (file, "%sh", names_big[REGNO (x)]);
1401 break;
1402 case CONST_INT:
21650cc9 1403 fprintf (file, "#%ld", ((-INTVAL (x)) & 0xff00) >> 8);
b839e0b4 1404 break;
1405 default:
3afe906b 1406 gcc_unreachable ();
b839e0b4 1407 }
1408 break;
e1629549 1409 case 'G':
3afe906b 1410 gcc_assert (GET_CODE (x) == CONST_INT);
21650cc9 1411 fprintf (file, "#%ld", 0xff & (-INTVAL (x)));
e1629549 1412 break;
b839e0b4 1413 case 'S':
1414 if (GET_CODE (x) == REG)
1415 fprintf (file, "%s", names_extended[REGNO (x)]);
e1629549 1416 else
b839e0b4 1417 goto def;
e1629549 1418 break;
b839e0b4 1419 case 'T':
1420 if (GET_CODE (x) == REG)
1421 fprintf (file, "%s", names_big[REGNO (x)]);
e1629549 1422 else
b839e0b4 1423 goto def;
e1629549 1424 break;
b839e0b4 1425 case 'V':
3a59a065 1426 bitint = exact_log2 (INTVAL (x) & 0xff);
3afe906b 1427 gcc_assert (bitint >= 0);
3a59a065 1428 fprintf (file, "#%d", bitint);
e1629549 1429 break;
b839e0b4 1430 case 'W':
e1629549 1431 bitint = exact_log2 ((~INTVAL (x)) & 0xff);
3afe906b 1432 gcc_assert (bitint >= 0);
3a59a065 1433 fprintf (file, "#%d", bitint);
e1629549 1434 break;
2c7be643 1435 case 'R':
b839e0b4 1436 case 'X':
1437 if (GET_CODE (x) == REG)
1438 fprintf (file, "%s", byte_reg (x, 0));
1439 else
1440 goto def;
1441 break;
1442 case 'Y':
3afe906b 1443 gcc_assert (bitint >= 0);
b839e0b4 1444 if (GET_CODE (x) == REG)
1445 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
1446 else
2c7be643 1447 print_operand (file, x, 'R');
b839e0b4 1448 bitint = -1;
1449 break;
1450 case 'Z':
1451 bitint = INTVAL (x);
e1629549 1452 fprintf (file, "#%d", bitint & 7);
1453 break;
4c924258 1454 case 'c':
1455 switch (GET_CODE (x))
1456 {
1457 case IOR:
1458 fprintf (file, "or");
1459 break;
1460 case XOR:
1461 fprintf (file, "xor");
1462 break;
77016b8f 1463 case AND:
1464 fprintf (file, "and");
1465 break;
4c924258 1466 default:
1467 break;
1468 }
1469 break;
e1629549 1470 case 'e':
1471 switch (GET_CODE (x))
1472 {
1473 case REG:
b839e0b4 1474 if (TARGET_H8300)
1475 fprintf (file, "%s", names_big[REGNO (x)]);
1476 else
1477 fprintf (file, "%s", names_upper_extended[REGNO (x)]);
e1629549 1478 break;
1479 case MEM:
e1629549 1480 print_operand (file, x, 0);
1481 break;
1482 case CONST_INT:
21650cc9 1483 fprintf (file, "#%ld", ((INTVAL (x) >> 16) & 0xffff));
e1629549 1484 break;
737a5d5b 1485 case CONST_DOUBLE:
1486 {
1487 long val;
1488 REAL_VALUE_TYPE rv;
1489 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1490 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
9305fe33 1491 fprintf (file, "#%ld", ((val >> 16) & 0xffff));
737a5d5b 1492 break;
1493 }
e1629549 1494 default:
3afe906b 1495 gcc_unreachable ();
e1629549 1496 break;
1497 }
1498 break;
e1629549 1499 case 'f':
1500 switch (GET_CODE (x))
1501 {
1502 case REG:
b839e0b4 1503 if (TARGET_H8300)
1504 fprintf (file, "%s", names_big[REGNO (x) + 1]);
1505 else
1506 fprintf (file, "%s", names_big[REGNO (x)]);
e1629549 1507 break;
e1629549 1508 case MEM:
eafc6604 1509 x = adjust_address (x, HImode, 2);
e1629549 1510 print_operand (file, x, 0);
1511 break;
e1629549 1512 case CONST_INT:
21650cc9 1513 fprintf (file, "#%ld", INTVAL (x) & 0xffff);
e1629549 1514 break;
737a5d5b 1515 case CONST_DOUBLE:
1516 {
1517 long val;
1518 REAL_VALUE_TYPE rv;
1519 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1520 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
9305fe33 1521 fprintf (file, "#%ld", (val & 0xffff));
737a5d5b 1522 break;
1523 }
e1629549 1524 default:
3afe906b 1525 gcc_unreachable ();
e1629549 1526 }
1527 break;
e1629549 1528 case 'j':
7fe1d31c 1529 fputs (cond_string (GET_CODE (x)), file);
e1629549 1530 break;
e1629549 1531 case 'k':
7fe1d31c 1532 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
e1629549 1533 break;
727c62dd 1534 case 'm':
3afe906b 1535 gcc_assert (GET_CODE (x) == CONST_INT);
1536 switch (INTVAL (x))
1537 {
1538 case 1:
1539 fputs (".b", file);
1540 break;
1541
1542 case 2:
1543 fputs (".w", file);
1544 break;
1545
1546 case 4:
1547 fputs (".l", file);
1548 break;
1549
1550 default:
1551 gcc_unreachable ();
1552 }
727c62dd 1553 break;
1554 case 'o':
1555 print_operand_address (file, x);
1556 break;
b839e0b4 1557 case 's':
1558 if (GET_CODE (x) == CONST_INT)
21650cc9 1559 fprintf (file, "#%ld", (INTVAL (x)) & 0xff);
b839e0b4 1560 else
1561 fprintf (file, "%s", byte_reg (x, 0));
1562 break;
1563 case 't':
1564 if (GET_CODE (x) == CONST_INT)
21650cc9 1565 fprintf (file, "#%ld", (INTVAL (x) >> 8) & 0xff);
b839e0b4 1566 else
1567 fprintf (file, "%s", byte_reg (x, 1));
1568 break;
b839e0b4 1569 case 'w':
1570 if (GET_CODE (x) == CONST_INT)
21650cc9 1571 fprintf (file, "#%ld", INTVAL (x) & 0xff);
b839e0b4 1572 else
69b4e418 1573 fprintf (file, "%s",
1574 byte_reg (x, TARGET_H8300 ? 2 : 0));
b839e0b4 1575 break;
1576 case 'x':
1577 if (GET_CODE (x) == CONST_INT)
21650cc9 1578 fprintf (file, "#%ld", (INTVAL (x) >> 8) & 0xff);
b839e0b4 1579 else
69b4e418 1580 fprintf (file, "%s",
1581 byte_reg (x, TARGET_H8300 ? 3 : 1));
b839e0b4 1582 break;
1583 case 'y':
1584 if (GET_CODE (x) == CONST_INT)
21650cc9 1585 fprintf (file, "#%ld", (INTVAL (x) >> 16) & 0xff);
b839e0b4 1586 else
1587 fprintf (file, "%s", byte_reg (x, 0));
1588 break;
1589 case 'z':
1590 if (GET_CODE (x) == CONST_INT)
21650cc9 1591 fprintf (file, "#%ld", (INTVAL (x) >> 24) & 0xff);
b839e0b4 1592 else
1593 fprintf (file, "%s", byte_reg (x, 1));
1594 break;
1595
e1629549 1596 default:
b839e0b4 1597 def:
e1629549 1598 switch (GET_CODE (x))
1599 {
1600 case REG:
b839e0b4 1601 switch (GET_MODE (x))
1602 {
1603 case QImode:
30c992ef 1604#if 0 /* Is it asm ("mov.b %0,r2l", ...) */
b839e0b4 1605 fprintf (file, "%s", byte_reg (x, 0));
1606#else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1607 fprintf (file, "%s", names_big[REGNO (x)]);
1608#endif
1609 break;
1610 case HImode:
1611 fprintf (file, "%s", names_big[REGNO (x)]);
1612 break;
1613 case SImode:
5d369cd7 1614 case SFmode:
b839e0b4 1615 fprintf (file, "%s", names_extended[REGNO (x)]);
1616 break;
1617 default:
3afe906b 1618 gcc_unreachable ();
b839e0b4 1619 }
e1629549 1620 break;
1621
1622 case MEM:
b99f3ebb 1623 {
1624 rtx addr = XEXP (x, 0);
1625
1626 fprintf (file, "@");
1627 output_address (addr);
1628
727c62dd 1629 /* Add a length suffix to constant addresses. Although this
1630 is often unnecessary, it helps to avoid ambiguity in the
1631 syntax of mova. If we wrote an insn like:
1632
1633 mova/w.l @(1,@foo.b),er0
1634
1635 then .b would be considered part of the symbol name.
1636 Adding a length after foo will avoid this. */
1637 if (CONSTANT_P (addr))
1638 switch (code)
1639 {
1640 case 'R':
1641 /* Used for mov.b and bit operations. */
1642 if (h8300_eightbit_constant_address_p (addr))
1643 {
1644 fprintf (file, ":8");
1645 break;
1646 }
1647
1648 /* Fall through. We should not get here if we are
1649 processing bit operations on H8/300 or H8/300H
1650 because 'U' constraint does not allow bit
1651 operations on the tiny area on these machines. */
1652
1653 case 'X':
1654 case 'T':
1655 case 'S':
1656 if (h8300_constant_length (addr) == 2)
1657 fprintf (file, ":16");
1658 else
1659 fprintf (file, ":32");
1660 break;
1661 default:
1662 break;
1663 }
b99f3ebb 1664 }
e1629549 1665 break;
1666
1667 case CONST_INT:
1668 case SYMBOL_REF:
1669 case CONST:
1670 case LABEL_REF:
1671 fprintf (file, "#");
1672 print_operand_address (file, x);
1673 break;
737a5d5b 1674 case CONST_DOUBLE:
1675 {
1676 long val;
1677 REAL_VALUE_TYPE rv;
1678 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1679 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
9305fe33 1680 fprintf (file, "#%ld", val);
737a5d5b 1681 break;
1682 }
9305fe33 1683 default:
1684 break;
e1629549 1685 }
1686 }
1687}
1688
1689/* Output assembly language output for the address ADDR to FILE. */
1690
1691void
230002f2 1692print_operand_address (FILE *file, rtx addr)
e1629549 1693{
727c62dd 1694 rtx index;
1695 int size;
1696
e1629549 1697 switch (GET_CODE (addr))
1698 {
1699 case REG:
b839e0b4 1700 fprintf (file, "%s", h8_reg_names[REGNO (addr)]);
e1629549 1701 break;
1702
1703 case PRE_DEC:
b839e0b4 1704 fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
e1629549 1705 break;
1706
1707 case POST_INC:
b839e0b4 1708 fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);
e1629549 1709 break;
1710
727c62dd 1711 case PRE_INC:
1712 fprintf (file, "+%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
1713 break;
1714
1715 case POST_DEC:
1716 fprintf (file, "%s-", h8_reg_names[REGNO (XEXP (addr, 0))]);
1717 break;
1718
e1629549 1719 case PLUS:
1720 fprintf (file, "(");
727c62dd 1721
1722 index = h8300_get_index (XEXP (addr, 0), VOIDmode, &size);
1723 if (GET_CODE (index) == REG)
e1629549 1724 {
1725 /* reg,foo */
1726 print_operand_address (file, XEXP (addr, 1));
1727 fprintf (file, ",");
727c62dd 1728 switch (size)
1729 {
1730 case 0:
1731 print_operand_address (file, index);
1732 break;
1733
1734 case 1:
1735 print_operand (file, index, 'X');
1736 fputs (".b", file);
1737 break;
1738
1739 case 2:
1740 print_operand (file, index, 'T');
1741 fputs (".w", file);
1742 break;
1743
1744 case 4:
1745 print_operand (file, index, 'S');
1746 fputs (".l", file);
1747 break;
1748 }
1749 /* print_operand_address (file, XEXP (addr, 0)); */
e1629549 1750 }
1751 else
1752 {
1753 /* foo+k */
1754 print_operand_address (file, XEXP (addr, 0));
1755 fprintf (file, "+");
1756 print_operand_address (file, XEXP (addr, 1));
1757 }
1758 fprintf (file, ")");
1759 break;
1760
1761 case CONST_INT:
b839e0b4 1762 {
03fb0c81 1763 /* Since the H8/300 only has 16-bit pointers, negative values are also
b839e0b4 1764 those >= 32768. This happens for example with pointer minus a
1765 constant. We don't want to turn (char *p - 2) into
1766 (char *p + 65534) because loop unrolling can build upon this
1767 (IE: char *p + 131068). */
1768 int n = INTVAL (addr);
1769 if (TARGET_H8300)
1770 n = (int) (short) n;
90a38175 1771 fprintf (file, "%d", n);
b839e0b4 1772 break;
1773 }
e1629549 1774
1775 default:
1776 output_addr_const (file, addr);
1777 break;
1778 }
1779}
1780\f
e1629549 1781/* Output all insn addresses and their sizes into the assembly language
1782 output file. This is helpful for debugging whether the length attributes
1783 in the md file are correct. This is not meant to be a user selectable
1784 option. */
1785
1786void
230002f2 1787final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1788 int num_operands ATTRIBUTE_UNUSED)
e1629549 1789{
1790 /* This holds the last insn address. */
1791 static int last_insn_address = 0;
1792
407921a5 1793 const int uid = INSN_UID (insn);
e1629549 1794
1795 if (TARGET_ADDRESSES)
1796 {
47fc0706 1797 fprintf (asm_out_file, "; 0x%x %d\n", INSN_ADDRESSES (uid),
1798 INSN_ADDRESSES (uid) - last_insn_address);
1799 last_insn_address = INSN_ADDRESSES (uid);
e1629549 1800 }
1801}
1802
b839e0b4 1803/* Prepare for an SI sized move. */
1804
1805int
1564ec41 1806h8300_expand_movsi (rtx operands[])
e1629549 1807{
b839e0b4 1808 rtx src = operands[1];
1809 rtx dst = operands[0];
1810 if (!reload_in_progress && !reload_completed)
1811 {
1812 if (!register_operand (dst, GET_MODE (dst)))
1813 {
1814 rtx tmp = gen_reg_rtx (GET_MODE (dst));
1815 emit_move_insn (tmp, src);
1816 operands[1] = tmp;
1817 }
1818 }
1819 return 0;
1820}
1821
1822/* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
eb2aa24e 1823 Define the offset between two registers, one to be eliminated, and
1824 the other its replacement, at the start of a routine. */
e1629549 1825
b839e0b4 1826int
230002f2 1827h8300_initial_elimination_offset (int from, int to)
b839e0b4 1828{
32351c92 1829 /* The number of bytes that the return address takes on the stack. */
1830 int pc_size = POINTER_SIZE / BITS_PER_UNIT;
b839e0b4 1831
f4ac50fb 1832 /* The number of bytes that the saved frame pointer takes on the stack. */
1833 int fp_size = frame_pointer_needed * UNITS_PER_WORD;
1834
1835 /* The number of bytes that the saved registers, excluding the frame
1836 pointer, take on the stack. */
1837 int saved_regs_size = 0;
b839e0b4 1838
f4ac50fb 1839 /* The number of bytes that the locals takes on the stack. */
1840 int frame_size = round_frame_size (get_frame_size ());
b839e0b4 1841
f4ac50fb 1842 int regno;
b839e0b4 1843
f4ac50fb 1844 for (regno = 0; regno <= HARD_FRAME_POINTER_REGNUM; regno++)
1845 if (WORD_REG_USED (regno))
1846 saved_regs_size += UNITS_PER_WORD;
b839e0b4 1847
f4ac50fb 1848 /* Adjust saved_regs_size because the above loop took the frame
1849 pointer int account. */
1850 saved_regs_size -= fp_size;
35a462ce 1851
3afe906b 1852 switch (to)
f4ac50fb 1853 {
3afe906b 1854 case HARD_FRAME_POINTER_REGNUM:
f4ac50fb 1855 switch (from)
1856 {
1857 case ARG_POINTER_REGNUM:
1858 return pc_size + fp_size;
1859 case RETURN_ADDRESS_POINTER_REGNUM:
1860 return fp_size;
1861 case FRAME_POINTER_REGNUM:
1862 return -saved_regs_size;
1863 default:
3afe906b 1864 gcc_unreachable ();
f4ac50fb 1865 }
3afe906b 1866 break;
1867 case STACK_POINTER_REGNUM:
f4ac50fb 1868 switch (from)
1869 {
1870 case ARG_POINTER_REGNUM:
1871 return pc_size + saved_regs_size + frame_size;
1872 case RETURN_ADDRESS_POINTER_REGNUM:
1873 return saved_regs_size + frame_size;
1874 case FRAME_POINTER_REGNUM:
1875 return frame_size;
1876 default:
3afe906b 1877 gcc_unreachable ();
f4ac50fb 1878 }
3afe906b 1879 break;
1880 default:
1881 gcc_unreachable ();
f4ac50fb 1882 }
3afe906b 1883 gcc_unreachable ();
b839e0b4 1884}
1885
cdfb02e8 1886/* Worker function for RETURN_ADDR_RTX. */
1887
f643a7d5 1888rtx
230002f2 1889h8300_return_addr_rtx (int count, rtx frame)
f643a7d5 1890{
1891 rtx ret;
1892
1893 if (count == 0)
1894 ret = gen_rtx_MEM (Pmode,
1895 gen_rtx_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM));
1896 else if (flag_omit_frame_pointer)
1897 return (rtx) 0;
1898 else
1899 ret = gen_rtx_MEM (Pmode,
1900 memory_address (Pmode,
1901 plus_constant (frame, UNITS_PER_WORD)));
1902 set_mem_alias_set (ret, get_frame_alias_set ());
1903 return ret;
1904}
1905
b839e0b4 1906/* Update the condition code from the insn. */
1907
9305fe33 1908void
230002f2 1909notice_update_cc (rtx body, rtx insn)
b839e0b4 1910{
1617b5d2 1911 rtx set;
1912
b839e0b4 1913 switch (get_attr_cc (insn))
1914 {
1915 case CC_NONE:
30c992ef 1916 /* Insn does not affect CC at all. */
b839e0b4 1917 break;
1918
1919 case CC_NONE_0HIT:
30c992ef 1920 /* Insn does not change CC, but the 0'th operand has been changed. */
b839e0b4 1921 if (cc_status.value1 != 0
ed420a25 1922 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
b839e0b4 1923 cc_status.value1 = 0;
ad992f91 1924 if (cc_status.value2 != 0
1925 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value2))
1926 cc_status.value2 = 0;
b839e0b4 1927 break;
1928
a618bce0 1929 case CC_SET_ZN:
ed420a25 1930 /* Insn sets the Z,N flags of CC to recog_data.operand[0].
30c992ef 1931 The V flag is unusable. The C flag may or may not be known but
1932 that's ok because alter_cond will change tests to use EQ/NE. */
b839e0b4 1933 CC_STATUS_INIT;
30c992ef 1934 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
1617b5d2 1935 set = single_set (insn);
1936 cc_status.value1 = SET_SRC (set);
1937 if (SET_DEST (set) != cc0_rtx)
1938 cc_status.value2 = SET_DEST (set);
b839e0b4 1939 break;
1940
a618bce0 1941 case CC_SET_ZNV:
ed420a25 1942 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
a618bce0 1943 The C flag may or may not be known but that's ok because
1944 alter_cond will change tests to use EQ/NE. */
1945 CC_STATUS_INIT;
1946 cc_status.flags |= CC_NO_CARRY;
1617b5d2 1947 set = single_set (insn);
1948 cc_status.value1 = SET_SRC (set);
1949 if (SET_DEST (set) != cc0_rtx)
83e2d3b1 1950 {
1951 /* If the destination is STRICT_LOW_PART, strip off
1952 STRICT_LOW_PART. */
1953 if (GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
1954 cc_status.value2 = XEXP (SET_DEST (set), 0);
1955 else
1956 cc_status.value2 = SET_DEST (set);
1957 }
a618bce0 1958 break;
1959
727c62dd 1960 case CC_COMPARE:
1961 /* The insn is a compare instruction. */
1962 CC_STATUS_INIT;
1963 cc_status.value1 = SET_SRC (body);
1964 break;
1965
1966 case CC_CLOBBER:
1967 /* Insn doesn't leave CC in a usable state. */
1968 CC_STATUS_INIT;
1969 break;
1970 }
1971}
727c62dd 1972\f
1973/* Given that X occurs in an address of the form (plus X constant),
1974 return the part of X that is expected to be a register. There are
1975 four kinds of addressing mode to recognize:
1976
1977 @(dd,Rn)
1978 @(dd,RnL.b)
1979 @(dd,Rn.w)
1980 @(dd,ERn.l)
1981
1982 If SIZE is nonnull, and the address is one of the last three forms,
1983 set *SIZE to the index multiplication factor. Set it to 0 for
1984 plain @(dd,Rn) addresses.
1985
1986 MODE is the mode of the value being accessed. It can be VOIDmode
1987 if the address is known to be valid, but its mode is unknown. */
1988
1989rtx
1990h8300_get_index (rtx x, enum machine_mode mode, int *size)
1991{
1992 int dummy, factor;
1993
1994 if (size == 0)
1995 size = &dummy;
1996
1997 factor = (mode == VOIDmode ? 0 : GET_MODE_SIZE (mode));
1998 if (TARGET_H8300SX
1999 && factor <= 4
2000 && (mode == VOIDmode
2001 || GET_MODE_CLASS (mode) == MODE_INT
2002 || GET_MODE_CLASS (mode) == MODE_FLOAT))
2003 {
2004 if (factor <= 1 && GET_CODE (x) == ZERO_EXTEND)
2005 {
2006 /* When accessing byte-sized values, the index can be
2007 a zero-extended QImode or HImode register. */
2008 *size = GET_MODE_SIZE (GET_MODE (XEXP (x, 0)));
2009 return XEXP (x, 0);
2010 }
2011 else
2012 {
2013 /* We're looking for addresses of the form:
2014
2015 (mult X I)
2016 or (mult (zero_extend X) I)
2017
2018 where I is the size of the operand being accessed.
2019 The canonical form of the second expression is:
2020
2021 (and (mult (subreg X) I) J)
2022
2023 where J == GET_MODE_MASK (GET_MODE (X)) * I. */
2024 rtx index;
2025
2026 if (GET_CODE (x) == AND
2027 && GET_CODE (XEXP (x, 1)) == CONST_INT
2028 && (factor == 0
2029 || INTVAL (XEXP (x, 1)) == 0xff * factor
2030 || INTVAL (XEXP (x, 1)) == 0xffff * factor))
2031 {
2032 index = XEXP (x, 0);
2033 *size = (INTVAL (XEXP (x, 1)) >= 0xffff ? 2 : 1);
2034 }
2035 else
2036 {
2037 index = x;
2038 *size = 4;
2039 }
2040
2041 if (GET_CODE (index) == MULT
2042 && GET_CODE (XEXP (index, 1)) == CONST_INT
2043 && (factor == 0 || factor == INTVAL (XEXP (index, 1))))
2044 return XEXP (index, 0);
2045 }
2046 }
2047 *size = 0;
2048 return x;
2049}
2050\f
2051static const h8300_length_table addb_length_table =
2052{
2053 /* #xx Rs @aa @Rs @xx */
2054 { 2, 2, 4, 4, 4 }, /* add.b xx,Rd */
2055 { 4, 4, 4, 4, 6 }, /* add.b xx,@aa */
2056 { 4, 4, 4, 4, 6 }, /* add.b xx,@Rd */
2057 { 6, 4, 4, 4, 6 } /* add.b xx,@xx */
2058};
2059
2060static const h8300_length_table addw_length_table =
2061{
2062 /* #xx Rs @aa @Rs @xx */
2063 { 2, 2, 4, 4, 4 }, /* add.w xx,Rd */
2064 { 4, 4, 4, 4, 6 }, /* add.w xx,@aa */
2065 { 4, 4, 4, 4, 6 }, /* add.w xx,@Rd */
2066 { 4, 4, 4, 4, 6 } /* add.w xx,@xx */
2067};
2068
2069static const h8300_length_table addl_length_table =
2070{
2071 /* #xx Rs @aa @Rs @xx */
2072 { 2, 2, 4, 4, 4 }, /* add.l xx,Rd */
2073 { 4, 4, 6, 6, 6 }, /* add.l xx,@aa */
2074 { 4, 4, 6, 6, 6 }, /* add.l xx,@Rd */
2075 { 4, 4, 6, 6, 6 } /* add.l xx,@xx */
2076};
2077
2078#define logicb_length_table addb_length_table
2079#define logicw_length_table addw_length_table
2080
2081static const h8300_length_table logicl_length_table =
2082{
2083 /* #xx Rs @aa @Rs @xx */
2084 { 2, 4, 4, 4, 4 }, /* and.l xx,Rd */
2085 { 4, 4, 6, 6, 6 }, /* and.l xx,@aa */
2086 { 4, 4, 6, 6, 6 }, /* and.l xx,@Rd */
2087 { 4, 4, 6, 6, 6 } /* and.l xx,@xx */
2088};
2089
2090static const h8300_length_table movb_length_table =
2091{
2092 /* #xx Rs @aa @Rs @xx */
2093 { 2, 2, 2, 2, 4 }, /* mov.b xx,Rd */
2094 { 4, 2, 4, 4, 4 }, /* mov.b xx,@aa */
2095 { 4, 2, 4, 4, 4 }, /* mov.b xx,@Rd */
2096 { 4, 4, 4, 4, 4 } /* mov.b xx,@xx */
2097};
2098
2099#define movw_length_table movb_length_table
2100
2101static const h8300_length_table movl_length_table =
2102{
2103 /* #xx Rs @aa @Rs @xx */
2104 { 2, 2, 4, 4, 4 }, /* mov.l xx,Rd */
2105 { 4, 4, 4, 4, 4 }, /* mov.l xx,@aa */
2106 { 4, 4, 4, 4, 4 }, /* mov.l xx,@Rd */
2107 { 4, 4, 4, 4, 4 } /* mov.l xx,@xx */
2108};
2109
2110/* Return the size of the given address or displacement constant. */
2111
2112static unsigned int
2113h8300_constant_length (rtx constant)
2114{
2115 /* Check for (@d:16,Reg). */
2116 if (GET_CODE (constant) == CONST_INT
2117 && IN_RANGE (INTVAL (constant), -0x8000, 0x7fff))
2118 return 2;
2119
2120 /* Check for (@d:16,Reg) in cases where the displacement is
2121 an absolute address. */
2122 if (Pmode == HImode || h8300_tiny_constant_address_p (constant))
2123 return 2;
2124
2125 return 4;
2126}
2127
2128/* Return the size of a displacement field in address ADDR, which should
2129 have the form (plus X constant). SIZE is the number of bytes being
2130 accessed. */
2131
2132static unsigned int
2133h8300_displacement_length (rtx addr, int size)
2134{
2135 rtx offset;
2136
2137 offset = XEXP (addr, 1);
2138
2139 /* Check for @(d:2,Reg). */
2140 if (register_operand (XEXP (addr, 0), VOIDmode)
2141 && GET_CODE (offset) == CONST_INT
2142 && (INTVAL (offset) == size
2143 || INTVAL (offset) == size * 2
2144 || INTVAL (offset) == size * 3))
2145 return 0;
2146
2147 return h8300_constant_length (offset);
2148}
2149
2150/* Store the class of operand OP in *CLASS and return the length of any
2151 extra operand fields. SIZE is the number of bytes in OP. CLASS
2152 can be null if only the length is needed. */
2153
2154static unsigned int
2155h8300_classify_operand (rtx op, int size, enum h8300_operand_class *class)
2156{
2157 enum h8300_operand_class dummy;
2158
2159 if (class == 0)
2160 class = &dummy;
2161
2162 if (CONSTANT_P (op))
2163 {
2164 *class = H8OP_IMMEDIATE;
2165
2166 /* Byte-sized immediates are stored in the opcode fields. */
2167 if (size == 1)
2168 return 0;
2169
2170 /* If this is a 32-bit instruction, see whether the constant
2171 will fit into a 16-bit immediate field. */
2172 if (TARGET_H8300SX
2173 && size == 4
2174 && GET_CODE (op) == CONST_INT
2175 && IN_RANGE (INTVAL (op), 0, 0xffff))
2176 return 2;
2177
2178 return size;
2179 }
2180 else if (GET_CODE (op) == MEM)
2181 {
2182 op = XEXP (op, 0);
2183 if (CONSTANT_P (op))
2184 {
2185 *class = H8OP_MEM_ABSOLUTE;
2186 return h8300_constant_length (op);
2187 }
2188 else if (GET_CODE (op) == PLUS && CONSTANT_P (XEXP (op, 1)))
2189 {
2190 *class = H8OP_MEM_COMPLEX;
2191 return h8300_displacement_length (op, size);
2192 }
2193 else if (GET_RTX_CLASS (GET_CODE (op)) == RTX_AUTOINC)
2194 {
2195 *class = H8OP_MEM_COMPLEX;
2196 return 0;
2197 }
2198 else if (register_operand (op, VOIDmode))
2199 {
2200 *class = H8OP_MEM_BASE;
2201 return 0;
2202 }
2203 }
3afe906b 2204 gcc_assert (register_operand (op, VOIDmode));
2205 *class = H8OP_REGISTER;
2206 return 0;
727c62dd 2207}
2208
2209/* Return the length of the instruction described by TABLE given that
2210 its operands are OP1 and OP2. OP1 must be an h8300_dst_operand
2211 and OP2 must be an h8300_src_operand. */
2212
2213static unsigned int
2214h8300_length_from_table (rtx op1, rtx op2, const h8300_length_table *table)
2215{
2216 enum h8300_operand_class op1_class, op2_class;
2217 unsigned int size, immediate_length;
2218
2219 size = GET_MODE_SIZE (GET_MODE (op1));
2220 immediate_length = (h8300_classify_operand (op1, size, &op1_class)
2221 + h8300_classify_operand (op2, size, &op2_class));
2222 return immediate_length + (*table)[op1_class - 1][op2_class];
2223}
2224
2225/* Return the length of a unary instruction such as neg or not given that
2226 its operand is OP. */
2227
2228unsigned int
2229h8300_unary_length (rtx op)
2230{
2231 enum h8300_operand_class class;
2232 unsigned int size, operand_length;
2233
2234 size = GET_MODE_SIZE (GET_MODE (op));
2235 operand_length = h8300_classify_operand (op, size, &class);
2236 switch (class)
2237 {
2238 case H8OP_REGISTER:
2239 return 2;
2240
2241 case H8OP_MEM_BASE:
2242 return (size == 4 ? 6 : 4);
2243
2244 case H8OP_MEM_ABSOLUTE:
2245 return operand_length + (size == 4 ? 6 : 4);
2246
2247 case H8OP_MEM_COMPLEX:
2248 return operand_length + 6;
2249
2250 default:
3afe906b 2251 gcc_unreachable ();
727c62dd 2252 }
2253}
2254
2255/* Likewise short immediate instructions such as add.w #xx:3,OP. */
2256
2257static unsigned int
2258h8300_short_immediate_length (rtx op)
2259{
2260 enum h8300_operand_class class;
2261 unsigned int size, operand_length;
2262
2263 size = GET_MODE_SIZE (GET_MODE (op));
2264 operand_length = h8300_classify_operand (op, size, &class);
2265
2266 switch (class)
2267 {
2268 case H8OP_REGISTER:
2269 return 2;
2270
2271 case H8OP_MEM_BASE:
2272 case H8OP_MEM_ABSOLUTE:
2273 case H8OP_MEM_COMPLEX:
2274 return 4 + operand_length;
2275
2276 default:
3afe906b 2277 gcc_unreachable ();
727c62dd 2278 }
2279}
2280
2281/* Likewise bitfield load and store instructions. */
b839e0b4 2282
727c62dd 2283static unsigned int
2284h8300_bitfield_length (rtx op, rtx op2)
2285{
2286 enum h8300_operand_class class;
2287 unsigned int size, operand_length;
2288
2289 if (GET_CODE (op) == REG)
2290 op = op2;
3afe906b 2291 gcc_assert (GET_CODE (op) != REG);
727c62dd 2292
2293 size = GET_MODE_SIZE (GET_MODE (op));
2294 operand_length = h8300_classify_operand (op, size, &class);
2295
2296 switch (class)
2297 {
2298 case H8OP_MEM_BASE:
2299 case H8OP_MEM_ABSOLUTE:
2300 case H8OP_MEM_COMPLEX:
2301 return 4 + operand_length;
2302
2303 default:
3afe906b 2304 gcc_unreachable ();
e1629549 2305 }
b839e0b4 2306}
2307
727c62dd 2308/* Calculate the length of general binary instruction INSN using TABLE. */
90e56b83 2309
727c62dd 2310static unsigned int
2311h8300_binary_length (rtx insn, const h8300_length_table *table)
90e56b83 2312{
727c62dd 2313 rtx set;
2314
2315 set = single_set (insn);
3afe906b 2316 gcc_assert (set);
727c62dd 2317
2318 if (BINARY_P (SET_SRC (set)))
2319 return h8300_length_from_table (XEXP (SET_SRC (set), 0),
2320 XEXP (SET_SRC (set), 1), table);
727c62dd 2321 else
3afe906b 2322 {
2323 gcc_assert (GET_RTX_CLASS (GET_CODE (SET_SRC (set))) == RTX_TERNARY);
2324 return h8300_length_from_table (XEXP (XEXP (SET_SRC (set), 1), 0),
2325 XEXP (XEXP (SET_SRC (set), 1), 1),
2326 table);
2327 }
90e56b83 2328}
2329
727c62dd 2330/* Subroutine of h8300_move_length. Return true if OP is 1- or 2-byte
2331 memory reference and either (1) it has the form @(d:16,Rn) or
2332 (2) its address has the code given by INC_CODE. */
90e56b83 2333
727c62dd 2334static bool
2335h8300_short_move_mem_p (rtx op, enum rtx_code inc_code)
90e56b83 2336{
727c62dd 2337 rtx addr;
2338 unsigned int size;
2339
2340 if (GET_CODE (op) != MEM)
2341 return false;
2342
2343 addr = XEXP (op, 0);
2344 size = GET_MODE_SIZE (GET_MODE (op));
2345 if (size != 1 && size != 2)
2346 return false;
2347
2348 return (GET_CODE (addr) == inc_code
2349 || (GET_CODE (addr) == PLUS
2350 && GET_CODE (XEXP (addr, 0)) == REG
2351 && h8300_displacement_length (addr, size) == 2));
90e56b83 2352}
2353
727c62dd 2354/* Calculate the length of move instruction INSN using the given length
2355 table. Although the tables are correct for most cases, there is some
2356 irregularity in the length of mov.b and mov.w. The following forms:
90e56b83 2357
727c62dd 2358 mov @ERs+, Rd
2359 mov @(d:16,ERs), Rd
2360 mov Rs, @-ERd
2361 mov Rs, @(d:16,ERd)
2362
2363 are two bytes shorter than most other "mov Rs, @complex" or
2364 "mov @complex,Rd" combinations. */
2365
2366static unsigned int
2367h8300_move_length (rtx *operands, const h8300_length_table *table)
90e56b83 2368{
727c62dd 2369 unsigned int size;
2370
2371 size = h8300_length_from_table (operands[0], operands[1], table);
2372 if (REG_P (operands[0]) && h8300_short_move_mem_p (operands[1], POST_INC))
2373 size -= 2;
2374 if (REG_P (operands[1]) && h8300_short_move_mem_p (operands[0], PRE_DEC))
2375 size -= 2;
2376 return size;
90e56b83 2377}
2378
727c62dd 2379/* Return the length of a mova instruction with the given operands.
2380 DEST is the register destination, SRC is the source address and
2381 OFFSET is the 16-bit or 32-bit displacement. */
0d565792 2382
727c62dd 2383static unsigned int
2384h8300_mova_length (rtx dest, rtx src, rtx offset)
0d565792 2385{
727c62dd 2386 unsigned int size;
2387
2388 size = (2
2389 + h8300_constant_length (offset)
2390 + h8300_classify_operand (src, GET_MODE_SIZE (GET_MODE (src)), 0));
2391 if (!REG_P (dest) || !REG_P (src) || REGNO (src) != REGNO (dest))
2392 size += 2;
2393 return size;
0d565792 2394}
2395
727c62dd 2396/* Compute the length of INSN based on its length_table attribute.
2397 OPERANDS is the array of its operands. */
0d565792 2398
727c62dd 2399unsigned int
2400h8300_insn_length_from_table (rtx insn, rtx * operands)
0d565792 2401{
727c62dd 2402 switch (get_attr_length_table (insn))
2403 {
2404 case LENGTH_TABLE_NONE:
3afe906b 2405 gcc_unreachable ();
727c62dd 2406
2407 case LENGTH_TABLE_ADDB:
2408 return h8300_binary_length (insn, &addb_length_table);
2409
2410 case LENGTH_TABLE_ADDW:
2411 return h8300_binary_length (insn, &addw_length_table);
2412
2413 case LENGTH_TABLE_ADDL:
2414 return h8300_binary_length (insn, &addl_length_table);
2415
2416 case LENGTH_TABLE_LOGICB:
2417 return h8300_binary_length (insn, &logicb_length_table);
2418
2419 case LENGTH_TABLE_MOVB:
2420 return h8300_move_length (operands, &movb_length_table);
2421
2422 case LENGTH_TABLE_MOVW:
2423 return h8300_move_length (operands, &movw_length_table);
2424
2425 case LENGTH_TABLE_MOVL:
2426 return h8300_move_length (operands, &movl_length_table);
2427
2428 case LENGTH_TABLE_MOVA:
2429 return h8300_mova_length (operands[0], operands[1], operands[2]);
2430
2431 case LENGTH_TABLE_MOVA_ZERO:
2432 return h8300_mova_length (operands[0], operands[1], const0_rtx);
2433
2434 case LENGTH_TABLE_UNARY:
2435 return h8300_unary_length (operands[0]);
2436
2437 case LENGTH_TABLE_MOV_IMM4:
2438 return 2 + h8300_classify_operand (operands[0], 0, 0);
2439
2440 case LENGTH_TABLE_SHORT_IMMEDIATE:
2441 return h8300_short_immediate_length (operands[0]);
2442
2443 case LENGTH_TABLE_BITFIELD:
2444 return h8300_bitfield_length (operands[0], operands[1]);
2445
2446 case LENGTH_TABLE_BITBRANCH:
2447 return h8300_bitfield_length (operands[1], operands[2]) - 2;
3afe906b 2448
2449 default:
2450 gcc_unreachable ();
727c62dd 2451 }
0d565792 2452}
2453
727c62dd 2454/* Return true if LHS and RHS are memory references that can be mapped
2455 to the same h8sx assembly operand. LHS appears as the destination of
2456 an instruction and RHS appears as a source.
079b5951 2457
727c62dd 2458 Three cases are allowed:
2459
2460 - RHS is @+Rn or @-Rn, LHS is @Rn
2461 - RHS is @Rn, LHS is @Rn+ or @Rn-
2462 - RHS and LHS have the same address and neither has side effects. */
2463
2464bool
2465h8sx_mergeable_memrefs_p (rtx lhs, rtx rhs)
079b5951 2466{
727c62dd 2467 if (GET_CODE (rhs) == MEM && GET_CODE (lhs) == MEM)
2468 {
2469 rhs = XEXP (rhs, 0);
2470 lhs = XEXP (lhs, 0);
2471
2472 if (GET_CODE (rhs) == PRE_INC || GET_CODE (rhs) == PRE_DEC)
2473 return rtx_equal_p (XEXP (rhs, 0), lhs);
2474
2475 if (GET_CODE (lhs) == POST_INC || GET_CODE (lhs) == POST_DEC)
2476 return rtx_equal_p (rhs, XEXP (lhs, 0));
2477
2478 if (rtx_equal_p (rhs, lhs))
2479 return true;
2480 }
2481 return false;
079b5951 2482}
2483
727c62dd 2484/* Return true if OPERANDS[1] can be mapped to the same assembly
2485 operand as OPERANDS[0]. */
079b5951 2486
727c62dd 2487bool
2488h8300_operands_match_p (rtx *operands)
079b5951 2489{
727c62dd 2490 if (register_operand (operands[0], VOIDmode)
2491 && register_operand (operands[1], VOIDmode))
2492 return true;
079b5951 2493
727c62dd 2494 if (h8sx_mergeable_memrefs_p (operands[0], operands[1]))
2495 return true;
2496
2497 return false;
079b5951 2498}
727c62dd 2499\f
2500/* Try using movmd to move LENGTH bytes from memory region SRC to memory
2501 region DEST. The two regions do not overlap and have the common
2502 alignment given by ALIGNMENT. Return true on success.
c6720edd 2503
727c62dd 2504 Using movmd for variable-length moves seems to involve some
2505 complex trade-offs. For instance:
4c924258 2506
727c62dd 2507 - Preparing for a movmd instruction is similar to preparing
2508 for a memcpy. The main difference is that the arguments
2509 are moved into er4, er5 and er6 rather than er0, er1 and er2.
2510
2511 - Since movmd clobbers the frame pointer, we need to save
2512 and restore it somehow when frame_pointer_needed. This can
2513 sometimes make movmd sequences longer than calls to memcpy().
2514
2515 - The counter register is 16 bits, so the instruction is only
2516 suitable for variable-length moves when sizeof (size_t) == 2.
2517 That's only true in normal mode.
2518
2519 - We will often lack static alignment information. Falling back
2520 on movmd.b would likely be slower than calling memcpy(), at least
2521 for big moves.
2522
2523 This function therefore only uses movmd when the length is a
2524 known constant, and only then if -fomit-frame-pointer is in
2525 effect or if we're not optimizing for size.
2526
2527 At the moment the function uses movmd for all in-range constants,
2528 but it might be better to fall back on memcpy() for large moves
2529 if ALIGNMENT == 1. */
2530
2531bool
2532h8sx_emit_movmd (rtx dest, rtx src, rtx length,
2533 HOST_WIDE_INT alignment)
4c924258 2534{
727c62dd 2535 if (!flag_omit_frame_pointer && optimize_size)
2536 return false;
4c924258 2537
727c62dd 2538 if (GET_CODE (length) == CONST_INT)
2539 {
2540 rtx dest_reg, src_reg, first_dest, first_src;
2541 HOST_WIDE_INT n;
2542 int factor;
2543
2544 /* Use movmd.l if the alignment allows it, otherwise fall back
2545 on movmd.b. */
2546 factor = (alignment >= 2 ? 4 : 1);
2547
2548 /* Make sure the length is within range. We can handle counter
2549 values up to 65536, although HImode truncation will make
2550 the count appear negative in rtl dumps. */
2551 n = INTVAL (length);
2552 if (n <= 0 || n / factor > 65536)
2553 return false;
2554
2555 /* Create temporary registers for the source and destination
2556 pointers. Initialize them to the start of each region. */
2557 dest_reg = copy_addr_to_reg (XEXP (dest, 0));
2558 src_reg = copy_addr_to_reg (XEXP (src, 0));
2559
2560 /* Create references to the movmd source and destination blocks. */
2561 first_dest = replace_equiv_address (dest, dest_reg);
2562 first_src = replace_equiv_address (src, src_reg);
2563
2564 set_mem_size (first_dest, GEN_INT (n & -factor));
2565 set_mem_size (first_src, GEN_INT (n & -factor));
2566
2567 length = copy_to_mode_reg (HImode, gen_int_mode (n / factor, HImode));
2568 emit_insn (gen_movmd (first_dest, first_src, length, GEN_INT (factor)));
2569
2570 if ((n & -factor) != n)
2571 {
2572 /* Move SRC and DEST past the region we just copied.
2573 This is done to update the memory attributes. */
2574 dest = adjust_address (dest, BLKmode, n & -factor);
2575 src = adjust_address (src, BLKmode, n & -factor);
2576
2577 /* Replace the addresses with the source and destination
2578 registers, which movmd has left with the right values. */
2579 dest = replace_equiv_address (dest, dest_reg);
2580 src = replace_equiv_address (src, src_reg);
2581
2582 /* Mop up the left-over bytes. */
2583 if (n & 2)
2584 emit_move_insn (adjust_address (dest, HImode, 0),
2585 adjust_address (src, HImode, 0));
2586 if (n & 1)
2587 emit_move_insn (adjust_address (dest, QImode, n & 2),
2588 adjust_address (src, QImode, n & 2));
2589 }
2590 return true;
2591 }
2592 return false;
4c924258 2593}
2594
727c62dd 2595/* Move ADDR into er6 after pushing its old value onto the stack. */
b839e0b4 2596
727c62dd 2597void
2598h8300_swap_into_er6 (rtx addr)
b839e0b4 2599{
727c62dd 2600 push (HARD_FRAME_POINTER_REGNUM);
2601 emit_move_insn (hard_frame_pointer_rtx, addr);
2602 if (REGNO (addr) == SP_REG)
2603 emit_move_insn (hard_frame_pointer_rtx,
2604 plus_constant (hard_frame_pointer_rtx,
2605 GET_MODE_SIZE (word_mode)));
2606}
e1629549 2607
727c62dd 2608/* Move the current value of er6 into ADDR and pop its old value
2609 from the stack. */
2610
2611void
2612h8300_swap_out_of_er6 (rtx addr)
2613{
2614 if (REGNO (addr) != SP_REG)
2615 emit_move_insn (addr, hard_frame_pointer_rtx);
2616 pop (HARD_FRAME_POINTER_REGNUM);
e1629549 2617}
b839e0b4 2618\f
2e295ea4 2619/* Return the length of mov instruction. */
2620
2621unsigned int
2622compute_mov_length (rtx *operands)
2623{
2624 /* If the mov instruction involves a memory operand, we compute the
2625 length, assuming the largest addressing mode is used, and then
2626 adjust later in the function. Otherwise, we compute and return
2627 the exact length in one step. */
2628 enum machine_mode mode = GET_MODE (operands[0]);
2629 rtx dest = operands[0];
2630 rtx src = operands[1];
2631 rtx addr;
2632
2633 if (GET_CODE (src) == MEM)
2634 addr = XEXP (src, 0);
2635 else if (GET_CODE (dest) == MEM)
2636 addr = XEXP (dest, 0);
2637 else
2638 addr = NULL_RTX;
2639
2640 if (TARGET_H8300)
2641 {
2642 unsigned int base_length;
2643
2644 switch (mode)
2645 {
2646 case QImode:
2647 if (addr == NULL_RTX)
2648 return 2;
2649
2650 /* The eightbit addressing is available only in QImode, so
2651 go ahead and take care of it. */
2652 if (h8300_eightbit_constant_address_p (addr))
2653 return 2;
2654
2655 base_length = 4;
2656 break;
2657
2658 case HImode:
2659 if (addr == NULL_RTX)
2660 {
2661 if (REG_P (src))
2662 return 2;
2663
2664 if (src == const0_rtx)
2665 return 2;
2666
2667 return 4;
2668 }
2669
2670 base_length = 4;
2671 break;
2672
2673 case SImode:
2674 if (addr == NULL_RTX)
2675 {
2676 if (REG_P (src))
2677 return 4;
2678
2679 if (GET_CODE (src) == CONST_INT)
2680 {
2681 if (src == const0_rtx)
2682 return 4;
2683
2684 if ((INTVAL (src) & 0xffff) == 0)
2685 return 6;
2686
2687 if ((INTVAL (src) & 0xffff) == 0)
2688 return 6;
786637e0 2689
2690 if ((INTVAL (src) & 0xffff)
2691 == ((INTVAL (src) >> 16) & 0xffff))
2692 return 6;
2e295ea4 2693 }
2694 return 8;
2695 }
2696
2697 base_length = 8;
2698 break;
2699
2700 case SFmode:
2701 if (addr == NULL_RTX)
2702 {
2703 if (REG_P (src))
2704 return 4;
2705
f62378f4 2706 if (CONST_DOUBLE_OK_FOR_LETTER_P (src, 'G'))
2707 return 4;
2708
ead5f19f 2709 return 8;
2e295ea4 2710 }
2711
2712 base_length = 8;
2713 break;
2714
2715 default:
3afe906b 2716 gcc_unreachable ();
2e295ea4 2717 }
2718
2719 /* Adjust the length based on the addressing mode used.
2720 Specifically, we subtract the difference between the actual
2721 length and the longest one, which is @(d:16,Rs). For SImode
2722 and SFmode, we double the adjustment because two mov.w are
2723 used to do the job. */
2724
2725 /* @Rs+ and @-Rd are 2 bytes shorter than the longest. */
2726 if (GET_CODE (addr) == PRE_DEC
2727 || GET_CODE (addr) == POST_INC)
2728 {
2729 if (mode == QImode || mode == HImode)
2730 return base_length - 2;
2731 else
2732 /* In SImode and SFmode, we use two mov.w instructions, so
3c364971 2733 double the adjustment. */
2e295ea4 2734 return base_length - 4;
2735 }
2736
2737 /* @Rs and @Rd are 2 bytes shorter than the longest. Note that
2738 in SImode and SFmode, the second mov.w involves an address
2739 with displacement, namely @(2,Rs) or @(2,Rd), so we subtract
2740 only 2 bytes. */
2741 if (GET_CODE (addr) == REG)
2742 return base_length - 2;
2743
2744 return base_length;
2745 }
2746 else
2747 {
2748 unsigned int base_length;
2749
2750 switch (mode)
2751 {
2752 case QImode:
2753 if (addr == NULL_RTX)
2754 return 2;
2755
2756 /* The eightbit addressing is available only in QImode, so
2757 go ahead and take care of it. */
2758 if (h8300_eightbit_constant_address_p (addr))
2759 return 2;
2760
2761 base_length = 8;
2762 break;
2763
2764 case HImode:
2765 if (addr == NULL_RTX)
2766 {
2767 if (REG_P (src))
2768 return 2;
2769
2770 if (src == const0_rtx)
2771 return 2;
2772
2773 return 4;
2774 }
2775
2776 base_length = 8;
2777 break;
2778
2779 case SImode:
2780 if (addr == NULL_RTX)
2781 {
2782 if (REG_P (src))
2783 {
2784 if (REGNO (src) == MAC_REG || REGNO (dest) == MAC_REG)
2785 return 4;
2786 else
2787 return 2;
2788 }
2789
2790 if (GET_CODE (src) == CONST_INT)
2791 {
2792 int val = INTVAL (src);
2793
2794 if (val == 0)
2795 return 2;
2796
2797 if (val == (val & 0x00ff) || val == (val & 0xff00))
2798 return 4;
6fe6e17a 2799
2e295ea4 2800 switch (val & 0xffffffff)
2801 {
2802 case 0xffffffff:
2803 case 0xfffffffe:
2804 case 0xfffffffc:
2805 case 0x0000ffff:
2806 case 0x0000fffe:
2807 case 0xffff0000:
2808 case 0xfffe0000:
2809 case 0x00010000:
2810 case 0x00020000:
2811 return 4;
2812 }
2813 }
2814 return 6;
2815 }
2816
2817 base_length = 10;
2818 break;
2819
2820 case SFmode:
2821 if (addr == NULL_RTX)
2822 {
2823 if (REG_P (src))
2824 return 2;
2825
c0438d5c 2826 if (CONST_DOUBLE_OK_FOR_LETTER_P (src, 'G'))
2e295ea4 2827 return 2;
f62378f4 2828
2e295ea4 2829 return 6;
2830 }
2831
2832 base_length = 10;
2833 break;
2834
2835 default:
3afe906b 2836 gcc_unreachable ();
2e295ea4 2837 }
2838
2839 /* Adjust the length based on the addressing mode used.
2840 Specifically, we subtract the difference between the actual
2841 length and the longest one, which is @(d:24,ERs). */
2842
2843 /* @ERs+ and @-ERd are 6 bytes shorter than the longest. */
2844 if (GET_CODE (addr) == PRE_DEC
2845 || GET_CODE (addr) == POST_INC)
2846 return base_length - 6;
2847
2848 /* @ERs and @ERd are 6 bytes shorter than the longest. */
2849 if (GET_CODE (addr) == REG)
2850 return base_length - 6;
2851
2852 /* @(d:16,ERs) and @(d:16,ERd) are 4 bytes shorter than the
2853 longest. */
2854 if (GET_CODE (addr) == PLUS
2855 && GET_CODE (XEXP (addr, 0)) == REG
2856 && GET_CODE (XEXP (addr, 1)) == CONST_INT
2857 && INTVAL (XEXP (addr, 1)) > -32768
2858 && INTVAL (XEXP (addr, 1)) < 32767)
2859 return base_length - 4;
2860
2861 /* @aa:16 is 4 bytes shorter than the longest. */
2862 if (h8300_tiny_constant_address_p (addr))
2863 return base_length - 4;
2864
2865 /* @aa:24 is 2 bytes shorter than the longest. */
2866 if (CONSTANT_P (addr))
2867 return base_length - 2;
2868
2869 return base_length;
2870 }
2871}
2872\f
cdfb02e8 2873/* Output an addition insn. */
2874
6a8a3fa3 2875const char *
230002f2 2876output_plussi (rtx *operands)
aa3382b1 2877{
2878 enum machine_mode mode = GET_MODE (operands[0]);
2879
3afe906b 2880 gcc_assert (mode == SImode);
aa3382b1 2881
2882 if (TARGET_H8300)
2883 {
469dc9d2 2884 if (GET_CODE (operands[2]) == REG)
2885 return "add.w\t%f2,%f0\n\taddx\t%y2,%y0\n\taddx\t%z2,%z0";
2886
2887 if (GET_CODE (operands[2]) == CONST_INT)
2888 {
2889 HOST_WIDE_INT n = INTVAL (operands[2]);
2890
2891 if ((n & 0xffffff) == 0)
2892 return "add\t%z2,%z0";
2893 if ((n & 0xffff) == 0)
2894 return "add\t%y2,%y0\n\taddx\t%z2,%z0";
2895 if ((n & 0xff) == 0)
2896 return "add\t%x2,%x0\n\taddx\t%y2,%y0\n\taddx\t%z2,%z0";
2897 }
2898
2899 return "add\t%w2,%w0\n\taddx\t%x2,%x0\n\taddx\t%y2,%y0\n\taddx\t%z2,%z0";
aa3382b1 2900 }
2901 else
2902 {
727c62dd 2903 if (GET_CODE (operands[2]) == CONST_INT
2904 && register_operand (operands[1], VOIDmode))
aa3382b1 2905 {
2906 HOST_WIDE_INT intval = INTVAL (operands[2]);
2907
727c62dd 2908 if (TARGET_H8300SX && (intval >= 1 && intval <= 7))
2909 return "add.l\t%S2,%S0";
2910 if (TARGET_H8300SX && (intval >= -7 && intval <= -1))
2911 return "sub.l\t%G2,%S0";
2912
aa3382b1 2913 /* See if we can finish with 2 bytes. */
2914
11233c59 2915 switch ((unsigned int) intval & 0xffffffff)
aa3382b1 2916 {
2917 case 0x00000001:
2918 case 0x00000002:
2919 case 0x00000004:
2920 return "adds\t%2,%S0";
2921
2922 case 0xffffffff:
2923 case 0xfffffffe:
2924 case 0xfffffffc:
2925 return "subs\t%G2,%S0";
2926
2927 case 0x00010000:
2928 case 0x00020000:
2929 operands[2] = GEN_INT (intval >> 16);
2930 return "inc.w\t%2,%e0";
2931
2932 case 0xffff0000:
2933 case 0xfffe0000:
2934 operands[2] = GEN_INT (intval >> 16);
2935 return "dec.w\t%G2,%e0";
2936 }
2937
2938 /* See if we can finish with 4 bytes. */
2939 if ((intval & 0xffff) == 0)
2940 {
2941 operands[2] = GEN_INT (intval >> 16);
2942 return "add.w\t%2,%e0";
2943 }
2944 }
2945
727c62dd 2946 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
2947 {
2948 operands[2] = GEN_INT (-INTVAL (operands[2]));
2949 return "sub.l\t%S2,%S0";
2950 }
aa3382b1 2951 return "add.l\t%S2,%S0";
2952 }
2953}
2954
727c62dd 2955/* ??? It would be much easier to add the h8sx stuff if a single function
2956 classified the addition as either inc/dec, adds/subs, add.w or add.l. */
cdfb02e8 2957/* Compute the length of an addition insn. */
2958
aa3382b1 2959unsigned int
230002f2 2960compute_plussi_length (rtx *operands)
aa3382b1 2961{
2962 enum machine_mode mode = GET_MODE (operands[0]);
2963
3afe906b 2964 gcc_assert (mode == SImode);
aa3382b1 2965
2966 if (TARGET_H8300)
2967 {
469dc9d2 2968 if (GET_CODE (operands[2]) == REG)
2969 return 6;
2970
2971 if (GET_CODE (operands[2]) == CONST_INT)
2972 {
2973 HOST_WIDE_INT n = INTVAL (operands[2]);
2974
2975 if ((n & 0xffffff) == 0)
2976 return 2;
2977 if ((n & 0xffff) == 0)
2978 return 4;
2979 if ((n & 0xff) == 0)
2980 return 6;
2981 }
2982
2983 return 8;
aa3382b1 2984 }
2985 else
2986 {
727c62dd 2987 if (GET_CODE (operands[2]) == CONST_INT
2988 && register_operand (operands[1], VOIDmode))
aa3382b1 2989 {
2990 HOST_WIDE_INT intval = INTVAL (operands[2]);
2991
727c62dd 2992 if (TARGET_H8300SX && (intval >= 1 && intval <= 7))
2993 return 2;
2994 if (TARGET_H8300SX && (intval >= -7 && intval <= -1))
2995 return 2;
2996
aa3382b1 2997 /* See if we can finish with 2 bytes. */
2998
11233c59 2999 switch ((unsigned int) intval & 0xffffffff)
aa3382b1 3000 {
3001 case 0x00000001:
3002 case 0x00000002:
3003 case 0x00000004:
3004 return 2;
3005
3006 case 0xffffffff:
3007 case 0xfffffffe:
3008 case 0xfffffffc:
3009 return 2;
3010
3011 case 0x00010000:
3012 case 0x00020000:
3013 return 2;
3014
3015 case 0xffff0000:
3016 case 0xfffe0000:
3017 return 2;
3018 }
3019
3020 /* See if we can finish with 4 bytes. */
3021 if ((intval & 0xffff) == 0)
3022 return 4;
3023 }
3024
727c62dd 3025 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
3026 return h8300_length_from_table (operands[0],
3027 GEN_INT (-INTVAL (operands[2])),
3028 &addl_length_table);
3029 else
3030 return h8300_length_from_table (operands[0], operands[2],
3031 &addl_length_table);
aa3382b1 3032 return 6;
3033 }
3034}
3035
cdfb02e8 3036/* Compute which flag bits are valid after an addition insn. */
3037
d00580fa 3038int
230002f2 3039compute_plussi_cc (rtx *operands)
aa3382b1 3040{
3041 enum machine_mode mode = GET_MODE (operands[0]);
3042
3afe906b 3043 gcc_assert (mode == SImode);
aa3382b1 3044
3045 if (TARGET_H8300)
3046 {
469dc9d2 3047 return CC_CLOBBER;
aa3382b1 3048 }
3049 else
3050 {
727c62dd 3051 if (GET_CODE (operands[2]) == CONST_INT
3052 && register_operand (operands[1], VOIDmode))
aa3382b1 3053 {
3054 HOST_WIDE_INT intval = INTVAL (operands[2]);
3055
727c62dd 3056 if (TARGET_H8300SX && (intval >= 1 && intval <= 7))
3057 return CC_SET_ZN;
3058 if (TARGET_H8300SX && (intval >= -7 && intval <= -1))
3059 return CC_SET_ZN;
3060
aa3382b1 3061 /* See if we can finish with 2 bytes. */
3062
11233c59 3063 switch ((unsigned int) intval & 0xffffffff)
aa3382b1 3064 {
3065 case 0x00000001:
3066 case 0x00000002:
3067 case 0x00000004:
3068 return CC_NONE_0HIT;
3069
3070 case 0xffffffff:
3071 case 0xfffffffe:
3072 case 0xfffffffc:
3073 return CC_NONE_0HIT;
3074
3075 case 0x00010000:
3076 case 0x00020000:
3077 return CC_CLOBBER;
3078
3079 case 0xffff0000:
3080 case 0xfffe0000:
3081 return CC_CLOBBER;
3082 }
3083
3084 /* See if we can finish with 4 bytes. */
3085 if ((intval & 0xffff) == 0)
3086 return CC_CLOBBER;
3087 }
3088
3089 return CC_SET_ZN;
3090 }
3091}
3092\f
cdfb02e8 3093/* Output a logical insn. */
3094
aa3382b1 3095const char *
230002f2 3096output_logical_op (enum machine_mode mode, rtx *operands)
6a8a3fa3 3097{
6ad7df02 3098 /* Figure out the logical op that we need to perform. */
3099 enum rtx_code code = GET_CODE (operands[3]);
6a8a3fa3 3100 /* Pretend that every byte is affected if both operands are registers. */
407921a5 3101 const unsigned HOST_WIDE_INT intval =
6a8a3fa3 3102 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
727c62dd 3103 /* Always use the full instruction if the
3104 first operand is in memory. It is better
3105 to use define_splits to generate the shorter
3106 sequence where valid. */
3107 && register_operand (operands[1], VOIDmode)
6a8a3fa3 3108 ? INTVAL (operands[2]) : 0x55555555);
3109 /* The determinant of the algorithm. If we perform an AND, 0
3110 affects a bit. Otherwise, 1 affects a bit. */
407921a5 3111 const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
e6cf6c71 3112 /* Break up DET into pieces. */
3113 const unsigned HOST_WIDE_INT b0 = (det >> 0) & 0xff;
3114 const unsigned HOST_WIDE_INT b1 = (det >> 8) & 0xff;
cdcf26ff 3115 const unsigned HOST_WIDE_INT b2 = (det >> 16) & 0xff;
3116 const unsigned HOST_WIDE_INT b3 = (det >> 24) & 0xff;
e6cf6c71 3117 const unsigned HOST_WIDE_INT w0 = (det >> 0) & 0xffff;
3118 const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff;
3119 int lower_half_easy_p = 0;
3120 int upper_half_easy_p = 0;
6a8a3fa3 3121 /* The name of an insn. */
3122 const char *opname;
3123 char insn_buf[100];
3124
3125 switch (code)
3126 {
3127 case AND:
3128 opname = "and";
3129 break;
3130 case IOR:
3131 opname = "or";
3132 break;
3133 case XOR:
3134 opname = "xor";
3135 break;
3136 default:
3afe906b 3137 gcc_unreachable ();
6a8a3fa3 3138 }
3139
3140 switch (mode)
3141 {
3142 case HImode:
3143 /* First, see if we can finish with one insn. */
3144 if ((TARGET_H8300H || TARGET_H8300S)
cdcf26ff 3145 && b0 != 0
3146 && b1 != 0)
6a8a3fa3 3147 {
3148 sprintf (insn_buf, "%s.w\t%%T2,%%T0", opname);
3149 output_asm_insn (insn_buf, operands);
3150 }
3151 else
3152 {
3153 /* Take care of the lower byte. */
cdcf26ff 3154 if (b0 != 0)
6a8a3fa3 3155 {
3156 sprintf (insn_buf, "%s\t%%s2,%%s0", opname);
3157 output_asm_insn (insn_buf, operands);
3158 }
3159 /* Take care of the upper byte. */
cdcf26ff 3160 if (b1 != 0)
6a8a3fa3 3161 {
3162 sprintf (insn_buf, "%s\t%%t2,%%t0", opname);
3163 output_asm_insn (insn_buf, operands);
3164 }
3165 }
3166 break;
3167 case SImode:
e6cf6c71 3168 if (TARGET_H8300H || TARGET_H8300S)
3169 {
3170 /* Determine if the lower half can be taken care of in no more
3171 than two bytes. */
3172 lower_half_easy_p = (b0 == 0
3173 || b1 == 0
3174 || (code != IOR && w0 == 0xffff));
3175
3176 /* Determine if the upper half can be taken care of in no more
3177 than two bytes. */
3178 upper_half_easy_p = ((code != IOR && w1 == 0xffff)
3179 || (code == AND && w1 == 0xff00));
3180 }
6a8a3fa3 3181
e6cf6c71 3182 /* Check if doing everything with one insn is no worse than
3183 using multiple insns. */
6a8a3fa3 3184 if ((TARGET_H8300H || TARGET_H8300S)
e6cf6c71 3185 && w0 != 0 && w1 != 0
0372ccb5 3186 && !(lower_half_easy_p && upper_half_easy_p)
3187 && !(code == IOR && w1 == 0xffff
3188 && (w0 & 0x8000) != 0 && lower_half_easy_p))
6a8a3fa3 3189 {
3190 sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname);
3191 output_asm_insn (insn_buf, operands);
3192 }
3193 else
3194 {
3195 /* Take care of the lower and upper words individually. For
3196 each word, we try different methods in the order of
3197
3198 1) the special insn (in case of AND or XOR),
3199 2) the word-wise insn, and
3200 3) The byte-wise insn. */
cdcf26ff 3201 if (w0 == 0xffff
a9d986d9 3202 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
6a8a3fa3 3203 output_asm_insn ((code == AND)
b0422000 3204 ? "sub.w\t%f0,%f0" : "not.w\t%f0",
6a8a3fa3 3205 operands);
3206 else if ((TARGET_H8300H || TARGET_H8300S)
cdcf26ff 3207 && (b0 != 0)
3208 && (b1 != 0))
6a8a3fa3 3209 {
3210 sprintf (insn_buf, "%s.w\t%%f2,%%f0", opname);
3211 output_asm_insn (insn_buf, operands);
3212 }
3213 else
3214 {
cdcf26ff 3215 if (b0 != 0)
6a8a3fa3 3216 {
3217 sprintf (insn_buf, "%s\t%%w2,%%w0", opname);
3218 output_asm_insn (insn_buf, operands);
3219 }
cdcf26ff 3220 if (b1 != 0)
6a8a3fa3 3221 {
3222 sprintf (insn_buf, "%s\t%%x2,%%x0", opname);
3223 output_asm_insn (insn_buf, operands);
3224 }
3225 }
3226
cdcf26ff 3227 if ((w1 == 0xffff)
a9d986d9 3228 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
6a8a3fa3 3229 output_asm_insn ((code == AND)
b0422000 3230 ? "sub.w\t%e0,%e0" : "not.w\t%e0",
6a8a3fa3 3231 operands);
0372ccb5 3232 else if ((TARGET_H8300H || TARGET_H8300S)
3233 && code == IOR
3234 && w1 == 0xffff
3235 && (w0 & 0x8000) != 0)
3236 {
3237 output_asm_insn ("exts.l\t%S0", operands);
3238 }
f4bdef90 3239 else if ((TARGET_H8300H || TARGET_H8300S)
3240 && code == AND
cdcf26ff 3241 && w1 == 0xff00)
f4bdef90 3242 {
1c75fadf 3243 output_asm_insn ("extu.w\t%e0", operands);
f4bdef90 3244 }
6a8a3fa3 3245 else if (TARGET_H8300H || TARGET_H8300S)
3246 {
cdcf26ff 3247 if (w1 != 0)
6a8a3fa3 3248 {
3249 sprintf (insn_buf, "%s.w\t%%e2,%%e0", opname);
3250 output_asm_insn (insn_buf, operands);
3251 }
3252 }
3253 else
3254 {
cdcf26ff 3255 if (b2 != 0)
6a8a3fa3 3256 {
3257 sprintf (insn_buf, "%s\t%%y2,%%y0", opname);
3258 output_asm_insn (insn_buf, operands);
3259 }
cdcf26ff 3260 if (b3 != 0)
6a8a3fa3 3261 {
3262 sprintf (insn_buf, "%s\t%%z2,%%z0", opname);
3263 output_asm_insn (insn_buf, operands);
3264 }
3265 }
3266 }
3267 break;
3268 default:
3afe906b 3269 gcc_unreachable ();
6a8a3fa3 3270 }
3271 return "";
3272}
359e4f59 3273
cdfb02e8 3274/* Compute the length of a logical insn. */
3275
359e4f59 3276unsigned int
230002f2 3277compute_logical_op_length (enum machine_mode mode, rtx *operands)
359e4f59 3278{
6ad7df02 3279 /* Figure out the logical op that we need to perform. */
3280 enum rtx_code code = GET_CODE (operands[3]);
359e4f59 3281 /* Pretend that every byte is affected if both operands are registers. */
407921a5 3282 const unsigned HOST_WIDE_INT intval =
359e4f59 3283 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
727c62dd 3284 /* Always use the full instruction if the
3285 first operand is in memory. It is better
3286 to use define_splits to generate the shorter
3287 sequence where valid. */
3288 && register_operand (operands[1], VOIDmode)
359e4f59 3289 ? INTVAL (operands[2]) : 0x55555555);
3290 /* The determinant of the algorithm. If we perform an AND, 0
3291 affects a bit. Otherwise, 1 affects a bit. */
407921a5 3292 const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
e6cf6c71 3293 /* Break up DET into pieces. */
3294 const unsigned HOST_WIDE_INT b0 = (det >> 0) & 0xff;
3295 const unsigned HOST_WIDE_INT b1 = (det >> 8) & 0xff;
cdcf26ff 3296 const unsigned HOST_WIDE_INT b2 = (det >> 16) & 0xff;
3297 const unsigned HOST_WIDE_INT b3 = (det >> 24) & 0xff;
e6cf6c71 3298 const unsigned HOST_WIDE_INT w0 = (det >> 0) & 0xffff;
3299 const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff;
3300 int lower_half_easy_p = 0;
3301 int upper_half_easy_p = 0;
359e4f59 3302 /* Insn length. */
3303 unsigned int length = 0;
3304
3305 switch (mode)
3306 {
3307 case HImode:
3308 /* First, see if we can finish with one insn. */
3309 if ((TARGET_H8300H || TARGET_H8300S)
cdcf26ff 3310 && b0 != 0
3311 && b1 != 0)
359e4f59 3312 {
727c62dd 3313 length = h8300_length_from_table (operands[1], operands[2],
3314 &logicw_length_table);
359e4f59 3315 }
3316 else
3317 {
3318 /* Take care of the lower byte. */
cdcf26ff 3319 if (b0 != 0)
359e4f59 3320 length += 2;
3321
3322 /* Take care of the upper byte. */
cdcf26ff 3323 if (b1 != 0)
359e4f59 3324 length += 2;
3325 }
3326 break;
3327 case SImode:
e6cf6c71 3328 if (TARGET_H8300H || TARGET_H8300S)
3329 {
3330 /* Determine if the lower half can be taken care of in no more
3331 than two bytes. */
3332 lower_half_easy_p = (b0 == 0
3333 || b1 == 0
3334 || (code != IOR && w0 == 0xffff));
3335
3336 /* Determine if the upper half can be taken care of in no more
3337 than two bytes. */
3338 upper_half_easy_p = ((code != IOR && w1 == 0xffff)
3339 || (code == AND && w1 == 0xff00));
3340 }
359e4f59 3341
e6cf6c71 3342 /* Check if doing everything with one insn is no worse than
3343 using multiple insns. */
359e4f59 3344 if ((TARGET_H8300H || TARGET_H8300S)
e6cf6c71 3345 && w0 != 0 && w1 != 0
0372ccb5 3346 && !(lower_half_easy_p && upper_half_easy_p)
3347 && !(code == IOR && w1 == 0xffff
3348 && (w0 & 0x8000) != 0 && lower_half_easy_p))
359e4f59 3349 {
727c62dd 3350 length = h8300_length_from_table (operands[1], operands[2],
3351 &logicl_length_table);
359e4f59 3352 }
3353 else
3354 {
3355 /* Take care of the lower and upper words individually. For
3356 each word, we try different methods in the order of
3357
3358 1) the special insn (in case of AND or XOR),
3359 2) the word-wise insn, and
3360 3) The byte-wise insn. */
cdcf26ff 3361 if (w0 == 0xffff
359e4f59 3362 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
3363 {
3364 length += 2;
3365 }
3366 else if ((TARGET_H8300H || TARGET_H8300S)
cdcf26ff 3367 && (b0 != 0)
3368 && (b1 != 0))
359e4f59 3369 {
3370 length += 4;
3371 }
3372 else
3373 {
cdcf26ff 3374 if (b0 != 0)
359e4f59 3375 length += 2;
3376
cdcf26ff 3377 if (b1 != 0)
359e4f59 3378 length += 2;
3379 }
3380
cdcf26ff 3381 if (w1 == 0xffff
359e4f59 3382 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
3383 {
3384 length += 2;
3385 }
0372ccb5 3386 else if ((TARGET_H8300H || TARGET_H8300S)
3387 && code == IOR
3388 && w1 == 0xffff
3389 && (w0 & 0x8000) != 0)
3390 {
3391 length += 2;
3392 }
f4bdef90 3393 else if ((TARGET_H8300H || TARGET_H8300S)
3394 && code == AND
cdcf26ff 3395 && w1 == 0xff00)
f4bdef90 3396 {
3397 length += 2;
3398 }
359e4f59 3399 else if (TARGET_H8300H || TARGET_H8300S)
3400 {
cdcf26ff 3401 if (w1 != 0)
359e4f59 3402 length += 4;
3403 }
3404 else
3405 {
cdcf26ff 3406 if (b2 != 0)
359e4f59 3407 length += 2;
3408
cdcf26ff 3409 if (b3 != 0)
359e4f59 3410 length += 2;
3411 }
3412 }
3413 break;
3414 default:
3afe906b 3415 gcc_unreachable ();
359e4f59 3416 }
3417 return length;
3418}
6ad7df02 3419
cdfb02e8 3420/* Compute which flag bits are valid after a logical insn. */
3421
6ad7df02 3422int
230002f2 3423compute_logical_op_cc (enum machine_mode mode, rtx *operands)
6ad7df02 3424{
3425 /* Figure out the logical op that we need to perform. */
3426 enum rtx_code code = GET_CODE (operands[3]);
3427 /* Pretend that every byte is affected if both operands are registers. */
407921a5 3428 const unsigned HOST_WIDE_INT intval =
6ad7df02 3429 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
727c62dd 3430 /* Always use the full instruction if the
3431 first operand is in memory. It is better
3432 to use define_splits to generate the shorter
3433 sequence where valid. */
3434 && register_operand (operands[1], VOIDmode)
6ad7df02 3435 ? INTVAL (operands[2]) : 0x55555555);
3436 /* The determinant of the algorithm. If we perform an AND, 0
3437 affects a bit. Otherwise, 1 affects a bit. */
407921a5 3438 const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
e6cf6c71 3439 /* Break up DET into pieces. */
3440 const unsigned HOST_WIDE_INT b0 = (det >> 0) & 0xff;
3441 const unsigned HOST_WIDE_INT b1 = (det >> 8) & 0xff;
3442 const unsigned HOST_WIDE_INT w0 = (det >> 0) & 0xffff;
3443 const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff;
3444 int lower_half_easy_p = 0;
3445 int upper_half_easy_p = 0;
6ad7df02 3446 /* Condition code. */
3447 enum attr_cc cc = CC_CLOBBER;
3448
3449 switch (mode)
3450 {
3451 case HImode:
3452 /* First, see if we can finish with one insn. */
3453 if ((TARGET_H8300H || TARGET_H8300S)
cdcf26ff 3454 && b0 != 0
3455 && b1 != 0)
6ad7df02 3456 {
3457 cc = CC_SET_ZNV;
3458 }
3459 break;
3460 case SImode:
e6cf6c71 3461 if (TARGET_H8300H || TARGET_H8300S)
3462 {
3463 /* Determine if the lower half can be taken care of in no more
3464 than two bytes. */
3465 lower_half_easy_p = (b0 == 0
3466 || b1 == 0
3467 || (code != IOR && w0 == 0xffff));
3468
3469 /* Determine if the upper half can be taken care of in no more
3470 than two bytes. */
3471 upper_half_easy_p = ((code != IOR && w1 == 0xffff)
3472 || (code == AND && w1 == 0xff00));
3473 }
6ad7df02 3474
e6cf6c71 3475 /* Check if doing everything with one insn is no worse than
3476 using multiple insns. */
6ad7df02 3477 if ((TARGET_H8300H || TARGET_H8300S)
e6cf6c71 3478 && w0 != 0 && w1 != 0
0372ccb5 3479 && !(lower_half_easy_p && upper_half_easy_p)
3480 && !(code == IOR && w1 == 0xffff
3481 && (w0 & 0x8000) != 0 && lower_half_easy_p))
6ad7df02 3482 {
3483 cc = CC_SET_ZNV;
3484 }
0372ccb5 3485 else
3486 {
3487 if ((TARGET_H8300H || TARGET_H8300S)
3488 && code == IOR
3489 && w1 == 0xffff
3490 && (w0 & 0x8000) != 0)
3491 {
3492 cc = CC_SET_ZNV;
3493 }
3494 }
6ad7df02 3495 break;
3496 default:
3afe906b 3497 gcc_unreachable ();
6ad7df02 3498 }
3499 return cc;
3500}
6a8a3fa3 3501\f
ab5a13fd 3502/* Expand a conditional branch. */
3503
3504void
3505h8300_expand_branch (enum rtx_code code, rtx label)
3506{
3507 rtx tmp;
3508
3509 tmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
3510 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
3511 gen_rtx_LABEL_REF (VOIDmode, label),
3512 pc_rtx);
3513 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
3514}
3515\f
b839e0b4 3516/* Shifts.
3517
f465f633 3518 We devote a fair bit of code to getting efficient shifts since we
3519 can only shift one bit at a time on the H8/300 and H8/300H and only
11f95d7c 3520 one or two bits at a time on the H8S.
f465f633 3521
3522 All shift code falls into one of the following ways of
3523 implementation:
3524
3525 o SHIFT_INLINE: Emit straight line code for the shift; this is used
3526 when a straight line shift is about the same size or smaller than
3527 a loop.
3528
3529 o SHIFT_ROT_AND: Rotate the value the opposite direction, then mask
3530 off the bits we don't need. This is used when only a few of the
3531 bits in the original value will survive in the shifted value.
3532
3533 o SHIFT_SPECIAL: Often it's possible to move a byte or a word to
3534 simulate a shift by 8, 16, or 24 bits. Once moved, a few inline
3535 shifts can be added if the shift count is slightly more than 8 or
3536 16. This case also includes other oddballs that are not worth
cc72e60a 3537 explaining here.
f465f633 3538
11f95d7c 3539 o SHIFT_LOOP: Emit a loop using one (or two on H8S) bit shifts.
f465f633 3540
140ee624 3541 For each shift count, we try to use code that has no trade-off
3542 between code size and speed whenever possible.
3543
3544 If the trade-off is unavoidable, we try to be reasonable.
3545 Specifically, the fastest version is one instruction longer than
3546 the shortest version, we take the fastest version. We also provide
3547 the use a way to switch back to the shortest version with -Os.
3548
3549 For the details of the shift algorithms for various shift counts,
3550 refer to shift_alg_[qhs]i. */
e1629549 3551
727c62dd 3552/* Classify a shift with the given mode and code. OP is the shift amount. */
3553
3554enum h8sx_shift_type
3555h8sx_classify_shift (enum machine_mode mode, enum rtx_code code, rtx op)
3556{
3557 if (!TARGET_H8300SX)
3558 return H8SX_SHIFT_NONE;
3559
3560 switch (code)
3561 {
3562 case ASHIFT:
3563 case LSHIFTRT:
3564 /* Check for variable shifts (shll Rs,Rd and shlr Rs,Rd). */
3565 if (GET_CODE (op) != CONST_INT)
3566 return H8SX_SHIFT_BINARY;
3567
3568 /* Reject out-of-range shift amounts. */
3569 if (INTVAL (op) <= 0 || INTVAL (op) >= GET_MODE_BITSIZE (mode))
3570 return H8SX_SHIFT_NONE;
3571
3572 /* Power-of-2 shifts are effectively unary operations. */
3573 if (exact_log2 (INTVAL (op)) >= 0)
3574 return H8SX_SHIFT_UNARY;
3575
3576 return H8SX_SHIFT_BINARY;
3577
3578 case ASHIFTRT:
3579 if (op == const1_rtx || op == const2_rtx)
3580 return H8SX_SHIFT_UNARY;
3581 return H8SX_SHIFT_NONE;
3582
3583 case ROTATE:
3584 if (GET_CODE (op) == CONST_INT
3585 && (INTVAL (op) == 1
3586 || INTVAL (op) == 2
3587 || INTVAL (op) == GET_MODE_BITSIZE (mode) - 2
3588 || INTVAL (op) == GET_MODE_BITSIZE (mode) - 1))
3589 return H8SX_SHIFT_UNARY;
3590 return H8SX_SHIFT_NONE;
3591
3592 default:
3593 return H8SX_SHIFT_NONE;
3594 }
3595}
3596
727c62dd 3597/* Return the asm template for a single h8sx shift instruction.
3598 OPERANDS[0] and OPERANDS[1] are the destination, OPERANDS[2]
3599 is the source and OPERANDS[3] is the shift. SUFFIX is the
3600 size suffix ('b', 'w' or 'l') and OPTYPE is the print_operand
3601 prefix for the destination operand. */
3602
3603const char *
3604output_h8sx_shift (rtx *operands, int suffix, int optype)
3605{
3606 static char buffer[16];
3607 const char *stem;
3608
3609 switch (GET_CODE (operands[3]))
3610 {
3611 case ASHIFT:
3612 stem = "shll";
3613 break;
3614
3615 case ASHIFTRT:
3616 stem = "shar";
3617 break;
3618
3619 case LSHIFTRT:
3620 stem = "shlr";
3621 break;
3622
3623 case ROTATE:
3624 stem = "rotl";
3625 if (INTVAL (operands[2]) > 2)
3626 {
3627 /* This is really a right rotate. */
3628 operands[2] = GEN_INT (GET_MODE_BITSIZE (GET_MODE (operands[0]))
3629 - INTVAL (operands[2]));
3630 stem = "rotr";
3631 }
3632 break;
3633
3634 default:
3afe906b 3635 gcc_unreachable ();
727c62dd 3636 }
3637 if (operands[2] == const1_rtx)
3638 sprintf (buffer, "%s.%c\t%%%c0", stem, suffix, optype);
3639 else
3640 sprintf (buffer, "%s.%c\t%%X2,%%%c0", stem, suffix, optype);
3641 return buffer;
3642}
b839e0b4 3643
6b07073d 3644/* Emit code to do shifts. */
b839e0b4 3645
727c62dd 3646bool
230002f2 3647expand_a_shift (enum machine_mode mode, int code, rtx operands[])
e1629549 3648{
727c62dd 3649 switch (h8sx_classify_shift (mode, code, operands[2]))
3650 {
3651 case H8SX_SHIFT_BINARY:
3652 operands[1] = force_reg (mode, operands[1]);
3653 return false;
3654
3655 case H8SX_SHIFT_UNARY:
3656 return false;
3657
3658 case H8SX_SHIFT_NONE:
3659 break;
3660 }
3661
e1629549 3662 emit_move_insn (operands[0], operands[1]);
3663
eb2aa24e 3664 /* Need a loop to get all the bits we want - we generate the
3665 code at emit time, but need to allocate a scratch reg now. */
b839e0b4 3666
7014838c 3667 emit_insn (gen_rtx_PARALLEL
3668 (VOIDmode,
b839e0b4 3669 gen_rtvec (2,
7014838c 3670 gen_rtx_SET (VOIDmode, operands[0],
dc55b8a9 3671 gen_rtx_fmt_ee (code, mode,
3672 operands[0], operands[2])),
7014838c 3673 gen_rtx_CLOBBER (VOIDmode,
3674 gen_rtx_SCRATCH (QImode)))));
727c62dd 3675 return true;
b839e0b4 3676}
3677
b839e0b4 3678/* Symbols of the various modes which can be used as indices. */
3679
3680enum shift_mode
27276a3b 3681{
3682 QIshift, HIshift, SIshift
3683};
b839e0b4 3684
30c992ef 3685/* For single bit shift insns, record assembler and what bits of the
3686 condition code are valid afterwards (represented as various CC_FOO
3687 bits, 0 means CC isn't left in a usable state). */
b839e0b4 3688
3689struct shift_insn
3690{
e99c3a1d 3691 const char *const assembler;
3692 const int cc_valid;
b839e0b4 3693};
3694
3695/* Assembler instruction shift table.
3696
3697 These tables are used to look up the basic shifts.
eb2aa24e 3698 They are indexed by cpu, shift_type, and mode. */
e1629549 3699
b839e0b4 3700static const struct shift_insn shift_one[2][3][3] =
3701{
3702/* H8/300 */
3703 {
3704/* SHIFT_ASHIFT */
3705 {
fd7729c5 3706 { "shll\t%X0", CC_SET_ZNV },
3707 { "add.w\t%T0,%T0", CC_SET_ZN },
3708 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", CC_CLOBBER }
b839e0b4 3709 },
3710/* SHIFT_LSHIFTRT */
3711 {
fd7729c5 3712 { "shlr\t%X0", CC_SET_ZNV },
3713 { "shlr\t%t0\n\trotxr\t%s0", CC_CLOBBER },
3714 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", CC_CLOBBER }
b839e0b4 3715 },
3716/* SHIFT_ASHIFTRT */
3717 {
fd7729c5 3718 { "shar\t%X0", CC_SET_ZNV },
3719 { "shar\t%t0\n\trotxr\t%s0", CC_CLOBBER },
3720 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", CC_CLOBBER }
b839e0b4 3721 }
3722 },
3723/* H8/300H */
3724 {
3725/* SHIFT_ASHIFT */
3726 {
fd7729c5 3727 { "shll.b\t%X0", CC_SET_ZNV },
3728 { "shll.w\t%T0", CC_SET_ZNV },
3729 { "shll.l\t%S0", CC_SET_ZNV }
b839e0b4 3730 },
3731/* SHIFT_LSHIFTRT */
3732 {
fd7729c5 3733 { "shlr.b\t%X0", CC_SET_ZNV },
3734 { "shlr.w\t%T0", CC_SET_ZNV },
3735 { "shlr.l\t%S0", CC_SET_ZNV }
b839e0b4 3736 },
3737/* SHIFT_ASHIFTRT */
3738 {
fd7729c5 3739 { "shar.b\t%X0", CC_SET_ZNV },
3740 { "shar.w\t%T0", CC_SET_ZNV },
3741 { "shar.l\t%S0", CC_SET_ZNV }
b839e0b4 3742 }
3743 }
3744};
e1629549 3745
52abe980 3746static const struct shift_insn shift_two[3][3] =
3747{
3748/* SHIFT_ASHIFT */
3749 {
fd7729c5 3750 { "shll.b\t#2,%X0", CC_SET_ZNV },
3751 { "shll.w\t#2,%T0", CC_SET_ZNV },
3752 { "shll.l\t#2,%S0", CC_SET_ZNV }
52abe980 3753 },
3754/* SHIFT_LSHIFTRT */
3755 {
fd7729c5 3756 { "shlr.b\t#2,%X0", CC_SET_ZNV },
3757 { "shlr.w\t#2,%T0", CC_SET_ZNV },
3758 { "shlr.l\t#2,%S0", CC_SET_ZNV }
52abe980 3759 },
3760/* SHIFT_ASHIFTRT */
3761 {
fd7729c5 3762 { "shar.b\t#2,%X0", CC_SET_ZNV },
3763 { "shar.w\t#2,%T0", CC_SET_ZNV },
3764 { "shar.l\t#2,%S0", CC_SET_ZNV }
52abe980 3765 }
3766};
3767
b839e0b4 3768/* Rotates are organized by which shift they'll be used in implementing.
3769 There's no need to record whether the cc is valid afterwards because
3770 it is the AND insn that will decide this. */
e1629549 3771
b839e0b4 3772static const char *const rotate_one[2][3][3] =
3773{
3774/* H8/300 */
3775 {
3776/* SHIFT_ASHIFT */
3777 {
52abe980 3778 "rotr\t%X0",
3779 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
b839e0b4 3780 0
3781 },
3782/* SHIFT_LSHIFTRT */
3783 {
52abe980 3784 "rotl\t%X0",
3785 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
b839e0b4 3786 0
3787 },
3788/* SHIFT_ASHIFTRT */
3789 {
52abe980 3790 "rotl\t%X0",
3791 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
b839e0b4 3792 0
e1629549 3793 }
b839e0b4 3794 },
3795/* H8/300H */
3796 {
3797/* SHIFT_ASHIFT */
3798 {
52abe980 3799 "rotr.b\t%X0",
3800 "rotr.w\t%T0",
3801 "rotr.l\t%S0"
b839e0b4 3802 },
3803/* SHIFT_LSHIFTRT */
e1629549 3804 {
52abe980 3805 "rotl.b\t%X0",
3806 "rotl.w\t%T0",
3807 "rotl.l\t%S0"
b839e0b4 3808 },
3809/* SHIFT_ASHIFTRT */
3810 {
52abe980 3811 "rotl.b\t%X0",
3812 "rotl.w\t%T0",
3813 "rotl.l\t%S0"
b839e0b4 3814 }
3815 }
3816};
3817
52abe980 3818static const char *const rotate_two[3][3] =
3819{
3820/* SHIFT_ASHIFT */
3821 {
3822 "rotr.b\t#2,%X0",
3823 "rotr.w\t#2,%T0",
3824 "rotr.l\t#2,%S0"
3825 },
3826/* SHIFT_LSHIFTRT */
3827 {
3828 "rotl.b\t#2,%X0",
3829 "rotl.w\t#2,%T0",
3830 "rotl.l\t#2,%S0"
3831 },
3832/* SHIFT_ASHIFTRT */
3833 {
3834 "rotl.b\t#2,%X0",
3835 "rotl.w\t#2,%T0",
3836 "rotl.l\t#2,%S0"
3837 }
3838};
3839
4765dbab 3840struct shift_info {
3841 /* Shift algorithm. */
3842 enum shift_alg alg;
3843
3844 /* The number of bits to be shifted by shift1 and shift2. Valid
3845 when ALG is SHIFT_SPECIAL. */
3846 unsigned int remainder;
3847
3848 /* Special insn for a shift. Valid when ALG is SHIFT_SPECIAL. */
3849 const char *special;
3850
3851 /* Insn for a one-bit shift. Valid when ALG is either SHIFT_INLINE
c46dc351 3852 or SHIFT_SPECIAL, and REMAINDER is nonzero. */
4765dbab 3853 const char *shift1;
3854
3855 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
c46dc351 3856 or SHIFT_SPECIAL, and REMAINDER is nonzero. */
4765dbab 3857 const char *shift2;
3858
fd7729c5 3859 /* CC status for SHIFT_INLINE. */
3860 int cc_inline;
3861
3862 /* CC status for SHIFT_SPECIAL. */
3863 int cc_special;
4765dbab 3864};
3865
230002f2 3866static void get_shift_alg (enum shift_type,
3867 enum shift_mode, unsigned int,
3868 struct shift_info *);
9305fe33 3869
ec0b80c6 3870/* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
3871 best algorithm for doing the shift. The assembler code is stored
140ee624 3872 in the pointers in INFO. We achieve the maximum efficiency in most
3873 cases when !TARGET_H8300. In case of TARGET_H8300, shifts in
3874 SImode in particular have a lot of room to optimize.
3875
3876 We first determine the strategy of the shift algorithm by a table
3877 lookup. If that tells us to use a hand crafted assembly code, we
3878 go into the big switch statement to find what that is. Otherwise,
3879 we resort to a generic way, such as inlining. In either case, the
3880 result is returned through INFO. */
b839e0b4 3881
5a40b38e 3882static void
230002f2 3883get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
3884 unsigned int count, struct shift_info *info)
b839e0b4 3885{
5d822c00 3886 enum h8_cpu cpu;
58285553 3887
3888 /* Find the target CPU. */
3889 if (TARGET_H8300)
5d822c00 3890 cpu = H8_300;
58285553 3891 else if (TARGET_H8300H)
5d822c00 3892 cpu = H8_300H;
58285553 3893 else
5d822c00 3894 cpu = H8_S;
58285553 3895
ce8940f6 3896 /* Find the shift algorithm. */
5d822c00 3897 info->alg = SHIFT_LOOP;
b839e0b4 3898 switch (shift_mode)
3899 {
3900 case QIshift:
5d822c00 3901 if (count < GET_MODE_BITSIZE (QImode))
ce8940f6 3902 info->alg = shift_alg_qi[cpu][shift_type][count];
3903 break;
58285553 3904
ce8940f6 3905 case HIshift:
5d822c00 3906 if (count < GET_MODE_BITSIZE (HImode))
ce8940f6 3907 info->alg = shift_alg_hi[cpu][shift_type][count];
3908 break;
3909
3910 case SIshift:
5d822c00 3911 if (count < GET_MODE_BITSIZE (SImode))
ce8940f6 3912 info->alg = shift_alg_si[cpu][shift_type][count];
3913 break;
3914
3915 default:
3afe906b 3916 gcc_unreachable ();
ce8940f6 3917 }
3918
3919 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
3920 switch (info->alg)
3921 {
3922 case SHIFT_INLINE:
3923 info->remainder = count;
3924 /* Fall through. */
3925
3926 case SHIFT_LOOP:
3927 /* It is up to the caller to know that looping clobbers cc. */
3928 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
3929 info->shift2 = shift_two[shift_type][shift_mode].assembler;
fd7729c5 3930 info->cc_inline = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
ce8940f6 3931 goto end;
3932
3933 case SHIFT_ROT_AND:
3934 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
3935 info->shift2 = rotate_two[shift_type][shift_mode];
fd7729c5 3936 info->cc_inline = CC_CLOBBER;
ce8940f6 3937 goto end;
3938
3939 case SHIFT_SPECIAL:
3940 /* REMAINDER is 0 for most cases, so initialize it to 0. */
3941 info->remainder = 0;
3942 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
3943 info->shift2 = shift_two[shift_type][shift_mode].assembler;
fd7729c5 3944 info->cc_inline = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
3945 info->cc_special = CC_CLOBBER;
ce8940f6 3946 break;
3947 }
52abe980 3948
ce8940f6 3949 /* Here we only deal with SHIFT_SPECIAL. */
3950 switch (shift_mode)
3951 {
3952 case QIshift:
58285553 3953 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
3954 through the entire value. */
3afe906b 3955 gcc_assert (shift_type == SHIFT_ASHIFTRT && count == 7);
3956 info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
3957 goto end;
58285553 3958
3959 case HIshift:
58285553 3960 if (count == 7)
52abe980 3961 {
79b29436 3962 switch (shift_type)
52abe980 3963 {
79b29436 3964 case SHIFT_ASHIFT:
3965 if (TARGET_H8300)
3966 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";
3967 else
3968 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
606a6902 3969 goto end;
79b29436 3970 case SHIFT_LSHIFTRT:
3971 if (TARGET_H8300)
3972 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";
3973 else
3974 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
606a6902 3975 goto end;
79b29436 3976 case SHIFT_ASHIFTRT:
4765dbab 3977 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
606a6902 3978 goto end;
b839e0b4 3979 }
e1629549 3980 }
a033fe93 3981 else if ((8 <= count && count <= 13)
8796f52f 3982 || (TARGET_H8300S && count == 14))
e1629549 3983 {
8db8f925 3984 info->remainder = count - 8;
3985
52abe980 3986 switch (shift_type)
b839e0b4 3987 {
52abe980 3988 case SHIFT_ASHIFT:
4765dbab 3989 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
606a6902 3990 goto end;
52abe980 3991 case SHIFT_LSHIFTRT:
903ae79d 3992 if (TARGET_H8300)
3993 {
3994 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
3995 info->shift1 = "shlr.b\t%s0";
fd7729c5 3996 info->cc_inline = CC_SET_ZNV;
903ae79d 3997 }
3998 else
3999 {
4000 info->special = "mov.b\t%t0,%s0\n\textu.w\t%T0";
fd7729c5 4001 info->cc_special = CC_SET_ZNV;
903ae79d 4002 }
606a6902 4003 goto end;
52abe980 4004 case SHIFT_ASHIFTRT:
4005 if (TARGET_H8300)
903ae79d 4006 {
4007 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
4008 info->shift1 = "shar.b\t%s0";
903ae79d 4009 }
52abe980 4010 else
903ae79d 4011 {
4012 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
fd7729c5 4013 info->cc_special = CC_SET_ZNV;
903ae79d 4014 }
606a6902 4015 goto end;
52abe980 4016 }
4017 }
a0bbe9df 4018 else if (count == 14)
4019 {
4020 switch (shift_type)
4021 {
4022 case SHIFT_ASHIFT:
4023 if (TARGET_H8300)
4024 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";
4025 goto end;
4026 case SHIFT_LSHIFTRT:
4027 if (TARGET_H8300)
4028 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";
4029 goto end;
4030 case SHIFT_ASHIFTRT:
4031 if (TARGET_H8300)
4032 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";
4033 else if (TARGET_H8300H)
fd7729c5 4034 {
4035 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";
4036 info->cc_special = CC_SET_ZNV;
4037 }
a0bbe9df 4038 else /* TARGET_H8300S */
3afe906b 4039 gcc_unreachable ();
a0bbe9df 4040 goto end;
4041 }
4042 }
f76e2664 4043 else if (count == 15)
52abe980 4044 {
f76e2664 4045 switch (shift_type)
4046 {
4047 case SHIFT_ASHIFT:
4048 info->special = "bld\t#0,%s0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#7,%t0";
4049 goto end;
4050 case SHIFT_LSHIFTRT:
4051 info->special = "bld\t#7,%t0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#0,%s0";
4052 goto end;
4053 case SHIFT_ASHIFTRT:
4054 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
4055 goto end;
4056 }
e1629549 4057 }
3afe906b 4058 gcc_unreachable ();
52abe980 4059
b839e0b4 4060 case SIshift:
f76e2664 4061 if (TARGET_H8300 && 8 <= count && count <= 9)
b839e0b4 4062 {
f76e2664 4063 info->remainder = count - 8;
4064
52abe980 4065 switch (shift_type)
b839e0b4 4066 {
52abe980 4067 case SHIFT_ASHIFT:
4765dbab 4068 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";
606a6902 4069 goto end;
52abe980 4070 case SHIFT_LSHIFTRT:
4765dbab 4071 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";
f76e2664 4072 info->shift1 = "shlr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0";
606a6902 4073 goto end;
52abe980 4074 case SHIFT_ASHIFTRT:
4765dbab 4075 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";
606a6902 4076 goto end;
b839e0b4 4077 }
b839e0b4 4078 }
9bbc06f2 4079 else if (count == 8 && !TARGET_H8300)
4080 {
4081 switch (shift_type)
4082 {
4083 case SHIFT_ASHIFT:
4765dbab 4084 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";
606a6902 4085 goto end;
9bbc06f2 4086 case SHIFT_LSHIFTRT:
4765dbab 4087 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";
606a6902 4088 goto end;
9bbc06f2 4089 case SHIFT_ASHIFTRT:
4765dbab 4090 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";
606a6902 4091 goto end;
9bbc06f2 4092 }
4093 }
f76e2664 4094 else if (count == 15 && TARGET_H8300)
4095 {
4096 switch (shift_type)
4097 {
4098 case SHIFT_ASHIFT:
3afe906b 4099 gcc_unreachable ();
f76e2664 4100 case SHIFT_LSHIFTRT:
a6f6d86d 4101 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";
f76e2664 4102 goto end;
4103 case SHIFT_ASHIFTRT:
a6f6d86d 4104 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";
f76e2664 4105 goto end;
4106 }
4107 }
37e1f65a 4108 else if (count == 15 && !TARGET_H8300)
4109 {
4110 switch (shift_type)
4111 {
4112 case SHIFT_ASHIFT:
4113 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
fd7729c5 4114 info->cc_special = CC_SET_ZNV;
37e1f65a 4115 goto end;
4116 case SHIFT_LSHIFTRT:
d2079f6d 4117 info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
fd7729c5 4118 info->cc_special = CC_SET_ZNV;
37e1f65a 4119 goto end;
7913b5f4 4120 case SHIFT_ASHIFTRT:
3afe906b 4121 gcc_unreachable ();
37e1f65a 4122 }
4123 }
f76e2664 4124 else if ((TARGET_H8300 && 16 <= count && count <= 20)
8db8f925 4125 || (TARGET_H8300H && 16 <= count && count <= 19)
776e0da8 4126 || (TARGET_H8300S && 16 <= count && count <= 21))
b839e0b4 4127 {
8db8f925 4128 info->remainder = count - 16;
4129
b839e0b4 4130 switch (shift_type)
4131 {
4132 case SHIFT_ASHIFT:
4765dbab 4133 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
f76e2664 4134 if (TARGET_H8300)
a033fe93 4135 info->shift1 = "add.w\t%e0,%e0";
606a6902 4136 goto end;
52abe980 4137 case SHIFT_LSHIFTRT:
f76e2664 4138 if (TARGET_H8300)
4139 {
903ae79d 4140 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
4141 info->shift1 = "shlr\t%x0\n\trotxr\t%w0";
f76e2664 4142 }
4143 else
4144 {
903ae79d 4145 info->special = "mov.w\t%e0,%f0\n\textu.l\t%S0";
fd7729c5 4146 info->cc_special = CC_SET_ZNV;
f76e2664 4147 }
606a6902 4148 goto end;
52abe980 4149 case SHIFT_ASHIFTRT:
4150 if (TARGET_H8300)
f76e2664 4151 {
4152 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
4153 info->shift1 = "shar\t%x0\n\trotxr\t%w0";
4154 }
52abe980 4155 else
f76e2664 4156 {
4157 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
fd7729c5 4158 info->cc_special = CC_SET_ZNV;
f76e2664 4159 }
606a6902 4160 goto end;
52abe980 4161 }
4162 }
f76e2664 4163 else if (TARGET_H8300 && 24 <= count && count <= 28)
81c3eb11 4164 {
4165 info->remainder = count - 24;
f2702e8a 4166
81c3eb11 4167 switch (shift_type)
4168 {
4169 case SHIFT_ASHIFT:
4170 info->special = "mov.b\t%w0,%z0\n\tsub.b\t%y0,%y0\n\tsub.w\t%f0,%f0";
4171 info->shift1 = "shll.b\t%z0";
fd7729c5 4172 info->cc_inline = CC_SET_ZNV;
81c3eb11 4173 goto end;
4174 case SHIFT_LSHIFTRT:
4175 info->special = "mov.b\t%z0,%w0\n\tsub.b\t%x0,%x0\n\tsub.w\t%e0,%e0";
4176 info->shift1 = "shlr.b\t%w0";
fd7729c5 4177 info->cc_inline = CC_SET_ZNV;
81c3eb11 4178 goto end;
4179 case SHIFT_ASHIFTRT:
4180 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";
4181 info->shift1 = "shar.b\t%w0";
fd7729c5 4182 info->cc_inline = CC_SET_ZNV;
b44470aa 4183 goto end;
4184 }
4185 }
0d219270 4186 else if ((TARGET_H8300H && count == 24)
4187 || (TARGET_H8300S && 24 <= count && count <= 25))
9bbc06f2 4188 {
0d219270 4189 info->remainder = count - 24;
4190
9bbc06f2 4191 switch (shift_type)
4192 {
4193 case SHIFT_ASHIFT:
4765dbab 4194 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";
606a6902 4195 goto end;
9bbc06f2 4196 case SHIFT_LSHIFTRT:
4765dbab 4197 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
fd7729c5 4198 info->cc_special = CC_SET_ZNV;
606a6902 4199 goto end;
9bbc06f2 4200 case SHIFT_ASHIFTRT:
4765dbab 4201 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
fd7729c5 4202 info->cc_special = CC_SET_ZNV;
606a6902 4203 goto end;
9bbc06f2 4204 }
4205 }
567c4b66 4206 else if (!TARGET_H8300 && count == 28)
4207 {
4208 switch (shift_type)
4209 {
4210 case SHIFT_ASHIFT:
4211 if (TARGET_H8300H)
4212 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";
4213 else
4214 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";
567c4b66 4215 goto end;
4216 case SHIFT_LSHIFTRT:
4217 if (TARGET_H8300H)
fd7729c5 4218 {
4219 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";
4220 info->cc_special = CC_SET_ZNV;
4221 }
567c4b66 4222 else
903ae79d 4223 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t#2,%S0\n\textu.l\t%S0";
567c4b66 4224 goto end;
4225 case SHIFT_ASHIFTRT:
3afe906b 4226 gcc_unreachable ();
567c4b66 4227 }
4228 }
4229 else if (!TARGET_H8300 && count == 29)
4230 {
4231 switch (shift_type)
4232 {
4233 case SHIFT_ASHIFT:
4234 if (TARGET_H8300H)
4235 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";
4236 else
4237 info->special = "sub.w\t%e0,%e0\n\trotr.l\t#2,%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0";
567c4b66 4238 goto end;
4239 case SHIFT_LSHIFTRT:
4240 if (TARGET_H8300H)
fd7729c5 4241 {
4242 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";
4243 info->cc_special = CC_SET_ZNV;
4244 }
567c4b66 4245 else
fd7729c5 4246 {
4247 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t%S0\n\textu.l\t%S0";
4248 info->cc_special = CC_SET_ZNV;
4249 }
567c4b66 4250 goto end;
4251 case SHIFT_ASHIFTRT:
3afe906b 4252 gcc_unreachable ();
567c4b66 4253 }
4254 }
4255 else if (!TARGET_H8300 && count == 30)
4256 {
4257 switch (shift_type)
4258 {
4259 case SHIFT_ASHIFT:
4260 if (TARGET_H8300H)
4261 info->special = "sub.w\t%e0,%e0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0";
4262 else
4263 info->special = "sub.w\t%e0,%e0\n\trotr.l\t#2,%S0\n\tsub.w\t%f0,%f0";
567c4b66 4264 goto end;
4265 case SHIFT_LSHIFTRT:
4266 if (TARGET_H8300H)
903ae79d 4267 info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0";
567c4b66 4268 else
903ae79d 4269 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\textu.l\t%S0";
567c4b66 4270 goto end;
4271 case SHIFT_ASHIFTRT:
3afe906b 4272 gcc_unreachable ();
567c4b66 4273 }
4274 }
b839e0b4 4275 else if (count == 31)
4276 {
37e1f65a 4277 if (TARGET_H8300)
b839e0b4 4278 {
37e1f65a 4279 switch (shift_type)
4280 {
4281 case SHIFT_ASHIFT:
4282 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
4283 goto end;
4284 case SHIFT_LSHIFTRT:
4285 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
4286 goto end;
4287 case SHIFT_ASHIFTRT:
4288 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
4289 goto end;
4290 }
b839e0b4 4291 }
4292 else
4293 {
37e1f65a 4294 switch (shift_type)
b839e0b4 4295 {
37e1f65a 4296 case SHIFT_ASHIFT:
4297 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
fd7729c5 4298 info->cc_special = CC_SET_ZNV;
37e1f65a 4299 goto end;
4300 case SHIFT_LSHIFTRT:
4301 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
fd7729c5 4302 info->cc_special = CC_SET_ZNV;
37e1f65a 4303 goto end;
4304 case SHIFT_ASHIFTRT:
903ae79d 4305 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\texts.w\t%T0\n\texts.l\t%S0";
fd7729c5 4306 info->cc_special = CC_SET_ZNV;
606a6902 4307 goto end;
b839e0b4 4308 }
b839e0b4 4309 }
4310 }
3afe906b 4311 gcc_unreachable ();
52abe980 4312
b839e0b4 4313 default:
3afe906b 4314 gcc_unreachable ();
e1629549 4315 }
b839e0b4 4316
5a40b38e 4317 end:
4318 if (!TARGET_H8300S)
4319 info->shift2 = NULL;
e1629549 4320}
4321
6b30b2e6 4322/* Given COUNT and MODE of a shift, return 1 if a scratch reg may be
4323 needed for some shift with COUNT and MODE. Return 0 otherwise. */
4324
4325int
230002f2 4326h8300_shift_needs_scratch_p (int count, enum machine_mode mode)
6b30b2e6 4327{
5d822c00 4328 enum h8_cpu cpu;
6b30b2e6 4329 int a, lr, ar;
4330
4331 if (GET_MODE_BITSIZE (mode) <= count)
4332 return 1;
4333
4334 /* Find out the target CPU. */
4335 if (TARGET_H8300)
5d822c00 4336 cpu = H8_300;
6b30b2e6 4337 else if (TARGET_H8300H)
5d822c00 4338 cpu = H8_300H;
6b30b2e6 4339 else
5d822c00 4340 cpu = H8_S;
6b30b2e6 4341
4342 /* Find the shift algorithm. */
4343 switch (mode)
4344 {
4345 case QImode:
4346 a = shift_alg_qi[cpu][SHIFT_ASHIFT][count];
4347 lr = shift_alg_qi[cpu][SHIFT_LSHIFTRT][count];
4348 ar = shift_alg_qi[cpu][SHIFT_ASHIFTRT][count];
4349 break;
4350
4351 case HImode:
4352 a = shift_alg_hi[cpu][SHIFT_ASHIFT][count];
4353 lr = shift_alg_hi[cpu][SHIFT_LSHIFTRT][count];
4354 ar = shift_alg_hi[cpu][SHIFT_ASHIFTRT][count];
4355 break;
4356
4357 case SImode:
4358 a = shift_alg_si[cpu][SHIFT_ASHIFT][count];
4359 lr = shift_alg_si[cpu][SHIFT_LSHIFTRT][count];
4360 ar = shift_alg_si[cpu][SHIFT_ASHIFTRT][count];
4361 break;
4362
4363 default:
3afe906b 4364 gcc_unreachable ();
6b30b2e6 4365 }
4366
33a9c2d6 4367 /* On H8/300H, count == 8 uses a scratch register. */
6b30b2e6 4368 return (a == SHIFT_LOOP || lr == SHIFT_LOOP || ar == SHIFT_LOOP
c6ff55c2 4369 || (TARGET_H8300H && mode == SImode && count == 8));
6b30b2e6 4370}
4371
cdfb02e8 4372/* Output the assembler code for doing shifts. */
b839e0b4 4373
9305fe33 4374const char *
230002f2 4375output_a_shift (rtx *operands)
e1629549 4376{
b839e0b4 4377 static int loopend_lab;
b839e0b4 4378 rtx shift = operands[3];
4379 enum machine_mode mode = GET_MODE (shift);
4380 enum rtx_code code = GET_CODE (shift);
4381 enum shift_type shift_type;
4382 enum shift_mode shift_mode;
4765dbab 4383 struct shift_info info;
3afe906b 4384 int n;
b839e0b4 4385
4386 loopend_lab++;
4387
4388 switch (mode)
4389 {
4390 case QImode:
4391 shift_mode = QIshift;
4392 break;
4393 case HImode:
4394 shift_mode = HIshift;
4395 break;
4396 case SImode:
4397 shift_mode = SIshift;
4398 break;
4399 default:
3afe906b 4400 gcc_unreachable ();
b839e0b4 4401 }
e1629549 4402
b839e0b4 4403 switch (code)
e1629549 4404 {
b839e0b4 4405 case ASHIFTRT:
4406 shift_type = SHIFT_ASHIFTRT;
4407 break;
4408 case LSHIFTRT:
4409 shift_type = SHIFT_LSHIFTRT;
4410 break;
4411 case ASHIFT:
4412 shift_type = SHIFT_ASHIFT;
4413 break;
4414 default:
3afe906b 4415 gcc_unreachable ();
b839e0b4 4416 }
e1629549 4417
3afe906b 4418 /* This case must be taken care of by one of the two splitters
4419 that convert a variable shift into a loop. */
4420 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
4421
4422 n = INTVAL (operands[2]);
4423
4424 /* If the count is negative, make it 0. */
4425 if (n < 0)
4426 n = 0;
4427 /* If the count is too big, truncate it.
4428 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
4429 do the intuitive thing. */
4430 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
4431 n = GET_MODE_BITSIZE (mode);
4432
4433 get_shift_alg (shift_type, shift_mode, n, &info);
4434
4435 switch (info.alg)
b839e0b4 4436 {
3afe906b 4437 case SHIFT_SPECIAL:
4438 output_asm_insn (info.special, operands);
4439 /* Fall through. */
b839e0b4 4440
3afe906b 4441 case SHIFT_INLINE:
4442 n = info.remainder;
b839e0b4 4443
3afe906b 4444 /* Emit two bit shifts first. */
4445 if (info.shift2 != NULL)
b839e0b4 4446 {
3afe906b 4447 for (; n > 1; n -= 2)
4448 output_asm_insn (info.shift2, operands);
4449 }
52abe980 4450
3afe906b 4451 /* Now emit one bit shifts for any residual. */
4452 for (; n > 0; n--)
4453 output_asm_insn (info.shift1, operands);
4454 return "";
4455
4456 case SHIFT_ROT_AND:
4457 {
4458 int m = GET_MODE_BITSIZE (mode) - n;
4459 const int mask = (shift_type == SHIFT_ASHIFT
4460 ? ((1 << m) - 1) << n
4461 : (1 << m) - 1);
4462 char insn_buf[200];
4463
4464 /* Not all possibilities of rotate are supported. They shouldn't
4465 be generated, but let's watch for 'em. */
4466 gcc_assert (info.shift1);
4467
4468 /* Emit two bit rotates first. */
4469 if (info.shift2 != NULL)
b839e0b4 4470 {
3afe906b 4471 for (; m > 1; m -= 2)
4472 output_asm_insn (info.shift2, operands);
4473 }
4474
4475 /* Now single bit rotates for any residual. */
4476 for (; m > 0; m--)
4477 output_asm_insn (info.shift1, operands);
4478
4479 /* Now mask off the high bits. */
4480 switch (mode)
4481 {
4482 case QImode:
4483 sprintf (insn_buf, "and\t#%d,%%X0", mask);
4484 break;
52abe980 4485
3afe906b 4486 case HImode:
4487 gcc_assert (TARGET_H8300H || TARGET_H8300S);
4488 sprintf (insn_buf, "and.w\t#%d,%%T0", mask);
4489 break;
52abe980 4490
3afe906b 4491 default:
4492 gcc_unreachable ();
b839e0b4 4493 }
cb95c693 4494
3afe906b 4495 output_asm_insn (insn_buf, operands);
4496 return "";
4497 }
cb95c693 4498
3afe906b 4499 case SHIFT_LOOP:
4500 /* A loop to shift by a "large" constant value.
4501 If we have shift-by-2 insns, use them. */
4502 if (info.shift2 != NULL)
4503 {
4504 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
4505 names_big[REGNO (operands[4])]);
4506 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
4507 output_asm_insn (info.shift2, operands);
4508 output_asm_insn ("add #0xff,%X4", operands);
4509 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
4510 if (n % 2)
4511 output_asm_insn (info.shift1, operands);
4512 }
4513 else
4514 {
4515 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
4516 names_big[REGNO (operands[4])]);
4517 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
4518 output_asm_insn (info.shift1, operands);
4519 output_asm_insn ("add #0xff,%X4", operands);
4520 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
52abe980 4521 }
3afe906b 4522 return "";
4523
4524 default:
4525 gcc_unreachable ();
e1629549 4526 }
e1629549 4527}
484c1e8d 4528
cdfb02e8 4529/* Count the number of assembly instructions in a string TEMPLATE. */
4530
484c1e8d 4531static unsigned int
230002f2 4532h8300_asm_insn_count (const char *template)
484c1e8d 4533{
4534 unsigned int count = 1;
4535
4536 for (; *template; template++)
4537 if (*template == '\n')
4538 count++;
4539
4540 return count;
4541}
4542
cdfb02e8 4543/* Compute the length of a shift insn. */
4544
484c1e8d 4545unsigned int
230002f2 4546compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
484c1e8d 4547{
4548 rtx shift = operands[3];
4549 enum machine_mode mode = GET_MODE (shift);
4550 enum rtx_code code = GET_CODE (shift);
4551 enum shift_type shift_type;
4552 enum shift_mode shift_mode;
4553 struct shift_info info;
4554 unsigned int wlength = 0;
4555
4556 switch (mode)
4557 {
4558 case QImode:
4559 shift_mode = QIshift;
4560 break;
4561 case HImode:
4562 shift_mode = HIshift;
4563 break;
4564 case SImode:
4565 shift_mode = SIshift;
4566 break;
4567 default:
3afe906b 4568 gcc_unreachable ();
484c1e8d 4569 }
4570
4571 switch (code)
4572 {
4573 case ASHIFTRT:
4574 shift_type = SHIFT_ASHIFTRT;
4575 break;
4576 case LSHIFTRT:
4577 shift_type = SHIFT_LSHIFTRT;
4578 break;
4579 case ASHIFT:
4580 shift_type = SHIFT_ASHIFT;
4581 break;
4582 default:
3afe906b 4583 gcc_unreachable ();
484c1e8d 4584 }
4585
4586 if (GET_CODE (operands[2]) != CONST_INT)
4587 {
4588 /* Get the assembler code to do one shift. */
4589 get_shift_alg (shift_type, shift_mode, 1, &info);
4590
4591 return (4 + h8300_asm_insn_count (info.shift1)) * 2;
4592 }
4593 else
4594 {
4595 int n = INTVAL (operands[2]);
4596
4597 /* If the count is negative, make it 0. */
4598 if (n < 0)
4599 n = 0;
4600 /* If the count is too big, truncate it.
4601 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
4602 do the intuitive thing. */
4603 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
4604 n = GET_MODE_BITSIZE (mode);
4605
4606 get_shift_alg (shift_type, shift_mode, n, &info);
4607
4608 switch (info.alg)
4609 {
4610 case SHIFT_SPECIAL:
4611 wlength += h8300_asm_insn_count (info.special);
f56f0ed0 4612
4613 /* Every assembly instruction used in SHIFT_SPECIAL case
4614 takes 2 bytes except xor.l, which takes 4 bytes, so if we
4615 see xor.l, we just pretend that xor.l counts as two insns
4616 so that the insn length will be computed correctly. */
4617 if (strstr (info.special, "xor.l") != NULL)
4618 wlength++;
4619
484c1e8d 4620 /* Fall through. */
4621
4622 case SHIFT_INLINE:
4623 n = info.remainder;
4624
4625 if (info.shift2 != NULL)
4626 {
4627 wlength += h8300_asm_insn_count (info.shift2) * (n / 2);
4628 n = n % 2;
4629 }
4630
4631 wlength += h8300_asm_insn_count (info.shift1) * n;
66b41076 4632
484c1e8d 4633 return 2 * wlength;
4634
4635 case SHIFT_ROT_AND:
4636 {
4637 int m = GET_MODE_BITSIZE (mode) - n;
4638
4639 /* Not all possibilities of rotate are supported. They shouldn't
4640 be generated, but let's watch for 'em. */
3afe906b 4641 gcc_assert (info.shift1);
484c1e8d 4642
4643 if (info.shift2 != NULL)
4644 {
4645 wlength += h8300_asm_insn_count (info.shift2) * (m / 2);
4646 m = m % 2;
4647 }
4648
4649 wlength += h8300_asm_insn_count (info.shift1) * m;
66b41076 4650
484c1e8d 4651 /* Now mask off the high bits. */
4652 switch (mode)
4653 {
4654 case QImode:
4655 wlength += 1;
4656 break;
4657 case HImode:
4658 wlength += 2;
4659 break;
4660 case SImode:
3afe906b 4661 gcc_assert (!TARGET_H8300);
484c1e8d 4662 wlength += 3;
4663 break;
4664 default:
3afe906b 4665 gcc_unreachable ();
484c1e8d 4666 }
4667 return 2 * wlength;
4668 }
4669
4670 case SHIFT_LOOP:
4671 /* A loop to shift by a "large" constant value.
4672 If we have shift-by-2 insns, use them. */
4673 if (info.shift2 != NULL)
4674 {
4675 wlength += 3 + h8300_asm_insn_count (info.shift2);
4676 if (n % 2)
4677 wlength += h8300_asm_insn_count (info.shift1);
4678 }
4679 else
4680 {
4681 wlength += 3 + h8300_asm_insn_count (info.shift1);
4682 }
4683 return 2 * wlength;
4684
4685 default:
3afe906b 4686 gcc_unreachable ();
484c1e8d 4687 }
4688 }
4689}
fd7729c5 4690
cdfb02e8 4691/* Compute which flag bits are valid after a shift insn. */
4692
fd7729c5 4693int
230002f2 4694compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
fd7729c5 4695{
4696 rtx shift = operands[3];
4697 enum machine_mode mode = GET_MODE (shift);
4698 enum rtx_code code = GET_CODE (shift);
4699 enum shift_type shift_type;
4700 enum shift_mode shift_mode;
4701 struct shift_info info;
3afe906b 4702 int n;
4703
fd7729c5 4704 switch (mode)
4705 {
4706 case QImode:
4707 shift_mode = QIshift;
4708 break;
4709 case HImode:
4710 shift_mode = HIshift;
4711 break;
4712 case SImode:
4713 shift_mode = SIshift;
4714 break;
4715 default:
3afe906b 4716 gcc_unreachable ();
fd7729c5 4717 }
4718
4719 switch (code)
4720 {
4721 case ASHIFTRT:
4722 shift_type = SHIFT_ASHIFTRT;
4723 break;
4724 case LSHIFTRT:
4725 shift_type = SHIFT_LSHIFTRT;
4726 break;
4727 case ASHIFT:
4728 shift_type = SHIFT_ASHIFT;
4729 break;
4730 default:
3afe906b 4731 gcc_unreachable ();
fd7729c5 4732 }
4733
3afe906b 4734 /* This case must be taken care of by one of the two splitters
4735 that convert a variable shift into a loop. */
4736 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
4737
4738 n = INTVAL (operands[2]);
4739
4740 /* If the count is negative, make it 0. */
4741 if (n < 0)
4742 n = 0;
4743 /* If the count is too big, truncate it.
4744 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
4745 do the intuitive thing. */
4746 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
4747 n = GET_MODE_BITSIZE (mode);
4748
4749 get_shift_alg (shift_type, shift_mode, n, &info);
4750
4751 switch (info.alg)
fd7729c5 4752 {
3afe906b 4753 case SHIFT_SPECIAL:
4754 if (info.remainder == 0)
4755 return info.cc_special;
fd7729c5 4756
3afe906b 4757 /* Fall through. */
fd7729c5 4758
3afe906b 4759 case SHIFT_INLINE:
4760 return info.cc_inline;
4761
4762 case SHIFT_ROT_AND:
4763 /* This case always ends with an and instruction. */
4764 return CC_SET_ZNV;
4765
4766 case SHIFT_LOOP:
4767 /* A loop to shift by a "large" constant value.
4768 If we have shift-by-2 insns, use them. */
4769 if (info.shift2 != NULL)
fd7729c5 4770 {
3afe906b 4771 if (n % 2)
4772 return info.cc_inline;
fd7729c5 4773 }
3afe906b 4774 return CC_CLOBBER;
4775
4776 default:
4777 gcc_unreachable ();
fd7729c5 4778 }
4779}
b839e0b4 4780\f
b4fa7cf2 4781/* A rotation by a non-constant will cause a loop to be generated, in
4782 which a rotation by one bit is used. A rotation by a constant,
4783 including the one in the loop, will be taken care of by
af63c5ce 4784 output_a_rotate () at the insn emit time. */
b4fa7cf2 4785
4786int
a620f9df 4787expand_a_rotate (rtx operands[])
b4fa7cf2 4788{
4789 rtx dst = operands[0];
4790 rtx src = operands[1];
4791 rtx rotate_amount = operands[2];
4792 enum machine_mode mode = GET_MODE (dst);
b4fa7cf2 4793
727c62dd 4794 if (h8sx_classify_shift (mode, ROTATE, rotate_amount) == H8SX_SHIFT_UNARY)
4795 return false;
4796
b4fa7cf2 4797 /* We rotate in place. */
4798 emit_move_insn (dst, src);
4799
4800 if (GET_CODE (rotate_amount) != CONST_INT)
4801 {
4802 rtx counter = gen_reg_rtx (QImode);
4803 rtx start_label = gen_label_rtx ();
4804 rtx end_label = gen_label_rtx ();
4805
4806 /* If the rotate amount is less than or equal to 0,
4807 we go out of the loop. */
bcd9bd66 4808 emit_cmp_and_jump_insns (rotate_amount, const0_rtx, LE, NULL_RTX,
7e69f45b 4809 QImode, 0, end_label);
b4fa7cf2 4810
4811 /* Initialize the loop counter. */
4812 emit_move_insn (counter, rotate_amount);
4813
4814 emit_label (start_label);
4815
4816 /* Rotate by one bit. */
18618acc 4817 switch (mode)
4818 {
4819 case QImode:
4820 emit_insn (gen_rotlqi3_1 (dst, dst, const1_rtx));
4821 break;
4822 case HImode:
4823 emit_insn (gen_rotlhi3_1 (dst, dst, const1_rtx));
4824 break;
4825 case SImode:
4826 emit_insn (gen_rotlsi3_1 (dst, dst, const1_rtx));
4827 break;
4828 default:
3afe906b 4829 gcc_unreachable ();
18618acc 4830 }
b4fa7cf2 4831
4832 /* Decrement the counter by 1. */
18618acc 4833 emit_insn (gen_addqi3 (counter, counter, constm1_rtx));
b4fa7cf2 4834
c46dc351 4835 /* If the loop counter is nonzero, we go back to the beginning
b4fa7cf2 4836 of the loop. */
bcd9bd66 4837 emit_cmp_and_jump_insns (counter, const0_rtx, NE, NULL_RTX, QImode, 1,
7e69f45b 4838 start_label);
b4fa7cf2 4839
4840 emit_label (end_label);
4841 }
4842 else
4843 {
4844 /* Rotate by AMOUNT bits. */
18618acc 4845 switch (mode)
4846 {
4847 case QImode:
4848 emit_insn (gen_rotlqi3_1 (dst, dst, rotate_amount));
4849 break;
4850 case HImode:
4851 emit_insn (gen_rotlhi3_1 (dst, dst, rotate_amount));
4852 break;
4853 case SImode:
4854 emit_insn (gen_rotlsi3_1 (dst, dst, rotate_amount));
4855 break;
4856 default:
3afe906b 4857 gcc_unreachable ();
18618acc 4858 }
b4fa7cf2 4859 }
4860
4861 return 1;
4862}
4863
cdfb02e8 4864/* Output a rotate insn. */
b4fa7cf2 4865
4866const char *
af63c5ce 4867output_a_rotate (enum rtx_code code, rtx *operands)
b4fa7cf2 4868{
4869 rtx dst = operands[0];
4870 rtx rotate_amount = operands[2];
4871 enum shift_mode rotate_mode;
4872 enum shift_type rotate_type;
4873 const char *insn_buf;
4874 int bits;
4875 int amount;
4876 enum machine_mode mode = GET_MODE (dst);
4877
3afe906b 4878 gcc_assert (GET_CODE (rotate_amount) == CONST_INT);
b4fa7cf2 4879
4880 switch (mode)
4881 {
4882 case QImode:
4883 rotate_mode = QIshift;
4884 break;
4885 case HImode:
4886 rotate_mode = HIshift;
4887 break;
4888 case SImode:
4889 rotate_mode = SIshift;
4890 break;
4891 default:
3afe906b 4892 gcc_unreachable ();
b4fa7cf2 4893 }
4894
4895 switch (code)
4896 {
4897 case ROTATERT:
4898 rotate_type = SHIFT_ASHIFT;
4899 break;
4900 case ROTATE:
4901 rotate_type = SHIFT_LSHIFTRT;
4902 break;
4903 default:
3afe906b 4904 gcc_unreachable ();
b4fa7cf2 4905 }
4906
4907 amount = INTVAL (rotate_amount);
4908
4909 /* Clean up AMOUNT. */
4910 if (amount < 0)
4911 amount = 0;
4912 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
4913 amount = GET_MODE_BITSIZE (mode);
4914
4915 /* Determine the faster direction. After this phase, amount will be
4916 at most a half of GET_MODE_BITSIZE (mode). */
de8409f8 4917 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
b4fa7cf2 4918 {
4919 /* Flip the direction. */
4920 amount = GET_MODE_BITSIZE (mode) - amount;
4921 rotate_type =
4922 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
4923 }
4924
4925 /* See if a byte swap (in HImode) or a word swap (in SImode) can
4926 boost up the rotation. */
4927 if ((mode == HImode && TARGET_H8300 && amount >= 5)
4928 || (mode == HImode && TARGET_H8300H && amount >= 6)
4929 || (mode == HImode && TARGET_H8300S && amount == 8)
4930 || (mode == SImode && TARGET_H8300H && amount >= 10)
4931 || (mode == SImode && TARGET_H8300S && amount >= 13))
4932 {
4933 switch (mode)
4934 {
4935 case HImode:
4936 /* This code works on any family. */
4937 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
4938 output_asm_insn (insn_buf, operands);
4939 break;
4940
4941 case SImode:
11f95d7c 4942 /* This code works on the H8/300H and H8S. */
b4fa7cf2 4943 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
4944 output_asm_insn (insn_buf, operands);
4945 break;
4946
4947 default:
3afe906b 4948 gcc_unreachable ();
b4fa7cf2 4949 }
4950
4951 /* Adjust AMOUNT and flip the direction. */
4952 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
4953 rotate_type =
4954 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
4955 }
4956
18618acc 4957 /* Output rotate insns. */
b4fa7cf2 4958 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2)
4959 {
4960 if (bits == 2)
4961 insn_buf = rotate_two[rotate_type][rotate_mode];
4962 else
4963 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode];
a86fab2e 4964
b4fa7cf2 4965 for (; amount >= bits; amount -= bits)
4966 output_asm_insn (insn_buf, operands);
4967 }
4968
4969 return "";
4970}
af63c5ce 4971
cdfb02e8 4972/* Compute the length of a rotate insn. */
4973
af63c5ce 4974unsigned int
4975compute_a_rotate_length (rtx *operands)
4976{
4977 rtx src = operands[1];
3ab64e09 4978 rtx amount_rtx = operands[2];
af63c5ce 4979 enum machine_mode mode = GET_MODE (src);
4980 int amount;
4981 unsigned int length = 0;
4982
3afe906b 4983 gcc_assert (GET_CODE (amount_rtx) == CONST_INT);
af63c5ce 4984
3ab64e09 4985 amount = INTVAL (amount_rtx);
af63c5ce 4986
4987 /* Clean up AMOUNT. */
4988 if (amount < 0)
4989 amount = 0;
4990 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
4991 amount = GET_MODE_BITSIZE (mode);
4992
4993 /* Determine the faster direction. After this phase, amount
4994 will be at most a half of GET_MODE_BITSIZE (mode). */
4995 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
4996 /* Flip the direction. */
4997 amount = GET_MODE_BITSIZE (mode) - amount;
4998
4999 /* See if a byte swap (in HImode) or a word swap (in SImode) can
5000 boost up the rotation. */
5001 if ((mode == HImode && TARGET_H8300 && amount >= 5)
5002 || (mode == HImode && TARGET_H8300H && amount >= 6)
5003 || (mode == HImode && TARGET_H8300S && amount == 8)
5004 || (mode == SImode && TARGET_H8300H && amount >= 10)
5005 || (mode == SImode && TARGET_H8300S && amount >= 13))
5006 {
5007 /* Adjust AMOUNT and flip the direction. */
5008 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
5009 length += 6;
5010 }
5011
5012 /* We use 2-bit rotations on the H8S. */
5013 if (TARGET_H8300S)
5014 amount = amount / 2 + amount % 2;
5015
5016 /* The H8/300 uses three insns to rotate one bit, taking 6
5017 length. */
5018 length += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2);
5019
5020 return length;
5021}
b4fa7cf2 5022\f
b839e0b4 5023/* Fix the operands of a gen_xxx so that it could become a bit
a86fab2e 5024 operating insn. */
e1629549 5025
5026int
eb53e102 5027fix_bit_operand (rtx *operands, enum rtx_code code)
e1629549 5028{
b090827b 5029 /* The bit_operand predicate accepts any memory during RTL generation, but
b839e0b4 5030 only 'U' memory afterwards, so if this is a MEM operand, we must force
5031 it to be valid for 'U' by reloading the address. */
e1629549 5032
eb53e102 5033 if (code == AND
5034 ? single_zero_operand (operands[2], QImode)
5035 : single_one_operand (operands[2], QImode))
e1629549 5036 {
c7619744 5037 /* OK to have a memory dest. */
5038 if (GET_CODE (operands[0]) == MEM
727c62dd 5039 && !OK_FOR_U (operands[0]))
b839e0b4 5040 {
c7619744 5041 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
5042 copy_to_mode_reg (Pmode,
5043 XEXP (operands[0], 0)));
5044 MEM_COPY_ATTRIBUTES (mem, operands[0]);
5045 operands[0] = mem;
5046 }
b839e0b4 5047
c7619744 5048 if (GET_CODE (operands[1]) == MEM
727c62dd 5049 && !OK_FOR_U (operands[1]))
c7619744 5050 {
5051 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
5052 copy_to_mode_reg (Pmode,
5053 XEXP (operands[1], 0)));
5054 MEM_COPY_ATTRIBUTES (mem, operands[0]);
5055 operands[1] = mem;
b839e0b4 5056 }
c7619744 5057 return 0;
b839e0b4 5058 }
e1629549 5059
b839e0b4 5060 /* Dest and src op must be register. */
e1629549 5061
b839e0b4 5062 operands[1] = force_reg (QImode, operands[1]);
5063 {
5064 rtx res = gen_reg_rtx (QImode);
bd80419e 5065 switch (code)
4b042441 5066 {
5067 case AND:
5068 emit_insn (gen_andqi3_1 (res, operands[1], operands[2]));
5069 break;
5070 case IOR:
5071 emit_insn (gen_iorqi3_1 (res, operands[1], operands[2]));
5072 break;
5073 case XOR:
5074 emit_insn (gen_xorqi3_1 (res, operands[1], operands[2]));
5075 break;
5076 default:
3afe906b 5077 gcc_unreachable ();
4b042441 5078 }
5079 emit_insn (gen_movqi (operands[0], res));
b839e0b4 5080 }
5081 return 1;
e1629549 5082}
b11bfc61 5083
b11bfc61 5084/* Return nonzero if FUNC is an interrupt function as specified
5085 by the "interrupt" attribute. */
5086
5087static int
230002f2 5088h8300_interrupt_function_p (tree func)
b11bfc61 5089{
5090 tree a;
5091
5092 if (TREE_CODE (func) != FUNCTION_DECL)
5093 return 0;
5094
e3c541f0 5095 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
b11bfc61 5096 return a != NULL_TREE;
5097}
5098
5344805f 5099/* Return nonzero if FUNC is a saveall function as specified by the
5100 "saveall" attribute. */
5101
5102static int
5103h8300_saveall_function_p (tree func)
5104{
5105 tree a;
5106
5107 if (TREE_CODE (func) != FUNCTION_DECL)
5108 return 0;
5109
5110 a = lookup_attribute ("saveall", DECL_ATTRIBUTES (func));
5111 return a != NULL_TREE;
5112}
5113
09c48b9c 5114/* Return nonzero if FUNC is an OS_Task function as specified
5115 by the "OS_Task" attribute. */
5116
5117static int
230002f2 5118h8300_os_task_function_p (tree func)
09c48b9c 5119{
5120 tree a;
5121
5122 if (TREE_CODE (func) != FUNCTION_DECL)
5123 return 0;
5124
e3c541f0 5125 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func));
09c48b9c 5126 return a != NULL_TREE;
5127}
5128
5129/* Return nonzero if FUNC is a monitor function as specified
5130 by the "monitor" attribute. */
5131
5132static int
230002f2 5133h8300_monitor_function_p (tree func)
09c48b9c 5134{
5135 tree a;
5136
5137 if (TREE_CODE (func) != FUNCTION_DECL)
5138 return 0;
5139
e3c541f0 5140 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func));
09c48b9c 5141 return a != NULL_TREE;
5142}
5143
b11bfc61 5144/* Return nonzero if FUNC is a function that should be called
5145 through the function vector. */
5146
5147int
230002f2 5148h8300_funcvec_function_p (tree func)
b11bfc61 5149{
5150 tree a;
5151
5152 if (TREE_CODE (func) != FUNCTION_DECL)
5153 return 0;
5154
e3c541f0 5155 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func));
b11bfc61 5156 return a != NULL_TREE;
5157}
5158
27a0be8f 5159/* Return nonzero if DECL is a variable that's in the eight bit
2c7be643 5160 data area. */
5161
5162int
230002f2 5163h8300_eightbit_data_p (tree decl)
2c7be643 5164{
5165 tree a;
5166
5167 if (TREE_CODE (decl) != VAR_DECL)
5168 return 0;
5169
e3c541f0 5170 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl));
2c7be643 5171 return a != NULL_TREE;
5172}
5173
27a0be8f 5174/* Return nonzero if DECL is a variable that's in the tiny
5175 data area. */
5176
5177int
230002f2 5178h8300_tiny_data_p (tree decl)
27a0be8f 5179{
5180 tree a;
5181
5182 if (TREE_CODE (decl) != VAR_DECL)
5183 return 0;
5184
e3c541f0 5185 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl));
27a0be8f 5186 return a != NULL_TREE;
5187}
5188
5344805f 5189/* Generate an 'interrupt_handler' attribute for decls. We convert
5190 all the pragmas to corresponding attributes. */
ad7d09f6 5191
5192static void
230002f2 5193h8300_insert_attributes (tree node, tree *attributes)
ad7d09f6 5194{
5344805f 5195 if (TREE_CODE (node) == FUNCTION_DECL)
5196 {
5197 if (pragma_interrupt)
5198 {
5199 pragma_interrupt = 0;
ad7d09f6 5200
5344805f 5201 /* Add an 'interrupt_handler' attribute. */
5202 *attributes = tree_cons (get_identifier ("interrupt_handler"),
5203 NULL, *attributes);
5204 }
41ed3bcd 5205
5344805f 5206 if (pragma_saveall)
5207 {
5208 pragma_saveall = 0;
5209
5210 /* Add an 'saveall' attribute. */
5211 *attributes = tree_cons (get_identifier ("saveall"),
5212 NULL, *attributes);
5213 }
5214 }
ad7d09f6 5215}
5216
e3c541f0 5217/* Supported attributes:
b11bfc61 5218
bd297402 5219 interrupt_handler: output a prologue and epilogue suitable for an
b11bfc61 5220 interrupt handler.
5221
5344805f 5222 saveall: output a prologue and epilogue that saves and restores
5223 all registers except the stack pointer.
5224
bd297402 5225 function_vector: This function should be called through the
27a0be8f 5226 function vector.
5227
5228 eightbit_data: This variable lives in the 8-bit data area and can
5229 be referenced with 8-bit absolute memory addresses.
5230
5231 tiny_data: This variable lives in the tiny data area and can be
5232 referenced with 16-bit absolute memory references. */
b11bfc61 5233
e3c541f0 5234const struct attribute_spec h8300_attribute_table[] =
b11bfc61 5235{
e3c541f0 5236 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
5237 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
5344805f 5238 { "saveall", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
e3c541f0 5239 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
5240 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
5241 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
5242 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute },
5243 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute },
5244 { NULL, 0, 0, false, false, false, NULL }
5245};
b11bfc61 5246
2c7be643 5247
e3c541f0 5248/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
5249 struct attribute_spec.handler. */
5250static tree
230002f2 5251h8300_handle_fndecl_attribute (tree *node, tree name,
5252 tree args ATTRIBUTE_UNUSED,
5253 int flags ATTRIBUTE_UNUSED,
5254 bool *no_add_attrs)
e3c541f0 5255{
5256 if (TREE_CODE (*node) != FUNCTION_DECL)
5257 {
9b2d6d13 5258 warning (OPT_Wattributes, "%qs attribute only applies to functions",
e3c541f0 5259 IDENTIFIER_POINTER (name));
5260 *no_add_attrs = true;
5261 }
5262
5263 return NULL_TREE;
5264}
5265
5266/* Handle an "eightbit_data" attribute; arguments as in
5267 struct attribute_spec.handler. */
5268static tree
230002f2 5269h8300_handle_eightbit_data_attribute (tree *node, tree name,
5270 tree args ATTRIBUTE_UNUSED,
5271 int flags ATTRIBUTE_UNUSED,
5272 bool *no_add_attrs)
e3c541f0 5273{
5274 tree decl = *node;
5275
5276 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
2c7be643 5277 {
b6a063c6 5278 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
e3c541f0 5279 }
5280 else
5281 {
9b2d6d13 5282 warning (OPT_Wattributes, "%qs attribute ignored",
5283 IDENTIFIER_POINTER (name));
e3c541f0 5284 *no_add_attrs = true;
27a0be8f 5285 }
5286
e3c541f0 5287 return NULL_TREE;
5288}
5289
5290/* Handle an "tiny_data" attribute; arguments as in
5291 struct attribute_spec.handler. */
5292static tree
230002f2 5293h8300_handle_tiny_data_attribute (tree *node, tree name,
5294 tree args ATTRIBUTE_UNUSED,
5295 int flags ATTRIBUTE_UNUSED,
5296 bool *no_add_attrs)
e3c541f0 5297{
5298 tree decl = *node;
5299
5300 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
27a0be8f 5301 {
b6a063c6 5302 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
e3c541f0 5303 }
5304 else
5305 {
9b2d6d13 5306 warning (OPT_Wattributes, "%qs attribute ignored",
5307 IDENTIFIER_POINTER (name));
e3c541f0 5308 *no_add_attrs = true;
2c7be643 5309 }
eb2aa24e 5310
e3c541f0 5311 return NULL_TREE;
b11bfc61 5312}
5313
d37aaac2 5314/* Mark function vectors, and various small data objects. */
7811991d 5315
5316static void
230002f2 5317h8300_encode_section_info (tree decl, rtx rtl, int first)
7811991d 5318{
d37aaac2 5319 int extra_flags = 0;
5320
2c129d70 5321 default_encode_section_info (decl, rtl, first);
d37aaac2 5322
7811991d 5323 if (TREE_CODE (decl) == FUNCTION_DECL
5324 && h8300_funcvec_function_p (decl))
d37aaac2 5325 extra_flags = SYMBOL_FLAG_FUNCVEC_FUNCTION;
7811991d 5326 else if (TREE_CODE (decl) == VAR_DECL
5327 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
5328 {
5329 if (h8300_eightbit_data_p (decl))
d37aaac2 5330 extra_flags = SYMBOL_FLAG_EIGHTBIT_DATA;
7811991d 5331 else if (first && h8300_tiny_data_p (decl))
d37aaac2 5332 extra_flags = SYMBOL_FLAG_TINY_DATA;
7811991d 5333 }
7b4a38a6 5334
d37aaac2 5335 if (extra_flags)
2c129d70 5336 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= extra_flags;
7b4a38a6 5337}
5338
cdfb02e8 5339/* Output a single-bit extraction. */
5340
9305fe33 5341const char *
230002f2 5342output_simode_bld (int bild, rtx operands[])
92eae32b 5343{
7ef78393 5344 if (TARGET_H8300)
5345 {
5346 /* Clear the destination register. */
5347 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
5348
5349 /* Now output the bit load or bit inverse load, and store it in
5350 the destination. */
5351 if (bild)
5352 output_asm_insn ("bild\t%Z2,%Y1", operands);
5353 else
5354 output_asm_insn ("bld\t%Z2,%Y1", operands);
92eae32b 5355
7ef78393 5356 output_asm_insn ("bst\t#0,%w0", operands);
5357 }
92eae32b 5358 else
7ef78393 5359 {
7d3e46b8 5360 /* Determine if we can clear the destination first. */
5361 int clear_first = (REG_P (operands[0]) && REG_P (operands[1])
5362 && REGNO (operands[0]) != REGNO (operands[1]));
5363
5364 if (clear_first)
5365 output_asm_insn ("sub.l\t%S0,%S0", operands);
5366
7ef78393 5367 /* Output the bit load or bit inverse load. */
5368 if (bild)
5369 output_asm_insn ("bild\t%Z2,%Y1", operands);
5370 else
5371 output_asm_insn ("bld\t%Z2,%Y1", operands);
5372
7d3e46b8 5373 if (!clear_first)
5374 output_asm_insn ("xor.l\t%S0,%S0", operands);
5375
5376 /* Perform the bit store. */
04b5bef5 5377 output_asm_insn ("rotxl.l\t%S0", operands);
7ef78393 5378 }
92eae32b 5379
5380 /* All done. */
5381 return "";
5382}
fe19f1e0 5383
727c62dd 5384/* Delayed-branch scheduling is more effective if we have some idea
5385 how long each instruction will be. Use a shorten_branches pass
5386 to get an initial estimate. */
5387
5388static void
5389h8300_reorg (void)
5390{
5391 if (flag_delayed_branch)
5392 shorten_branches (get_insns ());
5393}
5394
6e4758ce 5395#ifndef OBJECT_FORMAT_ELF
2cb4ac60 5396static void
537cd941 5397h8300_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED,
5398 tree decl)
2cb4ac60 5399{
5400 /* ??? Perhaps we should be using default_coff_asm_named_section. */
5401 fprintf (asm_out_file, "\t.section %s\n", name);
5402}
6e4758ce 5403#endif /* ! OBJECT_FORMAT_ELF */
6c48c1e4 5404
e566129f 5405/* Nonzero if X is a constant address suitable as an 8-bit absolute,
5406 which is a special case of the 'R' operand. */
5407
6c48c1e4 5408int
230002f2 5409h8300_eightbit_constant_address_p (rtx x)
6c48c1e4 5410{
1d60d981 5411 /* The ranges of the 8-bit area. */
424064e7 5412 const unsigned HOST_WIDE_INT n1 = trunc_int_for_mode (0xff00, HImode);
5413 const unsigned HOST_WIDE_INT n2 = trunc_int_for_mode (0xffff, HImode);
6c48c1e4 5414 const unsigned HOST_WIDE_INT h1 = trunc_int_for_mode (0x00ffff00, SImode);
5415 const unsigned HOST_WIDE_INT h2 = trunc_int_for_mode (0x00ffffff, SImode);
5416 const unsigned HOST_WIDE_INT s1 = trunc_int_for_mode (0xffffff00, SImode);
5417 const unsigned HOST_WIDE_INT s2 = trunc_int_for_mode (0xffffffff, SImode);
5418
5419 unsigned HOST_WIDE_INT addr;
5420
e55c1a72 5421 /* We accept symbols declared with eightbit_data. */
d37aaac2 5422 if (GET_CODE (x) == SYMBOL_REF)
5423 return (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_EIGHTBIT_DATA) != 0;
e55c1a72 5424
6c48c1e4 5425 if (GET_CODE (x) != CONST_INT)
5426 return 0;
5427
5428 addr = INTVAL (x);
5429
5430 return (0
35a462ce 5431 || ((TARGET_H8300 || TARGET_NORMAL_MODE) && IN_RANGE (addr, n1, n2))
6c48c1e4 5432 || (TARGET_H8300H && IN_RANGE (addr, h1, h2))
5433 || (TARGET_H8300S && IN_RANGE (addr, s1, s2)));
5434}
5435
e566129f 5436/* Nonzero if X is a constant address suitable as an 16-bit absolute
5437 on H8/300H and H8S. */
5438
6c48c1e4 5439int
230002f2 5440h8300_tiny_constant_address_p (rtx x)
6c48c1e4 5441{
462c2024 5442 /* The ranges of the 16-bit area. */
6c48c1e4 5443 const unsigned HOST_WIDE_INT h1 = trunc_int_for_mode (0x00000000, SImode);
5444 const unsigned HOST_WIDE_INT h2 = trunc_int_for_mode (0x00007fff, SImode);
5445 const unsigned HOST_WIDE_INT h3 = trunc_int_for_mode (0x00ff8000, SImode);
5446 const unsigned HOST_WIDE_INT h4 = trunc_int_for_mode (0x00ffffff, SImode);
5447 const unsigned HOST_WIDE_INT s1 = trunc_int_for_mode (0x00000000, SImode);
5448 const unsigned HOST_WIDE_INT s2 = trunc_int_for_mode (0x00007fff, SImode);
5449 const unsigned HOST_WIDE_INT s3 = trunc_int_for_mode (0xffff8000, SImode);
5450 const unsigned HOST_WIDE_INT s4 = trunc_int_for_mode (0xffffffff, SImode);
5451
5452 unsigned HOST_WIDE_INT addr;
5453
52d2fba2 5454 switch (GET_CODE (x))
5455 {
5456 case SYMBOL_REF:
abe5efd4 5457 /* In the normal mode, any symbol fits in the 16-bit absolute
5458 address range. We also accept symbols declared with
5459 tiny_data. */
5460 return (TARGET_NORMAL_MODE
5461 || (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_TINY_DATA) != 0);
3696208f 5462
52d2fba2 5463 case CONST_INT:
5464 addr = INTVAL (x);
5465 return (TARGET_NORMAL_MODE
5466 || (TARGET_H8300H
5467 && (IN_RANGE (addr, h1, h2) || IN_RANGE (addr, h3, h4)))
5468 || (TARGET_H8300S
5469 && (IN_RANGE (addr, s1, s2) || IN_RANGE (addr, s3, s4))));
6c48c1e4 5470
abe5efd4 5471 case CONST:
5472 return TARGET_NORMAL_MODE;
5473
52d2fba2 5474 default:
5475 return 0;
5476 }
6c48c1e4 5477
6c48c1e4 5478}
e33ecec3 5479
cdfb02e8 5480/* Return nonzero if ADDR1 and ADDR2 point to consecutive memory
5481 locations that can be accessed as a 16-bit word. */
5482
e33ecec3 5483int
230002f2 5484byte_accesses_mergeable_p (rtx addr1, rtx addr2)
e33ecec3 5485{
5486 HOST_WIDE_INT offset1, offset2;
5487 rtx reg1, reg2;
5488
5489 if (REG_P (addr1))
5490 {
5491 reg1 = addr1;
5492 offset1 = 0;
5493 }
5494 else if (GET_CODE (addr1) == PLUS
5495 && REG_P (XEXP (addr1, 0))
5496 && GET_CODE (XEXP (addr1, 1)) == CONST_INT)
5497 {
5498 reg1 = XEXP (addr1, 0);
5499 offset1 = INTVAL (XEXP (addr1, 1));
5500 }
5501 else
5502 return 0;
5503
5504 if (REG_P (addr2))
5505 {
5506 reg2 = addr2;
5507 offset2 = 0;
5508 }
5509 else if (GET_CODE (addr2) == PLUS
5510 && REG_P (XEXP (addr2, 0))
5511 && GET_CODE (XEXP (addr2, 1)) == CONST_INT)
5512 {
5513 reg2 = XEXP (addr2, 0);
5514 offset2 = INTVAL (XEXP (addr2, 1));
5515 }
5516 else
5517 return 0;
5518
5519 if (((reg1 == stack_pointer_rtx && reg2 == stack_pointer_rtx)
5520 || (reg1 == frame_pointer_rtx && reg2 == frame_pointer_rtx))
5521 && offset1 % 2 == 0
5522 && offset1 + 1 == offset2)
5523 return 1;
5524
5525 return 0;
5526}
8c71b4e9 5527
5528/* Return nonzero if we have the same comparison insn as I3 two insns
be002911 5529 before I3. I3 is assumed to be a comparison insn. */
8c71b4e9 5530
5531int
5532same_cmp_preceding_p (rtx i3)
5533{
5534 rtx i1, i2;
5535
5536 /* Make sure we have a sequence of three insns. */
5537 i2 = prev_nonnote_insn (i3);
5538 if (i2 == NULL_RTX)
5539 return 0;
5540 i1 = prev_nonnote_insn (i2);
5541 if (i1 == NULL_RTX)
5542 return 0;
5543
5544 return (INSN_P (i1) && rtx_equal_p (PATTERN (i1), PATTERN (i3))
5545 && any_condjump_p (i2) && onlyjump_p (i2));
5546}
01272fdf 5547
5b9da921 5548/* Return nonzero if we have the same comparison insn as I1 two insns
5549 after I1. I1 is assumed to be a comparison insn. */
5550
5551int
5552same_cmp_following_p (rtx i1)
5553{
5554 rtx i2, i3;
5555
5556 /* Make sure we have a sequence of three insns. */
5557 i2 = next_nonnote_insn (i1);
5558 if (i2 == NULL_RTX)
5559 return 0;
5560 i3 = next_nonnote_insn (i2);
5561 if (i3 == NULL_RTX)
5562 return 0;
5563
5564 return (INSN_P (i3) && rtx_equal_p (PATTERN (i1), PATTERN (i3))
5565 && any_condjump_p (i2) && onlyjump_p (i2));
5566}
5567
f41916c8 5568/* Return nonzero if OPERANDS are valid for stm (or ldm) that pushes
7bd28bba 5569 (or pops) N registers. OPERANDS are assumed to be an array of
f41916c8 5570 registers. */
5571
5572int
5573h8300_regs_ok_for_stm (int n, rtx operands[])
5574{
5575 switch (n)
5576 {
5577 case 2:
5578 return ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
5579 || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
5580 || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5));
5581 case 3:
5582 return ((REGNO (operands[0]) == 0
5583 && REGNO (operands[1]) == 1
5584 && REGNO (operands[2]) == 2)
5585 || (REGNO (operands[0]) == 4
5586 && REGNO (operands[1]) == 5
5587 && REGNO (operands[2]) == 6));
5588
5589 case 4:
5590 return (REGNO (operands[0]) == 0
5591 && REGNO (operands[1]) == 1
5592 && REGNO (operands[2]) == 2
5593 && REGNO (operands[3]) == 3);
3afe906b 5594 default:
5595 gcc_unreachable ();
f41916c8 5596 }
f41916c8 5597}
5598
01272fdf 5599/* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
5600
5601int
5602h8300_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
5603 unsigned int new_reg)
5604{
5605 /* Interrupt functions can only use registers that have already been
5606 saved by the prologue, even if they would normally be
5607 call-clobbered. */
5608
5609 if (h8300_current_function_interrupt_function_p ()
3072d30e 5610 && !df_regs_ever_live_p (new_reg))
01272fdf 5611 return 0;
5612
6fe6e17a 5613 return 1;
01272fdf 5614}
9a5775fe 5615
5616/* Return nonzero if X is a legitimate constant. */
5617
5618int
5619h8300_legitimate_constant_p (rtx x ATTRIBUTE_UNUSED)
5620{
5621 return 1;
5622}
5623
5624/* Return nonzero if X is a REG or SUBREG suitable as a base register. */
5625
5626static int
5627h8300_rtx_ok_for_base_p (rtx x, int strict)
5628{
5629 /* Strip off SUBREG if any. */
5630 if (GET_CODE (x) == SUBREG)
5631 x = SUBREG_REG (x);
5632
5633 return (REG_P (x)
5634 && (strict
5635 ? REG_OK_FOR_BASE_STRICT_P (x)
5636 : REG_OK_FOR_BASE_NONSTRICT_P (x)));
5637}
5638
5639/* Return nozero if X is a legitimate address. On the H8/300, a
5640 legitimate address has the form REG, REG+CONSTANT_ADDRESS or
5641 CONSTANT_ADDRESS. */
5642
5643int
727c62dd 5644h8300_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
9a5775fe 5645{
5646 /* The register indirect addresses like @er0 is always valid. */
5647 if (h8300_rtx_ok_for_base_p (x, strict))
5648 return 1;
5649
5650 if (CONSTANT_ADDRESS_P (x))
5651 return 1;
5652
727c62dd 5653 if (TARGET_H8300SX
5654 && ( GET_CODE (x) == PRE_INC
5655 || GET_CODE (x) == PRE_DEC
5656 || GET_CODE (x) == POST_INC
5657 || GET_CODE (x) == POST_DEC)
5658 && h8300_rtx_ok_for_base_p (XEXP (x, 0), strict))
5659 return 1;
5660
9a5775fe 5661 if (GET_CODE (x) == PLUS
5662 && CONSTANT_ADDRESS_P (XEXP (x, 1))
727c62dd 5663 && h8300_rtx_ok_for_base_p (h8300_get_index (XEXP (x, 0),
5664 mode, 0), strict))
9a5775fe 5665 return 1;
5666
5667 return 0;
5668}
a578a1cc 5669
5670/* Worker function for HARD_REGNO_NREGS.
5671
5672 We pretend the MAC register is 32bits -- we don't have any data
5673 types on the H8 series to handle more than 32bits. */
5674
5675int
5676h8300_hard_regno_nregs (int regno ATTRIBUTE_UNUSED, enum machine_mode mode)
5677{
5678 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
5679}
5680
5681/* Worker function for HARD_REGNO_MODE_OK. */
5682
5683int
5684h8300_hard_regno_mode_ok (int regno, enum machine_mode mode)
5685{
5686 if (TARGET_H8300)
5687 /* If an even reg, then anything goes. Otherwise the mode must be
5688 QI or HI. */
5689 return ((regno & 1) == 0) || (mode == HImode) || (mode == QImode);
5690 else
5691 /* MAC register can only be of SImode. Otherwise, anything
5692 goes. */
5693 return regno == MAC_REG ? mode == SImode : 1;
5694}
9fb90c4e 5695\f
f2f543a3 5696/* Perform target dependent optabs initialization. */
5697static void
5698h8300_init_libfuncs (void)
5699{
5700 set_optab_libfunc (smul_optab, HImode, "__mulhi3");
5701 set_optab_libfunc (sdiv_optab, HImode, "__divhi3");
5702 set_optab_libfunc (udiv_optab, HImode, "__udivhi3");
5703 set_optab_libfunc (smod_optab, HImode, "__modhi3");
5704 set_optab_libfunc (umod_optab, HImode, "__umodhi3");
5705}
5706\f
cdfb02e8 5707/* Worker function for TARGET_RETURN_IN_MEMORY. */
5708
5c6c612a 5709static bool
5710h8300_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
5711{
5712 return (TYPE_MODE (type) == BLKmode
5713 || GET_MODE_SIZE (TYPE_MODE (type)) > (TARGET_H8300 ? 4 : 8));
5714}
5715\f
9fb90c4e 5716/* Initialize the GCC target structure. */
5717#undef TARGET_ATTRIBUTE_TABLE
5718#define TARGET_ATTRIBUTE_TABLE h8300_attribute_table
5719
5720#undef TARGET_ASM_ALIGNED_HI_OP
5721#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
5722
92c473b8 5723#undef TARGET_ASM_FILE_START
5724#define TARGET_ASM_FILE_START h8300_file_start
5725#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
5726#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
5727
9fb90c4e 5728#undef TARGET_ASM_FILE_END
5729#define TARGET_ASM_FILE_END h8300_file_end
5730
5731#undef TARGET_ENCODE_SECTION_INFO
5732#define TARGET_ENCODE_SECTION_INFO h8300_encode_section_info
5733
5734#undef TARGET_INSERT_ATTRIBUTES
5735#define TARGET_INSERT_ATTRIBUTES h8300_insert_attributes
5736
5737#undef TARGET_RTX_COSTS
5738#define TARGET_RTX_COSTS h8300_rtx_costs
5739
f2f543a3 5740#undef TARGET_INIT_LIBFUNCS
5741#define TARGET_INIT_LIBFUNCS h8300_init_libfuncs
5742
5c6c612a 5743#undef TARGET_RETURN_IN_MEMORY
5744#define TARGET_RETURN_IN_MEMORY h8300_return_in_memory
5745
727c62dd 5746#undef TARGET_MACHINE_DEPENDENT_REORG
5747#define TARGET_MACHINE_DEPENDENT_REORG h8300_reorg
5748
51136ff4 5749#undef TARGET_DEFAULT_TARGET_FLAGS
5750#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT
5751
9fb90c4e 5752struct gcc_target targetm = TARGET_INITIALIZER;