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