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 "")