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