configure.ac: Support all v850 targets.

* configure.ac: Support all v850 targets.
        * configure: Regenerate.

        * config/v850/lib1funcs.asm (save_r2_r31, return_r2_r31,
        save_r20_r31, return_r20_r31, save_r21_r31, return_r21_r31,
        save_r22_r31, return_r22_r31, save_r23_r31, return_r23_r31,
        save_r24_r31, return_r24_r31, save_r25_r31, return_r25_r31,
        save_r26_r31, return_r26_r31, save_r27_r31, return_r27_r31,
        save_r28_r31, return_r28_r31, save_r29_r31, return_r29_r31,
        save_r31, return_r31, save_interrupt, return_interrupt,
        save_all_interrupt, return_all_interrupt, L_save_r2_r31,
        L_return_interrupt, callt_return_interrupt, L_restore_all_interrupt,
        L_save_##START##_r31c, L_callt_save_r31c: Updated as per the
        new ABI requirements.
        save_r6_r9, L_callt_save_r6_r9: Remove.
        * config/v850/predicates.md (even_reg_operand, disp23_operand,
        const_float_1_operand const_float_0_operand): New Predicates.
        (pattern_is_ok_for_prepare, pattern_is_ok_for_prologue,
        pattern_is_ok_for_epilogue): Update as per the ABI requirements.
        * config/v850/t-v850: Update multilibs for new target variants.
        (save_varargs, callt_save_varargs, callt_save_r6_r9): Remove.
        * config/v850/t-v850e: Likewise.
        * config/v850/v850.c (v850_issue_rate): New.
        (v850_strict_argument_naming): New.
        (function_arg): Modify to generate a different ABI.
        (print_operand): Update case 'z' to support float modes.
        (output_move_single): Modify to generate appropriate and better
        assembly.
        (v850_float_z_comparison_operator, v850_select_cc_mode,
        v850_float_nz_comparison_operator,  v850_gen_float_compare,
        v850_gen_compare): New functions to support comparison of
        float values.
        (ep_memory_offset): Add support for V850E2 targets.
        (INTERRUPT_FIXED_NUM, INTERRUPT_ALL_SAVE_NUM): Update.
        (INTERRUPT_REGPARM_NUM): Remove.
        (compute_register_save_size): Add extra case to save/restore
        long call.
        (use_prolog_function): New function to support prologue.
        (expand_prologue): Add support for V850E2 targets and modified
        as per the current ABI requirements.
        (expand_epilogue): Likewise.
        (construct_restore_jr): Modify based on TARGET_LONG_CALLS.
        (construct_save_jarl): Likewise.
        (construct_dispose_instruction): Update as per the current ABI
        requirements.
        (construct_prepare_instruction): Likewise.
        * config/v850/v850.h(TARGET_CPU_DEFAULT): Add target predefines.
        (TARGET_CPU_v850e2, TARGET_CPU_v850e2v3): Define
        (CPP_SPEC): Updated to support v850e2 targets.
        (STRICT_ALIGNMENT): Modified.
        (FIRST_PSEUDO_REGISTER): Updated to add even registers.
        (FIXED_REGISTERS): Likewise.
        (CALL_USED_REGISTERS): Likewise.
        (CONDITIONAL_REGISTER_USAGE): Updated.
        (HARD_REGNO_MODE_OK): Updated.
        (reg_class): Updated to add even registers.
        (REG_CLASS_NAMES): Likewise.
        (REG_CLASS_CONTENTS): Likewise.
        (REGNO_REG_CLASS): Updated for CC registers.
        (REG_CLASS_FROM_LETTER): Added support for even registers.
        (REGNO_OK_FOR_BASE_P): Updated for CC registers.
        (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, LINK_POINTER_REGNUM,
        ARG_POINTER_REGNUM): Updated.
        (FUNCTION_ARG_ADVANCE): Define.
        (REG_PARM_STACK_SPACE): Update as per the current ABI requirements.
        (OUTGOING_REG_PARM_STACK_SPACE): Remove.
        (EXTRA_CONSTRAINT): Add new constraint 'W' for 23-bit displacement.
        (GO_IF_LEGITIMATE_ADDRESS): Updated.
        (SELECT_CC_MODE): Define.
        (REGISTER_NAMES): Updated to add psw and fcc registers.
        (ADDITIONAL_REGISTER_NAMES): Updated.
        (ASM_OUTPUT_ADDR_DIFF_ELT): Updated to support new targets.
        (JUMP_TABLES_IN_TEXT_SECTION): Updated.
        * config/v850/v850.md (define_constants): Define new constants.
        (type): Update store,bit1,macc,div,fpu and single attributes.
        (cpu): New attribute.
        (cc): Add set_z attribute.
        (unsign23byte_load, sign23byte_load, unsign23hword_load,
        sign23hword_load, 23word_load, 23byte_store, 23hword_store,
        23word_store): New instructions for 23-bit displacement load and
        store.
        (movqi_internal, movhi_internal): Update the attributes.
        (movsi, movsi_internal_v850e): Updated to support v850e2 targets.
        (movsi_internal_v850e, movsi_internal, movsf_internal): Update
        the attributes.
        (v850_tst1): Modified using CC_REGNUM.
        (tstsi): Remove.
        (cmpsi): Modified as define_expand from define_insn.
        (cmpsi_insn, cmpsf, cmpdf): New instructions.
        (addsi3, subsi3, negsi2, divmodsi4, udivmodsi4, divmodhi4,
        udivmodhi4, v850_clr1_1, v850_clr1_2, v850_clr1_3, andsi3,
        v850_set1_1, v850_set1_3, iorsi3, v850_not1_1, v850_not1_3, xorsi3,
        one_cmplsi2): Clobber the CC_REGNUM register.
        (v850_clr1_1, v850_clr1_2, v850_clr1_3, andsi3, v850_set1_1,
        v850_set1_2, v850_set1_3, iorsi3, v850_not1_1, v850_not1_2,
        v850_not1_3, xorsi3, one_cmplsi2): Update the attributes
        accordingly.
        (setf_insn, set_z_insn, set_nz_insn): New instructions for
        v850e2v3 target.
        (movsicc_normal_cc, movsicc_reversed_cc): New instructions.
        (movsicc, movsicc_normal, movsicc_reversed): Add support for V850E2
        targets.
        (sasf_1, sasf_2): Remove.
        (sasf): New instruction.
        (rotlhi3, rotlhi3_8, rotlsi3, rotlsi3_16): Update to support V850E2
        targets. CC_REGNUM register is clobbered and attributes are
        updated.
        (branch_z_normal, branch_z_invert, branch_nz_normal,
        branch_nz_invert): New branch related instructions.
        (jump): Updated the attributes.
        (switch): Update to support new targets. CC_REGNUM register is
        clobbered and attributes are updated.
        (call_internal_short, call_internal_long, call_value_internal_short,
        call_value_internal_long): Updated the attributes.
        (zero_extendhisi2, zero_extendqisi2): CC_REGNUM register is
        clobbered and attributes are updated.
        (extendhisi_insn, extendhisi2, extendqisi_insn, extendqisi2):
        Update to support new targets. CC_REGNUM register is clobbered.
        (ashlsi3_v850e2, lshrsi3_v850e2, ashrsi3_v850e2): New shift
        instructions.
        (lshrsi3, ashrsi3): CC_REGNUM register is clobbered and attributes
        are updated.
        (ffssi2, addsf3, adddf3, subsf3, subdf3, mulsf3, muldf3, divsf3,
        divdf3, minsf3, mindf3, maxsf3, maxdf3, abssf2, absdf2, negsf2,
        negdf2, sqrtsf2, sqrtdf2, truncsfsi2, truncdfsi2, floatsisf2,
        floatsidf2, extendsfdf2, extenddfsf2, recipsf2, recipdf2,
        rsqrtsf2, rsqrtdf2, maddsf4, msubsf4, nmaddsf4, nmsubsf4,
        cmpsf_le_insn, cmpsf_lt_insn, cmpsf_ge_insn, cmpsf_gt_insn,
        cmpsf_eq_insn, cmpsf_ne_insn, cmpdf_le_insn, cmpdf_lt_insn,
        cmpdf_ge_insn, cmpdf_gt_insn, cmpdf_eq_insn, cmpdf_ne_insn, trfsr,
        movsfcc, movdfcc, movsfcc_z_insn, movsfcc_nz_insn, movdfcc_z_insn,
        movdfcc_nz_insn, movedfcc_z_zero, movedfcc_nz_zero): New floating
        point instructions defined for V850e2v3 target.
        (callt_save_interrupt, callt_return_interrupt, return_interrupt):
        Add support for V850E2 targets and CC_REGNUM register is clobbered.
        (callt_save_all_interrupt, callt_restore_all_interrupt): Add
        support for new targets.
        * config/v850/v850-modes.def: New file.
        * config/v850/v850.opt(mstrict-align): Remove.
        (mno-strict-align, mjump-tables-in-data-section, mv850e2,
        mv850e2v3): New command line options for V850.
        * config.gcc: Update the newly added files.
        * doc/invoke.texi: Update the newly added command line options for
        V850 target.

From-SVN: r162530
This commit is contained in:
Naveen.H.S 2010-07-26 09:39:04 +00:00 committed by Nick Clifton
parent 4e89a3faf8
commit 223a9d6445
16 changed files with 2395 additions and 1097 deletions

View File

@ -1,3 +1,8 @@
2010-07-26 Naveen.H.S <naveen.S@kpitcummins.com>
* configure.ac: Support all v850 targets.
* configure: Regenerate.
2010-07-23 Marc Glisse <marc.glisse@normalesup.org> 2010-07-23 Marc Glisse <marc.glisse@normalesup.org>
PR bootstrap/44455 PR bootstrap/44455

8
configure vendored
View File

@ -3730,13 +3730,7 @@ case "${target}" in
v810-*-*) v810-*-*)
noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libstdc++-v3 opcodes target-libgloss ${libgcj}" noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libstdc++-v3 opcodes target-libgloss ${libgcj}"
;; ;;
v850-*-*) v850*-*-*)
noconfigdirs="$noconfigdirs target-libgloss ${libgcj}"
;;
v850e-*-*)
noconfigdirs="$noconfigdirs target-libgloss ${libgcj}"
;;
v850ea-*-*)
noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" noconfigdirs="$noconfigdirs target-libgloss ${libgcj}"
;; ;;
vax-*-vms) vax-*-vms)

View File

@ -967,13 +967,7 @@ case "${target}" in
v810-*-*) v810-*-*)
noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libstdc++-v3 opcodes target-libgloss ${libgcj}" noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libstdc++-v3 opcodes target-libgloss ${libgcj}"
;; ;;
v850-*-*) v850*-*-*)
noconfigdirs="$noconfigdirs target-libgloss ${libgcj}"
;;
v850e-*-*)
noconfigdirs="$noconfigdirs target-libgloss ${libgcj}"
;;
v850ea-*-*)
noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" noconfigdirs="$noconfigdirs target-libgloss ${libgcj}"
;; ;;
vax-*-vms) vax-*-vms)

View File

