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>
PR bootstrap/44455

8
configure vendored
View File

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

View File

@ -967,13 +967,7 @@ case "${target}" in
v810-*-*)
noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libstdc++-v3 opcodes target-libgloss ${libgcj}"
;;
v850-*-*)
noconfigdirs="$noconfigdirs target-libgloss ${libgcj}"
;;
v850e-*-*)
noconfigdirs="$noconfigdirs target-libgloss ${libgcj}"
;;
v850ea-*-*)
v850*-*-*)
noconfigdirs="$noconfigdirs target-libgloss ${libgcj}"
;;
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>
PR tree-optimization/45052

View File

@ -2517,6 +2517,7 @@ v850e1-*-*)
tm_p_file=v850/v850-protos.h
tmake_file=v850/t-v850e
md_file=v850/v850.md
extra_modes=v850/v850-modes.def
out_file=v850/v850.c
extra_options="${extra_options} v850/v850.opt"
if test x$stabs = xyes
@ -2534,6 +2535,7 @@ v850e-*-*)
tm_p_file=v850/v850-protos.h
tmake_file=v850/t-v850e
md_file=v850/v850.md
extra_modes=v850/v850-modes.def
out_file=v850/v850.c
extra_options="${extra_options} v850/v850.opt"
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 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.
(define_predicate "call_address_operand"
@ -79,7 +90,7 @@
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"
(match_code "label_ref,symbol_ref,const_int,const_double,const,high,mem,reg,subreg")
@ -97,7 +108,21 @@
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"
(match_code "symbol_ref")
@ -115,7 +140,8 @@
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"
(match_code "const_int")
@ -140,7 +166,7 @@
/* If there are no registers to save then the function prologue
is not suitable. */
if (count <= 2)
if (count <= (TARGET_LONG_CALLS ? 3 : 2))
return 0;
/* 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. */
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
|| GET_CODE (XEXP (vector_element, 0)) != REG
|| !(REGNO (XEXP (vector_element, 0)) == 10
|| (TARGET_LONG_CALLS ? (REGNO (XEXP (vector_element, 0)) == 11) : 0 )))
|| REGNO (XEXP (vector_element, 0)) != 11)
return 0;
}
return 1;
return i == count;
})
;; 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"))))
*/
for (i = 3; i < count; i++)
for (i = 2; i < count; i++)
{
rtx vector_element = XVECEXP (op, 0, i);
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 dest;
rtx src;
rtx plus;
if (GET_CODE (vector_element) == CLOBBER)
continue;
if (GET_CODE (vector_element) != SET)
return 0;
@ -406,14 +441,15 @@
space just acquired by the first operand then abandon this quest.
Note: the test is <= because both values are negative. */
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 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"
(match_code "const_int")
@ -436,3 +472,31 @@
return 0;
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_29c \
_save_31c \
_save_varargs \
_save_interrupt \
_save_all_interrupt \
_callt_save_20 \
@ -70,12 +69,10 @@ LIB1ASMFUNCS = _mulsi3 \
_callt_save_28c \
_callt_save_29c \
_callt_save_31c \
_callt_save_varargs \
_callt_save_interrupt \
_callt_save_all_interrupt \
_callt_save_r2_r29 \
_callt_save_r2_r31 \
_callt_save_r6_r9 \
_negdi2 \
_cmpdi2 \
_ucmpdi2 \
@ -100,10 +97,10 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
# Create target-specific versions of the libraries
MULTILIB_OPTIONS = mv850e
MULTILIB_DIRNAMES = v850e
MULTILIB_OPTIONS = mv850/mv850e/mv850e2/mv850e2v3
MULTILIB_DIRNAMES = v850 v850e v850e2 v850e2v3
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

View File

@ -45,7 +45,6 @@ LIB1ASMFUNCS = _mulsi3 \
_save_28c \
_save_29c \
_save_31c \
_save_varargs \
_save_interrupt \
_save_all_interrupt \
_callt_save_20 \
@ -69,12 +68,10 @@ LIB1ASMFUNCS = _mulsi3 \
_callt_save_28c \
_callt_save_29c \
_callt_save_31c \
_callt_save_varargs \
_callt_save_interrupt \
_callt_save_all_interrupt \
_callt_save_r2_r29 \
_callt_save_r2_r31 \
_callt_save_r6_r9 \
_negdi2 \
_cmpdi2 \
_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_prepare_instruction (rtx);
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
extern rtx function_arg (CUMULATIVE_ARGS *, Mmode, tree, int);
#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 void v850_encode_data_area (tree, rtx);
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 rtx v850_function_value (const_tree, const_tree, bool);
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);
static int v850_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
static bool v850_strict_argument_naming (CUMULATIVE_ARGS *);
static bool v850_can_eliminate (const int, const int);
static void v850_asm_trampoline_template (FILE *);
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. */
static int v850_interrupt_cache_p = FALSE;
rtx v850_compare_op0, v850_compare_op1;
/* Whether current function is an interrupt handler. */
static int v850_interrupt_p = FALSE;
@ -169,6 +173,9 @@ static const struct attribute_spec v850_attribute_table[] =
#undef TARGET_MACHINE_DEPENDENT_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
#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
#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;
/* 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;
}
}
/* Handle the TARGET_PASS_BY_REFERENCE target hook.
Specify whether to pass the argument by reference. */
static bool
v850_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
enum machine_mode mode, const_tree type,
@ -274,6 +287,14 @@ v850_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
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
and type TYPE will be passed to a function. If the result
is NULL_RTX, the argument will be pushed. */
@ -287,7 +308,7 @@ function_arg (CUMULATIVE_ARGS * cum,
rtx result = NULL_RTX;
int size, align;
if (TARGET_GHS && !named)
if (!named)
return NULL_RTX;
if (mode == BLKmode)
@ -295,6 +316,8 @@ function_arg (CUMULATIVE_ARGS * cum,
else
size = GET_MODE_SIZE (mode);
size = (size + UNITS_PER_WORD -1) & ~(UNITS_PER_WORD -1);
if (size < 1)
{
/* Once we have stopped using argument registers, do not start up again. */
@ -302,7 +325,7 @@ function_arg (CUMULATIVE_ARGS * cum,
return NULL_RTX;
}
if (type)
if (size <= UNITS_PER_WORD && type)
align = TYPE_ALIGN (type) / BITS_PER_UNIT;
else
align = size;
@ -337,10 +360,8 @@ function_arg (CUMULATIVE_ARGS * cum,
return result;
}
/* Return the number of bytes which must be put into registers
for values which are part in registers and part in memory. */
static int
v850_arg_partial_bytes (CUMULATIVE_ARGS * cum, enum machine_mode mode,
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 the high and low words of a CONST_DOUBLE */
static void
@ -713,6 +733,11 @@ v850_print_operand (FILE * file, rtx x, int code)
case 'z': /* reg or zero */
if (GET_CODE (x) == REG)
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
{
gcc_assert (x == const0_rtx);
@ -917,13 +942,13 @@ output_move_single (rtx * operands)
return "mov %1,%0";
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. */
return "movhi hi(%1),%.,%0";
return "movhi hi0(%1),%.,%0";
/* A random constant. */
else if (TARGET_V850E)
else if (TARGET_V850E || TARGET_V850E2_ALL)
return "mov %1,%0";
else
return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0";
@ -939,13 +964,13 @@ output_move_single (rtx * operands)
return "mov %F1,%0";
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. */
return "movhi hi(%F1),%.,%0";
return "movhi hi0(%F1),%.,%0";
/* A random constant. */
else if (TARGET_V850E)
else if (TARGET_V850E || TARGET_V850E2_ALL)
return "mov %F1,%0";
else
@ -962,7 +987,7 @@ output_move_single (rtx * operands)
|| GET_CODE (src) == SYMBOL_REF
|| GET_CODE (src) == CONST)
{
if (TARGET_V850E)
if (TARGET_V850E || TARGET_V850E2_ALL)
return "mov hilo(%1),%0";
else
return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0";
@ -996,7 +1021,169 @@ output_move_single (rtx * operands)
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
MODE and signedness UNSIGNEDP. */
@ -1010,9 +1197,8 @@ 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
&& ( ( unsignedp && ! TARGET_US_BIT_SET)
|| (! unsignedp && TARGET_US_BIT_SET)))
else if ((TARGET_V850E || TARGET_V850E2_ALL)
&& unsignedp)
max_offset = (1 << 4);
else
max_offset = (1 << 7);
@ -1021,9 +1207,8 @@ 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
&& ( ( unsignedp && ! TARGET_US_BIT_SET)
|| (! unsignedp && TARGET_US_BIT_SET)))
else if ((TARGET_V850E || TARGET_V850E2_ALL)
&& unsignedp)
max_offset = (1 << 5);
else
max_offset = (1 << 8);
@ -1420,18 +1605,15 @@ v850_reorg (void)
}
}
/* # 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. */
#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. */
#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)
@ -1477,6 +1659,7 @@ compute_register_save_size (long * p_reg_saved)
case 1: /* temp used to hold ep */
case 4: /* gp */
case 10: /* temp used to call interrupt save/restore */
case 11: /* temp used to call interrupt save/restore (long call) */
case EP_REGNUM: /* ep */
size += 4;
break;
@ -1550,19 +1733,50 @@ compute_frame_size (int size, long * p_reg_saved)
+ 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
expand_prologue (void)
{
unsigned int i;
int offset;
unsigned int size = get_frame_size ();
unsigned int actual_fsize;
unsigned int init_stack_alloc = 0;
rtx save_regs[32];
rtx save_all;
unsigned int num_save;
unsigned int default_stack;
int code;
int interrupt_handler = v850_interrupt_function_p (current_function_decl);
long reg_saved = 0;
@ -1572,7 +1786,7 @@ expand_prologue (void)
/* Save/setup global registers for interrupt functions right now. */
if (interrupt_handler)
{
if (TARGET_V850E && ! TARGET_DISABLE_CALLT)
if (! TARGET_DISABLE_CALLT)
emit_insn (gen_callt_save_interrupt ());
else
emit_insn (gen_save_interrupt ());
@ -1583,93 +1797,48 @@ expand_prologue (void)
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. */
num_save = 0;
default_stack = 0;
for (i = 1; i < 31; i++)
for (i = 1; i < 32; i++)
{
if (((1L << i) & reg_saved) != 0)
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
registers we want to. */
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;
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)
if (use_prolog_function (num_save, actual_fsize))
{
int alloc_stack = 4 * num_save;
int offset = 0;
save_all = gen_rtx_PARALLEL
(VOIDmode,
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)
= gen_rtx_SET (VOIDmode,
stack_pointer_rtx,
plus_constant (stack_pointer_rtx, -alloc_stack));
offset = - default_stack;
gen_rtx_PLUS (Pmode,
stack_pointer_rtx,
GEN_INT(-alloc_stack)));
for (i = 0; i < num_save; i++)
{
offset -= 4;
XVECEXP (save_all, 0, i+1)
= gen_rtx_SET (VOIDmode,
gen_rtx_MEM (Pmode,
plus_constant (stack_pointer_rtx,
offset)),
gen_rtx_PLUS (Pmode,
stack_pointer_rtx,
GEN_INT(offset))),
save_regs[i]);
offset -= 4;
}
if (TARGET_V850)
if (TARGET_DISABLE_CALLT)
{
XVECEXP (save_all, 0, num_save + 1)
= gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 10));
@ -1686,12 +1855,6 @@ expand_prologue (void)
INSN_CODE (insn) = code;
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
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. */
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 ());
else
emit_insn (gen_save_all_interrupt ());
}
else
{
int offset;
/* 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. */
@ -1755,7 +1919,7 @@ Saved %d bytes via prologue function (%d vs. %d) for function %s\n",
if (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,
stack_pointer_rtx,
GEN_INT (-diff)));
@ -1777,15 +1941,12 @@ void
expand_epilogue (void)
{
unsigned int i;
int offset;
unsigned int size = get_frame_size ();
long reg_saved = 0;
int actual_fsize = compute_frame_size (size, &reg_saved);
unsigned int init_stack_free = 0;
rtx restore_regs[32];
rtx restore_all;
unsigned int num_restore;
unsigned int default_stack;
int code;
int interrupt_handler = v850_interrupt_function_p (current_function_decl);
@ -1803,49 +1964,28 @@ expand_epilogue (void)
/* Identify all of the saved registers. */
num_restore = 0;
default_stack = 0;
for (i = 1; i < 31; i++)
for (i = 1; i < 32; i++)
{
if (((1L << i) & reg_saved) != 0)
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
want to. */
restore_all = NULL_RTX;
if (TARGET_PROLOG_FUNCTION
&& num_restore > 0
&& actual_fsize >= (signed) default_stack
&& !interrupt_handler)
{
int alloc_stack = (4 * num_restore) + default_stack;
int unalloc_stack = actual_fsize - alloc_stack;
int restore_func_len = 4;
int alloc_stack = (4 * num_restore);
int restore_func_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. */
if (restore_func_len < restore_normal_len)
if (use_prolog_function (num_restore, actual_fsize))
{
int offset;
restore_all = gen_rtx_PARALLEL (VOIDmode,
rtvec_alloc (num_restore + 2));
XVECEXP (restore_all, 0, 0) = gen_rtx_RETURN (VOIDmode);
@ -1862,8 +2002,9 @@ expand_epilogue (void)
= gen_rtx_SET (VOIDmode,
restore_regs[i],
gen_rtx_MEM (Pmode,
plus_constant (stack_pointer_rtx,
offset)));
gen_rtx_PLUS (Pmode,
stack_pointer_rtx,
GEN_INT(offset))));
offset -= 4;
}
@ -1893,12 +2034,6 @@ expand_epilogue (void)
insn = emit_jump_insn (restore_all);
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
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). */
if (!restore_all)
{
unsigned int init_stack_free;
/* 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;
else
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;
diff = actual_fsize - ((interrupt_handler) ? 0 : init_stack_free);
diff = actual_fsize - init_stack_free;
if (CONST_OK_FOR_K (diff))
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. */
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 ());
else
emit_insn (gen_restore_all_interrupt ());
@ -1948,7 +2087,7 @@ Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",
else
{
/* 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. */
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. */
if (interrupt_handler)
{
if (TARGET_V850E && ! TARGET_DISABLE_CALLT)
if (! TARGET_DISABLE_CALLT)
emit_insn (gen_callt_return_interrupt ());
else
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;
}
/* Update the condition code from the insn. */
void
notice_update_cc (rtx body, rtx insn)
{
@ -2026,7 +2163,7 @@ notice_update_cc (rtx body, rtx insn)
case CC_SET_ZNV:
/* 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.flags |= CC_NO_CARRY;
cc_status.value1 = recog_data.operand[0];
@ -2044,7 +2181,7 @@ notice_update_cc (rtx body, rtx insn)
break;
}
}
/* Retrieve the data area that has been chosen for the given decl. */
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
as well. The code has already verified that the RTL matches these
requirements. */
char *
construct_restore_jr (rtx op)
{
@ -2287,7 +2425,7 @@ construct_restore_jr (rtx op)
stack_bytes -= (count - 2) * 4;
/* 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);
return NULL;
@ -2319,8 +2457,6 @@ construct_restore_jr (rtx op)
/* Discover the last register to pop. */
if (mask & (1 << LINK_POINTER_REGNUM))
{
gcc_assert (stack_bytes == 16);
last = LINK_POINTER_REGNUM;
}
else
@ -2376,7 +2512,7 @@ construct_save_jarl (rtx op)
int i;
static char buff [100]; /* XXX */
if (count <= 2)
if (count <= (TARGET_LONG_CALLS ? 3 : 2))
{
error ("bogus JARL construction: %d\n", count);
return NULL;
@ -2396,7 +2532,7 @@ construct_save_jarl (rtx op)
stack_bytes += (count - (TARGET_LONG_CALLS ? 3 : 2)) * 4;
/* 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);
return NULL;
@ -2428,8 +2564,6 @@ construct_save_jarl (rtx op)
/* Discover the last register to push. */
if (mask & (1 << LINK_POINTER_REGNUM))
{
gcc_assert (stack_bytes == -16);
last = LINK_POINTER_REGNUM;
}
else
@ -2719,7 +2853,7 @@ construct_dispose_instruction (rtx op)
}
if (! TARGET_DISABLE_CALLT
&& (use_callt || stack_bytes == 0 || stack_bytes == 16))
&& (use_callt || stack_bytes == 0))
{
if (use_callt)
{
@ -2735,8 +2869,8 @@ construct_dispose_instruction (rtx op)
if (i == 31)
sprintf (buff, "callt ctoff(__callt_return_r31c)");
else
sprintf (buff, "callt ctoff(__callt_return_r%d_r%d%s)",
i, (mask & (1 << 31)) ? 31 : 29, stack_bytes ? "c" : "");
sprintf (buff, "callt ctoff(__callt_return_r%d_r%s)",
i, (mask & (1 << 31)) ? "31c" : "29");
}
}
else
@ -2789,16 +2923,16 @@ construct_dispose_instruction (rtx op)
char *
construct_prepare_instruction (rtx op)
{
int count = XVECLEN (op, 0);
int count;
int stack_bytes;
unsigned long int mask;
int i;
static char buff[ 100 ]; /* XXX */
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;
}
@ -2810,8 +2944,6 @@ construct_prepare_instruction (rtx op)
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
will fit into the DISPOSE instruction. */
@ -2822,11 +2954,15 @@ construct_prepare_instruction (rtx op)
}
/* Now compute the bit mask of registers to push. */
count = 0;
mask = 0;
for (i = 1; i < count; i++)
for (i = 1; i < XVECLEN (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 (SET_SRC (vector_element)) == REG);
gcc_assert (register_is_ok_for_epilogue (SET_SRC (vector_element),
@ -2836,10 +2972,13 @@ construct_prepare_instruction (rtx op)
use_callt = 1;
else
mask |= 1 << REGNO (SET_SRC (vector_element));
count++;
}
stack_bytes += count * 4;
if ((! TARGET_DISABLE_CALLT)
&& (use_callt || stack_bytes == 0 || stack_bytes == -16))
&& (use_callt || stack_bytes == 0))
{
if (use_callt)
{
@ -2854,8 +2993,8 @@ construct_prepare_instruction (rtx op)
if (i == 31)
sprintf (buff, "callt ctoff(__callt_save_r31c)");
else
sprintf (buff, "callt ctoff(__callt_save_r%d_r%d%s)",
i, (mask & (1 << 31)) ? 31 : 29, stack_bytes ? "c" : "");
sprintf (buff, "callt ctoff(__callt_save_r%d_r%s)",
i, (mask & (1 << 31)) ? "31c" : "29");
}
else
{
@ -2900,7 +3039,7 @@ construct_prepare_instruction (rtx op)
return buff;
}
/* Return an RTX indicating where the return address to the
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);
emit_move_insn (mem, fnaddr);
}
static int
v850_issue_rate (void)
{
return (TARGET_V850E2_ALL? 2 : 1);
}
#include "gt-v850.h"

View File

@ -22,8 +22,13 @@
#ifndef 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. */
#undef LIB_SPEC
#define LIB_SPEC "%{!shared:%{!symbolic:--start-group -lc -lgcc --end-group}}"
#undef ENDFILE_SPEC
#undef LINK_SPEC
#undef STARTFILE_SPEC
@ -31,7 +36,10 @@
#define TARGET_CPU_generic 1
#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
#define TARGET_CPU_DEFAULT TARGET_CPU_generic
@ -58,17 +66,42 @@
#if TARGET_CPU_DEFAULT == TARGET_CPU_v850e1
#undef MASK_DEFAULT
#define MASK_DEFAULT MASK_V850E /* No practical difference. */
#define MASK_DEFAULT MASK_V850E /* No practical difference. */
#undef SUBTARGET_ASM_SPEC
#define SUBTARGET_ASM_SPEC "%{!mv*:-mv850e1}"
#define SUBTARGET_ASM_SPEC "%{!mv*:-mv850e1}"
#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
#define TARGET_VERSION fprintf (stderr, " (NEC V850E1)");
#define TARGET_VERSION fprintf (stderr, " (NEC V850E1)");
#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 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 \
{ "subtarget_asm_spec", SUBTARGET_ASM_SPEC }, \
@ -76,7 +109,7 @@
/* Names to predefine in the preprocessor for this target machine. */
#define TARGET_CPU_CPP_BUILTINS() do { \
builtin_define( "__v851__" ); \
builtin_define( "__v851__" ); \
builtin_define( "__v850" ); \
builtin_assert( "machine=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) \
{ \
target_flags |= MASK_STRICT_ALIGN; \
if (LEVEL) \
/* Note - we no longer enable MASK_EP when optimizing. This is \
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
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.
@ -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,
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
and are not available for the register allocator. */
#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, 1, 0, \
1, 1, \
1, 1}
/* 1 for registers not available across function calls.
@ -233,10 +266,11 @@ extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max];
like. */
#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, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 1, 1, \
1, 1, \
1, 1}
/* 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 */ \
29, 28, 27, 26, 25, 24, 23, 22, /* saved registers */ \
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
the pool of fixed registers. See PR 14505. */
#define CONDITIONAL_REGISTER_USAGE \
{ \
if (!TARGET_APP_REGS) \
{ \
fixed_regs[2] = 1; call_used_regs[2] = 1; \
fixed_regs[5] = 1; call_used_regs[5] = 1; \
} \
}
#define CONDITIONAL_REGISTER_USAGE \
{ \
if (TARGET_APP_REGS) \
{ \
fixed_regs[2] = 0; call_used_regs[2] = 0; \
fixed_regs[5] = 0; call_used_regs[5] = 1; \
} \
}
/* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE.
@ -281,7 +317,7 @@ extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max];
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
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
{
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
@ -326,17 +362,18 @@ enum reg_class
/* Give names of register classes as strings for dump file. */
#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.
This is an initializer for a vector of HARD_REG_SET
of length N_REG_CLASSES. */
#define REG_CLASS_CONTENTS \
{ \
{ 0x00000000 }, /* NO_REGS */ \
{ 0xffffffff }, /* GENERAL_REGS */ \
{ 0xffffffff }, /* ALL_REGS */ \
#define REG_CLASS_CONTENTS \
{ \
{ 0x00000000,0x0 }, /* NO_REGS */ \
{ 0xffffffff,0x0 }, /* GENERAL_REGS */ \
{ 0x55555554,0x0 }, /* EVEN_REGS */ \
{ 0xffffffff,0x0 }, /* ALL_REGS */ \
}
/* The same information, inverted:
@ -344,7 +381,7 @@ enum reg_class
reg number REGNO. This could be a conditional expression
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. */
@ -353,7 +390,8 @@ enum reg_class
/* 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. */
@ -363,8 +401,11 @@ enum reg_class
Since they use reg_renumber, they are safe only once reg_renumber
has been allocated, which happens in local-alloc.c. */
#define REGNO_OK_FOR_BASE_P(regno) \
((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
#define REGNO_OK_FOR_BASE_P(regno) \
(((regno) < FIRST_PSEUDO_REGISTER \
&& (regno) != CC_REGNUM \
&& (regno) != FCC_REGNUM) \
|| reg_renumber[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. */
/* 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. */
#define FRAME_POINTER_REGNUM 32
#define FRAME_POINTER_REGNUM 34
/* 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
offset of the automatic variables is not known until after register
@ -501,7 +542,7 @@ enum reg_class
#define HARD_FRAME_POINTER_REGNUM 29
/* 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. */
#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
of mode MODE and data type TYPE.
(TYPE is null for libcalls where that information may not be available.) */
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
((CUM).nbytes += ((MODE) != BLKmode \
? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD \
: (int_size_in_bytes (TYPE) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD))
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
((CUM).nbytes += \
((((TYPE) && int_size_in_bytes (TYPE) > 8) \
? GET_MODE_SIZE (Pmode) \
: ((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
allocated for it. */
#define REG_PARM_STACK_SPACE(DECL) (!TARGET_GHS ? 16 : 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
#define REG_PARM_STACK_SPACE(DECL) 0
/* 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)) \
|| (GET_CODE (OP) == CONST \
&& 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)))) \
: (C) == 'W' ? (GET_CODE (OP) == CONST_INT \
&& ((unsigned)(INTVAL (OP)) >= 0x8000) \
&& ((unsigned)(INTVAL (OP)) < 0x400000)) \
: 0)
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
@ -765,7 +808,7 @@ do { \
goto ADDR; \
if (GET_CODE (X) == PLUS \
&& 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) \
&& CONST_OK_FOR_K (INTVAL (XEXP (X, 1)) \
+ (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), 1)) == CONST_INT \
&& ! 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. */
/* 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.
This sequence is indexed by compiler's hard-register-number (see above). */
#define REGISTER_NAMES \
{ "r0", "r1", "r2", "sp", "gp", "r5", "r6" , "r7", \
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
"r24", "r25", "r26", "r27", "r28", "r29", "ep", "r31", \
#define REGISTER_NAMES \
{ "r0", "r1", "r2", "sp", "gp", "r5", "r6" , "r7", \
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
"r24", "r25", "r26", "r27", "r28", "r29", "ep", "r31", \
"psw", "fcc", \
".fp", ".ap"}
#define ADDITIONAL_REGISTER_NAMES \
{ { "zero", 0 }, \
{ "hp", 2 }, \
{ "r3", 3 }, \
{ "r4", 4 }, \
{ "tp", 5 }, \
{ "fp", 29 }, \
{ "r30", 30 }, \
{ "lp", 31} }
/* Register numbers */
#define ADDITIONAL_REGISTER_NAMES \
{ { "zero", ZERO_REGNUM }, \
{ "hp", 2 }, \
{ "r3", 3 }, \
{ "r4", 4 }, \
{ "tp", 5 }, \
{ "fp", 29 }, \
{ "r30", 30 }, \
{ "lp", LP_REGNUM} }
#define ASM_OUTPUT_REG_PUSH(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"
opcode. Se casesi in v850.md. */
#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 ? "(" : ""), \
(0 && ! TARGET_BIG_SWITCH && (TARGET_V850E || TARGET_V850E2_ALL) ? "(" : ""), \
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) \
if ((LOG) != 0) \
@ -949,7 +1007,7 @@ typedef enum
/* The switch instruction requires that the jump table immediately follow
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. */
#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
#endif /* ! GCC_V850_H */

File diff suppressed because it is too large Load Diff

View File

@ -66,10 +66,14 @@ mtda
Target RejectNegative Joined
Set the max size of data eligible for the TDA area
mstrict-align
Target Report Mask(STRICT_ALIGN)
mno-strict-align
Target Report Mask(NO_STRICT_ALIGN)
Enforce strict alignment
mjump-tables-in-data-section
Target Report Mask(JUMP_TABLES_IN_DATA_SECTION)
Enforce table jump
mUS-bit-set
Target Report Mask(US_BIT_SET)
@ -82,9 +86,17 @@ Target Report RejectNegative Mask(V850E)
Compile for the v850e processor
mv850e1
Target RejectNegative Mask(V850E) MaskExists
Target RejectNegative Mask(V850E1)
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
Target RejectNegative Joined
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
-mapp-regs -mno-app-regs @gol
-mdisable-callt -mno-disable-callt @gol
-mv850e2v3 @gol
-mv850e2 @gol
-mv850e1 @gol
-mv850e @gol
-mv850 -mbig-switch}
@ -16957,11 +16959,21 @@ the compiler. This setting is the default.
@opindex mno-app-regs
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
@opindex mv850e1
Specify that the target processor is the V850E1. The preprocessor
constants @samp{__v850e1__} and @samp{__v850e__} will be defined if
this option is used.
@item -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.
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
relevant @samp{__v850*__} preprocessor constant will be defined.
@ -16978,7 +16991,7 @@ defined, regardless of which processor variant is the target.
@item -mdisable-callt
@opindex mdisable-callt
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.
@end table