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