Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/h8300/h8300.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Subroutines for insn-output.c for Renesas H8/300. | 1 /* Subroutines for insn-output.c for Renesas H8/300. |
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, | 2 Copyright (C) 1992-2017 Free Software Foundation, Inc. |
3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 | |
4 Free Software Foundation, Inc. | |
5 Contributed by Steve Chamberlain (sac@cygnus.com), | 3 Contributed by Steve Chamberlain (sac@cygnus.com), |
6 Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com). | 4 Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com). |
7 | 5 |
8 This file is part of GCC. | 6 This file is part of GCC. |
9 | 7 |
22 <http://www.gnu.org/licenses/>. */ | 20 <http://www.gnu.org/licenses/>. */ |
23 | 21 |
24 #include "config.h" | 22 #include "config.h" |
25 #include "system.h" | 23 #include "system.h" |
26 #include "coretypes.h" | 24 #include "coretypes.h" |
27 #include "tm.h" | 25 #include "backend.h" |
26 #include "target.h" | |
28 #include "rtl.h" | 27 #include "rtl.h" |
29 #include "tree.h" | 28 #include "tree.h" |
29 #include "df.h" | |
30 #include "memmodel.h" | |
31 #include "tm_p.h" | |
32 #include "stringpool.h" | |
33 #include "attribs.h" | |
34 #include "optabs.h" | |
30 #include "regs.h" | 35 #include "regs.h" |
31 #include "hard-reg-set.h" | 36 #include "emit-rtl.h" |
32 #include "insn-config.h" | 37 #include "recog.h" |
38 #include "diagnostic-core.h" | |
39 #include "alias.h" | |
40 #include "stor-layout.h" | |
41 #include "varasm.h" | |
42 #include "calls.h" | |
33 #include "conditions.h" | 43 #include "conditions.h" |
34 #include "output.h" | 44 #include "output.h" |
35 #include "insn-attr.h" | 45 #include "insn-attr.h" |
36 #include "flags.h" | 46 #include "flags.h" |
37 #include "recog.h" | 47 #include "explow.h" |
38 #include "expr.h" | 48 #include "expr.h" |
39 #include "function.h" | 49 #include "tm-constrs.h" |
40 #include "optabs.h" | 50 #include "builtins.h" |
41 #include "diagnostic-core.h" | 51 |
42 #include "c-family/c-pragma.h" /* ??? */ | 52 /* This file should be included last. */ |
43 #include "tm_p.h" | |
44 #include "ggc.h" | |
45 #include "target.h" | |
46 #include "target-def.h" | 53 #include "target-def.h" |
47 #include "df.h" | |
48 | 54 |
49 /* Classifies a h8300_src_operand or h8300_dst_operand. | 55 /* Classifies a h8300_src_operand or h8300_dst_operand. |
50 | 56 |
51 H8OP_IMMEDIATE | 57 H8OP_IMMEDIATE |
52 A constant operand of some sort. | 58 A constant operand of some sort. |
84 static int h8300_monitor_function_p (tree); | 90 static int h8300_monitor_function_p (tree); |
85 static int h8300_os_task_function_p (tree); | 91 static int h8300_os_task_function_p (tree); |
86 static void h8300_emit_stack_adjustment (int, HOST_WIDE_INT, bool); | 92 static void h8300_emit_stack_adjustment (int, HOST_WIDE_INT, bool); |
87 static HOST_WIDE_INT round_frame_size (HOST_WIDE_INT); | 93 static HOST_WIDE_INT round_frame_size (HOST_WIDE_INT); |
88 static unsigned int compute_saved_regs (void); | 94 static unsigned int compute_saved_regs (void); |
89 static void push (int); | |
90 static void pop (int); | |
91 static const char *cond_string (enum rtx_code); | 95 static const char *cond_string (enum rtx_code); |
92 static unsigned int h8300_asm_insn_count (const char *); | 96 static unsigned int h8300_asm_insn_count (const char *); |
93 static tree h8300_handle_fndecl_attribute (tree *, tree, tree, int, bool *); | 97 static tree h8300_handle_fndecl_attribute (tree *, tree, tree, int, bool *); |
94 static tree h8300_handle_eightbit_data_attribute (tree *, tree, tree, int, bool *); | 98 static tree h8300_handle_eightbit_data_attribute (tree *, tree, tree, int, bool *); |
95 static tree h8300_handle_tiny_data_attribute (tree *, tree, tree, int, bool *); | 99 static tree h8300_handle_tiny_data_attribute (tree *, tree, tree, int, bool *); |
100 static void h8300_print_operand_address (FILE *, machine_mode, rtx); | |
101 static void h8300_print_operand (FILE *, rtx, int); | |
102 static bool h8300_print_operand_punct_valid_p (unsigned char code); | |
96 #ifndef OBJECT_FORMAT_ELF | 103 #ifndef OBJECT_FORMAT_ELF |
97 static void h8300_asm_named_section (const char *, unsigned int, tree); | 104 static void h8300_asm_named_section (const char *, unsigned int, tree); |
98 #endif | 105 #endif |
106 static int h8300_register_move_cost (machine_mode, reg_class_t, reg_class_t); | |
99 static int h8300_and_costs (rtx); | 107 static int h8300_and_costs (rtx); |
100 static int h8300_shift_costs (rtx); | 108 static int h8300_shift_costs (rtx); |
101 static void h8300_push_pop (int, int, bool, bool); | 109 static void h8300_push_pop (int, int, bool, bool); |
102 static int h8300_stack_offset_p (rtx, int); | 110 static int h8300_stack_offset_p (rtx, int); |
103 static int h8300_ldm_stm_regno (rtx, int, int, int); | 111 static int h8300_ldm_stm_regno (rtx, int, int, int); |
107 static unsigned int h8300_classify_operand (rtx, int, enum h8300_operand_class *); | 115 static unsigned int h8300_classify_operand (rtx, int, enum h8300_operand_class *); |
108 static unsigned int h8300_length_from_table (rtx, rtx, const h8300_length_table *); | 116 static unsigned int h8300_length_from_table (rtx, rtx, const h8300_length_table *); |
109 static unsigned int h8300_unary_length (rtx); | 117 static unsigned int h8300_unary_length (rtx); |
110 static unsigned int h8300_short_immediate_length (rtx); | 118 static unsigned int h8300_short_immediate_length (rtx); |
111 static unsigned int h8300_bitfield_length (rtx, rtx); | 119 static unsigned int h8300_bitfield_length (rtx, rtx); |
112 static unsigned int h8300_binary_length (rtx, const h8300_length_table *); | 120 static unsigned int h8300_binary_length (rtx_insn *, const h8300_length_table *); |
113 static bool h8300_short_move_mem_p (rtx, enum rtx_code); | 121 static bool h8300_short_move_mem_p (rtx, enum rtx_code); |
114 static unsigned int h8300_move_length (rtx *, const h8300_length_table *); | 122 static unsigned int h8300_move_length (rtx *, const h8300_length_table *); |
115 static bool h8300_hard_regno_scratch_ok (unsigned int); | 123 static bool h8300_hard_regno_scratch_ok (unsigned int); |
124 static rtx h8300_get_index (rtx, machine_mode mode, int *); | |
116 | 125 |
117 /* CPU_TYPE, says what cpu we're compiling for. */ | 126 /* CPU_TYPE, says what cpu we're compiling for. */ |
118 int cpu_type; | 127 int cpu_type; |
119 | 128 |
120 /* True if a #pragma interrupt has been seen for the current function. */ | 129 /* True if a #pragma interrupt has been seen for the current function. */ |
301 H8_300, | 310 H8_300, |
302 H8_300H, | 311 H8_300H, |
303 H8_S | 312 H8_S |
304 }; | 313 }; |
305 | 314 |
306 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ | |
307 | |
308 static const struct default_options h8300_option_optimization_table[] = | |
309 { | |
310 /* Basic block reordering is only beneficial on targets with cache | |
311 and/or variable-cycle branches where (cycle count taken != | |
312 cycle count not taken). */ | |
313 { OPT_LEVELS_ALL, OPT_freorder_blocks, NULL, 0 }, | |
314 { OPT_LEVELS_NONE, 0, NULL, 0 } | |
315 }; | |
316 | |
317 /* Initialize various cpu specific globals at start up. */ | 315 /* Initialize various cpu specific globals at start up. */ |
318 | 316 |
319 static void | 317 static void |
320 h8300_option_override (void) | 318 h8300_option_override (void) |
321 { | 319 { |
322 static const char *const h8_push_ops[2] = { "push" , "push.l" }; | 320 static const char *const h8_push_ops[2] = { "push" , "push.l" }; |
323 static const char *const h8_pop_ops[2] = { "pop" , "pop.l" }; | 321 static const char *const h8_pop_ops[2] = { "pop" , "pop.l" }; |
324 static const char *const h8_mov_ops[2] = { "mov.w", "mov.l" }; | 322 static const char *const h8_mov_ops[2] = { "mov.w", "mov.l" }; |
325 | 323 |
324 #ifndef OBJECT_FORMAT_ELF | |
325 if (TARGET_H8300SX) | |
326 { | |
327 error ("-msx is not supported in coff"); | |
328 target_flags |= MASK_H8300S; | |
329 } | |
330 #endif | |
331 | |
326 if (TARGET_H8300) | 332 if (TARGET_H8300) |
327 { | 333 { |
328 cpu_type = (int) CPU_H8300; | 334 cpu_type = (int) CPU_H8300; |
329 h8_reg_names = names_big; | 335 h8_reg_names = names_big; |
330 } | 336 } |
344 target_flags |= MASK_H8300S_1; | 350 target_flags |= MASK_H8300S_1; |
345 } | 351 } |
346 | 352 |
347 if (TARGET_H8300 && TARGET_NORMAL_MODE) | 353 if (TARGET_H8300 && TARGET_NORMAL_MODE) |
348 { | 354 { |
349 error ("-mn is used without -mh or -ms"); | 355 error ("-mn is used without -mh or -ms or -msx"); |
350 target_flags ^= MASK_NORMAL_MODE; | 356 target_flags ^= MASK_NORMAL_MODE; |
351 } | 357 } |
358 | |
359 if (! TARGET_H8300S && TARGET_EXR) | |
360 { | |
361 error ("-mexr is used without -ms"); | |
362 target_flags |= MASK_H8300S_1; | |
363 } | |
364 | |
365 if (TARGET_H8300 && TARGET_INT32) | |
366 { | |
367 error ("-mint32 is not supported for H8300 and H8300L targets"); | |
368 target_flags ^= MASK_INT32; | |
369 } | |
370 | |
371 if ((!TARGET_H8300S && TARGET_EXR) && (!TARGET_H8300SX && TARGET_EXR)) | |
372 { | |
373 error ("-mexr is used without -ms or -msx"); | |
374 target_flags |= MASK_H8300S_1; | |
375 } | |
376 | |
377 if ((!TARGET_H8300S && TARGET_NEXR) && (!TARGET_H8300SX && TARGET_NEXR)) | |
378 { | |
379 warning (OPT_mno_exr, "-mno-exr valid only with -ms or -msx \ | |
380 - Option ignored!"); | |
381 } | |
382 | |
383 #ifdef H8300_LINUX | |
384 if ((TARGET_NORMAL_MODE)) | |
385 { | |
386 error ("-mn is not supported for linux targets"); | |
387 target_flags ^= MASK_NORMAL_MODE; | |
388 } | |
389 #endif | |
352 | 390 |
353 /* Some of the shifts are optimized for speed by default. | 391 /* Some of the shifts are optimized for speed by default. |
354 See http://gcc.gnu.org/ml/gcc-patches/2002-07/msg01858.html | 392 See http://gcc.gnu.org/ml/gcc-patches/2002-07/msg01858.html |
355 If optimizing for size, change shift_alg for those shift to | 393 If optimizing for size, change shift_alg for those shift to |
356 SHIFT_LOOP. */ | 394 SHIFT_LOOP. */ |
414 restore er6 though, so bump up the cost. */ | 452 restore er6 though, so bump up the cost. */ |
415 h8300_move_ratio = 6; | 453 h8300_move_ratio = 6; |
416 } | 454 } |
417 | 455 |
418 /* This target defaults to strict volatile bitfields. */ | 456 /* This target defaults to strict volatile bitfields. */ |
419 if (flag_strict_volatile_bitfields < 0) | 457 if (flag_strict_volatile_bitfields < 0 && abi_version_at_least(2)) |
420 flag_strict_volatile_bitfields = 1; | 458 flag_strict_volatile_bitfields = 1; |
421 } | |
422 | |
423 /* Implement REG_CLASS_FROM_LETTER. | |
424 | |
425 Some patterns need to use er6 as a scratch register. This is | |
426 difficult to arrange since er6 is the frame pointer and usually | |
427 can't be spilled. | |
428 | |
429 Such patterns should define two alternatives, one which allows only | |
430 er6 and one which allows any general register. The former alternative | |
431 should have a 'd' constraint while the latter should be disparaged and | |
432 use 'D'. | |
433 | |
434 Normally, 'd' maps to DESTINATION_REGS and 'D' maps to GENERAL_REGS. | |
435 However, there are cases where they should be NO_REGS: | |
436 | |
437 - 'd' should be NO_REGS when reloading a function that uses the | |
438 frame pointer. In this case, DESTINATION_REGS won't contain any | |
439 spillable registers, so the first alternative can't be used. | |
440 | |
441 - -fno-omit-frame-pointer means that the frame pointer will | |
442 always be in use. It's therefore better to map 'd' to NO_REGS | |
443 before reload so that register allocator will pick the second | |
444 alternative. | |
445 | |
446 - we would like 'D' to be be NO_REGS when the frame pointer isn't | |
447 live, but we the frame pointer may turn out to be needed after | |
448 we start reload, and then we may have already decided we don't | |
449 have a choice, so we can't do that. Forcing the register | |
450 allocator to use er6 if possible might produce better code for | |
451 small functions: it's more efficient to save and restore er6 in | |
452 the prologue & epilogue than to do it in a define_split. | |
453 Hopefully disparaging 'D' will have a similar effect, without | |
454 forcing a reload failure if the frame pointer is found to be | |
455 needed too late. */ | |
456 | |
457 enum reg_class | |
458 h8300_reg_class_from_letter (int c) | |
459 { | |
460 switch (c) | |
461 { | |
462 case 'a': | |
463 return MAC_REGS; | |
464 | |
465 case 'c': | |
466 return COUNTER_REGS; | |
467 | |
468 case 'd': | |
469 if (!flag_omit_frame_pointer && !reload_completed) | |
470 return NO_REGS; | |
471 if (frame_pointer_needed && reload_in_progress) | |
472 return NO_REGS; | |
473 return DESTINATION_REGS; | |
474 | |
475 case 'D': | |
476 /* The meaning of a constraint shouldn't change dynamically, so | |
477 we can't make this NO_REGS. */ | |
478 return GENERAL_REGS; | |
479 | |
480 case 'f': | |
481 return SOURCE_REGS; | |
482 | |
483 default: | |
484 return NO_REGS; | |
485 } | |
486 } | 459 } |
487 | 460 |
488 /* Return the byte register name for a register rtx X. B should be 0 | 461 /* Return the byte register name for a register rtx X. B should be 0 |
489 if you want a lower byte register. B should be 1 if you want an | 462 if you want a lower byte register. B should be 1 if you want an |
490 upper byte register. */ | 463 upper byte register. */ |
518 && df_regs_ever_live_p (regno)) \ | 491 && df_regs_ever_live_p (regno)) \ |
519 /* Save call clobbered registers in non-leaf interrupt \ | 492 /* Save call clobbered registers in non-leaf interrupt \ |
520 handlers. */ \ | 493 handlers. */ \ |
521 || (h8300_current_function_interrupt_function_p () \ | 494 || (h8300_current_function_interrupt_function_p () \ |
522 && call_used_regs[regno] \ | 495 && call_used_regs[regno] \ |
523 && !current_function_is_leaf))) | 496 && !crtl->is_leaf))) |
524 | 497 |
525 /* We use this to wrap all emitted insns in the prologue. */ | 498 /* We use this to wrap all emitted insns in the prologue. */ |
526 static rtx | 499 static rtx_insn * |
527 F (rtx x, bool set_it) | 500 F (rtx_insn *x, bool set_it) |
528 { | 501 { |
529 if (set_it) | 502 if (set_it) |
530 RTX_FRAME_RELATED_P (x) = 1; | 503 RTX_FRAME_RELATED_P (x) = 1; |
531 return x; | 504 return x; |
532 } | 505 } |
542 { | 515 { |
543 int len = XVECLEN (par, 0); | 516 int len = XVECLEN (par, 0); |
544 int i; | 517 int i; |
545 | 518 |
546 for (i = 0; i < len; i++) | 519 for (i = 0; i < len; i++) |
547 F (XVECEXP (par, 0, i), true); | 520 RTX_FRAME_RELATED_P (XVECEXP (par, 0, i)) = 1; |
548 | 521 |
549 return par; | 522 return par; |
550 } | 523 } |
551 | 524 |
552 /* Output assembly language to FILE for the operation OP with operand size | 525 /* Output assembly language to FILE for the operation OP with operand size |
579 addition emitted here to make the adjustment interrupt-safe. | 552 addition emitted here to make the adjustment interrupt-safe. |
580 FIXME: We don't always tag those, because we don't know what | 553 FIXME: We don't always tag those, because we don't know what |
581 the splitter will do. */ | 554 the splitter will do. */ |
582 if (Pmode == HImode) | 555 if (Pmode == HImode) |
583 { | 556 { |
584 rtx x = emit_insn (gen_addhi3 (stack_pointer_rtx, | 557 rtx_insn *x = emit_insn (gen_addhi3 (stack_pointer_rtx, |
585 stack_pointer_rtx, GEN_INT (sign * size))); | 558 stack_pointer_rtx, |
559 GEN_INT (sign * size))); | |
586 if (size < 4) | 560 if (size < 4) |
587 F (x, in_prologue); | 561 F (x, in_prologue); |
588 } | 562 } |
589 else | 563 else |
590 F (emit_insn (gen_addsi3 (stack_pointer_rtx, | 564 F (emit_insn (gen_addsi3 (stack_pointer_rtx, |
624 return saved_regs; | 598 return saved_regs; |
625 } | 599 } |
626 | 600 |
627 /* Emit an insn to push register RN. */ | 601 /* Emit an insn to push register RN. */ |
628 | 602 |
629 static void | 603 static rtx |
630 push (int rn) | 604 push (int rn, bool in_prologue) |
631 { | 605 { |
632 rtx reg = gen_rtx_REG (word_mode, rn); | 606 rtx reg = gen_rtx_REG (word_mode, rn); |
633 rtx x; | 607 rtx x; |
634 | 608 |
635 if (TARGET_H8300) | 609 if (TARGET_H8300) |
636 x = gen_push_h8300 (reg); | 610 x = gen_push_h8300 (reg); |
637 else if (!TARGET_NORMAL_MODE) | 611 else if (!TARGET_NORMAL_MODE) |
638 x = gen_push_h8300hs_advanced (reg); | 612 x = gen_push_h8300hs_advanced (reg); |
639 else | 613 else |
640 x = gen_push_h8300hs_normal (reg); | 614 x = gen_push_h8300hs_normal (reg); |
641 x = F (emit_insn (x), true); | 615 x = F (emit_insn (x), in_prologue); |
642 add_reg_note (x, REG_INC, stack_pointer_rtx); | 616 add_reg_note (x, REG_INC, stack_pointer_rtx); |
617 return x; | |
643 } | 618 } |
644 | 619 |
645 /* Emit an insn to pop register RN. */ | 620 /* Emit an insn to pop register RN. */ |
646 | 621 |
647 static void | 622 static rtx |
648 pop (int rn) | 623 pop (int rn) |
649 { | 624 { |
650 rtx reg = gen_rtx_REG (word_mode, rn); | 625 rtx reg = gen_rtx_REG (word_mode, rn); |
651 rtx x; | 626 rtx x; |
652 | 627 |
656 x = gen_pop_h8300hs_advanced (reg); | 631 x = gen_pop_h8300hs_advanced (reg); |
657 else | 632 else |
658 x = gen_pop_h8300hs_normal (reg); | 633 x = gen_pop_h8300hs_normal (reg); |
659 x = emit_insn (x); | 634 x = emit_insn (x); |
660 add_reg_note (x, REG_INC, stack_pointer_rtx); | 635 add_reg_note (x, REG_INC, stack_pointer_rtx); |
636 return x; | |
661 } | 637 } |
662 | 638 |
663 /* Emit an instruction to push or pop NREGS consecutive registers | 639 /* Emit an instruction to push or pop NREGS consecutive registers |
664 starting at register REGNO. POP_P selects a pop rather than a | 640 starting at register REGNO. POP_P selects a pop rather than a |
665 push and RETURN_P is true if the instruction should return. | 641 push and RETURN_P is true if the instruction should return. |
687 if (!return_p && nregs == 1) | 663 if (!return_p && nregs == 1) |
688 { | 664 { |
689 if (pop_p) | 665 if (pop_p) |
690 pop (regno); | 666 pop (regno); |
691 else | 667 else |
692 push (regno); | 668 push (regno, false); |
693 return; | 669 return; |
694 } | 670 } |
695 | 671 |
696 /* We need one element for the return insn, if present, one for each | 672 /* We need one element for the return insn, if present, one for each |
697 register, and one for stack adjustment. */ | 673 register, and one for stack adjustment. */ |
700 i = 0; | 676 i = 0; |
701 | 677 |
702 /* Add the return instruction. */ | 678 /* Add the return instruction. */ |
703 if (return_p) | 679 if (return_p) |
704 { | 680 { |
705 RTVEC_ELT (vec, i) = gen_rtx_RETURN (VOIDmode); | 681 RTVEC_ELT (vec, i) = ret_rtx; |
706 i++; | 682 i++; |
707 } | 683 } |
708 | 684 |
709 /* Add the register moves. */ | 685 /* Add the register moves. */ |
710 for (j = 0; j < nregs; j++) | 686 for (j = 0; j < nregs; j++) |
714 if (pop_p) | 690 if (pop_p) |
715 { | 691 { |
716 /* Register REGNO + NREGS - 1 is popped first. Before the | 692 /* Register REGNO + NREGS - 1 is popped first. Before the |
717 stack adjustment, its slot is at address @sp. */ | 693 stack adjustment, its slot is at address @sp. */ |
718 lhs = gen_rtx_REG (SImode, regno + j); | 694 lhs = gen_rtx_REG (SImode, regno + j); |
719 rhs = gen_rtx_MEM (SImode, plus_constant (sp, (nregs - j - 1) * 4)); | 695 rhs = gen_rtx_MEM (SImode, plus_constant (Pmode, sp, |
696 (nregs - j - 1) * 4)); | |
720 } | 697 } |
721 else | 698 else |
722 { | 699 { |
723 /* Register REGNO is pushed first and will be stored at @(-4,sp). */ | 700 /* Register REGNO is pushed first and will be stored at @(-4,sp). */ |
724 lhs = gen_rtx_MEM (SImode, plus_constant (sp, (j + 1) * -4)); | 701 lhs = gen_rtx_MEM (SImode, plus_constant (Pmode, sp, (j + 1) * -4)); |
725 rhs = gen_rtx_REG (SImode, regno + j); | 702 rhs = gen_rtx_REG (SImode, regno + j); |
726 } | 703 } |
727 RTVEC_ELT (vec, i + j) = gen_rtx_SET (VOIDmode, lhs, rhs); | 704 RTVEC_ELT (vec, i + j) = gen_rtx_SET (lhs, rhs); |
728 } | 705 } |
729 | 706 |
730 /* Add the stack adjustment. */ | 707 /* Add the stack adjustment. */ |
731 offset = GEN_INT ((pop_p ? nregs : -nregs) * 4); | 708 offset = GEN_INT ((pop_p ? nregs : -nregs) * 4); |
732 RTVEC_ELT (vec, i + j) = gen_rtx_SET (VOIDmode, sp, | 709 RTVEC_ELT (vec, i + j) = gen_rtx_SET (sp, gen_rtx_PLUS (Pmode, sp, offset)); |
733 gen_rtx_PLUS (Pmode, sp, offset)); | |
734 | 710 |
735 x = gen_rtx_PARALLEL (VOIDmode, vec); | 711 x = gen_rtx_PARALLEL (VOIDmode, vec); |
736 if (!pop_p) | 712 if (!pop_p) |
737 x = Fpa (x); | 713 x = Fpa (x); |
738 | 714 |
863 we have a naked prologue. */ | 839 we have a naked prologue. */ |
864 if (h8300_os_task_function_p (current_function_decl)) | 840 if (h8300_os_task_function_p (current_function_decl)) |
865 return; | 841 return; |
866 | 842 |
867 if (h8300_monitor_function_p (current_function_decl)) | 843 if (h8300_monitor_function_p (current_function_decl)) |
868 /* My understanding of monitor functions is they act just like | 844 /* The monitor function act as normal functions, which means it |
869 interrupt functions, except the prologue must mask | 845 can accept parameters and return values. In addition to this, |
870 interrupts. */ | 846 interrupts are masked in prologue and return with "rte" in epilogue. */ |
871 emit_insn (gen_monitor_prologue ()); | 847 emit_insn (gen_monitor_prologue ()); |
872 | 848 |
873 if (frame_pointer_needed) | 849 if (frame_pointer_needed) |
874 { | 850 { |
875 /* Push fp. */ | 851 /* Push fp. */ |
876 push (HARD_FRAME_POINTER_REGNUM); | 852 push (HARD_FRAME_POINTER_REGNUM, true); |
877 F (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx), true); | 853 F (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx), true); |
878 } | 854 } |
879 | 855 |
880 /* Push the rest of the registers in ascending order. */ | 856 /* Push the rest of the registers in ascending order. */ |
881 saved_regs = compute_saved_regs (); | 857 saved_regs = compute_saved_regs (); |
904 } | 880 } |
905 } | 881 } |
906 | 882 |
907 /* Leave room for locals. */ | 883 /* Leave room for locals. */ |
908 h8300_emit_stack_adjustment (-1, round_frame_size (get_frame_size ()), true); | 884 h8300_emit_stack_adjustment (-1, round_frame_size (get_frame_size ()), true); |
885 | |
886 if (flag_stack_usage_info) | |
887 current_function_static_stack_size | |
888 = round_frame_size (get_frame_size ()) | |
889 + (__builtin_popcount (saved_regs) * UNITS_PER_WORD) | |
890 + (frame_pointer_needed ? UNITS_PER_WORD : 0); | |
909 } | 891 } |
910 | 892 |
911 /* Return nonzero if we can use "rts" for the function currently being | 893 /* Return nonzero if we can use "rts" for the function currently being |
912 compiled. */ | 894 compiled. */ |
913 | 895 |
984 returned_p = true; | 966 returned_p = true; |
985 h8300_push_pop (HARD_FRAME_POINTER_REGNUM, 1, true, returned_p); | 967 h8300_push_pop (HARD_FRAME_POINTER_REGNUM, 1, true, returned_p); |
986 } | 968 } |
987 | 969 |
988 if (!returned_p) | 970 if (!returned_p) |
989 emit_jump_insn (gen_rtx_RETURN (VOIDmode)); | 971 emit_jump_insn (ret_rtx); |
990 } | 972 } |
991 | 973 |
992 /* Return nonzero if the current function is an interrupt | 974 /* Return nonzero if the current function is an interrupt |
993 function. */ | 975 function. */ |
994 | 976 |
995 int | 977 int |
996 h8300_current_function_interrupt_function_p (void) | 978 h8300_current_function_interrupt_function_p (void) |
997 { | 979 { |
998 return (h8300_interrupt_function_p (current_function_decl) | 980 return (h8300_interrupt_function_p (current_function_decl)); |
999 || h8300_monitor_function_p (current_function_decl)); | 981 } |
982 | |
983 int | |
984 h8300_current_function_monitor_function_p () | |
985 { | |
986 return (h8300_monitor_function_p (current_function_decl)); | |
1000 } | 987 } |
1001 | 988 |
1002 /* Output assembly code for the start of the file. */ | 989 /* Output assembly code for the start of the file. */ |
1003 | 990 |
1004 static void | 991 static void |
1005 h8300_file_start (void) | 992 h8300_file_start (void) |
1006 { | 993 { |
1007 default_file_start (); | 994 default_file_start (); |
1008 | 995 |
1009 if (TARGET_H8300H) | 996 if (TARGET_H8300SX) |
1010 fputs (TARGET_NORMAL_MODE ? "\t.h8300hn\n" : "\t.h8300h\n", asm_out_file); | |
1011 else if (TARGET_H8300SX) | |
1012 fputs (TARGET_NORMAL_MODE ? "\t.h8300sxn\n" : "\t.h8300sx\n", asm_out_file); | 997 fputs (TARGET_NORMAL_MODE ? "\t.h8300sxn\n" : "\t.h8300sx\n", asm_out_file); |
1013 else if (TARGET_H8300S) | 998 else if (TARGET_H8300S) |
1014 fputs (TARGET_NORMAL_MODE ? "\t.h8300sn\n" : "\t.h8300s\n", asm_out_file); | 999 fputs (TARGET_NORMAL_MODE ? "\t.h8300sn\n" : "\t.h8300s\n", asm_out_file); |
1000 else if (TARGET_H8300H) | |
1001 fputs (TARGET_NORMAL_MODE ? "\t.h8300hn\n" : "\t.h8300h\n", asm_out_file); | |
1015 } | 1002 } |
1016 | 1003 |
1017 /* Output assembly language code for the end of file. */ | 1004 /* Output assembly language code for the end of file. */ |
1018 | 1005 |
1019 static void | 1006 static void |
1026 | 1013 |
1027 If USE_INCDEC_P is nonzero, we generate the last insn using inc/dec | 1014 If USE_INCDEC_P is nonzero, we generate the last insn using inc/dec |
1028 instead of adds/subs. */ | 1015 instead of adds/subs. */ |
1029 | 1016 |
1030 void | 1017 void |
1031 split_adds_subs (enum machine_mode mode, rtx *operands) | 1018 split_adds_subs (machine_mode mode, rtx *operands) |
1032 { | 1019 { |
1033 HOST_WIDE_INT val = INTVAL (operands[1]); | 1020 HOST_WIDE_INT val = INTVAL (operands[1]); |
1034 rtx reg = operands[0]; | 1021 rtx reg = operands[0]; |
1035 HOST_WIDE_INT sign = 1; | 1022 HOST_WIDE_INT sign = 1; |
1036 HOST_WIDE_INT amount; | 1023 HOST_WIDE_INT amount; |
1044 sign = -1; | 1031 sign = -1; |
1045 } | 1032 } |
1046 | 1033 |
1047 switch (mode) | 1034 switch (mode) |
1048 { | 1035 { |
1049 case HImode: | 1036 case E_HImode: |
1050 gen_add = gen_addhi3; | 1037 gen_add = gen_addhi3; |
1051 break; | 1038 break; |
1052 | 1039 |
1053 case SImode: | 1040 case E_SImode: |
1054 gen_add = gen_addsi3; | 1041 gen_add = gen_addsi3; |
1055 break; | 1042 break; |
1056 | 1043 |
1057 default: | 1044 default: |
1058 gcc_unreachable (); | 1045 gcc_unreachable (); |
1099 | 1086 |
1100 On the H8/300 all normal args are pushed, unless -mquickcall in which | 1087 On the H8/300 all normal args are pushed, unless -mquickcall in which |
1101 case the first 3 arguments are passed in registers. */ | 1088 case the first 3 arguments are passed in registers. */ |
1102 | 1089 |
1103 static rtx | 1090 static rtx |
1104 h8300_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, | 1091 h8300_function_arg (cumulative_args_t cum_v, machine_mode mode, |
1105 const_tree type, bool named) | 1092 const_tree type, bool named) |
1106 { | 1093 { |
1094 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); | |
1095 | |
1107 static const char *const hand_list[] = { | 1096 static const char *const hand_list[] = { |
1108 "__main", | 1097 "__main", |
1109 "__cmpsi2", | 1098 "__cmpsi2", |
1110 "__divhi3", | 1099 "__divhi3", |
1111 "__modhi3", | 1100 "__modhi3", |
1170 /* Update the data in CUM to advance over an argument | 1159 /* Update the data in CUM to advance over an argument |
1171 of mode MODE and data type TYPE. | 1160 of mode MODE and data type TYPE. |
1172 (TYPE is null for libcalls where that information may not be available.) */ | 1161 (TYPE is null for libcalls where that information may not be available.) */ |
1173 | 1162 |
1174 static void | 1163 static void |
1175 h8300_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, | 1164 h8300_function_arg_advance (cumulative_args_t cum_v, machine_mode mode, |
1176 const_tree type, bool named ATTRIBUTE_UNUSED) | 1165 const_tree type, bool named ATTRIBUTE_UNUSED) |
1177 { | 1166 { |
1167 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); | |
1168 | |
1178 cum->nbytes += (mode != BLKmode | 1169 cum->nbytes += (mode != BLKmode |
1179 ? (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD | 1170 ? (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD |
1180 : (int_size_in_bytes (type) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD); | 1171 : (int_size_in_bytes (type) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD); |
1181 } | 1172 } |
1182 | 1173 |
1183 | 1174 |
1175 /* Implements TARGET_REGISTER_MOVE_COST. | |
1176 | |
1177 Any SI register-to-register move may need to be reloaded, | |
1178 so inmplement h8300_register_move_cost to return > 2 so that reload never | |
1179 shortcuts. */ | |
1180 | |
1181 static int | |
1182 h8300_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED, | |
1183 reg_class_t from, reg_class_t to) | |
1184 { | |
1185 if (from == MAC_REGS || to == MAC_REG) | |
1186 return 6; | |
1187 else | |
1188 return 3; | |
1189 } | |
1190 | |
1184 /* Compute the cost of an and insn. */ | 1191 /* Compute the cost of an and insn. */ |
1185 | 1192 |
1186 static int | 1193 static int |
1187 h8300_and_costs (rtx x) | 1194 h8300_and_costs (rtx x) |
1188 { | 1195 { |
1222 } | 1229 } |
1223 | 1230 |
1224 /* Worker function for TARGET_RTX_COSTS. */ | 1231 /* Worker function for TARGET_RTX_COSTS. */ |
1225 | 1232 |
1226 static bool | 1233 static bool |
1227 h8300_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed) | 1234 h8300_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code, |
1228 { | 1235 int opno ATTRIBUTE_UNUSED, int *total, bool speed) |
1236 { | |
1237 int code = GET_CODE (x); | |
1238 | |
1229 if (TARGET_H8300SX && outer_code == MEM) | 1239 if (TARGET_H8300SX && outer_code == MEM) |
1230 { | 1240 { |
1231 /* Estimate the number of execution states needed to calculate | 1241 /* Estimate the number of execution states needed to calculate |
1232 the address. */ | 1242 the address. */ |
1233 if (register_operand (x, VOIDmode) | 1243 if (register_operand (x, VOIDmode) |
1253 use a size-based cost for !speed, the lack of | 1263 use a size-based cost for !speed, the lack of |
1254 of a mode makes the results very unpredictable. */ | 1264 of a mode makes the results very unpredictable. */ |
1255 *total = 0; | 1265 *total = 0; |
1256 return true; | 1266 return true; |
1257 } | 1267 } |
1258 if (-4 <= n || n <= 4) | 1268 if (-4 <= n && n <= 4) |
1259 { | 1269 { |
1260 switch ((int) n) | 1270 switch ((int) n) |
1261 { | 1271 { |
1262 case 0: | 1272 case 0: |
1263 *total = 0; | 1273 *total = 0; |
1316 case UMOD: | 1326 case UMOD: |
1317 case UDIV: | 1327 case UDIV: |
1318 if (TARGET_H8300SX) | 1328 if (TARGET_H8300SX) |
1319 switch (GET_MODE (x)) | 1329 switch (GET_MODE (x)) |
1320 { | 1330 { |
1321 case QImode: | 1331 case E_QImode: |
1322 case HImode: | 1332 case E_HImode: |
1323 *total = COSTS_N_INSNS (!speed ? 4 : 10); | 1333 *total = COSTS_N_INSNS (!speed ? 4 : 10); |
1324 return false; | 1334 return false; |
1325 | 1335 |
1326 case SImode: | 1336 case E_SImode: |
1327 *total = COSTS_N_INSNS (!speed ? 4 : 18); | 1337 *total = COSTS_N_INSNS (!speed ? 4 : 18); |
1328 return false; | 1338 return false; |
1329 | 1339 |
1330 default: | 1340 default: |
1331 break; | 1341 break; |
1335 | 1345 |
1336 case MULT: | 1346 case MULT: |
1337 if (TARGET_H8300SX) | 1347 if (TARGET_H8300SX) |
1338 switch (GET_MODE (x)) | 1348 switch (GET_MODE (x)) |
1339 { | 1349 { |
1340 case QImode: | 1350 case E_QImode: |
1341 case HImode: | 1351 case E_HImode: |
1342 *total = COSTS_N_INSNS (2); | 1352 *total = COSTS_N_INSNS (2); |
1343 return false; | 1353 return false; |
1344 | 1354 |
1345 case SImode: | 1355 case E_SImode: |
1346 *total = COSTS_N_INSNS (5); | 1356 *total = COSTS_N_INSNS (5); |
1347 return false; | 1357 return false; |
1348 | 1358 |
1349 default: | 1359 default: |
1350 break; | 1360 break; |
1447 } | 1457 } |
1448 | 1458 |
1449 /* Print operand X using operand code CODE to assembly language output file | 1459 /* Print operand X using operand code CODE to assembly language output file |
1450 FILE. */ | 1460 FILE. */ |
1451 | 1461 |
1452 void | 1462 static void |
1453 print_operand (FILE *file, rtx x, int code) | 1463 h8300_print_operand (FILE *file, rtx x, int code) |
1454 { | 1464 { |
1455 /* This is used for communication between codes V,W,Z and Y. */ | 1465 /* This is used for communication between codes V,W,Z and Y. */ |
1456 static int bitint; | 1466 static int bitint; |
1457 | 1467 |
1458 switch (code) | 1468 switch (code) |
1459 { | 1469 { |
1470 case 'C': | |
1471 if (h8300_constant_length (x) == 2) | |
1472 fprintf (file, ":16"); | |
1473 else | |
1474 fprintf (file, ":32"); | |
1475 return; | |
1460 case 'E': | 1476 case 'E': |
1461 switch (GET_CODE (x)) | 1477 switch (GET_CODE (x)) |
1462 { | 1478 { |
1463 case REG: | 1479 case REG: |
1464 fprintf (file, "%sl", names_big[REGNO (x)]); | 1480 fprintf (file, "%sl", names_big[REGNO (x)]); |
1527 case 'Y': | 1543 case 'Y': |
1528 gcc_assert (bitint >= 0); | 1544 gcc_assert (bitint >= 0); |
1529 if (GET_CODE (x) == REG) | 1545 if (GET_CODE (x) == REG) |
1530 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l'); | 1546 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l'); |
1531 else | 1547 else |
1532 print_operand (file, x, 'R'); | 1548 h8300_print_operand (file, x, 'R'); |
1533 bitint = -1; | 1549 bitint = -1; |
1534 break; | 1550 break; |
1535 case 'Z': | 1551 case 'Z': |
1536 bitint = INTVAL (x); | 1552 bitint = INTVAL (x); |
1537 fprintf (file, "#%d", bitint & 7); | 1553 fprintf (file, "#%d", bitint & 7); |
1560 fprintf (file, "%s", names_big[REGNO (x)]); | 1576 fprintf (file, "%s", names_big[REGNO (x)]); |
1561 else | 1577 else |
1562 fprintf (file, "%s", names_upper_extended[REGNO (x)]); | 1578 fprintf (file, "%s", names_upper_extended[REGNO (x)]); |
1563 break; | 1579 break; |
1564 case MEM: | 1580 case MEM: |
1565 print_operand (file, x, 0); | 1581 h8300_print_operand (file, x, 0); |
1566 break; | 1582 break; |
1567 case CONST_INT: | 1583 case CONST_INT: |
1568 fprintf (file, "#%ld", ((INTVAL (x) >> 16) & 0xffff)); | 1584 fprintf (file, "#%ld", ((INTVAL (x) >> 16) & 0xffff)); |
1569 break; | 1585 break; |
1570 case CONST_DOUBLE: | 1586 case CONST_DOUBLE: |
1571 { | 1587 { |
1572 long val; | 1588 long val; |
1573 REAL_VALUE_TYPE rv; | 1589 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val); |
1574 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
1575 REAL_VALUE_TO_TARGET_SINGLE (rv, val); | |
1576 fprintf (file, "#%ld", ((val >> 16) & 0xffff)); | 1590 fprintf (file, "#%ld", ((val >> 16) & 0xffff)); |
1577 break; | 1591 break; |
1578 } | 1592 } |
1579 default: | 1593 default: |
1580 gcc_unreachable (); | 1594 gcc_unreachable (); |
1590 else | 1604 else |
1591 fprintf (file, "%s", names_big[REGNO (x)]); | 1605 fprintf (file, "%s", names_big[REGNO (x)]); |
1592 break; | 1606 break; |
1593 case MEM: | 1607 case MEM: |
1594 x = adjust_address (x, HImode, 2); | 1608 x = adjust_address (x, HImode, 2); |
1595 print_operand (file, x, 0); | 1609 h8300_print_operand (file, x, 0); |
1596 break; | 1610 break; |
1597 case CONST_INT: | 1611 case CONST_INT: |
1598 fprintf (file, "#%ld", INTVAL (x) & 0xffff); | 1612 fprintf (file, "#%ld", INTVAL (x) & 0xffff); |
1599 break; | 1613 break; |
1600 case CONST_DOUBLE: | 1614 case CONST_DOUBLE: |
1601 { | 1615 { |
1602 long val; | 1616 long val; |
1603 REAL_VALUE_TYPE rv; | 1617 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val); |
1604 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
1605 REAL_VALUE_TO_TARGET_SINGLE (rv, val); | |
1606 fprintf (file, "#%ld", (val & 0xffff)); | 1618 fprintf (file, "#%ld", (val & 0xffff)); |
1607 break; | 1619 break; |
1608 } | 1620 } |
1609 default: | 1621 default: |
1610 gcc_unreachable (); | 1622 gcc_unreachable (); |
1635 default: | 1647 default: |
1636 gcc_unreachable (); | 1648 gcc_unreachable (); |
1637 } | 1649 } |
1638 break; | 1650 break; |
1639 case 'o': | 1651 case 'o': |
1640 print_operand_address (file, x); | 1652 h8300_print_operand_address (file, VOIDmode, x); |
1641 break; | 1653 break; |
1642 case 's': | 1654 case 's': |
1643 if (GET_CODE (x) == CONST_INT) | 1655 if (GET_CODE (x) == CONST_INT) |
1644 fprintf (file, "#%ld", (INTVAL (x)) & 0xff); | 1656 fprintf (file, "#%ld", (INTVAL (x)) & 0xff); |
1645 else | 1657 else |
1683 switch (GET_CODE (x)) | 1695 switch (GET_CODE (x)) |
1684 { | 1696 { |
1685 case REG: | 1697 case REG: |
1686 switch (GET_MODE (x)) | 1698 switch (GET_MODE (x)) |
1687 { | 1699 { |
1688 case QImode: | 1700 case E_QImode: |
1689 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */ | 1701 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */ |
1690 fprintf (file, "%s", byte_reg (x, 0)); | 1702 fprintf (file, "%s", byte_reg (x, 0)); |
1691 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */ | 1703 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */ |
1692 fprintf (file, "%s", names_big[REGNO (x)]); | 1704 fprintf (file, "%s", names_big[REGNO (x)]); |
1693 #endif | 1705 #endif |
1694 break; | 1706 break; |
1695 case HImode: | 1707 case E_HImode: |
1696 fprintf (file, "%s", names_big[REGNO (x)]); | 1708 fprintf (file, "%s", names_big[REGNO (x)]); |
1697 break; | 1709 break; |
1698 case SImode: | 1710 case E_SImode: |
1699 case SFmode: | 1711 case E_SFmode: |
1700 fprintf (file, "%s", names_extended[REGNO (x)]); | 1712 fprintf (file, "%s", names_extended[REGNO (x)]); |
1701 break; | 1713 break; |
1702 default: | 1714 default: |
1703 gcc_unreachable (); | 1715 gcc_unreachable (); |
1704 } | 1716 } |
1707 case MEM: | 1719 case MEM: |
1708 { | 1720 { |
1709 rtx addr = XEXP (x, 0); | 1721 rtx addr = XEXP (x, 0); |
1710 | 1722 |
1711 fprintf (file, "@"); | 1723 fprintf (file, "@"); |
1712 output_address (addr); | 1724 output_address (GET_MODE (x), addr); |
1713 | 1725 |
1714 /* Add a length suffix to constant addresses. Although this | 1726 /* Add a length suffix to constant addresses. Although this |
1715 is often unnecessary, it helps to avoid ambiguity in the | 1727 is often unnecessary, it helps to avoid ambiguity in the |
1716 syntax of mova. If we wrote an insn like: | 1728 syntax of mova. If we wrote an insn like: |
1717 | 1729 |
1728 { | 1740 { |
1729 fprintf (file, ":8"); | 1741 fprintf (file, ":8"); |
1730 break; | 1742 break; |
1731 } | 1743 } |
1732 | 1744 |
1733 /* Fall through. We should not get here if we are | 1745 /* FALLTHRU */ |
1734 processing bit operations on H8/300 or H8/300H | 1746 |
1735 because 'U' constraint does not allow bit | 1747 /* We should not get here if we are processing bit |
1736 operations on the tiny area on these machines. */ | 1748 operations on H8/300 or H8/300H because 'U' |
1749 constraint does not allow bit operations on the | |
1750 tiny area on these machines. */ | |
1737 | 1751 |
1738 case 'X': | 1752 case 'X': |
1739 case 'T': | 1753 case 'T': |
1740 case 'S': | 1754 case 'S': |
1741 if (h8300_constant_length (addr) == 2) | 1755 if (h8300_constant_length (addr) == 2) |
1752 case CONST_INT: | 1766 case CONST_INT: |
1753 case SYMBOL_REF: | 1767 case SYMBOL_REF: |
1754 case CONST: | 1768 case CONST: |
1755 case LABEL_REF: | 1769 case LABEL_REF: |
1756 fprintf (file, "#"); | 1770 fprintf (file, "#"); |
1757 print_operand_address (file, x); | 1771 h8300_print_operand_address (file, VOIDmode, x); |
1758 break; | 1772 break; |
1759 case CONST_DOUBLE: | 1773 case CONST_DOUBLE: |
1760 { | 1774 { |
1761 long val; | 1775 long val; |
1762 REAL_VALUE_TYPE rv; | 1776 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val); |
1763 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
1764 REAL_VALUE_TO_TARGET_SINGLE (rv, val); | |
1765 fprintf (file, "#%ld", val); | 1777 fprintf (file, "#%ld", val); |
1766 break; | 1778 break; |
1767 } | 1779 } |
1768 default: | 1780 default: |
1769 break; | 1781 break; |
1770 } | 1782 } |
1771 } | 1783 } |
1772 } | 1784 } |
1773 | 1785 |
1786 /* Implements TARGET_PRINT_OPERAND_PUNCT_VALID_P. */ | |
1787 | |
1788 static bool | |
1789 h8300_print_operand_punct_valid_p (unsigned char code) | |
1790 { | |
1791 return (code == '#'); | |
1792 } | |
1793 | |
1774 /* Output assembly language output for the address ADDR to FILE. */ | 1794 /* Output assembly language output for the address ADDR to FILE. */ |
1775 | 1795 |
1776 void | 1796 static void |
1777 print_operand_address (FILE *file, rtx addr) | 1797 h8300_print_operand_address (FILE *file, machine_mode mode, rtx addr) |
1778 { | 1798 { |
1779 rtx index; | 1799 rtx index; |
1780 int size; | 1800 int size; |
1781 | 1801 |
1782 switch (GET_CODE (addr)) | 1802 switch (GET_CODE (addr)) |
1806 | 1826 |
1807 index = h8300_get_index (XEXP (addr, 0), VOIDmode, &size); | 1827 index = h8300_get_index (XEXP (addr, 0), VOIDmode, &size); |
1808 if (GET_CODE (index) == REG) | 1828 if (GET_CODE (index) == REG) |
1809 { | 1829 { |
1810 /* reg,foo */ | 1830 /* reg,foo */ |
1811 print_operand_address (file, XEXP (addr, 1)); | 1831 h8300_print_operand_address (file, mode, XEXP (addr, 1)); |
1812 fprintf (file, ","); | 1832 fprintf (file, ","); |
1813 switch (size) | 1833 switch (size) |
1814 { | 1834 { |
1815 case 0: | 1835 case 0: |
1816 print_operand_address (file, index); | 1836 h8300_print_operand_address (file, mode, index); |
1817 break; | 1837 break; |
1818 | 1838 |
1819 case 1: | 1839 case 1: |
1820 print_operand (file, index, 'X'); | 1840 h8300_print_operand (file, index, 'X'); |
1821 fputs (".b", file); | 1841 fputs (".b", file); |
1822 break; | 1842 break; |
1823 | 1843 |
1824 case 2: | 1844 case 2: |
1825 print_operand (file, index, 'T'); | 1845 h8300_print_operand (file, index, 'T'); |
1826 fputs (".w", file); | 1846 fputs (".w", file); |
1827 break; | 1847 break; |
1828 | 1848 |
1829 case 4: | 1849 case 4: |
1830 print_operand (file, index, 'S'); | 1850 h8300_print_operand (file, index, 'S'); |
1831 fputs (".l", file); | 1851 fputs (".l", file); |
1832 break; | 1852 break; |
1833 } | 1853 } |
1834 /* print_operand_address (file, XEXP (addr, 0)); */ | 1854 /* h8300_print_operand_address (file, XEXP (addr, 0)); */ |
1835 } | 1855 } |
1836 else | 1856 else |
1837 { | 1857 { |
1838 /* foo+k */ | 1858 /* foo+k */ |
1839 print_operand_address (file, XEXP (addr, 0)); | 1859 h8300_print_operand_address (file, mode, XEXP (addr, 0)); |
1840 fprintf (file, "+"); | 1860 fprintf (file, "+"); |
1841 print_operand_address (file, XEXP (addr, 1)); | 1861 h8300_print_operand_address (file, mode, XEXP (addr, 1)); |
1842 } | 1862 } |
1843 fprintf (file, ")"); | 1863 fprintf (file, ")"); |
1844 break; | 1864 break; |
1845 | 1865 |
1846 case CONST_INT: | 1866 case CONST_INT: |
1867 output file. This is helpful for debugging whether the length attributes | 1887 output file. This is helpful for debugging whether the length attributes |
1868 in the md file are correct. This is not meant to be a user selectable | 1888 in the md file are correct. This is not meant to be a user selectable |
1869 option. */ | 1889 option. */ |
1870 | 1890 |
1871 void | 1891 void |
1872 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED, | 1892 final_prescan_insn (rtx_insn *insn, rtx *operand ATTRIBUTE_UNUSED, |
1873 int num_operands ATTRIBUTE_UNUSED) | 1893 int num_operands ATTRIBUTE_UNUSED) |
1874 { | 1894 { |
1875 /* This holds the last insn address. */ | 1895 /* This holds the last insn address. */ |
1876 static int last_insn_address = 0; | 1896 static int last_insn_address = 0; |
1877 | 1897 |
2004 else if (flag_omit_frame_pointer) | 2024 else if (flag_omit_frame_pointer) |
2005 return (rtx) 0; | 2025 return (rtx) 0; |
2006 else | 2026 else |
2007 ret = gen_rtx_MEM (Pmode, | 2027 ret = gen_rtx_MEM (Pmode, |
2008 memory_address (Pmode, | 2028 memory_address (Pmode, |
2009 plus_constant (frame, UNITS_PER_WORD))); | 2029 plus_constant (Pmode, frame, |
2030 UNITS_PER_WORD))); | |
2010 set_mem_alias_set (ret, get_frame_alias_set ()); | 2031 set_mem_alias_set (ret, get_frame_alias_set ()); |
2011 return ret; | 2032 return ret; |
2012 } | 2033 } |
2013 | 2034 |
2014 /* Update the condition code from the insn. */ | 2035 /* Update the condition code from the insn. */ |
2015 | 2036 |
2016 void | 2037 void |
2017 notice_update_cc (rtx body, rtx insn) | 2038 notice_update_cc (rtx body, rtx_insn *insn) |
2018 { | 2039 { |
2019 rtx set; | 2040 rtx set; |
2020 | 2041 |
2021 switch (get_attr_cc (insn)) | 2042 switch (get_attr_cc (insn)) |
2022 { | 2043 { |
2092 plain @(dd,Rn) addresses. | 2113 plain @(dd,Rn) addresses. |
2093 | 2114 |
2094 MODE is the mode of the value being accessed. It can be VOIDmode | 2115 MODE is the mode of the value being accessed. It can be VOIDmode |
2095 if the address is known to be valid, but its mode is unknown. */ | 2116 if the address is known to be valid, but its mode is unknown. */ |
2096 | 2117 |
2097 rtx | 2118 static rtx |
2098 h8300_get_index (rtx x, enum machine_mode mode, int *size) | 2119 h8300_get_index (rtx x, machine_mode mode, int *size) |
2099 { | 2120 { |
2100 int dummy, factor; | 2121 int dummy, factor; |
2101 | 2122 |
2102 if (size == 0) | 2123 if (size == 0) |
2103 size = &dummy; | 2124 size = &dummy; |
2154 } | 2175 } |
2155 *size = 0; | 2176 *size = 0; |
2156 return x; | 2177 return x; |
2157 } | 2178 } |
2158 | 2179 |
2180 /* Worker function for TARGET_MODE_DEPENDENT_ADDRESS_P. | |
2181 | |
2182 On the H8/300, the predecrement and postincrement address depend thus | |
2183 (the amount of decrement or increment being the length of the operand). */ | |
2184 | |
2185 static bool | |
2186 h8300_mode_dependent_address_p (const_rtx addr, | |
2187 addr_space_t as ATTRIBUTE_UNUSED) | |
2188 { | |
2189 if (GET_CODE (addr) == PLUS | |
2190 && h8300_get_index (XEXP (addr, 0), VOIDmode, 0) != XEXP (addr, 0)) | |
2191 return true; | |
2192 | |
2193 return false; | |
2194 } | |
2195 | |
2159 static const h8300_length_table addb_length_table = | 2196 static const h8300_length_table addb_length_table = |
2160 { | 2197 { |
2161 /* #xx Rs @aa @Rs @xx */ | 2198 /* #xx Rs @aa @Rs @xx */ |
2162 { 2, 2, 4, 4, 4 }, /* add.b xx,Rd */ | 2199 { 2, 2, 4, 4, 4 }, /* add.b xx,Rd */ |
2163 { 4, 4, 4, 4, 6 }, /* add.b xx,@aa */ | 2200 { 4, 4, 4, 4, 6 }, /* add.b xx,@aa */ |
2414 } | 2451 } |
2415 | 2452 |
2416 /* Calculate the length of general binary instruction INSN using TABLE. */ | 2453 /* Calculate the length of general binary instruction INSN using TABLE. */ |
2417 | 2454 |
2418 static unsigned int | 2455 static unsigned int |
2419 h8300_binary_length (rtx insn, const h8300_length_table *table) | 2456 h8300_binary_length (rtx_insn *insn, const h8300_length_table *table) |
2420 { | 2457 { |
2421 rtx set; | 2458 rtx set; |
2422 | 2459 |
2423 set = single_set (insn); | 2460 set = single_set (insn); |
2424 gcc_assert (set); | 2461 gcc_assert (set); |
2503 | 2540 |
2504 /* Compute the length of INSN based on its length_table attribute. | 2541 /* Compute the length of INSN based on its length_table attribute. |
2505 OPERANDS is the array of its operands. */ | 2542 OPERANDS is the array of its operands. */ |
2506 | 2543 |
2507 unsigned int | 2544 unsigned int |
2508 h8300_insn_length_from_table (rtx insn, rtx * operands) | 2545 h8300_insn_length_from_table (rtx_insn *insn, rtx * operands) |
2509 { | 2546 { |
2510 switch (get_attr_length_table (insn)) | 2547 switch (get_attr_length_table (insn)) |
2511 { | 2548 { |
2512 case LENGTH_TABLE_NONE: | 2549 case LENGTH_TABLE_NONE: |
2513 gcc_unreachable (); | 2550 gcc_unreachable (); |
2667 | 2704 |
2668 /* Create references to the movmd source and destination blocks. */ | 2705 /* Create references to the movmd source and destination blocks. */ |
2669 first_dest = replace_equiv_address (dest, dest_reg); | 2706 first_dest = replace_equiv_address (dest, dest_reg); |
2670 first_src = replace_equiv_address (src, src_reg); | 2707 first_src = replace_equiv_address (src, src_reg); |
2671 | 2708 |
2672 set_mem_size (first_dest, GEN_INT (n & -factor)); | 2709 set_mem_size (first_dest, n & -factor); |
2673 set_mem_size (first_src, GEN_INT (n & -factor)); | 2710 set_mem_size (first_src, n & -factor); |
2674 | 2711 |
2675 length = copy_to_mode_reg (HImode, gen_int_mode (n / factor, HImode)); | 2712 length = copy_to_mode_reg (HImode, gen_int_mode (n / factor, HImode)); |
2676 emit_insn (gen_movmd (first_dest, first_src, length, GEN_INT (factor))); | 2713 emit_insn (gen_movmd (first_dest, first_src, length, GEN_INT (factor))); |
2677 | 2714 |
2678 if ((n & -factor) != n) | 2715 if ((n & -factor) != n) |
2703 /* Move ADDR into er6 after pushing its old value onto the stack. */ | 2740 /* Move ADDR into er6 after pushing its old value onto the stack. */ |
2704 | 2741 |
2705 void | 2742 void |
2706 h8300_swap_into_er6 (rtx addr) | 2743 h8300_swap_into_er6 (rtx addr) |
2707 { | 2744 { |
2708 push (HARD_FRAME_POINTER_REGNUM); | 2745 rtx insn = push (HARD_FRAME_POINTER_REGNUM, false); |
2746 if (frame_pointer_needed) | |
2747 add_reg_note (insn, REG_CFA_DEF_CFA, | |
2748 plus_constant (Pmode, gen_rtx_MEM (Pmode, stack_pointer_rtx), | |
2749 2 * UNITS_PER_WORD)); | |
2750 else | |
2751 add_reg_note (insn, REG_CFA_ADJUST_CFA, | |
2752 gen_rtx_SET (stack_pointer_rtx, | |
2753 plus_constant (Pmode, stack_pointer_rtx, 4))); | |
2754 | |
2709 emit_move_insn (hard_frame_pointer_rtx, addr); | 2755 emit_move_insn (hard_frame_pointer_rtx, addr); |
2710 if (REGNO (addr) == SP_REG) | 2756 if (REGNO (addr) == SP_REG) |
2711 emit_move_insn (hard_frame_pointer_rtx, | 2757 emit_move_insn (hard_frame_pointer_rtx, |
2712 plus_constant (hard_frame_pointer_rtx, | 2758 plus_constant (Pmode, hard_frame_pointer_rtx, |
2713 GET_MODE_SIZE (word_mode))); | 2759 GET_MODE_SIZE (word_mode))); |
2714 } | 2760 } |
2715 | 2761 |
2716 /* Move the current value of er6 into ADDR and pop its old value | 2762 /* Move the current value of er6 into ADDR and pop its old value |
2717 from the stack. */ | 2763 from the stack. */ |
2718 | 2764 |
2719 void | 2765 void |
2720 h8300_swap_out_of_er6 (rtx addr) | 2766 h8300_swap_out_of_er6 (rtx addr) |
2721 { | 2767 { |
2768 rtx insn; | |
2769 | |
2722 if (REGNO (addr) != SP_REG) | 2770 if (REGNO (addr) != SP_REG) |
2723 emit_move_insn (addr, hard_frame_pointer_rtx); | 2771 emit_move_insn (addr, hard_frame_pointer_rtx); |
2724 pop (HARD_FRAME_POINTER_REGNUM); | 2772 |
2773 insn = pop (HARD_FRAME_POINTER_REGNUM); | |
2774 if (frame_pointer_needed) | |
2775 add_reg_note (insn, REG_CFA_DEF_CFA, | |
2776 plus_constant (Pmode, hard_frame_pointer_rtx, | |
2777 2 * UNITS_PER_WORD)); | |
2778 else | |
2779 add_reg_note (insn, REG_CFA_ADJUST_CFA, | |
2780 gen_rtx_SET (stack_pointer_rtx, | |
2781 plus_constant (Pmode, stack_pointer_rtx, -4))); | |
2725 } | 2782 } |
2726 | 2783 |
2727 /* Return the length of mov instruction. */ | 2784 /* Return the length of mov instruction. */ |
2728 | 2785 |
2729 unsigned int | 2786 unsigned int |
2731 { | 2788 { |
2732 /* If the mov instruction involves a memory operand, we compute the | 2789 /* If the mov instruction involves a memory operand, we compute the |
2733 length, assuming the largest addressing mode is used, and then | 2790 length, assuming the largest addressing mode is used, and then |
2734 adjust later in the function. Otherwise, we compute and return | 2791 adjust later in the function. Otherwise, we compute and return |
2735 the exact length in one step. */ | 2792 the exact length in one step. */ |
2736 enum machine_mode mode = GET_MODE (operands[0]); | 2793 machine_mode mode = GET_MODE (operands[0]); |
2737 rtx dest = operands[0]; | 2794 rtx dest = operands[0]; |
2738 rtx src = operands[1]; | 2795 rtx src = operands[1]; |
2739 rtx addr; | 2796 rtx addr; |
2740 | 2797 |
2741 if (GET_CODE (src) == MEM) | 2798 if (GET_CODE (src) == MEM) |
2749 { | 2806 { |
2750 unsigned int base_length; | 2807 unsigned int base_length; |
2751 | 2808 |
2752 switch (mode) | 2809 switch (mode) |
2753 { | 2810 { |
2754 case QImode: | 2811 case E_QImode: |
2755 if (addr == NULL_RTX) | 2812 if (addr == NULL_RTX) |
2756 return 2; | 2813 return 2; |
2757 | 2814 |
2758 /* The eightbit addressing is available only in QImode, so | 2815 /* The eightbit addressing is available only in QImode, so |
2759 go ahead and take care of it. */ | 2816 go ahead and take care of it. */ |
2761 return 2; | 2818 return 2; |
2762 | 2819 |
2763 base_length = 4; | 2820 base_length = 4; |
2764 break; | 2821 break; |
2765 | 2822 |
2766 case HImode: | 2823 case E_HImode: |
2767 if (addr == NULL_RTX) | 2824 if (addr == NULL_RTX) |
2768 { | 2825 { |
2769 if (REG_P (src)) | 2826 if (REG_P (src)) |
2770 return 2; | 2827 return 2; |
2771 | 2828 |
2776 } | 2833 } |
2777 | 2834 |
2778 base_length = 4; | 2835 base_length = 4; |
2779 break; | 2836 break; |
2780 | 2837 |
2781 case SImode: | 2838 case E_SImode: |
2782 if (addr == NULL_RTX) | 2839 if (addr == NULL_RTX) |
2783 { | 2840 { |
2784 if (REG_P (src)) | 2841 if (REG_P (src)) |
2785 return 4; | 2842 return 4; |
2786 | 2843 |
2803 } | 2860 } |
2804 | 2861 |
2805 base_length = 8; | 2862 base_length = 8; |
2806 break; | 2863 break; |
2807 | 2864 |
2808 case SFmode: | 2865 case E_SFmode: |
2809 if (addr == NULL_RTX) | 2866 if (addr == NULL_RTX) |
2810 { | 2867 { |
2811 if (REG_P (src)) | 2868 if (REG_P (src)) |
2812 return 4; | 2869 return 4; |
2813 | 2870 |
2814 if (CONST_DOUBLE_OK_FOR_LETTER_P (src, 'G')) | 2871 if (satisfies_constraint_G (src)) |
2815 return 4; | 2872 return 4; |
2816 | 2873 |
2817 return 8; | 2874 return 8; |
2818 } | 2875 } |
2819 | 2876 |
2855 { | 2912 { |
2856 unsigned int base_length; | 2913 unsigned int base_length; |
2857 | 2914 |
2858 switch (mode) | 2915 switch (mode) |
2859 { | 2916 { |
2860 case QImode: | 2917 case E_QImode: |
2861 if (addr == NULL_RTX) | 2918 if (addr == NULL_RTX) |
2862 return 2; | 2919 return 2; |
2863 | 2920 |
2864 /* The eightbit addressing is available only in QImode, so | 2921 /* The eightbit addressing is available only in QImode, so |
2865 go ahead and take care of it. */ | 2922 go ahead and take care of it. */ |
2867 return 2; | 2924 return 2; |
2868 | 2925 |
2869 base_length = 8; | 2926 base_length = 8; |
2870 break; | 2927 break; |
2871 | 2928 |
2872 case HImode: | 2929 case E_HImode: |
2873 if (addr == NULL_RTX) | 2930 if (addr == NULL_RTX) |
2874 { | 2931 { |
2875 if (REG_P (src)) | 2932 if (REG_P (src)) |
2876 return 2; | 2933 return 2; |
2877 | 2934 |
2882 } | 2939 } |
2883 | 2940 |
2884 base_length = 8; | 2941 base_length = 8; |
2885 break; | 2942 break; |
2886 | 2943 |
2887 case SImode: | 2944 case E_SImode: |
2888 if (addr == NULL_RTX) | 2945 if (addr == NULL_RTX) |
2889 { | 2946 { |
2890 if (REG_P (src)) | 2947 if (REG_P (src)) |
2891 { | 2948 { |
2892 if (REGNO (src) == MAC_REG || REGNO (dest) == MAC_REG) | 2949 if (REGNO (src) == MAC_REG || REGNO (dest) == MAC_REG) |
2923 } | 2980 } |
2924 | 2981 |
2925 base_length = 10; | 2982 base_length = 10; |
2926 break; | 2983 break; |
2927 | 2984 |
2928 case SFmode: | 2985 case E_SFmode: |
2929 if (addr == NULL_RTX) | 2986 if (addr == NULL_RTX) |
2930 { | 2987 { |
2931 if (REG_P (src)) | 2988 if (REG_P (src)) |
2932 return 2; | 2989 return 2; |
2933 | 2990 |
2934 if (CONST_DOUBLE_OK_FOR_LETTER_P (src, 'G')) | 2991 if (satisfies_constraint_G (src)) |
2935 return 2; | 2992 return 2; |
2936 | 2993 |
2937 return 6; | 2994 return 6; |
2938 } | 2995 } |
2939 | 2996 |
2981 /* Output an addition insn. */ | 3038 /* Output an addition insn. */ |
2982 | 3039 |
2983 const char * | 3040 const char * |
2984 output_plussi (rtx *operands) | 3041 output_plussi (rtx *operands) |
2985 { | 3042 { |
2986 enum machine_mode mode = GET_MODE (operands[0]); | 3043 machine_mode mode = GET_MODE (operands[0]); |
2987 | 3044 |
2988 gcc_assert (mode == SImode); | 3045 gcc_assert (mode == SImode); |
2989 | 3046 |
2990 if (TARGET_H8300) | 3047 if (TARGET_H8300) |
2991 { | 3048 { |
3065 /* Compute the length of an addition insn. */ | 3122 /* Compute the length of an addition insn. */ |
3066 | 3123 |
3067 unsigned int | 3124 unsigned int |
3068 compute_plussi_length (rtx *operands) | 3125 compute_plussi_length (rtx *operands) |
3069 { | 3126 { |
3070 enum machine_mode mode = GET_MODE (operands[0]); | 3127 machine_mode mode = GET_MODE (operands[0]); |
3071 | 3128 |
3072 gcc_assert (mode == SImode); | 3129 gcc_assert (mode == SImode); |
3073 | 3130 |
3074 if (TARGET_H8300) | 3131 if (TARGET_H8300) |
3075 { | 3132 { |
3144 /* Compute which flag bits are valid after an addition insn. */ | 3201 /* Compute which flag bits are valid after an addition insn. */ |
3145 | 3202 |
3146 enum attr_cc | 3203 enum attr_cc |
3147 compute_plussi_cc (rtx *operands) | 3204 compute_plussi_cc (rtx *operands) |
3148 { | 3205 { |
3149 enum machine_mode mode = GET_MODE (operands[0]); | 3206 machine_mode mode = GET_MODE (operands[0]); |
3150 | 3207 |
3151 gcc_assert (mode == SImode); | 3208 gcc_assert (mode == SImode); |
3152 | 3209 |
3153 if (TARGET_H8300) | 3210 if (TARGET_H8300) |
3154 { | 3211 { |
3199 } | 3256 } |
3200 | 3257 |
3201 /* Output a logical insn. */ | 3258 /* Output a logical insn. */ |
3202 | 3259 |
3203 const char * | 3260 const char * |
3204 output_logical_op (enum machine_mode mode, rtx *operands) | 3261 output_logical_op (machine_mode mode, rtx *operands) |
3205 { | 3262 { |
3206 /* Figure out the logical op that we need to perform. */ | 3263 /* Figure out the logical op that we need to perform. */ |
3207 enum rtx_code code = GET_CODE (operands[3]); | 3264 enum rtx_code code = GET_CODE (operands[3]); |
3208 /* Pretend that every byte is affected if both operands are registers. */ | 3265 /* Pretend that every byte is affected if both operands are registers. */ |
3209 const unsigned HOST_WIDE_INT intval = | 3266 const unsigned HOST_WIDE_INT intval = |
3245 gcc_unreachable (); | 3302 gcc_unreachable (); |
3246 } | 3303 } |
3247 | 3304 |
3248 switch (mode) | 3305 switch (mode) |
3249 { | 3306 { |
3250 case HImode: | 3307 case E_HImode: |
3251 /* First, see if we can finish with one insn. */ | 3308 /* First, see if we can finish with one insn. */ |
3252 if ((TARGET_H8300H || TARGET_H8300S) | 3309 if ((TARGET_H8300H || TARGET_H8300S) |
3253 && b0 != 0 | 3310 && b0 != 0 |
3254 && b1 != 0) | 3311 && b1 != 0) |
3255 { | 3312 { |
3270 sprintf (insn_buf, "%s\t%%t2,%%t0", opname); | 3327 sprintf (insn_buf, "%s\t%%t2,%%t0", opname); |
3271 output_asm_insn (insn_buf, operands); | 3328 output_asm_insn (insn_buf, operands); |
3272 } | 3329 } |
3273 } | 3330 } |
3274 break; | 3331 break; |
3275 case SImode: | 3332 case E_SImode: |
3276 if (TARGET_H8300H || TARGET_H8300S) | 3333 if (TARGET_H8300H || TARGET_H8300S) |
3277 { | 3334 { |
3278 /* Determine if the lower half can be taken care of in no more | 3335 /* Determine if the lower half can be taken care of in no more |
3279 than two bytes. */ | 3336 than two bytes. */ |
3280 lower_half_easy_p = (b0 == 0 | 3337 lower_half_easy_p = (b0 == 0 |
3380 } | 3437 } |
3381 | 3438 |
3382 /* Compute the length of a logical insn. */ | 3439 /* Compute the length of a logical insn. */ |
3383 | 3440 |
3384 unsigned int | 3441 unsigned int |
3385 compute_logical_op_length (enum machine_mode mode, rtx *operands) | 3442 compute_logical_op_length (machine_mode mode, rtx *operands) |
3386 { | 3443 { |
3387 /* Figure out the logical op that we need to perform. */ | 3444 /* Figure out the logical op that we need to perform. */ |
3388 enum rtx_code code = GET_CODE (operands[3]); | 3445 enum rtx_code code = GET_CODE (operands[3]); |
3389 /* Pretend that every byte is affected if both operands are registers. */ | 3446 /* Pretend that every byte is affected if both operands are registers. */ |
3390 const unsigned HOST_WIDE_INT intval = | 3447 const unsigned HOST_WIDE_INT intval = |
3410 /* Insn length. */ | 3467 /* Insn length. */ |
3411 unsigned int length = 0; | 3468 unsigned int length = 0; |
3412 | 3469 |
3413 switch (mode) | 3470 switch (mode) |
3414 { | 3471 { |
3415 case HImode: | 3472 case E_HImode: |
3416 /* First, see if we can finish with one insn. */ | 3473 /* First, see if we can finish with one insn. */ |
3417 if ((TARGET_H8300H || TARGET_H8300S) | 3474 if ((TARGET_H8300H || TARGET_H8300S) |
3418 && b0 != 0 | 3475 && b0 != 0 |
3419 && b1 != 0) | 3476 && b1 != 0) |
3420 { | 3477 { |
3430 /* Take care of the upper byte. */ | 3487 /* Take care of the upper byte. */ |
3431 if (b1 != 0) | 3488 if (b1 != 0) |
3432 length += 2; | 3489 length += 2; |
3433 } | 3490 } |
3434 break; | 3491 break; |
3435 case SImode: | 3492 case E_SImode: |
3436 if (TARGET_H8300H || TARGET_H8300S) | 3493 if (TARGET_H8300H || TARGET_H8300S) |
3437 { | 3494 { |
3438 /* Determine if the lower half can be taken care of in no more | 3495 /* Determine if the lower half can be taken care of in no more |
3439 than two bytes. */ | 3496 than two bytes. */ |
3440 lower_half_easy_p = (b0 == 0 | 3497 lower_half_easy_p = (b0 == 0 |
3526 } | 3583 } |
3527 | 3584 |
3528 /* Compute which flag bits are valid after a logical insn. */ | 3585 /* Compute which flag bits are valid after a logical insn. */ |
3529 | 3586 |
3530 enum attr_cc | 3587 enum attr_cc |
3531 compute_logical_op_cc (enum machine_mode mode, rtx *operands) | 3588 compute_logical_op_cc (machine_mode mode, rtx *operands) |
3532 { | 3589 { |
3533 /* Figure out the logical op that we need to perform. */ | 3590 /* Figure out the logical op that we need to perform. */ |
3534 enum rtx_code code = GET_CODE (operands[3]); | 3591 enum rtx_code code = GET_CODE (operands[3]); |
3535 /* Pretend that every byte is affected if both operands are registers. */ | 3592 /* Pretend that every byte is affected if both operands are registers. */ |
3536 const unsigned HOST_WIDE_INT intval = | 3593 const unsigned HOST_WIDE_INT intval = |
3554 /* Condition code. */ | 3611 /* Condition code. */ |
3555 enum attr_cc cc = CC_CLOBBER; | 3612 enum attr_cc cc = CC_CLOBBER; |
3556 | 3613 |
3557 switch (mode) | 3614 switch (mode) |
3558 { | 3615 { |
3559 case HImode: | 3616 case E_HImode: |
3560 /* First, see if we can finish with one insn. */ | 3617 /* First, see if we can finish with one insn. */ |
3561 if ((TARGET_H8300H || TARGET_H8300S) | 3618 if ((TARGET_H8300H || TARGET_H8300S) |
3562 && b0 != 0 | 3619 && b0 != 0 |
3563 && b1 != 0) | 3620 && b1 != 0) |
3564 { | 3621 { |
3565 cc = CC_SET_ZNV; | 3622 cc = CC_SET_ZNV; |
3566 } | 3623 } |
3567 break; | 3624 break; |
3568 case SImode: | 3625 case E_SImode: |
3569 if (TARGET_H8300H || TARGET_H8300S) | 3626 if (TARGET_H8300H || TARGET_H8300S) |
3570 { | 3627 { |
3571 /* Determine if the lower half can be taken care of in no more | 3628 /* Determine if the lower half can be taken care of in no more |
3572 than two bytes. */ | 3629 than two bytes. */ |
3573 lower_half_easy_p = (b0 == 0 | 3630 lower_half_easy_p = (b0 == 0 |
3617 rtx op1 = operands[2]; | 3674 rtx op1 = operands[2]; |
3618 rtx label = operands[3]; | 3675 rtx label = operands[3]; |
3619 rtx tmp; | 3676 rtx tmp; |
3620 | 3677 |
3621 tmp = gen_rtx_COMPARE (VOIDmode, op0, op1); | 3678 tmp = gen_rtx_COMPARE (VOIDmode, op0, op1); |
3622 emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx, tmp)); | 3679 emit_insn (gen_rtx_SET (cc0_rtx, tmp)); |
3623 | 3680 |
3624 tmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx); | 3681 tmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx); |
3625 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, | 3682 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, |
3626 gen_rtx_LABEL_REF (VOIDmode, label), | 3683 gen_rtx_LABEL_REF (VOIDmode, label), |
3627 pc_rtx); | 3684 pc_rtx); |
3628 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); | 3685 emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); |
3629 } | 3686 } |
3630 | 3687 |
3631 | 3688 |
3632 /* Expand a conditional store. */ | 3689 /* Expand a conditional store. */ |
3633 | 3690 |
3639 rtx op0 = operands[2]; | 3696 rtx op0 = operands[2]; |
3640 rtx op1 = operands[3]; | 3697 rtx op1 = operands[3]; |
3641 rtx tmp; | 3698 rtx tmp; |
3642 | 3699 |
3643 tmp = gen_rtx_COMPARE (VOIDmode, op0, op1); | 3700 tmp = gen_rtx_COMPARE (VOIDmode, op0, op1); |
3644 emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx, tmp)); | 3701 emit_insn (gen_rtx_SET (cc0_rtx, tmp)); |
3645 | 3702 |
3646 tmp = gen_rtx_fmt_ee (code, GET_MODE (dest), cc0_rtx, const0_rtx); | 3703 tmp = gen_rtx_fmt_ee (code, GET_MODE (dest), cc0_rtx, const0_rtx); |
3647 emit_insn (gen_rtx_SET (VOIDmode, dest, tmp)); | 3704 emit_insn (gen_rtx_SET (dest, tmp)); |
3648 } | 3705 } |
3649 | 3706 |
3650 /* Shifts. | 3707 /* Shifts. |
3651 | 3708 |
3652 We devote a fair bit of code to getting efficient shifts since we | 3709 We devote a fair bit of code to getting efficient shifts since we |
3684 refer to shift_alg_[qhs]i. */ | 3741 refer to shift_alg_[qhs]i. */ |
3685 | 3742 |
3686 /* Classify a shift with the given mode and code. OP is the shift amount. */ | 3743 /* Classify a shift with the given mode and code. OP is the shift amount. */ |
3687 | 3744 |
3688 enum h8sx_shift_type | 3745 enum h8sx_shift_type |
3689 h8sx_classify_shift (enum machine_mode mode, enum rtx_code code, rtx op) | 3746 h8sx_classify_shift (machine_mode mode, enum rtx_code code, rtx op) |
3690 { | 3747 { |
3691 if (!TARGET_H8300SX) | 3748 if (!TARGET_H8300SX) |
3692 return H8SX_SHIFT_NONE; | 3749 return H8SX_SHIFT_NONE; |
3693 | 3750 |
3694 switch (code) | 3751 switch (code) |
3729 } | 3786 } |
3730 | 3787 |
3731 /* Return the asm template for a single h8sx shift instruction. | 3788 /* Return the asm template for a single h8sx shift instruction. |
3732 OPERANDS[0] and OPERANDS[1] are the destination, OPERANDS[2] | 3789 OPERANDS[0] and OPERANDS[1] are the destination, OPERANDS[2] |
3733 is the source and OPERANDS[3] is the shift. SUFFIX is the | 3790 is the source and OPERANDS[3] is the shift. SUFFIX is the |
3734 size suffix ('b', 'w' or 'l') and OPTYPE is the print_operand | 3791 size suffix ('b', 'w' or 'l') and OPTYPE is the h8300_print_operand |
3735 prefix for the destination operand. */ | 3792 prefix for the destination operand. */ |
3736 | 3793 |
3737 const char * | 3794 const char * |
3738 output_h8sx_shift (rtx *operands, int suffix, int optype) | 3795 output_h8sx_shift (rtx *operands, int suffix, int optype) |
3739 { | 3796 { |
3776 } | 3833 } |
3777 | 3834 |
3778 /* Emit code to do shifts. */ | 3835 /* Emit code to do shifts. */ |
3779 | 3836 |
3780 bool | 3837 bool |
3781 expand_a_shift (enum machine_mode mode, enum rtx_code code, rtx operands[]) | 3838 expand_a_shift (machine_mode mode, enum rtx_code code, rtx operands[]) |
3782 { | 3839 { |
3783 switch (h8sx_classify_shift (mode, code, operands[2])) | 3840 switch (h8sx_classify_shift (mode, code, operands[2])) |
3784 { | 3841 { |
3785 case H8SX_SHIFT_BINARY: | 3842 case H8SX_SHIFT_BINARY: |
3786 operands[1] = force_reg (mode, operands[1]); | 3843 operands[1] = force_reg (mode, operands[1]); |
3799 code at emit time, but need to allocate a scratch reg now. */ | 3856 code at emit time, but need to allocate a scratch reg now. */ |
3800 | 3857 |
3801 emit_insn (gen_rtx_PARALLEL | 3858 emit_insn (gen_rtx_PARALLEL |
3802 (VOIDmode, | 3859 (VOIDmode, |
3803 gen_rtvec (2, | 3860 gen_rtvec (2, |
3804 gen_rtx_SET (VOIDmode, copy_rtx (operands[0]), | 3861 gen_rtx_SET (copy_rtx (operands[0]), |
3805 gen_rtx_fmt_ee (code, mode, | 3862 gen_rtx_fmt_ee (code, mode, |
3806 copy_rtx (operands[0]), operands[2])), | 3863 copy_rtx (operands[0]), operands[2])), |
3807 gen_rtx_CLOBBER (VOIDmode, | 3864 gen_rtx_CLOBBER (VOIDmode, |
3808 gen_rtx_SCRATCH (QImode))))); | 3865 gen_rtx_SCRATCH (QImode))))); |
3809 return true; | 3866 return true; |
4020 enum h8_cpu cpu; | 4077 enum h8_cpu cpu; |
4021 | 4078 |
4022 /* Find the target CPU. */ | 4079 /* Find the target CPU. */ |
4023 if (TARGET_H8300) | 4080 if (TARGET_H8300) |
4024 cpu = H8_300; | 4081 cpu = H8_300; |
4025 else if (TARGET_H8300H) | 4082 else if (TARGET_H8300S) |
4083 cpu = H8_S; | |
4084 else | |
4026 cpu = H8_300H; | 4085 cpu = H8_300H; |
4027 else | |
4028 cpu = H8_S; | |
4029 | 4086 |
4030 /* Find the shift algorithm. */ | 4087 /* Find the shift algorithm. */ |
4031 info->alg = SHIFT_LOOP; | 4088 info->alg = SHIFT_LOOP; |
4032 switch (shift_mode) | 4089 switch (shift_mode) |
4033 { | 4090 { |
4309 info->special = "mov.b\t%z0,%w0\n\tsub.b\t%x0,%x0\n\tsub.w\t%e0,%e0"; | 4366 info->special = "mov.b\t%z0,%w0\n\tsub.b\t%x0,%x0\n\tsub.w\t%e0,%e0"; |
4310 info->shift1 = "shlr.b\t%w0"; | 4367 info->shift1 = "shlr.b\t%w0"; |
4311 info->cc_inline = CC_SET_ZNV; | 4368 info->cc_inline = CC_SET_ZNV; |
4312 goto end; | 4369 goto end; |
4313 case SHIFT_ASHIFTRT: | 4370 case SHIFT_ASHIFTRT: |
4314 info->special = "mov.b\t%z0,%w0\n\tbld\t#7,%w0\n\tsubx\t%x0,%x0\n\tsubx\t%x0,%x0\n\tsubx\t%x0,%x0"; | 4371 info->special = "mov.b\t%z0,%w0\n\tbld\t#7,%w0\n\tsubx\t%x0,%x0\n\tsubx\t%y0,%y0\n\tsubx\t%z0,%z0"; |
4315 info->shift1 = "shar.b\t%w0"; | 4372 info->shift1 = "shar.b\t%w0"; |
4316 info->cc_inline = CC_SET_ZNV; | 4373 info->cc_inline = CC_SET_ZNV; |
4317 goto end; | 4374 goto end; |
4318 } | 4375 } |
4319 } | 4376 } |
4455 | 4512 |
4456 /* Given COUNT and MODE of a shift, return 1 if a scratch reg may be | 4513 /* Given COUNT and MODE of a shift, return 1 if a scratch reg may be |
4457 needed for some shift with COUNT and MODE. Return 0 otherwise. */ | 4514 needed for some shift with COUNT and MODE. Return 0 otherwise. */ |
4458 | 4515 |
4459 int | 4516 int |
4460 h8300_shift_needs_scratch_p (int count, enum machine_mode mode) | 4517 h8300_shift_needs_scratch_p (int count, machine_mode mode) |
4461 { | 4518 { |
4462 enum h8_cpu cpu; | 4519 enum h8_cpu cpu; |
4463 int a, lr, ar; | 4520 int a, lr, ar; |
4464 | 4521 |
4465 if (GET_MODE_BITSIZE (mode) <= count) | 4522 if (GET_MODE_BITSIZE (mode) <= count) |
4466 return 1; | 4523 return 1; |
4467 | 4524 |
4468 /* Find out the target CPU. */ | 4525 /* Find out the target CPU. */ |
4469 if (TARGET_H8300) | 4526 if (TARGET_H8300) |
4470 cpu = H8_300; | 4527 cpu = H8_300; |
4471 else if (TARGET_H8300H) | 4528 else if (TARGET_H8300S) |
4529 cpu = H8_S; | |
4530 else | |
4472 cpu = H8_300H; | 4531 cpu = H8_300H; |
4473 else | |
4474 cpu = H8_S; | |
4475 | 4532 |
4476 /* Find the shift algorithm. */ | 4533 /* Find the shift algorithm. */ |
4477 switch (mode) | 4534 switch (mode) |
4478 { | 4535 { |
4479 case QImode: | 4536 case E_QImode: |
4480 a = shift_alg_qi[cpu][SHIFT_ASHIFT][count]; | 4537 a = shift_alg_qi[cpu][SHIFT_ASHIFT][count]; |
4481 lr = shift_alg_qi[cpu][SHIFT_LSHIFTRT][count]; | 4538 lr = shift_alg_qi[cpu][SHIFT_LSHIFTRT][count]; |
4482 ar = shift_alg_qi[cpu][SHIFT_ASHIFTRT][count]; | 4539 ar = shift_alg_qi[cpu][SHIFT_ASHIFTRT][count]; |
4483 break; | 4540 break; |
4484 | 4541 |
4485 case HImode: | 4542 case E_HImode: |
4486 a = shift_alg_hi[cpu][SHIFT_ASHIFT][count]; | 4543 a = shift_alg_hi[cpu][SHIFT_ASHIFT][count]; |
4487 lr = shift_alg_hi[cpu][SHIFT_LSHIFTRT][count]; | 4544 lr = shift_alg_hi[cpu][SHIFT_LSHIFTRT][count]; |
4488 ar = shift_alg_hi[cpu][SHIFT_ASHIFTRT][count]; | 4545 ar = shift_alg_hi[cpu][SHIFT_ASHIFTRT][count]; |
4489 break; | 4546 break; |
4490 | 4547 |
4491 case SImode: | 4548 case E_SImode: |
4492 a = shift_alg_si[cpu][SHIFT_ASHIFT][count]; | 4549 a = shift_alg_si[cpu][SHIFT_ASHIFT][count]; |
4493 lr = shift_alg_si[cpu][SHIFT_LSHIFTRT][count]; | 4550 lr = shift_alg_si[cpu][SHIFT_LSHIFTRT][count]; |
4494 ar = shift_alg_si[cpu][SHIFT_ASHIFTRT][count]; | 4551 ar = shift_alg_si[cpu][SHIFT_ASHIFTRT][count]; |
4495 break; | 4552 break; |
4496 | 4553 |
4508 const char * | 4565 const char * |
4509 output_a_shift (rtx *operands) | 4566 output_a_shift (rtx *operands) |
4510 { | 4567 { |
4511 static int loopend_lab; | 4568 static int loopend_lab; |
4512 rtx shift = operands[3]; | 4569 rtx shift = operands[3]; |
4513 enum machine_mode mode = GET_MODE (shift); | 4570 machine_mode mode = GET_MODE (shift); |
4514 enum rtx_code code = GET_CODE (shift); | 4571 enum rtx_code code = GET_CODE (shift); |
4515 enum shift_type shift_type; | 4572 enum shift_type shift_type; |
4516 enum shift_mode shift_mode; | 4573 enum shift_mode shift_mode; |
4517 struct shift_info info; | 4574 struct shift_info info; |
4518 int n; | 4575 int n; |
4519 | 4576 |
4520 loopend_lab++; | 4577 loopend_lab++; |
4521 | 4578 |
4522 switch (mode) | 4579 switch (mode) |
4523 { | 4580 { |
4524 case QImode: | 4581 case E_QImode: |
4525 shift_mode = QIshift; | 4582 shift_mode = QIshift; |
4526 break; | 4583 break; |
4527 case HImode: | 4584 case E_HImode: |
4528 shift_mode = HIshift; | 4585 shift_mode = HIshift; |
4529 break; | 4586 break; |
4530 case SImode: | 4587 case E_SImode: |
4531 shift_mode = SIshift; | 4588 shift_mode = SIshift; |
4532 break; | 4589 break; |
4533 default: | 4590 default: |
4534 gcc_unreachable (); | 4591 gcc_unreachable (); |
4535 } | 4592 } |
4611 output_asm_insn (info.shift1, operands); | 4668 output_asm_insn (info.shift1, operands); |
4612 | 4669 |
4613 /* Now mask off the high bits. */ | 4670 /* Now mask off the high bits. */ |
4614 switch (mode) | 4671 switch (mode) |
4615 { | 4672 { |
4616 case QImode: | 4673 case E_QImode: |
4617 sprintf (insn_buf, "and\t#%d,%%X0", mask); | 4674 sprintf (insn_buf, "and\t#%d,%%X0", mask); |
4618 break; | 4675 break; |
4619 | 4676 |
4620 case HImode: | 4677 case E_HImode: |
4621 gcc_assert (TARGET_H8300H || TARGET_H8300S); | 4678 gcc_assert (TARGET_H8300H || TARGET_H8300S); |
4622 sprintf (insn_buf, "and.w\t#%d,%%T0", mask); | 4679 sprintf (insn_buf, "and.w\t#%d,%%T0", mask); |
4623 break; | 4680 break; |
4624 | 4681 |
4625 default: | 4682 default: |
4678 | 4735 |
4679 unsigned int | 4736 unsigned int |
4680 compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands) | 4737 compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands) |
4681 { | 4738 { |
4682 rtx shift = operands[3]; | 4739 rtx shift = operands[3]; |
4683 enum machine_mode mode = GET_MODE (shift); | 4740 machine_mode mode = GET_MODE (shift); |
4684 enum rtx_code code = GET_CODE (shift); | 4741 enum rtx_code code = GET_CODE (shift); |
4685 enum shift_type shift_type; | 4742 enum shift_type shift_type; |
4686 enum shift_mode shift_mode; | 4743 enum shift_mode shift_mode; |
4687 struct shift_info info; | 4744 struct shift_info info; |
4688 unsigned int wlength = 0; | 4745 unsigned int wlength = 0; |
4689 | 4746 |
4690 switch (mode) | 4747 switch (mode) |
4691 { | 4748 { |
4692 case QImode: | 4749 case E_QImode: |
4693 shift_mode = QIshift; | 4750 shift_mode = QIshift; |
4694 break; | 4751 break; |
4695 case HImode: | 4752 case E_HImode: |
4696 shift_mode = HIshift; | 4753 shift_mode = HIshift; |
4697 break; | 4754 break; |
4698 case SImode: | 4755 case E_SImode: |
4699 shift_mode = SIshift; | 4756 shift_mode = SIshift; |
4700 break; | 4757 break; |
4701 default: | 4758 default: |
4702 gcc_unreachable (); | 4759 gcc_unreachable (); |
4703 } | 4760 } |
4783 wlength += h8300_asm_insn_count (info.shift1) * m; | 4840 wlength += h8300_asm_insn_count (info.shift1) * m; |
4784 | 4841 |
4785 /* Now mask off the high bits. */ | 4842 /* Now mask off the high bits. */ |
4786 switch (mode) | 4843 switch (mode) |
4787 { | 4844 { |
4788 case QImode: | 4845 case E_QImode: |
4789 wlength += 1; | 4846 wlength += 1; |
4790 break; | 4847 break; |
4791 case HImode: | 4848 case E_HImode: |
4792 wlength += 2; | 4849 wlength += 2; |
4793 break; | 4850 break; |
4794 case SImode: | 4851 case E_SImode: |
4795 gcc_assert (!TARGET_H8300); | 4852 gcc_assert (!TARGET_H8300); |
4796 wlength += 3; | 4853 wlength += 3; |
4797 break; | 4854 break; |
4798 default: | 4855 default: |
4799 gcc_unreachable (); | 4856 gcc_unreachable (); |
4826 | 4883 |
4827 enum attr_cc | 4884 enum attr_cc |
4828 compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands) | 4885 compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands) |
4829 { | 4886 { |
4830 rtx shift = operands[3]; | 4887 rtx shift = operands[3]; |
4831 enum machine_mode mode = GET_MODE (shift); | 4888 machine_mode mode = GET_MODE (shift); |
4832 enum rtx_code code = GET_CODE (shift); | 4889 enum rtx_code code = GET_CODE (shift); |
4833 enum shift_type shift_type; | 4890 enum shift_type shift_type; |
4834 enum shift_mode shift_mode; | 4891 enum shift_mode shift_mode; |
4835 struct shift_info info; | 4892 struct shift_info info; |
4836 int n; | 4893 int n; |
4837 | 4894 |
4838 switch (mode) | 4895 switch (mode) |
4839 { | 4896 { |
4840 case QImode: | 4897 case E_QImode: |
4841 shift_mode = QIshift; | 4898 shift_mode = QIshift; |
4842 break; | 4899 break; |
4843 case HImode: | 4900 case E_HImode: |
4844 shift_mode = HIshift; | 4901 shift_mode = HIshift; |
4845 break; | 4902 break; |
4846 case SImode: | 4903 case E_SImode: |
4847 shift_mode = SIshift; | 4904 shift_mode = SIshift; |
4848 break; | 4905 break; |
4849 default: | 4906 default: |
4850 gcc_unreachable (); | 4907 gcc_unreachable (); |
4851 } | 4908 } |
4921 expand_a_rotate (rtx operands[]) | 4978 expand_a_rotate (rtx operands[]) |
4922 { | 4979 { |
4923 rtx dst = operands[0]; | 4980 rtx dst = operands[0]; |
4924 rtx src = operands[1]; | 4981 rtx src = operands[1]; |
4925 rtx rotate_amount = operands[2]; | 4982 rtx rotate_amount = operands[2]; |
4926 enum machine_mode mode = GET_MODE (dst); | 4983 machine_mode mode = GET_MODE (dst); |
4927 | 4984 |
4928 if (h8sx_classify_shift (mode, ROTATE, rotate_amount) == H8SX_SHIFT_UNARY) | 4985 if (h8sx_classify_shift (mode, ROTATE, rotate_amount) == H8SX_SHIFT_UNARY) |
4929 return false; | 4986 return false; |
4930 | 4987 |
4931 /* We rotate in place. */ | 4988 /* We rotate in place. */ |
4932 emit_move_insn (dst, src); | 4989 emit_move_insn (dst, src); |
4933 | 4990 |
4934 if (GET_CODE (rotate_amount) != CONST_INT) | 4991 if (GET_CODE (rotate_amount) != CONST_INT) |
4935 { | 4992 { |
4936 rtx counter = gen_reg_rtx (QImode); | 4993 rtx counter = gen_reg_rtx (QImode); |
4937 rtx start_label = gen_label_rtx (); | 4994 rtx_code_label *start_label = gen_label_rtx (); |
4938 rtx end_label = gen_label_rtx (); | 4995 rtx_code_label *end_label = gen_label_rtx (); |
4939 | 4996 |
4940 /* If the rotate amount is less than or equal to 0, | 4997 /* If the rotate amount is less than or equal to 0, |
4941 we go out of the loop. */ | 4998 we go out of the loop. */ |
4942 emit_cmp_and_jump_insns (rotate_amount, const0_rtx, LE, NULL_RTX, | 4999 emit_cmp_and_jump_insns (rotate_amount, const0_rtx, LE, NULL_RTX, |
4943 QImode, 0, end_label); | 5000 QImode, 0, end_label); |
4948 emit_label (start_label); | 5005 emit_label (start_label); |
4949 | 5006 |
4950 /* Rotate by one bit. */ | 5007 /* Rotate by one bit. */ |
4951 switch (mode) | 5008 switch (mode) |
4952 { | 5009 { |
4953 case QImode: | 5010 case E_QImode: |
4954 emit_insn (gen_rotlqi3_1 (dst, dst, const1_rtx)); | 5011 emit_insn (gen_rotlqi3_1 (dst, dst, const1_rtx)); |
4955 break; | 5012 break; |
4956 case HImode: | 5013 case E_HImode: |
4957 emit_insn (gen_rotlhi3_1 (dst, dst, const1_rtx)); | 5014 emit_insn (gen_rotlhi3_1 (dst, dst, const1_rtx)); |
4958 break; | 5015 break; |
4959 case SImode: | 5016 case E_SImode: |
4960 emit_insn (gen_rotlsi3_1 (dst, dst, const1_rtx)); | 5017 emit_insn (gen_rotlsi3_1 (dst, dst, const1_rtx)); |
4961 break; | 5018 break; |
4962 default: | 5019 default: |
4963 gcc_unreachable (); | 5020 gcc_unreachable (); |
4964 } | 5021 } |
4976 else | 5033 else |
4977 { | 5034 { |
4978 /* Rotate by AMOUNT bits. */ | 5035 /* Rotate by AMOUNT bits. */ |
4979 switch (mode) | 5036 switch (mode) |
4980 { | 5037 { |
4981 case QImode: | 5038 case E_QImode: |
4982 emit_insn (gen_rotlqi3_1 (dst, dst, rotate_amount)); | 5039 emit_insn (gen_rotlqi3_1 (dst, dst, rotate_amount)); |
4983 break; | 5040 break; |
4984 case HImode: | 5041 case E_HImode: |
4985 emit_insn (gen_rotlhi3_1 (dst, dst, rotate_amount)); | 5042 emit_insn (gen_rotlhi3_1 (dst, dst, rotate_amount)); |
4986 break; | 5043 break; |
4987 case SImode: | 5044 case E_SImode: |
4988 emit_insn (gen_rotlsi3_1 (dst, dst, rotate_amount)); | 5045 emit_insn (gen_rotlsi3_1 (dst, dst, rotate_amount)); |
4989 break; | 5046 break; |
4990 default: | 5047 default: |
4991 gcc_unreachable (); | 5048 gcc_unreachable (); |
4992 } | 5049 } |
5005 enum shift_mode rotate_mode; | 5062 enum shift_mode rotate_mode; |
5006 enum shift_type rotate_type; | 5063 enum shift_type rotate_type; |
5007 const char *insn_buf; | 5064 const char *insn_buf; |
5008 int bits; | 5065 int bits; |
5009 int amount; | 5066 int amount; |
5010 enum machine_mode mode = GET_MODE (dst); | 5067 machine_mode mode = GET_MODE (dst); |
5011 | 5068 |
5012 gcc_assert (GET_CODE (rotate_amount) == CONST_INT); | 5069 gcc_assert (GET_CODE (rotate_amount) == CONST_INT); |
5013 | 5070 |
5014 switch (mode) | 5071 switch (mode) |
5015 { | 5072 { |
5016 case QImode: | 5073 case E_QImode: |
5017 rotate_mode = QIshift; | 5074 rotate_mode = QIshift; |
5018 break; | 5075 break; |
5019 case HImode: | 5076 case E_HImode: |
5020 rotate_mode = HIshift; | 5077 rotate_mode = HIshift; |
5021 break; | 5078 break; |
5022 case SImode: | 5079 case E_SImode: |
5023 rotate_mode = SIshift; | 5080 rotate_mode = SIshift; |
5024 break; | 5081 break; |
5025 default: | 5082 default: |
5026 gcc_unreachable (); | 5083 gcc_unreachable (); |
5027 } | 5084 } |
5064 || (mode == SImode && TARGET_H8300H && amount >= 10) | 5121 || (mode == SImode && TARGET_H8300H && amount >= 10) |
5065 || (mode == SImode && TARGET_H8300S && amount >= 13)) | 5122 || (mode == SImode && TARGET_H8300S && amount >= 13)) |
5066 { | 5123 { |
5067 switch (mode) | 5124 switch (mode) |
5068 { | 5125 { |
5069 case HImode: | 5126 case E_HImode: |
5070 /* This code works on any family. */ | 5127 /* This code works on any family. */ |
5071 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0"; | 5128 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0"; |
5072 output_asm_insn (insn_buf, operands); | 5129 output_asm_insn (insn_buf, operands); |
5073 break; | 5130 break; |
5074 | 5131 |
5075 case SImode: | 5132 case E_SImode: |
5076 /* This code works on the H8/300H and H8S. */ | 5133 /* This code works on the H8/300H and H8S. */ |
5077 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0"; | 5134 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0"; |
5078 output_asm_insn (insn_buf, operands); | 5135 output_asm_insn (insn_buf, operands); |
5079 break; | 5136 break; |
5080 | 5137 |
5108 unsigned int | 5165 unsigned int |
5109 compute_a_rotate_length (rtx *operands) | 5166 compute_a_rotate_length (rtx *operands) |
5110 { | 5167 { |
5111 rtx src = operands[1]; | 5168 rtx src = operands[1]; |
5112 rtx amount_rtx = operands[2]; | 5169 rtx amount_rtx = operands[2]; |
5113 enum machine_mode mode = GET_MODE (src); | 5170 machine_mode mode = GET_MODE (src); |
5114 int amount; | 5171 int amount; |
5115 unsigned int length = 0; | 5172 unsigned int length = 0; |
5116 | 5173 |
5117 gcc_assert (GET_CODE (amount_rtx) == CONST_INT); | 5174 gcc_assert (GET_CODE (amount_rtx) == CONST_INT); |
5118 | 5175 |
5168 ? single_zero_operand (operands[2], QImode) | 5225 ? single_zero_operand (operands[2], QImode) |
5169 : single_one_operand (operands[2], QImode)) | 5226 : single_one_operand (operands[2], QImode)) |
5170 { | 5227 { |
5171 /* OK to have a memory dest. */ | 5228 /* OK to have a memory dest. */ |
5172 if (GET_CODE (operands[0]) == MEM | 5229 if (GET_CODE (operands[0]) == MEM |
5173 && !OK_FOR_U (operands[0])) | 5230 && !satisfies_constraint_U (operands[0])) |
5174 { | 5231 { |
5175 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]), | 5232 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]), |
5176 copy_to_mode_reg (Pmode, | 5233 copy_to_mode_reg (Pmode, |
5177 XEXP (operands[0], 0))); | 5234 XEXP (operands[0], 0))); |
5178 MEM_COPY_ATTRIBUTES (mem, operands[0]); | 5235 MEM_COPY_ATTRIBUTES (mem, operands[0]); |
5179 operands[0] = mem; | 5236 operands[0] = mem; |
5180 } | 5237 } |
5181 | 5238 |
5182 if (GET_CODE (operands[1]) == MEM | 5239 if (GET_CODE (operands[1]) == MEM |
5183 && !OK_FOR_U (operands[1])) | 5240 && !satisfies_constraint_U (operands[1])) |
5184 { | 5241 { |
5185 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]), | 5242 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]), |
5186 copy_to_mode_reg (Pmode, | 5243 copy_to_mode_reg (Pmode, |
5187 XEXP (operands[1], 0))); | 5244 XEXP (operands[1], 0))); |
5188 MEM_COPY_ATTRIBUTES (mem, operands[0]); | 5245 MEM_COPY_ATTRIBUTES (mem, operands[0]); |
5365 tiny_data: This variable lives in the tiny data area and can be | 5422 tiny_data: This variable lives in the tiny data area and can be |
5366 referenced with 16-bit absolute memory references. */ | 5423 referenced with 16-bit absolute memory references. */ |
5367 | 5424 |
5368 static const struct attribute_spec h8300_attribute_table[] = | 5425 static const struct attribute_spec h8300_attribute_table[] = |
5369 { | 5426 { |
5370 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ | 5427 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, |
5371 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute }, | 5428 affects_type_identity } */ |
5372 { "saveall", 0, 0, true, false, false, h8300_handle_fndecl_attribute }, | 5429 { "interrupt_handler", 0, 0, true, false, false, |
5373 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute }, | 5430 h8300_handle_fndecl_attribute, false }, |
5374 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute }, | 5431 { "saveall", 0, 0, true, false, false, |
5375 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute }, | 5432 h8300_handle_fndecl_attribute, false }, |
5376 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute }, | 5433 { "OS_Task", 0, 0, true, false, false, |
5377 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute }, | 5434 h8300_handle_fndecl_attribute, false }, |
5378 { NULL, 0, 0, false, false, false, NULL } | 5435 { "monitor", 0, 0, true, false, false, |
5436 h8300_handle_fndecl_attribute, false }, | |
5437 { "function_vector", 0, 0, true, false, false, | |
5438 h8300_handle_fndecl_attribute, false }, | |
5439 { "eightbit_data", 0, 0, true, false, false, | |
5440 h8300_handle_eightbit_data_attribute, false }, | |
5441 { "tiny_data", 0, 0, true, false, false, | |
5442 h8300_handle_tiny_data_attribute, false }, | |
5443 { NULL, 0, 0, false, false, false, NULL, false } | |
5379 }; | 5444 }; |
5380 | 5445 |
5381 | 5446 |
5382 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in | 5447 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in |
5383 struct attribute_spec.handler. */ | 5448 struct attribute_spec.handler. */ |
5407 { | 5472 { |
5408 tree decl = *node; | 5473 tree decl = *node; |
5409 | 5474 |
5410 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) | 5475 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) |
5411 { | 5476 { |
5412 DECL_SECTION_NAME (decl) = build_string (7, ".eight"); | 5477 set_decl_section_name (decl, ".eight"); |
5413 } | 5478 } |
5414 else | 5479 else |
5415 { | 5480 { |
5416 warning (OPT_Wattributes, "%qE attribute ignored", | 5481 warning (OPT_Wattributes, "%qE attribute ignored", |
5417 name); | 5482 name); |
5431 { | 5496 { |
5432 tree decl = *node; | 5497 tree decl = *node; |
5433 | 5498 |
5434 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) | 5499 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) |
5435 { | 5500 { |
5436 DECL_SECTION_NAME (decl) = build_string (6, ".tiny"); | 5501 set_decl_section_name (decl, ".tiny"); |
5437 } | 5502 } |
5438 else | 5503 else |
5439 { | 5504 { |
5440 warning (OPT_Wattributes, "%qE attribute ignored", | 5505 warning (OPT_Wattributes, "%qE attribute ignored", |
5441 name); | 5506 name); |
5553 unsigned HOST_WIDE_INT addr; | 5618 unsigned HOST_WIDE_INT addr; |
5554 | 5619 |
5555 /* We accept symbols declared with eightbit_data. */ | 5620 /* We accept symbols declared with eightbit_data. */ |
5556 if (GET_CODE (x) == SYMBOL_REF) | 5621 if (GET_CODE (x) == SYMBOL_REF) |
5557 return (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_EIGHTBIT_DATA) != 0; | 5622 return (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_EIGHTBIT_DATA) != 0; |
5623 | |
5624 if (GET_CODE (x) == CONST | |
5625 && GET_CODE (XEXP (x, 0)) == PLUS | |
5626 && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF | |
5627 && (SYMBOL_REF_FLAGS (XEXP (XEXP (x, 0), 0)) & SYMBOL_FLAG_EIGHTBIT_DATA) != 0) | |
5628 return 1; | |
5558 | 5629 |
5559 if (GET_CODE (x) != CONST_INT) | 5630 if (GET_CODE (x) != CONST_INT) |
5560 return 0; | 5631 return 0; |
5561 | 5632 |
5562 addr = INTVAL (x); | 5633 addr = INTVAL (x); |
5661 | 5732 |
5662 /* Return nonzero if we have the same comparison insn as I3 two insns | 5733 /* Return nonzero if we have the same comparison insn as I3 two insns |
5663 before I3. I3 is assumed to be a comparison insn. */ | 5734 before I3. I3 is assumed to be a comparison insn. */ |
5664 | 5735 |
5665 int | 5736 int |
5666 same_cmp_preceding_p (rtx i3) | 5737 same_cmp_preceding_p (rtx_insn *i3) |
5667 { | 5738 { |
5668 rtx i1, i2; | 5739 rtx_insn *i1, *i2; |
5669 | 5740 |
5670 /* Make sure we have a sequence of three insns. */ | 5741 /* Make sure we have a sequence of three insns. */ |
5671 i2 = prev_nonnote_insn (i3); | 5742 i2 = prev_nonnote_insn (i3); |
5672 if (i2 == NULL_RTX) | 5743 if (i2 == NULL) |
5673 return 0; | 5744 return 0; |
5674 i1 = prev_nonnote_insn (i2); | 5745 i1 = prev_nonnote_insn (i2); |
5675 if (i1 == NULL_RTX) | 5746 if (i1 == NULL) |
5676 return 0; | 5747 return 0; |
5677 | 5748 |
5678 return (INSN_P (i1) && rtx_equal_p (PATTERN (i1), PATTERN (i3)) | 5749 return (INSN_P (i1) && rtx_equal_p (PATTERN (i1), PATTERN (i3)) |
5679 && any_condjump_p (i2) && onlyjump_p (i2)); | 5750 && any_condjump_p (i2) && onlyjump_p (i2)); |
5680 } | 5751 } |
5681 | 5752 |
5682 /* Return nonzero if we have the same comparison insn as I1 two insns | 5753 /* Return nonzero if we have the same comparison insn as I1 two insns |
5683 after I1. I1 is assumed to be a comparison insn. */ | 5754 after I1. I1 is assumed to be a comparison insn. */ |
5684 | 5755 |
5685 int | 5756 int |
5686 same_cmp_following_p (rtx i1) | 5757 same_cmp_following_p (rtx_insn *i1) |
5687 { | 5758 { |
5688 rtx i2, i3; | 5759 rtx_insn *i2, *i3; |
5689 | 5760 |
5690 /* Make sure we have a sequence of three insns. */ | 5761 /* Make sure we have a sequence of three insns. */ |
5691 i2 = next_nonnote_insn (i1); | 5762 i2 = next_nonnote_insn (i1); |
5692 if (i2 == NULL_RTX) | 5763 if (i2 == NULL) |
5693 return 0; | 5764 return 0; |
5694 i3 = next_nonnote_insn (i2); | 5765 i3 = next_nonnote_insn (i2); |
5695 if (i3 == NULL_RTX) | 5766 if (i3 == NULL) |
5696 return 0; | 5767 return 0; |
5697 | 5768 |
5698 return (INSN_P (i3) && rtx_equal_p (PATTERN (i1), PATTERN (i3)) | 5769 return (INSN_P (i3) && rtx_equal_p (PATTERN (i1), PATTERN (i3)) |
5699 && any_condjump_p (i2) && onlyjump_p (i2)); | 5770 && any_condjump_p (i2) && onlyjump_p (i2)); |
5700 } | 5771 } |
5759 | 5830 |
5760 return true; | 5831 return true; |
5761 } | 5832 } |
5762 | 5833 |
5763 | 5834 |
5764 /* Return nonzero if X is a legitimate constant. */ | |
5765 | |
5766 int | |
5767 h8300_legitimate_constant_p (rtx x ATTRIBUTE_UNUSED) | |
5768 { | |
5769 return 1; | |
5770 } | |
5771 | |
5772 /* Return nonzero if X is a REG or SUBREG suitable as a base register. */ | 5835 /* Return nonzero if X is a REG or SUBREG suitable as a base register. */ |
5773 | 5836 |
5774 static int | 5837 static int |
5775 h8300_rtx_ok_for_base_p (rtx x, int strict) | 5838 h8300_rtx_ok_for_base_p (rtx x, int strict) |
5776 { | 5839 { |
5787 /* Return nozero if X is a legitimate address. On the H8/300, a | 5850 /* Return nozero if X is a legitimate address. On the H8/300, a |
5788 legitimate address has the form REG, REG+CONSTANT_ADDRESS or | 5851 legitimate address has the form REG, REG+CONSTANT_ADDRESS or |
5789 CONSTANT_ADDRESS. */ | 5852 CONSTANT_ADDRESS. */ |
5790 | 5853 |
5791 static bool | 5854 static bool |
5792 h8300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) | 5855 h8300_legitimate_address_p (machine_mode mode, rtx x, bool strict) |
5793 { | 5856 { |
5794 /* The register indirect addresses like @er0 is always valid. */ | 5857 /* The register indirect addresses like @er0 is always valid. */ |
5795 if (h8300_rtx_ok_for_base_p (x, strict)) | 5858 if (h8300_rtx_ok_for_base_p (x, strict)) |
5796 return 1; | 5859 return 1; |
5797 | 5860 |
5813 return 1; | 5876 return 1; |
5814 | 5877 |
5815 return 0; | 5878 return 0; |
5816 } | 5879 } |
5817 | 5880 |
5818 /* Worker function for HARD_REGNO_NREGS. | 5881 /* Implement TARGET_HARD_REGNO_MODE_OK. */ |
5819 | 5882 |
5820 We pretend the MAC register is 32bits -- we don't have any data | 5883 static bool |
5821 types on the H8 series to handle more than 32bits. */ | 5884 h8300_hard_regno_mode_ok (unsigned int regno, machine_mode mode) |
5822 | |
5823 int | |
5824 h8300_hard_regno_nregs (int regno ATTRIBUTE_UNUSED, enum machine_mode mode) | |
5825 { | |
5826 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; | |
5827 } | |
5828 | |
5829 /* Worker function for HARD_REGNO_MODE_OK. */ | |
5830 | |
5831 int | |
5832 h8300_hard_regno_mode_ok (int regno, enum machine_mode mode) | |
5833 { | 5885 { |
5834 if (TARGET_H8300) | 5886 if (TARGET_H8300) |
5835 /* If an even reg, then anything goes. Otherwise the mode must be | 5887 /* If an even reg, then anything goes. Otherwise the mode must be |
5836 QI or HI. */ | 5888 QI or HI. */ |
5837 return ((regno & 1) == 0) || (mode == HImode) || (mode == QImode); | 5889 return ((regno & 1) == 0) || (mode == HImode) || (mode == QImode); |
5838 else | 5890 else |
5839 /* MAC register can only be of SImode. Otherwise, anything | 5891 /* MAC register can only be of SImode. Otherwise, anything |
5840 goes. */ | 5892 goes. */ |
5841 return regno == MAC_REG ? mode == SImode : 1; | 5893 return regno == MAC_REG ? mode == SImode : 1; |
5842 } | 5894 } |
5895 | |
5896 /* Implement TARGET_MODES_TIEABLE_P. */ | |
5897 | |
5898 static bool | |
5899 h8300_modes_tieable_p (machine_mode mode1, machine_mode mode2) | |
5900 { | |
5901 return (mode1 == mode2 | |
5902 || ((mode1 == QImode | |
5903 || mode1 == HImode | |
5904 || ((TARGET_H8300H || TARGET_H8300S) && mode1 == SImode)) | |
5905 && (mode2 == QImode | |
5906 || mode2 == HImode | |
5907 || ((TARGET_H8300H || TARGET_H8300S) && mode2 == SImode)))); | |
5908 } | |
5909 | |
5910 /* Helper function for the move patterns. Make sure a move is legitimate. */ | |
5911 | |
5912 bool | |
5913 h8300_move_ok (rtx dest, rtx src) | |
5914 { | |
5915 rtx addr, other; | |
5916 | |
5917 /* Validate that at least one operand is a register. */ | |
5918 if (MEM_P (dest)) | |
5919 { | |
5920 if (MEM_P (src) || CONSTANT_P (src)) | |
5921 return false; | |
5922 addr = XEXP (dest, 0); | |
5923 other = src; | |
5924 } | |
5925 else if (MEM_P (src)) | |
5926 { | |
5927 addr = XEXP (src, 0); | |
5928 other = dest; | |
5929 } | |
5930 else | |
5931 return true; | |
5932 | |
5933 /* Validate that auto-inc doesn't affect OTHER. */ | |
5934 if (GET_RTX_CLASS (GET_CODE (addr)) != RTX_AUTOINC) | |
5935 return true; | |
5936 addr = XEXP (addr, 0); | |
5937 | |
5938 if (addr == stack_pointer_rtx) | |
5939 return register_no_sp_elim_operand (other, VOIDmode); | |
5940 else | |
5941 return !reg_overlap_mentioned_p(other, addr); | |
5942 } | |
5843 | 5943 |
5844 /* Perform target dependent optabs initialization. */ | 5944 /* Perform target dependent optabs initialization. */ |
5845 static void | 5945 static void |
5846 h8300_init_libfuncs (void) | 5946 h8300_init_libfuncs (void) |
5847 { | 5947 { |
5850 set_optab_libfunc (udiv_optab, HImode, "__udivhi3"); | 5950 set_optab_libfunc (udiv_optab, HImode, "__udivhi3"); |
5851 set_optab_libfunc (smod_optab, HImode, "__modhi3"); | 5951 set_optab_libfunc (smod_optab, HImode, "__modhi3"); |
5852 set_optab_libfunc (umod_optab, HImode, "__umodhi3"); | 5952 set_optab_libfunc (umod_optab, HImode, "__umodhi3"); |
5853 } | 5953 } |
5854 | 5954 |
5955 /* Worker function for TARGET_FUNCTION_VALUE. | |
5956 | |
5957 On the H8 the return value is in R0/R1. */ | |
5958 | |
5959 static rtx | |
5960 h8300_function_value (const_tree ret_type, | |
5961 const_tree fn_decl_or_type ATTRIBUTE_UNUSED, | |
5962 bool outgoing ATTRIBUTE_UNUSED) | |
5963 { | |
5964 return gen_rtx_REG (TYPE_MODE (ret_type), R0_REG); | |
5965 } | |
5966 | |
5967 /* Worker function for TARGET_LIBCALL_VALUE. | |
5968 | |
5969 On the H8 the return value is in R0/R1. */ | |
5970 | |
5971 static rtx | |
5972 h8300_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED) | |
5973 { | |
5974 return gen_rtx_REG (mode, R0_REG); | |
5975 } | |
5976 | |
5977 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P. | |
5978 | |
5979 On the H8, R0 is the only register thus used. */ | |
5980 | |
5981 static bool | |
5982 h8300_function_value_regno_p (const unsigned int regno) | |
5983 { | |
5984 return (regno == R0_REG); | |
5985 } | |
5986 | |
5855 /* Worker function for TARGET_RETURN_IN_MEMORY. */ | 5987 /* Worker function for TARGET_RETURN_IN_MEMORY. */ |
5856 | 5988 |
5857 static bool | 5989 static bool |
5858 h8300_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) | 5990 h8300_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) |
5859 { | 5991 { |
5924 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true | 6056 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true |
5925 | 6057 |
5926 #undef TARGET_ASM_FILE_END | 6058 #undef TARGET_ASM_FILE_END |
5927 #define TARGET_ASM_FILE_END h8300_file_end | 6059 #define TARGET_ASM_FILE_END h8300_file_end |
5928 | 6060 |
6061 #undef TARGET_PRINT_OPERAND | |
6062 #define TARGET_PRINT_OPERAND h8300_print_operand | |
6063 #undef TARGET_PRINT_OPERAND_ADDRESS | |
6064 #define TARGET_PRINT_OPERAND_ADDRESS h8300_print_operand_address | |
6065 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P | |
6066 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P h8300_print_operand_punct_valid_p | |
6067 | |
5929 #undef TARGET_ENCODE_SECTION_INFO | 6068 #undef TARGET_ENCODE_SECTION_INFO |
5930 #define TARGET_ENCODE_SECTION_INFO h8300_encode_section_info | 6069 #define TARGET_ENCODE_SECTION_INFO h8300_encode_section_info |
5931 | 6070 |
5932 #undef TARGET_INSERT_ATTRIBUTES | 6071 #undef TARGET_INSERT_ATTRIBUTES |
5933 #define TARGET_INSERT_ATTRIBUTES h8300_insert_attributes | 6072 #define TARGET_INSERT_ATTRIBUTES h8300_insert_attributes |
5934 | 6073 |
6074 #undef TARGET_REGISTER_MOVE_COST | |
6075 #define TARGET_REGISTER_MOVE_COST h8300_register_move_cost | |
6076 | |
5935 #undef TARGET_RTX_COSTS | 6077 #undef TARGET_RTX_COSTS |
5936 #define TARGET_RTX_COSTS h8300_rtx_costs | 6078 #define TARGET_RTX_COSTS h8300_rtx_costs |
5937 | 6079 |
5938 #undef TARGET_INIT_LIBFUNCS | 6080 #undef TARGET_INIT_LIBFUNCS |
5939 #define TARGET_INIT_LIBFUNCS h8300_init_libfuncs | 6081 #define TARGET_INIT_LIBFUNCS h8300_init_libfuncs |
5940 | 6082 |
6083 #undef TARGET_FUNCTION_VALUE | |
6084 #define TARGET_FUNCTION_VALUE h8300_function_value | |
6085 | |
6086 #undef TARGET_LIBCALL_VALUE | |
6087 #define TARGET_LIBCALL_VALUE h8300_libcall_value | |
6088 | |
6089 #undef TARGET_FUNCTION_VALUE_REGNO_P | |
6090 #define TARGET_FUNCTION_VALUE_REGNO_P h8300_function_value_regno_p | |
6091 | |
5941 #undef TARGET_RETURN_IN_MEMORY | 6092 #undef TARGET_RETURN_IN_MEMORY |
5942 #define TARGET_RETURN_IN_MEMORY h8300_return_in_memory | 6093 #define TARGET_RETURN_IN_MEMORY h8300_return_in_memory |
5943 | 6094 |
5944 #undef TARGET_FUNCTION_ARG | 6095 #undef TARGET_FUNCTION_ARG |
5945 #define TARGET_FUNCTION_ARG h8300_function_arg | 6096 #define TARGET_FUNCTION_ARG h8300_function_arg |
5951 #define TARGET_MACHINE_DEPENDENT_REORG h8300_reorg | 6102 #define TARGET_MACHINE_DEPENDENT_REORG h8300_reorg |
5952 | 6103 |
5953 #undef TARGET_HARD_REGNO_SCRATCH_OK | 6104 #undef TARGET_HARD_REGNO_SCRATCH_OK |
5954 #define TARGET_HARD_REGNO_SCRATCH_OK h8300_hard_regno_scratch_ok | 6105 #define TARGET_HARD_REGNO_SCRATCH_OK h8300_hard_regno_scratch_ok |
5955 | 6106 |
6107 #undef TARGET_HARD_REGNO_MODE_OK | |
6108 #define TARGET_HARD_REGNO_MODE_OK h8300_hard_regno_mode_ok | |
6109 | |
6110 #undef TARGET_MODES_TIEABLE_P | |
6111 #define TARGET_MODES_TIEABLE_P h8300_modes_tieable_p | |
6112 | |
6113 #undef TARGET_LRA_P | |
6114 #define TARGET_LRA_P hook_bool_void_false | |
6115 | |
5956 #undef TARGET_LEGITIMATE_ADDRESS_P | 6116 #undef TARGET_LEGITIMATE_ADDRESS_P |
5957 #define TARGET_LEGITIMATE_ADDRESS_P h8300_legitimate_address_p | 6117 #define TARGET_LEGITIMATE_ADDRESS_P h8300_legitimate_address_p |
5958 | 6118 |
5959 #undef TARGET_DEFAULT_TARGET_FLAGS | |
5960 #define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT | |
5961 | |
5962 #undef TARGET_CAN_ELIMINATE | 6119 #undef TARGET_CAN_ELIMINATE |
5963 #define TARGET_CAN_ELIMINATE h8300_can_eliminate | 6120 #define TARGET_CAN_ELIMINATE h8300_can_eliminate |
5964 | 6121 |
5965 #undef TARGET_CONDITIONAL_REGISTER_USAGE | 6122 #undef TARGET_CONDITIONAL_REGISTER_USAGE |
5966 #define TARGET_CONDITIONAL_REGISTER_USAGE h8300_conditional_register_usage | 6123 #define TARGET_CONDITIONAL_REGISTER_USAGE h8300_conditional_register_usage |
5969 #define TARGET_TRAMPOLINE_INIT h8300_trampoline_init | 6126 #define TARGET_TRAMPOLINE_INIT h8300_trampoline_init |
5970 | 6127 |
5971 #undef TARGET_OPTION_OVERRIDE | 6128 #undef TARGET_OPTION_OVERRIDE |
5972 #define TARGET_OPTION_OVERRIDE h8300_option_override | 6129 #define TARGET_OPTION_OVERRIDE h8300_option_override |
5973 | 6130 |
5974 #undef TARGET_OPTION_OPTIMIZATION_TABLE | 6131 #undef TARGET_MODE_DEPENDENT_ADDRESS_P |
5975 #define TARGET_OPTION_OPTIMIZATION_TABLE h8300_option_optimization_table | 6132 #define TARGET_MODE_DEPENDENT_ADDRESS_P h8300_mode_dependent_address_p |
5976 | |
5977 #undef TARGET_EXCEPT_UNWIND_INFO | |
5978 #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info | |
5979 | 6133 |
5980 struct gcc_target targetm = TARGET_INITIALIZER; | 6134 struct gcc_target targetm = TARGET_INITIALIZER; |