1;; Pipeline model for ST Microelectronics Loongson-2E/2F cores. 2 3;; Copyright (C) 2008-2015 Free Software Foundation, Inc. 4;; Contributed by CodeSourcery. 5;; 6;; GCC is free software; you can redistribute it and/or modify 7;; it under the terms of the GNU General Public License as published by 8;; the Free Software Foundation; either version 3, or (at your option) 9;; any later version. 10;; 11;; GCC is distributed in the hope that it will be useful, 12;; but WITHOUT ANY WARRANTY; without even the implied warranty of 13;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14;; GNU General Public License for more details. 15;; 16;; You should have received a copy of the GNU General Public License 17;; along with GCC; see the file COPYING3. If not see 18;; <http://www.gnu.org/licenses/>. 19 20(define_c_enum "unspec" [ 21 UNSPEC_LOONGSON_ALU1_TURN_ENABLED_INSN 22 UNSPEC_LOONGSON_ALU2_TURN_ENABLED_INSN 23 UNSPEC_LOONGSON_FALU1_TURN_ENABLED_INSN 24 UNSPEC_LOONGSON_FALU2_TURN_ENABLED_INSN 25]) 26 27;; Automaton for integer instructions. 28(define_automaton "ls2_alu") 29 30;; ALU1 and ALU2. 31;; We need to query these units to adjust round-robin counter. 32(define_query_cpu_unit "ls2_alu1_core,ls2_alu2_core" "ls2_alu") 33 34;; Pseudo units to help modeling of ALU1/2 round-robin dispatch strategy. 35(define_cpu_unit "ls2_alu1_turn,ls2_alu2_turn" "ls2_alu") 36 37;; Pseudo units to enable/disable ls2_alu[12]_turn units. 38;; ls2_alu[12]_turn unit can be subscribed only after ls2_alu[12]_turn_enabled 39;; unit is subscribed. 40(define_cpu_unit "ls2_alu1_turn_enabled,ls2_alu2_turn_enabled" "ls2_alu") 41(presence_set "ls2_alu1_turn" "ls2_alu1_turn_enabled") 42(presence_set "ls2_alu2_turn" "ls2_alu2_turn_enabled") 43 44;; Reservations for ALU1 (ALU2) instructions. 45;; Instruction goes to ALU1 (ALU2) and makes next ALU1/2 instruction to 46;; be dispatched to ALU2 (ALU1). 47(define_reservation "ls2_alu1" 48 "(ls2_alu1_core+ls2_alu2_turn_enabled)|ls2_alu1_core") 49(define_reservation "ls2_alu2" 50 "(ls2_alu2_core+ls2_alu1_turn_enabled)|ls2_alu2_core") 51 52;; Reservation for ALU1/2 instructions. 53;; Instruction will go to ALU1 iff ls2_alu1_turn_enabled is subscribed and 54;; switch the turn to ALU2 by subscribing ls2_alu2_turn_enabled. 55;; Or to ALU2 otherwise. 56(define_reservation "ls2_alu" 57 "(ls2_alu1_core+ls2_alu1_turn+ls2_alu2_turn_enabled) 58 |(ls2_alu1_core+ls2_alu1_turn) 59 |(ls2_alu2_core+ls2_alu2_turn+ls2_alu1_turn_enabled) 60 |(ls2_alu2_core+ls2_alu2_turn)") 61 62;; Automaton for floating-point instructions. 63(define_automaton "ls2_falu") 64 65;; FALU1 and FALU2. 66;; We need to query these units to adjust round-robin counter. 67(define_query_cpu_unit "ls2_falu1_core,ls2_falu2_core" "ls2_falu") 68 69;; Pseudo units to help modeling of FALU1/2 round-robin dispatch strategy. 70(define_cpu_unit "ls2_falu1_turn,ls2_falu2_turn" "ls2_falu") 71 72;; Pseudo units to enable/disable ls2_falu[12]_turn units. 73;; ls2_falu[12]_turn unit can be subscribed only after 74;; ls2_falu[12]_turn_enabled unit is subscribed. 75(define_cpu_unit "ls2_falu1_turn_enabled,ls2_falu2_turn_enabled" "ls2_falu") 76(presence_set "ls2_falu1_turn" "ls2_falu1_turn_enabled") 77(presence_set "ls2_falu2_turn" "ls2_falu2_turn_enabled") 78 79;; Reservations for FALU1 (FALU2) instructions. 80;; Instruction goes to FALU1 (FALU2) and makes next FALU1/2 instruction to 81;; be dispatched to FALU2 (FALU1). 82(define_reservation "ls2_falu1" 83 "(ls2_falu1_core+ls2_falu2_turn_enabled)|ls2_falu1_core") 84(define_reservation "ls2_falu2" 85 "(ls2_falu2_core+ls2_falu1_turn_enabled)|ls2_falu2_core") 86 87;; Reservation for FALU1/2 instructions. 88;; Instruction will go to FALU1 iff ls2_falu1_turn_enabled is subscribed and 89;; switch the turn to FALU2 by subscribing ls2_falu2_turn_enabled. 90;; Or to FALU2 otherwise. 91(define_reservation "ls2_falu" 92 "(ls2_falu1+ls2_falu1_turn+ls2_falu2_turn_enabled) 93 |(ls2_falu1+ls2_falu1_turn) 94 |(ls2_falu2+ls2_falu2_turn+ls2_falu1_turn_enabled) 95 |(ls2_falu2+ls2_falu2_turn)") 96 97;; The following 4 instructions each subscribe one of 98;; ls2_[f]alu{1,2}_turn_enabled units according to this attribute. 99;; These instructions are used in mips.c: sched_ls2_dfa_post_advance_cycle. 100 101(define_attr "ls2_turn_type" "alu1,alu2,falu1,falu2,unknown,atomic,syncloop" 102 (const_string "unknown")) 103 104;; Subscribe ls2_alu1_turn_enabled. 105(define_insn "ls2_alu1_turn_enabled_insn" 106 [(unspec [(const_int 0)] UNSPEC_LOONGSON_ALU1_TURN_ENABLED_INSN)] 107 "TUNE_LOONGSON_2EF" 108 { gcc_unreachable (); } 109 [(set_attr "ls2_turn_type" "alu1")]) 110 111(define_insn_reservation "ls2_alu1_turn_enabled" 0 112 (eq_attr "ls2_turn_type" "alu1") 113 "ls2_alu1_turn_enabled") 114 115;; Subscribe ls2_alu2_turn_enabled. 116(define_insn "ls2_alu2_turn_enabled_insn" 117 [(unspec [(const_int 0)] UNSPEC_LOONGSON_ALU2_TURN_ENABLED_INSN)] 118 "TUNE_LOONGSON_2EF" 119 { gcc_unreachable (); } 120 [(set_attr "ls2_turn_type" "alu2")]) 121 122(define_insn_reservation "ls2_alu2_turn_enabled" 0 123 (eq_attr "ls2_turn_type" "alu2") 124 "ls2_alu2_turn_enabled") 125 126;; Subscribe ls2_falu1_turn_enabled. 127(define_insn "ls2_falu1_turn_enabled_insn" 128 [(unspec [(const_int 0)] UNSPEC_LOONGSON_FALU1_TURN_ENABLED_INSN)] 129 "TUNE_LOONGSON_2EF" 130 { gcc_unreachable (); } 131 [(set_attr "ls2_turn_type" "falu1")]) 132 133(define_insn_reservation "ls2_falu1_turn_enabled" 0 134 (eq_attr "ls2_turn_type" "falu1") 135 "ls2_falu1_turn_enabled") 136 137;; Subscribe ls2_falu2_turn_enabled. 138(define_insn "ls2_falu2_turn_enabled_insn" 139 [(unspec [(const_int 0)] UNSPEC_LOONGSON_FALU2_TURN_ENABLED_INSN)] 140 "TUNE_LOONGSON_2EF" 141 { gcc_unreachable (); } 142 [(set_attr "ls2_turn_type" "falu2")]) 143 144(define_insn_reservation "ls2_falu2_turn_enabled" 0 145 (eq_attr "ls2_turn_type" "falu2") 146 "ls2_falu2_turn_enabled") 147 148;; Automaton for memory operations. 149(define_automaton "ls2_mem") 150 151;; Memory unit. 152(define_query_cpu_unit "ls2_mem" "ls2_mem") 153 154;; Reservation for integer instructions. 155(define_insn_reservation "ls2_alu" 2 156 (and (eq_attr "cpu" "loongson_2e,loongson_2f") 157 (eq_attr "type" "arith,condmove,const,logical,mfhi,mflo,move, 158 mthi,mtlo,nop,shift,signext,slt")) 159 "ls2_alu") 160 161;; Reservation for branch instructions. 162(define_insn_reservation "ls2_branch" 2 163 (and (eq_attr "cpu" "loongson_2e,loongson_2f") 164 (eq_attr "type" "branch,jump,call,trap")) 165 "ls2_alu1") 166 167;; Reservation for integer multiplication instructions. 168(define_insn_reservation "ls2_imult" 5 169 (and (eq_attr "cpu" "loongson_2e,loongson_2f") 170 (eq_attr "type" "imul,imul3nc")) 171 "ls2_alu2,ls2_alu2_core") 172 173;; Reservation for integer division / remainder instructions. 174;; These instructions use the SRT algorithm and hence take 2-38 cycles. 175(define_insn_reservation "ls2_idiv" 20 176 (and (eq_attr "cpu" "loongson_2e,loongson_2f") 177 (eq_attr "type" "idiv,idiv3")) 178 "ls2_alu2,ls2_alu2_core*18") 179 180;; Reservation for memory load instructions. 181(define_insn_reservation "ls2_load" 5 182 (and (eq_attr "cpu" "loongson_2e,loongson_2f") 183 (eq_attr "type" "load,fpload,mfc,mtc")) 184 "ls2_mem") 185 186(define_insn_reservation "ls2_prefetch" 0 187 (and (eq_attr "cpu" "loongson_2e,loongson_2f") 188 (eq_attr "type" "prefetch,prefetchx")) 189 "ls2_mem") 190 191;; Reservation for memory store instructions. 192;; With stores we assume they don't alias with dependent loads. 193;; Therefore we set the latency to zero. 194(define_insn_reservation "ls2_store" 0 195 (and (eq_attr "cpu" "loongson_2e,loongson_2f") 196 (eq_attr "type" "store,fpstore")) 197 "ls2_mem") 198 199;; Reservation for floating-point instructions of latency 3. 200(define_insn_reservation "ls2_fp3" 3 201 (and (eq_attr "cpu" "loongson_2e,loongson_2f") 202 (eq_attr "type" "fabs,fneg,fcmp,fmove")) 203 "ls2_falu1") 204 205;; Reservation for floating-point instructions of latency 5. 206(define_insn_reservation "ls2_fp5" 5 207 (and (eq_attr "cpu" "loongson_2e,loongson_2f") 208 (eq_attr "type" "fcvt")) 209 "ls2_falu1") 210 211;; Reservation for floating-point instructions that can go 212;; to either of FALU1/2 units. 213(define_insn_reservation "ls2_falu" 7 214 (and (eq_attr "cpu" "loongson_2e,loongson_2f") 215 (eq_attr "type" "fadd,fmul,fmadd")) 216 "ls2_falu") 217 218;; Reservation for floating-point division / remainder instructions. 219;; These instructions use the SRT algorithm and hence take a variable amount 220;; of cycles: 221;; div.s takes 5-11 cycles 222;; div.d takes 5-18 cycles 223(define_insn_reservation "ls2_fdiv" 9 224 (and (eq_attr "cpu" "loongson_2e,loongson_2f") 225 (eq_attr "type" "fdiv")) 226 "ls2_falu2,ls2_falu2_core*7") 227 228;; Reservation for floating-point sqrt instructions. 229;; These instructions use the SRT algorithm and hence take a variable amount 230;; of cycles: 231;; sqrt.s takes 5-17 cycles 232;; sqrt.d takes 5-32 cycles 233(define_insn_reservation "ls2_fsqrt" 15 234 (and (eq_attr "cpu" "loongson_2e,loongson_2f") 235 (eq_attr "type" "fsqrt")) 236 "ls2_falu2,ls2_falu2_core*13") 237 238;; Two consecutive ALU instructions. 239(define_insn_reservation "ls2_multi" 4 240 (and (eq_attr "cpu" "loongson_2e,loongson_2f") 241 (eq_attr "type" "multi")) 242 "(ls2_alu1,ls2_alu2_core)|(ls2_alu2,ls2_alu1_core)") 243 244;; Reservation for everything else. Normally, this reservation 245;; will only be used to handle cases like compiling for non-loongson 246;; CPUs with -mtune=loongson2?. 247;; 248;; This reservation depends upon the fact that DFA will check 249;; reservations in the same order as they appear in the file. 250(define_insn_reservation "ls2_unknown" 1 251 (eq_attr "cpu" "loongson_2e,loongson_2f") 252 "ls2_alu1_core+ls2_alu2_core+ls2_falu1_core+ls2_falu2_core+ls2_mem") 253