backport: re PR target/12476 (ARM/THUMB thunk calls broken)
Merge from csl-arm-branch. 2004-01-30 Paul Brook <paul@codesourcery.com> * aof.h (REGISTER_NAMES): Add vfp reg names (ADDITIONAL_REGISTER_NAMES): Ditto. * aout.h (REGISTER_NAMES): Ditto. (ADDITIONAL_REGISTER_NAMES): Ditto. * arm-protos.h: Update/Add Prototypes. * arm.c (init_fp_table): Rename from init_fpa_table. Update users. Only allow 0.0 for VFP. (fp_consts_inited): Rename from fpa_consts_inited. Update users. (values_fp): Rename from values_fpa. Update Users. (arm_const_double_rtx): Rename from const_double_rtx_ok_for_fpa. Update users. Only check valid constants for this hardware. (arm_float_rhs_operand): Rename from fpa_rhs_operand. Update Users. Only allow consts for FPA. (arm_float_add_operand): Rename from fpa_add_operand. Update users. Only allow consts for FPA. (use_return_insn): Check for saved VFP regs. (arm_legitimate_address_p): Handle VFP DFmode addressing. (arm_legitimize_address): Ditto. (arm_general_register_operand): New function. (vfp_mem_operand): New function. (vfp_compare_operand): New function. (vfp_secondary_reload_class): New function. (arm_float_compare_operand): New function. (vfp_print_multi): New function. (vfp_output_fstmx): New function. (vfp_emit_fstm): New function. (arm_output_epilogue): Output VPF reg restore code. (arm_expand_prologue): Output VFP reg save code. (arm_print_operand): Add 'P'. (arm_hard_regno_mode_ok): Return modes for VFP regs. (arm_regno_class): Return classes for VFP regs. (arm_compute_initial_elimination_offset): Include space for VFP regs. (arm_get_frame_size): Ditto. * arm.h (FIXED_REGISTERS): Add VFP regs. (CALL_USED_REGISTERS): Ditto. (CONDITIONAL_REGISTER_USAGE): Enable VFP regs. (FIRST_VFP_REGNUM): Define. (LAST_VFP_REGNUM): Define. (IS_VFP_REGNUM): Define. (FIRST_PSEUDO_REGISTER): Include VFP regs. (HARD_REGNO_NREGS): Handle VFP regs. (REG_ALLOC_ORDER): Add VFP regs. (enum reg_class): Add VFP_REGS. (REG_CLASS_NAMES): Ditto. (REG_CLASS_CONTENTS): Ditto. (CANNOT_CHANGE_MODE_CLASS) Handle VFP Regs. (REG_CLASS_FROM_LETTER): Add 'w'. (EXTRA_CONSTRAINT_ARM): Add 'U'. (EXTRA_MEMORY_CONSTRAINT): Define. (SECONDARY_OUTPUT_RELOAD_CLASS): Handle VFP regs. (SECONDARY_INPUT_RELOAD_CLASS): Ditto. (REGISTER_MOVE_COST): Ditto. (PREDICATE_CODES): Add arm_general_register_operand, arm_float_compare_operand and vfp_compare_operand. * arm.md (various): Rename as above. (divsf3): Enable when TARGET_VFP. (divdf3): Ditto. (movdfcc): Ditto. (sqrtsf2): Ditto. (sqrtdf2): Ditto. (arm_movdi): Disable when TARGET_VFP. (arm_movsi_insn): Ditto. (movsi): Only split with general regs. (cmpsf): Use arm_float_compare_operand. (push_fp_multi): Restrict to TARGET_FPA. (vfp.md): Include. * vfp.md: New file. * fpa.md (various): Rename as above. * doc/md.texi: Document ARM w and U constraints. 2004-01-15 Paul Brook <paul@codesourcery.com> * config.gcc: Add with_fpu. Allow with-float=softfp. * config/arm/arm.c (arm_override_options): Rename *-s to *s. Break out of loop when we find a float-abi. Fix typo. * config/arm/arm.h (OPTION_DEFAULT_SPECS): Add "fpu". Set -mfloat-abi=. * doc/install.texi: Document --with-fpu. 2003-01-14 Paul Brook <paul@codesourcery.com> * config.gcc (with_arch): Add armv6. * config/arm/arm.h: Rename TARGET_CPU_*_s to TARGET_CPU_*s. * config/arm/arm.c (arm_overrride_options): Ditto. 2004-01-08 Richard Earnshaw <rearnsha@arm.com> * arm.c (FL_ARCH3M): Renamed from FL_FAST_MULT. (FL_ARCH6): Renamed from FL_ARCH6J. (arm_arch3m): Renamed from arm_fast_multiply. (arm_arch6): Renamed from arm_arch6j. * arm.h: Update all uses of above. * arm-cores.def: Likewise. * arm.md: Likewise. * arm.h (CPP_CPU_ARCH_SPEC): Emit __ARM_ARCH_6J__ define for armV6j, not arm6j. Add entry for arch armv6. 2004-01-07 Richard Earnshaw <rearnsha@arm.com> * arm.c (arm_emit_extendsi): Delete. * arm-protos.h (arm_emit_extendsi): Delete. * arm.md (zero_extendhisi2): Also handle zero-extension of non-subregs. (zero_extendqisi2, extendhisi2, extendqisi2): Likewise. (thumb_zero_extendhisi2): Only match if not v6. (arm_zero_extendhisi2, thumb_zero_extendqisi2, arm_zero_extendqisi2) (thumb_extendhisi2, arm_extendhisi2, arm_extendqisi) (thumb_extendqisi2): Likewise. (thumb_zero_extendhisi2_v6, arm_zero_extendhisi2_v6): New patterns. (thumb_zero_extendqisi2_v6, arm_zero_extendqisi2_v6): New patterns. (thumb_extendhisi2_insn_v6, arm_extendhisi2_v6): New patterns. (thumb_extendqisi2_v6, arm_extendqisi_v6): New patterns. (arm_zero_extendhisi2_reg, arm_zero_extendqisi2_reg): Delete. (arm_extendhisi2_reg, arm_extendqisi2_reg): Delete. (arm_zero_extendhisi2addsi): Remove subreg. Add attributes. (arm_zero_extendqisi2addsi, arm_extendhisi2addsi): Likewise. (arm_extendqisi2addsi): Likewise. 2003-12-31 Mark Mitchell <mark@codesourcery.com> Revert this change: * config/arm/arm.h (THUMB_LEGTITIMIZE_RELOAD_ADDRESS): Reload REG + REG addressing modes. * config/arm/arm.h (THUMB_LEGTITIMIZE_RELOAD_ADDRESS): Reload REG + REG addressing modes. 2003-12-30 Mark Mitchell <mark@codesourcery.com> * config/arm/arm.h (THUMB_LEGITIMATE_CONSTANT_P): Accept CONSTANT_P_RTX. 2003-30-12 Paul Brook <paul@codesourcery.com> * longlong.h: protect arm inlines with !defined (__thumb__) 2003-30-12 Paul Brook <paul@codesourcery.com> * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Always define __arm__. 2003-12-30 Nathan Sidwell <nathan@codesourcery.com> * builtins.c (expand_builtin_apply_args_1): Fix typo in previous change. 2003-12-29 Nathan Sidwell <nathan@codesourcery.com> * builtins.c (expand_builtin_apply_args_1): Add pretend args size to the virtual incoming args pointer for downward stacks. 2003-12-29 Paul Brook <paul@codesourcery.com> * config/arm/arm-cores.def: Add cost function. * config/arm/arm.c (arm_*_rtx_costs): New functions. (arm_rtx_costs): Remove (struct processors): Add rtx_costs field. (all_cores, all_architectures): Ditto. (arm_override_options): Set targetm.rtx_costs. (thumb_rtx_costs): New function. (arm_rtx_costs_1): Remove cases handled elsewhere. * config/arm/arm.h (processor_type): Add COSTS parameter. 2003-12-29 Nathan Sidwell <nathan@codesourcery.com> * config/arm/arm.md (generic_sched): arm926 has its own scheduler. (arm926ejs.md): Include it. * config/arm/arm926ejs.md: New pipeline description. 2003-12-24 Paul Brook <paul@codesourcery.com> * config/arm/arm.c (arm_arch6j): New variable. (arm_override_options): Set it. (arm_emit_extendsi): New function. * config/arm/arm-protos.h (arm_emit_extendsi): Add prototype. * config/arm/arm.h (arm_arch6j): Declare. * config/arm/arm.md: Add sign/zero extend insns. 2003-12-23 Paul Brook <paul@codesourcery.com> * config/arm/arm.c (all_architectures): Add armv6. * doc/invoke.texi: Document it. 2003-12-19 Paul Brook <paul@codesourcery.com> * config/arm/arm.md: Add load1 and load_byte "type" attrs. Modify insn patterns to match. * config/arm/arm-generic.md: Ditto. * config/arm/cirrus.md: Ditto. * config/arm/fpa.md: Ditto. * config/amm/iwmmxt.md: Ditto. * config/arm/arm1026ejs.md: Ditto. * config/arm/arm1135jfs.md: Ditto. Add insn_reservation and bypasses for 11_loadb. 2003-12-18 Nathan Sidwell <nathan@codesourcery.com> * config/arm/arm-protos.h (arm_no_early_alu_shift_value_dep): Declare. * config/arm/arm.c (arm_adjust_cost): Check shift cost for TYPE_ALU_SHIFT and TYPE_ALU_SHIFT_REG. (arm_no_early_store_addr_dep, arm_no_early_alu_shift_dep, arm_no_early_mul_dep): Correctly deal with conditional execution, parallels and single shift operations. (arm_no_early_alu_shift_value_dep): Define. * arm.md (attr type): Replace 'normal' with 'alu', 'alu_shift' and 'alu_shift_reg'. (attr core_cycles): Adjust. (*addsi3_carryin_shift, andsi_not_shiftsi_si, *arm_shiftsi3, *shiftsi3_compare0, *notsi_shiftsi, *notsi_shiftsi_compare0, *not_shiftsi_compare0_scratch, *cmpsi_shiftsi, *cmpsi_shiftsi_swp, *cmpsi_neg_shiftsi, *arith_shiftsi, *arith_shiftsi_compare0, *arith_shiftsi_compare0_scratch, *sub_shiftsi, *sub_shiftsi_compare0, *sub_shiftsi_compare0_scratch, *if_shift_move, *if_move_shift, *if_shift_shift): Set type attribute appropriately. * config/arm/arm1026ejs.md (alu_op): Adjust. (alu_shift_op, alu_shift_reg_op): New. * config/arm/arm1136.md: Add better bypasses for early registers. Remove load[234] and store[234] bypasses. (11_alu_op): Adjust. (11_alu_shift_op, 11_alu_shift_reg_op): New. 2003-12-15 Nathan Sidwell <nathan@codesourcery.com> * config/arm/arm-protos.h (arm_no_early_store_addr_dep, arm_no_early_alu_shift_dep, arm_no_early_mul_dep): Declare. * config/arm/arm.c (arm_no_early_store_addr_dep, arm_no_early_alu_shift_dep, arm_no_early_mul_dep): Define. * config/arm/arm1026ejs.md: Add load-store bypass. * config/arm/arm1136jfs.md (11_alu_op): Take 2 cycles. Add bypasses between instructions. 2003-12-10 Paul Brook <paul@codesourcery.com> * config/arm/arm.c (arm_fpu_model): New variable. (arm_fload_abi): New variable. (target_fpe_name): Rename from target_fp_name. (target_fpu_name): New variable. (arm_is_cirrus): Remove. (fpu_desc): New struct. (all_fpus): Define. (pf_model_for_fpu): Define. (all_loat_abis): Define. (arm_override_options): Set fp arch flags based on -mfpu= and -float-abi=. (FIRST_FPA_REGNUM): Rename from FIRST_ARM_FP_REGNUM. (LAST_FPA_REGNUM): Rename from LAST_ARM_FP_REGNUM. (*): Use new TARGET_* flags. * config/arm/arm.h (TARGET_ANY_HARD_FLOAT): Remove. (TARGET_HARD_FLOAT): No longer implies TARGET_FPA. (TARGET_SOFT_FLOAT): Ditto. (TARGET_SOFT_FLOAT_ABI): New. (TARGET_MAVERICK): Rename from TARGET_CIRRUS. No longer implies TARGET_HARD_FLOAT. (TARGET_VFP): No longer implies TARGET_HARD_FLOAT. (TARGET_OPTIONS): Add -mfpu=. (FIRST_FPA_REGNUM): Rename from FIRST_ARM_FP_REGNUM. (LAST_FPA_REGNUM): Rename from LAST_ARM_FP_REGNUM. (arm_pf_model): Define. (arm_float_abi_type): Define. (fputype): Add FPUTYPE_VFP. Change SOFT_FPA->NONE * config/arm/arm.md: Use new TARGET_* flags. * config/arm/cirrus.md: Ditto. * config/arm/fpa.md: Ditto. * config/arm/elf.h (ASM_SPEC): Pass -mfloat-abi= and -mfpu=. * config/arm/semi.h (ASM_SPEC): Ditto. * config/arm/netbsd-elf.h (SUBTARGET_ASM_FLOAT_SPEC): Specify vfp. (FPUTYPE_DEFAULT): Set to VFP. * doc/invoke.texi: Document -mfpu= and -mfloat-abi=. 2003-11-22 Phil Edwards <phil@codesourcery.com> PR target/12476 * config/arm/arm.c (arm_output_mi_thunk): In Thumb mode, use 'bx' instead of 'b' to avoid branch range restrictions. Output the thunk immediately before the thunked-to function. * config/arm/arm.h (ARM_DECLARE_FUNCTION_NAME): Do not emit .thumb_func if a thunk is being generated. Emit .code 16 along with .thumb_func if a thunk is not being generated. 2003-11-15 Nicolas Pitre <nico@cam.org> * config/arm/arm.md (ashldi3, arm_ashldi3_1bit, ashrdi3, arm_ashrdi3_1bit, lshrdi3, arm_lshrdi3_1bit): New patterns. * config/arm/iwmmxt.md (ashrdi3_iwmmxt): Renamed from ashrdi3. (lshrdi3_iwmmxt): Renamed from lshrdi3. * config/arm/arm.c (IWMMXT_BUILTIN2): Renamed argument accordingly. 2003-11-12 Steve Woodford <scw@wasabisystems.com> Ian Lance Taylor <ian@wasabisystems.com> * config/arm/lib1funcs.asm (ARM_DIV_BODY, ARM_MOD_BODY): Add new code for __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__). 2003-11-05 Phil Edwards <phil@codesourcery.com> * config/arm/arm.md (insn): Add new V6 instruction names. (generic_sched): New attr. * config/arm/arm-generic.md: Use generic_sched here. * config/arm/arm1026ejs.md: Do not model fetch/issue/decode stages of pipeline. Adjust latency counts accordingly. * config/arm/arm1136jfs.md: New file. 2003-10-28 Mark Mitchell <mark@codesourcery.com> * config/arm/arm.h (processor_type): New enumeration type. (CPP_ARCH_DEFAULT_SPEC): Set appropriately for ARM 926EJ-S, ARM1026EJ-S, ARM1136J-S, and ARM1136JF-S processor cores. (CPP_CPU_ARCH_SPEC): Likewise. * config/arm/arm.c (arm_tune): New variable. (all_cores): Use cores.def. (all_architectures): Add representative processor. (arm_override_options): Restructure way in which tuning information is deduced. * arm.md: Update "insn" and "type" attributes throughout. (insn): New attribute. (type): Compute "mult" from "insn" attribute. Add load2, load3, load4 alternatives. (arm automaton): Move to arm-generic.md. * config/arm/arm-cores.def: New file. * config/arm/arm-generic.md: Likewise. * config/arm/arm1026ejs.md: Likewise. From-SVN: r77171
This commit is contained in:
parent
e93f124e0a
commit
9b66ebb146
329
gcc/ChangeLog
329
gcc/ChangeLog
|
@ -1,3 +1,332 @@
|
|||
2004-02-02 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
Merge from csl-arm-branch.
|
||||
|
||||
2004-01-30 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* aof.h (REGISTER_NAMES): Add vfp reg names
|
||||
(ADDITIONAL_REGISTER_NAMES): Ditto.
|
||||
* aout.h (REGISTER_NAMES): Ditto.
|
||||
(ADDITIONAL_REGISTER_NAMES): Ditto.
|
||||
* arm-protos.h: Update/Add Prototypes.
|
||||
* arm.c (init_fp_table): Rename from init_fpa_table. Update users.
|
||||
Only allow 0.0 for VFP.
|
||||
(fp_consts_inited): Rename from fpa_consts_inited. Update users.
|
||||
(values_fp): Rename from values_fpa. Update Users.
|
||||
(arm_const_double_rtx): Rename from const_double_rtx_ok_for_fpa.
|
||||
Update users. Only check valid constants for this hardware.
|
||||
(arm_float_rhs_operand): Rename from fpa_rhs_operand. Update Users.
|
||||
Only allow consts for FPA.
|
||||
(arm_float_add_operand): Rename from fpa_add_operand. Update users.
|
||||
Only allow consts for FPA.
|
||||
(use_return_insn): Check for saved VFP regs.
|
||||
(arm_legitimate_address_p): Handle VFP DFmode addressing.
|
||||
(arm_legitimize_address): Ditto.
|
||||
(arm_general_register_operand): New function.
|
||||
(vfp_mem_operand): New function.
|
||||
(vfp_compare_operand): New function.
|
||||
(vfp_secondary_reload_class): New function.
|
||||
(arm_float_compare_operand): New function.
|
||||
(vfp_print_multi): New function.
|
||||
(vfp_output_fstmx): New function.
|
||||
(vfp_emit_fstm): New function.
|
||||
(arm_output_epilogue): Output VPF reg restore code.
|
||||
(arm_expand_prologue): Output VFP reg save code.
|
||||
(arm_print_operand): Add 'P'.
|
||||
(arm_hard_regno_mode_ok): Return modes for VFP regs.
|
||||
(arm_regno_class): Return classes for VFP regs.
|
||||
(arm_compute_initial_elimination_offset): Include space for VFP regs.
|
||||
(arm_get_frame_size): Ditto.
|
||||
* arm.h (FIXED_REGISTERS): Add VFP regs.
|
||||
(CALL_USED_REGISTERS): Ditto.
|
||||
(CONDITIONAL_REGISTER_USAGE): Enable VFP regs.
|
||||
(FIRST_VFP_REGNUM): Define.
|
||||
(LAST_VFP_REGNUM): Define.
|
||||
(IS_VFP_REGNUM): Define.
|
||||
(FIRST_PSEUDO_REGISTER): Include VFP regs.
|
||||
(HARD_REGNO_NREGS): Handle VFP regs.
|
||||
(REG_ALLOC_ORDER): Add VFP regs.
|
||||
(enum reg_class): Add VFP_REGS.
|
||||
(REG_CLASS_NAMES): Ditto.
|
||||
(REG_CLASS_CONTENTS): Ditto.
|
||||
(CANNOT_CHANGE_MODE_CLASS) Handle VFP Regs.
|
||||
(REG_CLASS_FROM_LETTER): Add 'w'.
|
||||
(EXTRA_CONSTRAINT_ARM): Add 'U'.
|
||||
(EXTRA_MEMORY_CONSTRAINT): Define.
|
||||
(SECONDARY_OUTPUT_RELOAD_CLASS): Handle VFP regs.
|
||||
(SECONDARY_INPUT_RELOAD_CLASS): Ditto.
|
||||
(REGISTER_MOVE_COST): Ditto.
|
||||
(PREDICATE_CODES): Add arm_general_register_operand,
|
||||
arm_float_compare_operand and vfp_compare_operand.
|
||||
* arm.md (various): Rename as above.
|
||||
(divsf3): Enable when TARGET_VFP.
|
||||
(divdf3): Ditto.
|
||||
(movdfcc): Ditto.
|
||||
(sqrtsf2): Ditto.
|
||||
(sqrtdf2): Ditto.
|
||||
(arm_movdi): Disable when TARGET_VFP.
|
||||
(arm_movsi_insn): Ditto.
|
||||
(movsi): Only split with general regs.
|
||||
(cmpsf): Use arm_float_compare_operand.
|
||||
(push_fp_multi): Restrict to TARGET_FPA.
|
||||
(vfp.md): Include.
|
||||
* vfp.md: New file.
|
||||
* fpa.md (various): Rename as above.
|
||||
* doc/md.texi: Document ARM w and U constraints.
|
||||
|
||||
2004-01-15 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* config.gcc: Add with_fpu. Allow with-float=softfp.
|
||||
* config/arm/arm.c (arm_override_options): Rename *-s to *s.
|
||||
Break out of loop when we find a float-abi. Fix typo.
|
||||
* config/arm/arm.h (OPTION_DEFAULT_SPECS): Add "fpu".
|
||||
Set -mfloat-abi=.
|
||||
* doc/install.texi: Document --with-fpu.
|
||||
|
||||
2003-01-14 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* config.gcc (with_arch): Add armv6.
|
||||
* config/arm/arm.h: Rename TARGET_CPU_*_s to TARGET_CPU_*s.
|
||||
* config/arm/arm.c (arm_overrride_options): Ditto.
|
||||
|
||||
2004-01-08 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* arm.c (FL_ARCH3M): Renamed from FL_FAST_MULT.
|
||||
(FL_ARCH6): Renamed from FL_ARCH6J.
|
||||
(arm_arch3m): Renamed from arm_fast_multiply.
|
||||
(arm_arch6): Renamed from arm_arch6j.
|
||||
* arm.h: Update all uses of above.
|
||||
* arm-cores.def: Likewise.
|
||||
* arm.md: Likewise.
|
||||
|
||||
* arm.h (CPP_CPU_ARCH_SPEC): Emit __ARM_ARCH_6J__ define for armV6j,
|
||||
not arm6j. Add entry for arch armv6.
|
||||
|
||||
2004-01-07 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* arm.c (arm_emit_extendsi): Delete.
|
||||
* arm-protos.h (arm_emit_extendsi): Delete.
|
||||
* arm.md (zero_extendhisi2): Also handle zero-extension of
|
||||
non-subregs.
|
||||
(zero_extendqisi2, extendhisi2, extendqisi2): Likewise.
|
||||
(thumb_zero_extendhisi2): Only match if not v6.
|
||||
(arm_zero_extendhisi2, thumb_zero_extendqisi2, arm_zero_extendqisi2)
|
||||
(thumb_extendhisi2, arm_extendhisi2, arm_extendqisi)
|
||||
(thumb_extendqisi2): Likewise.
|
||||
(thumb_zero_extendhisi2_v6, arm_zero_extendhisi2_v6): New patterns.
|
||||
(thumb_zero_extendqisi2_v6, arm_zero_extendqisi2_v6): New patterns.
|
||||
(thumb_extendhisi2_insn_v6, arm_extendhisi2_v6): New patterns.
|
||||
(thumb_extendqisi2_v6, arm_extendqisi_v6): New patterns.
|
||||
(arm_zero_extendhisi2_reg, arm_zero_extendqisi2_reg): Delete.
|
||||
(arm_extendhisi2_reg, arm_extendqisi2_reg): Delete.
|
||||
(arm_zero_extendhisi2addsi): Remove subreg. Add attributes.
|
||||
(arm_zero_extendqisi2addsi, arm_extendhisi2addsi): Likewise.
|
||||
(arm_extendqisi2addsi): Likewise.
|
||||
|
||||
2003-12-31 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
Revert this change:
|
||||
* config/arm/arm.h (THUMB_LEGTITIMIZE_RELOAD_ADDRESS): Reload REG
|
||||
+ REG addressing modes.
|
||||
|
||||
* config/arm/arm.h (THUMB_LEGTITIMIZE_RELOAD_ADDRESS): Reload REG
|
||||
+ REG addressing modes.
|
||||
|
||||
2003-12-30 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* config/arm/arm.h (THUMB_LEGITIMATE_CONSTANT_P): Accept
|
||||
CONSTANT_P_RTX.
|
||||
|
||||
2003-30-12 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* longlong.h: protect arm inlines with !defined (__thumb__)
|
||||
|
||||
2003-30-12 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Always define __arm__.
|
||||
|
||||
2003-12-30 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* builtins.c (expand_builtin_apply_args_1): Fix typo in previous
|
||||
change.
|
||||
|
||||
2003-12-29 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* builtins.c (expand_builtin_apply_args_1): Add pretend args size
|
||||
to the virtual incoming args pointer for downward stacks.
|
||||
|
||||
2003-12-29 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* config/arm/arm-cores.def: Add cost function.
|
||||
* config/arm/arm.c (arm_*_rtx_costs): New functions.
|
||||
(arm_rtx_costs): Remove
|
||||
(struct processors): Add rtx_costs field.
|
||||
(all_cores, all_architectures): Ditto.
|
||||
(arm_override_options): Set targetm.rtx_costs.
|
||||
(thumb_rtx_costs): New function.
|
||||
(arm_rtx_costs_1): Remove cases handled elsewhere.
|
||||
* config/arm/arm.h (processor_type): Add COSTS parameter.
|
||||
|
||||
2003-12-29 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* config/arm/arm.md (generic_sched): arm926 has its own scheduler.
|
||||
(arm926ejs.md): Include it.
|
||||
* config/arm/arm926ejs.md: New pipeline description.
|
||||
|
||||
2003-12-24 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* config/arm/arm.c (arm_arch6j): New variable.
|
||||
(arm_override_options): Set it.
|
||||
(arm_emit_extendsi): New function.
|
||||
* config/arm/arm-protos.h (arm_emit_extendsi): Add prototype.
|
||||
* config/arm/arm.h (arm_arch6j): Declare.
|
||||
* config/arm/arm.md: Add sign/zero extend insns.
|
||||
|
||||
2003-12-23 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* config/arm/arm.c (all_architectures): Add armv6.
|
||||
* doc/invoke.texi: Document it.
|
||||
|
||||
2003-12-19 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* config/arm/arm.md: Add load1 and load_byte "type" attrs. Modify
|
||||
insn patterns to match.
|
||||
* config/arm/arm-generic.md: Ditto.
|
||||
* config/arm/cirrus.md: Ditto.
|
||||
* config/arm/fpa.md: Ditto.
|
||||
* config/amm/iwmmxt.md: Ditto.
|
||||
* config/arm/arm1026ejs.md: Ditto.
|
||||
* config/arm/arm1135jfs.md: Ditto. Add insn_reservation and bypasses
|
||||
for 11_loadb.
|
||||
|
||||
2003-12-18 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* config/arm/arm-protos.h (arm_no_early_alu_shift_value_dep): Declare.
|
||||
* config/arm/arm.c (arm_adjust_cost): Check shift cost for
|
||||
TYPE_ALU_SHIFT and TYPE_ALU_SHIFT_REG.
|
||||
(arm_no_early_store_addr_dep, arm_no_early_alu_shift_dep,
|
||||
arm_no_early_mul_dep): Correctly deal with conditional execution,
|
||||
parallels and single shift operations.
|
||||
(arm_no_early_alu_shift_value_dep): Define.
|
||||
* arm.md (attr type): Replace 'normal' with 'alu',
|
||||
'alu_shift' and 'alu_shift_reg'.
|
||||
(attr core_cycles): Adjust.
|
||||
(*addsi3_carryin_shift, andsi_not_shiftsi_si, *arm_shiftsi3,
|
||||
*shiftsi3_compare0, *notsi_shiftsi, *notsi_shiftsi_compare0,
|
||||
*not_shiftsi_compare0_scratch, *cmpsi_shiftsi, *cmpsi_shiftsi_swp,
|
||||
*cmpsi_neg_shiftsi, *arith_shiftsi, *arith_shiftsi_compare0,
|
||||
*arith_shiftsi_compare0_scratch, *sub_shiftsi,
|
||||
*sub_shiftsi_compare0, *sub_shiftsi_compare0_scratch,
|
||||
*if_shift_move, *if_move_shift, *if_shift_shift): Set type
|
||||
attribute appropriately.
|
||||
* config/arm/arm1026ejs.md (alu_op): Adjust.
|
||||
(alu_shift_op, alu_shift_reg_op): New.
|
||||
* config/arm/arm1136.md: Add better bypasses for early
|
||||
registers. Remove load[234] and store[234] bypasses.
|
||||
(11_alu_op): Adjust.
|
||||
(11_alu_shift_op, 11_alu_shift_reg_op): New.
|
||||
|
||||
2003-12-15 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* config/arm/arm-protos.h (arm_no_early_store_addr_dep,
|
||||
arm_no_early_alu_shift_dep, arm_no_early_mul_dep): Declare.
|
||||
* config/arm/arm.c (arm_no_early_store_addr_dep,
|
||||
arm_no_early_alu_shift_dep, arm_no_early_mul_dep): Define.
|
||||
* config/arm/arm1026ejs.md: Add load-store bypass.
|
||||
* config/arm/arm1136jfs.md (11_alu_op): Take 2 cycles.
|
||||
Add bypasses between instructions.
|
||||
|
||||
2003-12-10 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* config/arm/arm.c (arm_fpu_model): New variable.
|
||||
(arm_fload_abi): New variable.
|
||||
(target_fpe_name): Rename from target_fp_name.
|
||||
(target_fpu_name): New variable.
|
||||
(arm_is_cirrus): Remove.
|
||||
(fpu_desc): New struct.
|
||||
(all_fpus): Define.
|
||||
(pf_model_for_fpu): Define.
|
||||
(all_loat_abis): Define.
|
||||
(arm_override_options): Set fp arch flags based on -mfpu=
|
||||
and -float-abi=.
|
||||
(FIRST_FPA_REGNUM): Rename from FIRST_ARM_FP_REGNUM.
|
||||
(LAST_FPA_REGNUM): Rename from LAST_ARM_FP_REGNUM.
|
||||
(*): Use new TARGET_* flags.
|
||||
* config/arm/arm.h (TARGET_ANY_HARD_FLOAT): Remove.
|
||||
(TARGET_HARD_FLOAT): No longer implies TARGET_FPA.
|
||||
(TARGET_SOFT_FLOAT): Ditto.
|
||||
(TARGET_SOFT_FLOAT_ABI): New.
|
||||
(TARGET_MAVERICK): Rename from TARGET_CIRRUS. No longer implies
|
||||
TARGET_HARD_FLOAT.
|
||||
(TARGET_VFP): No longer implies TARGET_HARD_FLOAT.
|
||||
(TARGET_OPTIONS): Add -mfpu=.
|
||||
(FIRST_FPA_REGNUM): Rename from FIRST_ARM_FP_REGNUM.
|
||||
(LAST_FPA_REGNUM): Rename from LAST_ARM_FP_REGNUM.
|
||||
(arm_pf_model): Define.
|
||||
(arm_float_abi_type): Define.
|
||||
(fputype): Add FPUTYPE_VFP. Change SOFT_FPA->NONE
|
||||
* config/arm/arm.md: Use new TARGET_* flags.
|
||||
* config/arm/cirrus.md: Ditto.
|
||||
* config/arm/fpa.md: Ditto.
|
||||
* config/arm/elf.h (ASM_SPEC): Pass -mfloat-abi= and -mfpu=.
|
||||
* config/arm/semi.h (ASM_SPEC): Ditto.
|
||||
* config/arm/netbsd-elf.h (SUBTARGET_ASM_FLOAT_SPEC): Specify vfp.
|
||||
(FPUTYPE_DEFAULT): Set to VFP.
|
||||
* doc/invoke.texi: Document -mfpu= and -mfloat-abi=.
|
||||
|
||||
2003-11-22 Phil Edwards <phil@codesourcery.com>
|
||||
|
||||
PR target/12476
|
||||
* config/arm/arm.c (arm_output_mi_thunk): In Thumb mode, use
|
||||
'bx' instead of 'b' to avoid branch range restrictions. Output
|
||||
the thunk immediately before the thunked-to function.
|
||||
* config/arm/arm.h (ARM_DECLARE_FUNCTION_NAME): Do not emit
|
||||
.thumb_func if a thunk is being generated. Emit .code 16 along
|
||||
with .thumb_func if a thunk is not being generated.
|
||||
|
||||
2003-11-15 Nicolas Pitre <nico@cam.org>
|
||||
|
||||
* config/arm/arm.md (ashldi3, arm_ashldi3_1bit, ashrdi3,
|
||||
arm_ashrdi3_1bit, lshrdi3, arm_lshrdi3_1bit): New patterns.
|
||||
* config/arm/iwmmxt.md (ashrdi3_iwmmxt): Renamed from ashrdi3.
|
||||
(lshrdi3_iwmmxt): Renamed from lshrdi3.
|
||||
* config/arm/arm.c (IWMMXT_BUILTIN2): Renamed argument accordingly.
|
||||
|
||||
2003-11-12 Steve Woodford <scw@wasabisystems.com>
|
||||
Ian Lance Taylor <ian@wasabisystems.com>
|
||||
|
||||
* config/arm/lib1funcs.asm (ARM_DIV_BODY, ARM_MOD_BODY): Add new
|
||||
code for __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__).
|
||||
|
||||
2003-11-05 Phil Edwards <phil@codesourcery.com>
|
||||
|
||||
* config/arm/arm.md (insn): Add new V6 instruction names.
|
||||
(generic_sched): New attr.
|
||||
* config/arm/arm-generic.md: Use generic_sched here.
|
||||
* config/arm/arm1026ejs.md: Do not model fetch/issue/decode
|
||||
stages of pipeline. Adjust latency counts accordingly.
|
||||
* config/arm/arm1136jfs.md: New file.
|
||||
|
||||
2003-10-28 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* config/arm/arm.h (processor_type): New enumeration type.
|
||||
(CPP_ARCH_DEFAULT_SPEC): Set appropriately for ARM 926EJ-S,
|
||||
ARM1026EJ-S, ARM1136J-S, and ARM1136JF-S processor cores.
|
||||
(CPP_CPU_ARCH_SPEC): Likewise.
|
||||
* config/arm/arm.c (arm_tune): New variable.
|
||||
(all_cores): Use cores.def.
|
||||
(all_architectures): Add representative processor.
|
||||
(arm_override_options): Restructure way in which tuning
|
||||
information is deduced.
|
||||
* arm.md: Update "insn" and "type" attributes throughout.
|
||||
(insn): New attribute.
|
||||
(type): Compute "mult" from "insn" attribute. Add load2,
|
||||
load3, load4 alternatives.
|
||||
(arm automaton): Move to arm-generic.md.
|
||||
* config/arm/arm-cores.def: New file.
|
||||
* config/arm/arm-generic.md: Likewise.
|
||||
* config/arm/arm1026ejs.md: Likewise.
|
||||
|
||||
2004-02-03 Eric Botcazou <ebotcazou@libertysurf.fr>
|
||||
|
||||
* doc/invoke.texi (SPARC options): Remove -mflat and
|
||||
|
|
|
@ -2399,7 +2399,7 @@ fi
|
|||
;;
|
||||
|
||||
arm*-*-*)
|
||||
supported_defaults="arch cpu float tune"
|
||||
supported_defaults="arch cpu float tune fpu"
|
||||
for which in cpu tune; do
|
||||
eval "val=\$with_$which"
|
||||
case "$val" in
|
||||
|
@ -2426,7 +2426,7 @@ fi
|
|||
|
||||
case "$with_arch" in
|
||||
"" \
|
||||
| armv[2345] | armv2a | armv3m | armv4t | armv5t \
|
||||
| armv[23456] | armv2a | armv3m | armv4t | armv5t \
|
||||
| armv5te | armv6j | ep9312)
|
||||
# OK
|
||||
;;
|
||||
|
@ -2438,7 +2438,7 @@ fi
|
|||
|
||||
case "$with_float" in
|
||||
"" \
|
||||
| soft | hard)
|
||||
| soft | hard | softfp)
|
||||
# OK
|
||||
;;
|
||||
*)
|
||||
|
@ -2447,6 +2447,17 @@ fi
|
|||
;;
|
||||
esac
|
||||
|
||||
case "$with_fpu" in
|
||||
"" \
|
||||
| fpa | fpe2 | fpe3 | maverick | vfp )
|
||||
# OK
|
||||
;;
|
||||
*)
|
||||
echo "Unknown fpu used in --with-fpu=$fpu" 2>&1
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "x$with_arch" != x && test "x$with_cpu" != x; then
|
||||
echo "Warning: --with-arch overrides --with-cpu" 1>&2
|
||||
fi
|
||||
|
@ -2737,7 +2748,7 @@ fi
|
|||
esac
|
||||
|
||||
t=
|
||||
all_defaults="abi cpu arch tune schedule float mode"
|
||||
all_defaults="abi cpu arch tune schedule float mode fpu"
|
||||
for option in $all_defaults
|
||||
do
|
||||
eval "val=\$with_$option"
|
||||
|
|
|
@ -246,7 +246,12 @@ do { \
|
|||
"wr0", "wr1", "wr2", "wr3", \
|
||||
"wr4", "wr5", "wr6", "wr7", \
|
||||
"wr8", "wr9", "wr10", "wr11", \
|
||||
"wr12", "wr13", "wr14", "wr15" \
|
||||
"wr12", "wr13", "wr14", "wr15", \
|
||||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
|
||||
"s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", \
|
||||
"s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", \
|
||||
"s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", \
|
||||
"vfpcc"
|
||||
}
|
||||
|
||||
#define ADDITIONAL_REGISTER_NAMES \
|
||||
|
@ -267,6 +272,22 @@ do { \
|
|||
{"r13", 13}, {"sp", 13}, \
|
||||
{"r14", 14}, {"lr", 14}, \
|
||||
{"r15", 15}, {"pc", 15} \
|
||||
{"d0", 63}, \
|
||||
{"d1", 65}, \
|
||||
{"d2", 67}, \
|
||||
{"d3", 69}, \
|
||||
{"d4", 71}, \
|
||||
{"d5", 73}, \
|
||||
{"d6", 75}, \
|
||||
{"d7", 77}, \
|
||||
{"d8", 79}, \
|
||||
{"d9", 81}, \
|
||||
{"d10", 83}, \
|
||||
{"d11", 85}, \
|
||||
{"d12", 87}, \
|
||||
{"d13", 89}, \
|
||||
{"d14", 91}, \
|
||||
{"d15", 93}, \
|
||||
}
|
||||
|
||||
#define REGISTER_PREFIX "__"
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
|
||||
/* The assembler's names for the registers. */
|
||||
#ifndef REGISTER_NAMES
|
||||
#define REGISTER_NAMES \
|
||||
#define REGISTER_NAMES \
|
||||
{ \
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
|
||||
"r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc", \
|
||||
|
@ -63,7 +63,12 @@
|
|||
"wr0", "wr1", "wr2", "wr3", \
|
||||
"wr4", "wr5", "wr6", "wr7", \
|
||||
"wr8", "wr9", "wr10", "wr11", \
|
||||
"wr12", "wr13", "wr14", "wr15" \
|
||||
"wr12", "wr13", "wr14", "wr15", \
|
||||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
|
||||
"s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", \
|
||||
"s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", \
|
||||
"s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", \
|
||||
"vfpcc" \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -152,7 +157,23 @@
|
|||
{"mvdx12", 39}, \
|
||||
{"mvdx13", 40}, \
|
||||
{"mvdx14", 41}, \
|
||||
{"mvdx15", 42} \
|
||||
{"mvdx15", 42}, \
|
||||
{"d0", 63}, \
|
||||
{"d1", 65}, \
|
||||
{"d2", 67}, \
|
||||
{"d3", 69}, \
|
||||
{"d4", 71}, \
|
||||
{"d5", 73}, \
|
||||
{"d6", 75}, \
|
||||
{"d7", 77}, \
|
||||
{"d8", 79}, \
|
||||
{"d9", 81}, \
|
||||
{"d10", 83}, \
|
||||
{"d11", 85}, \
|
||||
{"d12", 87}, \
|
||||
{"d13", 89}, \
|
||||
{"d14", 91}, \
|
||||
{"d15", 93}, \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/* ARM CPU Cores
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Written by CodeSourcery, LLC
|
||||
|
||||
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. */
|
||||
|
||||
/* Before using #include to read this file, define a macro:
|
||||
|
||||
ARM_CORE(CORE_NAME, FLAGS)
|
||||
|
||||
The CORE_NAME is the name of the core, represented as an identifier
|
||||
rather than a string constant. The FLAGS are the bitwise-or of the
|
||||
traits that apply to that core.
|
||||
|
||||
If you update this table, you must update the "tune" attribue in
|
||||
arm.md. */
|
||||
|
||||
ARM_CORE(arm2, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE(arm250, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE(arm3, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE(arm6, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
|
||||
ARM_CORE(arm60, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
|
||||
ARM_CORE(arm600, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
|
||||
ARM_CORE(arm610, FL_MODE26 | FL_MODE32, slowmul)
|
||||
ARM_CORE(arm620, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
|
||||
ARM_CORE(arm7, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
|
||||
/* arm7m doesn't exist on its own, but only with D, (and I), but
|
||||
those don't alter the code, so arm7m is sometimes used. */
|
||||
ARM_CORE(arm7m, FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_ARCH3M, fastmul)
|
||||
ARM_CORE(arm7d, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
|
||||
ARM_CORE(arm7dm, FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_ARCH3M, fastmul)
|
||||
ARM_CORE(arm7di, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
|
||||
ARM_CORE(arm7dmi, FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_ARCH3M, fastmul)
|
||||
ARM_CORE(arm70, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
|
||||
ARM_CORE(arm700, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
|
||||
ARM_CORE(arm700i, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
|
||||
ARM_CORE(arm710, FL_MODE26 | FL_MODE32, slowmul)
|
||||
ARM_CORE(arm720, FL_MODE26 | FL_MODE32, slowmul)
|
||||
ARM_CORE(arm710c, FL_MODE26 | FL_MODE32, slowmul)
|
||||
ARM_CORE(arm7100, FL_MODE26 | FL_MODE32, slowmul)
|
||||
ARM_CORE(arm7500, FL_MODE26 | FL_MODE32, slowmul)
|
||||
/* Doesn't have an external co-proc, but does have embedded fpa. */
|
||||
ARM_CORE(arm7500fe, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
|
||||
/* V4 Architecture Processors */
|
||||
ARM_CORE(arm7tdmi, FL_CO_PROC | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB, fastmul)
|
||||
ARM_CORE(arm710t, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB, fastmul)
|
||||
ARM_CORE(arm720t, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB, fastmul)
|
||||
ARM_CORE(arm740t, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB, fastmul)
|
||||
ARM_CORE(arm8, FL_MODE26 | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED, fastmul)
|
||||
ARM_CORE(arm810, FL_MODE26 | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED, fastmul)
|
||||
ARM_CORE(arm9, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED, fastmul)
|
||||
ARM_CORE(arm920, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED, fastmul)
|
||||
ARM_CORE(arm920t, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED, fastmul)
|
||||
ARM_CORE(arm940t, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED, fastmul)
|
||||
ARM_CORE(arm9tdmi, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED, fastmul)
|
||||
ARM_CORE(arm9e, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED, 9e)
|
||||
|
||||
ARM_CORE(ep9312, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED | FL_CIRRUS, fastmul)
|
||||
ARM_CORE(strongarm, FL_MODE26 | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED | FL_STRONG, fastmul)
|
||||
ARM_CORE(strongarm110, FL_MODE26 | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED | FL_STRONG, fastmul)
|
||||
ARM_CORE(strongarm1100, FL_MODE26 | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED | FL_STRONG, fastmul)
|
||||
ARM_CORE(strongarm1110, FL_MODE26 | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED | FL_STRONG, fastmul)
|
||||
/* V5 Architecture Processors */
|
||||
ARM_CORE(arm10tdmi, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_ARCH5, fastmul)
|
||||
ARM_CORE(arm1020t, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_ARCH5, fastmul)
|
||||
ARM_CORE(arm926ejs, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E, 9e)
|
||||
ARM_CORE(arm1026ejs, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E, 9e)
|
||||
ARM_CORE(xscale, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_ARCH5 | FL_ARCH5E | FL_XSCALE, xscale)
|
||||
ARM_CORE(iwmmxt, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_ARCH5 | FL_ARCH5E | FL_XSCALE | FL_IWMMXT, xscale)
|
||||
/* V6 Architecture Processors */
|
||||
ARM_CORE(arm1136js, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E | FL_ARCH6, 9e)
|
||||
ARM_CORE(arm1136jfs, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E | FL_ARCH6 | FL_VFPV2, 9e)
|
|
@ -0,0 +1,152 @@
|
|||
;; Generic ARM Pipeline Description
|
||||
;; Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; 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. */
|
||||
|
||||
(define_automaton "arm")
|
||||
|
||||
;; Write buffer
|
||||
;
|
||||
; Strictly, we should model a 4-deep write buffer for ARM7xx based chips
|
||||
;
|
||||
; The write buffer on some of the arm6 processors is hard to model exactly.
|
||||
; There is room in the buffer for up to two addresses and up to eight words
|
||||
; of memory, but the two needn't be split evenly. When writing the two
|
||||
; addresses are fully pipelined. However, a read from memory that is not
|
||||
; currently in the cache will block until the writes have completed.
|
||||
; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so
|
||||
; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
|
||||
; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
|
||||
; cycle to add as well.
|
||||
(define_cpu_unit "write_buf" "arm")
|
||||
|
||||
;; Write blockage unit
|
||||
;
|
||||
; The write_blockage unit models (partially), the fact that reads will stall
|
||||
; until the write buffer empties.
|
||||
; The f_mem_r and r_mem_f could also block, but they are to the stack,
|
||||
; so we don't model them here
|
||||
(define_cpu_unit "write_blockage" "arm")
|
||||
|
||||
;; Core
|
||||
;
|
||||
(define_cpu_unit "core" "arm")
|
||||
|
||||
(define_insn_reservation "r_mem_f_wbuf" 5
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "model_wbuf" "yes")
|
||||
(eq_attr "type" "r_mem_f")))
|
||||
"core+write_buf*3")
|
||||
|
||||
(define_insn_reservation "store_wbuf" 5
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "model_wbuf" "yes")
|
||||
(eq_attr "type" "store1")))
|
||||
"core+write_buf*3+write_blockage*5")
|
||||
|
||||
(define_insn_reservation "store2_wbuf" 7
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "model_wbuf" "yes")
|
||||
(eq_attr "type" "store2")))
|
||||
"core+write_buf*4+write_blockage*7")
|
||||
|
||||
(define_insn_reservation "store3_wbuf" 9
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "model_wbuf" "yes")
|
||||
(eq_attr "type" "store3")))
|
||||
"core+write_buf*5+write_blockage*9")
|
||||
|
||||
(define_insn_reservation "store4_wbuf" 11
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "model_wbuf" "yes")
|
||||
(eq_attr "type" "store4")))
|
||||
"core+write_buf*6+write_blockage*11")
|
||||
|
||||
(define_insn_reservation "store2" 3
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "model_wbuf" "no")
|
||||
(eq_attr "type" "store2")))
|
||||
"core*3")
|
||||
|
||||
(define_insn_reservation "store3" 4
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "model_wbuf" "no")
|
||||
(eq_attr "type" "store3")))
|
||||
"core*4")
|
||||
|
||||
(define_insn_reservation "store4" 5
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "model_wbuf" "no")
|
||||
(eq_attr "type" "store4")))
|
||||
"core*5")
|
||||
|
||||
(define_insn_reservation "store_ldsched" 1
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "ldsched" "yes")
|
||||
(eq_attr "type" "store1")))
|
||||
"core")
|
||||
|
||||
(define_insn_reservation "load_ldsched_xscale" 3
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "ldsched" "yes")
|
||||
(and (eq_attr "type" "load_byte,load1")
|
||||
(eq_attr "is_xscale" "yes"))))
|
||||
"core")
|
||||
|
||||
(define_insn_reservation "load_ldsched" 2
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "ldsched" "yes")
|
||||
(and (eq_attr "type" "load_byte,load1")
|
||||
(eq_attr "is_xscale" "no"))))
|
||||
"core")
|
||||
|
||||
(define_insn_reservation "load_or_store" 2
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "ldsched" "!yes")
|
||||
(eq_attr "type" "load_byte,load1,load2,load3,load4,store1")))
|
||||
"core*2")
|
||||
|
||||
(define_insn_reservation "mult" 16
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "ldsched" "no") (eq_attr "type" "mult")))
|
||||
"core*16")
|
||||
|
||||
(define_insn_reservation "mult_ldsched_strongarm" 3
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "ldsched" "yes")
|
||||
(and (eq_attr "is_strongarm" "yes")
|
||||
(eq_attr "type" "mult"))))
|
||||
"core*2")
|
||||
|
||||
(define_insn_reservation "mult_ldsched" 4
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "ldsched" "yes")
|
||||
(and (eq_attr "is_strongarm" "no")
|
||||
(eq_attr "type" "mult"))))
|
||||
"core*4")
|
||||
|
||||
(define_insn_reservation "multi_cycle" 32
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "core_cycles" "multi")
|
||||
(eq_attr "type" "!mult,load_byte,load1,load2,load3,load4,store1,store2,store3,store4")))
|
||||
"core*32")
|
||||
|
||||
(define_insn_reservation "single_cycle" 1
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(eq_attr "core_cycles" "single"))
|
||||
"core")
|
|
@ -1,5 +1,6 @@
|
|||
/* Prototypes for exported functions defined in arm.c and pe.c
|
||||
Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Richard Earnshaw (rearnsha@arm.com)
|
||||
Minor hacks by Nick Clifton (nickc@cygnus.com)
|
||||
|
||||
|
@ -53,12 +54,14 @@ extern int arm_legitimate_address_p (enum machine_mode, rtx, int);
|
|||
extern int thumb_legitimate_address_p (enum machine_mode, rtx, int);
|
||||
extern int thumb_legitimate_offset_p (enum machine_mode, HOST_WIDE_INT);
|
||||
extern rtx arm_legitimize_address (rtx, rtx, enum machine_mode);
|
||||
extern int const_double_rtx_ok_for_fpa (rtx);
|
||||
extern int arm_const_double_rtx (rtx);
|
||||
extern int neg_const_double_rtx_ok_for_fpa (rtx);
|
||||
extern enum reg_class vfp_secondary_reload_class (enum machine_mode, rtx);
|
||||
|
||||
/* Predicates. */
|
||||
extern int s_register_operand (rtx, enum machine_mode);
|
||||
extern int arm_hard_register_operand (rtx, enum machine_mode);
|
||||
extern int arm_general_register_operand (rtx, enum machine_mode);
|
||||
extern int f_register_operand (rtx, enum machine_mode);
|
||||
extern int reg_or_int_operand (rtx, enum machine_mode);
|
||||
extern int arm_reload_memory_operand (rtx, enum machine_mode);
|
||||
|
@ -70,8 +73,8 @@ extern int arm_not_operand (rtx, enum machine_mode);
|
|||
extern int offsettable_memory_operand (rtx, enum machine_mode);
|
||||
extern int alignable_memory_operand (rtx, enum machine_mode);
|
||||
extern int bad_signed_byte_operand (rtx, enum machine_mode);
|
||||
extern int fpa_rhs_operand (rtx, enum machine_mode);
|
||||
extern int fpa_add_operand (rtx, enum machine_mode);
|
||||
extern int arm_float_rhs_operand (rtx, enum machine_mode);
|
||||
extern int arm_float_add_operand (rtx, enum machine_mode);
|
||||
extern int power_of_two_operand (rtx, enum machine_mode);
|
||||
extern int nonimmediate_di_operand (rtx, enum machine_mode);
|
||||
extern int di_operand (rtx, enum machine_mode);
|
||||
|
@ -95,6 +98,13 @@ extern int cirrus_general_operand (rtx, enum machine_mode);
|
|||
extern int cirrus_register_operand (rtx, enum machine_mode);
|
||||
extern int cirrus_shift_const (rtx, enum machine_mode);
|
||||
extern int cirrus_memory_offset (rtx);
|
||||
extern int vfp_mem_operand (rtx);
|
||||
extern int vfp_compare_operand (rtx, enum machine_mode);
|
||||
extern int arm_float_compare_operand (rtx, enum machine_mode);
|
||||
extern int arm_no_early_store_addr_dep (rtx, rtx);
|
||||
extern int arm_no_early_alu_shift_dep (rtx, rtx);
|
||||
extern int arm_no_early_alu_shift_value_dep (rtx, rtx);
|
||||
extern int arm_no_early_mul_dep (rtx, rtx);
|
||||
|
||||
extern int symbol_mentioned_p (rtx);
|
||||
extern int label_mentioned_p (rtx);
|
||||
|
@ -138,6 +148,7 @@ extern int arm_debugger_arg_offset (int, rtx);
|
|||
extern int arm_is_longcall_p (rtx, int, int);
|
||||
extern int arm_emit_vector_const (FILE *, rtx);
|
||||
extern const char * arm_output_load_gr (rtx *);
|
||||
extern const char *vfp_output_fstmx (rtx *);
|
||||
|
||||
#if defined TREE_CODE
|
||||
extern rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
|
||||
|
|
1649
gcc/config/arm/arm.c
1649
gcc/config/arm/arm.c
File diff suppressed because it is too large
Load Diff
|
@ -30,9 +30,10 @@
|
|||
#define TARGET_CPU_CPP_BUILTINS() \
|
||||
do \
|
||||
{ \
|
||||
if (TARGET_ARM) \
|
||||
builtin_define ("__arm__"); \
|
||||
else \
|
||||
/* Define __arm__ even when in thumb mode, for \
|
||||
consistency with armcc. */ \
|
||||
builtin_define ("__arm__"); \
|
||||
if (TARGET_THUMB) \
|
||||
builtin_define ("__thumb__"); \
|
||||
\
|
||||
if (TARGET_BIG_END) \
|
||||
|
@ -58,9 +59,7 @@
|
|||
if (TARGET_SOFT_FLOAT) \
|
||||
builtin_define ("__SOFTFP__"); \
|
||||
\
|
||||
/* FIXME: TARGET_HARD_FLOAT currently implies \
|
||||
FPA. */ \
|
||||
if (TARGET_VFP && !TARGET_HARD_FLOAT) \
|
||||
if (TARGET_VFP) \
|
||||
builtin_define ("__VFP_FP__"); \
|
||||
\
|
||||
/* Add a define for interworking. \
|
||||
|
@ -98,13 +97,27 @@
|
|||
#define TARGET_CPU_xscale 0x0100
|
||||
#define TARGET_CPU_ep9312 0x0200
|
||||
#define TARGET_CPU_iwmmxt 0x0400
|
||||
#define TARGET_CPU_arm926ej_s 0x0800
|
||||
#define TARGET_CPU_arm1026ej_s 0x1000
|
||||
#define TARGET_CPU_arm1136j_s 0x2000
|
||||
#define TARGET_CPU_arm1136jf_s 0x4000
|
||||
#define TARGET_CPU_arm926ejs 0x0800
|
||||
#define TARGET_CPU_arm1026ejs 0x1000
|
||||
#define TARGET_CPU_arm1136js 0x2000
|
||||
#define TARGET_CPU_arm1136jfs 0x4000
|
||||
/* Configure didn't specify. */
|
||||
#define TARGET_CPU_generic 0x8000
|
||||
|
||||
/* The various ARM cores. */
|
||||
enum processor_type
|
||||
{
|
||||
#define ARM_CORE(NAME, FLAGS, COSTS) \
|
||||
NAME,
|
||||
#include "arm-cores.def"
|
||||
#undef ARM_CORE
|
||||
/* Used to indicate that no processor has been specified. */
|
||||
arm_none
|
||||
};
|
||||
|
||||
/* The processor for which instructions should be scheduled. */
|
||||
extern enum processor_type arm_tune;
|
||||
|
||||
typedef enum arm_cond_code
|
||||
{
|
||||
ARM_EQ = 0, ARM_NE, ARM_CS, ARM_CC, ARM_MI, ARM_PL, ARM_VS, ARM_VC,
|
||||
|
@ -121,8 +134,12 @@ extern int arm_ccfsm_state;
|
|||
extern GTY(()) rtx arm_target_insn;
|
||||
/* Run-time compilation parameters selecting different hardware subsets. */
|
||||
extern int target_flags;
|
||||
/* The floating point instruction architecture, can be 2 or 3 */
|
||||
extern const char * target_fp_name;
|
||||
/* The floating point mode. */
|
||||
extern const char *target_fpu_name;
|
||||
/* For backwards compatability. */
|
||||
extern const char *target_fpe_name;
|
||||
/* Whether to use floating point hardware. */
|
||||
extern const char *target_float_abi_name;
|
||||
/* Define the information needed to generate branch insns. This is
|
||||
stored from the compare operation. */
|
||||
extern GTY(()) rtx arm_compare_op0;
|
||||
|
@ -181,6 +198,14 @@ extern GTY(()) rtx aof_pic_label;
|
|||
#if TARGET_CPU_DEFAULT == TARGET_CPU_iwmmxt
|
||||
#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_5TE__ -D__XSCALE__ -D__IWMMXT__"
|
||||
#else
|
||||
#if (TARGET_CPU_DEFAULT == TARGET_CPU_arm926ejs || \
|
||||
TARGET_CPU_DEFAULT == TARGET_CPU_arm1026ejs)
|
||||
#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_5TEJ__"
|
||||
#else
|
||||
#if (TARGET_CPU_DEFAULT == TARGET_CPU_arm1136js || \
|
||||
TARGET_CPU_DEFAULT == TARGET_CPU_arm1136jfs)
|
||||
#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_6J__"
|
||||
#else
|
||||
#error Unrecognized value in TARGET_CPU_DEFAULT.
|
||||
#endif
|
||||
#endif
|
||||
|
@ -190,6 +215,8 @@ extern GTY(()) rtx aof_pic_label;
|
|||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC "%(cpp_cpu_arch) %(subtarget_cpp_spec) \
|
||||
|
@ -225,7 +252,11 @@ extern GTY(()) rtx aof_pic_label;
|
|||
%{march=arm9:-D__ARM_ARCH_4T__} \
|
||||
%{march=arm920:-D__ARM_ARCH_4__} \
|
||||
%{march=arm920t:-D__ARM_ARCH_4T__} \
|
||||
%{march=arm926ejs:-D__ARM_ARCH_5TEJ__} \
|
||||
%{march=arm9tdmi:-D__ARM_ARCH_4T__} \
|
||||
%{march=arm1026ejs:-D__ARM_ARCH_5TEJ__} \
|
||||
%{march=arm1136js:-D__ARM_ARCH_6J__} \
|
||||
%{march=arm1136jfs:-D__ARM_ARCH_6J__} \
|
||||
%{march=strongarm:-D__ARM_ARCH_4__} \
|
||||
%{march=strongarm110:-D__ARM_ARCH_4__} \
|
||||
%{march=strongarm1100:-D__ARM_ARCH_4__} \
|
||||
|
@ -243,6 +274,8 @@ extern GTY(()) rtx aof_pic_label;
|
|||
%{march=armv5t:-D__ARM_ARCH_5T__} \
|
||||
%{march=armv5e:-D__ARM_ARCH_5E__} \
|
||||
%{march=armv5te:-D__ARM_ARCH_5TE__} \
|
||||
%{march=armv6:-D__ARM_ARCH6__} \
|
||||
%{march=armv6j:-D__ARM_ARCH6J__} \
|
||||
%{!march=*: \
|
||||
%{mcpu=arm2:-D__ARM_ARCH_2__} \
|
||||
%{mcpu=arm250:-D__ARM_ARCH_2__} \
|
||||
|
@ -266,7 +299,11 @@ extern GTY(()) rtx aof_pic_label;
|
|||
%{mcpu=arm9:-D__ARM_ARCH_4T__} \
|
||||
%{mcpu=arm920:-D__ARM_ARCH_4__} \
|
||||
%{mcpu=arm920t:-D__ARM_ARCH_4T__} \
|
||||
%{mcpu=arm926ejs:-D__ARM_ARCH_5TEJ__} \
|
||||
%{mcpu=arm9tdmi:-D__ARM_ARCH_4T__} \
|
||||
%{mcpu=arm1026ejs:-D__ARM_ARCH_5TEJ__} \
|
||||
%{mcpu=arm1136js:-D__ARM_ARCH_6J__} \
|
||||
%{mcpu=arm1136jfs:-D__ARM_ARCH_6J__} \
|
||||
%{mcpu=strongarm:-D__ARM_ARCH_4__} \
|
||||
%{mcpu=strongarm110:-D__ARM_ARCH_4__} \
|
||||
%{mcpu=strongarm1100:-D__ARM_ARCH_4__} \
|
||||
|
@ -414,13 +451,14 @@ extern GTY(()) rtx aof_pic_label;
|
|||
#define TARGET_APCS_REENT (target_flags & ARM_FLAG_APCS_REENT)
|
||||
#define TARGET_ATPCS (target_flags & ARM_FLAG_ATPCS)
|
||||
#define TARGET_MMU_TRAPS (target_flags & ARM_FLAG_MMU_TRAPS)
|
||||
#define TARGET_SOFT_FLOAT (target_flags & ARM_FLAG_SOFT_FLOAT)
|
||||
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
|
||||
#define TARGET_CIRRUS (arm_is_cirrus)
|
||||
#define TARGET_ANY_HARD_FLOAT (TARGET_HARD_FLOAT || TARGET_CIRRUS)
|
||||
#define TARGET_SOFT_FLOAT (arm_float_abi == ARM_FLOAT_ABI_SOFT)
|
||||
#define TARGET_SOFT_FLOAT_ABI (arm_float_abi != ARM_FLOAT_ABI_HARD)
|
||||
#define TARGET_HARD_FLOAT (arm_float_abi == ARM_FLOAT_ABI_HARD)
|
||||
#define TARGET_FPA (arm_fp_model == ARM_FP_MODEL_FPA)
|
||||
#define TARGET_MAVERICK (arm_fp_model == ARM_FP_MODEL_MAVERICK)
|
||||
#define TARGET_VFP (arm_fp_model == ARM_FP_MODEL_VFP)
|
||||
#define TARGET_IWMMXT (arm_arch_iwmmxt)
|
||||
#define TARGET_REALLY_IWMMXT (TARGET_IWMMXT && TARGET_ARM)
|
||||
#define TARGET_VFP (target_flags & ARM_FLAG_VFP)
|
||||
#define TARGET_BIG_END (target_flags & ARM_FLAG_BIG_END)
|
||||
#define TARGET_INTERWORK (target_flags & ARM_FLAG_INTERWORK)
|
||||
#define TARGET_LITTLE_WORDS (target_flags & ARM_FLAG_LITTLE_WORDS)
|
||||
|
@ -523,20 +561,23 @@ extern GTY(()) rtx aof_pic_label;
|
|||
{"", TARGET_DEFAULT, "" } \
|
||||
}
|
||||
|
||||
#define TARGET_OPTIONS \
|
||||
{ \
|
||||
{"cpu=", & arm_select[0].string, \
|
||||
N_("Specify the name of the target CPU"), 0}, \
|
||||
{"arch=", & arm_select[1].string, \
|
||||
N_("Specify the name of the target architecture"), 0}, \
|
||||
{"tune=", & arm_select[2].string, "", 0}, \
|
||||
{"fpe=", & target_fp_name, "" , 0}, \
|
||||
{"fp=", & target_fp_name, \
|
||||
N_("Specify the version of the floating point emulator"), 0},\
|
||||
{"structure-size-boundary=", & structure_size_string, \
|
||||
N_("Specify the minimum bit alignment of structures"), 0}, \
|
||||
{"pic-register=", & arm_pic_register_string, \
|
||||
N_("Specify the register to be used for PIC addressing"), 0} \
|
||||
#define TARGET_OPTIONS \
|
||||
{ \
|
||||
{"cpu=", & arm_select[0].string, \
|
||||
N_("Specify the name of the target CPU"), 0}, \
|
||||
{"arch=", & arm_select[1].string, \
|
||||
N_("Specify the name of the target architecture"), 0}, \
|
||||
{"tune=", & arm_select[2].string, "", 0}, \
|
||||
{"fpe=", & target_fpe_name, "", 0}, \
|
||||
{"fp=", & target_fpe_name, "", 0}, \
|
||||
{"fpu=", & target_fpu_name, \
|
||||
N_("Specify the name of the target floating point hardware/format"), 0}, \
|
||||
{"float-abi=", & target_float_abi_name, \
|
||||
N_("Specify if floating point hardware should be used"), 0}, \
|
||||
{"structure-size-boundary=", & structure_size_string, \
|
||||
N_("Specify the minimum bit alignment of structures"), 0}, \
|
||||
{"pic-register=", & arm_pic_register_string, \
|
||||
N_("Specify the register to be used for PIC addressing"), 0} \
|
||||
}
|
||||
|
||||
/* Support for a compile-time default CPU, et cetera. The rules are:
|
||||
|
@ -545,13 +586,16 @@ extern GTY(()) rtx aof_pic_label;
|
|||
by --with-arch.
|
||||
--with-tune is ignored if -mtune or -mcpu are specified (but not affected
|
||||
by -march).
|
||||
--with-float is ignored if -mhard-float or -msoft-float are
|
||||
specified. */
|
||||
--with-float is ignored if -mhard-float, -msoft-float or -mfloat-abi are
|
||||
specified.
|
||||
--with-fpu is ignored if -mfpu is specified. */
|
||||
#define OPTION_DEFAULT_SPECS \
|
||||
{"arch", "%{!march=*:%{!mcpu=*:-march=%(VALUE)}}" }, \
|
||||
{"cpu", "%{!march=*:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
|
||||
{"tune", "%{!mcpu=*:%{!mtune=*:-mtune=%(VALUE)}}" }, \
|
||||
{"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }
|
||||
{"float", \
|
||||
"%{!msoft-float:%{!mhard-float:%{!mfloat-abi=*:-mfloat-abi=%(VALUE)}}}" }, \
|
||||
{"fpu", "%{!mfpu=*:-mfpu=%(VALUE)}"},
|
||||
|
||||
struct arm_cpu_select
|
||||
{
|
||||
|
@ -576,12 +620,26 @@ enum prog_mode_type
|
|||
|
||||
extern enum prog_mode_type arm_prgmode;
|
||||
|
||||
/* What sort of floating point unit do we have? Hardware or software.
|
||||
If software, is it issue 2 or issue 3? */
|
||||
/* Which floating point model to use. */
|
||||
enum arm_fp_model
|
||||
{
|
||||
ARM_FP_MODEL_UNKNOWN,
|
||||
/* FPA model (Hardware or software). */
|
||||
ARM_FP_MODEL_FPA,
|
||||
/* Cirrus Maverick floating point model. */
|
||||
ARM_FP_MODEL_MAVERICK,
|
||||
/* VFP floating point model. */
|
||||
ARM_FP_MODEL_VFP
|
||||
};
|
||||
|
||||
extern enum arm_fp_model arm_fp_model;
|
||||
|
||||
/* Which floating point hardware is available. Also update
|
||||
fp_model_for_fpu in arm.c when adding entries to this list. */
|
||||
enum fputype
|
||||
{
|
||||
/* Software floating point, FPA style double fmt. */
|
||||
FPUTYPE_SOFT_FPA,
|
||||
/* No FP hardware. */
|
||||
FPUTYPE_NONE,
|
||||
/* Full FPA support. */
|
||||
FPUTYPE_FPA,
|
||||
/* Emulated FPA hardware, Issue 2 emulator (no LFM/SFM). */
|
||||
|
@ -589,7 +647,9 @@ enum fputype
|
|||
/* Emulated FPA hardware, Issue 3 emulator. */
|
||||
FPUTYPE_FPA_EMU3,
|
||||
/* Cirrus Maverick floating point co-processor. */
|
||||
FPUTYPE_MAVERICK
|
||||
FPUTYPE_MAVERICK,
|
||||
/* VFP. */
|
||||
FPUTYPE_VFP
|
||||
};
|
||||
|
||||
/* Recast the floating point class to be the floating point attribute. */
|
||||
|
@ -601,8 +661,21 @@ extern enum fputype arm_fpu_tune;
|
|||
/* What type of floating point instructions are available */
|
||||
extern enum fputype arm_fpu_arch;
|
||||
|
||||
enum float_abi_type
|
||||
{
|
||||
ARM_FLOAT_ABI_SOFT,
|
||||
ARM_FLOAT_ABI_SOFTFP,
|
||||
ARM_FLOAT_ABI_HARD
|
||||
};
|
||||
|
||||
extern enum float_abi_type arm_float_abi;
|
||||
|
||||
/* Default floating point architecture. Override in sub-target if
|
||||
necessary. */
|
||||
necessary.
|
||||
FIXME: Is this still neccessary/desirable? Do we want VFP chips to
|
||||
default to VFP unless overridden by a subtarget? If so it would be best
|
||||
to remove these definitions. It also assumes there is only one cpu model
|
||||
with a Maverick fpu. */
|
||||
#ifndef FPUTYPE_DEFAULT
|
||||
#define FPUTYPE_DEFAULT FPUTYPE_FPA_EMU2
|
||||
#endif
|
||||
|
@ -612,19 +685,21 @@ extern enum fputype arm_fpu_arch;
|
|||
#define FPUTYPE_DEFAULT FPUTYPE_MAVERICK
|
||||
#endif
|
||||
|
||||
/* Nonzero if the processor has a fast multiply insn, and one that does
|
||||
a 64-bit multiply of two 32-bit values. */
|
||||
extern int arm_fast_multiply;
|
||||
/* Nonzero if this chip supports the ARM Architecture 3M extensions. */
|
||||
extern int arm_arch3m;
|
||||
|
||||
/* Nonzero if this chip supports the ARM Architecture 4 extensions */
|
||||
/* Nonzero if this chip supports the ARM Architecture 4 extensions. */
|
||||
extern int arm_arch4;
|
||||
|
||||
/* Nonzero if this chip supports the ARM Architecture 5 extensions */
|
||||
/* Nonzero if this chip supports the ARM Architecture 5 extensions. */
|
||||
extern int arm_arch5;
|
||||
|
||||
/* Nonzero if this chip supports the ARM Architecture 5E extensions */
|
||||
/* Nonzero if this chip supports the ARM Architecture 5E extensions. */
|
||||
extern int arm_arch5e;
|
||||
|
||||
/* Nonzero if this chip supports the ARM Architecture 6 extensions. */
|
||||
extern int arm_arch6;
|
||||
|
||||
/* Nonzero if this chip can benefit from load scheduling. */
|
||||
extern int arm_ld_sched;
|
||||
|
||||
|
@ -871,6 +946,11 @@ extern const char * structure_size_string;
|
|||
mvf1-mvf3 Cirrus floating point scratch
|
||||
mvf4-mvf15 S Cirrus floating point variable. */
|
||||
|
||||
/* s0-s15 VFP scratch (aka d0-d7).
|
||||
s16-s31 S VFP variable (aka d8-d15).
|
||||
vfpcc Not a real register. Represents the VFP condition
|
||||
code flags. */
|
||||
|
||||
/* The stack backtrace structure is as follows:
|
||||
fp points to here: | save code pointer | [fp]
|
||||
| return link value | [fp, #-4]
|
||||
|
@ -895,17 +975,22 @@ extern const char * structure_size_string;
|
|||
|
||||
/* 1 for registers that have pervasive standard uses
|
||||
and are not available for the register allocator. */
|
||||
#define FIXED_REGISTERS \
|
||||
{ \
|
||||
0,0,0,0,0,0,0,0, \
|
||||
0,0,0,0,0,1,0,1, \
|
||||
0,0,0,0,0,0,0,0, \
|
||||
#define FIXED_REGISTERS \
|
||||
{ \
|
||||
0,0,0,0,0,0,0,0, \
|
||||
0,0,0,0,0,1,0,1, \
|
||||
0,0,0,0,0,0,0,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,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,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, \
|
||||
1 \
|
||||
}
|
||||
|
||||
/* 1 for registers not available across function calls.
|
||||
|
@ -926,7 +1011,12 @@ extern const char * structure_size_string;
|
|||
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,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 \
|
||||
}
|
||||
|
||||
#ifndef SUBTARGET_CONDITIONAL_REGISTER_USAGE
|
||||
|
@ -937,10 +1027,10 @@ extern const char * structure_size_string;
|
|||
{ \
|
||||
int regno; \
|
||||
\
|
||||
if (TARGET_SOFT_FLOAT || TARGET_THUMB) \
|
||||
if (TARGET_SOFT_FLOAT || TARGET_THUMB || !TARGET_FPA) \
|
||||
{ \
|
||||
for (regno = FIRST_ARM_FP_REGNUM; \
|
||||
regno <= LAST_ARM_FP_REGNUM; ++regno) \
|
||||
for (regno = FIRST_FPA_REGNUM; \
|
||||
regno <= LAST_FPA_REGNUM; ++regno) \
|
||||
fixed_regs[regno] = call_used_regs[regno] = 1; \
|
||||
} \
|
||||
\
|
||||
|
@ -960,16 +1050,28 @@ extern const char * structure_size_string;
|
|||
if (TARGET_THUMB) \
|
||||
fixed_regs[LR_REGNUM] = call_used_regs[LR_REGNUM] = 1; \
|
||||
\
|
||||
if (TARGET_CIRRUS) \
|
||||
if (TARGET_ARM && TARGET_HARD_FLOAT) \
|
||||
{ \
|
||||
for (regno = FIRST_ARM_FP_REGNUM; \
|
||||
regno <= LAST_ARM_FP_REGNUM; ++ regno) \
|
||||
fixed_regs[regno] = call_used_regs[regno] = 1; \
|
||||
for (regno = FIRST_CIRRUS_FP_REGNUM; \
|
||||
regno <= LAST_CIRRUS_FP_REGNUM; ++ regno) \
|
||||
if (TARGET_MAVERICK) \
|
||||
{ \
|
||||
fixed_regs[regno] = 0; \
|
||||
call_used_regs[regno] = regno < FIRST_CIRRUS_FP_REGNUM + 4; \
|
||||
for (regno = FIRST_FPA_REGNUM; \
|
||||
regno <= LAST_FPA_REGNUM; ++ regno) \
|
||||
fixed_regs[regno] = call_used_regs[regno] = 1; \
|
||||
for (regno = FIRST_CIRRUS_FP_REGNUM; \
|
||||
regno <= LAST_CIRRUS_FP_REGNUM; ++ regno) \
|
||||
{ \
|
||||
fixed_regs[regno] = 0; \
|
||||
call_used_regs[regno] = regno < FIRST_CIRRUS_FP_REGNUM + 4; \
|
||||
} \
|
||||
} \
|
||||
if (TARGET_VFP) \
|
||||
{ \
|
||||
for (regno = FIRST_VFP_REGNUM; \
|
||||
regno <= LAST_VFP_REGNUM; ++ regno) \
|
||||
{ \
|
||||
fixed_regs[regno] = 0; \
|
||||
call_used_regs[regno] = regno < FIRST_VFP_REGNUM + 16; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
|
@ -1031,7 +1133,8 @@ extern const char * structure_size_string;
|
|||
/* Convert fron bytes to ints. */
|
||||
#define ARM_NUM_INTS(X) (((X) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
|
||||
|
||||
/* The number of (integer) registers required to hold a quantity of type MODE. */
|
||||
/* The number of (integer) registers required to hold a quantity of type MODE.
|
||||
Also used for VFP registers. */
|
||||
#define ARM_NUM_REGS(MODE) \
|
||||
ARM_NUM_INTS (GET_MODE_SIZE (MODE))
|
||||
|
||||
|
@ -1096,8 +1199,8 @@ extern const char * structure_size_string;
|
|||
#define STACK_POINTER_REGNUM SP_REGNUM
|
||||
|
||||
/* ARM floating pointer registers. */
|
||||
#define FIRST_ARM_FP_REGNUM 16
|
||||
#define LAST_ARM_FP_REGNUM 23
|
||||
#define FIRST_FPA_REGNUM 16
|
||||
#define LAST_FPA_REGNUM 23
|
||||
|
||||
#define FIRST_IWMMXT_GR_REGNUM 43
|
||||
#define LAST_IWMMXT_GR_REGNUM 46
|
||||
|
@ -1119,10 +1222,16 @@ extern const char * structure_size_string;
|
|||
#define IS_CIRRUS_REGNUM(REGNUM) \
|
||||
(((REGNUM) >= FIRST_CIRRUS_FP_REGNUM) && ((REGNUM) <= LAST_CIRRUS_FP_REGNUM))
|
||||
|
||||
#define FIRST_VFP_REGNUM 63
|
||||
#define LAST_VFP_REGNUM 94
|
||||
#define IS_VFP_REGNUM(REGNUM) \
|
||||
(((REGNUM) >= FIRST_VFP_REGNUM) && ((REGNUM) <= LAST_VFP_REGNUM))
|
||||
|
||||
/* The number of hard registers is 16 ARM + 8 FPA + 1 CC + 1 SFP + 1 AFP. */
|
||||
/* + 16 Cirrus registers take us up to 43. */
|
||||
/* Intel Wireless MMX Technology registers add 16 + 4 more. */
|
||||
#define FIRST_PSEUDO_REGISTER 63
|
||||
/* VFP adds 32 + 1 more. */
|
||||
#define FIRST_PSEUDO_REGISTER 96
|
||||
|
||||
/* Value should be nonzero if functions must have frame pointers.
|
||||
Zero means the frame pointer need not be set up (and parms may be accessed
|
||||
|
@ -1143,9 +1252,10 @@ extern const char * structure_size_string;
|
|||
mode. */
|
||||
#define HARD_REGNO_NREGS(REGNO, MODE) \
|
||||
((TARGET_ARM \
|
||||
&& REGNO >= FIRST_ARM_FP_REGNUM \
|
||||
&& REGNO >= FIRST_FPA_REGNUM \
|
||||
&& REGNO != FRAME_POINTER_REGNUM \
|
||||
&& REGNO != ARG_POINTER_REGNUM) \
|
||||
&& !IS_VFP_REGNUM (REGNO) \
|
||||
? 1 : ARM_NUM_REGS (MODE))
|
||||
|
||||
/* Return true if REGNO is suitable for holding a quantity of type MODE. */
|
||||
|
@ -1171,6 +1281,7 @@ extern const char * structure_size_string;
|
|||
clobber it anyway. Allocate r0 through r3 in reverse order since r3 is
|
||||
least likely to contain a function parameter; in addition results are
|
||||
returned in r0. */
|
||||
|
||||
#define REG_ALLOC_ORDER \
|
||||
{ \
|
||||
3, 2, 1, 0, 12, 14, 4, 5, \
|
||||
|
@ -1181,7 +1292,12 @@ extern const char * structure_size_string;
|
|||
43, 44, 45, 46, 47, 48, 49, 50, \
|
||||
51, 52, 53, 54, 55, 56, 57, 58, \
|
||||
59, 60, 61, 62, \
|
||||
24, 25, 26 \
|
||||
24, 25, 26, \
|
||||
78, 77, 76, 75, 74, 73, 72, 71, \
|
||||
70, 69, 68, 67, 66, 65, 64, 63, \
|
||||
79, 80, 81, 82, 83, 84, 85, 86, \
|
||||
87, 88, 89, 90, 91, 92, 93, 94, \
|
||||
95 \
|
||||
}
|
||||
|
||||
/* Interrupt functions can only use registers that have already been
|
||||
|
@ -1200,6 +1316,7 @@ enum reg_class
|
|||
NO_REGS,
|
||||
FPA_REGS,
|
||||
CIRRUS_REGS,
|
||||
VFP_REGS,
|
||||
IWMMXT_GR_REGS,
|
||||
IWMMXT_REGS,
|
||||
LO_REGS,
|
||||
|
@ -1207,6 +1324,7 @@ enum reg_class
|
|||
BASE_REGS,
|
||||
HI_REGS,
|
||||
CC_REG,
|
||||
VFPCC_REG,
|
||||
GENERAL_REGS,
|
||||
ALL_REGS,
|
||||
LIM_REG_CLASSES
|
||||
|
@ -1220,6 +1338,7 @@ enum reg_class
|
|||
"NO_REGS", \
|
||||
"FPA_REGS", \
|
||||
"CIRRUS_REGS", \
|
||||
"VFP_REGS", \
|
||||
"IWMMXT_GR_REGS", \
|
||||
"IWMMXT_REGS", \
|
||||
"LO_REGS", \
|
||||
|
@ -1227,6 +1346,7 @@ enum reg_class
|
|||
"BASE_REGS", \
|
||||
"HI_REGS", \
|
||||
"CC_REG", \
|
||||
"VFPCC_REG" \
|
||||
"GENERAL_REGS", \
|
||||
"ALL_REGS", \
|
||||
}
|
||||
|
@ -1234,20 +1354,22 @@ enum reg_class
|
|||
/* 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, 0x0 }, /* NO_REGS */ \
|
||||
{ 0x00FF0000, 0x0 }, /* FPA_REGS */ \
|
||||
{ 0xF8000000, 0x000007FF }, /* CIRRUS_REGS */ \
|
||||
{ 0x00000000, 0x00007800 }, /* IWMMXT_GR_REGS */\
|
||||
{ 0x00000000, 0x7FFF8000 }, /* IWMMXT_REGS */ \
|
||||
{ 0x000000FF, 0x0 }, /* LO_REGS */ \
|
||||
{ 0x00002000, 0x0 }, /* STACK_REG */ \
|
||||
{ 0x000020FF, 0x0 }, /* BASE_REGS */ \
|
||||
{ 0x0000FF00, 0x0 }, /* HI_REGS */ \
|
||||
{ 0x01000000, 0x0 }, /* CC_REG */ \
|
||||
{ 0x0200FFFF, 0x0 }, /* GENERAL_REGS */\
|
||||
{ 0xFAFFFFFF, 0x7FFFFFFF } /* ALL_REGS */ \
|
||||
#define REG_CLASS_CONTENTS \
|
||||
{ \
|
||||
{ 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \
|
||||
{ 0x00FF0000, 0x00000000, 0x00000000 }, /* FPA_REGS */ \
|
||||
{ 0xF8000000, 0x000007FF, 0x00000000 }, /* CIRRUS_REGS */ \
|
||||
{ 0x00000000, 0x80000000, 0x7FFFFFFF }, /* VFP_REGS */ \
|
||||
{ 0x00000000, 0x00007800, 0x00000000 }, /* IWMMXT_GR_REGS */ \
|
||||
{ 0x00000000, 0x7FFF8000, 0x00000000 }, /* IWMMXT_REGS */ \
|
||||
{ 0x000000FF, 0x00000000, 0x00000000 }, /* LO_REGS */ \
|
||||
{ 0x00002000, 0x00000000, 0x00000000 }, /* STACK_REG */ \
|
||||
{ 0x000020FF, 0x00000000, 0x00000000 }, /* BASE_REGS */ \
|
||||
{ 0x0000FF00, 0x00000000, 0x00000000 }, /* HI_REGS */ \
|
||||
{ 0x01000000, 0x00000000, 0x00000000 }, /* CC_REG */ \
|
||||
{ 0x00000000, 0x00000000, 0x80000000 }, /* VFPCC_REG */ \
|
||||
{ 0x0200FFFF, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \
|
||||
{ 0xFAFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF } /* ALL_REGS */ \
|
||||
}
|
||||
|
||||
/* The same information, inverted:
|
||||
|
@ -1256,11 +1378,14 @@ enum reg_class
|
|||
or could index an array. */
|
||||
#define REGNO_REG_CLASS(REGNO) arm_regno_class (REGNO)
|
||||
|
||||
/* FPA registers can't do dubreg as all values are reformatted to internal
|
||||
precision. */
|
||||
/* FPA registers can't do subreg as all values are reformatted to internal
|
||||
precision. VFP registers may only be accesed in the mode they
|
||||
were set. */
|
||||
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
|
||||
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
|
||||
? reg_classes_intersect_p (FPA_REGS, (CLASS)) : 0)
|
||||
? reg_classes_intersect_p (FPA_REGS, (CLASS)) \
|
||||
|| reg_classes_intersect_p (VFP_REGS, (CLASS)) \
|
||||
: 0)
|
||||
|
||||
/* The class value for index registers, and the one for base regs. */
|
||||
#define INDEX_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
|
||||
|
@ -1287,6 +1412,7 @@ enum reg_class
|
|||
#define REG_CLASS_FROM_LETTER(C) \
|
||||
( (C) == 'f' ? FPA_REGS \
|
||||
: (C) == 'v' ? CIRRUS_REGS \
|
||||
: (C) == 'w' ? VFP_REGS \
|
||||
: (C) == 'y' ? IWMMXT_REGS \
|
||||
: (C) == 'z' ? IWMMXT_GR_REGS \
|
||||
: (C) == 'l' ? (TARGET_ARM ? GENERAL_REGS : LO_REGS) \
|
||||
|
@ -1331,10 +1457,10 @@ enum reg_class
|
|||
(TARGET_ARM ? \
|
||||
CONST_OK_FOR_ARM_LETTER (VALUE, C) : CONST_OK_FOR_THUMB_LETTER (VALUE, C))
|
||||
|
||||
/* Constant letter 'G' for the FPA immediate constants.
|
||||
/* Constant letter 'G' for the FP immediate constants.
|
||||
'H' means the same constant negated. */
|
||||
#define CONST_DOUBLE_OK_FOR_ARM_LETTER(X, C) \
|
||||
((C) == 'G' ? const_double_rtx_ok_for_fpa (X) : \
|
||||
((C) == 'G' ? arm_const_double_rtx (X) : \
|
||||
(C) == 'H' ? neg_const_double_rtx_ok_for_fpa (X) : 0)
|
||||
|
||||
#define CONST_DOUBLE_OK_FOR_LETTER_P(X, C) \
|
||||
|
@ -1345,7 +1471,8 @@ enum reg_class
|
|||
an offset from a register.
|
||||
`S' means any symbol that has the SYMBOL_REF_FLAG set or a CONSTANT_POOL
|
||||
address. This means that the symbol is in the text segment and can be
|
||||
accessed without using a load. */
|
||||
accessed without using a load.
|
||||
'U' is an address valid for VFP load/store insns. */
|
||||
|
||||
#define EXTRA_CONSTRAINT_ARM(OP, C) \
|
||||
((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG : \
|
||||
|
@ -1354,6 +1481,7 @@ enum reg_class
|
|||
&& CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) : \
|
||||
(C) == 'S' ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) : \
|
||||
(C) == 'T' ? cirrus_memory_offset (OP) : \
|
||||
(C) == 'U' ? vfp_mem_operand (OP) : \
|
||||
0)
|
||||
|
||||
#define EXTRA_CONSTRAINT_THUMB(X, C) \
|
||||
|
@ -1364,6 +1492,8 @@ enum reg_class
|
|||
(TARGET_ARM ? \
|
||||
EXTRA_CONSTRAINT_ARM (X, C) : EXTRA_CONSTRAINT_THUMB (X, C))
|
||||
|
||||
#define EXTRA_MEMORY_CONSTRAINT(C, STR) ((C) == 'U')
|
||||
|
||||
/* Given an rtx X being reloaded into a reg required to be
|
||||
in class CLASS, return the class of reg to actually use.
|
||||
In general this is just CLASS, but for the Thumb we prefer
|
||||
|
@ -1391,15 +1521,23 @@ enum reg_class
|
|||
or out of a register in CLASS in MODE. If it can be done directly,
|
||||
NO_REGS is returned. */
|
||||
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
|
||||
(TARGET_ARM ? \
|
||||
(((MODE) == HImode && ! arm_arch4 && true_regnum (X) == -1) \
|
||||
/* Restrict which direct reloads are allowed for VFP regs. */ \
|
||||
((TARGET_VFP && TARGET_HARD_FLOAT \
|
||||
&& (CLASS) == VFP_REGS) \
|
||||
? vfp_secondary_reload_class (MODE, X) \
|
||||
: TARGET_ARM \
|
||||
? (((MODE) == HImode && ! arm_arch4 && true_regnum (X) == -1) \
|
||||
? GENERAL_REGS : NO_REGS) \
|
||||
: THUMB_SECONDARY_OUTPUT_RELOAD_CLASS (CLASS, MODE, X))
|
||||
|
||||
/* If we need to load shorts byte-at-a-time, then we need a scratch. */
|
||||
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
|
||||
/* Restrict which direct reloads are allowed for VFP regs. */ \
|
||||
((TARGET_VFP && TARGET_HARD_FLOAT \
|
||||
&& (CLASS) == VFP_REGS) \
|
||||
? vfp_secondary_reload_class (MODE, X) : \
|
||||
/* Cannot load constants into Cirrus registers. */ \
|
||||
((TARGET_CIRRUS \
|
||||
(TARGET_MAVERICK && TARGET_HARD_FLOAT \
|
||||
&& (CLASS) == CIRRUS_REGS \
|
||||
&& (CONSTANT_P (X) || GET_CODE (X) == SYMBOL_REF)) \
|
||||
? GENERAL_REGS : \
|
||||
|
@ -1433,13 +1571,14 @@ enum reg_class
|
|||
HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
|
||||
HOST_WIDE_INT low, high; \
|
||||
\
|
||||
if (MODE == DImode || (TARGET_SOFT_FLOAT && MODE == DFmode)) \
|
||||
if (MODE == DImode || (TARGET_SOFT_FLOAT && TARGET_FPA \
|
||||
&& MODE == DFmode)) \
|
||||
low = ((val & 0xf) ^ 0x8) - 0x8; \
|
||||
else if (TARGET_CIRRUS) \
|
||||
else if (TARGET_MAVERICK && TARGET_HARD_FLOAT) \
|
||||
/* Need to be careful, -256 is not a valid offset. */ \
|
||||
low = val >= 0 ? (val & 0xff) : -((-val) & 0xff); \
|
||||
else if (MODE == SImode \
|
||||
|| (MODE == SFmode && TARGET_SOFT_FLOAT) \
|
||||
|| (MODE == SFmode && TARGET_SOFT_FLOAT && TARGET_FPA) \
|
||||
|| ((MODE == HImode || MODE == QImode) && ! arm_arch4)) \
|
||||
/* Need to be careful, -4096 is not a valid offset. */ \
|
||||
low = val >= 0 ? (val & 0xfff) : -((-val) & 0xfff); \
|
||||
|
@ -1447,7 +1586,7 @@ enum reg_class
|
|||
/* Need to be careful, -256 is not a valid offset. */ \
|
||||
low = val >= 0 ? (val & 0xff) : -((-val) & 0xff); \
|
||||
else if (GET_MODE_CLASS (MODE) == MODE_FLOAT \
|
||||
&& TARGET_HARD_FLOAT) \
|
||||
&& TARGET_HARD_FLOAT && TARGET_FPA) \
|
||||
/* Need to be careful, -1024 is not a valid offset. */ \
|
||||
low = val >= 0 ? (val & 0x3ff) : -((-val) & 0x3ff); \
|
||||
else \
|
||||
|
@ -1520,6 +1659,8 @@ enum reg_class
|
|||
(TARGET_ARM ? \
|
||||
((FROM) == FPA_REGS && (TO) != FPA_REGS ? 20 : \
|
||||
(FROM) != FPA_REGS && (TO) == FPA_REGS ? 20 : \
|
||||
(FROM) == VFP_REGS && (TO) != VFP_REGS ? 10 : \
|
||||
(FROM) != VFP_REGS && (TO) == VFP_REGS ? 10 : \
|
||||
(FROM) == IWMMXT_REGS && (TO) != IWMMXT_REGS ? 4 : \
|
||||
(FROM) != IWMMXT_REGS && (TO) == IWMMXT_REGS ? 4 : \
|
||||
(FROM) == IWMMXT_GR_REGS || (TO) == IWMMXT_GR_REGS ? 20 : \
|
||||
|
@ -1575,9 +1716,11 @@ enum reg_class
|
|||
/* Define how to find the value returned by a library function
|
||||
assuming the value has mode MODE. */
|
||||
#define LIBCALL_VALUE(MODE) \
|
||||
(TARGET_ARM && TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT \
|
||||
? gen_rtx_REG (MODE, FIRST_ARM_FP_REGNUM) \
|
||||
: TARGET_ARM && TARGET_CIRRUS && GET_MODE_CLASS (MODE) == MODE_FLOAT \
|
||||
(TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA \
|
||||
&& GET_MODE_CLASS (MODE) == MODE_FLOAT \
|
||||
? gen_rtx_REG (MODE, FIRST_FPA_REGNUM) \
|
||||
: TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK \
|
||||
&& GET_MODE_CLASS (MODE) == MODE_FLOAT \
|
||||
? gen_rtx_REG (MODE, FIRST_CIRRUS_FP_REGNUM) \
|
||||
: TARGET_REALLY_IWMMXT && VECTOR_MODE_SUPPORTED_P (MODE) \
|
||||
? gen_rtx_REG (MODE, FIRST_IWMMXT_REGNUM) \
|
||||
|
@ -1595,9 +1738,11 @@ enum reg_class
|
|||
/* On a Cirrus chip, mvf0 can return results. */
|
||||
#define FUNCTION_VALUE_REGNO_P(REGNO) \
|
||||
((REGNO) == ARG_REGISTER (1) \
|
||||
|| (TARGET_ARM && ((REGNO) == FIRST_CIRRUS_FP_REGNUM) && TARGET_CIRRUS) \
|
||||
|| (TARGET_ARM && ((REGNO) == FIRST_CIRRUS_FP_REGNUM) \
|
||||
&& TARGET_HARD_FLOAT && TARGET_MAVERICK) \
|
||||
|| (TARGET_ARM && ((REGNO) == FIRST_IWMMXT_REGNUM) && TARGET_IWMMXT) \
|
||||
|| (TARGET_ARM && ((REGNO) == FIRST_ARM_FP_REGNUM) && TARGET_HARD_FLOAT))
|
||||
|| (TARGET_ARM && ((REGNO) == FIRST_FPA_REGNUM) \
|
||||
&& TARGET_HARD_FLOAT && TARGET_FPA))
|
||||
|
||||
/* How large values are returned */
|
||||
/* A C expression which can inhibit the returning of certain function values
|
||||
|
@ -2081,6 +2226,7 @@ typedef struct
|
|||
#define THUMB_LEGITIMATE_CONSTANT_P(X) \
|
||||
( GET_CODE (X) == CONST_INT \
|
||||
|| GET_CODE (X) == CONST_DOUBLE \
|
||||
|| GET_CODE (X) == CONSTANT_P_RTX \
|
||||
|| CONSTANT_ADDRESS_P (X) \
|
||||
|| flag_pic)
|
||||
|
||||
|
@ -2433,10 +2579,11 @@ extern int making_const_table;
|
|||
{ \
|
||||
if (TARGET_THUMB) \
|
||||
{ \
|
||||
if (is_called_in_ARM_mode (DECL)) \
|
||||
if (is_called_in_ARM_mode (DECL) \
|
||||
|| current_function_is_thunk) \
|
||||
fprintf (STREAM, "\t.code 32\n") ; \
|
||||
else \
|
||||
fprintf (STREAM, "\t.thumb_func\n") ; \
|
||||
fprintf (STREAM, "\t.code 16\n\t.thumb_func\n") ; \
|
||||
} \
|
||||
if (TARGET_POKE_FUNCTION_NAME) \
|
||||
arm_poke_function_name (STREAM, (char *) NAME); \
|
||||
|
@ -2665,12 +2812,13 @@ extern int making_const_table;
|
|||
/* Define the codes that are matched by predicates in arm.c */
|
||||
#define PREDICATE_CODES \
|
||||
{"s_register_operand", {SUBREG, REG}}, \
|
||||
{"arm_general_register_operand", {SUBREG, REG}}, \
|
||||
{"arm_hard_register_operand", {REG}}, \
|
||||
{"f_register_operand", {SUBREG, REG}}, \
|
||||
{"arm_add_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"arm_addimm_operand", {CONST_INT}}, \
|
||||
{"fpa_add_operand", {SUBREG, REG, CONST_DOUBLE}}, \
|
||||
{"fpa_rhs_operand", {SUBREG, REG, CONST_DOUBLE}}, \
|
||||
{"arm_float_add_operand", {SUBREG, REG, CONST_DOUBLE}}, \
|
||||
{"arm_float_rhs_operand", {SUBREG, REG, CONST_DOUBLE}}, \
|
||||
{"arm_rhs_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"arm_not_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"reg_or_int_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
|
@ -2702,7 +2850,9 @@ extern int making_const_table;
|
|||
{"cirrus_register_operand", {REG}}, \
|
||||
{"cirrus_fp_register", {REG}}, \
|
||||
{"cirrus_shift_const", {CONST_INT}}, \
|
||||
{"dominant_cc_register", {REG}},
|
||||
{"dominant_cc_register", {REG}}, \
|
||||
{"arm_float_compare_operand", {REG, CONST_DOUBLE}}, \
|
||||
{"vfp_compare_operand", {REG, CONST_DOUBLE}},
|
||||
|
||||
/* Define this if you have special predicates that know special things
|
||||
about modes. Genrecog will warn about certain forms of
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,241 @@
|
|||
;; ARM 1026EJ-S Pipeline Description
|
||||
;; Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
;; Written by CodeSourcery, LLC.
|
||||
;;
|
||||
;; 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. */
|
||||
|
||||
;; These descriptions are based on the information contained in the
|
||||
;; ARM1026EJ-S Technical Reference Manual, Copyright (c) 2003 ARM
|
||||
;; Limited.
|
||||
;;
|
||||
|
||||
;; This automaton provides a pipeline description for the ARM
|
||||
;; 1026EJ-S core.
|
||||
;;
|
||||
;; The model given here assumes that the condition for all conditional
|
||||
;; instructions is "true", i.e., that all of the instructions are
|
||||
;; actually executed.
|
||||
|
||||
(define_automaton "arm1026ejs")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Pipelines
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; There are two pipelines:
|
||||
;;
|
||||
;; - An Arithmetic Logic Unit (ALU) pipeline.
|
||||
;;
|
||||
;; The ALU pipeline has fetch, issue, decode, execute, memory, and
|
||||
;; write stages. We only need to model the execute, memory and write
|
||||
;; stages.
|
||||
;;
|
||||
;; - A Load-Store Unit (LSU) pipeline.
|
||||
;;
|
||||
;; The LSU pipeline has decode, execute, memory, and write stages.
|
||||
;; We only model the execute, memory and write stages.
|
||||
|
||||
(define_cpu_unit "a_e,a_m,a_w" "arm1026ejs")
|
||||
(define_cpu_unit "l_e,l_m,l_w" "arm1026ejs")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ALU Instructions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; ALU instructions require three cycles to execute, and use the ALU
|
||||
;; pipeline in each of the three stages. The results are available
|
||||
;; after the execute stage stage has finished.
|
||||
;;
|
||||
;; If the destination register is the PC, the pipelines are stalled
|
||||
;; for several cycles. That case is not modeled here.
|
||||
|
||||
;; ALU operations with no shifted operand
|
||||
(define_insn_reservation "alu_op" 1
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "type" "alu"))
|
||||
"a_e,a_m,a_w")
|
||||
|
||||
;; ALU operations with a shift-by-constant operand
|
||||
(define_insn_reservation "alu_shift_op" 1
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "type" "alu_shift"))
|
||||
"a_e,a_m,a_w")
|
||||
|
||||
;; ALU operations with a shift-by-register operand
|
||||
;; These really stall in the decoder, in order to read
|
||||
;; the shift value in a second cycle. Pretend we take two cycles in
|
||||
;; the execute stage.
|
||||
(define_insn_reservation "alu_shift_reg_op" 2
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "type" "alu_shift_reg"))
|
||||
"a_e*2,a_m,a_w")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Multiplication Instructions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Multiplication instructions loop in the execute stage until the
|
||||
;; instruction has been passed through the multiplier array enough
|
||||
;; times.
|
||||
|
||||
;; The result of the "smul" and "smulw" instructions is not available
|
||||
;; until after the memory stage.
|
||||
(define_insn_reservation "mult1" 2
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "insn" "smulxy,smulwy"))
|
||||
"a_e,a_m,a_w")
|
||||
|
||||
;; The "smlaxy" and "smlawx" instructions require two iterations through
|
||||
;; the execute stage; the result is available immediately following
|
||||
;; the execute stage.
|
||||
(define_insn_reservation "mult2" 2
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "insn" "smlaxy,smlalxy,smlawx"))
|
||||
"a_e*2,a_m,a_w")
|
||||
|
||||
;; The "smlalxy", "mul", and "mla" instructions require two iterations
|
||||
;; through the execute stage; the result is not available until after
|
||||
;; the memory stage.
|
||||
(define_insn_reservation "mult3" 3
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "insn" "smlalxy,mul,mla"))
|
||||
"a_e*2,a_m,a_w")
|
||||
|
||||
;; The "muls" and "mlas" instructions loop in the execute stage for
|
||||
;; four iterations in order to set the flags. The value result is
|
||||
;; available after three iterations.
|
||||
(define_insn_reservation "mult4" 3
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "insn" "muls,mlas"))
|
||||
"a_e*4,a_m,a_w")
|
||||
|
||||
;; Long multiply instructions that produce two registers of
|
||||
;; output (such as umull) make their results available in two cycles;
|
||||
;; the least significant word is available before the most significant
|
||||
;; word. That fact is not modeled; instead, the instructions are
|
||||
;; described.as if the entire result was available at the end of the
|
||||
;; cycle in which both words are available.
|
||||
|
||||
;; The "umull", "umlal", "smull", and "smlal" instructions all take
|
||||
;; three iterations through the execute cycle, and make their results
|
||||
;; available after the memory cycle.
|
||||
(define_insn_reservation "mult5" 4
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "insn" "umull,umlal,smull,smlal"))
|
||||
"a_e*3,a_m,a_w")
|
||||
|
||||
;; The "umulls", "umlals", "smulls", and "smlals" instructions loop in
|
||||
;; the execute stage for five iterations in order to set the flags.
|
||||
;; The value result is vailable after four iterations.
|
||||
(define_insn_reservation "mult6" 4
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "insn" "umulls,umlals,smulls,smlals"))
|
||||
"a_e*5,a_m,a_w")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Load/Store Instructions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; The models for load/store instructions do not accurately describe
|
||||
;; the difference between operations with a base register writeback
|
||||
;; (such as "ldm!"). These models assume that all memory references
|
||||
;; hit in dcache.
|
||||
|
||||
;; LSU instructions require six cycles to execute. They use the ALU
|
||||
;; pipeline in all but the 5th cycle, and the LSU pipeline in cycles
|
||||
;; three through six.
|
||||
;; Loads and stores which use a scaled register offset or scaled
|
||||
;; register pre-indexed addressing mode take three cycles EXCEPT for
|
||||
;; those that are base + offset with LSL of 0 or 2, or base - offset
|
||||
;; with LSL of zero. The remainder take 1 cycle to execute.
|
||||
;; For 4byte loads there is a bypass from the load stage
|
||||
|
||||
(define_insn_reservation "load1_op" 2
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "type" "load_byte,load1"))
|
||||
"a_e+l_e,l_m,a_w+l_w")
|
||||
|
||||
(define_insn_reservation "store1_op" 0
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "type" "store1"))
|
||||
"a_e+l_e,l_m,a_w+l_w")
|
||||
|
||||
;; A load's result can be stored by an immediately following store
|
||||
(define_bypass 1 "load1_op" "store1_op" "arm_no_early_store_addr_dep")
|
||||
|
||||
;; On a LDM/STM operation, the LSU pipeline iterates until all of the
|
||||
;; registers have been processed.
|
||||
;;
|
||||
;; The time it takes to load the data depends on whether or not the
|
||||
;; base address is 64-bit aligned; if it is not, an additional cycle
|
||||
;; is required. This model assumes that the address is always 64-bit
|
||||
;; aligned. Because the processor can load two registers per cycle,
|
||||
;; that assumption means that we use the same instruction rservations
|
||||
;; for loading 2k and 2k - 1 registers.
|
||||
;;
|
||||
;; The ALU pipeline is stalled until the completion of the last memory
|
||||
;; stage in the LSU pipeline. That is modeled by keeping the ALU
|
||||
;; execute stage busy until that point.
|
||||
;;
|
||||
;; As with ALU operations, if one of the destination registers is the
|
||||
;; PC, there are additional stalls; that is not modeled.
|
||||
|
||||
(define_insn_reservation "load2_op" 2
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "type" "load2"))
|
||||
"a_e+l_e,l_m,a_w+l_w")
|
||||
|
||||
(define_insn_reservation "store2_op" 0
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "type" "store2"))
|
||||
"a_e+l_e,l_m,a_w+l_w")
|
||||
|
||||
(define_insn_reservation "load34_op" 3
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "type" "load3,load4"))
|
||||
"a_e+l_e,a_e+l_e+l_m,a_e+l_m,a_w+l_w")
|
||||
|
||||
(define_insn_reservation "store34_op" 0
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "type" "store3,store4"))
|
||||
"a_e+l_e,a_e+l_e+l_m,a_e+l_m,a_w+l_w")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Branch and Call Instructions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Branch instructions are difficult to model accurately. The ARM
|
||||
;; core can predict most branches. If the branch is predicted
|
||||
;; correctly, and predicted early enough, the branch can be completely
|
||||
;; eliminated from the instruction stream. Some branches can
|
||||
;; therefore appear to require zero cycles to execute. We assume that
|
||||
;; all branches are predicted correctly, and that the latency is
|
||||
;; therefore the minimum value.
|
||||
|
||||
(define_insn_reservation "branch_op" 0
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "type" "branch"))
|
||||
"nothing")
|
||||
|
||||
;; The latency for a call is not predictable. Therefore, we use 32 as
|
||||
;; roughly equivalent to postive infinity.
|
||||
|
||||
(define_insn_reservation "call_op" 32
|
||||
(and (eq_attr "tune" "arm1026ejs")
|
||||
(eq_attr "type" "call"))
|
||||
"nothing")
|
|
@ -0,0 +1,377 @@
|
|||
;; ARM 1136J[F]-S Pipeline Description
|
||||
;; Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
;; Written by CodeSourcery, LLC.
|
||||
;;
|
||||
;; 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. */
|
||||
|
||||
;; These descriptions are based on the information contained in the
|
||||
;; ARM1136JF-S Technical Reference Manual, Copyright (c) 2003 ARM
|
||||
;; Limited.
|
||||
;;
|
||||
|
||||
;; This automaton provides a pipeline description for the ARM
|
||||
;; 1136J-S and 1136JF-S cores.
|
||||
;;
|
||||
;; The model given here assumes that the condition for all conditional
|
||||
;; instructions is "true", i.e., that all of the instructions are
|
||||
;; actually executed.
|
||||
|
||||
(define_automaton "arm1136jfs")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Pipelines
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; There are three distinct pipelines (page 1-26 and following):
|
||||
;;
|
||||
;; - A 4-stage decode pipeline, shared by all three. It has fetch (1),
|
||||
;; fetch (2), decode, and issue stages. Since this is always involved,
|
||||
;; we do not model it in the scheduler.
|
||||
;;
|
||||
;; - A 4-stage ALU pipeline. It has shifter, ALU (main integer operations),
|
||||
;; and saturation stages. The fourth stage is writeback; see below.
|
||||
;;
|
||||
;; - A 4-stage multiply-accumulate pipeline. It has three stages, called
|
||||
;; MAC1 through MAC3, and a fourth writeback stage.
|
||||
;;
|
||||
;; The 4th-stage writeback is shared between the ALU and MAC pipelines,
|
||||
;; which operate in lockstep. Results from either pipeline will be
|
||||
;; moved into the writeback stage. Because the two pipelines operate
|
||||
;; in lockstep, we schedule them as a single "execute" pipeline.
|
||||
;;
|
||||
;; - A 4-stage LSU pipeline. It has address generation, data cache (1),
|
||||
;; data cache (2), and writeback stages. (Note that this pipeline,
|
||||
;; including the writeback stage, is independant from the ALU & LSU pipes.)
|
||||
|
||||
(define_cpu_unit "e_1,e_2,e_3,e_wb" "arm1136jfs") ; ALU and MAC
|
||||
; e_1 = Sh/Mac1, e_2 = ALU/Mac2, e_3 = SAT/Mac3
|
||||
(define_cpu_unit "l_a,l_dc1,l_dc2,l_wb" "arm1136jfs") ; Load/Store
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ALU Instructions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; ALU instructions require eight cycles to execute, and use the ALU
|
||||
;; pipeline in each of the eight stages. The results are available
|
||||
;; after the alu stage has finished.
|
||||
;;
|
||||
;; If the destination register is the PC, the pipelines are stalled
|
||||
;; for several cycles. That case is not modelled here.
|
||||
|
||||
;; ALU operations with no shifted operand
|
||||
(define_insn_reservation "11_alu_op" 2
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "type" "alu"))
|
||||
"e_1,e_2,e_3,e_wb")
|
||||
|
||||
;; ALU operations with a shift-by-constant operand
|
||||
(define_insn_reservation "11_alu_shift_op" 2
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "type" "alu_shift"))
|
||||
"e_1,e_2,e_3,e_wb")
|
||||
|
||||
;; ALU operations with a shift-by-register operand
|
||||
;; These really stall in the decoder, in order to read
|
||||
;; the shift value in a second cycle. Pretend we take two cycles in
|
||||
;; the shift stage.
|
||||
(define_insn_reservation "11_alu_shift_reg_op" 3
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "type" "alu_shift_reg"))
|
||||
"e_1*2,e_2,e_3,e_wb")
|
||||
|
||||
;; alu_ops can start sooner, if there is no shifter dependency
|
||||
(define_bypass 1 "11_alu_op,11_alu_shift_op"
|
||||
"11_alu_op")
|
||||
(define_bypass 1 "11_alu_op,11_alu_shift_op"
|
||||
"11_alu_shift_op"
|
||||
"arm_no_early_alu_shift_value_dep")
|
||||
(define_bypass 1 "11_alu_op,11_alu_shift_op"
|
||||
"11_alu_shift_reg_op"
|
||||
"arm_no_early_alu_shift_dep")
|
||||
(define_bypass 2 "11_alu_shift_reg_op"
|
||||
"11_alu_op")
|
||||
(define_bypass 2 "11_alu_shift_reg_op"
|
||||
"11_alu_shift_op"
|
||||
"arm_no_early_alu_shift_value_dep")
|
||||
(define_bypass 2 "11_alu_shift_reg_op"
|
||||
"11_alu_shift_reg_op"
|
||||
"arm_no_early_alu_shift_dep")
|
||||
|
||||
(define_bypass 1 "11_alu_op,11_alu_shift_op"
|
||||
"11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
|
||||
"arm_no_early_mul_dep")
|
||||
(define_bypass 2 "11_alu_shift_reg_op"
|
||||
"11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
|
||||
"arm_no_early_mul_dep")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Multiplication Instructions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Multiplication instructions loop in the first two execute stages until
|
||||
;; the instruction has been passed through the multiplier array enough
|
||||
;; times.
|
||||
|
||||
;; Multiply and multiply-accumulate results are available after four stages.
|
||||
(define_insn_reservation "11_mult1" 4
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "insn" "mul,mla"))
|
||||
"e_1*2,e_2,e_3,e_wb")
|
||||
|
||||
;; The *S variants set the condition flags, which requires three more cycles.
|
||||
(define_insn_reservation "11_mult2" 4
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "insn" "muls,mlas"))
|
||||
"e_1*2,e_2,e_3,e_wb")
|
||||
|
||||
(define_bypass 3 "11_mult1,11_mult2"
|
||||
"11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
|
||||
"arm_no_early_mul_dep")
|
||||
(define_bypass 3 "11_mult1,11_mult2"
|
||||
"11_alu_op")
|
||||
(define_bypass 3 "11_mult1,11_mult2"
|
||||
"11_alu_shift_op"
|
||||
"arm_no_early_alu_shift_value_dep")
|
||||
(define_bypass 3 "11_mult1,11_mult2"
|
||||
"11_alu_shift_reg_op"
|
||||
"arm_no_early_alu_shift_dep")
|
||||
(define_bypass 3 "11_mult1,11_mult2"
|
||||
"11_store1"
|
||||
"arm_no_early_store_addr_dep")
|
||||
|
||||
;; Signed and unsigned multiply long results are available across two cycles;
|
||||
;; the less significant word is available one cycle before the more significant
|
||||
;; word. Here we conservatively wait until both are available, which is
|
||||
;; after three iterations and the memory cycle. The same is also true of
|
||||
;; the two multiply-accumulate instructions.
|
||||
(define_insn_reservation "11_mult3" 5
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "insn" "smull,umull,smlal,umlal"))
|
||||
"e_1*3,e_2,e_3,e_wb*2")
|
||||
|
||||
;; The *S variants set the condition flags, which requires three more cycles.
|
||||
(define_insn_reservation "11_mult4" 5
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "insn" "smulls,umulls,smlals,umlals"))
|
||||
"e_1*3,e_2,e_3,e_wb*2")
|
||||
|
||||
(define_bypass 4 "11_mult3,11_mult4"
|
||||
"11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
|
||||
"arm_no_early_mul_dep")
|
||||
(define_bypass 4 "11_mult3,11_mult4"
|
||||
"11_alu_op")
|
||||
(define_bypass 4 "11_mult3,11_mult4"
|
||||
"11_alu_shift_op"
|
||||
"arm_no_early_alu_shift_value_dep")
|
||||
(define_bypass 4 "11_mult3,11_mult4"
|
||||
"11_alu_shift_reg_op"
|
||||
"arm_no_early_alu_shift_dep")
|
||||
(define_bypass 4 "11_mult3,11_mult4"
|
||||
"11_store1"
|
||||
"arm_no_early_store_addr_dep")
|
||||
|
||||
;; Various 16x16->32 multiplies and multiply-accumulates, using combinations
|
||||
;; of high and low halves of the argument registers. They take a single
|
||||
;; pass through the pipeline and make the result available after three
|
||||
;; cycles.
|
||||
(define_insn_reservation "11_mult5" 3
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "insn" "smulxy,smlaxy,smulwy,smlawy,smuad,smuadx,smlad,smladx,smusd,smusdx,smlsd,smlsdx"))
|
||||
"e_1,e_2,e_3,e_wb")
|
||||
|
||||
(define_bypass 2 "11_mult5"
|
||||
"11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
|
||||
"arm_no_early_mul_dep")
|
||||
(define_bypass 2 "11_mult5"
|
||||
"11_alu_op")
|
||||
(define_bypass 2 "11_mult5"
|
||||
"11_alu_shift_op"
|
||||
"arm_no_early_alu_shift_value_dep")
|
||||
(define_bypass 2 "11_mult5"
|
||||
"11_alu_shift_reg_op"
|
||||
"arm_no_early_alu_shift_dep")
|
||||
(define_bypass 2 "11_mult5"
|
||||
"11_store1"
|
||||
"arm_no_early_store_addr_dep")
|
||||
|
||||
;; The same idea, then the 32-bit result is added to a 64-bit quantity.
|
||||
(define_insn_reservation "11_mult6" 4
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "insn" "smlalxy"))
|
||||
"e_1*2,e_2,e_3,e_wb*2")
|
||||
|
||||
;; Signed 32x32 multiply, then the most significant 32 bits are extracted
|
||||
;; and are available after the memory stage.
|
||||
(define_insn_reservation "11_mult7" 4
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "insn" "smmul,smmulr"))
|
||||
"e_1*2,e_2,e_3,e_wb")
|
||||
|
||||
(define_bypass 3 "11_mult6,11_mult7"
|
||||
"11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
|
||||
"arm_no_early_mul_dep")
|
||||
(define_bypass 3 "11_mult6,11_mult7"
|
||||
"11_alu_op")
|
||||
(define_bypass 3 "11_mult6,11_mult7"
|
||||
"11_alu_shift_op"
|
||||
"arm_no_early_alu_shift_value_dep")
|
||||
(define_bypass 3 "11_mult6,11_mult7"
|
||||
"11_alu_shift_reg_op"
|
||||
"arm_no_early_alu_shift_dep")
|
||||
(define_bypass 3 "11_mult6,11_mult7"
|
||||
"11_store1"
|
||||
"arm_no_early_store_addr_dep")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Branch Instructions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; These vary greatly depending on their arguments and the results of
|
||||
;; stat prediction. Cycle count ranges from zero (unconditional branch,
|
||||
;; folded dynamic prediction) to seven (incorrect predictions, etc). We
|
||||
;; assume an optimal case for now, because the cost of a cache miss
|
||||
;; overwhelms the cost of everything else anyhow.
|
||||
|
||||
(define_insn_reservation "11_branches" 0
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "type" "branch"))
|
||||
"nothing")
|
||||
|
||||
;; Call latencies are not predictable. A semi-arbitrary very large
|
||||
;; number is used as "positive infinity" so that everything should be
|
||||
;; finished by the time of return.
|
||||
(define_insn_reservation "11_call" 32
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "type" "call"))
|
||||
"nothing")
|
||||
|
||||
;; Branches are predicted. A correctly predicted branch will be no
|
||||
;; cost, but we're conservative here, and use the timings a
|
||||
;; late-register would give us.
|
||||
(define_bypass 1 "11_alu_op,11_alu_shift_op"
|
||||
"11_branches")
|
||||
(define_bypass 2 "11_alu_shift_reg_op"
|
||||
"11_branches")
|
||||
(define_bypass 2 "11_load1,11_load2"
|
||||
"11_branches")
|
||||
(define_bypass 3 "11_load34"
|
||||
"11_branches")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Load/Store Instructions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; The models for load/store instructions do not accurately describe
|
||||
;; the difference between operations with a base register writeback.
|
||||
;; These models assume that all memory references hit in dcache. Also,
|
||||
;; if the PC is one of the registers involved, there are additional stalls
|
||||
;; not modelled here. Addressing modes are also not modelled.
|
||||
|
||||
(define_insn_reservation "11_load1" 3
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "type" "load1"))
|
||||
"l_a+e_1,l_dc1,l_dc2,l_wb")
|
||||
|
||||
;; Load byte results are not available until the writeback stage, where
|
||||
;; the correct byte is extracted.
|
||||
|
||||
(define_insn_reservation "11_loadb" 4
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "type" "load_byte"))
|
||||
"l_a+e_1,l_dc1,l_dc2,l_wb")
|
||||
|
||||
(define_insn_reservation "11_store1" 0
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "type" "store1"))
|
||||
"l_a+e_1,l_dc1,l_dc2,l_wb")
|
||||
|
||||
;; Load/store double words into adjacent registers. The timing and
|
||||
;; latencies are different depending on whether the address is 64-bit
|
||||
;; aligned. This model assumes that it is.
|
||||
(define_insn_reservation "11_load2" 3
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "type" "load2"))
|
||||
"l_a+e_1,l_dc1,l_dc2,l_wb")
|
||||
|
||||
(define_insn_reservation "11_store2" 0
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "type" "store2"))
|
||||
"l_a+e_1,l_dc1,l_dc2,l_wb")
|
||||
|
||||
;; Load/store multiple registers. Two registers are stored per cycle.
|
||||
;; Actual timing depends on how many registers are affected, so we
|
||||
;; optimistically schedule a low latency.
|
||||
(define_insn_reservation "11_load34" 4
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "type" "load3,load4"))
|
||||
"l_a+e_1,l_dc1*2,l_dc2,l_wb")
|
||||
|
||||
(define_insn_reservation "11_store34" 0
|
||||
(and (eq_attr "tune" "arm1136js,arm1136jfs")
|
||||
(eq_attr "type" "store3,store4"))
|
||||
"l_a+e_1,l_dc1*2,l_dc2,l_wb")
|
||||
|
||||
;; A store can start immediately after an alu op, if that alu op does
|
||||
;; not provide part of the address to access.
|
||||
(define_bypass 1 "11_alu_op,11_alu_shift_op"
|
||||
"11_store1"
|
||||
"arm_no_early_store_addr_dep")
|
||||
(define_bypass 2 "11_alu_shift_reg_op"
|
||||
"11_store1"
|
||||
"arm_no_early_store_addr_dep")
|
||||
|
||||
;; An alu op can start sooner after a load, if that alu op does not
|
||||
;; have an early register dependancy on the load
|
||||
(define_bypass 2 "11_load1"
|
||||
"11_alu_op")
|
||||
(define_bypass 2 "11_load1"
|
||||
"11_alu_shift_op"
|
||||
"arm_no_early_alu_shift_value_dep")
|
||||
(define_bypass 2 "11_load1"
|
||||
"11_alu_shift_reg_op"
|
||||
"arm_no_early_alu_shift_dep")
|
||||
|
||||
(define_bypass 3 "11_loadb"
|
||||
"11_alu_op")
|
||||
(define_bypass 3 "11_loadb"
|
||||
"11_alu_shift_op"
|
||||
"arm_no_early_alu_shift_value_dep")
|
||||
(define_bypass 3 "11_loadb"
|
||||
"11_alu_shift_reg_op"
|
||||
"arm_no_early_alu_shift_dep")
|
||||
|
||||
;; A mul op can start sooner after a load, if that mul op does not
|
||||
;; have an early multiply dependency
|
||||
(define_bypass 2 "11_load1"
|
||||
"11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
|
||||
"arm_no_early_mul_dep")
|
||||
(define_bypass 3 "11_load34"
|
||||
"11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
|
||||
"arm_no_early_mul_dep")
|
||||
(define_bypass 3 "11_loadb"
|
||||
"11_mult1,11_mult2,11_mult3,11_mult4,11_mult5,11_mult6,11_mult7"
|
||||
"arm_no_early_mul_dep")
|
||||
|
||||
;; A store can start sooner after a load, if that load does not
|
||||
;; produce part of the address to access
|
||||
(define_bypass 2 "11_load1"
|
||||
"11_store1"
|
||||
"arm_no_early_store_addr_dep")
|
||||
(define_bypass 3 "11_loadb"
|
||||
"11_store1"
|
||||
"arm_no_early_store_addr_dep")
|
|
@ -0,0 +1,188 @@
|
|||
;; ARM 926EJ-S Pipeline Description
|
||||
;; Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
;; Written by CodeSourcery, LLC.
|
||||
;;
|
||||
;; 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. */
|
||||
|
||||
;; These descriptions are based on the information contained in the
|
||||
;; ARM926EJ-S Technical Reference Manual, Copyright (c) 2002 ARM
|
||||
;; Limited.
|
||||
;;
|
||||
|
||||
;; This automaton provides a pipeline description for the ARM
|
||||
;; 926EJ-S core.
|
||||
;;
|
||||
;; The model given here assumes that the condition for all conditional
|
||||
;; instructions is "true", i.e., that all of the instructions are
|
||||
;; actually executed.
|
||||
|
||||
(define_automaton "arm926ejs")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Pipelines
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; There is a single pipeline
|
||||
;;
|
||||
;; The ALU pipeline has fetch, decode, execute, memory, and
|
||||
;; write stages. We only need to model the execute, memory and write
|
||||
;; stages.
|
||||
|
||||
(define_cpu_unit "e,m,w" "arm926ejs")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ALU Instructions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; ALU instructions require three cycles to execute, and use the ALU
|
||||
;; pipeline in each of the three stages. The results are available
|
||||
;; after the execute stage stage has finished.
|
||||
;;
|
||||
;; If the destination register is the PC, the pipelines are stalled
|
||||
;; for several cycles. That case is not modeled here.
|
||||
|
||||
;; ALU operations with no shifted operand
|
||||
(define_insn_reservation "9_alu_op" 1
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "type" "alu,alu_shift"))
|
||||
"e,m,w")
|
||||
|
||||
;; ALU operations with a shift-by-register operand
|
||||
;; These really stall in the decoder, in order to read
|
||||
;; the shift value in a second cycle. Pretend we take two cycles in
|
||||
;; the execute stage.
|
||||
(define_insn_reservation "9_alu_shift_reg_op" 2
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "type" "alu_shift_reg"))
|
||||
"e*2,m,w")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Multiplication Instructions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Multiplication instructions loop in the execute stage until the
|
||||
;; instruction has been passed through the multiplier array enough
|
||||
;; times. Multiply operations occur in both the execute and memory
|
||||
;; stages of the pipeline
|
||||
|
||||
(define_insn_reservation "9_mult1" 3
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "insn" "smlalxy,mul,mla"))
|
||||
"e*2,m,w")
|
||||
|
||||
(define_insn_reservation "9_mult2" 4
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "insn" "muls,mlas"))
|
||||
"e*3,m,w")
|
||||
|
||||
(define_insn_reservation "9_mult3" 4
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "insn" "umull,umlal,smull,smlal"))
|
||||
"e*3,m,w")
|
||||
|
||||
(define_insn_reservation "9_mult4" 5
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "insn" "umulls,umlals,smulls,smlals"))
|
||||
"e*4,m,w")
|
||||
|
||||
(define_insn_reservation "9_mult5" 2
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "insn" "smulxy,smlaxy,smlawx"))
|
||||
"e,m,w")
|
||||
|
||||
(define_insn_reservation "9_mult6" 3
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "insn" "smlalxy"))
|
||||
"e*2,m,w")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Load/Store Instructions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; The models for load/store instructions do not accurately describe
|
||||
;; the difference between operations with a base register writeback
|
||||
;; (such as "ldm!"). These models assume that all memory references
|
||||
;; hit in dcache.
|
||||
|
||||
;; Loads with a shifted offset take 3 cycles, and are (a) probably the
|
||||
;; most common and (b) the pessimistic assumption will lead to fewer stalls.
|
||||
(define_insn_reservation "9_load1_op" 3
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "type" "load1,load_byte"))
|
||||
"e*2,m,w")
|
||||
|
||||
(define_insn_reservation "9_store1_op" 0
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "type" "store1"))
|
||||
"e,m,w")
|
||||
|
||||
;; multiple word loads and stores
|
||||
(define_insn_reservation "9_load2_op" 3
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "type" "load2"))
|
||||
"e,m*2,w")
|
||||
|
||||
(define_insn_reservation "9_load3_op" 4
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "type" "load3"))
|
||||
"e,m*3,w")
|
||||
|
||||
(define_insn_reservation "9_load4_op" 5
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "type" "load4"))
|
||||
"e,m*4,w")
|
||||
|
||||
(define_insn_reservation "9_store2_op" 0
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "type" "store2"))
|
||||
"e,m*2,w")
|
||||
|
||||
(define_insn_reservation "9_store3_op" 0
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "type" "store3"))
|
||||
"e,m*3,w")
|
||||
|
||||
(define_insn_reservation "9_store4_op" 0
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "type" "store4"))
|
||||
"e,m*4,w")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Branch and Call Instructions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Branch instructions are difficult to model accurately. The ARM
|
||||
;; core can predict most branches. If the branch is predicted
|
||||
;; correctly, and predicted early enough, the branch can be completely
|
||||
;; eliminated from the instruction stream. Some branches can
|
||||
;; therefore appear to require zero cycles to execute. We assume that
|
||||
;; all branches are predicted correctly, and that the latency is
|
||||
;; therefore the minimum value.
|
||||
|
||||
(define_insn_reservation "9_branch_op" 0
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "type" "branch"))
|
||||
"nothing")
|
||||
|
||||
;; The latency for a call is not predictable. Therefore, we use 32 as
|
||||
;; roughly equivalent to postive infinity.
|
||||
|
||||
(define_insn_reservation "9_call_op" 32
|
||||
(and (eq_attr "tune" "arm926ejs")
|
||||
(eq_attr "type" "call"))
|
||||
"nothing")
|
|
@ -34,7 +34,7 @@
|
|||
[(set (match_operand:DI 0 "cirrus_fp_register" "=v")
|
||||
(plus:DI (match_operand:DI 1 "cirrus_fp_register" "v")
|
||||
(match_operand:DI 2 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfadd64%?\\t%V0, %V1, %V2"
|
||||
[(set_attr "type" "mav_farith")
|
||||
(set_attr "cirrus" "normal")]
|
||||
|
@ -44,7 +44,7 @@
|
|||
[(set (match_operand:SI 0 "cirrus_fp_register" "=v")
|
||||
(plus:SI (match_operand:SI 1 "cirrus_fp_register" "v")
|
||||
(match_operand:SI 2 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS && 0"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0"
|
||||
"cfadd32%?\\t%V0, %V1, %V2"
|
||||
[(set_attr "type" "mav_farith")
|
||||
(set_attr "cirrus" "normal")]
|
||||
|
@ -54,7 +54,7 @@
|
|||
[(set (match_operand:SF 0 "cirrus_fp_register" "=v")
|
||||
(plus:SF (match_operand:SF 1 "cirrus_fp_register" "v")
|
||||
(match_operand:SF 2 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfadds%?\\t%V0, %V1, %V2"
|
||||
[(set_attr "type" "mav_farith")
|
||||
(set_attr "cirrus" "normal")]
|
||||
|
@ -64,7 +64,7 @@
|
|||
[(set (match_operand:DF 0 "cirrus_fp_register" "=v")
|
||||
(plus:DF (match_operand:DF 1 "cirrus_fp_register" "v")
|
||||
(match_operand:DF 2 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfaddd%?\\t%V0, %V1, %V2"
|
||||
[(set_attr "type" "mav_farith")
|
||||
(set_attr "cirrus" "normal")]
|
||||
|
@ -74,7 +74,7 @@
|
|||
[(set (match_operand:DI 0 "cirrus_fp_register" "=v")
|
||||
(minus:DI (match_operand:DI 1 "cirrus_fp_register" "v")
|
||||
(match_operand:DI 2 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfsub64%?\\t%V0, %V1, %V2"
|
||||
[(set_attr "type" "mav_farith")
|
||||
(set_attr "cirrus" "normal")]
|
||||
|
@ -84,7 +84,7 @@
|
|||
[(set (match_operand:SI 0 "cirrus_fp_register" "=v")
|
||||
(minus:SI (match_operand:SI 1 "cirrus_fp_register" "v")
|
||||
(match_operand:SI 2 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS && 0"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0"
|
||||
"cfsub32%?\\t%V0, %V1, %V2"
|
||||
[(set_attr "type" "mav_farith")
|
||||
(set_attr "cirrus" "normal")]
|
||||
|
@ -94,7 +94,7 @@
|
|||
[(set (match_operand:SF 0 "cirrus_fp_register" "=v")
|
||||
(minus:SF (match_operand:SF 1 "cirrus_fp_register" "v")
|
||||
(match_operand:SF 2 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfsubs%?\\t%V0, %V1, %V2"
|
||||
[(set_attr "type" "mav_farith")
|
||||
(set_attr "cirrus" "normal")]
|
||||
|
@ -104,7 +104,7 @@
|
|||
[(set (match_operand:DF 0 "cirrus_fp_register" "=v")
|
||||
(minus:DF (match_operand:DF 1 "cirrus_fp_register" "v")
|
||||
(match_operand:DF 2 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfsubd%?\\t%V0, %V1, %V2"
|
||||
[(set_attr "type" "mav_farith")
|
||||
(set_attr "cirrus" "normal")]
|
||||
|
@ -114,7 +114,7 @@
|
|||
[(set (match_operand:SI 0 "cirrus_fp_register" "=v")
|
||||
(mult:SI (match_operand:SI 2 "cirrus_fp_register" "v")
|
||||
(match_operand:SI 1 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS && 0"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0"
|
||||
"cfmul32%?\\t%V0, %V1, %V2"
|
||||
[(set_attr "type" "mav_farith")
|
||||
(set_attr "cirrus" "normal")]
|
||||
|
@ -124,7 +124,7 @@
|
|||
[(set (match_operand:DI 0 "cirrus_fp_register" "=v")
|
||||
(mult:DI (match_operand:DI 2 "cirrus_fp_register" "v")
|
||||
(match_operand:DI 1 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfmul64%?\\t%V0, %V1, %V2"
|
||||
[(set_attr "type" "mav_dmult")
|
||||
(set_attr "cirrus" "normal")]
|
||||
|
@ -136,7 +136,7 @@
|
|||
(mult:SI (match_operand:SI 1 "cirrus_fp_register" "v")
|
||||
(match_operand:SI 2 "cirrus_fp_register" "v"))
|
||||
(match_operand:SI 3 "cirrus_fp_register" "0")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS && 0"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0"
|
||||
"cfmac32%?\\t%V0, %V1, %V2"
|
||||
[(set_attr "type" "mav_farith")
|
||||
(set_attr "cirrus" "normal")]
|
||||
|
@ -149,7 +149,7 @@
|
|||
(match_operand:SI 1 "cirrus_fp_register" "0")
|
||||
(mult:SI (match_operand:SI 2 "cirrus_fp_register" "v")
|
||||
(match_operand:SI 3 "cirrus_fp_register" "v"))))]
|
||||
"0 && TARGET_ARM && TARGET_CIRRUS"
|
||||
"0 && TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfmsc32%?\\t%V0, %V2, %V3"
|
||||
[(set_attr "type" "mav_farith")
|
||||
(set_attr "cirrus" "normal")]
|
||||
|
@ -159,7 +159,7 @@
|
|||
[(set (match_operand:SF 0 "cirrus_fp_register" "=v")
|
||||
(mult:SF (match_operand:SF 1 "cirrus_fp_register" "v")
|
||||
(match_operand:SF 2 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfmuls%?\\t%V0, %V1, %V2"
|
||||
[(set_attr "type" "mav_farith")
|
||||
(set_attr "cirrus" "normal")]
|
||||
|
@ -169,7 +169,7 @@
|
|||
[(set (match_operand:DF 0 "cirrus_fp_register" "=v")
|
||||
(mult:DF (match_operand:DF 1 "cirrus_fp_register" "v")
|
||||
(match_operand:DF 2 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfmuld%?\\t%V0, %V1, %V2"
|
||||
[(set_attr "type" "mav_dmult")
|
||||
(set_attr "cirrus" "normal")]
|
||||
|
@ -179,7 +179,7 @@
|
|||
[(set (match_operand:SI 0 "cirrus_fp_register" "=v")
|
||||
(ashift:SI (match_operand:SI 1 "cirrus_fp_register" "v")
|
||||
(match_operand:SI 2 "cirrus_shift_const" "")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS && 0"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0"
|
||||
"cfsh32%?\\t%V0, %V1, #%s2"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -188,7 +188,7 @@
|
|||
[(set (match_operand:SI 0 "cirrus_fp_register" "=v")
|
||||
(ashiftrt:SI (match_operand:SI 1 "cirrus_fp_register" "v")
|
||||
(match_operand:SI 2 "cirrus_shift_const" "")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS && 0"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0"
|
||||
"cfsh32%?\\t%V0, %V1, #-%s2"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -197,7 +197,7 @@
|
|||
[(set (match_operand:SI 0 "cirrus_fp_register" "=v")
|
||||
(ashift:SI (match_operand:SI 1 "cirrus_fp_register" "v")
|
||||
(match_operand:SI 2 "register_operand" "r")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS && 0"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0"
|
||||
"cfrshl32%?\\t%V1, %V0, %s2"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -206,7 +206,7 @@
|
|||
[(set (match_operand:DI 0 "cirrus_fp_register" "=v")
|
||||
(ashift:DI (match_operand:DI 1 "cirrus_fp_register" "v")
|
||||
(match_operand:SI 2 "register_operand" "r")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfrshl64%?\\t%V1, %V0, %s2"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -215,7 +215,7 @@
|
|||
[(set (match_operand:DI 0 "cirrus_fp_register" "=v")
|
||||
(ashift:DI (match_operand:DI 1 "cirrus_fp_register" "v")
|
||||
(match_operand:SI 2 "cirrus_shift_const" "")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfsh64%?\\t%V0, %V1, #%s2"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -224,7 +224,7 @@
|
|||
[(set (match_operand:DI 0 "cirrus_fp_register" "=v")
|
||||
(ashiftrt:DI (match_operand:DI 1 "cirrus_fp_register" "v")
|
||||
(match_operand:SI 2 "cirrus_shift_const" "")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfsh64%?\\t%V0, %V1, #-%s2"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -232,7 +232,7 @@
|
|||
(define_insn "*cirrus_absdi2"
|
||||
[(set (match_operand:DI 0 "cirrus_fp_register" "=v")
|
||||
(abs:DI (match_operand:DI 1 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfabs64%?\\t%V0, %V1"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -242,7 +242,7 @@
|
|||
[(set (match_operand:DI 0 "cirrus_fp_register" "=v")
|
||||
(neg:DI (match_operand:DI 1 "cirrus_fp_register" "v")))
|
||||
(clobber (reg:CC CC_REGNUM))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfneg64%?\\t%V0, %V1"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -250,7 +250,7 @@
|
|||
(define_insn "*cirrus_negsi2"
|
||||
[(set (match_operand:SI 0 "cirrus_fp_register" "=v")
|
||||
(neg:SI (match_operand:SI 1 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS && 0"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0"
|
||||
"cfneg32%?\\t%V0, %V1"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -258,7 +258,7 @@
|
|||
(define_insn "*cirrus_negsf2"
|
||||
[(set (match_operand:SF 0 "cirrus_fp_register" "=v")
|
||||
(neg:SF (match_operand:SF 1 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfnegs%?\\t%V0, %V1"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -266,7 +266,7 @@
|
|||
(define_insn "*cirrus_negdf2"
|
||||
[(set (match_operand:DF 0 "cirrus_fp_register" "=v")
|
||||
(neg:DF (match_operand:DF 1 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfnegd%?\\t%V0, %V1"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -276,7 +276,7 @@
|
|||
[(set (match_operand:SI 0 "cirrus_fp_register" "=v")
|
||||
(abs:SI (match_operand:SI 1 "cirrus_fp_register" "v")))
|
||||
(clobber (reg:CC CC_REGNUM))]
|
||||
"TARGET_ARM && TARGET_CIRRUS && 0"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0"
|
||||
"cfabs32%?\\t%V0, %V1"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -284,7 +284,7 @@
|
|||
(define_insn "*cirrus_abssf2"
|
||||
[(set (match_operand:SF 0 "cirrus_fp_register" "=v")
|
||||
(abs:SF (match_operand:SF 1 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfabss%?\\t%V0, %V1"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -292,7 +292,7 @@
|
|||
(define_insn "*cirrus_absdf2"
|
||||
[(set (match_operand:DF 0 "cirrus_fp_register" "=v")
|
||||
(abs:DF (match_operand:DF 1 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfabsd%?\\t%V0, %V1"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -302,7 +302,7 @@
|
|||
[(set (match_operand:SF 0 "cirrus_fp_register" "=v")
|
||||
(float:SF (match_operand:SI 1 "s_register_operand" "r")))
|
||||
(clobber (match_scratch:DF 2 "=v"))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfmv64lr%?\\t%Z2, %1\;cfcvt32s%?\\t%V0, %Y2"
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "cirrus" "move")]
|
||||
|
@ -312,7 +312,7 @@
|
|||
[(set (match_operand:DF 0 "cirrus_fp_register" "=v")
|
||||
(float:DF (match_operand:SI 1 "s_register_operand" "r")))
|
||||
(clobber (match_scratch:DF 2 "=v"))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfmv64lr%?\\t%Z2, %1\;cfcvt32d%?\\t%V0, %Y2"
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "cirrus" "move")]
|
||||
|
@ -321,14 +321,14 @@
|
|||
(define_insn "floatdisf2"
|
||||
[(set (match_operand:SF 0 "cirrus_fp_register" "=v")
|
||||
(float:SF (match_operand:DI 1 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfcvt64s%?\\t%V0, %V1"
|
||||
[(set_attr "cirrus" "normal")])
|
||||
|
||||
(define_insn "floatdidf2"
|
||||
[(set (match_operand:DF 0 "cirrus_fp_register" "=v")
|
||||
(float:DF (match_operand:DI 1 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfcvt64d%?\\t%V0, %V1"
|
||||
[(set_attr "cirrus" "normal")])
|
||||
|
||||
|
@ -336,7 +336,7 @@
|
|||
[(set (match_operand:SI 0 "s_register_operand" "=r")
|
||||
(fix:SI (fix:SF (match_operand:SF 1 "cirrus_fp_register" "v"))))
|
||||
(clobber (match_scratch:DF 2 "=v"))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cftruncs32%?\\t%Y2, %V1\;cfmvr64l%?\\t%0, %Z2"
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "cirrus" "normal")]
|
||||
|
@ -346,7 +346,7 @@
|
|||
[(set (match_operand:SI 0 "s_register_operand" "=r")
|
||||
(fix:SI (fix:DF (match_operand:DF 1 "cirrus_fp_register" "v"))))
|
||||
(clobber (match_scratch:DF 2 "=v"))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cftruncd32%?\\t%Y2, %V1\;cfmvr64l%?\\t%0, %Z2"
|
||||
[(set_attr "length" "8")]
|
||||
)
|
||||
|
@ -355,7 +355,7 @@
|
|||
[(set (match_operand:SF 0 "cirrus_fp_register" "=v")
|
||||
(float_truncate:SF
|
||||
(match_operand:DF 1 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfcvtds%?\\t%V0, %V1"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -363,7 +363,7 @@
|
|||
(define_insn "*cirrus_extendsfdf2"
|
||||
[(set (match_operand:DF 0 "cirrus_fp_register" "=v")
|
||||
(float_extend:DF (match_operand:SF 1 "cirrus_fp_register" "v")))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"cfcvtsd%?\\t%V0, %V1"
|
||||
[(set_attr "cirrus" "normal")]
|
||||
)
|
||||
|
@ -371,7 +371,7 @@
|
|||
(define_insn "*cirrus_arm_movdi"
|
||||
[(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,o<>,v,r,v,m,v")
|
||||
(match_operand:DI 1 "di_operand" "rIK,mi,r,r,v,m,v,v"))]
|
||||
"TARGET_ARM && TARGET_CIRRUS"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
|
||||
"*
|
||||
{
|
||||
switch (which_alternative)
|
||||
|
@ -394,7 +394,7 @@
|
|||
}
|
||||
}"
|
||||
[(set_attr "length" " 8, 8, 8, 8, 8, 4, 4, 4")
|
||||
(set_attr "type" " *,load,store2, *, *, load,store2, *")
|
||||
(set_attr "type" " *,load2,store2, *, *, load2,store2, *")
|
||||
(set_attr "pool_range" " *,1020, *, *, *, *, *, *")
|
||||
(set_attr "neg_pool_range" " *,1012, *, *, *, *, *, *")
|
||||
(set_attr "cirrus" "not, not, not,move,normal,double,double,normal")]
|
||||
|
@ -406,7 +406,7 @@
|
|||
(define_insn "*cirrus_arm_movsi_insn"
|
||||
[(set (match_operand:SI 0 "general_operand" "=r,r,r,m,*v,r,*v,T,*v")
|
||||
(match_operand:SI 1 "general_operand" "rI,K,mi,r,r,*v,T,*v,*v"))]
|
||||
"TARGET_ARM && TARGET_CIRRUS && 0
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0
|
||||
&& (register_operand (operands[0], SImode)
|
||||
|| register_operand (operands[1], SImode))"
|
||||
"@
|
||||
|
@ -419,7 +419,7 @@
|
|||
cfldr32%?\\t%V0, %1
|
||||
cfstr32%?\\t%V1, %0
|
||||
cfsh32%?\\t%V0, %V1, #0"
|
||||
[(set_attr "type" "*, *, load,store1, *, *, load,store1, *")
|
||||
[(set_attr "type" "*, *, load1,store1, *, *, load1,store1, *")
|
||||
(set_attr "pool_range" "*, *, 4096, *, *, *, 1024, *, *")
|
||||
(set_attr "neg_pool_range" "*, *, 4084, *, *, *, 1012, *, *")
|
||||
(set_attr "cirrus" "not,not, not, not,move,normal,normal,normal,normal")]
|
||||
|
@ -428,7 +428,7 @@
|
|||
(define_insn "*cirrus_movsf_hard_insn"
|
||||
[(set (match_operand:SF 0 "nonimmediate_operand" "=v,v,v,r,m,r,r,m")
|
||||
(match_operand:SF 1 "general_operand" "v,m,r,v,v,r,mE,r"))]
|
||||
"TARGET_ARM && TARGET_CIRRUS
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK
|
||||
&& (GET_CODE (operands[0]) != MEM
|
||||
|| register_operand (operands[1], SFmode))"
|
||||
"@
|
||||
|
@ -441,7 +441,7 @@
|
|||
ldr%?\\t%0, %1\\t%@ float
|
||||
str%?\\t%1, %0\\t%@ float"
|
||||
[(set_attr "length" " *, *, *, *, *, 4, 4, 4")
|
||||
(set_attr "type" " *, load, *, *,store1, *,load,store1")
|
||||
(set_attr "type" " *, load1, *, *,store1, *,load1,store1")
|
||||
(set_attr "pool_range" " *, *, *, *, *, *,4096, *")
|
||||
(set_attr "neg_pool_range" " *, *, *, *, *, *,4084, *")
|
||||
(set_attr "cirrus" "normal,normal,move,normal,normal,not, not, not")]
|
||||
|
@ -451,7 +451,7 @@
|
|||
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,Q,r,m,r,v,v,v,r,m")
|
||||
(match_operand:DF 1 "general_operand" "Q,r,r,r,mF,v,m,r,v,v"))]
|
||||
"TARGET_ARM
|
||||
&& TARGET_CIRRUS
|
||||
&& TARGET_HARD_FLOAT && TARGET_MAVERICK
|
||||
&& (GET_CODE (operands[0]) != MEM
|
||||
|| register_operand (operands[1], DFmode))"
|
||||
"*
|
||||
|
@ -469,7 +469,7 @@
|
|||
default: abort ();
|
||||
}
|
||||
}"
|
||||
[(set_attr "type" "load,store2, *,store2,load, *, load, *, *,store2")
|
||||
[(set_attr "type" "load1,store2, *,store2,load1, *, load1, *, *,store2")
|
||||
(set_attr "length" " 4, 4, 8, 8, 8, 4, 4, 8, 8, 4")
|
||||
(set_attr "pool_range" " *, *, *, *, 252, *, *, *, *, *")
|
||||
(set_attr "neg_pool_range" " *, *, *, *, 244, *, *, *, *, *")
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
|
||||
#ifndef SUBTARGET_ASM_FLOAT_SPEC
|
||||
#define SUBTARGET_ASM_FLOAT_SPEC "\
|
||||
%{mapcs-float:-mfloat} %{msoft-float:-mfpu=softfpa}"
|
||||
%{mapcs-float:-mfloat}"
|
||||
#endif
|
||||
|
||||
#ifndef ASM_SPEC
|
||||
|
@ -58,6 +58,8 @@
|
|||
%{mapcs-*:-mapcs-%*} \
|
||||
%(subtarget_asm_float_spec) \
|
||||
%{mthumb-interwork:-mthumb-interwork} \
|
||||
%{msoft-float:-mfloat-abi=soft} %{mhard-float:-mfloat-abi=hard} \
|
||||
%{mfloat-abi=*} %{mfpu=*} \
|
||||
%(subtarget_extra_asm_spec)"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -100,8 +100,8 @@
|
|||
(define_insn "*addsf3_fpa"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=f,f")
|
||||
(plus:SF (match_operand:SF 1 "s_register_operand" "%f,f")
|
||||
(match_operand:SF 2 "fpa_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:SF 2 "arm_float_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
adf%?s\\t%0, %1, %2
|
||||
suf%?s\\t%0, %1, #%N2"
|
||||
|
@ -112,8 +112,8 @@
|
|||
(define_insn "*adddf3_fpa"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=f,f")
|
||||
(plus:DF (match_operand:DF 1 "s_register_operand" "%f,f")
|
||||
(match_operand:DF 2 "fpa_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:DF 2 "arm_float_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
adf%?d\\t%0, %1, %2
|
||||
suf%?d\\t%0, %1, #%N2"
|
||||
|
@ -125,8 +125,8 @@
|
|||
[(set (match_operand:DF 0 "s_register_operand" "=f,f")
|
||||
(plus:DF (float_extend:DF
|
||||
(match_operand:SF 1 "s_register_operand" "f,f"))
|
||||
(match_operand:DF 2 "fpa_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:DF 2 "arm_float_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
adf%?d\\t%0, %1, %2
|
||||
suf%?d\\t%0, %1, #%N2"
|
||||
|
@ -139,7 +139,7 @@
|
|||
(plus:DF (match_operand:DF 1 "s_register_operand" "f")
|
||||
(float_extend:DF
|
||||
(match_operand:SF 2 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"adf%?d\\t%0, %1, %2"
|
||||
[(set_attr "type" "farith")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -151,7 +151,7 @@
|
|||
(match_operand:SF 1 "s_register_operand" "f"))
|
||||
(float_extend:DF
|
||||
(match_operand:SF 2 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"adf%?d\\t%0, %1, %2"
|
||||
[(set_attr "type" "farith")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -159,9 +159,9 @@
|
|||
|
||||
(define_insn "*subsf3_fpa"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=f,f")
|
||||
(minus:SF (match_operand:SF 1 "fpa_rhs_operand" "f,G")
|
||||
(match_operand:SF 2 "fpa_rhs_operand" "fG,f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "f,G")
|
||||
(match_operand:SF 2 "arm_float_rhs_operand" "fG,f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
suf%?s\\t%0, %1, %2
|
||||
rsf%?s\\t%0, %2, %1"
|
||||
|
@ -170,9 +170,9 @@
|
|||
|
||||
(define_insn "*subdf3_fpa"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=f,f")
|
||||
(minus:DF (match_operand:DF 1 "fpa_rhs_operand" "f,G")
|
||||
(match_operand:DF 2 "fpa_rhs_operand" "fG,f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "f,G")
|
||||
(match_operand:DF 2 "arm_float_rhs_operand" "fG,f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
suf%?d\\t%0, %1, %2
|
||||
rsf%?d\\t%0, %2, %1"
|
||||
|
@ -184,8 +184,8 @@
|
|||
[(set (match_operand:DF 0 "s_register_operand" "=f")
|
||||
(minus:DF (float_extend:DF
|
||||
(match_operand:SF 1 "s_register_operand" "f"))
|
||||
(match_operand:DF 2 "fpa_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"suf%?d\\t%0, %1, %2"
|
||||
[(set_attr "type" "farith")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -193,10 +193,10 @@
|
|||
|
||||
(define_insn "*subdf_df_esfdf_fpa"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=f,f")
|
||||
(minus:DF (match_operand:DF 1 "fpa_rhs_operand" "f,G")
|
||||
(minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "f,G")
|
||||
(float_extend:DF
|
||||
(match_operand:SF 2 "s_register_operand" "f,f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
suf%?d\\t%0, %1, %2
|
||||
rsf%?d\\t%0, %2, %1"
|
||||
|
@ -210,7 +210,7 @@
|
|||
(match_operand:SF 1 "s_register_operand" "f"))
|
||||
(float_extend:DF
|
||||
(match_operand:SF 2 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"suf%?d\\t%0, %1, %2"
|
||||
[(set_attr "type" "farith")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -219,8 +219,8 @@
|
|||
(define_insn "*mulsf3_fpa"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=f")
|
||||
(mult:SF (match_operand:SF 1 "s_register_operand" "f")
|
||||
(match_operand:SF 2 "fpa_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:SF 2 "arm_float_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"fml%?s\\t%0, %1, %2"
|
||||
[(set_attr "type" "ffmul")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -229,8 +229,8 @@
|
|||
(define_insn "*muldf3_fpa"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=f")
|
||||
(mult:DF (match_operand:DF 1 "s_register_operand" "f")
|
||||
(match_operand:DF 2 "fpa_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"muf%?d\\t%0, %1, %2"
|
||||
[(set_attr "type" "fmul")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -240,8 +240,8 @@
|
|||
[(set (match_operand:DF 0 "s_register_operand" "=f")
|
||||
(mult:DF (float_extend:DF
|
||||
(match_operand:SF 1 "s_register_operand" "f"))
|
||||
(match_operand:DF 2 "fpa_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"muf%?d\\t%0, %1, %2"
|
||||
[(set_attr "type" "fmul")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -252,7 +252,7 @@
|
|||
(mult:DF (match_operand:DF 1 "s_register_operand" "f")
|
||||
(float_extend:DF
|
||||
(match_operand:SF 2 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"muf%?d\\t%0, %1, %2"
|
||||
[(set_attr "type" "fmul")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -263,7 +263,7 @@
|
|||
(mult:DF
|
||||
(float_extend:DF (match_operand:SF 1 "s_register_operand" "f"))
|
||||
(float_extend:DF (match_operand:SF 2 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"muf%?d\\t%0, %1, %2"
|
||||
[(set_attr "type" "fmul")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -273,9 +273,9 @@
|
|||
|
||||
(define_insn "*divsf3_fpa"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=f,f")
|
||||
(div:SF (match_operand:SF 1 "fpa_rhs_operand" "f,G")
|
||||
(match_operand:SF 2 "fpa_rhs_operand" "fG,f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(div:SF (match_operand:SF 1 "arm_float_rhs_operand" "f,G")
|
||||
(match_operand:SF 2 "arm_float_rhs_operand" "fG,f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
fdv%?s\\t%0, %1, %2
|
||||
frd%?s\\t%0, %2, %1"
|
||||
|
@ -285,9 +285,9 @@
|
|||
|
||||
(define_insn "*divdf3_fpa"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=f,f")
|
||||
(div:DF (match_operand:DF 1 "fpa_rhs_operand" "f,G")
|
||||
(match_operand:DF 2 "fpa_rhs_operand" "fG,f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(div:DF (match_operand:DF 1 "arm_float_rhs_operand" "f,G")
|
||||
(match_operand:DF 2 "arm_float_rhs_operand" "fG,f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
dvf%?d\\t%0, %1, %2
|
||||
rdf%?d\\t%0, %2, %1"
|
||||
|
@ -299,8 +299,8 @@
|
|||
[(set (match_operand:DF 0 "s_register_operand" "=f")
|
||||
(div:DF (float_extend:DF
|
||||
(match_operand:SF 1 "s_register_operand" "f"))
|
||||
(match_operand:DF 2 "fpa_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"dvf%?d\\t%0, %1, %2"
|
||||
[(set_attr "type" "fdivd")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -308,10 +308,10 @@
|
|||
|
||||
(define_insn "*divdf_df_esfdf_fpa"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=f")
|
||||
(div:DF (match_operand:DF 1 "fpa_rhs_operand" "fG")
|
||||
(div:DF (match_operand:DF 1 "arm_float_rhs_operand" "fG")
|
||||
(float_extend:DF
|
||||
(match_operand:SF 2 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"rdf%?d\\t%0, %2, %1"
|
||||
[(set_attr "type" "fdivd")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -323,7 +323,7 @@
|
|||
(match_operand:SF 1 "s_register_operand" "f"))
|
||||
(float_extend:DF
|
||||
(match_operand:SF 2 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"dvf%?d\\t%0, %1, %2"
|
||||
[(set_attr "type" "fdivd")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -332,8 +332,8 @@
|
|||
(define_insn "*modsf3_fpa"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=f")
|
||||
(mod:SF (match_operand:SF 1 "s_register_operand" "f")
|
||||
(match_operand:SF 2 "fpa_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:SF 2 "arm_float_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"rmf%?s\\t%0, %1, %2"
|
||||
[(set_attr "type" "fdivs")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -342,8 +342,8 @@
|
|||
(define_insn "*moddf3_fpa"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=f")
|
||||
(mod:DF (match_operand:DF 1 "s_register_operand" "f")
|
||||
(match_operand:DF 2 "fpa_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"rmf%?d\\t%0, %1, %2"
|
||||
[(set_attr "type" "fdivd")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -353,8 +353,8 @@
|
|||
[(set (match_operand:DF 0 "s_register_operand" "=f")
|
||||
(mod:DF (float_extend:DF
|
||||
(match_operand:SF 1 "s_register_operand" "f"))
|
||||
(match_operand:DF 2 "fpa_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"rmf%?d\\t%0, %1, %2"
|
||||
[(set_attr "type" "fdivd")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -365,7 +365,7 @@
|
|||
(mod:DF (match_operand:DF 1 "s_register_operand" "f")
|
||||
(float_extend:DF
|
||||
(match_operand:SF 2 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"rmf%?d\\t%0, %1, %2"
|
||||
[(set_attr "type" "fdivd")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -377,7 +377,7 @@
|
|||
(match_operand:SF 1 "s_register_operand" "f"))
|
||||
(float_extend:DF
|
||||
(match_operand:SF 2 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"rmf%?d\\t%0, %1, %2"
|
||||
[(set_attr "type" "fdivd")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -386,7 +386,7 @@
|
|||
(define_insn "*negsf2_fpa"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=f")
|
||||
(neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"mnf%?s\\t%0, %1"
|
||||
[(set_attr "type" "ffarith")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -395,7 +395,7 @@
|
|||
(define_insn "*negdf2_fpa"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=f")
|
||||
(neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"mnf%?d\\t%0, %1"
|
||||
[(set_attr "type" "ffarith")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -405,7 +405,7 @@
|
|||
[(set (match_operand:DF 0 "s_register_operand" "=f")
|
||||
(neg:DF (float_extend:DF
|
||||
(match_operand:SF 1 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"mnf%?d\\t%0, %1"
|
||||
[(set_attr "type" "ffarith")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -414,7 +414,7 @@
|
|||
(define_insn "*abssf2_fpa"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=f")
|
||||
(abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"abs%?s\\t%0, %1"
|
||||
[(set_attr "type" "ffarith")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -423,7 +423,7 @@
|
|||
(define_insn "*absdf2_fpa"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=f")
|
||||
(abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"abs%?d\\t%0, %1"
|
||||
[(set_attr "type" "ffarith")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -433,7 +433,7 @@
|
|||
[(set (match_operand:DF 0 "s_register_operand" "=f")
|
||||
(abs:DF (float_extend:DF
|
||||
(match_operand:SF 1 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"abs%?d\\t%0, %1"
|
||||
[(set_attr "type" "ffarith")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -442,7 +442,7 @@
|
|||
(define_insn "*sqrtsf2_fpa"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=f")
|
||||
(sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"sqt%?s\\t%0, %1"
|
||||
[(set_attr "type" "float_em")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -451,7 +451,7 @@
|
|||
(define_insn "*sqrtdf2_fpa"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=f")
|
||||
(sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"sqt%?d\\t%0, %1"
|
||||
[(set_attr "type" "float_em")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -461,7 +461,7 @@
|
|||
[(set (match_operand:DF 0 "s_register_operand" "=f")
|
||||
(sqrt:DF (float_extend:DF
|
||||
(match_operand:SF 1 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"sqt%?d\\t%0, %1"
|
||||
[(set_attr "type" "float_em")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -470,7 +470,7 @@
|
|||
(define_insn "*floatsisf2_fpa"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=f")
|
||||
(float:SF (match_operand:SI 1 "s_register_operand" "r")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"flt%?s\\t%0, %1"
|
||||
[(set_attr "type" "r_2_f")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -479,7 +479,7 @@
|
|||
(define_insn "*floatsidf2_fpa"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=f")
|
||||
(float:DF (match_operand:SI 1 "s_register_operand" "r")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"flt%?d\\t%0, %1"
|
||||
[(set_attr "type" "r_2_f")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -488,7 +488,7 @@
|
|||
(define_insn "*fix_truncsfsi2_fpa"
|
||||
[(set (match_operand:SI 0 "s_register_operand" "=r")
|
||||
(fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"fix%?z\\t%0, %1"
|
||||
[(set_attr "type" "f_2_r")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -497,7 +497,7 @@
|
|||
(define_insn "*fix_truncdfsi2_fpa"
|
||||
[(set (match_operand:SI 0 "s_register_operand" "=r")
|
||||
(fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"fix%?z\\t%0, %1"
|
||||
[(set_attr "type" "f_2_r")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -507,7 +507,7 @@
|
|||
[(set (match_operand:SF 0 "s_register_operand" "=f")
|
||||
(float_truncate:SF
|
||||
(match_operand:DF 1 "s_register_operand" "f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"mvf%?s\\t%0, %1"
|
||||
[(set_attr "type" "ffarith")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -516,7 +516,7 @@
|
|||
(define_insn "*extendsfdf2_fpa"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=f")
|
||||
(float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"mvf%?d\\t%0, %1"
|
||||
[(set_attr "type" "ffarith")
|
||||
(set_attr "predicable" "yes")]
|
||||
|
@ -526,7 +526,7 @@
|
|||
[(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f, m,f,r,r,r, m")
|
||||
(match_operand:SF 1 "general_operand" "fG,H,mE,f,r,f,r,mE,r"))]
|
||||
"TARGET_ARM
|
||||
&& TARGET_HARD_FLOAT
|
||||
&& TARGET_HARD_FLOAT && TARGET_FPA
|
||||
&& (GET_CODE (operands[0]) != MEM
|
||||
|| register_operand (operands[1], SFmode))"
|
||||
"@
|
||||
|
@ -542,7 +542,7 @@
|
|||
[(set_attr "length" "4,4,4,4,8,8,4,4,4")
|
||||
(set_attr "predicable" "yes")
|
||||
(set_attr "type"
|
||||
"ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")
|
||||
"ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load1,store1")
|
||||
(set_attr "pool_range" "*,*,1024,*,*,*,*,4096,*")
|
||||
(set_attr "neg_pool_range" "*,*,1012,*,*,*,*,4084,*")]
|
||||
)
|
||||
|
@ -553,7 +553,7 @@
|
|||
(match_operand:DF 1 "general_operand"
|
||||
"Q, r,r,r,mF,fG,H,mF,f,r, f"))]
|
||||
"TARGET_ARM
|
||||
&& TARGET_HARD_FLOAT
|
||||
&& TARGET_HARD_FLOAT && TARGET_FPA
|
||||
&& (GET_CODE (operands[0]) != MEM
|
||||
|| register_operand (operands[1], DFmode))"
|
||||
"*
|
||||
|
@ -576,7 +576,7 @@
|
|||
[(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
|
||||
(set_attr "predicable" "yes")
|
||||
(set_attr "type"
|
||||
"load,store2,*,store2,load,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")
|
||||
"load1,store2,*,store2,load1,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")
|
||||
(set_attr "pool_range" "*,*,*,*,1020,*,*,1024,*,*,*")
|
||||
(set_attr "neg_pool_range" "*,*,*,*,1008,*,*,1008,*,*,*")]
|
||||
)
|
||||
|
@ -589,7 +589,7 @@
|
|||
(define_insn "*movxf_fpa"
|
||||
[(set (match_operand:XF 0 "nonimmediate_operand" "=f,f,f,m,f,r,r")
|
||||
(match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && reload_completed"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA && reload_completed"
|
||||
"*
|
||||
switch (which_alternative)
|
||||
{
|
||||
|
@ -613,8 +613,8 @@
|
|||
(define_insn "*cmpsf_fpa"
|
||||
[(set (reg:CCFP CC_REGNUM)
|
||||
(compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
|
||||
(match_operand:SF 1 "fpa_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:SF 1 "arm_float_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
cmf%?\\t%0, %1
|
||||
cnf%?\\t%0, #%N1"
|
||||
|
@ -625,8 +625,8 @@
|
|||
(define_insn "*cmpdf_fpa"
|
||||
[(set (reg:CCFP CC_REGNUM)
|
||||
(compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
|
||||
(match_operand:DF 1 "fpa_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
cmf%?\\t%0, %1
|
||||
cnf%?\\t%0, #%N1"
|
||||
|
@ -638,8 +638,8 @@
|
|||
[(set (reg:CCFP CC_REGNUM)
|
||||
(compare:CCFP (float_extend:DF
|
||||
(match_operand:SF 0 "s_register_operand" "f,f"))
|
||||
(match_operand:DF 1 "fpa_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
cmf%?\\t%0, %1
|
||||
cnf%?\\t%0, #%N1"
|
||||
|
@ -652,7 +652,7 @@
|
|||
(compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
|
||||
(float_extend:DF
|
||||
(match_operand:SF 1 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"cmf%?\\t%0, %1"
|
||||
[(set_attr "conds" "set")
|
||||
(set_attr "type" "f_2_r")]
|
||||
|
@ -661,8 +661,8 @@
|
|||
(define_insn "*cmpsf_trap_fpa"
|
||||
[(set (reg:CCFPE CC_REGNUM)
|
||||
(compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
|
||||
(match_operand:SF 1 "fpa_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:SF 1 "arm_float_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
cmf%?e\\t%0, %1
|
||||
cnf%?e\\t%0, #%N1"
|
||||
|
@ -673,8 +673,8 @@
|
|||
(define_insn "*cmpdf_trap_fpa"
|
||||
[(set (reg:CCFPE CC_REGNUM)
|
||||
(compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
|
||||
(match_operand:DF 1 "fpa_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
cmf%?e\\t%0, %1
|
||||
cnf%?e\\t%0, #%N1"
|
||||
|
@ -686,8 +686,8 @@
|
|||
[(set (reg:CCFPE CC_REGNUM)
|
||||
(compare:CCFPE (float_extend:DF
|
||||
(match_operand:SF 0 "s_register_operand" "f,f"))
|
||||
(match_operand:DF 1 "fpa_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
cmf%?e\\t%0, %1
|
||||
cnf%?e\\t%0, #%N1"
|
||||
|
@ -700,7 +700,7 @@
|
|||
(compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
|
||||
(float_extend:DF
|
||||
(match_operand:SF 1 "s_register_operand" "f"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"cmf%?e\\t%0, %1"
|
||||
[(set_attr "conds" "set")
|
||||
(set_attr "type" "f_2_r")]
|
||||
|
@ -711,9 +711,9 @@
|
|||
(if_then_else:SF
|
||||
(match_operator 3 "arm_comparison_operator"
|
||||
[(match_operand 4 "cc_register" "") (const_int 0)])
|
||||
(match_operand:SF 1 "fpa_add_operand" "0,0,fG,H,fG,fG,H,H")
|
||||
(match_operand:SF 2 "fpa_add_operand" "fG,H,0,0,fG,H,fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:SF 1 "arm_float_add_operand" "0,0,fG,H,fG,fG,H,H")
|
||||
(match_operand:SF 2 "arm_float_add_operand" "fG,H,0,0,fG,H,fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
mvf%D3s\\t%0, %2
|
||||
mnf%D3s\\t%0, #%N2
|
||||
|
@ -733,9 +733,9 @@
|
|||
(if_then_else:DF
|
||||
(match_operator 3 "arm_comparison_operator"
|
||||
[(match_operand 4 "cc_register" "") (const_int 0)])
|
||||
(match_operand:DF 1 "fpa_add_operand" "0,0,fG,H,fG,fG,H,H")
|
||||
(match_operand:DF 2 "fpa_add_operand" "fG,H,0,0,fG,H,fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT"
|
||||
(match_operand:DF 1 "arm_float_add_operand" "0,0,fG,H,fG,fG,H,H")
|
||||
(match_operand:DF 2 "arm_float_add_operand" "fG,H,0,0,fG,H,fG,H")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
|
||||
"@
|
||||
mvf%D3d\\t%0, %2
|
||||
mnf%D3d\\t%0, #%N2
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
}
|
||||
}"
|
||||
[(set_attr "length" "8,8,8,4,4,4,4,4")
|
||||
(set_attr "type" "*,load,store2,*,*,*,*,*")
|
||||
(set_attr "type" "*,load1,store2,*,*,*,*,*")
|
||||
(set_attr "pool_range" "*,1020,*,*,*,*,*,*")
|
||||
(set_attr "neg_pool_range" "*,1012,*,*,*,*,*,*")]
|
||||
)
|
||||
|
@ -110,7 +110,7 @@
|
|||
case 7: return \"wstrw\\t%1, %0\";
|
||||
default:return \"wstrw\\t%1, [sp, #-4]!\;wldrw\\t%0, [sp], #4\\t@move CG reg\";
|
||||
}"
|
||||
[(set_attr "type" "*,*,load,store1,*,*,load,store1,*")
|
||||
[(set_attr "type" "*,*,load1,store1,*,*,load1,store1,*")
|
||||
(set_attr "length" "*,*,*, *,*,*, 16, *,8")
|
||||
(set_attr "pool_range" "*,*,4096, *,*,*,1024, *,*")
|
||||
(set_attr "neg_pool_range" "*,*,4084, *,*,*, *, 1012,*")
|
||||
|
@ -148,7 +148,7 @@
|
|||
case 4: return \"tmcr%?\\t%0, %1\";
|
||||
default: return \"tmrc%?\\t%0, %1\";
|
||||
}"
|
||||
[(set_attr "type" "*,*,load,store1,*,*")
|
||||
[(set_attr "type" "*,*,load1,store1,*,*")
|
||||
(set_attr "pool_range" "*,*,4096, *,*,*")
|
||||
(set_attr "neg_pool_range" "*,*,4084, *,*,*")]
|
||||
)
|
||||
|
@ -169,7 +169,7 @@
|
|||
}"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "length" "4, 4, 4,4,4, 8")
|
||||
(set_attr "type" "*,store1,load,*,*,load")
|
||||
(set_attr "type" "*,store1,load1,*,*,load1")
|
||||
(set_attr "pool_range" "*, *, 256,*,*, 256")
|
||||
(set_attr "neg_pool_range" "*, *, 244,*,*, 244")])
|
||||
|
||||
|
@ -189,7 +189,7 @@
|
|||
}"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "length" "4, 4, 4,4,4, 8")
|
||||
(set_attr "type" "*,store1,load,*,*,load")
|
||||
(set_attr "type" "*,store1,load1,*,*,load1")
|
||||
(set_attr "pool_range" "*, *, 256,*,*, 256")
|
||||
(set_attr "neg_pool_range" "*, *, 244,*,*, 244")])
|
||||
|
||||
|
@ -209,7 +209,7 @@
|
|||
}"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "length" "4, 4, 4,4,4, 24")
|
||||
(set_attr "type" "*,store1,load,*,*,load")
|
||||
(set_attr "type" "*,store1,load1,*,*,load1")
|
||||
(set_attr "pool_range" "*, *, 256,*,*, 256")
|
||||
(set_attr "neg_pool_range" "*, *, 244,*,*, 244")])
|
||||
|
||||
|
@ -225,7 +225,7 @@
|
|||
"* return output_move_double (operands);"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "length" "8")
|
||||
(set_attr "type" "load")
|
||||
(set_attr "type" "load1")
|
||||
(set_attr "pool_range" "256")
|
||||
(set_attr "neg_pool_range" "244")])
|
||||
|
||||
|
@ -1149,7 +1149,7 @@
|
|||
"wsrawg%?\\t%0, %1, %2"
|
||||
[(set_attr "predicable" "yes")])
|
||||
|
||||
(define_insn "ashrdi3"
|
||||
(define_insn "ashrdi3_iwmmxt"
|
||||
[(set (match_operand:DI 0 "register_operand" "=y")
|
||||
(ashiftrt:DI (match_operand:DI 1 "register_operand" "y")
|
||||
(match_operand:SI 2 "register_operand" "z")))]
|
||||
|
@ -1173,7 +1173,7 @@
|
|||
"wsrlwg%?\\t%0, %1, %2"
|
||||
[(set_attr "predicable" "yes")])
|
||||
|
||||
(define_insn "lshrdi3"
|
||||
(define_insn "lshrdi3_iwmmxt"
|
||||
[(set (match_operand:DI 0 "register_operand" "=y")
|
||||
(lshiftrt:DI (match_operand:DI 1 "register_operand" "y")
|
||||
(match_operand:SI 2 "register_operand" "z")))]
|
||||
|
|
|
@ -243,6 +243,25 @@ pc .req r15
|
|||
/* ------------------------------------------------------------------------ */
|
||||
.macro ARM_DIV_BODY dividend, divisor, result, curbit
|
||||
|
||||
#if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
|
||||
|
||||
clz \curbit, \dividend
|
||||
clz \result, \divisor
|
||||
sub \curbit, \result, \curbit
|
||||
rsbs \curbit, \curbit, #31
|
||||
addne \curbit, \curbit, \curbit, lsl #1
|
||||
mov \result, #0
|
||||
addne pc, pc, \curbit, lsl #2
|
||||
nop
|
||||
.set shift, 32
|
||||
.rept 32
|
||||
.set shift, shift - 1
|
||||
cmp \dividend, \divisor, lsl #shift
|
||||
adc \result, \result, \result
|
||||
subcs \dividend, \dividend, \divisor, lsl #shift
|
||||
.endr
|
||||
|
||||
#else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
|
||||
#if __ARM_ARCH__ >= 5
|
||||
|
||||
clz \curbit, \divisor
|
||||
|
@ -253,7 +272,7 @@ pc .req r15
|
|||
mov \curbit, \curbit, lsl \result
|
||||
mov \result, #0
|
||||
|
||||
#else
|
||||
#else /* __ARM_ARCH__ < 5 */
|
||||
|
||||
@ Initially shift the divisor left 3 bits if possible,
|
||||
@ set curbit accordingly. This allows for curbit to be located
|
||||
|
@ -284,7 +303,7 @@ pc .req r15
|
|||
|
||||
mov \result, #0
|
||||
|
||||
#endif
|
||||
#endif /* __ARM_ARCH__ < 5 */
|
||||
|
||||
@ Division loop
|
||||
1: cmp \dividend, \divisor
|
||||
|
@ -304,6 +323,8 @@ pc .req r15
|
|||
movne \divisor, \divisor, lsr #4
|
||||
bne 1b
|
||||
|
||||
#endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
|
||||
|
||||
.endm
|
||||
/* ------------------------------------------------------------------------ */
|
||||
.macro ARM_DIV2_ORDER divisor, order
|
||||
|
@ -338,6 +359,22 @@ pc .req r15
|
|||
/* ------------------------------------------------------------------------ */
|
||||
.macro ARM_MOD_BODY dividend, divisor, order, spare
|
||||
|
||||
#if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
|
||||
|
||||
clz \order, \divisor
|
||||
clz \spare, \dividend
|
||||
sub \order, \order, \spare
|
||||
rsbs \order, \order, #31
|
||||
addne pc, pc, \order, lsl #3
|
||||
nop
|
||||
.set shift, 32
|
||||
.rept 32
|
||||
.set shift, shift - 1
|
||||
cmp \dividend, \divisor, lsl #shift
|
||||
subcs \dividend, \dividend, \divisor, lsl #shift
|
||||
.endr
|
||||
|
||||
#else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
|
||||
#if __ARM_ARCH__ >= 5
|
||||
|
||||
clz \order, \divisor
|
||||
|
@ -345,7 +382,7 @@ pc .req r15
|
|||
sub \order, \order, \spare
|
||||
mov \divisor, \divisor, lsl \order
|
||||
|
||||
#else
|
||||
#else /* __ARM_ARCH__ < 5 */
|
||||
|
||||
mov \order, #0
|
||||
|
||||
|
@ -367,7 +404,7 @@ pc .req r15
|
|||
addlo \order, \order, #1
|
||||
blo 1b
|
||||
|
||||
#endif
|
||||
#endif /* __ARM_ARCH__ < 5 */
|
||||
|
||||
@ Perform all needed substractions to keep only the reminder.
|
||||
@ Do comparisons in batch of 4 first.
|
||||
|
@ -404,6 +441,9 @@ pc .req r15
|
|||
4: cmp \dividend, \divisor
|
||||
subhs \dividend, \dividend, \divisor
|
||||
5:
|
||||
|
||||
#endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
|
||||
|
||||
.endm
|
||||
/* ------------------------------------------------------------------------ */
|
||||
.macro THUMB_DIV_MOD_BODY modulo
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
%{shared:-lc} \
|
||||
%{!shared:%{profile:-lc_p}%{!profile:-lc}}"
|
||||
|
||||
#define LIBGCC_SPEC "%{msoft-float:-lfloat} -lgcc"
|
||||
#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc"
|
||||
|
||||
/* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add
|
||||
the GNU/Linux magical crtbegin.o file (see crtstuff.c) which
|
||||
|
|
|
@ -57,14 +57,11 @@
|
|||
#define SUBTARGET_EXTRA_ASM_SPEC \
|
||||
"-matpcs %{fpic|fpie:-k} %{fPIC|fPIE:-k}"
|
||||
|
||||
/* Default floating point model is soft-VFP.
|
||||
FIXME: -mhard-float currently implies FPA. */
|
||||
/* Default to full VFP if -mhard-float is specified. */
|
||||
#undef SUBTARGET_ASM_FLOAT_SPEC
|
||||
#define SUBTARGET_ASM_FLOAT_SPEC \
|
||||
"%{mhard-float:-mfpu=fpa} \
|
||||
%{msoft-float:-mfpu=softvfp} \
|
||||
%{!mhard-float: \
|
||||
%{!msoft-float:-mfpu=softvfp}}"
|
||||
"%{mhard-float:{!mfpu=*:-mfpu=vfp}} \
|
||||
%{mfloat-abi=hard:{!mfpu=*:-mfpu=vfp}}"
|
||||
|
||||
#undef SUBTARGET_EXTRA_SPECS
|
||||
#define SUBTARGET_EXTRA_SPECS \
|
||||
|
@ -171,3 +168,7 @@ do \
|
|||
(void) sysarch (0, &s); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#undef FPUTYPE_DEFAULT
|
||||
#define FPUTYPE_DEFAULT FPUTYPE_VFP
|
||||
|
||||
|
|
|
@ -64,7 +64,8 @@
|
|||
%{mcpu=*:-mcpu=%*} \
|
||||
%{march=*:-march=%*} \
|
||||
%{mapcs-float:-mfloat} \
|
||||
%{msoft-float:-mfpu=softfpa} \
|
||||
%{msoft-float:-mfloat-abi=soft} %{mhard-float:mfloat-abi=hard} \
|
||||
%{mfloat-abi=*} %{mfpu=*} \
|
||||
%{mthumb-interwork:-mthumb-interwork} \
|
||||
%(subtarget_extra_asm_spec)"
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,744 @@
|
|||
;; ARM VFP coprocessor Machine Description
|
||||
;; Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
;; Written by CodeSourcery, LLC.
|
||||
;;
|
||||
;; 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. */
|
||||
|
||||
;; Additional register numbers
|
||||
(define_constants
|
||||
[(VFPCC_REGNUM 95)]
|
||||
)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Pipeline description
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define_automaton "vfp11")
|
||||
|
||||
;; There are 3 pipelines in the VFP11 unit.
|
||||
;;
|
||||
;; - A 8-stage FMAC pipeline (7 execute + writeback) with forward from
|
||||
;; fourth stage for simple operations.
|
||||
;;
|
||||
;; - A 5-stage DS pipeline (4 execute + writeback) for divide/sqrt insns.
|
||||
;; These insns also uses first execute stage of FMAC pipeline.
|
||||
;;
|
||||
;; - A 4-stage LS pipeline (execute + 2 memory + writeback) with forward from
|
||||
;; second memory stage for loads.
|
||||
|
||||
;; We do not model Write-After-Read hazards.
|
||||
;; We do not do write scheduling with the arm core, so it is only neccessary
|
||||
;; to model the first stage of each pieline
|
||||
;; ??? Need to model LS pipeline properly for load/store multiple?
|
||||
;; We do not model fmstat properly. This could be done by modeiling pipelines
|
||||
;; properly and defining an absence set between a dummy fmstat unit and all
|
||||
;; other vfp units.
|
||||
|
||||
(define_cpu_unit "fmac" "vfp11")
|
||||
|
||||
(define_cpu_unit "ds" "vfp11")
|
||||
|
||||
(define_cpu_unit "vfp_ls" "vfp11")
|
||||
|
||||
;; The VFP "type" attributes differ from those used in the FPA model.
|
||||
;; ffarith Fast floating point insns, eg. abs, neg, cpy, cmp.
|
||||
;; farith Most arithmetic insns.
|
||||
;; fmul Double preision multiply.
|
||||
;; fdivs Single precision sqrt or division.
|
||||
;; fdivd Double precision sqrt or division.
|
||||
;; f_load Floating point load from memory.
|
||||
;; f_store Floating point store to memory.
|
||||
;; f_2_r Transfer vfp to arm reg.
|
||||
;; r_2_f Transfer arm to vfp reg.
|
||||
|
||||
(define_insn_reservation "vfp_ffarith" 4
|
||||
(and (eq_attr "fpu" "vfp")
|
||||
(eq_attr "type" "ffarith"))
|
||||
"fmac")
|
||||
|
||||
(define_insn_reservation "vfp_farith" 8
|
||||
(and (eq_attr "fpu" "vfp")
|
||||
(eq_attr "type" "farith"))
|
||||
"fmac")
|
||||
|
||||
(define_insn_reservation "vfp_fmul" 9
|
||||
(and (eq_attr "fpu" "vfp")
|
||||
(eq_attr "type" "fmul"))
|
||||
"fmac*2")
|
||||
|
||||
(define_insn_reservation "vfp_fdivs" 19
|
||||
(and (eq_attr "fpu" "vfp")
|
||||
(eq_attr "type" "fdivs"))
|
||||
"ds*15")
|
||||
|
||||
(define_insn_reservation "vfp_fdivd" 33
|
||||
(and (eq_attr "fpu" "vfp")
|
||||
(eq_attr "type" "fdivd"))
|
||||
"fmac+ds*29")
|
||||
|
||||
;; Moves to/from arm regs also use the load/store pipeline.
|
||||
(define_insn_reservation "vfp_fload" 4
|
||||
(and (eq_attr "fpu" "vfp")
|
||||
(eq_attr "type" "f_load,r_2_f"))
|
||||
"vfp_ls")
|
||||
|
||||
(define_insn_reservation "vfp_fstore" 4
|
||||
(and (eq_attr "fpu" "vfp")
|
||||
(eq_attr "type" "f_load,f_2_r"))
|
||||
"vfp_ls")
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Insn pattersn
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; SImode moves
|
||||
;; ??? For now do not allow loading constants into vfp regs. This causes
|
||||
;; problems because small sonstants get converted into adds.
|
||||
(define_insn "*arm_movsi_vfp"
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,m,!w,r,!w,!w, U")
|
||||
(match_operand:SI 1 "general_operand" "rI,K,mi,r,r,!w,!w,Ui,!w"))]
|
||||
"TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
|
||||
&& ( s_register_operand (operands[0], SImode)
|
||||
|| s_register_operand (operands[1], SImode))"
|
||||
"@
|
||||
mov%?\\t%0, %1
|
||||
mvn%?\\t%0, #%B1
|
||||
ldr%?\\t%0, %1
|
||||
str%?\\t%1, %0
|
||||
fmsr%?\\t%0, %1\\t%@ int
|
||||
fmrs%?\\t%0, %1\\t%@ int
|
||||
fcpys%?\\t%0, %1\\t%@ int
|
||||
flds%?\\t%0, %1\\t%@ int
|
||||
fsts%?\\t%1, %0\\t%@ int"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "*,*,load1,store1,r_2_f,f_2_r,ffarith,f_load,f_store")
|
||||
(set_attr "pool_range" "*,*,4096,*,*,*,*,1020,*")
|
||||
(set_attr "neg_pool_range" "*,*,4084,*,*,*,*,1008,*")]
|
||||
)
|
||||
|
||||
|
||||
;; DImode moves
|
||||
|
||||
(define_insn "*arm_movdi_vfp"
|
||||
[(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,o<>,w,r,w,w ,U")
|
||||
(match_operand:DI 1 "di_operand" "rIK,mi,r ,r,w,w,Ui,w"))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"*
|
||||
switch (which_alternative)
|
||||
{
|
||||
case 0: case 1: case 2:
|
||||
return (output_move_double (operands));
|
||||
case 3:
|
||||
return \"fmdrr%?\\t%P0, %1\\t%@ int\";
|
||||
case 4:
|
||||
return \"fmrrd%?\\t%0, %1\\t%@ int\";
|
||||
case 5:
|
||||
return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
|
||||
case 6:
|
||||
return \"fldd%?\\t%P0, %1\\t%@ int\";
|
||||
case 7:
|
||||
return \"fstd%?\\t%P1, %0\\t%@ int\";
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
"
|
||||
[(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_load,f_store")
|
||||
(set_attr "length" "8,8,8,4,4,4,4,4")
|
||||
(set_attr "pool_range" "*,1020,*,*,*,*,1020,*")
|
||||
(set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
|
||||
)
|
||||
|
||||
|
||||
;; SFmode moves
|
||||
|
||||
(define_insn "*movsf_vfp"
|
||||
[(set (match_operand:SF 0 "nonimmediate_operand" "=w,r,w ,U,r ,m,w,r")
|
||||
(match_operand:SF 1 "general_operand" " r,w,UE,w,mE,r,w,r"))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
|
||||
&& ( s_register_operand (operands[0], SFmode)
|
||||
|| s_register_operand (operands[1], SFmode))"
|
||||
"@
|
||||
fmsr%?\\t%0, %1
|
||||
fmrs%?\\t%0, %1
|
||||
flds%?\\t%0, %1
|
||||
fsts%?\\t%1, %0
|
||||
ldr%?\\t%0, %1\\t%@ float
|
||||
str%?\\t%1, %0\\t%@ float
|
||||
fcpys%?\\t%0, %1
|
||||
mov%?\\t%0, %1\\t%@ float"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "r_2_f,f_2_r,ffarith,*,f_load,f_store,load1,store1")
|
||||
(set_attr "pool_range" "*,*,1020,*,4096,*,*,*")
|
||||
(set_attr "neg_pool_range" "*,*,1008,*,4080,*,*,*")]
|
||||
)
|
||||
|
||||
|
||||
;; DFmode moves
|
||||
|
||||
(define_insn "*movdf_vfp"
|
||||
[(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,r,r, m,w ,U,w,r")
|
||||
(match_operand:DF 1 "soft_df_operand" " r,w,mF,r,UF,w,w,r"))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"*
|
||||
{
|
||||
switch (which_alternative)
|
||||
{
|
||||
case 0:
|
||||
return \"fmdrr%?\\t%P0, %Q1, %R1\";
|
||||
case 1:
|
||||
return \"fmrrd%?\\t%Q0, %R0, %P1\";
|
||||
case 2: case 3: case 7:
|
||||
return output_move_double (operands);
|
||||
case 4:
|
||||
return \"fldd%?\\t%P0, %1\";
|
||||
case 5:
|
||||
return \"fstd%?\\t%P1, %0\";
|
||||
case 6:
|
||||
return \"fcpyd%?\\t%P0, %P1\";
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
"
|
||||
[(set_attr "type" "r_2_f,f_2_r,ffarith,*,load2,store2,f_load,f_store")
|
||||
(set_attr "length" "4,4,8,8,4,4,4,8")
|
||||
(set_attr "pool_range" "*,*,1020,*,1020,*,*,*")
|
||||
(set_attr "neg_pool_range" "*,*,1008,*,1008,*,*,*")]
|
||||
)
|
||||
|
||||
|
||||
;; Conditional move patterns
|
||||
|
||||
(define_insn "*movsfcc_vfp"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
|
||||
(if_then_else:SF
|
||||
(match_operator 3 "arm_comparison_operator"
|
||||
[(match_operand 4 "cc_register" "") (const_int 0)])
|
||||
(match_operand:SF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
|
||||
(match_operand:SF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"@
|
||||
fcpys%D3\\t%0, %2
|
||||
fcpys%d3\\t%0, %1
|
||||
fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
|
||||
fmsr%D3\\t%0, %2
|
||||
fmsr%d3\\t%0, %1
|
||||
fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
|
||||
fmrs%D3\\t%0, %2
|
||||
fmrs%d3\\t%0, %1
|
||||
fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
|
||||
[(set_attr "conds" "use")
|
||||
(set_attr "length" "4,4,8,4,4,8,4,4,8")
|
||||
(set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
|
||||
)
|
||||
|
||||
(define_insn "*movdfcc_vfp"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
|
||||
(if_then_else:DF
|
||||
(match_operator 3 "arm_comparison_operator"
|
||||
[(match_operand 4 "cc_register" "") (const_int 0)])
|
||||
(match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
|
||||
(match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"@
|
||||
fcpyd%D3\\t%P0, %P2
|
||||
fcpyd%d3\\t%P0, %P1
|
||||
fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
|
||||
fmdrr%D3\\t%P0, %Q2, %R2
|
||||
fmdrr%d3\\t%P0, %Q1, %R1
|
||||
fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
|
||||
fmrrd%D3\\t%Q0, %R0, %P2
|
||||
fmrrd%d3\\t%Q0, %R0, %P1
|
||||
fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
|
||||
[(set_attr "conds" "use")
|
||||
(set_attr "length" "4,4,8,4,4,8,4,4,8")
|
||||
(set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
|
||||
)
|
||||
|
||||
|
||||
;; Sign manipulation functions
|
||||
|
||||
(define_insn "*abssf2_vfp"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=w")
|
||||
(abs:SF (match_operand:SF 1 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fabss%?\\t%0, %1"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "ffarith")]
|
||||
)
|
||||
|
||||
(define_insn "*absdf2_vfp"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=w")
|
||||
(abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fabsd%?\\t%P0, %P1"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "ffarith")]
|
||||
)
|
||||
|
||||
(define_insn "*negsf2_vfp"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "+w")
|
||||
(neg:SF (match_operand:SF 1 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fnegs%?\\t%0, %1"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "ffarith")]
|
||||
)
|
||||
|
||||
(define_insn "*negdf2_vfp"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "+w")
|
||||
(neg:DF (match_operand:DF 1 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fnegd%?\\t%P0, %P1"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "ffarith")]
|
||||
)
|
||||
|
||||
|
||||
;; Arithmetic insns
|
||||
|
||||
(define_insn "*addsf3_vfp"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=w")
|
||||
(plus:SF (match_operand:SF 1 "s_register_operand" "w")
|
||||
(match_operand:SF 2 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fadds%?\\t%0, %1, %2"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
(define_insn "*adddf3_vfp"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=w")
|
||||
(plus:DF (match_operand:DF 1 "s_register_operand" "w")
|
||||
(match_operand:DF 2 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"faddd%?\\t%P0, %P1, %P2"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
|
||||
(define_insn "*subsf3_vfp"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=w")
|
||||
(minus:SF (match_operand:SF 1 "s_register_operand" "w")
|
||||
(match_operand:SF 2 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fsubs%?\\t%0, %1, %2"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
(define_insn "*subdf3_vfp"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=w")
|
||||
(minus:DF (match_operand:DF 1 "s_register_operand" "w")
|
||||
(match_operand:DF 2 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fsubd%?\\t%P0, %P1, %P2"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
|
||||
;; Division insns
|
||||
|
||||
(define_insn "*divsf3_vfp"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "+w")
|
||||
(div:SF (match_operand:SF 1 "s_register_operand" "w")
|
||||
(match_operand:SF 2 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fdivs%?\\t%0, %1, %2"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "fdivs")]
|
||||
)
|
||||
|
||||
(define_insn "*divdf3_vfp"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "+w")
|
||||
(div:DF (match_operand:DF 1 "s_register_operand" "w")
|
||||
(match_operand:DF 2 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fdivd%?\\t%P0, %P1, %P2"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "fdivd")]
|
||||
)
|
||||
|
||||
|
||||
;; Multiplication insns
|
||||
|
||||
(define_insn "*mulsf3_vfp"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "+w")
|
||||
(mult:SF (match_operand:SF 1 "s_register_operand" "w")
|
||||
(match_operand:SF 2 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fmuls%?\\t%0, %1, %2"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
(define_insn "*muldf3_vfp"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "+w")
|
||||
(mult:DF (match_operand:DF 1 "s_register_operand" "w")
|
||||
(match_operand:DF 2 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fmuld%?\\t%P0, %P1, %P2"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "fmul")]
|
||||
)
|
||||
|
||||
|
||||
(define_insn "*mulsf3negsf_vfp"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "+w")
|
||||
(mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "w"))
|
||||
(match_operand:SF 2 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fnmuls%?\\t%0, %1, %2"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
(define_insn "*muldf3negdf_vfp"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "+w")
|
||||
(mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
|
||||
(match_operand:DF 2 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fnmuld%?\\t%P0, %P1, %P2"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "fmul")]
|
||||
)
|
||||
|
||||
|
||||
;; Multiply-accumulate insns
|
||||
|
||||
;; 0 = 1 * 2 + 0
|
||||
(define_insn "*mulsf3addsf_vfp"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=w")
|
||||
(plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "w")
|
||||
(match_operand:SF 3 "s_register_operand" "w"))
|
||||
(match_operand:SF 1 "s_register_operand" "0")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fmacs%?\\t%0, %2, %3"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
(define_insn "*muldf3adddf_vfp"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=w")
|
||||
(plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
|
||||
(match_operand:DF 3 "s_register_operand" "w"))
|
||||
(match_operand:DF 1 "s_register_operand" "0")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fmacd%?\\t%P0, %P2, %P3"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "fmul")]
|
||||
)
|
||||
|
||||
;; 0 = 1 * 2 - 0
|
||||
(define_insn "*mulsf3subsf_vfp"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=w")
|
||||
(minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "w")
|
||||
(match_operand:SF 3 "s_register_operand" "w"))
|
||||
(match_operand:SF 1 "s_register_operand" "0")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fmscs%?\\t%0, %2, %3"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
(define_insn "*muldf3subdf_vfp"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=w")
|
||||
(minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
|
||||
(match_operand:DF 3 "s_register_operand" "w"))
|
||||
(match_operand:DF 1 "s_register_operand" "0")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fmscd%?\\t%P0, %P2, %P3"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "fmul")]
|
||||
)
|
||||
|
||||
;; 0 = -(1 * 2) + 0
|
||||
(define_insn "*mulsf3negsfaddsf_vfp"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=w")
|
||||
(minus:SF (match_operand:SF 1 "s_register_operand" "0")
|
||||
(mult:SF (match_operand:SF 2 "s_register_operand" "w")
|
||||
(match_operand:SF 3 "s_register_operand" "w"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fnmacs%?\\t%0, %2, %3"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
(define_insn "*fmuldf3negdfadddf_vfp"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=w")
|
||||
(minus:DF (match_operand:DF 1 "s_register_operand" "0")
|
||||
(mult:DF (match_operand:DF 2 "s_register_operand" "w")
|
||||
(match_operand:DF 3 "s_register_operand" "w"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fnmacd%?\\t%P0, %P2, %P3"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "fmul")]
|
||||
)
|
||||
|
||||
|
||||
;; 0 = -(1 * 2) - 0
|
||||
(define_insn "*mulsf3negsfsubsf_vfp"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=w")
|
||||
(minus:SF (mult:SF
|
||||
(neg:SF (match_operand:SF 2 "s_register_operand" "w"))
|
||||
(match_operand:SF 3 "s_register_operand" "w"))
|
||||
(match_operand:SF 1 "s_register_operand" "0")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fnmscs%?\\t%0, %2, %3"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
(define_insn "*muldf3negdfsubdf_vfp"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=w")
|
||||
(minus:DF (mult:DF
|
||||
(neg:DF (match_operand:DF 2 "s_register_operand" "w"))
|
||||
(match_operand:DF 3 "s_register_operand" "w"))
|
||||
(match_operand:DF 1 "s_register_operand" "0")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fnmscd%?\\t%P0, %P2, %P3"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "fmul")]
|
||||
)
|
||||
|
||||
|
||||
;; Conversion routines
|
||||
|
||||
(define_insn "*extendsfdf2_vfp"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=w")
|
||||
(float_extend:DF (match_operand:SF 1 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fcvtds%?\\t%P0, %1"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
(define_insn "*truncdfsf2_vfp"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=w")
|
||||
(float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fcvtsd%?\\t%0, %P1"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
(define_insn "*truncsisf2_vfp"
|
||||
[(set (match_operand:SI 0 "s_register_operand" "=w")
|
||||
(fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "w"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"ftosizs%?\\t%0, %1"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
(define_insn "*truncsidf2_vfp"
|
||||
[(set (match_operand:SI 0 "s_register_operand" "=w")
|
||||
(fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"ftosizd%?\\t%0, %P1"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
(define_insn "*floatsisf2_vfp"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=w")
|
||||
(float:SF (match_operand:SI 1 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fsitos%?\\t%0, %1"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
(define_insn "*floatsidf2_vfp"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=w")
|
||||
(float:DF (match_operand:SI 1 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fsitod%?\\t%P0, %1"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "farith")]
|
||||
)
|
||||
|
||||
|
||||
;; Sqrt insns.
|
||||
|
||||
(define_insn "*sqrtsf2_vfp"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=w")
|
||||
(sqrt:SF (match_operand:SF 1 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fsqrts%?\\t%0, %1"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "fdivs")]
|
||||
)
|
||||
|
||||
(define_insn "*sqrtdf2_vfp"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=w")
|
||||
(sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fsqrtd%?\\t%P0, %P1"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "fdivd")]
|
||||
)
|
||||
|
||||
|
||||
;; Patterns to split/copy vfp condition flags.
|
||||
|
||||
(define_insn "*movcc_vfp"
|
||||
[(set (reg CC_REGNUM)
|
||||
(reg VFPCC_REGNUM))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"fmstat%?"
|
||||
[(set_attr "conds" "set")
|
||||
(set_attr "type" "ffarith")]
|
||||
)
|
||||
|
||||
(define_insn_and_split "*cmpsf_split_vfp"
|
||||
[(set (reg:CCFP CC_REGNUM)
|
||||
(compare:CCFP (match_operand:SF 0 "s_register_operand" "w")
|
||||
(match_operand:SF 1 "vfp_compare_operand" "wG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"#"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
[(set (reg:CCFP VFPCC_REGNUM)
|
||||
(compare:CCFP (match_dup 0)
|
||||
(match_dup 1)))
|
||||
(set (reg:CCFP CC_REGNUM)
|
||||
(reg:CCFP VFPCC_REGNUM))]
|
||||
""
|
||||
)
|
||||
|
||||
(define_insn_and_split "*cmpsf_trap_split_vfp"
|
||||
[(set (reg:CCFPE CC_REGNUM)
|
||||
(compare:CCFPE (match_operand:SF 0 "s_register_operand" "w")
|
||||
(match_operand:SF 1 "vfp_compare_operand" "wG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"#"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
[(set (reg:CCFPE VFPCC_REGNUM)
|
||||
(compare:CCFPE (match_dup 0)
|
||||
(match_dup 1)))
|
||||
(set (reg:CCFPE CC_REGNUM)
|
||||
(reg:CCFPE VFPCC_REGNUM))]
|
||||
""
|
||||
)
|
||||
|
||||
(define_insn_and_split "*cmpdf_split_vfp"
|
||||
[(set (reg:CCFP CC_REGNUM)
|
||||
(compare:CCFP (match_operand:DF 0 "s_register_operand" "w")
|
||||
(match_operand:DF 1 "vfp_compare_operand" "wG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"#"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
[(set (reg:CCFP VFPCC_REGNUM)
|
||||
(compare:CCFP (match_dup 0)
|
||||
(match_dup 1)))
|
||||
(set (reg:CCFP CC_REGNUM)
|
||||
(reg:CCFPE VFPCC_REGNUM))]
|
||||
""
|
||||
)
|
||||
|
||||
(define_insn_and_split "*cmpdf_trap_split_vfp"
|
||||
[(set (reg:CCFPE CC_REGNUM)
|
||||
(compare:CCFPE (match_operand:DF 0 "s_register_operand" "w")
|
||||
(match_operand:DF 1 "vfp_compare_operand" "wG")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"#"
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
[(set (reg:CCFPE VFPCC_REGNUM)
|
||||
(compare:CCFPE (match_dup 0)
|
||||
(match_dup 1)))
|
||||
(set (reg:CCFPE CC_REGNUM)
|
||||
(reg:CCFPE VFPCC_REGNUM))]
|
||||
""
|
||||
)
|
||||
|
||||
|
||||
;; Comparison patterns
|
||||
|
||||
(define_insn "*cmpsf_vfp"
|
||||
[(set (reg:CCFP VFPCC_REGNUM)
|
||||
(compare:CCFP (match_operand:SF 0 "s_register_operand" "w,w")
|
||||
(match_operand:SF 1 "vfp_compare_operand" "w,G")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"@
|
||||
fcmps%?\\t%0, %1
|
||||
fcmpzs%?\\t%0"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "ffarith")]
|
||||
)
|
||||
|
||||
(define_insn "*cmpsf_trap_vfp"
|
||||
[(set (reg:CCFPE VFPCC_REGNUM)
|
||||
(compare:CCFPE (match_operand:SF 0 "s_register_operand" "w,w")
|
||||
(match_operand:SF 1 "vfp_compare_operand" "w,G")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"@
|
||||
fcmpes%?\\t%0, %1
|
||||
fcmpezs%?\\t%0"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "ffarith")]
|
||||
)
|
||||
|
||||
(define_insn "*cmpdf_vfp"
|
||||
[(set (reg:CCFP VFPCC_REGNUM)
|
||||
(compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w")
|
||||
(match_operand:DF 1 "vfp_compare_operand" "w,G")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"@
|
||||
fcmpd%?\\t%P0, %P1
|
||||
fcmpzd%?\\t%P0"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "ffarith")]
|
||||
)
|
||||
|
||||
(define_insn "*cmpdf_trap_vfp"
|
||||
[(set (reg:CCFPE VFPCC_REGNUM)
|
||||
(compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w")
|
||||
(match_operand:DF 1 "vfp_compare_operand" "w,G")))]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"@
|
||||
fcmped%?\\t%P0, %P1
|
||||
fcmpezd%?\\t%P0"
|
||||
[(set_attr "predicable" "yes")
|
||||
(set_attr "type" "ffarith")]
|
||||
)
|
||||
|
||||
|
||||
;; Store multiple insn used in function prologue.
|
||||
|
||||
(define_insn "*push_multi_vfp"
|
||||
[(match_parallel 2 "multi_register_push"
|
||||
[(set (match_operand:BLK 0 "memory_operand" "=m")
|
||||
(unspec:BLK [(match_operand:DF 1 "s_register_operand" "w")]
|
||||
UNSPEC_PUSH_MULT))])]
|
||||
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
|
||||
"* return vfp_output_fstmx (operands);"
|
||||
[(set_attr "type" "f_store")]
|
||||
)
|
||||
|
||||
|
||||
;; Unimplemented insns:
|
||||
;; fldm*
|
||||
;; fstm*
|
||||
;; fmdhr et al (VFPv1)
|
||||
;; Support for xD (single precisio only) variants.
|
||||
;; fmrrs, fmsrr
|
||||
;; fuito*
|
||||
;; ftoui*
|
|
@ -926,12 +926,13 @@ and SPARC@.
|
|||
@itemx --with-arch=@var{cpu}
|
||||
@itemx --with-tune=@var{cpu}
|
||||
@itemx --with-abi=@var{abi}
|
||||
@itemx --with-fpu=@var{type}
|
||||
@itemx --with-float=@var{type}
|
||||
These configure options provide default values for the @option{-mschedule=},
|
||||
@option{-march=}, @option{-mtune=}, and @option{-mabi=} options and for
|
||||
@option{-mhard-float} or @option{-msoft-float}. As with @option{--with-cpu},
|
||||
which switches will be accepted and acceptable values of the arguments depend
|
||||
on the target.
|
||||
@option{-march=}, @option{-mtune=}, @option{-mabi=}, and @option{-mfpu=}
|
||||
options and for @option{-mhard-float} or @option{-msoft-float}. As with
|
||||
@option{--with-cpu}, which switches will be accepted and acceptable values
|
||||
of the arguments depend on the target.
|
||||
|
||||
@item --enable-altivec
|
||||
Specify that the target supports AltiVec vector enhancements. This
|
||||
|
|
|
@ -375,9 +375,9 @@ in the following sections.
|
|||
-msched-prolog -mno-sched-prolog @gol
|
||||
-mlittle-endian -mbig-endian -mwords-little-endian @gol
|
||||
-malignment-traps -mno-alignment-traps @gol
|
||||
-msoft-float -mhard-float -mfpe @gol
|
||||
-mfloat-abi=@var{name} soft-float -mhard-float -mfpe @gol
|
||||
-mthumb-interwork -mno-thumb-interwork @gol
|
||||
-mcpu=@var{name} -march=@var{name} -mfpe=@var{name} @gol
|
||||
-mcpu=@var{name} -march=@var{name} -mfpu=@var{name} @gol
|
||||
-mstructure-size-boundary=@var{n} @gol
|
||||
-mabort-on-noreturn @gol
|
||||
-mlong-calls -mno-long-calls @gol
|
||||
|
@ -6497,6 +6497,16 @@ this option. In particular, you need to compile @file{libgcc.a}, the
|
|||
library that comes with GCC, with @option{-msoft-float} in order for
|
||||
this to work.
|
||||
|
||||
@item -mfloat-abi=@var{name}
|
||||
@opindex mfloat-abi
|
||||
Specifies which ABI to use for floating point values. Permissible values
|
||||
are: @samp{soft}, @samp{softfp} and @samp{hard}.
|
||||
|
||||
@samp{soft} and @samp{hard} are equivalent to @option{-msoft-float}
|
||||
and @option{-mhard-float} respectively. @samp{softfp} allows the generation
|
||||
of floating point instructions, but still uses the soft-float calling
|
||||
conventions.
|
||||
|
||||
@item -mlittle-endian
|
||||
@opindex mlittle-endian
|
||||
Generate code for a processor running in little-endian mode. This is
|
||||
|
@ -6595,16 +6605,23 @@ name to determine what kind of instructions it can emit when generating
|
|||
assembly code. This option can be used in conjunction with or instead
|
||||
of the @option{-mcpu=} option. Permissible names are: @samp{armv2},
|
||||
@samp{armv2a}, @samp{armv3}, @samp{armv3m}, @samp{armv4}, @samp{armv4t},
|
||||
@samp{armv5}, @samp{armv5t}, @samp{armv5te}, @samp{armv6j},
|
||||
@samp{armv5}, @samp{armv5t}, @samp{armv5te}, @samp{armv6}, @samp{armv6j},
|
||||
@samp{iwmmxt}, @samp{ep9312}.
|
||||
|
||||
@item -mfpe=@var{number}
|
||||
@item -mfpu=@var{name}
|
||||
@itemx -mfpe=@var{number}
|
||||
@itemx -mfp=@var{number}
|
||||
@opindex mfpu
|
||||
@opindex mfpe
|
||||
@opindex mfp
|
||||
This specifies the version of the floating point emulation available on
|
||||
the target. Permissible values are 2 and 3. @option{-mfp=} is a synonym
|
||||
for @option{-mfpe=}, for compatibility with older versions of GCC@.
|
||||
This specifies what floating point hardware (or hardware emulation) is
|
||||
available on the target. Permissible names are: @samp{fpa}, @samp{fpe2},
|
||||
@samp{fpe3}, @samp{maverick}, @samp{vfp}. @option{-mfp} and @option{-mfpe}
|
||||
are synonyms for @option{-mpfu}=@samp{fpe}@var{number}, for compatibility
|
||||
with older versions of GCC@.
|
||||
|
||||
If @option{-msoft-float} is specified this specifies the format of
|
||||
floating point values.
|
||||
|
||||
@item -mstructure-size-boundary=@var{n}
|
||||
@opindex mstructure-size-boundary
|
||||
|
|
|
@ -1340,6 +1340,9 @@ available on some particular machines.
|
|||
@item f
|
||||
Floating-point register
|
||||
|
||||
@item w
|
||||
VFP floating-point register
|
||||
|
||||
@item F
|
||||
One of the floating-point constants 0.0, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0
|
||||
or 10.0
|
||||
|
@ -1376,6 +1379,9 @@ An item in the constant pool
|
|||
A symbol in the text segment of the current file
|
||||
@end table
|
||||
|
||||
@item U
|
||||
A memory reference suitable for VFP load/store insns (reg+constant offset)
|
||||
|
||||
@item AVR family---@file{avr.h}
|
||||
@table @code
|
||||
@item l
|
||||
|
|
|
@ -186,7 +186,7 @@ do { \
|
|||
UDItype __umulsidi3 (USItype, USItype);
|
||||
#endif
|
||||
|
||||
#if defined (__arm__) && W_TYPE_SIZE == 32
|
||||
#if defined (__arm__) && !defined (__thumb__) && W_TYPE_SIZE == 32
|
||||
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
|
||||
__asm__ ("adds %1, %4, %5\n\tadc %0, %2, %3" \
|
||||
: "=r" ((USItype) (sh)), \
|
||||
|
|
Loading…
Reference in New Issue