comparison gcc/config/pdp11/pdp11.md @ 67:f6334be47118

update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
date Tue, 22 Mar 2011 17:18:12 +0900
parents 77e2b8dfacca
children 04ced10e8804
comparison
equal deleted inserted replaced
65:65488c3d617d 67:f6334be47118
1 ;;- Machine description for the pdp11 for GNU C compiler 1 ;;- Machine description for the pdp11 for GNU C compiler
2 ;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2004, 2005 2 ;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2004, 2005
3 ;; 2007, 2008 Free Software Foundation, Inc. 3 ;; 2007, 2008, 2010 Free Software Foundation, Inc.
4 ;; Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at). 4 ;; Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
5 5
6 ;; This file is part of GCC. 6 ;; This file is part of GCC.
7 7
8 ;; GCC is free software; you can redistribute it and/or modify 8 ;; GCC is free software; you can redistribute it and/or modify
17 17
18 ;; You should have received a copy of the GNU General Public License 18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see 19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. 20 ;; <http://www.gnu.org/licenses/>.
21 21
22 ;; Match CONST_DOUBLE zero for tstd/tstf. 22 (include "predicates.md")
23 (define_predicate "register_or_const0_operand" 23 (include "constraints.md")
24 (ior (match_operand 0 "register_operand") 24
25 (match_test "op == CONST0_RTX (GET_MODE (op))"))) 25 (define_constants
26 26 [
27 ;; Register numbers
28 (R0_REGNUM 0)
29 (RETVAL_REGNUM 0)
30 (HARD_FRAME_POINTER_REGNUM 5)
31 (STACK_POINTER_REGNUM 6)
32 (PC_REGNUM 7)
33 (AC0_REGNUM 8)
34 (AC3_REGNUM 11)
35 (AC4_REGNUM 12)
36 (AC5_REGNUM 13)
37 ;; The next two are not physical registers but are used for addressing
38 ;; arguments.
39 (FRAME_POINTER_REGNUM 14)
40 (ARG_POINTER_REGNUM 15)
41 (FIRST_PSEUDO_REGISTER 16)
42 ;; Branch offset limits, as byte offsets from instruction address
43 (MIN_BRANCH -254)
44 (MAX_BRANCH 256)
45 (MIN_SOB -126)
46 (MAX_SOB 0)])
27 47
28 ;; HI is 16 bit 48 ;; HI is 16 bit
29 ;; QI is 8 bit 49 ;; QI is 8 bit
50
51 ;; Integer modes supported on the PDP11, with a mapping from machine mode
52 ;; to mnemonic suffix. SImode and DImode always are special cases.
53 (define_mode_iterator PDPint [QI HI])
54 (define_mode_attr isfx [(QI "b") (HI "")])
30 55
31 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 56 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
32 57
33 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code 58 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
34 ;;- updates for most instructions. 59 ;;- updates for most instructions.
64 ;; define attributes 89 ;; define attributes
65 ;; currently type is only fpu or arith or unknown, maybe branch later ? 90 ;; currently type is only fpu or arith or unknown, maybe branch later ?
66 ;; default is arith 91 ;; default is arith
67 (define_attr "type" "unknown,arith,fp" (const_string "arith")) 92 (define_attr "type" "unknown,arith,fp" (const_string "arith"))
68 93
69 ;; length default is 1 word each 94 ;; length default is 2 bytes each
70 (define_attr "length" "" (const_int 1)) 95 (define_attr "length" "" (const_int 2))
71 96
72 ;; a user's asm statement 97 ;; a user's asm statement
73 (define_asm_attributes 98 (define_asm_attributes
74 [(set_attr "type" "unknown") 99 [(set_attr "type" "unknown")
75 ; all bets are off how long it is - make it 256, forces long jumps 100 ; length for asm is the max length per statement. That would be
76 ; whenever jumping around it !!! 101 ; 3 words, for a two-operand instruction with extra word addressing
77 (set_attr "length" "256")]) 102 ; modes for both operands.
103 (set_attr "length" "6")])
78 104
79 ;; define function units 105 ;; define function units
80 106
81 ;; arithmetic - values here immediately when next insn issued 107 ;; arithmetic - values here immediately when next insn issued
82 ;; or does it mean the number of cycles after this insn was issued? 108 ;; or does it mean the number of cycles after this insn was issued?
86 ;(define_function_unit "fpu" 1 1 (eq_attr "type" "fp") 0 0) 112 ;(define_function_unit "fpu" 1 1 (eq_attr "type" "fp") 0 0)
87 113
88 ;; compare 114 ;; compare
89 (define_insn "*cmpdf" 115 (define_insn "*cmpdf"
90 [(set (cc0) 116 [(set (cc0)
91 (compare (match_operand:DF 0 "general_operand" "fR,fR,Q,Q,F") 117 (compare (match_operand:DF 0 "general_operand" "fR,fR,Q,QF")
92 (match_operand:DF 1 "register_or_const0_operand" "G,a,G,a,a")))] 118 (match_operand:DF 1 "register_or_const0_operand" "G,a,G,a")))]
93 "TARGET_FPU" 119 "TARGET_FPU"
94 "* 120 "*
95 { 121 {
96 cc_status.flags = CC_IN_FPU; 122 cc_status.flags = CC_IN_FPU;
97 if (which_alternative == 0 || which_alternative == 2) 123 if (which_alternative == 0 || which_alternative == 2)
98 return \"{tstd|tstf} %0, %1\;cfcc\"; 124 return \"{tstd|tstf} %0\;cfcc\";
99 else 125 else
100 return \"{cmpd|cmpf} %0, %1\;cfcc\"; 126 return \"{cmpd|cmpf} %0, %1\;cfcc\";
101 }" 127 }"
102 [(set_attr "length" "2,2,3,3,6")]) 128 [(set_attr "length" "4,4,6,6")])
103 129
104 (define_insn "*cmphi" 130 (define_insn "*cmp<mode>"
105 [(set (cc0) 131 [(set (cc0)
106 (compare (match_operand:HI 0 "general_operand" "rR,rR,rR,Q,Qi,Qi") 132 (compare (match_operand:PDPint 0 "general_operand" "rR,rR,rR,Q,Qi,Qi")
107 (match_operand:HI 1 "general_operand" "N,rR,Qi,N,rR,Qi")))] 133 (match_operand:PDPint 1 "general_operand" "N,rR,Qi,N,rR,Qi")))]
108 "" 134 ""
109 "@ 135 "@
110 tst %0 136 tst<PDPint:isfx> %0
111 cmp %0,%1 137 cmp<PDPint:isfx> %0,%1
112 cmp %0,%1 138 cmp<PDPint:isfx> %0,%1
113 tst %0 139 tst<PDPint:isfx> %0
114 cmp %0,%1 140 cmp<PDPint:isfx> %0,%1
115 cmp %0,%1" 141 cmp<PDPint:isfx> %0,%1"
116 [(set_attr "length" "1,1,2,2,2,3")]) 142 [(set_attr "length" "2,2,4,4,4,6")])
117
118 (define_insn "*cmpqi"
119 [(set (cc0)
120 (compare (match_operand:QI 0 "general_operand" "rR,rR,rR,Q,Qi,Qi")
121 (match_operand:QI 1 "general_operand" "N,rR,Qi,N,rR,Qi")))]
122 ""
123 "@
124 tstb %0
125 cmpb %0,%1
126 cmpb %0,%1
127 tstb %0
128 cmpb %0,%1
129 cmpb %0,%1"
130 [(set_attr "length" "1,1,2,2,2,3")])
131
132 143
133 ;; sob instruction - we need an assembler which can make this instruction 144 ;; sob instruction - we need an assembler which can make this instruction
134 ;; valid under _all_ circumstances! 145 ;; valid under _all_ circumstances!
135 146
136 (define_insn "" 147 (define_insn ""
148 "* 159 "*
149 { 160 {
150 static int labelcount = 0; 161 static int labelcount = 0;
151 static char buf[1000]; 162 static char buf[1000];
152 163
153 if (get_attr_length (insn) == 1) 164 if (get_attr_length (insn) == 2)
154 return \"sob %0, %l1\"; 165 return \"sob %0, %l1\";
155 166
156 /* emulate sob */ 167 /* emulate sob */
157 output_asm_insn (\"dec %0\", operands); 168 output_asm_insn (\"dec %0\", operands);
158 169
164 sprintf (buf, \"LONG_SOB%d:\", labelcount++); 175 sprintf (buf, \"LONG_SOB%d:\", labelcount++);
165 output_asm_insn (buf, NULL); 176 output_asm_insn (buf, NULL);
166 177
167 return \"\"; 178 return \"\";
168 }" 179 }"
169 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) 180 [(set (attr "length") (if_then_else (ior (lt (minus (match_dup 0)
170 (pc)) 181 (pc))
171 (const_int -256)) 182 (const_int MIN_SOB))
172 (ge (minus (match_dup 0) 183 (gt (minus (match_dup 0)
173 (pc)) 184 (pc))
174 (const_int 0))) 185 (const_int MAX_SOB)))
175 (const_int 4) 186 (const_int 8)
176 (const_int 1)))]) 187 (const_int 2)))])
177 188
178 ;; These control RTL generation for conditional jump insns 189 ;; These control RTL generation for conditional jump insns
179 ;; and match them for register allocation. 190 ;; and match them for register allocation.
180 191
181 (define_expand "cbranchdf4" 192 (define_expand "cbranchdf4"
182 [(set (cc0) 193 [(set (cc0)
183 (compare (match_operand:DF 1 "general_operand") 194 (compare (match_operand:DF 1 "general_operand")
184 (match_operand:DF 2 "general_operand"))) 195 (match_operand:DF 2 "register_or_const0_operand")))
185 (set (pc) 196 (set (pc)
186 (if_then_else (match_operator 0 "ordered_comparison_operator" 197 (if_then_else (match_operator 0 "ordered_comparison_operator"
187 [(cc0) (const_int 0)]) 198 [(cc0) (const_int 0)])
188 (label_ref (match_operand 3 "" "")) 199 (label_ref (match_operand 3 "" ""))
189 (pc)))] 200 (pc)))]
190 "" 201 "TARGET_FPU"
191 "") 202 "")
192 203
193 (define_expand "cbranchhi4" 204 (define_expand "cbranch<mode>4"
194 [(set (cc0) 205 [(set (cc0)
195 (compare (match_operand:HI 1 "general_operand") 206 (compare (match_operand:PDPint 1 "general_operand")
196 (match_operand:HI 2 "general_operand"))) 207 (match_operand:PDPint 2 "general_operand")))
197 (set (pc)
198 (if_then_else (match_operator 0 "ordered_comparison_operator"
199 [(cc0) (const_int 0)])
200 (label_ref (match_operand 3 "" ""))
201 (pc)))]
202 ""
203 "")
204
205 (define_expand "cbranchqi4"
206 [(set (cc0)
207 (compare (match_operand:QI 1 "general_operand")
208 (match_operand:QI 2 "general_operand")))
209 (set (pc) 208 (set (pc)
210 (if_then_else (match_operator 0 "ordered_comparison_operator" 209 (if_then_else (match_operator 0 "ordered_comparison_operator"
211 [(cc0) (const_int 0)]) 210 [(cc0) (const_int 0)])
212 (label_ref (match_operand 3 "" "")) 211 (label_ref (match_operand 3 "" ""))
213 (pc)))] 212 (pc)))]
227 [(cc0) (const_int 0)]) 226 [(cc0) (const_int 0)])
228 (label_ref (match_operand 1 "" "")) 227 (label_ref (match_operand 1 "" ""))
229 (pc)))] 228 (pc)))]
230 "" 229 ""
231 "* return output_jump(GET_CODE (operands[0]), 0, get_attr_length(insn));" 230 "* return output_jump(GET_CODE (operands[0]), 0, get_attr_length(insn));"
232 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 1) 231 [(set (attr "length") (if_then_else (ior (lt (minus (match_dup 1)
233 (pc)) 232 (pc))
234 (const_int -128)) 233 (const_int MIN_BRANCH))
235 (ge (minus (match_dup 1) 234 (gt (minus (match_dup 1)
236 (pc)) 235 (pc))
237 (const_int 128))) 236 (const_int MAX_BRANCH)))
238 (const_int 3) 237 (const_int 6)
239 (const_int 1)))]) 238 (const_int 2)))])
240 239
241 240
242 ;; These match inverted jump insns for register allocation. 241 ;; These match inverted jump insns for register allocation.
243 242
244 (define_insn "*branch_inverted" 243 (define_insn "*branch_inverted"
247 [(cc0) (const_int 0)]) 246 [(cc0) (const_int 0)])
248 (pc) 247 (pc)
249 (label_ref (match_operand 1 "" ""))))] 248 (label_ref (match_operand 1 "" ""))))]
250 "" 249 ""
251 "* return output_jump(GET_CODE (operands[0]), 1, get_attr_length(insn));" 250 "* return output_jump(GET_CODE (operands[0]), 1, get_attr_length(insn));"
252 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 1) 251 [(set (attr "length") (if_then_else (ior (lt (minus (match_dup 1)
253 (pc)) 252 (pc))
254 (const_int -128)) 253 (const_int MIN_BRANCH))
255 (ge (minus (match_dup 1) 254 (gt (minus (match_dup 1)
256 (pc)) 255 (pc))
257 (const_int 128))) 256 (const_int MAX_BRANCH)))
258 (const_int 3) 257 (const_int 6)
259 (const_int 1)))]) 258 (const_int 2)))])
260 259
261 ;; Move instructions 260 ;; Move instructions
262 261
263 (define_insn "movdi" 262 (define_insn "movdi"
264 [(set (match_operand:DI 0 "general_operand" "=g,rm,o") 263 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,g")
265 (match_operand:DI 1 "general_operand" "m,r,a"))] 264 (match_operand:DI 1 "general_operand" "rN,g"))]
266 "" 265 ""
267 "* return output_move_quad (operands);" 266 "* return output_move_multiple (operands);"
268 ;; what's the mose expensive code - say twice movsi = 16 267 ;; what's the mose expensive code - say twice movsi = 16
269 [(set_attr "length" "16,16,16")]) 268 [(set_attr "length" "16,32")])
270 269
271 (define_insn "movsi" 270 (define_insn "movsi"
272 [(set (match_operand:SI 0 "general_operand" "=r,r,r,rm,m") 271 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,g,g")
273 (match_operand:SI 1 "general_operand" "rN,IJ,K,m,r"))] 272 (match_operand:SI 1 "general_operand" "rN,IJ,IJ,g"))]
274 "" 273 ""
275 "* return output_move_double (operands);" 274 "* return output_move_multiple (operands);"
276 ;; what's the most expensive code ? - I think 8! 275 ;; what's the most expensive code ? - I think 8!
277 ;; we could split it up and make several sub-cases... 276 ;; we could split it up and make several sub-cases...
278 [(set_attr "length" "2,3,4,8,8")]) 277 [(set_attr "length" "4,6,8,16")])
279 278
280 (define_insn "movhi" 279 (define_insn "mov<mode>"
281 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") 280 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,rR,Q,Q")
282 (match_operand:HI 1 "general_operand" "rRN,Qi,rRN,Qi"))] 281 (match_operand:PDPint 1 "general_operand" "rRN,Qi,rRN,Qi"))]
283 "" 282 ""
284 "* 283 "*
285 { 284 {
286 if (operands[1] == const0_rtx) 285 if (operands[1] == const0_rtx)
287 return \"clr %0\"; 286 return \"clr<PDPint:isfx> %0\";
288 287
289 return \"mov %1, %0\"; 288 return \"mov<PDPint:isfx> %1, %0\";
290 }" 289 }"
291 [(set_attr "length" "1,2,2,3")]) 290 [(set_attr "length" "2,4,4,6")])
292 291
293 (define_insn "movqi"
294 [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
295 (match_operand:QI 1 "general_operand" "g"))]
296 ""
297 "*
298 {
299 if (operands[1] == const0_rtx)
300 return \"clrb %0\";
301
302 return \"movb %1, %0\";
303 }"
304 [(set_attr "length" "1")])
305
306 ;; do we have to supply all these moves? e.g. to
307 ;; NO_LOAD_FPU_REGs ?
308 (define_insn "movdf" 292 (define_insn "movdf"
309 [(set (match_operand:DF 0 "general_operand" "=a,fR,a,Q,m") 293 [(set (match_operand:DF 0 "float_nonimm_operand" "=a,fR,a,Q,g")
310 (match_operand:DF 1 "general_operand" "fFR,a,Q,a,m"))] 294 (match_operand:DF 1 "float_operand" "fR,a,FQ,a,g"))]
311 "" 295 "TARGET_FPU"
312 "* if (which_alternative ==0) 296 "* if (which_alternative ==0 || which_alternative == 2)
313 return \"ldd %1, %0\"; 297 return \"ldd %1, %0\";
314 else if (which_alternative == 1) 298 else if (which_alternative == 1 || which_alternative == 3)
315 return \"std %1, %0\"; 299 return \"std %1, %0\";
316 else 300 else
317 return output_move_quad (operands); " 301 return output_move_multiple (operands); "
318 ;; just a guess.. 302 ;; last one is worst-case
319 [(set_attr "length" "1,1,5,5,16")]) 303 [(set_attr "length" "2,2,4,4,24")])
320 304
321 (define_insn "movsf" 305 (define_insn "movsf"
322 [(set (match_operand:SF 0 "general_operand" "=g,r,g") 306 [(set (match_operand:SF 0 "float_nonimm_operand" "=a,fR,a,Q,g")
323 (match_operand:SF 1 "general_operand" "r,rmF,g"))] 307 (match_operand:SF 1 "float_operand" "fR,a,FQ,a,g"))]
324 "TARGET_FPU" 308 "TARGET_FPU"
325 "* return output_move_double (operands);" 309 "* if (which_alternative ==0 || which_alternative == 2)
326 [(set_attr "length" "8,8,8")]) 310 return \"{ldcfd|movof} %1, %0\";
311 else if (which_alternative == 1 || which_alternative == 3)
312 return \"{stcdf|movfo} %1, %0\";
313 else
314 return output_move_multiple (operands); "
315 ;; last one is worst-case
316 [(set_attr "length" "2,2,4,4,12")])
327 317
328 ;; maybe fiddle a bit with move_ratio, then 318 ;; maybe fiddle a bit with move_ratio, then
329 ;; let constraints only accept a register ... 319 ;; let constraints only accept a register ...
330 320
331 (define_expand "movmemhi" 321 (define_expand "movmemhi"
332 [(parallel [(set (match_operand:BLK 0 "general_operand" "=g,g") 322 [(parallel [(set (match_operand:BLK 0 "general_operand" "=g,g")
333 (match_operand:BLK 1 "general_operand" "g,g")) 323 (match_operand:BLK 1 "general_operand" "g,g"))
334 (use (match_operand:HI 2 "arith_operand" "n,&mr")) 324 (use (match_operand:HI 2 "general_operand" "n,mr"))
335 (use (match_operand:HI 3 "immediate_operand" "i,i")) 325 (use (match_operand:HI 3 "immediate_operand" "i,i"))
336 (clobber (match_scratch:HI 4 "=&r,X")) 326 (clobber (match_scratch:HI 4 "=&r,X"))
337 (clobber (match_dup 5)) 327 (clobber (match_dup 5))
338 (clobber (match_dup 6)) 328 (clobber (match_dup 6))
339 (clobber (match_dup 2))])] 329 (clobber (match_dup 2))])]
350 operands[5] = XEXP (operands[0], 0); 340 operands[5] = XEXP (operands[0], 0);
351 operands[6] = XEXP (operands[1], 0); 341 operands[6] = XEXP (operands[1], 0);
352 }") 342 }")
353 343
354 344
355 (define_insn "" ; "movmemhi" 345 (define_insn "movmemhi1"
356 [(set (mem:BLK (match_operand:HI 0 "general_operand" "=r,r")) 346 [(set (mem:BLK (match_operand:HI 0 "register_operand" "r,r"))
357 (mem:BLK (match_operand:HI 1 "general_operand" "r,r"))) 347 (mem:BLK (match_operand:HI 1 "register_operand" "r,r")))
358 (use (match_operand:HI 2 "arith_operand" "n,&r")) 348 (use (match_operand:HI 2 "general_operand" "n,r"))
359 (use (match_operand:HI 3 "immediate_operand" "i,i")) 349 (use (match_operand:HI 3 "immediate_operand" "i,i"))
360 (clobber (match_scratch:HI 4 "=&r,X")) 350 (clobber (match_scratch:HI 4 "=&r,X"))
361 (clobber (match_dup 0)) 351 (clobber (match_dup 0))
362 (clobber (match_dup 1)) 352 (clobber (match_dup 1))
363 (clobber (match_dup 2))] 353 (clobber (match_dup 2))]
364 "(TARGET_BCOPY_BUILTIN)" 354 "(TARGET_BCOPY_BUILTIN)"
365 "* return output_block_move (operands);" 355 "* return output_block_move (operands);"
366 ;;; just a guess 356 ;;; just a guess
367 [(set_attr "length" "40")]) 357 [(set_attr "length" "80")])
368 358
369 359
370 360
371 ;;- truncation instructions 361 ;;- truncation instructions
372 362
373 (define_insn "truncdfsf2" 363 (define_insn "truncdfsf2"
374 [(set (match_operand:SF 0 "general_operand" "=r,R,Q") 364 [(set (match_operand:SF 0 "float_nonimm_operand" "=f,R,Q")
375 (float_truncate:SF (match_operand:DF 1 "register_operand" "a,a,a")))] 365 (float_truncate:SF (match_operand:DF 1 "register_operand" "f,a,a")))]
376 "TARGET_FPU" 366 "TARGET_FPU"
377 "* if (which_alternative ==0) 367 "* if (which_alternative ==0)
378 { 368 {
379 output_asm_insn(\"{stcdf|movfo} %1, -(sp)\", operands);
380 output_asm_insn(\"mov (sp)+, %0\", operands);
381 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0])+1);
382 output_asm_insn(\"mov (sp)+, %0\", operands);
383 return \"\"; 369 return \"\";
384 } 370 }
385 else if (which_alternative == 1) 371 else if (which_alternative == 1)
386 return \"{stcdf|movfo} %1, %0\"; 372 return \"{stcdf|movfo} %1, %0\";
387 else 373 else
388 return \"{stcdf|movfo} %1, %0\"; 374 return \"{stcdf|movfo} %1, %0\";
389 " 375 "
390 [(set_attr "length" "3,1,2")]) 376 [(set_attr "length" "0,2,4")])
391 377
392 378
393 (define_expand "truncsihi2" 379 (define_expand "truncsihi2"
394 [(set (match_operand:HI 0 "general_operand" "=g") 380 [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
395 (subreg:HI 381 (subreg:HI
396 (match_operand:SI 1 "general_operand" "or") 382 (match_operand:SI 1 "general_operand" "or")
397 0))] 383 0))]
398 "" 384 ""
399 "") 385 "")
400 386
401 387
402 ;;- zero extension instructions 388 ;;- zero extension instructions
403 389
404 (define_insn "zero_extendqihi2" 390 (define_insn "zero_extendqihi2"
405 [(set (match_operand:HI 0 "general_operand" "=r") 391 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,Q")
406 (zero_extend:HI (match_operand:QI 1 "general_operand" "0")))] 392 (zero_extend:HI (match_operand:QI 1 "general_operand" "0,0")))]
407 "" 393 ""
408 "bic $0177400, %0" 394 "bic $0177400, %0"
409 [(set_attr "length" "2")]) 395 [(set_attr "length" "4,6")])
410 396
411 (define_expand "zero_extendhisi2" 397 (define_expand "zero_extendhisi2"
412 [(set (subreg:HI 398 [(set (subreg:HI
413 (match_dup 0) 399 (match_dup 0)
414 2) 400 2)
422 408
423 409
424 ;;- sign extension instructions 410 ;;- sign extension instructions
425 411
426 (define_insn "extendsfdf2" 412 (define_insn "extendsfdf2"
427 [(set (match_operand:DF 0 "register_operand" "=a,a,a") 413 [(set (match_operand:DF 0 "register_operand" "=f,a,a")
428 (float_extend:DF (match_operand:SF 1 "general_operand" "r,R,Q")))] 414 (float_extend:DF (match_operand:SF 1 "float_operand" "f,R,Q")))]
429 "TARGET_FPU" 415 "TARGET_FPU"
430 "@ 416 "@
431 mov %1, -(sp)\;{ldcfd|movof} (sp)+,%0 417 /* nothing */
432 {ldcfd|movof} %1, %0 418 {ldcfd|movof} %1, %0
433 {ldcfd|movof} %1, %0" 419 {ldcfd|movof} %1, %0"
434 [(set_attr "length" "2,1,2")]) 420 [(set_attr "length" "0,2,4")])
435 421
436 ;; does movb sign extend in register-to-register move? 422 ;; does movb sign extend in register-to-register move?
437 (define_insn "extendqihi2" 423 (define_insn "extendqihi2"
438 [(set (match_operand:HI 0 "register_operand" "=r,r") 424 [(set (match_operand:HI 0 "register_operand" "=r,r")
439 (sign_extend:HI (match_operand:QI 1 "general_operand" "rR,Q")))] 425 (sign_extend:HI (match_operand:QI 1 "general_operand" "rR,Q")))]
440 "" 426 ""
441 "movb %1, %0" 427 "movb %1, %0"
442 [(set_attr "length" "1,2")]) 428 [(set_attr "length" "2,4")])
443 429
444 (define_insn "extendqisi2" 430 (define_insn "extendqisi2"
445 [(set (match_operand:SI 0 "register_operand" "=r,r") 431 [(set (match_operand:SI 0 "register_operand" "=r,r")
446 (sign_extend:SI (match_operand:QI 1 "general_operand" "rR,Q")))] 432 (sign_extend:SI (match_operand:QI 1 "general_operand" "rR,Q")))]
447 "TARGET_40_PLUS" 433 "TARGET_40_PLUS"
456 output_asm_insn(\"movb %1, %0\", operands); 442 output_asm_insn(\"movb %1, %0\", operands);
457 output_asm_insn(\"sxt %0\", latehalf); 443 output_asm_insn(\"sxt %0\", latehalf);
458 444
459 return \"\"; 445 return \"\";
460 }" 446 }"
461 [(set_attr "length" "2,3")]) 447 [(set_attr "length" "4,6")])
462 448
463 ;; maybe we have to use define_expand to say that we have the instruction, 449 ;; maybe we have to use define_expand to say that we have the instruction,
464 ;; unconditionally, and then match dependent on CPU type: 450 ;; unconditionally, and then match dependent on CPU type:
465 451
466 (define_expand "extendhisi2" 452 (define_expand "extendhisi2"
467 [(set (match_operand:SI 0 "general_operand" "=g") 453 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
468 (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))] 454 (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))]
469 "" 455 ""
470 "") 456 "")
471 457
472 (define_insn "" ; "extendhisi2" 458 (define_insn "" ; "extendhisi2"
473 [(set (match_operand:SI 0 "general_operand" "=o,<,r") 459 [(set (match_operand:SI 0 "nonimmediate_operand" "=o,<,r")
474 (sign_extend:SI (match_operand:HI 1 "general_operand" "g,g,g")))] 460 (sign_extend:SI (match_operand:HI 1 "general_operand" "g,g,g")))]
475 "TARGET_40_PLUS" 461 "TARGET_40_PLUS"
476 "* 462 "*
477 { 463 {
478 rtx latehalf[2]; 464 rtx latehalf[2];
513 default: 499 default:
514 500
515 gcc_unreachable (); 501 gcc_unreachable ();
516 } 502 }
517 }" 503 }"
518 [(set_attr "length" "5,3,3")]) 504 [(set_attr "length" "10,6,6")])
519 505
520 506
521 (define_insn "" 507 (define_insn ""
522 [(set (match_operand:SI 0 "register_operand" "=r") 508 [(set (match_operand:SI 0 "register_operand" "=r")
523 (sign_extend:SI (match_operand:HI 1 "general_operand" "0")))] 509 (sign_extend:SI (match_operand:HI 1 "general_operand" "0")))]
545 531
546 count += 2; 532 count += 2;
547 533
548 return \"\"; 534 return \"\";
549 }" 535 }"
550 [(set_attr "length" "6")]) 536 [(set_attr "length" "12")])
551 537
552 ;; make float to int and vice versa 538 ;; make float to int and vice versa
553 ;; using the cc_status.flag field we could probably cut down 539 ;; using the cc_status.flag field we could probably cut down
554 ;; on seti and setl 540 ;; on seti and setl
555 ;; assume that we are normally in double and integer mode - 541 ;; assume that we are normally in double and integer mode -
576 else if (which_alternative == 1) 562 else if (which_alternative == 1)
577 return \"setl\;{ldcld|movif} %1, %0\;seti\"; 563 return \"setl\;{ldcld|movif} %1, %0\;seti\";
578 else 564 else
579 return \"setl\;{ldcld|movif} %1, %0\;seti\"; 565 return \"setl\;{ldcld|movif} %1, %0\;seti\";
580 " 566 "
581 [(set_attr "length" "5,3,4")]) 567 [(set_attr "length" "10,6,8")])
582 568
583 (define_insn "floathidf2" 569 (define_insn "floathidf2"
584 [(set (match_operand:DF 0 "register_operand" "=a,a") 570 [(set (match_operand:DF 0 "register_operand" "=a,a")
585 (float:DF (match_operand:HI 1 "general_operand" "rR,Qi")))] 571 (float:DF (match_operand:HI 1 "general_operand" "rR,Qi")))]
586 "TARGET_FPU" 572 "TARGET_FPU"
587 "{ldcid|movif} %1, %0" 573 "{ldcid|movif} %1, %0"
588 [(set_attr "length" "1,2")]) 574 [(set_attr "length" "2,4")])
589 575
590 ;; cut float to int 576 ;; cut float to int
591 (define_insn "fix_truncdfsi2" 577 (define_insn "fix_truncdfsi2"
592 [(set (match_operand:SI 0 "general_operand" "=r,R,Q") 578 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,R,Q")
593 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a,a"))))] 579 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a,a"))))]
594 "TARGET_FPU" 580 "TARGET_FPU"
595 "* if (which_alternative ==0) 581 "* if (which_alternative ==0)
596 { 582 {
597 output_asm_insn(\"setl\", operands); 583 output_asm_insn(\"setl\", operands);
605 else if (which_alternative == 1) 591 else if (which_alternative == 1)
606 return \"setl\;{stcdl|movfi} %1, %0\;seti\"; 592 return \"setl\;{stcdl|movfi} %1, %0\;seti\";
607 else 593 else
608 return \"setl\;{stcdl|movfi} %1, %0\;seti\"; 594 return \"setl\;{stcdl|movfi} %1, %0\;seti\";
609 " 595 "
610 [(set_attr "length" "5,3,4")]) 596 [(set_attr "length" "10,6,8")])
611 597
612 (define_insn "fix_truncdfhi2" 598 (define_insn "fix_truncdfhi2"
613 [(set (match_operand:HI 0 "general_operand" "=rR,Q") 599 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,Q")
614 (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))] 600 (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))]
615 "TARGET_FPU" 601 "TARGET_FPU"
616 "{stcdi|movfi} %1, %0" 602 "{stcdi|movfi} %1, %0"
617 [(set_attr "length" "1,2")]) 603 [(set_attr "length" "2,4")])
618 604
619 605
620 ;;- arithmetic instructions 606 ;;- arithmetic instructions
621 ;;- add instructions 607 ;;- add instructions
622 608
623 (define_insn "adddf3" 609 (define_insn "adddf3"
624 [(set (match_operand:DF 0 "register_operand" "=a,a,a") 610 [(set (match_operand:DF 0 "register_operand" "=a,a")
625 (plus:DF (match_operand:DF 1 "register_operand" "%0,0,0") 611 (plus:DF (match_operand:DF 1 "register_operand" "%0,0")
626 (match_operand:DF 2 "general_operand" "fR,Q,F")))] 612 (match_operand:DF 2 "general_operand" "fR,QF")))]
627 "TARGET_FPU" 613 "TARGET_FPU"
628 "{addd|addf} %2, %0" 614 "{addd|addf} %2, %0"
629 [(set_attr "length" "1,2,5")]) 615 [(set_attr "length" "2,4")])
630 616
617 (define_insn "adddi3"
618 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,o")
619 (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0")
620 (match_operand:DI 2 "general_operand" "r,on,r,on")))]
621 ""
622 "*
623 {
624 rtx inops[2];
625 rtx exops[4][2];
626
627 inops[0] = operands[0];
628 inops[1] = operands[2];
629 pdp11_expand_operands (inops, exops, 2, NULL, either);
630
631 if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
632 output_asm_insn (\"add %1, %0\", exops[0]);
633 if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
634 {
635 output_asm_insn (\"add %1, %0\", exops[1]);
636 output_asm_insn (\"adc %0\", exops[0]);
637 }
638 if (!CONSTANT_P (exops[2][1]) || INTVAL (exops[2][1]) != 0)
639 {
640 output_asm_insn (\"add %1, %0\", exops[2]);
641 output_asm_insn (\"adc %0\", exops[1]);
642 output_asm_insn (\"adc %0\", exops[0]);
643 }
644 if (!CONSTANT_P (exops[3][1]) || INTVAL (exops[3][1]) != 0)
645 {
646 output_asm_insn (\"add %1, %0\", exops[3]);
647 output_asm_insn (\"adc %0\", exops[2]);
648 output_asm_insn (\"adc %0\", exops[1]);
649 output_asm_insn (\"adc %0\", exops[0]);
650 }
651
652 return \"\";
653 }"
654 [(set_attr "length" "20,28,40,48")])
655
656 ;; Note that the register operand is not marked earlyclobber.
657 ;; The reason is that SI values go in register pairs, so they
658 ;; can't partially overlap. They can be either disjoint, or
659 ;; source and destination can be equal. The latter case is
660 ;; handled properly because of the ordering of the individual
661 ;; instructions used. Specifically, carry from the low to the
662 ;; high word is added at the end, so the adding of the high parts
663 ;; will always used the original high part and not a high part
664 ;; modified by carry (which would amount to double carry).
631 (define_insn "addsi3" 665 (define_insn "addsi3"
632 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o") 666 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,o,o")
633 (plus:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0") 667 (plus:SI (match_operand:SI 1 "general_operand" "%0,0,0,0")
634 (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))] 668 (match_operand:SI 2 "general_operand" "r,on,r,on")))]
635 "" 669 ""
636 "* 670 "*
637 { /* Here we trust that operands don't overlap 671 {
638 672 rtx inops[2];
639 or is lateoperands the low word?? - looks like it! */ 673 rtx exops[2][2];
640
641 rtx lateoperands[3];
642 674
643 lateoperands[0] = operands[0]; 675 inops[0] = operands[0];
644 676 inops[1] = operands[2];
645 if (REG_P (operands[0])) 677 pdp11_expand_operands (inops, exops, 2, NULL, either);
646 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
647 else
648 operands[0] = adjust_address (operands[0], HImode, 2);
649 678
650 if (! CONSTANT_P(operands[2])) 679 if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
680 output_asm_insn (\"add %1, %0\", exops[0]);
681 if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
651 { 682 {
652 lateoperands[2] = operands[2]; 683 output_asm_insn (\"add %1, %0\", exops[1]);
653 684 output_asm_insn (\"adc %0\", exops[0]);
654 if (REG_P (operands[2]))
655 operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
656 else
657 operands[2] = adjust_address (operands[2], HImode, 2);
658
659 output_asm_insn (\"add %2, %0\", operands);
660 output_asm_insn (\"adc %0\", lateoperands);
661 output_asm_insn (\"add %2, %0\", lateoperands);
662 return \"\";
663 } 685 }
664 686
665 lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
666 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
667
668 if (INTVAL(operands[2]))
669 {
670 output_asm_insn (\"add %2, %0\", operands);
671 output_asm_insn (\"adc %0\", lateoperands);
672 }
673
674 if (INTVAL(lateoperands[2]))
675 output_asm_insn (\"add %2, %0\", lateoperands);
676
677 return \"\"; 687 return \"\";
678 }" 688 }"
679 [(set_attr "length" "3,5,6,8,3,1,5,5,3,8")]) 689 [(set_attr "length" "6,10,12,16")])
680 690
681 (define_insn "addhi3" 691 (define_insn "addhi3"
682 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") 692 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,rR,Q,Q")
683 (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0") 693 (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
684 (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))] 694 (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))]
685 "" 695 ""
686 "* 696 "*
687 { 697 {
693 return \"dec %0\"; 703 return \"dec %0\";
694 } 704 }
695 705
696 return \"add %2, %0\"; 706 return \"add %2, %0\";
697 }" 707 }"
698 [(set_attr "length" "1,2,2,3")]) 708 [(set_attr "length" "2,4,4,6")])
699
700 (define_insn "addqi3"
701 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
702 (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
703 (match_operand:QI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))]
704 ""
705 "*
706 {
707 if (GET_CODE (operands[2]) == CONST_INT)
708 {
709 if (INTVAL(operands[2]) == 1)
710 return \"incb %0\";
711 else if (INTVAL(operands[2]) == -1)
712 return \"decb %0\";
713 }
714
715 return \"add %2, %0\";
716 }"
717 [(set_attr "length" "1,2,2,3")])
718 709
719 710
720 ;;- subtract instructions 711 ;;- subtract instructions
721 ;; we don't have to care for constant second 712 ;; we don't have to care for constant second
722 ;; args, since they are canonical plus:xx now! 713 ;; args, since they are canonical plus:xx now!
726 [(set (match_operand:DF 0 "register_operand" "=a,a") 717 [(set (match_operand:DF 0 "register_operand" "=a,a")
727 (minus:DF (match_operand:DF 1 "register_operand" "0,0") 718 (minus:DF (match_operand:DF 1 "register_operand" "0,0")
728 (match_operand:DF 2 "general_operand" "fR,Q")))] 719 (match_operand:DF 2 "general_operand" "fR,Q")))]
729 "TARGET_FPU" 720 "TARGET_FPU"
730 "{subd|subf} %2, %0" 721 "{subd|subf} %2, %0"
731 [(set_attr "length" "1,2")]) 722 [(set_attr "length" "2,4")])
723
724 (define_insn "subdi3"
725 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,o")
726 (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0")
727 (match_operand:DI 2 "general_operand" "r,on,r,on")))]
728 ""
729 "*
730 {
731 rtx inops[2];
732 rtx exops[4][2];
733
734 inops[0] = operands[0];
735 inops[1] = operands[2];
736 pdp11_expand_operands (inops, exops, 2, NULL, either);
737
738 if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
739 output_asm_insn (\"sub %1, %0\", exops[0]);
740 if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
741 {
742 output_asm_insn (\"sub %1, %0\", exops[1]);
743 output_asm_insn (\"sbc %0\", exops[0]);
744 }
745 if (!CONSTANT_P (exops[2][1]) || INTVAL (exops[2][1]) != 0)
746 {
747 output_asm_insn (\"sub %1, %0\", exops[2]);
748 output_asm_insn (\"sbc %0\", exops[1]);
749 output_asm_insn (\"sbc %0\", exops[0]);
750 }
751 if (!CONSTANT_P (exops[3][1]) || INTVAL (exops[3][1]) != 0)
752 {
753 output_asm_insn (\"sub %1, %0\", exops[3]);
754 output_asm_insn (\"sbc %0\", exops[2]);
755 output_asm_insn (\"sbc %0\", exops[1]);
756 output_asm_insn (\"sbc %0\", exops[0]);
757 }
758
759 return \"\";
760 }"
761 [(set_attr "length" "20,28,40,48")])
732 762
733 (define_insn "subsi3" 763 (define_insn "subsi3"
734 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o") 764 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,o,o")
735 (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0") 765 (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0")
736 (match_operand:SI 2 "general_operand" "r,o,r,o")))] 766 (match_operand:SI 2 "general_operand" "r,on,r,on")))]
737 "" 767 ""
738 "* 768 "*
739 { /* Here we trust that operands don't overlap 769 {
740 770 rtx inops[2];
741 or is lateoperands the low word?? - looks like it! */ 771 rtx exops[2][2];
742
743 rtx lateoperands[3];
744 772
745 lateoperands[0] = operands[0]; 773 inops[0] = operands[0];
746 774 inops[1] = operands[2];
747 if (REG_P (operands[0])) 775 pdp11_expand_operands (inops, exops, 2, NULL, either);
748 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
749 else
750 operands[0] = adjust_address (operands[0], HImode, 2);
751 776
752 lateoperands[2] = operands[2]; 777 if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
753 778 output_asm_insn (\"sub %1, %0\", exops[0]);
754 if (REG_P (operands[2])) 779 if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
755 operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1); 780 {
756 else 781 output_asm_insn (\"sub %1, %0\", exops[1]);
757 operands[2] = adjust_address (operands[2], HImode, 2); 782 output_asm_insn (\"sbc %0\", exops[0]);
758 783 }
759 output_asm_insn (\"sub %2, %0\", operands); 784
760 output_asm_insn (\"sbc %0\", lateoperands);
761 output_asm_insn (\"sub %2, %0\", lateoperands);
762 return \"\"; 785 return \"\";
763 }" 786 }"
764 ;; offsettable memory addresses always are expensive!!! 787 [(set_attr "length" "6,10,12,16")])
765 [(set_attr "length" "3,5,6,8")])
766 788
767 (define_insn "subhi3" 789 (define_insn "subhi3"
768 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") 790 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,rR,Q,Q")
769 (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0") 791 (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
770 (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))] 792 (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
771 "" 793 ""
772 "* 794 "*
773 { 795 {
774 gcc_assert (GET_CODE (operands[2]) != CONST_INT); 796 gcc_assert (GET_CODE (operands[2]) != CONST_INT);
775 797
776 return \"sub %2, %0\"; 798 return \"sub %2, %0\";
777 }" 799 }"
778 [(set_attr "length" "1,2,2,3")]) 800 [(set_attr "length" "2,4,4,6")])
779
780 (define_insn "subqi3"
781 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
782 (minus:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
783 (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
784 ""
785 "*
786 {
787 gcc_assert (GET_CODE (operands[2]) != CONST_INT);
788
789 return \"sub %2, %0\";
790 }"
791 [(set_attr "length" "1,2,2,3")])
792 801
793 ;;;;- and instructions 802 ;;;;- and instructions
794 ;; Bit-and on the pdp (like on the VAX) is done with a clear-bits insn. 803 ;; Bit-and on the pdp (like on the VAX) is done with a clear-bits insn.
795 804
796 (define_insn "andsi3" 805 (define_expand "and<mode>3"
797 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o") 806 [(set (match_operand:PDPint 0 "nonimmediate_operand" "")
798 (and:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0") 807 (and:PDPint (not:PDPint (match_operand:PDPint 1 "general_operand" ""))
799 (not:SI (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K"))))] 808 (match_operand:PDPint 2 "general_operand" "")))]
800 "" 809 ""
801 "* 810 "
802 { /* Here we trust that operands don't overlap 811 {
803 812 rtx op1 = operands[1];
804 or is lateoperands the low word?? - looks like it! */ 813
805 814 /* If there is a constant argument, complement that one.
806 rtx lateoperands[3]; 815 Similarly, if one of the inputs is the same as the output,
807 816 complement the other input. */
808 lateoperands[0] = operands[0]; 817 if ((CONST_INT_P (operands[2]) && ! CONST_INT_P (op1)) ||
809 818 rtx_equal_p (operands[0], operands[1]))
810 if (REG_P (operands[0])) 819 {
811 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); 820 operands[1] = operands[2];
821 operands[2] = op1;
822 op1 = operands[1];
823 }
824
825 if (CONST_INT_P (op1))
826 operands[1] = GEN_INT (~INTVAL (op1));
812 else 827 else
813 operands[0] = adjust_address (operands[0], HImode, 2); 828 operands[1] = expand_unop (<MODE>mode, one_cmpl_optab, op1, 0, 1);
814 829 }")
815 if (! CONSTANT_P(operands[2])) 830
816 { 831 (define_insn "*bic<mode>"
817 lateoperands[2] = operands[2]; 832 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,rR,Q,Q")
818 833 (and:PDPint
819 if (REG_P (operands[2])) 834 (not: PDPint (match_operand:PDPint 1 "general_operand" "rR,Qi,rR,Qi"))
820 operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1); 835 (match_operand:PDPint 2 "general_operand" "0,0,0,0")))]
821 else 836 ""
822 operands[2] = adjust_address (operands[2], HImode, 2); 837 "bic<PDPint:isfx> %1, %0"
823 838 [(set_attr "length" "2,4,4,6")])
824 output_asm_insn (\"bic %2, %0\", operands);
825 output_asm_insn (\"bic %2, %0\", lateoperands);
826 return \"\";
827 }
828
829 lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
830 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
831
832 /* these have different lengths, so we should have
833 different constraints! */
834 if (INTVAL(operands[2]))
835 output_asm_insn (\"bic %2, %0\", operands);
836
837 if (INTVAL(lateoperands[2]))
838 output_asm_insn (\"bic %2, %0\", lateoperands);
839
840 return \"\";
841 }"
842 [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
843
844 (define_insn "andhi3"
845 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
846 (and:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
847 (not:HI (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi"))))]
848 ""
849 "bic %2, %0"
850 [(set_attr "length" "1,2,2,3")])
851
852 (define_insn "andqi3"
853 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
854 (and:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
855 (not:QI (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi"))))]
856 ""
857 "bicb %2, %0"
858 [(set_attr "length" "1,2,2,3")])
859 839
860 ;;- Bit set (inclusive or) instructions 840 ;;- Bit set (inclusive or) instructions
861 (define_insn "iorsi3" 841 (define_insn "ior<mode>3"
862 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o") 842 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,rR,Q,Q")
863 (ior:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0") 843 (ior:PDPint (match_operand:PDPint 1 "general_operand" "%0,0,0,0")
864 (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))] 844 (match_operand:PDPint 2 "general_operand" "rR,Qi,rR,Qi")))]
865 "" 845 ""
866 "* 846 "bis<PDPint:isfx> %2, %0"
867 { /* Here we trust that operands don't overlap 847 [(set_attr "length" "2,4,4,6")])
868
869 or is lateoperands the low word?? - looks like it! */
870
871 rtx lateoperands[3];
872
873 lateoperands[0] = operands[0];
874
875 if (REG_P (operands[0]))
876 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
877 else
878 operands[0] = adjust_address (operands[0], HImode, 2);
879
880 if (! CONSTANT_P(operands[2]))
881 {
882 lateoperands[2] = operands[2];
883
884 if (REG_P (operands[2]))
885 operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
886 else
887 operands[2] = adjust_address (operands[2], HImode, 2);
888
889 output_asm_insn (\"bis %2, %0\", operands);
890 output_asm_insn (\"bis %2, %0\", lateoperands);
891 return \"\";
892 }
893
894 lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
895 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
896
897 /* these have different lengths, so we should have
898 different constraints! */
899 if (INTVAL(operands[2]))
900 output_asm_insn (\"bis %2, %0\", operands);
901
902 if (INTVAL(lateoperands[2]))
903 output_asm_insn (\"bis %2, %0\", lateoperands);
904
905 return \"\";
906 }"
907 [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
908
909 (define_insn "iorhi3"
910 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
911 (ior:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
912 (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
913 ""
914 "bis %2, %0"
915 [(set_attr "length" "1,2,2,3")])
916
917 (define_insn "iorqi3"
918 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
919 (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
920 (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
921 ""
922 "bisb %2, %0")
923 848
924 ;;- xor instructions 849 ;;- xor instructions
925 (define_insn "xorsi3"
926 [(set (match_operand:SI 0 "register_operand" "=r")
927 (xor:SI (match_operand:SI 1 "register_operand" "%0")
928 (match_operand:SI 2 "arith_operand" "r")))]
929 "TARGET_40_PLUS"
930 "*
931 { /* Here we trust that operands don't overlap */
932
933 rtx lateoperands[3];
934
935 lateoperands[0] = operands[0];
936 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
937
938 if (REG_P(operands[2]))
939 {
940 lateoperands[2] = operands[2];
941 operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
942
943 output_asm_insn (\"xor %2, %0\", operands);
944 output_asm_insn (\"xor %2, %0\", lateoperands);
945
946 return \"\";
947 }
948
949 }"
950 [(set_attr "length" "2")])
951
952 (define_insn "xorhi3" 850 (define_insn "xorhi3"
953 [(set (match_operand:HI 0 "general_operand" "=rR,Q") 851 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,Q")
954 (xor:HI (match_operand:HI 1 "general_operand" "%0,0") 852 (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
955 (match_operand:HI 2 "register_operand" "r,r")))] 853 (match_operand:HI 2 "register_operand" "r,r")))]
956 "TARGET_40_PLUS" 854 "TARGET_40_PLUS"
957 "xor %2, %0" 855 "xor %2, %0"
958 [(set_attr "length" "1,2")]) 856 [(set_attr "length" "2,4")])
959 857
960 ;;- one complement instructions 858 ;;- one complement instructions
961 859
962 (define_insn "one_cmplhi2" 860 (define_insn "one_cmpl<mode>2"
963 [(set (match_operand:HI 0 "general_operand" "=rR,Q") 861 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,Q")
964 (not:HI (match_operand:HI 1 "general_operand" "0,0")))] 862 (not:PDPint (match_operand:PDPint 1 "general_operand" "0,0")))]
965 "" 863 ""
966 "com %0" 864 "com<PDPint:isfx> %0"
967 [(set_attr "length" "1,2")]) 865 [(set_attr "length" "2,4")])
968
969 (define_insn "one_cmplqi2"
970 [(set (match_operand:QI 0 "general_operand" "=rR,rR")
971 (not:QI (match_operand:QI 1 "general_operand" "0,g")))]
972 ""
973 "@
974 comb %0
975 movb %1, %0\; comb %0"
976 [(set_attr "length" "1,2")])
977 866
978 ;;- arithmetic shift instructions 867 ;;- arithmetic shift instructions
979 (define_insn "ashlsi3" 868 (define_insn "ashlsi3"
980 [(set (match_operand:SI 0 "register_operand" "=r,r") 869 [(set (match_operand:SI 0 "register_operand" "=r,r")
981 (ashift:SI (match_operand:SI 1 "register_operand" "0,0") 870 (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
982 (match_operand:HI 2 "general_operand" "rR,Qi")))] 871 (match_operand:HI 2 "general_operand" "rR,Qi")))]
983 "TARGET_45" 872 "TARGET_40_PLUS"
984 "ashc %2,%0" 873 "ashc %2,%0"
985 [(set_attr "length" "1,2")]) 874 [(set_attr "length" "2,4")])
986 875
987 ;; Arithmetic right shift on the pdp works by negating the shift count. 876 ;; Arithmetic right shift on the pdp works by negating the shift count.
988 (define_expand "ashrsi3" 877 (define_expand "ashrsi3"
989 [(set (match_operand:SI 0 "register_operand" "=r") 878 [(set (match_operand:SI 0 "register_operand" "=r")
990 (ashift:SI (match_operand:SI 1 "register_operand" "0") 879 (ashift:SI (match_operand:SI 1 "register_operand" "0")
997 886
998 ;; define asl aslb asr asrb - ashc missing! 887 ;; define asl aslb asr asrb - ashc missing!
999 888
1000 ;; asl 889 ;; asl
1001 (define_insn "" 890 (define_insn ""
1002 [(set (match_operand:HI 0 "general_operand" "=rR,Q") 891 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,Q")
1003 (ashift:HI (match_operand:HI 1 "general_operand" "0,0") 892 (ashift:HI (match_operand:HI 1 "general_operand" "0,0")
1004 (const_int 1)))] 893 (const_int 1)))]
1005 "" 894 ""
1006 "asl %0" 895 "asl %0"
1007 [(set_attr "length" "1,2")]) 896 [(set_attr "length" "2,4")])
1008 897
1009 ;; and another possibility for asr is << -1 898 ;; and another possibility for asr is << -1
1010 ;; might cause problems since -1 can also be encoded as 65535! 899 ;; might cause problems since -1 can also be encoded as 65535!
1011 ;; not in gcc2 ??? 900 ;; not in gcc2 ???
1012 901
1013 ;; asr 902 ;; asr
1014 (define_insn "" 903 (define_insn ""
1015 [(set (match_operand:HI 0 "general_operand" "=rR,Q") 904 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,Q")
1016 (ashift:HI (match_operand:HI 1 "general_operand" "0,0") 905 (ashift:HI (match_operand:HI 1 "general_operand" "0,0")
1017 (const_int -1)))] 906 (const_int -1)))]
1018 "" 907 ""
1019 "asr %0" 908 "asr %0"
1020 [(set_attr "length" "1,2")]) 909 [(set_attr "length" "2,4")])
1021 910
1022 ;; lsr 911 ;; lsr
1023 (define_insn "" 912 (define_insn "lsrhi1"
1024 [(set (match_operand:HI 0 "general_operand" "=rR,Q") 913 [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,Q")
1025 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0,0") 914 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0,0")
1026 (const_int 1)))] 915 (const_int 1)))]
1027 "" 916 ""
1028 "clc\;ror %0" 917 "clc\;ror %0"
1029 [(set_attr "length" "1,2")]) 918 [(set_attr "length" "2,4")])
1030 919
1031 (define_insn "lshrsi3" 920 (define_insn "lsrsi1"
1032 [(set (match_operand:SI 0 "register_operand" "=r") 921 [(set (match_operand:SI 0 "register_operand" "=r")
1033 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") 922 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1034 (const_int 1)))] 923 (const_int 1)))]
1035 "" 924 ""
1036 { 925 {
1047 output_asm_insn (\"ror %0\", lateoperands); 936 output_asm_insn (\"ror %0\", lateoperands);
1048 output_asm_insn (\"ror %0\", operands); 937 output_asm_insn (\"ror %0\", operands);
1049 938
1050 return \"\"; 939 return \"\";
1051 } 940 }
1052 [(set_attr "length" "5")]) 941 [(set_attr "length" "10")])
942
943 (define_expand "lshrsi3"
944 [(match_operand:SI 0 "register_operand" "")
945 (match_operand:SI 1 "register_operand" "0")
946 (match_operand:HI 2 "general_operand" "")]
947 ""
948 "
949 {
950 rtx r;
951
952 if (!TARGET_40_PLUS &&
953 (GET_CODE (operands[2]) != CONST_INT ||
954 (unsigned) INTVAL (operands[2]) > 3))
955 FAIL;
956 emit_insn (gen_lsrsi1 (operands[0], operands[1]));
957 if (GET_CODE (operands[2]) != CONST_INT)
958 {
959 r = gen_reg_rtx (HImode);
960 emit_insn (gen_addhi3 (r, operands [2], GEN_INT (-1)));
961 emit_insn (gen_ashrsi3 (operands[0], operands[0], r));
962 }
963 else if ((unsigned) INTVAL (operands[2]) != 1)
964 {
965 emit_insn (gen_ashlsi3 (operands[0], operands[0],
966 GEN_INT (1 - INTVAL (operands[2]))));
967 }
968 DONE;
969 }
970 "
971 )
1053 972
1054 ;; shift is by arbitrary count is expensive, 973 ;; shift is by arbitrary count is expensive,
1055 ;; shift by one cheap - so let's do that, if 974 ;; shift by one cheap - so let's do that, if
1056 ;; space doesn't matter 975 ;; space doesn't matter
1057 (define_insn "" 976 (define_insn ""
1058 [(set (match_operand:HI 0 "general_operand" "=r") 977 [(set (match_operand:HI 0 "nonimmediate_operand" "=r")
1059 (ashift:HI (match_operand:HI 1 "general_operand" "0") 978 (ashift:HI (match_operand:HI 1 "general_operand" "0")
1060 (match_operand:HI 2 "expand_shift_operand" "O")))] 979 (match_operand:HI 2 "expand_shift_operand" "O")))]
1061 "! optimize_size" 980 "! optimize_size"
1062 "* 981 "*
1063 { 982 {
1070 output_asm_insn(\"asl %0\", operands); 989 output_asm_insn(\"asl %0\", operands);
1071 990
1072 return \"\"; 991 return \"\";
1073 }" 992 }"
1074 ;; longest is 4 993 ;; longest is 4
1075 [(set (attr "length") (const_int 4))]) 994 [(set (attr "length") (const_int 8))])
1076 995
1077 ;; aslb 996 ;; aslb
1078 (define_insn "" 997 (define_insn ""
1079 [(set (match_operand:QI 0 "general_operand" "=r,o") 998 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,o")
1080 (ashift:QI (match_operand:QI 1 "general_operand" "0,0") 999 (ashift:QI (match_operand:QI 1 "general_operand" "0,0")
1081 (match_operand:HI 2 "const_immediate_operand" "n,n")))] 1000 (match_operand:HI 2 "const_int_operand" "n,n")))]
1082 "" 1001 ""
1083 "* 1002 "*
1084 { /* allowing predec or post_inc is possible, but hairy! */ 1003 { /* allowing predec or post_inc is possible, but hairy! */
1085 int i, cnt; 1004 int i, cnt;
1086 1005
1091 1010
1092 return \"\"; 1011 return \"\";
1093 }" 1012 }"
1094 ;; set attribute length ( match_dup 2 & 7 ) *(1 or 2) !!! 1013 ;; set attribute length ( match_dup 2 & 7 ) *(1 or 2) !!!
1095 [(set_attr_alternative "length" 1014 [(set_attr_alternative "length"
1096 [(const_int 7) 1015 [(const_int 14)
1097 (const_int 14)])]) 1016 (const_int 28)])])
1098 1017
1099 ;;; asr 1018 ;;; asr
1100 ;(define_insn "" 1019 ;(define_insn ""
1101 ; [(set (match_operand:HI 0 "general_operand" "=rR,Q") 1020 ; [(set (match_operand:HI 0 "nonimmediate_operand" "=rR,Q")
1102 ; (ashiftrt:HI (match_operand:HI 1 "general_operand" "0,0") 1021 ; (ashiftrt:HI (match_operand:HI 1 "general_operand" "0,0")
1103 ; (const_int 1)))] 1022 ; (const_int 1)))]
1104 ; "" 1023 ; ""
1105 ; "asr %0" 1024 ; "asr %0"
1106 ; [(set_attr "length" "1,2")]) 1025 ; [(set_attr "length" "2,4")])
1107 1026
1108 ;; asrb 1027 ;; asrb
1109 (define_insn "" 1028 (define_insn ""
1110 [(set (match_operand:QI 0 "general_operand" "=r,o") 1029 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,o")
1111 (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0") 1030 (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0")
1112 (match_operand:HI 2 "const_immediate_operand" "n,n")))] 1031 (match_operand:HI 2 "const_int_operand" "n,n")))]
1113 "" 1032 ""
1114 "* 1033 "*
1115 { /* allowing predec or post_inc is possible, but hairy! */ 1034 { /* allowing predec or post_inc is possible, but hairy! */
1116 int i, cnt; 1035 int i, cnt;
1117 1036
1121 output_asm_insn(\"asrb %0\", operands); 1040 output_asm_insn(\"asrb %0\", operands);
1122 1041
1123 return \"\"; 1042 return \"\";
1124 }" 1043 }"
1125 [(set_attr_alternative "length" 1044 [(set_attr_alternative "length"
1126 [(const_int 7) 1045 [(const_int 14)
1127 (const_int 14)])]) 1046 (const_int 28)])])
1128 1047
1129 ;; the following is invalid - too complex!!! - just say 14 !!! 1048 ;; the following is invalid - too complex!!! - just say 14 !!!
1130 ; [(set (attr "length") (plus (and (match_dup 2) 1049 ; [(set (attr "length") (plus (and (match_dup 2)
1131 ; (const_int 7)) 1050 ; (const_int 14))
1132 ; (and (match_dup 2) 1051 ; (and (match_dup 2)
1133 ; (const_int 7))))]) 1052 ; (const_int 14))))])
1134 1053
1135 1054
1136 1055
1137 ;; can we get +-1 in the next pattern? should 1056 ;; can we get +-1 in the next pattern? should
1138 ;; have been caught by previous patterns! 1057 ;; have been caught by previous patterns!
1139 1058
1140 (define_insn "ashlhi3" 1059 (define_insn "ashlhi3"
1141 [(set (match_operand:HI 0 "register_operand" "=r,r") 1060 [(set (match_operand:HI 0 "register_operand" "=r,r")
1142 (ashift:HI (match_operand:HI 1 "register_operand" "0,0") 1061 (ashift:HI (match_operand:HI 1 "register_operand" "0,0")
1143 (match_operand:HI 2 "general_operand" "rR,Qi")))] 1062 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1144 "" 1063 "TARGET_40_PLUS"
1145 "* 1064 "*
1146 { 1065 {
1147 if (GET_CODE(operands[2]) == CONST_INT) 1066 if (GET_CODE(operands[2]) == CONST_INT)
1148 { 1067 {
1149 if (INTVAL(operands[2]) == 1) 1068 if (INTVAL(operands[2]) == 1)
1152 return \"asr %0\"; 1071 return \"asr %0\";
1153 } 1072 }
1154 1073
1155 return \"ash %2,%0\"; 1074 return \"ash %2,%0\";
1156 }" 1075 }"
1157 [(set_attr "length" "1,2")]) 1076 [(set_attr "length" "2,4")])
1158 1077
1159 ;; Arithmetic right shift on the pdp works by negating the shift count. 1078 ;; Arithmetic right shift on the pdp works by negating the shift count.
1160 (define_expand "ashrhi3" 1079 (define_expand "ashrhi3"
1161 [(set (match_operand:HI 0 "register_operand" "=r") 1080 [(set (match_operand:HI 0 "register_operand" "=r")
1162 (ashift:HI (match_operand:HI 1 "register_operand" "0") 1081 (ashift:HI (match_operand:HI 1 "register_operand" "0")
1165 " 1084 "
1166 { 1085 {
1167 operands[2] = negate_rtx (HImode, operands[2]); 1086 operands[2] = negate_rtx (HImode, operands[2]);
1168 }") 1087 }")
1169 1088
1170 ;;;;- logical shift instructions 1089 (define_expand "lshrhi3"
1171 ;;(define_insn "lshrsi3" 1090 [(match_operand:HI 0 "register_operand" "")
1172 ;; [(set (match_operand:HI 0 "register_operand" "=r") 1091 (match_operand:HI 1 "register_operand" "")
1173 ;; (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") 1092 (match_operand:HI 2 "general_operand" "")]
1174 ;; (match_operand:HI 2 "arith_operand" "rI")))] 1093 ""
1175 ;; "" 1094 "
1176 ;; "srl %0,%2") 1095 {
1096 rtx r;
1097
1098 if (!TARGET_40_PLUS &&
1099 (GET_CODE (operands[2]) != CONST_INT ||
1100 (unsigned) INTVAL (operands[2]) > 3))
1101 FAIL;
1102 emit_insn (gen_lsrhi1 (operands[0], operands[1]));
1103 if (GET_CODE (operands[2]) != CONST_INT)
1104 {
1105 r = gen_reg_rtx (HImode);
1106 emit_insn (gen_addhi3 (r, operands [2], GEN_INT (-1)));
1107 emit_insn (gen_ashrhi3 (operands[0], operands[0], r));
1108 }
1109 else if ((unsigned) INTVAL (operands[2]) != 1)
1110 {
1111 emit_insn (gen_ashlhi3 (operands[0], operands[0],
1112 GEN_INT (1 - INTVAL (operands[2]))));
1113 }
1114 DONE;
1115 }
1116 "
1117 )
1177 1118
1178 ;; absolute 1119 ;; absolute
1179 1120
1180 (define_insn "absdf2" 1121 (define_insn "absdf2"
1181 [(set (match_operand:DF 0 "general_operand" "=fR,Q") 1122 [(set (match_operand:DF 0 "nonimmediate_operand" "=fR,Q")
1182 (abs:DF (match_operand:DF 1 "general_operand" "0,0")))] 1123 (abs:DF (match_operand:DF 1 "general_operand" "0,0")))]
1183 "TARGET_FPU" 1124 "TARGET_FPU"
1184 "{absd|absf} %0" 1125 "{absd|absf} %0"
1185 [(set_attr "length" "1,2")]) 1126 [(set_attr "length" "2,4")])
1186 1127
1187 (define_insn "abshi2"
1188 [(set (match_operand:HI 0 "general_operand" "=r,o")
1189 (abs:HI (match_operand:HI 1 "general_operand" "0,0")))]
1190 "TARGET_ABSHI_BUILTIN"
1191 "*
1192 {
1193 static int count = 0;
1194 char buf[200];
1195
1196 output_asm_insn(\"tst %0\", operands);
1197 sprintf(buf, \"bge abshi%d\", count);
1198 output_asm_insn(buf, NULL);
1199 output_asm_insn(\"neg %0\", operands);
1200 sprintf(buf, \"\\nabshi%d:\", count++);
1201 output_asm_insn(buf, NULL);
1202
1203 return \"\";
1204 }"
1205 [(set_attr "length" "3,5")])
1206
1207
1208 ;; define expand abshi - is much better !!! - but
1209 ;; will it be optimized into an abshi2 ?
1210 ;; it will leave better code, because the tsthi might be
1211 ;; optimized away!!
1212 ; -- just a thought - don't have time to check
1213 ;
1214 ;(define_expand "abshi2"
1215 ; [(match_operand:HI 0 "general_operand" "")
1216 ; (match_operand:HI 1 "general_operand" "")]
1217 ; ""
1218 ; "
1219 ;{
1220 ; rtx label = gen_label_rtx ();
1221 ;
1222 ; /* do I need this? */
1223 ; do_pending_stack_adjust ();
1224 ;
1225 ; emit_move_insn (operands[0], operands[1]);
1226 ;
1227 ; emit_insn (gen_tsthi (operands[0]));
1228 ; emit_insn (gen_bge (label1));
1229 ;
1230 ; emit_insn (gen_neghi(operands[0], operands[0])
1231 ;
1232 ; emit_barrier ();
1233 ;
1234 ; emit_label (label);
1235 ;
1236 ; /* allow REG_NOTES to be set on last insn (labels don't have enough
1237 ; fields, and can't be used for REG_NOTES anyway). */
1238 ; emit_use (stack_pointer_rtx);
1239 ; DONE;
1240 ;}")
1241 1128
1242 ;; negate insns 1129 ;; negate insns
1243 1130
1244 (define_insn "negdf2" 1131 (define_insn "negdf2"
1245 [(set (match_operand:DF 0 "general_operand" "=fR,Q") 1132 [(set (match_operand:DF 0 "float_nonimm_operand" "=fR,Q")
1246 (neg:DF (match_operand:DF 1 "register_operand" "0,0")))] 1133 (neg:DF (match_operand:DF 1 "register_operand" "0,0")))]
1247 "TARGET_FPU" 1134 "TARGET_FPU"
1248 "{negd|negf} %0" 1135 "{negd|negf} %0"
1249 [(set_attr "length" "1,2")]) 1136 [(set_attr "length" "2,4")])
1250 1137
1251 (define_insn "negsi2" 1138 (define_insn "negdi2"
1252 [(set (match_operand:SI 0 "register_operand" "=r") 1139 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
1253 (neg:SI (match_operand:SI 1 "general_operand" "0")))] 1140 (neg:DI (match_operand:DI 1 "general_operand" "0,0")))]
1254 "" 1141 ""
1255 { 1142 {
1256 1143 rtx exops[4][2];
1257 rtx lateoperands[2]; 1144
1258 1145 pdp11_expand_operands (operands, exops, 1, NULL, either);
1259 lateoperands[0] = operands[0]; 1146
1260 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); 1147 output_asm_insn (\"com %0\", exops[3]);
1261 1148 output_asm_insn (\"com %0\", exops[2]);
1262 lateoperands[1] = operands[1]; 1149 output_asm_insn (\"com %0\", exops[1]);
1263 operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1); 1150 output_asm_insn (\"com %0\", exops[0]);
1264 1151 output_asm_insn (\"add $1, %0\", exops[3]);
1265 output_asm_insn (\"com %0\", operands); 1152 output_asm_insn (\"adc %0\", exops[2]);
1266 output_asm_insn (\"com %0\", lateoperands); 1153 output_asm_insn (\"adc %0\", exops[1]);
1267 output_asm_insn (\"inc %0\", operands); 1154 output_asm_insn (\"adc %0\", exops[0]);
1268 output_asm_insn (\"adc %0\", lateoperands);
1269 1155
1270 return \"\"; 1156 return \"\";
1271 } 1157 }
1272 [(set_attr "length" "5")]) 1158 [(set_attr "length" "18,34")])
1273 1159
1274 (define_insn "neghi2" 1160 (define_insn "negsi2"
1275 [(set (match_operand:HI 0 "general_operand" "=rR,Q") 1161 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,o")
1276 (neg:HI (match_operand:HI 1 "general_operand" "0,0")))] 1162 (neg:SI (match_operand:SI 1 "general_operand" "0,0")))]
1277 "" 1163 ""
1278 "neg %0" 1164 {
1279 [(set_attr "length" "1,2")]) 1165 rtx exops[2][2];
1280 1166
1281 (define_insn "negqi2" 1167 pdp11_expand_operands (operands, exops, 1, NULL, either);
1282 [(set (match_operand:QI 0 "general_operand" "=rR,Q") 1168
1283 (neg:QI (match_operand:QI 1 "general_operand" "0,0")))] 1169 output_asm_insn (\"com %0\", exops[1]);
1284 "" 1170 output_asm_insn (\"com %0\", exops[0]);
1285 "negb %0" 1171 output_asm_insn (\"add $1, %0\", exops[1]);
1286 [(set_attr "length" "1,2")]) 1172 output_asm_insn (\"adc %0\", exops[0]);
1173
1174 return \"\";
1175 }
1176 [(set_attr "length" "12,20")])
1177
1178 (define_insn "neg<mode>2"
1179 [(set (match_operand:PDPint 0 "nonimmediate_operand" "=rR,Q")
1180 (neg:PDPint (match_operand:PDPint 1 "general_operand" "0,0")))]
1181 ""
1182 "neg<isfx> %0"
1183 [(set_attr "length" "2,4")])
1287 1184
1288 1185
1289 ;; Unconditional and other jump instructions 1186 ;; Unconditional and other jump instructions
1290 (define_insn "jump" 1187 (define_insn "jump"
1291 [(set (pc) 1188 [(set (pc)
1292 (label_ref (match_operand 0 "" "")))] 1189 (label_ref (match_operand 0 "" "")))]
1293 "" 1190 ""
1294 "jmp %l0" 1191 "*
1295 [(set_attr "length" "2")]) 1192 {
1193 if (get_attr_length (insn) == 2)
1194 return \"br %l0\";
1195 return \"jmp %l0\";
1196 }"
1197 [(set (attr "length") (if_then_else (ior (lt (minus (match_dup 0)
1198 (pc))
1199 (const_int MIN_BRANCH))
1200 (gt (minus (match_dup 0)
1201 (pc))
1202 (const_int MAX_BRANCH)))
1203 (const_int 4)
1204 (const_int 2)))])
1296 1205
1297 (define_insn "" 1206 (define_insn ""
1298 [(set (pc) 1207 [(set (pc)
1299 (label_ref (match_operand 0 "" ""))) 1208 (label_ref (match_operand 0 "" "")))
1300 (clobber (const_int 1))] 1209 (clobber (const_int 1))]
1301 "" 1210 ""
1302 "jmp %l0" 1211 "jmp %l0"
1303 [(set_attr "length" "2")]) 1212 [(set_attr "length" "4")])
1304 1213
1305 (define_insn "tablejump" 1214 (define_insn "tablejump"
1306 [(set (pc) (match_operand:HI 0 "general_operand" "rR,Q")) 1215 [(set (pc) (match_operand:HI 0 "general_operand" "r,R,Q"))
1307 (use (label_ref (match_operand 1 "" "")))] 1216 (use (label_ref (match_operand 1 "" "")))]
1308 "" 1217 ""
1309 "jmp %0" 1218 "@
1310 [(set_attr "length" "1,2")]) 1219 jmp (%0)
1220 jmp %@%0
1221 jmp %@%0"
1222 [(set_attr "length" "2,2,4")])
1311 1223
1312 ;; indirect jump - let's be conservative! 1224 ;; indirect jump - let's be conservative!
1313 ;; allow only register_operand, even though we could also 1225 ;; allow only register_operand, even though we could also
1314 ;; allow labels etc. 1226 ;; allow labels etc.
1315 1227
1326 ;; (use (reg:HI 0)) what was that ??? 1238 ;; (use (reg:HI 0)) what was that ???
1327 ] 1239 ]
1328 ;;- Don't use operand 1 for most machines. 1240 ;;- Don't use operand 1 for most machines.
1329 "" 1241 ""
1330 "jsr pc, %0" 1242 "jsr pc, %0"
1331 [(set_attr "length" "1,2")]) 1243 [(set_attr "length" "2,4")])
1332 1244
1333 ;;- jump to subroutine 1245 ;;- jump to subroutine
1334 (define_insn "call_value" 1246 (define_insn "call_value"
1335 [(set (match_operand 0 "" "") 1247 [(set (match_operand 0 "" "")
1336 (call (match_operand:HI 1 "general_operand" "rR,Q") 1248 (call (match_operand:HI 1 "general_operand" "rR,Q")
1338 ;; (use (reg:HI 0)) - what was that ???? 1250 ;; (use (reg:HI 0)) - what was that ????
1339 ] 1251 ]
1340 ;;- Don't use operand 2 for most machines. 1252 ;;- Don't use operand 2 for most machines.
1341 "" 1253 ""
1342 "jsr pc, %1" 1254 "jsr pc, %1"
1343 [(set_attr "length" "1,2")]) 1255 [(set_attr "length" "2,4")])
1344 1256
1345 ;;- nop instruction 1257 ;;- nop instruction
1346 (define_insn "nop" 1258 (define_insn "nop"
1347 [(const_int 0)] 1259 [(const_int 0)]
1348 "" 1260 ""
1350 1262
1351 1263
1352 ;;- multiply 1264 ;;- multiply
1353 1265
1354 (define_insn "muldf3" 1266 (define_insn "muldf3"
1355 [(set (match_operand:DF 0 "register_operand" "=a,a,a") 1267 [(set (match_operand:DF 0 "register_operand" "=a,a")
1356 (mult:DF (match_operand:DF 1 "register_operand" "%0,0,0") 1268 (mult:DF (match_operand:DF 1 "register_operand" "%0,0")
1357 (match_operand:DF 2 "general_operand" "fR,Q,F")))] 1269 (match_operand:DF 2 "float_operand" "fR,QF")))]
1358 "TARGET_FPU" 1270 "TARGET_FPU"
1359 "{muld|mulf} %2, %0" 1271 "{muld|mulf} %2, %0"
1360 [(set_attr "length" "1,2,5")]) 1272 [(set_attr "length" "2,4")])
1361 1273
1362 ;; 16 bit result multiply: 1274 ;; 16 bit result multiply:
1363 ;; currently we multiply only into odd registers, so we don't use two 1275 ;; currently we multiply only into odd registers, so we don't use two
1364 ;; registers - but this is a bit inefficient at times. If we define 1276 ;; registers - but this is a bit inefficient at times. If we define
1365 ;; a register class for each register, then we can specify properly 1277 ;; a register class for each register, then we can specify properly
1366 ;; which register need which scratch register .... 1278 ;; which register need which scratch register ....
1367 1279
1368 (define_insn "mulhi3" 1280 (define_insn "mulhi3"
1369 [(set (match_operand:HI 0 "register_operand" "=d,d") ; multiply regs 1281 [(set (match_operand:HI 0 "register_operand" "=d,d") ; multiply regs
1370 (mult:HI (match_operand:HI 1 "register_operand" "%0,0") 1282 (mult:HI (match_operand:HI 1 "register_operand" "%0,0")
1371 (match_operand:HI 2 "general_operand" "rR,Qi")))] 1283 (match_operand:HI 2 "float_operand" "rR,Qi")))]
1372 "TARGET_45" 1284 "TARGET_40_PLUS"
1373 "mul %2, %0" 1285 "mul %2, %0"
1374 [(set_attr "length" "1,2")]) 1286 [(set_attr "length" "2,4")])
1375 1287
1376 ;; 32 bit result 1288 ;; 32 bit result
1377 (define_expand "mulhisi3" 1289 (define_expand "mulhisi3"
1378 [(set (match_dup 3) 1290 [(set (match_dup 3)
1379 (match_operand:HI 1 "general_operand" "g,g")) 1291 (match_operand:HI 1 "nonimmediate_operand" "g,g"))
1380 (set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! 1292 (set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1381 (mult:SI (truncate:HI 1293 (mult:SI (truncate:HI
1382 (match_dup 0)) 1294 (match_dup 0))
1383 (match_operand:HI 2 "general_operand" "rR,Qi")))] 1295 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1384 "TARGET_45" 1296 "TARGET_40_PLUS"
1385 "operands[3] = gen_lowpart(HImode, operands[1]);") 1297 "operands[3] = gen_lowpart(HImode, operands[1]);")
1386 1298
1387 (define_insn "" 1299 (define_insn ""
1388 [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! 1300 [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1389 (mult:SI (truncate:HI 1301 (mult:SI (truncate:HI
1390 (match_operand:SI 1 "register_operand" "%0,0")) 1302 (match_operand:SI 1 "register_operand" "%0,0"))
1391 (match_operand:HI 2 "general_operand" "rR,Qi")))] 1303 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1392 "TARGET_45" 1304 "TARGET_40_PLUS"
1393 "mul %2, %0" 1305 "mul %2, %0"
1394 [(set_attr "length" "1,2")]) 1306 [(set_attr "length" "2,4")])
1395 1307
1396 ;(define_insn "mulhisi3" 1308 ;(define_insn "mulhisi3"
1397 ; [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! 1309 ; [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1398 ; (mult:SI (truncate:HI 1310 ; (mult:SI (truncate:HI
1399 ; (match_operand:SI 1 "register_operand" "%0,0")) 1311 ; (match_operand:SI 1 "register_operand" "%0,0"))
1400 ; (match_operand:HI 2 "general_operand" "rR,Qi")))] 1312 ; (match_operand:HI 2 "general_operand" "rR,Qi")))]
1401 ; "TARGET_45" 1313 ; "TARGET_40_PLUS"
1402 ; "mul %2, %0" 1314 ; "mul %2, %0"
1403 ; [(set_attr "length" "1,2")]) 1315 ; [(set_attr "length" "2,4")])
1404 1316
1405 ;;- divide 1317 ;;- divide
1406 (define_insn "divdf3" 1318 (define_insn "divdf3"
1407 [(set (match_operand:DF 0 "register_operand" "=a,a,a") 1319 [(set (match_operand:DF 0 "register_operand" "=a,a")
1408 (div:DF (match_operand:DF 1 "register_operand" "0,0,0") 1320 (div:DF (match_operand:DF 1 "register_operand" "0,0")
1409 (match_operand:DF 2 "general_operand" "fR,Q,F")))] 1321 (match_operand:DF 2 "general_operand" "fR,QF")))]
1410 "TARGET_FPU" 1322 "TARGET_FPU"
1411 "{divd|divf} %2, %0" 1323 "{divd|divf} %2, %0"
1412 [(set_attr "length" "1,2,5")]) 1324 [(set_attr "length" "2,4")])
1413 1325
1414 1326
1415 (define_expand "divhi3" 1327 (define_expand "divhi3"
1416 [(set (subreg:HI (match_dup 1) 0) 1328 [(set (subreg:HI (match_dup 1) 0)
1417 (div:HI (match_operand:SI 1 "general_operand" "0") 1329 (div:HI (match_operand:SI 1 "register_operand" "0")
1418 (match_operand:HI 2 "general_operand" "g"))) 1330 (match_operand:HI 2 "general_operand" "g")))
1419 (set (match_operand:HI 0 "general_operand" "=r") 1331 (set (match_operand:HI 0 "register_operand" "=r")
1420 (subreg:HI (match_dup 1) 0))] 1332 (subreg:HI (match_dup 1) 0))]
1421 "TARGET_45" 1333 "TARGET_40_PLUS"
1422 "") 1334 "")
1423 1335
1424 (define_insn "" 1336 (define_insn ""
1425 [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0) 1337 [(set (subreg:HI (match_operand:SI 0 "register_operand" "=r") 0)
1426 (div:HI (match_operand:SI 1 "general_operand" "0") 1338 (div:HI (match_operand:SI 1 "general_operand" "0")
1427 (match_operand:HI 2 "general_operand" "g")))] 1339 (match_operand:HI 2 "general_operand" "g")))]
1428 "TARGET_45" 1340 "TARGET_40_PLUS"
1429 "div %2,%0" 1341 "div %2,%0"
1430 [(set_attr "length" "2")]) 1342 [(set_attr "length" "4")])
1431 1343
1432 (define_expand "modhi3" 1344 (define_expand "modhi3"
1433 [(set (subreg:HI (match_dup 1) 2) 1345 [(set (subreg:HI (match_dup 1) 2)
1434 (mod:HI (match_operand:SI 1 "general_operand" "0") 1346 (mod:HI (match_operand:SI 1 "register_operand" "0")
1435 (match_operand:HI 2 "general_operand" "g"))) 1347 (match_operand:HI 2 "general_operand" "g")))
1436 (set (match_operand:HI 0 "general_operand" "=r") 1348 (set (match_operand:HI 0 "register_operand" "=r")
1437 (subreg:HI (match_dup 1) 2))] 1349 (subreg:HI (match_dup 1) 2))]
1438 "TARGET_45" 1350 "TARGET_40_PLUS"
1439 "") 1351 "")
1440 1352
1441 (define_insn "" 1353 (define_insn ""
1442 [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 2) 1354 [(set (subreg:HI (match_operand:SI 0 "register_operand" "=r") 2)
1443 (mod:HI (match_operand:SI 1 "general_operand" "0") 1355 (mod:HI (match_operand:SI 1 "general_operand" "0")
1444 (match_operand:HI 2 "general_operand" "g")))] 1356 (match_operand:HI 2 "general_operand" "g")))]
1445 "TARGET_45" 1357 "TARGET_40_PLUS"
1446 "div %2,%0" 1358 "div %2,%0"
1447 [(set_attr "length" "2")]) 1359 [(set_attr "length" "4")])
1448 1360
1449 ;(define_expand "divmodhi4" 1361 ;(define_expand "divmodhi4"
1450 ; [(parallel [(set (subreg:HI (match_dup 1) 0) 1362 ; [(parallel [(set (subreg:HI (match_dup 1) 0)
1451 ; (div:HI (match_operand:SI 1 "general_operand" "0") 1363 ; (div:HI (match_operand:SI 1 "register_operand" "0")
1452 ; (match_operand:HI 2 "general_operand" "g"))) 1364 ; (match_operand:HI 2 "general_operand" "g")))
1453 ; (set (subreg:HI (match_dup 1) 2) 1365 ; (set (subreg:HI (match_dup 1) 2)
1454 ; (mod:HI (match_dup 1) 1366 ; (mod:HI (match_dup 1)
1455 ; (match_dup 2)))]) 1367 ; (match_dup 2)))])
1456 ; (set (match_operand:HI 3 "general_operand" "=r") 1368 ; (set (match_operand:HI 3 "register_operand" "=r")
1457 ; (subreg:HI (match_dup 1) 2)) 1369 ; (subreg:HI (match_dup 1) 2))
1458 ; (set (match_operand:HI 0 "general_operand" "=r") 1370 ; (set (match_operand:HI 0 "register_operand" "=r")
1459 ; (subreg:HI (match_dup 1) 0))] 1371 ; (subreg:HI (match_dup 1) 0))]
1460 ; "TARGET_45" 1372 ; "TARGET_40_PLUS"
1461 ; "") 1373 ; "")
1462 ; 1374 ;
1463 ;(define_insn "" 1375 ;(define_insn ""
1464 ; [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0) 1376 ; [(set (subreg:HI (match_operand:SI 0 "register_operand" "=r") 0)
1465 ; (div:HI (match_operand:SI 1 "general_operand" "0") 1377 ; (div:HI (match_operand:SI 1 "general_operand" "0")
1466 ; (match_operand:HI 2 "general_operand" "g"))) 1378 ; (match_operand:HI 2 "general_operand" "g")))
1467 ; (set (subreg:HI (match_dup 0) 2) 1379 ; (set (subreg:HI (match_dup 0) 2)
1468 ; (mod:HI (match_dup 1) 1380 ; (mod:HI (match_dup 1)
1469 ; (match_dup 2)))] 1381 ; (match_dup 2)))]
1470 ; "TARGET_45" 1382 ; "TARGET_40_PLUS"
1471 ; "div %2, %0") 1383 ; "div %2, %0")
1472 ; 1384 ;
1473 1385
1474 ;; is rotate doing the right thing to be included here ???? 1386 ;; is rotate doing the right thing to be included here ????