]>
Commit | Line | Data |
---|---|---|
2c9c2489 | 1 | ;;- Machine description for the pdp11 for GNU C compiler |
9db9ab7e | 2 | ;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2004, 2005 |
2f83c7d6 | 3 | ;; 2007 Free Software Foundation, Inc. |
2c9c2489 RK |
4 | ;; Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at). |
5 | ||
7ec022b2 | 6 | ;; This file is part of GCC. |
2c9c2489 | 7 | |
7ec022b2 | 8 | ;; GCC is free software; you can redistribute it and/or modify |
2c9c2489 | 9 | ;; it under the terms of the GNU General Public License as published by |
2f83c7d6 | 10 | ;; the Free Software Foundation; either version 3, or (at your option) |
2c9c2489 RK |
11 | ;; any later version. |
12 | ||
7ec022b2 | 13 | ;; GCC is distributed in the hope that it will be useful, |
2c9c2489 RK |
14 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | ;; GNU General Public License for more details. | |
17 | ||
18 | ;; You should have received a copy of the GNU General Public License | |
2f83c7d6 NC |
19 | ;; along with GCC; see the file COPYING3. If not see |
20 | ;; <http://www.gnu.org/licenses/>. | |
2c9c2489 RK |
21 | |
22 | ||
23 | ;; HI is 16 bit | |
24 | ;; QI is 8 bit | |
25 | ||
26 | ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. | |
27 | ||
28 | ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code | |
29 | ;;- updates for most instructions. | |
30 | ||
31 | ;;- Operand classes for the register allocator: | |
32 | \f | |
33 | ;; Compare instructions. | |
34 | ||
35 | ;; currently we only support df floats, which saves us quite some | |
36 | ;; hassle switching the FP mode! | |
37 | ;; we assume that CPU is always in long float mode, and | |
38 | ;; 16 bit integer mode - currently, the prologue for main does this, | |
39 | ;; but maybe we should just set up a NEW crt0 properly, | |
40 | ;; -- and what about signal handling code? | |
41 | ;; (we don't even let sf floats in the register file, so | |
42 | ;; we only should have to worry about truncating and widening | |
43 | ;; when going to memory) | |
44 | ||
45 | ;; abort() call by g++ - must define libfunc for cmp_optab | |
46 | ;; and ucmp_optab for mode SImode, because we don't have that!!! | |
47 | ;; - yet since no libfunc is there, we abort () | |
48 | ||
49 | ;; The only thing that remains to be done then is output | |
50 | ;; the floats in a way the assembler can handle it (and | |
51 | ;; if you're really into it, use a PDP11 float emulation | |
3a598fbe | 52 | ;; library to do floating point constant folding - but |
2c9c2489 RK |
53 | ;; I guess you'll get reasonable results even when not |
54 | ;; doing this) | |
55 | ;; the last thing to do is fix the UPDATE_CC macro to check | |
56 | ;; for floating point condition codes, and set cc_status | |
57 | ;; properly, also setting the CC_IN_FCCR flag. | |
58 | ||
59 | ;; define attributes | |
60 | ;; currently type is only fpu or arith or unknown, maybe branch later ? | |
61 | ;; default is arith | |
62 | (define_attr "type" "unknown,arith,fp" (const_string "arith")) | |
63 | ||
64 | ;; length default is 1 word each | |
65 | (define_attr "length" "" (const_int 1)) | |
66 | ||
ddd5a7c1 | 67 | ;; a user's asm statement |
2c9c2489 RK |
68 | (define_asm_attributes |
69 | [(set_attr "type" "unknown") | |
70 | ; all bets are off how long it is - make it 256, forces long jumps | |
71 | ; whenever jumping around it !!! | |
72 | (set_attr "length" "256")]) | |
73 | ||
74 | ;; define function units | |
75 | ||
76 | ;; arithmetic - values here immediately when next insn issued | |
77 | ;; or does it mean the number of cycles after this insn was issued? | |
78 | ;; how do I say that fpu insns use cpu also? (pre-interaction phase) | |
79 | ||
80 | ;(define_function_unit "cpu" 1 1 (eq_attr "type" "arith") 0 0) | |
81 | ;(define_function_unit "fpu" 1 1 (eq_attr "type" "fp") 0 0) | |
82 | ||
83 | ;; compare | |
84 | (define_insn "cmpdf" | |
85 | [(set (cc0) | |
86 | (compare (match_operand:DF 0 "general_operand" "fR,Q,F") | |
87 | (match_operand:DF 1 "register_operand" "a,a,a")))] | |
88 | "TARGET_FPU" | |
89 | "* | |
90 | { | |
91 | cc_status.flags = CC_IN_FPU; | |
af36a4d2 | 92 | return \"{cmpd|cmpf} %0, %1\;cfcc\"; |
2c9c2489 RK |
93 | }" |
94 | [(set_attr "length" "2,3,6")]) | |
95 | ||
96 | ;; a bit of brain damage, maybe inline later - | |
97 | ;; problem is - gcc seems to NEED SImode because | |
98 | ;; of the cmp weirdness - maybe change gcc to handle this? | |
99 | ||
100 | (define_expand "cmpsi" | |
101 | [(set (reg:SI 0) | |
102 | (match_operand:SI 0 "general_operand" "g")) | |
103 | (set (reg:SI 2) | |
104 | (match_operand:SI 1 "general_operand" "g")) | |
105 | (parallel [(set (cc0) | |
106 | (compare (reg:SI 0) | |
107 | (reg:SI 2))) | |
108 | (clobber (reg:SI 0))])] | |
109 | "0" ;; disable for test | |
110 | "") | |
111 | ||
112 | ;; check for next insn for branch code - does this still | |
113 | ;; work in gcc 2.* ? | |
114 | ||
115 | (define_insn "" | |
116 | [(set (cc0) | |
117 | (compare (reg:SI 0) | |
118 | (reg:SI 2))) | |
119 | (clobber (reg:SI 0))] | |
120 | "" | |
121 | "* | |
122 | { | |
123 | rtx br_insn = NEXT_INSN (insn); | |
124 | RTX_CODE br_code; | |
125 | ||
d35d9223 | 126 | gcc_assert (GET_CODE (br_insn) == JUMP_INSN); |
2c9c2489 RK |
127 | br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0)); |
128 | ||
129 | switch(br_code) | |
130 | { | |
131 | case GEU: | |
132 | case LTU: | |
133 | case GTU: | |
134 | case LEU: | |
135 | ||
136 | return \"jsr pc, ___ucmpsi\;cmp $1,r0\"; | |
137 | ||
138 | case GE: | |
139 | case LT: | |
140 | case GT: | |
141 | case LE: | |
142 | case EQ: | |
143 | case NE: | |
144 | ||
145 | return \"jsr pc, ___cmpsi\;tst r0\"; | |
146 | ||
147 | default: | |
148 | ||
d35d9223 | 149 | gcc_unreachable (); |
2c9c2489 RK |
150 | } |
151 | }" | |
152 | [(set_attr "length" "4")]) | |
153 | ||
154 | ||
155 | (define_insn "cmphi" | |
156 | [(set (cc0) | |
157 | (compare (match_operand:HI 0 "general_operand" "rR,rR,Qi,Qi") | |
158 | (match_operand:HI 1 "general_operand" "rR,Qi,rR,Qi")))] | |
159 | "" | |
160 | "cmp %0,%1" | |
161 | [(set_attr "length" "1,2,2,3")]) | |
162 | ||
163 | (define_insn "cmpqi" | |
164 | [(set (cc0) | |
165 | (compare (match_operand:QI 0 "general_operand" "rR,rR,Qi,Qi") | |
166 | (match_operand:QI 1 "general_operand" "rR,Qi,rR,Qi")))] | |
167 | "" | |
168 | "cmpb %0,%1" | |
169 | [(set_attr "length" "1,2,2,3")]) | |
170 | ||
171 | ||
172 | ;; We have to have this because cse can optimize the previous pattern | |
173 | ;; into this one. | |
174 | ||
175 | (define_insn "tstdf" | |
176 | [(set (cc0) | |
177 | (match_operand:DF 0 "general_operand" "fR,Q"))] | |
178 | "TARGET_FPU" | |
179 | "* | |
180 | { | |
181 | cc_status.flags = CC_IN_FPU; | |
af36a4d2 | 182 | return \"{tstd|tstf} %0\;cfcc\"; |
2c9c2489 RK |
183 | }" |
184 | [(set_attr "length" "2,3")]) | |
185 | ||
186 | ||
187 | (define_expand "tstsi" | |
188 | [(set (reg:SI 0) | |
189 | (match_operand:SI 0 "general_operand" "g")) | |
190 | (parallel [(set (cc0) | |
191 | (reg:SI 0)) | |
192 | (clobber (reg:SI 0))])] | |
193 | "0" ;; disable for test | |
194 | "") | |
195 | ||
196 | (define_insn "" | |
197 | [(set (cc0) | |
198 | (reg:SI 0)) | |
199 | (clobber (reg:SI 0))] | |
200 | "" | |
201 | "jsr pc, ___tstsi\;tst r0" | |
202 | [(set_attr "length" "3")]) | |
203 | ||
204 | ||
205 | (define_insn "tsthi" | |
206 | [(set (cc0) | |
207 | (match_operand:HI 0 "general_operand" "rR,Q"))] | |
208 | "" | |
209 | "tst %0" | |
210 | [(set_attr "length" "1,2")]) | |
211 | ||
212 | (define_insn "tstqi" | |
213 | [(set (cc0) | |
214 | (match_operand:QI 0 "general_operand" "rR,Q"))] | |
215 | "" | |
216 | "tstb %0" | |
217 | [(set_attr "length" "1,2")]) | |
218 | ||
219 | ;; sob instruction - we need an assembler which can make this instruction | |
220 | ;; valid under _all_ circumstances! | |
221 | ||
222 | (define_insn "" | |
223 | [(set (pc) | |
224 | (if_then_else | |
997718c7 | 225 | (ne (plus:HI (match_operand:HI 0 "register_operand" "+r") |
2c9c2489 RK |
226 | (const_int -1)) |
227 | (const_int 0)) | |
228 | (label_ref (match_operand 1 "" "")) | |
229 | (pc))) | |
230 | (set (match_dup 0) | |
231 | (plus:HI (match_dup 0) | |
232 | (const_int -1)))] | |
233 | "TARGET_40_PLUS" | |
234 | "* | |
235 | { | |
236 | static int labelcount = 0; | |
237 | static char buf[1000]; | |
238 | ||
239 | if (get_attr_length (insn) == 1) | |
240 | return \"sob %0, %l1\"; | |
241 | ||
242 | /* emulate sob */ | |
243 | output_asm_insn (\"dec %0\", operands); | |
244 | ||
245 | sprintf (buf, \"bge LONG_SOB%d\", labelcount); | |
246 | output_asm_insn (buf, NULL); | |
247 | ||
248 | output_asm_insn (\"jmp %l1\", operands); | |
249 | ||
250 | sprintf (buf, \"LONG_SOB%d:\", labelcount++); | |
251 | output_asm_insn (buf, NULL); | |
252 | ||
253 | return \"\"; | |
254 | }" | |
255 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
256 | (pc)) | |
257 | (const_int -256)) | |
258 | (ge (minus (match_dup 0) | |
259 | (pc)) | |
260 | (const_int 0))) | |
261 | (const_int 4) | |
262 | (const_int 1)))]) | |
263 | ||
264 | ;; These control RTL generation for conditional jump insns | |
265 | ;; and match them for register allocation. | |
266 | ||
267 | ;; problem with too short jump distance! we need an assembler which can | |
43b55a67 | 268 | ;; make this valid for all jump distances! |
2c9c2489 RK |
269 | ;; e.g. gas! |
270 | ||
271 | ;; these must be changed to check for CC_IN_FCCR if float is to be | |
272 | ;; enabled | |
273 | ||
274 | (define_insn "beq" | |
275 | [(set (pc) | |
276 | (if_then_else (eq (cc0) | |
277 | (const_int 0)) | |
278 | (label_ref (match_operand 0 "" "")) | |
279 | (pc)))] | |
280 | "" | |
281 | "* return output_jump(\"beq\", \"bne\", get_attr_length(insn));" | |
282 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
283 | (pc)) | |
284 | (const_int -128)) | |
285 | (ge (minus (match_dup 0) | |
286 | (pc)) | |
287 | (const_int 128))) | |
288 | (const_int 3) | |
289 | (const_int 1)))]) | |
290 | ||
291 | ||
292 | (define_insn "bne" | |
293 | [(set (pc) | |
294 | (if_then_else (ne (cc0) | |
295 | (const_int 0)) | |
296 | (label_ref (match_operand 0 "" "")) | |
297 | (pc)))] | |
298 | "" | |
299 | "* return output_jump(\"bne\", \"beq\", get_attr_length(insn));" | |
300 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
301 | (pc)) | |
302 | (const_int -128)) | |
303 | (ge (minus (match_dup 0) | |
304 | (pc)) | |
305 | (const_int 128))) | |
306 | (const_int 3) | |
307 | (const_int 1)))]) | |
308 | ||
309 | (define_insn "bgt" | |
310 | [(set (pc) | |
311 | (if_then_else (gt (cc0) | |
312 | (const_int 0)) | |
313 | (label_ref (match_operand 0 "" "")) | |
314 | (pc)))] | |
315 | "" | |
316 | "* return output_jump(\"bgt\", \"ble\", get_attr_length(insn));" | |
317 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
318 | (pc)) | |
319 | (const_int -128)) | |
320 | (ge (minus (match_dup 0) | |
321 | (pc)) | |
322 | (const_int 128))) | |
323 | (const_int 3) | |
324 | (const_int 1)))]) | |
325 | ||
326 | (define_insn "bgtu" | |
327 | [(set (pc) | |
328 | (if_then_else (gtu (cc0) | |
329 | (const_int 0)) | |
330 | (label_ref (match_operand 0 "" "")) | |
331 | (pc)))] | |
332 | "" | |
333 | "* return output_jump(\"bhi\", \"blos\", get_attr_length(insn));" | |
334 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
335 | (pc)) | |
336 | (const_int -128)) | |
337 | (ge (minus (match_dup 0) | |
338 | (pc)) | |
339 | (const_int 128))) | |
340 | (const_int 3) | |
341 | (const_int 1)))]) | |
342 | ||
343 | (define_insn "blt" | |
344 | [(set (pc) | |
345 | (if_then_else (lt (cc0) | |
346 | (const_int 0)) | |
347 | (label_ref (match_operand 0 "" "")) | |
348 | (pc)))] | |
349 | "" | |
350 | "* return output_jump(\"blt\", \"bge\", get_attr_length(insn));" | |
351 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
352 | (pc)) | |
353 | (const_int -128)) | |
354 | (ge (minus (match_dup 0) | |
355 | (pc)) | |
356 | (const_int 128))) | |
357 | (const_int 3) | |
358 | (const_int 1)))]) | |
359 | ||
360 | ||
361 | (define_insn "bltu" | |
362 | [(set (pc) | |
363 | (if_then_else (ltu (cc0) | |
364 | (const_int 0)) | |
365 | (label_ref (match_operand 0 "" "")) | |
366 | (pc)))] | |
367 | "" | |
480ae58f | 368 | "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));" |
2c9c2489 RK |
369 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) |
370 | (pc)) | |
371 | (const_int -128)) | |
372 | (ge (minus (match_dup 0) | |
373 | (pc)) | |
374 | (const_int 128))) | |
375 | (const_int 3) | |
376 | (const_int 1)))]) | |
377 | ||
378 | (define_insn "bge" | |
379 | [(set (pc) | |
380 | (if_then_else (ge (cc0) | |
381 | (const_int 0)) | |
382 | (label_ref (match_operand 0 "" "")) | |
383 | (pc)))] | |
384 | "" | |
385 | "* return output_jump(\"bge\", \"blt\", get_attr_length(insn));" | |
386 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
387 | (pc)) | |
388 | (const_int -128)) | |
389 | (ge (minus (match_dup 0) | |
390 | (pc)) | |
391 | (const_int 128))) | |
392 | (const_int 3) | |
393 | (const_int 1)))]) | |
394 | ||
395 | (define_insn "bgeu" | |
396 | [(set (pc) | |
397 | (if_then_else (geu (cc0) | |
398 | (const_int 0)) | |
399 | (label_ref (match_operand 0 "" "")) | |
400 | (pc)))] | |
401 | "" | |
402 | "* return output_jump(\"bhis\", \"blo\", get_attr_length(insn));" | |
403 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
404 | (pc)) | |
405 | (const_int -128)) | |
406 | (ge (minus (match_dup 0) | |
407 | (pc)) | |
408 | (const_int 128))) | |
409 | (const_int 3) | |
410 | (const_int 1)))]) | |
411 | ||
412 | (define_insn "ble" | |
413 | [(set (pc) | |
414 | (if_then_else (le (cc0) | |
415 | (const_int 0)) | |
416 | (label_ref (match_operand 0 "" "")) | |
417 | (pc)))] | |
418 | "" | |
419 | "* return output_jump(\"ble\", \"bgt\", get_attr_length(insn));" | |
420 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
421 | (pc)) | |
422 | (const_int -128)) | |
423 | (ge (minus (match_dup 0) | |
424 | (pc)) | |
425 | (const_int 128))) | |
426 | (const_int 3) | |
427 | (const_int 1)))]) | |
428 | ||
429 | (define_insn "bleu" | |
430 | [(set (pc) | |
431 | (if_then_else (leu (cc0) | |
432 | (const_int 0)) | |
433 | (label_ref (match_operand 0 "" "")) | |
434 | (pc)))] | |
435 | "" | |
436 | "* return output_jump(\"blos\", \"bhi\", get_attr_length(insn));" | |
437 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
438 | (pc)) | |
439 | (const_int -128)) | |
440 | (ge (minus (match_dup 0) | |
441 | (pc)) | |
442 | (const_int 128))) | |
443 | (const_int 3) | |
444 | (const_int 1)))]) | |
445 | ||
446 | \f | |
447 | ;; These match inverted jump insns for register allocation. | |
448 | ||
449 | (define_insn "" | |
450 | [(set (pc) | |
451 | (if_then_else (eq (cc0) | |
452 | (const_int 0)) | |
453 | (pc) | |
454 | (label_ref (match_operand 0 "" ""))))] | |
455 | "" | |
456 | "* return output_jump(\"bne\", \"beq\", get_attr_length(insn));" | |
457 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
458 | (pc)) | |
459 | (const_int -128)) | |
460 | (ge (minus (match_dup 0) | |
461 | (pc)) | |
462 | (const_int 128))) | |
463 | (const_int 3) | |
464 | (const_int 1)))]) | |
465 | ||
466 | (define_insn "" | |
467 | [(set (pc) | |
468 | (if_then_else (ne (cc0) | |
469 | (const_int 0)) | |
470 | (pc) | |
471 | (label_ref (match_operand 0 "" ""))))] | |
472 | "" | |
473 | "* return output_jump(\"beq\", \"bne\", get_attr_length(insn));" | |
474 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
475 | (pc)) | |
476 | (const_int -128)) | |
477 | (ge (minus (match_dup 0) | |
478 | (pc)) | |
479 | (const_int 128))) | |
480 | (const_int 3) | |
481 | (const_int 1)))]) | |
482 | ||
483 | (define_insn "" | |
484 | [(set (pc) | |
485 | (if_then_else (gt (cc0) | |
486 | (const_int 0)) | |
487 | (pc) | |
488 | (label_ref (match_operand 0 "" ""))))] | |
489 | "" | |
490 | "* return output_jump(\"ble\", \"bgt\", get_attr_length(insn));" | |
491 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
492 | (pc)) | |
493 | (const_int -128)) | |
494 | (ge (minus (match_dup 0) | |
495 | (pc)) | |
496 | (const_int 128))) | |
497 | (const_int 3) | |
498 | (const_int 1)))]) | |
499 | ||
500 | (define_insn "" | |
501 | [(set (pc) | |
502 | (if_then_else (gtu (cc0) | |
503 | (const_int 0)) | |
504 | (pc) | |
505 | (label_ref (match_operand 0 "" ""))))] | |
506 | "" | |
507 | "* return output_jump(\"blos\", \"bhi\", get_attr_length(insn));" | |
508 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
509 | (pc)) | |
510 | (const_int -128)) | |
511 | (ge (minus (match_dup 0) | |
512 | (pc)) | |
513 | (const_int 128))) | |
514 | (const_int 3) | |
515 | (const_int 1)))]) | |
516 | ||
517 | (define_insn "" | |
518 | [(set (pc) | |
519 | (if_then_else (lt (cc0) | |
520 | (const_int 0)) | |
521 | (pc) | |
522 | (label_ref (match_operand 0 "" ""))))] | |
523 | "" | |
524 | "* return output_jump(\"bge\", \"blt\", get_attr_length(insn));" | |
525 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
526 | (pc)) | |
527 | (const_int -128)) | |
528 | (ge (minus (match_dup 0) | |
529 | (pc)) | |
530 | (const_int 128))) | |
531 | (const_int 3) | |
532 | (const_int 1)))]) | |
533 | ||
534 | (define_insn "" | |
535 | [(set (pc) | |
536 | (if_then_else (ltu (cc0) | |
537 | (const_int 0)) | |
538 | (pc) | |
539 | (label_ref (match_operand 0 "" ""))))] | |
540 | "" | |
480ae58f | 541 | "* return output_jump(\"bhis\", \"blo\", get_attr_length(insn));" |
2c9c2489 RK |
542 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) |
543 | (pc)) | |
544 | (const_int -128)) | |
545 | (ge (minus (match_dup 0) | |
546 | (pc)) | |
547 | (const_int 128))) | |
548 | (const_int 3) | |
549 | (const_int 1)))]) | |
550 | ||
551 | (define_insn "" | |
552 | [(set (pc) | |
553 | (if_then_else (ge (cc0) | |
554 | (const_int 0)) | |
555 | (pc) | |
556 | (label_ref (match_operand 0 "" ""))))] | |
557 | "" | |
558 | "* return output_jump(\"blt\", \"bge\", get_attr_length(insn));" | |
559 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
560 | (pc)) | |
561 | (const_int -128)) | |
562 | (ge (minus (match_dup 0) | |
563 | (pc)) | |
564 | (const_int 128))) | |
565 | (const_int 3) | |
566 | (const_int 1)))]) | |
567 | ||
568 | (define_insn "" | |
569 | [(set (pc) | |
570 | (if_then_else (geu (cc0) | |
571 | (const_int 0)) | |
572 | (pc) | |
573 | (label_ref (match_operand 0 "" ""))))] | |
574 | "" | |
480ae58f | 575 | "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));" |
2c9c2489 RK |
576 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) |
577 | (pc)) | |
578 | (const_int -128)) | |
579 | (ge (minus (match_dup 0) | |
580 | (pc)) | |
581 | (const_int 128))) | |
582 | (const_int 3) | |
583 | (const_int 1)))]) | |
584 | ||
585 | (define_insn "" | |
586 | [(set (pc) | |
587 | (if_then_else (le (cc0) | |
588 | (const_int 0)) | |
589 | (pc) | |
590 | (label_ref (match_operand 0 "" ""))))] | |
591 | "" | |
592 | "* return output_jump(\"bgt\", \"ble\", get_attr_length(insn));" | |
593 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
594 | (pc)) | |
595 | (const_int -128)) | |
596 | (ge (minus (match_dup 0) | |
597 | (pc)) | |
598 | (const_int 128))) | |
599 | (const_int 3) | |
600 | (const_int 1)))]) | |
601 | ||
602 | (define_insn "" | |
603 | [(set (pc) | |
604 | (if_then_else (leu (cc0) | |
605 | (const_int 0)) | |
606 | (pc) | |
607 | (label_ref (match_operand 0 "" ""))))] | |
608 | "" | |
609 | "* return output_jump(\"bhi\", \"blos\", get_attr_length(insn));" | |
610 | [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) | |
611 | (pc)) | |
612 | (const_int -128)) | |
613 | (ge (minus (match_dup 0) | |
614 | (pc)) | |
615 | (const_int 128))) | |
616 | (const_int 3) | |
617 | (const_int 1)))]) | |
618 | \f | |
619 | ;; Move instructions | |
620 | ||
621 | (define_insn "movdi" | |
cf860dc2 | 622 | [(set (match_operand:DI 0 "general_operand" "=g,rm,o") |
e7f9979a | 623 | (match_operand:DI 1 "general_operand" "m,r,a"))] |
2c9c2489 RK |
624 | "" |
625 | "* return output_move_quad (operands);" | |
626 | ;; what's the mose expensive code - say twice movsi = 16 | |
e7f9979a | 627 | [(set_attr "length" "16,16,16")]) |
2c9c2489 RK |
628 | |
629 | (define_insn "movsi" | |
630 | [(set (match_operand:SI 0 "general_operand" "=r,r,r,rm,m") | |
631 | (match_operand:SI 1 "general_operand" "rN,IJ,K,m,r"))] | |
632 | "" | |
633 | "* return output_move_double (operands);" | |
634 | ;; what's the most expensive code ? - I think 8! | |
635 | ;; we could split it up and make several sub-cases... | |
636 | [(set_attr "length" "2,3,4,8,8")]) | |
637 | ||
638 | (define_insn "movhi" | |
639 | [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") | |
640 | (match_operand:HI 1 "general_operand" "rRN,Qi,rRN,Qi"))] | |
641 | "" | |
642 | "* | |
643 | { | |
644 | if (operands[1] == const0_rtx) | |
645 | return \"clr %0\"; | |
646 | ||
647 | return \"mov %1, %0\"; | |
648 | }" | |
649 | [(set_attr "length" "1,2,2,3")]) | |
650 | ||
651 | (define_insn "movqi" | |
e7f9979a NS |
652 | [(set (match_operand:QI 0 "nonimmediate_operand" "=g") |
653 | (match_operand:QI 1 "general_operand" "g"))] | |
2c9c2489 RK |
654 | "" |
655 | "* | |
656 | { | |
657 | if (operands[1] == const0_rtx) | |
658 | return \"clrb %0\"; | |
659 | ||
660 | return \"movb %1, %0\"; | |
661 | }" | |
e7f9979a | 662 | [(set_attr "length" "1")]) |
2c9c2489 RK |
663 | |
664 | ;; do we have to supply all these moves? e.g. to | |
665 | ;; NO_LOAD_FPU_REGs ? | |
666 | (define_insn "movdf" | |
e7f9979a NS |
667 | [(set (match_operand:DF 0 "general_operand" "=a,fR,a,Q,m") |
668 | (match_operand:DF 1 "general_operand" "fFR,a,Q,a,m"))] | |
2c9c2489 | 669 | "" |
e7f9979a NS |
670 | "* if (which_alternative ==0) |
671 | return \"ldd %1, %0\"; | |
672 | else if (which_alternative == 1) | |
673 | return \"std %1, %0\"; | |
674 | else | |
675 | return output_move_quad (operands); " | |
2c9c2489 | 676 | ;; just a guess.. |
e7f9979a | 677 | [(set_attr "length" "1,1,5,5,16")]) |
2c9c2489 RK |
678 | |
679 | (define_insn "movsf" | |
680 | [(set (match_operand:SF 0 "general_operand" "=g,r,g") | |
681 | (match_operand:SF 1 "general_operand" "r,rmF,g"))] | |
682 | "TARGET_FPU" | |
683 | "* return output_move_double (operands);" | |
684 | [(set_attr "length" "8,8,8")]) | |
685 | ||
686 | ;; maybe fiddle a bit with move_ratio, then | |
ddd5a7c1 | 687 | ;; let constraints only accept a register ... |
2c9c2489 | 688 | |
70128ad9 | 689 | (define_expand "movmemhi" |
3a598fbe JL |
690 | [(parallel [(set (match_operand:BLK 0 "general_operand" "=g,g") |
691 | (match_operand:BLK 1 "general_operand" "g,g")) | |
2c9c2489 RK |
692 | (use (match_operand:HI 2 "arith_operand" "n,&mr")) |
693 | (use (match_operand:HI 3 "immediate_operand" "i,i")) | |
694 | (clobber (match_scratch:HI 4 "=&r,X")) | |
3a598fbe JL |
695 | (clobber (match_dup 5)) |
696 | (clobber (match_dup 6)) | |
2c9c2489 RK |
697 | (clobber (match_dup 2))])] |
698 | "(TARGET_BCOPY_BUILTIN)" | |
699 | " | |
700 | { | |
3a598fbe | 701 | operands[0] |
792760b9 RK |
702 | = replace_equiv_address (operands[0], |
703 | copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); | |
3a598fbe | 704 | operands[1] |
792760b9 RK |
705 | = replace_equiv_address (operands[1], |
706 | copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); | |
3a598fbe JL |
707 | |
708 | operands[5] = XEXP (operands[0], 0); | |
709 | operands[6] = XEXP (operands[1], 0); | |
2c9c2489 RK |
710 | }") |
711 | ||
712 | ||
70128ad9 | 713 | (define_insn "" ; "movmemhi" |
2c9c2489 RK |
714 | [(set (mem:BLK (match_operand:HI 0 "general_operand" "=r,r")) |
715 | (mem:BLK (match_operand:HI 1 "general_operand" "r,r"))) | |
716 | (use (match_operand:HI 2 "arith_operand" "n,&r")) | |
717 | (use (match_operand:HI 3 "immediate_operand" "i,i")) | |
718 | (clobber (match_scratch:HI 4 "=&r,X")) | |
719 | (clobber (match_dup 0)) | |
720 | (clobber (match_dup 1)) | |
721 | (clobber (match_dup 2))] | |
722 | "(TARGET_BCOPY_BUILTIN)" | |
723 | "* return output_block_move (operands);" | |
724 | ;;; just a guess | |
725 | [(set_attr "length" "40")]) | |
726 | ||
727 | ||
728 | \f | |
729 | ;;- truncation instructions | |
730 | ||
731 | (define_insn "truncdfsf2" | |
e3be1b32 RK |
732 | [(set (match_operand:SF 0 "general_operand" "=r,R,Q") |
733 | (float_truncate:SF (match_operand:DF 1 "register_operand" "a,a,a")))] | |
2c9c2489 | 734 | "TARGET_FPU" |
e3be1b32 RK |
735 | "* if (which_alternative ==0) |
736 | { | |
af36a4d2 | 737 | output_asm_insn(\"{stcdf|movfo} %1, -(sp)\", operands); |
e3be1b32 | 738 | output_asm_insn(\"mov (sp)+, %0\", operands); |
c5c76735 | 739 | operands[0] = gen_rtx_REG (HImode, REGNO (operands[0])+1); |
e3be1b32 RK |
740 | output_asm_insn(\"mov (sp)+, %0\", operands); |
741 | return \"\"; | |
742 | } | |
743 | else if (which_alternative == 1) | |
af36a4d2 | 744 | return \"{stcdf|movfo} %1, %0\"; |
e3be1b32 | 745 | else |
af36a4d2 | 746 | return \"{stcdf|movfo} %1, %0\"; |
e3be1b32 RK |
747 | " |
748 | [(set_attr "length" "3,1,2")]) | |
749 | ||
2c9c2489 RK |
750 | |
751 | (define_expand "truncsihi2" | |
752 | [(set (match_operand:HI 0 "general_operand" "=g") | |
753 | (subreg:HI | |
754 | (match_operand:SI 1 "general_operand" "or") | |
755 | 0))] | |
756 | "" | |
757 | "") | |
758 | ||
759 | \f | |
760 | ;;- zero extension instructions | |
761 | ||
762 | (define_insn "zero_extendqihi2" | |
763 | [(set (match_operand:HI 0 "general_operand" "=r") | |
764 | (zero_extend:HI (match_operand:QI 1 "general_operand" "0")))] | |
765 | "" | |
e7f9979a | 766 | "bic $0177400, %0" |
2c9c2489 RK |
767 | [(set_attr "length" "2")]) |
768 | ||
769 | (define_expand "zero_extendhisi2" | |
770 | [(set (subreg:HI | |
771 | (match_dup 0) | |
ddef6bc7 | 772 | 2) |
2c9c2489 RK |
773 | (match_operand:HI 1 "register_operand" "r")) |
774 | (set (subreg:HI | |
775 | (match_operand:SI 0 "register_operand" "=r") | |
776 | 0) | |
777 | (const_int 0))] | |
778 | "" | |
779 | "/* operands[1] = make_safe_from (operands[1], operands[0]); */") | |
780 | ||
781 | \f | |
782 | ;;- sign extension instructions | |
783 | ||
784 | (define_insn "extendsfdf2" | |
e3be1b32 | 785 | [(set (match_operand:DF 0 "register_operand" "=a,a,a") |
a6a715ca | 786 | (float_extend:DF (match_operand:SF 1 "general_operand" "r,R,Q")))] |
2c9c2489 | 787 | "TARGET_FPU" |
e3be1b32 | 788 | "@ |
af36a4d2 JM |
789 | mov %1, -(sp)\;{ldcfd|movof} (sp)+,%0 |
790 | {ldcfd|movof} %1, %0 | |
791 | {ldcfd|movof} %1, %0" | |
e3be1b32 | 792 | [(set_attr "length" "2,1,2")]) |
2c9c2489 RK |
793 | |
794 | ;; does movb sign extend in register-to-register move? | |
795 | (define_insn "extendqihi2" | |
796 | [(set (match_operand:HI 0 "register_operand" "=r,r") | |
797 | (sign_extend:HI (match_operand:QI 1 "general_operand" "rR,Q")))] | |
798 | "" | |
799 | "movb %1, %0" | |
800 | [(set_attr "length" "1,2")]) | |
801 | ||
802 | (define_insn "extendqisi2" | |
803 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
804 | (sign_extend:SI (match_operand:QI 1 "general_operand" "rR,Q")))] | |
805 | "TARGET_40_PLUS" | |
806 | "* | |
807 | { | |
808 | rtx latehalf[2]; | |
809 | ||
810 | /* make register pair available */ | |
811 | latehalf[0] = operands[0]; | |
c5c76735 JL |
812 | operands[0] = gen_rtx_REG (HImode, REGNO (operands[0])+ 1); |
813 | ||
2c9c2489 RK |
814 | output_asm_insn(\"movb %1, %0\", operands); |
815 | output_asm_insn(\"sxt %0\", latehalf); | |
816 | ||
817 | return \"\"; | |
818 | }" | |
819 | [(set_attr "length" "2,3")]) | |
820 | ||
821 | ;; maybe we have to use define_expand to say that we have the instruction, | |
822 | ;; unconditionally, and then match dependent on CPU type: | |
823 | ||
824 | (define_expand "extendhisi2" | |
825 | [(set (match_operand:SI 0 "general_operand" "=g") | |
826 | (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))] | |
827 | "" | |
828 | "") | |
829 | ||
830 | (define_insn "" ; "extendhisi2" | |
831 | [(set (match_operand:SI 0 "general_operand" "=o,<,r") | |
832 | (sign_extend:SI (match_operand:HI 1 "general_operand" "g,g,g")))] | |
833 | "TARGET_40_PLUS" | |
834 | "* | |
835 | { | |
836 | rtx latehalf[2]; | |
837 | ||
838 | /* we don't want to mess with auto increment */ | |
839 | ||
b72f00af | 840 | switch (which_alternative) |
2c9c2489 RK |
841 | { |
842 | case 0: | |
843 | ||
844 | latehalf[0] = operands[0]; | |
b72f00af | 845 | operands[0] = adjust_address(operands[0], HImode, 2); |
2c9c2489 RK |
846 | |
847 | output_asm_insn(\"mov %1, %0\", operands); | |
848 | output_asm_insn(\"sxt %0\", latehalf); | |
849 | ||
850 | return \"\"; | |
851 | ||
852 | case 1: | |
853 | ||
854 | /* - auto-decrement - right direction ;-) */ | |
855 | output_asm_insn(\"mov %1, %0\", operands); | |
856 | output_asm_insn(\"sxt %0\", operands); | |
857 | ||
858 | return \"\"; | |
859 | ||
860 | case 2: | |
861 | ||
862 | /* make register pair available */ | |
863 | latehalf[0] = operands[0]; | |
c5c76735 | 864 | operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); |
2c9c2489 RK |
865 | |
866 | output_asm_insn(\"mov %1, %0\", operands); | |
867 | output_asm_insn(\"sxt %0\", latehalf); | |
868 | ||
869 | return \"\"; | |
870 | ||
871 | default: | |
872 | ||
d35d9223 | 873 | gcc_unreachable (); |
2c9c2489 RK |
874 | } |
875 | }" | |
876 | [(set_attr "length" "5,3,3")]) | |
877 | ||
878 | ||
879 | (define_insn "" | |
880 | [(set (match_operand:SI 0 "register_operand" "=r") | |
881 | (sign_extend:SI (match_operand:HI 1 "general_operand" "0")))] | |
882 | "(! TARGET_40_PLUS)" | |
883 | "* | |
884 | { | |
09b893bb | 885 | static int count = 0; |
2c9c2489 RK |
886 | char buf[100]; |
887 | rtx lateoperands[2]; | |
888 | ||
889 | lateoperands[0] = operands[0]; | |
c5c76735 | 890 | operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); |
2c9c2489 RK |
891 | |
892 | output_asm_insn(\"tst %0\", operands); | |
893 | sprintf(buf, \"bge extendhisi%d\", count); | |
894 | output_asm_insn(buf, NULL); | |
895 | output_asm_insn(\"mov -1, %0\", lateoperands); | |
896 | sprintf(buf, \"bne extendhisi%d\", count+1); | |
897 | output_asm_insn(buf, NULL); | |
898 | sprintf(buf, \"\\nextendhisi%d:\", count); | |
899 | output_asm_insn(buf, NULL); | |
900 | output_asm_insn(\"clr %0\", lateoperands); | |
901 | sprintf(buf, \"\\nextendhisi%d:\", count+1); | |
902 | output_asm_insn(buf, NULL); | |
903 | ||
904 | count += 2; | |
905 | ||
906 | return \"\"; | |
907 | }" | |
908 | [(set_attr "length" "6")]) | |
909 | ||
910 | ;; make float to int and vice versa | |
ddd5a7c1 | 911 | ;; using the cc_status.flag field we could probably cut down |
2c9c2489 RK |
912 | ;; on seti and setl |
913 | ;; assume that we are normally in double and integer mode - | |
914 | ;; what do pdp library routines do to fpu mode ? | |
915 | ||
916 | (define_insn "floatsidf2" | |
e3be1b32 RK |
917 | [(set (match_operand:DF 0 "register_operand" "=a,a,a") |
918 | (float:DF (match_operand:SI 1 "general_operand" "r,R,Q")))] | |
2c9c2489 | 919 | "TARGET_FPU" |
e3be1b32 RK |
920 | "* if (which_alternative ==0) |
921 | { | |
922 | rtx latehalf[2]; | |
923 | ||
924 | latehalf[0] = NULL; | |
e7f9979a | 925 | latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1); |
e3be1b32 RK |
926 | output_asm_insn(\"mov %1, -(sp)\", latehalf); |
927 | output_asm_insn(\"mov %1, -(sp)\", operands); | |
928 | ||
929 | output_asm_insn(\"setl\", operands); | |
af36a4d2 | 930 | output_asm_insn(\"{ldcld|movif} (sp)+, %0\", operands); |
e3be1b32 RK |
931 | output_asm_insn(\"seti\", operands); |
932 | return \"\"; | |
933 | } | |
934 | else if (which_alternative == 1) | |
af36a4d2 | 935 | return \"setl\;{ldcld|movif} %1, %0\;seti\"; |
e3be1b32 | 936 | else |
af36a4d2 | 937 | return \"setl\;{ldcld|movif} %1, %0\;seti\"; |
e3be1b32 RK |
938 | " |
939 | [(set_attr "length" "5,3,4")]) | |
2c9c2489 RK |
940 | |
941 | (define_insn "floathidf2" | |
942 | [(set (match_operand:DF 0 "register_operand" "=a,a") | |
943 | (float:DF (match_operand:HI 1 "general_operand" "rR,Qi")))] | |
944 | "TARGET_FPU" | |
af36a4d2 | 945 | "{ldcid|movif} %1, %0" |
2c9c2489 RK |
946 | [(set_attr "length" "1,2")]) |
947 | ||
948 | ;; cut float to int | |
949 | (define_insn "fix_truncdfsi2" | |
e3be1b32 RK |
950 | [(set (match_operand:SI 0 "general_operand" "=r,R,Q") |
951 | (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a,a"))))] | |
2c9c2489 | 952 | "TARGET_FPU" |
e3be1b32 RK |
953 | "* if (which_alternative ==0) |
954 | { | |
955 | output_asm_insn(\"setl\", operands); | |
af36a4d2 | 956 | output_asm_insn(\"{stcdl|movfi} %1, -(sp)\", operands); |
e3be1b32 RK |
957 | output_asm_insn(\"seti\", operands); |
958 | output_asm_insn(\"mov (sp)+, %0\", operands); | |
c5c76735 | 959 | operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); |
e3be1b32 RK |
960 | output_asm_insn(\"mov (sp)+, %0\", operands); |
961 | return \"\"; | |
962 | } | |
963 | else if (which_alternative == 1) | |
af36a4d2 | 964 | return \"setl\;{stcdl|movfi} %1, %0\;seti\"; |
e3be1b32 | 965 | else |
af36a4d2 | 966 | return \"setl\;{stcdl|movfi} %1, %0\;seti\"; |
e3be1b32 RK |
967 | " |
968 | [(set_attr "length" "5,3,4")]) | |
2c9c2489 RK |
969 | |
970 | (define_insn "fix_truncdfhi2" | |
971 | [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
972 | (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))] | |
973 | "TARGET_FPU" | |
af36a4d2 | 974 | "{stcdi|movfi} %1, %0" |
2c9c2489 RK |
975 | [(set_attr "length" "1,2")]) |
976 | ||
977 | \f | |
978 | ;;- arithmetic instructions | |
979 | ;;- add instructions | |
980 | ||
981 | (define_insn "adddf3" | |
982 | [(set (match_operand:DF 0 "register_operand" "=a,a,a") | |
983 | (plus:DF (match_operand:DF 1 "register_operand" "%0,0,0") | |
984 | (match_operand:DF 2 "general_operand" "fR,Q,F")))] | |
985 | "TARGET_FPU" | |
af36a4d2 | 986 | "{addd|addf} %2, %0" |
2c9c2489 RK |
987 | [(set_attr "length" "1,2,5")]) |
988 | ||
989 | (define_insn "addsi3" | |
990 | [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o") | |
991 | (plus:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0") | |
992 | (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))] | |
993 | "" | |
994 | "* | |
995 | { /* Here we trust that operands don't overlap | |
996 | ||
997 | or is lateoperands the low word?? - looks like it! */ | |
998 | ||
2c9c2489 RK |
999 | rtx lateoperands[3]; |
1000 | ||
1001 | lateoperands[0] = operands[0]; | |
1002 | ||
1003 | if (REG_P (operands[0])) | |
c5c76735 | 1004 | operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); |
2c9c2489 | 1005 | else |
b72f00af | 1006 | operands[0] = adjust_address (operands[0], HImode, 2); |
2c9c2489 RK |
1007 | |
1008 | if (! CONSTANT_P(operands[2])) | |
1009 | { | |
1010 | lateoperands[2] = operands[2]; | |
1011 | ||
1012 | if (REG_P (operands[2])) | |
c5c76735 | 1013 | operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1); |
2c9c2489 | 1014 | else |
b72f00af | 1015 | operands[2] = adjust_address (operands[2], HImode, 2); |
2c9c2489 RK |
1016 | |
1017 | output_asm_insn (\"add %2, %0\", operands); | |
1018 | output_asm_insn (\"adc %0\", lateoperands); | |
1019 | output_asm_insn (\"add %2, %0\", lateoperands); | |
1020 | return \"\"; | |
1021 | } | |
1022 | ||
b0106b24 | 1023 | lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff); |
c5c76735 | 1024 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff); |
2c9c2489 RK |
1025 | |
1026 | if (INTVAL(operands[2])) | |
1027 | { | |
1028 | output_asm_insn (\"add %2, %0\", operands); | |
1029 | output_asm_insn (\"adc %0\", lateoperands); | |
1030 | } | |
1031 | ||
1032 | if (INTVAL(lateoperands[2])) | |
1033 | output_asm_insn (\"add %2, %0\", lateoperands); | |
1034 | ||
1035 | return \"\"; | |
1036 | }" | |
1037 | [(set_attr "length" "3,5,6,8,3,1,5,5,3,8")]) | |
1038 | ||
1039 | (define_insn "addhi3" | |
1040 | [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") | |
1041 | (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0") | |
1042 | (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))] | |
1043 | "" | |
1044 | "* | |
1045 | { | |
1046 | if (GET_CODE (operands[2]) == CONST_INT) | |
09b893bb JM |
1047 | { |
1048 | if (INTVAL(operands[2]) == 1) | |
1049 | return \"inc %0\"; | |
1050 | else if (INTVAL(operands[2]) == -1) | |
1051 | return \"dec %0\"; | |
1052 | } | |
2c9c2489 RK |
1053 | |
1054 | return \"add %2, %0\"; | |
1055 | }" | |
1056 | [(set_attr "length" "1,2,2,3")]) | |
1057 | ||
1058 | (define_insn "addqi3" | |
1059 | [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") | |
1060 | (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0") | |
1061 | (match_operand:QI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))] | |
1062 | "" | |
1063 | "* | |
1064 | { | |
1065 | if (GET_CODE (operands[2]) == CONST_INT) | |
09b893bb JM |
1066 | { |
1067 | if (INTVAL(operands[2]) == 1) | |
1068 | return \"incb %0\"; | |
1069 | else if (INTVAL(operands[2]) == -1) | |
1070 | return \"decb %0\"; | |
1071 | } | |
2c9c2489 | 1072 | |
e7f9979a | 1073 | return \"add %2, %0\"; |
2c9c2489 RK |
1074 | }" |
1075 | [(set_attr "length" "1,2,2,3")]) | |
1076 | ||
1077 | \f | |
1078 | ;;- subtract instructions | |
1079 | ;; we don't have to care for constant second | |
ddd5a7c1 | 1080 | ;; args, since they are canonical plus:xx now! |
2c9c2489 RK |
1081 | ;; also for minus:DF ?? |
1082 | ||
1083 | (define_insn "subdf3" | |
1084 | [(set (match_operand:DF 0 "register_operand" "=a,a") | |
1085 | (minus:DF (match_operand:DF 1 "register_operand" "0,0") | |
1086 | (match_operand:DF 2 "general_operand" "fR,Q")))] | |
1087 | "TARGET_FPU" | |
af36a4d2 | 1088 | "{subd|subf} %2, %0" |
2c9c2489 RK |
1089 | [(set_attr "length" "1,2")]) |
1090 | ||
1091 | (define_insn "subsi3" | |
1092 | [(set (match_operand:SI 0 "general_operand" "=r,r,o,o") | |
1093 | (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0") | |
1094 | (match_operand:SI 2 "general_operand" "r,o,r,o")))] | |
1095 | "" | |
1096 | "* | |
1097 | { /* Here we trust that operands don't overlap | |
1098 | ||
1099 | or is lateoperands the low word?? - looks like it! */ | |
1100 | ||
2c9c2489 RK |
1101 | rtx lateoperands[3]; |
1102 | ||
1103 | lateoperands[0] = operands[0]; | |
1104 | ||
1105 | if (REG_P (operands[0])) | |
c5c76735 | 1106 | operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); |
2c9c2489 | 1107 | else |
b72f00af | 1108 | operands[0] = adjust_address (operands[0], HImode, 2); |
2c9c2489 RK |
1109 | |
1110 | lateoperands[2] = operands[2]; | |
1111 | ||
1112 | if (REG_P (operands[2])) | |
c5c76735 | 1113 | operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1); |
2c9c2489 | 1114 | else |
b72f00af | 1115 | operands[2] = adjust_address (operands[2], HImode, 2); |
2c9c2489 RK |
1116 | |
1117 | output_asm_insn (\"sub %2, %0\", operands); | |
1118 | output_asm_insn (\"sbc %0\", lateoperands); | |
1119 | output_asm_insn (\"sub %2, %0\", lateoperands); | |
1120 | return \"\"; | |
1121 | }" | |
ddd5a7c1 | 1122 | ;; offsettable memory addresses always are expensive!!! |
2c9c2489 RK |
1123 | [(set_attr "length" "3,5,6,8")]) |
1124 | ||
1125 | (define_insn "subhi3" | |
1126 | [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") | |
1127 | (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0") | |
1128 | (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))] | |
1129 | "" | |
1130 | "* | |
1131 | { | |
d35d9223 | 1132 | gcc_assert (GET_CODE (operands[2]) != CONST_INT); |
2c9c2489 RK |
1133 | |
1134 | return \"sub %2, %0\"; | |
1135 | }" | |
1136 | [(set_attr "length" "1,2,2,3")]) | |
1137 | ||
1138 | (define_insn "subqi3" | |
1139 | [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") | |
1140 | (minus:QI (match_operand:QI 1 "general_operand" "0,0,0,0") | |
1141 | (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))] | |
1142 | "" | |
1143 | "* | |
1144 | { | |
d35d9223 | 1145 | gcc_assert (GET_CODE (operands[2]) != CONST_INT); |
2c9c2489 | 1146 | |
e7f9979a | 1147 | return \"sub %2, %0\"; |
2c9c2489 RK |
1148 | }" |
1149 | [(set_attr "length" "1,2,2,3")]) | |
1150 | ||
1151 | ;;;;- and instructions | |
8aeea6e6 | 1152 | ;; Bit-and on the pdp (like on the VAX) is done with a clear-bits insn. |
2c9c2489 | 1153 | |
e7f9979a | 1154 | (define_insn "andsi3" |
2c9c2489 RK |
1155 | [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o") |
1156 | (and:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0") | |
1157 | (not:SI (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K"))))] | |
1158 | "" | |
1159 | "* | |
1160 | { /* Here we trust that operands don't overlap | |
1161 | ||
1162 | or is lateoperands the low word?? - looks like it! */ | |
1163 | ||
2c9c2489 RK |
1164 | rtx lateoperands[3]; |
1165 | ||
1166 | lateoperands[0] = operands[0]; | |
1167 | ||
1168 | if (REG_P (operands[0])) | |
c5c76735 | 1169 | operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); |
2c9c2489 | 1170 | else |
b72f00af | 1171 | operands[0] = adjust_address (operands[0], HImode, 2); |
2c9c2489 RK |
1172 | |
1173 | if (! CONSTANT_P(operands[2])) | |
1174 | { | |
1175 | lateoperands[2] = operands[2]; | |
1176 | ||
1177 | if (REG_P (operands[2])) | |
c5c76735 | 1178 | operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1); |
2c9c2489 | 1179 | else |
b72f00af | 1180 | operands[2] = adjust_address (operands[2], HImode, 2); |
2c9c2489 RK |
1181 | |
1182 | output_asm_insn (\"bic %2, %0\", operands); | |
1183 | output_asm_insn (\"bic %2, %0\", lateoperands); | |
1184 | return \"\"; | |
1185 | } | |
1186 | ||
c5c76735 JL |
1187 | lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff); |
1188 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff); | |
2c9c2489 RK |
1189 | |
1190 | /* these have different lengths, so we should have | |
1191 | different constraints! */ | |
1192 | if (INTVAL(operands[2])) | |
1193 | output_asm_insn (\"bic %2, %0\", operands); | |
1194 | ||
1195 | if (INTVAL(lateoperands[2])) | |
1196 | output_asm_insn (\"bic %2, %0\", lateoperands); | |
1197 | ||
1198 | return \"\"; | |
1199 | }" | |
1200 | [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")]) | |
1201 | ||
e7f9979a | 1202 | (define_insn "andhi3" |
2c9c2489 RK |
1203 | [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") |
1204 | (and:HI (match_operand:HI 1 "general_operand" "0,0,0,0") | |
1205 | (not:HI (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi"))))] | |
1206 | "" | |
1207 | "bic %2, %0" | |
1208 | [(set_attr "length" "1,2,2,3")]) | |
1209 | ||
e7f9979a | 1210 | (define_insn "andqi3" |
2c9c2489 RK |
1211 | [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") |
1212 | (and:QI (match_operand:QI 1 "general_operand" "0,0,0,0") | |
1213 | (not:QI (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi"))))] | |
1214 | "" | |
1215 | "bicb %2, %0" | |
1216 | [(set_attr "length" "1,2,2,3")]) | |
1217 | ||
1218 | ;;- Bit set (inclusive or) instructions | |
1219 | (define_insn "iorsi3" | |
1220 | [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o") | |
1221 | (ior:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0") | |
1222 | (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))] | |
1223 | "" | |
1224 | "* | |
1225 | { /* Here we trust that operands don't overlap | |
1226 | ||
1227 | or is lateoperands the low word?? - looks like it! */ | |
1228 | ||
2c9c2489 RK |
1229 | rtx lateoperands[3]; |
1230 | ||
1231 | lateoperands[0] = operands[0]; | |
1232 | ||
1233 | if (REG_P (operands[0])) | |
c5c76735 | 1234 | operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); |
2c9c2489 | 1235 | else |
b72f00af | 1236 | operands[0] = adjust_address (operands[0], HImode, 2); |
2c9c2489 RK |
1237 | |
1238 | if (! CONSTANT_P(operands[2])) | |
c5c76735 JL |
1239 | { |
1240 | lateoperands[2] = operands[2]; | |
2c9c2489 | 1241 | |
c5c76735 JL |
1242 | if (REG_P (operands[2])) |
1243 | operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1); | |
1244 | else | |
b72f00af | 1245 | operands[2] = adjust_address (operands[2], HImode, 2); |
2c9c2489 | 1246 | |
c5c76735 JL |
1247 | output_asm_insn (\"bis %2, %0\", operands); |
1248 | output_asm_insn (\"bis %2, %0\", lateoperands); | |
1249 | return \"\"; | |
1250 | } | |
2c9c2489 | 1251 | |
c5c76735 JL |
1252 | lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff); |
1253 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff); | |
2c9c2489 RK |
1254 | |
1255 | /* these have different lengths, so we should have | |
1256 | different constraints! */ | |
1257 | if (INTVAL(operands[2])) | |
1258 | output_asm_insn (\"bis %2, %0\", operands); | |
1259 | ||
1260 | if (INTVAL(lateoperands[2])) | |
1261 | output_asm_insn (\"bis %2, %0\", lateoperands); | |
1262 | ||
1263 | return \"\"; | |
1264 | }" | |
1265 | [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")]) | |
1266 | ||
1267 | (define_insn "iorhi3" | |
1268 | [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") | |
1269 | (ior:HI (match_operand:HI 1 "general_operand" "%0,0,0,0") | |
1270 | (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))] | |
1271 | "" | |
1272 | "bis %2, %0" | |
1273 | [(set_attr "length" "1,2,2,3")]) | |
1274 | ||
1275 | (define_insn "iorqi3" | |
1276 | [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q") | |
1277 | (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0") | |
1278 | (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))] | |
1279 | "" | |
1280 | "bisb %2, %0") | |
1281 | ||
1282 | ;;- xor instructions | |
1283 | (define_insn "xorsi3" | |
e7f9979a NS |
1284 | [(set (match_operand:SI 0 "register_operand" "=r") |
1285 | (xor:SI (match_operand:SI 1 "register_operand" "%0") | |
1286 | (match_operand:SI 2 "arith_operand" "r")))] | |
2c9c2489 RK |
1287 | "TARGET_40_PLUS" |
1288 | "* | |
1289 | { /* Here we trust that operands don't overlap */ | |
1290 | ||
2c9c2489 RK |
1291 | rtx lateoperands[3]; |
1292 | ||
1293 | lateoperands[0] = operands[0]; | |
c5c76735 | 1294 | operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); |
2c9c2489 RK |
1295 | |
1296 | if (REG_P(operands[2])) | |
c5c76735 JL |
1297 | { |
1298 | lateoperands[2] = operands[2]; | |
1299 | operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1); | |
2c9c2489 | 1300 | |
c5c76735 JL |
1301 | output_asm_insn (\"xor %2, %0\", operands); |
1302 | output_asm_insn (\"xor %2, %0\", lateoperands); | |
2c9c2489 | 1303 | |
c5c76735 JL |
1304 | return \"\"; |
1305 | } | |
1306 | ||
2c9c2489 | 1307 | }" |
e7f9979a | 1308 | [(set_attr "length" "2")]) |
2c9c2489 RK |
1309 | |
1310 | (define_insn "xorhi3" | |
1311 | [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
1312 | (xor:HI (match_operand:HI 1 "general_operand" "%0,0") | |
1313 | (match_operand:HI 2 "register_operand" "r,r")))] | |
1314 | "TARGET_40_PLUS" | |
1315 | "xor %2, %0" | |
1316 | [(set_attr "length" "1,2")]) | |
1317 | ||
1318 | ;;- one complement instructions | |
1319 | ||
1320 | (define_insn "one_cmplhi2" | |
1321 | [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
1322 | (not:HI (match_operand:HI 1 "general_operand" "0,0")))] | |
1323 | "" | |
1324 | "com %0" | |
1325 | [(set_attr "length" "1,2")]) | |
1326 | ||
1327 | (define_insn "one_cmplqi2" | |
e7f9979a NS |
1328 | [(set (match_operand:QI 0 "general_operand" "=rR,rR") |
1329 | (not:QI (match_operand:QI 1 "general_operand" "0,g")))] | |
2c9c2489 | 1330 | "" |
e7f9979a NS |
1331 | "@ |
1332 | comb %0 | |
1333 | movb %1, %0\; comb %0" | |
2c9c2489 RK |
1334 | [(set_attr "length" "1,2")]) |
1335 | ||
1336 | ;;- arithmetic shift instructions | |
1337 | (define_insn "ashlsi3" | |
1338 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1339 | (ashift:SI (match_operand:SI 1 "register_operand" "0,0") | |
1340 | (match_operand:HI 2 "general_operand" "rR,Qi")))] | |
1341 | "TARGET_45" | |
1342 | "ashc %2,%0" | |
1343 | [(set_attr "length" "1,2")]) | |
1344 | ||
1345 | ;; Arithmetic right shift on the pdp works by negating the shift count. | |
1346 | (define_expand "ashrsi3" | |
1347 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1348 | (ashift:SI (match_operand:SI 1 "register_operand" "0") | |
1349 | (match_operand:HI 2 "general_operand" "g")))] | |
1350 | "" | |
1351 | " | |
1352 | { | |
1353 | operands[2] = negate_rtx (HImode, operands[2]); | |
1354 | }") | |
1355 | ||
1356 | ;; define asl aslb asr asrb - ashc missing! | |
1357 | ||
1358 | ;; asl | |
1359 | (define_insn "" | |
1360 | [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
1361 | (ashift:HI (match_operand:HI 1 "general_operand" "0,0") | |
1362 | (const_int 1)))] | |
1363 | "" | |
1364 | "asl %0" | |
1365 | [(set_attr "length" "1,2")]) | |
1366 | ||
1367 | ;; and another possibility for asr is << -1 | |
1368 | ;; might cause problems since -1 can also be encoded as 65535! | |
1369 | ;; not in gcc2 ??? | |
1370 | ||
1371 | ;; asr | |
1372 | (define_insn "" | |
1373 | [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
1374 | (ashift:HI (match_operand:HI 1 "general_operand" "0,0") | |
1375 | (const_int -1)))] | |
1376 | "" | |
1377 | "asr %0" | |
1378 | [(set_attr "length" "1,2")]) | |
1379 | ||
e7f9979a NS |
1380 | ;; lsr |
1381 | (define_insn "" | |
1382 | [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
1383 | (lshiftrt:HI (match_operand:HI 1 "general_operand" "0,0") | |
1384 | (const_int 1)))] | |
1385 | "" | |
1386 | "clc\;ror %0" | |
1387 | [(set_attr "length" "1,2")]) | |
1388 | ||
1389 | (define_insn "lshrsi3" | |
1390 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1391 | (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") | |
1392 | (const_int 1)))] | |
1393 | "" | |
cf860dc2 | 1394 | { |
e7f9979a NS |
1395 | |
1396 | rtx lateoperands[2]; | |
1397 | ||
1398 | lateoperands[0] = operands[0]; | |
1399 | operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); | |
1400 | ||
1401 | lateoperands[1] = operands[1]; | |
1402 | operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1); | |
1403 | ||
1404 | output_asm_insn (\"clc\", operands); | |
1405 | output_asm_insn (\"ror %0\", lateoperands); | |
1406 | output_asm_insn (\"ror %0\", operands); | |
1407 | ||
1408 | return \"\"; | |
1409 | } | |
1410 | [(set_attr "length" "5")]) | |
1411 | ||
2c9c2489 RK |
1412 | ;; shift is by arbitrary count is expensive, |
1413 | ;; shift by one cheap - so let's do that, if | |
1414 | ;; space doesn't matter | |
1415 | (define_insn "" | |
1416 | [(set (match_operand:HI 0 "general_operand" "=r") | |
1417 | (ashift:HI (match_operand:HI 1 "general_operand" "0") | |
1418 | (match_operand:HI 2 "expand_shift_operand" "O")))] | |
f4190acc | 1419 | "! optimize_size" |
2c9c2489 RK |
1420 | "* |
1421 | { | |
1422 | register int i; | |
1423 | ||
1424 | for (i = 1; i <= abs(INTVAL(operands[2])); i++) | |
1425 | if (INTVAL(operands[2]) < 0) | |
1426 | output_asm_insn(\"asr %0\", operands); | |
1427 | else | |
1428 | output_asm_insn(\"asl %0\", operands); | |
1429 | ||
1430 | return \"\"; | |
1431 | }" | |
1432 | ;; longest is 4 | |
1433 | [(set (attr "length") (const_int 4))]) | |
1434 | ||
1435 | ;; aslb | |
1436 | (define_insn "" | |
1437 | [(set (match_operand:QI 0 "general_operand" "=r,o") | |
1438 | (ashift:QI (match_operand:QI 1 "general_operand" "0,0") | |
1439 | (match_operand:HI 2 "const_immediate_operand" "n,n")))] | |
1440 | "" | |
1441 | "* | |
1442 | { /* allowing predec or post_inc is possible, but hairy! */ | |
1443 | int i, cnt; | |
1444 | ||
1445 | cnt = INTVAL(operands[2]) & 0x0007; | |
1446 | ||
1447 | for (i=0 ; i < cnt ; i++) | |
1448 | output_asm_insn(\"aslb %0\", operands); | |
1449 | ||
1450 | return \"\"; | |
1451 | }" | |
1452 | ;; set attribute length ( match_dup 2 & 7 ) *(1 or 2) !!! | |
1453 | [(set_attr_alternative "length" | |
1454 | [(const_int 7) | |
1455 | (const_int 14)])]) | |
1456 | ||
1457 | ;;; asr | |
1458 | ;(define_insn "" | |
1459 | ; [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
1460 | ; (ashiftrt:HI (match_operand:HI 1 "general_operand" "0,0") | |
1461 | ; (const_int 1)))] | |
1462 | ; "" | |
1463 | ; "asr %0" | |
1464 | ; [(set_attr "length" "1,2")]) | |
1465 | ||
1466 | ;; asrb | |
1467 | (define_insn "" | |
1468 | [(set (match_operand:QI 0 "general_operand" "=r,o") | |
1469 | (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0") | |
1470 | (match_operand:HI 2 "const_immediate_operand" "n,n")))] | |
1471 | "" | |
1472 | "* | |
1473 | { /* allowing predec or post_inc is possible, but hairy! */ | |
1474 | int i, cnt; | |
1475 | ||
1476 | cnt = INTVAL(operands[2]) & 0x0007; | |
1477 | ||
1478 | for (i=0 ; i < cnt ; i++) | |
1479 | output_asm_insn(\"asrb %0\", operands); | |
1480 | ||
1481 | return \"\"; | |
1482 | }" | |
1483 | [(set_attr_alternative "length" | |
1484 | [(const_int 7) | |
1485 | (const_int 14)])]) | |
1486 | ||
43b55a67 | 1487 | ;; the following is invalid - too complex!!! - just say 14 !!! |
2c9c2489 RK |
1488 | ; [(set (attr "length") (plus (and (match_dup 2) |
1489 | ; (const_int 7)) | |
1490 | ; (and (match_dup 2) | |
1491 | ; (const_int 7))))]) | |
1492 | ||
1493 | ||
1494 | ||
1495 | ;; can we get +-1 in the next pattern? should | |
1496 | ;; have been caught by previous patterns! | |
1497 | ||
1498 | (define_insn "ashlhi3" | |
1499 | [(set (match_operand:HI 0 "register_operand" "=r,r") | |
1500 | (ashift:HI (match_operand:HI 1 "register_operand" "0,0") | |
1501 | (match_operand:HI 2 "general_operand" "rR,Qi")))] | |
1502 | "" | |
1503 | "* | |
1504 | { | |
1505 | if (GET_CODE(operands[2]) == CONST_INT) | |
09b893bb JM |
1506 | { |
1507 | if (INTVAL(operands[2]) == 1) | |
1508 | return \"asl %0\"; | |
1509 | else if (INTVAL(operands[2]) == -1) | |
1510 | return \"asr %0\"; | |
1511 | } | |
2c9c2489 RK |
1512 | |
1513 | return \"ash %2,%0\"; | |
1514 | }" | |
1515 | [(set_attr "length" "1,2")]) | |
1516 | ||
1517 | ;; Arithmetic right shift on the pdp works by negating the shift count. | |
1518 | (define_expand "ashrhi3" | |
1519 | [(set (match_operand:HI 0 "register_operand" "=r") | |
1520 | (ashift:HI (match_operand:HI 1 "register_operand" "0") | |
1521 | (match_operand:HI 2 "general_operand" "g")))] | |
1522 | "" | |
1523 | " | |
1524 | { | |
1525 | operands[2] = negate_rtx (HImode, operands[2]); | |
1526 | }") | |
1527 | ||
1528 | ;;;;- logical shift instructions | |
1529 | ;;(define_insn "lshrsi3" | |
1530 | ;; [(set (match_operand:HI 0 "register_operand" "=r") | |
1531 | ;; (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") | |
1532 | ;; (match_operand:HI 2 "arith_operand" "rI")))] | |
1533 | ;; "" | |
1534 | ;; "srl %0,%2") | |
1535 | ||
1536 | ;; absolute | |
1537 | ||
1538 | (define_insn "absdf2" | |
1539 | [(set (match_operand:DF 0 "general_operand" "=fR,Q") | |
1540 | (abs:DF (match_operand:DF 1 "general_operand" "0,0")))] | |
1541 | "TARGET_FPU" | |
af36a4d2 | 1542 | "{absd|absf} %0" |
2c9c2489 RK |
1543 | [(set_attr "length" "1,2")]) |
1544 | ||
1545 | (define_insn "abshi2" | |
1546 | [(set (match_operand:HI 0 "general_operand" "=r,o") | |
1547 | (abs:HI (match_operand:HI 1 "general_operand" "0,0")))] | |
1548 | "TARGET_ABSHI_BUILTIN" | |
1549 | "* | |
1550 | { | |
09b893bb | 1551 | static int count = 0; |
2c9c2489 RK |
1552 | char buf[200]; |
1553 | ||
1554 | output_asm_insn(\"tst %0\", operands); | |
1555 | sprintf(buf, \"bge abshi%d\", count); | |
1556 | output_asm_insn(buf, NULL); | |
1557 | output_asm_insn(\"neg %0\", operands); | |
1558 | sprintf(buf, \"\\nabshi%d:\", count++); | |
1559 | output_asm_insn(buf, NULL); | |
1560 | ||
1561 | return \"\"; | |
1562 | }" | |
1563 | [(set_attr "length" "3,5")]) | |
1564 | ||
1565 | ||
1566 | ;; define expand abshi - is much better !!! - but | |
1567 | ;; will it be optimized into an abshi2 ? | |
1568 | ;; it will leave better code, because the tsthi might be | |
1569 | ;; optimized away!! | |
1570 | ; -- just a thought - don't have time to check | |
1571 | ; | |
1572 | ;(define_expand "abshi2" | |
1573 | ; [(match_operand:HI 0 "general_operand" "") | |
1574 | ; (match_operand:HI 1 "general_operand" "")] | |
1575 | ; "" | |
1576 | ; " | |
1577 | ;{ | |
1578 | ; rtx label = gen_label_rtx (); | |
1579 | ; | |
1580 | ; /* do I need this? */ | |
1581 | ; do_pending_stack_adjust (); | |
1582 | ; | |
1583 | ; emit_move_insn (operands[0], operands[1]); | |
1584 | ; | |
1585 | ; emit_insn (gen_tsthi (operands[0])); | |
1586 | ; emit_insn (gen_bge (label1)); | |
1587 | ; | |
1588 | ; emit_insn (gen_neghi(operands[0], operands[0]) | |
1589 | ; | |
1590 | ; emit_barrier (); | |
1591 | ; | |
1592 | ; emit_label (label); | |
1593 | ; | |
1594 | ; /* allow REG_NOTES to be set on last insn (labels don't have enough | |
1595 | ; fields, and can't be used for REG_NOTES anyway). */ | |
c5c76735 | 1596 | ; emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); |
2c9c2489 RK |
1597 | ; DONE; |
1598 | ;}") | |
1599 | ||
1600 | ;; negate insns | |
1601 | ||
1602 | (define_insn "negdf2" | |
1603 | [(set (match_operand:DF 0 "general_operand" "=fR,Q") | |
1604 | (neg:DF (match_operand:DF 1 "register_operand" "0,0")))] | |
1605 | "TARGET_FPU" | |
af36a4d2 | 1606 | "{negd|negf} %0" |
2c9c2489 RK |
1607 | [(set_attr "length" "1,2")]) |
1608 | ||
e7f9979a NS |
1609 | (define_insn "negsi2" |
1610 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1611 | (neg:SI (match_operand:SI 1 "general_operand" "0")))] | |
1612 | "" | |
cf860dc2 | 1613 | { |
e7f9979a NS |
1614 | |
1615 | rtx lateoperands[2]; | |
1616 | ||
1617 | lateoperands[0] = operands[0]; | |
1618 | operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); | |
1619 | ||
1620 | lateoperands[1] = operands[1]; | |
1621 | operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1); | |
1622 | ||
1623 | output_asm_insn (\"com %0\", operands); | |
1624 | output_asm_insn (\"com %0\", lateoperands); | |
1625 | output_asm_insn (\"inc %0\", operands); | |
1626 | output_asm_insn (\"adc %0\", lateoperands); | |
1627 | ||
1628 | return \"\"; | |
1629 | } | |
1630 | [(set_attr "length" "5")]) | |
1631 | ||
2c9c2489 RK |
1632 | (define_insn "neghi2" |
1633 | [(set (match_operand:HI 0 "general_operand" "=rR,Q") | |
1634 | (neg:HI (match_operand:HI 1 "general_operand" "0,0")))] | |
1635 | "" | |
1636 | "neg %0" | |
1637 | [(set_attr "length" "1,2")]) | |
1638 | ||
1639 | (define_insn "negqi2" | |
1640 | [(set (match_operand:QI 0 "general_operand" "=rR,Q") | |
1641 | (neg:QI (match_operand:QI 1 "general_operand" "0,0")))] | |
1642 | "" | |
1643 | "negb %0" | |
1644 | [(set_attr "length" "1,2")]) | |
1645 | ||
1646 | ||
1647 | ;; Unconditional and other jump instructions | |
1648 | (define_insn "jump" | |
1649 | [(set (pc) | |
1650 | (label_ref (match_operand 0 "" "")))] | |
1651 | "" | |
1652 | "jmp %l0" | |
1653 | [(set_attr "length" "2")]) | |
1654 | ||
1655 | (define_insn "" | |
1656 | [(set (pc) | |
1657 | (label_ref (match_operand 0 "" ""))) | |
1658 | (clobber (const_int 1))] | |
1659 | "" | |
1660 | "jmp %l0" | |
1661 | [(set_attr "length" "2")]) | |
1662 | ||
1663 | (define_insn "tablejump" | |
1664 | [(set (pc) (match_operand:HI 0 "general_operand" "rR,Q")) | |
1665 | (use (label_ref (match_operand 1 "" "")))] | |
1666 | "" | |
1667 | "jmp %0" | |
1668 | [(set_attr "length" "1,2")]) | |
1669 | ||
1670 | ;; indirect jump - let's be conservative! | |
1671 | ;; allow only register_operand, even though we could also | |
1672 | ;; allow labels etc. | |
1673 | ||
1674 | (define_insn "indirect_jump" | |
1675 | [(set (pc) (match_operand:HI 0 "register_operand" "r"))] | |
1676 | "" | |
1677 | "jmp (%0)") | |
1678 | ||
1679 | ;;- jump to subroutine | |
1680 | ||
1681 | (define_insn "call" | |
e7f9979a | 1682 | [(call (match_operand:HI 0 "general_operand" "rR,Q") |
2c9c2489 RK |
1683 | (match_operand:HI 1 "general_operand" "g,g")) |
1684 | ;; (use (reg:HI 0)) what was that ??? | |
1685 | ] | |
1686 | ;;- Don't use operand 1 for most machines. | |
1687 | "" | |
1688 | "jsr pc, %0" | |
1689 | [(set_attr "length" "1,2")]) | |
1690 | ||
1691 | ;;- jump to subroutine | |
1692 | (define_insn "call_value" | |
1693 | [(set (match_operand 0 "" "") | |
e7f9979a | 1694 | (call (match_operand:HI 1 "general_operand" "rR,Q") |
2c9c2489 RK |
1695 | (match_operand:HI 2 "general_operand" "g,g"))) |
1696 | ;; (use (reg:HI 0)) - what was that ???? | |
1697 | ] | |
1698 | ;;- Don't use operand 2 for most machines. | |
1699 | "" | |
1700 | "jsr pc, %1" | |
1701 | [(set_attr "length" "1,2")]) | |
1702 | ||
1703 | ;;- nop instruction | |
1704 | (define_insn "nop" | |
1705 | [(const_int 0)] | |
1706 | "" | |
1707 | "nop") | |
1708 | \f | |
1709 | ||
1710 | ;;- multiply | |
1711 | ||
1712 | (define_insn "muldf3" | |
1713 | [(set (match_operand:DF 0 "register_operand" "=a,a,a") | |
1714 | (mult:DF (match_operand:DF 1 "register_operand" "%0,0,0") | |
1715 | (match_operand:DF 2 "general_operand" "fR,Q,F")))] | |
1716 | "TARGET_FPU" | |
af36a4d2 | 1717 | "{muld|mulf} %2, %0" |
2c9c2489 RK |
1718 | [(set_attr "length" "1,2,5")]) |
1719 | ||
1720 | ;; 16 bit result multiply: | |
1721 | ;; currently we multiply only into odd registers, so we don't use two | |
1722 | ;; registers - but this is a bit inefficient at times. If we define | |
1723 | ;; a register class for each register, then we can specify properly | |
1724 | ;; which register need which scratch register .... | |
1725 | ||
1726 | (define_insn "mulhi3" | |
1727 | [(set (match_operand:HI 0 "register_operand" "=d,d") ; multiply regs | |
1728 | (mult:HI (match_operand:HI 1 "register_operand" "%0,0") | |
1729 | (match_operand:HI 2 "general_operand" "rR,Qi")))] | |
1730 | "TARGET_45" | |
1731 | "mul %2, %0" | |
1732 | [(set_attr "length" "1,2")]) | |
1733 | ||
1734 | ;; 32 bit result | |
781e6f76 RK |
1735 | (define_expand "mulhisi3" |
1736 | [(set (match_dup 3) | |
1737 | (match_operand:HI 1 "general_operand" "g,g")) | |
1738 | (set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! | |
1739 | (mult:SI (truncate:HI | |
1740 | (match_dup 0)) | |
1741 | (match_operand:HI 2 "general_operand" "rR,Qi")))] | |
1742 | "TARGET_45" | |
1743 | "operands[3] = gen_lowpart(HImode, operands[1]);") | |
1744 | ||
1745 | (define_insn "" | |
2c9c2489 | 1746 | [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! |
781e6f76 RK |
1747 | (mult:SI (truncate:HI |
1748 | (match_operand:SI 1 "register_operand" "%0,0")) | |
2c9c2489 RK |
1749 | (match_operand:HI 2 "general_operand" "rR,Qi")))] |
1750 | "TARGET_45" | |
1751 | "mul %2, %0" | |
1752 | [(set_attr "length" "1,2")]) | |
1753 | ||
781e6f76 RK |
1754 | ;(define_insn "mulhisi3" |
1755 | ; [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! | |
1756 | ; (mult:SI (truncate:HI | |
1757 | ; (match_operand:SI 1 "register_operand" "%0,0")) | |
1758 | ; (match_operand:HI 2 "general_operand" "rR,Qi")))] | |
1759 | ; "TARGET_45" | |
1760 | ; "mul %2, %0" | |
1761 | ; [(set_attr "length" "1,2")]) | |
1762 | ||
2c9c2489 | 1763 | ;;- divide |
2c9c2489 RK |
1764 | (define_insn "divdf3" |
1765 | [(set (match_operand:DF 0 "register_operand" "=a,a,a") | |
1766 | (div:DF (match_operand:DF 1 "register_operand" "0,0,0") | |
1767 | (match_operand:DF 2 "general_operand" "fR,Q,F")))] | |
1768 | "TARGET_FPU" | |
af36a4d2 | 1769 | "{divd|divf} %2, %0" |
2c9c2489 RK |
1770 | [(set_attr "length" "1,2,5")]) |
1771 | ||
0c253776 | 1772 | |
2c9c2489 | 1773 | (define_expand "divhi3" |
0c253776 RK |
1774 | [(set (subreg:HI (match_dup 1) 0) |
1775 | (div:HI (match_operand:SI 1 "general_operand" "0") | |
1776 | (match_operand:HI 2 "general_operand" "g"))) | |
1777 | (set (match_operand:HI 0 "general_operand" "=r") | |
1778 | (subreg:HI (match_dup 1) 0))] | |
2c9c2489 | 1779 | "TARGET_45" |
0c253776 | 1780 | "") |
2c9c2489 | 1781 | |
2c9c2489 | 1782 | (define_insn "" |
0c253776 RK |
1783 | [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0) |
1784 | (div:HI (match_operand:SI 1 "general_operand" "0") | |
1785 | (match_operand:HI 2 "general_operand" "g")))] | |
2c9c2489 RK |
1786 | "TARGET_45" |
1787 | "div %2,%0" | |
1788 | [(set_attr "length" "2")]) | |
1789 | ||
1790 | (define_expand "modhi3" | |
ddef6bc7 | 1791 | [(set (subreg:HI (match_dup 1) 2) |
0c253776 RK |
1792 | (mod:HI (match_operand:SI 1 "general_operand" "0") |
1793 | (match_operand:HI 2 "general_operand" "g"))) | |
1794 | (set (match_operand:HI 0 "general_operand" "=r") | |
ddef6bc7 | 1795 | (subreg:HI (match_dup 1) 2))] |
2c9c2489 | 1796 | "TARGET_45" |
0c253776 | 1797 | "") |
2c9c2489 | 1798 | |
2c9c2489 | 1799 | (define_insn "" |
e7f9979a | 1800 | [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 2) |
0c253776 RK |
1801 | (mod:HI (match_operand:SI 1 "general_operand" "0") |
1802 | (match_operand:HI 2 "general_operand" "g")))] | |
2c9c2489 | 1803 | "TARGET_45" |
0c253776 | 1804 | "div %2,%0" |
2c9c2489 RK |
1805 | [(set_attr "length" "2")]) |
1806 | ||
0c253776 RK |
1807 | ;(define_expand "divmodhi4" |
1808 | ; [(parallel [(set (subreg:HI (match_dup 1) 0) | |
1809 | ; (div:HI (match_operand:SI 1 "general_operand" "0") | |
1810 | ; (match_operand:HI 2 "general_operand" "g"))) | |
ddef6bc7 | 1811 | ; (set (subreg:HI (match_dup 1) 2) |
0c253776 RK |
1812 | ; (mod:HI (match_dup 1) |
1813 | ; (match_dup 2)))]) | |
1814 | ; (set (match_operand:HI 3 "general_operand" "=r") | |
ddef6bc7 | 1815 | ; (subreg:HI (match_dup 1) 2)) |
0c253776 RK |
1816 | ; (set (match_operand:HI 0 "general_operand" "=r") |
1817 | ; (subreg:HI (match_dup 1) 0))] | |
1818 | ; "TARGET_45" | |
1819 | ; "") | |
1820 | ; | |
1821 | ;(define_insn "" | |
1822 | ; [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0) | |
1823 | ; (div:HI (match_operand:SI 1 "general_operand" "0") | |
1824 | ; (match_operand:HI 2 "general_operand" "g"))) | |
ddef6bc7 | 1825 | ; (set (subreg:HI (match_dup 0) 2) |
0c253776 RK |
1826 | ; (mod:HI (match_dup 1) |
1827 | ; (match_dup 2)))] | |
1828 | ; "TARGET_45" | |
1829 | ; "div %2, %0") | |
1830 | ; | |
2c9c2489 RK |
1831 | |
1832 | ;; is rotate doing the right thing to be included here ???? |