]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/h8300/h8300.c
* Makefile.in: Rebuilt.
[thirdparty/gcc.git] / gcc / config / h8300 / h8300.c
CommitLineData
e1629549 1/* Subroutines for insn-output.c for Hitachi H8/300.
f060a027 2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
45272a5b 3 Free Software Foundation, Inc.
b839e0b4 4 Contributed by Steve Chamberlain (sac@cygnus.com),
5 Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
e1629549 6
7This file is part of GNU CC.
8
9GNU CC is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2, or (at your option)
12any later version.
13
14GNU CC is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with GNU CC; see the file COPYING. If not, write to
b0603eb3 21the Free Software Foundation, 59 Temple Place - Suite 330,
22Boston, MA 02111-1307, USA. */
e1629549 23
e1629549 24#include "config.h"
7014838c 25#include "system.h"
e1629549 26#include "rtl.h"
4faf81b8 27#include "tree.h"
e1629549 28#include "regs.h"
29#include "hard-reg-set.h"
30#include "real.h"
31#include "insn-config.h"
32#include "conditions.h"
e1629549 33#include "output.h"
34#include "insn-attr.h"
35#include "flags.h"
36#include "recog.h"
37#include "expr.h"
4faf81b8 38#include "function.h"
9305fe33 39#include "toplev.h"
1fcd08b1 40#include "c-pragma.h"
9305fe33 41#include "tm_p.h"
f8870f17 42#include "ggc.h"
a767736d 43#include "target.h"
44#include "target-def.h"
e1629549 45
46/* Forward declarations. */
32bd1bda 47static int h8300_interrupt_function_p PARAMS ((tree));
48static int h8300_monitor_function_p PARAMS ((tree));
49static int h8300_os_task_function_p PARAMS ((tree));
50static void dosize PARAMS ((FILE *, const char *, unsigned int));
b1292c73 51static int round_frame_size PARAMS ((int));
52static unsigned int compute_saved_regs PARAMS ((void));
53static void push PARAMS ((FILE *, int));
54static void pop PARAMS ((FILE *, int));
32bd1bda 55static const char *cond_string PARAMS ((enum rtx_code));
e3c541f0 56const struct attribute_spec h8300_attribute_table[];
57static tree h8300_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
58static tree h8300_handle_eightbit_data_attribute PARAMS ((tree *, tree, tree, int, bool *));
59static tree h8300_handle_tiny_data_attribute PARAMS ((tree *, tree, tree, int, bool *));
17d9b0c3 60static void h8300_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
61static void h8300_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
29a0ebee 62static void h8300_asm_named_section PARAMS ((const char *, unsigned int));
b11bfc61 63
b839e0b4 64/* CPU_TYPE, says what cpu we're compiling for. */
65int cpu_type;
66
b11bfc61 67/* True if the current function is an interrupt handler
68 (either via #pragma or an attribute specification). */
69int interrupt_handler;
70
737a5d5b 71/* True if the current function is an OS Task
09c48b9c 72 (via an attribute specification). */
73int os_task;
74
75/* True if the current function is a monitor
76 (via an attribute specification). */
77int monitor;
e1629549 78
79/* True if a #pragma saveall has been seen for the current function. */
80int pragma_saveall;
81
9305fe33 82static const char *const names_big[] =
eb2aa24e 83{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" };
b839e0b4 84
9305fe33 85static const char *const names_extended[] =
eb2aa24e 86{ "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" };
b839e0b4 87
9305fe33 88static const char *const names_upper_extended[] =
eb2aa24e 89{ "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7" };
b839e0b4 90
91/* Points to one of the above. */
92/* ??? The above could be put in an array indexed by CPU_TYPE. */
9305fe33 93const char * const *h8_reg_names;
b839e0b4 94
95/* Various operations needed by the following, indexed by CPU_TYPE. */
b839e0b4 96
eb2aa24e 97static const char *const h8_push_ops[2] = { "push", "push.l" };
98static const char *const h8_pop_ops[2] = { "pop", "pop.l" };
99static const char *const h8_mov_ops[2] = { "mov.w", "mov.l" };
b839e0b4 100
9305fe33 101const char *h8_push_op, *h8_pop_op, *h8_mov_op;
a767736d 102\f
103/* Initialize the GCC target structure. */
e3c541f0 104#undef TARGET_ATTRIBUTE_TABLE
105#define TARGET_ATTRIBUTE_TABLE h8300_attribute_table
b839e0b4 106
17d9b0c3 107#undef TARGET_ASM_FUNCTION_PROLOGUE
108#define TARGET_ASM_FUNCTION_PROLOGUE h8300_output_function_prologue
109#undef TARGET_ASM_FUNCTION_EPILOGUE
110#define TARGET_ASM_FUNCTION_EPILOGUE h8300_output_function_epilogue
111
57e4bbfb 112struct gcc_target targetm = TARGET_INITIALIZER;
a767736d 113\f
b839e0b4 114/* Initialize various cpu specific globals at start up. */
115
116void
117h8300_init_once ()
118{
119 if (TARGET_H8300)
120 {
121 cpu_type = (int) CPU_H8300;
122 h8_reg_names = names_big;
123 }
124 else
125 {
b1292c73 126 /* For this we treat the H8/300H and H8/S the same. */
b839e0b4 127 cpu_type = (int) CPU_H8300H;
128 h8_reg_names = names_extended;
129 }
130 h8_push_op = h8_push_ops[cpu_type];
131 h8_pop_op = h8_pop_ops[cpu_type];
132 h8_mov_op = h8_mov_ops[cpu_type];
92d7ef92 133
134 if (!TARGET_H8300S && TARGET_MAC)
f060a027 135 {
136 error ("-ms2600 is used without -ms.");
137 target_flags |= 1;
138 }
b839e0b4 139}
e1629549 140
9305fe33 141const char *
e1629549 142byte_reg (x, b)
143 rtx x;
144 int b;
145{
9305fe33 146 static const char *const names_small[] =
b839e0b4 147 {"r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
92eae32b 148 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h"};
e1629549 149
150 return names_small[REGNO (x) * 2 + b];
151}
152
153/* REGNO must be saved/restored across calls if this macro is true. */
b839e0b4 154
155#define WORD_REG_USED(regno) \
3754a8bb 156 (regno < 7 \
eb2aa24e 157 /* No need to save registers if this function will not return. */\
3754a8bb 158 && ! TREE_THIS_VOLATILE (current_function_decl) \
159 && (pragma_saveall \
160 /* Save any call saved register that was used. */ \
161 || (regs_ever_live[regno] && !call_used_regs[regno]) \
162 /* Save the frame pointer if it was used. */ \
163 || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno])\
164 /* Save any register used in an interrupt handler. */ \
165 || (interrupt_handler && regs_ever_live[regno]) \
166 /* Save call clobbered registers in non-leaf interrupt \
167 handlers. */ \
168 || (interrupt_handler \
169 && call_used_regs[regno] \
170 && !current_function_is_leaf)))
e1629549 171
172/* Output assembly language to FILE for the operation OP with operand size
b839e0b4 173 SIZE to adjust the stack pointer. */
b839e0b4 174
e1629549 175static void
b9393aaf 176dosize (file, op, size)
e1629549 177 FILE *file;
9305fe33 178 const char *op;
e1629549 179 unsigned int size;
e1629549 180{
bfc1492f 181 /* On the H8/300H and H8/S, for sizes <= 8 bytes, it is as good or
182 better to use adds/subs insns rather than add.l/sub.l with an
183 immediate value.
184
185 Also, on the H8/300, if we don't have a temporary to hold the
186 size of the frame in the prologue, we simply emit a sequence of
187 subs since this shouldn't happen often. */
188 if ((TARGET_H8300 && size <= 4)
189 || ((TARGET_H8300H || TARGET_H8300S) && size <= 8)
190 || (TARGET_H8300 && current_function_needs_context
eded7a01 191 && ! strcmp (op, "sub")))
b9393aaf 192 {
53aec781 193 unsigned HOST_WIDE_INT amount;
b9393aaf 194
bfc1492f 195 /* Try different amounts in descending order. */
196 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
197 amount > 0;
198 amount /= 2)
c5eea78f 199 {
27276a3b 200 for (; size >= amount; size -= amount)
bfc1492f 201 fprintf (file, "\t%ss\t#%d,sp\n", op, amount);
c5eea78f 202 }
bfc1492f 203 }
204 else
205 {
b839e0b4 206 if (TARGET_H8300)
bfc1492f 207 fprintf (file, "\tmov.w\t#%d,r3\n\t%s.w\tr3,sp\n", size, op);
b839e0b4 208 else
bfc1492f 209 fprintf (file, "\t%s.l\t#%d,sp\n", op, size);
e1629549 210 }
211}
212
b1292c73 213/* Round up frame size SIZE. */
214
215static int
216round_frame_size (size)
217 int size;
218{
219 return (size + STACK_BOUNDARY / 8 - 1) & -STACK_BOUNDARY / 8;
220}
221
222/* Compute which registers to push/pop.
223 Return a bit vector of registers. */
224
225static unsigned int
226compute_saved_regs ()
227{
228 unsigned int saved_regs = 0;
229 int regno;
230
231 /* Construct a bit vector of registers to be pushed/popped. */
232 for (regno = 0; regno <= 6; regno++)
233 {
234 if (WORD_REG_USED (regno))
235 saved_regs |= 1 << regno;
236 }
237
238 /* Don't push/pop the frame pointer as it is treated separately. */
239 if (frame_pointer_needed)
240 saved_regs &= ~(1 << FRAME_POINTER_REGNUM);
241
242 return saved_regs;
243}
244
245/* Output assembly language code to push register RN. */
246
247static void
248push (file, rn)
249 FILE *file;
250 int rn;
251{
252 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[rn]);
253}
254
255/* Output assembly language code to pop register RN. */
256
257static void
258pop (file, rn)
259 FILE *file;
260 int rn;
261{
262 fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[rn]);
263}
e1629549 264
265/* This is what the stack looks like after the prolog of
266 a function with a frame has been set up:
267
b839e0b4 268 <args>
269 PC
270 FP <- fp
271 <locals>
272 <saved registers> <- sp
e1629549 273
274 This is what the stack looks like after the prolog of
275 a function which doesn't have a frame:
276
b839e0b4 277 <args>
278 PC
279 <locals>
280 <saved registers> <- sp
e1629549 281*/
282
b1292c73 283/* Output assembly language code for the function prologue. */
284
17d9b0c3 285static void
286h8300_output_function_prologue (file, size)
e1629549 287 FILE *file;
17d9b0c3 288 HOST_WIDE_INT size;
e1629549 289{
b1292c73 290 int fsize = round_frame_size (size);
e1629549 291 int idx;
b1292c73 292 int saved_regs;
97709d8d 293 int n_regs;
e1629549 294
0d37f3a1 295 /* Note a function with the interrupt attribute and set interrupt_handler
296 accordingly. */
b11bfc61 297 if (h8300_interrupt_function_p (current_function_decl))
298 interrupt_handler = 1;
299
09c48b9c 300 /* If the current function has the OS_Task attribute set, then
301 we have a naked prologue. */
302 if (h8300_os_task_function_p (current_function_decl))
303 {
304 fprintf (file, ";OS_Task prologue\n");
305 os_task = 1;
306 return;
307 }
308
309 if (h8300_monitor_function_p (current_function_decl))
310 {
311 /* My understanding of monitor functions is they act just
312 like interrupt functions, except the prologue must
313 mask interrupts. */
314 fprintf (file, ";monitor prologue\n");
315 interrupt_handler = 1;
316 monitor = 1;
0cce0c62 317 if (TARGET_H8300)
318 {
319 fprintf (file, "\tsubs\t#2,sp\n");
b1292c73 320 push (file, 0);
0cce0c62 321 fprintf (file, "\tstc\tccr,r0l\n");
e327b148 322 fprintf (file, "\tmov.b\tr0l,@(2,sp)\n");
323 pop (file, 0);
0cce0c62 324 fprintf (file, "\torc\t#128,ccr\n");
e327b148 325 }
326 else if (TARGET_H8300H)
327 {
328 push (file, 0);
329 fprintf (file, "\tstc\tccr,r0l\n");
0cce0c62 330 fprintf (file, "\tmov.b\tr0l,@(4,sp)\n");
e327b148 331 pop (file, 0);
332 fprintf (file, "\torc\t#128,ccr\n");
0cce0c62 333 }
e327b148 334 else if (TARGET_H8300S)
0cce0c62 335 {
e327b148 336 fprintf (file, "\tstc\texr,@-sp\n");
b1292c73 337 push (file, 0);
0cce0c62 338 fprintf (file, "\tstc\tccr,r0l\n");
e327b148 339 fprintf (file, "\tmov.b\tr0l,@(6,sp)\n");
340 pop (file, 0);
0cce0c62 341 fprintf (file, "\torc\t#128,ccr\n");
0cce0c62 342 }
e327b148 343 else
344 abort ();
09c48b9c 345 }
346
b839e0b4 347 if (frame_pointer_needed)
348 {
eb2aa24e 349 /* Push fp. */
b1292c73 350 push (file, FRAME_POINTER_REGNUM);
b839e0b4 351 fprintf (file, "\t%s\t%s,%s\n", h8_mov_op,
352 h8_reg_names[STACK_POINTER_REGNUM],
353 h8_reg_names[FRAME_POINTER_REGNUM]);
69b4e418 354 }
b839e0b4 355
eb2aa24e 356 /* Leave room for locals. */
69b4e418 357 dosize (file, "sub", fsize);
e1629549 358
b1292c73 359 /* Push the rest of the registers in ascending order. */
360 saved_regs = compute_saved_regs ();
97709d8d 361 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx += n_regs)
362 {
b1292c73 363 int regno = idx;
97709d8d 364
365 n_regs = 1;
b1292c73 366 if (saved_regs & (1 << regno))
69b4e418 367 {
368 if (TARGET_H8300S)
369 {
97709d8d 370 /* See how many registers we can push at the same time. */
371 if ((regno == 0 || regno == 4)
b1292c73 372 && ((saved_regs >> regno) & 0x0f) == 0x0f)
97709d8d 373 n_regs = 4;
374
375 else if ((regno == 0 || regno == 4)
b1292c73 376 && ((saved_regs >> regno) & 0x07) == 0x07)
97709d8d 377 n_regs = 3;
378
379 else if ((regno == 0 || regno == 2 || regno == 4 || regno == 6)
b1292c73 380 && ((saved_regs >> regno) & 0x03) == 0x03)
97709d8d 381 n_regs = 2;
69b4e418 382 }
97709d8d 383
384 if (n_regs == 1)
b1292c73 385 push (file, regno);
97709d8d 386 else
387 fprintf (file, "\tstm.l\t%s-%s,@-sp\n",
388 h8_reg_names[regno],
389 h8_reg_names[regno + (n_regs - 1)]);
e1629549 390 }
391 }
392}
393
394/* Output assembly language code for the function epilogue. */
395
17d9b0c3 396static void
397h8300_output_function_epilogue (file, size)
e1629549 398 FILE *file;
17d9b0c3 399 HOST_WIDE_INT size;
e1629549 400{
b1292c73 401 int fsize = round_frame_size (size);
e1629549 402 int idx;
403 rtx insn = get_last_insn ();
b1292c73 404 int saved_regs;
97709d8d 405 int n_regs;
e1629549 406
09c48b9c 407 if (os_task)
408 {
409 /* OS_Task epilogues are nearly naked -- they just have an
410 rts instruction. */
411 fprintf (file, ";OS_task epilogue\n");
412 fprintf (file, "\trts\n");
413 goto out;
414 }
415
eb2aa24e 416 /* Monitor epilogues are the same as interrupt function epilogues.
09c48b9c 417 Just make a note that we're in an monitor epilogue. */
418 if (monitor)
eb2aa24e 419 fprintf (file, ";monitor epilogue\n");
09c48b9c 420
e1629549 421 /* If the last insn was a BARRIER, we don't have to write any code. */
422 if (GET_CODE (insn) == NOTE)
423 insn = prev_nonnote_insn (insn);
424 if (insn && GET_CODE (insn) == BARRIER)
b57f4a50 425 goto out;
e1629549 426
b1292c73 427 /* Pop the saved registers in descending order. */
428 saved_regs = compute_saved_regs ();
97709d8d 429 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx += n_regs)
430 {
b1292c73 431 int regno = (FIRST_PSEUDO_REGISTER - 1) - idx;
97709d8d 432
433 n_regs = 1;
b1292c73 434 if (saved_regs & (1 << regno))
e1629549 435 {
69b4e418 436 if (TARGET_H8300S)
437 {
97709d8d 438 /* See how many registers we can pop at the same time. */
439 if ((regno == 7 || regno == 3)
b1292c73 440 && ((saved_regs >> (regno - 3)) & 0x0f) == 0x0f)
97709d8d 441 n_regs = 4;
442
443 else if ((regno == 6 || regno == 2)
b1292c73 444 && ((saved_regs >> (regno - 2)) & 0x07) == 0x07)
97709d8d 445 n_regs = 3;
446
447 else if ((regno == 7 || regno == 5 || regno == 3 || regno == 1)
b1292c73 448 && ((saved_regs >> (regno - 1)) & 0x03) == 0x03)
97709d8d 449 n_regs = 2;
69b4e418 450 }
97709d8d 451
452 if (n_regs == 1)
b1292c73 453 pop (file, regno);
97709d8d 454 else
455 fprintf (file, "\tldm.l\t@sp+,%s-%s\n",
456 h8_reg_names[regno - (n_regs - 1)],
457 h8_reg_names[regno]);
e1629549 458 }
e1629549 459 }
b839e0b4 460
eb2aa24e 461 /* Deallocate locals. */
69b4e418 462 dosize (file, "add", fsize);
463
eb2aa24e 464 /* Pop frame pointer if we had one. */
69b4e418 465 if (frame_pointer_needed)
b1292c73 466 pop (file, FRAME_POINTER_REGNUM);
69b4e418 467
0d37f3a1 468 if (interrupt_handler)
469 fprintf (file, "\trte\n");
e1629549 470 else
0d37f3a1 471 fprintf (file, "\trts\n");
e1629549 472
eb2aa24e 473 out:
b11bfc61 474 interrupt_handler = 0;
09c48b9c 475 os_task = 0;
476 monitor = 0;
e1629549 477 pragma_saveall = 0;
b839e0b4 478}
479
480/* Output assembly code for the start of the file. */
481
9305fe33 482void
b839e0b4 483asm_file_start (file)
484 FILE *file;
485{
486 fprintf (file, ";\tGCC For the Hitachi H8/300\n");
487 fprintf (file, ";\tBy Hitachi America Ltd and Cygnus Support\n");
b839e0b4 488 if (optimize)
489 fprintf (file, "; -O%d\n", optimize);
490 if (TARGET_H8300H)
491 fprintf (file, "\n\t.h8300h\n");
69b4e418 492 else if (TARGET_H8300S)
493 fprintf (file, "\n\t.h8300s\n");
b839e0b4 494 else
495 fprintf (file, "\n\n");
496 output_file_directive (file, main_input_filename);
497}
498
499/* Output assembly language code for the end of file. */
500
501void
502asm_file_end (file)
503 FILE *file;
504{
505 fprintf (file, "\t.end\n");
e1629549 506}
507\f
b839e0b4 508/* Return true if VALUE is a valid constant for constraint 'P'.
509 IE: VALUE is a power of two <= 2**15. */
e1629549 510
511int
b839e0b4 512small_power_of_two (value)
8e7d5182 513 HOST_WIDE_INT value;
e1629549 514{
8e7d5182 515 int power = exact_log2 (value);
516 return power >= 0 && power <= 15;
e1629549 517}
518
b839e0b4 519/* Return true if VALUE is a valid constant for constraint 'O', which
520 means that the constant would be ok to use as a bit for a bclr
521 instruction. */
522
523int
524ok_for_bclr (value)
8e7d5182 525 HOST_WIDE_INT value;
b839e0b4 526{
527 return small_power_of_two ((~value) & 0xff);
528}
529
f39dbbab 530/* Return true if OP is a valid source operand for an integer move
e1629549 531 instruction. */
b839e0b4 532
e1629549 533int
534general_operand_src (op, mode)
535 rtx op;
536 enum machine_mode mode;
537{
b839e0b4 538 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
539 return 1;
e1629549 540 return general_operand (op, mode);
541}
542
543/* Return true if OP is a valid destination operand for an integer move
10b87dba 544 instruction. */
b839e0b4 545
e1629549 546int
547general_operand_dst (op, mode)
548 rtx op;
549 enum machine_mode mode;
550{
b839e0b4 551 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == PRE_DEC)
552 return 1;
e1629549 553 return general_operand (op, mode);
554}
b839e0b4 555
556/* Return true if OP is a const valid for a bit clear instruction. */
557
558int
559o_operand (operand, mode)
560 rtx operand;
9305fe33 561 enum machine_mode mode ATTRIBUTE_UNUSED;
b839e0b4 562{
563 return (GET_CODE (operand) == CONST_INT
564 && CONST_OK_FOR_O (INTVAL (operand)));
565}
566
567/* Return true if OP is a const valid for a bit set or bit xor instruction. */
568
569int
570p_operand (operand, mode)
571 rtx operand;
9305fe33 572 enum machine_mode mode ATTRIBUTE_UNUSED;
b839e0b4 573{
574 return (GET_CODE (operand) == CONST_INT
575 && CONST_OK_FOR_P (INTVAL (operand)));
576}
577
578/* Return true if OP is a valid call operand. */
579
580int
581call_insn_operand (op, mode)
582 rtx op;
9305fe33 583 enum machine_mode mode ATTRIBUTE_UNUSED;
b839e0b4 584{
585 if (GET_CODE (op) == MEM)
586 {
587 rtx inside = XEXP (op, 0);
588 if (register_operand (inside, Pmode))
589 return 1;
590 if (CONSTANT_ADDRESS_P (inside))
591 return 1;
592 }
593 return 0;
594}
595
9c068f13 596/* Return 1 if an addition/subtraction of a constant integer can be
3c4d0c20 597 transformed into two consecutive adds/subs that are faster than the
9c068f13 598 straightforward way. Otherwise, return 0. */
3c4d0c20 599
0a56558f 600int
8e7d5182 601two_insn_adds_subs_operand (op, mode)
0a56558f 602 rtx op;
3c4d0c20 603 enum machine_mode mode;
0a56558f 604{
605 if (GET_CODE (op) == CONST_INT)
606 {
8e7d5182 607 HOST_WIDE_INT value = INTVAL (op);
0a56558f 608
3c4d0c20 609 /* Force VALUE to be positive so that we do not have to consider
610 the negative case. */
611 if (value < 0)
612 value = -value;
8e7d5182 613 if (TARGET_H8300H || TARGET_H8300S)
614 {
3c4d0c20 615 /* A constant addition/subtraction takes 2 states in QImode,
616 4 states in HImode, and 6 states in SImode. Thus, the
617 only case we can win is when SImode is used, in which
0c2bee79 618 case, two adds/subs are used, taking 4 states. */
3c4d0c20 619 if (mode == SImode
620 && (value == 2 + 1
621 || value == 4 + 1
622 || value == 4 + 2
623 || value == 4 + 4))
9c068f13 624 return 1;
8e7d5182 625 }
626 else
627 {
3c4d0c20 628 /* A constant addition/subtraction takes 2 states in
629 QImode. It takes 6 states in HImode, requiring the
630 constant to be loaded to a register first, and a lot more
631 in SImode. Thus the only case we can win is when either
632 HImode or SImode is used. */
633 if (mode != QImode
634 && (value == 2 + 1
635 || value == 2 + 2))
8e7d5182 636 return 1;
637 }
638 }
fe19f1e0 639
fe19f1e0 640 return 0;
641}
642
8e7d5182 643/* Split an add of a small constant into two adds/subs insns. */
644
645void
646split_adds_subs (mode, operands)
647 enum machine_mode mode;
0a56558f 648 rtx *operands;
649{
8e7d5182 650 HOST_WIDE_INT val = INTVAL (operands[1]);
651 rtx reg = operands[0];
d8afbfc6 652 HOST_WIDE_INT sign = 1;
653 HOST_WIDE_INT amount;
0a56558f 654
d8afbfc6 655 /* Force VAL to be positive so that we do not have to consider the
656 sign. */
657 if (val < 0)
0a56558f 658 {
d8afbfc6 659 val = -val;
660 sign = -1;
661 }
0a56558f 662
d8afbfc6 663 /* Try different amounts in descending order. */
664 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
665 amount > 0;
666 amount /= 2)
667 {
27276a3b 668 for (; val >= amount; val -= amount)
8e7d5182 669 {
d8afbfc6 670 rtx tmp = gen_rtx_PLUS (mode, reg, GEN_INT (sign * amount));
8e7d5182 671 emit_insn (gen_rtx_SET (VOIDmode, reg, tmp));
8e7d5182 672 }
0a56558f 673 }
674
d8afbfc6 675 return;
0a56558f 676}
677
b11bfc61 678/* Return true if OP is a valid call operand, and OP represents
679 an operand for a small call (4 bytes instead of 6 bytes). */
680
681int
682small_call_insn_operand (op, mode)
683 rtx op;
9305fe33 684 enum machine_mode mode ATTRIBUTE_UNUSED;
b11bfc61 685{
686 if (GET_CODE (op) == MEM)
687 {
688 rtx inside = XEXP (op, 0);
689
690 /* Register indirect is a small call. */
691 if (register_operand (inside, Pmode))
692 return 1;
693
694 /* A call through the function vector is a small
695 call too. */
696 if (GET_CODE (inside) == SYMBOL_REF
697 && SYMBOL_REF_FLAG (inside))
698 return 1;
699 }
700 /* Otherwise it's a large call. */
701 return 0;
702}
703
b839e0b4 704/* Return true if OP is a valid jump operand. */
705
706int
707jump_address_operand (op, mode)
708 rtx op;
709 enum machine_mode mode;
710{
711 if (GET_CODE (op) == REG)
712 return mode == Pmode;
713
714 if (GET_CODE (op) == MEM)
715 {
716 rtx inside = XEXP (op, 0);
717 if (register_operand (inside, Pmode))
718 return 1;
719 if (CONSTANT_ADDRESS_P (inside))
720 return 1;
721 }
722 return 0;
723}
724
725/* Recognize valid operands for bitfield instructions. */
726
727extern int rtx_equal_function_value_matters;
728
729int
730bit_operand (op, mode)
731 rtx op;
732 enum machine_mode mode;
733{
734 /* We can except any general operand, expept that MEM operands must
735 be limited to those that use addresses valid for the 'U' constraint. */
736 if (!general_operand (op, mode))
737 return 0;
738
739 /* Accept any mem during RTL generation. Otherwise, the code that does
740 insv and extzv will think that we can not handle memory. However,
741 to avoid reload problems, we only accept 'U' MEM operands after RTL
742 generation. This means that any named pattern which uses this predicate
743 must force its operands to match 'U' before emitting RTL. */
744
745 if (GET_CODE (op) == REG)
746 return 1;
747 if (GET_CODE (op) == SUBREG)
748 return 1;
749 if (!rtx_equal_function_value_matters)
eb2aa24e 750 /* We're building rtl. */
751 return GET_CODE (op) == MEM;
b839e0b4 752 else
eb2aa24e 753 return (GET_CODE (op) == MEM
754 && EXTRA_CONSTRAINT (op, 'U'));
b839e0b4 755}
756
27a0be8f 757int
758bit_memory_operand (op, mode)
759 rtx op;
9305fe33 760 enum machine_mode mode ATTRIBUTE_UNUSED;
27a0be8f 761{
762 return (GET_CODE (op) == MEM
763 && EXTRA_CONSTRAINT (op, 'U'));
764}
765
b839e0b4 766/* Recognize valid operators for bit test. */
767
768int
769eq_operator (x, mode)
770 rtx x;
9305fe33 771 enum machine_mode mode ATTRIBUTE_UNUSED;
b839e0b4 772{
773 return (GET_CODE (x) == EQ || GET_CODE (x) == NE);
774}
775
e1629549 776/* Handle machine specific pragmas for compatibility with existing
b839e0b4 777 compilers for the H8/300.
e1629549 778
779 pragma saveall generates prolog/epilog code which saves and
780 restores all the registers on function entry.
b839e0b4 781
e1629549 782 pragma interrupt saves and restores all registers, and exits with
783 an rte instruction rather than an rts. A pointer to a function
784 with this attribute may be safely used in an interrupt vector. */
b839e0b4 785
1fcd08b1 786void
787h8300_pr_interrupt (pfile)
788 cpp_reader *pfile ATTRIBUTE_UNUSED;
e1629549 789{
1fcd08b1 790 interrupt_handler = 1;
791}
b97b38c0 792
1fcd08b1 793void
794h8300_pr_saveall (pfile)
795 cpp_reader *pfile ATTRIBUTE_UNUSED;
796{
797 pragma_saveall = 1;
e1629549 798}
1fcd08b1 799
e1629549 800/* If the next arg with MODE and TYPE is to be passed in a register, return
801 the rtx to represent where it is passed. CUM represents the state after
802 the last argument. NAMED is not used. */
803
9305fe33 804static const char *const hand_list[] =
b839e0b4 805{
806 "__main",
807 "__cmpsi2",
808 "__divhi3",
809 "__modhi3",
810 "__udivhi3",
811 "__umodhi3",
812 "__divsi3",
813 "__modsi3",
814 "__udivsi3",
815 "__umodsi3",
816 "__mulhi3",
817 "__mulsi3",
818 "__reg_memcpy",
819 "__reg_memset",
820 "__ucmpsi2",
821 0,
822};
823
824/* Return an RTX to represent where a value with mode MODE will be returned
825 from a function. If the result is 0, the argument is pushed. */
826
e1629549 827rtx
828function_arg (cum, mode, type, named)
829 CUMULATIVE_ARGS *cum;
830 enum machine_mode mode;
831 tree type;
832 int named;
833{
834 rtx result = 0;
9305fe33 835 const char *fname;
b839e0b4 836 int regpass = 0;
837
0d37f3a1 838 /* Never pass unnamed arguments in registers. */
839 if (!named)
840 return 0;
841
b839e0b4 842 /* Pass 3 regs worth of data in regs when user asked on the command line. */
843 if (TARGET_QUICKCALL)
844 regpass = 3;
845
846 /* If calling hand written assembler, use 4 regs of args. */
847
848 if (cum->libcall)
849 {
9305fe33 850 const char * const *p;
b839e0b4 851
852 fname = XSTR (cum->libcall, 0);
853
854 /* See if this libcall is one of the hand coded ones. */
e1629549 855
b839e0b4 856 for (p = hand_list; *p && strcmp (*p, fname) != 0; p++)
857 ;
e1629549 858
b839e0b4 859 if (*p)
860 regpass = 4;
861 }
862
863 if (regpass)
864 {
865 int size;
866
867 if (mode == BLKmode)
868 size = int_size_in_bytes (type);
869 else
870 size = GET_MODE_SIZE (mode);
871
872 if (size + cum->nbytes > regpass * UNITS_PER_WORD)
873 {
874 result = 0;
875 }
876 else
877 {
878 switch (cum->nbytes / UNITS_PER_WORD)
879 {
880 case 0:
7014838c 881 result = gen_rtx_REG (mode, 0);
b839e0b4 882 break;
883 case 1:
7014838c 884 result = gen_rtx_REG (mode, 1);
b839e0b4 885 break;
886 case 2:
7014838c 887 result = gen_rtx_REG (mode, 2);
b839e0b4 888 break;
889 case 3:
7014838c 890 result = gen_rtx_REG (mode, 3);
b839e0b4 891 break;
892 default:
893 result = 0;
894 }
895 }
896 }
e1629549 897
b839e0b4 898 return result;
899}
900\f
901/* Return the cost of the rtx R with code CODE. */
e1629549 902
b839e0b4 903int
904const_costs (r, c)
905 rtx r;
906 enum rtx_code c;
907{
908 switch (c)
e1629549 909 {
b839e0b4 910 case CONST_INT:
911 switch (INTVAL (r))
e1629549 912 {
913 case 0:
b839e0b4 914 case 1:
e1629549 915 case 2:
b839e0b4 916 case -1:
917 case -2:
e1629549 918 return 0;
9d3a9c4d 919 case 4:
920 case -4:
69b4e418 921 if (TARGET_H8300H || TARGET_H8300S)
9d3a9c4d 922 return 0;
923 else
924 return 1;
b839e0b4 925 default:
926 return 1;
e1629549 927 }
b839e0b4 928
929 case CONST:
930 case LABEL_REF:
931 case SYMBOL_REF:
932 return 3;
933
934 case CONST_DOUBLE:
935 return 20;
936
937 default:
938 return 4;
e1629549 939 }
e1629549 940}
b839e0b4 941\f
e1629549 942/* Documentation for the machine specific operand escapes:
943
734f720f 944 'A' print rn in H8/300 mode, erN in H8/300H mode
e1629549 945 'C' print (operand - 2).
b839e0b4 946 'E' like s but negative.
947 'F' like t but negative.
948 'G' constant just the negative
e1629549 949 'M' turn a 'M' constant into its negative mod 2.
b839e0b4 950 'P' if operand is incing/decing sp, print .w, otherwise .b.
2c7be643 951 'R' print operand as a byte:8 address if appropriate, else fall back to
952 'X' handling.
b839e0b4 953 'S' print operand as a long word
e1629549 954 'T' print operand as a word
b839e0b4 955 'U' if operand is incing/decing sp, print l, otherwise nothing.
956 'V' find the set bit, and print its number.
957 'W' find the clear bit, and print its number.
958 'X' print operand as a byte
e1629549 959 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
2c7be643 960 If this operand isn't a register, fall back to 'R' handling.
b839e0b4 961 'Z' print int & 7.
962 'b' print the bit opcode
963 'c' print the ibit opcode
964 'd' bcc if EQ, bcs if NE
965 'e' first word of 32 bit value - if reg, then least reg. if mem
966 then least. if const then most sig word
967 'f' second word of 32 bit value - if reg, then biggest reg. if mem
968 then +2. if const then least sig word
969 'g' bcs if EQ, bcc if NE
e1629549 970 'j' print operand as condition code.
971 'k' print operand as reverse condition code.
b839e0b4 972 's' print as low byte of 16 bit value
973 't' print as high byte of 16 bit value
974 'w' print as low byte of 32 bit value
975 'x' print as 2nd byte of 32 bit value
976 'y' print as 3rd byte of 32 bit value
977 'z' print as msb of 32 bit value
978*/
e1629549 979
980/* Return assembly language string which identifies a comparison type. */
981
9305fe33 982static const char *
e1629549 983cond_string (code)
984 enum rtx_code code;
985{
986 switch (code)
987 {
988 case NE:
989 return "ne";
990 case EQ:
991 return "eq";
992 case GE:
993 return "ge";
994 case GT:
995 return "gt";
996 case LE:
997 return "le";
998 case LT:
999 return "lt";
1000 case GEU:
1001 return "hs";
1002 case GTU:
1003 return "hi";
1004 case LEU:
1005 return "ls";
1006 case LTU:
1007 return "lo";
1008 default:
1009 abort ();
1010 }
1011}
1012
1013/* Print operand X using operand code CODE to assembly language output file
1014 FILE. */
1015
1016void
1017print_operand (file, x, code)
1018 FILE *file;
1019 rtx x;
1020 int code;
1021{
e1629549 1022 /* This is used for communication between the 'P' and 'U' codes. */
9305fe33 1023 static const char *last_p;
e1629549 1024
30c992ef 1025 /* This is used for communication between codes V,W,Z and Y. */
e1629549 1026 static int bitint;
1027
1028 switch (code)
1029 {
b839e0b4 1030 case 'A':
e1629549 1031 if (GET_CODE (x) == REG)
b839e0b4 1032 fprintf (file, "%s", h8_reg_names[REGNO (x)]);
e1629549 1033 else
1034 goto def;
1035 break;
b839e0b4 1036 case 'C':
1037 fprintf (file, "#%d", INTVAL (x) - 2);
1038 break;
1039 case 'E':
1040 switch (GET_CODE (x))
1041 {
1042 case REG:
1043 fprintf (file, "%sl", names_big[REGNO (x)]);
1044 break;
1045 case CONST_INT:
1046 fprintf (file, "#%d", (-INTVAL (x)) & 0xff);
1047 break;
1048 default:
1049 abort ();
1050 }
1051 break;
1052 case 'F':
1053 switch (GET_CODE (x))
1054 {
1055 case REG:
1056 fprintf (file, "%sh", names_big[REGNO (x)]);
1057 break;
1058 case CONST_INT:
1059 fprintf (file, "#%d", ((-INTVAL (x)) & 0xff00) >> 8);
1060 break;
1061 default:
1062 abort ();
1063 }
1064 break;
e1629549 1065 case 'G':
1066 if (GET_CODE (x) != CONST_INT)
1067 abort ();
1068 fprintf (file, "#%d", 0xff & (-INTVAL (x)));
1069 break;
b839e0b4 1070 case 'M':
1071 /* For 3/-3 and 4/-4, the other 2 is handled separately. */
1072 switch (INTVAL (x))
1073 {
1074 case 2:
1075 case 4:
1076 case -2:
1077 case -4:
1078 fprintf (file, "#2");
1079 break;
1080 case 1:
1081 case 3:
1082 case -1:
1083 case -3:
1084 fprintf (file, "#1");
1085 break;
1086 default:
1087 abort ();
1088 }
e1629549 1089 break;
b839e0b4 1090 case 'P':
1091 if (REGNO (XEXP (XEXP (x, 0), 0)) == STACK_POINTER_REGNUM)
1092 {
1093 last_p = "";
1094 fprintf (file, ".w");
1095 }
e1629549 1096 else
b839e0b4 1097 {
1098 last_p = "l";
1099 fprintf (file, ".b");
1100 }
e1629549 1101 break;
b839e0b4 1102 case 'S':
1103 if (GET_CODE (x) == REG)
1104 fprintf (file, "%s", names_extended[REGNO (x)]);
e1629549 1105 else
b839e0b4 1106 goto def;
e1629549 1107 break;
b839e0b4 1108 case 'T':
1109 if (GET_CODE (x) == REG)
1110 fprintf (file, "%s", names_big[REGNO (x)]);
e1629549 1111 else
b839e0b4 1112 goto def;
e1629549 1113 break;
b839e0b4 1114 case 'U':
1115 fprintf (file, "%s%s", names_big[REGNO (x)], last_p);
e1629549 1116 break;
b839e0b4 1117 case 'V':
1118 bitint = exact_log2 (INTVAL (x));
1119 if (bitint == -1)
e1629549 1120 abort ();
e1629549 1121 fprintf (file, "#%d", bitint & 7);
1122 break;
b839e0b4 1123 case 'W':
e1629549 1124 bitint = exact_log2 ((~INTVAL (x)) & 0xff);
1125 if (bitint == -1)
1126 abort ();
1127 fprintf (file, "#%d", bitint & 7);
1128 break;
2c7be643 1129 case 'R':
b839e0b4 1130 case 'X':
1131 if (GET_CODE (x) == REG)
1132 fprintf (file, "%s", byte_reg (x, 0));
1133 else
1134 goto def;
1135 break;
1136 case 'Y':
e1629549 1137 if (bitint == -1)
1138 abort ();
b839e0b4 1139 if (GET_CODE (x) == REG)
1140 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
1141 else
2c7be643 1142 print_operand (file, x, 'R');
b839e0b4 1143 bitint = -1;
1144 break;
1145 case 'Z':
1146 bitint = INTVAL (x);
e1629549 1147 fprintf (file, "#%d", bitint & 7);
1148 break;
b839e0b4 1149 case 'b':
1150 switch (GET_CODE (x))
e1629549 1151 {
b839e0b4 1152 case IOR:
1153 fprintf (file, "bor");
1154 break;
1155 case XOR:
1156 fprintf (file, "bxor");
1157 break;
1158 case AND:
1159 fprintf (file, "band");
1160 break;
9305fe33 1161 default:
1162 break;
e1629549 1163 }
b839e0b4 1164 break;
1165 case 'c':
1166 switch (GET_CODE (x))
e1629549 1167 {
b839e0b4 1168 case IOR:
1169 fprintf (file, "bior");
1170 break;
1171 case XOR:
1172 fprintf (file, "bixor");
1173 break;
1174 case AND:
1175 fprintf (file, "biand");
1176 break;
9305fe33 1177 default:
1178 break;
e1629549 1179 }
1180 break;
b839e0b4 1181 case 'd':
1182 switch (GET_CODE (x))
e1629549 1183 {
b839e0b4 1184 case EQ:
1185 fprintf (file, "bcc");
e1629549 1186 break;
b839e0b4 1187 case NE:
1188 fprintf (file, "bcs");
e1629549 1189 break;
e1629549 1190 default:
1191 abort ();
1192 }
1193 break;
e1629549 1194 case 'e':
1195 switch (GET_CODE (x))
1196 {
1197 case REG:
b839e0b4 1198 if (TARGET_H8300)
1199 fprintf (file, "%s", names_big[REGNO (x)]);
1200 else
1201 fprintf (file, "%s", names_upper_extended[REGNO (x)]);
e1629549 1202 break;
1203 case MEM:
e1629549 1204 print_operand (file, x, 0);
1205 break;
1206 case CONST_INT:
1207 fprintf (file, "#%d", ((INTVAL (x) >> 16) & 0xffff));
1208 break;
737a5d5b 1209 case CONST_DOUBLE:
1210 {
1211 long val;
1212 REAL_VALUE_TYPE rv;
1213 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1214 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
9305fe33 1215 fprintf (file, "#%ld", ((val >> 16) & 0xffff));
737a5d5b 1216 break;
1217 }
e1629549 1218 default:
1219 abort ();
1220 break;
1221 }
1222 break;
e1629549 1223 case 'f':
1224 switch (GET_CODE (x))
1225 {
1226 case REG:
b839e0b4 1227 if (TARGET_H8300)
1228 fprintf (file, "%s", names_big[REGNO (x) + 1]);
1229 else
1230 fprintf (file, "%s", names_big[REGNO (x)]);
e1629549 1231 break;
e1629549 1232 case MEM:
eafc6604 1233 x = adjust_address (x, HImode, 2);
e1629549 1234 print_operand (file, x, 0);
1235 break;
e1629549 1236 case CONST_INT:
1237 fprintf (file, "#%d", INTVAL (x) & 0xffff);
1238 break;
737a5d5b 1239 case CONST_DOUBLE:
1240 {
1241 long val;
1242 REAL_VALUE_TYPE rv;
1243 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1244 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
9305fe33 1245 fprintf (file, "#%ld", (val & 0xffff));
737a5d5b 1246 break;
1247 }
e1629549 1248 default:
1249 abort ();
1250 }
1251 break;
b839e0b4 1252 case 'g':
e1629549 1253 switch (GET_CODE (x))
1254 {
b839e0b4 1255 case NE:
1256 fprintf (file, "bcc");
e1629549 1257 break;
b839e0b4 1258 case EQ:
1259 fprintf (file, "bcs");
e1629549 1260 break;
e1629549 1261 default:
1262 abort ();
1263 }
1264 break;
e1629549 1265 case 'j':
1266 asm_fprintf (file, cond_string (GET_CODE (x)));
1267 break;
e1629549 1268 case 'k':
1269 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
1270 break;
b839e0b4 1271 case 's':
1272 if (GET_CODE (x) == CONST_INT)
1273 fprintf (file, "#%d", (INTVAL (x)) & 0xff);
1274 else
1275 fprintf (file, "%s", byte_reg (x, 0));
1276 break;
1277 case 't':
1278 if (GET_CODE (x) == CONST_INT)
1279 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1280 else
1281 fprintf (file, "%s", byte_reg (x, 1));
1282 break;
1283 case 'u':
1284 if (GET_CODE (x) != CONST_INT)
1285 abort ();
1286 fprintf (file, "%d", INTVAL (x));
1287 break;
1288 case 'w':
1289 if (GET_CODE (x) == CONST_INT)
1290 fprintf (file, "#%d", INTVAL (x) & 0xff);
1291 else
69b4e418 1292 fprintf (file, "%s",
1293 byte_reg (x, TARGET_H8300 ? 2 : 0));
b839e0b4 1294 break;
1295 case 'x':
1296 if (GET_CODE (x) == CONST_INT)
1297 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1298 else
69b4e418 1299 fprintf (file, "%s",
1300 byte_reg (x, TARGET_H8300 ? 3 : 1));
b839e0b4 1301 break;
1302 case 'y':
1303 if (GET_CODE (x) == CONST_INT)
1304 fprintf (file, "#%d", (INTVAL (x) >> 16) & 0xff);
1305 else
1306 fprintf (file, "%s", byte_reg (x, 0));
1307 break;
1308 case 'z':
1309 if (GET_CODE (x) == CONST_INT)
1310 fprintf (file, "#%d", (INTVAL (x) >> 24) & 0xff);
1311 else
1312 fprintf (file, "%s", byte_reg (x, 1));
1313 break;
1314
e1629549 1315 default:
b839e0b4 1316 def:
e1629549 1317 switch (GET_CODE (x))
1318 {
1319 case REG:
b839e0b4 1320 switch (GET_MODE (x))
1321 {
1322 case QImode:
30c992ef 1323#if 0 /* Is it asm ("mov.b %0,r2l", ...) */
b839e0b4 1324 fprintf (file, "%s", byte_reg (x, 0));
1325#else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1326 fprintf (file, "%s", names_big[REGNO (x)]);
1327#endif
1328 break;
1329 case HImode:
1330 fprintf (file, "%s", names_big[REGNO (x)]);
1331 break;
1332 case SImode:
5d369cd7 1333 case SFmode:
b839e0b4 1334 fprintf (file, "%s", names_extended[REGNO (x)]);
1335 break;
1336 default:
1337 abort ();
1338 }
e1629549 1339 break;
1340
1341 case MEM:
1342 fprintf (file, "@");
1343 output_address (XEXP (x, 0));
2c7be643 1344
d6ea8179 1345 /* If this is an 'R' operand (reference into the 8-bit
1346 area), then specify a symbolic address as "foo:8",
1347 otherwise if operand is still in eight bit section, use
1348 "foo:16". */
eb2aa24e 1349 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
2c7be643 1350 && SYMBOL_REF_FLAG (XEXP (x, 0)))
d6ea8179 1351 fprintf (file, (code == 'R' ? ":8" : ":16"));
1352 else if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
eb2aa24e 1353 && TINY_DATA_NAME_P (XSTR (XEXP (x, 0), 0)))
27a0be8f 1354 fprintf (file, ":16");
ea04e431 1355 else if ((code == 'R')
1356 && EIGHTBIT_CONSTANT_ADDRESS_P (XEXP (x, 0)))
1357 fprintf (file, ":8");
e1629549 1358 break;
1359
1360 case CONST_INT:
1361 case SYMBOL_REF:
1362 case CONST:
1363 case LABEL_REF:
1364 fprintf (file, "#");
1365 print_operand_address (file, x);
1366 break;
737a5d5b 1367 case CONST_DOUBLE:
1368 {
1369 long val;
1370 REAL_VALUE_TYPE rv;
1371 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1372 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
9305fe33 1373 fprintf (file, "#%ld", val);
737a5d5b 1374 break;
1375 }
9305fe33 1376 default:
1377 break;
e1629549 1378 }
1379 }
1380}
1381
1382/* Output assembly language output for the address ADDR to FILE. */
1383
1384void
1385print_operand_address (file, addr)
1386 FILE *file;
1387 rtx addr;
1388{
1389 switch (GET_CODE (addr))
1390 {
1391 case REG:
b839e0b4 1392 fprintf (file, "%s", h8_reg_names[REGNO (addr)]);
e1629549 1393 break;
1394
1395 case PRE_DEC:
b839e0b4 1396 fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
e1629549 1397 break;
1398
1399 case POST_INC:
b839e0b4 1400 fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);
e1629549 1401 break;
1402
1403 case PLUS:
1404 fprintf (file, "(");
1405 if (GET_CODE (XEXP (addr, 0)) == REG)
1406 {
1407 /* reg,foo */
1408 print_operand_address (file, XEXP (addr, 1));
1409 fprintf (file, ",");
1410 print_operand_address (file, XEXP (addr, 0));
1411 }
1412 else
1413 {
1414 /* foo+k */
1415 print_operand_address (file, XEXP (addr, 0));
1416 fprintf (file, "+");
1417 print_operand_address (file, XEXP (addr, 1));
1418 }
1419 fprintf (file, ")");
1420 break;
1421
1422 case CONST_INT:
b839e0b4 1423 {
53aec781 1424 /* Since the H8/300 only has 16 bit pointers, negative values are also
b839e0b4 1425 those >= 32768. This happens for example with pointer minus a
1426 constant. We don't want to turn (char *p - 2) into
1427 (char *p + 65534) because loop unrolling can build upon this
1428 (IE: char *p + 131068). */
1429 int n = INTVAL (addr);
1430 if (TARGET_H8300)
1431 n = (int) (short) n;
1432 if (n < 0)
eb2aa24e 1433 /* ??? Why the special case for -ve values? */
b839e0b4 1434 fprintf (file, "-%d", -n);
1435 else
1436 fprintf (file, "%d", n);
1437 break;
1438 }
e1629549 1439
1440 default:
1441 output_addr_const (file, addr);
1442 break;
1443 }
1444}
1445\f
e1629549 1446/* Output all insn addresses and their sizes into the assembly language
1447 output file. This is helpful for debugging whether the length attributes
1448 in the md file are correct. This is not meant to be a user selectable
1449 option. */
1450
1451void
1452final_prescan_insn (insn, operand, num_operands)
9305fe33 1453 rtx insn, *operand ATTRIBUTE_UNUSED;
1454 int num_operands ATTRIBUTE_UNUSED;
e1629549 1455{
1456 /* This holds the last insn address. */
1457 static int last_insn_address = 0;
1458
1459 int uid = INSN_UID (insn);
1460
b839e0b4 1461 if (TARGET_RTL_DUMP)
1462 {
1463 fprintf (asm_out_file, "\n****************");
1464 print_rtl (asm_out_file, PATTERN (insn));
1465 fprintf (asm_out_file, "\n");
1466 }
1467
e1629549 1468 if (TARGET_ADDRESSES)
1469 {
47fc0706 1470 fprintf (asm_out_file, "; 0x%x %d\n", INSN_ADDRESSES (uid),
1471 INSN_ADDRESSES (uid) - last_insn_address);
1472 last_insn_address = INSN_ADDRESSES (uid);
e1629549 1473 }
1474}
1475
b839e0b4 1476/* Prepare for an SI sized move. */
1477
1478int
1479do_movsi (operands)
1480 rtx operands[];
e1629549 1481{
b839e0b4 1482 rtx src = operands[1];
1483 rtx dst = operands[0];
1484 if (!reload_in_progress && !reload_completed)
1485 {
1486 if (!register_operand (dst, GET_MODE (dst)))
1487 {
1488 rtx tmp = gen_reg_rtx (GET_MODE (dst));
1489 emit_move_insn (tmp, src);
1490 operands[1] = tmp;
1491 }
1492 }
1493 return 0;
1494}
1495
1496/* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
eb2aa24e 1497 Define the offset between two registers, one to be eliminated, and
1498 the other its replacement, at the start of a routine. */
e1629549 1499
b839e0b4 1500int
1501initial_offset (from, to)
9305fe33 1502 int from, to;
b839e0b4 1503{
1504 int offset = 0;
1505
1506 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1507 offset = UNITS_PER_WORD + frame_pointer_needed * UNITS_PER_WORD;
f643a7d5 1508 else if (from == RETURN_ADDRESS_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1509 offset = frame_pointer_needed * UNITS_PER_WORD;
b839e0b4 1510 else
e1629549 1511 {
b839e0b4 1512 int regno;
1513
1514 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1dbee3e1 1515 if (WORD_REG_USED (regno))
b839e0b4 1516 offset += UNITS_PER_WORD;
1517
1518 /* See the comments for get_frame_size. We need to round it up to
1519 STACK_BOUNDARY. */
1520
1521 offset += ((get_frame_size () + STACK_BOUNDARY / BITS_PER_UNIT - 1)
1522 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
1523
1524 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1525 offset += UNITS_PER_WORD; /* Skip saved PC */
1526 }
1527 return offset;
1528}
1529
f643a7d5 1530rtx
1531h8300_return_addr_rtx (count, frame)
1532 int count;
1533 rtx frame;
1534{
1535 rtx ret;
1536
1537 if (count == 0)
1538 ret = gen_rtx_MEM (Pmode,
1539 gen_rtx_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM));
1540 else if (flag_omit_frame_pointer)
1541 return (rtx) 0;
1542 else
1543 ret = gen_rtx_MEM (Pmode,
1544 memory_address (Pmode,
1545 plus_constant (frame, UNITS_PER_WORD)));
1546 set_mem_alias_set (ret, get_frame_alias_set ());
1547 return ret;
1548}
1549
b839e0b4 1550/* Update the condition code from the insn. */
1551
9305fe33 1552void
b839e0b4 1553notice_update_cc (body, insn)
1554 rtx body;
1555 rtx insn;
1556{
1557 switch (get_attr_cc (insn))
1558 {
1559 case CC_NONE:
30c992ef 1560 /* Insn does not affect CC at all. */
b839e0b4 1561 break;
1562
1563 case CC_NONE_0HIT:
30c992ef 1564 /* Insn does not change CC, but the 0'th operand has been changed. */
b839e0b4 1565 if (cc_status.value1 != 0
ed420a25 1566 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
b839e0b4 1567 cc_status.value1 = 0;
b839e0b4 1568 break;
1569
a618bce0 1570 case CC_SET_ZN:
ed420a25 1571 /* Insn sets the Z,N flags of CC to recog_data.operand[0].
30c992ef 1572 The V flag is unusable. The C flag may or may not be known but
1573 that's ok because alter_cond will change tests to use EQ/NE. */
b839e0b4 1574 CC_STATUS_INIT;
30c992ef 1575 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
ed420a25 1576 cc_status.value1 = recog_data.operand[0];
b839e0b4 1577 break;
1578
a618bce0 1579 case CC_SET_ZNV:
ed420a25 1580 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
a618bce0 1581 The C flag may or may not be known but that's ok because
1582 alter_cond will change tests to use EQ/NE. */
1583 CC_STATUS_INIT;
1584 cc_status.flags |= CC_NO_CARRY;
ed420a25 1585 cc_status.value1 = recog_data.operand[0];
a618bce0 1586 break;
1587
30c992ef 1588 case CC_COMPARE:
1589 /* The insn is a compare instruction. */
b839e0b4 1590 CC_STATUS_INIT;
30c992ef 1591 cc_status.value1 = SET_SRC (body);
b839e0b4 1592 break;
1593
b839e0b4 1594 case CC_CLOBBER:
30c992ef 1595 /* Insn doesn't leave CC in a usable state. */
b839e0b4 1596 CC_STATUS_INIT;
1597 break;
e1629549 1598 }
b839e0b4 1599}
1600
eb2aa24e 1601/* Recognize valid operators for bit instructions. */
b839e0b4 1602
1603int
1604bit_operator (x, mode)
1605 rtx x;
9305fe33 1606 enum machine_mode mode ATTRIBUTE_UNUSED;
b839e0b4 1607{
1608 enum rtx_code code = GET_CODE (x);
e1629549 1609
b839e0b4 1610 return (code == XOR
1611 || code == AND
1612 || code == IOR);
e1629549 1613}
b839e0b4 1614\f
6a8a3fa3 1615const char *
1616output_logical_op (mode, code, operands)
1617 enum machine_mode mode;
1618 int code;
1619 rtx *operands;
1620{
1621 /* Pretend that every byte is affected if both operands are registers. */
1622 unsigned HOST_WIDE_INT intval =
1623 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
1624 ? INTVAL (operands[2]) : 0x55555555);
1625 /* The determinant of the algorithm. If we perform an AND, 0
1626 affects a bit. Otherwise, 1 affects a bit. */
1627 unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
1628 /* The name of an insn. */
1629 const char *opname;
1630 char insn_buf[100];
1631
1632 switch (code)
1633 {
1634 case AND:
1635 opname = "and";
1636 break;
1637 case IOR:
1638 opname = "or";
1639 break;
1640 case XOR:
1641 opname = "xor";
1642 break;
1643 default:
1644 abort ();
1645 }
1646
1647 switch (mode)
1648 {
1649 case HImode:
1650 /* First, see if we can finish with one insn. */
1651 if ((TARGET_H8300H || TARGET_H8300S)
1652 && ((det & 0x00ff) != 0)
1653 && ((det & 0xff00) != 0))
1654 {
1655 sprintf (insn_buf, "%s.w\t%%T2,%%T0", opname);
1656 output_asm_insn (insn_buf, operands);
1657 }
1658 else
1659 {
1660 /* Take care of the lower byte. */
1661 if ((det & 0x00ff) != 0)
1662 {
1663 sprintf (insn_buf, "%s\t%%s2,%%s0", opname);
1664 output_asm_insn (insn_buf, operands);
1665 }
1666 /* Take care of the upper byte. */
1667 if ((det & 0xff00) != 0)
1668 {
1669 sprintf (insn_buf, "%s\t%%t2,%%t0", opname);
1670 output_asm_insn (insn_buf, operands);
1671 }
1672 }
1673 break;
1674 case SImode:
1675 /* First, see if we can finish with one insn.
1676
1677 If code is either AND or XOR, we exclude two special cases,
1678 0xffffff00 and 0xffff00ff, because insns like sub.w or neg.w
1679 can do a better job. */
1680 if ((TARGET_H8300H || TARGET_H8300S)
1681 && ((det & 0x0000ffff) != 0)
1682 && ((det & 0xffff0000) != 0)
1683 && (code == IOR || det != 0xffffff00)
1684 && (code == IOR || det != 0xffff00ff))
1685 {
1686 sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname);
1687 output_asm_insn (insn_buf, operands);
1688 }
1689 else
1690 {
1691 /* Take care of the lower and upper words individually. For
1692 each word, we try different methods in the order of
1693
1694 1) the special insn (in case of AND or XOR),
1695 2) the word-wise insn, and
1696 3) The byte-wise insn. */
1697 if ((TARGET_H8300H || TARGET_H8300S)
1698 && ((det & 0x0000ffff) == 0x0000ffff)
1699 && code != IOR)
1700 output_asm_insn ((code == AND)
1701 ? "sub.w\t%f0,%f0" : "neg.w\t%f0",
1702 operands);
1703 else if ((TARGET_H8300H || TARGET_H8300S)
1704 && ((det & 0x000000ff) != 0)
1705 && ((det & 0x0000ff00) != 0))
1706 {
1707 sprintf (insn_buf, "%s.w\t%%f2,%%f0", opname);
1708 output_asm_insn (insn_buf, operands);
1709 }
1710 else
1711 {
1712 if ((det & 0x000000ff) != 0)
1713 {
1714 sprintf (insn_buf, "%s\t%%w2,%%w0", opname);
1715 output_asm_insn (insn_buf, operands);
1716 }
1717 if ((det & 0x0000ff00) != 0)
1718 {
1719 sprintf (insn_buf, "%s\t%%x2,%%x0", opname);
1720 output_asm_insn (insn_buf, operands);
1721 }
1722 }
1723
1724 if ((TARGET_H8300H || TARGET_H8300S)
1725 && ((det & 0xffff0000) == 0xffff0000)
1726 && code != IOR)
1727 output_asm_insn ((code == AND)
1728 ? "sub.w\t%e0,%e0" : "neg.w\t%e0",
1729 operands);
1730 else if (TARGET_H8300H || TARGET_H8300S)
1731 {
1732 if ((det & 0xffff0000) != 0)
1733 {
1734 sprintf (insn_buf, "%s.w\t%%e2,%%e0", opname);
1735 output_asm_insn (insn_buf, operands);
1736 }
1737 }
1738 else
1739 {
1740 if ((det & 0x00ff0000) != 0)
1741 {
1742 sprintf (insn_buf, "%s\t%%y2,%%y0", opname);
1743 output_asm_insn (insn_buf, operands);
1744 }
1745 if ((det & 0xff000000) != 0)
1746 {
1747 sprintf (insn_buf, "%s\t%%z2,%%z0", opname);
1748 output_asm_insn (insn_buf, operands);
1749 }
1750 }
1751 }
1752 break;
1753 default:
1754 abort ();
1755 }
1756 return "";
1757}
1758\f
b839e0b4 1759/* Shifts.
1760
1761 We devote a fair bit of code to getting efficient shifts since we can only
52abe980 1762 shift one bit at a time on the H8/300 and H8/300H and only one or two
1763 bits at a time on the H8/S.
1764
1765 The basic shift methods:
1766
1767 * loop shifts -- emit a loop using one (or two on H8/S) bit shifts;
1768 this is the default. SHIFT_LOOP
1769
1770 * inlined shifts -- emit straight line code for the shift; this is
1771 used when a straight line shift is about the same size or smaller
1772 than a loop. We allow the inline version to be slightly longer in
1773 some cases as it saves a register. SHIFT_INLINE
1774
1775 * rotate + and -- rotate the value the opposite direction, then
1776 mask off the values we don't need. This is used when only a few
1777 of the bits in the original value will survive in the shifted value.
1778 Again, this is used when it's about the same size or smaller than
1779 a loop. We allow this version to be slightly longer as it is usually
1780 much faster than a loop. SHIFT_ROT_AND
1781
1782 * swap (+ shifts) -- often it's possible to swap bytes/words to
1783 simulate a shift by 8/16. Once swapped a few inline shifts can be
1784 added if the shift count is slightly more than 8 or 16. This is used
1785 when it's about the same size or smaller than a loop. We allow this
1786 version to be slightly longer as it is usually much faster than a loop.
1787 SHIFT_SPECIAL
1788
1789 * There other oddballs. Not worth explaining. SHIFT_SPECIAL
1790
b839e0b4 1791 Here are some thoughts on what the absolutely positively best code is.
1792 "Best" here means some rational trade-off between code size and speed,
1793 where speed is more preferred but not at the expense of generating 20 insns.
1794
52abe980 1795 A trailing '*' after the shift count indicates the "best" mode isn't
1796 implemented.
1797
b839e0b4 1798 H8/300 QImode shifts
52abe980 1799 1-4 - do them inline
1800 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1801 ASHIFTRT: loop
1802 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1803 ASHIFTRT: shll, subx (propagate carry bit to all bits)
b839e0b4 1804
1805 H8/300 HImode shifts
52abe980 1806 1-4 - do them inline
1807 5-6 - loop
1808 7 - shift 2nd half other way into carry.
1809 copy 1st half into 2nd half
1810 rotate 2nd half other way with carry
1811 rotate 1st half other way (no carry)
1812 mask off bits in 1st half (ASHIFT | LSHIFTRT).
1813 sign extend 1st half (ASHIFTRT)
1814 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1815 9-12 - do shift by 8, inline remaining shifts
1816 13-14* - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1817 - ASHIFTRT: loop
1818 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1819 - ASHIFTRT: shll, subx, set other byte
b839e0b4 1820
1821 H8/300 SImode shifts
52abe980 1822 1-2 - do them inline
1823 3-6 - loop
1824 7* - shift other way once, move bytes into place,
1825 move carry into place (possibly with sign extension)
1826 8 - move bytes into place, zero or sign extend other
1827 9-14 - loop
1828 15* - shift other way once, move word into place, move carry into place
1829 16 - move word, zero or sign extend other
1830 17-23 - loop
1831 24* - move bytes into place, zero or sign extend other
1832 25-27 - loop
1833 28-30* - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,
1834 zero others
1835 ASHIFTRT: loop
3398e91d 1836 31 - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,
52abe980 1837 zero others
1838 ASHIFTRT: shll top byte, subx, copy to other bytes
1839
1840 H8/300H QImode shifts (same as H8/300 QImode shifts)
1841 1-4 - do them inline
1842 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1843 ASHIFTRT: loop
1844 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1845 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1846
b839e0b4 1847 H8/300H HImode shifts
52abe980 1848 1-4 - do them inline
1849 5-6 - loop
1850 7 - shift 2nd half other way into carry.
1851 copy 1st half into 2nd half
1852 rotate entire word other way using carry
1853 mask off remaining bits (ASHIFT | LSHIFTRT)
1854 sign extend remaining bits (ASHIFTRT)
1855 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1856 9-12 - do shift by 8, inline remaining shifts
1857 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1858 - ASHIFTRT: loop
1859 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1860 - ASHIFTRT: shll, subx, set other byte
b839e0b4 1861
1862 H8/300H SImode shifts
1863 (These are complicated by the fact that we don't have byte level access to
1864 the top word.)
1865 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
52abe980 1866 1-4 - do them inline
1867 5-14 - loop
1868 15* - shift other way once, move word into place, move carry into place
1869 (with sign extension for ASHIFTRT)
1870 16 - move word into place, zero or sign extend other
1871 17-20 - do 16bit shift, then inline remaining shifts
1872 20-23 - loop
1873 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1874 move word 0 to word 1, zero word 0
1875 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1876 zero word 1, zero byte 1
1877 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1878 sign extend byte 0, sign extend word 0
1879 25-27* - either loop, or
1880 do 24 bit shift, inline rest
1881 28-30 - ASHIFT: rotate 4/3/2, mask
1882 LSHIFTRT: rotate 4/3/2, mask
1883 ASHIFTRT: loop
1884 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1885
1886 H8/S QImode shifts
1887 1-6 - do them inline
1888 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1889 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1890
1891 H8/S HImode shifts
1892 1-7 - do them inline
1893 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1894 9-12 - do shift by 8, inline remaining shifts
1895 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1896 - ASHIFTRT: loop
1897 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1898 - ASHIFTRT: shll, subx, set other byte
1899
1900 H8/S SImode shifts
1901 (These are complicated by the fact that we don't have byte level access to
1902 the top word.)
1903 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1904 1-10 - do them inline
1905 11-14 - loop
1906 15* - shift other way once, move word into place, move carry into place
1907 (with sign extension for ASHIFTRT)
1908 16 - move word into place, zero or sign extend other
1909 17-20 - do 16bit shift, then inline remaining shifts
a150fb62 1910 21-23 - loop
52abe980 1911 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1912 move word 0 to word 1, zero word 0
1913 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1914 zero word 1, zero byte 1
1915 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1916 sign extend byte 0, sign extend word 0
1917 25-27* - either loop, or
1918 do 24 bit shift, inline rest
1919 28-30 - ASHIFT: rotate 4/3/2, mask
1920 LSHIFTRT: rotate 4/3/2, mask
1921 ASHIFTRT: loop
1922 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1923
1924 Panic!!! */
e1629549 1925
1926int
b839e0b4 1927nshift_operator (x, mode)
1928 rtx x;
9305fe33 1929 enum machine_mode mode ATTRIBUTE_UNUSED;
b839e0b4 1930{
1931 switch (GET_CODE (x))
1932 {
1933 case ASHIFTRT:
1934 case LSHIFTRT:
1935 case ASHIFT:
1936 return 1;
1937
1938 default:
1939 return 0;
1940 }
1941}
1942
1943/* Called from the .md file to emit code to do shifts.
53aec781 1944 Return a boolean indicating success.
1945 (Currently this is always TRUE). */
b839e0b4 1946
1947int
1948expand_a_shift (mode, code, operands)
1949 enum machine_mode mode;
e1629549 1950 int code;
1951 rtx operands[];
e1629549 1952{
e1629549 1953 emit_move_insn (operands[0], operands[1]);
1954
eb2aa24e 1955 /* Need a loop to get all the bits we want - we generate the
1956 code at emit time, but need to allocate a scratch reg now. */
b839e0b4 1957
7014838c 1958 emit_insn (gen_rtx_PARALLEL
1959 (VOIDmode,
b839e0b4 1960 gen_rtvec (2,
7014838c 1961 gen_rtx_SET (VOIDmode, operands[0],
1962 gen_rtx (code, mode, operands[0],
1963 operands[2])),
1964 gen_rtx_CLOBBER (VOIDmode,
1965 gen_rtx_SCRATCH (QImode)))));
b839e0b4 1966
1967 return 1;
1968}
1969
1970/* Shift algorithm determination.
1971
1972 There are various ways of doing a shift:
1973 SHIFT_INLINE: If the amount is small enough, just generate as many one-bit
1974 shifts as we need.
1975 SHIFT_ROT_AND: If the amount is large but close to either end, rotate the
1976 necessary bits into position and then set the rest to zero.
1977 SHIFT_SPECIAL: Hand crafted assembler.
1978 SHIFT_LOOP: If the above methods fail, just loop. */
1979
1980enum shift_alg
1981{
1982 SHIFT_INLINE,
1983 SHIFT_ROT_AND,
1984 SHIFT_SPECIAL,
0cdad59a 1985 SHIFT_LOOP
b839e0b4 1986};
1987
1988/* Symbols of the various shifts which can be used as indices. */
1989
1990enum shift_type
27276a3b 1991{
1992 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
1993};
b839e0b4 1994
1995/* Symbols of the various modes which can be used as indices. */
1996
1997enum shift_mode
27276a3b 1998{
1999 QIshift, HIshift, SIshift
2000};
b839e0b4 2001
30c992ef 2002/* For single bit shift insns, record assembler and what bits of the
2003 condition code are valid afterwards (represented as various CC_FOO
2004 bits, 0 means CC isn't left in a usable state). */
b839e0b4 2005
2006struct shift_insn
2007{
e99c3a1d 2008 const char *const assembler;
2009 const int cc_valid;
b839e0b4 2010};
2011
2012/* Assembler instruction shift table.
2013
2014 These tables are used to look up the basic shifts.
eb2aa24e 2015 They are indexed by cpu, shift_type, and mode. */
e1629549 2016
b839e0b4 2017static const struct shift_insn shift_one[2][3][3] =
2018{
2019/* H8/300 */
2020 {
2021/* SHIFT_ASHIFT */
2022 {
a618bce0 2023 { "shll\t%X0", CC_NO_CARRY },
52abe980 2024 { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2025 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }
b839e0b4 2026 },
2027/* SHIFT_LSHIFTRT */
2028 {
a618bce0 2029 { "shlr\t%X0", CC_NO_CARRY },
52abe980 2030 { "shlr\t%t0\n\trotxr\t%s0", 0 },
2031 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
b839e0b4 2032 },
2033/* SHIFT_ASHIFTRT */
2034 {
52abe980 2035 { "shar\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2036 { "shar\t%t0\n\trotxr\t%s0", 0 },
2037 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
b839e0b4 2038 }
2039 },
2040/* H8/300H */
2041 {
2042/* SHIFT_ASHIFT */
2043 {
a618bce0 2044 { "shll.b\t%X0", CC_NO_CARRY },
2045 { "shll.w\t%T0", CC_NO_CARRY },
2046 { "shll.l\t%S0", CC_NO_CARRY }
b839e0b4 2047 },
2048/* SHIFT_LSHIFTRT */
2049 {
a618bce0 2050 { "shlr.b\t%X0", CC_NO_CARRY },
2051 { "shlr.w\t%T0", CC_NO_CARRY },
2052 { "shlr.l\t%S0", CC_NO_CARRY }
b839e0b4 2053 },
2054/* SHIFT_ASHIFTRT */
2055 {
52abe980 2056 { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2057 { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2058 { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
b839e0b4 2059 }
2060 }
2061};
e1629549 2062
52abe980 2063static const struct shift_insn shift_two[3][3] =
2064{
2065/* SHIFT_ASHIFT */
2066 {
a618bce0 2067 { "shll.b\t#2,%X0", CC_NO_CARRY },
2068 { "shll.w\t#2,%T0", CC_NO_CARRY },
2069 { "shll.l\t#2,%S0", CC_NO_CARRY }
52abe980 2070 },
2071/* SHIFT_LSHIFTRT */
2072 {
a618bce0 2073 { "shlr.b\t#2,%X0", CC_NO_CARRY },
2074 { "shlr.w\t#2,%T0", CC_NO_CARRY },
2075 { "shlr.l\t#2,%S0", CC_NO_CARRY }
52abe980 2076 },
2077/* SHIFT_ASHIFTRT */
2078 {
2079 { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2080 { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2081 { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
2082 }
2083};
2084
b839e0b4 2085/* Rotates are organized by which shift they'll be used in implementing.
2086 There's no need to record whether the cc is valid afterwards because
2087 it is the AND insn that will decide this. */
e1629549 2088
b839e0b4 2089static const char *const rotate_one[2][3][3] =
2090{
2091/* H8/300 */
2092 {
2093/* SHIFT_ASHIFT */
2094 {
52abe980 2095 "rotr\t%X0",
2096 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
b839e0b4 2097 0
2098 },
2099/* SHIFT_LSHIFTRT */
2100 {
52abe980 2101 "rotl\t%X0",
2102 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
b839e0b4 2103 0
2104 },
2105/* SHIFT_ASHIFTRT */
2106 {
52abe980 2107 "rotl\t%X0",
2108 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
b839e0b4 2109 0
e1629549 2110 }
b839e0b4 2111 },
2112/* H8/300H */
2113 {
2114/* SHIFT_ASHIFT */
2115 {
52abe980 2116 "rotr.b\t%X0",
2117 "rotr.w\t%T0",
2118 "rotr.l\t%S0"
b839e0b4 2119 },
2120/* SHIFT_LSHIFTRT */
e1629549 2121 {
52abe980 2122 "rotl.b\t%X0",
2123 "rotl.w\t%T0",
2124 "rotl.l\t%S0"
b839e0b4 2125 },
2126/* SHIFT_ASHIFTRT */
2127 {
52abe980 2128 "rotl.b\t%X0",
2129 "rotl.w\t%T0",
2130 "rotl.l\t%S0"
b839e0b4 2131 }
2132 }
2133};
2134
52abe980 2135static const char *const rotate_two[3][3] =
2136{
2137/* SHIFT_ASHIFT */
2138 {
2139 "rotr.b\t#2,%X0",
2140 "rotr.w\t#2,%T0",
2141 "rotr.l\t#2,%S0"
2142 },
2143/* SHIFT_LSHIFTRT */
2144 {
2145 "rotl.b\t#2,%X0",
2146 "rotl.w\t#2,%T0",
2147 "rotl.l\t#2,%S0"
2148 },
2149/* SHIFT_ASHIFTRT */
2150 {
2151 "rotl.b\t#2,%X0",
2152 "rotl.w\t#2,%T0",
2153 "rotl.l\t#2,%S0"
2154 }
2155};
2156
58285553 2157/* Macros to keep the shift algorithm tables small. */
2158#define INL SHIFT_INLINE
2159#define ROT SHIFT_ROT_AND
2160#define LOP SHIFT_LOOP
2161#define SPC SHIFT_SPECIAL
2162
2163/* The shift algorithms for each machine, mode, shift type, and shift
2164 count are defined below. The three tables below correspond to
2165 QImode, HImode, and SImode, respectively. Each table is organized
2166 by, in the order of indecies, machine, shift type, and shift count. */
2167
2168static const enum shift_alg shift_alg_qi[3][3][8] = {
2169 {
2170 /* TARGET_H8300 */
2171 /* 0 1 2 3 4 5 6 7 */
2172 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2173 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2174 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
2175 },
2176 {
2177 /* TARGET_H8300H */
2178 /* 0 1 2 3 4 5 6 7 */
2179 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2180 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2181 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
2182 },
2183 {
2184 /* TARGET_H8300S */
2185 /* 0 1 2 3 4 5 6 7 */
776e0da8 2186 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_ASHIFT */
2187 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_LSHIFTRT */
58285553 2188 { INL, INL, INL, INL, INL, INL, INL, SPC } /* SHIFT_ASHIFTRT */
2189 }
2190};
2191
2192static const enum shift_alg shift_alg_hi[3][3][16] = {
2193 {
2194 /* TARGET_H8300 */
2195 /* 0 1 2 3 4 5 6 7 */
2196 /* 8 9 10 11 12 13 14 15 */
2197 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2198 SPC, SPC, SPC, SPC, SPC, LOP, LOP, ROT }, /* SHIFT_ASHIFT */
2199 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2200 SPC, SPC, SPC, SPC, SPC, LOP, LOP, ROT }, /* SHIFT_LSHIFTRT */
2201 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2202 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2203 },
2204 {
2205 /* TARGET_H8300H */
2206 /* 0 1 2 3 4 5 6 7 */
2207 /* 8 9 10 11 12 13 14 15 */
2208 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2209 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2210 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2211 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2212 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2213 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2214 },
2215 {
2216 /* TARGET_H8300S */
2217 /* 0 1 2 3 4 5 6 7 */
2218 /* 8 9 10 11 12 13 14 15 */
2219 { INL, INL, INL, INL, INL, INL, INL, INL,
2220 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2221 { INL, INL, INL, INL, INL, INL, INL, INL,
2222 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2223 { INL, INL, INL, INL, INL, INL, INL, INL,
2224 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2225 }
2226};
2227
2228static const enum shift_alg shift_alg_si[3][3][32] = {
2229 {
2230 /* TARGET_H8300 */
2231 /* 0 1 2 3 4 5 6 7 */
2232 /* 8 9 10 11 12 13 14 15 */
2233 /* 16 17 18 19 20 21 22 23 */
2234 /* 24 25 26 27 28 29 30 31 */
2235 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2236 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2237 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2238 LOP, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
2239 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2240 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2241 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2242 LOP, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
2243 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2244 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2245 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2246 LOP, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2247 },
2248 {
2249 /* TARGET_H8300H */
2250 /* 0 1 2 3 4 5 6 7 */
2251 /* 8 9 10 11 12 13 14 15 */
2252 /* 16 17 18 19 20 21 22 23 */
2253 /* 24 25 26 27 28 29 30 31 */
2254 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
37e1f65a 2255 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
58285553 2256 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
37e1f65a 2257 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
58285553 2258 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
37e1f65a 2259 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
58285553 2260 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
37e1f65a 2261 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
58285553 2262 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
2263 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2264 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
2265 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2266 },
2267 {
2268 /* TARGET_H8300S */
2269 /* 0 1 2 3 4 5 6 7 */
2270 /* 8 9 10 11 12 13 14 15 */
2271 /* 16 17 18 19 20 21 22 23 */
2272 /* 24 25 26 27 28 29 30 31 */
2273 { INL, INL, INL, INL, INL, INL, INL, INL,
37e1f65a 2274 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
776e0da8 2275 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
37e1f65a 2276 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
58285553 2277 { INL, INL, INL, INL, INL, INL, INL, INL,
37e1f65a 2278 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
776e0da8 2279 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
37e1f65a 2280 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
58285553 2281 { INL, INL, INL, INL, INL, INL, INL, INL,
2282 INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
776e0da8 2283 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
58285553 2284 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2285 }
2286};
2287
2288#undef INL
2289#undef ROT
2290#undef LOP
2291#undef SPC
2292
4765dbab 2293struct shift_info {
2294 /* Shift algorithm. */
2295 enum shift_alg alg;
2296
2297 /* The number of bits to be shifted by shift1 and shift2. Valid
2298 when ALG is SHIFT_SPECIAL. */
2299 unsigned int remainder;
2300
2301 /* Special insn for a shift. Valid when ALG is SHIFT_SPECIAL. */
2302 const char *special;
2303
2304 /* Insn for a one-bit shift. Valid when ALG is either SHIFT_INLINE
2305 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2306 const char *shift1;
2307
2308 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
2309 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2310 const char *shift2;
2311
2312 /* Valid CC flags. */
2313 int cc_valid_p;
2314};
2315
5a40b38e 2316static void get_shift_alg PARAMS ((enum shift_type,
58285553 2317 enum shift_mode, unsigned int,
5a40b38e 2318 struct shift_info *));
9305fe33 2319
ec0b80c6 2320/* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
2321 best algorithm for doing the shift. The assembler code is stored
2322 in the pointers in INFO. We don't achieve maximum efficiency in
2323 all cases, but the hooks are here to do so.
b839e0b4 2324
2325 For now we just use lots of switch statements. Since we don't even come
2326 close to supporting all the cases, this is simplest. If this function ever
2327 gets too big, perhaps resort to a more table based lookup. Of course,
2328 at this point you may just wish to do it all in rtl.
2329
2330 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
2331 1,2,3,4 will be inlined (1,2 for SI). */
2332
5a40b38e 2333static void
4765dbab 2334get_shift_alg (shift_type, shift_mode, count, info)
b839e0b4 2335 enum shift_type shift_type;
1545e1eb 2336 enum shift_mode shift_mode;
58285553 2337 unsigned int count;
4765dbab 2338 struct shift_info *info;
b839e0b4 2339{
58285553 2340 int cpu;
2341
2342 /* Find the target CPU. */
2343 if (TARGET_H8300)
2344 cpu = 0;
2345 else if (TARGET_H8300H)
2346 cpu = 1;
2347 else
2348 cpu = 2;
2349
ce8940f6 2350 /* Find the shift algorithm. */
b839e0b4 2351 switch (shift_mode)
2352 {
2353 case QIshift:
58285553 2354 if (GET_MODE_BITSIZE (QImode) <= count)
ce8940f6 2355 info->alg = SHIFT_LOOP;
2356 else
2357 info->alg = shift_alg_qi[cpu][shift_type][count];
2358 break;
58285553 2359
ce8940f6 2360 case HIshift:
2361 if (GET_MODE_BITSIZE (HImode) <= count)
2362 info->alg = SHIFT_LOOP;
2363 else
2364 info->alg = shift_alg_hi[cpu][shift_type][count];
2365 break;
2366
2367 case SIshift:
2368 if (GET_MODE_BITSIZE (SImode) <= count)
2369 info->alg = SHIFT_LOOP;
2370 else
2371 info->alg = shift_alg_si[cpu][shift_type][count];
2372 break;
2373
2374 default:
2375 abort ();
2376 }
2377
2378 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
2379 switch (info->alg)
2380 {
2381 case SHIFT_INLINE:
2382 info->remainder = count;
2383 /* Fall through. */
2384
2385 case SHIFT_LOOP:
2386 /* It is up to the caller to know that looping clobbers cc. */
2387 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2388 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2389 info->cc_valid_p = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
2390 goto end;
2391
2392 case SHIFT_ROT_AND:
2393 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
2394 info->shift2 = rotate_two[shift_type][shift_mode];
2395 info->cc_valid_p = 0;
2396 goto end;
2397
2398 case SHIFT_SPECIAL:
2399 /* REMAINDER is 0 for most cases, so initialize it to 0. */
2400 info->remainder = 0;
2401 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2402 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2403 info->cc_valid_p = 0;
2404 break;
2405 }
52abe980 2406
ce8940f6 2407 /* Here we only deal with SHIFT_SPECIAL. */
2408 switch (shift_mode)
2409 {
2410 case QIshift:
58285553 2411 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2412 through the entire value. */
2413 if (shift_type == SHIFT_ASHIFTRT && count == 7)
2414 {
2415 info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
606a6902 2416 goto end;
58285553 2417 }
2418 abort ();
2419
2420 case HIshift:
58285553 2421 if (count == 7)
52abe980 2422 {
2423 if (shift_type == SHIFT_ASHIFT && TARGET_H8300)
b839e0b4 2424 {
4765dbab 2425 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";
606a6902 2426 goto end;
b839e0b4 2427 }
52abe980 2428
2429 if (shift_type == SHIFT_ASHIFT && TARGET_H8300H)
b839e0b4 2430 {
4765dbab 2431 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
606a6902 2432 goto end;
52abe980 2433 }
2434
2435 if (shift_type == SHIFT_LSHIFTRT && TARGET_H8300)
2436 {
4765dbab 2437 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";
606a6902 2438 goto end;
52abe980 2439 }
2440
2441 if (shift_type == SHIFT_LSHIFTRT && TARGET_H8300H)
2442 {
4765dbab 2443 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
606a6902 2444 goto end;
52abe980 2445 }
2446
2447 if (shift_type == SHIFT_ASHIFTRT)
2448 {
4765dbab 2449 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
606a6902 2450 goto end;
b839e0b4 2451 }
e1629549 2452 }
8db8f925 2453 else if (8 <= count && count <= 12)
e1629549 2454 {
8db8f925 2455 info->remainder = count - 8;
2456
52abe980 2457 switch (shift_type)
b839e0b4 2458 {
52abe980 2459 case SHIFT_ASHIFT:
4765dbab 2460 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
8db8f925 2461 info->shift1 = "shal.b\t%t0";
2462 info->shift2 = "shal.b\t#2,%t0";
606a6902 2463 goto end;
52abe980 2464 case SHIFT_LSHIFTRT:
4765dbab 2465 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
8db8f925 2466 info->shift1 = "shlr.b\t%s0";
2467 info->shift2 = "shlr.b\t#2,%s0";
606a6902 2468 goto end;
52abe980 2469 case SHIFT_ASHIFTRT:
2470 if (TARGET_H8300)
8db8f925 2471 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
52abe980 2472 else
4765dbab 2473 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
8db8f925 2474 info->shift1 = "shar.b\t%s0";
2475 info->shift2 = "shar.b\t#2,%s0";
606a6902 2476 goto end;
52abe980 2477 }
2478 }
58285553 2479 else if (count == 15 && shift_type == SHIFT_ASHIFTRT)
52abe980 2480 {
58285553 2481 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
606a6902 2482 goto end;
e1629549 2483 }
58285553 2484 abort ();
52abe980 2485
b839e0b4 2486 case SIshift:
58285553 2487 if (count == 8 && TARGET_H8300)
b839e0b4 2488 {
52abe980 2489 switch (shift_type)
b839e0b4 2490 {
52abe980 2491 case SHIFT_ASHIFT:
4765dbab 2492 info->special = "mov.b\t%y0,%z0\n\tmov.b\t%x0,%y0\n\tmov.b\t%w0,%x0\n\tsub.b\t%w0,%w0";
606a6902 2493 goto end;
52abe980 2494 case SHIFT_LSHIFTRT:
4765dbab 2495 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";
606a6902 2496 goto end;
52abe980 2497 case SHIFT_ASHIFTRT:
4765dbab 2498 info->special = "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tshll\t%z0\n\tsubx\t%z0,%z0";
606a6902 2499 goto end;
b839e0b4 2500 }
b839e0b4 2501 }
9bbc06f2 2502 else if (count == 8 && !TARGET_H8300)
2503 {
2504 switch (shift_type)
2505 {
2506 case SHIFT_ASHIFT:
4765dbab 2507 info->special = "mov.w\t%e0,%f4\n\tmov.b\t%s4,%t4\n\tmov.b\t%t0,%s4\n\tmov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f4,%e0";
606a6902 2508 goto end;
9bbc06f2 2509 case SHIFT_LSHIFTRT:
4765dbab 2510 info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\textu.w\t%f4\n\tmov.w\t%f4,%e0";
606a6902 2511 goto end;
9bbc06f2 2512 case SHIFT_ASHIFTRT:
4765dbab 2513 info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\texts.w\t%f4\n\tmov.w\t%f4,%e0";
606a6902 2514 goto end;
9bbc06f2 2515 }
2516 }
37e1f65a 2517 else if (count == 15 && !TARGET_H8300)
2518 {
2519 switch (shift_type)
2520 {
2521 case SHIFT_ASHIFT:
2522 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
2523 goto end;
2524 case SHIFT_LSHIFTRT:
2525 info->special = "shll.w\t%e0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
2526 goto end;
2527 }
2528 }
8db8f925 2529 else if ((TARGET_H8300 && count == 16)
2530 || (TARGET_H8300H && 16 <= count && count <= 19)
776e0da8 2531 || (TARGET_H8300S && 16 <= count && count <= 21))
b839e0b4 2532 {
8db8f925 2533 info->remainder = count - 16;
2534
b839e0b4 2535 switch (shift_type)
2536 {
2537 case SHIFT_ASHIFT:
4765dbab 2538 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
8db8f925 2539 info->shift1 = "shll.l\t%S0";
2540 info->shift2 = "shll.l\t#2,%S0";
606a6902 2541 goto end;
52abe980 2542 case SHIFT_LSHIFTRT:
4765dbab 2543 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
8db8f925 2544 info->shift1 = "shlr.l\t%S0";
2545 info->shift2 = "shlr.l\t#2,%S0";
606a6902 2546 goto end;
52abe980 2547 case SHIFT_ASHIFTRT:
2548 if (TARGET_H8300)
4765dbab 2549 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
52abe980 2550 else
4765dbab 2551 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
8db8f925 2552 info->shift1 = "shar.l\t%S0";
2553 info->shift2 = "shar.l\t#2,%S0";
606a6902 2554 goto end;
52abe980 2555 }
2556 }
9bbc06f2 2557 else if (count == 24 && !TARGET_H8300)
2558 {
2559 switch (shift_type)
2560 {
2561 case SHIFT_ASHIFT:
4765dbab 2562 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
606a6902 2563 goto end;
9bbc06f2 2564 case SHIFT_LSHIFTRT:
4765dbab 2565 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
606a6902 2566 goto end;
9bbc06f2 2567 case SHIFT_ASHIFTRT:
4765dbab 2568 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
606a6902 2569 goto end;
9bbc06f2 2570 }
2571 }
b839e0b4 2572 else if (count == 31)
2573 {
37e1f65a 2574 if (TARGET_H8300)
b839e0b4 2575 {
37e1f65a 2576 switch (shift_type)
2577 {
2578 case SHIFT_ASHIFT:
2579 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2580 goto end;
2581 case SHIFT_LSHIFTRT:
2582 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2583 goto end;
2584 case SHIFT_ASHIFTRT:
2585 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2586 goto end;
2587 }
b839e0b4 2588 }
2589 else
2590 {
37e1f65a 2591 switch (shift_type)
b839e0b4 2592 {
37e1f65a 2593 case SHIFT_ASHIFT:
2594 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
2595 goto end;
2596 case SHIFT_LSHIFTRT:
2597 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
2598 goto end;
2599 case SHIFT_ASHIFTRT:
2600 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
606a6902 2601 goto end;
b839e0b4 2602 }
b839e0b4 2603 }
2604 }
58285553 2605 abort ();
52abe980 2606
b839e0b4 2607 default:
2608 abort ();
e1629549 2609 }
b839e0b4 2610
5a40b38e 2611 end:
2612 if (!TARGET_H8300S)
2613 info->shift2 = NULL;
e1629549 2614}
2615
b839e0b4 2616/* Emit the assembler code for doing shifts. */
2617
9305fe33 2618const char *
b839e0b4 2619emit_a_shift (insn, operands)
9305fe33 2620 rtx insn ATTRIBUTE_UNUSED;
b839e0b4 2621 rtx *operands;
e1629549 2622{
b839e0b4 2623 static int loopend_lab;
b839e0b4 2624 rtx shift = operands[3];
2625 enum machine_mode mode = GET_MODE (shift);
2626 enum rtx_code code = GET_CODE (shift);
2627 enum shift_type shift_type;
2628 enum shift_mode shift_mode;
4765dbab 2629 struct shift_info info;
b839e0b4 2630
2631 loopend_lab++;
2632
2633 switch (mode)
2634 {
2635 case QImode:
2636 shift_mode = QIshift;
2637 break;
2638 case HImode:
2639 shift_mode = HIshift;
2640 break;
2641 case SImode:
2642 shift_mode = SIshift;
2643 break;
2644 default:
2645 abort ();
2646 }
e1629549 2647
b839e0b4 2648 switch (code)
e1629549 2649 {
b839e0b4 2650 case ASHIFTRT:
2651 shift_type = SHIFT_ASHIFTRT;
2652 break;
2653 case LSHIFTRT:
2654 shift_type = SHIFT_LSHIFTRT;
2655 break;
2656 case ASHIFT:
2657 shift_type = SHIFT_ASHIFT;
2658 break;
2659 default:
2660 abort ();
2661 }
e1629549 2662
b839e0b4 2663 if (GET_CODE (operands[2]) != CONST_INT)
2664 {
eb2aa24e 2665 /* Indexing by reg, so have to loop and test at top. */
b839e0b4 2666 output_asm_insn ("mov.b %X2,%X4", operands);
2667 fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab);
2668
2669 /* Get the assembler code to do one shift. */
4765dbab 2670 get_shift_alg (shift_type, shift_mode, 1, &info);
cb95c693 2671
2672 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
4765dbab 2673 output_asm_insn (info.shift1, operands);
cb95c693 2674 output_asm_insn ("add #0xff,%X4", operands);
2675 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2676 fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
2677
2678 return "";
b839e0b4 2679 }
2680 else
2681 {
2682 int n = INTVAL (operands[2]);
b839e0b4 2683
2684 /* If the count is negative, make it 0. */
2685 if (n < 0)
2686 n = 0;
2687 /* If the count is too big, truncate it.
2688 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2689 do the intuitive thing. */
53aec781 2690 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
b839e0b4 2691 n = GET_MODE_BITSIZE (mode);
2692
5a40b38e 2693 get_shift_alg (shift_type, shift_mode, n, &info);
b839e0b4 2694
5a40b38e 2695 switch (info.alg)
b839e0b4 2696 {
5a40b38e 2697 case SHIFT_SPECIAL:
2698 output_asm_insn (info.special, operands);
2699 /* Fall through. */
2700
b839e0b4 2701 case SHIFT_INLINE:
5a40b38e 2702 n = info.remainder;
2703
52abe980 2704 /* Emit two bit shifts first. */
4765dbab 2705 while (n > 1 && info.shift2 != NULL)
52abe980 2706 {
4765dbab 2707 output_asm_insn (info.shift2, operands);
52abe980 2708 n -= 2;
2709 }
2710
2711 /* Now emit one bit shifts for any residual. */
2712 while (n > 0)
2713 {
4765dbab 2714 output_asm_insn (info.shift1, operands);
52abe980 2715 n -= 1;
2716 }
2717
2718 /* Keep track of CC. */
4765dbab 2719 if (info.cc_valid_p)
30c992ef 2720 {
2721 cc_status.value1 = operands[0];
4765dbab 2722 cc_status.flags |= info.cc_valid_p;
30c992ef 2723 }
b839e0b4 2724 return "";
52abe980 2725
b839e0b4 2726 case SHIFT_ROT_AND:
2727 {
2728 int m = GET_MODE_BITSIZE (mode) - n;
2729 int mask = (shift_type == SHIFT_ASHIFT
9305fe33 2730 ? ((1 << (GET_MODE_BITSIZE (mode) - n)) - 1) << n
2731 : (1 << (GET_MODE_BITSIZE (mode) - n)) - 1);
b839e0b4 2732 char insn_buf[200];
cb95c693 2733
b839e0b4 2734 /* Not all possibilities of rotate are supported. They shouldn't
2735 be generated, but let's watch for 'em. */
4765dbab 2736 if (info.shift1 == 0)
b839e0b4 2737 abort ();
52abe980 2738
2739 /* Emit two bit rotates first. */
4765dbab 2740 while (m > 1 && info.shift2 != NULL)
52abe980 2741 {
4765dbab 2742 output_asm_insn (info.shift2, operands);
52abe980 2743 m -= 2;
2744 }
2745
2746 /* Now single bit rotates for any residual. */
2747 while (m > 0)
2748 {
4765dbab 2749 output_asm_insn (info.shift1, operands);
52abe980 2750 m -= 1;
2751 }
2752
2753 /* Now mask off the high bits. */
b839e0b4 2754 if (TARGET_H8300)
2755 {
2756 switch (mode)
2757 {
2758 case QImode:
a150fb62 2759 sprintf (insn_buf, "and\t#%d,%%X0", mask);
b839e0b4 2760 cc_status.value1 = operands[0];
a618bce0 2761 cc_status.flags |= CC_NO_CARRY;
b839e0b4 2762 break;
2763 case HImode:
a150fb62 2764 sprintf (insn_buf, "and\t#%d,%%s0\n\tand\t#%d,%%t0",
9305fe33 2765 mask & 255, mask >> 8);
b839e0b4 2766 break;
2767 case SImode:
2768 abort ();
9305fe33 2769 default:
2770 break;
b839e0b4 2771 }
2772 }
2773 else
2774 {
a150fb62 2775 sprintf (insn_buf, "and.%c\t#%d,%%%c0",
b839e0b4 2776 "bwl"[shift_mode], mask,
2777 mode == QImode ? 'X' : mode == HImode ? 'T' : 'S');
2778 cc_status.value1 = operands[0];
a618bce0 2779 cc_status.flags |= CC_NO_CARRY;
b839e0b4 2780 }
2781 output_asm_insn (insn_buf, operands);
2782 return "";
2783 }
cb95c693 2784
cb95c693 2785 case SHIFT_LOOP:
2786 /* A loop to shift by a "large" constant value.
2787 If we have shift-by-2 insns, use them. */
4765dbab 2788 if (info.shift2 != NULL)
cb95c693 2789 {
2790 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
2791 names_big[REGNO (operands[4])]);
2792 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
4765dbab 2793 output_asm_insn (info.shift2, operands);
cb95c693 2794 output_asm_insn ("add #0xff,%X4", operands);
2795 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2796 if (n % 2)
4765dbab 2797 output_asm_insn (info.shift1, operands);
cb95c693 2798 }
2799 else
2800 {
2801 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
2802 names_big[REGNO (operands[4])]);
2803 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
4765dbab 2804 output_asm_insn (info.shift1, operands);
cb95c693 2805 output_asm_insn ("add #0xff,%X4", operands);
2806 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2807 }
52abe980 2808 return "";
cb95c693 2809
2810 default:
2811 abort ();
52abe980 2812 }
e1629549 2813 }
e1629549 2814}
b839e0b4 2815\f
b4fa7cf2 2816/* A rotation by a non-constant will cause a loop to be generated, in
2817 which a rotation by one bit is used. A rotation by a constant,
2818 including the one in the loop, will be taken care of by
2819 emit_a_rotate () at the insn emit time. */
2820
2821int
2822expand_a_rotate (code, operands)
2823 int code;
2824 rtx operands[];
2825{
2826 rtx dst = operands[0];
2827 rtx src = operands[1];
2828 rtx rotate_amount = operands[2];
2829 enum machine_mode mode = GET_MODE (dst);
2830 rtx tmp;
2831
2832 /* We rotate in place. */
2833 emit_move_insn (dst, src);
2834
2835 if (GET_CODE (rotate_amount) != CONST_INT)
2836 {
2837 rtx counter = gen_reg_rtx (QImode);
2838 rtx start_label = gen_label_rtx ();
2839 rtx end_label = gen_label_rtx ();
2840
2841 /* If the rotate amount is less than or equal to 0,
2842 we go out of the loop. */
2843 emit_cmp_and_jump_insns (rotate_amount, GEN_INT (0),
2844 LE, NULL_RTX, QImode, 0, 0, end_label);
2845
2846 /* Initialize the loop counter. */
2847 emit_move_insn (counter, rotate_amount);
2848
2849 emit_label (start_label);
2850
2851 /* Rotate by one bit. */
2852 tmp = gen_rtx (code, mode, dst, GEN_INT (1));
2853 emit_insn (gen_rtx_SET (mode, dst, tmp));
2854
2855 /* Decrement the counter by 1. */
2856 tmp = gen_rtx_PLUS (QImode, counter, GEN_INT (-1));
2857 emit_insn (gen_rtx_SET (VOIDmode, counter, tmp));
2858
2859 /* If the loop counter is non-zero, we go back to the beginning
2860 of the loop. */
2861 emit_cmp_and_jump_insns (counter, GEN_INT (0),
2862 NE, NULL_RTX, QImode, 1, 0, start_label);
2863
2864 emit_label (end_label);
2865 }
2866 else
2867 {
2868 /* Rotate by AMOUNT bits. */
2869 tmp = gen_rtx (code, mode, dst, rotate_amount);
2870 emit_insn (gen_rtx_SET (mode, dst, tmp));
2871 }
2872
2873 return 1;
2874}
2875
2876/* Emit rotate insns. */
2877
2878const char *
2879emit_a_rotate (code, operands)
2880 int code;
2881 rtx *operands;
2882{
2883 rtx dst = operands[0];
2884 rtx rotate_amount = operands[2];
2885 enum shift_mode rotate_mode;
2886 enum shift_type rotate_type;
2887 const char *insn_buf;
2888 int bits;
2889 int amount;
2890 enum machine_mode mode = GET_MODE (dst);
2891
2892 if (GET_CODE (rotate_amount) != CONST_INT)
2893 abort ();
2894
2895 switch (mode)
2896 {
2897 case QImode:
2898 rotate_mode = QIshift;
2899 break;
2900 case HImode:
2901 rotate_mode = HIshift;
2902 break;
2903 case SImode:
2904 rotate_mode = SIshift;
2905 break;
2906 default:
2907 abort ();
2908 }
2909
2910 switch (code)
2911 {
2912 case ROTATERT:
2913 rotate_type = SHIFT_ASHIFT;
2914 break;
2915 case ROTATE:
2916 rotate_type = SHIFT_LSHIFTRT;
2917 break;
2918 default:
2919 abort ();
2920 }
2921
2922 amount = INTVAL (rotate_amount);
2923
2924 /* Clean up AMOUNT. */
2925 if (amount < 0)
2926 amount = 0;
2927 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
2928 amount = GET_MODE_BITSIZE (mode);
2929
2930 /* Determine the faster direction. After this phase, amount will be
2931 at most a half of GET_MODE_BITSIZE (mode). */
2932 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / 2)
2933 {
2934 /* Flip the direction. */
2935 amount = GET_MODE_BITSIZE (mode) - amount;
2936 rotate_type =
2937 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
2938 }
2939
2940 /* See if a byte swap (in HImode) or a word swap (in SImode) can
2941 boost up the rotation. */
2942 if ((mode == HImode && TARGET_H8300 && amount >= 5)
2943 || (mode == HImode && TARGET_H8300H && amount >= 6)
2944 || (mode == HImode && TARGET_H8300S && amount == 8)
2945 || (mode == SImode && TARGET_H8300H && amount >= 10)
2946 || (mode == SImode && TARGET_H8300S && amount >= 13))
2947 {
2948 switch (mode)
2949 {
2950 case HImode:
2951 /* This code works on any family. */
2952 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
2953 output_asm_insn (insn_buf, operands);
2954 break;
2955
2956 case SImode:
2957 /* This code works on the H8/300H and H8/S. */
2958 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
2959 output_asm_insn (insn_buf, operands);
2960 break;
2961
2962 default:
2963 abort ();
2964 }
2965
2966 /* Adjust AMOUNT and flip the direction. */
2967 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
2968 rotate_type =
2969 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
2970 }
2971
2972 /* Emit rotate insns. */
2973 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2)
2974 {
2975 if (bits == 2)
2976 insn_buf = rotate_two[rotate_type][rotate_mode];
2977 else
2978 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode];
a86fab2e 2979
b4fa7cf2 2980 for (; amount >= bits; amount -= bits)
2981 output_asm_insn (insn_buf, operands);
2982 }
2983
2984 return "";
2985}
2986\f
b839e0b4 2987/* Fix the operands of a gen_xxx so that it could become a bit
a86fab2e 2988 operating insn. */
e1629549 2989
2990int
b839e0b4 2991fix_bit_operand (operands, what, type)
2992 rtx *operands;
9305fe33 2993 int what;
b839e0b4 2994 enum rtx_code type;
e1629549 2995{
b090827b 2996 /* The bit_operand predicate accepts any memory during RTL generation, but
b839e0b4 2997 only 'U' memory afterwards, so if this is a MEM operand, we must force
2998 it to be valid for 'U' by reloading the address. */
e1629549 2999
b839e0b4 3000 if (GET_CODE (operands[2]) == CONST_INT)
e1629549 3001 {
b839e0b4 3002 if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), what))
3003 {
3004 /* Ok to have a memory dest. */
27276a3b 3005 if (GET_CODE (operands[0]) == MEM
3006 && !EXTRA_CONSTRAINT (operands[0], 'U'))
b839e0b4 3007 {
7014838c 3008 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
3009 copy_to_mode_reg (Pmode,
3010 XEXP (operands[0], 0)));
6a0934dd 3011 MEM_COPY_ATTRIBUTES (mem, operands[0]);
b839e0b4 3012 operands[0] = mem;
3013 }
3014
27276a3b 3015 if (GET_CODE (operands[1]) == MEM
3016 && !EXTRA_CONSTRAINT (operands[1], 'U'))
b839e0b4 3017 {
7014838c 3018 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
3019 copy_to_mode_reg (Pmode,
3020 XEXP (operands[1], 0)));
6a0934dd 3021 MEM_COPY_ATTRIBUTES (mem, operands[0]);
b839e0b4 3022 operands[1] = mem;
3023 }
3024 return 0;
3025 }
3026 }
e1629549 3027
b839e0b4 3028 /* Dest and src op must be register. */
e1629549 3029
b839e0b4 3030 operands[1] = force_reg (QImode, operands[1]);
3031 {
3032 rtx res = gen_reg_rtx (QImode);
7014838c 3033 emit_insn (gen_rtx_SET (VOIDmode, res,
3034 gen_rtx (type, QImode, operands[1], operands[2])));
3035 emit_insn (gen_rtx_SET (VOIDmode, operands[0], res));
b839e0b4 3036 }
3037 return 1;
e1629549 3038}
b11bfc61 3039
b11bfc61 3040/* Return nonzero if FUNC is an interrupt function as specified
3041 by the "interrupt" attribute. */
3042
3043static int
3044h8300_interrupt_function_p (func)
3045 tree func;
3046{
3047 tree a;
3048
3049 if (TREE_CODE (func) != FUNCTION_DECL)
3050 return 0;
3051
e3c541f0 3052 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
b11bfc61 3053 return a != NULL_TREE;
3054}
3055
09c48b9c 3056/* Return nonzero if FUNC is an OS_Task function as specified
3057 by the "OS_Task" attribute. */
3058
3059static int
3060h8300_os_task_function_p (func)
3061 tree func;
3062{
3063 tree a;
3064
3065 if (TREE_CODE (func) != FUNCTION_DECL)
3066 return 0;
3067
e3c541f0 3068 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func));
09c48b9c 3069 return a != NULL_TREE;
3070}
3071
3072/* Return nonzero if FUNC is a monitor function as specified
3073 by the "monitor" attribute. */
3074
3075static int
3076h8300_monitor_function_p (func)
3077 tree func;
3078{
3079 tree a;
3080
3081 if (TREE_CODE (func) != FUNCTION_DECL)
3082 return 0;
3083
e3c541f0 3084 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func));
09c48b9c 3085 return a != NULL_TREE;
3086}
3087
b11bfc61 3088/* Return nonzero if FUNC is a function that should be called
3089 through the function vector. */
3090
3091int
3092h8300_funcvec_function_p (func)
3093 tree func;
3094{
3095 tree a;
3096
3097 if (TREE_CODE (func) != FUNCTION_DECL)
3098 return 0;
3099
e3c541f0 3100 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func));
b11bfc61 3101 return a != NULL_TREE;
3102}
3103
27a0be8f 3104/* Return nonzero if DECL is a variable that's in the eight bit
2c7be643 3105 data area. */
3106
3107int
9d3caf0b 3108h8300_eightbit_data_p (decl)
2c7be643 3109 tree decl;
3110{
3111 tree a;
3112
3113 if (TREE_CODE (decl) != VAR_DECL)
3114 return 0;
3115
e3c541f0 3116 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl));
2c7be643 3117 return a != NULL_TREE;
3118}
3119
27a0be8f 3120/* Return nonzero if DECL is a variable that's in the tiny
3121 data area. */
3122
3123int
3124h8300_tiny_data_p (decl)
3125 tree decl;
3126{
3127 tree a;
3128
3129 if (TREE_CODE (decl) != VAR_DECL)
3130 return 0;
3131
e3c541f0 3132 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl));
27a0be8f 3133 return a != NULL_TREE;
3134}
3135
e3c541f0 3136/* Supported attributes:
b11bfc61 3137
bd297402 3138 interrupt_handler: output a prologue and epilogue suitable for an
b11bfc61 3139 interrupt handler.
3140
bd297402 3141 function_vector: This function should be called through the
27a0be8f 3142 function vector.
3143
3144 eightbit_data: This variable lives in the 8-bit data area and can
3145 be referenced with 8-bit absolute memory addresses.
3146
3147 tiny_data: This variable lives in the tiny data area and can be
3148 referenced with 16-bit absolute memory references. */
b11bfc61 3149
e3c541f0 3150const struct attribute_spec h8300_attribute_table[] =
b11bfc61 3151{
e3c541f0 3152 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
3153 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3154 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3155 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3156 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3157 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute },
3158 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute },
3159 { NULL, 0, 0, false, false, false, NULL }
3160};
b11bfc61 3161
2c7be643 3162
e3c541f0 3163/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
3164 struct attribute_spec.handler. */
3165static tree
3166h8300_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
3167 tree *node;
3168 tree name;
3169 tree args ATTRIBUTE_UNUSED;
3170 int flags ATTRIBUTE_UNUSED;
3171 bool *no_add_attrs;
3172{
3173 if (TREE_CODE (*node) != FUNCTION_DECL)
3174 {
3175 warning ("`%s' attribute only applies to functions",
3176 IDENTIFIER_POINTER (name));
3177 *no_add_attrs = true;
3178 }
3179
3180 return NULL_TREE;
3181}
3182
3183/* Handle an "eightbit_data" attribute; arguments as in
3184 struct attribute_spec.handler. */
3185static tree
3186h8300_handle_eightbit_data_attribute (node, name, args, flags, no_add_attrs)
3187 tree *node;
3188 tree name;
3189 tree args ATTRIBUTE_UNUSED;
3190 int flags ATTRIBUTE_UNUSED;
3191 bool *no_add_attrs;
3192{
3193 tree decl = *node;
3194
3195 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
2c7be643 3196 {
3197 if (DECL_INITIAL (decl) == NULL_TREE)
3198 {
3199 warning ("Only initialized variables can be placed into the 8-bit area.");
e3c541f0 3200 *no_add_attrs = true;
2c7be643 3201 }
e3c541f0 3202 else
3203 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
3204 }
3205 else
3206 {
3207 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3208 *no_add_attrs = true;
27a0be8f 3209 }
3210
e3c541f0 3211 return NULL_TREE;
3212}
3213
3214/* Handle an "tiny_data" attribute; arguments as in
3215 struct attribute_spec.handler. */
3216static tree
3217h8300_handle_tiny_data_attribute (node, name, args, flags, no_add_attrs)
3218 tree *node;
3219 tree name;
3220 tree args ATTRIBUTE_UNUSED;
3221 int flags ATTRIBUTE_UNUSED;
3222 bool *no_add_attrs;
3223{
3224 tree decl = *node;
3225
3226 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
27a0be8f 3227 {
3228 if (DECL_INITIAL (decl) == NULL_TREE)
3229 {
3230 warning ("Only initialized variables can be placed into the 8-bit area.");
e3c541f0 3231 *no_add_attrs = true;
27a0be8f 3232 }
e3c541f0 3233 else
3234 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
3235 }
3236 else
3237 {
3238 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3239 *no_add_attrs = true;
2c7be643 3240 }
eb2aa24e 3241
e3c541f0 3242 return NULL_TREE;
b11bfc61 3243}
3244
9305fe33 3245void
27a0be8f 3246h8300_encode_label (decl)
3247 tree decl;
3248{
9305fe33 3249 const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
27a0be8f 3250 int len = strlen (str);
b8d11217 3251 char *newstr = alloca (len + 2);
27a0be8f 3252
b8d11217 3253 newstr[0] = '&';
3254 strcpy (&newstr[1], str);
27a0be8f 3255
b8d11217 3256 XSTR (XEXP (DECL_RTL (decl), 0), 0) =
3257 ggc_alloc_string (newstr, len + 1);
27a0be8f 3258}
3259
9305fe33 3260const char *
92eae32b 3261output_simode_bld (bild, log2, operands)
3262 int bild;
3263 int log2;
3264 rtx operands[];
3265{
3266 /* Clear the destination register. */
69b4e418 3267 if (TARGET_H8300H || TARGET_H8300S)
92eae32b 3268 output_asm_insn ("sub.l\t%S0,%S0", operands);
3269 else
3270 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
3271
3272 /* Get the bit number we want to load. */
3273 if (log2)
3274 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
3275
3276 /* Now output the bit load or bit inverse load, and store it in
3277 the destination. */
3278 if (bild)
3279 output_asm_insn ("bild\t%Z2,%Y1\n\tbst\t#0,%w0", operands);
3280 else
3281 output_asm_insn ("bld\t%Z2,%Y1\n\tbst\t#0,%w0", operands);
3282
3283 /* All done. */
3284 return "";
3285}
fe19f1e0 3286
9e042f31 3287/* Given INSN and its current length LENGTH, return the adjustment
fe19f1e0 3288 (in bytes) to correctly compute INSN's length.
3289
3290 We use this to get the lengths of various memory references correct. */
3291
9305fe33 3292int
fe19f1e0 3293h8300_adjust_insn_length (insn, length)
3294 rtx insn;
9305fe33 3295 int length ATTRIBUTE_UNUSED;
fe19f1e0 3296{
8d0fbce4 3297 rtx pat;
3298
8a040e41 3299 /* We must filter these ou before calling get_attr_adjust_length. */
3300 if (GET_CODE (PATTERN (insn)) == USE
3301 || GET_CODE (PATTERN (insn)) == CLOBBER
4bd2ebc6 3302 || GET_CODE (PATTERN (insn)) == SEQUENCE
3303 || GET_CODE (PATTERN (insn)) == ADDR_VEC
3304 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
8a040e41 3305 return 0;
3306
8d0fbce4 3307 if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO)
3308 return 0;
3309
3310 pat = PATTERN (insn);
fe19f1e0 3311
3312 /* Adjust length for reg->mem and mem->reg copies. */
3313 if (GET_CODE (pat) == SET
3314 && (GET_CODE (SET_SRC (pat)) == MEM
3315 || GET_CODE (SET_DEST (pat)) == MEM))
3316 {
3317 /* This insn might need a length adjustment. */
3318 rtx addr;
3319
3320 if (GET_CODE (SET_SRC (pat)) == MEM)
3321 addr = XEXP (SET_SRC (pat), 0);
3322 else
3323 addr = XEXP (SET_DEST (pat), 0);
3324
3325 /* On the H8/300, only one adjustment is necessary; if the
3326 address mode is register indirect, then this insn is two
3327 bytes shorter than indicated in the machine description. */
3328 if (TARGET_H8300 && GET_CODE (addr) == REG)
3329 return -2;
3330
69b4e418 3331 /* On the H8/300H and H8/S, register indirect is 6 bytes shorter than
fe19f1e0 3332 indicated in the machine description. */
69b4e418 3333 if ((TARGET_H8300H || TARGET_H8300S)
3334 && GET_CODE (addr) == REG)
fe19f1e0 3335 return -6;
3336
69b4e418 3337 /* On the H8/300H and H8/300S, reg + d, for small displacements is 4
3338 bytes shorter than indicated in the machine description. */
3339 if ((TARGET_H8300H || TARGET_H8300S)
fe19f1e0 3340 && GET_CODE (addr) == PLUS
3341 && GET_CODE (XEXP (addr, 0)) == REG
3342 && GET_CODE (XEXP (addr, 1)) == CONST_INT
3343 && INTVAL (XEXP (addr, 1)) > -32768
3344 && INTVAL (XEXP (addr, 1)) < 32767)
3345 return -4;
27a0be8f 3346
69b4e418 3347 /* On the H8/300H and H8/300S, abs:16 is two bytes shorter than the
27a0be8f 3348 more general abs:24. */
69b4e418 3349 if ((TARGET_H8300H || TARGET_H8300S)
27a0be8f 3350 && GET_CODE (addr) == SYMBOL_REF
3351 && TINY_DATA_NAME_P (XSTR (addr, 0)))
3352 return -2;
fe19f1e0 3353 }
3354
3355 /* Loading some constants needs adjustment. */
3356 if (GET_CODE (pat) == SET
3357 && GET_CODE (SET_SRC (pat)) == CONST_INT
3358 && GET_MODE (SET_DEST (pat)) == SImode
3359 && INTVAL (SET_SRC (pat)) != 0)
3360 {
53aec781 3361 int val = INTVAL (SET_SRC (pat));
3362
fe19f1e0 3363 if (TARGET_H8300
53aec781 3364 && ((val & 0xffff) == 0
3365 || ((val >> 16) & 0xffff) == 0))
fe19f1e0 3366 return -2;
3367
69b4e418 3368 if (TARGET_H8300H || TARGET_H8300S)
fe19f1e0 3369 {
fe19f1e0 3370 if (val == (val & 0xff)
3371 || val == (val & 0xff00))
3372 return -6;
3373
3374 if (val == -4 || val == -2 || val == -1)
3375 return -6;
3376 }
3377 }
3378
9addec68 3379 /* Shifts need various adjustments. */
3380 if (GET_CODE (pat) == PARALLEL
3381 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
3382 && (GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFTRT
eb2aa24e 3383 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == LSHIFTRT
3384 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFT))
9addec68 3385 {
3386 rtx src = SET_SRC (XVECEXP (pat, 0, 0));
3387 enum machine_mode mode = GET_MODE (src);
8d0fbce4 3388 int shift;
9addec68 3389
3390 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3391 return 0;
3392
8d0fbce4 3393 shift = INTVAL (XEXP (src, 1));
3394 /* According to ANSI, negative shift is undefined. It is
3395 considered to be zero in this case (see function
eb2aa24e 3396 emit_a_shift above). */
8d0fbce4 3397 if (shift < 0)
3398 shift = 0;
3399
9addec68 3400 /* QImode shifts by small constants take one insn
3401 per shift. So the adjustment is 20 (md length) -
3402 # shifts * 2. */
8d0fbce4 3403 if (mode == QImode && shift <= 4)
3404 return -(20 - shift * 2);
9addec68 3405
3406 /* Similarly for HImode and SImode shifts by
69b4e418 3407 small constants on the H8/300H and H8/300S. */
3408 if ((TARGET_H8300H || TARGET_H8300S)
8d0fbce4 3409 && (mode == HImode || mode == SImode) && shift <= 4)
3410 return -(20 - shift * 2);
9addec68 3411
3412 /* HImode shifts by small constants for the H8/300. */
8d0fbce4 3413 if (mode == HImode && shift <= 4)
3414 return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 2 : 4)));
9addec68 3415
3416 /* SImode shifts by small constants for the H8/300. */
8d0fbce4 3417 if (mode == SImode && shift <= 2)
3418 return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 6 : 8)));
9addec68 3419
3420 /* XXX ??? Could check for more shift/rotate cases here. */
3421 }
eb2aa24e 3422
b4fa7cf2 3423 /* Rotations need various adjustments. */
3424 if (GET_CODE (pat) == SET
3425 && (GET_CODE (SET_SRC (pat)) == ROTATE
3426 || GET_CODE (SET_SRC (pat)) == ROTATERT))
3427 {
3428 rtx src = SET_SRC (pat);
3429 enum machine_mode mode = GET_MODE (src);
3430 int amount;
3431 int states = 0;
3432
3433 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3434 return 0;
3435
3436 amount = INTVAL (XEXP (src, 1));
3437
3438 /* Clean up AMOUNT. */
3439 if (amount < 0)
3440 amount = 0;
3441 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3442 amount = GET_MODE_BITSIZE (mode);
3443
3444 /* Determine the faster direction. After this phase, amount
3445 will be at most a half of GET_MODE_BITSIZE (mode). */
3446 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / 2)
3447 /* Flip the direction. */
3448 amount = GET_MODE_BITSIZE (mode) - amount;
3449
3450 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3451 boost up the rotation. */
3452 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3453 || (mode == HImode && TARGET_H8300H && amount >= 6)
3454 || (mode == HImode && TARGET_H8300S && amount == 8)
3455 || (mode == SImode && TARGET_H8300H && amount >= 10)
3456 || (mode == SImode && TARGET_H8300S && amount >= 13))
3457 {
3458 /* Adjust AMOUNT and flip the direction. */
3459 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3460 states += 6;
3461 }
3462
3463 /* We use 2-bit rotatations on the H8/S. */
3464 if (TARGET_H8300S)
3465 amount = amount / 2 + amount % 2;
3466
3467 /* The H8/300 uses three insns to rotate one bit, taking 6
3468 states. */
3469 states += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2);
3470
3471 return -(20 - states);
3472 }
3473
fe19f1e0 3474 return 0;
3475}
2cb4ac60 3476
3477static void
29a0ebee 3478h8300_asm_named_section (name, flags)
2cb4ac60 3479 const char *name;
3480 unsigned int flags ATTRIBUTE_UNUSED;
2cb4ac60 3481{
3482 /* ??? Perhaps we should be using default_coff_asm_named_section. */
3483 fprintf (asm_out_file, "\t.section %s\n", name);
3484}