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