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