Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/pdp11/pdp11.md @ 158:494b0b89df80 default tip
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 18:13:55 +0900 |
parents | 1830386684a0 |
children |
rev | line source |
---|---|
0 | 1 ;;- Machine description for the pdp11 for GNU C compiler |
145 | 2 ;; Copyright (C) 1994-2020 Free Software Foundation, Inc. |
0 | 3 ;; Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at). |
4 | |
5 ;; This file is part of GCC. | |
6 | |
7 ;; GCC is free software; you can redistribute it and/or modify | |
8 ;; it under the terms of the GNU General Public License as published by | |
9 ;; the Free Software Foundation; either version 3, or (at your option) | |
10 ;; any later version. | |
11 | |
12 ;; GCC is distributed in the hope that it will be useful, | |
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 ;; GNU General Public License for more details. | |
16 | |
17 ;; You should have received a copy of the GNU General Public License | |
18 ;; along with GCC; see the file COPYING3. If not see | |
19 ;; <http://www.gnu.org/licenses/>. | |
20 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
21 (include "predicates.md") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
22 (include "constraints.md") |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
23 |
111 | 24 (define_c_enum "unspecv" |
25 [ | |
26 UNSPECV_BLOCKAGE | |
27 UNSPECV_SETD | |
28 UNSPECV_SETI | |
145 | 29 UNSPECV_CPYMEM |
111 | 30 ]) |
31 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
32 (define_constants |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
33 [ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
34 ;; Register numbers |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
35 (R0_REGNUM 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
36 (RETVAL_REGNUM 0) |
145 | 37 (FRAME_POINTER_REGNUM 5) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
38 (STACK_POINTER_REGNUM 6) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
39 (PC_REGNUM 7) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
40 (AC0_REGNUM 8) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
41 (AC3_REGNUM 11) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
42 (AC4_REGNUM 12) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
43 (AC5_REGNUM 13) |
145 | 44 ;; The next one is not a physical register but is used for |
45 ;; addressing arguments. | |
46 (ARG_POINTER_REGNUM 14) | |
131 | 47 ;; Condition code registers |
145 | 48 (CC_REGNUM 15) |
49 (FCC_REGNUM 16) | |
131 | 50 ;; End of hard registers |
145 | 51 (FIRST_PSEUDO_REGISTER 17) |
131 | 52 |
53 ;; Branch offset limits, as byte offsets from (pc). That is NOT | |
54 ;; the same thing as "instruction address" -- it is for backward | |
55 ;; branches, but for forward branches it refers to the address | |
56 ;; following the instruction. So the max forward distance | |
57 ;; matches what the processor handbook says, while the max | |
58 ;; backward branch is 2 less than the book. | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
59 (MIN_BRANCH -254) |
131 | 60 (MAX_BRANCH 254) |
61 (MIN_SOB -124) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
62 (MAX_SOB 0)]) |
0 | 63 |
131 | 64 ;; DF is 64 bit |
65 ;; SF is 32 bit | |
66 ;; SI is 32 bit | |
0 | 67 ;; HI is 16 bit |
68 ;; QI is 8 bit | |
69 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
70 ;; Integer modes supported on the PDP11, with a mapping from machine mode |
131 | 71 ;; to mnemonic suffix. SImode and DImode are usually special cases. |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
72 (define_mode_iterator PDPint [QI HI]) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
73 (define_mode_attr isfx [(QI "b") (HI "")]) |
131 | 74 (define_mode_attr mname [(QI "QImode") (HI "HImode") (SI "SImode") (DI "DImode")]) |
75 (define_mode_attr e_mname [(QI "E_QImode") (HI "E_HImode") (SI "E_SImode") (DI "E_DImode")]) | |
76 (define_mode_attr hmode [(QI "hi") (HI "hi") (SI "si") (DI "di")]) | |
77 | |
78 ;; These are analogous for use in splitters and expanders. | |
79 (define_mode_iterator HSint [HI SI]) | |
80 (define_mode_iterator QHSint [QI HI SI]) | |
81 (define_mode_iterator QHSDint [QI HI SI DI]) | |
82 | |
83 (define_code_iterator SHF [ashift ashiftrt lshiftrt]) | |
84 | |
85 ;; Substitution to turn a CC clobber into a CC setter. We have four of | |
86 ;; these: for CCmode vs. CCNZmode, and for CC_REGNUM vs. FCC_REGNUM. | |
87 (define_subst "cc_cc" | |
88 [(set (match_operand 0 "") (match_operand 1 "")) | |
89 (clobber (reg CC_REGNUM))] | |
90 "" | |
91 [(set (reg:CC CC_REGNUM) | |
92 (compare:CC (match_dup 1) (const_int 0))) | |
93 (set (match_dup 0) (match_dup 1))]) | |
94 | |
95 (define_subst "cc_ccnz" | |
96 [(set (match_operand 0 "") (match_operand 1 "")) | |
97 (clobber (reg CC_REGNUM))] | |
98 "" | |
99 [(set (reg:CCNZ CC_REGNUM) | |
100 (compare:CCNZ (match_dup 1) (const_int 0))) | |
101 (set (match_dup 0) (match_dup 1))]) | |
102 | |
103 (define_subst "fcc_cc" | |
104 [(set (match_operand 0 "") (match_operand 1 "")) | |
105 (clobber (reg FCC_REGNUM))] | |
106 "" | |
107 [(set (reg:CC FCC_REGNUM) | |
108 (compare:CC (match_dup 1) (const_int 0))) | |
109 (set (match_dup 0) (match_dup 1))]) | |
110 | |
111 (define_subst "fcc_ccnz" | |
112 [(set (match_operand 0 "") (match_operand 1 "")) | |
113 (clobber (reg FCC_REGNUM))] | |
114 "" | |
115 [(set (reg:CCNZ FCC_REGNUM) | |
116 (compare:CCNZ (match_dup 1) (const_int 0))) | |
117 (set (match_dup 0) (match_dup 1))]) | |
118 | |
119 (define_subst_attr "cc_cc" "cc_cc" "_nocc" "_cc") | |
120 (define_subst_attr "fcc_cc" "fcc_cc" "_nocc" "_cc") | |
121 (define_subst_attr "cc_ccnz" "cc_ccnz" "_nocc" "_cc") | |
122 (define_subst_attr "fcc_ccnz" "fcc_ccnz" "_nocc" "_cc") | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
123 |
0 | 124 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. |
125 | |
126 ;; Compare instructions. | |
127 | |
128 ;; currently we only support df floats, which saves us quite some | |
129 ;; hassle switching the FP mode! | |
130 ;; we assume that CPU is always in long float mode, and | |
131 ;; 16 bit integer mode - currently, the prologue for main does this, | |
132 ;; but maybe we should just set up a NEW crt0 properly, | |
133 ;; -- and what about signal handling code? | |
134 ;; (we don't even let sf floats in the register file, so | |
135 ;; we only should have to worry about truncating and widening | |
136 ;; when going to memory) | |
137 | |
138 ;; abort() call by g++ - must define libfunc for cmp_optab | |
139 ;; and ucmp_optab for mode SImode, because we don't have that!!! | |
140 ;; - yet since no libfunc is there, we abort () | |
141 | |
142 ;; define attributes | |
143 ;; currently type is only fpu or arith or unknown, maybe branch later ? | |
144 ;; default is arith | |
145 (define_attr "type" "unknown,arith,fp" (const_string "arith")) | |
146 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
147 ;; length default is 2 bytes each |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
148 (define_attr "length" "" (const_int 2)) |
0 | 149 |
131 | 150 ;; instruction base cost (not counting operands) |
151 (define_attr "base_cost" "" (const_int 2)) | |
152 | |
0 | 153 ;; a user's asm statement |
154 (define_asm_attributes | |
155 [(set_attr "type" "unknown") | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
156 ; length for asm is the max length per statement. That would be |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
157 ; 3 words, for a two-operand instruction with extra word addressing |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
158 ; modes for both operands. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
159 (set_attr "length" "6")]) |
0 | 160 |
161 ;; define function units | |
162 | |
111 | 163 ;; Prologue and epilogue support. |
164 | |
165 (define_expand "prologue" | |
166 [(const_int 0)] | |
167 "" | |
168 { | |
169 pdp11_expand_prologue (); | |
170 DONE; | |
171 }) | |
172 | |
173 (define_expand "epilogue" | |
174 [(const_int 0)] | |
175 "" | |
176 { | |
177 pdp11_expand_epilogue (); | |
178 DONE; | |
179 }) | |
180 | |
145 | 181 (define_insn "rtspc" |
111 | 182 [(return)] |
183 "" | |
131 | 184 "rts\tpc") |
111 | 185 |
186 (define_insn "blockage" | |
187 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] | |
188 "" | |
189 "" | |
190 [(set_attr "length" "0")]) | |
191 | |
192 (define_insn "setd" | |
193 [(unspec_volatile [(const_int 0)] UNSPECV_SETD)] | |
194 "" | |
195 "setd") | |
196 | |
197 (define_insn "seti" | |
198 [(unspec_volatile [(const_int 0)] UNSPECV_SETI)] | |
199 "" | |
200 "seti") | |
201 | |
0 | 202 ;; arithmetic - values here immediately when next insn issued |
203 ;; or does it mean the number of cycles after this insn was issued? | |
204 ;; how do I say that fpu insns use cpu also? (pre-interaction phase) | |
205 | |
206 ;(define_function_unit "cpu" 1 1 (eq_attr "type" "arith") 0 0) | |
207 ;(define_function_unit "fpu" 1 1 (eq_attr "type" "fp") 0 0) | |
208 | |
209 ;; compare | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
210 (define_insn "*cmpdf" |
131 | 211 [(set (reg:CC FCC_REGNUM) |
212 (compare:CC (match_operand:DF 0 "general_operand" "fR,fR,Q,QF") | |
213 (match_operand:DF 1 "register_or_const0_operand" "G,a,G,a")))] | |
214 "TARGET_FPU && reload_completed" | |
0 | 215 "* |
216 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
217 if (which_alternative == 0 || which_alternative == 2) |
131 | 218 return \"{tstd|tstf}\t%0\"; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
219 else |
131 | 220 return \"{cmpd|cmpf}\t%0,%1\"; |
0 | 221 }" |
131 | 222 [(set_attr "length" "2,2,4,4") |
223 (set_attr "base_cost" "4") | |
224 (set_attr "type" "fp")]) | |
0 | 225 |
131 | 226 ;; Copy floating point processor condition code register to main CPU |
227 ;; condition code register. | |
228 (define_insn "*cfcc" | |
229 [(set (reg CC_REGNUM) (reg FCC_REGNUM))] | |
230 "TARGET_FPU && reload_completed" | |
231 "cfcc") | |
232 | |
233 (define_insn "cmp<mode>" | |
234 [(set (reg:CC CC_REGNUM) | |
235 (compare:CC (match_operand:PDPint 0 "general_operand" "rR,rR,rR,Q,Qi,Qi") | |
236 (match_operand:PDPint 1 "general_operand" "N,rR,Qi,N,rR,Qi")))] | |
0 | 237 "" |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
238 "@ |
131 | 239 tst<PDPint:isfx>\t%0 |
240 cmp<PDPint:isfx>\t%0,%1 | |
241 cmp<PDPint:isfx>\t%0,%1 | |
242 tst<PDPint:isfx>\t%0 | |
243 cmp<PDPint:isfx>\t%0,%1 | |
244 cmp<PDPint:isfx>\t%0,%1" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
245 [(set_attr "length" "2,2,4,4,4,6")]) |
0 | 246 |
145 | 247 ;; Two word compare |
248 (define_insn "cmpsi" | |
249 [(set (reg:CC CC_REGNUM) | |
250 (compare:CC (match_operand:SI 0 "general_operand" "rDQi") | |
251 (match_operand:SI 1 "general_operand" "rDQi")))] | |
252 "" | |
253 { | |
254 rtx inops[2]; | |
255 rtx exops[2][2]; | |
256 rtx lb[1]; | |
257 | |
258 inops[0] = operands[0]; | |
259 inops[1] = operands[1]; | |
260 pdp11_expand_operands (inops, exops, 2, 2, NULL, big); | |
261 lb[0] = gen_label_rtx (); | |
262 | |
263 if (CONST_INT_P (exops[0][1]) && INTVAL (exops[0][1]) == 0) | |
264 output_asm_insn ("tst\t%0", exops[0]); | |
265 else | |
266 output_asm_insn ("cmp\t%0,%1", exops[0]); | |
267 output_asm_insn ("bne\t%l0", lb); | |
268 if (CONST_INT_P (exops[1][1]) && INTVAL (exops[1][1]) == 0) | |
269 output_asm_insn ("tst\t%0", exops[1]); | |
270 else | |
271 output_asm_insn ("cmp\t%0,%1", exops[1]); | |
272 output_asm_label (lb[0]); | |
273 fputs (":\n", asm_out_file); | |
274 | |
275 return ""; | |
276 } | |
277 [(set (attr "length") | |
278 (symbol_ref "pdp11_cmp_length (operands, 2)")) | |
279 (set_attr "base_cost" "0")]) | |
280 | |
281 ;; Four word compare | |
282 (define_insn "cmpdi" | |
283 [(set (reg:CC CC_REGNUM) | |
284 (compare:CC (match_operand:DI 0 "general_operand" "rDQi") | |
285 (match_operand:DI 1 "general_operand" "rDQi")))] | |
286 "" | |
287 { | |
288 rtx inops[4]; | |
289 rtx exops[4][2]; | |
290 rtx lb[1]; | |
291 int i; | |
292 | |
293 inops[0] = operands[0]; | |
294 inops[1] = operands[1]; | |
295 pdp11_expand_operands (inops, exops, 2, 4, NULL, big); | |
296 lb[0] = gen_label_rtx (); | |
297 | |
298 for (i = 0; i < 3; i++) | |
299 { | |
300 if (CONST_INT_P (exops[i][1]) && INTVAL (exops[i][1]) == 0) | |
301 output_asm_insn ("tst\t%0", exops[i]); | |
302 else | |
303 output_asm_insn ("cmp\t%0,%1", exops[i]); | |
304 output_asm_insn ("bne\t%l0", lb); | |
305 } | |
306 if (CONST_INT_P (exops[3][1]) && INTVAL (exops[3][1]) == 0) | |
307 output_asm_insn ("tst\t%0", exops[3]); | |
308 else | |
309 output_asm_insn ("cmp\t%0,%1", exops[3]); | |
310 output_asm_label (lb[0]); | |
311 fputs (":\n", asm_out_file); | |
312 | |
313 return ""; | |
314 } | |
315 [(set (attr "length") | |
316 (symbol_ref "pdp11_cmp_length (operands, 2)")) | |
317 (set_attr "base_cost" "0")]) | |
318 | |
131 | 319 ;; sob instruction |
320 ;; | |
321 ;; This expander has to check for mode match because the doloop pass | |
322 ;; in gcc that invokes it does not do so, i.e., it may attempt to apply | |
323 ;; this pattern even if the count operand is QI or SI mode. | |
324 (define_expand "doloop_end" | |
325 [(parallel [(set (pc) | |
326 (if_then_else | |
327 (ne (match_operand:HI 0 "nonimmediate_operand" "+r,!m") | |
328 (const_int 1)) | |
329 (label_ref (match_operand 1 "" "")) | |
330 (pc))) | |
331 (set (match_dup 0) | |
332 (plus:HI (match_dup 0) | |
333 (const_int -1)))])] | |
334 "TARGET_40_PLUS" | |
335 "{ | |
336 if (GET_MODE (operands[0]) != HImode) | |
337 FAIL; | |
338 }") | |
0 | 339 |
131 | 340 ;; Do a define_split because some alternatives clobber CC. |
341 ;; Some don't, but it isn't all that interesting to cover that case. | |
342 (define_insn_and_split "doloop_end_insn" | |
0 | 343 [(set (pc) |
344 (if_then_else | |
131 | 345 (ne (match_operand:HI 0 "nonimmediate_operand" "+r,!m") |
346 (const_int 1)) | |
0 | 347 (label_ref (match_operand 1 "" "")) |
348 (pc))) | |
349 (set (match_dup 0) | |
350 (plus:HI (match_dup 0) | |
351 (const_int -1)))] | |
352 "TARGET_40_PLUS" | |
131 | 353 "#" |
354 "&& reload_completed" | |
355 [(parallel [(set (pc) | |
356 (if_then_else | |
357 (ne (match_dup 0) (const_int 1)) | |
358 (label_ref (match_dup 1)) | |
359 (pc))) | |
360 (set (match_dup 0) | |
361 (plus:HI (match_dup 0) | |
362 (const_int -1))) | |
363 (clobber (reg:CC CC_REGNUM))])] | |
364 "") | |
365 | |
366 ;; Note that there is a memory alternative here. This is as documented | |
367 ;; in gccint, which says that doloop_end, since it has both a jump and | |
368 ;; an output interrupt "must handle its own reloads". That translates | |
369 ;; to: must accept memory operands as valid though they may be deprecated. | |
370 (define_insn "doloop_end_nocc" | |
371 [(set (pc) | |
372 (if_then_else | |
373 (ne (match_operand:HI 0 "nonimmediate_operand" "+r,!m") | |
374 (const_int 1)) | |
375 (label_ref (match_operand 1 "" "")) | |
376 (pc))) | |
377 (set (match_dup 0) | |
378 (plus:HI (match_dup 0) | |
379 (const_int -1))) | |
380 (clobber (reg:CC CC_REGNUM))] | |
381 "TARGET_40_PLUS && reload_completed" | |
0 | 382 "* |
383 { | |
131 | 384 rtx lb[1]; |
0 | 385 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
386 if (get_attr_length (insn) == 2) |
131 | 387 return \"sob\t%0,%l1\"; |
0 | 388 |
389 /* emulate sob */ | |
131 | 390 lb[0] = gen_label_rtx (); |
391 output_asm_insn (\"dec\t%0\", operands); | |
392 output_asm_insn (\"beq\t%l0\", lb); | |
393 output_asm_insn (\"jmp\t%l1\", operands); | |
0 | 394 |
131 | 395 output_asm_label (lb[0]); |
396 fputs (\":\\n\", asm_out_file); | |
0 | 397 |
398 return \"\"; | |
399 }" | |
131 | 400 [(set (attr "length") |
401 (if_then_else (eq (symbol_ref ("which_alternative")) (const_int 1)) | |
402 (const_int 10) | |
403 (if_then_else (ior (lt (minus (match_dup 1) (pc)) | |
404 (const_int MIN_SOB)) | |
405 (gt (minus (match_dup 1) (pc)) | |
406 (const_int MAX_SOB))) | |
407 (const_int 8) | |
408 (const_int 2))))]) | |
0 | 409 |
410 ;; These control RTL generation for conditional jump insns | |
411 ;; and match them for register allocation. | |
131 | 412 ;; Post reload these get expanded into insns that actually |
413 ;; manipulate the condition code registers. We can't do that before | |
414 ;; because instructions generated by reload clobber condition codes (new | |
415 ;; CC design, type #2). | |
416 (define_insn_and_split "cbranchdf4" | |
417 [(set (pc) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
418 (if_then_else (match_operator 0 "ordered_comparison_operator" |
131 | 419 [(match_operand:DF 1 "general_operand" "fg") |
420 (match_operand:DF 2 "general_operand" "a")]) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
421 (label_ref (match_operand 3 "" "")) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
422 (pc)))] |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
423 "TARGET_FPU" |
131 | 424 "#" |
425 "&& reload_completed" | |
426 [(set (reg:CC FCC_REGNUM) | |
427 (compare:CC (match_dup 1) (match_dup 2))) | |
428 (set (pc) | |
429 (if_then_else (match_op_dup 0 | |
430 [(reg:CC FCC_REGNUM) (const_int 0)]) | |
431 (label_ref (match_dup 3)) | |
432 (pc)))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
433 "") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
434 |
131 | 435 (define_insn_and_split "cbranch<mode>4" |
436 [(set (pc) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
437 (if_then_else (match_operator 0 "ordered_comparison_operator" |
145 | 438 [(match_operand:QHSDint 1 "general_operand" "g") |
439 (match_operand:QHSDint 2 "general_operand" "g")]) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
440 (label_ref (match_operand 3 "" "")) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
441 (pc)))] |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
442 "" |
131 | 443 "#" |
444 "reload_completed" | |
445 [(set (reg:CC CC_REGNUM) | |
446 (compare:CC (match_dup 1) (match_dup 2))) | |
447 (set (pc) | |
448 (if_then_else (match_op_dup 0 | |
449 [(reg:CC CC_REGNUM) (const_int 0)]) | |
450 (label_ref (match_dup 3)) | |
451 (pc)))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
452 "") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
453 |
131 | 454 ;; This splitter turns a branch on float condition into a branch on |
455 ;; CPU condition, by adding a CFCC. | |
456 (define_split | |
457 [(set (pc) | |
458 (if_then_else (match_operator 0 "ordered_comparison_operator" | |
459 [(reg:CC FCC_REGNUM) (const_int 0)]) | |
460 (label_ref (match_operand 1 "" "")) | |
461 (pc)))] | |
462 "TARGET_FPU && reload_completed" | |
463 [(set (reg:CC CC_REGNUM) (reg:CC FCC_REGNUM)) | |
464 (set (pc) | |
465 (if_then_else (match_op_dup 0 | |
466 [(reg:CC CC_REGNUM) (const_int 0)]) | |
467 (label_ref (match_dup 1)) | |
468 (pc)))] | |
469 "") | |
0 | 470 |
131 | 471 (define_insn "cond_branch" |
472 [(set (pc) | |
473 (if_then_else (match_operator 0 "ordered_comparison_operator" | |
474 [(reg:CC CC_REGNUM) (const_int 0)]) | |
475 (label_ref (match_operand 1 "" "")) | |
476 (pc)))] | |
477 "reload_completed" | |
478 "* return output_jump (operands, 0, get_attr_length (insn));" | |
479 [(set (attr "length") (if_then_else (ior (lt (minus (match_dup 1) | |
480 (pc)) | |
481 (const_int MIN_BRANCH)) | |
482 (gt (minus (match_dup 1) | |
483 (pc)) | |
484 (const_int MAX_BRANCH))) | |
485 (const_int 6) | |
486 (const_int 2)))]) | |
0 | 487 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
488 (define_insn "*branch" |
0 | 489 [(set (pc) |
131 | 490 (if_then_else (match_operator 0 "ccnz_operator" |
491 [(reg:CCNZ CC_REGNUM) (const_int 0)]) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
492 (label_ref (match_operand 1 "" "")) |
0 | 493 (pc)))] |
131 | 494 "reload_completed" |
495 "* return output_jump (operands, 1, get_attr_length (insn));" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
496 [(set (attr "length") (if_then_else (ior (lt (minus (match_dup 1) |
0 | 497 (pc)) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
498 (const_int MIN_BRANCH)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
499 (gt (minus (match_dup 1) |
0 | 500 (pc)) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
501 (const_int MAX_BRANCH))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
502 (const_int 6) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
503 (const_int 2)))]) |
0 | 504 |
505 | |
506 ;; Move instructions | |
507 | |
131 | 508 ;; "length" is defined even though this pattern won't appear at |
509 ;; assembly language output time. But the length is used by | |
510 ;; pdp11_insn_cost, before the post-reload splitter adds the | |
511 ;; CC clobber to the insn. | |
0 | 512 (define_insn "movdi" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
513 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,g") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
514 (match_operand:DI 1 "general_operand" "rN,g"))] |
0 | 515 "" |
131 | 516 "" |
517 [(set_attr "length" "16,32")]) | |
518 | |
519 | |
520 (define_insn "*movdi_nocc" | |
521 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,g") | |
522 (match_operand:DI 1 "general_operand" "rN,g")) | |
523 (clobber (reg:CC CC_REGNUM))] | |
524 "" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
525 "* return output_move_multiple (operands);" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
526 [(set_attr "length" "16,32")]) |
0 | 527 |
528 (define_insn "movsi" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
529 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,g,g") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
530 (match_operand:SI 1 "general_operand" "rN,IJ,IJ,g"))] |
0 | 531 "" |
131 | 532 "" |
533 [(set_attr "length" "4,6,8,16")]) | |
534 | |
535 (define_insn "*movsi_nocc" | |
536 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,g,g") | |
537 (match_operand:SI 1 "general_operand" "rN,IJ,IJ,g")) | |
538 (clobber (reg:CC CC_REGNUM))] | |
539 "" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
540 "* return output_move_multiple (operands);" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
541 [(set_attr "length" "4,6,8,16")]) |
0 | 542 |
145 | 543 ;; That long string of "Z" constraints enforces the restriction that |
544 ;; a register source and auto increment or decrement destination must | |
545 ;; not use the same register, because that case is not consistently | |
546 ;; implemented across the PDP11 models. | |
547 ;; TODO: the same should be applied to insn like add, but this is not | |
548 ;; necessary yet because the incdec optimization pass does not apply | |
549 ;; that optimization to 3-operand insns at the moment. | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
550 (define_insn "mov<mode>" |
145 | 551 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,Za,Zb,Zc,Zd,Ze,Zf,Zg,rD,rR,Q,Q") |
552 (match_operand:PDPint 1 "general_operand" "RN,Z0,Z1,Z2,Z3,Z4,Z5,Z6,r,Qi,rRN,Qi"))] | |
0 | 553 "" |
131 | 554 "" |
145 | 555 [(set_attr "length" "2,2,2,2,2,2,2,2,2,4,4,6")]) |
131 | 556 |
557 ;; This splits all the integer moves: DI and SI modes as well as | |
558 ;; the simple machine operations. | |
559 (define_split | |
560 [(set (match_operand:QHSDint 0 "nonimmediate_operand" "") | |
561 (match_operand:QHSDint 1 "general_operand" ""))] | |
562 "reload_completed" | |
563 [(parallel [(set (match_dup 0) | |
564 (match_dup 1)) | |
565 (clobber (reg:CC CC_REGNUM))])] | |
566 "") | |
567 | |
568 ;; MOV clears V | |
569 (define_insn "*mov<mode>_<cc_cc>" | |
145 | 570 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,Za,Zb,Zc,Zd,Ze,Zf,Zg,rD,rR,Q,Q") |
571 (match_operand:PDPint 1 "general_operand" "RN,Z0,Z1,Z2,Z3,Z4,Z5,Z6,r,Qi,rRN,Qi")) | |
131 | 572 (clobber (reg:CC CC_REGNUM))] |
573 "reload_completed" | |
0 | 574 "* |
575 { | |
576 if (operands[1] == const0_rtx) | |
131 | 577 return \"clr<PDPint:isfx>\t%0\"; |
0 | 578 |
131 | 579 return \"mov<PDPint:isfx>\t%1,%0\"; |
0 | 580 }" |
145 | 581 [(set_attr "length" "2,2,2,2,2,2,2,2,2,4,4,6")]) |
0 | 582 |
131 | 583 ;; movdf has unusually complicated condition code handling, because |
584 ;; load (into float register) updates the FCC, while store (from | |
585 ;; float register) leaves it untouched. | |
586 ;; | |
587 ;; 1. Loads are: ac4, ac5, or non-register into load-register | |
588 ;; 2. Stores are: load-register to non-register, ac4, or ac5 | |
589 ;; 3. Moves from ac0-ac3 to another ac0-ac3 can be handled | |
590 ;; either as loads or as stores. | |
591 | |
592 (define_expand "movdf" | |
593 [(set (match_operand:DF 0 "float_nonimm_operand" "") | |
594 (match_operand:DF 1 "float_operand" ""))] | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
595 "TARGET_FPU" |
131 | 596 "") |
0 | 597 |
131 | 598 ;; Splitter for all these cases. Store is the first two |
599 ;; alternatives, which are not split. Note that case 3 | |
600 ;; is treated as a store, i.e., not split. | |
601 (define_insn_and_split "movdf_split" | |
602 [(set (match_operand:DF 0 "float_nonimm_operand" "=fR,FQ,a,a,a") | |
603 (match_operand:DF 1 "float_operand" "a,a,hR,FQ,G"))] | |
0 | 604 "TARGET_FPU" |
131 | 605 "* |
606 gcc_assert (which_alternative < 2); | |
607 return \"std\t%1,%0\"; | |
608 " | |
609 "&& reload_completed" | |
610 [(parallel [(set (match_dup 0) | |
611 (match_dup 1)) | |
612 (clobber (reg:CC FCC_REGNUM))])] | |
613 "{ | |
614 if (GET_CODE (operands[1]) == REG && | |
615 REGNO_REG_CLASS (REGNO (operands[1])) == LOAD_FPU_REGS) | |
616 FAIL; | |
617 }" | |
618 [(set_attr "length" "2,4,0,0,0")]) | |
619 | |
620 ;; Loads (case 1). | |
621 (define_insn "*ldd<fcc_cc>" | |
622 [(set (match_operand:DF 0 "float_nonimm_operand" "=a,a,a") | |
623 (match_operand:DF 1 "float_operand" "hR,FQ,G")) | |
624 (clobber (reg:CC FCC_REGNUM))] | |
625 "TARGET_FPU && reload_completed" | |
626 "@ | |
627 ldd\t%1,%0 | |
628 ldd\t%1,%0 | |
629 clrd\t%0" | |
630 [(set_attr "length" "2,4,2")]) | |
0 | 631 |
131 | 632 ;; SFmode is easier because that uses convert load/store, which |
633 ;; always change condition codes. | |
634 ;; Note that these insns are cheating a bit. We actually have | |
635 ;; DFmode operands in the FPU registers, which is why the | |
636 ;; ldcfd and stcdf instructions appear. But GCC likes to think | |
637 ;; of these as SFmode loads and does the conversion once in the | |
638 ;; register, at least in many cases. So we pretend to do this, | |
639 ;; but then extend and truncate register-to-register are NOP and | |
640 ;; generate no code. | |
641 (define_insn_and_split "movsf" | |
642 [(set (match_operand:SF 0 "float_nonimm_operand" "=a,fR,a,Q,a") | |
643 (match_operand:SF 1 "float_operand" "fRG,a,FQ,a,G"))] | |
644 "TARGET_FPU" | |
645 "#" | |
646 "&& reload_completed" | |
647 [(parallel [(set (match_dup 0) | |
648 (match_dup 1)) | |
649 (clobber (reg:CC FCC_REGNUM))])] | |
650 "" | |
651 [(set_attr "length" "2,2,4,4,2")]) | |
652 | |
653 (define_insn "*movsf<fcc_ccnz>" | |
654 [(set (match_operand:SF 0 "float_nonimm_operand" "=a,fR,a,Q,a") | |
655 (match_operand:SF 1 "float_operand" "fR,a,FQ,a,G")) | |
656 (clobber (reg:CC FCC_REGNUM))] | |
657 "TARGET_FPU && reload_completed" | |
658 "@ | |
659 {ldcfd|movof}\t%1,%0 | |
660 {stcdf|movfo}\t%1,%0 | |
661 {ldcfd|movof}\t%1,%0 | |
662 {stcdf|movfo}\t%1,%0 | |
663 clrf\t%0" | |
664 [(set_attr "length" "2,2,4,4,2")]) | |
0 | 665 |
131 | 666 ;; Expand a block move. We turn this into a move loop. |
145 | 667 (define_expand "cpymemhi" |
668 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_CPYMEM) | |
669 (match_operand:BLK 0 "general_operand" "=g") | |
670 (match_operand:BLK 1 "general_operand" "g") | |
671 (match_operand:HI 2 "immediate_operand" "i") | |
672 (match_operand:HI 3 "immediate_operand" "i") | |
673 (clobber (mem:BLK (scratch))) | |
674 (clobber (match_dup 0)) | |
675 (clobber (match_dup 1)) | |
676 (clobber (match_dup 2))])] | |
131 | 677 "" |
0 | 678 " |
679 { | |
145 | 680 int count; |
681 count = INTVAL (operands[2]); | |
682 if (count == 0) | |
683 DONE; | |
684 if (INTVAL (operands [3]) >= 2 && (count & 1) == 0) | |
685 count >>= 1; | |
686 else | |
687 operands[3] = const1_rtx; | |
688 operands[2] = copy_to_mode_reg (HImode, | |
689 gen_rtx_CONST_INT (HImode, count)); | |
690 | |
691 /* Load BLKmode MEM addresses into scratch registers. */ | |
692 operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); | |
693 operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); | |
0 | 694 }") |
695 | |
145 | 696 ;; Expand a block move. We turn this into a move loop. |
697 (define_insn_and_split "cpymemhi1" | |
698 [(unspec_volatile [(const_int 0)] UNSPECV_CPYMEM) | |
699 (match_operand:HI 0 "register_operand" "+r") | |
700 (match_operand:HI 1 "register_operand" "+r") | |
701 (match_operand:HI 2 "register_operand" "+r") | |
702 (match_operand:HI 3 "immediate_operand" "i") | |
703 (clobber (mem:BLK (scratch))) | |
704 (clobber (match_dup 0)) | |
705 (clobber (match_dup 1)) | |
706 (clobber (match_dup 2))] | |
707 "" | |
708 "#" | |
709 "reload_completed" | |
710 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_CPYMEM) | |
711 (match_dup 0) | |
712 (match_dup 1) | |
713 (match_dup 2) | |
714 (match_dup 3) | |
715 (clobber (mem:BLK (scratch))) | |
716 (clobber (match_dup 0)) | |
717 (clobber (match_dup 1)) | |
718 (clobber (match_dup 2)) | |
719 (clobber (reg:CC CC_REGNUM))])] | |
720 "") | |
721 | |
722 (define_insn "cpymemhi_nocc" | |
723 [(unspec_volatile [(const_int 0)] UNSPECV_CPYMEM) | |
724 (match_operand:HI 0 "register_operand" "+r") | |
725 (match_operand:HI 1 "register_operand" "+r") | |
726 (match_operand:HI 2 "register_operand" "+r") | |
727 (match_operand:HI 3 "immediate_operand" "i") | |
728 (clobber (mem:BLK (scratch))) | |
729 (clobber (match_dup 0)) | |
730 (clobber (match_dup 1)) | |
731 (clobber (match_dup 2)) | |
732 (clobber (reg:CC CC_REGNUM))] | |
733 "reload_completed" | |
734 "* | |
735 { | |
736 rtx lb[2]; | |
737 | |
738 lb[0] = operands[2]; | |
739 lb[1] = gen_label_rtx (); | |
740 | |
741 output_asm_label (lb[1]); | |
742 fputs (\":\n\", asm_out_file); | |
743 if (INTVAL (operands[3]) > 1) | |
744 output_asm_insn (\"mov\t(%1)+,(%0)+\", operands); | |
745 else | |
746 output_asm_insn (\"movb\t(%1)+,(%0)+\", operands); | |
747 if (TARGET_40_PLUS) | |
748 output_asm_insn (\"sob\t%0,%l1\", lb); | |
749 else | |
750 { | |
751 output_asm_insn (\"dec\t%0\", lb); | |
752 output_asm_insn (\"bne\t%l1\", lb); | |
753 } | |
754 return \"\"; | |
755 }" | |
756 [(set (attr "length") | |
757 (if_then_else (match_test "TARGET_40_PLUS") | |
758 (const_int 4) | |
759 (const_int 6)))]) | |
0 | 760 |
761 ;;- truncation instructions | |
762 | |
131 | 763 ;; We sometimes end up doing a register to register truncate, |
764 ;; which isn't right because we actually load registers always | |
765 ;; with a DFmode value. But even with PROMOTE the compiler | |
766 ;; doesn't always get that (so we don't use it). That means | |
767 ;; a register to register truncate is a NOP. | |
768 (define_insn_and_split "truncdfsf2" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
769 [(set (match_operand:SF 0 "float_nonimm_operand" "=f,R,Q") |
131 | 770 (float_truncate:SF (match_operand:DF 1 "register_operand" "0,a,a")))] |
0 | 771 "TARGET_FPU" |
131 | 772 { |
773 gcc_assert (which_alternative == 0); | |
774 return ""; | |
775 } | |
776 "&& reload_completed" | |
777 [(parallel [(set (match_dup 0) (float_truncate:SF (match_dup 1))) | |
778 (clobber (reg:CC FCC_REGNUM))])] | |
779 "{ | |
780 if (GET_CODE (operands[0]) == REG && | |
781 GET_CODE (operands[1]) == REG && | |
782 REGNO (operands[0]) == REGNO (operands[1])) | |
783 FAIL; | |
784 }" | |
785 [(set_attr "length" "0,0,0")]) | |
0 | 786 |
131 | 787 (define_insn "*truncdfsf2_<fcc_cc>" |
788 [(set (match_operand:SF 0 "float_nonimm_operand" "=R,Q") | |
789 (float_truncate:SF (match_operand:DF 1 "register_operand" "a,a"))) | |
790 (clobber (reg:CC FCC_REGNUM))] | |
791 "TARGET_FPU && reload_completed" | |
792 "{stcdf|movfo}\t%1,%0" | |
793 [(set_attr "length" "2,4")]) | |
0 | 794 |
795 | |
131 | 796 ;;- zero extension instruction |
797 | |
798 (define_insn_and_split "zero_extendqihi2" | |
799 [(set (match_operand:HI 0 "nonimmediate_operand" "=rD,Q,&r,&r") | |
800 (zero_extend:HI (match_operand:QI 1 "general_operand" "0,0,rR,Q")))] | |
801 "" | |
802 "#" | |
803 "reload_completed" | |
804 [(parallel [(set (match_dup 0) (zero_extend:HI (match_dup 1))) | |
805 (clobber (reg:CC CC_REGNUM))])] | |
806 "{ | |
807 rtx r; | |
0 | 808 |
131 | 809 if (!REG_P (operands[0])) |
810 { | |
811 r = gen_rtx_MEM (QImode, operands[0]); | |
812 adjust_address (r, QImode, 1); | |
813 emit_move_insn (r, const0_rtx); | |
814 DONE; | |
815 } | |
145 | 816 else if (!REG_P (operands[1]) || |
817 REGNO (operands[0]) != REGNO (operands[1])) | |
131 | 818 { |
819 /* Alternatives 2 and 3 */ | |
820 emit_move_insn (operands[0], const0_rtx); | |
821 r = gen_rtx_REG (QImode, REGNO (operands[0])); | |
822 emit_insn (gen_iorqi3_nocc (r, r, operands[1])); | |
823 DONE; | |
824 } | |
825 }" | |
826 [(set_attr "length" "4,4,4,6")]) | |
827 | |
828 (define_insn "*zero_extendqihi2<cc_cc>" | |
829 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,Q") | |
830 (zero_extend:HI (match_operand:QI 1 "general_operand" "0,0"))) | |
831 (clobber (reg:CC CC_REGNUM))])] | |
832 "reload_completed" | |
833 "bic\t%#0177400,%0" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
834 [(set_attr "length" "4,6")]) |
0 | 835 |
836 ;;- sign extension instructions | |
837 | |
131 | 838 ;; We sometimes end up doing a register to register extend, |
839 ;; which isn't right because we actually load registers always | |
840 ;; with a DFmode value. But even with PROMOTE the compiler | |
841 ;; doesn't always get that (so we don't use it). That means | |
842 ;; a register to register truncate is a NOP. | |
843 (define_insn_and_split "extendsfdf2" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
844 [(set (match_operand:DF 0 "register_operand" "=f,a,a") |
131 | 845 (float_extend:DF (match_operand:SF 1 "float_operand" "0,R,Q")))] |
0 | 846 "TARGET_FPU" |
131 | 847 { |
848 gcc_assert (which_alternative == 0); | |
849 return ""; | |
850 } | |
851 "&& reload_completed" | |
852 [(parallel [(set (match_dup 0) (float_extend:DF (match_dup 1))) | |
853 (clobber (reg:CC FCC_REGNUM))])] | |
854 "{ | |
855 if (GET_CODE (operands[0]) == REG && | |
856 GET_CODE (operands[1]) == REG && | |
857 REGNO (operands[0]) == REGNO (operands[1])) | |
858 FAIL; | |
859 }" | |
860 [(set_attr "length" "0,0,0")]) | |
0 | 861 |
131 | 862 (define_insn "*extendsfdf2_<fcc_cc>" |
863 [(set (match_operand:DF 0 "register_operand" "=a,a") | |
864 (float_extend:DF (match_operand:SF 1 "float_operand" "R,Q"))) | |
865 (clobber (reg:CC FCC_REGNUM))] | |
866 "TARGET_FPU && reload_completed" | |
867 "{ldcfd|movof}\t%1,%0" | |
868 [(set_attr "length" "2,4") | |
869 (set_attr "base_cost" "6")]) | |
870 | |
871 ;; movb sign extends if destination is a register | |
872 (define_insn_and_split "extendqihi2" | |
0 | 873 [(set (match_operand:HI 0 "register_operand" "=r,r") |
874 (sign_extend:HI (match_operand:QI 1 "general_operand" "rR,Q")))] | |
875 "" | |
131 | 876 "#" |
877 "reload_completed" | |
878 [(parallel [(set (match_dup 0) (sign_extend:HI (match_dup 1))) | |
879 (clobber (reg:CC CC_REGNUM))])] | |
880 "" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
881 [(set_attr "length" "2,4")]) |
0 | 882 |
131 | 883 ;; MOVB clears V |
884 (define_insn "*extendqihi2<cc_cc>" | |
885 [(set (match_operand:HI 0 "register_operand" "=r,r") | |
886 (sign_extend:HI (match_operand:QI 1 "general_operand" "rR,Q"))) | |
887 (clobber (reg:CC CC_REGNUM))] | |
888 "reload_completed" | |
889 "movb\t%1,%0" | |
890 [(set_attr "length" "2,4")]) | |
0 | 891 |
131 | 892 (define_insn_and_split "extendhisi2" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
893 [(set (match_operand:SI 0 "nonimmediate_operand" "=o,<,r") |
0 | 894 (sign_extend:SI (match_operand:HI 1 "general_operand" "g,g,g")))] |
895 "TARGET_40_PLUS" | |
131 | 896 "#" |
897 "&& reload_completed" | |
898 [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1))) | |
899 (clobber (reg:CC CC_REGNUM))])] | |
900 "" | |
901 [(set_attr "length" "10,6,6")]) | |
902 | |
903 (define_insn "*extendhisi2_nocc" | |
904 [(set (match_operand:SI 0 "nonimmediate_operand" "=o,<,r") | |
905 (sign_extend:SI (match_operand:HI 1 "general_operand" "g,g,g"))) | |
906 (clobber (reg:CC CC_REGNUM))] | |
907 "TARGET_40_PLUS && reload_completed" | |
0 | 908 "* |
909 { | |
910 rtx latehalf[2]; | |
911 | |
912 /* we don't want to mess with auto increment */ | |
913 | |
914 switch (which_alternative) | |
915 { | |
916 case 0: | |
917 | |
918 latehalf[0] = operands[0]; | |
919 operands[0] = adjust_address(operands[0], HImode, 2); | |
920 | |
131 | 921 output_asm_insn(\"mov\t%1,%0\", operands); |
922 output_asm_insn(\"sxt\t%0\", latehalf); | |
0 | 923 |
924 return \"\"; | |
925 | |
926 case 1: | |
927 | |
928 /* - auto-decrement - right direction ;-) */ | |
131 | 929 output_asm_insn(\"mov\t%1,%0\", operands); |
930 output_asm_insn(\"sxt\t%0\", operands); | |
0 | 931 |
932 return \"\"; | |
933 | |
934 case 2: | |
935 | |
936 /* make register pair available */ | |
937 latehalf[0] = operands[0]; | |
938 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); | |
939 | |
131 | 940 output_asm_insn(\"mov\t%1,%0\", operands); |
941 output_asm_insn(\"sxt\t%0\", latehalf); | |
0 | 942 |
943 return \"\"; | |
944 | |
945 default: | |
946 | |
947 gcc_unreachable (); | |
948 } | |
949 }" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
950 [(set_attr "length" "10,6,6")]) |
0 | 951 |
952 ;; make float to int and vice versa | |
953 ;; assume that we are normally in double and integer mode - | |
954 ;; what do pdp library routines do to fpu mode ? | |
955 | |
131 | 956 ;; Note: the hardware treats register source as |
957 ;; a 16-bit (high order only) source, which isn't | |
958 ;; what we want. But we do need to support register | |
959 ;; dest because gcc asks for it. | |
960 (define_insn_and_split "floatsidf2" | |
0 | 961 [(set (match_operand:DF 0 "register_operand" "=a,a,a") |
962 (float:DF (match_operand:SI 1 "general_operand" "r,R,Q")))] | |
963 "TARGET_FPU" | |
131 | 964 "#" |
965 "&& reload_completed" | |
966 [(parallel [(set (match_dup 0) (float:DF (match_dup 1))) | |
967 (clobber (reg:CC FCC_REGNUM))])] | |
968 "" | |
969 [(set_attr "length" "10,6,8")]) | |
970 | |
971 (define_insn "*floatsidf2<fcc_cc>" | |
972 [(set (match_operand:DF 0 "register_operand" "=a,a,a") | |
973 (float:DF (match_operand:SI 1 "general_operand" "r,R,Q"))) | |
974 (clobber (reg:CC FCC_REGNUM))] | |
975 "TARGET_FPU && reload_completed" | |
0 | 976 "* if (which_alternative ==0) |
977 { | |
978 rtx latehalf[2]; | |
131 | 979 |
0 | 980 latehalf[0] = NULL; |
981 latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1); | |
131 | 982 output_asm_insn(\"mov\t%1,-(sp)\", latehalf); |
983 output_asm_insn(\"mov\t%1,-(sp)\", operands); | |
0 | 984 |
985 output_asm_insn(\"setl\", operands); | |
131 | 986 output_asm_insn(\"{ldcld|movif}\t(sp)+,%0\", operands); |
0 | 987 output_asm_insn(\"seti\", operands); |
988 return \"\"; | |
989 } | |
990 else | |
131 | 991 return \"setl\;{ldcld|movif}\t%1,%0\;seti\"; |
0 | 992 " |
131 | 993 [(set_attr "length" "10,6,8") |
994 (set_attr "base_cost" "12")]) | |
0 | 995 |
131 | 996 (define_insn_and_split "floathidf2" |
0 | 997 [(set (match_operand:DF 0 "register_operand" "=a,a") |
998 (float:DF (match_operand:HI 1 "general_operand" "rR,Qi")))] | |
999 "TARGET_FPU" | |
131 | 1000 "#" |
1001 "&& reload_completed" | |
1002 [(parallel [(set (match_dup 0) (float:DF (match_dup 1))) | |
1003 (clobber (reg:CC FCC_REGNUM))])] | |
1004 "" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1005 [(set_attr "length" "2,4")]) |
131 | 1006 |
1007 (define_insn "*floathidf2<fcc_cc>" | |
1008 [(set (match_operand:DF 0 "register_operand" "=a,a") | |
1009 (float:DF (match_operand:HI 1 "general_operand" "rR,Qi"))) | |
1010 (clobber (reg:CC FCC_REGNUM))] | |
1011 "TARGET_FPU && reload_completed" | |
1012 "{ldcid|movif}\t%1,%0" | |
1013 [(set_attr "length" "2,4") | |
1014 (set_attr "base_cost" "12")]) | |
1015 | |
0 | 1016 ;; cut float to int |
131 | 1017 |
1018 ;; Note: the hardware treats register destination as | |
1019 ;; a 16-bit (high order only) destination, which isn't | |
1020 ;; what we want. But we do need to support register | |
1021 ;; dest because gcc asks for it. | |
1022 (define_insn_and_split "fix_truncdfsi2" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1023 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,R,Q") |
0 | 1024 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a,a"))))] |
1025 "TARGET_FPU" | |
131 | 1026 "#" |
1027 "&& reload_completed" | |
1028 [(parallel [(set (match_dup 0) (fix:SI (fix:DF (match_dup 1)))) | |
1029 (clobber (reg:CC CC_REGNUM)) | |
1030 (clobber (reg:CC FCC_REGNUM))])] | |
1031 "" | |
1032 [(set_attr "length" "10,6,8")]) | |
1033 | |
1034 ;; Note: this clobbers both sets of condition codes! | |
1035 (define_insn "*fix_truncdfsi2_nocc" | |
1036 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,R,Q") | |
1037 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a,a")))) | |
1038 (clobber (reg:CC CC_REGNUM)) | |
1039 (clobber (reg:CC FCC_REGNUM))] | |
1040 "TARGET_FPU && reload_completed" | |
0 | 1041 "* if (which_alternative ==0) |
1042 { | |
1043 output_asm_insn(\"setl\", operands); | |
131 | 1044 output_asm_insn(\"{stcdl|movfi}\t%1,-(sp)\", operands); |
0 | 1045 output_asm_insn(\"seti\", operands); |
131 | 1046 output_asm_insn(\"mov\t(sp)+,%0\", operands); |
0 | 1047 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); |
131 | 1048 output_asm_insn(\"mov\t(sp)+,%0\", operands); |
0 | 1049 return \"\"; |
1050 } | |
1051 else | |
131 | 1052 return \"setl\;{stcdl|movfi}\t%1,%0\;seti\"; |
0 | 1053 " |
131 | 1054 [(set_attr "length" "10,6,8") |
1055 (set_attr "base_cost" "12")]) | |
0 | 1056 |
131 | 1057 (define_insn_and_split "fix_truncdfhi2" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1058 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,Q") |
0 | 1059 (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))] |
1060 "TARGET_FPU" | |
131 | 1061 "#" |
1062 "&& reload_completed" | |
1063 [(parallel [(set (match_dup 0) (fix:HI (fix:DF (match_dup 1)))) | |
1064 (clobber (reg:CC CC_REGNUM)) | |
1065 (clobber (reg:CC FCC_REGNUM))])] | |
1066 "" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1067 [(set_attr "length" "2,4")]) |
0 | 1068 |
131 | 1069 ;; Note: this clobbers both sets of condition codes! |
1070 (define_insn "*fix_truncdfhi2_nocc" | |
1071 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,Q") | |
1072 (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "a,a")))) | |
1073 (clobber (reg:CC CC_REGNUM)) | |
1074 (clobber (reg:CC FCC_REGNUM))] | |
1075 "TARGET_FPU && reload_completed" | |
1076 "{stcdi|movfi}\t%1,%0" | |
1077 [(set_attr "length" "2,4") | |
1078 (set_attr "base_cost" "12")]) | |
1079 | |
0 | 1080 |
1081 ;;- arithmetic instructions | |
1082 ;;- add instructions | |
1083 | |
131 | 1084 (define_insn_and_split "adddf3" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1085 [(set (match_operand:DF 0 "register_operand" "=a,a") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1086 (plus:DF (match_operand:DF 1 "register_operand" "%0,0") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1087 (match_operand:DF 2 "general_operand" "fR,QF")))] |
0 | 1088 "TARGET_FPU" |
131 | 1089 "#" |
1090 "&& reload_completed" | |
1091 [(parallel [(set (match_dup 0) | |
1092 (plus:DF (match_dup 1) (match_dup 2))) | |
1093 (clobber (reg:CC FCC_REGNUM))])] | |
1094 "" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1095 [(set_attr "length" "2,4")]) |
0 | 1096 |
131 | 1097 ;; Float add sets V if overflow from add |
1098 (define_insn "*adddf3<fcc_ccnz>" | |
1099 [(set (match_operand:DF 0 "register_operand" "=a,a") | |
1100 (plus:DF (match_operand:DF 1 "register_operand" "%0,0") | |
1101 (match_operand:DF 2 "general_operand" "fR,QF"))) | |
1102 (clobber (reg:CC FCC_REGNUM))] | |
1103 "TARGET_FPU && reload_completed" | |
1104 "{addd|addf}\t%2,%0" | |
1105 [(set_attr "length" "2,4") | |
1106 (set_attr "base_cost" "6")]) | |
1107 | |
1108 (define_insn_and_split "adddi3" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1109 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,o") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1110 (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1111 (match_operand:DI 2 "general_operand" "r,on,r,on")))] |
0 | 1112 "" |
131 | 1113 "#" |
1114 "reload_completed" | |
1115 [(parallel [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2))) | |
1116 (clobber (reg:CC CC_REGNUM))])] | |
1117 "" | |
1118 [(set_attr "length" "20,28,40,48")]) | |
1119 | |
1120 (define_insn "*adddi3_nocc" | |
1121 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,o") | |
1122 (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0") | |
1123 (match_operand:DI 2 "general_operand" "r,on,r,on"))) | |
1124 (clobber (reg:CC CC_REGNUM))] | |
1125 "reload_completed" | |
0 | 1126 "* |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1127 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1128 rtx inops[2]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1129 rtx exops[4][2]; |
0 | 1130 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1131 inops[0] = operands[0]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1132 inops[1] = operands[2]; |
145 | 1133 pdp11_expand_operands (inops, exops, 2, 4, NULL, big); |
0 | 1134 |
145 | 1135 if (!CONST_INT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0) |
131 | 1136 output_asm_insn (\"add\t%1,%0\", exops[0]); |
145 | 1137 if (!CONST_INT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0) |
0 | 1138 { |
131 | 1139 output_asm_insn (\"add\t%1,%0\", exops[1]); |
1140 output_asm_insn (\"adc\t%0\", exops[0]); | |
0 | 1141 } |
145 | 1142 if (!CONST_INT_P (exops[2][1]) || INTVAL (exops[2][1]) != 0) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1143 { |
131 | 1144 output_asm_insn (\"add\t%1,%0\", exops[2]); |
1145 output_asm_insn (\"adc\t%0\", exops[1]); | |
1146 output_asm_insn (\"adc\t%0\", exops[0]); | |
0 | 1147 } |
145 | 1148 if (!CONST_INT_P (exops[3][1]) || INTVAL (exops[3][1]) != 0) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1149 { |
131 | 1150 output_asm_insn (\"add\t%1,%0\", exops[3]); |
1151 output_asm_insn (\"adc\t%0\", exops[2]); | |
1152 output_asm_insn (\"adc\t%0\", exops[1]); | |
1153 output_asm_insn (\"adc\t%0\", exops[0]); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1154 } |
0 | 1155 |
1156 return \"\"; | |
1157 }" | |
131 | 1158 [(set_attr "length" "20,28,40,48") |
1159 (set_attr "base_cost" "0")]) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1160 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1161 ;; Note that the register operand is not marked earlyclobber. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1162 ;; The reason is that SI values go in register pairs, so they |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1163 ;; can't partially overlap. They can be either disjoint, or |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1164 ;; source and destination can be equal. The latter case is |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1165 ;; handled properly because of the ordering of the individual |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1166 ;; instructions used. Specifically, carry from the low to the |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1167 ;; high word is added at the end, so the adding of the high parts |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1168 ;; will always used the original high part and not a high part |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1169 ;; modified by carry (which would amount to double carry). |
131 | 1170 (define_insn_and_split "addsi3" |
1171 [(set (match_operand:SI 0 "nonimmediate_operand" "=&r,r,o,o") | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1172 (plus:SI (match_operand:SI 1 "general_operand" "%0,0,0,0") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1173 (match_operand:SI 2 "general_operand" "r,on,r,on")))] |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1174 "" |
131 | 1175 "#" |
1176 "reload_completed" | |
1177 [(parallel [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2))) | |
1178 (clobber (reg:CC CC_REGNUM))])] | |
1179 "" | |
1180 [(set_attr "length" "6,10,12,16")]) | |
1181 | |
1182 (define_insn "*addsi3_nocc" | |
1183 [(set (match_operand:SI 0 "nonimmediate_operand" "=&r,r,o,o") | |
1184 (plus:SI (match_operand:SI 1 "general_operand" "%0,0,0,0") | |
1185 (match_operand:SI 2 "general_operand" "r,on,r,on"))) | |
1186 (clobber (reg:CC CC_REGNUM))] | |
1187 "reload_completed" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1188 "* |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1189 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1190 rtx inops[2]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1191 rtx exops[2][2]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1192 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1193 inops[0] = operands[0]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1194 inops[1] = operands[2]; |
145 | 1195 pdp11_expand_operands (inops, exops, 2, 2, NULL, big); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1196 |
145 | 1197 if (!CONST_INT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0) |
131 | 1198 output_asm_insn (\"add\t%1,%0\", exops[0]); |
145 | 1199 if (!CONST_INT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1200 { |
131 | 1201 output_asm_insn (\"add\t%1,%0\", exops[1]); |
1202 output_asm_insn (\"adc\t%0\", exops[0]); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1203 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1204 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1205 return \"\"; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1206 }" |
131 | 1207 [(set_attr "length" "6,10,12,16") |
1208 (set_attr "base_cost" "0")]) | |
0 | 1209 |
131 | 1210 (define_insn_and_split "addhi3" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1211 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,rR,Q,Q") |
0 | 1212 (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0") |
1213 (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))] | |
1214 "" | |
131 | 1215 "#" |
1216 "reload_completed" | |
1217 [(parallel [(set (match_dup 0) | |
1218 (plus:HI (match_dup 1) (match_dup 2))) | |
1219 (clobber (reg:CC CC_REGNUM))])] | |
1220 "" | |
1221 [(set_attr "length" "2,4,4,6")]) | |
1222 | |
1223 ;; Add sets V if overflow from the add | |
1224 (define_insn "*addhi3<cc_ccnz>" | |
1225 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,rR,Q,Q") | |
1226 (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0") | |
1227 (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi"))) | |
1228 (clobber (reg:CC CC_REGNUM))] | |
1229 "reload_completed" | |
0 | 1230 "* |
1231 { | |
1232 if (GET_CODE (operands[2]) == CONST_INT) | |
1233 { | |
1234 if (INTVAL(operands[2]) == 1) | |
131 | 1235 return \"inc\t%0\"; |
0 | 1236 else if (INTVAL(operands[2]) == -1) |
131 | 1237 return \"dec\t%0\"; |
0 | 1238 } |
1239 | |
131 | 1240 return \"add\t%2,%0\"; |
0 | 1241 }" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1242 [(set_attr "length" "2,4,4,6")]) |
0 | 1243 |
131 | 1244 (define_insn_and_split "addqi3" |
1245 [(set (match_operand:QI 0 "nonimmediate_operand" "=rR,Q") | |
1246 (plus:QI (match_operand:QI 1 "general_operand" "%0,0") | |
1247 (match_operand:QI 2 "incdec_operand" "LM,LM")))] | |
1248 "" | |
1249 "#" | |
1250 "reload_completed" | |
1251 [(parallel [(set (match_dup 0) | |
1252 (plus:QI (match_dup 1) (match_dup 2))) | |
1253 (clobber (reg:CC CC_REGNUM))])] | |
1254 "" | |
1255 [(set_attr "length" "2,4")]) | |
1256 | |
1257 ;; Inc/dec sets V if overflow from the operation | |
1258 (define_insn "*addqi3<cc_ccnz>" | |
1259 [(set (match_operand:QI 0 "nonimmediate_operand" "=rR,Q") | |
1260 (plus:QI (match_operand:QI 1 "general_operand" "%0,0") | |
1261 (match_operand:QI 2 "incdec_operand" "LM,LM"))) | |
1262 (clobber (reg:CC CC_REGNUM))] | |
1263 "reload_completed" | |
1264 "* | |
1265 { | |
1266 if (INTVAL(operands[2]) == 1) | |
1267 return \"incb\t%0\"; | |
1268 else | |
1269 return \"decb\t%0\"; | |
1270 }" | |
1271 [(set_attr "length" "2,4")]) | |
1272 | |
0 | 1273 |
1274 ;;- subtract instructions | |
1275 ;; we don't have to care for constant second | |
1276 ;; args, since they are canonical plus:xx now! | |
1277 ;; also for minus:DF ?? | |
1278 | |
131 | 1279 (define_insn_and_split "subdf3" |
0 | 1280 [(set (match_operand:DF 0 "register_operand" "=a,a") |
1281 (minus:DF (match_operand:DF 1 "register_operand" "0,0") | |
1282 (match_operand:DF 2 "general_operand" "fR,Q")))] | |
1283 "TARGET_FPU" | |
131 | 1284 "#" |
1285 "&& reload_completed" | |
1286 [(parallel [(set (match_dup 0) | |
1287 (minus:DF (match_dup 1) (match_dup 2))) | |
1288 (clobber (reg:CC FCC_REGNUM))])] | |
1289 "" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1290 [(set_attr "length" "2,4")]) |
0 | 1291 |
131 | 1292 (define_insn "*subdf3<fcc_ccnz>" |
1293 [(set (match_operand:DF 0 "register_operand" "=a,a") | |
1294 (minus:DF (match_operand:DF 1 "register_operand" "0,0") | |
1295 (match_operand:DF 2 "general_operand" "fR,QF"))) | |
1296 (clobber (reg:CC FCC_REGNUM))] | |
1297 "TARGET_FPU && reload_completed" | |
1298 "{subd|subf}\t%2,%0" | |
1299 [(set_attr "length" "2,4") | |
1300 (set_attr "base_cost" "6")]) | |
1301 | |
1302 (define_insn_and_split "subdi3" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1303 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,o") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1304 (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1305 (match_operand:DI 2 "general_operand" "r,on,r,on")))] |
0 | 1306 "" |
131 | 1307 "#" |
1308 "reload_completed" | |
1309 [(parallel [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2))) | |
1310 (clobber (reg:CC CC_REGNUM))])] | |
1311 "" | |
1312 [(set_attr "length" "20,28,40,48")]) | |
1313 | |
1314 (define_insn "*subdi3_nocc" | |
1315 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,o") | |
1316 (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0") | |
1317 (match_operand:DI 2 "general_operand" "r,on,r,on"))) | |
1318 (clobber (reg:CC CC_REGNUM))] | |
1319 "reload_completed" | |
0 | 1320 "* |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1321 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1322 rtx inops[2]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1323 rtx exops[4][2]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1324 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1325 inops[0] = operands[0]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1326 inops[1] = operands[2]; |
145 | 1327 pdp11_expand_operands (inops, exops, 2, 4, NULL, big); |
0 | 1328 |
145 | 1329 if (!CONST_INT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0) |
131 | 1330 output_asm_insn (\"sub\t%1,%0\", exops[0]); |
145 | 1331 if (!CONST_INT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1332 { |
131 | 1333 output_asm_insn (\"sub\t%1,%0\", exops[1]); |
1334 output_asm_insn (\"sbc\t%0\", exops[0]); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1335 } |
145 | 1336 if (!CONST_INT_P (exops[2][1]) || INTVAL (exops[2][1]) != 0) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1337 { |
131 | 1338 output_asm_insn (\"sub\t%1,%0\", exops[2]); |
1339 output_asm_insn (\"sbc\t%0\", exops[1]); | |
1340 output_asm_insn (\"sbc\t%0\", exops[0]); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1341 } |
145 | 1342 if (!CONST_INT_P (exops[3][1]) || INTVAL (exops[3][1]) != 0) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1343 { |
131 | 1344 output_asm_insn (\"sub\t%1,%0\", exops[3]); |
1345 output_asm_insn (\"sbc\t%0\", exops[2]); | |
1346 output_asm_insn (\"sbc\t%0\", exops[1]); | |
1347 output_asm_insn (\"sbc\t%0\", exops[0]); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1348 } |
0 | 1349 |
1350 return \"\"; | |
1351 }" | |
131 | 1352 [(set_attr "length" "20,28,40,48") |
1353 (set_attr "base_cost" "0")]) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1354 |
131 | 1355 (define_insn_and_split "subsi3" |
1356 [(set (match_operand:SI 0 "nonimmediate_operand" "=&r,r,o,o") | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1357 (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1358 (match_operand:SI 2 "general_operand" "r,on,r,on")))] |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1359 "" |
131 | 1360 "#" |
1361 "reload_completed" | |
1362 [(parallel [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2))) | |
1363 (clobber (reg:CC CC_REGNUM))])] | |
1364 "" | |
1365 [(set_attr "length" "6,10,12,16")]) | |
1366 | |
1367 (define_insn "*subsi3_nocc" | |
1368 [(set (match_operand:SI 0 "nonimmediate_operand" "=&r,r,o,o") | |
1369 (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0") | |
1370 (match_operand:SI 2 "general_operand" "r,on,r,on"))) | |
1371 (clobber (reg:CC CC_REGNUM))] | |
1372 "reload_completed" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1373 "* |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1374 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1375 rtx inops[2]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1376 rtx exops[2][2]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1377 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1378 inops[0] = operands[0]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1379 inops[1] = operands[2]; |
145 | 1380 pdp11_expand_operands (inops, exops, 2, 2, NULL, big); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1381 |
145 | 1382 if (!CONST_INT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0) |
131 | 1383 output_asm_insn (\"sub\t%1,%0\", exops[0]); |
145 | 1384 if (!CONST_INT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1385 { |
131 | 1386 output_asm_insn (\"sub\t%1,%0\", exops[1]); |
1387 output_asm_insn (\"sbc\t%0\", exops[0]); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1388 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1389 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1390 return \"\"; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1391 }" |
131 | 1392 [(set_attr "length" "6,10,12,16") |
1393 (set_attr "base_cost" "0")]) | |
0 | 1394 |
131 | 1395 (define_insn_and_split "subhi3" |
1396 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,rR,Q,Q") | |
1397 (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0") | |
1398 (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))] | |
1399 "" | |
1400 "#" | |
1401 "reload_completed" | |
1402 [(parallel [(set (match_dup 0) | |
1403 (minus:HI (match_dup 1) (match_dup 2))) | |
1404 (clobber (reg:CC CC_REGNUM))])] | |
1405 "" | |
1406 [(set_attr "length" "2,4,4,6")]) | |
1407 | |
1408 ;; Note: the manual says that (minus m (const_int n)) is converted | |
1409 ;; to (plus m (const_int -n)) but that does not appear to be | |
1410 ;; the case when it's wrapped in a PARALLEL. So instead we handle | |
1411 ;; that case here, which is easy enough. | |
1412 (define_insn "*subhi3<cc_ccnz>" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1413 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,rR,Q,Q") |
0 | 1414 (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0") |
131 | 1415 (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi"))) |
1416 (clobber (reg:CC CC_REGNUM))] | |
1417 "reload_completed" | |
0 | 1418 "* |
1419 { | |
131 | 1420 if (GET_CODE (operands[2]) == CONST_INT) |
1421 { | |
1422 if (INTVAL(operands[2]) == 1) | |
1423 return \"dec\t%0\"; | |
1424 else if (INTVAL(operands[2]) == -1) | |
1425 return \"inc\t%0\"; | |
1426 } | |
0 | 1427 |
131 | 1428 return \"sub\t%2,%0\"; |
0 | 1429 }" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1430 [(set_attr "length" "2,4,4,6")]) |
0 | 1431 |
131 | 1432 (define_insn_and_split "subqi3" |
1433 [(set (match_operand:QI 0 "nonimmediate_operand" "=rR,Q") | |
1434 (plus:QI (match_operand:QI 1 "general_operand" "%0,0") | |
1435 (match_operand:QI 2 "incdec_operand" "LM,LM")))] | |
1436 "" | |
1437 "#" | |
1438 "reload_completed" | |
1439 [(parallel [(set (match_dup 0) | |
1440 (plus:QI (match_dup 1) (match_dup 2))) | |
1441 (clobber (reg:CC CC_REGNUM))])] | |
1442 "" | |
1443 [(set_attr "length" "2,4")]) | |
1444 | |
1445 ;; Inc/dec sets V if overflow from the operation | |
1446 (define_insn "*subqi3<cc_ccnz>" | |
1447 [(set (match_operand:QI 0 "nonimmediate_operand" "=rR,Q") | |
1448 (plus:QI (match_operand:QI 1 "general_operand" "%0,0") | |
1449 (match_operand:QI 2 "incdec_operand" "LM,LM"))) | |
1450 (clobber (reg:CC CC_REGNUM))] | |
1451 "reload_completed" | |
1452 "* | |
1453 { | |
1454 if (INTVAL(operands[2]) == -1) | |
1455 return \"incb\t%0\"; | |
1456 else | |
1457 return \"decb\t%0\"; | |
1458 }" | |
1459 [(set_attr "length" "2,4")]) | |
1460 | |
0 | 1461 ;;;;- and instructions |
1462 ;; Bit-and on the pdp (like on the VAX) is done with a clear-bits insn. | |
1463 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1464 (define_expand "and<mode>3" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1465 [(set (match_operand:PDPint 0 "nonimmediate_operand" "") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1466 (and:PDPint (not:PDPint (match_operand:PDPint 1 "general_operand" "")) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1467 (match_operand:PDPint 2 "general_operand" "")))] |
0 | 1468 "" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1469 " |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1470 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1471 rtx op1 = operands[1]; |
0 | 1472 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1473 /* If there is a constant argument, complement that one. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1474 Similarly, if one of the inputs is the same as the output, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1475 complement the other input. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1476 if ((CONST_INT_P (operands[2]) && ! CONST_INT_P (op1)) || |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1477 rtx_equal_p (operands[0], operands[1])) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1478 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1479 operands[1] = operands[2]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1480 operands[2] = op1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1481 op1 = operands[1]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1482 } |
0 | 1483 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1484 if (CONST_INT_P (op1)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1485 operands[1] = GEN_INT (~INTVAL (op1)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1486 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1487 operands[1] = expand_unop (<MODE>mode, one_cmpl_optab, op1, 0, 1); |
131 | 1488 }" |
1489 [(set_attr "length" "2,4,4,6")]) | |
0 | 1490 |
131 | 1491 (define_insn_and_split "*bic<mode>" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1492 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,rR,Q,Q") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1493 (and:PDPint |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1494 (not: PDPint (match_operand:PDPint 1 "general_operand" "rR,Qi,rR,Qi")) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1495 (match_operand:PDPint 2 "general_operand" "0,0,0,0")))] |
0 | 1496 "" |
131 | 1497 "#" |
1498 "reload_completed" | |
1499 [(parallel [(set (match_dup 0) | |
1500 (and:PDPint (not:PDPint (match_dup 1)) (match_dup 2))) | |
1501 (clobber (reg:CC CC_REGNUM))])] | |
1502 "") | |
1503 | |
1504 (define_insn "*bic<mode><cc_cc>" | |
1505 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,rR,Q,Q") | |
1506 (and:PDPint | |
1507 (not: PDPint (match_operand:PDPint 1 "general_operand" "rR,Qi,rR,Qi")) | |
1508 (match_operand:PDPint 2 "general_operand" "0,0,0,0"))) | |
1509 (clobber (reg:CC CC_REGNUM))] | |
1510 "reload_completed" | |
1511 "bic<PDPint:isfx>\t%1,%0" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1512 [(set_attr "length" "2,4,4,6")]) |
0 | 1513 |
1514 ;;- Bit set (inclusive or) instructions | |
131 | 1515 (define_insn_and_split "ior<mode>3" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1516 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,rR,Q,Q") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1517 (ior:PDPint (match_operand:PDPint 1 "general_operand" "%0,0,0,0") |
131 | 1518 (match_operand:PDPint 2 "general_operand" "rR,Qi,rR,Qi")))] |
1519 "" | |
1520 "#" | |
1521 "reload_completed" | |
1522 [(parallel [(set (match_dup 0) | |
1523 (ior:PDPint (match_dup 1) (match_dup 2))) | |
1524 (clobber (reg:CC CC_REGNUM))])] | |
0 | 1525 "" |
131 | 1526 [(set_attr "length" "2,4,4,6")]) |
1527 | |
1528 (define_insn "ior<mode>3<cc_cc>" | |
1529 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,rR,Q,Q") | |
1530 (ior:PDPint (match_operand:PDPint 1 "general_operand" "%0,0,0,0") | |
1531 (match_operand:PDPint 2 "general_operand" "rR,Qi,rR,Qi"))) | |
1532 (clobber (reg:CC CC_REGNUM))] | |
1533 "reload_completed" | |
1534 "bis<PDPint:isfx>\t%2,%0" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1535 [(set_attr "length" "2,4,4,6")]) |
0 | 1536 |
1537 ;;- xor instructions | |
131 | 1538 (define_insn_and_split "xorhi3" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1539 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,Q") |
0 | 1540 (xor:HI (match_operand:HI 1 "general_operand" "%0,0") |
1541 (match_operand:HI 2 "register_operand" "r,r")))] | |
1542 "TARGET_40_PLUS" | |
131 | 1543 "#" |
1544 "&& reload_completed" | |
1545 [(parallel [(set (match_dup 0) | |
1546 (xor:HI (match_dup 1) (match_dup 2))) | |
1547 (clobber (reg:CC CC_REGNUM))])] | |
1548 "" | |
1549 [(set_attr "length" "2,4")]) | |
1550 | |
1551 (define_insn "*xorhi3<cc_cc>" | |
1552 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,Q") | |
1553 (xor:HI (match_operand:HI 1 "general_operand" "%0,0") | |
1554 (match_operand:HI 2 "register_operand" "r,r"))) | |
1555 (clobber (reg:CC CC_REGNUM))] | |
1556 "TARGET_40_PLUS && reload_completed" | |
1557 "xor\t%2,%0" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1558 [(set_attr "length" "2,4")]) |
0 | 1559 |
1560 ;;- one complement instructions | |
1561 | |
131 | 1562 (define_insn_and_split "one_cmpl<mode>2" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1563 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,Q") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1564 (not:PDPint (match_operand:PDPint 1 "general_operand" "0,0")))] |
0 | 1565 "" |
131 | 1566 "#" |
1567 "reload_completed" | |
1568 [(parallel [(set (match_dup 0) | |
1569 (not:PDPint (match_dup 1))) | |
1570 (clobber (reg:CC CC_REGNUM))])] | |
1571 "" | |
1572 [(set_attr "length" "2,4")]) | |
1573 | |
1574 (define_insn "*one_cmpl<mode>2<cc_cc>" | |
1575 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,Q") | |
1576 (not:PDPint (match_operand:PDPint 1 "general_operand" "0,0"))) | |
1577 (clobber (reg:CC CC_REGNUM))] | |
1578 "reload_completed" | |
1579 "com<PDPint:isfx>\t%0" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1580 [(set_attr "length" "2,4")]) |
0 | 1581 |
1582 ;;- arithmetic shift instructions | |
131 | 1583 ;; |
1584 ;; There is a fair amount of complexity here because with -m10 | |
1585 ;; (pdp-11/10, /20) we only have shift by one bit. Iterators are | |
1586 ;; used to reduce the amount of very similar code. | |
1587 ;; | |
1588 ;; First the insns used for small constant shifts. | |
1589 (define_insn_and_split "<code><mode>_sc" | |
1590 [(set (match_operand:QHSint 0 "nonimmediate_operand" "=rD,Q") | |
1591 (SHF:QHSint (match_operand:QHSint 1 "general_operand" "0,0") | |
1592 (match_operand:HI 2 "expand_shift_operand" "O,O")))] | |
1593 "" | |
1594 "#" | |
1595 "reload_completed" | |
1596 [(parallel [(set (match_dup 0) (SHF:QHSint (match_dup 1) (match_dup 2))) | |
1597 (clobber (reg:CC CC_REGNUM))])] | |
1598 "" | |
1599 [(set (attr "length") | |
1600 (symbol_ref "pdp11_shift_length (operands, <QHSint:mname>, | |
1601 <CODE>, which_alternative == 0)")) | |
1602 (set_attr "base_cost" "0")]) | |
0 | 1603 |
131 | 1604 (define_insn "<code><mode>_sc<cc_ccnz>" |
1605 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rD,Q") | |
1606 (SHF:PDPint (match_operand:PDPint 1 "general_operand" "0,0") | |
1607 (match_operand:HI 2 "expand_shift_operand" "O,O"))) | |
1608 (clobber (reg:CC CC_REGNUM))] | |
1609 "reload_completed" | |
1610 "* return pdp11_assemble_shift (operands, <PDPint:mname>, <CODE>);" | |
1611 [(set (attr "length") | |
1612 (symbol_ref "pdp11_shift_length (operands, <PDPint:mname>, | |
1613 <CODE>, which_alternative == 0)")) | |
1614 (set_attr "base_cost" "0")]) | |
0 | 1615 |
131 | 1616 ;; This one comes only in clobber flavor. |
1617 (define_insn "<code>si_sc_nocc" | |
1618 [(set (match_operand:SI 0 "nonimmediate_operand" "=rD,Q") | |
1619 (SHF:SI (match_operand:SI 1 "general_operand" "0,0") | |
1620 (match_operand:HI 2 "expand_shift_operand" "O,O"))) | |
1621 (clobber (reg:CC CC_REGNUM))] | |
1622 "reload_completed" | |
1623 "* return pdp11_assemble_shift (operands, SImode, <CODE>);" | |
1624 [(set (attr "length") | |
1625 (symbol_ref "pdp11_shift_length (operands, SImode, | |
1626 <CODE>, which_alternative == 0)")) | |
1627 (set_attr "base_cost" "0")]) | |
0 | 1628 |
131 | 1629 ;; Next, shifts that are done as a loop on base (11/10 class) machines. |
1630 ;; This applies to shift counts too large to unroll, or variable shift | |
1631 ;; counts. The check for count <= 0 is done before we get here. | |
1632 (define_insn_and_split "<code><mode>_base" | |
1633 [(set (match_operand:QHSint 0 "nonimmediate_operand" "=rD,Q") | |
1634 (SHF:QHSint (match_operand:QHSint 1 "general_operand" "0,0") | |
1635 (match_operand:HI 2 "register_operand" "r,r"))) | |
1636 (clobber (match_dup 2))] | |
0 | 1637 "" |
131 | 1638 "#" |
1639 "reload_completed" | |
1640 [(parallel [(set (match_dup 0) (SHF:QHSint (match_dup 1) (match_dup 2))) | |
1641 (clobber (match_dup 2)) | |
1642 (clobber (reg:CC CC_REGNUM))])] | |
1643 "" | |
1644 [(set (attr "length") | |
1645 (symbol_ref "pdp11_shift_length (operands, <QHSint:mname>, | |
1646 <CODE>, which_alternative == 0)")) | |
1647 (set_attr "base_cost" "0")]) | |
0 | 1648 |
131 | 1649 (define_insn "<code><mode>_base_nocc" |
1650 [(set (match_operand:QHSint 0 "nonimmediate_operand" "=rD,Q") | |
1651 (SHF:QHSint (match_operand:QHSint 1 "general_operand" "0,0") | |
1652 (match_operand:HI 2 "register_operand" "r,r"))) | |
1653 (clobber (match_dup 2)) | |
1654 (clobber (reg:CC CC_REGNUM))] | |
1655 "reload_completed" | |
1656 "* return pdp11_assemble_shift (operands, <QHSint:mname>, <CODE>);" | |
1657 [(set (attr "length") | |
1658 (symbol_ref "pdp11_shift_length (operands, <QHSint:mname>, | |
1659 <CODE>, which_alternative == 0)")) | |
1660 (set_attr "base_cost" "0")]) | |
0 | 1661 |
131 | 1662 ;; Next the insns that use the extended instructions ash and ashc. |
1663 ;; Note that these are just left shifts, and HI/SI only. (Right shifts | |
1664 ;; are done by shifting by a negative amount.) | |
1665 (define_insn_and_split "aslhi_op" | |
1666 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r") | |
0 | 1667 (ashift:HI (match_operand:HI 1 "general_operand" "0,0") |
131 | 1668 (match_operand:HI 2 "general_operand" "rR,Qi")))] |
1669 "TARGET_40_PLUS" | |
1670 "#" | |
1671 "&& reload_completed" | |
1672 [(parallel [(set (match_dup 0) | |
1673 (ashift:HI (match_dup 1) (match_dup 2))) | |
1674 (clobber (reg:CC CC_REGNUM))])] | |
0 | 1675 "" |
131 | 1676 [(set_attr "length" "2,4") |
1677 (set_attr "base_cost" "8")]) | |
0 | 1678 |
131 | 1679 (define_insn "aslhi_op<cc_ccnz>" |
1680 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r") | |
1681 (ashift:HI (match_operand:HI 1 "general_operand" "0,0") | |
1682 (match_operand:HI 2 "general_operand" "rR,Qi"))) | |
1683 (clobber (reg:CC CC_REGNUM))] | |
1684 "TARGET_40_PLUS && reload_completed" | |
1685 "ash\t%2,%0" | |
1686 [(set_attr "length" "2,4") | |
1687 (set_attr "base_cost" "8")]) | |
0 | 1688 |
131 | 1689 (define_insn_and_split "aslsi_op" |
1690 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r") | |
1691 (ashift:SI (match_operand:SI 1 "general_operand" "0,0") | |
1692 (match_operand:HI 2 "general_operand" "rR,Qi")))] | |
1693 "TARGET_40_PLUS" | |
1694 "#" | |
1695 "&& reload_completed" | |
1696 [(parallel [(set (match_dup 0) | |
1697 (ashift:SI (match_dup 1) (match_dup 2))) | |
1698 (clobber (reg:CC CC_REGNUM))])] | |
1699 "" | |
1700 [(set_attr "length" "2,4") | |
1701 (set_attr "base_cost" "8")]) | |
0 | 1702 |
131 | 1703 (define_insn "aslsi_op_<cc_ccnz>" |
1704 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r") | |
1705 (ashift:SI (match_operand:SI 1 "general_operand" "0,0") | |
1706 (match_operand:HI 2 "general_operand" "rR,Qi"))) | |
1707 (clobber (reg:CC CC_REGNUM))] | |
1708 "TARGET_40_PLUS && reload_completed" | |
1709 "ashc\t%2,%0" | |
1710 [(set_attr "length" "2,4") | |
1711 (set_attr "base_cost" "8")]) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1712 |
131 | 1713 ;; Now the expanders that produce the insns defined above. |
1714 (define_expand "ashl<mode>3" | |
1715 [(match_operand:QHSint 0 "nonimmediate_operand" "") | |
1716 (match_operand:QHSint 1 "general_operand" "") | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1717 (match_operand:HI 2 "general_operand" "")] |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1718 "" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1719 " |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1720 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1721 rtx r; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1722 |
131 | 1723 if (!pdp11_expand_shift (operands, gen_ashift<mode>_sc, gen_ashift<mode>_base)) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1724 { |
131 | 1725 if (<QHSint:e_mname> == E_QImode) |
1726 { | |
1727 r = copy_to_mode_reg (HImode, gen_rtx_ZERO_EXTEND (HImode, operands[1])); | |
1728 emit_insn (gen_aslhi_op (r, r, operands[2])); | |
1729 emit_insn (gen_movqi (operands[0], gen_rtx_SUBREG (QImode, r, 0))); | |
1730 } | |
1731 else | |
1732 { | |
1733 emit_insn (gen_asl<QHSint:hmode>_op (operands[0], operands[1], operands[2])); | |
1734 } | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1735 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1736 DONE; |
0 | 1737 }") |
1738 | |
131 | 1739 (define_expand "ashr<mode>3" |
1740 [(match_operand:QHSint 0 "nonimmediate_operand" "") | |
1741 (match_operand:QHSint 1 "general_operand" "") | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1742 (match_operand:HI 2 "general_operand" "")] |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1743 "" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1744 " |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1745 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1746 rtx r; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1747 |
131 | 1748 if (!pdp11_expand_shift (operands, gen_ashiftrt<mode>_sc, gen_ashiftrt<mode>_base)) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1749 { |
131 | 1750 operands[2] = negate_rtx (HImode, operands[2]); |
1751 if (<QHSint:e_mname> == E_QImode) | |
1752 { | |
1753 r = copy_to_mode_reg (HImode, gen_rtx_ZERO_EXTEND (HImode, operands[1])); | |
1754 emit_insn (gen_aslhi_op (r, r, operands[2])); | |
1755 emit_insn (gen_movqi (operands[0], gen_rtx_SUBREG (QImode, r, 0))); | |
1756 } | |
1757 else | |
1758 { | |
1759 emit_insn (gen_asl<QHSint:hmode>_op (operands[0], operands[1], operands[2])); | |
1760 } | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1761 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1762 DONE; |
131 | 1763 }") |
1764 | |
1765 (define_expand "lshr<mode>3" | |
1766 [(match_operand:QHSint 0 "nonimmediate_operand" "") | |
1767 (match_operand:QHSint 1 "general_operand" "") | |
1768 (match_operand:HI 2 "general_operand" "")] | |
1769 "" | |
1770 " | |
1771 { | |
1772 rtx r, n; | |
1773 | |
1774 if (!pdp11_expand_shift (operands, gen_lshiftrt<mode>_sc, gen_lshiftrt<mode>_base)) | |
1775 { | |
1776 if (<QHSint:e_mname> == E_QImode) | |
1777 { | |
1778 r = copy_to_mode_reg (HImode, gen_rtx_ZERO_EXTEND (HImode, operands[1])); | |
1779 emit_insn (gen_aslhi_op (r, r, operands[2])); | |
1780 emit_insn (gen_movqi (operands[0], gen_rtx_SUBREG (QImode, r, 0))); | |
1781 } | |
1782 else | |
1783 { | |
1784 r = gen_reg_rtx (<QHSint:mname>); | |
1785 emit_insn (gen_lshiftrt<mode>_sc (r, operands[1], const1_rtx)); | |
1786 if (GET_CODE (operands[2]) != CONST_INT) | |
1787 { | |
1788 n = gen_reg_rtx (HImode); | |
1789 emit_insn (gen_addhi3 (n, operands [2], GEN_INT (-1))); | |
1790 emit_insn (gen_ashr<mode>3 (operands[0], r, n)); | |
1791 } | |
1792 else | |
1793 emit_insn (gen_asl<QHSint:hmode>_op (operands[0], r, | |
1794 GEN_INT (1 - INTVAL (operands[2])))); | |
1795 } | |
1796 } | |
1797 DONE; | |
1798 }") | |
0 | 1799 |
1800 ;; absolute | |
1801 | |
131 | 1802 (define_insn_and_split "absdf2" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1803 [(set (match_operand:DF 0 "nonimmediate_operand" "=fR,Q") |
0 | 1804 (abs:DF (match_operand:DF 1 "general_operand" "0,0")))] |
1805 "TARGET_FPU" | |
131 | 1806 "#" |
1807 "&& reload_completed" | |
1808 [(parallel [(set (match_dup 0) (abs:DF (match_dup 1))) | |
1809 (clobber (reg:CC FCC_REGNUM))])] | |
1810 "" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1811 [(set_attr "length" "2,4")]) |
0 | 1812 |
131 | 1813 (define_insn "absdf2<fcc_cc>" |
1814 [(set (match_operand:DF 0 "nonimmediate_operand" "=fR,Q") | |
1815 (abs:DF (match_operand:DF 1 "general_operand" "0,0"))) | |
1816 (clobber (reg:CC FCC_REGNUM))] | |
1817 "TARGET_FPU && reload_completed" | |
1818 "{absd|absf}\t%0" | |
1819 [(set_attr "length" "2,4")]) | |
0 | 1820 |
1821 ;; negate insns | |
1822 | |
131 | 1823 (define_insn_and_split "negdf2" |
1824 [(set (match_operand:DF 0 "nonimmediate_operand" "=fR,Q") | |
1825 (neg:DF (match_operand:DF 1 "general_operand" "0,0")))] | |
0 | 1826 "TARGET_FPU" |
131 | 1827 "#" |
1828 "&& reload_completed" | |
1829 [(parallel [(set (match_dup 0) (neg:DF (match_dup 1))) | |
1830 (clobber (reg:CC FCC_REGNUM))])] | |
1831 "" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1832 [(set_attr "length" "2,4")]) |
0 | 1833 |
131 | 1834 (define_insn "negdf2<fcc_cc>" |
1835 [(set (match_operand:DF 0 "nonimmediate_operand" "=fR,Q") | |
1836 (neg:DF (match_operand:DF 1 "general_operand" "0,0"))) | |
1837 (clobber (reg:CC FCC_REGNUM))] | |
1838 "TARGET_FPU && reload_completed" | |
1839 "{negd|negf}\t%0" | |
1840 [(set_attr "length" "2,4")]) | |
1841 | |
1842 (define_insn_and_split "negdi2" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1843 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1844 (neg:DI (match_operand:DI 1 "general_operand" "0,0")))] |
0 | 1845 "" |
131 | 1846 "#" |
1847 "reload_completed" | |
1848 [(parallel [(set (match_dup 0) (neg:DI (match_dup 1))) | |
1849 (clobber (reg:CC CC_REGNUM))])] | |
1850 "" | |
1851 [(set_attr "length" "18,34")]) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1852 |
131 | 1853 ;; TODO: this can be neg/adc/neg/adc... I believe. Check. Saves one word. |
1854 (define_insn "negdi2_nocc" | |
1855 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") | |
1856 (neg:DI (match_operand:DI 1 "general_operand" "0,0"))) | |
1857 (clobber (reg:CC CC_REGNUM))] | |
1858 "reload_completed" | |
1859 { | |
145 | 1860 rtx inops[2]; |
131 | 1861 rtx exops[4][2]; |
145 | 1862 |
1863 inops[0] = operands[0]; | |
1864 pdp11_expand_operands (inops, exops, 1, 4, NULL, big); | |
131 | 1865 |
1866 output_asm_insn (\"com\t%0\", exops[3]); | |
1867 output_asm_insn (\"com\t%0\", exops[2]); | |
1868 output_asm_insn (\"com\t%0\", exops[1]); | |
1869 output_asm_insn (\"com\t%0\", exops[0]); | |
1870 output_asm_insn (\"add\t%#1,%0\", exops[3]); | |
1871 output_asm_insn (\"adc\t%0\", exops[2]); | |
1872 output_asm_insn (\"adc\t%0\", exops[1]); | |
1873 output_asm_insn (\"adc\t%0\", exops[0]); | |
1874 | |
1875 return \"\"; | |
1876 } | |
1877 [(set_attr "length" "18,34") | |
1878 (set_attr "base_cost" "0")]) | |
0 | 1879 |
131 | 1880 (define_insn_and_split "negsi2" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1881 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,o") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1882 (neg:SI (match_operand:SI 1 "general_operand" "0,0")))] |
0 | 1883 "" |
131 | 1884 "#" |
1885 "reload_completed" | |
1886 [(parallel [(set (match_dup 0) (neg:SI (match_dup 1))) | |
1887 (clobber (reg:CC CC_REGNUM))])] | |
1888 "" | |
1889 [(set_attr "length" "10,18")]) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1890 |
131 | 1891 ;; TODO: this can be neg/adc/neg/adc... I believe. Check. Saves one word. |
1892 (define_insn "negsi2_nocc" | |
1893 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,o") | |
1894 (neg:SI (match_operand:SI 1 "general_operand" "0,0"))) | |
1895 (clobber (reg:CC CC_REGNUM))] | |
1896 "reload_completed" | |
1897 { | |
145 | 1898 rtx inops[2]; |
1899 rtx exops[4][2]; | |
1900 | |
1901 inops[0] = operands[0]; | |
1902 pdp11_expand_operands (inops, exops, 1, 2, NULL, big); | |
131 | 1903 |
1904 output_asm_insn (\"com\t%0\", exops[1]); | |
1905 output_asm_insn (\"com\t%0\", exops[0]); | |
1906 output_asm_insn (\"add\t%#1,%0\", exops[1]); | |
1907 output_asm_insn (\"adc\t%0\", exops[0]); | |
1908 | |
1909 return \"\"; | |
1910 } | |
1911 [(set_attr "length" "10,18") | |
1912 (set_attr "base_cost" "0")]) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1913 |
131 | 1914 (define_insn_and_split "neg<mode>2" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1915 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,Q") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1916 (neg:PDPint (match_operand:PDPint 1 "general_operand" "0,0")))] |
0 | 1917 "" |
131 | 1918 "#" |
1919 "reload_completed" | |
1920 [(parallel [(set (match_dup 0) (neg:PDPint (match_dup 1))) | |
1921 (clobber (reg:CC CC_REGNUM))])] | |
1922 "" | |
1923 [(set_attr "length" "2,4")]) | |
1924 | |
1925 (define_insn "neg<mode>2<cc_ccnz>" | |
1926 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,Q") | |
1927 (neg:PDPint (match_operand:PDPint 1 "general_operand" "0,0"))) | |
1928 (clobber (reg:CC CC_REGNUM))] | |
1929 "" | |
1930 "neg<PDPint:isfx>\t%0" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1931 [(set_attr "length" "2,4")]) |
0 | 1932 |
1933 | |
1934 ;; Unconditional and other jump instructions | |
1935 (define_insn "jump" | |
1936 [(set (pc) | |
1937 (label_ref (match_operand 0 "" "")))] | |
1938 "" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1939 "* |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1940 { |
131 | 1941 if (get_attr_length (insn) == 2) |
1942 return \"br\t%l0\"; | |
1943 return \"jmp\t%l0\"; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1944 }" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1945 [(set (attr "length") (if_then_else (ior (lt (minus (match_dup 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1946 (pc)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1947 (const_int MIN_BRANCH)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1948 (gt (minus (match_dup 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1949 (pc)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1950 (const_int MAX_BRANCH))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1951 (const_int 4) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1952 (const_int 2)))]) |
0 | 1953 |
1954 (define_insn "tablejump" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1955 [(set (pc) (match_operand:HI 0 "general_operand" "r,R,Q")) |
0 | 1956 (use (label_ref (match_operand 1 "" "")))] |
1957 "" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1958 "@ |
131 | 1959 jmp\t(%0) |
1960 jmp\t%@%0 | |
1961 jmp\t%@%0" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1962 [(set_attr "length" "2,2,4")]) |
0 | 1963 |
131 | 1964 ;; indirect jump. TODO: this needs a constraint that allows memory |
1965 ;; references but not indirection, since we add a level of indirection | |
1966 ;; in the generated code. | |
0 | 1967 (define_insn "indirect_jump" |
131 | 1968 [(set (pc) (match_operand:HI 0 "general_operand" "r"))] |
0 | 1969 "" |
131 | 1970 "jmp\t@%0" |
1971 [(set_attr "length" "2")]) | |
0 | 1972 |
1973 ;;- jump to subroutine | |
1974 | |
1975 (define_insn "call" | |
1976 [(call (match_operand:HI 0 "general_operand" "rR,Q") | |
131 | 1977 (match_operand:HI 1 "general_operand" "g,g"))] |
0 | 1978 ;;- Don't use operand 1 for most machines. |
1979 "" | |
131 | 1980 "jsr\tpc,%0" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1981 [(set_attr "length" "2,4")]) |
0 | 1982 |
1983 ;;- jump to subroutine | |
1984 (define_insn "call_value" | |
1985 [(set (match_operand 0 "" "") | |
1986 (call (match_operand:HI 1 "general_operand" "rR,Q") | |
131 | 1987 (match_operand:HI 2 "general_operand" "g,g")))] |
0 | 1988 ;;- Don't use operand 2 for most machines. |
1989 "" | |
131 | 1990 "jsr\tpc,%1" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1991 [(set_attr "length" "2,4")]) |
0 | 1992 |
131 | 1993 (define_expand "untyped_call" |
1994 [(parallel [(call (match_operand 0 "" "") | |
1995 (const_int 0)) | |
1996 (match_operand 1 "" "") | |
1997 (match_operand 2 "" "")])] | |
1998 "" | |
1999 { | |
2000 int i; | |
2001 | |
2002 emit_call_insn (gen_call (operands[0], const0_rtx)); | |
2003 | |
2004 for (i = 0; i < XVECLEN (operands[2], 0); i++) | |
2005 { | |
2006 rtx set = XVECEXP (operands[2], 0, i); | |
2007 emit_move_insn (SET_DEST (set), SET_SRC (set)); | |
2008 } | |
2009 | |
2010 /* The optimizer does not know that the call sets the function value | |
2011 registers we stored in the result block. We avoid problems by | |
2012 claiming that all hard registers are used and clobbered at this | |
2013 point. */ | |
2014 emit_insn (gen_blockage ()); | |
2015 | |
2016 DONE; | |
2017 }) | |
2018 | |
0 | 2019 ;;- nop instruction |
2020 (define_insn "nop" | |
2021 [(const_int 0)] | |
2022 "" | |
2023 "nop") | |
2024 | |
2025 | |
2026 ;;- multiply | |
2027 | |
131 | 2028 (define_insn_and_split "muldf3" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2029 [(set (match_operand:DF 0 "register_operand" "=a,a") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2030 (mult:DF (match_operand:DF 1 "register_operand" "%0,0") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2031 (match_operand:DF 2 "float_operand" "fR,QF")))] |
0 | 2032 "TARGET_FPU" |
131 | 2033 "#" |
2034 "&& reload_completed" | |
2035 [(parallel [(set (match_dup 0) (mult:DF (match_dup 1) (match_dup 2))) | |
2036 (clobber (reg:CC FCC_REGNUM))])] | |
2037 "" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2038 [(set_attr "length" "2,4")]) |
0 | 2039 |
131 | 2040 (define_insn "muldf3<fcc_ccnz>" |
2041 [(set (match_operand:DF 0 "register_operand" "=a,a") | |
2042 (mult:DF (match_operand:DF 1 "register_operand" "%0,0") | |
2043 (match_operand:DF 2 "float_operand" "fR,QF"))) | |
2044 (clobber (reg:CC FCC_REGNUM))] | |
2045 "TARGET_FPU && reload_completed" | |
2046 "{muld|mulf}\t%2,%0" | |
2047 [(set_attr "length" "2,4") | |
2048 (set_attr "base_cost" "20")]) | |
0 | 2049 |
131 | 2050 ;; 16 bit result multiply. This uses odd numbered registers. |
2051 | |
2052 (define_insn_and_split "mulhi3" | |
0 | 2053 [(set (match_operand:HI 0 "register_operand" "=d,d") ; multiply regs |
2054 (mult:HI (match_operand:HI 1 "register_operand" "%0,0") | |
131 | 2055 (match_operand:HI 2 "general_operand" "rR,Qi")))] |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2056 "TARGET_40_PLUS" |
131 | 2057 "#" |
2058 "&& reload_completed" | |
2059 [(parallel [(set (match_dup 0) (mult:HI (match_dup 1) (match_dup 2))) | |
2060 (clobber (reg:CC CC_REGNUM))])] | |
2061 "" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2062 [(set_attr "length" "2,4")]) |
0 | 2063 |
131 | 2064 (define_insn "mulhi3<cc_cc>" |
2065 [(set (match_operand:HI 0 "register_operand" "=d,d") | |
2066 (mult:HI (match_operand:HI 1 "register_operand" "%0,0") | |
2067 (match_operand:HI 2 "general_operand" "rR,Qi"))) | |
2068 (clobber (reg:CC CC_REGNUM))] | |
2069 "TARGET_40_PLUS && reload_completed" | |
2070 "mul\t%2,%0" | |
2071 [(set_attr "length" "2,4") | |
2072 (set_attr "base_cost" "20")]) | |
2073 | |
2074 ;; 32 bit result from 16 bit operands | |
2075 (define_insn_and_split "mulhisi3" | |
2076 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
2077 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,0")) | |
2078 (sign_extend:SI (match_operand:HI 2 "general_operand" "rR,Qi"))))] | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2079 "TARGET_40_PLUS" |
131 | 2080 "#" |
2081 "&& reload_completed" | |
2082 [(parallel [(set (match_dup 0) | |
2083 (mult:SI (sign_extend:SI (match_dup 1)) | |
2084 (sign_extend:SI (match_dup 2)))) | |
2085 (clobber (reg:CC CC_REGNUM))])] | |
2086 "" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2087 [(set_attr "length" "2,4")]) |
0 | 2088 |
131 | 2089 (define_insn "mulhisi3<cc_cc>" |
2090 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
2091 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,0")) | |
2092 (sign_extend:SI (match_operand:HI 2 "general_operand" "rR,Qi")))) | |
2093 (clobber (reg:CC CC_REGNUM))] | |
2094 "TARGET_40_PLUS && reload_completed" | |
2095 "mul\t%2,%0" | |
2096 [(set_attr "length" "2,4") | |
2097 (set_attr "base_cost" "20")]) | |
0 | 2098 |
2099 ;;- divide | |
131 | 2100 (define_insn_and_split "divdf3" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2101 [(set (match_operand:DF 0 "register_operand" "=a,a") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2102 (div:DF (match_operand:DF 1 "register_operand" "0,0") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2103 (match_operand:DF 2 "general_operand" "fR,QF")))] |
0 | 2104 "TARGET_FPU" |
131 | 2105 "#" |
2106 "&& reload_completed" | |
2107 [(parallel [(set (match_dup 0) (div:DF (match_dup 1) (match_dup 2))) | |
2108 (clobber (reg:CC FCC_REGNUM))])] | |
2109 "" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2110 [(set_attr "length" "2,4")]) |
131 | 2111 |
2112 (define_insn "divdf3<fcc_ccnz>" | |
2113 [(set (match_operand:DF 0 "register_operand" "=a,a") | |
2114 (div:DF (match_operand:DF 1 "register_operand" "0,0") | |
2115 (match_operand:DF 2 "general_operand" "fR,QF"))) | |
2116 (clobber (reg:CC FCC_REGNUM))] | |
2117 "TARGET_FPU && reload_completed" | |
2118 "{divd|divf}\t%2,%0" | |
2119 [(set_attr "length" "2,4") | |
2120 (set_attr "base_cost" "20")]) | |
0 | 2121 |
131 | 2122 (define_expand "divmodhi4" |
2123 [(parallel | |
2124 [(set (subreg:HI (match_dup 1) 0) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2125 (div:HI (match_operand:SI 1 "register_operand" "0") |
0 | 2126 (match_operand:HI 2 "general_operand" "g"))) |
131 | 2127 (set (subreg:HI (match_dup 1) 2) |
2128 (mod:HI (match_dup 1) (match_dup 2)))]) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2129 (set (match_operand:HI 0 "register_operand" "=r") |
131 | 2130 (subreg:HI (match_dup 1) 0)) |
2131 (set (match_operand:HI 3 "register_operand" "=r") | |
0 | 2132 (subreg:HI (match_dup 1) 2))] |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2133 "TARGET_40_PLUS" |
0 | 2134 "") |
2135 | |
131 | 2136 (define_insn_and_split "*divmodhi4" |
2137 [(set (subreg:HI (match_operand:SI 0 "register_operand" "=r,r") 0) | |
2138 (div:HI (match_operand:SI 1 "register_operand" "0,0") | |
2139 (match_operand:HI 2 "general_operand" "rR,Qi"))) | |
2140 (set (subreg:HI (match_dup 1) 2) | |
2141 (mod:HI (match_dup 1) (match_dup 2)))] | |
2142 "TARGET_40_PLUS" | |
2143 "#" | |
2144 "&& reload_completed" | |
2145 [(parallel [(set (subreg:HI (match_dup 0) 0) | |
2146 (div:HI (match_dup 1) (match_dup 2))) | |
2147 (set (subreg:HI (match_dup 1) 2) | |
2148 (mod:HI (match_dup 1) (match_dup 2))) | |
2149 (clobber (reg:CC CC_REGNUM))])] | |
2150 "" | |
2151 [(set_attr "length" "2,4")]) | |
2152 | |
2153 ;; Note that there is no corresponding CC setter pattern. | |
2154 ;; The reason is that it won't be generated, because | |
2155 ;; compare-elim.c only does the transformation on input | |
2156 ;; insns that have a two-element PARALLEL, as opposed to | |
2157 ;; the three-element one we have here. | |
2158 (define_insn "divmodhi4_nocc" | |
2159 [(set (subreg:HI (match_operand:SI 0 "register_operand" "=r,r") 0) | |
2160 (div:HI (match_operand:SI 1 "register_operand" "0,0") | |
2161 (match_operand:HI 2 "general_operand" "rR,Qi"))) | |
2162 (set (subreg:HI (match_dup 1) 2) | |
2163 (mod:HI (match_dup 1) (match_dup 2))) | |
2164 (clobber (reg:CC CC_REGNUM))] | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2165 "TARGET_40_PLUS" |
131 | 2166 "div\t%2,%0" |
2167 [(set_attr "length" "2,4") | |
2168 (set_attr "base_cost" "40")]) | |
2169 | |
2170 ;; Byte swap | |
2171 (define_insn_and_split "bswaphi2" | |
2172 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,Q") | |
2173 (bswap:HI (match_operand:HI 1 "general_operand" "0,0")))] | |
2174 "" | |
2175 "#" | |
2176 "reload_completed" | |
2177 [(parallel [(set (match_dup 0) (bswap:HI (match_dup 1))) | |
2178 (clobber (reg:CC CC_REGNUM))])] | |
2179 "" | |
2180 [(set_attr "length" "2,4")]) | |
2181 | |
2182 (define_insn "bswaphi2<cc_ccnz>" | |
2183 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,Q") | |
2184 (bswap:HI (match_operand:HI 1 "general_operand" "0,0"))) | |
2185 (clobber (reg:CC CC_REGNUM))] | |
2186 "" | |
2187 "swab\t%0" | |
2188 [(set_attr "length" "2,4")]) | |
2189 | |
2190 (define_insn_and_split "bswapsi2" | |
2191 [(set (match_operand:SI 0 "register_operand" "=&r") | |
2192 (bswap:SI (match_operand:SI 1 "general_operand" "g")))] | |
2193 "" | |
2194 "#" | |
2195 "reload_completed" | |
2196 [(parallel [(set (match_dup 0) | |
2197 (bswap:SI (match_dup 1))) | |
2198 (clobber (reg:CC CC_REGNUM))])] | |
2199 "" | |
2200 [(set_attr "length" "10")]) | |
0 | 2201 |
131 | 2202 (define_insn "bswapsi2_nocc" |
2203 [(set (match_operand:SI 0 "register_operand" "=&r,&r,&r") | |
2204 (bswap:SI (match_operand:SI 1 "general_operand" "r,D,Q"))) | |
2205 (clobber (reg:CC CC_REGNUM))] | |
2206 "" | |
2207 { | |
145 | 2208 rtx inops[2]; |
131 | 2209 rtx exops[2][2]; |
2210 rtx t; | |
145 | 2211 |
2212 inops[0] = operands[0]; | |
2213 inops[1] = operands[1]; | |
2214 pdp11_expand_operands (inops, exops, 2, 2, NULL, either); | |
131 | 2215 |
2216 t = exops[0][0]; | |
2217 exops[0][0] = exops[1][0]; | |
2218 exops[1][0] = t; | |
2219 | |
2220 output_asm_insn ("mov\t%0,%1", exops[0]); | |
2221 output_asm_insn ("mov\t%0,%1", exops[1]); | |
2222 output_asm_insn ("swab\t%0", exops[0]); | |
2223 output_asm_insn ("swab\t%0", exops[1]); | |
2224 return ""; | |
2225 } | |
2226 [(set_attr "length" "8,10,12")]) | |
2227 | |
2228 (define_expand "rotrhi3" | |
2229 [(match_operand:HI 0 "register_operand" "") | |
2230 (match_operand:HI 1 "register_operand" "") | |
2231 (match_operand:HI 2 "general_operand" "")] | |
2232 "TARGET_40_PLUS" | |
2233 " | |
2234 { | |
2235 operands[2] = negate_rtx (HImode, operands[2]); | |
2236 emit_insn (gen_rotlhi3 (operands[0], operands[1], operands[2])); | |
2237 DONE; | |
2238 }") | |
2239 | |
2240 (define_insn_and_split "rotlhi3" | |
2241 [(set (match_operand:HI 0 "register_operand" "=d,d") | |
2242 (rotate:HI (match_operand:HI 1 "register_operand" "0,0") | |
2243 (match_operand:HI 2 "general_operand" "rR,Qi")))] | |
2244 "TARGET_40_PLUS" | |
2245 "#" | |
2246 "&& reload_completed" | |
2247 [(parallel [(set (match_dup 0) | |
2248 (rotate:HI (match_dup 1) (match_dup 2))) | |
2249 (clobber (reg:CC CC_REGNUM))])] | |
2250 "" | |
2251 [(set_attr "length" "2,4") | |
2252 (set_attr "base_cost" "8")]) | |
2253 | |
2254 (define_insn "rotlhi3<cc_ccnz>" | |
2255 [(set (match_operand:HI 0 "register_operand" "=d,d") | |
2256 (rotate:HI (match_operand:HI 1 "register_operand" "0,0") | |
2257 (match_operand:HI 2 "general_operand" "rR,Qi"))) | |
2258 (clobber (reg:CC CC_REGNUM))] | |
2259 "TARGET_40_PLUS && reload_completed" | |
2260 "ashc\t%2,%0" | |
2261 [(set_attr "length" "2,4") | |
2262 (set_attr "base_cost" "8")]) | |
2263 | |
2264 | |
2265 | |
2266 ;; Some peephole optimizations | |
2267 | |
2268 ;; Move then conditional branch on the result of the move is handled | |
2269 ;; by compare elimination, but an earlier pass sometimes changes the | |
2270 ;; compare operand to the move input, and then the compare is not | |
2271 ;; eliminated. Do so here. | |
2272 (define_peephole2 | |
2273 [(parallel [(set (match_operand:PDPint 0 "nonimmediate_operand" "") | |
2274 (match_operand:PDPint 1 "general_operand" "")) | |
2275 (clobber (reg:CC CC_REGNUM))]) | |
2276 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))] | |
2277 "" | |
2278 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0))) | |
2279 (set (match_dup 0) (match_dup 1))])] | |
2280 "") |