From 716019c0ad646715c24467a80bf0595a1a2ad7cb Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Tue, 14 Mar 2006 00:29:07 +0000 Subject: [PATCH] rs6000.opt (mdlmzb): New option. * config/rs6000/rs6000.opt (mdlmzb): New option. (msched-prolog, msched-epilog): Use Var not Mask. * doc/invoke.texi (-mdlmzb): Document. * config/rs6000/rs6000.c (TARGET_DEFAULT_TARGET_FLAGS): Remove MASK_SCHED_PROLOG. (rs6000_override_options): Enable -mdlmzb for 405 and 440. * config/rs6000/rs6000.md: Add dlmzb support for 405 and 440. testsuite: * gcc.target/powerpc/405-dlmzb-strlen-1.c, gcc.target/powerpc/440-dlmzb-strlen-1.c: New tests. From-SVN: r112040 --- gcc/ChangeLog | 10 +++ gcc/config/rs6000/rs6000.c | 15 ++-- gcc/config/rs6000/rs6000.md | 69 +++++++++++++++++++ gcc/config/rs6000/rs6000.opt | 8 ++- gcc/doc/invoke.texi | 11 ++- gcc/testsuite/ChangeLog | 5 ++ .../gcc.target/powerpc/405-dlmzb-strlen-1.c | 17 +++++ .../gcc.target/powerpc/440-dlmzb-strlen-1.c | 17 +++++ 8 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/405-dlmzb-strlen-1.c create mode 100644 gcc/testsuite/gcc.target/powerpc/440-dlmzb-strlen-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fdc7531b53e..d2c7e51b74f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2006-03-14 Joseph S. Myers + + * config/rs6000/rs6000.opt (mdlmzb): New option. + (msched-prolog, msched-epilog): Use Var not Mask. + * doc/invoke.texi (-mdlmzb): Document. + * config/rs6000/rs6000.c (TARGET_DEFAULT_TARGET_FLAGS): Remove + MASK_SCHED_PROLOG. + (rs6000_override_options): Enable -mdlmzb for 405 and 440. + * config/rs6000/rs6000.md: Add dlmzb support for 405 and 440. + 2006-03-13 Uttam Pawar PR rtl-optimization/25739 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 231154c18d1..23f76c38e9c 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1002,7 +1002,7 @@ static const char alt_reg_names[][8] = #undef TARGET_DEFAULT_TARGET_FLAGS #define TARGET_DEFAULT_TARGET_FLAGS \ - (TARGET_DEFAULT | MASK_SCHED_PROLOG) + (TARGET_DEFAULT) #undef TARGET_STACK_PROTECT_FAIL #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail @@ -1135,11 +1135,13 @@ rs6000_override_options (const char *default_cpu) {"403", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN}, {"405", PROCESSOR_PPC405, - POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW}, - {"405fp", PROCESSOR_PPC405, POWERPC_BASE_MASK | MASK_MULHW}, + POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB}, + {"405fp", PROCESSOR_PPC405, + POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB}, {"440", PROCESSOR_PPC440, - POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW}, - {"440fp", PROCESSOR_PPC440, POWERPC_BASE_MASK | MASK_MULHW}, + POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB}, + {"440fp", PROCESSOR_PPC440, + POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB}, {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK}, {"601", PROCESSOR_PPC601, MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING}, @@ -1209,7 +1211,8 @@ rs6000_override_options (const char *default_cpu) POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING, POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC - | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW) + | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW + | MASK_DLMZB) }; rs6000_init_hard_regno_mode_ok (); diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index d214e212e64..fc57e5b3833 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -69,6 +69,9 @@ (UNSPEC_CMPXCHG 42) (UNSPEC_XCHG 43) (UNSPEC_AND 44) + (UNSPEC_DLMZB 45) + (UNSPEC_DLMZB_CR 46) + (UNSPEC_DLMZB_STRLEN 47) ]) ;; @@ -1343,6 +1346,72 @@ "mullhwu %0, %1, %2" [(set_attr "type" "imul3")]) +;; IBM 405 and 440 string-search dlmzb instruction support. +(define_insn "dlmzb" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "gpc_reg_operand" "r")] + UNSPEC_DLMZB_CR)) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (unspec:SI [(match_dup 1) + (match_dup 2)] + UNSPEC_DLMZB))] + "TARGET_DLMZB" + "dlmzb. %0, %1, %2") + +(define_expand "strlensi" + [(set (match_operand:SI 0 "gpc_reg_operand" "") + (unspec:SI [(match_operand:BLK 1 "general_operand" "") + (match_operand:QI 2 "const_int_operand" "") + (match_operand 3 "const_int_operand" "")] + UNSPEC_DLMZB_STRLEN)) + (clobber (match_scratch:CC 4 "=x"))] + "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size" +{ + rtx result = operands[0]; + rtx src = operands[1]; + rtx search_char = operands[2]; + rtx align = operands[3]; + rtx addr, scratch_string, word1, word2, scratch_dlmzb; + rtx loop_label, end_label, mem, cr0, cond; + if (search_char != const0_rtx + || GET_CODE (align) != CONST_INT + || INTVAL (align) < 8) + FAIL; + word1 = gen_reg_rtx (SImode); + word2 = gen_reg_rtx (SImode); + scratch_dlmzb = gen_reg_rtx (SImode); + scratch_string = gen_reg_rtx (Pmode); + loop_label = gen_label_rtx (); + end_label = gen_label_rtx (); + addr = force_reg (Pmode, XEXP (src, 0)); + emit_move_insn (scratch_string, addr); + emit_label (loop_label); + mem = change_address (src, SImode, scratch_string); + emit_move_insn (word1, mem); + emit_move_insn (word2, adjust_address (mem, SImode, 4)); + cr0 = gen_rtx_REG (CCmode, CR0_REGNO); + emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0)); + cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx); + emit_jump_insn (gen_rtx_SET (VOIDmode, + pc_rtx, + gen_rtx_IF_THEN_ELSE (VOIDmode, + cond, + gen_rtx_LABEL_REF + (VOIDmode, + end_label), + pc_rtx))); + emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8))); + emit_jump_insn (gen_rtx_SET (VOIDmode, + pc_rtx, + gen_rtx_LABEL_REF (VOIDmode, loop_label))); + emit_label (end_label); + emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb)); + emit_insn (gen_subsi3 (result, scratch_string, addr)); + emit_insn (gen_subsi3 (result, result, const1_rtx)); + DONE; +}) + (define_split [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index d50cc3ae601..1ecd87b5c3c 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -72,6 +72,10 @@ mmulhw Target Report Mask(MULHW) Use 4xx half-word multiply instructions +mdlmzb +Target Report Mask(DLMZB) +Use 4xx string-search dlmzb instruction + mmultiple Target Report Mask(MULTIPLE) Generate load/store multiple instructions @@ -113,11 +117,11 @@ Target Report RejectNegative InverseMask(NO_FUSED_MADD, FUSED_MADD) Generate fused multiply/add instructions msched-prolog -Target Report Mask(SCHED_PROLOG) +Target Report Var(TARGET_SCHED_PROLOG) Init(1) Schedule the start and end of the procedure msched-epilog -Target Undocumented Mask(SCHED_PROLOG) MaskExists +Target Undocumented Var(TARGET_SCHED_PROLOG) VarExists maix-struct-return Target Report RejectNegative Var(aix_struct_return) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index c1de501d5e3..f11214f7f9c 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -670,6 +670,7 @@ See RS/6000 and PowerPC Options. -mspe=yes -mspe=no @gol -mvrsave -mno-vrsave @gol -mmulhw -mno-mulhw @gol +-mdlmzb -mno-dlmzb @gol -mfloat-gprs=yes -mfloat-gprs=no -mfloat-gprs=single -mfloat-gprs=double @gol -mprototype -mno-prototype @gol -msim -mmvme -mads -myellowknife -memb -msdata @gol @@ -11106,7 +11107,7 @@ following options: @option{-maltivec}, @option{-mfprnd}, @option{-mhard-float}, @option{-mmfcrf}, @option{-mmultiple}, @option{-mnew-mnemonics}, @option{-mpopcntb}, @option{-mpower}, @option{-mpower2}, @option{-mpowerpc64}, @option{-mpowerpc-gpopt}, -@option{-mpowerpc-gfxopt}, @option{-mstring}, @option{-mmulhw}. +@option{-mpowerpc-gfxopt}, @option{-mstring}, @option{-mmulhw}, @option{dlmzb}. The particular options set for any particular CPU will vary between compiler versions, depending on what setting seems to produce optimal code for that CPU; @@ -11370,6 +11371,14 @@ multiply-accumulate instructions on the IBM 405 and 440 processors. These instructions are generated by default when targetting those processors. +@item -mdlmzb +@itemx -mno-dlmzb +@opindex mdlmzb +@opindex mno-dlmzb +Generate code that uses (does not use) the string-search @samp{dlmzb} +instruction on the IBM 405 and 440 processors. This instruction is +generated by default when targetting those processors. + @item -mno-bit-align @itemx -mbit-align @opindex mno-bit-align diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b91ceeaadf3..5d89febca76 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-03-14 Joseph S. Myers + + * gcc.target/powerpc/405-dlmzb-strlen-1.c, + gcc.target/powerpc/440-dlmzb-strlen-1.c: New tests. + 2006-03-13 Roger Sayle PR middle-end/26557 diff --git a/gcc/testsuite/gcc.target/powerpc/405-dlmzb-strlen-1.c b/gcc/testsuite/gcc.target/powerpc/405-dlmzb-strlen-1.c new file mode 100644 index 00000000000..dc309515010 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/405-dlmzb-strlen-1.c @@ -0,0 +1,17 @@ +/* Test generation of dlmzb for strlen on 405. */ +/* Origin: Joseph Myers */ +/* { dg-do compile } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-options "-O2 -mcpu=405" } */ + +/* { dg-final { scan-assembler "dlmzb\\. " } } */ + +typedef __SIZE_TYPE__ size_t; + +size_t strlen(const char *); + +size_t +strlen8(const long long *s) +{ + return strlen((const char *)s); +} diff --git a/gcc/testsuite/gcc.target/powerpc/440-dlmzb-strlen-1.c b/gcc/testsuite/gcc.target/powerpc/440-dlmzb-strlen-1.c new file mode 100644 index 00000000000..c69a7c91bcc --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/440-dlmzb-strlen-1.c @@ -0,0 +1,17 @@ +/* Test generation of dlmzb for strlen on 440. */ +/* Origin: Joseph Myers */ +/* { dg-do compile } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-options "-O2 -mcpu=440" } */ + +/* { dg-final { scan-assembler "dlmzb\\. " } } */ + +typedef __SIZE_TYPE__ size_t; + +size_t strlen(const char *); + +size_t +strlen8(const long long *s) +{ + return strlen((const char *)s); +}