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