From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32391 invoked by alias); 1 Jul 2007 05:05:11 -0000 Received: (qmail 32381 invoked by uid 22791); 1 Jul 2007 05:05:10 -0000 X-Spam-Check-By: sourceware.org Received: from smtp1.dnsmadeeasy.com (HELO smtp1.dnsmadeeasy.com) (205.234.170.134) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sun, 01 Jul 2007 05:05:07 +0000 Received: from smtp1.dnsmadeeasy.com (localhost [127.0.0.1]) by smtp1.dnsmadeeasy.com (Postfix) with ESMTP id 6DBC22F502B for ; Sun, 1 Jul 2007 05:05:05 +0000 (UTC) X-Authenticated-Name: js.dnsmadeeasy X-Transit-System: In case of SPAM please contact abuse@dnsmadeeasy.com Received: from avtrex.com (unknown [67.116.42.147]) by smtp1.dnsmadeeasy.com (Postfix) with ESMTP for ; Sun, 1 Jul 2007 05:05:05 +0000 (UTC) Received: from jennifer.localdomain ([192.168.7.222]) by avtrex.com with Microsoft SMTPSVC(6.0.3790.1830); Sat, 30 Jun 2007 22:05:03 -0700 Message-ID: <46873597.30607@avtrex.com> Date: Sun, 01 Jul 2007 05:05:00 -0000 From: David Daney User-Agent: Thunderbird 2.0.0.4 (X11/20070615) MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org Subject: [Patch] 2/3 MIPS support for builtin __builtin_flush_icache(). References: <468734D3.3020908@avtrex.com> In-Reply-To: <468734D3.3020908@avtrex.com> Content-Type: multipart/mixed; boundary="------------020405060105050705020403" X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2007-07/txt/msg00008.txt.bz2 This is a multi-part message in MIME format. --------------020405060105050705020403 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1336 This is the second part of the __builtin_flush_icache patch. It adds support for MIPS. flush_icache is expanded to either a library call or an in-line cache flushing sequence if the ISA supports it. It it is expanded in-line it is done by two insns (synci_loop and clear_hazard). A possible follow on optimization would be to fold the clear_hazard into the next jump instruction that follows the synci_loop. I also changed INITIALIZE_TRAMPOLINE to emit flush_icache instead of the library call it used previously. Bootstrapped and tested on x86_64-unknown-linux-gnu all default languages with no regressions. Also tested on: x86_64 cross to mipsel-linux --with-arch=mips32 i686 cross to mipsel-linux --with-arch=mips32r2 with no regressions. OK to commit? 2007-06-30 David Daney * config/mips/mips.h (ISA_HAS_SYNCI): New target capability predicate. (INITIALIZE_TRAMPOLINE): Emit flush_icache instead library call. * config/mips/mips.md (UNSPEC_SYNCI_LOOP): New constant (UNSPEC_CLEAR_HAZARD): New constant. (flush_icache): New expand. (synci_loop): New insn. (clear_hazard): New insn. * testsuite/gcc.target/mips/flush-icache-2.c: New test. * testsuite/gcc.target/mips/flush-icache-1.c: New test. * testsuite/gcc.target/mips/flush-icache-3.c: New test. --------------020405060105050705020403 Content-Type: text/x-patch; name="flush-cache2.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="flush-cache2.diff" Content-length: 5846 Index: config/mips/mips.h =================================================================== --- config/mips/mips.h (revision 125997) +++ config/mips/mips.h (working copy) @@ -770,6 +770,10 @@ extern const struct mips_rtx_cost_data * || ISA_MIPS32R2 \ || ISA_MIPS64 \ || TARGET_MIPS5500) + +/* ISA includes synci, jr.hb and jalr.hb */ +#define ISA_HAS_SYNCI ISA_MIPS32R2 + /* Add -G xx support. */ @@ -2122,15 +2126,7 @@ typedef struct mips_args { chain_addr = plus_constant (func_addr, GET_MODE_SIZE (ptr_mode)); \ emit_move_insn (gen_rtx_MEM (ptr_mode, func_addr), FUNC); \ emit_move_insn (gen_rtx_MEM (ptr_mode, chain_addr), CHAIN); \ - \ - /* Flush both caches. We need to flush the data cache in case \ - the system has a write-back cache. */ \ - /* ??? Should check the return value for errors. */ \ - if (mips_cache_flush_func && mips_cache_flush_func[0]) \ - emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mips_cache_flush_func), \ - 0, VOIDmode, 3, ADDR, Pmode, \ - GEN_INT (TRAMPOLINE_SIZE), TYPE_MODE (integer_type_node),\ - GEN_INT (3), TYPE_MODE (integer_type_node)); \ + emit_insn (gen_flush_icache (copy_rtx (ADDR), GEN_INT (TRAMPOLINE_SIZE))); \ } /* Addressing modes, and classification of registers for them. */ Index: config/mips/mips.md =================================================================== --- config/mips/mips.md (revision 125997) +++ config/mips/mips.md (working copy) @@ -50,6 +50,8 @@ (define_constants (UNSPEC_TLS_GET_TP 28) (UNSPEC_MFHC1 31) (UNSPEC_MTHC1 32) + (UNSPEC_SYNCI_LOOP 33) + (UNSPEC_CLEAR_HAZARD 34) (UNSPEC_ADDRESS_FIRST 100) @@ -4171,6 +4173,72 @@ (define_insn "cprestore" } [(set_attr "type" "store") (set_attr "length" "4,12")]) + +(define_expand "flush_icache" + [(match_operand:SI 0 "general_operand" "r") + (match_operand:SI 1 "general_operand" "r")] + "" + " +{ + if (ISA_HAS_SYNCI) + { + emit_insn (gen_synci_loop (copy_rtx (operands[0]), + copy_rtx (operands[1]))); + emit_insn (gen_clear_hazard ()); + } + else + /* Flush both caches. We need to flush the data cache in case + the system has a write-back cache. */ + /* ??? Should check the return value for errors. */ + if (mips_cache_flush_func && mips_cache_flush_func[0]) + emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mips_cache_flush_func), + 0, VOIDmode, 3, copy_rtx (operands[0]), Pmode, + copy_rtx (operands[1]), TYPE_MODE (integer_type_node), + GEN_INT (3), TYPE_MODE (integer_type_node)); + DONE; +}") + +(define_insn "synci_loop" + [(unspec_volatile[(match_operand:SI 0 "general_operand" "r") + (match_operand:SI 1 "general_operand" "r") + (clobber (match_scratch:SI 2 "=0")) + (clobber (match_scratch:SI 3 "=1")) + (clobber (match_scratch:SI 4 "=r")) + (clobber (match_scratch:SI 5 "=r"))] + UNSPEC_SYNCI_LOOP)] + "ISA_HAS_SYNCI" +{ + return ".set\tpush\n" + "\t.set\tnoreorder\n" + "\t.set\tnomacro\n" + "\taddu\t%3,%0,%1\n" + "\trdhwr\t%4,$1\n" + "1:\tsynci\t0(%2)\n" + "\tsltu\t%5,%2,%3\n" + "\tbne\t%5,$0,1b\n" + "\taddu\t%2,%2,%4\n" + "\tsync\n" + "\t.set\tpop"; + } + [(set_attr "length" "28")]) + +(define_insn "clear_hazard" + [(unspec_volatile [(clobber (match_scratch:SI 0 "=r"))] UNSPEC_CLEAR_HAZARD) + (clobber (reg:SI 31))] + "ISA_HAS_SYNCI" +{ + return ".set\tpush\n" + "\t.set\tnoreorder\n" + "\t.set\tnomacro\n" + "\tbal\t1f\n" + "\tnop\n" + "1:\taddiu\t%0,$31,12\n" + "\tjr.hb\t%0\n" + "\tnop\n" + "\t.set\tpop"; +} + [(set_attr "length" "20")]) + ;; Block moves, see mips.c for more details. ;; Argument 0 is the destination Index: testsuite/gcc.target/mips/flush-icache-2.c =================================================================== --- testsuite/gcc.target/mips/flush-icache-2.c (revision 0) +++ testsuite/gcc.target/mips/flush-icache-2.c (revision 0) @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -mips32" } */ +/* { dg-final { scan-assembler-not "synci" } } */ +/* { dg-final { scan-assembler-not "jr.hb" } } */ +/* { dg-final { scan-assembler "_flush_cache" } } */ + +void f() +{ + int size = 40; + char *memory = __builtin_alloca(size); + __builtin_flush_icache(memory, size); +} + Index: testsuite/gcc.target/mips/flush-icache-1.c =================================================================== --- testsuite/gcc.target/mips/flush-icache-1.c (revision 0) +++ testsuite/gcc.target/mips/flush-icache-1.c (revision 0) @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -mips32r2" } */ +/* { dg-final { scan-assembler "synci" } } */ +/* { dg-final { scan-assembler "jr.hb" } } */ +/* { dg-final { scan-assembler-not "_flush_cache" } } */ + +void f() +{ + int size = 40; + char *memory = __builtin_alloca(size); + __builtin_flush_icache(memory, size); +} + Index: testsuite/gcc.target/mips/flush-icache-3.c =================================================================== --- testsuite/gcc.target/mips/flush-icache-3.c (revision 0) +++ testsuite/gcc.target/mips/flush-icache-3.c (revision 0) @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -mips32r2" } */ +/* { dg-final { scan-assembler-not "synci" } } */ +/* { dg-final { scan-assembler-not "jr.hb" } } */ +/* { dg-final { scan-assembler-not "_flush_cache" } } */ + +void f() +{ + char *memory = __builtin_alloca(40); + __builtin_flush_icache(memory, 0); +} + --------------020405060105050705020403--