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