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