From patchwork Fri Jul 13 10:10:35 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chung-Lin Tang X-Patchwork-Id: 170836 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id C73B22C02EA for ; Fri, 13 Jul 2012 20:11:27 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1342779088; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC: Subject:Content-Type:Mailing-List:Precedence:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=abHt+I6KzSYOAoAwZoLXGkyywyM=; b=tmq0CJzdZeDBj3A E6auPvgXigfcd5KDcuR9XBNYlZGQiPRVuYrq7mq9lGiyukPax6pW+hDLzLNcCK8T /ZyEK1MurnY42jVAWM8spInMXg2A+hGrrBugTpgxcA6OWrl9WPbTE+VMnIsk/Bqe SQOQioIaaNO9MzDHouy7dUmwUWcg= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=XlkKAelznYKIz6uOlRI0EZb4A0Jdh+RwpBZsHVE9f524g9QSTjqDVAXGdacDWU LL6I0/tTBwTyCjl9vIPwyjCZkHOj5XLhiJsN78oIbWj0IFmvZ0L3afoA2qpp63qw iQV63je2KsL9aZnr0+kw/iMtpEBYWeL2f/Q9nnBVlVNd0=; Received: (qmail 21931 invoked by alias); 13 Jul 2012 10:11:16 -0000 Received: (qmail 21902 invoked by uid 22791); 13 Jul 2012 10:11:07 -0000 X-SWARE-Spam-Status: No, hits=-3.4 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 13 Jul 2012 10:10:48 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1Spcpj-0006XS-KM from ChungLin_Tang@mentor.com ; Fri, 13 Jul 2012 03:10:47 -0700 Received: from SVR-ORW-FEM-03.mgc.mentorg.com ([147.34.97.39]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Fri, 13 Jul 2012 03:09:52 -0700 Received: from [0.0.0.0] (147.34.91.1) by svr-orw-fem-03.mgc.mentorg.com (147.34.97.39) with Microsoft SMTP Server id 14.1.289.1; Fri, 13 Jul 2012 03:10:43 -0700 Message-ID: <4FFFF41B.7070803@codesourcery.com> Date: Fri, 13 Jul 2012 18:10:35 +0800 From: Chung-Lin Tang User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:13.0) Gecko/20120614 Thunderbird/13.0.1 MIME-Version: 1.0 To: gcc-patches CC: Richard Sandiford Subject: [PATCH][MIPS] NetLogic XLP scheduling X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi Richard, This patch adds scheduling support for the NetLogic XLP, including a new pipeline description, and associated changes. Asides from the new xlp.md description file, there are also some sync primitive attribute modifications, for better scheduling of sync loops (Maxim should be able to better explain this). Other generic changes include a new "hilo" insn attribute, to mark which of HI/LO does a m[ft]hilo insn access. Can you see if this is okay for trunk? Thanks, Chung-Lin From 014ff721a2e6cb96236dcf5e11d7f15c3b927386 Mon Sep 17 00:00:00 2001 From: Maxim Kuvyrkov Date: Mon, 18 Jun 2012 18:10:19 -0700 Subject: [PATCH] XLP scheduling. 2012-07-13 Chung-Lin Tang Maxim Kuvyrkov NetLogic Microsystems Inc. * config/mips/mips.md (define_attr "type"): New values "atomic" and "syncloop". (hilo): New attribute for indicating which of hi/lo accessed. (include xlp.md): New include. (mfhi_,mthi_): Set hilo" attribute. * config/mips/sync.md: Set "type" attribute for instructions. * config/mips/generic.md (generic_atomic, generic_syncloop): New reservations. * config/mips/xlp.md: New file. * config/mips/mips-proto.h (mips_hilo_use): Declare. * config/mips/mips.c (mips_issue_rate): Handle XLP. (mips_hilo_use): New function for computing "hilo" attribute. --- gcc/config/mips/generic.md | 16 +++ gcc/config/mips/mips-protos.h | 2 + gcc/config/mips/mips.c | 28 ++++++ gcc/config/mips/mips.md | 18 +++- gcc/config/mips/sync.md | 78 ++++++++++----- gcc/config/mips/xlp.md | 217 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 332 insertions(+), 27 deletions(-) create mode 100644 gcc/config/mips/xlp.md diff --git a/gcc/config/mips/generic.md b/gcc/config/mips/generic.md index d61511f..02b1d8b 100644 --- a/gcc/config/mips/generic.md +++ b/gcc/config/mips/generic.md @@ -103,3 +103,19 @@ (define_insn_reservation "generic_frecip_fsqrt_step" 5 (eq_attr "type" "frdiv1,frdiv2,frsqrt1,frsqrt2") "alu") + +(define_insn_reservation "generic_atomic" 10 + (eq_attr "type" "atomic") + "alu") + +;; Sync loop consists of (in order) +;; (1) optional sync, +;; (2) LL instruction, +;; (3) branch and 1-2 ALU instructions, +;; (4) SC instruction, +;; (5) branch and ALU instruction. +;; The net result of this reservation is a big delay with a flush of +;; ALU pipeline. +(define_insn_reservation "generic_sync_loop" 40 + (eq_attr "type" "syncloop") + "alu*39") diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index d1fa160..1b1cbcb 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -334,6 +334,8 @@ extern void mips_final_prescan_insn (rtx, rtx *, int); extern int mips_trampoline_code_size (void); extern void mips_function_profiler (FILE *); +extern int mips_hilo_use (rtx); + typedef rtx (*mulsidi3_gen_fn) (rtx, rtx, rtx); #ifdef RTX_CODE extern mulsidi3_gen_fn mips_mulsidi3_gen_fn (enum rtx_code); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 7356ce5..f46eb49 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -12480,6 +12480,9 @@ mips_issue_rate (void) case PROCESSOR_LOONGSON_3A: return 4; + case PROCESSOR_XLP: + return (reload_completed ? 4 : 3); + default: return 1; } @@ -17407,6 +17410,31 @@ mips_expand_vec_minmax (rtx target, rtx op0, rtx op1, x = gen_rtx_IOR (vmode, t0, t1); emit_insn (gen_rtx_SET (VOIDmode, target, x)); } + +/* Determine HI/LO access on INSN, return 1 for HI, -1 for LO, + and 0 for no access. Used for determining "hilo" attribute. */ + +int +mips_hilo_use (rtx insn) +{ + rtx pat, dest, src; + enum attr_type insn_type; + + if (! (pat = single_set (insn))) + return 0; + + insn_type = get_attr_type (insn); + dest = SET_DEST (pat); + src = SET_SRC (pat); + + if ((insn_type == TYPE_MTHILO && REGNO (dest) == HI_REGNUM) + || (insn_type == TYPE_MFHILO && REGNO (src) == HI_REGNUM)) + return 1; + if ((insn_type == TYPE_MTHILO && REGNO (dest) == LO_REGNUM) + || (insn_type == TYPE_MFHILO && REGNO (src) == LO_REGNUM)) + return -1; + return 0; +} /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 5b1735f..d2a304e 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -274,6 +274,8 @@ ;; frsqrt1 floating point reciprocal square root step1 ;; frsqrt2 floating point reciprocal square root step2 ;; multi multiword sequence (or user asm statements) +;; atomic atomic memory update instruction +;; sync_loop memory atomic operation implemented as a sync loop ;; nop no operation ;; ghost an instruction that produces no real code (define_attr "type" @@ -281,7 +283,7 @@ prefetch,prefetchx,condmove,mtc,mfc,mthilo,mfhilo,const,arith,logical, shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move, fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt, - frsqrt,frsqrt1,frsqrt2,multi,nop,ghost" + frsqrt,frsqrt1,frsqrt2,multi,atomic,syncloop,nop,ghost" (cond [(eq_attr "jal" "!unset") (const_string "call") (eq_attr "got" "load") (const_string "load") @@ -589,6 +591,17 @@ (const_string "yes") (const_string "no"))) +;; For mfhilo/mthilo insns, determine which of hi or lo is the operand +(define_attr "hilo" "hi,lo,none" + (cond [(and (eq_attr "type" "mthilo,mfhilo") + (gt (symbol_ref "mips_hilo_use (insn)") (const_int 0))) + (const_string "hi") + + (and (eq_attr "type" "mthilo,mfhilo") + (lt (symbol_ref "mips_hilo_use (insn)") (const_int 0))) + (const_string "lo")] + (const_string "none"))) + ;; Describe a user's asm statement. (define_asm_attributes [(set_attr "type" "multi") @@ -936,6 +949,7 @@ (include "sb1.md") (include "sr71k.md") (include "xlr.md") +(include "xlp.md") (include "generic.md") ;; @@ -4735,6 +4749,7 @@ "" { return ISA_HAS_MACCHI ? "macchi\t%0,%.,%." : "mfhi\t%0"; } [(set_attr "move_type" "mfhilo") + (set_attr "hilo" "hi") (set_attr "mode" "")]) ;; Set the high part of a HI/LO value, given that the low part has @@ -4748,6 +4763,7 @@ "" "mthi\t%z1" [(set_attr "move_type" "mthilo") + (set_attr "hilo" "hi") (set_attr "mode" "SI")]) ;; Emit a doubleword move in which exactly one of the operands is diff --git a/gcc/config/mips/sync.md b/gcc/config/mips/sync.md index 0a7905a..6585d91 100644 --- a/gcc/config/mips/sync.md +++ b/gcc/config/mips/sync.md @@ -99,7 +99,8 @@ UNSPEC_COMPARE_AND_SWAP_12))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_oldval" "0") + [(set_attr "type" "syncloop") + (set_attr "sync_oldval" "0") (set_attr "sync_mem" "1") (set_attr "sync_inclusive_mask" "2") (set_attr "sync_exclusive_mask" "3") @@ -114,7 +115,8 @@ UNSPEC_SYNC_OLD_OP))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "addiu,addu") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "addiu,addu") (set_attr "sync_mem" "0") (set_attr "sync_insn1_op2" "1")]) @@ -145,7 +147,8 @@ (clobber (match_scratch:SI 4 "=&d"))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "") (set_attr "sync_insn2" "and") (set_attr "sync_mem" "0") (set_attr "sync_inclusive_mask" "1") @@ -186,7 +189,8 @@ (clobber (match_scratch:SI 5 "=&d"))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "") (set_attr "sync_insn2" "and") (set_attr "sync_oldval" "0") (set_attr "sync_mem" "1") @@ -232,7 +236,8 @@ (match_dup 4)] UNSPEC_SYNC_NEW_OP_12))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "") (set_attr "sync_insn2" "and") (set_attr "sync_oldval" "0") (set_attr "sync_newval" "0") @@ -268,7 +273,8 @@ (clobber (match_scratch:SI 4 "=&d"))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "and") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "and") (set_attr "sync_insn2" "xor") (set_attr "sync_mem" "0") (set_attr "sync_inclusive_mask" "1") @@ -307,7 +313,8 @@ (clobber (match_scratch:SI 5 "=&d"))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "and") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "and") (set_attr "sync_insn2" "xor") (set_attr "sync_oldval" "0") (set_attr "sync_mem" "1") @@ -351,7 +358,8 @@ (match_dup 4)] UNSPEC_SYNC_NEW_OP_12))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "and") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "and") (set_attr "sync_insn2" "xor") (set_attr "sync_oldval" "0") (set_attr "sync_newval" "0") @@ -368,7 +376,8 @@ UNSPEC_SYNC_OLD_OP))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "subu") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "subu") (set_attr "sync_mem" "0") (set_attr "sync_insn1_op2" "1")]) @@ -383,7 +392,8 @@ UNSPEC_SYNC_OLD_OP))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "addiu,addu") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "addiu,addu") (set_attr "sync_oldval" "0") (set_attr "sync_mem" "1") (set_attr "sync_insn1_op2" "2")]) @@ -398,7 +408,8 @@ UNSPEC_SYNC_OLD_OP))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "subu") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "subu") (set_attr "sync_oldval" "0") (set_attr "sync_mem" "1") (set_attr "sync_insn1_op2" "2")]) @@ -413,7 +424,8 @@ UNSPEC_SYNC_NEW_OP))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "addiu,addu") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "addiu,addu") (set_attr "sync_oldval" "0") (set_attr "sync_newval" "0") (set_attr "sync_mem" "1") @@ -429,7 +441,8 @@ UNSPEC_SYNC_NEW_OP))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "subu") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "subu") (set_attr "sync_oldval" "0") (set_attr "sync_newval" "0") (set_attr "sync_mem" "1") @@ -443,7 +456,8 @@ UNSPEC_SYNC_OLD_OP))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" ",") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" ",") (set_attr "sync_mem" "0") (set_attr "sync_insn1_op2" "1")]) @@ -457,7 +471,8 @@ UNSPEC_SYNC_OLD_OP))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" ",") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" ",") (set_attr "sync_oldval" "0") (set_attr "sync_mem" "1") (set_attr "sync_insn1_op2" "2")]) @@ -472,7 +487,8 @@ UNSPEC_SYNC_NEW_OP))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" ",") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" ",") (set_attr "sync_oldval" "0") (set_attr "sync_newval" "0") (set_attr "sync_mem" "1") @@ -484,7 +500,8 @@ UNSPEC_SYNC_OLD_OP))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "andi,and") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "andi,and") (set_attr "sync_insn2" "not") (set_attr "sync_mem" "0") (set_attr "sync_insn1_op2" "1")]) @@ -497,7 +514,8 @@ UNSPEC_SYNC_OLD_OP))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "andi,and") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "andi,and") (set_attr "sync_insn2" "not") (set_attr "sync_oldval" "0") (set_attr "sync_mem" "1") @@ -511,7 +529,8 @@ UNSPEC_SYNC_NEW_OP))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "andi,and") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "andi,and") (set_attr "sync_insn2" "not") (set_attr "sync_oldval" "0") (set_attr "sync_newval" "0") @@ -526,7 +545,8 @@ UNSPEC_SYNC_EXCHANGE))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_memmodel" "11") + [(set_attr "type" "syncloop") + (set_attr "sync_memmodel" "11") (set_attr "sync_insn1" "li,move") (set_attr "sync_oldval" "0") (set_attr "sync_mem" "1") @@ -555,7 +575,8 @@ UNSPEC_SYNC_EXCHANGE_12))] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_memmodel" "11") + [(set_attr "type" "syncloop") + (set_attr "sync_memmodel" "11") (set_attr "sync_oldval" "0") (set_attr "sync_mem" "1") ;; Unused, but needed to give the number of operands expected by @@ -594,7 +615,8 @@ UNSPEC_ATOMIC_COMPARE_AND_SWAP)] "GENERATE_LL_SC" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "li,move") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "li,move") (set_attr "sync_oldval" "1") (set_attr "sync_cmp" "0") (set_attr "sync_mem" "2") @@ -639,7 +661,8 @@ UNSPEC_ATOMIC_EXCHANGE)] "GENERATE_LL_SC && !ISA_HAS_SWAP" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "li,move") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "li,move") (set_attr "sync_oldval" "0") (set_attr "sync_mem" "1") (set_attr "sync_insn1_op2" "2") @@ -654,7 +677,8 @@ (unspec_volatile:GPR [(match_operand:GPR 2 "register_operand" "0")] UNSPEC_ATOMIC_EXCHANGE))] "ISA_HAS_SWAP" - "swap\t%0,%b1") + "swap\t%0,%b1" + [(set_attr "type" "atomic")]) (define_expand "atomic_fetch_add" [(match_operand:GPR 0 "register_operand") @@ -695,7 +719,8 @@ UNSPEC_ATOMIC_FETCH_OP)] "GENERATE_LL_SC && !ISA_HAS_LDADD" { return mips_output_sync_loop (insn, operands); } - [(set_attr "sync_insn1" "addiu,addu") + [(set_attr "type" "syncloop") + (set_attr "sync_insn1" "addiu,addu") (set_attr "sync_oldval" "0") (set_attr "sync_mem" "1") (set_attr "sync_insn1_op2" "2") @@ -712,4 +737,5 @@ (match_operand:GPR 2 "register_operand" "0"))] UNSPEC_ATOMIC_FETCH_OP))] "ISA_HAS_LDADD" - "ldadd\t%0,%b1") + "ldadd\t%0,%b1" + [(set_attr "type" "atomic")]) diff --git a/gcc/config/mips/xlp.md b/gcc/config/mips/xlp.md new file mode 100644 index 0000000..e57133f --- /dev/null +++ b/gcc/config/mips/xlp.md @@ -0,0 +1,217 @@ +;; DFA-based pipeline description for the XLP. +;; Copyright (C) 2012 Free Software Foundation, Inc. +;; +;; xlp.md Machine Description for the Broadcom XLP Microprocessor +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "xlp_cpu") + +;; CPU function units. +(define_cpu_unit "xlp_ex0" "xlp_cpu") +(define_cpu_unit "xlp_ex1" "xlp_cpu") +(define_cpu_unit "xlp_ex2" "xlp_cpu") +(define_cpu_unit "xlp_ex3" "xlp_cpu") + +;; Integer Multiply Unit +(define_cpu_unit "xlp_div" "xlp_cpu") + +;; ALU2 completion port. +(define_cpu_unit "xlp_ex2_wrb" "xlp_cpu") + +(define_automaton "xlp_fpu") + +;; Floating-point units. +(define_cpu_unit "xlp_fp" "xlp_fpu") + +;; Floating Point Sqrt/Divide +(define_cpu_unit "xlp_divsq" "xlp_fpu") + +;; FPU completion port. +(define_cpu_unit "xlp_fp_wrb" "xlp_fpu") + +;; Define reservations for common combinations. + +;; +;; The ordering of the instruction-execution-path/resource-usage +;; descriptions (also known as reservation RTL) is roughly ordered +;; based on the define attribute RTL for the "type" classification. +;; When modifying, remember that the first test that matches is the +;; reservation used! +;; +(define_insn_reservation "ir_xlp_unknown" 1 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "unknown,multi")) + "xlp_ex0+xlp_ex1+xlp_ex2+xlp_ex3") + +(define_insn_reservation "ir_xlp_branch" 1 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "branch,jump,call")) + "xlp_ex3") + +(define_insn_reservation "ir_xlp_prefetch" 1 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "prefetch,prefetchx")) + "xlp_ex0|xlp_ex1") + +(define_insn_reservation "ir_xlp_load" 4 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "load")) + "xlp_ex0|xlp_ex1") + +(define_insn_reservation "ir_xlp_fpload" 5 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "fpload,fpidxload")) + "xlp_ex0|xlp_ex1") + +(define_insn_reservation "ir_xlp_alu" 1 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "const,arith,shift,slt,clz,signext,logical,move,trap,nop")) + "xlp_ex0|xlp_ex1|(xlp_ex2,xlp_ex2_wrb)|xlp_ex3") + +(define_insn_reservation "ir_xlp_condmov" 1 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "condmove") + (eq_attr "mode" "SI,DI")) + "xlp_ex2,xlp_ex2_wrb") + +(define_insn_reservation "ir_xlp_mul" 5 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "imul,imadd")) + "xlp_ex2,nothing*4,xlp_ex2_wrb") + +(define_insn_reservation "ir_xlp_mul3" 3 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "imul3")) + "xlp_ex2,nothing*2,xlp_ex2_wrb") + +(define_insn_reservation "ir_xlp_div" 24 + (and (eq_attr "cpu" "xlp") + (eq_attr "mode" "SI") + (eq_attr "type" "idiv")) + "xlp_ex2+xlp_div,xlp_div*23,xlp_ex2_wrb") + +(define_insn_reservation "ir_xlp_ddiv" 48 + (and (eq_attr "cpu" "xlp") + (eq_attr "mode" "DI") + (eq_attr "type" "idiv")) + "xlp_ex2+xlp_div,xlp_div*47,xlp_ex2_wrb") + +(define_insn_reservation "ir_xlp_store" 1 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "store,fpstore,fpidxstore")) + "xlp_ex0|xlp_ex1") + +(define_insn_reservation "ir_xlp_fpmove" 2 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "mfc")) + "xlp_ex3,xlp_fp,xlp_fp_wrb") + +(define_insn_reservation "ir_xlp_mfhi" 1 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "mfhilo") + (eq_attr "hilo" "hi")) + "xlp_ex2,xlp_ex2_wrb") + +(define_insn_reservation "ir_xlp_mflo" 1 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "mfhilo") + (eq_attr "hilo" "lo")) + "xlp_ex2,xlp_ex2_wrb") + +(define_insn_reservation "ir_xlp_mthi" 1 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "mthilo") + (eq_attr "hilo" "hi")) + "xlp_ex2,xlp_ex2_wrb") + +(define_insn_reservation "ir_xlp_mtlo" 3 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "mthilo") + (eq_attr "hilo" "lo")) + "xlp_ex2,nothing*2,xlp_ex2_wrb") + +(define_insn_reservation "ir_xlp_fp2" 2 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "fmove,fneg,fabs,condmove")) + "xlp_fp,nothing,xlp_fp_wrb") + +(define_insn_reservation "ir_xlp_fp3" 3 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "fcmp")) + "xlp_fp,nothing*2,xlp_fp_wrb") + +(define_insn_reservation "ir_xlp_fp4" 4 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "fcvt")) + "xlp_fp,nothing*3,xlp_fp_wrb") + +(define_insn_reservation "ir_xlp_fp5" 5 + (and (eq_attr "cpu" "xlp") + (eq_attr "mode" "SF") + (eq_attr "type" "fadd,fmul")) + "xlp_fp,nothing*4,xlp_fp_wrb") + +(define_insn_reservation "ir_xlp_fp6" 6 + (and (eq_attr "cpu" "xlp") + (eq_attr "mode" "DF") + (eq_attr "type" "fadd,fmul")) + "xlp_fp,nothing*5,xlp_fp_wrb") + +(define_insn_reservation "ir_xlp_fp9" 9 + (and (eq_attr "cpu" "xlp") + (eq_attr "mode" "SF") + (eq_attr "type" "fmadd")) + "xlp_fp,nothing*3,xlp_fp,nothing*3,xlp_fp_wrb") + +(define_insn_reservation "ir_xlp_fp11" 11 + (and (eq_attr "cpu" "xlp") + (eq_attr "mode" "DF") + (eq_attr "type" "fmadd")) + "xlp_fp,nothing*4,xlp_fp,nothing*4,xlp_fp_wrb") + +(define_insn_reservation "ir_xlp_fpcomplex_s" 23 + (and (eq_attr "cpu" "xlp") + (eq_attr "mode" "SF") + (eq_attr "type" "fdiv,frdiv,frdiv1,frdiv2,fsqrt,frsqrt,frsqrt1,frsqrt2")) + "xlp_fp+xlp_divsq,xlp_divsq*22,xlp_fp_wrb") + +(define_insn_reservation "ir_xlp_fpcomplex_d" 38 + (and (eq_attr "cpu" "xlp") + (eq_attr "mode" "DF") + (eq_attr "type" "fdiv,frdiv,frdiv1,frdiv2,fsqrt,frsqrt,frsqrt1,frsqrt2")) + "xlp_fp+xlp_divsq,xlp_divsq*37,xlp_fp_wrb") + +(define_bypass 3 "ir_xlp_mul" "ir_xlp_mfhi") + +(define_insn_reservation "ir_xlp_atomic" 15 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "atomic")) + "xlp_ex0|xlp_ex1") + +;; Sync loop consists of (in order) +;; (1) optional sync, +;; (2) LL instruction, +;; (3) branch and 1-2 ALU instructions, +;; (4) SC instruction, +;; (5) optional sync, +;; (6) branch and ALU instruction. +;; The net result of this reservation is a big delay with flush of +;; ALU pipeline and outgoing reservations discouraging use of EX3. +(define_insn_reservation "ir_xlp_sync_loop" 40 + (and (eq_attr "cpu" "xlp") + (eq_attr "type" "syncloop")) + "(xlp_ex0+xlp_ex1+xlp_ex2+xlp_ex3)*39,xlp_ex3+(xlp_ex0|xlp_ex1|(xlp_ex2,xlp_ex2_wrb))")