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