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