]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
svn merge -r265930:265934 svn+ssh://gcc.gnu.org/svn/gcc/trunk devel/gomp-5_0-branch
authorJakub Jelinek <jakub@gcc.gnu.org>
Thu, 8 Nov 2018 21:07:23 +0000 (22:07 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 8 Nov 2018 21:07:23 +0000 (22:07 +0100)
From-SVN: r265937

18 files changed:
gcc/ChangeLog
gcc/common/config/arm/arm-common.c
gcc/config/arm/arm-cpus.in
gcc/config/arm/arm-generic.md
gcc/config/arm/arm-protos.h
gcc/config/arm/arm-tables.opt
gcc/config/arm/arm-tune.md
gcc/config/arm/parsecpu.awk
gcc/config/pdp11/constraints.md
gcc/config/pdp11/pdp11-protos.h
gcc/config/pdp11/pdp11.c
gcc/config/pdp11/pdp11.h
gcc/config/pdp11/pdp11.md
gcc/config/pdp11/pdp11.opt
gcc/config/pdp11/t-pdp11
gcc/doc/invoke.texi
libgomp/ChangeLog
libgomp/testsuite/libgomp.c-c++-common/task-reduction-8.c

index c3e77f3e27e5ff657263e8d599a28ebf558a3eff..e131f6243d859aa8d3647e845434d116eab523bd 100644 (file)
@@ -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
index 76c357b4258b68d0c2cd78cb54819c280d50963a..32cf36e94f62db7bf5df542c27be5c341a61705c 100644 (file)
@@ -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)
index b3163a90260c66a8df18d00282443434dee96e15..1def1cace68e446c56e6e313ba9c0587d012b64f 100644 (file)
@@ -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
index 81200fa499ac92a3610b35d6018e2967101818da..da97303c7587f4b39042b14999a30299e3ab381d 100644 (file)
 (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")
 (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")
index cea98669111d318954e9f6102db74172e675304b..8d6d2395b84c1fd9c64912db3eacc95424f71172 100644 (file)
@@ -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;
 };
index ceac4b4be419c9bd27db281e9880948ff5c40d76..cd496366cec73f6ce95346dd057c71e5523741ef 100644 (file)
@@ -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)
 
index 2bd7e8741166af43f606cee1eb2cc3a0c712af29..bbe09cf466c53bc32d3a3c75611cb0856a62d32b 100644 (file)
@@ -22,7 +22,6 @@
 
 (define_attr "tune"
        "arm8,arm810,strongarm,
-       strongarm110,strongarm1100,strongarm1110,
        fa526,fa626,arm7tdmi,
        arm7tdmis,arm710t,arm720t,
        arm740t,arm9,arm9tdmi,
index aabe1b0c64c814011fb41066e73d702b1847f188..ba2dee5fdcb40bd7f7fe1ee65f7ef4c460355b0c 100644 (file)
@@ -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 != "") {
index 33882ed034ec4ba6c2453d977903011837126b25..d821af3d7fed2d8f1fff16ed8bb699a797af3bc4 100644 (file)
        (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)"))
+  
index 0ed61ea6106fe4037eac7a3a33f095723dfac850..135d437a2eee43304995fb101747eb2d8ee7340c 100644 (file)
@@ -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 */
index 06129f1d2d9db5257845cfc9beac55bcbec86ec5..0019efe39f1a67608c20f88757f68d1a73ce56ee 100644 (file)
@@ -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
 \f
 /* 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);
       }
-}
-
-/* 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!
+  if (frame_pointer_needed)
+    emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
 
-   switching to kernel is probably more expensive, so we'll leave it 
-   like this and not use the second set of registers... 
+  /* Make local variable space.  */
+  if (fsize)
+    emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
+                          GEN_INT (-fsize)));
+}
 
-   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.  */
-
-      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
-             {
-               emit_move_insn (via_ac, x);
-               emit_move_insn (reg, via_ac);
-             }
-         }
+  /* Restore registers via pops.  */
 
-      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.
-
-        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 = 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);
 
-      for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--)
-       if (pdp11_saved_regno (regno)
-           && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
+       if (LOAD_FPU_REG_P (regno))
+         emit_move_insn (reg, x);
+       else
          {
-           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;
+           emit_move_insn (via_ac, x);
+           emit_move_insn (reg, via_ac);
          }
-    }
-
-  /* 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);
-    }
+  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);
+      }
 
-  emit_jump_insn (gen_return ());
+  emit_jump_insn (gen_rtspc ());
 }
 
 /* Return the best assembler insn template
@@ -539,21 +461,23 @@ singlemove_string (rtx *operands)
 
 \f
 /* 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;
-
-    /* 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));
+  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);
 
-    /* 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
index d65d8f5b8a241bff66816bbd309c01130ac1137c..92c237b3b7e65799710cc516e0b42c2adc0ef8e4 100644 (file)
@@ -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):      \
-                                                                     \
-)
+  (CPU_REG_CLASS (CLASS) ?     \
+   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD):     \
+   1                                                                   \
+  )
 \f
 /* 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.  */
 
index 773715d7030e9357ef2b4821450d3ea43495ccdc..fc5efc7939013d3be9982f827aee653b31678ab7 100644 (file)
@@ -26,6 +26,7 @@
     UNSPECV_BLOCKAGE
     UNSPECV_SETD
     UNSPECV_SETI
+    UNSPECV_MOVMEM
   ])
 
 (define_constants
    ;; 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
   DONE;
 })
 
-(define_expand "return"
-  [(return)]
-  "reload_completed && !frame_pointer_needed && pdp11_sp_frame_offset () == 0"
-  "")
-
-(define_insn "*rts"
+(define_insn "rtspc"
   [(return)]
   ""
   "rts\tpc")
    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
 (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)))]
   ""
   "* 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.
   
 ;; 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"
   "*
 
   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
 
 ;; 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)))])
 \f
 ;;- truncation instructions
 
         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);
   
   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]);
   
   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]);
   
   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]);
   
   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]);
    (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]);
    (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]);
    (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];
index 5da3b39569c74de7139335c5b2761231bef6cc41..79fca28b665cd015d0b766e0e71d830e87edf95c 100644 (file)
@@ -68,4 +68,4 @@ Use UNIX assembler syntax.
 
 mlra
 Target Report Mask(LRA)
-Use LRA register allocator
+Use LRA register allocator.
index ab01bff73fa7d940834bd4a1ff6a6346b4fe42ec..467d2284b202cf208c3407df6644dfce4ae15e8b 100644 (file)
 
 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
index 24136eb5cc747871a16a4cad1d21a8edcec5932b..4ff3a1505af517d531a2860674bbfe9e05b13709 100644 (file)
@@ -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
index 81bfc77a0e0fe89e39f4a5ebd0d449a0ccb1fb5a..636cb4992efb26ca5ed70822bc7f91a5e52d7c66 100644 (file)
@@ -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
index 7b0859db6f01a1b12f7ab8926627f23e7457a23a..52d238a5b15a63b430a55898226dd51f96d56bb1 100644 (file)
@@ -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)