@ -1,3 +1,147 @@
2010-07-26 Naveen.H.S <naveen.S@kpitcummins.com>
* config/v850/lib1funcs.asm (save_r2_r31, return_r2_r31,
save_r20_r31, return_r20_r31, save_r21_r31, return_r21_r31,
save_r22_r31, return_r22_r31, save_r23_r31, return_r23_r31,
save_r24_r31, return_r24_r31, save_r25_r31, return_r25_r31,
save_r26_r31, return_r26_r31, save_r27_r31, return_r27_r31,
save_r28_r31, return_r28_r31, save_r29_r31, return_r29_r31,
save_r31, return_r31, save_interrupt, return_interrupt,
save_all_interrupt, return_all_interrupt, L_save_r2_r31,
L_return_interrupt, callt_return_interrupt, L_restore_all_interrupt,
L_save_##START##_r31c, L_callt_save_r31c: Updated as per the
new ABI requirements.
save_r6_r9, L_callt_save_r6_r9: Remove.
* config/v850/predicates.md (even_reg_operand, disp23_operand,
const_float_1_operand const_float_0_operand): New Predicates.
(pattern_is_ok_for_prepare, pattern_is_ok_for_prologue,
pattern_is_ok_for_epilogue): Update as per the ABI requirements.
* config/v850/t-v850: Update multilibs for new target variants.
(save_varargs, callt_save_varargs, callt_save_r6_r9): Remove.
* config/v850/t-v850e: Likewise.
* config/v850/v850.c (v850_issue_rate): New.
(v850_strict_argument_naming): New.
(function_arg): Modify to generate a different ABI.
(print_operand): Update case 'z' to support float modes.
(output_move_single): Modify to generate appropriate and better
assembly.
(v850_float_z_comparison_operator, v850_select_cc_mode,
v850_float_nz_comparison_operator, v850_gen_float_compare,
v850_gen_compare): New functions to support comparison of
float values.
(ep_memory_offset): Add support for V850E2 targets.
(INTERRUPT_FIXED_NUM, INTERRUPT_ALL_SAVE_NUM): Update.
(INTERRUPT_REGPARM_NUM): Remove.
(compute_register_save_size): Add extra case to save/restore
long call.
(use_prolog_function): New function to support prologue.
(expand_prologue): Add support for V850E2 targets and modified
as per the current ABI requirements.
(expand_epilogue): Likewise.
(construct_restore_jr): Modify based on TARGET_LONG_CALLS.
(construct_save_jarl): Likewise.
(construct_dispose_instruction): Update as per the current ABI
requirements.
(construct_prepare_instruction): Likewise.
* config/v850/v850.h(TARGET_CPU_DEFAULT): Add target predefines.
(TARGET_CPU_v850e2, TARGET_CPU_v850e2v3): Define
(CPP_SPEC): Updated to support v850e2 targets.
(STRICT_ALIGNMENT): Modified.
(FIRST_PSEUDO_REGISTER): Updated to add even registers.
(FIXED_REGISTERS): Likewise.
(CALL_USED_REGISTERS): Likewise.
(CONDITIONAL_REGISTER_USAGE): Updated.
(HARD_REGNO_MODE_OK): Updated.
(reg_class): Updated to add even registers.
(REG_CLASS_NAMES): Likewise.
(REG_CLASS_CONTENTS): Likewise.
(REGNO_REG_CLASS): Updated for CC registers.
(REG_CLASS_FROM_LETTER): Added support for even registers.
(REGNO_OK_FOR_BASE_P): Updated for CC registers.
(STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, LINK_POINTER_REGNUM,
ARG_POINTER_REGNUM): Updated.
(FUNCTION_ARG_ADVANCE): Define.
(REG_PARM_STACK_SPACE): Update as per the current ABI requirements.
(OUTGOING_REG_PARM_STACK_SPACE): Remove.
(EXTRA_CONSTRAINT): Add new constraint 'W' for 23-bit displacement.
(GO_IF_LEGITIMATE_ADDRESS): Updated.
(SELECT_CC_MODE): Define.
(REGISTER_NAMES): Updated to add psw and fcc registers.
(ADDITIONAL_REGISTER_NAMES): Updated.
(ASM_OUTPUT_ADDR_DIFF_ELT): Updated to support new targets.
(JUMP_TABLES_IN_TEXT_SECTION): Updated.
* config/v850/v850.md (define_constants): Define new constants.
(type): Update store,bit1,macc,div,fpu and single attributes.
(cpu): New attribute.
(cc): Add set_z attribute.
(unsign23byte_load, sign23byte_load, unsign23hword_load,
sign23hword_load, 23word_load, 23byte_store, 23hword_store,
23word_store): New instructions for 23-bit displacement load and
store.
(movqi_internal, movhi_internal): Update the attributes.
(movsi, movsi_internal_v850e): Updated to support v850e2 targets.
(movsi_internal_v850e, movsi_internal, movsf_internal): Update
the attributes.
(v850_tst1): Modified using CC_REGNUM.
(tstsi): Remove.
(cmpsi): Modified as define_expand from define_insn.
(cmpsi_insn, cmpsf, cmpdf): New instructions.
(addsi3, subsi3, negsi2, divmodsi4, udivmodsi4, divmodhi4,
udivmodhi4, v850_clr1_1, v850_clr1_2, v850_clr1_3, andsi3,
v850_set1_1, v850_set1_3, iorsi3, v850_not1_1, v850_not1_3, xorsi3,
one_cmplsi2): Clobber the CC_REGNUM register.
(v850_clr1_1, v850_clr1_2, v850_clr1_3, andsi3, v850_set1_1,
v850_set1_2, v850_set1_3, iorsi3, v850_not1_1, v850_not1_2,
v850_not1_3, xorsi3, one_cmplsi2): Update the attributes
accordingly.
(setf_insn, set_z_insn, set_nz_insn): New instructions for
v850e2v3 target.
(movsicc_normal_cc, movsicc_reversed_cc): New instructions.
(movsicc, movsicc_normal, movsicc_reversed): Add support for V850E2
targets.
(sasf_1, sasf_2): Remove.
(sasf): New instruction.
(rotlhi3, rotlhi3_8, rotlsi3, rotlsi3_16): Update to support V850E2
targets. CC_REGNUM register is clobbered and attributes are
updated.
(branch_z_normal, branch_z_invert, branch_nz_normal,
branch_nz_invert): New branch related instructions.
(jump): Updated the attributes.
(switch): Update to support new targets. CC_REGNUM register is
clobbered and attributes are updated.
(call_internal_short, call_internal_long, call_value_internal_short,
call_value_internal_long): Updated the attributes.
(zero_extendhisi2, zero_extendqisi2): CC_REGNUM register is
clobbered and attributes are updated.
(extendhisi_insn, extendhisi2, extendqisi_insn, extendqisi2):
Update to support new targets. CC_REGNUM register is clobbered.
(ashlsi3_v850e2, lshrsi3_v850e2, ashrsi3_v850e2): New shift
instructions.
(lshrsi3, ashrsi3): CC_REGNUM register is clobbered and attributes
are updated.
(ffssi2, addsf3, adddf3, subsf3, subdf3, mulsf3, muldf3, divsf3,
divdf3, minsf3, mindf3, maxsf3, maxdf3, abssf2, absdf2, negsf2,
negdf2, sqrtsf2, sqrtdf2, truncsfsi2, truncdfsi2, floatsisf2,
floatsidf2, extendsfdf2, extenddfsf2, recipsf2, recipdf2,
rsqrtsf2, rsqrtdf2, maddsf4, msubsf4, nmaddsf4, nmsubsf4,
cmpsf_le_insn, cmpsf_lt_insn, cmpsf_ge_insn, cmpsf_gt_insn,
cmpsf_eq_insn, cmpsf_ne_insn, cmpdf_le_insn, cmpdf_lt_insn,
cmpdf_ge_insn, cmpdf_gt_insn, cmpdf_eq_insn, cmpdf_ne_insn, trfsr,
movsfcc, movdfcc, movsfcc_z_insn, movsfcc_nz_insn, movdfcc_z_insn,
movdfcc_nz_insn, movedfcc_z_zero, movedfcc_nz_zero): New floating
point instructions defined for V850e2v3 target.
(callt_save_interrupt, callt_return_interrupt, return_interrupt):
Add support for V850E2 targets and CC_REGNUM register is clobbered.
(callt_save_all_interrupt, callt_restore_all_interrupt): Add
support for new targets.
* config/v850/v850-modes.def: New file.
* config/v850/v850.opt(mstrict-align): Remove.
(mno-strict-align, mjump-tables-in-data-section, mv850e2,
mv850e2v3): New command line options for V850.
* config.gcc: Update the newly added files.
* doc/invoke.texi: Update the newly added command line options for
V850 target.
2010-07-26 Richard Guenther <rguenther@suse.de> 2010-07-26 Richard Guenther <rguenther@suse.de>
PR tree-optimization/45052 PR tree-optimization/45052

View File

@ -2517,6 +2517,7 @@ v850e1-*-*)
tm_p_file=v850/v850-protos.h tm_p_file=v850/v850-protos.h
tmake_file=v850/t-v850e tmake_file=v850/t-v850e
md_file=v850/v850.md md_file=v850/v850.md
extra_modes=v850/v850-modes.def
out_file=v850/v850.c out_file=v850/v850.c
extra_options="${extra_options} v850/v850.opt" extra_options="${extra_options} v850/v850.opt"
if test x$stabs = xyes if test x$stabs = xyes
@ -2534,6 +2535,7 @@ v850e-*-*)
tm_p_file=v850/v850-protos.h tm_p_file=v850/v850-protos.h
tmake_file=v850/t-v850e tmake_file=v850/t-v850e
md_file=v850/v850.md md_file=v850/v850.md
extra_modes=v850/v850-modes.def
out_file=v850/v850.c out_file=v850/v850.c
extra_options="${extra_options} v850/v850.opt" extra_options="${extra_options} v850/v850.opt"
if test x$stabs = xyes if test x$stabs = xyes

File diff suppressed because it is too large Load Diff

View File

@ -68,6 +68,17 @@
return register_operand (op, mode); return register_operand (op, mode);
}) })
;; Return true if OP is a even number register.
(define_predicate "even_reg_operand"
(match_code "reg")
{
return (GET_CODE (op) == REG
&& (REGNO (op) >= FIRST_PSEUDO_REGISTER
|| ((REGNO (op) > 0) && (REGNO (op) < 32)
&& ((REGNO (op) & 1)==0))));
})
;; Return true if OP is a valid call operand. ;; Return true if OP is a valid call operand.
(define_predicate "call_address_operand" (define_predicate "call_address_operand"
@ -79,7 +90,7 @@
return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG); return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);
}) })
;; TODO: Add a comment here. ;; Return true if OP is a valid source operand for SImode move.
(define_predicate "movsi_source_operand" (define_predicate "movsi_source_operand"
(match_code "label_ref,symbol_ref,const_int,const_double,const,high,mem,reg,subreg") (match_code "label_ref,symbol_ref,const_int,const_double,const,high,mem,reg,subreg")
@ -97,7 +108,21 @@
return general_operand (op, mode); return general_operand (op, mode);
}) })
;; TODO: Add a comment here. ;; Return true if OP is a valid operand for 23 bit displacement
;; operations.
(define_predicate "disp23_operand"
(match_code "const_int")
{
if (GET_CODE (op) == CONST_INT
&& ((unsigned)(INTVAL (op)) >= 0x8000)
&& ((unsigned)(INTVAL (op)) < 0x400000))
return 1;
else
return 0;
})
;; Return true if OP is a symbol ref with 16-bit signed value.
(define_predicate "special_symbolref_operand" (define_predicate "special_symbolref_operand"
(match_code "symbol_ref") (match_code "symbol_ref")
@ -115,7 +140,8 @@
return FALSE; return FALSE;
}) })
;; TODO: Add a comment here. ;; Return true if OP is a valid operand for bit related operations
;; containing only single 1 in its binary representation.
(define_predicate "power_of_two_operand" (define_predicate "power_of_two_operand"
(match_code "const_int") (match_code "const_int")
@ -140,7 +166,7 @@
/* If there are no registers to save then the function prologue /* If there are no registers to save then the function prologue
is not suitable. */ is not suitable. */
if (count <= 2) if (count <= (TARGET_LONG_CALLS ? 3 : 2))
return 0; return 0;
/* The pattern matching has already established that we are adjusting the /* The pattern matching has already established that we are adjusting the
@ -198,18 +224,24 @@
} }
/* Make sure that the last entries in the vector are clobbers. */ /* Make sure that the last entries in the vector are clobbers. */
for (; i < count; i++) vector_element = XVECEXP (op, 0, i++);
if (GET_CODE (vector_element) != CLOBBER
|| GET_CODE (XEXP (vector_element, 0)) != REG
|| REGNO (XEXP (vector_element, 0)) != 10)
return 0;
if (TARGET_LONG_CALLS)
{ {
vector_element = XVECEXP (op, 0, i); vector_element = XVECEXP (op, 0, i++);
if (GET_CODE (vector_element) != CLOBBER if (GET_CODE (vector_element) != CLOBBER
|| GET_CODE (XEXP (vector_element, 0)) != REG || GET_CODE (XEXP (vector_element, 0)) != REG
|| !(REGNO (XEXP (vector_element, 0)) == 10 || REGNO (XEXP (vector_element, 0)) != 11)
|| (TARGET_LONG_CALLS ? (REGNO (XEXP (vector_element, 0)) == 11) : 0 )))
return 0; return 0;
} }
return 1; return i == count;
}) })
;; Return nonzero if the given RTX is suitable for collapsing into ;; Return nonzero if the given RTX is suitable for collapsing into
@ -239,7 +271,7 @@
(mem:SI (plus:SI (reg:SI 3) (match_operand:SI n "immediate_operand" "i")))) (mem:SI (plus:SI (reg:SI 3) (match_operand:SI n "immediate_operand" "i"))))
*/ */
for (i = 3; i < count; i++) for (i = 2; i < count; i++)
{ {
rtx vector_element = XVECEXP (op, 0, i); rtx vector_element = XVECEXP (op, 0, i);
rtx dest; rtx dest;
@ -372,13 +404,16 @@
*/ */
for (i = 2; i < count; i++) for (i = 1; i < count; i++)
{ {
rtx vector_element = XVECEXP (op, 0, i); rtx vector_element = XVECEXP (op, 0, i);
rtx dest; rtx dest;
rtx src; rtx src;
rtx plus; rtx plus;
if (GET_CODE (vector_element) == CLOBBER)
continue;
if (GET_CODE (vector_element) != SET) if (GET_CODE (vector_element) != SET)
return 0; return 0;
@ -406,14 +441,15 @@
space just acquired by the first operand then abandon this quest. space just acquired by the first operand then abandon this quest.
Note: the test is <= because both values are negative. */ Note: the test is <= because both values are negative. */
if (INTVAL (XEXP (plus, 1)) if (INTVAL (XEXP (plus, 1))
<= INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1))) < INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)))
return 0; return 0;
} }
return 1; return 1;
}) })
;; TODO: Add a comment here. ;; Return true if OP is a valid operand for bit related operations
;; containing only single 0 in its binary representation.
(define_predicate "not_power_of_two_operand" (define_predicate "not_power_of_two_operand"
(match_code "const_int") (match_code "const_int")
@ -436,3 +472,31 @@
return 0; return 0;
return 1; return 1;
}) })
;; Return true if OP is a float value operand with value as 1.
(define_predicate "const_float_1_operand"
(match_code "const_int")
{
if (GET_CODE (op) != CONST_DOUBLE
|| mode != GET_MODE (op)
|| (mode != DFmode && mode != SFmode))
return 0;
return op == CONST1_RTX(mode);
})
;; Return true if OP is a float value operand with value as 0.
(define_predicate "const_float_0_operand"
(match_code "const_int")
{
if (GET_CODE (op) != CONST_DOUBLE
|| mode != GET_MODE (op)
|| (mode != DFmode && mode != SFmode))
return 0;
return op == CONST0_RTX(mode);
})

