go: update builtin function attributes
[official-gcc.git] / gcc / config / h8300 / addsub.md
blob32eba9df67aa8829d63ddc0c351be24ce9cf7210
1 ;; ----------------------------------------------------------------------
2 ;; ADD INSTRUCTIONS
3 ;; ----------------------------------------------------------------------
5 (define_expand "add<mode>3"
6   [(set (match_operand:QHSI 0 "register_operand" "")
7         (plus:QHSI (match_operand:QHSI 1 "register_operand" "")
8                    (match_operand:QHSI 2 "h8300_src_operand" "")))]
9   ""
10   "")
12 (define_insn_and_split "*addqi3"
13   [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
14         (plus:QI (match_operand:QI 1 "h8300_dst_operand" "%0")
15                  (match_operand:QI 2 "h8300_src_operand" "rQi")))]
16   "h8300_operands_match_p (operands)"
17   "#"
18   "&& reload_completed"
19   [(parallel [(set (match_dup 0) (plus:QI (match_dup 1) (match_dup 2)))
20               (clobber (reg:CC CC_REG))])])
22 (define_insn "*addqi3_flags<cczn>"
23   [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
24         (plus:QI (match_operand:QI 1 "h8300_dst_operand" "%0")
25                  (match_operand:QI 2 "h8300_src_operand" "rQi")))
26    (clobber (reg:CC CC_REG))]
27   "reload_completed && h8300_operands_match_p (operands)"
28   "add.b        %X2,%X0"
29   [(set_attr "length_table" "add")])
31 (define_insn_and_split "*addhi"
32   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
33         (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
34                  (match_operand:HI 2 "h8300_src_operand" "L,N,J,n,r")))]
35   "!TARGET_H8300SX"
36   "#"
37   "&& reload_completed"
38   [(parallel [(set (match_dup 0) (plus:HI (match_dup 1) (match_dup 2)))
39               (clobber (reg:CC CC_REG))])])
41 (define_insn "*addhi3_flags<cczn>"
42   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
43         (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
44                  (match_operand:HI 2 "h8300_src_operand" "M,O,J,n,r")))
45    (clobber (reg:CC CC_REG))]
46   "reload_completed && !TARGET_H8300SX"
47   "*
48   {
49     switch (which_alternative)
50       {
51       case 0:
52         return \"inc %T2,%T0\";
53       case 1:
54         return \"dec %G2,%T0\";
55       case 2:
56         return \"add.b  %t2,%t0\";
57       case 3:
58         {
59           /* If the constant is 4 or -4 and we do not need the
60              flags, then we can use adds/subs which is two bytes
61              shorter.  */
62           rtx x = XVECEXP (PATTERN (insn), 0, 1);
63           bool clobber = GET_CODE (x) == CLOBBER;
64           if (clobber && INTVAL (operands[2]) == 4)
65             return \"adds       %2,%S0\";
66           if (clobber && INTVAL (operands[2]) == -4)
67             return \"subs       %G2,%S0\";
68           return \"add.w        %T2,%T0\";
69         }
70       case 4:
71         return \"add.w  %T2,%T0\";
72       default:
73         gcc_unreachable ();
74       }
75   }"
76   [(set_attr "length" "2,2,2,4,2")])
78 (define_insn_and_split "*addhi3_h8sx"
79   [(set (match_operand:HI 0 "h8300_dst_operand" "=rU,rU,r,rQ")
80         (plus:HI (match_operand:HI 1 "h8300_dst_operand" "%0,0,0,0")
81                  (match_operand:HI 2 "h8300_src_operand" "P3>X,P3<X,J,rQi")))]
82   "TARGET_H8300SX && h8300_operands_match_p (operands)"
83   "#"
84   "&& reload_completed"
85   [(parallel [(set (match_dup 0) (plus:HI (match_dup 1) (match_dup 2)))
86               (clobber (reg:CC CC_REG))])])
88 (define_insn "*addhi3_h8sx_flags<cczn>"
89   [(set (match_operand:HI 0 "h8300_dst_operand" "=rU,rU,r,rQ")
90         (plus:HI (match_operand:HI 1 "h8300_dst_operand" "%0,0,0,0")
91                  (match_operand:HI 2 "h8300_src_operand" "P3>X,P3<X,J,rQi")))
92    (clobber (reg:CC CC_REG))]
93   "reload_completed && TARGET_H8300SX && h8300_operands_match_p (operands)"
94   "@
95    add.w        %T2:3,%T0
96    sub.w        %G2:3,%T0
97    add.b        %t2,%t0
98    add.w        %T2,%T0"
99   [(set_attr "length_table" "short_immediate,short_immediate,*,add")
100    (set_attr "length" "*,*,2,*")])
102 (define_split
103   [(set (match_operand:HSI 0 "register_operand" "")
104         (plus:HSI (match_dup 0)
105                  (match_operand:HSI 1 "two_insn_adds_subs_operand" "")))]
106   "!reload_completed"
107   [(const_int 0)]
108   {
109     split_adds_subs (<MODE>mode, operands);
110     DONE;
111   })
114 (define_insn_and_split "*addsi"
115   [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ,rQ")
116         (plus:SI (match_operand:SI 1 "h8300_dst_operand" "%0,0")
117                  (match_operand:SI 2 "h8300_src_operand" "i,rQ")))]
118   "h8300_operands_match_p (operands)"
119   "#"
120   "&& reload_completed"
121   [(parallel [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
122               (clobber (reg:CC CC_REG))])])
124 (define_insn "*addsi_flags<cczn>"
125   [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ,rQ")
126         (plus:SI (match_operand:SI 1 "h8300_dst_operand" "%0,0")
127                  (match_operand:SI 2 "h8300_src_operand" "i,rQ")))
128    (clobber (reg:CC CC_REG))]
129   "reload_completed && h8300_operands_match_p (operands)"
131   rtx x = XVECEXP (PATTERN (insn), 0, 1);
132   return output_plussi (operands, GET_CODE (x) != CLOBBER);
134   [(set (attr "length")
135         (symbol_ref "compute_plussi_length (operands, false)"))])
137 ;; ----------------------------------------------------------------------
138 ;; SUBTRACT INSTRUCTIONS
139 ;; ----------------------------------------------------------------------
141 (define_expand "sub<mode>3"
142   [(set (match_operand:QHSI 0 "register_operand" "")
143         (minus:QHSI (match_operand:QHSI 1 "register_operand" "")
144                     (match_operand:QHSI 2 "h8300_src_operand" "")))]
145   "")
147 (define_insn_and_split "*subqi3"
148   [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
149         (minus:QI (match_operand:QI 1 "h8300_dst_operand" "0")
150                   (match_operand:QI 2 "h8300_dst_operand" "rQ")))]
151   "h8300_operands_match_p (operands)"
152   "#"
153   "&& reload_completed"
154   [(parallel [(set (match_dup 0) (minus:QI (match_dup 1) (match_dup 2)))
155               (clobber (reg:CC CC_REG))])])
157 (define_insn "*subqi3_flags<cczn>"
158   [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
159         (minus:QI (match_operand:QI 1 "h8300_dst_operand" "0")
160                   (match_operand:QI 2 "h8300_dst_operand" "rQ")))
161    (clobber (reg:CC CC_REG))]
162   "reload_completed && h8300_operands_match_p (operands)"
163   "sub.b        %X2,%X0"
164   [(set_attr "length_table" "add")])
166 (define_insn_and_split "*sub<mode>3"
167   [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ,rQ")
168         (minus:HSI (match_operand:HSI 1 "h8300_dst_operand" "0,0")
169                    (match_operand:HSI 2 "h8300_src_operand" "rQ,i")))]
170   "h8300_operands_match_p (operands)"
171   "#"
172   "&& reload_completed"
173   [(parallel [(set (match_dup 0) (minus:HSI (match_dup 1) (match_dup 2)))
174               (clobber (reg:CC CC_REG))])])
176 (define_insn "*sub<mode>3_flags<cczn>"
177   [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ,rQ")
178         (minus:HSI (match_operand:HSI 1 "h8300_dst_operand" "0,0")
179                    (match_operand:HSI 2 "h8300_src_operand" "rQ,i")))
180    (clobber (reg:CC CC_REG))]
181   "reload_completed && h8300_operands_match_p (operands)"
182   { 
183     if (<MODE>mode == HImode)
184       return "sub.w     %T2,%T0";
185     else if (<MODE>mode == SImode)
186       return "sub.l     %S2,%S0";
187     gcc_unreachable ();
188   }
189   [(set_attr "length_table" "add")])
191 ;; ----------------------------------------------------------------------
192 ;; NEGATION INSTRUCTIONS
193 ;; ----------------------------------------------------------------------
195 (define_expand "neg<mode>2"
196   [(set (match_operand:QHSIF 0 "register_operand" "")
197         (neg:QHSIF (match_operand:QHSIF 1 "register_operand" "")))]
198   ""
199   "")
201 (define_insn_and_split "*neg<mode>2"
202   [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
203         (neg:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))]
204   ""
205   "#"
206   "&& reload_completed"
207   [(parallel [(set (match_dup 0) (neg:QHSI (match_dup 1)))
208               (clobber (reg:CC CC_REG))])])
210 (define_insn "*neg<mode>2_flags<cczn>"
211   [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
212         (neg:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))
213    (clobber (reg:CC CC_REG))]
214   "reload_completed"
215   {
216     if (<MODE>mode == E_QImode)
217       return "neg       %X0";
218     if (<MODE>mode == E_HImode)
219       return "neg.w     %T0";
220     if (<MODE>mode == E_SImode)
221       return "neg.l     %S0";
222     gcc_unreachable ();
223   }
224   [(set_attr "length_table" "unary")])
226 (define_insn_and_split "*negsf2"
227   [(set (match_operand:SF 0 "register_operand" "=r")
228         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
229   ""
230   "#"
231   "&& reload_completed"
232   [(parallel [(set (match_dup 0) (neg:SF (match_dup 1)))
233               (clobber (reg:CC CC_REG))])])
234   
235 (define_insn "*negsf2_clobber_flags"
236   [(set (match_operand:SF 0 "register_operand" "=r")
237        (neg:SF (match_operand:SF 1 "register_operand" "0")))
238    (clobber (reg:CC CC_REG))]
239   "reload_completed"
240   "xor.w\\t#32768,%e0"
241   [(set_attr "length" "4")])
243 (define_expand "uaddv<mode>4"
244   [(set (match_operand:QHSI 0 "register_operand" "")
245         (plus:QHSI (match_operand:QHSI 1 "register_operand" "")
246                    (match_operand:QHSI 2 "register_operand" "")))
247    (set (pc)
248         (if_then_else (ltu (match_dup 0) (match_dup 1))
249                       (label_ref (match_operand 3 ""))
250                       (pc)))]
251   "")
253 (define_insn_and_split "*uaddv"
254   [(set (match_operand:QHSI2 3 "register_operand" "=&r")
255         (ltu:QHSI2 (plus:QHSI (match_operand:QHSI 1 "register_operand" "%0")
256                            (match_operand:QHSI 2 "register_operand" "r"))
257                 (match_dup 1)))
258    (set (match_operand:QHSI 0 "register_operand" "=r")
259         (plus:QHSI (match_dup 1) (match_dup 2)))]
260   ""
261   "#"
262   "&& reload_completed"
263   [(parallel [(set (match_dup 3) (ltu:QHSI2 (plus:QHSI (match_dup 1) (match_dup 2))
264                                           (match_dup 1)))
265               (set (match_dup 0) (plus:QHSI (match_dup 1) (match_dup 2)))
266               (clobber (reg:CC CC_REG))])])
268 (define_insn "*uaddv"
269   [(set (match_operand:QHSI2 3 "register_operand" "=&r")
270         (ltu:QHSI2 (plus:QHSI (match_operand:QHSI 1 "register_operand" "%0")
271                              (match_operand:QHSI 2 "register_operand" "r"))
272                 (match_dup 1)))
273    (set (match_operand:QHSI 0 "register_operand" "=r")
274         (plus (match_dup 1) (match_dup 2)))
275    (clobber (reg:CC CC_REG))]
276   ""
278   if (E_<QHSI2:MODE>mode == E_QImode)
279     {
280       if (E_<QHSI:MODE>mode == E_QImode)
281         return "sub.b\t%X3,%X3\;add.b\t%X2,%X0\;addx\t%X3,%X3";
282       else if (E_<QHSI:MODE>mode == E_HImode)
283         return "sub.b\t%X3,%X3\;add.w\t%T2,%T0\;addx\t%X3,%X3";
284       else if (E_<QHSI:MODE>mode == E_SImode)
285         return "sub.b\t%X3,%X3\;add.l\t%S2,%S0\;addx\t%X3,%X3";
286     }
287   else if (E_<QHSI2:MODE>mode == E_HImode)
288     {
289       if (E_<QHSI:MODE>mode == E_QImode)
290         return "sub.w\t%T3,%T3\;add.b\t%X2,%X0\;addx\t%X3,%X3";
291       else if (E_<QHSI:MODE>mode == E_HImode)
292         return "sub.w\t%T3,%T3\;add.w\t%T2,%T0\;addx\t%X3,%X3";
293       else if (E_<QHSI:MODE>mode == E_SImode)
294         return "sub.w\t%T3,%T3\;add.l\t%S2,%S0\;addx\t%X3,%X3";
295     }
296   else if (E_<QHSI2:MODE>mode == E_SImode)
297     {
298       if (E_<QHSI:MODE>mode == E_QImode)
299         return "sub.l\t%S3,%S3\;add.b\t%X2,%X0\;addx\t%X3,%X3";
300       else if (E_<QHSI:MODE>mode == E_HImode)
301         return "sub.l\t%S3,%S3\;add.w\t%T2,%T0\;addx\t%X3,%X3";
302       else if (E_<QHSI:MODE>mode == E_SImode)
303         return "sub.l\t%S3,%S3\;add.l\t%S2,%S0\;addx\t%X3,%X3";
304     }
305   else
306     gcc_unreachable ();
308   [(set_attr "length" "6")])
310 (define_expand "usubv<mode>4"
311   [(set (match_operand:QHSI 0 "register_operand" "")
312         (minus:QHSI (match_operand:QHSI 1 "register_operand" "")
313                     (match_operand:QHSI 2 "register_operand" "")))
314    (set (pc)
315         (if_then_else (ltu (match_dup 1) (match_dup 2))
316                       (label_ref (match_operand 3 ""))
317                       (pc)))]
318   "")