1 ;; Machine Descriptions for R8C/M16C/M32C 2 ;; Copyright (C) 2005-2022 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