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