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