From dbdbd982df2d044f3b43b2f41ef1ada5667160f9 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 31 Jan 2013 18:36:02 +0000 Subject: 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 --- gcc/ChangeLog | 55 +++++ gcc/config.gcc | 7 +- gcc/config/v850/constraints.md | 2 +- gcc/config/v850/predicates.md | 20 ++ gcc/config/v850/t-v850 | 3 + gcc/config/v850/v850-protos.h | 2 + gcc/config/v850/v850.c | 86 ++++++-- gcc/config/v850/v850.h | 38 +++- gcc/config/v850/v850.md | 445 +++++++++++++++++++++++++++++++---------- gcc/config/v850/v850.opt | 11 + gcc/doc/invoke.texi | 170 +++++++++++++--- 11 files changed, 689 insertions(+), 150 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b3c1c52..341e9aa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,58 @@ +2013-01-31 Hiroyuki Ono + Nick Clifton + + * 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. + 2013-01-31 Paul Koning PR debug/55059 diff --git a/gcc/config.gcc b/gcc/config.gcc index ca76fc8..b6a6ad0 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -2554,6 +2554,9 @@ v850-*-rtems*) ;; v850*-*-*) case ${target} in + v850e3v5-*-*) + target_cpu_default="TARGET_CPU_v850e3v5" + ;; v850e2v3-*-*) target_cpu_default="TARGET_CPU_v850e2v3" ;; @@ -3614,7 +3617,7 @@ case "${target}" in v850*-*-*) supported_defaults=cpu case ${with_cpu} in - "" | v850e | v850e1 | v850e2 | v850es | v850e2v3) + "" | v850e | v850e1 | v850e2 | v850es | v850e2v3 | v850e3v5) # OK ;; *) @@ -3741,7 +3744,7 @@ case ${target} in case "x$with_cpu" in x) ;; - xv850e | xv850e1 | xv850e2 | xv850e2v3) + xv850e | xv850e1 | xv850e2 | xv850e2v3 | xv850e3v5) target_cpu_default2="TARGET_CPU_$with_cpu" ;; xv850es) diff --git a/gcc/config/v850/constraints.md b/gcc/config/v850/constraints.md index a10122d..11a97c9 100644 --- a/gcc/config/v850/constraints.md +++ b/gcc/config/v850/constraints.md @@ -76,7 +76,7 @@ (match_test "0"))) ;;; Extra constraints. -(define_constraint "Q" +(define_memory_constraint "Q" "A memory address that does not contain a symbol address." (and (match_code "mem") (match_test "ep_memory_operand (op, mode, FALSE)"))) diff --git a/gcc/config/v850/predicates.md b/gcc/config/v850/predicates.md index 37851c4..10674a9 100644 --- a/gcc/config/v850/predicates.md +++ b/gcc/config/v850/predicates.md @@ -498,6 +498,26 @@ return op == CONST0_RTX(mode); }) +(define_predicate "label_ref_operand" + (match_code "label_ref") +) + + +(define_predicate "e3v5_shift_operand" + (match_code "const_int,reg") + { + if (CONST_INT_P (op)) + return IN_RANGE (INTVAL (op), 0, 31); + return true; + } +) + +(define_predicate "ior_operator" + (match_code "ior") +{ + return (GET_CODE (op) == IOR); +}) + ;; Return true if the floating point comparison operation ;; given produces a canonical answer. (define_predicate "v850_float_z_comparison_operator" diff --git a/gcc/config/v850/t-v850 b/gcc/config/v850/t-v850 index f876316..b91b505 100644 --- a/gcc/config/v850/t-v850 +++ b/gcc/config/v850/t-v850 @@ -20,6 +20,9 @@ MULTILIB_OPTIONS = m8byte-align mgcc-abi msoft-float MULTILIB_DIRNAMES = 8byte gcc-abi soft-float +MULTILIB_OPTIONS += mv850e3v5 +MULTILIB_DIRNAMES += v850e3v5 + TCFLAGS = -mno-app-regs -msmall-sld -Wa,-mwarn-signed-overflow -Wa,-mwarn-unsigned-overflow v850-c.o: $(srcdir)/config/v850/v850-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ diff --git a/gcc/config/v850/v850-protos.h b/gcc/config/v850/v850-protos.h index 151f5b5..be253dd 100644 --- a/gcc/config/v850/v850-protos.h +++ b/gcc/config/v850/v850-protos.h @@ -39,6 +39,8 @@ extern char * construct_restore_jr (rtx); extern char * construct_dispose_instruction (rtx); extern char * construct_prepare_instruction (rtx); extern int ep_memory_operand (rtx, enum machine_mode, int); +extern int v850_adjust_insn_length (rtx, int); +extern const char * v850_gen_movdi (rtx *); extern rtx v850_gen_compare (enum rtx_code, enum machine_mode, rtx, rtx); extern enum machine_mode v850_gen_float_compare (enum rtx_code, 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 diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h index 573b149..e08c622 100644 --- a/gcc/config/v850/v850.h +++ b/gcc/config/v850/v850.h @@ -37,7 +37,7 @@ extern GTY(()) rtx v850_compare_op1; #define TARGET_CPU_v850e1 3 #define TARGET_CPU_v850e2 4 #define TARGET_CPU_v850e2v3 5 - +#define TARGET_CPU_v850e3v5 6 #ifndef TARGET_CPU_DEFAULT #define TARGET_CPU_DEFAULT TARGET_CPU_generic @@ -86,7 +86,22 @@ extern GTY(()) rtx v850_compare_op1; #define SUBTARGET_CPP_SPEC "%{!mv*:-D__v850e2v3__} %{mv850e2v3:-D__v850e2v3__}" #endif -#define TARGET_V850E2_ALL (TARGET_V850E2 || TARGET_V850E2V3) +#if TARGET_CPU_DEFAULT == TARGET_CPU_v850e3v5 +#undef MASK_DEFAULT +#define MASK_DEFAULT MASK_V850E3V5 +#undef SUBTARGET_ASM_SPEC +#define SUBTARGET_ASM_SPEC "%{!mv*:-mv850e3v5}" +#undef SUBTARGET_CPP_SPEC +#define SUBTARGET_CPP_SPEC "%{!mv*:-D__v850e3v5__} %{mv850e3v5:-D__v850e3v5__}" +#undef TARGET_VERSION +#define TARGET_VERSION fprintf (stderr, " (Renesas V850E3V5)"); +#endif + +#define TARGET_V850E3V5_UP ((TARGET_V850E3V5)) +#define TARGET_V850E2V3_UP ((TARGET_V850E2V3) || TARGET_V850E3V5_UP) +#define TARGET_V850E2_UP ((TARGET_V850E2) || TARGET_V850E2V3_UP) +#define TARGET_V850E_UP ((TARGET_V850E) || TARGET_V850E2_UP) +#define TARGET_ALL ((TARGET_V850) || TARGET_V850E_UP) #define ASM_SPEC "%{m850es:-mv850e1}%{!mv850es:%{mv*:-mv%*}} \ %{mrelax:-mrelax} \ @@ -96,14 +111,15 @@ extern GTY(()) rtx v850_compare_op1; #define LINK_SPEC "%{mgcc-abi:-m v850}" #define CPP_SPEC "\ + %{mv850e3v5:-D__v850e3v5__} \ %{mv850e2v3:-D__v850e2v3__} \ %{mv850e2:-D__v850e2__} \ %{mv850es:-D__v850e1__} \ %{mv850e1:-D__v850e1__} \ %{mv850e:-D__v850e__} \ %{mv850:-D__v850__} \ - %(subtarget_cpp_spec)" \ - " %{mep:-D__EP__}" + %(subtarget_cpp_spec) \ + %{mep:-D__EP__}" #define EXTRA_SPECS \ { "subtarget_asm_spec", SUBTARGET_ASM_SPEC }, \ @@ -111,7 +127,7 @@ extern GTY(()) rtx v850_compare_op1; /* Macro to decide when FPU instructions can be used. */ -#define TARGET_USE_FPU (TARGET_V850E2V3 && ! TARGET_SOFT_FLOAT) +#define TARGET_USE_FPU (TARGET_V850E2V3_UP && ! TARGET_SOFT_FLOAT) #define TARGET_CPU_CPP_BUILTINS() \ do \ @@ -136,7 +152,7 @@ extern GTY(()) rtx v850_compare_op1; } \ while(0) -#define MASK_CPU (MASK_V850 | MASK_V850E | MASK_V850E1 | MASK_V850E2 | MASK_V850E2V3) +#define MASK_CPU (MASK_V850 | MASK_V850E | MASK_V850E1 | MASK_V850E2 | MASK_V850E2V3 | MASK_V850E3V5) /* Target machine storage layout */ @@ -380,7 +396,8 @@ enum reg_class insn_const_int_ok_for_constraint (VALUE, CONSTRAINT_N) #define CONST_OK_FOR_O(VALUE) \ insn_const_int_ok_for_constraint (VALUE, CONSTRAINT_O) - +#define CONST_OK_FOR_W(VALUE) \ + insn_const_int_ok_for_constraint (VALUE, CONSTRAINT_W) /* Stack layout; function entry, exit and calling. */ @@ -797,9 +814,9 @@ typedef enum #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ fprintf (FILE, "\t%s %s.L%d-.L%d%s\n", \ (TARGET_BIG_SWITCH ? ".long" : ".short"), \ - (0 && ! TARGET_BIG_SWITCH && (TARGET_V850E || TARGET_V850E2_ALL) ? "(" : ""), \ + (0 && ! TARGET_BIG_SWITCH && (TARGET_V850E_UP) ? "(" : ""), \ VALUE, REL, \ - (0 && ! TARGET_BIG_SWITCH && (TARGET_V850E || TARGET_V850E2_ALL) ? ")>>1" : "")) + (0 && ! TARGET_BIG_SWITCH && (TARGET_V850E_UP) ? ")>>1" : "")) #define ASM_OUTPUT_ALIGN(FILE, LOG) \ if ((LOG) != 0) \ @@ -960,4 +977,7 @@ extern tree GHS_current_section_names [(int) COUNT_OF_GHS_SECTION_KINDS]; -isystem . */ #define NO_IMPLICIT_EXTERN_C +#define ADJUST_INSN_LENGTH(INSN, LENGTH) \ + ((LENGTH) = v850_adjust_insn_length ((INSN), (LENGTH))) + #endif /* ! GCC_V850_H */ diff --git a/gcc/config/v850/v850.md b/gcc/config/v850/v850.md index f05f2f9..4ed0e40 100644 --- a/gcc/config/v850/v850.md +++ b/gcc/config/v850/v850.md @@ -43,6 +43,7 @@ (LP_REGNUM 31) ; Return address register (CC_REGNUM 32) ; Condition code pseudo register (FCC_REGNUM 33) ; Floating Condition code pseudo register + (UNSPEC_LOOP 200) ; loop counter ] ) @@ -59,7 +60,7 @@ (define_attr "type" "load,store,bit1,mult,macc,div,fpu,single,other" (const_string "other")) -(define_attr "cpu" "none,v850,v850e,v850e1,v850e2,v850e2v3" +(define_attr "cpu" "none,v850,v850e,v850e1,v850e2,v850e2v3,v850e3v5" (cond [(match_test "TARGET_V850") (const_string "v850") (match_test "TARGET_V850E") @@ -68,8 +69,10 @@ (const_string "v850e1") (match_test "TARGET_V850E2") (const_string "v850e2") - (match_test "TARGET_V850E2") - (const_string "v850e2v3")] + (match_test "TARGET_V850E2V3") + (const_string "v850e2v3") + (match_test "TARGET_V850E3V5") + (const_string "v850e3v5")] (const_string "none"))) ;; Condition code settings. @@ -109,7 +112,7 @@ (sign_extend:SI (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r") (match_operand 2 "disp23_operand" "W")))))] - "TARGET_V850E2V3" + "TARGET_V850E2V3_UP" "ld.b %2[%1],%0" [(set_attr "length" "4") (set_attr "cc" "none_0hit")]) @@ -119,7 +122,7 @@ (zero_extend:SI (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r") (match_operand 2 "disp23_operand" "W")))))] - "TARGET_V850E2V3" + "TARGET_V850E2V3_UP" "ld.bu %2[%1],%0" [(set_attr "length" "4") (set_attr "cc" "none_0hit")]) @@ -129,7 +132,7 @@ (sign_extend:SI (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r") (match_operand 2 "disp23_operand" "W")))))] - "TARGET_V850E2V3" + "TARGET_V850E2V3_UP" "ld.h %2[%1],%0" [(set_attr "length" "4") (set_attr "cc" "none_0hit")]) @@ -139,7 +142,7 @@ (zero_extend:SI (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r") (match_operand 2 "disp23_operand" "W")))))] - "TARGET_V850E2V3" + "TARGET_V850E2V3_UP" "ld.hu %2[%1],%0" [(set_attr "length" "4") (set_attr "cc" "none_0hit")]) @@ -148,7 +151,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") (match_operand 2 "disp23_operand" "W"))))] - "TARGET_V850E2V3" + "TARGET_V850E2V3_UP" "ld.w %2[%1],%0" [(set_attr "length" "4") (set_attr "cc" "none_0hit")]) @@ -157,7 +160,7 @@ [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "r") (match_operand 1 "disp23_operand" "W"))) (match_operand:QI 2 "register_operand" "r"))] - "TARGET_V850E2V3" + "TARGET_V850E2V3_UP" "st.b %2,%1[%0]" [(set_attr "length" "4") (set_attr "cc" "none_0hit")]) @@ -166,7 +169,7 @@ [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "r") (match_operand 1 "disp23_operand" "W"))) (match_operand:HI 2 "register_operand" "r"))] - "TARGET_V850E2V3" + "TARGET_V850E2V3_UP" "st.h %2,%1[%0]" [(set_attr "length" "4") (set_attr "cc" "none_0hit")]) @@ -175,11 +178,47 @@ [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r") (match_operand 1 "disp23_operand" "W"))) (match_operand:SI 2 "register_operand" "r"))] - "TARGET_V850E2V3" + "TARGET_V850E2V3_UP" "st.w %2,%1[%0]" [(set_attr "length" "4") (set_attr "cc" "none_0hit")]) +;; movdi + +(define_expand "movdi" + [(set (match_operand:DI 0 "general_operand") + (match_operand:DI 1 "general_operand"))] + "TARGET_V850E3V5_UP" + { + /* One of the ops has to be in a register or 0. */ + if (!register_operand (operand0, DImode) + && !register_operand (operand1, DImode)) + operands[1] = copy_to_mode_reg (DImode, operand1); + + if (register_operand (operand0, DImode) + && (CONST_INT_P (operands[1]) || CONST_DOUBLE_P (operands[1]))) + { + int i; + + for (i = 0; i < UNITS_PER_WORD * 2; i += UNITS_PER_WORD) + emit_move_insn (simplify_gen_subreg (SImode, operands[0], DImode, i), + simplify_gen_subreg (SImode, operands[1], DImode, i)); + DONE; + } + } +) + +(define_insn "*movdi_internal" + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,e!r,m") + (match_operand:DI 1 "nonimmediate_operand" "r,m,e!r"))] + "TARGET_V850E3V5_UP + || (register_operand (operands[0], DImode) && register_operand (operands[1], DImode))" + { return v850_gen_movdi (operands); } + [(set_attr "length" "4,12,12") + (set_attr "cc" "none_0hit") + (set_attr "type" "other,load,store")] +) + ;; movqi (define_expand "movqi" @@ -265,7 +304,7 @@ must be done with HIGH & LO_SUM patterns. */ if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != HIGH - && ! (TARGET_V850E || TARGET_V850E2_ALL) + && ! (TARGET_V850E_UP) && !special_symbolref_operand (operands[1], VOIDmode) && !(GET_CODE (operands[1]) == CONST_INT && (CONST_OK_FOR_J (INTVAL (operands[1])) @@ -297,7 +336,7 @@ (define_insn "*movsi_internal_v850e" [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m,r") (match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))] - "(TARGET_V850E || TARGET_V850E2_ALL) + "(TARGET_V850E_UP) && (register_operand (operands[0], SImode) || reg_or_0_operand (operands[1], SImode))" { @@ -412,17 +451,17 @@ (label_ref (match_operand 3 "")) (pc))) (clobber (cc0))] - "TARGET_V850E2V3" + "TARGET_USE_FPU" { - v850_compare_op0 = operands[1]; - v850_compare_op1 = operands[2]; - - enum rtx_code cond = GET_CODE(operands[0]); + enum rtx_code cond = GET_CODE (operands[0]); enum machine_mode mode; rtx fcc_reg; rtx cc_reg; rtx tmp; + v850_compare_op0 = operands[1]; + v850_compare_op1 = operands[2]; + if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT) FAIL; @@ -442,7 +481,7 @@ (match_operator:SI 1 "ordered_comparison_operator" [(match_operand:SF 2 "register_operand" "r") (match_operand:SF 3 "register_operand" "r")]))] - "TARGET_V850E2V3" + "TARGET_USE_FPU" { if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE) return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf nz, %0"; @@ -466,17 +505,17 @@ (label_ref (match_operand 3 "")) (pc))) (clobber (cc0))] - "TARGET_V850E2V3" + "TARGET_USE_FPU" { - v850_compare_op0 = operands[1]; - v850_compare_op1 = operands[2]; - - enum rtx_code cond = GET_CODE(operands[0]); + enum rtx_code cond = GET_CODE (operands[0]); enum machine_mode mode; rtx fcc_reg; rtx cc_reg; rtx tmp; + v850_compare_op0 = operands[1]; + v850_compare_op1 = operands[2]; + if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT) FAIL; @@ -496,7 +535,7 @@ (match_operator:SI 1 "ordered_comparison_operator" [(match_operand:DF 2 "even_reg_operand" "r") (match_operand:DF 3 "even_reg_operand" "r")]))] - "TARGET_V850E2V3" + "TARGET_USE_FPU" { if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE) return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf nz, %0"; @@ -633,7 +672,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (match_operand:SI 1 "register_operand" "%0") (match_operand:SI 2 "reg_or_int9_operand" "rO")))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" "mul %2,%1,%." [(set_attr "length" "4") (set_attr "cc" "none_0hit") @@ -657,9 +696,9 @@ (mod:SI (match_dup 1) (match_dup 2))) (clobber (reg:CC CC_REGNUM))] - "TARGET_V850E || TARGET_V850E2_ALL" + "TARGET_V850E_UP" { - if (TARGET_V850E2_ALL) + if (TARGET_V850E2_UP) return "divq %2,%0,%3"; else return "div %2,%0,%3"; @@ -676,9 +715,9 @@ (umod:SI (match_dup 1) (match_dup 2))) (clobber (reg:CC CC_REGNUM))] - "TARGET_V850E || TARGET_V850E2_ALL" + "TARGET_V850E_UP" { - if (TARGET_V850E2_ALL) + if (TARGET_V850E2_UP) return "divqu %2,%0,%3"; else return "divu %2,%0,%3"; @@ -698,7 +737,7 @@ (mod:HI (match_dup 1) (match_dup 2))) (clobber (reg:CC CC_REGNUM))] - "TARGET_V850E || TARGET_V850E2_ALL" + "TARGET_V850E_UP" "divh %2,%0,%3" [(set_attr "length" "4") (set_attr "cc" "clobber") @@ -715,7 +754,7 @@ (umod:HI (match_dup 1) (match_dup 2))) (clobber (reg:CC CC_REGNUM))] - "TARGET_V850E || TARGET_V850E2_ALL" + "TARGET_V850E_UP" "zxh %0 ; divhu %2,%0,%3" [(set_attr "length" "4") (set_attr "cc" "clobber") @@ -984,6 +1023,17 @@ ;; optimize_bitfield_compare in fold-const usually converts single ;; bit extracts into an AND with a mask. +(define_insn "insv" + [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") + (match_operand:SI 1 "immediate_operand" "n") + (match_operand:SI 2 "immediate_operand" "n")) + (match_operand:SI 3 "register_operand" "r"))] + "TARGET_V850E3V5_UP" + "bins %3, %2, %1, %0" + [(set_attr "length" "4") + (set_attr "cc" "set_zn")] +) + ;; ----------------------------------------------------------------- ;; Scc INSTRUCTIONS ;; ----------------------------------------------------------------- @@ -1018,7 +1068,7 @@ (define_insn "set_z_insn" [(set (match_operand:SI 0 "register_operand" "=r") (match_operand 1 "v850_float_z_comparison_operator" ""))] - "TARGET_V850E2V3" + "TARGET_V850E2V3_UP" "setf z,%0" [(set_attr "length" "4") (set_attr "cc" "none_0hit")]) @@ -1026,7 +1076,7 @@ (define_insn "set_nz_insn" [(set (match_operand:SI 0 "register_operand" "=r") (match_operand 1 "v850_float_nz_comparison_operator" ""))] - "TARGET_V850E2V3" + "TARGET_V850E2V3_UP" "setf nz,%0" [(set_attr "length" "4") (set_attr "cc" "none_0hit")]) @@ -1045,7 +1095,7 @@ (match_operand 1 "comparison_operator") (match_operand:SI 2 "reg_or_const_operand" "rJ") (match_operand:SI 3 "reg_or_const_operand" "rI")))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" { /* Make sure that we have an integer comparison... */ if (GET_MODE (XEXP (operands[1], 0)) != CCmode @@ -1093,7 +1143,7 @@ [(reg:CC CC_REGNUM) (const_int 0)]) (match_operand:SI 2 "reg_or_int5_operand" "rJ") (match_operand:SI 3 "reg_or_0_operand" "rI")))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" "cmov %c1,%2,%z3,%0"; [(set_attr "length" "6") (set_attr "cc" "compare")]) @@ -1105,7 +1155,7 @@ [(reg:CC CC_REGNUM) (const_int 0)]) (match_operand:SI 2 "reg_or_0_operand" "rI") (match_operand:SI 3 "reg_or_int5_operand" "rJ")))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" "cmov %C1,%3,%z2,%0" [(set_attr "length" "6") (set_attr "cc" "compare")]) @@ -1118,7 +1168,7 @@ (match_operand:SI 5 "reg_or_int5_operand" "rJ")]) (match_operand:SI 2 "reg_or_int5_operand" "rJ") (match_operand:SI 3 "reg_or_0_operand" "rI")))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" "cmp %5,%4 ; cmov %c1,%2,%z3,%0" [(set_attr "length" "6") (set_attr "cc" "clobber")]) @@ -1131,7 +1181,7 @@ (match_operand:SI 5 "reg_or_int5_operand" "rJ")]) (match_operand:SI 2 "reg_or_0_operand" "rI") (match_operand:SI 3 "reg_or_int5_operand" "rJ")))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" "cmp %5,%4 ; cmov %C1,%3,%z2,%0" [(set_attr "length" "6") (set_attr "cc" "clobber")]) @@ -1147,7 +1197,7 @@ (const_int 0)]) (match_operand:SI 4 "reg_or_int5_operand" "rJ") (match_operand:SI 5 "reg_or_0_operand" "rI")))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" "tst1 %3,%2 ; cmov %c1,%4,%z5,%0" [(set_attr "length" "8") (set_attr "cc" "clobber")]) @@ -1163,7 +1213,7 @@ (const_int 0)]) (match_operand:SI 4 "reg_or_0_operand" "rI") (match_operand:SI 5 "reg_or_int5_operand" "rJ")))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" "tst1 %3,%2 ; cmov %C1,%5,%z4,%0" [(set_attr "length" "8") (set_attr "cc" "clobber")]) @@ -1182,7 +1232,7 @@ (ashift:SI (match_operand:SI 2 "register_operand" "0") (const_int 1)))) (clobber (reg:CC CC_REGNUM))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" "cmp %4,%3 ; sasf %c1,%0" [(set_attr "length" "6") (set_attr "cc" "clobber")]) @@ -1196,7 +1246,7 @@ (match_operand:SI 2 "const_int_operand" "") (match_operand:SI 3 "const_int_operand" ""))) (clobber (reg:CC CC_REGNUM))] - "(TARGET_V850E || TARGET_V850E2_ALL) + "(TARGET_V850E_UP) && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1) && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1) && (GET_CODE (operands[5]) == CONST_INT @@ -1225,7 +1275,7 @@ (rotate:HI (match_operand:HI 1 "register_operand" "") (match_operand:HI 2 "const_int_operand" ""))) (clobber (reg:CC CC_REGNUM))])] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" { if (INTVAL (operands[2]) != 8) FAIL; @@ -1236,7 +1286,7 @@ (rotate:HI (match_operand:HI 1 "register_operand" "r") (const_int 8))) (clobber (reg:CC CC_REGNUM))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" "bsh %1,%0" [(set_attr "length" "4") (set_attr "cc" "clobber")]) @@ -1246,18 +1296,55 @@ (rotate:SI (match_operand:SI 1 "register_operand" "") (match_operand:SI 2 "const_int_operand" ""))) (clobber (reg:CC CC_REGNUM))])] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" { if (INTVAL (operands[2]) != 16) FAIL; }) +(define_insn "rotlsi3_a" + [(set (match_operand:SI 0 "register_operand" "=r") + (match_operator:SI 4 "ior_operator" + [(ashift:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "const_int_operand" "n")) + (lshiftrt:SI (match_dup 1) + (match_operand:SI 3 "const_int_operand" "n"))]))] + "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)" + "rotl %2, %1, %0" + [(set_attr "length" "4") + (set_attr "cc" "set_zn")] +) + +(define_insn "rotlsi3_b" + [(set (match_operand:SI 0 "register_operand" "=r") + (match_operator:SI 4 "ior_operator" + [(lshiftrt:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 3 "const_int_operand" "n")) + (ashift:SI (match_dup 1) + (match_operand:SI 2 "const_int_operand" "n"))]))] + "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)" + "rotl %2, %1, %0" + [(set_attr "length" "4") + (set_attr "cc" "set_zn")] +) + +(define_insn "rotlsi3_v850e3v5" + [(set (match_operand:SI 0 "register_operand" "=r") + (rotate:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "e3v5_shift_operand" "rn"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_V850E3V5_UP" + "rotl %2, %1, %0" + [(set_attr "length" "4") + (set_attr "cc" "set_zn")] +) + (define_insn "*rotlsi3_16" [(set (match_operand:SI 0 "register_operand" "=r") (rotate:SI (match_operand:SI 1 "register_operand" "r") (const_int 16))) (clobber (reg:CC CC_REGNUM))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" "hsw %1,%0" [(set_attr "length" "4") (set_attr "cc" "clobber")]) @@ -1266,6 +1353,99 @@ ;; JUMP INSTRUCTIONS ;; ---------------------------------------------------------------------- +;; Doloop + +(define_expand "doloop_begin" + [(use (match_operand 0 "" "")) ; loop pseudo + (use (match_operand 1 "" "")) ; iterations; zero if unknown + (use (match_operand 2 "" "")) ; max iterations + (use (match_operand 3 "" "")) ; loop level + (use (match_operand 4 "" ""))] ; condition + "TARGET_V850E3V5_UP && TARGET_LOOP" + { + rtx loop_cnt = operands[0]; + rtx loop_level = operands[3]; + + if (INTVAL (loop_level) > 1) + FAIL; + if (GET_MODE (loop_cnt) != SImode) + FAIL; + + emit_insn (gen_fix_loop_counter (loop_cnt)); + DONE; + } +) + +(define_insn "fix_loop_counter" + [(unspec:SI [(match_operand:SI 0 "register_operand" "+r,!m") + (clobber (match_scratch:SI 1 "=X,r"))] UNSPEC_LOOP)] + "TARGET_V850E3V5_UP && TARGET_LOOP" + { + switch (which_alternative) + { + case 0: return "add 1, %0 # LOOP_BEGIN"; + case 1: return "ld.w %0, %1; add 1, %1; st.w %1, %0 # LOOP_BEGIN"; + default: gcc_unreachable (); + } + } + [(set_attr "length" "2,6") + (set_attr "cc" "none")] +) + +(define_expand "doloop_end" + [(use (match_operand 0 "" "")) ; loop pseudo + (use (match_operand 1 "" "")) ; iterations; zero if unknown + (use (match_operand 2 "" "")) ; max iterations + (use (match_operand 3 "" "")) ; loop level + (use (match_operand 4 "" "")) ; label + (use (match_operand 5 "" ""))] ; entered at top + "TARGET_V850E3V5_UP && TARGET_LOOP" + { + rtx loop_cnt = operands[0]; + rtx loop_level = operands[3]; + rtx label = operands[4]; + + if (INTVAL (loop_level) > 1) + FAIL; + if (GET_MODE (loop_cnt) != SImode) + FAIL; + + emit_jump_insn (gen_doloop_end_internal_loop (label, loop_cnt)); + DONE; + } +) + +(define_insn "doloop_end_internal_loop" + [(set (pc) + (if_then_else (ne (match_operand:SI 1 "register_operand" "+r,!m") + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc))) + (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1))) + (clobber (match_scratch:SI 2 "=X,r")) + (clobber (reg:CC CC_REGNUM))] + "TARGET_V850E3V5_UP && TARGET_LOOP" + { + switch (which_alternative) + { + case 0: + if (get_attr_length (insn) == 4) + return "loop %1, %0 # LOOP.1.0"; + + return "add -1, %1; bne %l0 # LOOP.1.1"; + case 1: + return "ld.w %1, %2; add -1, %2; st.w %2, %1; bne %l0 # LOOP.2.1"; + default: + gcc_unreachable (); + } + } + [(set (attr "length") + (if_then_else (lt (abs (minus (match_dup 0) (pc))) + (const_int 65534)) + (const_int 4) + (const_int 14))) + (set_attr "cc" "none")]) + ;; Conditional jump instructions (define_insn "*branch_normal" @@ -1285,14 +1465,18 @@ if (get_attr_length (insn) == 2) return "b%b1 %l0"; - else - return "b%B1 .+6 ; jr %l0"; + if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4) + return "b%b1 %l0"; + return "b%B1 .+6 ; jr %l0"; } [(set (attr "length") (if_then_else (lt (abs (minus (match_dup 0) (pc))) (const_int 256)) (const_int 2) - (const_int 6))) + (if_then_else (lt (abs (minus (match_dup 0) (pc))) + (const_int 65536)) + (const_int 4) + (const_int 6)))) (set_attr "cc" "none")]) (define_insn "*branch_invert" @@ -1308,17 +1492,24 @@ || GET_CODE (operands[1]) == GE || GET_CODE (operands[1]) == LE || GET_CODE (operands[1]) == LT)) - return 0; + return NULL; + if (get_attr_length (insn) == 2) return "b%B1 %l0"; - else - return "b%b1 .+6 ; jr %l0"; + + if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4) + return "b%B1 %l0"; + + return "b%b1 .+6 ; jr %l0"; } [(set (attr "length") (if_then_else (lt (abs (minus (match_dup 0) (pc))) (const_int 256)) (const_int 2) - (const_int 6))) + (if_then_else (lt (abs (minus (match_dup 0) (pc))) + (const_int 65536)) + (const_int 4) + (const_int 6)))) (set_attr "cc" "none")]) (define_insn "branch_z_normal" @@ -1326,18 +1517,24 @@ (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "") (label_ref (match_operand 0 "" "")) (pc)))] - "TARGET_V850E2V3" + "TARGET_V850E2V3_UP" { if (get_attr_length (insn) == 2) return "bz %l0"; - else - return "bnz 1f ; jr %l0 ; 1:"; + + if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4) + return "bz %l0"; + + return "bnz 1f ; jr %l0 ; 1:"; } [(set (attr "length") (if_then_else (lt (abs (minus (match_dup 0) (pc))) (const_int 256)) (const_int 2) - (const_int 6))) + (if_then_else (lt (abs (minus (match_dup 0) (pc))) + (const_int 65536)) + (const_int 4) + (const_int 6)))) (set_attr "cc" "none")]) (define_insn "*branch_z_invert" @@ -1345,18 +1542,24 @@ (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "") (pc) (label_ref (match_operand 0 "" ""))))] - "TARGET_V850E2V3" + "TARGET_V850E2V3_UP" { if (get_attr_length (insn) == 2) return "bnz %l0"; - else - return "bz 1f ; jr %l0 ; 1:"; + + if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4) + return "bnz %l0"; + + return "bz 1f ; jr %l0 ; 1:"; } [(set (attr "length") (if_then_else (lt (abs (minus (match_dup 0) (pc))) (const_int 256)) (const_int 2) - (const_int 6))) + (if_then_else (lt (abs (minus (match_dup 0) (pc))) + (const_int 65536)) + (const_int 4) + (const_int 6)))) (set_attr "cc" "none")]) (define_insn "branch_nz_normal" @@ -1364,18 +1567,24 @@ (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "") (label_ref (match_operand 0 "" "")) (pc)))] - "TARGET_V850E2V3" + "TARGET_V850E2V3_UP" { if (get_attr_length (insn) == 2) return "bnz %l0"; - else - return "bz 1f ; jr %l0 ; 1:"; + + if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4) + return "bnz %l0"; + + return "bz 1f ; jr %l0 ; 1:"; } [(set (attr "length") (if_then_else (lt (abs (minus (match_dup 0) (pc))) (const_int 256)) (const_int 2) - (const_int 6))) + (if_then_else (lt (abs (minus (match_dup 0) (pc))) + (const_int 65536)) + (const_int 4) + (const_int 6)))) (set_attr "cc" "none")]) (define_insn "*branch_nz_invert" @@ -1383,18 +1592,24 @@ (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "") (pc) (label_ref (match_operand 0 "" ""))))] - "TARGET_V850E2V3" + "TARGET_V850E2V3_UP" { if (get_attr_length (insn) == 2) return "bz %l0"; - else - return "bnz 1f ; jr %l0 ; 1:"; + + if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4) + return "bz %l0"; + + return "bnz 1f ; jr %l0 ; 1:"; } [(set (attr "length") (if_then_else (lt (abs (minus (match_dup 0) (pc))) (const_int 256)) (const_int 2) - (const_int 6))) + (if_then_else (lt (abs (minus (match_dup 0) (pc))) + (const_int 65536)) + (const_int 4) + (const_int 6)))) (set_attr "cc" "none")]) ;; Unconditional and other jump instructions. @@ -1440,7 +1655,7 @@ (const_int 1)) (label_ref (match_operand 1 "" ""))))) (label_ref (match_dup 1))))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" "switch %0" [(set_attr "length" "2") (set_attr "cc" "none")]) @@ -1512,9 +1727,17 @@ (match_operand:SI 1 "general_operand" "g,g")) (clobber (reg:SI 31))] "! TARGET_LONG_CALLS" - "@ - jarl %0,r31 - jarl .+4,r31 ; add 4,r31 ; jmp %0" + { + if (which_alternative == 1) + { + if (TARGET_V850E3V5_UP) + return "jarl [%0], r31"; + + return "jarl .+4, r31 ; add 4, r31 ; jmp %0"; + } + + return "jarl %0, r31"; + } [(set_attr "length" "4,8") (set_attr "cc" "clobber,clobber")] ) @@ -1529,11 +1752,17 @@ { if (GET_CODE (operands[0]) == REG) return "jarl %0,r31"; - else - return "movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11"; + + if (TARGET_V850E3V5_UP) + return "mov hilo(%0), r11 ; jarl [r11], r31"; + + return "movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11"; } - else - return "jarl .+4,r31 ; add 4,r31 ; jmp %0"; + + if (TARGET_V850E3V5_UP) + return "jarl [%0], r31"; + + return "jarl .+4,r31 ; add 4,r31 ; jmp %0"; } [(set_attr "length" "16,8") (set_attr "cc" "clobber,clobber")] @@ -1568,9 +1797,17 @@ (match_operand:SI 2 "general_operand" "g,g"))) (clobber (reg:SI 31))] "! TARGET_LONG_CALLS" - "@ - jarl %1,r31 - jarl .+4,r31 ; add 4,r31 ; jmp %1" + { + if (which_alternative == 1) + { + if (TARGET_V850E3V5_UP) + return "jarl [%1], r31"; + + return "jarl .+4, r31 ; add 4, r31 ; jmp %1"; + } + + return "jarl %1, r31"; + } [(set_attr "length" "4,8") (set_attr "cc" "clobber,clobber")] ) @@ -1586,12 +1823,18 @@ { if (GET_CODE (operands[1]) == REG) return "jarl %1, r31"; - else + /* Reload can generate this pattern.... */ - return "movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11"; + if (TARGET_V850E3V5_UP) + return "mov hilo(%1), r11 ; jarl [r11], r31"; + + return "movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11"; } - else - return "jarl .+4, r31 ; add 4, r31 ; jmp %1"; + + if (TARGET_V850E3V5_UP) + return "jarl [%1], r31"; + + return "jarl .+4, r31 ; add 4, r31 ; jmp %1"; } [(set_attr "length" "16,8") (set_attr "cc" "clobber,clobber")] @@ -1613,7 +1856,7 @@ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m"))) (clobber (reg:CC CC_REGNUM))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" "@ zxh %0 andi 65535,%1,%0 @@ -1639,7 +1882,7 @@ (clobber (reg:CC CC_REGNUM))])] "" { - if (! (TARGET_V850E || TARGET_V850E2_ALL)) + if (! (TARGET_V850E_UP)) operands[1] = force_reg (HImode, operands[1]); }) @@ -1648,7 +1891,7 @@ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m"))) (clobber (reg:CC CC_REGNUM))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" "@ zxb %0 andi 255,%1,%0 @@ -1674,7 +1917,7 @@ (clobber (reg:CC CC_REGNUM))])] "" { - if (! (TARGET_V850E || TARGET_V850E2_ALL)) + if (! (TARGET_V850E_UP)) operands[1] = force_reg (QImode, operands[1]); }) @@ -1686,7 +1929,7 @@ [(set (match_operand:SI 0 "register_operand" "=r,r,r") (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m"))) (clobber (reg:CC CC_REGNUM))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" "@ sxh %0 sld.h %1,%0 @@ -1718,7 +1961,7 @@ [(set (match_operand:SI 0 "register_operand" "=r,r,r") (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m"))) (clobber (reg:CC CC_REGNUM))] - "(TARGET_V850E || TARGET_V850E2_ALL)" + "(TARGET_V850E_UP)" "@ sxb %0 sld.b %1,%0 @@ -1767,7 +2010,7 @@ (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "nonmemory_operand" "r"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_V850E2_ALL" + "TARGET_V850E2_UP" "shl %2,%1,%0" [(set_attr "length" "4") (set_attr "cc" "set_znv")]) @@ -1791,7 +2034,7 @@ (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "nonmemory_operand" "r"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_V850E2_ALL" + "TARGET_V850E2_UP" "shr %2,%1,%0" [(set_attr "length" "4") (set_attr "cc" "set_zn")]) @@ -1815,7 +2058,7 @@ (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "nonmemory_operand" "r"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_V850E2_ALL" + "TARGET_V850E2_UP" "sar %2,%1,%0" [(set_attr "length" "4") (set_attr "cc" "set_zn")]) @@ -1828,7 +2071,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (ffs:SI (match_operand:SI 1 "register_operand" "r"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_V850E2_ALL" + "TARGET_V850E2_UP" "sch1r %1,%0" [(set_attr "length" "4") (set_attr "cc" "clobber")]) @@ -2529,7 +2772,7 @@ (set (mem:SI (plus:SI (reg:SI 3) (match_operand:SI 2 "immediate_operand" "i"))) (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])] - "TARGET_PROLOG_FUNCTION && (TARGET_V850E || TARGET_V850E2_ALL)" + "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)" { return construct_prepare_instruction (operands[0]); } @@ -2563,7 +2806,7 @@ (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r") (mem:SI (plus:SI (reg:SI 3) (match_operand:SI 3 "immediate_operand" "i"))))])] - "TARGET_PROLOG_FUNCTION && (TARGET_V850E || TARGET_V850E2_ALL)" + "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)" { return construct_dispose_instruction (operands[0]); } @@ -2594,7 +2837,7 @@ ;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION. (define_insn "callt_save_interrupt" [(unspec_volatile [(const_int 0)] 2)] - "(TARGET_V850E || TARGET_V850E2_ALL) && !TARGET_DISABLE_CALLT" + "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT" ;; The CALLT instruction stores the next address of CALLT to CTPC register ;; without saving its previous value. So if the interrupt handler ;; or its caller could possibly execute the CALLT insn, save_interrupt @@ -2616,7 +2859,7 @@ (define_insn "callt_return_interrupt" [(unspec_volatile [(const_int 0)] 3)] - "(TARGET_V850E || TARGET_V850E2_ALL) && !TARGET_DISABLE_CALLT" + "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT" "callt ctoff(__callt_return_interrupt)" [(set_attr "length" "2") (set_attr "cc" "clobber")]) @@ -2693,7 +2936,7 @@ (define_insn "callt_save_all_interrupt" [(unspec_volatile [(const_int 0)] 0)] - "(TARGET_V850E || TARGET_V850E2_ALL) && !TARGET_DISABLE_CALLT" + "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT" "callt ctoff(__callt_save_all_interrupt)" [(set_attr "length" "2") (set_attr "cc" "none")]) @@ -2793,7 +3036,7 @@ (define_insn "callt_restore_all_interrupt" [(unspec_volatile [(const_int 0)] 1)] - "(TARGET_V850E || TARGET_V850E2_ALL) && !TARGET_DISABLE_CALLT" + "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT" "callt ctoff(__callt_restore_all_interrupt)" [(set_attr "length" "2") (set_attr "cc" "none")]) diff --git a/gcc/config/v850/v850.opt b/gcc/config/v850/v850.opt index 4418c0b..feba0dd 100644 --- a/gcc/config/v850/v850.opt +++ b/gcc/config/v850/v850.opt @@ -112,6 +112,17 @@ mv850e2v3 Target Report RejectNegative Mask(V850E2V3) Compile for the v850e2v3 processor +mv850e3v5 +Target Report RejectNegative Mask(V850E3V5) +Compile for the v850e3v5 processor + +mv850e2v4 +Target RejectNegative Mask(V850E3V5) MaskExists + +mloop +Target Report Mask(LOOP) +Enable v850e3v5 loop instructions + mzda= Target RejectNegative Joined UInteger Set the max size of data eligible for the ZDA area diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index ef06b0b..e9fe4ef 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -956,11 +956,16 @@ See RS/6000 and PowerPC Options. -mtda=@var{n} -msda=@var{n} -mzda=@var{n} @gol -mapp-regs -mno-app-regs @gol -mdisable-callt -mno-disable-callt @gol --mv850e2v3 @gol --mv850e2 @gol --mv850e1 -mv850es @gol --mv850e @gol --mv850 -mbig-switch} +-mv850e2v3 -mv850e2 -mv850e1 -mv850es @gol +-mv850e -mv850 -mv850e3v5 @gol +-mloop @gol +-mrelax @gol +-mlong-jumps @gol +-msoft-float @gol +-mhard-float @gol +-mgcc-abi @gol +-mrh850-abi @gol +-mbig-switch} @emph{VAX Options} @gccoptlist{-mg -mgnu -munix} @@ -6083,7 +6088,7 @@ vectorizer passes print the source location of loops which got successfully vectorized. @item missed Print information about missed optimizations. Individual passes -control which informations to include in the output. For example, +control which information to include in the output. For example, @smallexample gcc -O2 -ftree-vectorize -fopt-info-vec-missed @@ -8401,7 +8406,7 @@ requires the complete toolchain to be aware of LTO. It requires a linker with linker plugin support for basic functionality. Additionally, @command{nm}, @command{ar} and @command{ranlib} need to support linker plugins to allow a full-featured build environment -(capable of building static libraries etc). gcc provides the @command{gcc-ar}, +(capable of building static libraries etc). GCC provides the @command{gcc-ar}, @command{gcc-nm}, @command{gcc-ranlib} wrappers to pass the right options to these tools. With non fat LTO makefiles need to be modified to use them. @@ -19591,26 +19596,20 @@ the first 32 kilobytes of memory. @opindex mv850 Specify that the target processor is the V850. -@item -mbig-switch -@opindex mbig-switch -Generate code suitable for big switch tables. Use this option only if -the assembler/linker complain about out of range branches within a switch -table. - -@item -mapp-regs -@opindex mapp-regs -This option causes r2 and r5 to be used in the code generated by -the compiler. This setting is the default. +@item -mv850e3v5 +@opindex mv850e3v5 +Specify that the target processor is the V850E3V5. The preprocessor +constant @samp{__v850e3v5__} is defined if this option is used. -@item -mno-app-regs -@opindex mno-app-regs -This option causes r2 and r5 to be treated as fixed registers. +@item -mv850e2v4 +@opindex mv850e2v4 +Specify that the target processor is the V850E3V5. This is an alias for +the @option{-mv850e3v5} option. @item -mv850e2v3 @opindex mv850e2v3 Specify that the target processor is the V850E2V3. The preprocessor -constant @samp{__v850e2v3__} is defined if -this option is used. +constant @samp{__v850e2v3__} is defined if this option is used. @item -mv850e2 @opindex mv850e2 @@ -19634,7 +19633,7 @@ Specify that the target processor is the V850E@. The preprocessor constant @samp{__v850e__} is defined if this option is used. If neither @option{-mv850} nor @option{-mv850e} nor @option{-mv850e1} -nor @option{-mv850e2} nor @option{-mv850e2v3} +nor @option{-mv850e2} nor @option{-mv850e2v3} nor @option{-mv850e3v5} are defined then a default target processor is chosen and the relevant @samp{__v850*__} preprocessor constant is defined. @@ -19642,10 +19641,131 @@ The preprocessor constants @samp{__v850} and @samp{__v851__} are always defined, regardless of which processor variant is the target. @item -mdisable-callt +@itemx -mno-disable-callt @opindex mdisable-callt +@opindex mno-disable-callt This option suppresses generation of the @code{CALLT} instruction for the -v850e, v850e1, v850e2 and v850e2v3 flavors of the v850 architecture. The default is -@option{-mno-disable-callt} which allows the @code{CALLT} instruction to be used. +v850e, v850e1, v850e2, v850e2v3 and v850e3v5 flavors of the v850 +architecture. + +This option is enabled by default when the RH850 ABI is +in use (see @option{-mrh850-abi}), and disabled by default when the +GCC ABI is in use. If @code{CALLT} instructions are being generated +then the C preprocessor symbol @code{__V850_CALLT__} will be defined. + +@item -mrelax +@itemx -mno-relax +@opindex mrelax +@opindex mno-relax +Pass on (or do not pass on) the @option{-mrelax} command line option +to the assembler. + +@item -mlong-jumps +@itemx -mno-long-jumps +@opindex mlong-jumps +@opindex mno-long-jumps +Disable (or re-enable) the generation of PC-relative jump instructions. + +@item -msoft-float +@itemx -mhard-float +@opindex msoft-float +@opindex mhard-float +Disable (or re-enable) the generation of hardware floating point +instructions. This option is only significant when the target +architecture is @samp{V850E2V3} or higher. If hardware floating point +instructions are being generated then the C preprocessor symbol +@code{__FPU_OK__} will be defined, otherwise the symbol +@code{__NO_FPU__} will be defined. + +@item -mloop +@opindex mloop +Enables the use of the e3v5 LOOP instruction. The use of this +instruction is not enabled by default when the e3v5 architecture is +selected because its use is still experimental. + +@item -mrh850-abi +@itemx -mghs +@opindex mrh850-abi +@opindex mghs +Enables support for the RH850 version of the V850 ABI. This is the +default. With this version of the ABI the following rules apply: + +@itemize +@item +Integer sized structures and unions are returned via a memory pointer +rather than a register. + +@item +Large structures and unions (more than 8 bytes in size) are passed by +value. + +@item +Functions are aligned to 16-bit boundaries. + +@item +The @option{-m8byte-align} command line option is supported. + +@item +The @option{-mdisable-callt} command line option is enabled by +default. The @option{-mno-disable-callt} command line option is not +supported. +@end itemize + +When this version of the ABI is enabled the C preprocessor symbol +@code{__V850_RH850_ABI__} is defined. + +@item -mgcc-abi +@opindex mgcc-abi +Enables support for the old GCC version of the V850 ABI. With this +version of the ABI the following rules apply: + +@itemize +@item +Integer sized structures and unions are returned in register @code{r10}. + +@item +Large structures and unions (more than 8 bytes in size) are passed by +reference. + +@item +Functions are aligned to 32-bit boundaries, unless optimizing for +size. + +@item +The @option{-m8byte-align} command line option is not supported. + +@item +The @option{-mdisable-callt} command line option is supported but not +enabled by default. +@end itemize + +When this version of the ABI is enabled the C preprocessor symbol +@code{__V850_GCC_ABI__} is defined. + +@item -m8byte-align +@itemx -mno-8byte-align +@opindex m8byte-align +@opindex mno-8byte-align +Enables support for @code{doubles} and @code{long long} types to be +aligned on 8-byte boundaries. The default is to restrict the +alignment of all objects to at most 4-bytes. When +@option{-m8byte-align} is in effect the C preprocessor symbol +@code{__V850_8BYTE_ALIGN__} will be defined. + +@item -mbig-switch +@opindex mbig-switch +Generate code suitable for big switch tables. Use this option only if +the assembler/linker complain about out of range branches within a switch +table. + +@item -mapp-regs +@opindex mapp-regs +This option causes r2 and r5 to be used in the code generated by +the compiler. This setting is the default. + +@item -mno-app-regs +@opindex mno-app-regs +This option causes r2 and r5 to be treated as fixed registers. @end table -- cgit v1.1