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