From 9bb86f4147d6827f4fb1c70a4fda7c118e527471 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 5 Oct 2004 14:06:25 +0000 Subject: [PATCH] s390.c (s390_dump_pool): Remove return value. * config/s390/s390.c (s390_dump_pool): Remove return value. Use gen_pool_align, gen_pool_section_start/end instead of gen_pool_start/end_31/64. * config/s390/s390.md (UNSPECV_POOL_START, UNSPECV_POOL_END): Remove. (UNSPECV_POOL_SECTION, UNSPECV_POOL_ALIGN): New constants. ("pool_start_31", "pool_end_31"): Remove. ("pool_start_64", "pool_end_64"): Likewise. ("pool_align", "pool_section_start", "pool_section_end": New insns. * config/s390/s390.c (s390_cannot_copy_insn_p): New function. (TARGET_CANNOT_COPY_INSN_P): Define. (s390_cannot_force_const_mem): Handle UNSPEC_INSN. (struct constant_pool): New member 'execute'. (s390_add_execute, s390_find_execute): New functions. (s390_execute_label, s390_execute_target): Likewise. (s390_dump_pool): Output in-pool execute target templates. (s390_dump_execute): New function. (s390_alloc_pool, s390_free_pool): Handle execute templates. (s390_mainpool_start, s390_mainpool_finish): Likewise. (s390_chunkify_start, s390_chunkify_finish): Likewise. * config/s390/s390.md (UNSPEC_INSN, UNSPEC_EXECUTE): New constants. ("*execute"): New insn pattern. ("movmem_short", "*movmem_short"): Use splitters to generate explicit execute pattern, remove embedded execute. ("clrmem_short", "*clrmem_short"): Likewise. ("cmpmem_short", "*cmpmem_short"): Likewise. From-SVN: r88555 --- gcc/ChangeLog | 29 ++++ gcc/config/s390/s390.c | 241 +++++++++++++++++++++++++++---- gcc/config/s390/s390.md | 308 ++++++++++++++++++++++++++++------------ 3 files changed, 460 insertions(+), 118 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 63c93cedd23f..82a9ad6f9ad6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,32 @@ +2004-10-05 Ulrich Weigand + + * config/s390/s390.c (s390_dump_pool): Remove return value. + Use gen_pool_align, gen_pool_section_start/end instead of + gen_pool_start/end_31/64. + * config/s390/s390.md (UNSPECV_POOL_START, UNSPECV_POOL_END): Remove. + (UNSPECV_POOL_SECTION, UNSPECV_POOL_ALIGN): New constants. + ("pool_start_31", "pool_end_31"): Remove. + ("pool_start_64", "pool_end_64"): Likewise. + ("pool_align", "pool_section_start", "pool_section_end": New insns. + + * config/s390/s390.c (s390_cannot_copy_insn_p): New function. + (TARGET_CANNOT_COPY_INSN_P): Define. + (s390_cannot_force_const_mem): Handle UNSPEC_INSN. + (struct constant_pool): New member 'execute'. + (s390_add_execute, s390_find_execute): New functions. + (s390_execute_label, s390_execute_target): Likewise. + (s390_dump_pool): Output in-pool execute target templates. + (s390_dump_execute): New function. + (s390_alloc_pool, s390_free_pool): Handle execute templates. + (s390_mainpool_start, s390_mainpool_finish): Likewise. + (s390_chunkify_start, s390_chunkify_finish): Likewise. + * config/s390/s390.md (UNSPEC_INSN, UNSPEC_EXECUTE): New constants. + ("*execute"): New insn pattern. + ("movmem_short", "*movmem_short"): Use splitters to generate + explicit execute pattern, remove embedded execute. + ("clrmem_short", "*clrmem_short"): Likewise. + ("cmpmem_short", "*cmpmem_short"): Likewise. + 2004-10-05 Daniel Berlin * tree-ssa.c (verify_ssa): Verify phi arguments only diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 21679c3ea81c..c1414cf48f3d 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -70,6 +70,7 @@ static enum attr_type s390_safe_attr_type (rtx); static int s390_adjust_priority (rtx, int); static int s390_issue_rate (void); static int s390_first_cycle_multipass_dfa_lookahead (void); +static bool s390_cannot_copy_insn_p (rtx); static bool s390_rtx_costs (rtx, int, int, int *); static int s390_address_cost (rtx); static void s390_reorg (void); @@ -127,6 +128,8 @@ static bool s390_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode mode, #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead +#undef TARGET_CANNOT_COPY_INSN_P +#define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p #undef TARGET_RTX_COSTS #define TARGET_RTX_COSTS s390_rtx_costs #undef TARGET_ADDRESS_COST @@ -2123,6 +2126,11 @@ s390_cannot_force_const_mem (rtx x) case UNSPEC_INDNTPOFF: return false; + /* If the literal pool shares the code section, be put + execute template placeholders into the pool as well. */ + case UNSPEC_INSN: + return TARGET_CPU_ZARCH; + default: return true; } @@ -4720,6 +4728,7 @@ struct constant_pool bitmap insns; struct constant *constants[NR_C_MODES]; + struct constant *execute; rtx label; int size; }; @@ -4738,7 +4747,12 @@ static void s390_add_pool_insn (struct constant_pool *, rtx); static struct constant_pool *s390_find_pool (struct constant_pool *, rtx); static void s390_add_constant (struct constant_pool *, rtx, enum machine_mode); static rtx s390_find_constant (struct constant_pool *, rtx, enum machine_mode); -static rtx s390_dump_pool (struct constant_pool *, bool); +static void s390_add_execute (struct constant_pool *, rtx); +static rtx s390_find_execute (struct constant_pool *, rtx); +static rtx s390_execute_label (rtx); +static rtx s390_execute_target (rtx); +static void s390_dump_pool (struct constant_pool *, bool); +static void s390_dump_execute (struct constant_pool *); static struct constant_pool *s390_alloc_pool (void); static void s390_free_pool (struct constant_pool *); @@ -4857,24 +4871,130 @@ s390_find_constant (struct constant_pool *pool, rtx val, return offset; } +/* Add execute target for INSN to the constant pool POOL. */ + +static void +s390_add_execute (struct constant_pool *pool, rtx insn) +{ + struct constant *c; + + for (c = pool->execute; c != NULL; c = c->next) + if (INSN_UID (insn) == INSN_UID (c->value)) + break; + + if (c == NULL) + { + rtx label = s390_execute_label (insn); + gcc_assert (label); + + c = (struct constant *) xmalloc (sizeof *c); + c->value = insn; + c->label = label == const0_rtx ? gen_label_rtx () : XEXP (label, 0); + c->next = pool->execute; + pool->execute = c; + pool->size += label == const0_rtx ? 6 : 0; + } +} + +/* Find execute target for INSN in the constant pool POOL. + Return an RTX describing the distance from the start of + the pool to the location of the execute target. */ + +static rtx +s390_find_execute (struct constant_pool *pool, rtx insn) +{ + struct constant *c; + rtx offset; + + for (c = pool->execute; c != NULL; c = c->next) + if (INSN_UID (insn) == INSN_UID (c->value)) + break; + + if (c == NULL) + abort (); + + offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label), + gen_rtx_LABEL_REF (Pmode, pool->label)); + offset = gen_rtx_CONST (Pmode, offset); + return offset; +} + +/* Check whether INSN is an execute. Return the label_ref to its + execute target template if so, NULL_RTX otherwise. */ + +static rtx +s390_execute_label (rtx insn) +{ + if (GET_CODE (insn) == INSN + && GET_CODE (PATTERN (insn)) == PARALLEL + && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == UNSPEC + && XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE) + return XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 2); + + return NULL_RTX; +} + +/* For an execute INSN, extract the execute target template. */ + +static rtx +s390_execute_target (rtx insn) +{ + rtx pattern = PATTERN (insn); + gcc_assert (s390_execute_label (insn)); + + if (XVECLEN (pattern, 0) == 2) + { + pattern = copy_rtx (XVECEXP (pattern, 0, 1)); + } + else + { + rtvec vec = rtvec_alloc (XVECLEN (pattern, 0) - 1); + int i; + + for (i = 0; i < XVECLEN (pattern, 0) - 1; i++) + RTVEC_ELT (vec, i) = copy_rtx (XVECEXP (pattern, 0, i + 1)); + + pattern = gen_rtx_PARALLEL (VOIDmode, vec); + } + + return pattern; +} + +/* Indicate that INSN cannot be duplicated. This is the case for + execute insns that carry a unique label. */ + +static bool +s390_cannot_copy_insn_p (rtx insn) +{ + rtx label = s390_execute_label (insn); + return label && label != const0_rtx; +} + /* Dump out the constants in POOL. If REMOTE_LABEL is true, do not emit the pool base label. */ -static rtx +static void s390_dump_pool (struct constant_pool *pool, bool remote_label) { struct constant *c; - rtx insn; + rtx insn = pool->pool_insn; int i; - /* Pool start insn switches to proper section - and guarantees necessary alignment. */ + /* Switch to rodata section. */ if (TARGET_CPU_ZARCH) - insn = emit_insn_after (gen_pool_start_64 (), pool->pool_insn); + { + insn = emit_insn_after (gen_pool_section_start (), insn); + INSN_ADDRESSES_NEW (insn, -1); + } + + /* Ensure minimum pool alignment. */ + if (TARGET_CPU_ZARCH) + insn = emit_insn_after (gen_pool_align (GEN_INT (8)), insn); else - insn = emit_insn_after (gen_pool_start_31 (), pool->pool_insn); + insn = emit_insn_after (gen_pool_align (GEN_INT (4)), insn); INSN_ADDRESSES_NEW (insn, -1); + /* Emit pool base label. */ if (!remote_label) { insn = emit_label_after (pool->label, insn); @@ -4908,21 +5028,60 @@ s390_dump_pool (struct constant_pool *pool, bool remote_label) INSN_ADDRESSES_NEW (insn, -1); } - /* Pool end insn switches back to previous section - and guarantees necessary alignment. */ - if (TARGET_CPU_ZARCH) - insn = emit_insn_after (gen_pool_end_64 (), insn); - else - insn = emit_insn_after (gen_pool_end_31 (), insn); + /* Ensure minimum alignment for instructions. */ + insn = emit_insn_after (gen_pool_align (GEN_INT (2)), insn); INSN_ADDRESSES_NEW (insn, -1); + /* Output in-pool execute template insns. */ + for (c = pool->execute; c; c = c->next) + { + if (s390_execute_label (c->value) != const0_rtx) + continue; + + insn = emit_label_after (c->label, insn); + INSN_ADDRESSES_NEW (insn, -1); + + insn = emit_insn_after (s390_execute_target (c->value), insn); + INSN_ADDRESSES_NEW (insn, -1); + } + + /* Switch back to previous section. */ + if (TARGET_CPU_ZARCH) + { + insn = emit_insn_after (gen_pool_section_end (), insn); + INSN_ADDRESSES_NEW (insn, -1); + } + insn = emit_barrier_after (insn); INSN_ADDRESSES_NEW (insn, -1); /* Remove placeholder insn. */ remove_insn (pool->pool_insn); - return insn; + /* Output out-of-pool execute template isns. */ + s390_dump_execute (pool); +} + +/* Dump out the out-of-pool execute template insns in POOL + at the end of the instruction stream. */ + +static void +s390_dump_execute (struct constant_pool *pool) +{ + struct constant *c; + rtx insn; + + for (c = pool->execute; c; c = c->next) + { + if (s390_execute_label (c->value) == const0_rtx) + continue; + + insn = emit_label (c->label); + INSN_ADDRESSES_NEW (insn, -1); + + insn = emit_insn (s390_execute_target (c->value)); + INSN_ADDRESSES_NEW (insn, -1); + } } /* Allocate new constant_pool structure. */ @@ -4938,6 +5097,7 @@ s390_alloc_pool (void) for (i = 0; i < NR_C_MODES; i++) pool->constants[i] = NULL; + pool->execute = NULL; pool->label = gen_label_rtx (); pool->first_insn = NULL_RTX; pool->pool_insn = NULL_RTX; @@ -4952,17 +5112,20 @@ s390_alloc_pool (void) static void s390_free_pool (struct constant_pool *pool) { + struct constant *c, *next; int i; for (i = 0; i < NR_C_MODES; i++) + for (c = pool->constants[i]; c; c = next) + { + next = c->next; + free (c); + } + + for (c = pool->execute; c; c = next) { - struct constant *c = pool->constants[i]; - while (c != NULL) - { - struct constant *next = c->next; - free (c); - c = next; - } + next = c->next; + free (c); } BITMAP_XFREE (pool->insns); @@ -4992,7 +5155,11 @@ s390_mainpool_start (void) pool->pool_insn = insn; } - if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN) + if (s390_execute_label (insn)) + { + s390_add_execute (pool, insn); + } + else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN) { rtx pool_ref = NULL_RTX; find_constant_pool_ref (PATTERN (insn), &pool_ref); @@ -5034,6 +5201,9 @@ s390_mainpool_finish (struct constant_pool *pool) /* If the pool is empty, we're done. */ if (pool->size == 0) { + /* However, we may have out-of-pool execute templates. */ + s390_dump_execute (pool); + /* We don't actually need a base register after all. */ cfun->machine->base_reg = NULL_RTX; @@ -5120,8 +5290,12 @@ s390_mainpool_finish (struct constant_pool *pool) find_constant_pool_ref (PATTERN (insn), &pool_ref); if (pool_ref) { - addr = s390_find_constant (pool, get_pool_constant (pool_ref), - get_pool_mode (pool_ref)); + if (s390_execute_label (insn)) + addr = s390_find_execute (pool, insn); + else + addr = s390_find_constant (pool, get_pool_constant (pool_ref), + get_pool_mode (pool_ref)); + replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr); INSN_CODE (insn) = -1; } @@ -5184,7 +5358,15 @@ s390_chunkify_start (void) } } - if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN) + if (s390_execute_label (insn)) + { + if (!curr_pool) + curr_pool = s390_start_pool (&pool_list, insn); + + s390_add_execute (curr_pool, insn); + s390_add_pool_insn (curr_pool, insn); + } + else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN) { rtx pool_ref = NULL_RTX; find_constant_pool_ref (PATTERN (insn), &pool_ref); @@ -5439,8 +5621,13 @@ s390_chunkify_finish (struct constant_pool *pool_list) find_constant_pool_ref (PATTERN (insn), &pool_ref); if (pool_ref) { - addr = s390_find_constant (curr_pool, get_pool_constant (pool_ref), - get_pool_mode (pool_ref)); + if (s390_execute_label (insn)) + addr = s390_find_execute (curr_pool, insn); + else + addr = s390_find_constant (curr_pool, + get_pool_constant (pool_ref), + get_pool_mode (pool_ref)); + replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr); INSN_CODE (insn) = -1; } diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index a2408d751964..5a6499323297 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -94,6 +94,8 @@ (UNSPEC_RELOAD_BASE 210) (UNSPEC_MAIN_BASE 211) (UNSPEC_LTREF 212) + (UNSPEC_INSN 213) + (UNSPEC_EXECUTE 214) ; TLS relocation specifiers (UNSPEC_TLSGD 500) @@ -126,8 +128,8 @@ ; Literal pool (UNSPECV_POOL 200) - (UNSPECV_POOL_START 201) - (UNSPECV_POOL_END 202) + (UNSPECV_POOL_SECTION 201) + (UNSPECV_POOL_ALIGN 202) (UNSPECV_POOL_ENTRY 203) (UNSPECV_MAIN_POOL 300) @@ -1594,6 +1596,17 @@ ;; String instructions. ;; +(define_insn "*execute" + [(match_parallel 0 "" + [(unspec [(match_operand 1 "register_operand" "a") + (match_operand:BLK 2 "memory_operand" "R") + (match_operand 3 "" "")] UNSPEC_EXECUTE)])] + "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT + && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD" + "ex\t%1,%2" + [(set_attr "op_type" "RX")]) + + ; ; strlenM instruction pattern(s). ; @@ -1698,36 +1711,72 @@ [(set (match_operand:BLK 0 "memory_operand" "") (match_operand:BLK 1 "memory_operand" "")) (use (match_operand 2 "nonmemory_operand" "")) + (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) (clobber (match_dup 3))])] "" "operands[3] = gen_rtx_SCRATCH (Pmode);") (define_insn "*movmem_short" - [(set (match_operand:BLK 0 "memory_operand" "=Q,Q") - (match_operand:BLK 1 "memory_operand" "Q,Q")) - (use (match_operand 2 "nonmemory_operand" "n,a")) - (clobber (match_scratch 3 "=X,&a"))] + [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q") + (match_operand:BLK 1 "memory_operand" "Q,Q,Q")) + (use (match_operand 2 "nonmemory_operand" "n,a,a")) + (use (match_operand 3 "immediate_operand" "X,R,X")) + (clobber (match_scratch 4 "=X,X,&a"))] "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode) - && GET_MODE (operands[3]) == Pmode" -{ - switch (which_alternative) - { - case 0: - return "mvc\t%O0(%b2+1,%R0),%1"; + && GET_MODE (operands[4]) == Pmode" + "#" + [(set_attr "op_type" "SS,RX,RX") + (set_attr "type" "cs")]) - case 1: - output_asm_insn ("bras\t%3,.+10", operands); - output_asm_insn ("mvc\t%O0(1,%R0),%1", operands); - return "ex\t%2,0(%3)"; +(define_split + [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand 2 "const_int_operand" "")) + (use (match_operand 3 "immediate_operand" "")) + (clobber (scratch))] + "reload_completed" + [(parallel + [(set (match_dup 0) (match_dup 1)) + (use (match_dup 2))])] + "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);") - default: - abort (); - } -} - [(set_attr "op_type" "SS,NN") - (set_attr "type" "cs,cs") - (set_attr "atype" "*,agen") - (set_attr "length" "*,14")]) +(define_split + [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand 2 "register_operand" "")) + (use (match_operand 3 "memory_operand" "")) + (clobber (scratch))] + "reload_completed" + [(parallel + [(unspec [(match_dup 2) (match_dup 3) + (const_int 0)] UNSPEC_EXECUTE) + (set (match_dup 0) (match_dup 1)) + (use (const_int 1))])] + "") + +(define_split + [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand 2 "register_operand" "")) + (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) + (clobber (match_operand 3 "register_operand" ""))] + "reload_completed && TARGET_CPU_ZARCH" + [(set (match_dup 3) (label_ref (match_dup 4))) + (parallel + [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) + (label_ref (match_dup 4))] UNSPEC_EXECUTE) + (set (match_dup 0) (match_dup 1)) + (use (const_int 1))])] + "operands[4] = gen_label_rtx ();") + +(define_insn "*mvc" + [(set (match_operand:BLK 0 "memory_operand" "=Q") + (match_operand:BLK 1 "memory_operand" "Q")) + (use (match_operand 2 "const_int_operand" "n"))] + "" + "mvc\t%O0(%2,%R0),%1" + [(set_attr "op_type" "SS") + (set_attr "type" "cs")]) ; Move a block of arbitrary length. @@ -1820,38 +1869,81 @@ [(set (match_operand:BLK 0 "memory_operand" "") (const_int 0)) (use (match_operand 1 "nonmemory_operand" "")) + (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) (clobber (match_dup 2)) (clobber (reg:CC 33))])] "" "operands[2] = gen_rtx_SCRATCH (Pmode);") (define_insn "*clrmem_short" - [(set (match_operand:BLK 0 "memory_operand" "=Q,Q") + [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q") (const_int 0)) - (use (match_operand 1 "nonmemory_operand" "n,a")) - (clobber (match_scratch 2 "=X,&a")) + (use (match_operand 1 "nonmemory_operand" "n,a,a")) + (use (match_operand 2 "immediate_operand" "X,R,X")) + (clobber (match_scratch 3 "=X,X,&a")) (clobber (reg:CC 33))] "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode) - && GET_MODE (operands[2]) == Pmode" -{ - switch (which_alternative) - { - case 0: - return "xc\t%O0(%b1+1,%R0),%0"; + && GET_MODE (operands[3]) == Pmode" + "#" + [(set_attr "op_type" "SS,RX,RX") + (set_attr "type" "cs")]) - case 1: - output_asm_insn ("bras\t%2,.+10", operands); - output_asm_insn ("xc\t%O0(1,%R0),%0", operands); - return "ex\t%1,0(%2)"; +(define_split + [(set (match_operand:BLK 0 "memory_operand" "") + (const_int 0)) + (use (match_operand 1 "const_int_operand" "")) + (use (match_operand 2 "immediate_operand" "")) + (clobber (scratch)) + (clobber (reg:CC 33))] + "reload_completed" + [(parallel + [(set (match_dup 0) (const_int 0)) + (use (match_dup 1)) + (clobber (reg:CC 33))])] + "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);") - default: - abort (); - } -} - [(set_attr "op_type" "SS,NN") - (set_attr "type" "cs,cs") - (set_attr "atype" "*,agen") - (set_attr "length" "*,14")]) +(define_split + [(set (match_operand:BLK 0 "memory_operand" "") + (const_int 0)) + (use (match_operand 1 "register_operand" "")) + (use (match_operand 2 "memory_operand" "")) + (clobber (scratch)) + (clobber (reg:CC 33))] + "reload_completed" + [(parallel + [(unspec [(match_dup 1) (match_dup 2) + (const_int 0)] UNSPEC_EXECUTE) + (set (match_dup 0) (const_int 0)) + (use (const_int 1)) + (clobber (reg:CC 33))])] + "") + +(define_split + [(set (match_operand:BLK 0 "memory_operand" "") + (const_int 0)) + (use (match_operand 1 "register_operand" "")) + (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) + (clobber (match_operand 2 "register_operand" "")) + (clobber (reg:CC 33))] + "reload_completed && TARGET_CPU_ZARCH" + [(set (match_dup 2) (label_ref (match_dup 3))) + (parallel + [(unspec [(match_dup 1) (mem:BLK (match_dup 2)) + (label_ref (match_dup 3))] UNSPEC_EXECUTE) + (set (match_dup 0) (const_int 0)) + (use (const_int 1)) + (clobber (reg:CC 33))])] + "operands[3] = gen_label_rtx ();") + +(define_insn "*xc_zero" + [(set (match_operand:BLK 0 "memory_operand" "=Q") + (const_int 0)) + (use (match_operand 1 "const_int_operand" "n")) + (clobber (reg:CC 33))] + "" + "xc\t%O0(%1,%R0),%0" + [(set_attr "op_type" "SS") + (set_attr "type" "cs")]) ; Clear a block of arbitrary length. @@ -1931,37 +2023,77 @@ (compare:CCU (match_operand:BLK 0 "memory_operand" "") (match_operand:BLK 1 "memory_operand" ""))) (use (match_operand 2 "nonmemory_operand" "")) + (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) (clobber (match_dup 3))])] "" "operands[3] = gen_rtx_SCRATCH (Pmode);") (define_insn "*cmpmem_short" [(set (reg:CCU 33) - (compare:CCU (match_operand:BLK 0 "memory_operand" "=Q,Q") - (match_operand:BLK 1 "memory_operand" "Q,Q"))) - (use (match_operand 2 "nonmemory_operand" "n,a")) - (clobber (match_scratch 3 "=X,&a"))] + (compare:CCU (match_operand:BLK 0 "memory_operand" "=Q,Q,Q") + (match_operand:BLK 1 "memory_operand" "Q,Q,Q"))) + (use (match_operand 2 "nonmemory_operand" "n,a,a")) + (use (match_operand 3 "immediate_operand" "X,R,X")) + (clobber (match_scratch 4 "=X,X,&a"))] "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode) - && GET_MODE (operands[3]) == Pmode" -{ - switch (which_alternative) - { - case 0: - return "clc\t%O0(%b2+1,%R0),%1"; + && GET_MODE (operands[4]) == Pmode" + "#" + [(set_attr "op_type" "SS,RX,RX") + (set_attr "type" "cs")]) - case 1: - output_asm_insn ("bras\t%3,.+10", operands); - output_asm_insn ("clc\t%O0(1,%R0),%1", operands); - return "ex\t%2,0(%3)"; +(define_split + [(set (reg:CCU 33) + (compare:CCU (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" ""))) + (use (match_operand 2 "const_int_operand" "")) + (use (match_operand 3 "immediate_operand" "")) + (clobber (scratch))] + "reload_completed" + [(parallel + [(set (reg:CCU 33) (compare:CCU (match_dup 0) (match_dup 1))) + (use (match_dup 2))])] + "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);") - default: - abort (); - } -} - [(set_attr "op_type" "SS,NN") - (set_attr "type" "cs,cs") - (set_attr "atype" "*,agen") - (set_attr "length" "*,14")]) +(define_split + [(set (reg:CCU 33) + (compare:CCU (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" ""))) + (use (match_operand 2 "register_operand" "")) + (use (match_operand 3 "memory_operand" "")) + (clobber (scratch))] + "reload_completed" + [(parallel + [(unspec [(match_dup 2) (match_dup 3) + (const_int 0)] UNSPEC_EXECUTE) + (set (reg:CCU 33) (compare:CCU (match_dup 0) (match_dup 1))) + (use (const_int 1))])] + "") + +(define_split + [(set (reg:CCU 33) + (compare:CCU (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" ""))) + (use (match_operand 2 "register_operand" "")) + (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) + (clobber (match_operand 3 "register_operand" ""))] + "reload_completed && TARGET_CPU_ZARCH" + [(set (match_dup 3) (label_ref (match_dup 4))) + (parallel + [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) + (label_ref (match_dup 4))] UNSPEC_EXECUTE) + (set (reg:CCU 33) (compare:CCU (match_dup 0) (match_dup 1))) + (use (const_int 1))])] + "operands[4] = gen_label_rtx ();") + +(define_insn "*clc" + [(set (reg:CCU 33) + (compare:CCU (match_operand:BLK 0 "memory_operand" "=Q") + (match_operand:BLK 1 "memory_operand" "Q"))) + (use (match_operand 2 "const_int_operand" "n"))] + "" + "clc\t%O0(%2,%R0),%1" + [(set_attr "op_type" "SS") + (set_attr "type" "cs")]) ; Compare a block of arbitrary length. @@ -7170,33 +7302,27 @@ (set (attr "length") (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))]) -(define_insn "pool_start_31" - [(unspec_volatile [(const_int 0)] UNSPECV_POOL_START)] - "!TARGET_CPU_ZARCH" - ".align\t4" - [(set_attr "op_type" "NN") - (set_attr "length" "2")]) - -(define_insn "pool_end_31" - [(unspec_volatile [(const_int 0)] UNSPECV_POOL_END)] - "!TARGET_CPU_ZARCH" - ".align\t2" - [(set_attr "op_type" "NN") - (set_attr "length" "2")]) +(define_insn "pool_align" + [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] + UNSPECV_POOL_ALIGN)] + "" + ".align\t%0" + [(set_attr "op_type" "NN") + (set (attr "length") (symbol_ref "INTVAL (operands[0])"))]) -(define_insn "pool_start_64" - [(unspec_volatile [(const_int 0)] UNSPECV_POOL_START)] - "TARGET_CPU_ZARCH" - ".section\t.rodata\;.align\t8" - [(set_attr "op_type" "NN") - (set_attr "length" "0")]) +(define_insn "pool_section_start" + [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)] + "" + ".section\t.rodata" + [(set_attr "op_type" "NN") + (set_attr "length" "0")]) -(define_insn "pool_end_64" - [(unspec_volatile [(const_int 0)] UNSPECV_POOL_END)] - "TARGET_CPU_ZARCH" +(define_insn "pool_section_end" + [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)] + "" ".previous" - [(set_attr "op_type" "NN") - (set_attr "length" "0")]) + [(set_attr "op_type" "NN") + (set_attr "length" "0")]) (define_insn "main_base_31_small" [(set (match_operand 0 "register_operand" "=a") -- 2.43.5