diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1c9daf251e6..7bbb1cf6bf3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2008-09-05 Bob Wilson + + * config/xtensa/predicates.md (nonimmed_operand, mem_operand): Use + constantpool_mem_p. + (constantpool_operand): New. + (move_operand): Disallow sub-word modes for the constant pool. + * config/xtensa/xtensa.c (TARGET_SECONDARY_RELOAD): Define. + (xtensa_secondary_reload_class): Replace with.... + (xtensa_secondary_reload): this function. Remove SIGN_EXTEND check. + Set icode for sub-word reloads from the constant pool. + * config/xtensa/xtensa.h (SECONDARY_INPUT_RELOAD_CLASS): Delete. + (SECONDARY_OUTPUT_RELOAD_CLASS): Delete. + * config/xtensa/xtensa.md (reload_literal): New. + * config/xtensa/xtensa-protos.h: Update prototypes. + 2008-09-05 Joseph Myers * config/mips/mips.h (enum reg_class): Add FRAME_REGS. diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md index 39a4cc16991..c96f63730c4 100644 --- a/gcc/config/xtensa/predicates.md +++ b/gcc/config/xtensa/predicates.md @@ -1,5 +1,5 @@ ;; Predicate definitions for Xtensa. -;; Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. +;; Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. ;; ;; This file is part of GCC. ;; @@ -37,13 +37,17 @@ ;; Non-immediate operand excluding the constant pool. (define_predicate "nonimmed_operand" (ior (and (match_operand 0 "memory_operand") - (match_test "!constantpool_address_p (XEXP (op, 0))")) + (match_test "!constantpool_mem_p (op)")) (match_operand 0 "register_operand"))) ;; Memory operand excluding the constant pool. (define_predicate "mem_operand" (and (match_operand 0 "memory_operand") - (match_test "!constantpool_address_p (XEXP (op, 0))"))) + (match_test "!constantpool_mem_p (op)"))) + +;; Memory operand in the constant pool. +(define_predicate "constantpool_operand" + (match_test "constantpool_mem_p (op)")) (define_predicate "mask_operand" (ior (and (match_code "const_int") @@ -131,7 +135,9 @@ (define_predicate "move_operand" (ior (ior (match_operand 0 "register_operand") - (match_operand 0 "memory_operand")) + (and (match_operand 0 "memory_operand") + (match_test "!constantpool_mem_p (op) + || GET_MODE_SIZE (mode) % UNITS_PER_WORD == 0"))) (ior (and (match_code "const_int") (match_test "GET_MODE_CLASS (mode) == MODE_INT && xtensa_simm12b (INTVAL (op))")) diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h index 82d7262922d..7ecde9baf21 100644 --- a/gcc/config/xtensa/xtensa-protos.h +++ b/gcc/config/xtensa/xtensa-protos.h @@ -1,5 +1,6 @@ /* Prototypes of target machine for GNU compiler for Xtensa. - Copyright 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. + Copyright 2001, 2002, 2003, 2004, 2005, 2007, 2008 + Free Software Foundation, Inc. Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica. This file is part of GCC. @@ -66,9 +67,10 @@ extern bool xtensa_output_addr_const_extra (FILE *, rtx); extern void xtensa_output_literal (FILE *, rtx, enum machine_mode, int); extern rtx xtensa_return_addr (int, rtx); extern enum reg_class xtensa_preferred_reload_class (rtx, enum reg_class, int); -extern enum reg_class xtensa_secondary_reload_class (enum reg_class, - enum machine_mode, rtx, - int); +struct secondary_reload_info; +extern enum reg_class xtensa_secondary_reload (bool, rtx, enum reg_class, + enum machine_mode, + struct secondary_reload_info *); extern void xtensa_initialize_trampoline (rtx, rtx, rtx); #endif /* RTX_CODE */ diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index 3bb71eb5c13..1af9cbab450 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -216,6 +216,9 @@ static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] = #undef TARGET_EXPAND_BUILTIN #define TARGET_EXPAND_BUILTIN xtensa_expand_builtin +#undef TARGET_SECONDARY_RELOAD +#define TARGET_SECONDARY_RELOAD xtensa_secondary_reload + struct gcc_target targetm = TARGET_INITIALIZER; @@ -2840,22 +2843,23 @@ xtensa_preferred_reload_class (rtx x, enum reg_class rclass, int isoutput) enum reg_class -xtensa_secondary_reload_class (enum reg_class rclass, - enum machine_mode mode ATTRIBUTE_UNUSED, - rtx x, int isoutput) +xtensa_secondary_reload (bool in_p, rtx x, enum reg_class rclass, + enum machine_mode mode, secondary_reload_info *sri) { int regno; - if (GET_CODE (x) == SIGN_EXTEND) - x = XEXP (x, 0); - regno = xt_true_regnum (x); - - if (!isoutput) + if (in_p && constantpool_mem_p (x)) { - if (rclass == FP_REGS && constantpool_mem_p (x)) + if (rclass == FP_REGS) return RL_REGS; + + if (mode == QImode) + sri->icode = CODE_FOR_reloadqi_literal; + else if (mode == HImode) + sri->icode = CODE_FOR_reloadhi_literal; } + regno = xt_true_regnum (x); if (ACC_REG_P (regno)) return ((rclass == GR_REGS || rclass == RL_REGS) ? NO_REGS : RL_REGS); if (rclass == ACC_REG) diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h index fecb56996e3..ab3b648ffa4 100644 --- a/gcc/config/xtensa/xtensa.h +++ b/gcc/config/xtensa/xtensa.h @@ -508,12 +508,6 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER]; #define PREFERRED_OUTPUT_RELOAD_CLASS(X, CLASS) \ xtensa_preferred_reload_class (X, CLASS, 1) -#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \ - xtensa_secondary_reload_class (CLASS, MODE, X, 0) - -#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \ - xtensa_secondary_reload_class (CLASS, MODE, X, 1) - /* Return the maximum number of consecutive registers needed to represent mode MODE in a register of class CLASS. */ #define CLASS_UNITS(mode, size) \ diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index cffbcd12f94..4f831d3f22c 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -880,6 +880,31 @@ (set_attr "mode" "QI") (set_attr "length" "2,2,3,3,3,3,3,3")]) +;; Sub-word reloads from the constant pool. + +(define_expand "reload_literal" + [(parallel [(match_operand:HQI 0 "register_operand" "=r") + (match_operand:HQI 1 "constantpool_operand" "") + (match_operand:SI 2 "register_operand" "=&r")])] + "" +{ + rtx lit, scratch; + unsigned word_off, byte_off; + + gcc_assert (GET_CODE (operands[1]) == SUBREG); + lit = SUBREG_REG (operands[1]); + scratch = operands[2]; + word_off = SUBREG_BYTE (operands[1]) & ~(UNITS_PER_WORD - 1); + byte_off = SUBREG_BYTE (operands[1]) - word_off; + + lit = adjust_address (lit, SImode, word_off); + emit_insn (gen_movsi (scratch, lit)); + emit_insn (gen_mov (operands[0], + gen_rtx_SUBREG (mode, scratch, byte_off))); + + DONE; +}) + ;; 32-bit floating point moves (define_expand "movsf"