xref: /netbsd-src/external/gpl3/gcc/dist/gcc/config/h8300/addsub.md (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1;; ----------------------------------------------------------------------
2;; ADD INSTRUCTIONS
3;; ----------------------------------------------------------------------
4
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  "")
11
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))])])
21
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")])
30
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))])])
40
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")])
77
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))])])
87
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,*")])
101
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  })
112
113
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))])])
123
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)"
130{
131  rtx x = XVECEXP (PATTERN (insn), 0, 1);
132  return output_plussi (operands, GET_CODE (x) != CLOBBER);
133}
134  [(set (attr "length")
135	(symbol_ref "compute_plussi_length (operands, false)"))])
136
137;; ----------------------------------------------------------------------
138;; SUBTRACT INSTRUCTIONS
139;; ----------------------------------------------------------------------
140
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  "")
146
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))])])
156
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")])
165
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))])])
175
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")])
190
191;; ----------------------------------------------------------------------
192;; NEGATION INSTRUCTIONS
193;; ----------------------------------------------------------------------
194
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  "")
200
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))])])
209
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")])
225
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")])
242