1;; ---------------------------------------------------------------------- 2;; MULTIPLY INSTRUCTIONS 3;; ---------------------------------------------------------------------- 4 5;; Note that the H8/300 can only handle umulqihi3. 6 7(define_expand "mulqihi3" 8 [(set (match_operand:HI 0 "register_operand" "") 9 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "")) 10 ;; intentionally-mismatched modes 11 (match_operand:QI 2 "reg_or_nibble_operand" "")))] 12 "" 13 { 14 if (GET_MODE (operands[2]) != VOIDmode) 15 operands[2] = gen_rtx_SIGN_EXTEND (HImode, operands[2]); 16 }) 17 18(define_insn_and_split "*mulqihi3_const" 19 [(set (match_operand:HI 0 "register_operand" "=r") 20 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0")) 21 (match_operand:QI 2 "nibble_operand" "IP4>X")))] 22 "TARGET_H8300SX" 23 "#" 24 "&& reload_completed" 25 [(parallel [(set (match_dup 0) 26 (mult:HI (sign_extend:HI (match_dup 1)) (match_dup 2))) 27 (clobber (reg:CC CC_REG))])]) 28 29(define_insn "*mulqihi3_const<cczn>" 30 [(set (match_operand:HI 0 "register_operand" "=r") 31 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0")) 32 (match_operand:QI 2 "nibble_operand" "IP4>X"))) 33 (clobber (reg:CC CC_REG))] 34 "TARGET_H8300SX" 35 "mulxs.b %X2,%T0" 36 [(set_attr "length" "4")]) 37 38(define_insn_and_split "*mulqihi3" 39 [(set (match_operand:HI 0 "register_operand" "=r") 40 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0")) 41 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))] 42 "" 43 "#" 44 "&& reload_completed" 45 [(parallel [(set (match_dup 0) 46 (mult:HI (sign_extend:HI (match_dup 1)) 47 (sign_extend:HI (match_dup 2)))) 48 (clobber (reg:CC CC_REG))])]) 49 50(define_insn "*mulqihi3<cczn>" 51 [(set (match_operand:HI 0 "register_operand" "=r") 52 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0")) 53 (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))) 54 (clobber (reg:CC CC_REG))] 55 "" 56 "mulxs.b %X2,%T0" 57 [(set_attr "length" "4")]) 58 59(define_expand "mulhisi3" 60 [(set (match_operand:SI 0 "register_operand" "") 61 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "")) 62 ;; intentionally-mismatched modes 63 (match_operand:HI 2 "reg_or_nibble_operand" "")))] 64 "" 65 { 66 if (GET_MODE (operands[2]) != VOIDmode) 67 operands[2] = gen_rtx_SIGN_EXTEND (SImode, operands[2]); 68 }) 69 70(define_insn_and_split "*mulhisi3_const" 71 [(set (match_operand:SI 0 "register_operand" "=r") 72 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0")) 73 (match_operand:SI 2 "nibble_operand" "IP4>X")))] 74 "TARGET_H8300SX" 75 "#" 76 "&& reload_completed" 77 [(parallel [(set (match_dup 0) 78 (mult:SI (sign_extend:SI (match_dup 1)) (match_dup 2))) 79 (clobber (reg:CC CC_REG))])]) 80 81(define_insn "*mulhisi3_const<cczn>" 82 [(set (match_operand:SI 0 "register_operand" "=r") 83 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0")) 84 (match_operand:SI 2 "nibble_operand" "IP4>X"))) 85 (clobber (reg:CC CC_REG))] 86 "TARGET_H8300SX" 87 "mulxs.w %T2,%S0" 88 [(set_attr "length" "4")]) 89 90(define_insn_and_split "*mulhisi3" 91 [(set (match_operand:SI 0 "register_operand" "=r") 92 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0")) 93 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))] 94 "" 95 "#" 96 "&& reload_completed" 97 [(parallel [(set (match_dup 0) 98 (mult:SI (sign_extend:SI (match_dup 1)) 99 (sign_extend:SI (match_dup 2)))) 100 (clobber (reg:CC CC_REG))])]) 101 102(define_insn "*mulhisi3<cczn>" 103 [(set (match_operand:SI 0 "register_operand" "=r") 104 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0")) 105 (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))) 106 (clobber (reg:CC CC_REG))] 107 "" 108 "mulxs.w %T2,%S0" 109 [(set_attr "length" "4")]) 110 111(define_expand "umulqihi3" 112 [(set (match_operand:HI 0 "register_operand" "") 113 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "")) 114 ;; intentionally-mismatched modes 115 (match_operand:QI 2 "reg_or_nibble_operand" "")))] 116 "" 117 { 118 if (GET_MODE (operands[2]) != VOIDmode) 119 operands[2] = gen_rtx_ZERO_EXTEND (HImode, operands[2]); 120 }) 121 122(define_insn "*umulqihi3_const" 123 [(set (match_operand:HI 0 "register_operand" "=r") 124 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0")) 125 (match_operand:QI 2 "nibble_operand" "IP4>X")))] 126 "TARGET_H8300SX" 127 "mulxu.b %X2,%T0" 128 [(set_attr "length" "4")]) 129 130(define_insn "*umulqihi3" 131 [(set (match_operand:HI 0 "register_operand" "=r") 132 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0")) 133 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))] 134 "" 135 "mulxu.b %X2,%T0" 136 [(set_attr "length" "2")]) 137 138(define_expand "umulhisi3" 139 [(set (match_operand:SI 0 "register_operand" "") 140 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "")) 141 ;; intentionally-mismatched modes 142 (match_operand:HI 2 "reg_or_nibble_operand" "")))] 143 "" 144 { 145 if (GET_MODE (operands[2]) != VOIDmode) 146 operands[2] = gen_rtx_ZERO_EXTEND (SImode, operands[2]); 147 }) 148 149(define_insn "*umulhisi3_const" 150 [(set (match_operand:SI 0 "register_operand" "=r") 151 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0")) 152 (match_operand:SI 2 "nibble_operand" "IP4>X")))] 153 "TARGET_H8300SX" 154 "mulxu.w %T2,%S0" 155 [(set_attr "length" "4")]) 156 157(define_insn "*umulhisi3" 158 [(set (match_operand:SI 0 "register_operand" "=r") 159 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0")) 160 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))] 161 "" 162 "mulxu.w %T2,%S0" 163 [(set_attr "length" "2")]) 164 165;; We could have used mulu.[wl] here, but mulu.[lw] is only available 166;; on a H8SX with a multiplier, whereas muls.w seems to be available 167;; on all H8SX variants. 168 169(define_insn_and_split "mul<mode>3" 170 [(set (match_operand:HSI 0 "register_operand" "=r") 171 (mult:HSI (match_operand:HSI 1 "register_operand" "%0") 172 (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))] 173 "TARGET_H8300SX" 174 "#" 175 "&& reload_completed" 176 [(parallel [(set (match_dup 0) (mult:HSI (match_dup 1) (match_dup 2))) 177 (clobber (reg:CC CC_REG))])]) 178 179(define_insn "mul<mode>3_clobber_flags" 180 [(set (match_operand:HSI 0 "register_operand" "=r") 181 (mult:HSI (match_operand:HSI 1 "register_operand" "%0") 182 (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X"))) 183 (clobber (reg:CC CC_REG))] 184 "TARGET_H8300SX" 185 { return <MODE>mode == HImode ? "muls.w\\t%T2,%T0" : "muls.l\\t%S2,%S0"; } 186 [(set_attr "length" "4")]) 187 188(define_insn_and_split "smulsi3_highpart" 189 [(set (match_operand:SI 0 "register_operand" "=r") 190 (truncate:SI 191 (lshiftrt:DI 192 (mult:DI 193 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0")) 194 (sign_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X"))) 195 (const_int 32))))] 196 "TARGET_H8300SXMUL" 197 "#" 198 "&& reload_completed" 199 [(parallel [(set (match_dup 0) 200 (truncate:SI (lshiftrt:DI (mult:DI 201 (sign_extend:DI (match_dup 1)) 202 (sign_extend:DI (match_dup 2))) 203 (const_int 32)))) 204 (clobber (reg:CC CC_REG))])]) 205 206(define_insn "smulsi3_highpart_clobber_flags" 207 [(set (match_operand:SI 0 "register_operand" "=r") 208 (truncate:SI 209 (lshiftrt:DI 210 (mult:DI 211 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0")) 212 (sign_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X"))) 213 (const_int 32)))) 214 (clobber (reg:CC CC_REG))] 215 "TARGET_H8300SXMUL" 216 "muls/u.l\\t%S2,%S0" 217 [(set_attr "length" "4")]) 218 219(define_insn "umulsi3_highpart" 220 [(set (match_operand:SI 0 "register_operand" "=r") 221 (truncate:SI 222 (ashiftrt:DI 223 (mult:DI 224 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 225 (zero_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X"))) 226 (const_int 32))))] 227 "TARGET_H8300SX" 228 "mulu/u.l\\t%S2,%S0" 229 [(set_attr "length" "4")]) 230 231;; This is a "bridge" instruction. Combine can't cram enough insns 232;; together to crate a MAC instruction directly, but it can create 233;; this instruction, which then allows combine to create the real 234;; MAC insn. 235;; 236;; Unfortunately, if combine doesn't create a MAC instruction, this 237;; insn must generate reasonably correct code. Egad. 238 239(define_insn "" 240 [(set (match_operand:SI 0 "register_operand" "=a") 241 (mult:SI 242 (sign_extend:SI 243 (mem:HI (post_inc:SI (match_operand:SI 1 "register_operand" "r")))) 244 (sign_extend:SI 245 (mem:HI (post_inc:SI (match_operand:SI 2 "register_operand" "r"))))))] 246 "TARGET_MAC" 247 "clrmac\;mac @%2+,@%1+" 248 [(set_attr "length" "6")]) 249 250(define_insn "" 251 [(set (match_operand:SI 0 "register_operand" "=a") 252 (plus:SI (mult:SI 253 (sign_extend:SI (mem:HI 254 (post_inc:SI (match_operand:SI 1 "register_operand" "r")))) 255 (sign_extend:SI (mem:HI 256 (post_inc:SI (match_operand:SI 2 "register_operand" "r"))))) 257 (match_operand:SI 3 "register_operand" "0")))] 258 "TARGET_MAC" 259 "mac @%2+,@%1+" 260 [(set_attr "length" "4")]) 261 262