1;; Machine Descriptions for R8C/M16C/M32C 2;; Copyright (C) 2005-2020 Free Software Foundation, Inc. 3;; Contributed by Red Hat. 4;; 5;; This file is part of GCC. 6;; 7;; GCC is free software; you can redistribute it and/or modify it 8;; under the terms of the GNU General Public License as published 9;; by the Free Software Foundation; either version 3, or (at your 10;; option) any later version. 11;; 12;; GCC is distributed in the hope that it will be useful, but WITHOUT 13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15;; License for more details. 16;; 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21;; multiply and divide 22 23; Here is the pattern for the const_int. 24(define_insn "mulqihi3_c" 25 [(set (match_operand:HI 0 "mra_operand" "=RhiSd,??Rmm") 26 (mult:HI (sign_extend:HI (match_operand:QI 1 "mra_operand" "%0,0")) 27 (match_operand 2 "immediate_operand" "i,i")))] 28 "" 29 "mul.b\t%2,%1" 30 [(set_attr "flags" "o")] 31) 32 33; Here is the pattern for registers and such. 34(define_insn "mulqihi3_r" 35 [(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm,Raa,Raa") 36 (mult:HI (sign_extend:HI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0")) 37 (sign_extend:HI (match_operand:QI 2 "mra_operand" "RqiSd,?Rmm,RqiSd,?Rmm,RhlSd,?Rmm"))))] 38 "" 39 "mul.b\t%2,%1" 40 [(set_attr "flags" "o")] 41) 42 43; Don't try to sign_extend a const_int. Same for all other multiplies. 44(define_expand "mulqihi3" 45 [(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm,Raa,Raa") 46 (mult:HI (sign_extend:HI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0")) 47 (match_operand:QI 2 "mra_operand" "RqiSd,?Rmm,RqiSd,?Rmm,RhlSd,?Rmm")))] 48 "" 49 "{ if (GET_MODE (operands[2]) != VOIDmode) 50 operands[2] = gen_rtx_SIGN_EXTEND (HImode, operands[2]); }" 51) 52 53(define_insn "umulqihi3_c" 54 [(set (match_operand:HI 0 "mra_operand" "=RhiSd,??Rmm") 55 (mult:HI (zero_extend:HI (match_operand:QI 1 "mra_operand" "%0,0")) 56 (match_operand 2 "immediate_operand" "i,i")))] 57 "" 58 "mulu.b\t%U2,%1" 59 [(set_attr "flags" "o")] 60) 61 62(define_insn "umulqihi3_r" 63 [(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm,Raa,Raa") 64 (mult:HI (zero_extend:HI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0")) 65 (zero_extend:HI (match_operand:QI 2 "mra_operand" "RqiSd,?Rmm,RqiSd,?Rmm,RhlSd,?Rmm"))))] 66 "" 67 "mulu.b\t%U2,%1" 68 [(set_attr "flags" "o")] 69) 70 71(define_expand "umulqihi3" 72 [(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm,Raa,Raa") 73 (mult:HI (zero_extend:HI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0")) 74 (match_operand:QI 2 "mra_operand" "RqiSd,?Rmm,RqiSd,?Rmm,RhlSd,?Rmm")))] 75 "" 76 "{ if (GET_MODE (operands[2]) != VOIDmode) 77 operands[2] = gen_rtx_ZERO_EXTEND (HImode, operands[2]); }" 78) 79 80(define_insn "mulhisi3_c" 81 [(set (match_operand:SI 0 "ra_operand" "=Rsi") 82 (mult:SI (sign_extend:SI (match_operand:HI 1 "mra_operand" "%0")) 83 (match_operand:HI 2 "immediate_operand" "i")))] 84 "" 85 "mul.w\t%2,%1" 86 [(set_attr "flags" "o")] 87) 88 89(define_insn "mulhisi3_r" 90 [(set (match_operand:SI 0 "mra_operand" "=Rsi,Rsi") 91 (mult:SI (sign_extend:SI (match_operand:HI 1 "mra_operand" "%0,0")) 92 (sign_extend:SI (match_operand:HI 2 "mra_operand" "RhiSd,?Rmm"))))] 93 "" 94 "mul.w\t%2,%1" 95 [(set_attr "flags" "o")] 96) 97 98(define_expand "mulhisi3" 99 [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm") 100 (mult:SI (sign_extend:SI (match_operand:HI 1 "mra_operand" "%0,0,0,0")) 101 (match_operand:HI 2 "mra_operand" "RhiSd,?Rmm,RhiSd,?Rmm")))] 102 "" 103 "{ if (GET_MODE (operands[2]) != VOIDmode) 104 operands[2] = gen_rtx_SIGN_EXTEND (SImode, operands[2]); }" 105) 106 107(define_insn "umulhisi3_c" 108 [(set (match_operand:SI 0 "ra_operand" "=Rsi") 109 (mult:SI (zero_extend:SI (match_operand:HI 1 "mra_operand" "%0")) 110 (match_operand 2 "immediate_operand" "i")))] 111 "" 112 "mulu.w\t%u2,%1" 113 [(set_attr "flags" "o")] 114) 115 116(define_insn "umulhisi3_r" 117 [(set (match_operand:SI 0 "mra_operand" "=Rsi,Rsi") 118 (mult:SI (zero_extend:SI (match_operand:HI 1 "mra_operand" "%0,0")) 119 (zero_extend:SI (match_operand:HI 2 "mra_operand" "RhiSd,?Rmm"))))] 120 "" 121 "mulu.w\t%u2,%1" 122 [(set_attr "flags" "o")] 123) 124 125(define_expand "umulhisi3" 126 [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm") 127 (mult:SI (zero_extend:SI (match_operand:HI 1 "mra_operand" "%0,0,0,0")) 128 (match_operand:HI 2 "mra_operand" "RhiSd,?Rmm,RhiSd,?Rmm")))] 129 "" 130 "{ if (GET_MODE (operands[2]) != VOIDmode) 131 operands[2] = gen_rtx_ZERO_EXTEND (SImode, operands[2]); }" 132) 133 134 135; GCC expects to be able to multiply pointer-sized integers too, but 136; fortunately it only multiplies by powers of two, although sometimes 137; they're negative. 138(define_insn "mulpsi3_op" 139 [(set (match_operand:PSI 0 "mra_operand" "=RsiSd") 140 (mult:PSI (match_operand:PSI 1 "mra_operand" "%0") 141 (match_operand 2 "m32c_psi_scale" "Ilb")))] 142 "TARGET_A24" 143 "shl.l\t%b2,%0" 144 [(set_attr "flags" "szc")] 145 ) 146 147(define_expand "mulpsi3" 148 [(set (match_operand:PSI 0 "mra_operand" "=RsiSd") 149 (mult:PSI (match_operand:PSI 1 "mra_operand" "%0") 150 (match_operand 2 "m32c_psi_scale" "Ilb")))] 151 "TARGET_A24" 152 "if (GET_CODE (operands[2]) != CONST_INT 153 || ! m32c_psi_scale (operands[2], PSImode)) 154 { 155 m32c_expand_neg_mulpsi3 (operands); 156 DONE; 157 }" 158 ) 159 160(define_insn "mulsi3" 161 [(set (match_operand:SI 0 "r0123_operand" "=R02,R02") 162 (mult:SI (match_operand:SI 1 "r0123_operand" "%0,0") 163 (match_operand:SI 2 "mra_operand" "RsiSd,?Rmm")))] 164 "TARGET_M32C" 165 "mul.l\t%2,%1" 166 [(set_attr "flags" "o")] 167) 168 169(define_expand "divmodqi4" 170 [(set (match_dup 4) 171 (sign_extend:HI (match_operand:QI 1 "register_operand" "0,0"))) 172 (parallel [(set (match_operand:QI 0 "register_operand" "=R0w,R0w") 173 (div:QI (match_dup 4) 174 (match_operand:QI 2 "general_operand" "iRqiSd,?Rmm"))) 175 (set (match_operand:QI 3 "register_operand" "=&R0h,&R0h") 176 (mod:QI (match_dup 4) (match_dup 2))) 177 ])] 178 "0" 179 "operands[4] = gen_reg_rtx (HImode);" 180 ) 181 182(define_insn "divmodqi4_n" 183 [(set (match_operand:QI 0 "register_operand" "=R0l,R0l") 184 (div:QI (match_operand:HI 1 "register_operand" "R0w,R0w") 185 (match_operand:QI 2 "general_operand" "iRqiSd,?Rmm"))) 186 (set (match_operand:QI 3 "register_operand" "=R0h,R0h") 187 (mod:QI (match_dup 1) (match_dup 2))) 188 ] 189 "0" 190 "div.b\t%2" 191 [(set_attr "flags" "o")] 192 ) 193 194(define_expand "udivmodqi4" 195 [(set (match_dup 4) 196 (zero_extend:HI (match_operand:QI 1 "register_operand" "0,0"))) 197 (parallel [(set (match_operand:QI 0 "register_operand" "=R0l,R0l") 198 (udiv:QI (match_dup 4) 199 (match_operand:QI 2 "general_operand" "iRqiSd,?Rmm"))) 200 (set (match_operand:QI 3 "register_operand" "=&R0h,&R0h") 201 (umod:QI (match_dup 4) (match_dup 2))) 202 ])] 203 "0" 204 "operands[4] = gen_reg_rtx (HImode);" 205 ) 206 207(define_insn "udivmodqi4_n" 208 [(set (match_operand:QI 0 "register_operand" "=R0l,R0l") 209 (udiv:QI (match_operand:HI 1 "register_operand" "R0w,R0w") 210 (match_operand:QI 2 "general_operand" "iRqiSd,?Rmm"))) 211 (set (match_operand:QI 3 "register_operand" "=R0h,R0h") 212 (umod:QI (match_dup 1) (match_dup 2))) 213 ] 214 "0" 215 "divu.b\t%2" 216 [(set_attr "flags" "o")] 217 ) 218 219(define_expand "divmodhi4" 220 [(set (match_dup 4) 221 (sign_extend:SI (match_operand:HI 1 "register_operand" "0,0"))) 222 (parallel [(set (match_operand:HI 0 "register_operand" "=R0w,R0w") 223 (div:HI (match_dup 4) 224 (match_operand:HI 2 "general_operand" "iRhiSd,?Rmm"))) 225 (set (match_operand:HI 3 "register_operand" "=R2w,R2w") 226 (mod:HI (match_dup 4) (match_dup 2))) 227 ])] 228 "" 229 "operands[4] = gen_reg_rtx (SImode);" 230 ) 231 232(define_insn "divmodhi4_n" 233 [(set (match_operand:HI 0 "m32c_r0_operand" "=R0w,R0w") 234 (div:HI (match_operand:SI 1 "m32c_r0_operand" "R02,R02") 235 (match_operand:HI 2 "m32c_notr2_operand" "iR1wR3wRaaSd,?Rmm"))) 236 (set (match_operand:HI 3 "m32c_r2_operand" "=R2w,R2w") 237 (mod:HI (match_dup 1) (match_dup 2))) 238 ] 239 "" 240 "div.w\t%2" 241 [(set_attr "flags" "o")] 242 ) 243 244(define_expand "udivmodhi4" 245 [(set (match_dup 4) 246 (zero_extend:SI (match_operand:HI 1 "register_operand" "0,0"))) 247 (parallel [(set (match_operand:HI 0 "register_operand" "=R0w,R0w") 248 (udiv:HI (match_dup 4) 249 (match_operand:HI 2 "general_operand" "iRhiSd,?Rmm"))) 250 (set (match_operand:HI 3 "register_operand" "=R2w,R2w") 251 (umod:HI (match_dup 4) (match_dup 2))) 252 ])] 253 "" 254 "operands[4] = gen_reg_rtx (SImode);" 255 ) 256 257(define_insn "udivmodhi4_n" 258 [(set (match_operand:HI 0 "m32c_r0_operand" "=R0w,R0w") 259 (udiv:HI (match_operand:SI 1 "m32c_r0_operand" "R02,R02") 260 (match_operand:HI 2 "m32c_notr2_operand" "iR1wR3wRaaSd,?Rmm"))) 261 (set (match_operand:HI 3 "m32c_r2_operand" "=R2w,R2w") 262 (umod:HI (match_dup 1) (match_dup 2))) 263 ] 264 "" 265 "divu.w\t%2" 266 [(set_attr "flags" "o")] 267 ) 268 269(define_insn "divsi3" 270 [(set (match_operand:SI 0 "r0123_operand" "=R02,R02") 271 (div:SI (match_operand:SI 1 "r0123_operand" "0,0") 272 (match_operand:SI 2 "mra_operand" "RsiSd,?Rmm")))] 273 "TARGET_M32C" 274 "div.l\t%2" 275 [(set_attr "flags" "o")] 276) 277 278(define_insn "udivsi3" 279 [(set (match_operand:SI 0 "r0123_operand" "=R02,R02") 280 (udiv:SI (match_operand:SI 1 "r0123_operand" "0,0") 281 (match_operand:SI 2 "mra_operand" "RsiSd,?Rmm")))] 282 "TARGET_M32C" 283 "divu.l\t%2" 284 [(set_attr "flags" "o")] 285) 286 287 288