diff options
author | Nick Clifton <nickc@gcc.gnu.org> | 2013-01-31 18:36:02 +0000 |
---|---|---|
committer | Nick Clifton <nickc@gcc.gnu.org> | 2013-01-31 18:36:02 +0000 |
commit | dbdbd982df2d044f3b43b2f41ef1ada5667160f9 (patch) | |
tree | 74fc8090f85709b8d53297f1a682f42daa03d155 /gcc/config/v850/v850.c | |
parent | 73861a4142c04fdeb77b72f8c534e2e967a69bae (diff) | |
download | gcc-dbdbd982df2d044f3b43b2f41ef1ada5667160f9.zip gcc-dbdbd982df2d044f3b43b2f41ef1ada5667160f9.tar.gz gcc-dbdbd982df2d044f3b43b2f41ef1ada5667160f9.tar.bz2 |
lib1funcs.S: Add support for e3v5 architecture variant.
* config/v850/lib1funcs.S: Add support for e3v5 architecture
variant.
* config/v850/constraints.md (Q): Define as a memory constraint.
* config/v850/predicates.md (label_ref_operand): New predicate.
(e3v5_shift_operand): New predicate.
(ior_operator): New predicate.
* config/v850/t-v850: Add e3v5 multilib.
* config/v850/v850-protos.h (v850_adjust_insn_length): Prototype.
(v850_gen_movdi): Prototype.
* config/v850/v850.c: Add support for e3v5 architecture.
Rename all uses of TARGET_V850E || TARGET_V850E2_ALL to
TARGET_V850E_UP.
(construct_save_jarl): Add e3v5 long JARL support.
(v850_adjust_insn_length): New function. Adjust length of call
insns when using e3v5 instructions.
(v850_gen_movdi): New function: Generate instructions to move a
DImode value.
* config/v850/v850.h (TARGET_CPU_v850e3v5): Define.
(CPP_SPEC): Define __v850e3v5__ as appropriate.
(TARGET_USE_FPU): Enable for e3v5.
(CONST_OK_FOR_W): New macro.
(ADJUST_INSN_LENGTH): Define.
* config/v850/v850.md (UNSPEC_LOOP): Define.
(attr cpu): Add v850e3v5.
Rename all uses of TARGET_V850E2 to TARGET_V850E2V3_UP.
(movdi): New pattern.
(movdi_internal): New pattern.
(cbranchsf4): Conditionalize on TARGET_USE_FPU.
(cbranchdf4): Conditionalize on TARGET_USE_FPU.
(cstoresf4): Likewise.
(cstoredf4): Likewise.
(insv): New pattern.
(rotlso3_a): New pattern.
(rotlsi3_b): New pattern
(rotlsi3_v850e3v5): New pattern.
(doloop_begin): New pattern.
(fix_loop_counter): New pattern.
(doloop_end): New pattern.
(branch_normal): Add e3v5 long branch support.
(branch_invert): Likewise.
(branch_z_normal): Likewise.
(branch_z_invert): Likewise.
(branch_nz_normal): Likewise.
(branch_nz_invert): Likewise.
(call_internal_short): Add e3v5 register-indirect JARL support.
(call_internal_long): Likewise.
(call_value_internal_short): Likewise.
(call_value_internal_long): Likewise.
* config/v850/v850.opt (mv850e3v5, mv850e2v4): New options.
(mloop): New option.
* config.gcc: Add support for configuring v840e3v5 target.
* doc/invoke.texi: Document new v850 specific command line
options.
From-SVN: r195623
Diffstat (limited to 'gcc/config/v850/v850.c')
-rw-r--r-- | gcc/config/v850/v850.c | 86 |
1 files changed, 74 insertions, 12 deletions
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c index 12c7928..67cc2c2 100644 --- a/gcc/config/v850/v850.c +++ b/gcc/config/v850/v850.c @@ -824,7 +824,7 @@ output_move_single (rtx * operands) return "movhi hi0(%1),%.,%0"; /* A random constant. */ - else if (TARGET_V850E || TARGET_V850E2_ALL) + else if (TARGET_V850E_UP) return "mov %1,%0"; else return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0"; @@ -846,7 +846,7 @@ output_move_single (rtx * operands) return "movhi hi0(%F1),%.,%0"; /* A random constant. */ - else if (TARGET_V850E || TARGET_V850E2_ALL) + else if (TARGET_V850E_UP) return "mov %F1,%0"; else @@ -863,7 +863,7 @@ output_move_single (rtx * operands) || GET_CODE (src) == SYMBOL_REF || GET_CODE (src) == CONST) { - if (TARGET_V850E || TARGET_V850E2_ALL) + if (TARGET_V850E_UP) return "mov hilo(%1),%0"; else return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0"; @@ -1018,7 +1018,7 @@ ep_memory_offset (enum machine_mode mode, int unsignedp ATTRIBUTE_UNUSED) case QImode: if (TARGET_SMALL_SLD) max_offset = (1 << 4); - else if ((TARGET_V850E || TARGET_V850E2_ALL) + else if ((TARGET_V850E_UP) && unsignedp) max_offset = (1 << 4); else @@ -1028,7 +1028,7 @@ ep_memory_offset (enum machine_mode mode, int unsignedp ATTRIBUTE_UNUSED) case HImode: if (TARGET_SMALL_SLD) max_offset = (1 << 5); - else if ((TARGET_V850E || TARGET_V850E2_ALL) + else if ((TARGET_V850E_UP) && unsignedp) max_offset = (1 << 5); else @@ -1656,7 +1656,7 @@ expand_prologue (void) /* Save/setup global registers for interrupt functions right now. */ if (interrupt_handler) { - if (! TARGET_DISABLE_CALLT && (TARGET_V850E || TARGET_V850E2_ALL)) + if (! TARGET_DISABLE_CALLT && (TARGET_V850E_UP)) emit_insn (gen_callt_save_interrupt ()); else emit_insn (gen_save_interrupt ()); @@ -1759,7 +1759,7 @@ expand_prologue (void) /* Special case interrupt functions that save all registers for a call. */ if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0) { - if (! TARGET_DISABLE_CALLT && (TARGET_V850E || TARGET_V850E2_ALL)) + if (! TARGET_DISABLE_CALLT && (TARGET_V850E_UP)) emit_insn (gen_callt_save_all_interrupt ()); else emit_insn (gen_save_all_interrupt ()); @@ -1967,7 +1967,7 @@ expand_epilogue (void) /* And return or use reti for interrupt handlers. */ if (interrupt_handler) { - if (! TARGET_DISABLE_CALLT && (TARGET_V850E || TARGET_V850E2_ALL)) + if (! TARGET_DISABLE_CALLT && (TARGET_V850E_UP)) emit_insn (gen_callt_return_interrupt ()); else emit_jump_insn (gen_return_interrupt ()); @@ -2437,8 +2437,11 @@ construct_save_jarl (rtx op) else sprintf (name, "__save_%s_%s", reg_names [first], reg_names [last]); - sprintf (buff, "movhi hi(%s), r0, r11\n\tmovea lo(%s), r11, r11\n\tjarl .+4, r10\n\tadd 4, r10\n\tjmp r11", - name, name); + if (TARGET_V850E3V5_UP) + sprintf (buff, "mov hilo(%s), r11\n\tjarl [r11], r10", name); + else + sprintf (buff, "movhi hi(%s), r0, r11\n\tmovea lo(%s), r11, r11\n\tjarl .+4, r10\n\tadd 4, r10\n\tjmp r11", + name, name); } else { @@ -3048,7 +3051,7 @@ v850_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) static int v850_issue_rate (void) { - return (TARGET_V850E2_ALL? 2 : 1); + return (TARGET_V850E2_UP ? 2 : 1); } /* Implement TARGET_LEGITIMATE_CONSTANT_P. */ @@ -3082,6 +3085,32 @@ v850_memory_move_cost (enum machine_mode mode, return (GET_MODE_SIZE (mode) / 2) * (in ? 3 : 1); } } + +int +v850_adjust_insn_length (rtx insn, int length) +{ + if (TARGET_V850E3V5_UP) + { + if (CALL_P (insn)) + { + if (TARGET_LONG_CALLS) + { + /* call_internal_long, call_value_internal_long. */ + if (length == 8) + length = 4; + if (length == 16) + length = 10; + } + else + { + /* call_internal_short, call_value_internal_short. */ + if (length == 8) + length = 4; + } + } + } + return length; +} /* V850 specific attributes. */ @@ -3102,7 +3131,6 @@ static const struct attribute_spec v850_attribute_table[] = { NULL, 0, 0, false, false, false, NULL, false } }; - static void v850_option_override (void) { @@ -3114,6 +3142,40 @@ v850_option_override (void) target_flags |= MASK_DISABLE_CALLT; } +const char * +v850_gen_movdi (rtx * operands) +{ + if (REG_P (operands[0])) + { + if (REG_P (operands[1])) + { + if (REGNO (operands[0]) == (REGNO (operands[1]) - 1)) + return "mov %1, %0; mov %R1, %R0"; + + return "mov %R1, %R0; mov %1, %0"; + } + + if (MEM_P (operands[1])) + { + if (REGNO (operands[0]) & 1) + /* Use two load word instructions to synthesise a load double. */ + return "ld.w %1, %0 ; ld.w %R1, %R0" ; + + return "ld.dw %1, %0"; + } + + return "mov %1, %0; mov %R1, %R0"; + } + + gcc_assert (REG_P (operands[1])); + + if (REGNO (operands[1]) & 1) + /* Use two store word instructions to synthesise a store double. */ + return "st.w %1, %0 ; st.w %R1, %R0 "; + + return "st.dw %1, %0"; +} + /* Initialize the GCC target structure. */ #undef TARGET_OPTION_OVERRIDE |