diff options
author | Bob Wilson <bwilson@gcc.gnu.org> | 2003-05-14 18:37:26 +0000 |
---|---|---|
committer | Bob Wilson <bwilson@gcc.gnu.org> | 2003-05-14 18:37:26 +0000 |
commit | f42f5a1b1ec954dd53ea998ff4188c1de8001b0d (patch) | |
tree | 53e02cd6e93361aefa86a3f9c17e1833caeb547d /gcc/config/xtensa/xtensa.c | |
parent | ae49d6e592571b46ae39832868e53958e94e26b4 (diff) | |
download | gcc-f42f5a1b1ec954dd53ea998ff4188c1de8001b0d.zip gcc-f42f5a1b1ec954dd53ea998ff4188c1de8001b0d.tar.gz gcc-f42f5a1b1ec954dd53ea998ff4188c1de8001b0d.tar.bz2 |
lib2funcs.S (TRAMPOLINE_SIZE): Change from 49 to 59.
* config/xtensa/lib2funcs.S (TRAMPOLINE_SIZE): Change from 49 to 59.
* config/xtensa/xtensa-config.h (XCHAL_HAVE_CONST16,
XCHAL_HAVE_L32R): New.
* config/xtensa/xtensa-protos.h (non_const_move_operand,
xtensa_load_constant, xtensa_function_prologue,
xtensa_function_epilogue): Delete prototypes.
(xtensa_expand_prologue): New.
* config/xtensa/xtensa.c (frame_size_const,
TARGET_ASM_FUNCTION_PROLOGUE, TARGET_MACHINE_DEPENDENT_REORG,
non_const_move_operand, xtensa_load_constant, xtensa_reorg,
xtensa_function_prologue): Delete.
(add_operand, xtensa_mem_offset): Formatting.
(move_operand): If the const16 option is available, allow any SFmode
and SImode constants.
(xtensa_emit_move_sequence): Inline the former contents of
xtensa_load_constant with modifications to handle the const16 option.
(override_options): Add xtensa_char_to_class['W'] and set it to
the general register class only if the const16 option is enabled.
Fix formatting. Disallow PIC when using the const16 option.
(print_operand): Reorganize to switch on "letter" instead of the
RTL code. Add output_operand_lossage calls for invalid cases.
Add support for 't' and 'b' letters.
(xtensa_expand_prologue): New function to replace
xtensa_function_prologue and xtensa_reorg.
(xtensa_function_epilogue): Declare this as static. Delete code
to print the retw.n or retw instruction.
(xtensa_return_addr): Use A0_REG instead of 0.
(xtensa_rtx_costs): Add costs for using the const16 option.
* config/xtensa/xtensa.h (MASK_CONST16, TARGET_CONST16): New.
(TARGET_DEFAULT): Add CONST16 if L32R instructions not available.
(TARGET_SWITCHES): Add "const16" and "no-const16".
(REG_CLASS_FROM_LETTER): Add comment about new 'W' letter.
(EXTRA_CONSTRAINT): Change 'T' constraint to only apply when not
using the const16 option.
(TRAMPOLINE_TEMPLATE): Rewrite to avoid hardwired use of l32r insn.
(TRAMPOLINE_SIZE): Change from 49 to 59.
(INITIALIZE_TRAMPOLINE): Adjust offsets to match new trampoline.
(GO_IF_LEGITIMATE_ADDRESS): Do not allow constant pool addresses
when using the const16 option.
(PREDICATE_CODES): Delete non_const_move_operand.
* config/xtensa/xtensa.md (define_constants): Add A1_REG, A8_REG, and
UNSPECV_ENTRY.
(movdi, movdf): If the source is a constant, always expand to a
sequence of movsi insns.
(movdi_internal, movdf_internal): Remove alternative using l32r insns.
(movsi_internal, movsf_internal): Add alternative using const16 insns.
(movsf): Add const16 support.
(entry, prologue, epilogue): New.
(set_frame_ptr): Add missing mode for unspec_volatile operation.
Likewise for subsequent split pattern.
* doc/invoke.texi (Option Summary, Xtensa Options): Document new
"-mconst16" and "-mno-const16" options.
From-SVN: r66809
Diffstat (limited to 'gcc/config/xtensa/xtensa.c')
-rw-r--r-- | gcc/config/xtensa/xtensa.c | 484 |
1 files changed, 240 insertions, 244 deletions
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index cc5db91..25bf647 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -198,29 +198,18 @@ static rtx gen_conditional_move PARAMS ((rtx)); static rtx fixup_subreg_mem PARAMS ((rtx x)); static enum machine_mode xtensa_find_mode_for_size PARAMS ((unsigned)); static struct machine_function * xtensa_init_machine_status PARAMS ((void)); -static void xtensa_reorg PARAMS ((void)); static void printx PARAMS ((FILE *, signed int)); +static void xtensa_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT)); static unsigned int xtensa_multibss_section_type_flags PARAMS ((tree, const char *, int)); static void xtensa_select_rtx_section PARAMS ((enum machine_mode, rtx, unsigned HOST_WIDE_INT)); static bool xtensa_rtx_costs PARAMS ((rtx, int, int, int *)); -static rtx frame_size_const; static int current_function_arg_words; static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER; -/* This macro generates the assembly code for function entry. - FILE is a stdio stream to output the code to. - SIZE is an int: how many units of temporary storage to allocate. - Refer to the array 'regs_ever_live' to determine which registers - to save; 'regs_ever_live[I]' is nonzero if register number I - is ever used in the function. This macro is responsible for - knowing which registers should not be saved even if used. */ - -#undef TARGET_ASM_FUNCTION_PROLOGUE -#define TARGET_ASM_FUNCTION_PROLOGUE xtensa_function_prologue /* This macro generates the assembly code for function exit, on machines that need it. If FUNCTION_EPILOGUE is not defined @@ -244,9 +233,6 @@ static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] = #undef TARGET_ADDRESS_COST #define TARGET_ADDRESS_COST hook_int_rtx_0 -#undef TARGET_MACHINE_DEPENDENT_REORG -#define TARGET_MACHINE_DEPENDENT_REORG xtensa_reorg - struct gcc_target targetm = TARGET_INITIALIZER; @@ -412,8 +398,7 @@ add_operand (op, mode) enum machine_mode mode; { if (GET_CODE (op) == CONST_INT) - return (xtensa_simm8 (INTVAL (op)) || - xtensa_simm8x256 (INTVAL (op))); + return (xtensa_simm8 (INTVAL (op)) || xtensa_simm8x256 (INTVAL (op))); return register_operand (op, mode); } @@ -610,19 +595,23 @@ move_operand (op, mode) rtx op; enum machine_mode mode; { - if (register_operand (op, mode)) + if (register_operand (op, mode) + || memory_operand (op, mode)) return TRUE; + if (mode == SFmode) + return TARGET_CONST16 && CONSTANT_P (op); + /* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and result in 0/1. */ if (GET_CODE (op) == CONSTANT_P_RTX) return TRUE; - if (GET_CODE (op) == CONST_INT) - return xtensa_simm12b (INTVAL (op)); + if (GET_CODE (op) == CONST_INT && xtensa_simm12b (INTVAL (op))) + return TRUE; - if (GET_CODE (op) == MEM) - return memory_address_p (mode, XEXP (op, 0)); + if (mode == SImode) + return TARGET_CONST16 && CONSTANT_P (op); return FALSE; } @@ -702,21 +691,6 @@ constantpool_mem_p (op) } -int -non_const_move_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - if (register_operand (op, mode)) - return 1; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - if (GET_CODE (op) == MEM) - return memory_address_p (mode, XEXP (op, 0)); - return FALSE; -} - - /* Accept the floating point constant 1 in the appropriate mode. */ int @@ -778,32 +752,6 @@ xtensa_extend_reg (dst, src) } -void -xtensa_load_constant (dst, src) - rtx dst; - rtx src; -{ - enum machine_mode mode = GET_MODE (dst); - src = force_const_mem (SImode, src); - - /* PC-relative loads are always SImode so we have to add a SUBREG if that - is not the desired mode */ - - if (mode != SImode) - { - if (register_operand (dst, mode)) - dst = simplify_gen_subreg (SImode, dst, mode, 0); - else - { - src = force_reg (SImode, src); - src = gen_lowpart_SUBREG (mode, src); - } - } - - emit_move_insn (dst, src); -} - - int branch_operator (x, mode) rtx x; @@ -899,8 +847,8 @@ xtensa_mem_offset (v, mode) moved in < "move_ratio" pieces. The worst case is when the block is aligned but has a size of (3 mod 4) (does this happen?) so that the last piece requires a byte load/store. */ - return (xtensa_uimm8 (v) && - xtensa_uimm8 (v + MOVE_MAX * LARGEST_MOVE_RATIO)); + return (xtensa_uimm8 (v) + && xtensa_uimm8 (v + MOVE_MAX * LARGEST_MOVE_RATIO)); case QImode: return xtensa_uimm8 (v); @@ -1260,7 +1208,6 @@ xtensa_expand_scc (operands) /* Emit insns to move operands[1] into operands[0]. - Return 1 if we have written out everything that needs to be done to do the move. Otherwise, return 0 and the caller will emit the move normally. */ @@ -1275,8 +1222,27 @@ xtensa_emit_move_sequence (operands, mode) && (GET_CODE (operands[1]) != CONST_INT || !xtensa_simm12b (INTVAL (operands[1])))) { - xtensa_load_constant (operands[0], operands[1]); - return 1; + if (!TARGET_CONST16) + operands[1] = force_const_mem (SImode, operands[1]); + + /* PC-relative loads are always SImode, and CONST16 is only + supported in the movsi pattern, so add a SUBREG for any other + (smaller) mode. */ + + if (mode != SImode) + { + if (register_operand (operands[0], mode)) + { + operands[0] = simplify_gen_subreg (SImode, operands[0], mode, 0); + emit_move_insn (operands[0], operands[1]); + return 1; + } + else + { + operands[1] = force_reg (SImode, operands[1]); + operands[1] = gen_lowpart_SUBREG (mode, operands[1]); + } + } } if (!(reload_in_progress | reload_completed)) @@ -1299,6 +1265,7 @@ xtensa_emit_move_sequence (operands, mode) return 0; } + static rtx fixup_subreg_mem (x) rtx x; @@ -1848,6 +1815,7 @@ override_options () xtensa_char_to_class['C'] = ((TARGET_MUL16) ? GR_REGS: NO_REGS); xtensa_char_to_class['D'] = ((TARGET_DENSITY) ? GR_REGS: NO_REGS); xtensa_char_to_class['d'] = ((TARGET_DENSITY) ? AR_REGS: NO_REGS); + xtensa_char_to_class['W'] = ((TARGET_CONST16) ? GR_REGS: NO_REGS); /* Set up array giving whether a given register can hold a given mode. */ for (mode = VOIDmode; @@ -1862,8 +1830,8 @@ override_options () int temp; if (ACC_REG_P (regno)) - temp = (TARGET_MAC16 && - (class == MODE_INT) && (size <= UNITS_PER_WORD)); + temp = (TARGET_MAC16 + && (class == MODE_INT) && (size <= UNITS_PER_WORD)); else if (GP_REG_P (regno)) temp = ((regno & 1) == 0 || (size <= UNITS_PER_WORD)); else if (FP_REG_P (regno)) @@ -1879,9 +1847,19 @@ override_options () init_machine_status = xtensa_init_machine_status; - /* Check PIC settings. There's no need for -fPIC on Xtensa and - some targets need to always use PIC. */ - if (flag_pic > 1 || (XTENSA_ALWAYS_PIC)) + /* Check PIC settings. PIC is only supported when using L32R + instructions, and some targets need to always use PIC. */ + if (flag_pic && TARGET_CONST16) + error ("-f%s is not supported with CONST16 instructions", + (flag_pic > 1 ? "PIC" : "pic")); + else if (XTENSA_ALWAYS_PIC) + { + if (TARGET_CONST16) + error ("PIC is required but not supported with CONST16 instructions"); + flag_pic = 1; + } + /* There's no need for -fPIC (as opposed to -fpic) on Xtensa. */ + if (flag_pic > 1) flag_pic = 1; } @@ -1918,6 +1896,8 @@ override_options () 'D' REG, print second register of double-word register operand 'N' MEM, print address of next word following a memory operand 'v' MEM, if memory reference is volatile, output a MEMW before it + 't' any constant, add "@h" suffix for top 16 bits + 'b' any constant, add "@l" suffix for bottom 16 bits */ static void @@ -1936,94 +1916,146 @@ printx (file, val) void -print_operand (file, op, letter) +print_operand (file, x, letter) FILE *file; /* file to write to */ - rtx op; /* operand to print */ + rtx x; /* operand to print */ int letter; /* %<letter> or 0 */ { - enum rtx_code code; - - if (! op) + if (!x) error ("PRINT_OPERAND null pointer"); - code = GET_CODE (op); - switch (code) + switch (letter) { - case REG: - case SUBREG: - { - int regnum = xt_true_regnum (op); - if (letter == 'D') - regnum++; - fprintf (file, "%s", reg_names[regnum]); - break; - } + case 'D': + if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG) + fprintf (file, "%s", reg_names[xt_true_regnum (x) + 1]); + else + output_operand_lossage ("invalid %%D value"); + break; - case MEM: - /* For a volatile memory reference, emit a MEMW before the - load or store. */ - if (letter == 'v') - { - if (MEM_VOLATILE_P (op) && TARGET_SERIALIZE_VOLATILE) - fprintf (file, "memw\n\t"); - break; - } - else if (letter == 'N') - { - enum machine_mode mode; - switch (GET_MODE (op)) - { - case DFmode: mode = SFmode; break; - case DImode: mode = SImode; break; - default: abort (); - } - op = adjust_address (op, mode, 4); - } + case 'v': + if (GET_CODE (x) == MEM) + { + /* For a volatile memory reference, emit a MEMW before the + load or store. */ + if (MEM_VOLATILE_P (x) && TARGET_SERIALIZE_VOLATILE) + fprintf (file, "memw\n\t"); + } + else + output_operand_lossage ("invalid %%v value"); + break; - output_address (XEXP (op, 0)); - break; + case 'N': + if (GET_CODE (x) == MEM + && (GET_MODE (x) == DFmode || GET_MODE (x) == DImode)) + { + x = adjust_address (x, GET_MODE (x) == DFmode ? SFmode : SImode, 4); + output_address (XEXP (x, 0)); + } + else + output_operand_lossage ("invalid %%N value"); + break; - case CONST_INT: - switch (letter) + case 'K': + if (GET_CODE (x) == CONST_INT) { - case 'K': - { - int num_bits = 0; - unsigned val = INTVAL (op); - while (val & 1) - { - num_bits += 1; - val = val >> 1; - } - if ((val != 0) || (num_bits == 0) || (num_bits > 16)) - fatal_insn ("invalid mask", op); + int num_bits = 0; + unsigned val = INTVAL (x); + while (val & 1) + { + num_bits += 1; + val = val >> 1; + } + if ((val != 0) || (num_bits == 0) || (num_bits > 16)) + fatal_insn ("invalid mask", x); - fprintf (file, "%d", num_bits); - break; - } + fprintf (file, "%d", num_bits); + } + else + output_operand_lossage ("invalid %%K value"); + break; - case 'L': - fprintf (file, "%ld", (32 - INTVAL (op)) & 0x1f); - break; + case 'L': + if (GET_CODE (x) == CONST_INT) + fprintf (file, "%ld", (32 - INTVAL (x)) & 0x1f); + else + output_operand_lossage ("invalid %%L value"); + break; - case 'R': - fprintf (file, "%ld", INTVAL (op) & 0x1f); - break; + case 'R': + if (GET_CODE (x) == CONST_INT) + fprintf (file, "%ld", INTVAL (x) & 0x1f); + else + output_operand_lossage ("invalid %%R value"); + break; - case 'x': - printx (file, INTVAL (op)); - break; + case 'x': + if (GET_CODE (x) == CONST_INT) + printx (file, INTVAL (x)); + else + output_operand_lossage ("invalid %%x value"); + break; - case 'd': - default: - fprintf (file, "%ld", INTVAL (op)); - break; + case 'd': + if (GET_CODE (x) == CONST_INT) + fprintf (file, "%ld", INTVAL (x)); + else + output_operand_lossage ("invalid %%d value"); + break; + case 't': + case 'b': + if (GET_CODE (x) == CONST_INT) + { + printx (file, INTVAL (x)); + fputs (letter == 't' ? "@h" : "@l", file); + } + else if (GET_CODE (x) == CONST_DOUBLE) + { + REAL_VALUE_TYPE r; + REAL_VALUE_FROM_CONST_DOUBLE (r, x); + if (GET_MODE (x) == SFmode) + { + long l; + REAL_VALUE_TO_TARGET_SINGLE (r, l); + fprintf (file, "0x%08lx@%c", l, letter == 't' ? 'h' : 'l'); + } + else + output_operand_lossage ("invalid %%t/%%b value"); + } + else if (GET_CODE (x) == CONST) + { + /* X must be a symbolic constant on ELF. Write an expression + suitable for 'const16' that sets the high or low 16 bits. */ + if (GET_CODE (XEXP (x, 0)) != PLUS + || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF + && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF) + || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT) + output_operand_lossage ("invalid %%t/%%b value"); + print_operand (file, XEXP (XEXP (x, 0), 0), 0); + fputs (letter == 't' ? "@h" : "@l", file); + /* There must be a non-alphanumeric character between 'h' or 'l' + and the number. The '-' is added by print_operand() already. */ + if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0) + fputs ("+", file); + print_operand (file, XEXP (XEXP (x, 0), 1), 0); + } + else + { + output_addr_const (file, x); + fputs (letter == 't' ? "@h" : "@l", file); } break; default: - output_addr_const (file, op); + if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG) + fprintf (file, "%s", reg_names[xt_true_regnum (x)]); + else if (GET_CODE (x) == MEM) + output_address (XEXP (x, 0)); + else if (GET_CODE (x) == CONST_INT) + fprintf (file, "%ld", INTVAL (x)); + else + output_addr_const (file, x); } } @@ -2191,129 +2223,85 @@ xtensa_frame_pointer_required () } -/* If the stack frame size is too big to fit in the immediate field of - the ENTRY instruction, we need to store the frame size in the - constant pool. However, the code in xtensa_function_prologue runs too - late to be able to add anything to the constant pool. Since the - final frame size isn't known until reload is complete, this seems - like the best place to do it. +void +xtensa_expand_prologue () +{ + HOST_WIDE_INT total_size; + rtx size_rtx; - There may also be some fixup required if there is an incoming argument - in a7 and the function requires a frame pointer. */ + total_size = compute_frame_size (get_frame_size ()); + size_rtx = GEN_INT (total_size); -static void -xtensa_reorg () -{ - rtx first, insn, set_frame_ptr_insn = 0; - - unsigned long tsize = compute_frame_size (get_frame_size ()); - first = get_insns (); - if (tsize < (1 << (12+3))) - frame_size_const = 0; + if (total_size < (1 << (12+3))) + emit_insn (gen_entry (size_rtx, size_rtx)); else { - frame_size_const = force_const_mem (SImode, GEN_INT (tsize - 16));; - - /* make sure the constant is used so it doesn't get eliminated - from the constant pool */ - emit_insn_before (gen_rtx_USE (SImode, frame_size_const), first); + /* Use a8 as a temporary since a0-a7 may be live. */ + rtx tmp_reg = gen_rtx_REG (Pmode, A8_REG); + emit_insn (gen_entry (size_rtx, GEN_INT (MIN_FRAME_SIZE))); + emit_move_insn (tmp_reg, GEN_INT (total_size - MIN_FRAME_SIZE)); + emit_insn (gen_subsi3 (tmp_reg, stack_pointer_rtx, tmp_reg)); + emit_move_insn (stack_pointer_rtx, tmp_reg); } - if (!frame_pointer_needed) - return; - - /* Search all instructions, looking for the insn that sets up the - frame pointer. This search will fail if the function does not - have an incoming argument in $a7, but in that case, we can just - set up the frame pointer at the very beginning of the - function. */ - - for (insn = first; insn; insn = NEXT_INSN (insn)) + if (frame_pointer_needed) { - rtx pat; + rtx first, insn, set_frame_ptr_insn = 0; - if (!INSN_P (insn)) - continue; + push_topmost_sequence (); + first = get_insns (); + pop_topmost_sequence (); - pat = PATTERN (insn); - if (GET_CODE (pat) == SET - && GET_CODE (SET_SRC (pat)) == UNSPEC_VOLATILE - && (XINT (SET_SRC (pat), 1) == UNSPECV_SET_FP)) - { - set_frame_ptr_insn = insn; - break; - } - } + /* Search all instructions, looking for the insn that sets up the + frame pointer. This search will fail if the function does not + have an incoming argument in $a7, but in that case, we can just + set up the frame pointer at the very beginning of the + function. */ - if (set_frame_ptr_insn) - { - /* for all instructions prior to set_frame_ptr_insn, replace - hard_frame_pointer references with stack_pointer */ - for (insn = first; insn != set_frame_ptr_insn; insn = NEXT_INSN (insn)) + for (insn = first; insn; insn = NEXT_INSN (insn)) { - if (INSN_P (insn)) - PATTERN (insn) = replace_rtx (copy_rtx (PATTERN (insn)), - hard_frame_pointer_rtx, - stack_pointer_rtx); - } - } - else - { - /* emit the frame pointer move immediately after the NOTE that starts - the function */ - emit_insn_after (gen_movsi (hard_frame_pointer_rtx, - stack_pointer_rtx), first); - } -} - + rtx pat; -/* Set up the stack and frame (if desired) for the function. */ + if (!INSN_P (insn)) + continue; -void -xtensa_function_prologue (file, size) - FILE *file; - HOST_WIDE_INT size ATTRIBUTE_UNUSED; -{ - unsigned long tsize = compute_frame_size (get_frame_size ()); - - if (frame_pointer_needed) - fprintf (file, "\t.frame\ta7, %ld\n", tsize); - else - fprintf (file, "\t.frame\tsp, %ld\n", tsize); - - - if (tsize < (1 << (12+3))) - { - fprintf (file, "\tentry\tsp, %ld\n", tsize); - } - else - { - fprintf (file, "\tentry\tsp, 16\n"); + pat = PATTERN (insn); + if (GET_CODE (pat) == SET + && GET_CODE (SET_SRC (pat)) == UNSPEC_VOLATILE + && (XINT (SET_SRC (pat), 1) == UNSPECV_SET_FP)) + { + set_frame_ptr_insn = insn; + break; + } + } - /* use a8 as a temporary since a0-a7 may be live */ - fprintf (file, "\tl32r\ta8, "); - print_operand (file, frame_size_const, 0); - fprintf (file, "\n\tsub\ta8, sp, a8\n"); - fprintf (file, "\tmovsp\tsp, a8\n"); + if (set_frame_ptr_insn) + { + /* For all instructions prior to set_frame_ptr_insn, replace + hard_frame_pointer references with stack_pointer. */ + for (insn = first; + insn != set_frame_ptr_insn; + insn = NEXT_INSN (insn)) + { + if (INSN_P (insn)) + PATTERN (insn) = replace_rtx (copy_rtx (PATTERN (insn)), + hard_frame_pointer_rtx, + stack_pointer_rtx); + } + } + else + emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx); } } -/* Do any necessary cleanup after a function to restore - stack, frame, and regs. */ +/* Clear variables at function end. */ void xtensa_function_epilogue (file, size) - FILE *file; + FILE *file ATTRIBUTE_UNUSED; HOST_WIDE_INT size ATTRIBUTE_UNUSED; { - rtx insn = get_last_insn (); - /* If the last insn was a BARRIER, we don't have to write anything. */ - if (GET_CODE (insn) == NOTE) - insn = prev_nonnote_insn (insn); - if (insn == 0 || GET_CODE (insn) != BARRIER) - fprintf (file, TARGET_DENSITY ? "\tretw.n\n" : "\tretw\n"); - xtensa_current_frame_size = 0; } @@ -2326,7 +2314,7 @@ xtensa_return_addr (count, frame) rtx result, retaddr; if (count == -1) - retaddr = gen_rtx_REG (Pmode, 0); + retaddr = gen_rtx_REG (Pmode, A0_REG); else { rtx addr = plus_constant (frame, -4 * UNITS_PER_WORD); @@ -2882,6 +2870,8 @@ xtensa_rtx_costs (x, code, outer_code, total) } if (xtensa_simm12b (INTVAL (x))) *total = 5; + else if (TARGET_CONST16) + *total = COSTS_N_INSNS (2); else *total = 6; return true; @@ -2889,11 +2879,17 @@ xtensa_rtx_costs (x, code, outer_code, total) case CONST: case LABEL_REF: case SYMBOL_REF: - *total = 5; + if (TARGET_CONST16) + *total = COSTS_N_INSNS (2); + else + *total = 5; return true; case CONST_DOUBLE: - *total = 7; + if (TARGET_CONST16) + *total = COSTS_N_INSNS (4); + else + *total = 7; return true; case MEM: |