From 2d70f6d43551f5e6344909b8f2020a92ae7e4839 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 30 Jan 2014 16:01:43 +0000 Subject: [PATCH] rl78.c (register_sizes): Make the "upper half" of %fp 2 to keep registers after it properly word-aligned. * config/rl78/rl78.c (register_sizes): Make the "upper half" of %fp 2 to keep registers after it properly word-aligned. (rl78_alloc_physical_registers_umul): Handle the case where both input operands are the same. Co-Authored-By: DJ Delorie From-SVN: r207308 --- gcc/ChangeLog | 8 +++++ gcc/config/rl78/rl78.c | 74 ++++++++++++++++++++++++------------------ 2 files changed, 51 insertions(+), 31 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ca5a89311ef..b659fb59eee 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2014-01-30 Nick Clifton + DJ Delorie + + * config/rl78/rl78.c (register_sizes): Make the "upper half" of + %fp 2 to keep registers after it properly word-aligned. + (rl78_alloc_physical_registers_umul): Handle the case where both + input operands are the same. + 2014-01-30 Richard Biener PR tree-optimization/59903 diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c index 227a39be6f2..b5cd2ad7516 100644 --- a/gcc/config/rl78/rl78.c +++ b/gcc/config/rl78/rl78.c @@ -327,13 +327,15 @@ rl78_option_override (void) } /* Most registers are 8 bits. Some are 16 bits because, for example, - gcc doesn't like dealing with $FP as a register pair. This table - maps register numbers to size in bytes. */ + gcc doesn't like dealing with $FP as a register pair (the second + half of $fp is also 2 to keep reload happy wrt register pairs, but + no register class includes it). This table maps register numbers + to size in bytes. */ static const int register_sizes[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1 }; @@ -381,7 +383,7 @@ rl78_hard_regno_mode_ok (int regno, enum machine_mode mode) /* These are not to be used by gcc. */ if (regno == 23 || regno == ES_REG || regno == CS_REG) return 0; - /* $fp can alway sbe accessed as a 16-bit value. */ + /* $fp can always be accessed as a 16-bit value. */ if (regno == FP_REG && s == 2) return 1; if (regno < SP_REG) @@ -659,10 +661,10 @@ is_brk_interrupt_func (const_tree decl) /* Check "interrupt" attributes. */ static tree rl78_handle_func_attribute (tree * node, - tree name, - tree args, - int flags ATTRIBUTE_UNUSED, - bool * no_add_attrs) + tree name, + tree args, + int flags ATTRIBUTE_UNUSED, + bool * no_add_attrs) { gcc_assert (DECL_P (* node)); gcc_assert (args == NULL_TREE); @@ -820,14 +822,14 @@ rl78_far_p (rtx x) if (! MEM_P (x)) return 0; #if DEBUG0 - fprintf (stderr, "\033[35mrl78_far_p: "); debug_rtx(x); + fprintf (stderr, "\033[35mrl78_far_p: "); debug_rtx (x); fprintf (stderr, " = %d\033[0m\n", MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR); #endif return MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR; } /* Return the appropriate mode for a named address pointer. */ -#undef TARGET_ADDR_SPACE_POINTER_MODE +#undef TARGET_ADDR_SPACE_POINTER_MODE #define TARGET_ADDR_SPACE_POINTER_MODE rl78_addr_space_pointer_mode static enum machine_mode rl78_addr_space_pointer_mode (addr_space_t addrspace) @@ -844,7 +846,7 @@ rl78_addr_space_pointer_mode (addr_space_t addrspace) } /* Returns TRUE for valid addresses. */ -#undef TARGET_VALID_POINTER_MODE +#undef TARGET_VALID_POINTER_MODE #define TARGET_VALID_POINTER_MODE rl78_valid_pointer_mode static bool rl78_valid_pointer_mode (enum machine_mode m) @@ -853,7 +855,7 @@ rl78_valid_pointer_mode (enum machine_mode m) } /* Return the appropriate mode for a named address address. */ -#undef TARGET_ADDR_SPACE_ADDRESS_MODE +#undef TARGET_ADDR_SPACE_ADDRESS_MODE #define TARGET_ADDR_SPACE_ADDRESS_MODE rl78_addr_space_address_mode static enum machine_mode rl78_addr_space_address_mode (addr_space_t addrspace) @@ -1796,7 +1798,7 @@ rl78_peep_movhi_p (rtx *operands) { #if DEBUG_PEEP fprintf (stderr, "no peep: wrong mem %d\n", i); - debug_rtx(m); + debug_rtx (m); debug_rtx (operands[i+2]); #endif return false; @@ -1832,7 +1834,7 @@ rl78_setup_peep_movhi (rtx *operands) break; case CONST_INT: - operands[i+4] = GEN_INT ((INTVAL (operands[i]) & 0xff) + ((char)INTVAL (operands[i+2])) * 256); + operands[i+4] = GEN_INT ((INTVAL (operands[i]) & 0xff) + ((char) INTVAL (operands[i+2])) * 256); break; case MEM: @@ -2031,7 +2033,7 @@ update_content (unsigned char index, unsigned char val, enum machine_mode mode) else fprintf (dump_file, "%s and vice versa\n", get_content_name (val, mode)); } - + if (mode == HImode) { val = val == NOT_KNOWN ? val : val + 1; @@ -2054,7 +2056,7 @@ update_content (unsigned char index, unsigned char val, enum machine_mode mode) ++ i; continue; } - + if (content_memory[i] == index || (val != NOT_KNOWN && content_memory[i] == val)) { @@ -2269,7 +2271,7 @@ EM2 (int line ATTRIBUTE_UNUSED, rtx r) { #if DEBUG_ALLOC fprintf (stderr, "\033[36m%d: ", line); - debug_rtx(r); + debug_rtx (r); fprintf (stderr, "\033[0m"); #endif /*SCHED_GROUP_P (r) = 1;*/ @@ -2363,7 +2365,7 @@ gen_and_emit_move (rtx to, rtx from, rtx where, bool before) else { rtx move = mode == QImode ? gen_movqi (to, from) : gen_movhi (to, from); - + EM (move); if (where == NULL_RTX) @@ -2521,7 +2523,7 @@ force_into_acc (rtx src, rtx before) return; move = mode == QImode ? gen_movqi (A, src) : gen_movhi (AX, src); - + EM (move); emit_insn_before (move, before); @@ -2683,7 +2685,7 @@ has_constraint (unsigned int opnum, enum constraint_num constraint) /* No constraints means anything is accepted. */ if (p == NULL || *p == 0 || *p == ',') return true; - + do { char c; @@ -2750,7 +2752,7 @@ rl78_alloc_physical_registers_op2 (rtx insn) } /* Make a note of whether (H)L is being used. It matters - because if OP (2) alsoneeds reloading, then we must take + because if OP (2) also needs reloading, then we must take care not to corrupt HL. */ hl_used = reg_mentioned_p (L, OP (0)) || reg_mentioned_p (L, OP (1)); @@ -2764,7 +2766,7 @@ rl78_alloc_physical_registers_op2 (rtx insn) /* If op0 is a Ws1 type memory address then switching the base address register to HL might allow us to perform an in-memory operation. (eg for the INCW instruction). - + FIXME: Adding the move into HL is costly if this optimization is not going to work, so for now, make sure that we know that the new insn will match the requirements of the addhi3_real pattern. Really we ought to @@ -2786,7 +2788,7 @@ rl78_alloc_physical_registers_op2 (rtx insn) newbase = gen_and_emit_move (HL, base, insn, true); record_content (newbase, NULL_RTX); newbase = gen_rtx_PLUS (HImode, newbase, addend); - + OP (0) = OP (1) = change_address (OP (0), VOIDmode, newbase); /* We do not want to fail here as this means that @@ -2817,7 +2819,7 @@ rl78_alloc_physical_registers_op2 (rtx insn) record_content (HL, NULL_RTX); newbase = gen_rtx_PLUS (HImode, HL, addend); - + OP (2) = change_address (OP (2), VOIDmode, newbase); /* We do not want to fail here as this means that @@ -2857,7 +2859,7 @@ rl78_alloc_physical_registers_op2 (rtx insn) ; OP (2) = hl_used ? move_to_de (2, first) : move_to_hl (2, first); - + MUST_BE_OK (insn); } @@ -2923,7 +2925,7 @@ rl78_alloc_physical_registers_cmp (rtx insn) default: gcc_unreachable (); } - + if (GET_CODE (cmp) == EQ || GET_CODE (cmp) == NE) PATTERN (insn) = gen_cbranchhi4_real (cmp, OP (2), OP (1), OP (3)); else @@ -2939,7 +2941,7 @@ rl78_alloc_physical_registers_cmp (rtx insn) OP (1) = OP (2) = BC; MUST_BE_OK (insn); } - + tmp_id = get_max_insn_count (); saved_op1 = OP (1); @@ -2967,7 +2969,7 @@ rl78_alloc_physical_registers_cmp (rtx insn) MUST_BE_OK (insn); } -/* Like op2, but AX = A op X. */ +/* Like op2, but AX = A * X. */ static void rl78_alloc_physical_registers_umul (rtx insn) { @@ -2996,8 +2998,18 @@ rl78_alloc_physical_registers_umul (rtx insn) tmp_id = get_max_insn_count (); saved_op1 = OP (1); - - OP (1) = move_to_acc (1, insn); + + if (rtx_equal_p (OP (1), OP (2))) + { + gcc_assert (GET_MODE (OP (2)) == QImode); + /* The MULU instruction does not support duplicate arguments + but we know that if we copy OP (2) to X it will do so via + A and thus OP (1) will already be loaded into A. */ + OP (2) = move_to_x (2, insn); + OP (1) = A; + } + else + OP (1) = move_to_acc (1, insn); MAYBE_OK (insn); @@ -3129,7 +3141,7 @@ rl78_alloc_physical_registers (void) { if (LABEL_P (insn)) clear_content_memory (); - + continue; }