const char *
mips_emit_prefetch (rtx *operands)
{
- /* For the mips32/64 architectures the hint fields are arranged
- by operation (load/store) and locality (normal/streamed/retained).
- Irritatingly, numbers 2 and 3 are reserved leaving no simple
- algorithm for figuring the hint. */
-
int write = INTVAL (operands[1]);
int locality = INTVAL (operands[2]);
+ int indexed = GET_CODE (operands[3]) == REG;
+ int code;
+ char buffer[30];
+
+ if (locality <= 0)
+ code = (write ? 5 : 4); /* store_streamed / load_streamed. */
+ else if (locality <= 2)
+ code = (write ? 1 : 0); /* store / load. */
+ else
+ code = (write ? 7 : 6); /* store_retained / load_retained. */
- static const char * const alt[2][4] = {
- {
- "pref\t4,%3(%0)",
- "pref\t0,%3(%0)",
- "pref\t0,%3(%0)",
- "pref\t6,%3(%0)"
- },
- {
- "pref\t5,%3(%0)",
- "pref\t1,%3(%0)",
- "pref\t1,%3(%0)",
- "pref\t7,%3(%0)"
- }
- };
-
- return alt[write][locality];
+ sprintf (buffer, "%s\t%d,%%3(%%0)", indexed ? "prefx" : "pref", code);
+ output_asm_insn (buffer, operands);
+ return "";
}
|| ISA_MIPS32R2 \
|| ISA_MIPS64)
-/* This is a catch all for the other new mips4 instructions: indexed load and
- indexed prefetch instructions, the FP madd and msub instructions,
- and the FP recip and recip sqrt instructions */
+/* This is a catch all for other mips4 instructions: indexed load, the
+ FP madd and msub instructions, and the FP recip and recip sqrt
+ instructions. */
#define ISA_HAS_FP4 ((ISA_MIPS4 \
|| ISA_MIPS64) \
&& !TARGET_MIPS16)
|| TARGET_SR71K \
))
-/* ISA has data prefetch instruction. */
+/* ISA has data prefetch instructions. This controls use of 'pref'. */
#define ISA_HAS_PREFETCH ((ISA_MIPS4 \
|| ISA_MIPS32 \
|| ISA_MIPS32R2 \
|| ISA_MIPS64) \
&& !TARGET_MIPS16)
+/* ISA has data indexed prefetch instructions. This controls use of
+ 'prefx', along with TARGET_HARD_FLOAT and TARGET_DOUBLE_FLOAT.
+ (prefx is a cop1x instruction, so can only be used if FP is
+ enabled.) */
+#define ISA_HAS_PREFETCHX ((ISA_MIPS4 \
+ || ISA_MIPS64) \
+ && !TARGET_MIPS16)
+
/* True if trunc.w.s and trunc.w.d are real (not synthetic)
instructions. Both require TARGET_HARD_FLOAT, and trunc.w.d
also requires TARGET_DOUBLE_FLOAT. */
;; call unconditional call
;; load load instruction(s)
;; store store instruction(s)
-;; prefetch memory prefetch
+;; prefetch memory prefetch (register + offset)
+;; prefetchx memory indexed prefetch (register + register)
;; move data movement within same register set
;; condmove conditional moves
;; xfer transfer to/from coprocessor
;; multi multiword sequence (or user asm statements)
;; nop no operation
(define_attr "type"
- "unknown,branch,jump,call,load,store,prefetch,move,condmove,xfer,hilo,const,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
+ "unknown,branch,jump,call,load,store,prefetch,prefetchx,move,condmove,xfer,hilo,const,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
(cond [(eq_attr "jal" "!unset")
(const_string "call")]
(const_string "unknown")))
{ return mips_emit_prefetch (operands); }
[(set_attr "type" "prefetch")])
+(define_insn "prefetch_indexed_si"
+ [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
+ (match_operand:SI 3 "register_operand" "r"))
+ (match_operand:SI 1 "const_int_operand" "n")
+ (match_operand:SI 2 "const_int_operand" "n"))]
+ "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
+ { return mips_emit_prefetch (operands); }
+ [(set_attr "type" "prefetchx")])
+
(define_insn "prefetch_si"
[(prefetch (match_operand:SI 0 "register_operand" "r")
(match_operand:SI 1 "const_int_operand" "n")
{ return mips_emit_prefetch (operands); }
[(set_attr "type" "prefetch")])
+(define_insn "prefetch_indexed_di"
+ [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
+ (match_operand:DI 3 "register_operand" "r"))
+ (match_operand:DI 1 "const_int_operand" "n")
+ (match_operand:DI 2 "const_int_operand" "n"))]
+ "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
+ { return mips_emit_prefetch (operands); }
+ [(set_attr "type" "prefetchx")])
+
(define_insn "prefetch_di"
[(prefetch (match_operand:DI 0 "register_operand" "r")
(match_operand:DI 1 "const_int_operand" "n")