View File

@ -46,7 +46,6 @@ LIB1ASMFUNCS = _mulsi3 \
_save_28c \ _save_28c \
_save_29c \ _save_29c \
_save_31c \ _save_31c \
_save_varargs \
_save_interrupt \ _save_interrupt \
_save_all_interrupt \ _save_all_interrupt \
_callt_save_20 \ _callt_save_20 \
@ -70,12 +69,10 @@ LIB1ASMFUNCS = _mulsi3 \
_callt_save_28c \ _callt_save_28c \
_callt_save_29c \ _callt_save_29c \
_callt_save_31c \ _callt_save_31c \
_callt_save_varargs \
_callt_save_interrupt \ _callt_save_interrupt \
_callt_save_all_interrupt \ _callt_save_all_interrupt \
_callt_save_r2_r29 \ _callt_save_r2_r29 \
_callt_save_r2_r31 \ _callt_save_r2_r31 \
_callt_save_r6_r9 \
_negdi2 \ _negdi2 \
_cmpdi2 \ _cmpdi2 \
_ucmpdi2 \ _ucmpdi2 \
@ -100,10 +97,10 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c cat $(srcdir)/config/fp-bit.c >> fp-bit.c
# Create target-specific versions of the libraries # Create target-specific versions of the libraries
MULTILIB_OPTIONS = mv850e MULTILIB_OPTIONS = mv850/mv850e/mv850e2/mv850e2v3
MULTILIB_DIRNAMES = v850e MULTILIB_DIRNAMES = v850 v850e v850e2 v850e2v3
INSTALL_LIBGCC = install-multilib INSTALL_LIBGCC = install-multilib
MULTILIB_MATCHES = mv850e=mv850e1 MULTILIB_MATCHES = mv850e=mv850e1
TCFLAGS = -mno-app-regs -msmall-sld -Wa,-mwarn-signed-overflow -Wa,-mwarn-unsigned-overflow TCFLAGS = -mno-app-regs -msmall-sld -Wa,-mwarn-signed-overflow -Wa,-mwarn-unsigned-overflow

View File

@ -45,7 +45,6 @@ LIB1ASMFUNCS = _mulsi3 \
_save_28c \ _save_28c \
_save_29c \ _save_29c \
_save_31c \ _save_31c \
_save_varargs \
_save_interrupt \ _save_interrupt \
_save_all_interrupt \ _save_all_interrupt \
_callt_save_20 \ _callt_save_20 \
@ -69,12 +68,10 @@ LIB1ASMFUNCS = _mulsi3 \
_callt_save_28c \ _callt_save_28c \
_callt_save_29c \ _callt_save_29c \
_callt_save_31c \ _callt_save_31c \
_callt_save_varargs \
_callt_save_interrupt \ _callt_save_interrupt \
_callt_save_all_interrupt \ _callt_save_all_interrupt \
_callt_save_r2_r29 \ _callt_save_r2_r29 \
_callt_save_r2_r31 \ _callt_save_r2_r31 \
_callt_save_r6_r9 \
_negdi2 \ _negdi2 \
_cmpdi2 \ _cmpdi2 \
_ucmpdi2 \ _ucmpdi2 \

View File

