mips.h (ISA_HAS_SYNCI): New target capability predicate.
2007-07-10 David Daney <ddaney@avtrex.com> * config/mips/mips.h (ISA_HAS_SYNCI): New target capability predicate. (INITIALIZE_TRAMPOLINE): Emit clear_cache insn instead of library call. * config/mips/mips.c (mips_expand_synci_loop): New function. * config/mips/mips.md (UNSPEC_CLEAR_HAZARD): New constant. (UNSPEC_RDHWR): Same. (UNSPEC_SYNCI): Same. (UNSPEC_SYNC): Same. (clear_cache): New expand. (sync): New insn. (synci): Same. (rdhwr): Same. (clear_hazard): Same. * config/mips/mips-protos.h (mips_expand_synci_loop): Declare function. * testsuite/gcc.target/mips/clear-cache-1.c: New test. * testsuite/gcc.target/mips/clear-cache-2.c: New test. From-SVN: r126537
This commit is contained in:
parent
f8335a4ff0
commit
df770e0442
7 changed files with 152 additions and 11 deletions
|
@ -1,3 +1,24 @@
|
|||
2007-07-10 David Daney <ddaney@avtrex.com>
|
||||
|
||||
* config/mips/mips.h (ISA_HAS_SYNCI): New target capability
|
||||
predicate.
|
||||
(INITIALIZE_TRAMPOLINE): Emit clear_cache insn instead of library
|
||||
call.
|
||||
* config/mips/mips.c (mips_expand_synci_loop): New function.
|
||||
* config/mips/mips.md (UNSPEC_CLEAR_HAZARD): New constant.
|
||||
(UNSPEC_RDHWR): Same.
|
||||
(UNSPEC_SYNCI): Same.
|
||||
(UNSPEC_SYNC): Same.
|
||||
(clear_cache): New expand.
|
||||
(sync): New insn.
|
||||
(synci): Same.
|
||||
(rdhwr): Same.
|
||||
(clear_hazard): Same.
|
||||
* config/mips/mips-protos.h (mips_expand_synci_loop): Declare
|
||||
function.
|
||||
* testsuite/gcc.target/mips/clear-cache-1.c: New test.
|
||||
* testsuite/gcc.target/mips/clear-cache-2.c: New test.
|
||||
|
||||
2007-07-10 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* emit-rtl.c (gen_reg_rtx): Check can_create_pseudo_p rather than
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Prototypes of target machine for GNU compiler. MIPS version.
|
||||
Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
1999, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
|
||||
Contributed by A. Lichnewsky (lich@inria.inria.fr).
|
||||
Changed by Michael Meissner (meissner@osf.org).
|
||||
64-bit r4000 support by Ian Lance Taylor (ian@cygnus.com) and
|
||||
|
@ -187,6 +187,7 @@ extern void mips_expand_call (rtx, rtx, rtx, rtx, int);
|
|||
extern void mips_emit_fcc_reload (rtx, rtx, rtx);
|
||||
extern void mips_set_return_address (rtx, rtx);
|
||||
extern bool mips_expand_block_move (rtx, rtx, rtx);
|
||||
extern void mips_expand_synci_loop (rtx, rtx);
|
||||
|
||||
extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx);
|
||||
extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
|
|
|
@ -3883,6 +3883,33 @@ mips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length)
|
|||
mips_block_move_straight (dest, src, leftover);
|
||||
}
|
||||
|
||||
|
||||
/* Expand a loop of synci insns for the address range [BEGIN, END). */
|
||||
|
||||
void
|
||||
mips_expand_synci_loop (rtx begin, rtx end)
|
||||
{
|
||||
rtx inc, label, cmp, cmp_result;
|
||||
|
||||
/* Load INC with the cache line size (rdhwr INC,$1). */
|
||||
inc = gen_reg_rtx (SImode);
|
||||
emit_insn (gen_rdhwr (inc, const1_rtx));
|
||||
|
||||
/* Loop back to here. */
|
||||
label = gen_label_rtx ();
|
||||
emit_label (label);
|
||||
|
||||
emit_insn (gen_synci (begin));
|
||||
|
||||
cmp = gen_reg_rtx (Pmode);
|
||||
mips_emit_binary (GTU, cmp, begin, end);
|
||||
|
||||
mips_emit_binary (PLUS, begin, begin, inc);
|
||||
|
||||
cmp_result = gen_rtx_EQ (VOIDmode, cmp, const0_rtx);
|
||||
emit_jump_insn (gen_condjump (cmp_result, label));
|
||||
}
|
||||
|
||||
/* Expand a movmemsi instruction. */
|
||||
|
||||
bool
|
||||
|
|
|
@ -804,6 +804,10 @@ extern const struct mips_rtx_cost_data *mips_cost;
|
|||
|| ISA_MIPS32R2 \
|
||||
|| ISA_MIPS64 \
|
||||
|| TARGET_MIPS5500)
|
||||
|
||||
/* ISA includes synci, jr.hb and jalr.hb. */
|
||||
#define ISA_HAS_SYNCI ISA_MIPS32R2
|
||||
|
||||
|
||||
/* Add -G xx support. */
|
||||
|
||||
|
@ -2151,21 +2155,16 @@ typedef struct mips_args {
|
|||
|
||||
#define INITIALIZE_TRAMPOLINE(ADDR, FUNC, CHAIN) \
|
||||
{ \
|
||||
rtx func_addr, chain_addr; \
|
||||
rtx func_addr, chain_addr, end_addr; \
|
||||
\
|
||||
func_addr = plus_constant (ADDR, 32); \
|
||||
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)); \
|
||||
end_addr = gen_reg_rtx (Pmode); \
|
||||
emit_insn (gen_add3_insn (end_addr, copy_rtx (ADDR), \
|
||||
GEN_INT (TRAMPOLINE_SIZE))); \
|
||||
emit_insn (gen_clear_cache (copy_rtx (ADDR), end_addr)); \
|
||||
}
|
||||
|
||||
/* Addressing modes, and classification of registers for them. */
|
||||
|
|
|
@ -50,6 +50,10 @@
|
|||
(UNSPEC_TLS_GET_TP 28)
|
||||
(UNSPEC_MFHC1 31)
|
||||
(UNSPEC_MTHC1 32)
|
||||
(UNSPEC_CLEAR_HAZARD 33)
|
||||
(UNSPEC_RDHWR 34)
|
||||
(UNSPEC_SYNCI 35)
|
||||
(UNSPEC_SYNC 36)
|
||||
|
||||
(UNSPEC_ADDRESS_FIRST 100)
|
||||
|
||||
|
@ -4221,6 +4225,69 @@
|
|||
}
|
||||
[(set_attr "type" "store")
|
||||
(set_attr "length" "4,12")])
|
||||
|
||||
;; Expand in-line code to clear the instruction cache between operand[0] and
|
||||
;; operand[1].
|
||||
(define_expand "clear_cache"
|
||||
[(match_operand 0 "pmode_register_operand")
|
||||
(match_operand 1 "pmode_register_operand")]
|
||||
""
|
||||
"
|
||||
{
|
||||
if (ISA_HAS_SYNCI)
|
||||
{
|
||||
mips_expand_synci_loop (operands[0], operands[1]);
|
||||
emit_insn (gen_sync ());
|
||||
emit_insn (gen_clear_hazard ());
|
||||
}
|
||||
else if (mips_cache_flush_func && mips_cache_flush_func[0])
|
||||
{
|
||||
rtx len = gen_reg_rtx (Pmode);
|
||||
emit_insn (gen_sub3_insn (len, operands[1], operands[0]));
|
||||
/* Flush both caches. We need to flush the data cache in case
|
||||
the system has a write-back cache. */
|
||||
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mips_cache_flush_func),
|
||||
0, VOIDmode, 3, operands[0], Pmode,
|
||||
len, TYPE_MODE (integer_type_node),
|
||||
GEN_INT (3), TYPE_MODE (integer_type_node));
|
||||
}
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn "sync"
|
||||
[(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
|
||||
"ISA_HAS_SYNCI"
|
||||
"sync")
|
||||
|
||||
(define_insn "synci"
|
||||
[(unspec_volatile [(match_operand 0 "pmode_register_operand" "d")]
|
||||
UNSPEC_SYNCI)]
|
||||
"ISA_HAS_SYNCI"
|
||||
"synci\t0(%0)")
|
||||
|
||||
(define_insn "rdhwr"
|
||||
[(set (match_operand:SI 0 "general_operand" "=d")
|
||||
(unspec_volatile [(match_operand:SI 1 "const_int_operand" "n")]
|
||||
UNSPEC_RDHWR))]
|
||||
"ISA_HAS_SYNCI"
|
||||
"rdhwr\t%0,$%1")
|
||||
|
||||
(define_insn "clear_hazard"
|
||||
[(unspec_volatile [(const_int 0)] 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$31,$31,12\n"
|
||||
"\tjr.hb\t$31\n"
|
||||
"\tnop\n"
|
||||
"\t.set\tpop";
|
||||
}
|
||||
[(set_attr "length" "20")])
|
||||
|
||||
;; Block moves, see mips.c for more details.
|
||||
;; Argument 0 is the destination
|
||||
|
|
13
gcc/testsuite/gcc.target/mips/clear-cache-1.c
Normal file
13
gcc/testsuite/gcc.target/mips/clear-cache-1.c
Normal file
|
@ -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___clear_cache(memory, memory + size);
|
||||
}
|
||||
|
13
gcc/testsuite/gcc.target/mips/clear-cache-2.c
Normal file
13
gcc/testsuite/gcc.target/mips/clear-cache-2.c
Normal file
|
@ -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___clear_cache(memory, memory + size);
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue