svn merge -r265930:265934 svn+ssh://gcc.gnu.org/svn/gcc/trunk
From-SVN: r265937
This commit is contained in:
parent
306e92f648
commit
f2ee7edfe3
398
gcc/ChangeLog
398
gcc/ChangeLog
|
@ -1,3 +1,401 @@
|
|||
2018-11-08 Paul Koning <ni1d@arrl.net>
|
||||
|
||||
* config/pdp11/constraints.md: Add "Z" series constraints for use
|
||||
with pre-dec and post-inc addressing.
|
||||
* config/pdp11/pdp11-protos.m (expand_block_move): Delete.
|
||||
(pdp11_expand_operands): Add int argument (word count).
|
||||
(pdp11_sp_frame_offset): Delete.
|
||||
(pdp11_cmp_length): New function.
|
||||
(pushpop_regeq): New function.
|
||||
* config/pdp11/pdp11.c (TARGET_STACK_PROTECT_RUNTIME_ENABLED_P):
|
||||
Add hook.
|
||||
(pdp11_expand_prologue, pdp11_expand_epilogue): Rewrite for new
|
||||
frame layout.
|
||||
(pdp11_initial_elimination_offset): Ditto.
|
||||
(pdp11_expand_operands): Add word count argument. Bugfixes.
|
||||
(output_move_multiple): Change how pointer adjustment is done.
|
||||
(pdp11_gen_int_label): Correct format.
|
||||
(output_ascii): Ditto.
|
||||
(pdp11_asm_output_var): Add code for DEC assembler case.
|
||||
(pdp11_asm_print_operand): Bugfix for CONST_DOUBLE holding integer
|
||||
value.
|
||||
(legitimate_const_double_p): Ditto.
|
||||
(pdp11_register_move_cost): Adjust for new register classes.
|
||||
(pdp11_regno_reg_class): Ditto.
|
||||
(expand_block_move): Delete.
|
||||
(pushpop_regeq): New function.
|
||||
(pdp11_legitimate_address_p): Bugfix in check for constant
|
||||
offset.
|
||||
(pdp11_sp_frame_offset): Delete.
|
||||
(pdp11_reg_save_size): New helper function for new frame layout.
|
||||
(output_addr_const_pdp11): Remove CONST_DOUBLE case.
|
||||
(pdp11_expand_shift): Bugfix in check for constant shift count.
|
||||
(pdp11_shift_length): Ditto.
|
||||
(pdp11_assemble_shift): Copy input to pdp11_expand_operands.
|
||||
(pdp11_cmp_length): New function.
|
||||
* config/pdp11/pdp11.h (TARGET_CPU_CPP_BUILTINS): Add macros for
|
||||
some compile options.
|
||||
(FIXED_REGISTERS): Remove HARD_FRAME_POINTER_REGNUM.
|
||||
(CALL_USED_REGISTERS): Ditto.
|
||||
(ELIMINABLE_REGS): Ditto.
|
||||
(REGISTER_NAMES): Ditto.
|
||||
(reg_class): Add classes NOTR0_REG through NOTSP_REG for use by Z
|
||||
constraints.
|
||||
(REG_CLASS_NAMES): Ditto.
|
||||
(REG_CLASS_CONTENTS): Ditto. Also remove
|
||||
HARD_FRAME_POINTER_REGNUM.
|
||||
(CPU_REG_CLASS): New macro.
|
||||
(CLASS_MAX_NREGS): Adjust for new register classes.
|
||||
(FUNCTION_PROFILER): Make no-op.
|
||||
(may_call_alloca): Remove unused declaration.
|
||||
(ASM_OUTPUT_ALIGN): Add workaround for PR87795.
|
||||
(ASM_OUTPUT_SKIP): Fix format.
|
||||
* config/pdp11/pdp11.md (unspecv): Add UNSPECV_MOVMEM.
|
||||
(HARD_FRAME_POINTER_REGNUM): Remove.
|
||||
(return): Delete.
|
||||
(*rts): Rename. Remove epilogue related checks.
|
||||
(cmpsi, cmpdi): New insn.
|
||||
(cbranch<mode>4): Change to apply to SI and DI modes as well.
|
||||
(mov<mode>): Change constraints to enforce that push/pop
|
||||
destination cannot use the same register as source.
|
||||
(*mov<mode><cc_cc>): Ditto.
|
||||
(movmemhi, movmemhi1, movmemhi_nocc): Change to expand block move
|
||||
at assembly output rather than as RTL expander.
|
||||
(zero_extendqihi2): Bugfix in check for same registers.
|
||||
(adddi3_nocc): Bugfix in check for constant operand.
|
||||
(addsi3_nocc): Ditto.
|
||||
(subdi3_nocc): Ditto.
|
||||
(subsi3_nocc): Ditto.
|
||||
(negdi2_nocc): Copy input to pdp11_expand_operands.
|
||||
(negsi2_nocc): Ditto.
|
||||
(bswap2_nocc): Ditto.
|
||||
* config/pdp11/pdp11.opt (mlra): Fix documentation.
|
||||
* config/pdp11/t-pdp11: Use -Os.
|
||||
|
||||
2018-11-08 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* config/arm/parsecpu.awk (/alias/): New parsing rule.
|
||||
(/begin cpu/): Check that the cpu name hasn't been previously defined.
|
||||
(gen_comm_data): Print out CPU alias tables.
|
||||
(check_cpu): Match aliases when checking the CPU name.
|
||||
* config/arm/arm-protos.h (cpu_alias): New structure.
|
||||
(cpu_option): Add entry for aliases.
|
||||
* config/arm/arm-cpus.in (strongarm): Add aliases for strongarm110
|
||||
strongarm1100 and strongarm1110.
|
||||
(strongarm110, strongarm1100, strongarm1110): Delete CPU entries.
|
||||
(config/arm/arm-generic.md): Remove redundant references to
|
||||
strongarm110, strongarm1100 and strongarm1110.
|
||||
* common/config/arm/arm-common.c (arm_print_hint_for_cpu_option):
|
||||
Scan aliases for additional hints.
|
||||
(arm_parse_cpu_option_name): Also match a cpu name against the list
|
||||
of aliases.
|
||||
* config/arm/arm-tables.opt: Regenerated.
|
||||
* config/arm/arm-tune.md: Regenerated.
|
||||
|
||||
2018-11-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* builtin-types.def (BT_FN_VOID_BOOL, BT_FN_VOID_SIZE_SIZE_PTR,
|
||||
BT_FN_UINT_UINT_PTR_PTR, BT_FN_UINT_OMPFN_PTR_UINT_UINT,
|
||||
BT_FN_BOOL_UINT_LONGPTR_LONG_LONG_LONGPTR_LONGPTR_PTR_PTR,
|
||||
BT_FN_BOOL_UINT_ULLPTR_LONG_ULL_ULLPTR_ULLPTR_PTR_PTR,
|
||||
BT_FN_BOOL_LONG_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR_PTR_PTR,
|
||||
BT_FN_BOOL_BOOL_ULL_ULL_ULL_LONG_ULL_ULLPTR_ULLPTR_PTR_PTR): New.
|
||||
* gengtype.c (open_base_files): Add omp-general.h.
|
||||
* gimple.c (gimple_build_omp_critical):
|
||||
(gimple_build_omp_taskgroup): Add CLAUSES argument. Call
|
||||
gimple_omp_taskgroup_set_clauses.
|
||||
(gimple_build_omp_atomic_load): Add mo argument, call
|
||||
gimple_omp_atomic_set_memory_order.
|
||||
(gimple_build_omp_atomic_store): Likewise.
|
||||
(gimple_copy): Adjust handling of GIMPLE_OMP_TASKGROUP.
|
||||
* gimple.def (GIMPLE_OMP_TASKGROUP): Use GSS_OMP_SINGLE_LAYOUT
|
||||
instead of GSS_OMP.
|
||||
(GIMPLE_OMP_TEAMS): Use GSS_OMP_PARALLEL_LAYOUT instead
|
||||
of GSS_OMP_SINGLE_LAYOUT, adjust comments.
|
||||
* gimple.h (enum gf_mask): Add GF_OMP_TEAMS_HOST, GF_OMP_TASK_TASKWAIT
|
||||
and GF_OMP_ATOMIC_MEMORY_ORDER. Remove GF_OMP_ATOMIC_SEQ_CST, use
|
||||
different value for GF_OMP_ATOMIC_NEED_VALUE.
|
||||
(struct gimple_statement_omp_taskreg): Add GIMPLE_OMP_TEAMS to
|
||||
comments.
|
||||
(struct gimple_statement_omp_single_layout): And remove here.
|
||||
(struct gomp_teams): Inherit from gimple_statement_omp_taskreg rather
|
||||
than gimple_statement_omp_single_layout.
|
||||
(is_a_helper <gimple_statement_omp_taskreg *>::test): Allow
|
||||
GIMPLE_OMP_TEAMS.
|
||||
(is_a_helper <const gimple_statement_omp_taskreg *>::test): Likewise.
|
||||
(gimple_omp_subcode): Formatting fix.
|
||||
(gimple_omp_teams_child_fn, gimple_omp_teams_child_fn_ptr,
|
||||
gimple_omp_teams_set_child_fn, gimple_omp_teams_data_arg,
|
||||
gimple_omp_teams_data_arg_ptr, gimple_omp_teams_set_data_arg,
|
||||
gimple_omp_teams_host, gimple_omp_teams_set_host,
|
||||
gimple_omp_task_taskwait_p, gimple_omp_task_set_taskwait_p,
|
||||
gimple_omp_taskgroup_clauses, gimple_omp_taskgroup_clauses_ptr,
|
||||
gimple_omp_taskgroup_set_clauses): New inline functions.
|
||||
(gimple_build_omp_atomic_load): Add enum omp_memory_order argument.
|
||||
(gimple_build_omp_atomic_store): Likewise.
|
||||
(gimple_omp_atomic_seq_cst_p): Remove.
|
||||
(gimple_omp_atomic_memory_order): New function.
|
||||
(gimple_omp_atomic_set_seq_cst): Remove.
|
||||
(gimple_omp_atomic_set_memory_order): New function.
|
||||
(gimple_build_omp_taskgroup): Add clauses argument.
|
||||
* gimple-pretty-print.c (dump_gimple_omp_taskgroup): New function.
|
||||
(dump_gimple_omp_task): Print taskwait with depend clauses.
|
||||
(dump_gimple_omp_atomic_load, dump_gimple_omp_atomic_store): Use
|
||||
dump_omp_atomic_memory_order.
|
||||
(pp_gimple_stmt_1): Handle GIMPLE_OMP_TASKGROUP.
|
||||
* gimplify.c (enum gimplify_omp_var_data): Add GOVD_MAP_ALLOC_ONLY,
|
||||
GOVD_MAP_FROM_ONLY and GOVD_NONTEMPORAL.
|
||||
(enum omp_region_type): Reserve bits 1 and 2 for auxiliary flags,
|
||||
renumber values of most of ORT_* enumerators, add ORT_HOST_TEAMS,
|
||||
ORT_COMBINED_HOST_TEAMS, ORT_TASKGROUP, ORT_TASKLOOP and
|
||||
ORT_UNTIED_TASKLOOP enumerators.
|
||||
(enum gimplify_defaultmap_kind): New.
|
||||
(struct gimplify_omp_ctx): Remove target_map_scalars_firstprivate and
|
||||
target_map_pointers_as_0len_arrays members, add defaultmap.
|
||||
(new_omp_context): Initialize defaultmap member.
|
||||
(gimple_add_tmp_var): Handle ORT_TASKGROUP like ORT_WORKSHARE.
|
||||
(maybe_fold_stmt): Don't fold even in host teams regions.
|
||||
(omp_firstprivatize_variable): Handle ORT_TASKGROUP like
|
||||
ORT_WORKSHARE. Test ctx->defaultmap[GDMK_SCALAR] instead of
|
||||
ctx->omp_firstprivatize_variable.
|
||||
(omp_add_variable): Don't add private/firstprivate for VLAs in
|
||||
ORT_TASKGROUP.
|
||||
(omp_default_clause): Print "taskloop" rather than "task" if
|
||||
ORT_*TASKLOOP.
|
||||
(omp_notice_variable): Handle ORT_TASKGROUP like ORT_WORKSHARE.
|
||||
Handle new defaultmap clause kinds.
|
||||
(omp_is_private): Handle ORT_TASKGROUP like ORT_WORKSHARE. Allow simd
|
||||
iterator to be lastprivate or private. Fix up diagnostics if linear
|
||||
is used on collapse>1 simd iterator.
|
||||
(omp_check_private): Handle ORT_TASKGROUP like ORT_WORKSHARE.
|
||||
(gimplify_omp_depend): New function.
|
||||
(gimplify_scan_omp_clauses): Add shared clause on parallel for
|
||||
combined parallel master taskloop{, simd} if taskloop has
|
||||
firstprivate, lastprivate or reduction clause. Handle
|
||||
OMP_CLAUSE_REDUCTION_TASK diagnostics. Adjust tests for
|
||||
ORT_COMBINED_TEAMS. Gimplify depend clauses with iterators. Handle
|
||||
cancel and simd OMP_CLAUSE_IF_MODIFIERs. Handle
|
||||
OMP_CLAUSE_NONTEMPORAL. Handle new defaultmap clause kinds. Handle
|
||||
OMP_CLAUSE_{TASK,IN}_REDUCTION. Diagnose invalid conditional
|
||||
lastprivate.
|
||||
(gimplify_adjust_omp_clauses_1): Ignore GOVD_NONTEMPORAL. Handle
|
||||
GOVD_MAP_ALLOC_ONLY and GOVD_MAP_FROM_ONLY.
|
||||
(gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_NONTEMPORAL. Handle
|
||||
OMP_CLAUSE_{TASK,IN}_REDUCTION.
|
||||
(gimplify_omp_task): Handle taskwait with depend clauses.
|
||||
(gimplify_omp_for): Add shared clause on parallel for combined
|
||||
parallel master taskloop{, simd} if taskloop has firstprivate,
|
||||
lastprivate or reduction clause. Use ORT_TASKLOOP or
|
||||
ORT_UNTIED_TASKLOOP instead of ORT_TASK or ORT_UNTIED_TASK. Adjust
|
||||
tests for ORT_COMBINED_TEAMS. Handle C++ range for loops with
|
||||
NULL TREE_PURPOSE in OMP_FOR_ORIG_DECLS. Firstprivatize
|
||||
__for_end and __for_range temporaries on OMP_PARALLEL for
|
||||
distribute parallel for{, simd}. Move OMP_CLAUSE_REDUCTION
|
||||
and OMP_CLAUSE_IN_REDUCTION from taskloop to the task construct
|
||||
sandwiched in between two taskloops.
|
||||
(computable_teams_clause): Test ctx->defaultmap[GDMK_SCALAR]
|
||||
instead of ctx->omp_firstprivatize_variable.
|
||||
(gimplify_omp_workshare): Set ort to ORT_HOST_TEAMS or
|
||||
ORT_COMBINED_HOST_TEAMS if not inside of target construct. If
|
||||
host teams, use gimplify_and_return_first etc. for body like
|
||||
for target or target data constructs, and at the end call
|
||||
gimple_omp_teams_set_host on the GIMPLE_OMP_TEAMS object.
|
||||
(gimplify_omp_atomic): Use OMP_ATOMIC_MEMORY_ORDER instead
|
||||
of OMP_ATOMIC_SEQ_CST, pass it as new argument to
|
||||
gimple_build_omp_atomic_load and gimple_build_omp_atomic_store, remove
|
||||
gimple_omp_atomic_set_seq_cst calls.
|
||||
(gimplify_expr) <case OMP_TASKGROUP>: Move handling into a separate
|
||||
case, handle taskgroup clauses.
|
||||
* lto-streamer-out.c (hash_tree): Handle
|
||||
OMP_CLAUSE_{TASK,IN}_REDUCTION.
|
||||
* Makefile.in (GTFILES): Add omp-general.h.
|
||||
* omp-builtins.def (BUILT_IN_GOMP_TASKWAIT_DEPEND,
|
||||
BUILT_IN_GOMP_LOOP_NONMONOTONIC_RUNTIME_START,
|
||||
BUILT_IN_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_START,
|
||||
BUILT_IN_GOMP_LOOP_START, BUILT_IN_GOMP_LOOP_ORDERED_START,
|
||||
BUILT_IN_GOMP_LOOP_DOACROSS_START,
|
||||
BUILT_IN_GOMP_LOOP_NONMONOTONIC_RUNTIME_NEXT,
|
||||
BUILT_IN_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_NEXT,
|
||||
BUILT_IN_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_START,
|
||||
BUILT_IN_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_START,
|
||||
BUILT_IN_GOMP_LOOP_ULL_START, BUILT_IN_GOMP_LOOP_ULL_ORDERED_START,
|
||||
BUILT_IN_GOMP_LOOP_ULL_DOACROSS_START,
|
||||
BUILT_IN_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_NEXT,
|
||||
BUILT_IN_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_NEXT,
|
||||
BUILT_IN_GOMP_PARALLEL_LOOP_NONMONOTONIC_RUNTIME,
|
||||
BUILT_IN_GOMP_PARALLEL_LOOP_MAYBE_NONMONOTONIC_RUNTIME,
|
||||
BUILT_IN_GOMP_PARALLEL_REDUCTIONS, BUILT_IN_GOMP_SECTIONS2_START,
|
||||
BUILT_IN_GOMP_TEAMS_REG, BUILT_IN_GOMP_TASKGROUP_REDUCTION_REGISTER,
|
||||
BUILT_IN_GOMP_TASKGROUP_REDUCTION_UNREGISTER,
|
||||
BUILT_IN_GOMP_TASK_REDUCTION_REMAP,
|
||||
BUILT_IN_GOMP_WORKSHARE_TASK_REDUCTION_UNREGISTER): New builtins.
|
||||
* omp-expand.c (workshare_safe_to_combine_p): Return false for
|
||||
non-worksharing loops.
|
||||
(omp_adjust_chunk_size): Don't adjust anything if chunk_size is zero.
|
||||
(determine_parallel_type): Don't combine parallel with worksharing
|
||||
which has _reductemp_ clause.
|
||||
(expand_parallel_call): Emit the GOMP_*nonmonotonic_runtime* or
|
||||
GOMP_*maybe_nonmonotonic_runtime* builtins instead of GOMP_*runtime*
|
||||
if there is nonmonotonic modifier or if there is no modifier and no
|
||||
ordered clause. For dynamic and guided schedule without monotonic
|
||||
and nonmonotonic modifier, default to nonmonotonic.
|
||||
(expand_omp_for): Likewise. Adjust expand_omp_for_generic caller, use
|
||||
GOMP_loop{,_ull}{,_ordered,_doacross}_start builtins if there are
|
||||
task reductions.
|
||||
(expand_task_call): Add GOMP_TASK_FLAG_REDUCTION flag to flags if
|
||||
there are any reduction clauses.
|
||||
(expand_taskwait_call): New function.
|
||||
(expand_teams_call): New function.
|
||||
(expand_omp_taskreg): Allow GIMPLE_OMP_TEAMS and call
|
||||
expand_teams_call for it. Formatting fix. Handle taskwait with
|
||||
depend clauses.
|
||||
(expand_omp_for_generic): Add SCHED_ARG argument. Handle expansion
|
||||
of worksharing loops with task reductions.
|
||||
(expand_omp_for_static_nochunk, expand_omp_for_static_chunk): Handle
|
||||
expansion of worksharing loops with task reductions.
|
||||
(expand_omp_sections): Handle expansion of sections with task
|
||||
reductions.
|
||||
(expand_omp_synch): For host teams call expand_omp_taskreg.
|
||||
(omp_memory_order_to_memmodel): New function.
|
||||
(expand_omp_atomic_load, expand_omp_atomic_store,
|
||||
expand_omp_atomic_fetch_op): Use it and gimple_omp_atomic_memory_order
|
||||
instead of gimple_omp_atomic_seq_cst_p.
|
||||
(build_omp_regions_1, omp_make_gimple_edges): Treat taskwait with
|
||||
depend clauses as a standalone directive.
|
||||
* omp-general.c (enum omp_requires): New variable.
|
||||
(omp_extract_for_data): Initialize have_reductemp member. Allow
|
||||
NE_EXPR even in OpenMP loops, transform them into LT_EXPR or
|
||||
GT_EXPR loops depending on incr sign. Formatting fixes.
|
||||
* omp-general.h (struct omp_for_data): Add have_reductemp member.
|
||||
(enum omp_requires): New enum.
|
||||
(omp_requires_mask): Declare.
|
||||
* omp-grid.c (grid_eliminate_combined_simd_part): Formatting fix.
|
||||
Fix comment typos.
|
||||
* omp-low.c (struct omp_context): Add task_reductions and
|
||||
task_reduction_map fields.
|
||||
(is_host_teams_ctx): New function.
|
||||
(is_taskreg_ctx): Return true also if is_host_teams_ctx.
|
||||
(use_pointer_for_field): Use is_global_var instead of
|
||||
TREE_STATIC || DECL_EXTERNAL, and apply only if not privatized
|
||||
in outer contexts.
|
||||
(build_outer_var_ref): Ignore taskgroup outer contexts.
|
||||
(delete_omp_context): Release task_reductions and task_reduction_map.
|
||||
(scan_sharing_clauses): Don't add any fields for reduction clause on
|
||||
taskloop. Handle OMP_CLAUSE__REDUCTEMP_. Handle
|
||||
OMP_CLAUSE_{IN,TASK}_REDUCTION and OMP_CLAUSE_REDUCTION with task
|
||||
modifier. Don't ignore shared clauses in is_host_teams_ctx contexts.
|
||||
Handle OMP_CLAUSE_NONTEMPORAL.
|
||||
(add_taskreg_looptemp_clauses): Add OMP_CLAUSE__REDUCTEMP_ clause if
|
||||
needed.
|
||||
(scan_omp_parallel): Add _reductemp_ clause if there are any reduction
|
||||
clauses with task modifier.
|
||||
(scan_omp_task): Handle taskwait with depend clauses.
|
||||
(finish_taskreg_scan): Move field corresponding to _reductemp_ clause
|
||||
first. Move also OMP_CLAUSE__REDUCTEMP_ clause in front if present.
|
||||
Handle GIMPLE_OMP_TEAMS like GIMPLE_OMP_PARALLEL.
|
||||
(scan_omp_for): Fix comment formatting.
|
||||
(scan_omp_teams): Handle host teams constructs.
|
||||
(check_omp_nesting_restrictions): Allow teams with no outer
|
||||
OpenMP context. Adjust diagnostics for teams strictly nested into
|
||||
some explicit OpenMP construct other than target. Allow OpenMP atomics
|
||||
inside of simd regions.
|
||||
(scan_omp_1_stmt): Call scan_sharing_clauses for taskgroups.
|
||||
(scan_omp_1_stmt) <case GIMPLE_OMP_TEAMS>: Temporarily bump
|
||||
taskreg_nesting_level while scanning host teams construct.
|
||||
(task_reduction_read): New function.
|
||||
(lower_rec_input_clauses): Handle OMP_CLAUSE_REDUCTION on taskloop
|
||||
construct. Handle OMP_CLAUSE_IN_REDUCTION and OMP_CLAUSE__REDUCTEMP_
|
||||
clauses. Handle OMP_CLAUSE_REDUCTION with task modifier. Remove
|
||||
second argument create_tmp_var if it is NULL. Don't ignore shared
|
||||
clauses in is_host_teams_ctx contexts. Handle
|
||||
OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE on OMP_CLAUSE_FIRSTPRIVATE
|
||||
clauses.
|
||||
(lower_reduction_clauses): Ignore reduction clauses with task
|
||||
modifier. Remove second argument create_tmp_var if it is NULL.
|
||||
Initialize OMP_ATOMIC_MEMORY_ORDER to relaxed.
|
||||
(lower_send_clauses): Ignore reduction clauses with task modifier.
|
||||
Handle OMP_CLAUSE__REDUCTEMP_. Don't send anything for
|
||||
OMP_CLAUSE_REDUCTION on taskloop. Handle OMP_CLAUSE_IN_REDUCTION.
|
||||
(maybe_add_implicit_barrier_cancel): Add OMP_RETURN argument, don't
|
||||
rely that it is the last stmt in body so far. Ignore outer taskgroup
|
||||
contexts.
|
||||
(omp_task_reductions_find_first, omp_task_reduction_iterate,
|
||||
lower_omp_task_reductions): New functions.
|
||||
(lower_omp_sections): Handle reduction clauses with taskgroup
|
||||
modifiers. Adjust maybe_add_implicit_barrier_cancel caller.
|
||||
(lower_omp_single): Adjust maybe_add_implicit_barrier_cancel caller.
|
||||
(lower_omp_for): Likewise. Handle reduction clauses with taskgroup
|
||||
modifiers.
|
||||
(lower_omp_taskgroup): Handle taskgroup reductions.
|
||||
(create_task_copyfn): Copy over OMP_CLAUSE__REDUCTEMP_ pointer.
|
||||
Handle OMP_CLAUSE_IN_REDUCTION and OMP_CLAUSE_REDUCTION clauses.
|
||||
(lower_depend_clauses): If there are any
|
||||
OMP_CLAUSE_DEPEND_DEPOBJ or OMP_CLAUSE_DEPEND_MUTEXINOUTSET
|
||||
depend clauses, use a new array format. If OMP_CLAUSE_DEPEND_LAST is
|
||||
seen, assume lowering is done already and return early. Set kind
|
||||
on artificial depend clause to OMP_CLAUSE_DEPEND_LAST.
|
||||
(lower_omp_taskreg): Handle reduction clauses with task modifier on
|
||||
parallel construct. Handle reduction clause on taskloop construct.
|
||||
Handle taskwait with depend clauses.
|
||||
(lower_omp_1): Use lower_omp_taskreg instead of lower_omp_teams
|
||||
for host teams constructs.
|
||||
* tree.c (omp_clause_num_ops): Add in_reduction, task_reduction,
|
||||
nontemporal and _reductemp_ clause entries.
|
||||
(omp_clause_code_name): Likewise.
|
||||
(walk_tree_1): Handle OMP_CLAUSE_{IN,TASK}_REDUCTION,
|
||||
OMP_CLAUSE_NONTEMPORAL and OMP_CLAUSE__REDUCTEMP_.
|
||||
* tree-core.h (enum omp_clause_code): Add
|
||||
OMP_CLAUSE_{{IN,TASK}_REDUCTION,NONTEMPORAL,_REDUCTEMP_}.
|
||||
(enum omp_clause_defaultmap_kind, enum omp_memory_order): New.
|
||||
(struct tree_base): Add omp_atomic_memory_order field into union.
|
||||
Remove OMP_ATOMIC_SEQ_CST comment.
|
||||
(enum omp_clause_depend_kind): Add OMP_CLAUSE_DEPEND_MUTEXINOUTSET
|
||||
and OMP_CLAUSE_DEPEND_DEPOBJ.
|
||||
(struct tree_omp_clause): Add subcode.defaultmap_kind.
|
||||
* tree.def (OMP_TASKGROUP): Add another operand, move next to other
|
||||
OpenMP constructs with body and clauses operands.
|
||||
* tree.h (OMP_BODY): Use OMP_MASTER instead of OMP_TASKGROUP.
|
||||
(OMP_CLAUSES): Use OMP_TASKGROUP instead of OMP_SINGLE.
|
||||
(OMP_TASKGROUP_CLAUSES): Define.
|
||||
(OMP_CLAUSE_DECL): Use OMP_CLAUSE__REDUCTEMP_ instead of
|
||||
OMP_CLAUSE__LOOPTEMP_.
|
||||
(OMP_ATOMIC_SEQ_CST): Remove.
|
||||
(OMP_ATOMIC_MEMORY_ORDER, OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE,
|
||||
OMP_CLAUSE_LASTPRIVATE_CONDITIONAL): Define.
|
||||
(OMP_CLAUSE_REDUCTION_CODE, OMP_CLAUSE_REDUCTION_INIT,
|
||||
OMP_CLAUSE_REDUCTION_MERGE, OMP_CLAUSE_REDUCTION_PLACEHOLDER,
|
||||
OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER,
|
||||
OMP_CLAUSE_REDUCTION_OMP_ORIG_REF): Handle
|
||||
OMP_CLAUSE_{,IN_,TASK_}REDUCTION.
|
||||
(OMP_CLAUSE_REDUCTION_TASK, OMP_CLAUSE_REDUCTION_INSCAN,
|
||||
OMP_CLAUSE_DEFAULTMAP_KIND, OMP_CLAUSE_DEFAULTMAP_CATEGORY,
|
||||
OMP_CLAUSE_DEFAULTMAP_BEHAVIOR, OMP_CLAUSE_DEFAULTMAP_SET_KIND):
|
||||
Define.
|
||||
* tree-inline.c (remap_gimple_stmt): Remap taskgroup clauses.
|
||||
* tree-nested.c (convert_nonlocal_omp_clauses): Handle
|
||||
OMP_CLAUSE__REDUCTEMP_, OMP_CLAUSE_NONTEMPORAL.
|
||||
(convert_local_omp_clauses): Likewise. Remove useless test.
|
||||
* tree-parloops.c (create_call_for_reduction_1): Pass
|
||||
OMP_MEMORY_ORDER_RELAXED as new argument to
|
||||
dump_gimple_omp_atomic_load and dump_gimple_omp_atomic_store.
|
||||
* tree-pretty-print.c (dump_omp_iterators): New function.
|
||||
(dump_omp_clause): Handle OMP_CLAUSE__REDUCTEMP_,
|
||||
OMP_CLAUSE_NONTEMPORAL, OMP_CLAUSE_{TASK,IN}_REDUCTION. Print
|
||||
reduction modifiers. Handle OMP_CLAUSE_DEPEND_DEPOBJ and
|
||||
OMP_CLAUSE_DEPEND_MUTEXINOUTSET. Print iterators in depend clauses.
|
||||
Print __internal__ for OMP_CLAUSE_DEPEND_LAST. Handle cancel and
|
||||
simd OMP_CLAUSE_IF_MODIFIERs. Handle new kinds of
|
||||
OMP_CLAUSE_DEFAULTMAP. Print conditional: for
|
||||
OMP_CLAUSE_LASTPRIVATE_CONDITIONAL.
|
||||
(dump_omp_atomic_memory_order): New function.
|
||||
(dump_generic_node): Use it. Print taskgroup clauses. Print
|
||||
taskwait with depend clauses.
|
||||
* tree-pretty-print.h (dump_omp_atomic_memory_order): Declare.
|
||||
* tree-streamer-in.c (unpack_ts_omp_clause_value_fields):
|
||||
Handle OMP_CLAUSE_{TASK,IN}_REDUCTION.
|
||||
* tree-streamer-out.c (pack_ts_omp_clause_value_fields,
|
||||
write_ts_omp_clause_tree_pointers): Likewise.
|
||||
|
||||
2018-11-08 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
PR ipa/86395
|
||||
|
|
|
@ -309,7 +309,16 @@ arm_print_hint_for_cpu_option (const char *target,
|
|||
{
|
||||
auto_vec<const char*> candidates;
|
||||
for (; list->common.name != NULL; list++)
|
||||
candidates.safe_push (list->common.name);
|
||||
{
|
||||
candidates.safe_push (list->common.name);
|
||||
if (list->aliases)
|
||||
{
|
||||
for (const cpu_alias *alias = list->aliases; alias->name != NULL;
|
||||
alias++)
|
||||
if (alias->visible)
|
||||
candidates.safe_push (alias->name);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_LOCAL_CPU_DETECT
|
||||
/* Add also "native" as possible value. */
|
||||
|
@ -345,6 +354,16 @@ arm_parse_cpu_option_name (const cpu_option *list, const char *optname,
|
|||
if (strncmp (entry->common.name, target, len) == 0
|
||||
&& entry->common.name[len] == '\0')
|
||||
return entry;
|
||||
|
||||
/* Match against any legal alias for this CPU candidate. */
|
||||
if (entry->aliases)
|
||||
{
|
||||
for (const cpu_alias *alias = entry->aliases; alias->name != NULL;
|
||||
alias++)
|
||||
if (strncmp (alias->name, target, len) == 0
|
||||
&& alias->name[len] == '\0')
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
if (complain)
|
||||
|
|
|
@ -617,6 +617,7 @@ end arch iwmmxt2
|
|||
# format:
|
||||
# begin cpu <name>
|
||||
# [cname <c-compatible-name>]
|
||||
# [alias <name>+]
|
||||
# [tune for <cpu-name>]
|
||||
# [tune flags <list>]
|
||||
# architecture <name>
|
||||
|
@ -630,6 +631,9 @@ end arch iwmmxt2
|
|||
#
|
||||
# If omitted, cname is formed from transforming the cpuname to convert
|
||||
# non-valid punctuation characters to '_'.
|
||||
# Any number of alias names may be specified for a CPU. If the name starts
|
||||
# with a '!' then it will be recognized as a valid name, but will not
|
||||
# be printed in any help text listing permitted CPUs.
|
||||
# If specified, tune for specifies a CPU target to use for tuning this core.
|
||||
# isa flags are appended to those defined by the architecture.
|
||||
# Each add option must have a distinct feature set and each remove
|
||||
|
@ -658,29 +662,12 @@ begin cpu arm810
|
|||
end cpu arm810
|
||||
|
||||
begin cpu strongarm
|
||||
alias strongarm110 !strongarm1100 !strongarm1110
|
||||
tune flags LDSCHED STRONG
|
||||
architecture armv4
|
||||
costs strongarm
|
||||
end cpu strongarm
|
||||
|
||||
begin cpu strongarm110
|
||||
tune flags LDSCHED STRONG
|
||||
architecture armv4
|
||||
costs strongarm
|
||||
end cpu strongarm110
|
||||
|
||||
begin cpu strongarm1100
|
||||
tune flags LDSCHED STRONG
|
||||
architecture armv4
|
||||
costs strongarm
|
||||
end cpu strongarm1100
|
||||
|
||||
begin cpu strongarm1110
|
||||
tune flags LDSCHED STRONG
|
||||
architecture armv4
|
||||
costs strongarm
|
||||
end cpu strongarm1110
|
||||
|
||||
begin cpu fa526
|
||||
tune flags LDSCHED
|
||||
architecture armv4
|
||||
|
|
|
@ -122,8 +122,7 @@
|
|||
(define_insn_reservation "mult_ldsched_strongarm" 3
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "ldsched" "yes")
|
||||
(and (eq_attr "tune"
|
||||
"strongarm,strongarm110,strongarm1100,strongarm1110")
|
||||
(and (eq_attr "tune" "strongarm")
|
||||
(ior (eq_attr "mul32" "yes")
|
||||
(eq_attr "mul64" "yes")))))
|
||||
"core*2")
|
||||
|
@ -131,8 +130,7 @@
|
|||
(define_insn_reservation "mult_ldsched" 4
|
||||
(and (eq_attr "generic_sched" "yes")
|
||||
(and (eq_attr "ldsched" "yes")
|
||||
(and (eq_attr "tune"
|
||||
"!strongarm,strongarm110,strongarm1100,strongarm1110")
|
||||
(and (eq_attr "tune" "!strongarm")
|
||||
(ior (eq_attr "mul32" "yes")
|
||||
(eq_attr "mul64" "yes")))))
|
||||
"core*4")
|
||||
|
|
|
@ -498,6 +498,16 @@ struct arm_build_target
|
|||
|
||||
extern struct arm_build_target arm_active_target;
|
||||
|
||||
/* Table entry for a CPU alias. */
|
||||
struct cpu_alias
|
||||
{
|
||||
/* The alias name. */
|
||||
const char *const name;
|
||||
/* True if the name should be displayed in help text listing cpu names. */
|
||||
bool visible;
|
||||
};
|
||||
|
||||
/* Table entry for an architectural feature extension. */
|
||||
struct cpu_arch_extension
|
||||
{
|
||||
/* Feature name. */
|
||||
|
@ -511,6 +521,7 @@ struct cpu_arch_extension
|
|||
const enum isa_feature isa_bits[isa_num_bits];
|
||||
};
|
||||
|
||||
/* Common elements of both CPU and architectural options. */
|
||||
struct cpu_arch_option
|
||||
{
|
||||
/* Name for this option. */
|
||||
|
@ -521,6 +532,7 @@ struct cpu_arch_option
|
|||
enum isa_feature isa_bits[isa_num_bits];
|
||||
};
|
||||
|
||||
/* Table entry for an architecture entry. */
|
||||
struct arch_option
|
||||
{
|
||||
/* Common option fields. */
|
||||
|
@ -535,10 +547,13 @@ struct arch_option
|
|||
enum processor_type tune_id;
|
||||
};
|
||||
|
||||
/* Table entry for a CPU entry. */
|
||||
struct cpu_option
|
||||
{
|
||||
/* Common option fields. */
|
||||
cpu_arch_option common;
|
||||
/* List of aliases for this CPU. */
|
||||
const struct cpu_alias *aliases;
|
||||
/* Architecture upon which this CPU is based. */
|
||||
enum arch_type arch;
|
||||
};
|
||||
|
|
|
@ -33,15 +33,6 @@ Enum(processor_type) String(arm810) Value( TARGET_CPU_arm810)
|
|||
EnumValue
|
||||
Enum(processor_type) String(strongarm) Value( TARGET_CPU_strongarm)
|
||||
|
||||
EnumValue
|
||||
Enum(processor_type) String(strongarm110) Value( TARGET_CPU_strongarm110)
|
||||
|
||||
EnumValue
|
||||
Enum(processor_type) String(strongarm1100) Value( TARGET_CPU_strongarm1100)
|
||||
|
||||
EnumValue
|
||||
Enum(processor_type) String(strongarm1110) Value( TARGET_CPU_strongarm1110)
|
||||
|
||||
EnumValue
|
||||
Enum(processor_type) String(fa526) Value( TARGET_CPU_fa526)
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
(define_attr "tune"
|
||||
"arm8,arm810,strongarm,
|
||||
strongarm110,strongarm1100,strongarm1110,
|
||||
fa526,fa626,arm7tdmi,
|
||||
arm7tdmis,arm710t,arm720t,
|
||||
arm740t,arm9,arm9tdmi,
|
||||
|
|
|
@ -261,6 +261,18 @@ function gen_comm_data () {
|
|||
print " { NULL, false, false, {isa_nobit}}"
|
||||
print "};\n"
|
||||
}
|
||||
|
||||
if (cpus[n] in cpu_aliases) {
|
||||
print "static const cpu_alias cpu_aliastab_" \
|
||||
cpu_cnames[cpus[n]] "[] = {"
|
||||
naliases = split (cpu_aliases[cpus[n]], aliases)
|
||||
for (alias = 1; alias <= naliases; alias++) {
|
||||
print " { \"" aliases[alias] "\", " \
|
||||
cpu_alias_visible[cpus[n],aliases[alias]] "},"
|
||||
}
|
||||
print " { NULL, false}"
|
||||
print "};\n"
|
||||
}
|
||||
}
|
||||
|
||||
print "const cpu_option all_cores[] ="
|
||||
|
@ -295,12 +307,16 @@ function gen_comm_data () {
|
|||
}
|
||||
print_isa_bits_for(all_isa_bits, " ")
|
||||
print "\n },"
|
||||
# aliases
|
||||
if (cpus[n] in cpu_aliases) {
|
||||
print " cpu_aliastab_" cpu_cnames[cpus[n]] ","
|
||||
} else print " NULL,"
|
||||
# arch
|
||||
print " TARGET_ARCH_" arch_cnames[feats[1]]
|
||||
print " },"
|
||||
}
|
||||
|
||||
print " {{NULL, NULL, {isa_nobit}}, TARGET_ARCH_arm_none}"
|
||||
print " {{NULL, NULL, {isa_nobit}}, NULL, TARGET_ARCH_arm_none}"
|
||||
print "};"
|
||||
|
||||
narchs = split (arch_list, archs)
|
||||
|
@ -486,13 +502,17 @@ function gen_opt () {
|
|||
function check_cpu (name) {
|
||||
exts = split (name, extensions, "+")
|
||||
|
||||
if (! (extensions[1] in cpu_cnames)) {
|
||||
return "error"
|
||||
cpu_name = extensions[1]
|
||||
if (! (cpu_name in cpu_cnames)) {
|
||||
if (! (cpu_name in cpu_all_aliases)) {
|
||||
return "error"
|
||||
}
|
||||
cpu_name = cpu_all_aliases[cpu_name]
|
||||
}
|
||||
|
||||
for (n = 2; n <= exts; n++) {
|
||||
if (!((extensions[1], extensions[n]) in cpu_opt_remove) \
|
||||
&& !((extensions[1], extensions[n]) in cpu_optaliases)) {
|
||||
if (!((cpu_name, extensions[n]) in cpu_opt_remove) \
|
||||
&& !((cpu_name, extensions[n]) in cpu_optaliases)) {
|
||||
return "error"
|
||||
}
|
||||
}
|
||||
|
@ -642,6 +662,12 @@ BEGIN {
|
|||
toplevel()
|
||||
cpu_name = $3
|
||||
parse_ok = 1
|
||||
if (cpu_name in cpu_cnames) {
|
||||
fatal(cpu_name " is already defined")
|
||||
}
|
||||
if (cpu_name in cpu_all_aliases) {
|
||||
fatal(cpu_name " has already been defined as an alias")
|
||||
}
|
||||
}
|
||||
|
||||
/^[ ]*cname / {
|
||||
|
@ -651,6 +677,33 @@ BEGIN {
|
|||
parse_ok = 1
|
||||
}
|
||||
|
||||
/^[ ]*alias / {
|
||||
if (NF < 2) fatal("syntax: alias <name>+")
|
||||
if (cpu_name == "") fatal("\"alias\" outside of cpu block")
|
||||
alias_count = NF
|
||||
for (n = 2; n <= alias_count; n++) {
|
||||
visible = "true"
|
||||
alias = $n
|
||||
if (alias ~ /!.*/) {
|
||||
visible = "false"
|
||||
gsub(/^!/, "", alias)
|
||||
}
|
||||
if (alias in cpu_cnames) {
|
||||
fatal(alias " is already defined as a cpu name")
|
||||
}
|
||||
if (n == 2) {
|
||||
cpu_aliases[cpu_name] = alias
|
||||
} else cpu_aliases[cpu_name] = cpu_aliases[cpu_name] " " alias
|
||||
cpu_alias_visible[cpu_name,alias] = visible
|
||||
if (alias in cpu_all_aliases) {
|
||||
fatal(alias " is already an alias for " cpu_all_aliases[alias])
|
||||
}
|
||||
cpu_all_aliases[alias] = cpu_name
|
||||
}
|
||||
cpu_has_alias[cpu_name] = 1
|
||||
parse_ok = 1
|
||||
}
|
||||
|
||||
/^[ ]*tune for / {
|
||||
if (NF != 3) fatal("syntax: tune for <cpu-name>")
|
||||
if (cpu_name != "") {
|
||||
|
|
|
@ -88,3 +88,32 @@
|
|||
(match_test "memory_address_p (GET_MODE (op), XEXP (op, 0))
|
||||
&& no_side_effect_operand (op, GET_MODE (op))")))
|
||||
|
||||
;; What follows is a set of constraints used to prevent the generation
|
||||
;; of insns that have a register as source, and an auto-increment or
|
||||
;; auto-decrement memory reference as the destination where the register
|
||||
;; is the same as the source. On the PDP11, such instructions are not
|
||||
;; implemented consistently across the models and often do something
|
||||
;; different from what the RTL intends.
|
||||
(define_register_constraint "Z0" "NOTR0_REG" "Register other than 0")
|
||||
(define_register_constraint "Z1" "NOTR1_REG" "Register other than 1")
|
||||
(define_register_constraint "Z2" "NOTR2_REG" "Register other than 2")
|
||||
(define_register_constraint "Z3" "NOTR3_REG" "Register other than 3")
|
||||
(define_register_constraint "Z4" "NOTR4_REG" "Register other than 4")
|
||||
(define_register_constraint "Z5" "NOTR5_REG" "Register other than 5")
|
||||
(define_register_constraint "Z6" "NOTSP_REG"
|
||||
"Register other than stack pointer (register 6)")
|
||||
(define_memory_constraint "Za" "R0 push/pop"
|
||||
(match_test "pushpop_regeq (op, 0)"))
|
||||
(define_memory_constraint "Zb" "R1 push/pop"
|
||||
(match_test "pushpop_regeq (op, 1)"))
|
||||
(define_memory_constraint "Zc" "R2 push/pop"
|
||||
(match_test "pushpop_regeq (op, 2)"))
|
||||
(define_memory_constraint "Zd" "R3 push/pop"
|
||||
(match_test "pushpop_regeq (op, 3)"))
|
||||
(define_memory_constraint "Ze" "R4 push/pop"
|
||||
(match_test "pushpop_regeq (op, 4)"))
|
||||
(define_memory_constraint "Zf" "R5 push/pop"
|
||||
(match_test "pushpop_regeq (op, 5)"))
|
||||
(define_memory_constraint "Zg" "SP push/pop"
|
||||
(match_test "pushpop_regeq (op, 6)"))
|
||||
|
||||
|
|
|
@ -26,14 +26,12 @@ extern int legitimate_const_double_p (rtx);
|
|||
extern void notice_update_cc_on_set (rtx, rtx);
|
||||
extern void output_addr_const_pdp11 (FILE *, rtx);
|
||||
extern const char *output_move_multiple (rtx *);
|
||||
extern void expand_block_move (rtx *);
|
||||
extern const char *output_jump (rtx *, int, int);
|
||||
extern void print_operand_address (FILE *, rtx);
|
||||
typedef enum { no_action, dec_before, inc_after } pdp11_action;
|
||||
typedef enum { little, either, big } pdp11_partorder;
|
||||
extern bool pdp11_expand_operands (rtx *, rtx [][2], int,
|
||||
extern bool pdp11_expand_operands (rtx *, rtx [][2], int, int,
|
||||
pdp11_action *, pdp11_partorder);
|
||||
extern int pdp11_sp_frame_offset (void);
|
||||
extern int pdp11_initial_elimination_offset (int, int);
|
||||
extern enum reg_class pdp11_regno_reg_class (int);
|
||||
extern bool pdp11_fixed_cc_regs (unsigned int *, unsigned int *);
|
||||
|
@ -42,6 +40,8 @@ extern bool pdp11_expand_shift (rtx *, rtx (*) (rtx, rtx, rtx),
|
|||
rtx (*) (rtx, rtx, rtx));
|
||||
extern const char * pdp11_assemble_shift (rtx *, machine_mode, int);
|
||||
extern int pdp11_shift_length (rtx *, machine_mode, int, bool);
|
||||
extern int pdp11_cmp_length (rtx *, int);
|
||||
extern bool pushpop_regeq (rtx, int);
|
||||
extern bool pdp11_small_shift (int);
|
||||
|
||||
#endif /* RTX_CODE */
|
||||
|
|
|
@ -304,6 +304,9 @@ static bool pdp11_scalar_mode_supported_p (scalar_mode);
|
|||
|
||||
#undef TARGET_HAVE_SPECULATION_SAFE_VALUE
|
||||
#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
|
||||
|
||||
#undef TARGET_STACK_PROTECT_RUNTIME_ENABLED_P
|
||||
#define TARGET_STACK_PROTECT_RUNTIME_ENABLED_P hook_bool_void_false
|
||||
|
||||
/* A helper function to determine if REGNO should be saved in the
|
||||
current function's stack frame. */
|
||||
|
@ -316,6 +319,13 @@ pdp11_saved_regno (unsigned regno)
|
|||
|
||||
/* Expand the function prologue. */
|
||||
|
||||
/* Frame layout, from high to low memory (stack push order):
|
||||
return address (from jsr instruction)
|
||||
saved CPU registers, lowest number first
|
||||
saved FPU registers, lowest number first, always 64 bit mode
|
||||
*** frame pointer points here ***
|
||||
local variables
|
||||
alloca storage if any. */
|
||||
void
|
||||
pdp11_expand_prologue (void)
|
||||
{
|
||||
|
@ -331,31 +341,9 @@ pdp11_expand_prologue (void)
|
|||
emit_insn (gen_seti ());
|
||||
}
|
||||
|
||||
if (frame_pointer_needed)
|
||||
{
|
||||
x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
|
||||
x = gen_frame_mem (Pmode, x);
|
||||
emit_move_insn (x, hard_frame_pointer_rtx);
|
||||
|
||||
emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
|
||||
}
|
||||
|
||||
/* Make frame. */
|
||||
if (fsize)
|
||||
{
|
||||
emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
|
||||
GEN_INT (-fsize)));
|
||||
|
||||
/* Prevent frame references via the frame pointer from being
|
||||
scheduled before the frame is allocated. */
|
||||
if (frame_pointer_needed)
|
||||
emit_insn (gen_blockage ());
|
||||
}
|
||||
|
||||
/* Save CPU registers. */
|
||||
for (regno = R0_REGNUM; regno <= PC_REGNUM; regno++)
|
||||
if (pdp11_saved_regno (regno)
|
||||
&& (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
|
||||
if (pdp11_saved_regno (regno))
|
||||
{
|
||||
x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
|
||||
x = gen_frame_mem (Pmode, x);
|
||||
|
@ -383,25 +371,21 @@ pdp11_expand_prologue (void)
|
|||
x = gen_frame_mem (DFmode, x);
|
||||
emit_move_insn (x, via_ac);
|
||||
}
|
||||
|
||||
if (frame_pointer_needed)
|
||||
emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
|
||||
|
||||
/* Make local variable space. */
|
||||
if (fsize)
|
||||
emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
|
||||
GEN_INT (-fsize)));
|
||||
}
|
||||
|
||||
/* The function epilogue should not depend on the current stack pointer!
|
||||
It should use the frame pointer only. This is mandatory because
|
||||
of alloca; we also take advantage of it to omit stack adjustments
|
||||
before returning. */
|
||||
|
||||
/* Maybe we can make leaf functions faster by switching to the
|
||||
second register file - this way we don't have to save regs!
|
||||
leaf functions are ~ 50% of all functions (dynamically!)
|
||||
|
||||
set/clear bit 11 (dec. 2048) of status word for switching register files -
|
||||
but how can we do this? the pdp11/45 manual says bit may only
|
||||
be set (p.24), but not cleared!
|
||||
|
||||
switching to kernel is probably more expensive, so we'll leave it
|
||||
like this and not use the second set of registers...
|
||||
|
||||
maybe as option if you want to generate code for kernel mode? */
|
||||
/* Generate epilogue. This uses the frame pointer to pop the local
|
||||
variables and any alloca data off the stack. If there is no alloca
|
||||
and frame pointer elimination hasn't been disabled, there is no
|
||||
frame pointer and the local variables are popped by adjusting the
|
||||
stack pointer instead. */
|
||||
|
||||
void
|
||||
pdp11_expand_epilogue (void)
|
||||
|
@ -410,6 +394,20 @@ pdp11_expand_epilogue (void)
|
|||
unsigned regno;
|
||||
rtx x, reg, via_ac = NULL;
|
||||
|
||||
/* Deallocate the local variables. */
|
||||
if (fsize)
|
||||
{
|
||||
if (frame_pointer_needed)
|
||||
{
|
||||
/* We can deallocate the frame with a single move. */
|
||||
emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
|
||||
}
|
||||
else
|
||||
emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
|
||||
GEN_INT (fsize)));
|
||||
}
|
||||
|
||||
/* Restore the FPU registers. */
|
||||
if (pdp11_saved_regno (AC4_REGNUM) || pdp11_saved_regno (AC5_REGNUM))
|
||||
{
|
||||
/* Find a temporary with which to restore AC4/5. */
|
||||
|
@ -421,109 +419,33 @@ pdp11_expand_epilogue (void)
|
|||
}
|
||||
}
|
||||
|
||||
/* If possible, restore registers via pops. */
|
||||
if (!frame_pointer_needed || crtl->sp_is_unchanging)
|
||||
{
|
||||
/* Restore registers via pops. */
|
||||
/* Restore registers via pops. */
|
||||
|
||||
for (regno = AC5_REGNUM; regno >= AC0_REGNUM; regno--)
|
||||
if (pdp11_saved_regno (regno))
|
||||
for (regno = AC5_REGNUM; regno >= AC0_REGNUM; regno--)
|
||||
if (pdp11_saved_regno (regno))
|
||||
{
|
||||
x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
|
||||
x = gen_frame_mem (DFmode, x);
|
||||
reg = gen_rtx_REG (DFmode, regno);
|
||||
|
||||
if (LOAD_FPU_REG_P (regno))
|
||||
emit_move_insn (reg, x);
|
||||
else
|
||||
{
|
||||
x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
|
||||
x = gen_frame_mem (DFmode, x);
|
||||
reg = gen_rtx_REG (DFmode, regno);
|
||||
|
||||
if (LOAD_FPU_REG_P (regno))
|
||||
emit_move_insn (reg, x);
|
||||
else
|
||||
{
|
||||
emit_move_insn (via_ac, x);
|
||||
emit_move_insn (reg, via_ac);
|
||||
}
|
||||
emit_move_insn (via_ac, x);
|
||||
emit_move_insn (reg, via_ac);
|
||||
}
|
||||
}
|
||||
|
||||
for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--)
|
||||
if (pdp11_saved_regno (regno)
|
||||
&& (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
|
||||
{
|
||||
x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
|
||||
x = gen_frame_mem (Pmode, x);
|
||||
emit_move_insn (gen_rtx_REG (Pmode, regno), x);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Restore registers via moves. */
|
||||
/* ??? If more than a few registers need to be restored, it's smaller
|
||||
to generate a pointer through which we can emit pops. Consider
|
||||
that moves cost 2*NREG words and pops cost NREG+3 words. This
|
||||
means that the crossover is NREG=3.
|
||||
for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--)
|
||||
if (pdp11_saved_regno (regno))
|
||||
{
|
||||
x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
|
||||
x = gen_frame_mem (Pmode, x);
|
||||
emit_move_insn (gen_rtx_REG (Pmode, regno), x);
|
||||
}
|
||||
|
||||
Possible registers to use are:
|
||||
(1) The first call-saved general register. This register will
|
||||
be restored with the last pop.
|
||||
(2) R1, if it's not used as a return register.
|
||||
(3) FP itself. This option may result in +4 words, since we
|
||||
may need two add imm,rn instructions instead of just one.
|
||||
This also has the downside that we're not representing
|
||||
the unwind info in any way, so during the epilogue the
|
||||
debugger may get lost. */
|
||||
|
||||
HOST_WIDE_INT ofs = -pdp11_sp_frame_offset ();
|
||||
|
||||
for (regno = AC5_REGNUM; regno >= AC0_REGNUM; regno--)
|
||||
if (pdp11_saved_regno (regno))
|
||||
{
|
||||
x = plus_constant (Pmode, hard_frame_pointer_rtx, ofs);
|
||||
x = gen_frame_mem (DFmode, x);
|
||||
reg = gen_rtx_REG (DFmode, regno);
|
||||
|
||||
if (LOAD_FPU_REG_P (regno))
|
||||
emit_move_insn (reg, x);
|
||||
else
|
||||
{
|
||||
emit_move_insn (via_ac, x);
|
||||
emit_move_insn (reg, via_ac);
|
||||
}
|
||||
ofs += 8;
|
||||
}
|
||||
|
||||
for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--)
|
||||
if (pdp11_saved_regno (regno)
|
||||
&& (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
|
||||
{
|
||||
x = plus_constant (Pmode, hard_frame_pointer_rtx, ofs);
|
||||
x = gen_frame_mem (Pmode, x);
|
||||
emit_move_insn (gen_rtx_REG (Pmode, regno), x);
|
||||
ofs += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Deallocate the stack frame. */
|
||||
if (fsize)
|
||||
{
|
||||
/* Prevent frame references via any pointer from being
|
||||
scheduled after the frame is deallocated. */
|
||||
emit_insn (gen_blockage ());
|
||||
|
||||
if (frame_pointer_needed)
|
||||
{
|
||||
/* We can deallocate the frame with a single move. */
|
||||
emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
|
||||
}
|
||||
else
|
||||
emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
|
||||
GEN_INT (fsize)));
|
||||
}
|
||||
|
||||
if (frame_pointer_needed)
|
||||
{
|
||||
x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
|
||||
x = gen_frame_mem (Pmode, x);
|
||||
emit_move_insn (hard_frame_pointer_rtx, x);
|
||||
}
|
||||
|
||||
emit_jump_insn (gen_return ());
|
||||
emit_jump_insn (gen_rtspc ());
|
||||
}
|
||||
|
||||
/* Return the best assembler insn template
|
||||
|
@ -539,21 +461,23 @@ singlemove_string (rtx *operands)
|
|||
|
||||
|
||||
/* Expand multi-word operands (SImode or DImode) into the 2 or 4
|
||||
corresponding HImode operands. The number of operands is given
|
||||
as the third argument, and the required order of the parts as
|
||||
the fourth argument. */
|
||||
corresponding HImode operands. The number of operands is given as
|
||||
the third argument, the word count for the mode as the fourth
|
||||
argument, and the required order of parts as the sixth argument.
|
||||
The word count is explicit because sometimes we're asked to compare
|
||||
two constants, both of which have mode VOIDmode, so we can't always
|
||||
rely on the input operand mode to imply the operand size. */
|
||||
bool
|
||||
pdp11_expand_operands (rtx *operands, rtx exops[][2], int opcount,
|
||||
pdp11_expand_operands (rtx *operands, rtx exops[][2],
|
||||
int opcount, int words,
|
||||
pdp11_action *action, pdp11_partorder order)
|
||||
{
|
||||
int words, op, w, i, sh;
|
||||
int op, w, i, sh;
|
||||
pdp11_partorder useorder;
|
||||
bool sameoff = false;
|
||||
enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype;
|
||||
long sval[2];
|
||||
|
||||
words = GET_MODE_BITSIZE (GET_MODE (operands[0])) / 16;
|
||||
|
||||
/* If either piece order is accepted and one is pre-decrement
|
||||
while the other is post-increment, set order to be high order
|
||||
word first. That will force the pre-decrement to be turned
|
||||
|
@ -566,19 +490,16 @@ pdp11_expand_operands (rtx *operands, rtx exops[][2], int opcount,
|
|||
useorder = either;
|
||||
if (opcount == 2)
|
||||
{
|
||||
if (!REG_P (operands[0]) && !REG_P (operands[1]) &&
|
||||
!(CONSTANT_P (operands[1]) ||
|
||||
GET_CODE (operands[1]) == CONST_DOUBLE) &&
|
||||
if (GET_CODE (operands[0]) == MEM &&
|
||||
GET_CODE (operands[1]) == MEM &&
|
||||
((GET_CODE (XEXP (operands[0], 0)) == POST_INC &&
|
||||
GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) ||
|
||||
(GET_CODE (XEXP (operands[0], 0)) == PRE_DEC &&
|
||||
GET_CODE (XEXP (operands[1], 0)) == POST_INC)))
|
||||
useorder = big;
|
||||
else if ((!REG_P (operands[0]) &&
|
||||
else if ((GET_CODE (operands[0]) == MEM &&
|
||||
GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ||
|
||||
(!REG_P (operands[1]) &&
|
||||
!(CONSTANT_P (operands[1]) ||
|
||||
GET_CODE (operands[1]) == CONST_DOUBLE) &&
|
||||
(GET_CODE (operands[1]) == MEM &&
|
||||
GET_CODE (XEXP (operands[1], 0)) == PRE_DEC))
|
||||
useorder = little;
|
||||
else if (REG_P (operands[0]) && REG_P (operands[1]) &&
|
||||
|
@ -615,7 +536,7 @@ pdp11_expand_operands (rtx *operands, rtx exops[][2], int opcount,
|
|||
/* First classify the operand. */
|
||||
if (REG_P (operands[op]))
|
||||
optype = REGOP;
|
||||
else if (CONSTANT_P (operands[op])
|
||||
else if (CONST_INT_P (operands[op])
|
||||
|| GET_CODE (operands[op]) == CONST_DOUBLE)
|
||||
optype = CNSTOP;
|
||||
else if (GET_CODE (XEXP (operands[op], 0)) == POST_INC)
|
||||
|
@ -663,8 +584,11 @@ pdp11_expand_operands (rtx *operands, rtx exops[][2], int opcount,
|
|||
}
|
||||
|
||||
if (GET_CODE (operands[op]) == CONST_DOUBLE)
|
||||
REAL_VALUE_TO_TARGET_DOUBLE
|
||||
(*CONST_DOUBLE_REAL_VALUE (operands[op]), sval);
|
||||
{
|
||||
gcc_assert (GET_MODE (operands[op]) != VOIDmode);
|
||||
REAL_VALUE_TO_TARGET_DOUBLE
|
||||
(*CONST_DOUBLE_REAL_VALUE (operands[op]), sval);
|
||||
}
|
||||
|
||||
for (i = 0; i < words; i++)
|
||||
{
|
||||
|
@ -707,24 +631,31 @@ pdp11_expand_operands (rtx *operands, rtx exops[][2], int opcount,
|
|||
const char *
|
||||
output_move_multiple (rtx *operands)
|
||||
{
|
||||
rtx inops[2];
|
||||
rtx exops[4][2];
|
||||
rtx adjops[2];
|
||||
|
||||
pdp11_action action[2];
|
||||
int i, words;
|
||||
|
||||
words = GET_MODE_BITSIZE (GET_MODE (operands[0])) / 16;
|
||||
adjops[1] = gen_rtx_CONST_INT (HImode, words * 2);
|
||||
|
||||
pdp11_expand_operands (operands, exops, 2, action, either);
|
||||
inops[0] = operands[0];
|
||||
inops[1] = operands[1];
|
||||
|
||||
pdp11_expand_operands (inops, exops, 2, words, action, either);
|
||||
|
||||
/* Check for explicit decrement before. */
|
||||
if (action[0] == dec_before)
|
||||
{
|
||||
operands[0] = XEXP (operands[0], 0);
|
||||
output_asm_insn ("sub\t%#4,%0", operands);
|
||||
adjops[0] = XEXP (XEXP (operands[0], 0), 0);
|
||||
output_asm_insn ("sub\t%1,%0", adjops);
|
||||
}
|
||||
if (action[1] == dec_before)
|
||||
{
|
||||
operands[1] = XEXP (operands[1], 0);
|
||||
output_asm_insn ("sub\t%#4,%1", operands);
|
||||
adjops[0] = XEXP (XEXP (operands[1], 0), 0);
|
||||
output_asm_insn ("sub\t%1,%0", adjops);
|
||||
}
|
||||
|
||||
/* Do the words. */
|
||||
|
@ -734,13 +665,13 @@ output_move_multiple (rtx *operands)
|
|||
/* Check for increment after. */
|
||||
if (action[0] == inc_after)
|
||||
{
|
||||
operands[0] = XEXP (operands[0], 0);
|
||||
output_asm_insn ("add\t%#4,%0", operands);
|
||||
adjops[0] = XEXP (XEXP (operands[0], 0), 0);
|
||||
output_asm_insn ("add\t%1,%0", adjops);
|
||||
}
|
||||
if (action[1] == inc_after)
|
||||
{
|
||||
operands[1] = XEXP (operands[1], 0);
|
||||
output_asm_insn ("add\t%#4,%1", operands);
|
||||
adjops[0] = XEXP (XEXP (operands[1], 0), 0);
|
||||
output_asm_insn ("add\t%1,%0", adjops);
|
||||
}
|
||||
|
||||
return "";
|
||||
|
@ -752,9 +683,9 @@ pdp11_gen_int_label (char *label, const char *prefix, int num)
|
|||
{
|
||||
if (TARGET_DEC_ASM)
|
||||
/* +1 because GCC numbers labels starting at zero. */
|
||||
sprintf (label, "*%lu$", num + 1);
|
||||
sprintf (label, "*%u$", num + 1);
|
||||
else
|
||||
sprintf (label, "*%s_%lu", prefix, num);
|
||||
sprintf (label, "*%s_%u", prefix, num);
|
||||
}
|
||||
|
||||
/* Output an ascii string. */
|
||||
|
@ -780,7 +711,7 @@ output_ascii (FILE *file, const char *p, int size)
|
|||
{
|
||||
if (delim)
|
||||
putc ('"', file);
|
||||
fprintf (file, "<%o%>", c);
|
||||
fprintf (file, "<%o>", c);
|
||||
delim = false;
|
||||
}
|
||||
else
|
||||
|
@ -815,15 +746,30 @@ pdp11_asm_output_var (FILE *file, const char *name, int size,
|
|||
{
|
||||
if (align > 8)
|
||||
fprintf (file, "\t.even\n");
|
||||
if (global)
|
||||
if (TARGET_DEC_ASM)
|
||||
{
|
||||
fprintf (file, ".globl ");
|
||||
assemble_name (file, name);
|
||||
if (global)
|
||||
fputs ("::", file);
|
||||
else
|
||||
fputs (":", file);
|
||||
if (align > 8)
|
||||
fprintf (file, "\t.blkw\t%o\n", (size & 0xffff) / 2);
|
||||
else
|
||||
fprintf (file, "\t.blkb\t%o\n", size & 0xffff);
|
||||
}
|
||||
fprintf (file, "\n");
|
||||
assemble_name (file, name);
|
||||
fputs (":", file);
|
||||
ASM_OUTPUT_SKIP (file, size);
|
||||
else
|
||||
{
|
||||
if (global)
|
||||
{
|
||||
fprintf (file, ".globl ");
|
||||
assemble_name (file, name);
|
||||
}
|
||||
fprintf (file, "\n");
|
||||
assemble_name (file, name);
|
||||
fputs (":", file);
|
||||
ASM_OUTPUT_SKIP (file, size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Special format operators handled here:
|
||||
|
@ -855,7 +801,7 @@ pdp11_asm_print_operand (FILE *file, rtx x, int code)
|
|||
fprintf (file, "%s", reg_names[REGNO (x)]);
|
||||
else if (GET_CODE (x) == MEM)
|
||||
output_address (GET_MODE (x), XEXP (x, 0));
|
||||
else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != SImode)
|
||||
else if (GET_CODE (x) == CONST_DOUBLE && FLOAT_MODE_P (GET_MODE (x)))
|
||||
{
|
||||
REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), sval);
|
||||
if (TARGET_DEC_ASM)
|
||||
|
@ -1013,8 +959,7 @@ static int
|
|||
pdp11_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
|
||||
reg_class_t c1, reg_class_t c2)
|
||||
{
|
||||
if (((c1 == MUL_REGS || c1 == GENERAL_REGS) &&
|
||||
(c2 == MUL_REGS || c2 == GENERAL_REGS)))
|
||||
if (CPU_REG_CLASS (c1) && CPU_REG_CLASS (c2))
|
||||
return 2;
|
||||
else if ((c1 >= LOAD_FPU_REGS && c1 <= FPU_REGS && c2 == LOAD_FPU_REGS) ||
|
||||
(c2 >= LOAD_FPU_REGS && c2 <= FPU_REGS && c1 == LOAD_FPU_REGS))
|
||||
|
@ -1512,50 +1457,32 @@ no_side_effect_operand(rtx op, machine_mode mode ATTRIBUTE_UNUSED)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* expand a block move:
|
||||
*
|
||||
* operands[0] ... to
|
||||
* operands[1] ... from
|
||||
* operands[2] ... length
|
||||
* operands[3] ... alignment
|
||||
*/
|
||||
|
||||
void
|
||||
expand_block_move(rtx *operands)
|
||||
/* Return TRUE if op is a push or pop using the register "regno". */
|
||||
bool
|
||||
pushpop_regeq (rtx op, int regno)
|
||||
{
|
||||
rtx lb, test;
|
||||
rtx fromop, toop, counter;
|
||||
int count;
|
||||
rtx addr;
|
||||
|
||||
/* False if not memory reference. */
|
||||
if (GET_CODE (op) != MEM)
|
||||
return FALSE;
|
||||
|
||||
/* Get the address of the memory reference. */
|
||||
addr = XEXP (op, 0);
|
||||
|
||||
/* Transform BLKmode MEM reference into a (reg)+ operand. */
|
||||
toop = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
|
||||
toop = gen_rtx_POST_INC (Pmode, toop);
|
||||
fromop = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
|
||||
fromop = gen_rtx_POST_INC (Pmode, fromop);
|
||||
|
||||
count = INTVAL (operands[2]);
|
||||
if (INTVAL (operands [3]) >= 2 && (count & 1) == 0)
|
||||
{
|
||||
count >>= 1;
|
||||
toop = gen_rtx_MEM (HImode, toop);
|
||||
fromop = gen_rtx_MEM (HImode, fromop);
|
||||
}
|
||||
else
|
||||
{
|
||||
toop = gen_rtx_MEM (QImode, toop);
|
||||
fromop = gen_rtx_MEM (QImode, fromop);
|
||||
}
|
||||
counter = copy_to_mode_reg (HImode, gen_rtx_CONST_INT (HImode, count));
|
||||
|
||||
/* Label at top of loop */
|
||||
lb = gen_label_rtx ();
|
||||
emit_label (lb);
|
||||
emit_move_insn (toop, fromop);
|
||||
emit_insn (gen_subhi3 (counter, counter, const1_rtx));
|
||||
test = gen_rtx_NE (HImode, counter, const0_rtx);
|
||||
emit_jump_insn (gen_cbranchhi4 (test, counter, const0_rtx, lb));
|
||||
if (GET_CODE (addr) == MEM)
|
||||
addr = XEXP (addr, 0);
|
||||
|
||||
switch (GET_CODE (addr))
|
||||
{
|
||||
case PRE_DEC:
|
||||
case POST_INC:
|
||||
case PRE_MODIFY:
|
||||
case POST_MODIFY:
|
||||
return REGNO (XEXP (addr, 0)) == regno;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function checks whether a real value can be encoded as
|
||||
|
@ -1565,7 +1492,12 @@ int
|
|||
legitimate_const_double_p (rtx address)
|
||||
{
|
||||
long sval[2];
|
||||
|
||||
/* If it's too big for HOST_WIDE_INT, it's definitely to big here. */
|
||||
if (GET_MODE (address) == VOIDmode)
|
||||
return 0;
|
||||
REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (address), sval);
|
||||
|
||||
if ((sval[0] & 0xffff) == 0 && sval[1] == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
|
@ -1723,7 +1655,7 @@ pdp11_legitimate_address_p (machine_mode mode,
|
|||
&& GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS
|
||||
&& GET_CODE (XEXP (xfoob, 0)) == REG
|
||||
&& REGNO (XEXP (xfoob, 0)) == STACK_POINTER_REGNUM
|
||||
&& CONSTANT_P (XEXP (xfoob, 1))
|
||||
&& CONST_INT_P (XEXP (xfoob, 1))
|
||||
&& INTVAL (XEXP (xfoob,1)) == -2;
|
||||
|
||||
case POST_MODIFY:
|
||||
|
@ -1733,7 +1665,7 @@ pdp11_legitimate_address_p (machine_mode mode,
|
|||
&& GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS
|
||||
&& GET_CODE (XEXP (xfoob, 0)) == REG
|
||||
&& REGNO (XEXP (xfoob, 0)) == STACK_POINTER_REGNUM
|
||||
&& CONSTANT_P (XEXP (xfoob, 1))
|
||||
&& CONST_INT_P (XEXP (xfoob, 1))
|
||||
&& INTVAL (XEXP (xfoob,1)) == 2;
|
||||
|
||||
case MEM:
|
||||
|
@ -1792,16 +1724,18 @@ pdp11_legitimate_address_p (machine_mode mode,
|
|||
enum reg_class
|
||||
pdp11_regno_reg_class (int regno)
|
||||
{
|
||||
if (regno == FRAME_POINTER_REGNUM || regno == ARG_POINTER_REGNUM)
|
||||
return GENERAL_REGS;
|
||||
if (regno == ARG_POINTER_REGNUM)
|
||||
return NOTSP_REG;
|
||||
else if (regno == CC_REGNUM || regno == FCC_REGNUM)
|
||||
return CC_REGS;
|
||||
else if (regno > AC3_REGNUM)
|
||||
return NO_LOAD_FPU_REGS;
|
||||
else if (regno >= AC0_REGNUM)
|
||||
return LOAD_FPU_REGS;
|
||||
else if (regno & 1)
|
||||
return MUL_REGS;
|
||||
else if (regno == 6)
|
||||
return NOTR0_REG;
|
||||
else if (regno < 6)
|
||||
return NOTSP_REG;
|
||||
else
|
||||
return GENERAL_REGS;
|
||||
}
|
||||
|
@ -1815,11 +1749,11 @@ pdp11_fixed_cc_regs (unsigned int *p1, unsigned int *p2)
|
|||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
pdp11_sp_frame_offset (void)
|
||||
static int
|
||||
pdp11_reg_save_size (void)
|
||||
{
|
||||
int offset = 0, regno;
|
||||
offset = get_frame_size();
|
||||
|
||||
for (regno = 0; regno <= PC_REGNUM; regno++)
|
||||
if (pdp11_saved_regno (regno))
|
||||
offset += 2;
|
||||
|
@ -1836,32 +1770,18 @@ pdp11_sp_frame_offset (void)
|
|||
int
|
||||
pdp11_initial_elimination_offset (int from, int to)
|
||||
{
|
||||
/* Get the size of the register save area. */
|
||||
int spoff;
|
||||
|
||||
if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
|
||||
return 4;
|
||||
else if (from == FRAME_POINTER_REGNUM
|
||||
&& to == HARD_FRAME_POINTER_REGNUM)
|
||||
return 0;
|
||||
if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
|
||||
return get_frame_size ();
|
||||
else if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
|
||||
return pdp11_reg_save_size () + 2;
|
||||
else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
|
||||
return pdp11_reg_save_size () + 2 + get_frame_size ();
|
||||
else
|
||||
{
|
||||
gcc_assert (to == STACK_POINTER_REGNUM);
|
||||
|
||||
/* Get the size of the register save area. */
|
||||
spoff = pdp11_sp_frame_offset ();
|
||||
if (from == FRAME_POINTER_REGNUM)
|
||||
return spoff;
|
||||
|
||||
gcc_assert (from == ARG_POINTER_REGNUM);
|
||||
|
||||
/* If there is a frame pointer, that is saved too. */
|
||||
if (frame_pointer_needed)
|
||||
spoff += 2;
|
||||
|
||||
/* Account for the saved PC in the function call. */
|
||||
return spoff + 2;
|
||||
}
|
||||
}
|
||||
gcc_assert (0);
|
||||
}
|
||||
|
||||
/* A copy of output_addr_const modified for pdp11 expression syntax.
|
||||
output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't
|
||||
|
@ -1913,21 +1833,6 @@ output_addr_const_pdp11 (FILE *file, rtx x)
|
|||
output_addr_const_pdp11 (file, XEXP (x, 0));
|
||||
break;
|
||||
|
||||
case CONST_DOUBLE:
|
||||
if (GET_MODE (x) == VOIDmode)
|
||||
{
|
||||
/* We can use %o if the number is one word and positive. */
|
||||
if (TARGET_DEC_ASM)
|
||||
fprintf (file, "%o", (int) CONST_DOUBLE_LOW (x) & 0xffff);
|
||||
else
|
||||
fprintf (file, "%#o", (int) CONST_DOUBLE_LOW (x) & 0xffff);
|
||||
}
|
||||
else
|
||||
/* We can't handle floating point constants;
|
||||
PRINT_OPERAND must handle them. */
|
||||
output_operand_lossage ("floating constant misused");
|
||||
break;
|
||||
|
||||
case PLUS:
|
||||
/* Some assemblers need integer constants to appear last (e.g. masm). */
|
||||
if (GET_CODE (XEXP (x, 0)) == CONST_INT)
|
||||
|
@ -2033,7 +1938,7 @@ pdp11_expand_shift (rtx *operands, rtx (*shift_sc) (rtx, rtx, rtx),
|
|||
rtx r, test;
|
||||
rtx_code_label *lb;
|
||||
|
||||
if (CONSTANT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2])))
|
||||
if (CONST_INT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2])))
|
||||
emit_insn ((*shift_sc) (operands[0], operands[1], operands[2]));
|
||||
else if (TARGET_40_PLUS)
|
||||
return false;
|
||||
|
@ -2043,7 +1948,7 @@ pdp11_expand_shift (rtx *operands, rtx (*shift_sc) (rtx, rtx, rtx),
|
|||
r = gen_reg_rtx (HImode);
|
||||
emit_move_insn (operands[0], operands[1]);
|
||||
emit_move_insn (r, operands[2]);
|
||||
if (!CONSTANT_P (operands[2]))
|
||||
if (!CONST_INT_P (operands[2]))
|
||||
{
|
||||
test = gen_rtx_LE (HImode, r, const0_rtx);
|
||||
emit_jump_insn (gen_cbranchhi4 (test, r, const0_rtx, lb));
|
||||
|
@ -2053,7 +1958,7 @@ pdp11_expand_shift (rtx *operands, rtx (*shift_sc) (rtx, rtx, rtx),
|
|||
optimizer and it doesn't appreciate flow changes happening
|
||||
while it's doing things. */
|
||||
emit_insn ((*shift_base) (operands[0], operands[1], r));
|
||||
if (!CONSTANT_P (operands[2]))
|
||||
if (!CONST_INT_P (operands[2]))
|
||||
{
|
||||
emit_label (lb);
|
||||
|
||||
|
@ -2072,16 +1977,20 @@ const char *
|
|||
pdp11_assemble_shift (rtx *operands, machine_mode m, int code)
|
||||
{
|
||||
int i, n;
|
||||
rtx exops[4][2];
|
||||
rtx inops[2];
|
||||
rtx exops[2][2];
|
||||
rtx lb[1];
|
||||
pdp11_action action[2];
|
||||
const bool small = CONSTANT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2]));
|
||||
const bool small = CONST_INT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2]));
|
||||
|
||||
gcc_assert (small || !TARGET_40_PLUS);
|
||||
|
||||
if (m == E_SImode)
|
||||
pdp11_expand_operands (operands, exops, 1, action, either);
|
||||
|
||||
{
|
||||
inops[0] = operands[0];
|
||||
pdp11_expand_operands (inops, exops, 1, 2, action, either);
|
||||
}
|
||||
|
||||
if (!small)
|
||||
{
|
||||
/* Loop case, generate the top of loop label. */
|
||||
|
@ -2179,7 +2088,7 @@ pdp11_shift_length (rtx *operands, machine_mode m, int code, bool simple_operand
|
|||
/* If shifting by a small constant, the loop is unrolled by the
|
||||
shift count. Otherwise, account for the size of the decrement
|
||||
and branch. */
|
||||
if (CONSTANT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2])))
|
||||
if (CONST_INT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2])))
|
||||
shift_size *= INTVAL (operands[2]);
|
||||
else
|
||||
shift_size += 4;
|
||||
|
@ -2191,6 +2100,39 @@ pdp11_shift_length (rtx *operands, machine_mode m, int code, bool simple_operand
|
|||
return shift_size;
|
||||
}
|
||||
|
||||
/* Return the length of 2 or 4 word integer compares. */
|
||||
int
|
||||
pdp11_cmp_length (rtx *operands, int words)
|
||||
{
|
||||
rtx inops[2];
|
||||
rtx exops[4][2];
|
||||
rtx lb[1];
|
||||
int i, len = 0;
|
||||
|
||||
if (!reload_completed)
|
||||
return 2;
|
||||
|
||||
inops[0] = operands[0];
|
||||
inops[1] = operands[1];
|
||||
|
||||
pdp11_expand_operands (inops, exops, 2, words, NULL, big);
|
||||
|
||||
for (i = 0; i < words; i++)
|
||||
{
|
||||
len += 4; /* cmp instruction word and branch that follows. */
|
||||
if (!REG_P (exops[i][0]) &&
|
||||
!simple_memory_operand (exops[i][0], HImode))
|
||||
len += 2; /* first operand extra word. */
|
||||
if (!REG_P (exops[i][1]) &&
|
||||
!simple_memory_operand (exops[i][1], HImode) &&
|
||||
!(CONST_INT_P (exops[i][1]) && INTVAL (exops[i][1]) == 0))
|
||||
len += 2; /* second operand extra word. */
|
||||
}
|
||||
|
||||
/* Deduct one word because there is no branch at the end. */
|
||||
return len - 2;
|
||||
}
|
||||
|
||||
/* Prepend to CLOBBERS hard registers that are automatically clobbered
|
||||
for an asm We do this for CC_REGNUM and FCC_REGNUM (on FPU target)
|
||||
to maintain source compatibility with the original cc0-based
|
||||
|
|
|
@ -32,6 +32,20 @@ along with GCC; see the file COPYING3. If not see
|
|||
do \
|
||||
{ \
|
||||
builtin_define_std ("pdp11"); \
|
||||
if (TARGET_INT16) \
|
||||
builtin_define_with_int_value ("__pdp11_int", 16); \
|
||||
else \
|
||||
builtin_define_with_int_value ("__pdp11_int", 32); \
|
||||
if (TARGET_40) \
|
||||
builtin_define_with_int_value ("__pdp11_model", 40); \
|
||||
else if (TARGET_45) \
|
||||
builtin_define_with_int_value ("__pdp11_model", 45); \
|
||||
else \
|
||||
builtin_define_with_int_value ("__pdp11_model", 10); \
|
||||
if (TARGET_FPU) \
|
||||
builtin_define ("__pdp11_fpu"); \
|
||||
if (TARGET_AC0) \
|
||||
builtin_define ("__pdp11_ac0"); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
@ -153,7 +167,7 @@ extern const struct real_format pdp11_d_format;
|
|||
#define FIXED_REGISTERS \
|
||||
{0, 0, 0, 0, 0, 0, 1, 1, \
|
||||
0, 0, 0, 0, 0, 0, 1, 1, \
|
||||
1, 1 }
|
||||
1 }
|
||||
|
||||
|
||||
|
||||
|
@ -168,7 +182,7 @@ extern const struct real_format pdp11_d_format;
|
|||
#define CALL_USED_REGISTERS \
|
||||
{1, 1, 0, 0, 0, 0, 1, 1, \
|
||||
0, 0, 0, 0, 0, 0, 1, 1, \
|
||||
1, 1 }
|
||||
1 }
|
||||
|
||||
|
||||
/* Specify the registers used for certain standard purposes.
|
||||
|
@ -211,6 +225,13 @@ CC_REGS is the condition codes (CPU and FPU)
|
|||
|
||||
enum reg_class
|
||||
{ NO_REGS,
|
||||
NOTR0_REG,
|
||||
NOTR1_REG,
|
||||
NOTR2_REG,
|
||||
NOTR3_REG,
|
||||
NOTR4_REG,
|
||||
NOTR5_REG,
|
||||
NOTSP_REG,
|
||||
MUL_REGS,
|
||||
GENERAL_REGS,
|
||||
LOAD_FPU_REGS,
|
||||
|
@ -229,6 +250,13 @@ enum reg_class
|
|||
|
||||
#define REG_CLASS_NAMES \
|
||||
{ "NO_REGS", \
|
||||
"NOTR0_REG", \
|
||||
"NOTR1_REG", \
|
||||
"NOTR2_REG", \
|
||||
"NOTR3_REG", \
|
||||
"NOTR4_REG", \
|
||||
"NOTR5_REG", \
|
||||
"SP_REG", \
|
||||
"MUL_REGS", \
|
||||
"GENERAL_REGS", \
|
||||
"LOAD_FPU_REGS", \
|
||||
|
@ -243,13 +271,20 @@ enum reg_class
|
|||
|
||||
#define REG_CLASS_CONTENTS \
|
||||
{ {0x00000}, /* NO_REGS */ \
|
||||
{0x000aa}, /* MUL_REGS */ \
|
||||
{0x0c0ff}, /* GENERAL_REGS */ \
|
||||
{0x000fe}, /* NOTR0_REG */ \
|
||||
{0x000fd}, /* NOTR1_REG */ \
|
||||
{0x000fb}, /* NOTR2_REG */ \
|
||||
{0x000f7}, /* NOTR3_REG */ \
|
||||
{0x000ef}, /* NOTR4_REG */ \
|
||||
{0x000df}, /* NOTR5_REG */ \
|
||||
{0x000bf}, /* NOTSP_REG */ \
|
||||
{0x0002a}, /* MUL_REGS */ \
|
||||
{0x040ff}, /* GENERAL_REGS */ \
|
||||
{0x00f00}, /* LOAD_FPU_REGS */ \
|
||||
{0x03000}, /* NO_LOAD_FPU_REGS */ \
|
||||
{0x03f00}, /* FPU_REGS */ \
|
||||
{0x30000}, /* CC_REGS */ \
|
||||
{0x3ffff}} /* ALL_REGS */
|
||||
{0x18000}, /* CC_REGS */ \
|
||||
{0x1ffff}} /* ALL_REGS */
|
||||
|
||||
/* The same information, inverted:
|
||||
Return the class number of the smallest class containing
|
||||
|
@ -262,13 +297,17 @@ enum reg_class
|
|||
#define INDEX_REG_CLASS GENERAL_REGS
|
||||
#define BASE_REG_CLASS GENERAL_REGS
|
||||
|
||||
/* Return TRUE if the class is a CPU register. */
|
||||
#define CPU_REG_CLASS(CLASS) \
|
||||
(CLASS >= NOTR0_REG && CLASS <= GENERAL_REGS)
|
||||
|
||||
/* Return the maximum number of consecutive registers
|
||||
needed to represent mode MODE in a register of class CLASS. */
|
||||
#define CLASS_MAX_NREGS(CLASS, MODE) \
|
||||
((CLASS == GENERAL_REGS || CLASS == MUL_REGS)? \
|
||||
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD): \
|
||||
1 \
|
||||
)
|
||||
(CPU_REG_CLASS (CLASS) ? \
|
||||
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD): \
|
||||
1 \
|
||||
)
|
||||
|
||||
/* Stack layout; function entry, exit and calling. */
|
||||
|
||||
|
@ -328,16 +367,13 @@ extern int current_first_parm_offset;
|
|||
/* Output assembler code to FILE to increment profiler label # LABELNO
|
||||
for profiling a function entry. */
|
||||
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||
gcc_unreachable ();
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO)
|
||||
|
||||
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
|
||||
the stack pointer does not matter. The value is tested only in
|
||||
functions that have frame pointers.
|
||||
No definition is equivalent to always zero. */
|
||||
|
||||
extern int may_call_alloca;
|
||||
|
||||
#define EXIT_IGNORE_STACK 1
|
||||
|
||||
/* Definitions for register eliminations.
|
||||
|
@ -347,17 +383,14 @@ extern int may_call_alloca;
|
|||
followed by "to". Eliminations of the same "from" register are listed
|
||||
in order of preference.
|
||||
|
||||
There are two registers that can always be eliminated on the pdp11.
|
||||
The frame pointer and the arg pointer can be replaced by either the
|
||||
hard frame pointer or to the stack pointer, depending upon the
|
||||
circumstances. The hard frame pointer is not used before reload and
|
||||
so it is not eligible for elimination. */
|
||||
There are two registers that can be eliminated on the pdp11. The
|
||||
arg pointer can be replaced by the frame pointer; the frame pointer
|
||||
can often be replaced by the stack pointer. */
|
||||
|
||||
#define ELIMINABLE_REGS \
|
||||
{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
|
||||
{ ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
|
||||
{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
|
||||
{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
|
||||
{ ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
|
||||
{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
|
||||
|
||||
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
|
||||
((OFFSET) = pdp11_initial_elimination_offset ((FROM), (TO)))
|
||||
|
@ -514,8 +547,8 @@ extern int may_call_alloca;
|
|||
|
||||
#define REGISTER_NAMES \
|
||||
{"r0", "r1", "r2", "r3", "r4", "r5", "sp", "pc", \
|
||||
"ac0", "ac1", "ac2", "ac3", "ac4", "ac5", "fp", "ap", \
|
||||
"cc", "fcc" }
|
||||
"ac0", "ac1", "ac2", "ac3", "ac4", "ac5", "ap", "cc", \
|
||||
"fcc" }
|
||||
|
||||
/* Globalizing directive for a label. */
|
||||
#define GLOBAL_ASM_OP "\t.globl\t"
|
||||
|
@ -568,28 +601,22 @@ extern int may_call_alloca;
|
|||
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
|
||||
pdp11_output_addr_vec_elt (FILE, VALUE)
|
||||
|
||||
/* This is how to output an assembler line
|
||||
that says to advance the location counter
|
||||
to a multiple of 2**LOG bytes.
|
||||
/* This is how to output an assembler line that says to advance the
|
||||
location counter to a multiple of 2**LOG bytes. Only values 0 and
|
||||
1 should appear, but due to PR87795 larger values (which are not
|
||||
supported) can also appear. So we treat all alignment of LOG >= 1
|
||||
as word (2 byte) alignment.
|
||||
*/
|
||||
|
||||
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
|
||||
switch (LOG) \
|
||||
{ \
|
||||
case 0: \
|
||||
break; \
|
||||
case 1: \
|
||||
fprintf (FILE, "\t.even\n"); \
|
||||
break; \
|
||||
default: \
|
||||
gcc_unreachable (); \
|
||||
}
|
||||
if (LOG != 0) \
|
||||
fprintf (FILE, "\t.even\n")
|
||||
|
||||
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
|
||||
if (TARGET_DEC_ASM) \
|
||||
fprintf (FILE, "\t.blkb\t%ho\n", (SIZE) & 0xffff); \
|
||||
fprintf (FILE, "\t.blkb\t%o\n", (SIZE) & 0xffff); \
|
||||
else \
|
||||
fprintf (FILE, "\t.=.+ %#ho\n", (SIZE) & 0xffff);
|
||||
fprintf (FILE, "\t.=.+ %#o\n", (SIZE) & 0xffff);
|
||||
|
||||
/* This says how to output an assembler line
|
||||
to define a global common symbol. */
|
||||
|
@ -597,7 +624,6 @@ extern int may_call_alloca;
|
|||
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
|
||||
pdp11_asm_output_var (FILE, NAME, SIZE, ALIGN, true)
|
||||
|
||||
|
||||
/* This says how to output an assembler line
|
||||
to define a local common symbol. */
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
UNSPECV_BLOCKAGE
|
||||
UNSPECV_SETD
|
||||
UNSPECV_SETI
|
||||
UNSPECV_MOVMEM
|
||||
])
|
||||
|
||||
(define_constants
|
||||
|
@ -33,22 +34,21 @@
|
|||
;; Register numbers
|
||||
(R0_REGNUM 0)
|
||||
(RETVAL_REGNUM 0)
|
||||
(HARD_FRAME_POINTER_REGNUM 5)
|
||||
(FRAME_POINTER_REGNUM 5)
|
||||
(STACK_POINTER_REGNUM 6)
|
||||
(PC_REGNUM 7)
|
||||
(AC0_REGNUM 8)
|
||||
(AC3_REGNUM 11)
|
||||
(AC4_REGNUM 12)
|
||||
(AC5_REGNUM 13)
|
||||
;; The next two are not physical registers but are used for addressing
|
||||
;; arguments.
|
||||
(FRAME_POINTER_REGNUM 14)
|
||||
(ARG_POINTER_REGNUM 15)
|
||||
;; The next one is not a physical register but is used for
|
||||
;; addressing arguments.
|
||||
(ARG_POINTER_REGNUM 14)
|
||||
;; Condition code registers
|
||||
(CC_REGNUM 16)
|
||||
(FCC_REGNUM 17)
|
||||
(CC_REGNUM 15)
|
||||
(FCC_REGNUM 16)
|
||||
;; End of hard registers
|
||||
(FIRST_PSEUDO_REGISTER 18)
|
||||
(FIRST_PSEUDO_REGISTER 17)
|
||||
|
||||
;; Branch offset limits, as byte offsets from (pc). That is NOT
|
||||
;; the same thing as "instruction address" -- it is for backward
|
||||
|
@ -178,12 +178,7 @@
|
|||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "return"
|
||||
[(return)]
|
||||
"reload_completed && !frame_pointer_needed && pdp11_sp_frame_offset () == 0"
|
||||
"")
|
||||
|
||||
(define_insn "*rts"
|
||||
(define_insn "rtspc"
|
||||
[(return)]
|
||||
""
|
||||
"rts\tpc")
|
||||
|
@ -249,6 +244,78 @@
|
|||
cmp<PDPint:isfx>\t%0,%1"
|
||||
[(set_attr "length" "2,2,4,4,4,6")])
|
||||
|
||||
;; Two word compare
|
||||
(define_insn "cmpsi"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC (match_operand:SI 0 "general_operand" "rDQi")
|
||||
(match_operand:SI 1 "general_operand" "rDQi")))]
|
||||
""
|
||||
{
|
||||
rtx inops[2];
|
||||
rtx exops[2][2];
|
||||
rtx lb[1];
|
||||
|
||||
inops[0] = operands[0];
|
||||
inops[1] = operands[1];
|
||||
pdp11_expand_operands (inops, exops, 2, 2, NULL, big);
|
||||
lb[0] = gen_label_rtx ();
|
||||
|
||||
if (CONST_INT_P (exops[0][1]) && INTVAL (exops[0][1]) == 0)
|
||||
output_asm_insn ("tst\t%0", exops[0]);
|
||||
else
|
||||
output_asm_insn ("cmp\t%0,%1", exops[0]);
|
||||
output_asm_insn ("bne\t%l0", lb);
|
||||
if (CONST_INT_P (exops[1][1]) && INTVAL (exops[1][1]) == 0)
|
||||
output_asm_insn ("tst\t%0", exops[1]);
|
||||
else
|
||||
output_asm_insn ("cmp\t%0,%1", exops[1]);
|
||||
output_asm_label (lb[0]);
|
||||
fputs (":\n", asm_out_file);
|
||||
|
||||
return "";
|
||||
}
|
||||
[(set (attr "length")
|
||||
(symbol_ref "pdp11_cmp_length (operands, 2)"))
|
||||
(set_attr "base_cost" "0")])
|
||||
|
||||
;; Four word compare
|
||||
(define_insn "cmpdi"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC (match_operand:DI 0 "general_operand" "rDQi")
|
||||
(match_operand:DI 1 "general_operand" "rDQi")))]
|
||||
""
|
||||
{
|
||||
rtx inops[4];
|
||||
rtx exops[4][2];
|
||||
rtx lb[1];
|
||||
int i;
|
||||
|
||||
inops[0] = operands[0];
|
||||
inops[1] = operands[1];
|
||||
pdp11_expand_operands (inops, exops, 2, 4, NULL, big);
|
||||
lb[0] = gen_label_rtx ();
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (CONST_INT_P (exops[i][1]) && INTVAL (exops[i][1]) == 0)
|
||||
output_asm_insn ("tst\t%0", exops[i]);
|
||||
else
|
||||
output_asm_insn ("cmp\t%0,%1", exops[i]);
|
||||
output_asm_insn ("bne\t%l0", lb);
|
||||
}
|
||||
if (CONST_INT_P (exops[3][1]) && INTVAL (exops[3][1]) == 0)
|
||||
output_asm_insn ("tst\t%0", exops[3]);
|
||||
else
|
||||
output_asm_insn ("cmp\t%0,%1", exops[3]);
|
||||
output_asm_label (lb[0]);
|
||||
fputs (":\n", asm_out_file);
|
||||
|
||||
return "";
|
||||
}
|
||||
[(set (attr "length")
|
||||
(symbol_ref "pdp11_cmp_length (operands, 2)"))
|
||||
(set_attr "base_cost" "0")])
|
||||
|
||||
;; sob instruction
|
||||
;;
|
||||
;; This expander has to check for mode match because the doloop pass
|
||||
|
@ -368,8 +435,8 @@
|
|||
(define_insn_and_split "cbranch<mode>4"
|
||||
[(set (pc)
|
||||
(if_then_else (match_operator 0 "ordered_comparison_operator"
|
||||
[(match_operand:PDPint 1 "general_operand" "g")
|
||||
(match_operand:PDPint 2 "general_operand" "g")])
|
||||
[(match_operand:QHSDint 1 "general_operand" "g")
|
||||
(match_operand:QHSDint 2 "general_operand" "g")])
|
||||
(label_ref (match_operand 3 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
|
@ -473,12 +540,19 @@
|
|||
"* return output_move_multiple (operands);"
|
||||
[(set_attr "length" "4,6,8,16")])
|
||||
|
||||
;; That long string of "Z" constraints enforces the restriction that
|
||||
;; a register source and auto increment or decrement destination must
|
||||
;; not use the same register, because that case is not consistently
|
||||
;; implemented across the PDP11 models.
|
||||
;; TODO: the same should be applied to insn like add, but this is not
|
||||
;; necessary yet because the incdec optimization pass does not apply
|
||||
;; that optimization to 3-operand insns at the moment.
|
||||
(define_insn "mov<mode>"
|
||||
[(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,rR,Q,Q")
|
||||
(match_operand:PDPint 1 "general_operand" "rRN,Qi,rRN,Qi"))]
|
||||
[(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,Za,Zb,Zc,Zd,Ze,Zf,Zg,rD,rR,Q,Q")
|
||||
(match_operand:PDPint 1 "general_operand" "RN,Z0,Z1,Z2,Z3,Z4,Z5,Z6,r,Qi,rRN,Qi"))]
|
||||
""
|
||||
""
|
||||
[(set_attr "length" "2,4,4,6")])
|
||||
[(set_attr "length" "2,2,2,2,2,2,2,2,2,4,4,6")])
|
||||
|
||||
;; This splits all the integer moves: DI and SI modes as well as
|
||||
;; the simple machine operations.
|
||||
|
@ -493,8 +567,8 @@
|
|||
|
||||
;; MOV clears V
|
||||
(define_insn "*mov<mode>_<cc_cc>"
|
||||
[(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,rR,Q,Q")
|
||||
(match_operand:PDPint 1 "general_operand" "rRN,Qi,rRN,Qi"))
|
||||
[(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,Za,Zb,Zc,Zd,Ze,Zf,Zg,rD,rR,Q,Q")
|
||||
(match_operand:PDPint 1 "general_operand" "RN,Z0,Z1,Z2,Z3,Z4,Z5,Z6,r,Qi,rRN,Qi"))
|
||||
(clobber (reg:CC CC_REGNUM))]
|
||||
"reload_completed"
|
||||
"*
|
||||
|
@ -504,7 +578,7 @@
|
|||
|
||||
return \"mov<PDPint:isfx>\t%1,%0\";
|
||||
}"
|
||||
[(set_attr "length" "2,4,4,6")])
|
||||
[(set_attr "length" "2,2,2,2,2,2,2,2,2,4,4,6")])
|
||||
|
||||
;; movdf has unusually complicated condition code handling, because
|
||||
;; load (into float register) updates the FCC, while store (from
|
||||
|
@ -591,18 +665,98 @@
|
|||
|
||||
;; Expand a block move. We turn this into a move loop.
|
||||
(define_expand "movmemhi"
|
||||
[(match_operand:BLK 0 "general_operand" "=g")
|
||||
(match_operand:BLK 1 "general_operand" "g")
|
||||
(match_operand:HI 2 "immediate_operand" "i")
|
||||
(match_operand:HI 3 "immediate_operand" "i")]
|
||||
[(parallel [(unspec_volatile [(const_int 0)] UNSPECV_MOVMEM)
|
||||
(match_operand:BLK 0 "general_operand" "=g")
|
||||
(match_operand:BLK 1 "general_operand" "g")
|
||||
(match_operand:HI 2 "immediate_operand" "i")
|
||||
(match_operand:HI 3 "immediate_operand" "i")
|
||||
(clobber (mem:BLK (scratch)))
|
||||
(clobber (match_dup 0))
|
||||
(clobber (match_dup 1))
|
||||
(clobber (match_dup 2))])]
|
||||
""
|
||||
"
|
||||
{
|
||||
if (INTVAL (operands[2]) != 0)
|
||||
expand_block_move (operands);
|
||||
DONE;
|
||||
int count;
|
||||
count = INTVAL (operands[2]);
|
||||
if (count == 0)
|
||||
DONE;
|
||||
if (INTVAL (operands [3]) >= 2 && (count & 1) == 0)
|
||||
count >>= 1;
|
||||
else
|
||||
operands[3] = const1_rtx;
|
||||
operands[2] = copy_to_mode_reg (HImode,
|
||||
gen_rtx_CONST_INT (HImode, count));
|
||||
|
||||
/* Load BLKmode MEM addresses into scratch registers. */
|
||||
operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
|
||||
operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
|
||||
}")
|
||||
|
||||
;; Expand a block move. We turn this into a move loop.
|
||||
(define_insn_and_split "movmemhi1"
|
||||
[(unspec_volatile [(const_int 0)] UNSPECV_MOVMEM)
|
||||
(match_operand:HI 0 "register_operand" "+r")
|
||||
(match_operand:HI 1 "register_operand" "+r")
|
||||
(match_operand:HI 2 "register_operand" "+r")
|
||||
(match_operand:HI 3 "immediate_operand" "i")
|
||||
(clobber (mem:BLK (scratch)))
|
||||
(clobber (match_dup 0))
|
||||
(clobber (match_dup 1))
|
||||
(clobber (match_dup 2))]
|
||||
""
|
||||
"#"
|
||||
"reload_completed"
|
||||
[(parallel [(unspec_volatile [(const_int 0)] UNSPECV_MOVMEM)
|
||||
(match_dup 0)
|
||||
(match_dup 1)
|
||||
(match_dup 2)
|
||||
(match_dup 3)
|
||||
(clobber (mem:BLK (scratch)))
|
||||
(clobber (match_dup 0))
|
||||
(clobber (match_dup 1))
|
||||
(clobber (match_dup 2))
|
||||
(clobber (reg:CC CC_REGNUM))])]
|
||||
"")
|
||||
|
||||
(define_insn "movmemhi_nocc"
|
||||
[(unspec_volatile [(const_int 0)] UNSPECV_MOVMEM)
|
||||
(match_operand:HI 0 "register_operand" "+r")
|
||||
(match_operand:HI 1 "register_operand" "+r")
|
||||
(match_operand:HI 2 "register_operand" "+r")
|
||||
(match_operand:HI 3 "immediate_operand" "i")
|
||||
(clobber (mem:BLK (scratch)))
|
||||
(clobber (match_dup 0))
|
||||
(clobber (match_dup 1))
|
||||
(clobber (match_dup 2))
|
||||
(clobber (reg:CC CC_REGNUM))]
|
||||
"reload_completed"
|
||||
"*
|
||||
{
|
||||
rtx lb[2];
|
||||
|
||||
lb[0] = operands[2];
|
||||
lb[1] = gen_label_rtx ();
|
||||
|
||||
output_asm_label (lb[1]);
|
||||
fputs (\":\n\", asm_out_file);
|
||||
if (INTVAL (operands[3]) > 1)
|
||||
output_asm_insn (\"mov\t(%1)+,(%0)+\", operands);
|
||||
else
|
||||
output_asm_insn (\"movb\t(%1)+,(%0)+\", operands);
|
||||
if (TARGET_40_PLUS)
|
||||
output_asm_insn (\"sob\t%0,%l1\", lb);
|
||||
else
|
||||
{
|
||||
output_asm_insn (\"dec\t%0\", lb);
|
||||
output_asm_insn (\"bne\t%l1\", lb);
|
||||
}
|
||||
return \"\";
|
||||
}"
|
||||
[(set (attr "length")
|
||||
(if_then_else (match_test "TARGET_40_PLUS")
|
||||
(const_int 4)
|
||||
(const_int 6)))])
|
||||
|
||||
;;- truncation instructions
|
||||
|
||||
|
@ -659,7 +813,8 @@
|
|||
emit_move_insn (r, const0_rtx);
|
||||
DONE;
|
||||
}
|
||||
else if (!rtx_equal_p (operands[0], operands[1]))
|
||||
else if (!REG_P (operands[1]) ||
|
||||
REGNO (operands[0]) != REGNO (operands[1]))
|
||||
{
|
||||
/* Alternatives 2 and 3 */
|
||||
emit_move_insn (operands[0], const0_rtx);
|
||||
|
@ -975,22 +1130,22 @@
|
|||
|
||||
inops[0] = operands[0];
|
||||
inops[1] = operands[2];
|
||||
pdp11_expand_operands (inops, exops, 2, NULL, either);
|
||||
pdp11_expand_operands (inops, exops, 2, 4, NULL, big);
|
||||
|
||||
if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
|
||||
if (!CONST_INT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
|
||||
output_asm_insn (\"add\t%1,%0\", exops[0]);
|
||||
if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
|
||||
if (!CONST_INT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
|
||||
{
|
||||
output_asm_insn (\"add\t%1,%0\", exops[1]);
|
||||
output_asm_insn (\"adc\t%0\", exops[0]);
|
||||
}
|
||||
if (!CONSTANT_P (exops[2][1]) || INTVAL (exops[2][1]) != 0)
|
||||
if (!CONST_INT_P (exops[2][1]) || INTVAL (exops[2][1]) != 0)
|
||||
{
|
||||
output_asm_insn (\"add\t%1,%0\", exops[2]);
|
||||
output_asm_insn (\"adc\t%0\", exops[1]);
|
||||
output_asm_insn (\"adc\t%0\", exops[0]);
|
||||
}
|
||||
if (!CONSTANT_P (exops[3][1]) || INTVAL (exops[3][1]) != 0)
|
||||
if (!CONST_INT_P (exops[3][1]) || INTVAL (exops[3][1]) != 0)
|
||||
{
|
||||
output_asm_insn (\"add\t%1,%0\", exops[3]);
|
||||
output_asm_insn (\"adc\t%0\", exops[2]);
|
||||
|
@ -1037,11 +1192,11 @@
|
|||
|
||||
inops[0] = operands[0];
|
||||
inops[1] = operands[2];
|
||||
pdp11_expand_operands (inops, exops, 2, NULL, either);
|
||||
pdp11_expand_operands (inops, exops, 2, 2, NULL, big);
|
||||
|
||||
if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
|
||||
if (!CONST_INT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
|
||||
output_asm_insn (\"add\t%1,%0\", exops[0]);
|
||||
if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
|
||||
if (!CONST_INT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
|
||||
{
|
||||
output_asm_insn (\"add\t%1,%0\", exops[1]);
|
||||
output_asm_insn (\"adc\t%0\", exops[0]);
|
||||
|
@ -1169,22 +1324,22 @@
|
|||
|
||||
inops[0] = operands[0];
|
||||
inops[1] = operands[2];
|
||||
pdp11_expand_operands (inops, exops, 2, NULL, either);
|
||||
pdp11_expand_operands (inops, exops, 2, 4, NULL, big);
|
||||
|
||||
if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
|
||||
if (!CONST_INT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
|
||||
output_asm_insn (\"sub\t%1,%0\", exops[0]);
|
||||
if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
|
||||
if (!CONST_INT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
|
||||
{
|
||||
output_asm_insn (\"sub\t%1,%0\", exops[1]);
|
||||
output_asm_insn (\"sbc\t%0\", exops[0]);
|
||||
}
|
||||
if (!CONSTANT_P (exops[2][1]) || INTVAL (exops[2][1]) != 0)
|
||||
if (!CONST_INT_P (exops[2][1]) || INTVAL (exops[2][1]) != 0)
|
||||
{
|
||||
output_asm_insn (\"sub\t%1,%0\", exops[2]);
|
||||
output_asm_insn (\"sbc\t%0\", exops[1]);
|
||||
output_asm_insn (\"sbc\t%0\", exops[0]);
|
||||
}
|
||||
if (!CONSTANT_P (exops[3][1]) || INTVAL (exops[3][1]) != 0)
|
||||
if (!CONST_INT_P (exops[3][1]) || INTVAL (exops[3][1]) != 0)
|
||||
{
|
||||
output_asm_insn (\"sub\t%1,%0\", exops[3]);
|
||||
output_asm_insn (\"sbc\t%0\", exops[2]);
|
||||
|
@ -1222,11 +1377,11 @@
|
|||
|
||||
inops[0] = operands[0];
|
||||
inops[1] = operands[2];
|
||||
pdp11_expand_operands (inops, exops, 2, NULL, either);
|
||||
pdp11_expand_operands (inops, exops, 2, 2, NULL, big);
|
||||
|
||||
if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
|
||||
if (!CONST_INT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
|
||||
output_asm_insn (\"sub\t%1,%0\", exops[0]);
|
||||
if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
|
||||
if (!CONST_INT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
|
||||
{
|
||||
output_asm_insn (\"sub\t%1,%0\", exops[1]);
|
||||
output_asm_insn (\"sbc\t%0\", exops[0]);
|
||||
|
@ -1702,9 +1857,11 @@
|
|||
(clobber (reg:CC CC_REGNUM))]
|
||||
"reload_completed"
|
||||
{
|
||||
rtx inops[2];
|
||||
rtx exops[4][2];
|
||||
|
||||
pdp11_expand_operands (operands, exops, 1, NULL, either);
|
||||
|
||||
inops[0] = operands[0];
|
||||
pdp11_expand_operands (inops, exops, 1, 4, NULL, big);
|
||||
|
||||
output_asm_insn (\"com\t%0\", exops[3]);
|
||||
output_asm_insn (\"com\t%0\", exops[2]);
|
||||
|
@ -1738,9 +1895,11 @@
|
|||
(clobber (reg:CC CC_REGNUM))]
|
||||
"reload_completed"
|
||||
{
|
||||
rtx exops[2][2];
|
||||
|
||||
pdp11_expand_operands (operands, exops, 1, NULL, either);
|
||||
rtx inops[2];
|
||||
rtx exops[4][2];
|
||||
|
||||
inops[0] = operands[0];
|
||||
pdp11_expand_operands (inops, exops, 1, 2, NULL, big);
|
||||
|
||||
output_asm_insn (\"com\t%0\", exops[1]);
|
||||
output_asm_insn (\"com\t%0\", exops[0]);
|
||||
|
@ -2046,10 +2205,13 @@
|
|||
(clobber (reg:CC CC_REGNUM))]
|
||||
""
|
||||
{
|
||||
rtx inops[2];
|
||||
rtx exops[2][2];
|
||||
rtx t;
|
||||
|
||||
pdp11_expand_operands (operands, exops, 2, NULL, either);
|
||||
|
||||
inops[0] = operands[0];
|
||||
inops[1] = operands[1];
|
||||
pdp11_expand_operands (inops, exops, 2, 2, NULL, either);
|
||||
|
||||
t = exops[0][0];
|
||||
exops[0][0] = exops[1][0];
|
||||
|
|
|
@ -68,4 +68,4 @@ Use UNIX assembler syntax.
|
|||
|
||||
mlra
|
||||
Target Report Mask(LRA)
|
||||
Use LRA register allocator
|
||||
Use LRA register allocator.
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
|
||||
MULTILIB_OPTIONS = msoft-float
|
||||
|
||||
# Optimize for space
|
||||
LIBGCC2_CFLAGS = -Os
|
||||
CRTSTUFF_T_CFLAGS = -Os
|
||||
|
||||
# Because the pdp11 POINTER_SIZE is only 16, in dwarf2out.c,
|
||||
# DWARF_ARANGES_PAD_SIZE is 0, thus a loop in output_aranges that checks
|
||||
# (i < (unsigned) DWARF_ARANGES_PAD_SIZE) elicits a warning that the
|
||||
|
|
|
@ -14115,7 +14115,7 @@ information on callsites that were inlined, along with callsites
|
|||
that were not inlined.
|
||||
|
||||
By default, the dump will contain messages about successful
|
||||
optimizations (equivalent to @option {-optimized}) together with
|
||||
optimizations (equivalent to @option{-optimized}) together with
|
||||
low-level details about the analysis.
|
||||
|
||||
@item -fdump-lang-all
|
||||
|
|
|
@ -1,3 +1,345 @@
|
|||
2018-11-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* testsuite/libgomp.c-c++-common/task-reduction-8.c (bar): Add
|
||||
in_reduction clause for s[0].
|
||||
|
||||
* affinity.c (gomp_display_affinity_place): New function.
|
||||
* affinity-fmt.c: New file.
|
||||
* alloc.c (gomp_aligned_alloc, gomp_aligned_free): New functions.
|
||||
* config/linux/affinity.c (gomp_display_affinity_place): New function.
|
||||
* config/nvptx/icv-device.c (omp_get_num_teams, omp_get_team_num):
|
||||
Move these functions to ...
|
||||
* config/nvptx/teams.c: ... here. New file.
|
||||
* config/nvptx/target.c (omp_pause_resource, omp_pause_resource_all):
|
||||
New functions.
|
||||
* config/nvptx/team.c (gomp_team_start, gomp_pause_host): New
|
||||
functions.
|
||||
* configure.ac: Check for aligned_alloc, posix_memalign, memalign
|
||||
and _aligned_malloc.
|
||||
(HAVE_UNAME, HAVE_GETHOSTNAME, HAVE_GETPID): Add new tests.
|
||||
* configure.tgt: Add -DUSING_INITIAL_EXEC_TLS to XCFLAGS for Linux.
|
||||
* env.c (gomp_display_affinity_var, gomp_affinity_format_var,
|
||||
gomp_affinity_format_len): New variables.
|
||||
(parse_schedule): Parse monotonic and nonmonotonic modifiers in
|
||||
OMP_SCHEDULE variable. Set GFS_MONOTONIC for monotonic schedules.
|
||||
(handle_omp_display_env): Display monotonic/nonmonotonic schedule
|
||||
modifiers. Display (non-default) chunk sizes. Print
|
||||
OMP_DISPLAY_AFFINITY and OMP_AFFINITY_FORMAT.
|
||||
(initialize_env): Don't call pthread_attr_setdetachstate. Handle
|
||||
OMP_DISPLAY_AFFINITY and OMP_AFFINITY_FORMAT env vars.
|
||||
* fortran.c: Include stdio.h and string.h.
|
||||
(omp_pause_resource, omp_pause_resource_all): Add ialias_redirect.
|
||||
(omp_get_schedule_, omp_get_schedule_8_): Mask off GFS_MONOTONIC bit.
|
||||
(omp_set_affinity_format_, omp_get_affinity_format_,
|
||||
omp_display_affinity_, omp_capture_affinity_, omp_pause_resource_,
|
||||
omp_pause_resource_all_): New functions.
|
||||
* icv.c (omp_set_schedule): Mask off omp_sched_monotonic bit in
|
||||
switch.
|
||||
* icv-device.c (omp_get_num_teams, omp_get_team_num): Move these
|
||||
functions to ...
|
||||
* teams.c: ... here. New file.
|
||||
* libgomp_g.h: Include gstdint.h.
|
||||
(GOMP_loop_nonmonotonic_runtime_start,
|
||||
GOMP_loop_maybe_nonmonotonic_runtime_start, GOMP_loop_start,
|
||||
GOMP_loop_ordered_start, GOMP_loop_nonmonotonic_runtime_next,
|
||||
GOMP_loop_maybe_nonmonotonic_runtime_next, GOMP_loop_doacross_start,
|
||||
GOMP_parallel_loop_nonmonotonic_runtime,
|
||||
GOMP_parallel_loop_maybe_nonmonotonic_runtime,
|
||||
GOMP_loop_ull_nonmonotonic_runtime_start,
|
||||
GOMP_loop_ull_maybe_nonmonotonic_runtime_start, GOMP_loop_ull_start,
|
||||
GOMP_loop_ull_ordered_start, GOMP_loop_ull_nonmonotonic_runtime_next,
|
||||
GOMP_loop_ull_maybe_nonmonotonic_runtime_next,
|
||||
GOMP_loop_ull_doacross_start, GOMP_parallel_reductions,
|
||||
GOMP_taskwait_depend, GOMP_taskgroup_reduction_register,
|
||||
GOMP_taskgroup_reduction_unregister, GOMP_task_reduction_remap,
|
||||
GOMP_workshare_task_reduction_unregister, GOMP_sections2_start,
|
||||
GOMP_teams_reg): Declare.
|
||||
* libgomp.h (GOMP_HAVE_EFFICIENT_ALIGNED_ALLOC): Define unless
|
||||
gomp_aligned_alloc uses fallback implementation.
|
||||
(gomp_aligned_alloc, gomp_aligned_free): Declare.
|
||||
(enum gomp_schedule_type): Add GFS_MONOTONIC.
|
||||
(struct gomp_doacross_work_share): Add extra field.
|
||||
(struct gomp_work_share): Add task_reductions field.
|
||||
(struct gomp_taskgroup): Add workshare and reductions fields.
|
||||
(GOMP_NEEDS_THREAD_HANDLE): Define if needed.
|
||||
(gomp_thread_handle): New typedef.
|
||||
(gomp_display_affinity_place, gomp_set_affinity_format,
|
||||
gomp_display_string, gomp_display_affinity,
|
||||
gomp_display_affinity_thread): Declare.
|
||||
(gomp_doacross_init, gomp_doacross_ull_init): Add size_t argument.
|
||||
(gomp_parallel_reduction_register, gomp_workshare_taskgroup_start,
|
||||
gomp_workshare_task_reduction_register): Declare.
|
||||
(gomp_team_start): Add taskgroup argument.
|
||||
(gomp_pause_host): Declare.
|
||||
(gomp_init_work_share, gomp_work_share_start): Change bool argument
|
||||
to size_t.
|
||||
(gomp_thread_self, gomp_thread_to_pthread_t): New inline functions.
|
||||
* libgomp.map (GOMP_5.0): Export GOMP_loop_start,
|
||||
GOMP_loop_ordered_start, GOMP_loop_doacross_start,
|
||||
GOMP_loop_ull_start, GOMP_loop_ull_ordered_start,
|
||||
GOMP_loop_ull_doacross_start,
|
||||
GOMP_workshare_task_reduction_unregister, GOMP_sections2_start,
|
||||
GOMP_loop_maybe_nonmonotonic_runtime_next,
|
||||
GOMP_loop_maybe_nonmonotonic_runtime_start,
|
||||
GOMP_loop_nonmonotonic_runtime_next,
|
||||
GOMP_loop_nonmonotonic_runtime_start,
|
||||
GOMP_loop_ull_maybe_nonmonotonic_runtime_next,
|
||||
GOMP_loop_ull_maybe_nonmonotonic_runtime_start,
|
||||
GOMP_loop_ull_nonmonotonic_runtime_next,
|
||||
GOMP_loop_ull_nonmonotonic_runtime_start,
|
||||
GOMP_parallel_loop_maybe_nonmonotonic_runtime,
|
||||
GOMP_parallel_loop_nonmonotonic_runtime, GOMP_parallel_reductions,
|
||||
GOMP_taskgroup_reduction_register,
|
||||
GOMP_taskgroup_reduction_unregister, GOMP_task_reduction_remap,
|
||||
GOMP_teams_reg and GOMP_taskwait_depend.
|
||||
(OMP_5.0): Export omp_pause_resource{,_all}{,_},
|
||||
omp_{capture,display}_affinity{,_}, and
|
||||
omp_[gs]et_affinity_format{,_}.
|
||||
* loop.c: Include string.h.
|
||||
(GOMP_loop_runtime_next): Add ialias.
|
||||
(GOMP_taskgroup_reduction_register): Add ialias_redirect.
|
||||
(gomp_loop_static_start, gomp_loop_dynamic_start,
|
||||
gomp_loop_guided_start, gomp_loop_ordered_static_start,
|
||||
gomp_loop_ordered_dynamic_start, gomp_loop_ordered_guided_start,
|
||||
gomp_loop_doacross_static_start, gomp_loop_doacross_dynamic_start,
|
||||
gomp_loop_doacross_guided_start): Adjust gomp_work_share_start
|
||||
or gomp_doacross_init callers.
|
||||
(gomp_adjust_sched, GOMP_loop_start, GOMP_loop_ordered_start,
|
||||
GOMP_loop_doacross_start): New functions.
|
||||
(GOMP_loop_runtime_start, GOMP_loop_ordered_runtime_start,
|
||||
GOMP_loop_doacross_runtime_start, GOMP_parallel_loop_runtime_start):
|
||||
Mask off GFS_MONOTONIC bit.
|
||||
(GOMP_loop_maybe_nonmonotonic_runtime_next,
|
||||
GOMP_loop_maybe_nonmonotonic_runtime_start,
|
||||
GOMP_loop_nonmonotonic_runtime_next,
|
||||
GOMP_loop_nonmonotonic_runtime_start,
|
||||
GOMP_parallel_loop_maybe_nonmonotonic_runtime,
|
||||
GOMP_parallel_loop_nonmonotonic_runtime): New aliases or wrapper
|
||||
functions.
|
||||
(gomp_parallel_loop_start): Pass NULL as taskgroup to
|
||||
gomp_team_start.
|
||||
* loop_ull.c: Include string.h.
|
||||
(GOMP_loop_ull_runtime_next): Add ialias.
|
||||
(GOMP_taskgroup_reduction_register): Add ialias_redirect.
|
||||
(gomp_loop_ull_static_start, gomp_loop_ull_dynamic_start,
|
||||
gomp_loop_ull_guided_start, gomp_loop_ull_ordered_static_start,
|
||||
gomp_loop_ull_ordered_dynamic_start,
|
||||
gomp_loop_ull_ordered_guided_start,
|
||||
gomp_loop_ull_doacross_static_start,
|
||||
gomp_loop_ull_doacross_dynamic_start,
|
||||
gomp_loop_ull_doacross_guided_start): Adjust gomp_work_share_start
|
||||
and gomp_doacross_ull_init callers.
|
||||
(gomp_adjust_sched, GOMP_loop_ull_start, GOMP_loop_ull_ordered_start,
|
||||
GOMP_loop_ull_doacross_start): New functions.
|
||||
(GOMP_loop_ull_runtime_start,
|
||||
GOMP_loop_ull_ordered_runtime_start,
|
||||
GOMP_loop_ull_doacross_runtime_start): Mask off GFS_MONOTONIC bit.
|
||||
(GOMP_loop_ull_maybe_nonmonotonic_runtime_next,
|
||||
GOMP_loop_ull_maybe_nonmonotonic_runtime_start,
|
||||
GOMP_loop_ull_nonmonotonic_runtime_next,
|
||||
GOMP_loop_ull_nonmonotonic_runtime_start): Likewise.
|
||||
* Makefile.am (libgomp_la_SOURCES): Add teams.c and affinity-fmt.c.
|
||||
* omp.h.in (enum omp_sched_t): Add omp_sched_monotonic.
|
||||
(omp_pause_resource_t, omp_depend_t): New typedefs.
|
||||
(enum omp_lock_hint_t): Renamed to ...
|
||||
(enum omp_sync_hint_t): ... this. Define omp_sync_hint_*
|
||||
enumerators using numbers and omp_lock_hint_* as their aliases.
|
||||
(omp_lock_hint_t): New typedef. Rename to ...
|
||||
(omp_sync_hint_t): ... this.
|
||||
(omp_init_lock_with_hint, omp_init_nest_lock_with_hint): Use
|
||||
omp_sync_hint_t instead of omp_lock_hint_t.
|
||||
(omp_pause_resource, omp_pause_resource_all, omp_set_affinity_format,
|
||||
omp_get_affinity_format, omp_display_affinity, omp_capture_affinity):
|
||||
Declare.
|
||||
(omp_target_is_present, omp_target_disassociate_ptr):
|
||||
Change first argument from void * to const void *.
|
||||
(omp_target_memcpy, omp_target_memcpy_rect): Change second argument
|
||||
from void * to const void *.
|
||||
(omp_target_associate_ptr): Change first and second arguments from
|
||||
void * to const void *.
|
||||
* omp_lib.f90.in (omp_pause_resource_kind, omp_pause_soft,
|
||||
omp_pause_hard): New parameters.
|
||||
(omp_pause_resource, omp_pause_resource_all, omp_set_affinity_format,
|
||||
omp_get_affinity_format, omp_display_affinity, omp_capture_affinity):
|
||||
New interfaces.
|
||||
* omp_lib.h.in (omp_pause_resource_kind, omp_pause_soft,
|
||||
omp_pause_hard): New parameters.
|
||||
(omp_pause_resource, omp_pause_resource_all, omp_set_affinity_format,
|
||||
omp_get_affinity_format, omp_display_affinity, omp_capture_affinity):
|
||||
New externals.
|
||||
* ordered.c (gomp_doacross_init, gomp_doacross_ull_init): Add
|
||||
EXTRA argument. If not needed to prepare array, if extra is 0,
|
||||
clear ws->doacross, otherwise allocate just doacross structure and
|
||||
extra payload. If array is needed, allocate also extra payload.
|
||||
(GOMP_doacross_post, GOMP_doacross_wait, GOMP_doacross_ull_post,
|
||||
GOMP_doacross_ull_wait): Handle doacross->array == NULL like
|
||||
doacross == NULL.
|
||||
* parallel.c (GOMP_parallel_start): Pass NULL as taskgroup to
|
||||
gomp_team_start.
|
||||
(GOMP_parallel): Likewise. Formatting fix.
|
||||
(GOMP_parallel_reductions): New function.
|
||||
(GOMP_cancellation_point): If taskgroup has workshare
|
||||
flag set, check cancelled of prev taskgroup if any.
|
||||
(GOMP_cancel): If taskgroup has workshare flag set, set cancelled
|
||||
on prev taskgroup if any.
|
||||
* sections.c: Include string.h.
|
||||
(GOMP_taskgroup_reduction_register): Add ialias_redirect.
|
||||
(GOMP_sections_start): Adjust gomp_work_share_start caller.
|
||||
(GOMP_sections2_start): New function.
|
||||
(GOMP_parallel_sections_start, GOMP_parallel_sections):
|
||||
Pass NULL as taskgroup to gomp_team_start.
|
||||
* single.c (GOMP_single_start, GOMP_single_copy_start): Adjust
|
||||
gomp_work_share_start callers.
|
||||
* target.c (GOMP_target_update_ext, GOMP_target_enter_exit_data):
|
||||
If taskgroup has workshare flag set, check cancelled on prev
|
||||
taskgroup if any. Guard all cancellation tests with
|
||||
gomp_cancel_var test.
|
||||
(omp_target_is_present, omp_target_disassociate_ptr):
|
||||
Change ptr argument from void * to const void *.
|
||||
(omp_target_memcpy): Change src argument from void * to const void *.
|
||||
(omp_target_memcpy_rect): Likewise.
|
||||
(omp_target_memcpy_rect_worker): Likewise. Use const char * casts
|
||||
instead of char * where needed.
|
||||
(omp_target_associate_ptr): Change host_ptr and device_ptr arguments
|
||||
from void * to const void *.
|
||||
(omp_pause_resource, omp_pause_resource_all): New functions.
|
||||
* task.c (gomp_task_handle_depend): Handle new depend array format
|
||||
in addition to the old. Handle mutexinoutset kinds the same as
|
||||
inout for now, handle unspecified kinds.
|
||||
(gomp_create_target_task): If taskgroup has workshare flag set, check
|
||||
cancelled on prev taskgroup if any. Guard all cancellation tests with
|
||||
gomp_cancel_var test. Handle new depend array format count in
|
||||
addition to the old.
|
||||
(GOMP_task): Likewise. Adjust function comment.
|
||||
(gomp_task_run_pre): If taskgroup has workshare flag set, check
|
||||
cancelled on prev taskgroup if any. Guard all cancellation tests with
|
||||
gomp_cancel_var test.
|
||||
(GOMP_taskwait_depend): New function.
|
||||
(gomp_task_maybe_wait_for_dependencies): Handle new depend array
|
||||
format in addition to the old. Handle mutexinoutset kinds the same as
|
||||
inout for now, handle unspecified kinds. Fix a function comment typo.
|
||||
(gomp_taskgroup_init): New function.
|
||||
(GOMP_taskgroup_start): Use it.
|
||||
(gomp_reduction_register, gomp_create_artificial_team,
|
||||
GOMP_taskgroup_reduction_register,
|
||||
GOMP_taskgroup_reduction_unregister, GOMP_task_reduction_remap,
|
||||
gomp_parallel_reduction_register,
|
||||
gomp_workshare_task_reduction_register,
|
||||
gomp_workshare_taskgroup_start,
|
||||
GOMP_workshare_task_reduction_unregister): New functions.
|
||||
* taskloop.c (GOMP_taskloop): If taskgroup has workshare flag set,
|
||||
check cancelled on prev taskgroup if any. Guard all cancellation
|
||||
tests with gomp_cancel_var test. Handle GOMP_TASK_FLAG_REDUCTION flag
|
||||
by calling GOMP_taskgroup_reduction_register.
|
||||
* team.c (gomp_thread_attr): Remove comment.
|
||||
(struct gomp_thread_start_data): Add handle field.
|
||||
(gomp_thread_start): Call pthread_detach.
|
||||
(gomp_new_team): Adjust gomp_init_work_share caller.
|
||||
(gomp_free_pool_helper): Call pthread_detach.
|
||||
(gomp_team_start): Add taskgroup argument, initialize implicit
|
||||
tasks' taskgroup field to that. Don't call
|
||||
pthread_attr_setdetachstate. Handle OMP_DISPLAY_AFFINITY env var.
|
||||
(gomp_team_end): Determine nesting by thr->ts.level != 0
|
||||
rather than thr->ts.team != NULL.
|
||||
(gomp_pause_pool_helper, gomp_pause_host): New functions.
|
||||
* work.c (alloc_work_share): Use gomp_aligned_alloc instead of
|
||||
gomp_malloc if GOMP_HAVE_EFFICIENT_ALIGNED_ALLOC is defined.
|
||||
(gomp_init_work_share): Change ORDERED argument from bool to size_t,
|
||||
if more than 1 allocate also extra payload at the end of array. Never
|
||||
keep ordered_team_ids NULL, set it to inline_ordered_team_ids instead.
|
||||
(gomp_work_share_start): Change ORDERED argument from bool to size_t,
|
||||
return true instead of ws.
|
||||
* Makefile.in: Regenerated.
|
||||
* configure: Regenerated.
|
||||
* config.h.in: Regenerated.
|
||||
* testsuite/libgomp.c/cancel-for-2.c (foo): Use cancel modifier
|
||||
in some cases.
|
||||
* testsuite/libgomp.c-c++-common/cancel-parallel-1.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/cancel-taskgroup-3.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/depend-iterator-1.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/depend-iterator-2.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/depend-mutexinout-1.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/depend-mutexinout-2.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/depobj-1.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/display-affinity-1.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/for-10.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/for-11.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/for-12.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/for-13.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/for-14.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/for-15.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/for-2.h: If CONDNE macro is defined,
|
||||
define a different N(test), don't define N(f0) to N(f14), but instead
|
||||
define N(f20) to N(f34) using != comparisons.
|
||||
* testsuite/libgomp.c-c++-common/for-7.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/for-8.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/for-9.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/master-combined-1.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/pause-1.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/pause-2.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/pr66199-10.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/pr66199-11.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/pr66199-12.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/pr66199-13.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/pr66199-14.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/simd-1.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/taskloop-reduction-1.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/taskloop-reduction-2.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/taskloop-reduction-3.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/taskloop-reduction-4.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/task-reduction-11.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/task-reduction-12.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/task-reduction-1.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/task-reduction-2.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/task-reduction-3.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/task-reduction-4.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/task-reduction-5.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/task-reduction-6.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/task-reduction-7.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/task-reduction-8.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/task-reduction-9.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/taskwait-depend-1.c: New test.
|
||||
* testsuite/libgomp.c++/depend-1.C: New test.
|
||||
* testsuite/libgomp.c++/depend-iterator-1.C: New test.
|
||||
* testsuite/libgomp.c++/depobj-1.C: New test.
|
||||
* testsuite/libgomp.c++/for-16.C: New test.
|
||||
* testsuite/libgomp.c++/for-21.C: New test.
|
||||
* testsuite/libgomp.c++/for-22.C: New test.
|
||||
* testsuite/libgomp.c++/for-23.C: New test.
|
||||
* testsuite/libgomp.c++/for-24.C: New test.
|
||||
* testsuite/libgomp.c++/for-25.C: New test.
|
||||
* testsuite/libgomp.c++/for-26.C: New test.
|
||||
* testsuite/libgomp.c++/taskloop-reduction-1.C: New test.
|
||||
* testsuite/libgomp.c++/taskloop-reduction-2.C: New test.
|
||||
* testsuite/libgomp.c++/taskloop-reduction-3.C: New test.
|
||||
* testsuite/libgomp.c++/taskloop-reduction-4.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-10.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-11.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-12.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-13.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-14.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-15.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-16.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-17.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-18.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-19.C: New test.
|
||||
* testsuite/libgomp.c/task-reduction-1.c: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-1.C: New test.
|
||||
* testsuite/libgomp.c/task-reduction-2.c: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-2.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-3.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-4.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-5.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-6.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-7.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-8.C: New test.
|
||||
* testsuite/libgomp.c++/task-reduction-9.C: New test.
|
||||
* testsuite/libgomp.c/teams-1.c: New test.
|
||||
* testsuite/libgomp.c/teams-2.c: New test.
|
||||
* testsuite/libgomp.c/thread-limit-4.c: New test.
|
||||
* testsuite/libgomp.c/thread-limit-5.c: New test.
|
||||
* testsuite/libgomp.fortran/display-affinity-1.f90: New test.
|
||||
|
||||
2018-11-06 Chung-Lin Tang <cltang@codesourcery.com>
|
||||
|
||||
* oacc-mem.c (memcpy_tofrom_device): New function, combined from
|
||||
|
|
|
@ -45,7 +45,8 @@ unsigned long long int
|
|||
bar (int z, int *a, unsigned long long int *b, int *s)
|
||||
{
|
||||
unsigned long long int x = 1;
|
||||
#pragma omp taskloop reduction (*:x) in_reduction (*:b[0])
|
||||
#pragma omp taskloop reduction (*:x) in_reduction (*:b[0]) \
|
||||
in_reduction (+:s[0])
|
||||
for (int i = z; i < z + 8; i++)
|
||||
{
|
||||
#pragma omp task in_reduction (*:x)
|
||||
|
|
Loading…
Reference in New Issue