@ -0,0 +1,29 @@
/* Definitions of target machine for GNU compiler. NEC V850 series
Copyright (C) 2005
Free Software Foundation, Inc.
Contributed by NEC EL
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
CC_MODE (CC_FPU_LT);
CC_MODE (CC_FPU_LE);
CC_MODE (CC_FPU_GT);
CC_MODE (CC_FPU_GE);
CC_MODE (CC_FPU_EQ);
CC_MODE (CC_FPU_NE);

View File

@ -43,6 +43,11 @@ extern char * construct_restore_jr (rtx);
extern char * construct_dispose_instruction (rtx); extern char * construct_dispose_instruction (rtx);
extern char * construct_prepare_instruction (rtx); extern char * construct_prepare_instruction (rtx);
extern int ep_memory_operand (rtx, Mmode, int); extern int ep_memory_operand (rtx, Mmode, int);
extern int v850_float_z_comparison_operator (rtx, Mmode);
extern int v850_float_nz_comparison_operator (rtx, Mmode);
extern rtx v850_gen_compare (enum rtx_code, Mmode, rtx, rtx);
extern Mmode v850_gen_float_compare (enum rtx_code, Mmode, rtx, rtx);
extern Mmode v850_select_cc_mode (RTX_CODE, rtx, rtx);
#ifdef TREE_CODE #ifdef TREE_CODE
extern rtx function_arg (CUMULATIVE_ARGS *, Mmode, tree, int); extern rtx function_arg (CUMULATIVE_ARGS *, Mmode, tree, int);
#endif #endif

View File

@ -65,6 +65,7 @@ static void v850_asm_init_sections (void);
static section *v850_select_section (tree, int, unsigned HOST_WIDE_INT); static section *v850_select_section (tree, int, unsigned HOST_WIDE_INT);
static void v850_encode_data_area (tree, rtx); static void v850_encode_data_area (tree, rtx);
static void v850_encode_section_info (tree, rtx, int); static void v850_encode_section_info (tree, rtx, int);
static int v850_issue_rate (void);
static bool v850_return_in_memory (const_tree, const_tree); static bool v850_return_in_memory (const_tree, const_tree);
static rtx v850_function_value (const_tree, const_tree, bool); static rtx v850_function_value (const_tree, const_tree, bool);
static void v850_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, static void v850_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
@ -73,6 +74,7 @@ static bool v850_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
const_tree, bool); const_tree, bool);
static int v850_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, static int v850_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool); tree, bool);
static bool v850_strict_argument_naming (CUMULATIVE_ARGS *);
static bool v850_can_eliminate (const int, const int); static bool v850_can_eliminate (const int, const int);
static void v850_asm_trampoline_template (FILE *); static void v850_asm_trampoline_template (FILE *);
static void v850_trampoline_init (rtx, tree, rtx); static void v850_trampoline_init (rtx, tree, rtx);
@ -101,6 +103,8 @@ data_area_stack_element * data_area_stack = NULL;
function is an interrupt handler. */ function is an interrupt handler. */
static int v850_interrupt_cache_p = FALSE; static int v850_interrupt_cache_p = FALSE;
rtx v850_compare_op0, v850_compare_op1;
/* Whether current function is an interrupt handler. */ /* Whether current function is an interrupt handler. */
static int v850_interrupt_p = FALSE; static int v850_interrupt_p = FALSE;
@ -169,6 +173,9 @@ static const struct attribute_spec v850_attribute_table[] =
#undef TARGET_MACHINE_DEPENDENT_REORG #undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG v850_reorg #define TARGET_MACHINE_DEPENDENT_REORG v850_reorg
#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE v850_issue_rate
#undef TARGET_PROMOTE_PROTOTYPES #undef TARGET_PROMOTE_PROTOTYPES
#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
@ -198,6 +205,9 @@ static const struct attribute_spec v850_attribute_table[] =
#undef TARGET_TRAMPOLINE_INIT #undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT v850_trampoline_init #define TARGET_TRAMPOLINE_INIT v850_trampoline_init
#undef TARGET_STRICT_ARGUMENT_NAMING
#define TARGET_STRICT_ARGUMENT_NAMING v850_strict_argument_naming
struct gcc_target targetm = TARGET_INITIALIZER; struct gcc_target targetm = TARGET_INITIALIZER;
/* Set the maximum size of small memory area TYPE to the value given /* Set the maximum size of small memory area TYPE to the value given
@ -258,7 +268,10 @@ v850_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
return true; return true;
} }
} }
/* Handle the TARGET_PASS_BY_REFERENCE target hook.
Specify whether to pass the argument by reference. */
static bool static bool
v850_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, v850_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
enum machine_mode mode, const_tree type, enum machine_mode mode, const_tree type,
@ -274,6 +287,14 @@ v850_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
return size > 8; return size > 8;
} }
/* Implementing the Varargs Macros. */
static bool
v850_strict_argument_naming (CUMULATIVE_ARGS * ca ATTRIBUTE_UNUSED)
{
return !TARGET_GHS ? true : false;
}
/* Return an RTX to represent where an argument with mode MODE /* Return an RTX to represent where an argument with mode MODE
and type TYPE will be passed to a function. If the result and type TYPE will be passed to a function. If the result
is NULL_RTX, the argument will be pushed. */ is NULL_RTX, the argument will be pushed. */
@ -287,7 +308,7 @@ function_arg (CUMULATIVE_ARGS * cum,
rtx result = NULL_RTX; rtx result = NULL_RTX;
int size, align; int size, align;
if (TARGET_GHS && !named) if (!named)
return NULL_RTX; return NULL_RTX;
if (mode == BLKmode) if (mode == BLKmode)
@ -295,6 +316,8 @@ function_arg (CUMULATIVE_ARGS * cum,
else else
size = GET_MODE_SIZE (mode); size = GET_MODE_SIZE (mode);
size = (size + UNITS_PER_WORD -1) & ~(UNITS_PER_WORD -1);
if (size < 1) if (size < 1)
{ {
/* Once we have stopped using argument registers, do not start up again. */ /* Once we have stopped using argument registers, do not start up again. */
@ -302,7 +325,7 @@ function_arg (CUMULATIVE_ARGS * cum,
return NULL_RTX; return NULL_RTX;
} }
if (type) if (size <= UNITS_PER_WORD && type)
align = TYPE_ALIGN (type) / BITS_PER_UNIT; align = TYPE_ALIGN (type) / BITS_PER_UNIT;
else else
align = size; align = size;
@ -337,10 +360,8 @@ function_arg (CUMULATIVE_ARGS * cum,
return result; return result;
} }
/* Return the number of bytes which must be put into registers /* Return the number of bytes which must be put into registers
for values which are part in registers and part in memory. */ for values which are part in registers and part in memory. */
static int static int
v850_arg_partial_bytes (CUMULATIVE_ARGS * cum, enum machine_mode mode, v850_arg_partial_bytes (CUMULATIVE_ARGS * cum, enum machine_mode mode,
tree type, bool named) tree type, bool named)
@ -378,7 +399,6 @@ v850_arg_partial_bytes (CUMULATIVE_ARGS * cum, enum machine_mode mode,
return 4 * UNITS_PER_WORD - cum->nbytes; return 4 * UNITS_PER_WORD - cum->nbytes;
} }
/* Return the high and low words of a CONST_DOUBLE */ /* Return the high and low words of a CONST_DOUBLE */
static void static void
@ -713,6 +733,11 @@ v850_print_operand (FILE * file, rtx x, int code)
case 'z': /* reg or zero */ case 'z': /* reg or zero */
if (GET_CODE (x) == REG) if (GET_CODE (x) == REG)
fputs (reg_names[REGNO (x)], file); fputs (reg_names[REGNO (x)], file);
else if ((GET_MODE(x) == SImode
|| GET_MODE(x) == DFmode
|| GET_MODE(x) == SFmode)
&& x == CONST0_RTX(GET_MODE(x)))
fputs (reg_names[0], file);
else else
{ {
gcc_assert (x == const0_rtx); gcc_assert (x == const0_rtx);
@ -917,13 +942,13 @@ output_move_single (rtx * operands)
return "mov %1,%0"; return "mov %1,%0";
else if (CONST_OK_FOR_K (value)) /* Signed 16-bit immediate. */ else if (CONST_OK_FOR_K (value)) /* Signed 16-bit immediate. */
return "movea lo(%1),%.,%0"; return "movea %1,%.,%0";
else if (CONST_OK_FOR_L (value)) /* Upper 16 bits were set. */ else if (CONST_OK_FOR_L (value)) /* Upper 16 bits were set. */
return "movhi hi(%1),%.,%0"; return "movhi hi0(%1),%.,%0";
/* A random constant. */ /* A random constant. */
else if (TARGET_V850E) else if (TARGET_V850E || TARGET_V850E2_ALL)
return "mov %1,%0"; return "mov %1,%0";
else else
return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0"; return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0";
@ -939,13 +964,13 @@ output_move_single (rtx * operands)
return "mov %F1,%0"; return "mov %F1,%0";
else if (CONST_OK_FOR_K (high)) /* Signed 16-bit immediate. */ else if (CONST_OK_FOR_K (high)) /* Signed 16-bit immediate. */
return "movea lo(%F1),%.,%0"; return "movea %F1,%.,%0";
else if (CONST_OK_FOR_L (high)) /* Upper 16 bits were set. */ else if (CONST_OK_FOR_L (high)) /* Upper 16 bits were set. */
return "movhi hi(%F1),%.,%0"; return "movhi hi0(%F1),%.,%0";
/* A random constant. */ /* A random constant. */
else if (TARGET_V850E) else if (TARGET_V850E || TARGET_V850E2_ALL)
return "mov %F1,%0"; return "mov %F1,%0";
else else
@ -962,7 +987,7 @@ output_move_single (rtx * operands)
|| GET_CODE (src) == SYMBOL_REF || GET_CODE (src) == SYMBOL_REF
|| GET_CODE (src) == CONST) || GET_CODE (src) == CONST)
{ {
if (TARGET_V850E) if (TARGET_V850E || TARGET_V850E2_ALL)
return "mov hilo(%1),%0"; return "mov hilo(%1),%0";
else else
return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0"; return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0";
@ -996,7 +1021,169 @@ output_move_single (rtx * operands)
return ""; return "";
} }
/* Generate comparison code. */
int
v850_float_z_comparison_operator (rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
if (GET_RTX_CLASS (code) != RTX_COMPARE
&& GET_RTX_CLASS (code) != RTX_COMM_COMPARE)
return 0;
if (mode != GET_MODE (op) && mode != VOIDmode)
return 0;
if ((GET_CODE (XEXP (op, 0)) != REG
|| REGNO (XEXP (op, 0)) != CC_REGNUM)
|| XEXP (op, 1) != const0_rtx)
return 0;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_LTmode)
return code == LT;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_LEmode)
return code == LE;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_EQmode)
return code == EQ;
return 0;
}
int
v850_float_nz_comparison_operator (rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
if (GET_RTX_CLASS (code) != RTX_COMPARE
&& GET_RTX_CLASS (code) != RTX_COMM_COMPARE)
return 0;
if (mode != GET_MODE (op) && mode != VOIDmode)
return 0;
if ((GET_CODE (XEXP (op, 0)) != REG
|| REGNO (XEXP (op, 0)) != CC_REGNUM)
|| XEXP (op, 1) != const0_rtx)
return 0;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_GTmode)
return code == GT;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_GEmode)
return code == GE;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_NEmode)
return code == NE;
return 0;
}
enum machine_mode
v850_select_cc_mode (enum rtx_code cond, rtx op0, rtx op1)
{
if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
{
switch (cond)
{
case LE:
return CC_FPU_LEmode;
case GE:
return CC_FPU_GEmode;
case LT:
return CC_FPU_LTmode;
case GT:
return CC_FPU_GTmode;
case EQ:
return CC_FPU_EQmode;
case NE:
return CC_FPU_NEmode;
default:
abort ();
}
}
return CCmode;
}
enum machine_mode
v850_gen_float_compare (enum rtx_code cond, enum machine_mode mode ATTRIBUTE_UNUSED, rtx op0, rtx op1)
{
if (GET_MODE(op0) == DFmode)
{
switch (cond)
{
case LE:
emit_insn (gen_cmpdf_le_insn (op0, op1));
break;
case GE:
emit_insn (gen_cmpdf_ge_insn (op0, op1));
break;
case LT:
emit_insn (gen_cmpdf_lt_insn (op0, op1));
break;
case GT:
emit_insn (gen_cmpdf_gt_insn (op0, op1));
break;
case EQ:
emit_insn (gen_cmpdf_eq_insn (op0, op1));
break;
case NE:
emit_insn (gen_cmpdf_ne_insn (op0, op1));
break;
default:
abort ();
}
}
else if (GET_MODE(v850_compare_op0) == SFmode)
{
switch (cond)
{
case LE:
emit_insn (gen_cmpsf_le_insn(op0, op1));
break;
case GE:
emit_insn (gen_cmpsf_ge_insn(op0, op1));
break;
case LT:
emit_insn (gen_cmpsf_lt_insn(op0, op1));
break;
case GT:
emit_insn (gen_cmpsf_gt_insn(op0, op1));
break;
case EQ:
emit_insn (gen_cmpsf_eq_insn(op0, op1));
break;
case NE:
emit_insn (gen_cmpsf_ne_insn(op0, op1));
break;
default:
abort ();
}
}
else
{
abort ();
}
return v850_select_cc_mode (cond, op0, op1);
}
rtx
v850_gen_compare (enum rtx_code cond, enum machine_mode mode, rtx op0, rtx op1)
{
if (GET_MODE_CLASS(GET_MODE (op0)) != MODE_FLOAT)
{
emit_insn (gen_cmpsi_insn (op0, op1));
return gen_rtx_fmt_ee (cond, mode, gen_rtx_REG(CCmode, CC_REGNUM), const0_rtx);
}
else
{
rtx cc_reg;
mode = v850_gen_float_compare (cond, mode, op0, op1);
cc_reg = gen_rtx_REG (mode, CC_REGNUM);
emit_insn (gen_rtx_SET(mode, cc_reg, gen_rtx_REG (mode, FCC_REGNUM)));
return gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
}
}
/* Return maximum offset supported for a short EP memory reference of mode /* Return maximum offset supported for a short EP memory reference of mode
MODE and signedness UNSIGNEDP. */ MODE and signedness UNSIGNEDP. */
@ -1010,9 +1197,8 @@ ep_memory_offset (enum machine_mode mode, int unsignedp ATTRIBUTE_UNUSED)
case QImode: case QImode:
if (TARGET_SMALL_SLD) if (TARGET_SMALL_SLD)
max_offset = (1 << 4); max_offset = (1 << 4);
else if (TARGET_V850E else if ((TARGET_V850E || TARGET_V850E2_ALL)
&& ( ( unsignedp && ! TARGET_US_BIT_SET) && unsignedp)
|| (! unsignedp && TARGET_US_BIT_SET)))
max_offset = (1 << 4); max_offset = (1 << 4);
else else
max_offset = (1 << 7); max_offset = (1 << 7);
@ -1021,9 +1207,8 @@ ep_memory_offset (enum machine_mode mode, int unsignedp ATTRIBUTE_UNUSED)
case HImode: case HImode:
if (TARGET_SMALL_SLD) if (TARGET_SMALL_SLD)
max_offset = (1 << 5); max_offset = (1 << 5);
else if (TARGET_V850E else if ((TARGET_V850E || TARGET_V850E2_ALL)
&& ( ( unsignedp && ! TARGET_US_BIT_SET) && unsignedp)
|| (! unsignedp && TARGET_US_BIT_SET)))
max_offset = (1 << 5); max_offset = (1 << 5);
else else
max_offset = (1 << 8); max_offset = (1 << 8);
@ -1420,18 +1605,15 @@ v850_reorg (void)
} }
} }
/* # of registers saved by the interrupt handler. */ /* # of registers saved by the interrupt handler. */
#define INTERRUPT_FIXED_NUM 4 #define INTERRUPT_FIXED_NUM 5
/* # of bytes for registers saved by the interrupt handler. */ /* # of bytes for registers saved by the interrupt handler. */
#define INTERRUPT_FIXED_SAVE_SIZE (4 * INTERRUPT_FIXED_NUM) #define INTERRUPT_FIXED_SAVE_SIZE (4 * INTERRUPT_FIXED_NUM)
/* # of registers saved in register parameter area. */
#define INTERRUPT_REGPARM_NUM 4
/* # of words saved for other registers. */ /* # of words saved for other registers. */
#define INTERRUPT_ALL_SAVE_NUM \ #define INTERRUPT_ALL_SAVE_NUM \
(30 - INTERRUPT_FIXED_NUM + INTERRUPT_REGPARM_NUM) (30 - INTERRUPT_FIXED_NUM)
#define INTERRUPT_ALL_SAVE_SIZE (4 * INTERRUPT_ALL_SAVE_NUM) #define INTERRUPT_ALL_SAVE_SIZE (4 * INTERRUPT_ALL_SAVE_NUM)
@ -1477,6 +1659,7 @@ compute_register_save_size (long * p_reg_saved)
case 1: /* temp used to hold ep */ case 1: /* temp used to hold ep */
case 4: /* gp */ case 4: /* gp */
case 10: /* temp used to call interrupt save/restore */ case 10: /* temp used to call interrupt save/restore */
case 11: /* temp used to call interrupt save/restore (long call) */
case EP_REGNUM: /* ep */ case EP_REGNUM: /* ep */
size += 4; size += 4;
break; break;
@ -1550,19 +1733,50 @@ compute_frame_size (int size, long * p_reg_saved)
+ crtl->outgoing_args_size); + crtl->outgoing_args_size);
} }
static int
use_prolog_function (int num_save, int frame_size)
{
int alloc_stack = (4 * num_save);
int unalloc_stack = frame_size - alloc_stack;
int save_func_len, restore_func_len;
int save_normal_len, restore_normal_len;
if (! TARGET_DISABLE_CALLT)
save_func_len = restore_func_len = 2;
else
save_func_len = restore_func_len = TARGET_LONG_CALLS ? (4+4+4+2+2) : 4;
if (unalloc_stack)
{
save_func_len += CONST_OK_FOR_J (-unalloc_stack) ? 2 : 4;
restore_func_len += CONST_OK_FOR_J (-unalloc_stack) ? 2 : 4;
}
/* See if we would have used ep to save the stack. */
if (TARGET_EP && num_save > 3 && (unsigned)frame_size < 255)
save_normal_len = restore_normal_len = (3 * 2) + (2 * num_save);
else
save_normal_len = restore_normal_len = 4 * num_save;
save_normal_len += CONST_OK_FOR_J (-frame_size) ? 2 : 4;
restore_normal_len += (CONST_OK_FOR_J (frame_size) ? 2 : 4) + 2;
/* Don't bother checking if we don't actually save any space.
This happens for instance if one register is saved and additional
stack space is allocated. */
return ((save_func_len + restore_func_len) < (save_normal_len + restore_normal_len));
}
void void
expand_prologue (void) expand_prologue (void)
{ {
unsigned int i; unsigned int i;
int offset;
unsigned int size = get_frame_size (); unsigned int size = get_frame_size ();
unsigned int actual_fsize; unsigned int actual_fsize;
unsigned int init_stack_alloc = 0; unsigned int init_stack_alloc = 0;
rtx save_regs[32]; rtx save_regs[32];
rtx save_all; rtx save_all;
unsigned int num_save; unsigned int num_save;
unsigned int default_stack;
int code; int code;
int interrupt_handler = v850_interrupt_function_p (current_function_decl); int interrupt_handler = v850_interrupt_function_p (current_function_decl);
long reg_saved = 0; long reg_saved = 0;
@ -1572,7 +1786,7 @@ expand_prologue (void)
/* Save/setup global registers for interrupt functions right now. */ /* Save/setup global registers for interrupt functions right now. */
if (interrupt_handler) if (interrupt_handler)
{ {
if (TARGET_V850E && ! TARGET_DISABLE_CALLT) if (! TARGET_DISABLE_CALLT)
emit_insn (gen_callt_save_interrupt ()); emit_insn (gen_callt_save_interrupt ());
else else
emit_insn (gen_save_interrupt ()); emit_insn (gen_save_interrupt ());
@ -1583,93 +1797,48 @@ expand_prologue (void)
actual_fsize -= INTERRUPT_ALL_SAVE_SIZE; actual_fsize -= INTERRUPT_ALL_SAVE_SIZE;
} }
/* Save arg registers to the stack if necessary. */
else if (crtl->args.info.anonymous_args)
{
if (TARGET_PROLOG_FUNCTION && TARGET_V850E && !TARGET_DISABLE_CALLT)
emit_insn (gen_save_r6_r9_v850e ());
else if (TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS)
emit_insn (gen_save_r6_r9 ());
else
{
offset = 0;
for (i = 6; i < 10; i++)
{
emit_move_insn (gen_rtx_MEM (SImode,
plus_constant (stack_pointer_rtx,
offset)),
gen_rtx_REG (SImode, i));
offset += 4;
}
}
}
/* Identify all of the saved registers. */ /* Identify all of the saved registers. */
num_save = 0; num_save = 0;
default_stack = 0; for (i = 1; i < 32; i++)
for (i = 1; i < 31; i++)
{ {
if (((1L << i) & reg_saved) != 0) if (((1L << i) & reg_saved) != 0)
save_regs[num_save++] = gen_rtx_REG (Pmode, i); save_regs[num_save++] = gen_rtx_REG (Pmode, i);
} }
/* If the return pointer is saved, the helper functions also allocate
16 bytes of stack for arguments to be saved in. */
if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
{
save_regs[num_save++] = gen_rtx_REG (Pmode, LINK_POINTER_REGNUM);
default_stack = 16;
}
/* See if we have an insn that allocates stack space and saves the particular /* See if we have an insn that allocates stack space and saves the particular
registers we want to. */ registers we want to. */
save_all = NULL_RTX; save_all = NULL_RTX;
if (TARGET_PROLOG_FUNCTION && num_save > 0 && actual_fsize >= default_stack) if (TARGET_PROLOG_FUNCTION && num_save > 0)
{ {
int alloc_stack = (4 * num_save) + default_stack; if (use_prolog_function (num_save, actual_fsize))
int unalloc_stack = actual_fsize - alloc_stack;
int save_func_len = 4;
int save_normal_len;
if (unalloc_stack)
save_func_len += CONST_OK_FOR_J (unalloc_stack) ? 2 : 4;
/* see if we would have used ep to save the stack */
if (TARGET_EP && num_save > 3 && (unsigned)actual_fsize < 255)
save_normal_len = (3 * 2) + (2 * num_save);
else
save_normal_len = 4 * num_save;
save_normal_len += CONST_OK_FOR_J (actual_fsize) ? 2 : 4;
/* Don't bother checking if we don't actually save any space.
This happens for instance if one register is saved and additional
stack space is allocated. */
if (save_func_len < save_normal_len)
{ {
int alloc_stack = 4 * num_save;
int offset = 0;
save_all = gen_rtx_PARALLEL save_all = gen_rtx_PARALLEL
(VOIDmode, (VOIDmode,
rtvec_alloc (num_save + 1 rtvec_alloc (num_save + 1
+ (TARGET_V850 ? (TARGET_LONG_CALLS ? 2 : 1) : 0))); + (TARGET_DISABLE_CALLT ? (TARGET_LONG_CALLS ? 2 : 1) : 0)));
XVECEXP (save_all, 0, 0) XVECEXP (save_all, 0, 0)
= gen_rtx_SET (VOIDmode, = gen_rtx_SET (VOIDmode,
stack_pointer_rtx, stack_pointer_rtx,
plus_constant (stack_pointer_rtx, -alloc_stack)); gen_rtx_PLUS (Pmode,
stack_pointer_rtx,
offset = - default_stack; GEN_INT(-alloc_stack)));
for (i = 0; i < num_save; i++) for (i = 0; i < num_save; i++)
{ {
offset -= 4;
XVECEXP (save_all, 0, i+1) XVECEXP (save_all, 0, i+1)
= gen_rtx_SET (VOIDmode, = gen_rtx_SET (VOIDmode,
gen_rtx_MEM (Pmode, gen_rtx_MEM (Pmode,
plus_constant (stack_pointer_rtx, gen_rtx_PLUS (Pmode,
offset)), stack_pointer_rtx,
GEN_INT(offset))),
save_regs[i]); save_regs[i]);
offset -= 4;
} }
if (TARGET_V850) if (TARGET_DISABLE_CALLT)
{ {
XVECEXP (save_all, 0, num_save + 1) XVECEXP (save_all, 0, num_save + 1)
= gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 10)); = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 10));
@ -1686,12 +1855,6 @@ expand_prologue (void)
INSN_CODE (insn) = code; INSN_CODE (insn) = code;
actual_fsize -= alloc_stack; actual_fsize -= alloc_stack;
if (TARGET_DEBUG)
fprintf (stderr, "\
Saved %d bytes via prologue function (%d vs. %d) for function %s\n",
save_normal_len - save_func_len,
save_normal_len, save_func_len,
IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
} }
else else
save_all = NULL_RTX; save_all = NULL_RTX;
@ -1705,13 +1868,14 @@ Saved %d bytes via prologue function (%d vs. %d) for function %s\n",
/* Special case interrupt functions that save all registers for a call. */ /* Special case interrupt functions that save all registers for a call. */
if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0) if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
{ {
if (TARGET_V850E && ! TARGET_DISABLE_CALLT) if (! TARGET_DISABLE_CALLT)
emit_insn (gen_callt_save_all_interrupt ()); emit_insn (gen_callt_save_all_interrupt ());
else else
emit_insn (gen_save_all_interrupt ()); emit_insn (gen_save_all_interrupt ());
} }
else else
{ {
int offset;
/* If the stack is too big, allocate it in chunks so we can do the /* If the stack is too big, allocate it in chunks so we can do the
register saves. We use the register save size so we use the ep register saves. We use the register save size so we use the ep
register. */ register. */
@ -1755,7 +1919,7 @@ Saved %d bytes via prologue function (%d vs. %d) for function %s\n",
if (actual_fsize > init_stack_alloc) if (actual_fsize > init_stack_alloc)
{ {
int diff = actual_fsize - init_stack_alloc; int diff = actual_fsize - init_stack_alloc;
if (CONST_OK_FOR_K (diff)) if (CONST_OK_FOR_K (-diff))
emit_insn (gen_addsi3 (stack_pointer_rtx, emit_insn (gen_addsi3 (stack_pointer_rtx,
stack_pointer_rtx, stack_pointer_rtx,
GEN_INT (-diff))); GEN_INT (-diff)));
@ -1777,15 +1941,12 @@ void
expand_epilogue (void) expand_epilogue (void)
{ {
unsigned int i; unsigned int i;
int offset;
unsigned int size = get_frame_size (); unsigned int size = get_frame_size ();
long reg_saved = 0; long reg_saved = 0;
int actual_fsize = compute_frame_size (size, &reg_saved); int actual_fsize = compute_frame_size (size, &reg_saved);
unsigned int init_stack_free = 0;
rtx restore_regs[32]; rtx restore_regs[32];
rtx restore_all; rtx restore_all;
unsigned int num_restore; unsigned int num_restore;
unsigned int default_stack;
int code; int code;
int interrupt_handler = v850_interrupt_function_p (current_function_decl); int interrupt_handler = v850_interrupt_function_p (current_function_decl);
@ -1803,49 +1964,28 @@ expand_epilogue (void)
/* Identify all of the saved registers. */ /* Identify all of the saved registers. */
num_restore = 0; num_restore = 0;
default_stack = 0; for (i = 1; i < 32; i++)
for (i = 1; i < 31; i++)
{ {
if (((1L << i) & reg_saved) != 0) if (((1L << i) & reg_saved) != 0)
restore_regs[num_restore++] = gen_rtx_REG (Pmode, i); restore_regs[num_restore++] = gen_rtx_REG (Pmode, i);
} }
/* If the return pointer is saved, the helper functions also allocate
16 bytes of stack for arguments to be saved in. */
if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
{
restore_regs[num_restore++] = gen_rtx_REG (Pmode, LINK_POINTER_REGNUM);
default_stack = 16;
}
/* See if we have an insn that restores the particular registers we /* See if we have an insn that restores the particular registers we
want to. */ want to. */
restore_all = NULL_RTX; restore_all = NULL_RTX;
if (TARGET_PROLOG_FUNCTION if (TARGET_PROLOG_FUNCTION
&& num_restore > 0 && num_restore > 0
&& actual_fsize >= (signed) default_stack
&& !interrupt_handler) && !interrupt_handler)
{ {
int alloc_stack = (4 * num_restore) + default_stack; int alloc_stack = (4 * num_restore);
int unalloc_stack = actual_fsize - alloc_stack; int restore_func_len;
int restore_func_len = 4;
int restore_normal_len; int restore_normal_len;
if (unalloc_stack)
restore_func_len += CONST_OK_FOR_J (unalloc_stack) ? 2 : 4;
/* See if we would have used ep to restore the registers. */
if (TARGET_EP && num_restore > 3 && (unsigned)actual_fsize < 255)
restore_normal_len = (3 * 2) + (2 * num_restore);
else
restore_normal_len = 4 * num_restore;
restore_normal_len += (CONST_OK_FOR_J (actual_fsize) ? 2 : 4) + 2;
/* Don't bother checking if we don't actually save any space. */ /* Don't bother checking if we don't actually save any space. */
if (restore_func_len < restore_normal_len) if (use_prolog_function (num_restore, actual_fsize))
{ {
int offset;
restore_all = gen_rtx_PARALLEL (VOIDmode, restore_all = gen_rtx_PARALLEL (VOIDmode,
rtvec_alloc (num_restore + 2)); rtvec_alloc (num_restore + 2));
XVECEXP (restore_all, 0, 0) = gen_rtx_RETURN (VOIDmode); XVECEXP (restore_all, 0, 0) = gen_rtx_RETURN (VOIDmode);
@ -1862,8 +2002,9 @@ expand_epilogue (void)
= gen_rtx_SET (VOIDmode, = gen_rtx_SET (VOIDmode,
restore_regs[i], restore_regs[i],
gen_rtx_MEM (Pmode, gen_rtx_MEM (Pmode,
plus_constant (stack_pointer_rtx, gen_rtx_PLUS (Pmode,
offset))); stack_pointer_rtx,
GEN_INT(offset))));
offset -= 4; offset -= 4;
} }
@ -1893,12 +2034,6 @@ expand_epilogue (void)
insn = emit_jump_insn (restore_all); insn = emit_jump_insn (restore_all);
INSN_CODE (insn) = code; INSN_CODE (insn) = code;
if (TARGET_DEBUG)
fprintf (stderr, "\
Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",
restore_normal_len - restore_func_len,
restore_normal_len, restore_func_len,
IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
} }
else else
restore_all = NULL_RTX; restore_all = NULL_RTX;
@ -1909,8 +2044,12 @@ Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",
old fashioned way (one by one). */ old fashioned way (one by one). */
if (!restore_all) if (!restore_all)
{ {
unsigned int init_stack_free;
/* If the stack is large, we need to cut it down in 2 pieces. */ /* If the stack is large, we need to cut it down in 2 pieces. */
if (actual_fsize && !CONST_OK_FOR_K (-actual_fsize)) if (interrupt_handler)
init_stack_free = 0;
else if (actual_fsize && !CONST_OK_FOR_K (-actual_fsize))
init_stack_free = 4 * num_restore; init_stack_free = 4 * num_restore;
else else
init_stack_free = (signed) actual_fsize; init_stack_free = (signed) actual_fsize;
@ -1920,7 +2059,7 @@ Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",
{ {
int diff; int diff;
diff = actual_fsize - ((interrupt_handler) ? 0 : init_stack_free); diff = actual_fsize - init_stack_free;
if (CONST_OK_FOR_K (diff)) if (CONST_OK_FOR_K (diff))
emit_insn (gen_addsi3 (stack_pointer_rtx, emit_insn (gen_addsi3 (stack_pointer_rtx,
@ -1940,7 +2079,7 @@ Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",
for a call. */ for a call. */
if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0) if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
{ {
if (TARGET_V850E && ! TARGET_DISABLE_CALLT) if (! TARGET_DISABLE_CALLT)
emit_insn (gen_callt_restore_all_interrupt ()); emit_insn (gen_callt_restore_all_interrupt ());
else else
emit_insn (gen_restore_all_interrupt ()); emit_insn (gen_restore_all_interrupt ());
@ -1948,7 +2087,7 @@ Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",
else else
{ {
/* Restore registers from the beginning of the stack frame. */ /* Restore registers from the beginning of the stack frame. */
offset = init_stack_free - 4; int offset = init_stack_free - 4;
/* Restore the return pointer first. */ /* Restore the return pointer first. */
if (num_restore > 0 if (num_restore > 0
@ -1982,7 +2121,7 @@ Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",
/* And return or use reti for interrupt handlers. */ /* And return or use reti for interrupt handlers. */
if (interrupt_handler) if (interrupt_handler)
{ {
if (TARGET_V850E && ! TARGET_DISABLE_CALLT) if (! TARGET_DISABLE_CALLT)
emit_insn (gen_callt_return_interrupt ()); emit_insn (gen_callt_return_interrupt ());
else else
emit_jump_insn (gen_return_interrupt ()); emit_jump_insn (gen_return_interrupt ());
@ -1997,9 +2136,7 @@ Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",
v850_interrupt_p = FALSE; v850_interrupt_p = FALSE;
} }
/* Update the condition code from the insn. */ /* Update the condition code from the insn. */
void void
notice_update_cc (rtx body, rtx insn) notice_update_cc (rtx body, rtx insn)
{ {
@ -2026,7 +2163,7 @@ notice_update_cc (rtx body, rtx insn)
case CC_SET_ZNV: case CC_SET_ZNV:
/* Insn sets the Z,N,V flags of CC to recog_data.operand[0]. /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
C is in an unusable state. */ C is in an unusable state. */
CC_STATUS_INIT; CC_STATUS_INIT;
cc_status.flags |= CC_NO_CARRY; cc_status.flags |= CC_NO_CARRY;
cc_status.value1 = recog_data.operand[0]; cc_status.value1 = recog_data.operand[0];
@ -2044,7 +2181,7 @@ notice_update_cc (rtx body, rtx insn)
break; break;
} }
} }
/* Retrieve the data area that has been chosen for the given decl. */ /* Retrieve the data area that has been chosen for the given decl. */
v850_data_area v850_data_area
@ -2258,6 +2395,7 @@ v850_encode_section_info (tree decl, rtx rtl, int first)
pops registers off the stack and possibly releases some extra stack space pops registers off the stack and possibly releases some extra stack space
as well. The code has already verified that the RTL matches these as well. The code has already verified that the RTL matches these
requirements. */ requirements. */
char * char *
construct_restore_jr (rtx op) construct_restore_jr (rtx op)
{ {
@ -2287,7 +2425,7 @@ construct_restore_jr (rtx op)
stack_bytes -= (count - 2) * 4; stack_bytes -= (count - 2) * 4;
/* Make sure that the amount we are popping either 0 or 16 bytes. */ /* Make sure that the amount we are popping either 0 or 16 bytes. */
if (stack_bytes != 0 && stack_bytes != 16) if (stack_bytes != 0)
{ {
error ("bad amount of stack space removal: %d", stack_bytes); error ("bad amount of stack space removal: %d", stack_bytes);
return NULL; return NULL;
@ -2319,8 +2457,6 @@ construct_restore_jr (rtx op)
/* Discover the last register to pop. */ /* Discover the last register to pop. */
if (mask & (1 << LINK_POINTER_REGNUM)) if (mask & (1 << LINK_POINTER_REGNUM))
{ {
gcc_assert (stack_bytes == 16);
last = LINK_POINTER_REGNUM; last = LINK_POINTER_REGNUM;
} }
else else
@ -2376,7 +2512,7 @@ construct_save_jarl (rtx op)
int i; int i;
static char buff [100]; /* XXX */ static char buff [100]; /* XXX */
if (count <= 2) if (count <= (TARGET_LONG_CALLS ? 3 : 2))
{ {
error ("bogus JARL construction: %d\n", count); error ("bogus JARL construction: %d\n", count);
return NULL; return NULL;
@ -2396,7 +2532,7 @@ construct_save_jarl (rtx op)
stack_bytes += (count - (TARGET_LONG_CALLS ? 3 : 2)) * 4; stack_bytes += (count - (TARGET_LONG_CALLS ? 3 : 2)) * 4;
/* Make sure that the amount we are popping either 0 or 16 bytes. */ /* Make sure that the amount we are popping either 0 or 16 bytes. */
if (stack_bytes != 0 && stack_bytes != -16) if (stack_bytes != 0)
{ {
error ("bad amount of stack space removal: %d", stack_bytes); error ("bad amount of stack space removal: %d", stack_bytes);
return NULL; return NULL;
@ -2428,8 +2564,6 @@ construct_save_jarl (rtx op)
/* Discover the last register to push. */ /* Discover the last register to push. */
if (mask & (1 << LINK_POINTER_REGNUM)) if (mask & (1 << LINK_POINTER_REGNUM))
{ {
gcc_assert (stack_bytes == -16);
last = LINK_POINTER_REGNUM; last = LINK_POINTER_REGNUM;
} }
else else
@ -2719,7 +2853,7 @@ construct_dispose_instruction (rtx op)
} }
if (! TARGET_DISABLE_CALLT if (! TARGET_DISABLE_CALLT
&& (use_callt || stack_bytes == 0 || stack_bytes == 16)) && (use_callt || stack_bytes == 0))
{ {
if (use_callt) if (use_callt)
{ {
@ -2735,8 +2869,8 @@ construct_dispose_instruction (rtx op)
if (i == 31) if (i == 31)
sprintf (buff, "callt ctoff(__callt_return_r31c)"); sprintf (buff, "callt ctoff(__callt_return_r31c)");
else else
sprintf (buff, "callt ctoff(__callt_return_r%d_r%d%s)", sprintf (buff, "callt ctoff(__callt_return_r%d_r%s)",
i, (mask & (1 << 31)) ? 31 : 29, stack_bytes ? "c" : ""); i, (mask & (1 << 31)) ? "31c" : "29");
} }
} }
else else
@ -2789,16 +2923,16 @@ construct_dispose_instruction (rtx op)
char * char *
construct_prepare_instruction (rtx op) construct_prepare_instruction (rtx op)
{ {
int count = XVECLEN (op, 0); int count;
int stack_bytes; int stack_bytes;
unsigned long int mask; unsigned long int mask;
int i; int i;
static char buff[ 100 ]; /* XXX */ static char buff[ 100 ]; /* XXX */
int use_callt = 0; int use_callt = 0;
if (count <= 1) if (XVECLEN (op, 0) <= 1)
{ {
error ("bogus PREPEARE construction: %d", count); error ("bogus PREPEARE construction: %d", XVECLEN (op, 0));
return NULL; return NULL;
} }
@ -2810,8 +2944,6 @@ construct_prepare_instruction (rtx op)
stack_bytes = INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)); stack_bytes = INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1));
/* Each push will put 4 bytes from the stack. */
stack_bytes += (count - 1) * 4;
/* Make sure that the amount we are popping /* Make sure that the amount we are popping
will fit into the DISPOSE instruction. */ will fit into the DISPOSE instruction. */
@ -2822,11 +2954,15 @@ construct_prepare_instruction (rtx op)
} }
/* Now compute the bit mask of registers to push. */ /* Now compute the bit mask of registers to push. */
count = 0;
mask = 0; mask = 0;
for (i = 1; i < count; i++) for (i = 1; i < XVECLEN (op, 0); i++)
{ {
rtx vector_element = XVECEXP (op, 0, i); rtx vector_element = XVECEXP (op, 0, i);
if (GET_CODE (vector_element) == CLOBBER)
continue;
gcc_assert (GET_CODE (vector_element) == SET); gcc_assert (GET_CODE (vector_element) == SET);
gcc_assert (GET_CODE (SET_SRC (vector_element)) == REG); gcc_assert (GET_CODE (SET_SRC (vector_element)) == REG);
gcc_assert (register_is_ok_for_epilogue (SET_SRC (vector_element), gcc_assert (register_is_ok_for_epilogue (SET_SRC (vector_element),
@ -2836,10 +2972,13 @@ construct_prepare_instruction (rtx op)
use_callt = 1; use_callt = 1;
else else
mask |= 1 << REGNO (SET_SRC (vector_element)); mask |= 1 << REGNO (SET_SRC (vector_element));
count++;
} }
stack_bytes += count * 4;
if ((! TARGET_DISABLE_CALLT) if ((! TARGET_DISABLE_CALLT)
&& (use_callt || stack_bytes == 0 || stack_bytes == -16)) && (use_callt || stack_bytes == 0))
{ {
if (use_callt) if (use_callt)
{ {
@ -2854,8 +2993,8 @@ construct_prepare_instruction (rtx op)
if (i == 31) if (i == 31)
sprintf (buff, "callt ctoff(__callt_save_r31c)"); sprintf (buff, "callt ctoff(__callt_save_r31c)");
else else
sprintf (buff, "callt ctoff(__callt_save_r%d_r%d%s)", sprintf (buff, "callt ctoff(__callt_save_r%d_r%s)",
i, (mask & (1 << 31)) ? 31 : 29, stack_bytes ? "c" : ""); i, (mask & (1 << 31)) ? "31c" : "29");
} }
else else
{ {
@ -2900,7 +3039,7 @@ construct_prepare_instruction (rtx op)
return buff; return buff;
} }
/* Return an RTX indicating where the return address to the /* Return an RTX indicating where the return address to the
calling function can be found. */ calling function can be found. */
@ -3045,5 +3184,10 @@ v850_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
mem = adjust_address (m_tramp, SImode, 20); mem = adjust_address (m_tramp, SImode, 20);
emit_move_insn (mem, fnaddr); emit_move_insn (mem, fnaddr);
} }
static int
v850_issue_rate (void)
{
return (TARGET_V850E2_ALL? 2 : 1);
}
#include "gt-v850.h" #include "gt-v850.h"

View File

@ -22,8 +22,13 @@
#ifndef GCC_V850_H #ifndef GCC_V850_H
#define GCC_V850_H #define GCC_V850_H
extern GTY(()) rtx v850_compare_op0;
extern GTY(()) rtx v850_compare_op1;
/* These are defined in svr4.h but we want to override them. */ /* These are defined in svr4.h but we want to override them. */
#undef LIB_SPEC #undef LIB_SPEC
#define LIB_SPEC "%{!shared:%{!symbolic:--start-group -lc -lgcc --end-group}}"
#undef ENDFILE_SPEC #undef ENDFILE_SPEC
#undef LINK_SPEC #undef LINK_SPEC
#undef STARTFILE_SPEC #undef STARTFILE_SPEC
@ -31,7 +36,10 @@
#define TARGET_CPU_generic 1 #define TARGET_CPU_generic 1
#define TARGET_CPU_v850e 2 #define TARGET_CPU_v850e 2
#define TARGET_CPU_v850e1 3 #define TARGET_CPU_v850e1 3
#define TARGET_CPU_v850e2 4
#define TARGET_CPU_v850e2v3 5
#ifndef TARGET_CPU_DEFAULT #ifndef TARGET_CPU_DEFAULT
#define TARGET_CPU_DEFAULT TARGET_CPU_generic #define TARGET_CPU_DEFAULT TARGET_CPU_generic
@ -58,17 +66,42 @@
#if TARGET_CPU_DEFAULT == TARGET_CPU_v850e1 #if TARGET_CPU_DEFAULT == TARGET_CPU_v850e1
#undef MASK_DEFAULT #undef MASK_DEFAULT
#define MASK_DEFAULT MASK_V850E /* No practical difference. */ #define MASK_DEFAULT MASK_V850E /* No practical difference. */
#undef SUBTARGET_ASM_SPEC #undef SUBTARGET_ASM_SPEC
#define SUBTARGET_ASM_SPEC "%{!mv*:-mv850e1}" #define SUBTARGET_ASM_SPEC "%{!mv*:-mv850e1}"
#undef SUBTARGET_CPP_SPEC #undef SUBTARGET_CPP_SPEC
#define SUBTARGET_CPP_SPEC "%{!mv*:-D__v850e1__} %{mv850e1:-D__v850e1__}" #define SUBTARGET_CPP_SPEC "%{!mv*:-D__v850e1__} %{mv850e1:-D__v850e1__}"
#undef TARGET_VERSION #undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (NEC V850E1)"); #define TARGET_VERSION fprintf (stderr, " (NEC V850E1)");
#endif #endif
#if TARGET_CPU_DEFAULT == TARGET_CPU_v850e2
#undef MASK_DEFAULT
#define MASK_DEFAULT MASK_V850E2
#undef SUBTARGET_ASM_SPEC
#define SUBTARGET_ASM_SPEC "%{!mv*:-mv850e2}"
#undef SUBTARGET_CPP_SPEC
#define SUBTARGET_CPP_SPEC "%{!mv*:-D__v850e2__} %{mv850e2:-D__v850e2__}"
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (NEC V850E2)");
#endif
#if TARGET_CPU_DEFAULT == TARGET_CPU_v850e2v3
#undef MASK_DEFAULT
#define MASK_DEFAULT MASK_V850E2V3
#undef SUBTARGET_ASM_SPEC
#define SUBTARGET_ASM_SPEC "%{!mv*:-mv850e2v3}"
#undef SUBTARGET_CPP_SPEC
#define SUBTARGET_CPP_SPEC "%{!mv*:-D__v850e2v3__} %{mv850e2v3:-D__v850e2v3__}"
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (NEC V850E2V3)");
#endif
#define TARGET_V850E2_ALL (TARGET_V850E2 || TARGET_V850E2V3)
#define ASM_SPEC "%{mv*:-mv%*}" #define ASM_SPEC "%{mv*:-mv%*}"
#define CPP_SPEC "%{mv850e:-D__v850e__} %{mv850:-D__v850__} %(subtarget_cpp_spec)" #define CPP_SPEC "%{mv850e2v3:-D__v850e2v3__} %{mv850e2:-D__v850e2__} %{mv850e:-D__v850e__} %{mv850:-D__v850__} %(subtarget_cpp_spec)" \
" %{mep:-D__EP__}"
#define EXTRA_SPECS \ #define EXTRA_SPECS \
{ "subtarget_asm_spec", SUBTARGET_ASM_SPEC }, \ { "subtarget_asm_spec", SUBTARGET_ASM_SPEC }, \
@ -76,7 +109,7 @@
/* Names to predefine in the preprocessor for this target machine. */ /* Names to predefine in the preprocessor for this target machine. */
#define TARGET_CPU_CPP_BUILTINS() do { \ #define TARGET_CPU_CPP_BUILTINS() do { \
builtin_define( "__v851__" ); \ builtin_define( "__v851__" ); \
builtin_define( "__v850" ); \ builtin_define( "__v850" ); \
builtin_assert( "machine=v850" ); \ builtin_assert( "machine=v850" ); \
builtin_assert( "cpu=v850" ); \ builtin_assert( "cpu=v850" ); \
@ -130,7 +163,6 @@ extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max];
#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) \ #define OPTIMIZATION_OPTIONS(LEVEL,SIZE) \
{ \ { \
target_flags |= MASK_STRICT_ALIGN; \
if (LEVEL) \ if (LEVEL) \
/* Note - we no longer enable MASK_EP when optimizing. This is \ /* Note - we no longer enable MASK_EP when optimizing. This is \
because of a hardware bug which stops the SLD and SST instructions\ because of a hardware bug which stops the SLD and SST instructions\
@ -196,7 +228,7 @@ extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max];
/* Define this if move instructions will actually fail to work /* Define this if move instructions will actually fail to work
when given unaligned data. */ when given unaligned data. */
#define STRICT_ALIGNMENT TARGET_STRICT_ALIGN #define STRICT_ALIGNMENT (!TARGET_NO_STRICT_ALIGN)
/* Define this as 1 if `char' should by default be signed; else as 0. /* Define this as 1 if `char' should by default be signed; else as 0.
@ -212,16 +244,17 @@ extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max];
All registers that the compiler knows about must be given numbers, All registers that the compiler knows about must be given numbers,
even those that are not normally considered general registers. */ even those that are not normally considered general registers. */
#define FIRST_PSEUDO_REGISTER 34 #define FIRST_PSEUDO_REGISTER 36
/* 1 for registers that have pervasive standard uses /* 1 for registers that have pervasive standard uses
and are not available for the register allocator. */ and are not available for the register allocator. */
#define FIXED_REGISTERS \ #define FIXED_REGISTERS \
{ 1, 1, 0, 1, 1, 0, 0, 0, \ { 1, 1, 1, 1, 1, 1, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 1, 0, \ 0, 0, 0, 0, 0, 0, 1, 0, \
1, 1, \
1, 1} 1, 1}
/* 1 for registers not available across function calls. /* 1 for registers not available across function calls.
@ -233,10 +266,11 @@ extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max];
like. */ like. */
#define CALL_USED_REGISTERS \ #define CALL_USED_REGISTERS \
{ 1, 1, 0, 1, 1, 1, 1, 1, \ { 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 0, 0, 0, 0, \ 1, 1, 1, 1, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 1, 1, \ 0, 0, 0, 0, 0, 0, 1, 1, \
1, 1, \
1, 1} 1, 1}
/* List the order in which to allocate registers. Each register must be /* List the order in which to allocate registers. Each register must be
@ -254,19 +288,21 @@ extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max];
6, 7, 8, 9, 31, /* argument registers */ \ 6, 7, 8, 9, 31, /* argument registers */ \
29, 28, 27, 26, 25, 24, 23, 22, /* saved registers */ \ 29, 28, 27, 26, 25, 24, 23, 22, /* saved registers */ \
21, 20, 2, \ 21, 20, 2, \
0, 1, 3, 4, 5, 30, 32, 33 /* fixed registers */ \ 0, 1, 3, 4, 5, 30, 32, 33, /* fixed registers */ \
34, 35 \
} }
/* If TARGET_APP_REGS is not defined then add r2 and r5 to /* If TARGET_APP_REGS is not defined then add r2 and r5 to
the pool of fixed registers. See PR 14505. */ the pool of fixed registers. See PR 14505. */
#define CONDITIONAL_REGISTER_USAGE \ #define CONDITIONAL_REGISTER_USAGE \
{ \ { \
if (!TARGET_APP_REGS) \ if (TARGET_APP_REGS) \
{ \ { \
fixed_regs[2] = 1; call_used_regs[2] = 1; \ fixed_regs[2] = 0; call_used_regs[2] = 0; \
fixed_regs[5] = 1; call_used_regs[5] = 1; \ fixed_regs[5] = 0; call_used_regs[5] = 1; \
} \ } \
} }
/* Return number of consecutive hard regs needed starting at reg REGNO /* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE. to hold something of mode MODE.
@ -281,7 +317,7 @@ extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max];
MODE. */ MODE. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \ #define HARD_REGNO_MODE_OK(REGNO, MODE) \
((((REGNO) & 1) == 0) || (GET_MODE_SIZE (MODE) <= 4)) ((GET_MODE_SIZE (MODE) <= 4) || (((REGNO) & 1) == 0 && (REGNO) != 0))
/* Value is 1 if it is a good idea to tie two pseudo registers /* Value is 1 if it is a good idea to tie two pseudo registers
when one has mode MODE1 and one has mode MODE2. when one has mode MODE1 and one has mode MODE2.
@ -313,7 +349,7 @@ extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max];
enum reg_class enum reg_class
{ {
NO_REGS, GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES NO_REGS, GENERAL_REGS, EVEN_REGS, ALL_REGS, LIM_REG_CLASSES
}; };
#define N_REG_CLASSES (int) LIM_REG_CLASSES #define N_REG_CLASSES (int) LIM_REG_CLASSES
@ -326,17 +362,18 @@ enum reg_class
/* Give names of register classes as strings for dump file. */ /* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \ #define REG_CLASS_NAMES \
{ "NO_REGS", "GENERAL_REGS", "ALL_REGS", "LIM_REGS" } { "NO_REGS", "GENERAL_REGS", "EVEN_REGS", "ALL_REGS", "LIM_REGS" }
/* Define which registers fit in which classes. /* Define which registers fit in which classes.
This is an initializer for a vector of HARD_REG_SET This is an initializer for a vector of HARD_REG_SET
of length N_REG_CLASSES. */ of length N_REG_CLASSES. */
#define REG_CLASS_CONTENTS \ #define REG_CLASS_CONTENTS \
{ \ { \
{ 0x00000000 }, /* NO_REGS */ \ { 0x00000000,0x0 }, /* NO_REGS */ \
{ 0xffffffff }, /* GENERAL_REGS */ \ { 0xffffffff,0x0 }, /* GENERAL_REGS */ \
{ 0xffffffff }, /* ALL_REGS */ \ { 0x55555554,0x0 }, /* EVEN_REGS */ \
{ 0xffffffff,0x0 }, /* ALL_REGS */ \
} }
/* The same information, inverted: /* The same information, inverted:
@ -344,7 +381,7 @@ enum reg_class
reg number REGNO. This could be a conditional expression reg number REGNO. This could be a conditional expression
or could index an array. */ or could index an array. */
#define REGNO_REG_CLASS(REGNO) GENERAL_REGS #define REGNO_REG_CLASS(REGNO) ((REGNO == CC_REGNUM || REGNO == FCC_REGNUM) ? NO_REGS : GENERAL_REGS)
/* The class value for index registers, and the one for base regs. */ /* The class value for index registers, and the one for base regs. */
@ -353,7 +390,8 @@ enum reg_class
/* Get reg_class from a letter such as appears in the machine description. */ /* Get reg_class from a letter such as appears in the machine description. */
#define REG_CLASS_FROM_LETTER(C) (NO_REGS) #define REG_CLASS_FROM_LETTER(C) \
(C == 'e' ? EVEN_REGS : (NO_REGS))
/* Macros to check register numbers against specific register classes. */ /* Macros to check register numbers against specific register classes. */
@ -363,8 +401,11 @@ enum reg_class
Since they use reg_renumber, they are safe only once reg_renumber Since they use reg_renumber, they are safe only once reg_renumber
has been allocated, which happens in local-alloc.c. */ has been allocated, which happens in local-alloc.c. */
#define REGNO_OK_FOR_BASE_P(regno) \ #define REGNO_OK_FOR_BASE_P(regno) \
((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0) (((regno) < FIRST_PSEUDO_REGISTER \
&& (regno) != CC_REGNUM \
&& (regno) != FCC_REGNUM) \
|| reg_renumber[regno] >= 0)
#define REGNO_OK_FOR_INDEX_P(regno) 0 #define REGNO_OK_FOR_INDEX_P(regno) 0
@ -470,13 +511,13 @@ enum reg_class
The values of these macros are register numbers. */ The values of these macros are register numbers. */
/* Register to use for pushing function arguments. */ /* Register to use for pushing function arguments. */
#define STACK_POINTER_REGNUM 3 #define STACK_POINTER_REGNUM SP_REGNUM
/* Base register for access to local variables of the function. */ /* Base register for access to local variables of the function. */
#define FRAME_POINTER_REGNUM 32 #define FRAME_POINTER_REGNUM 34
/* Register containing return address from latest function call. */ /* Register containing return address from latest function call. */
#define LINK_POINTER_REGNUM 31 #define LINK_POINTER_REGNUM LP_REGNUM
/* On some machines the offset between the frame pointer and starting /* On some machines the offset between the frame pointer and starting
offset of the automatic variables is not known until after register offset of the automatic variables is not known until after register
@ -501,7 +542,7 @@ enum reg_class
#define HARD_FRAME_POINTER_REGNUM 29 #define HARD_FRAME_POINTER_REGNUM 29
/* Base register for access to arguments of the function. */ /* Base register for access to arguments of the function. */
#define ARG_POINTER_REGNUM 33 #define ARG_POINTER_REGNUM 35
/* Register in which static-chain is passed to a function. */ /* Register in which static-chain is passed to a function. */
#define STATIC_CHAIN_REGNUM 20 #define STATIC_CHAIN_REGNUM 20
@ -593,19 +634,18 @@ struct cum_arg { int nbytes; int anonymous_args; };
/* Update the data in CUM to advance over an argument /* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE. of mode MODE and data type TYPE.
(TYPE is null for libcalls where that information may not be available.) */ (TYPE is null for libcalls where that information may not be available.) */
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ ((CUM).nbytes += \
((CUM).nbytes += ((MODE) != BLKmode \ ((((TYPE) && int_size_in_bytes (TYPE) > 8) \
? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD \ ? GET_MODE_SIZE (Pmode) \
: (int_size_in_bytes (TYPE) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD)) : ((MODE) != BLKmode \
? GET_MODE_SIZE ((MODE)) \
: int_size_in_bytes ((TYPE)))) \
+ UNITS_PER_WORD - 1) & -UNITS_PER_WORD)
/* When a parameter is passed in a register, stack space is still /* When a parameter is passed in a register, stack space is still
allocated for it. */ allocated for it. */
#define REG_PARM_STACK_SPACE(DECL) (!TARGET_GHS ? 16 : 0) #define REG_PARM_STACK_SPACE(DECL) 0
/* Define this if the above stack space is to be considered part of the
space allocated by the caller. */
#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
/* 1 if N is a possible register number for function argument passing. */ /* 1 if N is a possible register number for function argument passing. */
@ -723,8 +763,11 @@ struct cum_arg { int nbytes; int anonymous_args; };
&& SYMBOL_REF_ZDA_P (OP)) \ && SYMBOL_REF_ZDA_P (OP)) \
|| (GET_CODE (OP) == CONST \ || (GET_CODE (OP) == CONST \
&& GET_CODE (XEXP (OP, 0)) == PLUS \ && GET_CODE (XEXP (OP, 0)) == PLUS \
&& GET_CODE (XEXP (XEXP (OP, 0), 0)) == SYMBOL_REF \ && GET_CODE (XEXP (XEXP (OP, 0), 0)) == SYMBOL_REF\
&& SYMBOL_REF_ZDA_P (XEXP (XEXP (OP, 0), 0)))) \ && SYMBOL_REF_ZDA_P (XEXP (XEXP (OP, 0), 0)))) \
: (C) == 'W' ? (GET_CODE (OP) == CONST_INT \
&& ((unsigned)(INTVAL (OP)) >= 0x8000) \
&& ((unsigned)(INTVAL (OP)) < 0x400000)) \
: 0) : 0)
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
@ -765,7 +808,7 @@ do { \
goto ADDR; \ goto ADDR; \
if (GET_CODE (X) == PLUS \ if (GET_CODE (X) == PLUS \
&& RTX_OK_FOR_BASE_P (XEXP (X, 0)) \ && RTX_OK_FOR_BASE_P (XEXP (X, 0)) \
&& CONSTANT_ADDRESS_P (XEXP (X, 1)) \ && (GET_CODE (XEXP (X,1)) == CONST_INT && CONST_OK_FOR_K (INTVAL(XEXP (X,1)) + GET_MODE_NUNITS(MODE) * UNITS_PER_WORD)) \
&& ((MODE == QImode || INTVAL (XEXP (X, 1)) % 2 == 0) \ && ((MODE == QImode || INTVAL (XEXP (X, 1)) % 2 == 0) \
&& CONST_OK_FOR_K (INTVAL (XEXP (X, 1)) \ && CONST_OK_FOR_K (INTVAL (XEXP (X, 1)) \
+ (GET_MODE_NUNITS (MODE) * UNITS_PER_WORD)))) \ + (GET_MODE_NUNITS (MODE) * UNITS_PER_WORD)))) \
@ -783,7 +826,18 @@ do { \
&& GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \ && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \
&& GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \ && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
&& ! CONST_OK_FOR_K (INTVAL (XEXP (XEXP (X, 0), 1))))) && ! CONST_OK_FOR_K (INTVAL (XEXP (XEXP (X, 0), 1)))))
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
return the mode to be used for the comparison.
For floating-point equality comparisons, CCFPEQmode should be used.
VOIDmode should be used in all other cases.
For integer comparisons against zero, reduce to CCNOmode or CCZmode if
possible, to allow for more combinations. */
#define SELECT_CC_MODE(OP, X, Y) v850_select_cc_mode (OP, X, Y)
/* Tell final.c how to eliminate redundant test instructions. */ /* Tell final.c how to eliminate redundant test instructions. */
/* Here we define machine-dependent flags and fields in cc_status /* Here we define machine-dependent flags and fields in cc_status
@ -889,22 +943,25 @@ typedef enum
/* How to refer to registers in assembler output. /* How to refer to registers in assembler output.
This sequence is indexed by compiler's hard-register-number (see above). */ This sequence is indexed by compiler's hard-register-number (see above). */
#define REGISTER_NAMES \ #define REGISTER_NAMES \
{ "r0", "r1", "r2", "sp", "gp", "r5", "r6" , "r7", \ { "r0", "r1", "r2", "sp", "gp", "r5", "r6" , "r7", \
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
"r24", "r25", "r26", "r27", "r28", "r29", "ep", "r31", \ "r24", "r25", "r26", "r27", "r28", "r29", "ep", "r31", \
"psw", "fcc", \
".fp", ".ap"} ".fp", ".ap"}
#define ADDITIONAL_REGISTER_NAMES \ /* Register numbers */
{ { "zero", 0 }, \
{ "hp", 2 }, \ #define ADDITIONAL_REGISTER_NAMES \
{ "r3", 3 }, \ { { "zero", ZERO_REGNUM }, \
{ "r4", 4 }, \ { "hp", 2 }, \
{ "tp", 5 }, \ { "r3", 3 }, \
{ "fp", 29 }, \ { "r4", 4 }, \
{ "r30", 30 }, \ { "tp", 5 }, \
{ "lp", 31} } { "fp", 29 }, \
{ "r30", 30 }, \
{ "lp", LP_REGNUM} }
#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)
#define ASM_OUTPUT_REG_POP(FILE,REGNO) #define ASM_OUTPUT_REG_POP(FILE,REGNO)
@ -919,12 +976,13 @@ typedef enum
/* Disable the shift, which is for the currently disabled "switch" /* Disable the shift, which is for the currently disabled "switch"
opcode. Se casesi in v850.md. */ opcode. Se casesi in v850.md. */
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
fprintf (FILE, "\t%s %s.L%d-.L%d%s\n", \ fprintf (FILE, "\t%s %s.L%d-.L%d%s\n", \
(TARGET_BIG_SWITCH ? ".long" : ".short"), \ (TARGET_BIG_SWITCH ? ".long" : ".short"), \
(0 && ! TARGET_BIG_SWITCH && TARGET_V850E ? "(" : ""), \ (0 && ! TARGET_BIG_SWITCH && (TARGET_V850E || TARGET_V850E2_ALL) ? "(" : ""), \
VALUE, REL, \ VALUE, REL, \
(0 && ! TARGET_BIG_SWITCH && TARGET_V850E ? ")>>1" : "")) (0 && ! TARGET_BIG_SWITCH && (TARGET_V850E || TARGET_V850E2_ALL) ? ")>>1" : ""))
#define ASM_OUTPUT_ALIGN(FILE, LOG) \ #define ASM_OUTPUT_ALIGN(FILE, LOG) \
if ((LOG) != 0) \ if ((LOG) != 0) \
@ -949,7 +1007,7 @@ typedef enum
/* The switch instruction requires that the jump table immediately follow /* The switch instruction requires that the jump table immediately follow
it. */ it. */
#define JUMP_TABLES_IN_TEXT_SECTION 1 #define JUMP_TABLES_IN_TEXT_SECTION (!TARGET_JUMP_TABLES_IN_DATA_SECTION)
/* svr4.h defines this assuming that 4 byte alignment is required. */ /* svr4.h defines this assuming that 4 byte alignment is required. */
#undef ASM_OUTPUT_BEFORE_CASE_LABEL #undef ASM_OUTPUT_BEFORE_CASE_LABEL
@ -1075,3 +1133,5 @@ extern union tree_node * GHS_current_section_names [(int) COUNT_OF_GHS_SECTION_K
#define TARGET_ASM_INIT_SECTIONS v850_asm_init_sections #define TARGET_ASM_INIT_SECTIONS v850_asm_init_sections
#endif /* ! GCC_V850_H */ #endif /* ! GCC_V850_H */

File diff suppressed because it is too large Load Diff

View File

@ -66,10 +66,14 @@ mtda
Target RejectNegative Joined Target RejectNegative Joined
Set the max size of data eligible for the TDA area Set the max size of data eligible for the TDA area
mstrict-align mno-strict-align
Target Report Mask(STRICT_ALIGN) Target Report Mask(NO_STRICT_ALIGN)
Enforce strict alignment Enforce strict alignment
mjump-tables-in-data-section
Target Report Mask(JUMP_TABLES_IN_DATA_SECTION)
Enforce table jump
mUS-bit-set mUS-bit-set
Target Report Mask(US_BIT_SET) Target Report Mask(US_BIT_SET)
@ -82,9 +86,17 @@ Target Report RejectNegative Mask(V850E)
Compile for the v850e processor Compile for the v850e processor
mv850e1 mv850e1
Target RejectNegative Mask(V850E) MaskExists Target RejectNegative Mask(V850E1)
Compile for the v850e1 processor Compile for the v850e1 processor
mv850e2
Target Report RejectNegative Mask(V850E2)
Compile for the v850e2 processor
mv850e2v3
Target Report RejectNegative Mask(V850E2V3)
Compile for the v850e2v3 processor
mzda mzda
Target RejectNegative Joined Target RejectNegative Joined
Set the max size of data eligible for the ZDA area Set the max size of data eligible for the ZDA area

View File

@ -868,6 +868,8 @@ See RS/6000 and PowerPC Options.
-mtda=@var{n} -msda=@var{n} -mzda=@var{n} @gol -mtda=@var{n} -msda=@var{n} -mzda=@var{n} @gol
-mapp-regs -mno-app-regs @gol -mapp-regs -mno-app-regs @gol
-mdisable-callt -mno-disable-callt @gol -mdisable-callt -mno-disable-callt @gol
-mv850e2v3 @gol
-mv850e2 @gol
-mv850e1 @gol -mv850e1 @gol
-mv850e @gol -mv850e @gol
-mv850 -mbig-switch} -mv850 -mbig-switch}
@ -16957,11 +16959,21 @@ the compiler. This setting is the default.
@opindex mno-app-regs @opindex mno-app-regs
This option will cause r2 and r5 to be treated as fixed registers. This option will cause r2 and r5 to be treated as fixed registers.
@item -mv850e2v3
@opindex mv850e2v3
Specify that the target processor is the V850E2V3. The preprocessor
constants @samp{__v850e2v3__} will be defined if
this option is used.
@item -mv850e2
@opindex mv850e2
Specify that the target processor is the V850E2. The preprocessor
constants @samp{__v850e2__} will be defined if
@item -mv850e1 @item -mv850e1
@opindex mv850e1 @opindex mv850e1
Specify that the target processor is the V850E1. The preprocessor Specify that the target processor is the V850E1. The preprocessor
constants @samp{__v850e1__} and @samp{__v850e__} will be defined if constants @samp{__v850e1__} and @samp{__v850e__} will be defined if
this option is used.
@item -mv850e @item -mv850e
@opindex mv850e @opindex mv850e
@ -16969,6 +16981,7 @@ Specify that the target processor is the V850E@. The preprocessor
constant @samp{__v850e__} will be defined if this option is used. constant @samp{__v850e__} will be defined if this option is used.
If neither @option{-mv850} nor @option{-mv850e} nor @option{-mv850e1} If neither @option{-mv850} nor @option{-mv850e} nor @option{-mv850e1}
nor @option{-mv850e2} nor @option{-mv850e2v3}
are defined then a default target processor will be chosen and the are defined then a default target processor will be chosen and the
relevant @samp{__v850*__} preprocessor constant will be defined. relevant @samp{__v850*__} preprocessor constant will be defined.
@ -16978,7 +16991,7 @@ defined, regardless of which processor variant is the target.
@item -mdisable-callt @item -mdisable-callt
@opindex mdisable-callt @opindex mdisable-callt
This option will suppress generation of the CALLT instruction for the This option will suppress generation of the CALLT instruction for the
v850e and v850e1 flavors of the v850 architecture. The default is v850e, v850e1, v850e2 and v850e2v3 flavors of the v850 architecture. The default is
@option{-mno-disable-callt} which allows the CALLT instruction to be used. @option{-mno-disable-callt} which allows the CALLT instruction to be used.
@end table @end table