Daily bump.
[official-gcc.git] / gcc / config / h8300 / multiply.md
blob8b9328c1282d55f658b9e9a41b6d5af80e5eb4a2
1 ;; ----------------------------------------------------------------------
2 ;; MULTIPLY INSTRUCTIONS
3 ;; ----------------------------------------------------------------------
5 ;; Note that the H8/300 can only handle umulqihi3.
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   })
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))])])
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")])
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))])])
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")])
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   })
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))])])
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")])
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))])])
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")])
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   })
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")])
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")])
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   })
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")])
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")])
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.
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))])])
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")])
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))])])
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")])
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")])
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.
236 ;; Unfortunately, if combine doesn't create a MAC instruction, this
237 ;; insn must generate reasonably correct code.  Egad.
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")])
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")])