comparison extra/gcc6809lw-4.6.4-7.patch @ 439:ff4b6095ee72

Bump patch number on gcc6809 patch. The previous update from Brett Gordon <beretta42@gmail.com> updated the gcc6809 patch but didn't update it's patch number tag. Update the tag now.
author William Astle <lost@l-w.ca>
date Tue, 15 Aug 2017 20:49:58 -0600
parents extra/gcc6809lw-4.6.4-6.patch@f18cc0c87a7e
children
comparison
equal deleted inserted replaced
438:f18cc0c87a7e 439:ff4b6095ee72
1 diff -urN gcc-4.6.4-clean/config.sub gcc-4.6.4/config.sub
2 --- gcc-4.6.4-clean/config.sub 2010-05-25 07:22:07.000000000 -0600
3 +++ gcc-4.6.4/config.sub 2015-07-20 19:44:52.766843181 -0600
4 @@ -313,7 +313,7 @@
5 c6x)
6 basic_machine=tic6x-unknown
7 ;;
8 - m6811 | m68hc11 | m6812 | m68hc12 | picochip)
9 + m6809 | m6811 | m68hc11 | m6812 | m68hc12 | picochip)
10 # Motorola 68HC11/12.
11 basic_machine=$basic_machine-unknown
12 os=-none
13 @@ -354,7 +354,7 @@
14 | i*86-* | i860-* | i960-* | ia64-* \
15 | ip2k-* | iq2000-* \
16 | lm32-* \
17 - | m32c-* | m32r-* | m32rle-* \
18 + | m32c-* | m32r-* | m32rle-* | m6809-* \
19 | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
20 | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
21 | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
22 @@ -509,6 +509,10 @@
23 basic_machine=arm-unknown
24 os=-cegcc
25 ;;
26 + coco)
27 + basic_machine=coco
28 + os=-none
29 + ;;
30 convex-c1)
31 basic_machine=c1-convex
32 os=-bsd
33 diff -urN gcc-4.6.4-clean/configure gcc-4.6.4/configure
34 --- gcc-4.6.4-clean/configure 2011-12-18 03:03:44.000000000 -0700
35 +++ gcc-4.6.4/configure 2015-07-20 19:44:52.766843181 -0600
36 @@ -3439,6 +3439,9 @@
37 m32r-*-*)
38 noconfigdirs="$noconfigdirs ${libgcj}"
39 ;;
40 + m6809*)
41 + noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 target-libgloss ${libgcj}"
42 + ;;
43 m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
44 noconfigdirs="$noconfigdirs target-libstdc++-v3 ${libgcj}"
45 libgloss_dir=m68hc11
46 diff -urN gcc-4.6.4-clean/configure.ac gcc-4.6.4/configure.ac
47 --- gcc-4.6.4-clean/configure.ac 2011-11-18 04:45:44.000000000 -0700
48 +++ gcc-4.6.4/configure.ac 2015-07-20 19:44:52.766843181 -0600
49 @@ -885,6 +885,9 @@
50 m32r-*-*)
51 noconfigdirs="$noconfigdirs ${libgcj}"
52 ;;
53 + m6809*)
54 + noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 target-libgloss ${libgcj}"
55 + ;;
56 m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
57 noconfigdirs="$noconfigdirs target-libstdc++-v3 ${libgcj}"
58 libgloss_dir=m68hc11
59 diff -urN gcc-4.6.4-clean/gcc/calls.c gcc-4.6.4/gcc/calls.c
60 --- gcc-4.6.4-clean/gcc/calls.c 2012-02-09 10:27:25.000000000 -0700
61 +++ gcc-4.6.4/gcc/calls.c 2015-07-20 19:44:52.766843181 -0600
62 @@ -2561,7 +2561,7 @@
63 call sequence.
64 Also do the adjustments before a throwing call, otherwise
65 exception handling can fail; PR 19225. */
66 - if (pending_stack_adjust >= 32
67 + if (pending_stack_adjust >= 8
68 || (pending_stack_adjust > 0
69 && (flags & ECF_MAY_BE_ALLOCA))
70 || (pending_stack_adjust > 0
71 diff -urN gcc-4.6.4-clean/gcc/config/m6809/crt0.S gcc-4.6.4/gcc/config/m6809/crt0.S
72 --- gcc-4.6.4-clean/gcc/config/m6809/crt0.S 1969-12-31 17:00:00.000000000 -0700
73 +++ gcc-4.6.4/gcc/config/m6809/crt0.S 2015-07-20 19:44:52.766843181 -0600
74 @@ -0,0 +1,173 @@
75 +;;;
76 +;;; Copyright 2006, 2007, 2008, 2009 by Brian Dominy <brian@oddchange.com>
77 +;;;
78 +;;; This file is part of GCC.
79 +;;;
80 +;;; GCC is free software; you can redistribute it and/or modify
81 +;;; it under the terms of the GNU General Public License as published by
82 +;;; the Free Software Foundation; either version 3, or (at your option)
83 +;;; any later version.
84 +;;;
85 +;;; GCC is distributed in the hope that it will be useful,
86 +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
87 +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
88 +;;; GNU General Public License for more details.
89 +
90 +;;; You should have received a copy of the GNU General Public License
91 +;;; along with GCC; see the file COPYING3. If not see
92 +;;; <http://www.gnu.org/licenses/>.
93 +
94 + /* Declare external for main() */
95 + .globl _main
96 +
97 +
98 +/* The startup is heavily dependent on the type of machine and
99 +OS environment that is available at the start point.
100 +For the most part, the general idea is the same across machines,
101 +but the implementation is vastly different. This is managed via
102 +conditional compiles throughout the startup code for each of the
103 +supported machines. */
104 +
105 +#ifdef TARGET_COCO /* CoCo memory map */
106 +
107 +#define COCO_RAMROM_MODE 0xFFDE
108 +#define COCO_ALLRAM_MODE 0xFFDF
109 +#define COCO_PAGE1 0xFFD5
110 +
111 +/* SAM M1 and M0 adjusts the memory size */
112 +
113 +#define BASIC_WARMSTART_FLAG 0x0071
114 +#define BASIC_START 0xA027
115 +
116 +#define __STACK_TOP 0x6800
117 +
118 +#else /* Simulator (default) memory map */
119 +
120 +#define SIM_EXIT_REG 0xFF01
121 +
122 +#define __STACK_TOP 0xFE00
123 +
124 +#endif
125 +
126 +
127 + .area .data
128 + .area .ctors
129 + .area .dtors
130 + .area .bss
131 +
132 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
133 + ;;;
134 + ;;; __exit : Exit point from the program
135 + ;;; For simulation, this writes to a special I/O register that
136 + ;;; the simulator interprets as end-of-program.
137 + ;;;
138 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
139 + .area .text
140 + .globl __exit
141 +__exit:
142 +#ifdef TARGET_COCO
143 + ;; Go back to ROM/RAM mode
144 + sta COCO_RAMROM_MODE
145 + clr BASIC_WARMSTART_FLAG
146 + jmp BASIC_START
147 +#else
148 + tfr x,d
149 + stb SIM_EXIT_REG
150 + bra __exit
151 +#endif
152 +
153 +
154 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
155 + ;;;
156 + ;;; __start : Entry point to the program
157 + ;;;
158 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
159 + .area .text
160 + .globl __start
161 +__start:
162 +
163 +#ifdef HAVE_DIRECT
164 + ;; Initialize the direct page pointer
165 + lda #<s_.direct
166 + tfr a,dp
167 +#endif
168 +
169 +#ifdef TARGET_COCO
170 + ;; Turn off interrupts
171 + orcc #(0x10|0x40)
172 +
173 + ;; Setup All RAM Mode
174 + sta COCO_ALLRAM_MODE
175 +#endif /* TARGET_COCO */
176 +
177 + ;; Initialize the stack
178 + lds #__STACK_TOP - 2
179 +
180 + ;; Call any "initializer" functions
181 + ldu #s_.ctors
182 +__ctors_loop:
183 + ldy ,u++
184 + cmpy #0
185 + beq __ctors_done
186 + jsr ,y
187 + bra __ctors_loop
188 +__ctors_done:
189 +
190 + ;; Enable interrupts on the simulator
191 +#ifndef TARGET_COCO
192 + andcc #~(0x10|0x40)
193 +#endif
194 +
195 + ;; Set up the environment
196 +
197 + ;; Set up argc/argv arrays
198 +
199 + ;; Call the main function. The exit code will
200 + ;; be returned in the X register, unless compiled
201 + ;; with -mdret, in which case it comes back in D.
202 + jsr _main
203 +
204 + ;; Call any finalizer functions
205 + ldu #s_.dtors
206 +__dtors_loop:
207 + ldy ,u++
208 + cmpy #0
209 + beq __dtors_done
210 + jsr ,y
211 + bra __dtors_loop
212 +__dtors_done:
213 +
214 + ;; If main returns, then invoke _exit() to stop the program
215 + ;; The C library doesn't support -mdret yet, so move the
216 + ;; argument first.
217 +#ifdef __DRET__
218 + tfr d,x
219 +#endif
220 + jmp _exit
221 +
222 +
223 +
224 + ;;;
225 + ;;; __crt0_vector : Default handler for interrupts
226 + ;;;
227 + .area .text
228 +___crt0_vector:
229 + ;; The default behavior is to simply ignore all
230 + ;; non-reset interrupts.
231 + rti
232 +
233 +
234 + ;;;
235 + ;;; vector : The interrupt vector table
236 + ;;; The linker will ensure that this gets loaded at address 0xFFF0.
237 + ;;;
238 + .area vector
239 +vectors:
240 + .word ___crt0_vector
241 + .word ___crt0_vector
242 + .word ___crt0_vector
243 + .word ___crt0_vector
244 + .word ___crt0_vector
245 + .word ___crt0_vector
246 + .word ___crt0_vector
247 + .word __start
248 diff -urN gcc-4.6.4-clean/gcc/config/m6809/libgcc1.s gcc-4.6.4/gcc/config/m6809/libgcc1.s
249 --- gcc-4.6.4-clean/gcc/config/m6809/libgcc1.s 1969-12-31 17:00:00.000000000 -0700
250 +++ gcc-4.6.4/gcc/config/m6809/libgcc1.s 2015-07-20 19:44:52.766843181 -0600
251 @@ -0,0 +1,511 @@
252 +/* libgcc routines for m6809
253 + Copyright (C) 2006 Free Software Foundation, Inc.
254 +
255 +This file is part of GCC.
256 +
257 +GCC is free software; you can redistribute it and/or modify
258 +it under the terms of the GNU General Public License as published by
259 +the Free Software Foundation; either version 3, or (at your option)
260 +any later version.
261 +
262 +GCC is distributed in the hope that it will be useful,
263 +but WITHOUT ANY WARRANTY; without even the implied warranty of
264 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
265 +GNU General Public License for more details.
266 +
267 +You should have received a copy of the GNU General Public License
268 +along with GCC; see the file COPYING3. If not see
269 +<http://www.gnu.org/licenses/>. */
270 +
271 +/* As a special exception, if you link this library with other files,
272 + some of which are compiled with GCC, to produce an executable,
273 + this library does not by itself cause the resulting executable
274 + to be covered by the GNU General Public License.
275 + This exception does not however invalidate any other reasons why
276 + the executable file might be covered by the GNU General Public License. */
277 +
278 +
279 +#define SIGFPE jmp _abort
280 +
281 +
282 + ; Shift functions
283 + ; On input, D is value to be shifted, and X has shift count.
284 + ; Result is also in D.
285 +
286 +#ifdef L_ashlhi3
287 + .area .text
288 + .globl _ashlhi3
289 +_ashlhi3:
290 + pshs x
291 +1$:
292 + leax -1,x
293 + cmpx #-1
294 + beq 2$
295 + aslb
296 + rola
297 + bra 1$
298 +2$:
299 + puls x,pc
300 +#endif
301 +
302 +#ifdef L_ashrhi3
303 + .area .text
304 + .globl _ashrhi3
305 +_ashrhi3:
306 + pshs x
307 +1$:
308 + leax -1,x
309 + cmpx #-1
310 + beq 2$
311 + asra
312 + rorb
313 + bra 1$
314 +2$:
315 + puls x,pc
316 +#endif
317 +
318 +
319 +#ifdef L_lshrhi3
320 + .area .text
321 + .globl _lshrhi3
322 +_lshrhi3:
323 + pshs x
324 +1$:
325 + leax -1,x
326 + cmpx #-1
327 + beq 2$
328 + lsra
329 + rorb
330 + bra 1$
331 +2$:
332 + puls x,pc
333 +#endif
334 +
335 +
336 +
337 +#ifdef L_softregs
338 + .area direct
339 + .globl m0, m1, m2, m3, m4, m5, m6, m7
340 + .globl m8, m9, m10, m11, m12, m13, m14, m15
341 +m0: .blkb 1
342 +m1: .blkb 1
343 +m2: .blkb 1
344 +m3: .blkb 1
345 +m4: .blkb 1
346 +m5: .blkb 1
347 +m6: .blkb 1
348 +m7: .blkb 1
349 +m8: .blkb 1
350 +m9: .blkb 1
351 +m10: .blkb 1
352 +m11: .blkb 1
353 +m12: .blkb 1
354 +m13: .blkb 1
355 +m14: .blkb 1
356 +m15: .blkb 1
357 +#endif
358 +
359 +
360 +#ifdef L_ashlsi3_one
361 + .area .text
362 + .globl _ashlsi3_one
363 +_ashlsi3_one:
364 + asl 3,x
365 + rol 2,x
366 + rol 1,x
367 + rol ,x
368 + rts
369 +#endif
370 +
371 +#ifdef L_ashlsi3
372 + /* X points to the SImode (source/dest)
373 + B is the count */
374 +_ashlsi3:
375 + pshs u
376 + cmpb #16
377 + blt try8
378 + subb #16
379 + ; Shift by 16
380 + ldu 2,x
381 + stu ,x
382 +try8:
383 + cmpb #8
384 + blt try_rest
385 + subb #8
386 + ; Shift by 8
387 +
388 +try_rest:
389 + tstb
390 + beq done
391 +do_rest:
392 + ; Shift by 1
393 + asl 3,x
394 + rol 2,x
395 + rol 1,x
396 + rol ,x
397 + decb
398 + bne do_rest
399 +done:
400 + puls u,pc
401 +#endif
402 +
403 +#ifdef L_ashrsi3_one
404 + .area .text
405 + .globl _ashlsi3_one
406 +_ashrsi3_one:
407 + asr ,x
408 + ror 1,x
409 + ror 2,x
410 + ror 3,x
411 + rts
412 +#endif
413 +
414 +
415 +#ifdef L_lshrsi3_one
416 + .area .text
417 + .globl _lshrsi3_one
418 +_lshrsi3_one:
419 + lsr ,x
420 + ror 1,x
421 + ror 2,x
422 + ror 3,x
423 + rts
424 +#endif
425 +
426 +
427 +#ifdef L_clzsi2
428 + .area .text
429 + .globl ___clzhi2
430 + ; Input: X = 16-bit unsigned integer
431 + ; Output: X = number of leading zeros
432 + ; This function destroys the value in D.
433 +___clzhi2:
434 + pshs x
435 + ; Find the offset of the leftmost '1' bit in
436 + ; the left half of the word.
437 + ;
438 + ; Bits are numbered in the table with 1 meaning the
439 + ; LSB and 8 meaning the MSB.
440 + ;
441 + ; If nonzero, then clz is 8-a.
442 + tfr x,d
443 + ldx #___clz_tab
444 + tfr a,b
445 + clra
446 + ldb d,x
447 + bne upper_bit_set
448 +
449 +lower_bit_set:
450 + ; If the upper byte is zero, then check the lower
451 + ; half of the word. Return 16-a.
452 + puls d
453 + clra
454 + ldb d,x
455 + negb
456 + addb #16
457 + bra done
458 +
459 +upper_bit_set:
460 + negb
461 + addb #8
462 + puls x
463 +
464 +done:
465 + tfr d,x
466 + puls pc
467 +#endif
468 +
469 +#ifdef L_clzdi2
470 + .area .text
471 + .globl ___clzsi2
472 + ; Input: 32-bit unsigned integer is on the stack, just
473 + ; above the return address
474 + ; Output: X = number of leading zeros
475 +___clzsi2:
476 + ; Check the upper 16-bit word
477 + ; If it is not zero, then return clzhi2(X).
478 + ; A branch can be used instead of a call since no
479 + ; postprocessing is needed. Use long branch form
480 + ; though since functions may not be near each other.
481 + ldx 2,s
482 + lbne ___clzhi2
483 + ldx 4,s
484 + jsr ___clzhi2
485 + leax 16,x
486 + rts
487 +#endif
488 +
489 +#ifdef L_ctzsi2
490 + .area .text
491 + .globl ___ctzhi2
492 + ; Input: X = 16-bit unsigned integer
493 + ; Output: X = number of trailing zeros
494 + ; F(x) = 15 - clzhi2(X & -x)
495 + ; This function destroys the value in D.
496 +___ctzhi2:
497 + tfr x,d
498 + coma
499 + comb
500 + addd #1
501 + pshs a
502 + pshs b
503 + tfr x,d
504 + andb ,s+
505 + anda ,s+
506 + tfr d,x
507 + jsr ___clzhi2
508 + tfr x,d
509 + subd #16
510 + coma
511 + comb
512 + tfr d,x
513 + rts
514 +#endif
515 +
516 +
517 +#ifdef L_ctzdi2
518 + .area .text
519 + .globl ___ctzsi2
520 + ; Input: 32-bit unsigned integer is on the stack, just
521 + ; above the return address
522 + ; Output: X = number of leading zeros
523 +___ctzsi2:
524 + ; Check the lower 16-bit word
525 + ; If it is not zero, then return ctzhi2(X).
526 + ; A branch can be used instead of a call since no
527 + ; postprocessing is needed. Use long branch form
528 + ; though since functions may not be near each other.
529 + ldx 4,s
530 + lbne ___ctzhi2
531 + ldx 2,s
532 + jsr ___ctzhi2
533 + leax 16,x
534 + rts
535 +#endif
536 +
537 +
538 +#ifdef L_mulhi3
539 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
540 +;;; ___mulhi3 - signed/unsigned multiply
541 +;;; Called by GCC to implement 16x16 multiplication
542 +;;; Arguments: Two 16-bit values, one in stack, one in X.
543 +;;; Result: 16-bit result in X
544 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
545 + .area .text
546 + .globl _mulhi3
547 +_mulhi3:
548 + pshs x
549 + lda 5,s ; left msb * right lsb * 256
550 + ldb ,s
551 + mul
552 + tfr b,a
553 + clrb
554 + tfr d,x
555 + ldb 1,s ; left lsb * right msb * 256
556 + lda 4,s
557 + mul
558 + tfr b,a
559 + clrb
560 + leax d,x
561 + ldb 1,s ; left lsb * right lsb
562 + lda 5,s
563 + mul
564 + leax d,x
565 + puls d,pc ; kill D to remove initial push
566 +#endif
567 +
568 +
569 +#ifdef L_divhi3
570 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
571 +;;; ___divhi3 - signed division
572 +;;; Arguments: Dividend in X, divisor on the stack
573 +;;; Returns result in X.
574 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
575 + .area .text
576 + .globl _divhi3
577 +_divhi3:
578 + ldd 2,s
579 + bne do_div ; check dividend
580 + SIGFPE
581 +do_div:
582 + pshs x
583 + jsr _seuclid
584 + puls x,pc
585 +#endif
586 +
587 +
588 +#ifdef L_modhi3
589 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
590 +;;; ___modhi3 - signed modulo
591 +;;; Arguments: Dividend in X, divisor on the stack
592 +;;; Returns result in X.
593 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
594 + .area .text
595 + .globl _modhi3
596 +_modhi3:
597 + ldd 2,s
598 + bne do_mod ; check dividend
599 + SIGFPE
600 +do_mod:
601 + pshs x
602 + jsr _seuclid
603 + leas 2,s
604 + tfr d,x
605 + rts
606 +#endif
607 +
608 +
609 +
610 +#ifdef L_udivhi3
611 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
612 +;;; ___udivhi3 - unsigned division
613 +;;; Arguments: Dividend in X, divisor on the stack
614 +;;; Returns result in X.
615 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
616 + .area .text
617 + .globl _udivhi3
618 +_udivhi3:
619 + ldd 2,s
620 + bne do_udiv ; check dividend
621 + SIGFPE
622 +do_udiv:
623 + pshs x
624 + jsr _euclid
625 + puls x,pc
626 +#endif
627 +
628 +
629 +#ifdef L_umodhi3
630 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
631 +;;; ___umodhi3 - unsigned modulo
632 +;;; Arguments: Dividend in X, divisor on the stack
633 +;;; Returns result in X.
634 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
635 + .area .text
636 + .globl _umodhi3
637 +_umodhi3:
638 + ldd 2,s
639 + bne do_umod ; check dividend
640 + SIGFPE
641 +do_umod:
642 + pshs x
643 + jsr _euclid
644 + leas 2,s
645 + tfr d,x
646 + rts
647 +#endif
648 +
649 +
650 +#ifdef L_euclid
651 +; unsigned euclidean division
652 +; calling: (left / right)
653 +; push left
654 +; ldd right
655 +; jsr _euclid
656 +; quotient on the stack (left)
657 +; modulus in d
658 +
659 + .area .text
660 + .globl _euclid
661 + left=5
662 + right=1 ; word
663 + count=0 ; byte
664 + CARRY=1 ; alias
665 +_euclid:
666 + leas -3,s ; 2 local variables
667 + clr count,s ; prescale divisor
668 + inc count,s
669 + tsta
670 +presc:
671 + bmi presc_done
672 + inc count,s
673 + aslb
674 + rola
675 + bra presc
676 +presc_done:
677 + std right,s
678 + ldd left,s
679 + clr left,s ; quotient = 0
680 + clr left+1,s
681 +mod1:
682 + subd right,s ; check subtract
683 + bcc mod2
684 + addd right,s
685 + andcc #~CARRY
686 + bra mod3
687 +mod2:
688 + orcc #CARRY
689 +mod3:
690 + rol left+1,s ; roll in carry
691 + rol left,s
692 + lsr right,s
693 + ror right+1,s
694 + dec count,s
695 + bne mod1
696 + leas 3,s
697 + rts
698 +#endif
699 +
700 +#ifdef L_seuclid
701 +; signed euclidean division
702 +; calling: (left / right)
703 +; push left
704 +; ldd right
705 +; jsr _seuclid
706 +; quotient on the stack (left)
707 +; modulus in d
708 + .area .text
709 + .globl _seuclid
710 + left=6
711 + right=2
712 + quot_sign=1
713 + mod_sign=0
714 +_seuclid:
715 + leas -4,s ; 3 local variables
716 + std right,s
717 + clr mod_sign,s
718 + clr quot_sign,s
719 + ldd left,s
720 + bge mod_abs
721 + inc mod_sign,s ; sign(mod) = sign(left)
722 + inc quot_sign,s
723 + bsr negd ; abs(left) -> D
724 +mod_abs:
725 + pshs b,a ; push abs(left)
726 + ldd right+2,s ; all references shifted by 2
727 + bge quot_abs
728 + dec quot_sign+2,s ; sign(quot) = sign(left) XOR sign(right)
729 + bsr negd ; abs(right) -> D
730 +quot_abs:
731 + jsr _euclid ; call (unsigned) euclidean division
732 + std right+2,s
733 + puls a,b ; quot -> D
734 + tst quot_sign,s ; all references no longer shifted
735 + beq quot_done
736 + bsr negd
737 +quot_done:
738 + std left,s ; quot -> left
739 + ldd right,s
740 + tst mod_sign,s
741 + beq mod_done
742 + bsr negd
743 +mod_done:
744 + leas 4,s ; destroy stack frame
745 + rts
746 +
747 +negd: ; self-explanatory !
748 + nega
749 + negb
750 + sbca #0
751 + rts
752 +#endif
753 +
754 +
755 +
756 +#ifdef L_pending_addsi3
757 +_addsi3:
758 + rts
759 +#endif /* L_pending_addsi3 */
760 +
761 +
762 +
763 diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.c gcc-4.6.4/gcc/config/m6809/m6809.c
764 --- gcc-4.6.4-clean/gcc/config/m6809/m6809.c 1969-12-31 17:00:00.000000000 -0700
765 +++ gcc-4.6.4/gcc/config/m6809/m6809.c 2015-07-20 22:11:37.726714746 -0600
766 @@ -0,0 +1,3025 @@
767 +/*-------------------------------------------------------------------
768 + FILE: m6809.c
769 +-------------------------------------------------------------------*/
770 +/* Subroutines for insn-output.c for MC6809.
771 + Copyright (C) 1989-2007 Free Software Foundation, Inc.
772 +
773 + MC6809 Version by Tom Jones (jones@sal.wisc.edu)
774 + Space Astronomy Laboratory
775 + University of Wisconsin at Madison
776 +
777 + minor changes to adapt it to gcc-2.5.8 by Matthias Doerfel
778 + ( msdoerfe@informatik.uni-erlangen.de )
779 + also added #pragma interrupt (inspired by gcc-6811)
780 +
781 + minor changes to adapt it to gcc-2.8.0 by Eric Botcazou
782 + (ebotcazou@multimania.com)
783 +
784 + minor changes to adapt it to gcc-2.95.3 by Eric Botcazou
785 + (ebotcazou@multimania.com)
786 +
787 + major cleanup, improvements, and upgrade to gcc 3.4 by Brian Dominy
788 + (brian@oddchange.com)
789 +
790 + additional adjustments, etc., for gcc 4.6.1 by William Astle (lost@l-w.ca)
791 +
792 +This file is part of GCC.
793 +
794 +GCC is free software; you can redistribute it and/or modify
795 +it under the terms of the GNU General Public License as published by
796 +the Free Software Foundation; either version 3, or (at your option)
797 +any later version.
798 +
799 +GCC is distributed in the hope that it will be useful,
800 +but WITHOUT ANY WARRANTY; without even the implied warranty of
801 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
802 +GNU General Public License for more details.
803 +
804 +You should have received a copy of the GNU General Public License
805 +along with GCC; see the file COPYING3. If not see
806 +<http://www.gnu.org/licenses/>. */
807 +
808 +#include <string.h>
809 +#include <time.h>
810 +#include <sys/types.h>
811 +#include <sys/timeb.h>
812 +#include <stdio.h>
813 +#include "config.h"
814 +#include "system.h"
815 +#include "coretypes.h"
816 +#include "tm.h"
817 +#include "tree.h"
818 +#include "rtl.h"
819 +#include "tm_p.h"
820 +#include "regs.h"
821 +#include "flags.h"
822 +#include "hard-reg-set.h"
823 +#include "real.h"
824 +#include "tree.h"
825 +#include "insn-config.h"
826 +#include "conditions.h"
827 +#include "insn-flags.h"
828 +#include "output.h"
829 +#include "insn-attr.h"
830 +#include "function.h"
831 +#include "target.h"
832 +#include "target-def.h"
833 +#include "expr.h"
834 +#include "recog.h"
835 +#include "cpplib.h"
836 +#include "c-family/c-pragma.h"
837 +#include "c-family/c-common.h"
838 +#include "toplev.h"
839 +#include "optabs.h"
840 +#include "version.h"
841 +#include "df.h"
842 +#include "rtlhooks-def.h"
843 +
844 +/* macro to return TRUE if length of operand mode is one byte */
845 +#define BYTE_MODE(X) ((GET_MODE_SIZE (GET_MODE (X))) == 1)
846 +
847 +
848 +/* REAL_REG_P(x) is a true if the rtx 'x' represents a real CPU
849 +register and not a fake one that is emulated in software. */
850 +#define REAL_REG_P(x) (REG_P(x) && !M_REG_P(x))
851 +
852 +/*-------------------------------------------------------------------
853 + Target hooks, moved from target.h
854 +-------------------------------------------------------------------*/
855 +static void m6809_encode_section_info (tree decl, rtx rtl, int new_decl_p ATTRIBUTE_UNUSED);
856 +
857 +#undef TARGET_ENCODE_SECTION_INFO
858 +#define TARGET_ENCODE_SECTION_INFO m6809_encode_section_info
859 +
860 +#undef TARGET_ASM_FILE_START
861 +#define TARGET_ASM_FILE_START m6809_asm_file_start
862 +
863 +#undef TARGET_ASM_ALIGNED_HI_OP
864 +#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
865 +
866 +#undef TARGET_ASM_ALIGNED_SI_OP
867 +#define TARGET_ASM_ALIGNED_SI_OP NULL
868 +
869 +#undef TARGET_ASM_UNALIGNED_HI_OP
870 +#define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
871 +
872 +#undef TARGET_ASM_UNALIGNED_SI_OP
873 +#define TARGET_ASM_UNALIGNED_SI_OP NULL
874 +
875 +#undef TARGET_RTX_COSTS
876 +#define TARGET_RTX_COSTS m6809_rtx_costs
877 +
878 +#undef TARGET_ATTRIBUTE_TABLE
879 +#define TARGET_ATTRIBUTE_TABLE m6809_attribute_table
880 +
881 +#undef TARGET_INIT_BUILTINS
882 +#define TARGET_INIT_BUILTINS m6809_init_builtins
883 +
884 +#undef TARGET_EXPAND_BUILTIN
885 +#define TARGET_EXPAND_BUILTIN m6809_expand_builtin
886 +
887 +#undef TARGET_DEFAULT_TARGET_FLAGS
888 +#define TARGET_DEFAULT_TARGET_FLAGS (MASK_REG_ARGS | MASK_DIRECT)
889 +
890 +#undef TARGET_FUNCTION_OK_FOR_SIBCALL
891 +#define TARGET_FUNCTION_OK_FOR_SIBCALL m6809_function_ok_for_sibcall
892 +
893 +#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
894 +#define TARGET_ASM_TRAMPOLINE_TEMPLATE m6809_asm_trampoline_template
895 +
896 +#undef TARGET_TRAMPOLINE_INIT
897 +#define TARGET_TRAMPOLINE_INIT m6809_initialize_trampoline
898 +
899 +#undef TARGET_FRAME_POINTER_REQUIRED
900 +#define TARGET_FRAME_POINTER_REQUIRED m6809_frame_pointer_required
901 +
902 +#undef TARGET_OPTION_OVERRIDE
903 +#define TARGET_OPTION_OVERRIDE m6809_override_options
904 +
905 +/* External variables used */
906 +extern int reload_completed; /* set in toplev.c */
907 +extern FILE *asm_out_file;
908 +
909 +static int last_mem_size; /* operand size (bytes) */
910 +
911 +/* True if the section was recently changed and another .area
912 + * directive needs to be output before emitting the next label. */
913 +int section_changed = 0;
914 +
915 +/* Section names. The defaults here are used until an
916 + * __attribute__((section)) is seen that changes it. */
917 +char code_section_op[128] = "\t.area .text";
918 +char data_section_op[128] = "\t.area .data";
919 +char bss_section_op[128] = "\t.area .bss";
920 +const char *code_bank_option = 0;
921 +
922 +/* TRUE if the direct mode prefix might be valid in this context.
923 + * This is set by 'print_address' prior to calling output_addr_const,
924 + * which performs into 'print_direct_prefix' to do the final checks. */
925 +static int check_direct_prefix_flag;
926 +
927 +/* Nonzero if an address is being printed in a context which does not
928 + * permit any PIC modifications to the address */
929 +static int pic_ok_for_addr_p = 1;
930 +
931 +/* Current code page. This supports machines which can do bank
932 + * switching to allow for more than 64KB of code/data. */
933 +char far_code_page[64];
934 +
935 +/* Current bank name */
936 +static char current_bank_name[8] = "-1";
937 +
938 +/* Default bank name */
939 +static char default_code_bank_name[8] = "-1";
940 +
941 +/* Direct memory reserved as soft registers */
942 +unsigned int m6809_soft_regs = 0;
943 +
944 +/* ABI version */
945 +unsigned int m6809_abi_version = M6809_ABI_VERSION_REGS;
946 +
947 +
948 +/**
949 + * Called after options have been parsed.
950 + * If overrides have been specified on the command-line, then
951 + * these values are copied into the main storage variables.
952 + */
953 +void
954 +m6809_override_options (void)
955 +{
956 + /* Handle -mfar-code-page */
957 + if (far_code_page_option == 0)
958 + far_code_page_option = "__default_code_page";
959 + strcpy (far_code_page, far_code_page_option);
960 +
961 + /* Handle -mcode-section, -mdata-section, and -mbss-section */
962 + if (code_section_ptr != 0)
963 + sprintf (code_section_op, "\t.area %s", code_section_ptr);
964 + if (data_section_ptr != 0)
965 + sprintf (data_section_op, "\t.area %s", data_section_ptr);
966 + if (bss_section_ptr != 0)
967 + sprintf (bss_section_op, "\t.area %s", bss_section_ptr);
968 +
969 + /* Handle -mcode-bank */
970 + if (code_bank_option != 0)
971 + sprintf (default_code_bank_name, "%s", code_bank_option);
972 +
973 + /* Handle -mabi-version or -mno-reg-args */
974 + if (m6809_abi_version_ptr != 0)
975 + {
976 + if (!strcmp (m6809_abi_version_ptr, "stack"))
977 + m6809_abi_version = M6809_ABI_VERSION_STACK;
978 + else if (!strcmp (m6809_abi_version_ptr, "regs"))
979 + m6809_abi_version = M6809_ABI_VERSION_REGS;
980 + else if (!strcmp (m6809_abi_version_ptr, "bx"))
981 + m6809_abi_version = M6809_ABI_VERSION_BX;
982 + else if (!strcmp (m6809_abi_version_ptr, "latest"))
983 + m6809_abi_version = M6809_ABI_VERSION_LATEST;
984 + else
985 + m6809_abi_version = atoi (m6809_abi_version_ptr);
986 + }
987 +
988 + /* The older -mno-reg-args option is deprecated, and treated
989 + as -mabi=stack. */
990 + if (!TARGET_REG_ARGS)
991 + {
992 + warning (WARNING_OPT "-mno-reg-args deprecated; use -mabi=stack instead.");
993 + m6809_abi_version = M6809_ABI_VERSION_STACK;
994 + }
995 +
996 + /* -fexceptions is unsupported */
997 + flag_exceptions = 0;
998 + flag_non_call_exceptions = 0;
999 + flag_unwind_tables = 0;
1000 +}
1001 +
1002 +
1003 +/**
1004 + * Output prefix that directs the assembler to use a direct-mode
1005 + * instruction if globally enabled, address is a symbol, and symbol
1006 + * has been marked as in direct page. Also, never do this if
1007 + * using the indirect mode. */
1008 +void
1009 +print_direct_prefix (FILE * file, rtx addr)
1010 +{
1011 + if (TARGET_DIRECT &&
1012 + (GET_CODE (addr) == SYMBOL_REF) &&
1013 + SYMBOL_REF_FLAG (addr) &&
1014 + check_direct_prefix_flag)
1015 + {
1016 + putc ('*', file);
1017 + }
1018 +}
1019 +
1020 +
1021 +/** Prints an operand (that is not an address) in assembly from RTL. */
1022 +void
1023 +print_operand (FILE * file, rtx x, int code)
1024 +{
1025 + if (REG_P (x)) {
1026 + /* gcc currently allocates the entire 16-bit 'd' register
1027 + * even when it only needs an 8-bit value. So here it
1028 + * is tricked into printing only the lower 8-bit 'b'
1029 + * register into the assembly output.
1030 + *
1031 + * Eventually gcc should be modified to allocate a/b
1032 + * independently and this hack can be removed.
1033 + *
1034 + * Occasionally, we may want to do an operation using
1035 + * the 'a' register instead of 'b'; use the 'A' code
1036 + * to specify that.
1037 + */
1038 + if (code == 'A')
1039 + fputs ("a", file);
1040 + else if ((BYTE_MODE (x)) && (REGNO (x) == HARD_D_REGNUM))
1041 + fputs ("b", file);
1042 + else if (M_REG_P (x) && code == 'L')
1043 + /* Soft registers can be treated like memory and accessed
1044 + * at a particular offset. TODO : handle 'W' */
1045 + fputs (reg_names[REGNO (x)+1], file);
1046 + else
1047 + fputs (reg_names[REGNO (x)], file);
1048 + }
1049 +
1050 + else if (MEM_P (x)) {
1051 + last_mem_size = GET_MODE_SIZE (GET_MODE (x));
1052 + if (code == 'L') { /* LSH of word address */
1053 + if (GET_CODE (XEXP (x, 0)) == MEM)
1054 + {
1055 + /* Offseting an indirect addressing mode is not supported */
1056 + error ("expression too complex for 6809 (offset indirect mode)");
1057 + debug_rtx (x);
1058 + }
1059 + else
1060 + x = adjust_address (x, QImode, 1);
1061 + }
1062 + else if (code == 'M') { /* MSH of word address */
1063 + if (GET_CODE (XEXP (x, 0)) == MEM)
1064 + {
1065 + /* Offseting an indirect addressing mode is not supported */
1066 + error ("expression too complex for 6809 (offset indirect mode)");
1067 + debug_rtx (x);
1068 + }
1069 + else
1070 + x = adjust_address (x, QImode, 0);
1071 + }
1072 + else if (code == 'W') { /* least significant half of 32-bit */
1073 + x = adjust_address (x, HImode, 2);
1074 + }
1075 +
1076 + pic_ok_for_addr_p = (code != 'C');
1077 + output_address (XEXP (x, 0));
1078 + }
1079 +
1080 + else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != DImode) {
1081 + union { double d; int i[2]; } u;
1082 + u.i[0] = CONST_DOUBLE_LOW (x);
1083 + u.i[1] = CONST_DOUBLE_HIGH (x);
1084 + fprintf (file, "#%#9.9g", u.d);
1085 + }
1086 +
1087 + else if (code == 'R') {
1088 + fprintf (file, "%s",
1089 + m6809_get_regs_printable (INTVAL (x)));
1090 + }
1091 +
1092 + else {
1093 + if (code == 'L') { /* LSH of word address */
1094 + x = gen_rtx_CONST_INT (VOIDmode, (INTVAL(x) & 0xff));
1095 + }
1096 + else if (code == 'M') { /* MSH of word address */
1097 + x = gen_rtx_CONST_INT (VOIDmode, ((INTVAL(x) >> 8) & 0xff));
1098 + }
1099 +
1100 + putc ('#', file);
1101 + output_addr_const (file, x);
1102 + }
1103 +}
1104 +
1105 +
1106 +/** Prints an address operand to assembler from its RTL representation. */
1107 +void
1108 +print_operand_address (FILE *file, rtx addr)
1109 +{
1110 + register rtx base = 0;
1111 + register rtx offset = 0;
1112 + int regno;
1113 + int indirect_flag = 0;
1114 +
1115 + check_direct_prefix_flag = 0;
1116 +
1117 + /*** check for indirect addressing ***/
1118 + if (MEM_P (addr)) {
1119 + last_mem_size = GET_MODE_SIZE (GET_MODE (addr));
1120 + addr = XEXP (addr, 0);
1121 + if (pic_ok_for_addr_p)
1122 + {
1123 + indirect_flag = 1;
1124 + fprintf (file, "[");
1125 + }
1126 + }
1127 +
1128 +
1129 + switch (GET_CODE (addr)) {
1130 + case REG:
1131 + regno = REGNO (addr);
1132 + fprintf (file, ",%s", reg_names[regno]);
1133 + break;
1134 +
1135 + case PRE_DEC:
1136 + regno = REGNO (XEXP (addr, 0));
1137 + fputs (((last_mem_size == 1) ? ",-" : ",--"), file);
1138 + fprintf (file, "%s", reg_names[regno]);
1139 + break;
1140 +
1141 + case POST_INC:
1142 + regno = REGNO (XEXP (addr, 0));
1143 + fprintf (file, ",%s", reg_names[regno]);
1144 + fputs (((last_mem_size == 1) ? "+" : "++"), file);
1145 + break;
1146 +
1147 + case PLUS:
1148 + base = XEXP (addr, 0);
1149 + if (MEM_P (base))
1150 + base = XEXP (base, 0);
1151 +
1152 + offset = XEXP (addr, 1);
1153 + if (MEM_P (offset))
1154 + offset = XEXP (offset, 0);
1155 +
1156 + if ((CONSTANT_ADDRESS_P (base)) && (CONSTANT_ADDRESS_P (offset))) {
1157 + if (!indirect_flag)
1158 + check_direct_prefix_flag = 1;
1159 + output_addr_const (file, base);
1160 + check_direct_prefix_flag = 0;
1161 + fputs ("+", file);
1162 + output_addr_const (file, offset);
1163 + }
1164 +
1165 + else if ((CONSTANT_ADDRESS_P (base)) && (A_REG_P (offset))) {
1166 + output_addr_const (file, base);
1167 + fprintf (file, ",%s", reg_names[REGNO (offset)]);
1168 + }
1169 +
1170 + else if ((CONSTANT_ADDRESS_P (offset)) && (A_REG_P (base))) {
1171 + output_addr_const (file, offset);
1172 + fprintf (file, ",%s", reg_names[REGNO (base)]);
1173 + }
1174 +
1175 + /*** accumulator offset ***/
1176 + else if (((D_REG_P (offset)) || (Q_REG_P (offset)))
1177 + && (A_REG_P (base))) {
1178 + fprintf (file, "%s,%s",
1179 + reg_names[REGNO (offset)], reg_names[REGNO (base)]);
1180 + }
1181 +
1182 + else if (((D_REG_P (base)) || (Q_REG_P (base)))
1183 + && (A_REG_P (offset))) {
1184 + fprintf (file, "%s,%s",
1185 + reg_names[REGNO (base)], reg_names[REGNO (offset)]);
1186 + }
1187 +
1188 + else if (GET_CODE (base) == PRE_DEC) {
1189 + regno = REGNO (XEXP (base, 0));
1190 + fputs (((last_mem_size == 1) ? ",-" : ",--"), file);
1191 + fprintf (file, "%s", reg_names[regno]);
1192 + }
1193 +
1194 + else
1195 + abort ();
1196 +
1197 + break;
1198 +
1199 + default:
1200 + /* Set this global before calling output_addr_const() */
1201 + if (!indirect_flag)
1202 + check_direct_prefix_flag = 1;
1203 +
1204 + /* When printing a SYMBOL_REF in PIC mode, do not print the leading
1205 + * '#' and follow it by ',pcr' to enable relative addressing. */
1206 + if (flag_pic && pic_ok_for_addr_p && GET_CODE (addr) == SYMBOL_REF)
1207 + {
1208 + ASM_OUTPUT_SYMBOL_REF (file, addr);
1209 + fputs (",pcr", file);
1210 + pic_ok_for_addr_p = 1;
1211 + }
1212 + else
1213 + {
1214 + output_addr_const (file, addr);
1215 + }
1216 +
1217 + check_direct_prefix_flag = 0;
1218 + break;
1219 + }
1220 +
1221 + if (indirect_flag)
1222 + fprintf (file, "]");
1223 +}
1224 +
1225 +/*-------------------------------------------------------------------
1226 + Update the CC Status
1227 +---------------------------------------------------------------------
1228 + Set the cc_status for the results of an insn whose pattern is EXP.
1229 + We assume that jumps don't affect the condition codes.
1230 + All else, clobbers the condition codes, by assumption.
1231 +
1232 + We assume that ALL add, minus, etc. instructions effect the condition
1233 + codes.
1234 +-------------------------------------------------------------------*/
1235 +void
1236 +notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
1237 +{
1238 + int src_code;
1239 + int dst_code;
1240 +
1241 + /*** recognize SET insn's ***/
1242 + if (GET_CODE (exp) == SET)
1243 + {
1244 + src_code = GET_CODE (SET_SRC (exp));
1245 + dst_code = GET_CODE (SET_DEST (exp));
1246 +
1247 + /* Jumps do not alter the cc's. */
1248 + if (SET_DEST (exp) == pc_rtx)
1249 + return;
1250 +
1251 + /* Moving one register into another register (tfr):
1252 + Doesn't alter the cc's. */
1253 + if (REG_P (SET_DEST (exp)) && (REG_P (SET_SRC (exp))))
1254 + return;
1255 +
1256 + /* Moving memory into a register (load): Sets cc's. */
1257 + if (REG_P (SET_DEST (exp)) && src_code == MEM) {
1258 + cc_status.value1 = SET_SRC (exp);
1259 + cc_status.value2 = SET_DEST (exp);
1260 + cc_status.flags |= CC_NO_OVERFLOW;
1261 + return;
1262 + }
1263 +
1264 + /* Moving register into memory (store): Sets cc's. */
1265 + if (dst_code == MEM && REG_P (SET_SRC (exp))) {
1266 + cc_status.value1 = SET_SRC (exp);
1267 + cc_status.value2 = SET_DEST (exp);
1268 + cc_status.flags |= CC_NO_OVERFLOW;
1269 + return;
1270 + }
1271 +
1272 + /* Function calls clobber the cc's. */
1273 + else if (GET_CODE (SET_SRC (exp)) == CALL) {
1274 + CC_STATUS_INIT;
1275 + return;
1276 + }
1277 +
1278 + /* Tests and compares set the cc's in predictable ways. */
1279 + else if (SET_DEST (exp) == cc0_rtx)
1280 + {
1281 + cc_status.flags = 0;
1282 + cc_status.value1 = SET_SRC (exp);
1283 + cc_status.value2 = SET_DEST (exp);
1284 + return;
1285 + }
1286 +
1287 + else if (A_REG_P (SET_DEST (exp)))
1288 + {
1289 + CC_STATUS_INIT;
1290 + return;
1291 + }
1292 +
1293 + else
1294 + {
1295 + /* Certain instructions affect the condition codes. */
1296 + switch (src_code)
1297 + {
1298 + case PLUS:
1299 + case MINUS:
1300 + case NEG:
1301 + case ASHIFT:
1302 + /* These instructions set the condition codes,
1303 + * and may modify the V bit. */
1304 + cc_status.flags |= CC_NO_OVERFLOW;
1305 + /* FALLTHRU */
1306 +
1307 + case AND:
1308 + case IOR:
1309 + case XOR:
1310 + case ASHIFTRT:
1311 + case LSHIFTRT:
1312 + /* These instructions set the condition codes,
1313 + * but cannot overflow (V=0). */
1314 + cc_status.value1 = SET_SRC (exp);
1315 + cc_status.value2 = SET_DEST (exp);
1316 + break;
1317 +
1318 + default:
1319 + /* Everything else is clobbered */
1320 + CC_STATUS_INIT;
1321 + }
1322 + return;
1323 + }
1324 + } /* SET */
1325 +
1326 + else if (GET_CODE (exp) == PARALLEL
1327 + && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
1328 + {
1329 + if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
1330 + return;
1331 + if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
1332 + {
1333 + CC_STATUS_INIT;
1334 + cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
1335 + return;
1336 + }
1337 + }
1338 +
1339 + /*** default action if we haven't recognized something
1340 + and returned earlier ***/
1341 + CC_STATUS_INIT;
1342 +}
1343 +
1344 +
1345 +/** Returns nonzero if the expression EXP can be implemented using one
1346 + * of the 6809's single operand instructions. */
1347 +int
1348 +m6809_single_operand_operator (rtx exp)
1349 +{
1350 + rtx op1;
1351 + HOST_WIDE_INT val;
1352 + enum rtx_code code;
1353 +
1354 + debug_rtx(exp);
1355 +
1356 + code = GET_CODE (exp);
1357 +
1358 + /* Unary operators always qualify */
1359 + switch (code)
1360 + {
1361 + case NEG:
1362 + case NOT:
1363 + return 1;
1364 +
1365 + default:
1366 + break;
1367 + }
1368 +
1369 + /* Binary operators can only qualify if the second
1370 + * argument is a CONST_INT of certain value. */
1371 + op1 = XEXP (exp, 1);
1372 + if (GET_CODE (op1) != CONST_INT)
1373 + return 0;
1374 + val = INTVAL (op1);
1375 + switch (code)
1376 + {
1377 + case PLUS:
1378 + case MINUS:
1379 + if (val == -1 || val == 1)
1380 + return 1;
1381 + break;
1382 +
1383 + case ASHIFT:
1384 + case ASHIFTRT:
1385 + case LSHIFTRT:
1386 + case ROTATE:
1387 + case ROTATERT:
1388 + if (val == 1)
1389 + return 1;
1390 + break;
1391 +
1392 + default:
1393 + break;
1394 + }
1395 +
1396 + return 0;
1397 +}
1398 +
1399 +
1400 +/** Return a bitarray of the hard registers which are used by a function. */
1401 +unsigned int
1402 +m6809_get_live_regs (void)
1403 +{
1404 + unsigned int regs = 0;
1405 + int regno;
1406 +
1407 + if (frame_pointer_needed)
1408 + regs |= (1 << HARD_FRAME_POINTER_REGNUM);
1409 +
1410 + for (regno = HARD_X_REGNUM; regno <= HARD_U_REGNUM; regno++)
1411 + if (df_regs_ever_live_p (regno) && ! call_used_regs[regno])
1412 + regs |= (1 << regno);
1413 +
1414 + return regs;
1415 +}
1416 +
1417 +
1418 +/** Return a printable version of a list of hard registers, suitable
1419 + * for use in a PSHx or PULx insn. */
1420 +const char *
1421 +m6809_get_regs_printable (unsigned int regs)
1422 +{
1423 + static char list[64];
1424 + char *listp = list;
1425 + unsigned int regno;
1426 +
1427 + for (regno=0; regno < FIRST_PSEUDO_REGISTER; regno++)
1428 + if ((regs & (1 << regno)) && !S_REGNO_P (regno))
1429 + listp += sprintf (listp,
1430 + (listp == list) ? "%s" : ",%s", reg_names[regno]);
1431 +
1432 + return list;
1433 +}
1434 +
1435 +
1436 +/** Return the total number of bytes covered by a set of hard registers. */
1437 +unsigned int
1438 +m6809_get_regs_size (unsigned int regs)
1439 +{
1440 + unsigned int regno;
1441 + unsigned int size = 0;
1442 +
1443 + for (regno=0; regno < FIRST_PSEUDO_REGISTER; regno++)
1444 + {
1445 + /* Only count register in the given register set */
1446 + if (REGSET_CONTAINS_P (regno, regs))
1447 + {
1448 + /* Add 1 or 2 byte, depending on the size of the register.
1449 + * Since 'D' may be in both sets, check for WORD_REGSET first. */
1450 + if (REGSET_CONTAINS_P(regno, WORD_REGSET))
1451 + size += 2;
1452 + else if (REGSET_CONTAINS_P(regno, BYTE_REGSET))
1453 + size++;
1454 + }
1455 + }
1456 + return size;
1457 +}
1458 +
1459 +
1460 +/* Given the target of call instruction in X,
1461 + * return the tree node that contains the function declaration for
1462 + * that target.
1463 + *
1464 + * If the rtx or the tree do not appear valid for any reason,
1465 + * then return NULL_TREE.
1466 + */
1467 +static tree call_target_decl (rtx x)
1468 +{
1469 + tree decl;
1470 +
1471 + /* Make sure the target is really a MEM. */
1472 + if (!x || !MEM_P (x))
1473 + return NULL_TREE;
1474 +
1475 + /* Make sure the address is a SYMBOL_REF. */
1476 + x = XEXP (x, 0);
1477 + if (!x || (GET_CODE (x) != SYMBOL_REF))
1478 + return NULL_TREE;
1479 +
1480 + /* Get the declaration of this symbol */
1481 + decl = SYMBOL_REF_DECL (x);
1482 +
1483 + /* Make sure the declaration is really a function. */
1484 + if (!decl || (TREE_CODE(decl) != FUNCTION_DECL))
1485 + return NULL_TREE;
1486 +
1487 + return decl;
1488 +}
1489 +
1490 +
1491 +/** Returns nonzero if a function, whose declaration is in DECL,
1492 + * was declared to have the attribute given by ATTR_NAME. */
1493 +int
1494 +m6809_function_has_type_attr_p (tree decl, const char *attr_name)
1495 +{
1496 + tree type;
1497 +
1498 + type = TREE_TYPE (decl);
1499 + return lookup_attribute (attr_name, TYPE_ATTRIBUTES (type)) != NULL;
1500 +}
1501 +
1502 +
1503 +
1504 +/** Returns nonzero if the current function was declared to have the
1505 + * attribute given by ATTR_NAME. */
1506 +int
1507 +m6809_current_function_has_type_attr_p (const char *attr_name)
1508 +{
1509 + return m6809_function_has_type_attr_p (current_function_decl, attr_name);
1510 +}
1511 +
1512 +
1513 +/** Return nonzero if the current function has no return value. */
1514 +int
1515 +m6809_current_function_is_void (void)
1516 +{
1517 + return (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))));
1518 +}
1519 +
1520 +
1521 +/** Get the value of a declaration's 'bank', as set by the 'bank'
1522 + * attribute. If no bank was declared, it returns NULL by default. */
1523 +const char *
1524 +m6809_get_decl_bank (tree decl)
1525 +{
1526 + tree attr;
1527 +
1528 + /* Lookup the 'bank' attribute. If it does not exist, then
1529 + * return NULL */
1530 + attr = lookup_attribute ("bank", DECL_ATTRIBUTES (decl));
1531 + if (attr == NULL_TREE)
1532 + return NULL;
1533 +
1534 + /* Make sure it has a value assigned to it */
1535 + attr = TREE_VALUE (attr);
1536 + if (attr == NULL_TREE)
1537 + {
1538 + warning (WARNING_OPT "banked function did not declare a bank number");
1539 + return NULL;
1540 + }
1541 +
1542 + /* Return the bank name */
1543 + attr = TREE_VALUE (attr);
1544 + return TREE_STRING_POINTER (attr);
1545 +}
1546 +
1547 +
1548 +void
1549 +m6809_declare_function_name (FILE *asm_out_file, const char *name, tree decl)
1550 +{
1551 + /* Check the function declaration for special properties.
1552 + *
1553 + * If the function was declare with __attribute__((bank)), output
1554 + * assembler definitions to force the function to go into the named
1555 + * bank.
1556 + */
1557 + const char *bank_name = m6809_get_decl_bank (decl);
1558 + if (bank_name != NULL)
1559 + {
1560 + /* Declare __self_bank as a local assembler value that denotes
1561 + * which bank the current function is in. This is required only
1562 + * when the bank actually changes. */
1563 + if (strcmp (bank_name, current_bank_name))
1564 + {
1565 + fprintf (asm_out_file, "__self_bank\t.equ %s\n", bank_name);
1566 + strcpy (current_bank_name, bank_name);
1567 + }
1568 +
1569 + /* Declare a global assembler value that denotes which bank the
1570 + * named function is in. */
1571 + fprintf (asm_out_file, "__%s_bank\t.gblequ %s\n", name, bank_name);
1572 +
1573 + /* Force the current function into a new area */
1574 + fprintf (asm_out_file, "\t.bank bank_%s (FSFX=_%s)\n",
1575 + bank_name, bank_name);
1576 + fprintf (asm_out_file, "\t.area bank_%s (BANK=bank_%s)\n",
1577 + bank_name, bank_name);
1578 + }
1579 +
1580 + /* Emit the label for the function's name */
1581 + ASM_OUTPUT_LABEL (asm_out_file, name);
1582 +}
1583 +
1584 +#if 0
1585 +/**
1586 + * Handle pragmas. Note that only the last branch pragma seen in the
1587 + * source has any affect on code generation.
1588 + */
1589 +
1590 +#define BAD_PRAGMA(msgid, arg) \
1591 + do { warning (WARNING_OPT msgid, arg); return -1; } while (0)
1592 +
1593 +static int
1594 +pragma_parse (const char *name, tree *sect)
1595 +{
1596 + tree s, x;
1597 +
1598 + if (pragma_lex (&x) != CPP_OPEN_PAREN)
1599 + BAD_PRAGMA ("missing '(' after '#pragma %s' - ignored", name);
1600 +
1601 + if (pragma_lex (&s) != CPP_STRING)
1602 + BAD_PRAGMA ("missing section name in '#pragma %s' - ignored", name);
1603 +
1604 + if (pragma_lex (&x) != CPP_CLOSE_PAREN)
1605 + BAD_PRAGMA ("missing ')' for '#pragma %s' - ignored", name);
1606 +
1607 + if (pragma_lex (&x) != CPP_EOF)
1608 + warning (WARNING_OPT "junk at end of '#pragma %s'", name);
1609 +
1610 + *sect = s;
1611 + return 0;
1612 +}
1613 +
1614 +
1615 +/*
1616 + * Handle #pragma section.
1617 + * This is deprecated; code should use __attribute__(section("name"))
1618 + * instead.
1619 + */
1620 +void pragma_section (cpp_reader *pfile ATTRIBUTE_UNUSED)
1621 +{
1622 + tree sect;
1623 +
1624 + if (pragma_parse ("section", &sect))
1625 + return;
1626 +
1627 + snprintf (code_section_op, 6+TREE_STRING_LENGTH (sect),
1628 + ".area\t%s", TREE_STRING_POINTER (sect));
1629 + snprintf (data_section_op, 6+TREE_STRING_LENGTH (sect),
1630 + ".area\t%s", TREE_STRING_POINTER (sect));
1631 +
1632 + /* Mark a flag that sections have changed. Upon emitting another
1633 + * declaration, the new .area directive will be written. */
1634 + section_changed++;
1635 +}
1636 +#endif
1637 +
1638 +/**
1639 + * Check a `double' value for validity for a particular machine mode.
1640 + * Called by the CHECK_FLOAT_VALUE() machine-dependent macro.
1641 + */
1642 +int
1643 +check_float_value (enum machine_mode mode, double *d, int overflow)
1644 +{
1645 + if (mode == SFmode) {
1646 + if (*d > 1.7014117331926443e+38) {
1647 + error("magnitude of constant too large for `float'");
1648 + *d = 1.7014117331926443e+38;
1649 + }
1650 + else if (*d < -1.7014117331926443e+38) {
1651 + error("magnitude of constant too large for `float'");
1652 + *d = -1.7014117331926443e+38;
1653 + }
1654 + else if ((*d > 0) && (*d < 2.9387358770557188e-39)) {
1655 + warning(WARNING_OPT "`float' constant truncated to zero");
1656 + *d = 0.0;
1657 + }
1658 + else if ((*d < 0) && (*d > -2.9387358770557188e-39)) {
1659 + warning(WARNING_OPT "`float' constant truncated to zero");
1660 + *d = 0.0;
1661 + }
1662 + }
1663 + return overflow;
1664 +}
1665 +
1666 +
1667 +
1668 +/** Declare that the target supports named output sections. */
1669 +bool m6809_have_named_section = (bool)1;
1670 +
1671 +
1672 +/** Write to the assembler file a directive to place
1673 + * subsequent objects to a different section in the
1674 + * object file. ASxxxx uses the "area" directive for
1675 + * this purpose. It does not however support generalized
1676 + * alignment, and can only place items on an odd/even
1677 + * boundary. */
1678 +void
1679 +m6809_asm_named_section (
1680 + const char *name,
1681 + unsigned int flags ATTRIBUTE_UNUSED,
1682 + tree decl)
1683 +{
1684 + fprintf (asm_out_file, "\t.area\t%s\n", name);
1685 +}
1686 +
1687 +
1688 +enum reg_class
1689 +m6809_preferred_reload_class (rtx x, enum reg_class regclass)
1690 +{
1691 + /* Check cases based on type code of rtx */
1692 + switch (GET_CODE(x))
1693 + {
1694 + /*
1695 + * Observation, 2015-07-19, William Astle
1696 + *
1697 + * The original comparison for range for 16 bits was wrong, adding 0x80
1698 + * instead of 0x8000. Replaced both 8 bit and 16 bit comparisions with
1699 + * a more straight forward range comparison - excessive cleverness isn't
1700 + * really required here.
1701 + */
1702 + case CONST_INT:
1703 + /* Constants that can fit into 1 byte should be
1704 + * loaded into a Q_REGS reg */
1705 + if ((INTVAL(x) >= -128 && INTVAL(x) <= 127) &&
1706 +// if (((unsigned) (INTVAL(x) + 0x80) < 0x100) &&
1707 + (regclass > A_REGS))
1708 + return Q_REGS;
1709 +
1710 + /* 16-bit constants should be loaded into A_REGS
1711 + * when possible. gcc may already require A_REGS
1712 + * or D_REGS for certain types of instructions.
1713 + * This case applies mostly to simple copy operations
1714 + * to/from memory when any register will do, but
1715 + * it's best to avoid using D register since it is
1716 + * needed for other things.
1717 + */
1718 + else if ((INTVAL(x) >= -32768 && INTVAL(x) <= 32767) &&
1719 +// else if (((unsigned) (INTVAL(x) + 0x80) < 0x10000) &&
1720 + (regclass > A_REGS))
1721 + return A_REGS;
1722 + break;
1723 +
1724 + case SYMBOL_REF:
1725 + case LABEL_REF:
1726 + /* Addresses should always be loaded into A_REGS */
1727 + if (regclass >= A_REGS)
1728 + return (A_REGS);
1729 +
1730 + default:
1731 + break;
1732 + }
1733 +
1734 + /* Check cases based on mode of rtx */
1735 + if ((GET_MODE(x) == QImode) && (regclass != A_REGS))
1736 + return Q_REGS;
1737 +
1738 + /* Default: return whatever class reload suggested */
1739 + return regclass;
1740 +}
1741 +
1742 +
1743 +/**
1744 + * Check a new declaration for the "section" attribute.
1745 + * If it exists, and the target section is "direct", then mark
1746 + * the declaration (in RTL) to indicate special treatment.
1747 + * When the variable is referenced later, we test for this flag
1748 + * and can emit special asm text to force the assembler to use
1749 + * short instructions.
1750 + */
1751 +static void
1752 +m6809_encode_section_info (tree decl, rtx rtl, int new_decl_p ATTRIBUTE_UNUSED)
1753 +{
1754 + tree attr, id;
1755 + const char *name;
1756 + const char *decl_name;
1757 +
1758 + /* We only care about variable declarations, not functions */
1759 + if (TREE_CODE (decl) != VAR_DECL)
1760 + return;
1761 +
1762 + /* For debugging purposes only; grab the decl's name */
1763 + decl_name = IDENTIFIER_POINTER (DECL_NAME (decl));
1764 +
1765 + /* Give up if the decl doesn't have any RTL */
1766 + if (!DECL_RTL (decl))
1767 + return;
1768 +
1769 + /* See if it has a section attribute */
1770 + attr = lookup_attribute ("section", DECL_ATTRIBUTES (decl));
1771 + if (!attr)
1772 + return;
1773 +
1774 + /* See if the section attribute has a value */
1775 + id = TREE_VALUE (TREE_VALUE (attr));
1776 + if (!id)
1777 + return;
1778 + name = TREE_STRING_POINTER (id);
1779 + if (!name)
1780 + return;
1781 +
1782 + /* See if the value is 'direct'. If so, mark it. */
1783 + if (!strcmp (name, "direct"))
1784 + SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
1785 +}
1786 +
1787 +
1788 +/**
1789 + * Output code to perform a complex shift, for which there is no
1790 + * direct support in the instruction set.
1791 + *
1792 + * shift1 is an instruction pattern for performing a 1-bit modification.
1793 + * This code wraps that pattern in a loop to perform the shift N times,
1794 + * where N is given by the address register in operands[2].
1795 + *
1796 + * To support 16-bit shifts, shift2 can also be provided: it is
1797 + * a second instruction to be included in the loop. 8-bit shift
1798 + * insns will pass NULL here.
1799 + *
1800 + * The insn length of shift1/shift2 is assumed to be 1 byte,
1801 + * which works in all of the cases it is needed so far.
1802 + */
1803 +static void
1804 +m6809_gen_register_shift (
1805 + rtx *operands,
1806 + const char *shift1,
1807 + const char *shift2 )
1808 +{
1809 + char beq_pattern[32];
1810 + char bra_pattern[32];
1811 +
1812 + int shiftlen = (shift1 && shift2) ? 2 : 1;
1813 + int cmplen = (REGNO (operands[2]) == HARD_X_REGNUM) ? 3 : 4;
1814 +
1815 + int beq_offset = 2 + shiftlen + 2;
1816 + int bra_offset = shiftlen + 2 + cmplen + 2;
1817 +
1818 + sprintf (beq_pattern, "beq\t.+%d", beq_offset);
1819 + sprintf (bra_pattern, "bra\t.-%d", bra_offset);
1820 +
1821 + output_asm_insn ("pshs\t%2", operands);
1822 + output_asm_insn ("lea%2\t-1,%2", operands);
1823 + output_asm_insn ("cmp%2\t#-1", operands);
1824 + output_asm_insn (beq_pattern, operands);
1825 + if (shift1)
1826 + output_asm_insn (shift1, operands);
1827 + if (shift2)
1828 + output_asm_insn (shift2, operands);
1829 + output_asm_insn (bra_pattern, operands);
1830 + output_asm_insn ("puls\t%2", operands);
1831 +}
1832 +
1833 +
1834 +/** Generate RTL for the upper 8-bits of a 16-bit constant. */
1835 +rtx
1836 +gen_rtx_const_high (rtx r)
1837 +{
1838 + unsigned char v = (INTVAL (r) >> 8) & 0xFF;
1839 + signed char s = (signed char)v;
1840 + return gen_int_mode (s, QImode);
1841 +}
1842 +
1843 +
1844 +/** Generate RTL for the lower 8-bits of a 16-bit constant. */
1845 +rtx
1846 +gen_rtx_const_low (rtx r)
1847 +{
1848 + unsigned char v = INTVAL (r) & 0xFF;
1849 + signed char s = (signed char)v;
1850 + return gen_int_mode (s, QImode);
1851 +}
1852 +
1853 +
1854 +/** Generate RTL to allocate/free bytes on the stack.
1855 + * CODE is given as MINUS when allocating and PLUS when freeing,
1856 + * to match the semantics of a downward-growing stack. SIZE
1857 + * is always given as a positive integer.
1858 + */
1859 +static rtx
1860 +gen_rtx_stack_adjust (enum rtx_code code, int size)
1861 +{
1862 + if (size <= 0)
1863 + return NULL_RTX;
1864 +
1865 + if (code == MINUS)
1866 + size = -size;
1867 +
1868 + return gen_rtx_SET (Pmode, stack_pointer_rtx,
1869 + gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1870 + gen_int_mode (size, HImode)));
1871 +}
1872 +
1873 +
1874 +/** Generate RTL to push/pop a set of registers. */
1875 +rtx
1876 +gen_rtx_register_pushpop (int op, int regs)
1877 +{
1878 + rtx nregs = gen_int_mode (regs, QImode);
1879 +
1880 + if (op == UNSPEC_PUSH_RS)
1881 + return gen_register_push (nregs);
1882 + else
1883 + return gen_register_pop (nregs);
1884 +}
1885 +
1886 +
1887 +/* Given a register set REGS, where the bit positions correspond to
1888 + * hard register numbers, return another bitmask that represents the
1889 + * order in which those registers would be pushed/popped.
1890 + * Registers that are pushed first have higher bit positions.
1891 + * The pop order is just the reverse bitmask.
1892 + * These values are the same as the bitmasks actually used in the
1893 + * machine instructions. */
1894 +static unsigned int
1895 +register_push_order (int regs)
1896 +{
1897 + unsigned int order = 0;
1898 +
1899 + if (REGSET_CONTAINS_P (HARD_PC_REGNUM, regs))
1900 + order |= 0x80;
1901 + if (REGSET_CONTAINS_P (HARD_U_REGNUM, regs))
1902 + order |= 0x40;
1903 + if (REGSET_CONTAINS_P (HARD_Y_REGNUM, regs))
1904 + order |= 0x20;
1905 + if (REGSET_CONTAINS_P (HARD_X_REGNUM, regs))
1906 + order |= 0x10;
1907 + if (REGSET_CONTAINS_P (HARD_DP_REGNUM, regs))
1908 + order |= 0x8;
1909 + if (REGSET_CONTAINS_P (HARD_B_REGNUM, regs))
1910 + order |= 0x4;
1911 + if (REGSET_CONTAINS_P (HARD_A_REGNUM, regs))
1912 + order |= 0x2;
1913 + if (REGSET_CONTAINS_P (HARD_CC_REGNUM, regs))
1914 + order |= 0x1;
1915 +
1916 + if (REGSET_CONTAINS_P (HARD_D_REGNUM, regs))
1917 + order |= (0x4 | 0x2);
1918 + return order;
1919 +}
1920 +
1921 +
1922 +/* Returns nonzero if two consecutive push or pop instructions,
1923 + * as determined by the OP, can be merged into a single instruction.
1924 + * The first instruction in the sequence pushes/pops REGS1; the
1925 + * second applies to REGS2.
1926 + *
1927 + * If true, the resulting instruction can use (regs1 | regs2)
1928 + * safely.
1929 + */
1930 +int
1931 +m6809_can_merge_pushpop_p (int op, int regs1, int regs2)
1932 +{
1933 + /* Register sets must not overlap */
1934 + if (regs1 & regs2)
1935 + return 0;
1936 +
1937 + if (op == UNSPEC_PUSH_RS)
1938 + return (register_push_order (regs1) > register_push_order (regs2));
1939 + else if (op == UNSPEC_POP_RS)
1940 + return (register_push_order (regs1) < register_push_order (regs2));
1941 + else
1942 + return 0;
1943 +}
1944 +
1945 +
1946 +/** Emit instructions for making a library call.
1947 + * MODE is the mode of the operation.
1948 + * NAME is the library function name.
1949 + * OPERANDS is the rtx array provided by the recognizer.
1950 + * COUNT is the number of input operands to the call, and
1951 + * should be 1 for a unary op or 2 for a binary op.
1952 + */
1953 +void
1954 +emit_libcall_insns (enum machine_mode mode,
1955 + const char *name,
1956 + rtx *operands,
1957 + int count)
1958 +{
1959 + /* Generate an rtx for the call target. */
1960 + rtx symbol = gen_rtx_SYMBOL_REF (Pmode, name);
1961 +
1962 + /* Emit the library call. Slightly different based
1963 + on the number of operands */
1964 + if (count == 2)
1965 + emit_library_call (symbol, LCT_NORMAL, mode,
1966 + 2, operands[1], mode, operands[2], mode);
1967 + else
1968 + emit_library_call (symbol, LCT_NORMAL, mode,
1969 + 1, operands[1], mode);
1970 +
1971 + /* The library call is expected to put its result
1972 + in LIBCALL_VALUE, so need to copy it into the destination. */
1973 + emit_move_insn (operands[0], LIBCALL_VALUE(mode));
1974 +}
1975 +
1976 +
1977 +/**
1978 + * A small helper function that writes out a single branch instruction.
1979 + * OPCODE is the short name, e.g. "ble".
1980 + * OPERANDS has the rtx for the target label.
1981 + * LONG_P is nonzero if we are emitting a long branch, and need to
1982 + * prepend an 'l' to the opcode name.
1983 + */
1984 +void output_branch_insn1 (const char *opcode, rtx *operands, int long_p)
1985 +{
1986 + char pattern[64];
1987 + sprintf (pattern, "%s%s\t%%l0", long_p ? "l" : "", opcode);
1988 + output_asm_insn (pattern, operands);
1989 +}
1990 +
1991 +/**
1992 + * Output a branch/conditional branch insn of the proper
1993 + * length. code identifies the particular branch insn.
1994 + * operands holds the branch target in operands[0].
1995 + * length says what the size of this insn should be.
1996 + * Based on the length, we know whether it should be a
1997 + * short (8-bit) or long (16-bit) branch.
1998 + */
1999 +const char *
2000 +output_branch_insn (enum rtx_code code, rtx *operands, int length)
2001 +{
2002 + int shortform;
2003 +
2004 + /* Decide whether or not to use the long or short form.
2005 + * Calculate automatically based on insn lengths. */
2006 + shortform = ((length > 2) ? 0 : 1);
2007 +
2008 + /* Determine the proper opcode.
2009 + * Use the short (2-byte) opcode if the target is within
2010 + * reach. Otherwise, use jmp (3-byte opcode), unless
2011 + * compiling with -fpic, in which case we'll need to use
2012 + * lbra (4-byte opcode).
2013 + */
2014 + switch (code)
2015 + {
2016 + case LABEL_REF:
2017 + if (shortform)
2018 + output_branch_insn1 ("bra", operands, 0);
2019 + else if (flag_pic)
2020 + output_branch_insn1 ("bra", operands, 1);
2021 + else
2022 + output_branch_insn1 ("jmp", operands, 0);
2023 + break;
2024 + case EQ:
2025 + output_branch_insn1 ("beq", operands, !shortform);
2026 + break;
2027 + case NE:
2028 + output_branch_insn1 ("bne", operands, !shortform);
2029 + break;
2030 + case GT:
2031 + output_branch_insn1 ("bgt", operands, !shortform);
2032 + break;
2033 + case GTU:
2034 + output_branch_insn1 ("bhi", operands, !shortform);
2035 + break;
2036 + case LT:
2037 + if (cc_prev_status.flags & CC_NO_OVERFLOW)
2038 + {
2039 + output_branch_insn1 ("bmi", operands, !shortform);
2040 + }
2041 + else
2042 + {
2043 + output_branch_insn1 ("blt", operands, !shortform);
2044 + }
2045 + break;
2046 + case LTU:
2047 + output_branch_insn1 ("blo", operands, !shortform);
2048 + break;
2049 + case GE:
2050 + if (cc_prev_status.flags & CC_NO_OVERFLOW)
2051 + {
2052 + output_branch_insn1 ("bpl", operands, !shortform);
2053 + }
2054 + else
2055 + {
2056 + output_branch_insn1 ("bge", operands, !shortform);
2057 + }
2058 + break;
2059 + case GEU:
2060 + output_branch_insn1 ("bhs", operands, !shortform);
2061 + break;
2062 + case LE:
2063 + if (cc_prev_status.flags & CC_NO_OVERFLOW)
2064 + {
2065 + output_branch_insn1 ("bmi", operands, !shortform);
2066 + output_branch_insn1 ("beq", operands, !shortform);
2067 + }
2068 + else
2069 + {
2070 + output_branch_insn1 ("ble", operands, !shortform);
2071 + }
2072 + break;
2073 + case LEU:
2074 + output_branch_insn1 ("bls", operands, !shortform);
2075 + break;
2076 + default:
2077 + abort();
2078 + break;
2079 + }
2080 + return "";
2081 +}
2082 +
2083 +
2084 +/** Returns the "cost" of an RTL expression.
2085 + * In general, the expression "COSTS_N_INSNS(1)" is used to represent
2086 + * the cost of a fast 8-bit arithmetic instruction that operates on
2087 + * a reg/mem or a reg/immed. Other costs are relative to this.
2088 + *
2089 + * Notes:
2090 + * - The cost of a REG is always zero; this cannot be changed.
2091 + *
2092 + * - On the 6809, instructions on two registers will nearly always take
2093 + * longer than those that operate on a register and a constant/memory,
2094 + * because of the way the instruction set is structured.
2095 + *
2096 + * TODO: multiply HImode by 2 should be done via shifts, instead of add.
2097 + */
2098 +static bool
2099 +m6809_rtx_costs (rtx X, int code, int outer_code ATTRIBUTE_UNUSED,
2100 + int *total, bool speed)
2101 +{
2102 + int has_const_arg = 0;
2103 + HOST_WIDE_INT const_arg;
2104 + enum machine_mode mode;
2105 + int nargs = 1;
2106 + rtx op0, op1;
2107 +
2108 + /* Data RTXs return a value between 0-3, depending on complexity.
2109 + All of these are less than COSTS_N_INSNS(1). */
2110 + switch (code)
2111 + {
2112 + case CC0:
2113 + case PC:
2114 + *total = 0;
2115 + return true;
2116 +
2117 + case CONST_INT:
2118 + if (X == const0_rtx)
2119 + {
2120 + *total = 0;
2121 + return true;
2122 + }
2123 + else if ((unsigned) INTVAL (X) < 077)
2124 + {
2125 + *total = 1;
2126 + return true;
2127 + }
2128 + else
2129 + {
2130 + *total = 2;
2131 + return true;
2132 + }
2133 +
2134 + case LABEL_REF: case CONST:
2135 + *total = 2;
2136 + return true;
2137 +
2138 + case SYMBOL_REF:
2139 + /* References to memory are made cheaper if they have
2140 + * the 'direct' mode attribute set */
2141 + *total = (SYMBOL_REF_FLAG (X)) ? 1 : 2;
2142 + return true;
2143 +
2144 + case MEM:
2145 + /* See what form of address was given */
2146 + X = XEXP (X, 0);
2147 + switch (GET_CODE (X))
2148 + {
2149 + case SYMBOL_REF:
2150 + *total = (SYMBOL_REF_FLAG (X)) ? 1 : 2;
2151 + break;
2152 +
2153 + case CONST_INT:
2154 + *total = 2;
2155 + break;
2156 +
2157 + case MEM:
2158 + *total = COSTS_N_INSNS (1) + 2;
2159 + break;
2160 +
2161 + default:
2162 + break;
2163 + }
2164 + return true;
2165 +
2166 + case CONST_DOUBLE:
2167 + /* TODO : not sure about this value. */
2168 + *total = 3;
2169 + return true;
2170 +
2171 + default:
2172 + break;
2173 + }
2174 +
2175 + /* Decode the rtx */
2176 + mode = GET_MODE (X);
2177 + op0 = XEXP (X, 0);
2178 + op1 = XEXP (X, 1);
2179 +
2180 + /* We don't implement anything in SImode or greater. */
2181 + if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (SImode))
2182 + {
2183 + *total = COSTS_N_INSNS (100);
2184 + return true;
2185 + }
2186 +
2187 + /* Figure out if there is a constant argument, and its value. */
2188 + if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
2189 + || GET_RTX_CLASS (code) == RTX_COMM_ARITH)
2190 + {
2191 + nargs = 2;
2192 + if (GET_CODE (op1) == CONST_INT)
2193 + {
2194 + has_const_arg = 1;
2195 + const_arg = INTVAL (op1);
2196 + }
2197 + }
2198 +
2199 + /* Penalize a reg/reg operation by adding MEMORY_MOVE_COST,
2200 + * Ignore soft registers, since these are really in memory.
2201 + *
2202 + * TODO: penalize HImode reg/reg for most operations, except maybe
2203 + * additions since index registers allow for that.
2204 + *
2205 + * TODO: shifts by constant N do not always require N instructions;
2206 + * some of this can be done cheaper. The number of actual insns can be
2207 + * predicted well.
2208 + */
2209 + if (nargs == 2 && REAL_REG_P (op0) && REAL_REG_P (op1))
2210 + {
2211 + *total = MEMORY_MOVE_COST (mode, Q_REGS, 0);
2212 + }
2213 + else
2214 + {
2215 + *total = 0;
2216 + }
2217 +
2218 + /* Operator RTXs are counted as COSTS_N_INSNS(N), where N is
2219 + the estimated number of actual machine instructions needed to
2220 + perform the computation. Some small adjustments are made since
2221 + some "instructions" are more complex than others. */
2222 + switch (code)
2223 + {
2224 + case PLUS: case MINUS: case COMPARE:
2225 + /* 6809 handles these natively in QImode, and in HImode as long
2226 + * as operand 1 is constant. */
2227 + if (mode == QImode || (mode == HImode && has_const_arg))
2228 + *total += COSTS_N_INSNS (1);
2229 + else
2230 + *total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
2231 +
2232 + /* -1, 0, and 1 can be done using inherent instructions
2233 + * for PLUS and MINUS in QImode, so don't add extra cost. */
2234 + if (has_const_arg
2235 + && (mode == QImode || mode == HImode)
2236 + && (const_arg == -1 || const_arg == 0 || const_arg == 1)
2237 + && (code == PLUS || code == MINUS))
2238 + {
2239 + return true;
2240 + }
2241 + break;
2242 +
2243 + case AND: case IOR: case XOR:
2244 + case NEG: case NOT:
2245 + /* 6809 handles these natively in QImode, but requires
2246 + * splitting in HImode. Treat these as 2 insns. */
2247 + *total += COSTS_N_INSNS (1) * GET_MODE_SIZE (mode);
2248 + break;
2249 +
2250 + case ASHIFT: case ASHIFTRT: case LSHIFTRT:
2251 + case ROTATE: case ROTATERT:
2252 + /* 6809 can do shift/rotates of a QImode by a constant in
2253 + * 1 insn times the shift count, or in HImode by a constant
2254 + * by splitting to 2 insns.
2255 + *
2256 + * Shift by a nonconstant will take significantly longer
2257 + * than any of these. */
2258 + if (has_const_arg)
2259 + {
2260 + const_arg %= (GET_MODE_SIZE (mode) * 8);
2261 + if (const_arg == 0)
2262 + {
2263 + *total += COSTS_N_INSNS(1);
2264 + return true;
2265 + }
2266 +
2267 + /* HImode shifts greater than 8 get optimized due
2268 + * to register transfer from b to a; this cuts down the
2269 + * cost. */
2270 + if (const_arg >= 8)
2271 + {
2272 + *total += COSTS_N_INSNS (1);
2273 + const_arg -= 8;
2274 + }
2275 +
2276 + /* The computed cost is 'const_arg' 1-bit shifts, doubled
2277 + if in HImode, minus the cost of the constant itself which
2278 + will be added in later but really shouldn't be. */
2279 + *total += COSTS_N_INSNS (const_arg) * GET_MODE_SIZE (mode) - 1;
2280 + return true;
2281 + }
2282 + else
2283 + {
2284 + /* It may take up to 7 iterations of about 6-7 real
2285 + * instructions, so make this expensive. */
2286 + *total += COSTS_N_INSNS (50);
2287 + }
2288 + break;
2289 +
2290 + case MULT:
2291 + {
2292 + /* Multiply is cheap when both arguments are 8-bits. They
2293 + could be QImode, or QImode widened to HImode, or a constant
2294 + that fits into 8-bits. As long as both operands qualify,
2295 + we can use a single mul instruction.
2296 +
2297 + Assume that fast multiply can be used, and change this if we find
2298 + differently... */
2299 + int ok_for_qihi3 = 1;
2300 +
2301 + /* Check the first operand */
2302 + switch (GET_MODE (op0))
2303 + {
2304 + case QImode:
2305 + break;
2306 + case HImode:
2307 + if (GET_CODE (op0) != SIGN_EXTEND && GET_CODE (op0) != ZERO_EXTEND)
2308 + ok_for_qihi3 = 0;
2309 + break;
2310 + default:
2311 + ok_for_qihi3 = 0;
2312 + break;
2313 + }
2314 +
2315 + /* Likewise, check the second operand. This is where constants may appear. */
2316 + switch (GET_MODE (op1))
2317 + {
2318 + case QImode:
2319 + break;
2320 + case HImode:
2321 + if (GET_CODE (op1) != SIGN_EXTEND && GET_CODE (op1) != ZERO_EXTEND)
2322 + ok_for_qihi3 = 0;
2323 + break;
2324 + case VOIDmode:
2325 + if (!CONST_OK_FOR_LETTER_P (const_arg, 'K'))
2326 + ok_for_qihi3 = 0;
2327 + break;
2328 + default:
2329 + ok_for_qihi3 = 0;
2330 + break;
2331 + }
2332 +
2333 + /* Fast multiply takes about 4 times as many cycles as a normal
2334 + arithmetic operation. Otherwise, it will take an expensive libcall. */
2335 + if (ok_for_qihi3)
2336 + *total += COSTS_N_INSNS (4);
2337 + else
2338 + *total = COSTS_N_INSNS (50);
2339 + break;
2340 + }
2341 +
2342 + case DIV: case UDIV: case MOD: case UMOD:
2343 + /* These all require more expensive libcalls. */
2344 + *total += COSTS_N_INSNS (100);
2345 + break;
2346 +
2347 + /* TODO : TRUNCATE, SIGN_EXTEND, and ZERO_EXTEND */
2348 +
2349 + /* These can normally be done with autoincrement, etc., so
2350 + * don't charge for them. */
2351 + case PRE_DEC:
2352 + case PRE_INC:
2353 + case POST_DEC:
2354 + case POST_INC:
2355 + break;
2356 +
2357 + default:
2358 + break;
2359 + }
2360 +
2361 + /* Always return false, and let the caller gather the costs
2362 + * of the operands */
2363 + return false;
2364 +}
2365 +
2366 +
2367 +static tree
2368 +m6809_handle_fntype_attribute (tree *node, tree name,
2369 + tree args ATTRIBUTE_UNUSED,
2370 + int flags ATTRIBUTE_UNUSED,
2371 + bool *no_add_attrs)
2372 +{
2373 + if (TREE_CODE (*node) != FUNCTION_TYPE)
2374 + {
2375 + warning (WARNING_OPT "'%s' only valid for functions",
2376 + IDENTIFIER_POINTER (name));
2377 + *no_add_attrs = TRUE;
2378 + }
2379 +
2380 + return NULL_TREE;
2381 +}
2382 +
2383 +
2384 +static tree
2385 +m6809_handle_data_type_attribute (tree *node ATTRIBUTE_UNUSED,
2386 + tree name ATTRIBUTE_UNUSED,
2387 + tree args ATTRIBUTE_UNUSED,
2388 + int flags ATTRIBUTE_UNUSED,
2389 + bool *no_add_attrs ATTRIBUTE_UNUSED)
2390 +{
2391 + return NULL_TREE;
2392 +}
2393 +
2394 +
2395 +
2396 +static tree
2397 +m6809_handle_default_attribute (tree *node ATTRIBUTE_UNUSED,
2398 + tree name ATTRIBUTE_UNUSED,
2399 + tree args ATTRIBUTE_UNUSED,
2400 + int flags ATTRIBUTE_UNUSED,
2401 + bool *no_add_attrs ATTRIBUTE_UNUSED )
2402 +{
2403 + return NULL_TREE;
2404 +}
2405 +
2406 +
2407 +/* Table of valid machine attributes */
2408 +const struct attribute_spec m6809_attribute_table[] = { /*
2409 +{ name, min, max, decl, type, fntype, handler } */
2410 +{ "interrupt", 0, 0, false, true, true, m6809_handle_fntype_attribute },
2411 +{ "naked", 0, 0, false, true, true, m6809_handle_fntype_attribute },
2412 +{ "far", 0, 1, false, true, true, m6809_handle_fntype_attribute },
2413 +{ "bank", 0, 1, true, false, false, m6809_handle_default_attribute },
2414 +{ "boolean", 0, 0, false, true, false, m6809_handle_data_type_attribute },
2415 +{ NULL, 0, 0, false, true, false, NULL },
2416 +};
2417 +
2418 +
2419 +/** Initialize builtin routines for the 6809. */
2420 +void
2421 +m6809_init_builtins (void)
2422 +{
2423 + /* Create type trees for each function signature required.
2424 + *
2425 + * void_ftype_void = void f(void)
2426 + * void_ftype_uchar = void f(unsigned char)
2427 + * uchar_ftype_uchar2 = unsigned char f (unsigned char, unsigned char)
2428 + */
2429 + tree void_ftype_void =
2430 + build_function_type (void_type_node, void_list_node);
2431 +
2432 + tree void_ftype_uchar =
2433 + build_function_type (void_type_node,
2434 + tree_cons (NULL_TREE, unsigned_char_type_node, void_list_node));
2435 +
2436 + tree uchar_ftype_uchar2 =
2437 + build_function_type (unsigned_char_type_node,
2438 + tree_cons (NULL_TREE, unsigned_char_type_node,
2439 + tree_cons (NULL_TREE, unsigned_char_type_node, void_list_node)));
2440 +
2441 + /* Register each builtin function. */
2442 + add_builtin_function ("__builtin_swi", void_ftype_void,
2443 + M6809_SWI, BUILT_IN_MD, NULL, NULL_TREE);
2444 +
2445 + add_builtin_function ("__builtin_swi2", void_ftype_void,
2446 + M6809_SWI2, BUILT_IN_MD, NULL, NULL_TREE);
2447 +
2448 + add_builtin_function ("__builtin_swi3", void_ftype_void,
2449 + M6809_SWI3, BUILT_IN_MD, NULL, NULL_TREE);
2450 +
2451 + add_builtin_function ("__builtin_cwai", void_ftype_uchar,
2452 + M6809_CWAI, BUILT_IN_MD, NULL, NULL_TREE);
2453 +
2454 + add_builtin_function ("__builtin_sync", void_ftype_void,
2455 + M6809_SYNC, BUILT_IN_MD, NULL, NULL_TREE);
2456 +
2457 + add_builtin_function ("__builtin_nop", void_ftype_void,
2458 + M6809_NOP, BUILT_IN_MD, NULL, NULL_TREE);
2459 +
2460 + add_builtin_function ("__builtin_blockage", void_ftype_void,
2461 + M6809_BLOCKAGE, BUILT_IN_MD, NULL, NULL_TREE);
2462 +
2463 + add_builtin_function ("__builtin_add_decimal", uchar_ftype_uchar2,
2464 + M6809_ADD_DECIMAL, BUILT_IN_MD, NULL, NULL_TREE);
2465 +
2466 + add_builtin_function ("__builtin_add_carry", uchar_ftype_uchar2,
2467 + M6809_ADD_CARRY, BUILT_IN_MD, NULL, NULL_TREE);
2468 +
2469 + add_builtin_function ("__builtin_sub_carry", uchar_ftype_uchar2,
2470 + M6809_SUB_CARRY, BUILT_IN_MD, NULL, NULL_TREE);
2471 +}
2472 +
2473 +
2474 +/** Used by m6809_expand_builtin, given a tree ARGLIST which
2475 + * refers to the operands of a builtin call, return an rtx
2476 + * that represents the nth operand, as denoted by OPNUM, which
2477 + * is a zero-based integer. MODE gives the expected mode
2478 + * of the operand.
2479 + *
2480 + * This rtx is suitable for use in the emitted RTL for the
2481 + * builtin instruction. */
2482 +rtx
2483 +m6809_builtin_operand (tree arglist, enum machine_mode mode, int opnum)
2484 +{
2485 + tree arg;
2486 + rtx r;
2487 +
2488 + arg = CALL_EXPR_ARG (arglist, opnum);
2489 +
2490 + /* Convert the tree to RTL */
2491 + r = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL);
2492 + if (r == NULL_RTX)
2493 + return NULL_RTX;
2494 + return r;
2495 +}
2496 +
2497 +
2498 +/** Expand a builtin that was registered in init_builtins into
2499 + * RTL. */
2500 +rtx
2501 +m6809_expand_builtin (tree exp,
2502 + rtx target,
2503 + rtx subtarget ATTRIBUTE_UNUSED,
2504 + enum machine_mode mode ATTRIBUTE_UNUSED,
2505 + int ignore ATTRIBUTE_UNUSED )
2506 +{
2507 + tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2508 + tree arglist = exp;
2509 + unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
2510 + rtx r0, r1;
2511 +
2512 + switch (fcode)
2513 + {
2514 + case M6809_SWI:
2515 + r0 = gen_rtx_CONST_INT (VOIDmode, 1);
2516 + emit_insn (target = gen_m6809_swi (r0));
2517 + return target;
2518 +
2519 + case M6809_SWI2:
2520 + r0 = gen_rtx_CONST_INT (VOIDmode, 2);
2521 + emit_insn (target = gen_m6809_swi (r0));
2522 + return target;
2523 +
2524 + case M6809_SWI3:
2525 + r0 = gen_rtx_CONST_INT (VOIDmode, 3);
2526 + emit_insn (target = gen_m6809_swi (r0));
2527 + return target;
2528 +
2529 + case M6809_CWAI:
2530 + r0 = m6809_builtin_operand (arglist, QImode, 0);
2531 + emit_insn (target = gen_m6809_cwai (r0));
2532 + return target;
2533 +
2534 + case M6809_SYNC:
2535 + emit_insn (target = gen_m6809_sync ());
2536 + return target;
2537 +
2538 + case M6809_ADD_CARRY:
2539 + r0 = m6809_builtin_operand (arglist, QImode, 0);
2540 + r1 = m6809_builtin_operand (arglist, QImode, 1);
2541 + if (!target)
2542 + target = gen_reg_rtx (QImode);
2543 + emit_insn (gen_addqi3_carry (target, r0, r1));
2544 + return target;
2545 +
2546 + case M6809_SUB_CARRY:
2547 + r0 = m6809_builtin_operand (arglist, QImode, 0);
2548 + r1 = m6809_builtin_operand (arglist, QImode, 1);
2549 + if (!target)
2550 + target = gen_reg_rtx (QImode);
2551 + emit_insn (gen_subqi3_carry (target, r0, r1));
2552 + return target;
2553 +
2554 + case M6809_NOP:
2555 + emit_insn (target = gen_nop ());
2556 + return target;
2557 +
2558 + case M6809_BLOCKAGE:
2559 + emit_insn (target = gen_blockage ());
2560 + return target;
2561 +
2562 + case M6809_ADD_DECIMAL:
2563 + r0 = m6809_builtin_operand (arglist, QImode, 0);
2564 + r1 = m6809_builtin_operand (arglist, QImode, 1);
2565 + if (!target)
2566 + target = gen_reg_rtx (QImode);
2567 + emit_insn (gen_addqi3_decimal (target, r0, r1));
2568 + return target;
2569 +
2570 + default:
2571 + warning (WARNING_OPT "unknown builtin expansion ignored");
2572 + return NULL_RTX;
2573 + }
2574 +}
2575 +
2576 +
2577 +
2578 +/* Returns nonzero if 'x' represents a function that was declared
2579 + * as __noreturn__. */
2580 +int
2581 +noreturn_functionp (rtx x)
2582 +{
2583 + tree decl = call_target_decl (x);
2584 +
2585 + if (decl == NULL_TREE)
2586 + return 0;
2587 + else
2588 + return TREE_THIS_VOLATILE (decl);
2589 +}
2590 +
2591 +
2592 +const char *
2593 +far_function_type_p (tree type)
2594 +{
2595 + tree attr;
2596 + const char *page;
2597 +
2598 + /* Return whether or not this decl has the far attribute */
2599 + attr = lookup_attribute ("far", TYPE_ATTRIBUTES (type));
2600 + if (attr == NULL_TREE)
2601 + return NULL;
2602 +
2603 + /* If it is far, check for a value */
2604 + attr = TREE_VALUE (attr);
2605 + if (attr == NULL_TREE)
2606 + {
2607 + warning (WARNING_OPT "far code page not specified, using local value");
2608 + return far_code_page;
2609 + }
2610 +
2611 + /* We have a TREE_LIST of attribute values, get the first one.
2612 + * It should be an INTEGER_CST. */
2613 + attr = TREE_VALUE (attr);
2614 + page = TREE_STRING_POINTER (attr);
2615 + return page;
2616 +}
2617 +
2618 +
2619 +/* For a far function, returns the identifier that states which page
2620 + * it resides in. Otherwise, returns NULL for ordinary functions. */
2621 +const char *
2622 +far_functionp (rtx x)
2623 +{
2624 + tree decl, decl_type;
2625 + const char *page;
2626 +
2627 + /* Find the FUNCTION_DECL corresponding to the rtx being called. */
2628 + decl = call_target_decl (x);
2629 + if (decl == NULL_TREE)
2630 + return NULL;
2631 +
2632 + /* See if the function has the new 'banked' attribute. These
2633 + * are numeric instead of text */
2634 + page = m6809_get_decl_bank (decl);
2635 + if (page)
2636 + return page;
2637 +
2638 + /* No, lookup the type of the function and see if the type
2639 + * specifies far or not. */
2640 + decl_type = TREE_TYPE (decl);
2641 + if (decl_type == NULL_TREE)
2642 + return NULL;
2643 + return far_function_type_p (decl_type);
2644 +}
2645 +
2646 +
2647 +
2648 +/** Outputs the assembly language for a far call. */
2649 +void
2650 +output_far_call_insn (rtx *operands, int has_return)
2651 +{
2652 + static char page_data[64];
2653 + const char *called_page;
2654 +
2655 + /* The logic is the same for functions whether or not there
2656 + * is a return value. Skip over the return value in this
2657 + * case, so that the call location is always operands[0]. */
2658 + if (has_return)
2659 + operands++;
2660 +
2661 + /* Get the name of the page being called */
2662 + called_page = far_functionp (operands[0]);
2663 +
2664 +#if 0 /* TODO : broken logic */
2665 + /* See if the called page name is a 'bank' */
2666 + if (isdigit (*called_page))
2667 + {
2668 + /* New style banking */
2669 + if (!strcmp (called_page, current_bank_name))
2670 + {
2671 + /* Same page */
2672 + output_asm_insn ("jsr\t%0", operands);
2673 + }
2674 + else
2675 + {
2676 + /* Different page */
2677 + output_asm_insn ("jsr\t__far_call_handler\t;new style", operands);
2678 + output_asm_insn ("\t.dw\t%0", operands);
2679 + sprintf (page_data, "\t.db\t%s", called_page);
2680 + output_asm_insn (page_data, operands);
2681 + }
2682 + return;
2683 + }
2684 +#endif
2685 +
2686 + /* Are we calling a different page than we are running in? */
2687 + if (!strcmp (called_page, far_code_page))
2688 + {
2689 + /* Same page : no need to execute a far call */
2690 + if (flag_pic)
2691 + output_asm_insn ("lbsr\t%C0", operands);
2692 + else
2693 + output_asm_insn ("jsr\t%0", operands);
2694 + }
2695 + else
2696 + {
2697 + /* Different page : need to emit far call thunk */
2698 +
2699 + /* First output a call to the thunk for making far calls. */
2700 + if (flag_pic)
2701 + output_asm_insn ("lbsr\t__far_call_handler", operands);
2702 + else
2703 + output_asm_insn ("jsr\t__far_call_handler\t;old style", operands);
2704 +
2705 + /* Now output the name of the call site */
2706 + output_asm_insn ("\t.dw\t%C0", operands);
2707 +
2708 + /* Finally output the page number */
2709 + sprintf (page_data, "\t.db\t%s", far_functionp (operands[0]));
2710 + output_asm_insn (page_data, operands);
2711 + }
2712 +}
2713 +
2714 +
2715 +int
2716 +m6809_init_cumulative_args (CUMULATIVE_ARGS cum ATTRIBUTE_UNUSED,
2717 + tree fntype,
2718 + rtx libname ATTRIBUTE_UNUSED)
2719 +{
2720 + cum = 0;
2721 +
2722 + /* For far functions, the current implementation does not allow for
2723 + * stack parameters. So note whenever the called function is far
2724 + * and in a different page than the current one; such a function
2725 + * should give an error if a stack parameter is generated. */
2726 + if (fntype)
2727 + {
2728 + const char *called_page = far_function_type_p (fntype);
2729 + if (called_page && strcmp (called_page, far_code_page) && !TARGET_FAR_STACK_PARAM)
2730 + cum |= CUM_STACK_INVALID;
2731 + }
2732 +
2733 + if (fntype && TYPE_ARG_TYPES (fntype) != 0 &&
2734 + (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) != void_type_node))
2735 + {
2736 + /* has variable arguments, cannot use registers */
2737 + cum |= (CUM_X_MASK | CUM_B_MASK | CUM_STACK_ONLY);
2738 + }
2739 +
2740 + if (m6809_abi_version == M6809_ABI_VERSION_STACK)
2741 + {
2742 + /* cannot use registers ; only use the stack */
2743 + cum |= (CUM_STACK_ONLY | CUM_X_MASK | CUM_B_MASK);
2744 + }
2745 +
2746 + return cum;
2747 +}
2748 +
2749 +
2750 +rtx
2751 +m6809_function_arg_on_stack (CUMULATIVE_ARGS *cump)
2752 +{
2753 + if (*cump & CUM_STACK_INVALID)
2754 + {
2755 + *cump &= ~CUM_STACK_INVALID;
2756 + error ("far function needs stack, will not work");
2757 + }
2758 + return NULL_RTX;
2759 +}
2760 +
2761 +void m6809_asm_trampoline_template(FILE *f)
2762 +{
2763 + fprintf(f, "ldy #0000\n");
2764 + fprintf(f, "jmp 0x0000\n");
2765 +}
2766 +
2767 +/*
2768 + * Trampoline output:
2769 + *
2770 + * ldu #&cxt 4 bytes --LDY- ?? ??
2771 + * jmp fnaddr 3 bytes JMP ?? ??
2772 + */
2773 +void
2774 +m6809_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
2775 +{
2776 + rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
2777 + /* TODO - optimize by generating the entire trampoline code here,
2778 + * and removing the template altogether, since there are only two
2779 + * bytes there that matter. */
2780 + emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 2)), cxt);
2781 + emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 5)), fnaddr);
2782 +}
2783 +
2784 +
2785 +/** Echo the version of the compiler and the name of the source file
2786 + * at the beginning of each assembler output file. asm_out_file
2787 + * is a global FILE * pointing to the output stream. */
2788 +void
2789 +m6809_asm_file_start (void)
2790 +{
2791 + const char *module_name;
2792 +
2793 + fprintf (asm_out_file, "\n;;; gcc for m6809 : %s %s\n",
2794 + __DATE__, __TIME__);
2795 + fprintf (asm_out_file, ";;; %s\n", version_string);
2796 +
2797 + fprintf (asm_out_file, ";;; ABI version %d\n", m6809_abi_version);
2798 + fprintf (asm_out_file, ";;; %s\n",
2799 + (TARGET_BYTE_INT ? "-mint8" : "-mint16"));
2800 + if (TARGET_EXPERIMENT)
2801 + fprintf (asm_out_file, ";;; -mexperiment\n");
2802 + if (TARGET_WPC)
2803 + fprintf (asm_out_file, ";;; -mwpc\n");
2804 + if (TARGET_6309)
2805 + fprintf (asm_out_file, ";;; -m6309\n");
2806 +
2807 + /* Print the name of the module, which is taken as the base name
2808 + * of the input file.
2809 + * See the 'User-Defined Symbols' section of the assembler
2810 + * documentation for the rules on valid symbols.
2811 + */
2812 + module_name = lbasename (main_input_filename);
2813 +
2814 + fprintf (asm_out_file, "\t.module\t");
2815 +
2816 + if (*module_name >= '0' && *module_name <= '9')
2817 + fprintf (asm_out_file, "_");
2818 +
2819 + while (*module_name)
2820 + {
2821 + if ((*module_name >= '0' && *module_name <= '9')
2822 + || (*module_name >= 'A' && *module_name <= 'Z')
2823 + || (*module_name >= 'a' && *module_name <= 'z')
2824 + || *module_name == '$'
2825 + || *module_name == '.'
2826 + || *module_name == '_')
2827 + {
2828 + fprintf (asm_out_file, "%c", *module_name);
2829 + }
2830 + else
2831 + {
2832 + fprintf (asm_out_file, "_");
2833 + }
2834 + module_name++;
2835 + }
2836 +
2837 + fprintf (asm_out_file, "\n");
2838 +}
2839 +
2840 +
2841 +/** Returns true if prologue/epilogue code is required for the
2842 + * current function being compiled.
2843 + *
2844 + * This is just the inverse of whether the function is declared as
2845 + * 'naked'.
2846 + */
2847 +int
2848 +prologue_epilogue_required (void)
2849 +{
2850 + return !m6809_current_function_has_type_attr_p ("naked")
2851 + && !m6809_current_function_has_type_attr_p ("noreturn");
2852 +}
2853 +
2854 +
2855 +/** Expand RTL for function entry */
2856 +void
2857 +emit_prologue_insns (void)
2858 +{
2859 + rtx insn;
2860 + unsigned int live_regs = m6809_get_live_regs ();
2861 + unsigned int frame_size = get_frame_size ();
2862 +
2863 + /* Save all registers used, including the frame pointer */
2864 + if (live_regs && !m6809_current_function_has_type_attr_p ("interrupt"))
2865 + {
2866 + insn = emit_insn (
2867 + gen_rtx_register_pushpop (UNSPEC_PUSH_RS, live_regs));
2868 + RTX_FRAME_RELATED_P (insn) = 1;
2869 + }
2870 +
2871 + /* Allocate space for local variables */
2872 + if (frame_size != 0)
2873 + {
2874 + insn = emit_insn (gen_rtx_stack_adjust (MINUS, frame_size));
2875 + RTX_FRAME_RELATED_P (insn) = 1;
2876 + }
2877 +
2878 + /* Set the frame pointer if it is needed */
2879 + if (frame_pointer_needed)
2880 + {
2881 + insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
2882 + RTX_FRAME_RELATED_P (insn) = 1;
2883 + }
2884 +}
2885 +
2886 +
2887 +/** Expand RTL for function exit */
2888 +void
2889 +emit_epilogue_insns (bool sibcall_p)
2890 +{
2891 + unsigned int live_regs = m6809_get_live_regs ();
2892 + unsigned int frame_size = get_frame_size ();
2893 +
2894 + if (frame_size != 0)
2895 + emit_insn (gen_rtx_stack_adjust (PLUS, frame_size));
2896 +
2897 + if (sibcall_p)
2898 + {
2899 + if (live_regs)
2900 + emit_insn (gen_rtx_register_pushpop (UNSPEC_POP_RS, live_regs));
2901 + }
2902 + else
2903 + {
2904 + if (live_regs && !m6809_current_function_has_type_attr_p ("interrupt"))
2905 + emit_insn (
2906 + gen_rtx_register_pushpop (UNSPEC_POP_RS, PC_REGBIT | live_regs));
2907 +
2908 + if (m6809_current_function_has_type_attr_p ("interrupt"))
2909 + emit_jump_insn (gen_return_rti ());
2910 + else
2911 + emit_jump_insn (gen_return_rts ());
2912 + }
2913 +}
2914 +
2915 +#if 0
2916 +/** Predefine some preprocessor names according to the currently
2917 + * selected compiler options */
2918 +void
2919 +m6809_cpu_cpp_builtins (void)
2920 +{
2921 + if (TARGET_6309)
2922 + {
2923 + builtin_define_std ("__M6309__");
2924 + builtin_define_std ("__m6309__");
2925 + }
2926 + else
2927 + {
2928 + builtin_define_std ("__M6809__");
2929 + builtin_define_std ("__m6809__");
2930 + }
2931 +
2932 + if (TARGET_BYTE_INT)
2933 + builtin_define_std ("__int8__");
2934 + else
2935 + builtin_define_std ("__int16__");
2936 +
2937 + switch (m6809_abi_version)
2938 + {
2939 + case M6809_ABI_VERSION_STACK:
2940 + builtin_define_std ("__regargs__");
2941 + builtin_define_std ("__ABI_STACK__");
2942 + break;
2943 + case M6809_ABI_VERSION_REGS:
2944 + builtin_define_std ("__ABI_REGS__");
2945 + break;
2946 + case M6809_ABI_VERSION_BX:
2947 + builtin_define_std ("__ABI_BX__");
2948 + break;
2949 + default:
2950 + break;
2951 + }
2952 +
2953 + if (TARGET_WPC)
2954 + builtin_define_std ("__WPC__");
2955 +
2956 + if (TARGET_DRET)
2957 + builtin_define_std ("__DRET__");
2958 +}
2959 +#endif
2960 +
2961 +#define MAX_ASM_ASCII_STRING 48
2962 +
2963 +void
2964 +m6809_output_ascii (FILE *fp, const char *str, unsigned long size)
2965 +{
2966 + unsigned long i;
2967 + bool use_ascii = true;
2968 +
2969 + /* If the size is too large, then break this up into multiple
2970 + outputs. The assembler can only output roughly 48 bytes at a
2971 + time. Note that if there are lots of escape sequences in
2972 + the string, this may fail. */
2973 + if (size > MAX_ASM_ASCII_STRING)
2974 + {
2975 + m6809_output_ascii (fp, str, MAX_ASM_ASCII_STRING);
2976 + m6809_output_ascii (fp, str + MAX_ASM_ASCII_STRING,
2977 + size - MAX_ASM_ASCII_STRING);
2978 + return;
2979 + }
2980 +
2981 + /* Check for 8-bit codes, which cannot be embedded in an .ascii */
2982 + for (i = 0; i < size; i++)
2983 + {
2984 + int c = str[i] & 0377;
2985 + if (c >= 0x80)
2986 + {
2987 + use_ascii = false;
2988 + break;
2989 + }
2990 + }
2991 +
2992 + if (use_ascii)
2993 + fprintf (fp, "\t.ascii \"");
2994 +
2995 + for (i = 0; i < size; i++)
2996 + {
2997 + int c = str[i] & 0377;
2998 +
2999 + if (use_ascii)
3000 + {
3001 + /* Just output the plain character if it is printable,
3002 + otherwise output the escape code for the character.
3003 + The assembler recognizes the same C-style octal escape sequences,
3004 + except that it only supports 7-bit codes. */
3005 + if (c >= ' ' && c < 0177 && c != '\\' && c != '"')
3006 + putc (c, fp);
3007 + else switch (c)
3008 + {
3009 + case '\n':
3010 +#ifndef TARGET_COCO
3011 + fputs ("\\n", fp);
3012 + break;
3013 +#endif
3014 + /* On the CoCo, we fallthrough and treat '\n' like '\r'. */
3015 + case '\r':
3016 + fputs ("\\r", fp);
3017 + break;
3018 + case '\t':
3019 + fputs ("\\t", fp);
3020 + break;
3021 + case '\f':
3022 + fputs ("\\f", fp);
3023 + break;
3024 + case 0:
3025 + fputs ("\\0", fp);
3026 + break;
3027 + default:
3028 + fprintf (fp, "\\%03o", c);
3029 + break;
3030 + }
3031 + }
3032 + else
3033 + {
3034 + fprintf (fp, "\t.byte\t0x%02X\n", c);
3035 + }
3036 + }
3037 +
3038 + if (use_ascii)
3039 + fprintf (fp, "\"\n");
3040 +}
3041 +
3042 +
3043 +void
3044 +m6809_output_quoted_string (FILE *asm_file, const char *string)
3045 +{
3046 + char c;
3047 +
3048 + if (strlen (string) > MAX_ASM_ASCII_STRING)
3049 + {
3050 + /* The string length is too large. We'll have to truncate it.
3051 + This is only called from debugging functions, so it's usually
3052 + not critical. */
3053 +
3054 + char truncated_string[MAX_ASM_ASCII_STRING+1];
3055 +
3056 + /* Copy as many characters as we can. */
3057 + strncpy (truncated_string, string, MAX_ASM_ASCII_STRING);
3058 + truncated_string[MAX_ASM_ASCII_STRING] = '\0';
3059 + string = truncated_string;
3060 + }
3061 +
3062 + /* Copied from toplev.c */
3063 +
3064 + putc ('\"', asm_file);
3065 + while ((c = *string++) != 0) {
3066 + if (ISPRINT (c)) {
3067 + if (c == '\"' || c == '\\')
3068 + putc ('\\', asm_file);
3069 + putc (c, asm_file);
3070 + }
3071 + else
3072 + fprintf (asm_file, "\\%03o", (unsigned char) c);
3073 + }
3074 + putc ('\"', asm_file);
3075 +}
3076 +
3077 +
3078 +/** Output the assembly code for a shift instruction where the
3079 + * shift count is not constant. */
3080 +void
3081 +m6809_output_shift_insn (int rtx_code, rtx *operands)
3082 +{
3083 + struct shift_opcode *op;
3084 +
3085 + if (GET_CODE (operands[2]) == CONST_INT)
3086 + abort ();
3087 +
3088 + if (optimize_size && GET_MODE (operands[0]) == HImode)
3089 + {
3090 + switch (rtx_code)
3091 + {
3092 + case ASHIFT:
3093 + output_asm_insn ("jsr\t_ashlhi3", operands);
3094 + break;
3095 + case ASHIFTRT:
3096 + output_asm_insn ("jsr\t_ashrhi3", operands);
3097 + break;
3098 + case LSHIFTRT:
3099 + output_asm_insn ("jsr\t_lshrhi3", operands);
3100 + break;
3101 + }
3102 + }
3103 + else if (GET_MODE (operands[0]) == HImode)
3104 + {
3105 + switch (rtx_code)
3106 + {
3107 + case ASHIFT:
3108 + m6809_gen_register_shift (operands, "aslb", "rola");
3109 + break;
3110 + case ASHIFTRT:
3111 + m6809_gen_register_shift (operands, "asra", "rorb");
3112 + break;
3113 + case LSHIFTRT:
3114 + m6809_gen_register_shift (operands, "lsra", "rorb");
3115 + break;
3116 + }
3117 + }
3118 + else
3119 + {
3120 + switch (rtx_code)
3121 + {
3122 + case ASHIFT:
3123 + m6809_gen_register_shift (operands, "aslb", NULL);
3124 + break;
3125 + case ASHIFTRT:
3126 + m6809_gen_register_shift (operands, "asrb", NULL);
3127 + break;
3128 + case LSHIFTRT:
3129 + m6809_gen_register_shift (operands, "lsrb", NULL);
3130 + break;
3131 + }
3132 + }
3133 +}
3134 +
3135 +
3136 +void
3137 +m6809_emit_move_insn (rtx dst, rtx src)
3138 +{
3139 + emit_insn (gen_rtx_SET (VOIDmode, dst, src));
3140 + if (ACC_A_REG_P (dst))
3141 + emit_insn (gen_rtx_USE (VOIDmode, dst));
3142 +}
3143 +
3144 +
3145 +/** Split a complex shift instruction into multiple CPU
3146 + * shift instructions. */
3147 +void
3148 +m6809_split_shift (enum rtx_code code, rtx *operands)
3149 +{
3150 + enum machine_mode mode;
3151 + int count;
3152 +
3153 + mode = GET_MODE (operands[0]);
3154 + count = INTVAL (operands[2]);
3155 +
3156 + /* Handle a shift count outside the range of 0 .. N-1, where
3157 + * N is the mode size in bits. We normalize the count, and
3158 + * for negative counts we also invert the direction of the
3159 + * shift. */
3160 + if ((count < 0) || (count >= 8 * GET_MODE_SIZE (mode)))
3161 + {
3162 + if (count < 0)
3163 + {
3164 + count = -count;
3165 + code = (code == ASHIFT) ? ASHIFTRT : ASHIFT;
3166 + }
3167 + count %= (8 * GET_MODE_SIZE (mode));
3168 + m6809_emit_move_insn (operands[0],
3169 + gen_rtx_fmt_ee (code, mode, operands[1],
3170 + gen_rtx_CONST_INT (VOIDmode, count)));
3171 + }
3172 +
3173 + /* Handle shift by zero explicitly as a no-op. */
3174 + if (count == 0)
3175 + {
3176 + emit_insn (gen_nop ());
3177 + return;
3178 + }
3179 +
3180 + /* Decompose the shift by a constant N > 8 into two
3181 + * shifts, first by 8 and then by N-8.
3182 + * This "speeds up" the process for large shifts that would be
3183 + * handled below, but allows for some optimization.
3184 + * In some cases shift by 8 can be implemented fast. If an
3185 + * instruction to shift by 8 is defined, it will be used here;
3186 + * otherwise it will be further decomposed as below. */
3187 + if (mode == HImode && count > 8)
3188 + {
3189 + rtx output = operands[0];
3190 +
3191 + m6809_emit_move_insn (operands[0],
3192 + gen_rtx_fmt_ee (code, mode, operands[1],
3193 + gen_rtx_CONST_INT (VOIDmode, 8)));
3194 +
3195 + /* Unsigned shifts always produce a zero in either the
3196 + * upper or lower half of the output; then, that part
3197 + * does not need to be shifted anymore. We modify the
3198 + * output and the subsequent instructions to operate in
3199 + * QImode only on the relevant part. */
3200 + if (REG_P (output))
3201 + {
3202 + if (code == ASHIFT)
3203 + {
3204 + output = gen_rtx_REG (QImode, HARD_A_REGNUM);
3205 + mode = QImode;
3206 + }
3207 + else
3208 + {
3209 + output = gen_rtx_REG (QImode, HARD_D_REGNUM);
3210 + mode = QImode;
3211 + }
3212 + }
3213 +
3214 + m6809_emit_move_insn (output,
3215 + gen_rtx_fmt_ee (code, mode, copy_rtx (output),
3216 + gen_rtx_CONST_INT (VOIDmode, count-8)));
3217 + return;
3218 + }
3219 +
3220 + /* Rewrite the unsigned shift of an 8-bit register by a large constant N
3221 + * (near to the maximum of 8) as a rotate and mask. */
3222 + if (mode == QImode && REG_P (operands[0]) && count >= ((code == ASHIFTRT) ? 7 : 6))
3223 + {
3224 + unsigned int mask;
3225 + unsigned int was_signed = (code == ASHIFTRT);
3226 +
3227 + code = (code == ASHIFT) ? ROTATERT : ROTATE;
3228 + if (code == ROTATE)
3229 + mask = (count == 6) ? 0x03 : 0x01;
3230 + else
3231 + mask = (count == 6) ? 0xC0 - 0x100 : 0x80 - 0x100;
3232 + count = 9 - count;
3233 +
3234 + do {
3235 + m6809_emit_move_insn (operands[0],
3236 + gen_rtx_fmt_ee (code, QImode, operands[1], const1_rtx));
3237 + } while (--count != 0);
3238 +
3239 + m6809_emit_move_insn (operands[0],
3240 + gen_rtx_fmt_ee (AND, QImode, operands[1],
3241 + gen_rtx_CONST_INT (VOIDmode, mask)));
3242 +
3243 + if (was_signed)
3244 + {
3245 + emit_insn (gen_negqi2 (operands[0], copy_rtx (operands[0])));
3246 + if (ACC_A_REG_P (operands[0]))
3247 + emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
3248 + }
3249 + return;
3250 + }
3251 +
3252 + /* Decompose the shift by any constant N > 1 into a sequence
3253 + * of N shifts.
3254 + * This is done recursively, by creating a shift by 1 and a
3255 + * shift by N-1, as long as N>1. */
3256 + if (count > 1)
3257 + {
3258 + m6809_emit_move_insn (operands[0],
3259 + gen_rtx_fmt_ee (code, mode, operands[1], const1_rtx));
3260 +
3261 + m6809_emit_move_insn (operands[0],
3262 + gen_rtx_fmt_ee (code, mode, operands[1],
3263 + gen_rtx_CONST_INT (VOIDmode, count-1)));
3264 + return;
3265 + }
3266 +
3267 + /* Decompose the single shift of a 16-bit quantity into two
3268 + * CPU instructions, one for each 8-bit half.
3269 + */
3270 + if (mode == HImode && count == 1)
3271 + {
3272 + rtx first, second;
3273 + enum rtx_code rotate_code;
3274 +
3275 + rotate_code = (code == ASHIFT) ? ROTATE : ROTATERT;
3276 +
3277 + /* Split the operand into two 8-bit entities.
3278 + * FIRST is the one that will get shifted via a regular CPU
3279 + * instruction.
3280 + * SECOND is the one that will have the result of the first shift
3281 + * rotated in.
3282 + *
3283 + * We initialize first and second as if we are doing a left shift,
3284 + * then swap the operands if it's a right shift.
3285 + */
3286 + if (REG_P (operands[0]))
3287 + {
3288 + first = gen_rtx_REG (QImode, HARD_D_REGNUM); /* HARD_B_REGNUM? */
3289 + second = gen_rtx_REG (QImode, HARD_A_REGNUM);
3290 + }
3291 + else
3292 + {
3293 + first = adjust_address (operands[0], QImode, 1);
3294 + second = adjust_address (operands[0], QImode, 0);
3295 + }
3296 +
3297 + if (rotate_code == ROTATERT)
3298 + {
3299 + rtx tmp; tmp = first; first = second; second = tmp;
3300 + }
3301 +
3302 + /* Decompose into a shift and a rotate instruction. */
3303 + m6809_emit_move_insn (first,
3304 + gen_rtx_fmt_ee (code, QImode, copy_rtx (first), const1_rtx));
3305 + m6809_emit_move_insn (second,
3306 + gen_rtx_fmt_ee (rotate_code, QImode, copy_rtx (second), const1_rtx));
3307 + return;
3308 + }
3309 +}
3310 +
3311 +
3312 +/** Adjust register usage based on compile-time flags. */
3313 +void
3314 +m6809_conditional_register_usage (void)
3315 +{
3316 + unsigned int soft_regno;
3317 +
3318 +#ifdef CONFIG_SOFT_REGS_ALWAYS
3319 + m6809_soft_regs = CONFIG_SOFT_REGS_ALWAYS;
3320 +#else
3321 + if (!m6809_soft_reg_count)
3322 + return;
3323 + m6809_soft_regs = atoi (m6809_soft_reg_count);
3324 +#endif
3325 +
3326 + if (m6809_soft_regs == 0)
3327 + return;
3328 +
3329 + if (m6809_soft_regs > NUM_M_REGS)
3330 + m6809_soft_regs = NUM_M_REGS;
3331 +
3332 + /* Registers are marked FIXED by default. Free up if
3333 + the user wishes. */
3334 + for (soft_regno = 1; soft_regno < m6809_soft_regs; soft_regno++)
3335 + {
3336 + fixed_regs[SOFT_M0_REGNUM + soft_regno] = 0;
3337 +
3338 + /* Mark the softregs as call-clobbered, so that they need
3339 + * not be saved/restored on function entry/exit. */
3340 + call_used_regs[SOFT_M0_REGNUM + soft_regno] = 1;
3341 + }
3342 +}
3343 +
3344 +
3345 +/** Return a RTX representing how to return a value from a function.
3346 + VALTYPE gives the type of the value, FUNC identifies the function
3347 + itself.
3348 +
3349 + In general, we only care about the width of the result. */
3350 +rtx
3351 +m6809_function_value (const tree valtype, const tree func ATTRIBUTE_UNUSED)
3352 +{
3353 + unsigned int regno;
3354 + enum machine_mode mode;
3355 +
3356 + /* Get the mode (i.e. width) of the result. */
3357 + mode = TYPE_MODE (valtype);
3358 +
3359 + if (lookup_attribute ("boolean", TYPE_ATTRIBUTES (valtype)))
3360 + regno = HARD_Z_REGNUM;
3361 + else if (mode == QImode || (TARGET_DRET && mode == HImode))
3362 + regno = HARD_D_REGNUM;
3363 + else
3364 + regno = HARD_X_REGNUM;
3365 + return gen_rtx_REG (mode, regno);
3366 +}
3367 +
3368 +
3369 +/** Return 1 if REGNO is possibly needed to return the result
3370 +of a function, 0 otherwise. */
3371 +int
3372 +m6809_function_value_regno_p (unsigned int regno)
3373 +{
3374 + if (regno == HARD_Z_REGNUM)
3375 + return 1;
3376 + else if ((TARGET_BYTE_INT || TARGET_DRET) && regno == HARD_D_REGNUM)
3377 + return 1;
3378 + else if (!TARGET_DRET && regno == HARD_X_REGNUM)
3379 + return 1;
3380 + else
3381 + return 0;
3382 +}
3383 +
3384 +
3385 +#ifdef TRACE_PEEPHOLE
3386 +int
3387 +m6809_match_peephole2 (unsigned int peephole_id, unsigned int stage)
3388 +{
3389 + if (stage == PEEP_END)
3390 + {
3391 + printf ("%s: peephole %d pattern and predicate matched\n",
3392 + main_input_filename, peephole_id);
3393 + fflush (stdout);
3394 + }
3395 + else if (stage == PEEP_COND)
3396 + {
3397 + printf ("%s: peephole %d? at least pattern matched\n",
3398 + main_input_filename, peephole_id);
3399 + fflush (stdout);
3400 + }
3401 + return 1;
3402 +}
3403 +#else
3404 +int
3405 +m6809_match_peephole2 (unsigned int peephole_id ATTRIBUTE_UNUSED,
3406 + unsigned int stage ATTRIBUTE_UNUSED)
3407 +{
3408 + return 1;
3409 +}
3410 +#endif /* TRACE_PEEPHOLE */
3411 +
3412 +
3413 +/** Return 1 if it is OK to store a value of MODE in REGNO. */
3414 +int
3415 +m6809_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
3416 +{
3417 + /* Soft registers, as they are just memory, can really hold
3418 + values of any type. However we restrict them to values of
3419 + size HImode or QImode to prevent exhausting them for larger
3420 + values.
3421 + Word values cannot be placed into the first soft register,
3422 + as it is the low byte that is being placed there, which
3423 + corrupts the (non-soft) register before it. */
3424 + if (M_REGNO_P (regno))
3425 + {
3426 + switch (GET_MODE_SIZE (mode))
3427 + {
3428 + case 1:
3429 + return 1;
3430 + case 2:
3431 + return regno != SOFT_M0_REGNUM;
3432 + default:
3433 + return 0;
3434 + }
3435 + }
3436 +
3437 + /* VOIDmode can be stored anywhere */
3438 + else if (mode == VOIDmode)
3439 + return 1;
3440 +
3441 + /* Zero is a reserved register, but problems occur if we don't
3442 + say yes here??? */
3443 + else if (regno == 0)
3444 + return 1;
3445 +
3446 + /* For other registers, return true only if the requested size
3447 + exactly matches the hardware size. */
3448 + else if ((G_REGNO_P (regno)) && (GET_MODE_SIZE (mode) == 2))
3449 + return 1;
3450 + else if ((BYTE_REGNO_P (regno)) && (GET_MODE_SIZE (mode) == 1))
3451 + return 1;
3452 + else
3453 + return 0;
3454 +}
3455 +
3456 +
3457 +/* exp is the call expression. DECL is the called function,
3458 + * or NULL for an indirect call */
3459 +bool
3460 +m6809_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
3461 +{
3462 + tree type, arg;
3463 + const char *name;
3464 + bool result = 0;
3465 + int argcount = 0;
3466 + int step = 1;
3467 +
3468 + /* If there is no DECL, it is an indirect call.
3469 + * Never optimize this??? */
3470 + if (decl == NULL)
3471 + goto done;
3472 +
3473 + /* Never allow an interrupt handler to be optimized this way. */
3474 + if (m6809_function_has_type_attr_p (decl, "interrupt"))
3475 + goto done;
3476 +
3477 + /* Skip sibcall if the type can't be found for
3478 + * some reason */
3479 + step++;
3480 + name = IDENTIFIER_POINTER (DECL_NAME (decl));
3481 + type = TREE_TYPE (decl);
3482 + if (type == NULL)
3483 + goto done;
3484 +
3485 + /* Skip sibcall if the target is a far function */
3486 + step++;
3487 + if (far_function_type_p (type) != NULL)
3488 + goto done;
3489 +
3490 + /* Skip sibcall if the called function's arguments are
3491 + * variable */
3492 + step++;
3493 + if (TYPE_ARG_TYPES (type) == NULL)
3494 + goto done;
3495 +
3496 + /* Allow sibcalls in other cases. */
3497 + result = 1;
3498 +done:
3499 + /* printf ("%s ok for sibcall? %s, step %d, args %d\n", name, result ? "yes" : "no", step, argcount); */
3500 + return result;
3501 +}
3502 +
3503 +
3504 +/** Emit code for the 'casesi' pattern.
3505 + * This pattern is only used in 8-bit mode, and can be disabled
3506 + * with -mold-case there as well. The rationale for this is to
3507 + * do a better job than the simpler but well-tested 'tablejump'
3508 + * method.
3509 + *
3510 + * For small jumptables, where the switch expression is an
3511 + * 8-bit value, the lookup can be done more efficiently
3512 + * using the "B,X" style index mode. */
3513 +void
3514 +m6809_do_casesi (rtx index, rtx lower_bound, rtx range,
3515 + rtx table_label, rtx default_label)
3516 +{
3517 + enum machine_mode mode;
3518 + rtx scaled;
3519 + rtx table_in_reg;
3520 +
3521 + /* expr.c has to be patched so that it does not promote
3522 + * the expression to SImode, but rather to HImode.
3523 + * Fail now if that isn't the case. */
3524 + if (GET_MODE_SIZE (GET_MODE (index)) > GET_MODE_SIZE (HImode))
3525 + error ("try_casesi promotion bug");
3526 +
3527 + /* Determine whether or not we are going to work primarily in
3528 + * QImode or HImode. This depends on the size of the index
3529 + * into the lookup table. QImode can only be used when the
3530 + * index is less than 0x40, since it will be doubled but
3531 + * must remain unsigned. */
3532 + if ((GET_CODE (range) == CONST_INT) && (INTVAL (range) < 0x40))
3533 + mode = QImode;
3534 + else
3535 + mode = HImode;
3536 +
3537 + /* Convert to QImode if necessary */
3538 + if (mode == QImode)
3539 + {
3540 + index = gen_lowpart_general (mode, index);
3541 + lower_bound = gen_lowpart_general (mode, lower_bound);
3542 + }
3543 +
3544 + /* Translate from case value to table index by subtraction */
3545 + if (lower_bound != const0_rtx)
3546 + index = expand_binop (mode, sub_optab, index, lower_bound,
3547 + NULL_RTX, 0, OPTAB_LIB_WIDEN);
3548 +
3549 + /* Emit compare-and-jump to test for index out-of-range */
3550 + emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
3551 + default_label);
3552 +
3553 + /* Put the table address is in a register */
3554 + table_in_reg = gen_reg_rtx (Pmode);
3555 + emit_move_insn (table_in_reg, gen_rtx_LABEL_REF (Pmode, table_label));
3556 +
3557 + /* Emit table lookup and jump */
3558 + if (mode == QImode)
3559 + {
3560 + /* Scale the index */
3561 + scaled = gen_reg_rtx (QImode);
3562 + emit_insn (gen_ashlqi3 (scaled, index, const1_rtx));
3563 +
3564 + /* Emit the jump */
3565 + emit_jump_insn (gen_tablejump_short_offset (scaled, table_in_reg));
3566 + }
3567 + else
3568 + {
3569 + /* Scale the index */
3570 + emit_insn (gen_ashlhi3 (index, index, const1_rtx));
3571 +
3572 + /* Emit the jump */
3573 + emit_jump_insn (gen_tablejump_long_offset (index, table_in_reg));
3574 + }
3575 +
3576 + /* Copied from expr.c */
3577 + if (!CASE_VECTOR_PC_RELATIVE && !flag_pic)
3578 + emit_barrier ();
3579 +}
3580 +
3581 +
3582 +/** Output the assembly code for a 32-bit add/subtract. */
3583 +void
3584 +m6809_output_addsi3 (int rtx_code, rtx *operands)
3585 +{
3586 + rtx xoperands[8];
3587 + rtx dst = operands[0];
3588 +
3589 + /* Prepare the operands by splitting each SImode into two HImodes
3590 + that can be operated independently. The high word of operand 1
3591 + is further divided into two QImode components for use with 'adc'
3592 + style instructions. */
3593 + xoperands[7] = operands[3];
3594 +
3595 + xoperands[0] = adjust_address (dst, HImode, 2);
3596 + xoperands[3] = adjust_address (dst, HImode, 0);
3597 +
3598 +#if 1
3599 + xoperands[2] = adjust_address (operands[1], HImode, 2);
3600 + xoperands[6] = adjust_address (operands[1], HImode, 0);
3601 +
3602 + /* Operand 2 may be a MEM or a CONST_INT */
3603 + if (GET_CODE (operands[2]) == CONST_INT)
3604 + {
3605 + xoperands[1] = gen_int_mode (INTVAL (operands[2]) & 0xFFFF, HImode);
3606 + xoperands[4] = gen_int_mode ((INTVAL (operands[2]) >> 24) & 0xFF, QImode);
3607 + xoperands[5] = gen_int_mode ((INTVAL (operands[2]) >> 16) & 0xFF, QImode);
3608 + }
3609 + else
3610 + {
3611 + xoperands[1] = adjust_address (operands[2], HImode, 2);
3612 + xoperands[4] = adjust_address (operands[2], QImode, 0);
3613 + xoperands[5] = adjust_address (operands[2], QImode, 1);
3614 + }
3615 +
3616 +#endif
3617 +
3618 +#if 0
3619 + xoperands[1] = adjust_address (operands[1], HImode, 2);
3620 + xoperands[4] = adjust_address (operands[1], QImode, 0);
3621 + xoperands[5] = adjust_address (operands[1], QImode, 1);
3622 +
3623 + /* Operand 2 may be a MEM or a CONST_INT */
3624 + if (GET_CODE (operands[2]) == CONST_INT)
3625 + {
3626 + xoperands[2] = gen_int_mode ((INTVAL (operands[2])) & 0xFFFF, HImode);
3627 + xoperands[6] = gen_int_mode ((INTVAL (operands[2]) >> 16) & 0xFFFF, HImode);
3628 + }
3629 + else
3630 + {
3631 + xoperands[2] = adjust_address (operands[2], HImode, 2);
3632 + xoperands[6] = adjust_address (operands[2], HImode, 0);
3633 + }
3634 +#endif
3635 +
3636 + /* Output the assembly code. */
3637 + if (rtx_code == PLUS)
3638 + {
3639 + output_asm_insn ("ld%7\t%2", xoperands);
3640 + output_asm_insn ("add%7\t%1", xoperands);
3641 + output_asm_insn ("st%7\t%0", xoperands);
3642 + output_asm_insn ("ld%7\t%6", xoperands);
3643 + output_asm_insn ("adcb\t%5", xoperands);
3644 + output_asm_insn ("adca\t%4", xoperands);
3645 + output_asm_insn ("st%7\t%3", xoperands);
3646 + }
3647 + else
3648 + {
3649 + output_asm_insn ("ld%7\t%2", xoperands);
3650 + output_asm_insn ("sub%7\t%1", xoperands);
3651 + output_asm_insn ("st%7\t%0", xoperands);
3652 + output_asm_insn ("ld%7\t%6", xoperands);
3653 + output_asm_insn ("sbcb\t%5", xoperands);
3654 + output_asm_insn ("sbca\t%4", xoperands);
3655 + output_asm_insn ("st%7\t%3", xoperands);
3656 + }
3657 +}
3658 +
3659 +
3660 +#if 0
3661 +/** Output the assembly code for a 32-bit shift.
3662 +Operands 0 and 1 must be the same rtx, forced by a matching
3663 +constraint. Operand 2 must be a CONST_INT. Operand 3 is
3664 +"d" in case a temporary reg is needed. */
3665 +void
3666 +m6809_output_shiftsi3 (int rtx_code, rtx *operands)
3667 +{
3668 + unsigned int count = INTVAL (operands[2]) % 32;
3669 + unsigned int size = 4; /* sizeof (SImode) */
3670 + int s;
3671 + rtx xoperands[4];
3672 + int op;
3673 + int start, end, step;
3674 +
3675 + /* Initialize */
3676 + if (rtx_code == ASHIFT)
3677 + {
3678 + start = size-1;
3679 + end = -1;
3680 + step = -1;
3681 + }
3682 + else
3683 + {
3684 + start = 0;
3685 + end = size;
3686 + step = 1;
3687 + }
3688 +
3689 + xoperands[2] = operands[2];
3690 + xoperands[3] = operands[3];
3691 +
3692 + if (count <= 0)
3693 + abort ();
3694 + if (rtx_code == ROTATE || rtx_code == ROTATERT)
3695 + abort ();
3696 +
3697 + /* Extract bit shifts over 16 bits by HImode moves. */
3698 + if (count >= 16)
3699 + {
3700 + }
3701 +
3702 + /* Extract bit shifts over 8 bits by QImode moves. */
3703 + if (count >= 8)
3704 + {
3705 + }
3706 +
3707 + /* Iterate over the number of bits to be shifted. */
3708 + while (count > 0)
3709 + {
3710 + /* Each bit to be shifted requires 1 proper bit shift
3711 + and 3 rotates. */
3712 +
3713 + /* First, do the arithmetic/logical shift. Left shifts
3714 + start from the LSB; right shifts start from the MSB. */
3715 + xoperands[0] = adjust_address (operands[0], QImode, start);
3716 + switch (rtx_code)
3717 + {
3718 + case ASHIFT:
3719 + output_asm_insn ("asl\t%0", xoperands);
3720 + start--;
3721 + break;
3722 + case ASHIFTRT:
3723 + output_asm_insn ("asr\t%0", xoperands);
3724 + start++;
3725 + break;
3726 + case LSHIFTRT:
3727 + output_asm_insn ("lsr\t%0", xoperands);
3728 + start++;
3729 + break;
3730 + }
3731 +
3732 + /* Next, rotate the other bytes */
3733 + for (s = start; s != end; s += step)
3734 + {
3735 + xoperands[0] = adjust_address (operands[0], QImode, s);
3736 + switch (rtx_code)
3737 + {
3738 + case ASHIFT:
3739 + output_asm_insn ("rol\t%0", xoperands);
3740 + break;
3741 + case ASHIFTRT:
3742 + case LSHIFTRT:
3743 + output_asm_insn ("ror\t%0", xoperands);
3744 + break;
3745 + }
3746 + }
3747 + count--;
3748 + }
3749 +}
3750 +#endif
3751 +
3752 +int
3753 +power_of_two_p (unsigned int n)
3754 +{
3755 + return (n & (n-1)) == 0;
3756 +}
3757 +
3758 +
3759 +int
3760 +m6809_can_eliminate (int from, int to)
3761 +{
3762 + if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
3763 + return !frame_pointer_needed;
3764 + return 1;
3765 +}
3766 +
3767 +
3768 +int
3769 +m6809_initial_elimination_offset (int from, int to)
3770 +{
3771 + switch (from)
3772 + {
3773 + case ARG_POINTER_REGNUM:
3774 + return get_frame_size () + m6809_get_regs_size (m6809_get_live_regs ());
3775 + case FRAME_POINTER_REGNUM:
3776 + return get_frame_size ();
3777 + default:
3778 + gcc_unreachable ();
3779 + }
3780 +}
3781 +
3782 +
3783 +bool
3784 +m6809_frame_pointer_required (void)
3785 +{
3786 + return false;
3787 +}
3788 +
3789 +
3790 +/* Defines the target-specific hooks structure. */
3791 +struct gcc_target targetm = TARGET_INITIALIZER;
3792 diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.h gcc-4.6.4/gcc/config/m6809/m6809.h
3793 --- gcc-4.6.4-clean/gcc/config/m6809/m6809.h 1969-12-31 17:00:00.000000000 -0700
3794 +++ gcc-4.6.4/gcc/config/m6809/m6809.h 2015-07-20 21:56:53.518727644 -0600
3795 @@ -0,0 +1,1352 @@
3796 +/* Definitions of target machine for GNU compiler. MC6809 version.
3797 +
3798 + MC6809 Version by Tom Jones (jones@sal.wisc.edu)
3799 + Space Astronomy Laboratory
3800 + University of Wisconsin at Madison
3801 +
3802 + minor changes to adapt it to gcc-2.5.8 by Matthias Doerfel
3803 + ( msdoerfe@informatik.uni-erlangen.de )
3804 + also added #pragma interrupt (inspired by gcc-6811)
3805 +
3806 + minor changes to adapt it to gcc-2.8.0 by Eric Botcazou
3807 + (ebotcazou@multimania.com)
3808 +
3809 + minor changes to adapt it to egcs-1.1.2 by Eric Botcazou
3810 + (ebotcazou@multimania.com)
3811 +
3812 + minor changes to adapt it to gcc-2.95.3 by Eric Botcazou
3813 + (ebotcazou@multimania.com)
3814 +
3815 + changes for gcc-3.1.1 by ???
3816 +
3817 + further changes for gcc-3.1.1 and beyond by Brian Dominy
3818 + (brian@oddchange.com)
3819 +
3820 + even more changes for gcc-4.6.1 by William Astle (lost@l-w.ca)
3821 +
3822 +This file is part of GCC.
3823 +
3824 +GCC is free software; you can redistribute it and/or modify
3825 +it under the terms of the GNU General Public License as published by
3826 +the Free Software Foundation; either version 3, or (at your option)
3827 +any later version.
3828 +
3829 +GCC is distributed in the hope that it will be useful,
3830 +but WITHOUT ANY WARRANTY; without even the implied warranty of
3831 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3832 +GNU General Public License for more details.
3833 +
3834 +You should have received a copy of the GNU General Public License
3835 +along with GCC; see the file COPYING3. If not see
3836 +<http://www.gnu.org/licenses/>. */
3837 +
3838 +
3839 +/* Helper macros for creating strings with macros */
3840 +#define C_STRING(x) C_STR(x)
3841 +#define C_STR(x) #x
3842 +
3843 +/* Certain parts of GCC include host-side includes, which is bad.
3844 + * Some things that get pulled in need to be undone.
3845 + */
3846 +#undef HAVE_GAS_HIDDEN
3847 +
3848 +/* Names to predefine in the preprocessor for this target machine. */
3849 +/*#define TARGET_CPU_CPP_BUILTINS() m6809_cpu_cpp_builtins () */
3850 +#define TARGET_CPU_CPP_BUILTINS() do \
3851 + { \
3852 + if (TARGET_6309) \
3853 + { \
3854 + builtin_define_std ("__M6309__"); \
3855 + builtin_define_std ("__m6309__"); \
3856 + } \
3857 + else \
3858 + { \
3859 + builtin_define_std ("__M6809__"); \
3860 + builtin_define_std ("__m6809__"); \
3861 + } \
3862 + \
3863 + if (TARGET_BYTE_INT) \
3864 + builtin_define_std ("__int8__"); \
3865 + else \
3866 + builtin_define_std ("__int16__"); \
3867 + \
3868 + switch (m6809_abi_version) \
3869 + { \
3870 + case M6809_ABI_VERSION_STACK: \
3871 + builtin_define_std ("__regargs__"); \
3872 + builtin_define_std ("__ABI_STACK__"); \
3873 + break; \
3874 + case M6809_ABI_VERSION_REGS: \
3875 + builtin_define_std ("__ABI_REGS__"); \
3876 + break; \
3877 + case M6809_ABI_VERSION_BX: \
3878 + builtin_define_std ("__ABI_BX__"); \
3879 + break; \
3880 + default: \
3881 + break; \
3882 + } \
3883 + \
3884 + if (TARGET_WPC) \
3885 + builtin_define_std ("__WPC__"); \
3886 + \
3887 + if (TARGET_DRET) \
3888 + builtin_define_std ("__DRET__"); \
3889 + } while (0)
3890 +
3891 +/* As an embedded target, we have no libc. */
3892 +#ifndef inhibit_libc
3893 +#define inhibit_libc
3894 +#endif
3895 +
3896 +/* Print subsidiary information on the compiler version in use. */
3897 +#define TARGET_VERSION fprintf (stderr, " (MC6809)");
3898 +
3899 +/* Run-time compilation parameters selecting different hardware subsets. */
3900 +/*extern int target_flags; */
3901 +extern short *reg_renumber; /* def in local_alloc.c */
3902 +
3903 +/* Runtime current values of section names */
3904 +extern int section_changed;
3905 +extern char code_section_op[], data_section_op[], bss_section_op[];
3906 +
3907 +#define WARNING_OPT 0,
3908 +/*extern const char *m6809_abi_version_ptr; */
3909 +extern unsigned int m6809_soft_regs;
3910 +extern unsigned int m6809_abi_version;
3911 +
3912 +/* ABI versions */
3913 +
3914 +#define M6809_ABI_VERSION_STACK 0
3915 +#define M6809_ABI_VERSION_REGS 1
3916 +#define M6809_ABI_VERSION_BX 2
3917 +#define M6809_ABI_VERSION_LATEST (M6809_ABI_VERSION_BX)
3918 +
3919 +/* Allow $ in identifiers */
3920 +#define DOLLARS_IN_IDENTIFIERS 1
3921 +
3922 +/*--------------------------------------------------------------
3923 + Target machine storage layout
3924 +--------------------------------------------------------------*/
3925 +
3926 +/* Define this if most significant bit is lowest numbered
3927 + in instructions that operate on numbered bit-fields. */
3928 +#define BITS_BIG_ENDIAN 0
3929 +
3930 +/* Define to 1 if most significant byte of a word is the lowest numbered. */
3931 +#define BYTES_BIG_ENDIAN 1
3932 +
3933 +/* Define to 1 if most significant word of a multiword value is the lowest numbered. */
3934 +#define WORDS_BIG_ENDIAN 1
3935 +
3936 +/* Number of bits in an addressible storage unit */
3937 +#define BITS_PER_UNIT 8
3938 +
3939 +/* Width in bits of a "word", or the contents of a machine register.
3940 + * Although the 6809 has a few byte registers, define this to 16-bits
3941 + * since this is the natural size of most registers. */
3942 +#define BITS_PER_WORD 16
3943 +
3944 +/* Width of a word, in units (bytes). */
3945 +#define UNITS_PER_WORD (BITS_PER_WORD/8)
3946 +
3947 +/* Width in bits of a pointer. See also the macro `Pmode' defined below. */
3948 +#define POINTER_SIZE 16
3949 +
3950 +/* Allocation boundary (bits) for storing pointers in memory. */
3951 +#define POINTER_BOUNDARY 8
3952 +
3953 +/* Allocation boundary (bits) for storing arguments in argument list. */
3954 +/* PARM_BOUNDARY is divided by BITS_PER_WORD in expr.c -- tej */
3955 +#define PARM_BOUNDARY 8
3956 +
3957 +/* Boundary (bits) on which stack pointer should be aligned. */
3958 +#define STACK_BOUNDARY 8
3959 +
3960 +/* Allocation boundary (bits) for the code of a function. */
3961 +#define FUNCTION_BOUNDARY 8
3962 +
3963 +/* Alignment of field after `int : 0' in a structure. */
3964 +#define EMPTY_FIELD_BOUNDARY 8
3965 +
3966 +/* Every structure's size must be a multiple of this. */
3967 +#define STRUCTURE_SIZE_BOUNDARY 8
3968 +
3969 +/* Largest mode size to use when putting an object, including
3970 + * a structure, into a register. By limiting this to 16, no
3971 + * 32-bit objects will ever be allocated to a pair of hard
3972 + * registers. This is a good thing, since there aren't that
3973 + * many of them. 32-bit objects are only needed for floats
3974 + * and "long long"s. Larger values have been tried and did not
3975 + * work. */
3976 +#define MAX_FIXED_MODE_SIZE 16
3977 +
3978 +/* No data type wants to be aligned rounder than this. */
3979 +#define BIGGEST_ALIGNMENT 8
3980 +
3981 +/* Define this if move instructions will actually fail to work
3982 + when given unaligned data. */
3983 +#define STRICT_ALIGNMENT 0
3984 +
3985 +/*--------------------------------------------------------------
3986 + Standard register usage.
3987 +--------------------------------------------------------------*/
3988 +
3989 +/* Register values as bitmasks.
3990 + * TODO : merge D_REGBIT and B_REGBIT, and treat this as the same
3991 + * register. */
3992 +#define RSVD1_REGBIT (1 << HARD_RSVD1_REGNUM)
3993 +#define D_REGBIT (1 << HARD_D_REGNUM)
3994 +#define X_REGBIT (1 << HARD_X_REGNUM)
3995 +#define Y_REGBIT (1 << HARD_Y_REGNUM)
3996 +#define U_REGBIT (1 << HARD_U_REGNUM)
3997 +#define S_REGBIT (1 << HARD_S_REGNUM)
3998 +#define PC_REGBIT (1 << HARD_PC_REGNUM)
3999 +#define Z_REGBIT (1 << HARD_Z_REGNUM)
4000 +#define A_REGBIT (1 << HARD_A_REGNUM)
4001 +#define B_REGBIT (1 << HARD_B_REGNUM)
4002 +#define CC_REGBIT (1 << HARD_CC_REGNUM)
4003 +#define DP_REGBIT (1 << HARD_DP_REGNUM)
4004 +#define SOFT_FP_REGBIT (1 << SOFT_FP_REGNUM)
4005 +#define SOFT_AP_REGBIT (1 << SOFT_AP_REGNUM)
4006 +#define M_REGBIT(n) (1 << (SOFT_M0_REGNUM + n))
4007 +
4008 +/* Macros for dealing with set of registers.
4009 + * A register set is just a bitwise-OR of all the register
4010 + * bitmask values. */
4011 +
4012 +/* Which registers can hold 8-bits */
4013 +#define BYTE_REGSET \
4014 + (Z_REGBIT | A_REGBIT | D_REGBIT | CC_REGBIT | DP_REGBIT)
4015 +
4016 +/* Which registers can hold 16-bits.
4017 + * Note: D_REGBIT is defined as both an 8-bit and 16-bit register */
4018 +#define WORD_REGSET \
4019 + (D_REGBIT | X_REGBIT | Y_REGBIT | U_REGBIT | S_REGBIT | PC_REGBIT | SOFT_FP_REGBIT | SOFT_AP_REGBIT | RSVD1_REGBIT)
4020 +
4021 +/* Returns nonzero if a given REGNO is in the REGSET. */
4022 +#define REGSET_CONTAINS_P(regno, regset) (((1 << (regno)) & (regset)) != 0)
4023 +
4024 +/* Defines related to the number of soft registers supported.
4025 + * The actual number used may be less depending on -msoft-reg-count.
4026 + * If you change one of these, you should change them all. */
4027 +#define NUM_M_REGS 8
4028 +#define M_REGS_FIXED 1, 1, 1, 1, 1, 1, 1, 1
4029 +#define M_REGS_CALL_USED 1, 1, 1, 1, 1, 1, 1, 1
4030 +#define HARD_M_REGNUMS \
4031 + SOFT_M0_REGNUM+0, SOFT_M0_REGNUM+1, SOFT_M0_REGNUM+2, SOFT_M0_REGNUM+3, \
4032 + SOFT_M0_REGNUM+4, SOFT_M0_REGNUM+5, SOFT_M0_REGNUM+6, SOFT_M0_REGNUM+7
4033 +
4034 +#define SOFT_M_REGBITS (((1UL << NUM_M_REGS) - 1) << (SOFT_M0_REGNUM))
4035 +
4036 +/* Number of actual hardware registers.
4037 + The hardware registers are assigned numbers for the compiler
4038 + from 0 to just below FIRST_PSEUDO_REGISTER.
4039 + All registers that the compiler knows about must be given numbers,
4040 + even those that are not normally considered general registers.
4041 + Make sure the constant below matches the value of SOFT_M0_REGNUM;
4042 + for some reason, GCC won't compile if that name is used here directly. */
4043 +#ifdef SOFT_M0_REGNUM
4044 +#if (SOFT_M0_REGNUM != 14)
4045 +#error "bad register numbering"
4046 +#endif
4047 +#endif
4048 +#define FIRST_PSEUDO_REGISTER (14 + NUM_M_REGS)
4049 +
4050 +/* 1 for registers that have pervasive standard uses
4051 + and are not available for the register allocator.
4052 + The psuedoregisters (M_REGS) are declared fixed here, but
4053 + will be unfixed if -msoft-reg-count is seen later. */
4054 +#define FIXED_REGISTERS \
4055 + {1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, M_REGS_FIXED, }
4056 + /* -, X, Y, U, S, PC,D, Z, A, B, C, DP,FP,AP,M... */
4057 +
4058 +/* 1 for registers not available across function calls.
4059 + These must include the FIXED_REGISTERS and also any
4060 + registers that can be used without being saved.
4061 + The latter must include the registers where values are returned
4062 + and the register where structure-value addresses are passed.
4063 + Aside from that, you can include as many other registers as you like. */
4064 +#define CALL_USED_REGISTERS \
4065 + {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, M_REGS_CALL_USED, }
4066 + /* -, X, Y, U, S, PC,D, Z, A, B, C, DP,FP,AP,M... */
4067 +
4068 +/* Return number of consecutive hard regs needed starting at reg REGNO
4069 + to hold something of mode MODE.
4070 + For the 6809, we distinguish between word-length and byte-length
4071 + registers. */
4072 +#define HARD_REGNO_NREGS(REGNO, MODE) \
4073 + (REGSET_CONTAINS_P (REGNO, WORD_REGSET) ? \
4074 + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) : \
4075 + (GET_MODE_SIZE (MODE)))
4076 +
4077 +
4078 +/* Value is 1 if hard register REGNO can hold a value
4079 +of machine-mode MODE. */
4080 +#define HARD_REGNO_MODE_OK(REGNO, MODE) m6809_hard_regno_mode_ok (REGNO, MODE)
4081 +
4082 +/* Value is 1 if it is a good idea to tie two pseudo registers
4083 + when one has mode MODE1 and one has mode MODE2.
4084 + If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
4085 + for any hard reg, then this must be 0 for correct output. */
4086 +#define MODES_TIEABLE_P(MODE1, MODE2) 0
4087 +
4088 +/* Specify the registers used for certain standard purposes.
4089 + The values of these macros are register numbers. */
4090 +
4091 +/* program counter if referenced as a register */
4092 +#define PC_REGNUM HARD_PC_REGNUM
4093 +
4094 +/* Register to use for pushing function arguments. */
4095 +#define STACK_POINTER_REGNUM HARD_S_REGNUM
4096 +
4097 +/* Base register for access to local variables of the function.
4098 + * Before reload, FRAME_POINTER_REGNUM will be used. Later,
4099 + * the elimination pass will convert these to STACK_POINTER_REGNUM
4100 + * if possible, or else HARD_FRAME_POINTER_REGNUM. The idea is to
4101 + * avoid tying up a hard register (U) for the frame pointer if
4102 + * it can be eliminated entirely, making it available for use as
4103 + * a general register. */
4104 +#define FRAME_POINTER_REGNUM SOFT_FP_REGNUM
4105 +#define HARD_FRAME_POINTER_REGNUM HARD_U_REGNUM
4106 +
4107 +/* Define a table of possible eliminations.
4108 + * The idea is to try to avoid using hard registers for the argument
4109 + * and frame pointers if they can be derived from the stack pointer
4110 + * instead, which already has a hard register reserved for it.
4111 + *
4112 + * The order of entries in this table will try to convert
4113 + * ARG_POINTER_REGNUM and FRAME_POINTER_REGNUM into stack pointer
4114 + * references first, but if that fails, they will be converted to use
4115 + * HARD_FRAME_POINTER_REGNUM.
4116 + */
4117 +#define ELIMINABLE_REGS \
4118 +{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
4119 + { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \
4120 + { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
4121 + { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }}
4122 +
4123 +/* #define CAN_ELIMINATE(FROM, TO) m6809_can_eliminate (FROM, TO) */
4124 +
4125 +/* Define how to offset the frame or argument pointer to turn it
4126 + * into a stack pointer reference. This is based on the way that
4127 + * the frame is constructed in the function prologue. */
4128 +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
4129 + (OFFSET) = m6809_initial_elimination_offset (FROM, TO)
4130 +
4131 +/* Base register for access to arguments of the function.
4132 + * This is only used prior to reload; no instructions will ever
4133 + * be output referring to this register. */
4134 +#define ARG_POINTER_REGNUM SOFT_AP_REGNUM
4135 +
4136 +/* Register in which static-chain is passed to a function. */
4137 +#define STATIC_CHAIN_REGNUM HARD_Y_REGNUM
4138 +
4139 +/* #define CONDITIONAL_REGISTER_USAGE (m6809_conditional_register_usage ()) */
4140 +
4141 +/* Order in which hard registers are allocated to pseudos.
4142 + *
4143 + * Since the D register is the only valid reg for 8-bit values
4144 + * now, avoid using it for 16-bit values by putting it after all
4145 + * other 16-bits.
4146 + *
4147 + * Prefer X first since the first 16-bit function argument goes
4148 + * there. We may be able to pass in to a subroutine without
4149 + * a copy.
4150 + *
4151 + * Prefer U over Y since instructions using Y take one extra
4152 + * byte, and thus one extra cycle to execute.
4153 + */
4154 +#define REG_ALLOC_ORDER \
4155 + { HARD_X_REGNUM, HARD_U_REGNUM, HARD_Y_REGNUM, HARD_D_REGNUM, \
4156 + HARD_M_REGNUMS, HARD_S_REGNUM, HARD_PC_REGNUM, \
4157 + HARD_B_REGNUM, HARD_A_REGNUM, HARD_CC_REGNUM, \
4158 + HARD_DP_REGNUM, SOFT_FP_REGNUM, SOFT_AP_REGNUM, \
4159 + 6, HARD_Z_REGNUM }
4160 +
4161 +/*--------------------------------------------------------------
4162 + classes of registers
4163 +--------------------------------------------------------------*/
4164 +
4165 +/* Define the classes of registers for register constraints in the
4166 + machine description. Also define ranges of constants.
4167 +
4168 + One of the classes must always be named ALL_REGS and include all hard regs.
4169 + If there is more than one class, another class must be named NO_REGS
4170 + and contain no registers.
4171 +
4172 + The name GENERAL_REGS must be the name of a class (or an alias for
4173 + another name such as ALL_REGS). This is the class of registers
4174 + that is allowed by "g" or "r" in a register constraint.
4175 + Also, registers outside this class are allocated only when
4176 + instructions express preferences for them.
4177 +
4178 + The classes must be numbered in nondecreasing order; that is,
4179 + a larger-numbered class must never be contained completely
4180 + in a smaller-numbered class.
4181 +
4182 + For any two classes, it is very desirable that there be another
4183 + class that represents their union. */
4184 +
4185 +enum reg_class {
4186 + NO_REGS, /* The trivial class with no registers in it */
4187 + D_REGS, /* 16-bit (word (HI)) data (D) */
4188 + ACC_A_REGS, /* The A register */
4189 + ACC_B_REGS, /* The B register */
4190 + X_REGS, /* The X register */
4191 + Z_REGS, /* The Z (zero-bit) register */
4192 + Q_REGS, /* 8-bit (byte (QI)) data (A,B) */
4193 + M_REGS, /* 8-bit (byte (QI)) soft registers */
4194 + CC_REGS, /* 8-bit condition code register */
4195 + I_REGS, /* An index register (A,B,D) */
4196 + T_REGS, /* 16-bit addresses, not including stack or PC (X,Y,U) */
4197 + A_REGS, /* 16-bit addresses (X,Y,U,S,PC) */
4198 + S_REGS, /* 16-bit soft registers (FP, AP) */
4199 + P_REGS, /* 16-bit pushable registers (D,X,Y,U); omit PC and S */
4200 + G_REGS, /* 16-bit data and address (D,X,Y,U,S,PC) */
4201 + ALL_REGS, /* All registers */
4202 + LIM_REG_CLASSES
4203 +};
4204 +
4205 +#define N_REG_CLASSES (int) LIM_REG_CLASSES
4206 +
4207 +/* Since GENERAL_REGS is a smaller class than ALL_REGS,
4208 + it is not an alias to ALL_REGS, but to G_REGS. */
4209 +#define GENERAL_REGS G_REGS
4210 +
4211 +/* Give names of register classes as strings for dump file. */
4212 +#define REG_CLASS_NAMES \
4213 + { "NO_REGS", "D_REGS", "ACC_A_REGS", "ACC_B_REGS", "X_REGS", "Z_REGS", "Q_REGS", "M_REGS", \
4214 + "CC_REGS", "I_REGS", "T_REGS", "A_REGS", "S_REGS", "P_REGS", "G_REGS", \
4215 + "ALL_REGS" }
4216 +
4217 +/* Define which registers fit in which classes.
4218 + This is an initializer for a vector of HARD_REG_SET
4219 + of length N_REG_CLASSES. */
4220 +
4221 +#define D_REGSET (D_REGBIT)
4222 +#define ACC_A_REGSET (A_REGBIT)
4223 +#define ACC_B_REGSET (D_REGBIT)
4224 +#define X_REGSET (X_REGBIT)
4225 +#define Z_REGSET (Z_REGBIT)
4226 +#define Q_REGSET (D_REGBIT | A_REGBIT)
4227 +#define M_REGSET (SOFT_M_REGBITS)
4228 +#define CC_REGSET (CC_REGBIT)
4229 +#define I_REGSET (A_REGBIT | B_REGBIT | D_REGBIT)
4230 +#define T_REGSET (X_REGBIT | Y_REGBIT | U_REGBIT)
4231 +#define A_REGSET (X_REGBIT | Y_REGBIT | U_REGBIT | S_REGBIT | PC_REGBIT)
4232 +#define S_REGSET (SOFT_FP_REGBIT | SOFT_AP_REGBIT)
4233 +#define P_REGSET (D_REGBIT | X_REGBIT | Y_REGBIT | U_REGBIT)
4234 +#define G_REGSET \
4235 + (D_REGSET | Q_REGSET | I_REGSET | A_REGSET | M_REGSET | S_REGSET)
4236 +#define ALL_REGSET (G_REGSET)
4237 +
4238 +#define REG_CLASS_CONTENTS { \
4239 + {0}, \
4240 + {D_REGSET}, \
4241 + {ACC_A_REGSET}, \
4242 + {ACC_B_REGSET}, \
4243 + {X_REGSET}, \
4244 + {Z_REGSET}, \
4245 + {Q_REGSET}, \
4246 + {M_REGSET}, \
4247 + {CC_REGSET}, \
4248 + {I_REGSET}, \
4249 + {T_REGSET}, \
4250 + {A_REGSET}, \
4251 + {S_REGSET}, \
4252 + {P_REGSET}, \
4253 + {G_REGSET}, \
4254 + {ALL_REGSET}, \
4255 +}
4256 +
4257 +/* The same information, inverted.
4258 + * This is defined to use the REG_CLASS_CONTENTS defines above, so that
4259 + * these two sets of definitions are always consistent. */
4260 +
4261 +#define REGNO_REG_CLASS(REGNO) \
4262 + (D_REGNO_P (REGNO) ? D_REGS : \
4263 + (Z_REGNO_P (REGNO) ? Z_REGS : \
4264 + (ACC_A_REGNO_P (REGNO) ? ACC_A_REGS : \
4265 + (ACC_B_REGNO_P (REGNO) ? ACC_B_REGS : \
4266 + (X_REGNO_P (REGNO) ? X_REGS : \
4267 + (Q_REGNO_P (REGNO) ? Q_REGS : \
4268 + (M_REGNO_P (REGNO) ? M_REGS : \
4269 + (CC_REGNO_P (REGNO) ? CC_REGS : \
4270 + (I_REGNO_P (REGNO) ? I_REGS : \
4271 + (T_REGNO_P (REGNO) ? T_REGS : \
4272 + (A_REGNO_P (REGNO) ? A_REGS : \
4273 + (S_REGNO_P (REGNO) ? S_REGS : \
4274 + (P_REGNO_P (REGNO) ? P_REGS : \
4275 + (G_REGNO_P (REGNO) ? G_REGS : ALL_REGS))))))))))))))
4276 +
4277 +#define D_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, D_REGSET))
4278 +#define ACC_A_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, ACC_A_REGSET))
4279 +#define ACC_B_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, ACC_B_REGSET))
4280 +#define X_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, X_REGSET))
4281 +#define Z_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, Z_REGSET))
4282 +#define Q_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, Q_REGSET))
4283 +#define M_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, M_REGSET))
4284 +#define CC_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, CC_REGSET))
4285 +#define I_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, I_REGSET))
4286 +#define T_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, T_REGSET))
4287 +#define A_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, A_REGSET))
4288 +#define S_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, S_REGSET))
4289 +#define P_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, P_REGSET))
4290 +#define G_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, G_REGSET))
4291 +
4292 +/* Macros that test an rtx 'X' to see if it's in a particular
4293 + * register class. 'X' need not be a REG necessarily. */
4294 +
4295 +#define D_REG_P(X) (REG_P (X) && D_REGNO_P (REGNO (X)))
4296 +#define ACC_A_REG_P(X) (REG_P (X) && ACC_A_REGNO_P (REGNO (X)))
4297 +#define ACC_B_REG_P(X) (REG_P (X) && ACC_B_REGNO_P (REGNO (X)))
4298 +#define X_REG_P(X) (REG_P (X) && X_REGNO_P (REGNO (X)))
4299 +#define Z_REG_P(X) (REG_P (X) && Z_REGNO_P (REGNO (X)))
4300 +#define I_REG_P(X) (REG_P (X) && I_REGNO_P (REGNO (X)))
4301 +#define T_REG_P(X) (REG_P (X) && T_REGNO_P (REGNO (X)))
4302 +#define A_REG_P(X) (REG_P (X) && A_REGNO_P (REGNO (X)))
4303 +#define S_REG_P(X) (REG_P (X) && S_REGNO_P (REGNO (X)))
4304 +#define P_REG_P(X) (REG_P (X) && P_REGNO_P (REGNO (X)))
4305 +#define Q_REG_P(X) (REG_P (X) && Q_REGNO_P (REGNO (X)))
4306 +#define M_REG_P(X) (REG_P (X) && M_REGNO_P (REGNO (X)))
4307 +#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
4308 +
4309 +/* Redefine this in terms of BYTE_REGSET */
4310 +#define BYTE_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, BYTE_REGSET))
4311 +
4312 +/* The class value for index registers, and the one for base regs. */
4313 +#define INDEX_REG_CLASS I_REGS
4314 +#define BASE_REG_CLASS A_REGS
4315 +
4316 +/* Get reg_class from a letter in the machine description. */
4317 +#define REG_CLASS_FROM_LETTER(C) \
4318 + (((C) == 'a' ? A_REGS : \
4319 + ((C) == 'd' ? D_REGS : \
4320 + ((C) == 'x' ? I_REGS : \
4321 + ((C) == 't' ? M_REGS : \
4322 + ((C) == 'c' ? CC_REGS : \
4323 + ((C) == 'A' ? ACC_A_REGS : \
4324 + ((C) == 'B' ? ACC_B_REGS : \
4325 + ((C) == 'v' ? X_REGS : \
4326 + ((C) == 'u' ? S_REGS : \
4327 + ((C) == 'U' ? P_REGS : \
4328 + ((C) == 'T' ? T_REGS : \
4329 + ((C) == 'z' ? Z_REGS : \
4330 + ((C) == 'q' ? Q_REGS : NO_REGS))))))))))))))
4331 +
4332 +/*--------------------------------------------------------------
4333 + The letters I through O in a register constraint string
4334 + can be used to stand for particular ranges of immediate operands.
4335 + This macro defines what the ranges are.
4336 + C is the letter, and VALUE is a constant value.
4337 + Return 1 if VALUE is in the range specified by C.
4338 +
4339 + For the 6809, J, K, L are used for indexed addressing.
4340 + `I' is used for the constant 1.
4341 + `J' is used for the 5-bit offsets.
4342 + `K' is used for the 8-bit offsets.
4343 + `L' is used for the range of signed numbers that fit in 16 bits.
4344 + `M' is used for the exact value '8'.
4345 + `N' is used for the constant -1.
4346 + `O' is used for the constant 0.
4347 +--------------------------------------------------------------*/
4348 +
4349 +#define CONST_OK_FOR_LETTER_P(VALUE, C) \
4350 + ((C) == 'I' ? ((VALUE) == 1) : \
4351 + (C) == 'J' ? ((VALUE) >= -16 && (VALUE) <= 15) : \
4352 + (C) == 'K' ? ((VALUE) >= -128 && (VALUE) <= 127) : \
4353 + (C) == 'L' ? ((VALUE) >= -32768 && (VALUE) <= 32767) : \
4354 + (C) == 'M' ? ((VALUE) == 8) : \
4355 + (C) == 'N' ? ((VALUE) == -1) : \
4356 + (C) == 'O' ? ((VALUE) == 0) : 0)
4357 +
4358 +/* Similar, but for floating constants, and defining letters G and H.
4359 + No floating-point constants are valid on MC6809. */
4360 +#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
4361 + ((C) == 'G' ? (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT \
4362 + && VALUE == CONST0_RTX (GET_MODE (VALUE))) : 0)
4363 +
4364 +/* Given an rtx X being reloaded into a reg required to be
4365 + in class CLASS, return the class of reg to actually use.
4366 + In general this is just CLASS; but on some machines
4367 + in some cases it is preferable to use a more restrictive class. */
4368 +#define PREFERRED_RELOAD_CLASS(X,CLASS) m6809_preferred_reload_class(X,CLASS)
4369 +
4370 +#define SMALL_REGISTER_CLASSES 1
4371 +
4372 +/* Return the maximum number of consecutive registers
4373 + needed to represent mode MODE in a register of class CLASS. */
4374 +#define CLASS_MAX_NREGS(CLASS, MODE) \
4375 + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
4376 +
4377 +/*--------------------------------------------------------------
4378 + Stack layout; function entry, exit and calling.
4379 +--------------------------------------------------------------*/
4380 +
4381 +/* Define this if pushing a word on the stack
4382 + makes the stack pointer a smaller address. */
4383 +#define STACK_GROWS_DOWNWARD
4384 +
4385 +
4386 +/* Define this if the nominal address of the stack frame
4387 + is at the high-address end of the local variables;
4388 + that is, each additional local variable allocated
4389 + goes at a more negative offset in the frame. */
4390 +#define FRAME_GROWS_DOWNWARD 1
4391 +
4392 +
4393 +/* Offset within stack frame to start allocating local variables at.
4394 + If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
4395 + first local allocated. Otherwise, it is the offset to the BEGINNING
4396 + of the first local allocated. */
4397 +#define STARTING_FRAME_OFFSET 0
4398 +
4399 +
4400 +/* Always push stack arguments for now. Accumulation is not yet working. */
4401 +#define PUSH_ROUNDING(BYTES) (BYTES)
4402 +
4403 +
4404 +/* Offset of first parameter from the argument pointer register value.
4405 + * ARG_POINTER_REGNUM is defined to point to the return address pushed
4406 + * onto the stack, so we must offset by 2 bytes to get to the arguments. */
4407 +#define FIRST_PARM_OFFSET(FNDECL) 2
4408 +
4409 +/* Value is 1 if returning from a function call automatically
4410 + pops the arguments described by the number-of-args field in the call.
4411 + FUNTYPE is the data type of the function (as a tree),
4412 + or for a library call it is an identifier node for the subroutine name. */
4413 +/* #define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 */
4414 +
4415 +/* Define how to find the value returned by a function.
4416 + VALTYPE is the data type of the value (as a tree).
4417 + If the precise function being called is known, FUNC is its FUNCTION_DECL;
4418 + otherwise, FUNC is 0. */
4419 +#define FUNCTION_VALUE(VALTYPE, FUNC) m6809_function_value (VALTYPE, FUNC)
4420 +
4421 +/* Define how to find the value returned by a library function
4422 + assuming the value has mode MODE. */
4423 +
4424 +/* All return values are in the X-register. */
4425 +#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, HARD_X_REGNUM)
4426 +
4427 +/* Define this if using the nonreentrant convention for returning
4428 + structure and union values. No; it is inefficient and buggy. */
4429 +#undef PCC_STATIC_STRUCT_RETURN
4430 +
4431 +/* 1 if N is a possible register number for a function value. */
4432 +#define FUNCTION_VALUE_REGNO_P(N) m6809_function_value_regno_p (N)
4433 +
4434 +/* Define this to be true when FUNCTION_VALUE_REGNO_P is true for
4435 + more than one register. */
4436 +#define NEEDS_UNTYPED_CALL 1
4437 +
4438 +/* 1 if N is a possible register number for function argument passing. */
4439 +#define FUNCTION_ARG_REGNO_P(N) \
4440 + ((m6809_abi_version != M6809_ABI_VERSION_STACK) ? \
4441 + (((N) == HARD_D_REGNUM) || ((N) == HARD_X_REGNUM)) : \
4442 + 0)
4443 +
4444 +/*--------------------------------------------------------------
4445 + Argument Lists
4446 +--------------------------------------------------------------*/
4447 +
4448 +/* Cumulative arguments are tracked in a single integer,
4449 + * which is the number of bytes of arguments scanned so far,
4450 + * plus which registers have already been used. The register
4451 + * info is kept in some of the upper bits */
4452 +#define CUMULATIVE_ARGS unsigned int
4453 +
4454 +#define CUM_STACK_ONLY 0x80000000
4455 +#define CUM_X_MASK 0x40000000
4456 +#define CUM_B_MASK 0x20000000
4457 +#define CUM_STACK_INVALID 0x10000000
4458 +#define CUM_STACK_MASK 0xFFFFFFF
4459 +
4460 +#define CUM_ADVANCE_8BIT(cum) \
4461 + (((cum) & CUM_B_MASK) ? (cum)++ : ((cum) |= CUM_B_MASK))
4462 +
4463 +#define CUM_ADVANCE_16BIT(cum) \
4464 + (((cum) & CUM_X_MASK) ? (cum) += 2 : ((cum) |= CUM_X_MASK))
4465 +
4466 +/* Initialize a variable CUM of type CUMULATIVE_ARGS
4467 + for a call to a function whose data type is FNTYPE.
4468 + For a library call, FNTYPE is 0.
4469 + N_NAMED was added in gcc 3.4 and is not used currently. */
4470 +#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT,N_NAMED) \
4471 + ((CUM) = m6809_init_cumulative_args (CUM, FNTYPE, LIBNAME))
4472 +
4473 +#define FUNCTION_ARG_SIZE(MODE, TYPE) \
4474 + ((MODE) != BLKmode ? GET_MODE_SIZE (MODE) \
4475 + : (unsigned) int_size_in_bytes (TYPE))
4476 +
4477 +/* Update the data in CUM to advance over an argument
4478 + of mode MODE and data type TYPE.
4479 + (TYPE is null for libcalls where that information may not be available.) */
4480 +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
4481 + (((MODE == QImode) && !((CUM) & CUM_STACK_ONLY)) ? \
4482 + CUM_ADVANCE_8BIT (CUM) : \
4483 + ((MODE == HImode) && !((CUM) & CUM_STACK_ONLY)) ? \
4484 + CUM_ADVANCE_16BIT (CUM) : \
4485 + ((CUM) = ((CUM) + (TYPE ? int_size_in_bytes (TYPE) : 2))))
4486 +
4487 +/* Define where to put the arguments to a function.
4488 + Value is zero to push the argument on the stack,
4489 + or a hard register rtx in which to store the argument.
4490 + This macro is used _before_ FUNCTION_ARG_ADVANCE.
4491 +
4492 + For the 6809, the first 8-bit function argument can be placed into B,
4493 + and the first 16-bit arg can go into X. All other arguments
4494 + will be pushed onto the stack.
4495 +
4496 + Command-line options can adjust this behavior somewhat.
4497 + */
4498 +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
4499 + ((MODE == VOIDmode) ? NULL_RTX : \
4500 + ((MODE == BLKmode) || (GET_MODE_SIZE (MODE) > 2)) ? NULL_RTX : \
4501 + ((MODE == QImode) && !((CUM) & (CUM_STACK_ONLY | CUM_B_MASK))) ? \
4502 + gen_rtx_REG (QImode, HARD_D_REGNUM) : \
4503 + ((MODE == HImode) && !((CUM) & (CUM_STACK_ONLY | CUM_X_MASK))) ? \
4504 + gen_rtx_REG (HImode, HARD_X_REGNUM) : m6809_function_arg_on_stack (&CUM))
4505 +
4506 +/* Output assembler code to FILE to increment profiler label # LABELNO
4507 + for profiling a function entry. */
4508 +#define FUNCTION_PROFILER(FILE, LABELNO) \
4509 + fprintf (FILE, "\tldd\t#LP%u\n\tjsr\tmcount\n", (LABELNO));
4510 +
4511 +/* Stack pointer must be correct on function exit */
4512 +#define EXIT_IGNORE_STACK 0
4513 +
4514 +/*****************************************************************************
4515 +**
4516 +** Trampolines for Nested Functions
4517 +**
4518 +*****************************************************************************/
4519 +
4520 +/* Length in units of the trampoline for entering a nested function. */
4521 +#define TRAMPOLINE_SIZE 7
4522 +
4523 +/*--------------------------------------------------------------
4524 + Addressing modes,
4525 + and classification of registers for them.
4526 +--------------------------------------------------------------*/
4527 +
4528 +/* 6809 has postincrement and predecrement addressing modes */
4529 +#define HAVE_POST_INCREMENT 1
4530 +#define HAVE_PRE_DECREMENT 1
4531 +
4532 +/* Whether or not to use index registers is configurable.
4533 + * Experiments show that things work better when this is off, so
4534 + * that's the way it is for now. */
4535 +#undef USE_INDEX_REGISTERS
4536 +
4537 +
4538 +/* Macros to check register numbers against specific register classes. */
4539 +#define REG_VALID_FOR_BASE_P(REGNO) \
4540 + (((REGNO) < FIRST_PSEUDO_REGISTER) && A_REGNO_P (REGNO))
4541 +
4542 +/* MC6809 index registers do not allow scaling, */
4543 +/* but there is "accumulator-offset" mode. */
4544 +#ifdef USE_INDEX_REGISTERS
4545 +#define REG_VALID_FOR_INDEX_P(REGNO) \
4546 + (((REGNO) < FIRST_PSEUDO_REGISTER) && I_REGNO_P (REGNO))
4547 +#else
4548 +#define REG_VALID_FOR_INDEX_P(REGNO) 0
4549 +#endif
4550 +
4551 +/* Internal macro, the nonstrict definition for REGNO_OK_FOR_BASE_P */
4552 +#define REGNO_OK_FOR_BASE_NONSTRICT_P(REGNO) \
4553 + ((REGNO) >= FIRST_PSEUDO_REGISTER \
4554 + || REG_VALID_FOR_BASE_P (REGNO) \
4555 + || (REGNO) == FRAME_POINTER_REGNUM \
4556 + || (REGNO) == HARD_FRAME_POINTER_REGNUM \
4557 + || (REGNO) == ARG_POINTER_REGNUM \
4558 + || (reg_renumber && REG_VALID_FOR_BASE_P (reg_renumber[REGNO])))
4559 +
4560 +/* Internal macro, the nonstrict definition for REGNO_OK_FOR_INDEX_P */
4561 +#define REGNO_OK_FOR_INDEX_NONSTRICT_P(REGNO) \
4562 + ((REGNO) >= FIRST_PSEUDO_REGISTER \
4563 + || REG_VALID_FOR_INDEX_P (REGNO) \
4564 + || (reg_renumber && REG_VALID_FOR_INDEX_P (reg_renumber[REGNO])))
4565 +
4566 +
4567 +/* Internal macro, the strict definition for REGNO_OK_FOR_BASE_P */
4568 +#define REGNO_OK_FOR_BASE_STRICT_P(REGNO) \
4569 + ((REGNO) < FIRST_PSEUDO_REGISTER ? REG_VALID_FOR_BASE_P (REGNO) \
4570 + : (reg_renumber && REG_VALID_FOR_BASE_P (reg_renumber[REGNO])))
4571 +
4572 +
4573 +/* Internal macro, the strict definition for REGNO_OK_FOR_INDEX_P */
4574 +#define REGNO_OK_FOR_INDEX_STRICT_P(REGNO) \
4575 + ((REGNO) < FIRST_PSEUDO_REGISTER ? REG_VALID_FOR_INDEX_P (REGNO) \
4576 + : (reg_renumber && REG_VALID_FOR_INDEX_P (reg_renumber[REGNO])))
4577 +
4578 +
4579 +#define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_BASE_STRICT_P (REGNO)
4580 +
4581 +#define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_INDEX_STRICT_P (REGNO)
4582 +
4583 +#define REG_OK_FOR_BASE_STRICT_P(X) REGNO_OK_FOR_BASE_STRICT_P (REGNO (X))
4584 +#define REG_OK_FOR_BASE_NONSTRICT_P(X) REGNO_OK_FOR_BASE_NONSTRICT_P (REGNO (X))
4585 +#define REG_OK_FOR_INDEX_STRICT_P(X) REGNO_OK_FOR_INDEX_STRICT_P (REGNO (X))
4586 +#define REG_OK_FOR_INDEX_NONSTRICT_P(X) REGNO_OK_FOR_INDEX_NONSTRICT_P (REGNO (X))
4587 +
4588 +#ifndef REG_OK_STRICT
4589 +#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_NONSTRICT_P(X)
4590 +#ifdef USE_INDEX_REGISTERS
4591 +#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_INDEX_NONSTRICT_P(X)
4592 +#else
4593 +#define REG_OK_FOR_INDEX_P(X) 0
4594 +#endif
4595 +#else
4596 +#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_STRICT_P (X)
4597 +#ifdef USE_INDEX_REGISTERS
4598 +#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_INDEX_STRICT_P (X)
4599 +#else
4600 +#define REG_OK_FOR_INDEX_P(X) 0
4601 +#endif
4602 +#endif
4603 +
4604 +/* Maximum number of registers that can appear in a valid memory address */
4605 +#ifdef USE_INDEX_REGISTERS
4606 +#define MAX_REGS_PER_ADDRESS 2
4607 +#else
4608 +#define MAX_REGS_PER_ADDRESS 1
4609 +#endif
4610 +
4611 +/* 1 if X is an rtx for a constant that is a valid address.
4612 + * We allow any constant, plus the sum of any two constants (this allows
4613 + * offsetting a symbol ref) */
4614 +#define CONSTANT_ADDRESS_P(X) \
4615 + ((CONSTANT_P (X)) \
4616 + || ((GET_CODE (X) == PLUS) \
4617 + && (CONSTANT_P (XEXP (X, 0))) && (CONSTANT_P (XEXP (X, 1)))))
4618 +
4619 +/* Nonzero if the constant value X is a legitimate general operand.
4620 + It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
4621 +/* Any single-word constant is ok; the only contexts
4622 + allowing general_operand of mode DI or DF are movdi and movdf. */
4623 +#define LEGITIMATE_CONSTANT_P(X) (GET_CODE (X) != CONST_DOUBLE)
4624 +
4625 +/* Nonzero if the X is a legitimate immediate operand in PIC mode. */
4626 +#define LEGITIMATE_PIC_OPERAND_P(X) !symbolic_operand (X, VOIDmode)
4627 +
4628 +/*--------------------------------------------------------------
4629 + Test for valid memory addresses
4630 +--------------------------------------------------------------*/
4631 +/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
4632 + that is a valid memory address for an instruction.
4633 + The MODE argument is the machine mode for the MEM expression
4634 + that wants to use this address. */
4635 +
4636 +/*--------------------------------------------------------------
4637 + Valid addresses are either direct or indirect (MEM) versions
4638 + of the following forms.
4639 + constant N
4640 + register ,X
4641 + constant indexed N,X
4642 + accumulator indexed D,X
4643 + auto_increment ,X++
4644 + auto_decrement ,--X
4645 +--------------------------------------------------------------*/
4646 +
4647 +#define REGISTER_ADDRESS_P(X) \
4648 + (REG_P (X) && REG_OK_FOR_BASE_P (X))
4649 +
4650 +#define EXTENDED_ADDRESS_P(X) \
4651 + CONSTANT_ADDRESS_P (X) \
4652 +
4653 +#define LEGITIMATE_BASE_P(X) \
4654 + ((REG_P (X) && REG_OK_FOR_BASE_P (X)) \
4655 + || (GET_CODE (X) == SIGN_EXTEND \
4656 + && GET_CODE (XEXP (X, 0)) == REG \
4657 + && GET_MODE (XEXP (X, 0)) == HImode \
4658 + && REG_OK_FOR_BASE_P (XEXP (X, 0))))
4659 +
4660 +#define LEGITIMATE_OFFSET_P(X) \
4661 + (CONSTANT_ADDRESS_P (X) || (REG_P (X) && REG_OK_FOR_INDEX_P (X)))
4662 +
4663 +/* 1 if X is the sum of a base register and an offset. */
4664 +#define INDEXED_ADDRESS(X) \
4665 + ((GET_CODE (X) == PLUS \
4666 + && LEGITIMATE_BASE_P (XEXP (X, 0)) \
4667 + && LEGITIMATE_OFFSET_P (XEXP (X, 1))) \
4668 + || (GET_CODE (X) == PLUS \
4669 + && LEGITIMATE_BASE_P (XEXP (X, 1)) \
4670 + && LEGITIMATE_OFFSET_P (XEXP (X, 0))))
4671 +
4672 +#define STACK_REG_P(X) (REG_P(X) && REGNO(X) == HARD_S_REGNUM)
4673 +
4674 +#define STACK_PUSH_P(X) \
4675 + (MEM_P (X) && GET_CODE (XEXP (X, 0)) == PRE_DEC && STACK_REG_P (XEXP (XEXP (X, 0), 0)))
4676 +
4677 +#define STACK_POP_P(X) \
4678 + (MEM_P (X) && GET_CODE (XEXP (X, 0)) == POST_INC && STACK_REG_P (XEXP (XEXP (X, 0), 0)))
4679 +
4680 +#define PUSH_POP_ADDRESS_P(X) \
4681 + (((GET_CODE (X) == PRE_DEC) || (GET_CODE (X) == POST_INC)) \
4682 + && (LEGITIMATE_BASE_P (XEXP (X, 0))))
4683 +
4684 +/* Go to ADDR if X is a valid address. */
4685 +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
4686 +{ \
4687 + if (REGISTER_ADDRESS_P(X)) goto ADDR; \
4688 + if (PUSH_POP_ADDRESS_P (X)) goto ADDR; \
4689 + if (EXTENDED_ADDRESS_P (X)) goto ADDR; \
4690 + if (INDEXED_ADDRESS (X)) goto ADDR; \
4691 + if (MEM_P (X) && REGISTER_ADDRESS_P(XEXP (X, 0))) goto ADDR; \
4692 + if (MEM_P (X) && PUSH_POP_ADDRESS_P (XEXP (X, 0))) goto ADDR; \
4693 + if (MEM_P (X) && EXTENDED_ADDRESS_P (XEXP (X, 0))) goto ADDR; \
4694 + if (MEM_P (X) && INDEXED_ADDRESS (XEXP (X, 0))) goto ADDR; \
4695 +}
4696 +
4697 +/*--------------------------------------------------------------
4698 + Address Fix-up
4699 +--------------------------------------------------------------*/
4700 +/* Go to LABEL if ADDR (a legitimate address expression)
4701 + has an effect that depends on the machine mode it is used for.
4702 + In the latest GCC, this case is already handled by the core code
4703 + so no action is required here. */
4704 +#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) {}
4705 +
4706 +
4707 +/*--------------------------------------------------------------
4708 + Miscellaneous Parameters
4709 +--------------------------------------------------------------*/
4710 +/* Specify the machine mode that this machine uses
4711 + for the index in the tablejump instruction. */
4712 +#define CASE_VECTOR_MODE Pmode
4713 +
4714 +/* Define this as 1 if `char' should by default be signed; else as 0. */
4715 +#define DEFAULT_SIGNED_CHAR 0
4716 +
4717 +/* This flag, if defined, says the same insns that convert to a signed fixnum
4718 + also convert validly to an unsigned one. */
4719 +#define FIXUNS_TRUNC_LIKE_FIX_TRUNC
4720 +
4721 +/* Max number of bytes we can move from memory to memory/register
4722 + in one reasonably fast instruction. */
4723 +#define MOVE_MAX 2
4724 +
4725 +/* Int can be 8 or 16 bits (default is 16) */
4726 +#define INT_TYPE_SIZE (TARGET_BYTE_INT ? 8 : 16)
4727 +
4728 +/* Short is always 16 bits */
4729 +#define SHORT_TYPE_SIZE (TARGET_BYTE_INT ? 8 : 16)
4730 +
4731 +/* Size (bits) of the type "long" on target machine */
4732 +#define LONG_TYPE_SIZE (TARGET_BYTE_INT ? 16 : 32)
4733 +
4734 +/* Size (bits) of the type "long long" on target machine */
4735 +#define LONG_LONG_TYPE_SIZE 32
4736 +
4737 +/* Size (bits) of the type "char" on target machine */
4738 +#define CHAR_TYPE_SIZE 8
4739 +
4740 +/* Size (bits) of the type "float" on target machine */
4741 +#define FLOAT_TYPE_SIZE 32
4742 +
4743 +/* Size (bits) of the type "double" on target machine.
4744 + * Note that the C standard does not require that doubles
4745 + * hold any more bits than float. Since the 6809 has so few
4746 + * registers, we cannot really support more than 32-bits. */
4747 +#define DOUBLE_TYPE_SIZE 32
4748 +
4749 +/* Size (bits) of the type "long double" on target machine */
4750 +#define LONG_DOUBLE_TYPE_SIZE 32
4751 +
4752 +/* Define the type used for "size_t". With a 64KB address space,
4753 + * only a 16-bit value here makes sense. */
4754 +#define SIZE_TYPE (TARGET_BYTE_INT ? "long unsigned int" : "unsigned int")
4755 +
4756 +/* Likewise, the difference between two pointers is also a 16-bit
4757 + * signed value. */
4758 +#define PTRDIFF_TYPE (TARGET_BYTE_INT ? "long int" : "int")
4759 +
4760 +/* Nonzero if access to memory by bytes is slow and undesirable. */
4761 +#define SLOW_BYTE_ACCESS 0
4762 +
4763 +/* Define if shifts truncate the shift count
4764 + which implies one can omit a sign-extension or zero-extension
4765 + of a shift count. */
4766 +#define SHIFT_COUNT_TRUNCATED 0
4767 +
4768 +/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
4769 + is done just by pretending it is already truncated. */
4770 +#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
4771 +
4772 +/* It is as good to call a constant function address as to
4773 + call an address kept in a register. */
4774 +#define NO_FUNCTION_CSE
4775 +
4776 +/* Specify the machine mode that pointers have.
4777 + After generation of rtl, the compiler makes no further distinction
4778 + between pointers and any other objects of this machine mode. */
4779 +#define Pmode HImode
4780 +
4781 +/* A function address in a call instruction
4782 + is a byte address (for indexing purposes)
4783 + so give the MEM rtx a byte's mode. */
4784 +#define FUNCTION_MODE HImode
4785 +
4786 +/* Define the cost of moving a value from a register in CLASS1
4787 + * to CLASS2, of a given MODE.
4788 + *
4789 + * On the 6809, hard register transfers are all basically equivalent.
4790 + * But soft register moves are treated more like memory moves. */
4791 +#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
4792 + (((CLASS1 == M_REGS) || (CLASS2 == M_REGS)) ? 4 : 7)
4793 +
4794 +/* Define the cost of moving a value between a register and memory. */
4795 +#define MEMORY_MOVE_COST(MODE, CLASS, IN) 5
4796 +
4797 +/* Check a `double' value for validity for a particular machine mode. */
4798 +
4799 +#define CHECK_FLOAT_VALUE(MODE, D, OVERFLOW) \
4800 + ((OVERFLOW) = check_float_value (MODE, &D, OVERFLOW))
4801 +
4802 +
4803 +/*--------------------------------------------------------------
4804 + machine-dependent
4805 +--------------------------------------------------------------*/
4806 +/* Tell final.c how to eliminate redundant test instructions. */
4807 +
4808 +/* Here we define machine-dependent flags and fields in cc_status
4809 + (see `conditions.h'). */
4810 +
4811 +/* Store in cc_status the expressions
4812 + that the condition codes will describe
4813 + after execution of an instruction whose pattern is EXP.
4814 + Do not alter them if the instruction would not alter the cc's. */
4815 +
4816 +/* On the 6809, most of the insns to store in an address register
4817 + fail to set the cc's. However, in some cases these instructions
4818 + can make it possibly invalid to use the saved cc's. In those
4819 + cases we clear out some or all of the saved cc's so they won't be used. */
4820 +
4821 +#define NOTICE_UPDATE_CC(EXP, INSN) \
4822 + notice_update_cc((EXP), (INSN))
4823 +
4824 +/*****************************************************************************
4825 +**
4826 +** pragma support
4827 +**
4828 +*****************************************************************************/
4829 +
4830 +#if 0
4831 +#define REGISTER_TARGET_PRAGMAS() \
4832 +do { \
4833 + extern void pragma_section PARAMS ((cpp_reader *)); \
4834 + c_register_pragma (0, "section", pragma_section); \
4835 +} while (0)
4836 +
4837 +#endif
4838 +
4839 +/*--------------------------------------------------------------
4840 + ASSEMBLER FORMAT
4841 +--------------------------------------------------------------*/
4842 +
4843 +#define FMT_HOST_WIDE_INT "%ld"
4844 +
4845 +/* Output to assembler file text saying following lines
4846 + may contain character constants, extra white space, comments, etc. */
4847 +#define ASM_APP_ON ";----- asm -----\n"
4848 +
4849 +/* Output to assembler file text saying following lines
4850 + no longer contain unusual constructs. */
4851 +#define ASM_APP_OFF ";--- end asm ---\n"
4852 +
4853 +/* Use a semicolon to begin a comment. */
4854 +#define ASM_COMMENT_START "; "
4855 +
4856 +/* Output assembly directives to switch to section 'name' */
4857 +#undef TARGET_ASM_NAMED_SECTION
4858 +#define TARGET_ASM_NAMED_SECTION m6809_asm_named_section
4859 +
4860 +#undef TARGET_HAVE_NAMED_SECTION
4861 +#define TARGET_HAVE_NAMED_SECTION m6809_have_named_section
4862 +
4863 +/* Output before read-only data. */
4864 +#define TEXT_SECTION_ASM_OP (code_section_op)
4865 +
4866 +/* Output before writable data. */
4867 +#define DATA_SECTION_ASM_OP (data_section_op)
4868 +
4869 +/* Output before uninitialized data. */
4870 +#define BSS_SECTION_ASM_OP (bss_section_op)
4871 +
4872 +/* Support the ctors and dtors sections for g++. */
4873 +
4874 +#undef CTORS_SECTION_ASM_OP
4875 +#define CTORS_SECTION_ASM_OP "\t.area .ctors"
4876 +#undef DTORS_SECTION_ASM_OP
4877 +#define DTORS_SECTION_ASM_OP "\t.area .dtors"
4878 +
4879 +
4880 +#undef DO_GLOBAL_CTORS_BODY
4881 +#undef DO_GLOBAL_DTORS_BODY
4882 +
4883 +#define HAS_INIT_SECTION
4884 +
4885 +/* This is how to output an assembler line
4886 + that says to advance the location counter
4887 + to a multiple of 2**LOG bytes. */
4888 +
4889 +#define ASM_OUTPUT_ALIGN(FILE,LOG) \
4890 + if ((LOG) > 1) \
4891 + fprintf (FILE, "\t.bndry %u\n", 1 << (LOG))
4892 +
4893 +/* The .set foo,bar construct doesn't work by default */
4894 +#undef SET_ASM_OP
4895 +#define ASM_OUTPUT_DEF(FILE, LABEL1, LABEL2) \
4896 + do \
4897 + { \
4898 + fputc ('\t', FILE); \
4899 + assemble_name (FILE, LABEL1); \
4900 + fputs (" = ", FILE); \
4901 + assemble_name (FILE, LABEL2); \
4902 + fputc ('\n', FILE); \
4903 + } \
4904 + while (0)
4905 +
4906 +/* How to refer to registers in assembler output.
4907 + This sequence is indexed by compiler's hard-register-number (see above). */
4908 +#define MNAME(x) [SOFT_M0_REGNUM+(x)] = "*m" C_STRING(x) ,
4909 +
4910 +#define REGISTER_NAMES { \
4911 + [HARD_D_REGNUM]= "d", \
4912 + [HARD_X_REGNUM]= "x", \
4913 + [HARD_Y_REGNUM]= "y", \
4914 + [HARD_U_REGNUM]= "u", \
4915 + [HARD_S_REGNUM]= "s", \
4916 + [HARD_PC_REGNUM]= "pc", \
4917 + [HARD_A_REGNUM]= "a", \
4918 + [HARD_B_REGNUM]= "b", \
4919 + [HARD_CC_REGNUM]= "cc",\
4920 + [HARD_DP_REGNUM]= "dp", \
4921 + [SOFT_FP_REGNUM]= "soft_fp", \
4922 + [SOFT_AP_REGNUM]= "soft_ap", \
4923 + MNAME(0) MNAME(1) MNAME(2) MNAME(3) \
4924 + MNAME(4) MNAME(5) MNAME(6) MNAME(7) \
4925 + [HARD_RSVD1_REGNUM] = "-", \
4926 + [HARD_Z_REGNUM] = "z" /* bit 2 of CC */ }
4927 +
4928 +/*****************************************************************************
4929 +**
4930 +** Debug Support
4931 +**
4932 +*****************************************************************************/
4933 +
4934 +/* Default to DBX-style debugging */
4935 +#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
4936 +
4937 +#define DBX_DEBUGGING_INFO
4938 +
4939 +#define DEFAULT_GDB_EXTENSIONS 0
4940 +
4941 +#define ASM_STABS_OP ";\t.stabs\t"
4942 +#define ASM_STABD_OP ";\t.stabd\t"
4943 +#define ASM_STABN_OP ";\t.stabn\t"
4944 +
4945 +#define DBX_CONTIN_LENGTH 54
4946 +
4947 +#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(ASMFILE, FILENAME) \
4948 +do { \
4949 + const char *p = FILENAME; \
4950 + while ((p = strchr (p, '/')) != NULL) { \
4951 + p = FILENAME = p+1; \
4952 + } \
4953 + fprintf (ASMFILE, "%s", ASM_STABS_OP); \
4954 + output_quoted_string (ASMFILE, FILENAME); \
4955 + fprintf (ASMFILE, ",%d,0,0,", N_SO); \
4956 + assemble_name (ASMFILE, ltext_label_name); \
4957 + fputc ('\n', ASMFILE); \
4958 + switch_to_section (text_section); \
4959 + (*targetm.asm_out.internal_label) (ASMFILE, "Ltext", 0); \
4960 +} while (0)
4961 +
4962 +/* With -g, GCC sometimes outputs string literals that are longer than
4963 + * the assembler can handle. Without actual debug support, these are
4964 + * not really required. Redefine the function to output strings to
4965 + * output as much as possible. */
4966 +#define OUTPUT_QUOTED_STRING(FILE, STR) m6809_output_quoted_string (FILE, STR)
4967 +
4968 +/*****************************************************************************
4969 +**
4970 +** Output and Generation of Labels
4971 +**
4972 +*****************************************************************************/
4973 +
4974 +/* Prefixes for various assembly-time objects */
4975 +
4976 +#define REGISTER_PREFIX ""
4977 +
4978 +#define LOCAL_LABEL_PREFIX ""
4979 +
4980 +#define USER_LABEL_PREFIX "_"
4981 +
4982 +#define IMMEDIATE_PREFIX "#"
4983 +
4984 +/* This is how to output the definition of a user-level label named NAME,
4985 + such as the label on a static function or variable NAME. */
4986 +
4987 +#define ASM_OUTPUT_LABEL(FILE,NAME) \
4988 +do { \
4989 + if (section_changed) { \
4990 + fprintf (FILE, "\n%s\n\n", code_section_op); \
4991 + section_changed = 0; \
4992 + } \
4993 + assemble_name (FILE, NAME); \
4994 + fputs (":\n", FILE); \
4995 +} while (0)
4996 +
4997 +/* This is how to output the label for a function definition. It
4998 + invokes ASM_OUTPUT_LABEL, but may examine the DECL tree node for
4999 + other properties. */
5000 +#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \
5001 + m6809_declare_function_name (FILE,NAME,DECL)
5002 +
5003 +/* This is how to output a command to make the user-level label
5004 + named NAME defined for reference from other files. */
5005 +
5006 +#define GLOBAL_ASM_OP "\t.globl "
5007 +
5008 +/* This is how to output a reference to a user label named NAME. */
5009 +#define ASM_OUTPUT_LABELREF(FILE,NAME) \
5010 + fprintf (FILE, "_%s", NAME)
5011 +
5012 +/* This is how to output a reference to a symbol ref
5013 + * Check to see if the symbol is in the direct page */
5014 +#define ASM_OUTPUT_SYMBOL_REF(FILE,sym) \
5015 +{ \
5016 + print_direct_prefix (FILE, sym); \
5017 + assemble_name (FILE, XSTR (sym, 0)); \
5018 +}
5019 +
5020 +/* External references aren't necessary, so don't emit anything */
5021 +#define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME)
5022 +
5023 +/* This is how to store into the string LABEL
5024 + the symbol_ref name of an internal numbered label where
5025 + PREFIX is the class of label and NUM is the number within the class.
5026 + This is suitable for output with `assemble_name'. */
5027 +#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
5028 + sprintf (LABEL, "*%s%lu", PREFIX, (unsigned long int)NUM)
5029 +
5030 +/* This is how to output an assembler line defining an `int' constant. */
5031 +#define ASM_OUTPUT_INT(FILE,VALUE) \
5032 +( fprintf (FILE, "\t.word "), \
5033 + output_addr_const (FILE, (VALUE)), \
5034 + fprintf (FILE, "\n"))
5035 +
5036 +/* Likewise for `char' and `short' constants. */
5037 +#define ASM_OUTPUT_SHORT(FILE,VALUE) \
5038 +( fprintf (FILE, "\t.word "), \
5039 + output_addr_const (FILE, (VALUE)), \
5040 + fprintf (FILE, "\n"))
5041 +
5042 +/* This is how to output a string. */
5043 +#define ASM_OUTPUT_ASCII(FILE,STR,SIZE) m6809_output_ascii (FILE, STR, SIZE)
5044 +
5045 +/* This is how to output an insn to push a register on the stack.
5046 + It need not be very fast code. */
5047 +
5048 +#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
5049 + fprintf (FILE, "\tpshs\t%s\n", reg_names[REGNO])
5050 +
5051 +/* This is how to output an insn to pop a register from the stack.
5052 + It need not be very fast code. */
5053 +
5054 +#define ASM_OUTPUT_REG_POP(FILE,REGNO) \
5055 + fprintf (FILE, "\tpuls\t%s\n", reg_names[REGNO])
5056 +
5057 +/* This is how to output an element of a case-vector that is absolute. */
5058 +
5059 +#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
5060 + fprintf (FILE, "\t.word L%u\n", VALUE)
5061 +
5062 +/* This is how to output an element of a case-vector that is relative. */
5063 +
5064 +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
5065 + fprintf (FILE, "\t.word L%u-L%u\n", VALUE, REL)
5066 +
5067 +
5068 +/*****************************************************************************
5069 +**
5070 +** Assembler Commands for Alignment
5071 +**
5072 +*****************************************************************************/
5073 +
5074 +/* ASM_OUTPUT_SKIP is supposed to zero initialize the data.
5075 + * So use the .byte and .word directives instead of .blkb */
5076 +#define ASM_OUTPUT_SKIP(FILE,SIZE) \
5077 + do { \
5078 + int __size = SIZE; \
5079 + while (__size > 0) { \
5080 + if (__size >= 2) \
5081 + { \
5082 + fprintf (FILE, "\t.word\t0\t;skip space %d\n", __size); \
5083 + __size -= 2; \
5084 + } \
5085 + else \
5086 + { \
5087 + fprintf (FILE, "\t.byte\t0\t;skip space\n"); \
5088 + __size--; \
5089 + } \
5090 + } \
5091 + } while (0)
5092 +
5093 +/* This says how to output an assembler line
5094 + to define a global common symbol. */
5095 +
5096 +#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
5097 + do { \
5098 + switch_to_section (bss_section); \
5099 + fputs ("\t.globl\t", FILE); \
5100 + assemble_name ((FILE), (NAME)); \
5101 + fputs ("\n", FILE); \
5102 + assemble_name ((FILE), (NAME)); \
5103 + fprintf ((FILE), ":\t.blkb\t" FMT_HOST_WIDE_INT "\n", (ROUNDED));} while(0)
5104 +
5105 +/* This says how to output an assembler line
5106 + to define a local common symbol. */
5107 +
5108 +#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
5109 +do { \
5110 + switch_to_section (bss_section); \
5111 + assemble_name ((FILE), (NAME)); \
5112 + fprintf ((FILE), ":\t.blkb\t" FMT_HOST_WIDE_INT "\n", (ROUNDED));} while(0)
5113 +
5114 +/* Store in OUTPUT a string (made with alloca) containing
5115 + an assembler-name for a local static variable named NAME.
5116 + LABELNO is an integer which is different for each call. */
5117 +
5118 +#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
5119 +( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
5120 + sprintf ((OUTPUT), "%s.%lu", (NAME), (unsigned long int)(LABELNO)))
5121 +
5122 +/* Print an instruction operand X on file FILE.
5123 + CODE is the code from the %-spec for printing this operand.
5124 + If `%z3' was used to print operand 3, then CODE is 'z'. */
5125 +#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
5126 +
5127 +/* Print a memory operand whose address is X, on file FILE. */
5128 +#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
5129 +
5130 +/* Don't let stack pushes build up too much. */
5131 +#define MAX_PENDING_STACK 8
5132 +
5133 +/* Define values for builtin operations */
5134 +enum m6809_builtins
5135 +{
5136 + M6809_SWI,
5137 + M6809_SWI2,
5138 + M6809_SWI3,
5139 + M6809_CWAI,
5140 + M6809_SYNC,
5141 + M6809_ADD_CARRY,
5142 + M6809_SUB_CARRY,
5143 + M6809_ADD_DECIMAL,
5144 + M6809_NOP,
5145 + M6809_BLOCKAGE
5146 +};
5147 +
5148 diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.md gcc-4.6.4/gcc/config/m6809/m6809.md
5149 --- gcc-4.6.4-clean/gcc/config/m6809/m6809.md 1969-12-31 17:00:00.000000000 -0700
5150 +++ gcc-4.6.4/gcc/config/m6809/m6809.md 2015-07-20 22:05:21.702720231 -0600
5151 @@ -0,0 +1,2358 @@
5152 +;; GCC machine description for Motorola 6809
5153 +;; Copyright (C) 1989, 2005, 2006, 2007, 2008,
5154 +;; 2009 Free Software Foundation, Inc.
5155 +;;
5156 +;; Mostly by Brian Dominy (brian@oddchange.com) with substantial renovations
5157 +;; by William Astle (lost@l-w.ca).
5158 +;;
5159 +;; Based on earlier work by Tom Jones (jones@sal.wisc.edu) and
5160 +;; Matthias Doerfel (msdoerfe@informatik.uni-erlangen.de)
5161 +;;
5162 +;; This file is part of GCC.
5163 +;;
5164 +;; GCC is free software; you can redistribute it and/or modify
5165 +;; it under the terms of the GNU General Public License as published by
5166 +;; the Free Software Foundation; either version 3, or (at your option)
5167 +;; any later version.
5168 +;;
5169 +;; GCC is distributed in the hope that it will be useful,
5170 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
5171 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5172 +;; GNU General Public License for more details.
5173 +;;
5174 +;; You should have received a copy of the GNU General Public License
5175 +;; along with GCC; see the file COPYING3. If not see
5176 +;; <http://www.gnu.org/licenses/>.
5177 +;;
5178 +;; General information:
5179 +;; --------------------
5180 +;; * This backend is mostly a rewrite from earlier (3.1.1 and before)
5181 +;; versions.
5182 +;;
5183 +;; * The 'A' and 'B' registers are treated as a single register by the
5184 +;; register allocator; hence, the instruction templates assume that
5185 +;; both can be modified if either one is available for use. No
5186 +;; attempt is made to split instructions to refer to a particular half
5187 +;; of the register. It is always referred to as the 'D' register, even
5188 +;; in QImode (when it will be displayed as 'B').
5189 +;;
5190 +;; * There is full support for proper branch instruction generation,
5191 +;; based on instruction lengths. However, many instruction patterns
5192 +;; are still overloaded to emit lots of real instructions, which can
5193 +;; make the length calculation difficult; in those cases, I've tried
5194 +;; to be pessimistic and assume the worst-case.
5195 +;;
5196 +;; * The instruction type attributes are only defined for branch
5197 +;; vs. non branch instructions for now, since there is seemingly no
5198 +;; reason to define these for other types anyway.
5199 +;;
5200 +;; * The limited number of total registers presents the greatest
5201 +;; challenge. There are 'soft registers' -- memory locations
5202 +;; used to simulate real regs -- which can be helpful.
5203 +;;
5204 +;; * Position-independent code (PIC) is supported and has been tested
5205 +;; but not to the extent of absolute code generation.
5206 +;;
5207 +;; * All of the 6809 special opcodes, e.g. SWI and SYNC, are defined
5208 +;; as UNSPEC instructions, and can be accessed from C code using
5209 +;; __builtin_xxxx() style functions.
5210 +;;
5211 +;; What still needs to be done:
5212 +;; ----------------------------
5213 +;; * Replace remaining instances of (define_peephole) with
5214 +;; (define_peephole2), or remove them completely if they are not
5215 +;; matching anyway. Add more peepholes for things actually encountered.
5216 +;;
5217 +;; * Indexing addressing can lead to crashes in complex functions when
5218 +;; register pressure is high. Only the 'D' register can actually be
5219 +;; used as an index register, and its demand by other instructions
5220 +;; can sometimes mean that it is impossible to satisfy constraints.
5221 +;; Currently, indexing is completely disabled to avoid these types
5222 +;; of problems, although code is slightly more inefficient in some
5223 +;; working cases.
5224 +;;
5225 +;; * 32-bit math is terribly inefficient.
5226 +;;
5227 +
5228 +
5229 +;;--------------------------------------------------------------------
5230 +;;- Constants
5231 +;;--------------------------------------------------------------------
5232 +
5233 +;
5234 +; Define constants for hard register numbers.
5235 +;
5236 +(define_constants [
5237 + (HARD_RSVD1_REGNUM 0)
5238 + (HARD_X_REGNUM 1) (HARD_Y_REGNUM 2) (HARD_U_REGNUM 3)
5239 + (HARD_S_REGNUM 4) (HARD_PC_REGNUM 5) (HARD_D_REGNUM 6)
5240 + (HARD_Z_REGNUM 7)
5241 + (HARD_A_REGNUM 8) (HARD_B_REGNUM 9)
5242 + (HARD_CC_REGNUM 10) (HARD_DP_REGNUM 11)
5243 + (SOFT_FP_REGNUM 12) (SOFT_AP_REGNUM 13)
5244 + (SOFT_M0_REGNUM 14) (SOFT_M1_REGNUM 15)
5245 + (SOFT_M2_REGNUM 16) (SOFT_M3_REGNUM 17)
5246 +])
5247 +
5248 +
5249 +;
5250 +; The range in which a short branch insn can be used.
5251 +;
5252 +(define_constants [
5253 + (MIN_SHORT_BRANCH_OFFSET -127)
5254 + (MAX_SHORT_BRANCH_OFFSET 128)
5255 +])
5256 +
5257 +
5258 +;
5259 +; The lengths of various types of real 6809 instructions.
5260 +;
5261 +; By default, ordinary insns are 4 bytes long. This is often not
5262 +; right, and the insn patterns below will redefine this to the
5263 +; correct value.
5264 +;
5265 +; Branch instruction lengths (conditional and unconditionals) are
5266 +; well known and declared here. The short insns are used when the
5267 +; offset is within the range declared above (between MIN_SHORT
5268 +; and MAX_SHORT) ; otherwise the long form is used.
5269 +;
5270 +(define_constants [
5271 + (DEFAULT_INSN_LENGTH 4)
5272 + (SHORT_CBRANCH_LENGTH 2)
5273 + (LONG_CBRANCH_LENGTH 4)
5274 + (SHORT_BRANCH_LENGTH 2)
5275 + (LONG_BRANCH_LENGTH 3)
5276 +])
5277 +
5278 +
5279 +;
5280 +; Constants for insn cycle counts.
5281 +; Note that these counts all assume 1-byte opcodes. 2-byte
5282 +; opcodes require 1 extra cycles for fetching the extra byte.
5283 +;
5284 +(define_constants [
5285 + ;; The default insn length, when it cannot be calculated.
5286 + ;; Take a conservative approach and estimate high.
5287 + (DEFAULT_INSN_CYCLES 10)
5288 +
5289 + ;; Cycle counts for ALU and load operations.
5290 + (ALU_INHERENT_CYCLES 2)
5291 + (ALU_IMMED_CYCLES 2)
5292 + (ALU_DIRECT_CYCLES 4)
5293 + (ALU_INDEXED_BASE_CYCLES 4)
5294 + (ALU_EXTENDED_CYCLES 5)
5295 +
5296 + ;; If an ALU operation is on a 16-bit register (D), then
5297 + ;; add this number of cycles to the total count.
5298 + (ALU_16BIT_CYCLES 2)
5299 +
5300 + ;; A load of a 16-bit register incurs this extra amount.
5301 + (LOAD_16BIT_CYCLES 1)
5302 +
5303 + ;; Cycle counts for memory-only operations (bit shifts, clear, test)
5304 + (MEM_DIRECT_CYCLES 6)
5305 + (MEM_INDEXED_BASE_CYCLES 6)
5306 + (MEM_EXTENDED_CYCLES 7)
5307 +
5308 + ;; Cycle count for any reg-reg transfer (regardless of size)
5309 + (EXG_CYCLES 8)
5310 + (TFR_CYCLES 6)
5311 +
5312 + ;; Cycle count for a condition code update (andcc/orcc)
5313 + (CC_CYCLES 3)
5314 +
5315 + (JMP_DIRECT_CYCLES 3)
5316 + (JMP_INDEXED_BASE_CYCLES 3)
5317 + (JMP_EXTENDED_CYCLES 4)
5318 +
5319 + (JSR_DIRECT_CYCLES 7)
5320 + (JSR_INDEXED_BASE_CYCLES 7)
5321 + (JSR_EXTENDED_CYCLES 8)
5322 +
5323 + (LEA_BASE_CYCLES 4)
5324 +
5325 + ;; Cycle count for a psh/pul operations. Add to this the
5326 + ;; total number of bytes moved for the correct count.
5327 + (PSH_PUL_CYCLES 5)
5328 +
5329 + ;; Miscellaneous cycle counts
5330 + (CWAI_CYCLES 20)
5331 + (MUL_CYCLES 11)
5332 + (NOP_CYCLES 2)
5333 + (RTI_CYCLES 15)
5334 + (RTS_CYCLES 5)
5335 + (SWI_CYCLES 20)
5336 + (SYNC_CYCLES 4)
5337 +])
5338 +
5339 +
5340 +;
5341 +; An enumeration of values for each "unspec"; i.e. unspecified
5342 +; instruction. These represent insns that are meaningful on the
5343 +; 6809 but which have no intrinsic meaning to GCC itself.
5344 +; These insns can be generated explicitly using the __builtin_xxx
5345 +; syntax; they are also implicitly generated by the backend
5346 +; as needed to implement other insns.
5347 +;
5348 +(define_constants [
5349 + (UNSPEC_BLOCKAGE 0)
5350 + (UNSPEC_PUSH_RS 1)
5351 + (UNSPEC_POP_RS 2)
5352 + (UNSPEC_SWI 3)
5353 + (UNSPEC_CWAI 4)
5354 + (UNSPEC_ADD_CARRY 5)
5355 + (UNSPEC_SUB_CARRY 6)
5356 + (UNSPEC_SYNC 7)
5357 + (UNSPEC_ADD_DECIMAL 8)
5358 +])
5359 +
5360 +
5361 +;;--------------------------------------------------------------------
5362 +;;- Predicates
5363 +;;--------------------------------------------------------------------
5364 +
5365 +(include "predicates.md")
5366 +
5367 +;;--------------------------------------------------------------------
5368 +;;- Attributes
5369 +;;--------------------------------------------------------------------
5370 +
5371 +;;
5372 +;; The type attribute is used to distinguish between different
5373 +;; types of branch instructions, so that their lengths can be
5374 +;; calculated correctly.
5375 +;;
5376 +(define_attr "type" "branch,cbranch,unknown" (const_string "unknown"))
5377 +
5378 +;;
5379 +;; The length of a branch instruction is calculated based on how
5380 +;; far away the branch target is. Lengths of other insns default
5381 +;; to 4. set_attr is used in instruction templates to specify
5382 +;; the length when it is known exactly. When not sure, err on
5383 +;; the high side to avoid compile errors.
5384 +;;
5385 +(define_attr "length" ""
5386 + (cond [
5387 + (eq_attr "type" "branch")
5388 + (if_then_else (lt (minus (match_dup 0) (pc))
5389 + (const_int MIN_SHORT_BRANCH_OFFSET))
5390 + (const_int LONG_BRANCH_LENGTH)
5391 + (if_then_else (gt (minus (match_dup 0) (pc))
5392 + (const_int MAX_SHORT_BRANCH_OFFSET))
5393 + (const_int LONG_BRANCH_LENGTH)
5394 + (const_int SHORT_BRANCH_LENGTH)))
5395 + (eq_attr "type" "cbranch")
5396 + (if_then_else (lt (minus (match_dup 0) (pc))
5397 + (const_int MIN_SHORT_BRANCH_OFFSET))
5398 + (const_int LONG_CBRANCH_LENGTH)
5399 + (if_then_else (gt (minus (match_dup 0) (pc))
5400 + (const_int MAX_SHORT_BRANCH_OFFSET))
5401 + (const_int LONG_CBRANCH_LENGTH)
5402 + (const_int SHORT_CBRANCH_LENGTH)))
5403 + ] (const_int DEFAULT_INSN_LENGTH)))
5404 +
5405 +
5406 +;;
5407 +;; The default attributes for 'asm' statements.
5408 +;; The default length is the longest possible single 6809 instruction,
5409 +;; which is 5 bytes. GCC will automatically multiply this by the
5410 +;; number of real insns contained in an asm statement.
5411 +;;
5412 +(define_asm_attributes
5413 + [(set_attr "length" "5")
5414 + (set_attr "type" "unknown")])
5415 +
5416 +;;
5417 +;; An attribute for the number of cycles that it takes an instruction
5418 +;; to execute.
5419 +;;
5420 +(define_attr "cycles" "" (const_int DEFAULT_INSN_CYCLES))
5421 +
5422 +
5423 +;;--------------------------------------------------------------------
5424 +;;- Instruction patterns. When multiple patterns apply,
5425 +;;- the first one in the file is chosen.
5426 +;;-
5427 +;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
5428 +;;-
5429 +;;- Note: NOTICE_UPDATE_CC in m6809.h handles condition code updates
5430 +;;- for most instructions.
5431 +;;--------------------------------------------------------------------
5432 +
5433 +;;--------------------------------------------------------------------
5434 +;;- Test
5435 +;;--------------------------------------------------------------------
5436 +
5437 +;; cmpx is 3 bytes, not 4
5438 +(define_insn "*tsthi_x"
5439 + [(set (cc0) (match_operand:HI 0 "register_operand_x" "v"))]
5440 + ""
5441 + "cmpx\t#0"
5442 + [(set_attr "length" "3")])
5443 +
5444 +;; subd #0 is 3 bytes, better than cmpd #0 which is 4 bytes
5445 +(define_insn "*tsthi_d"
5446 + [(set (cc0) (match_operand:HI 0 "register_operand_d" "d"))]
5447 + ""
5448 + "subd\t#0"
5449 + [(set_attr "length" "3")])
5450 +
5451 +(define_insn "*tsthi"
5452 + [(set (cc0) (match_operand:HI 0 "register_operand" "a"))]
5453 + ""
5454 + "cmp%0\t#0"
5455 + [(set_attr "length" "4")])
5456 +
5457 +(define_insn "*bitqi3"
5458 + [(set (cc0)
5459 + (and:QI (match_operand:QI 0 "register_operand" "%q")
5460 + (match_operand:QI 1 "general_operand" "mi")))]
5461 + ""
5462 + "bit%0\t%1"
5463 + [(set_attr "length" "3")])
5464 +
5465 +
5466 +(define_insn "tstqi"
5467 + [(set (cc0) (match_operand:QI 0 "nonimmediate_operand" "q,mt"))]
5468 + ""
5469 + "@
5470 + tst%0
5471 + tst\t%0"
5472 + [(set_attr "length" "1,3")])
5473 +
5474 +;;--------------------------------------------------------------------
5475 +;;- Compare instructions
5476 +;;--------------------------------------------------------------------
5477 +
5478 +;; - cmphi for register to memory or register compares
5479 +(define_insn "cmphi"
5480 + [(set (cc0)
5481 + (compare
5482 + (match_operand:HI 0 "general_operand" "da, mi, ??Ud")
5483 + (match_operand:HI 1 "general_operand" "mi, da, dU")))]
5484 + ""
5485 +{
5486 + if ((REG_P (operands[0])) && (REG_P (operands[1]))) {
5487 + output_asm_insn ("pshs\t%1\t;cmphi: R:%1 with R:%0", operands);
5488 + return "cmp%0\t,s++\t;cmphi:";
5489 + }
5490 + if (GET_CODE (operands[0]) == REG)
5491 + return "cmp%0\t%1\t;cmphi:";
5492 + else {
5493 + cc_status.flags |= CC_REVERSED;
5494 + return "cmp%1\t%0\t;cmphi:(R)";
5495 + }
5496 +}
5497 + [(set_attr "length" "5,5,7")])
5498 +
5499 +
5500 +(define_insn "cmpqi"
5501 + [(set (cc0)
5502 + (compare (match_operand:QI 0 "whole_general_operand" "q,q, q,O,mt,K")
5503 + (match_operand:QI 1 "whole_general_operand" "O,mt,K,q,q, q")))]
5504 + ""
5505 +{
5506 + if (REG_P (operands[0]) && !M_REG_P (operands[0]))
5507 + {
5508 + if (operands[1] == const0_rtx)
5509 + return "tst%0\t;cmpqi:(ZERO)";
5510 + else
5511 + return "cmp%0\t%1\t;cmpqi:";
5512 + }
5513 + else
5514 + {
5515 + cc_status.flags |= CC_REVERSED;
5516 +
5517 + if (operands[0] == const0_rtx)
5518 + return "tst%1\t;cmpqi:(RZERO)";
5519 + else
5520 + return "cmp%1\t%0\t;cmpqi:(R)";
5521 + }
5522 +}
5523 + [(set_attr "length" "1,3,2,1,3,2")])
5524 +
5525 +
5526 +;;--------------------------------------------------------------------
5527 +;;- Compare/branch pattern
5528 +;;--------------------------------------------------------------------
5529 +
5530 +(define_expand "cbranchhi4"
5531 + [(set (cc0)
5532 + (compare
5533 + (match_operand:HI 1 "general_operand" "da, mi, ??Ud")
5534 + (match_operand:HI 2 "general_operand" "mi, da, dU")))
5535 + (set (pc)
5536 + (if_then_else
5537 + (match_operator 0 "ordered_comparison_operator" [(cc0) (const_int 0)])
5538 + (label_ref (match_operand 3 "" ""))
5539 + (pc)))]
5540 + ""
5541 + ""
5542 +)
5543 +
5544 +(define_expand "cbranchqi4"
5545 + [(set (cc0)
5546 + (compare
5547 + (match_operand:QI 1 "whole_general_operand" "q,q, q,O,mt,K")
5548 + (match_operand:QI 2 "whole_general_operand" "O,mt,K,q,q, q")))
5549 + (set (pc)
5550 + (if_then_else
5551 + (match_operator 0 "ordered_comparison_operator" [(cc0) (const_int 0)])
5552 + (label_ref (match_operand 3 "" ""))
5553 + (pc)))]
5554 + ""
5555 + ""
5556 +)
5557 +
5558 +;;--------------------------------------------------------------------
5559 +;;- Move
5560 +;;--------------------------------------------------------------------
5561 +
5562 +; this looks good (obviously not finished) but I still see 'movsi'
5563 +; places in udivsi3 where it's broken
5564 +; (define_insn "pushsi1"
5565 +; [(set (mem:SI (pre_dec (reg:HI HARD_S_REGNUM)))
5566 +; (match_operand:SI 0 "general_operand" "o"))
5567 +; (set (reg:HI HARD_S_REGNUM)
5568 +; (plus:HI (reg:HI HARD_S_REGNUM) (const_int -4))) ]
5569 +; ""
5570 +; "; pushsi %0"
5571 +; [(set_attr "length" "12")])
5572 +;
5573 +; (define_insn "popsi1"
5574 +; [(set (match_operand:SI 0 "general_operand" "=o")
5575 +; (mem:SI (post_inc (reg:HI HARD_S_REGNUM))))
5576 +; (set (reg:HI HARD_S_REGNUM)
5577 +; (plus:HI (reg:HI HARD_S_REGNUM) (const_int 4))) ]
5578 +; ""
5579 +; "; popsi %0"
5580 +; [(set_attr "length" "12")])
5581 +
5582 +; (define_insn "movsi"
5583 +; [(set (match_operand:SI 0 "nonimmediate_operand" "=o")
5584 +; (match_operand:SI 1 "general_operand" " oi"))]
5585 +; ""
5586 +; "; movsi %0 <- %1"
5587 +; [(set_attr "length" "1")])
5588 +
5589 +; this doesn't work
5590 +; (define_expand "movsi"
5591 +; [(parallel [
5592 +; (set (match_operand:SI 0 "nonimmediate_operand" "")
5593 +; (match_operand:SI 1 "general_operand" ""))
5594 +; (clobber (match_scratch:HI 2 ""))])]
5595 +; ""
5596 +; {
5597 +; rtx insn;
5598 +; if (STACK_PUSH_P (operands[0]) || STACK_POP_P (operands[1]))
5599 +; {
5600 +; REG_NOTES (insn) = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn));
5601 +; }
5602 +; insn = emit_move_multi_word (SImode, operands[0], operands[1]);
5603 +; DONE;
5604 +; })
5605 +
5606 +
5607 +(define_expand "movhi"
5608 + [(set (match_operand:HI 0 "nonimmediate_operand" "")
5609 + (match_operand:HI 1 "general_operand" ""))]
5610 + ""
5611 +{
5612 + /* One of the ops has to be in a register prior to reload */
5613 + if (!register_operand (operand0, HImode) &&
5614 + !register_operand (operand1, HImode))
5615 + operands[1] = copy_to_mode_reg (HImode, operand1);
5616 +})
5617 +
5618 +;;; Try a splitter to handle failure cases where we try to move
5619 +;;; an immediate constant (zero usually) directly to memory.
5620 +;;; This absolutely requires an intermediate register.
5621 +(define_split
5622 + [(set (match_operand:HI 0 "memory_operand" "")
5623 + (match_operand:HI 1 "immediate_operand" ""))
5624 + (clobber (match_operand:HI 2 "register_operand" ""))]
5625 + ""
5626 + [(set (match_dup 2) (match_dup 1))
5627 + (set (match_dup 0) (match_dup 2))]
5628 + "")
5629 +
5630 +
5631 +;;; This would be a nice method for loading from a word array,
5632 +;;; but it is never generated because the combiner cannot merge
5633 +;;; more than 3 instructions (there are four here). This is
5634 +;;; perhaps better done via a peephole.
5635 +(define_insn "*movhi_array_load"
5636 + [(set (match_operand:HI 0 "nonimmediate_operand" "=da")
5637 + (mem:HI (plus:HI (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%B")) (const_int 1))
5638 + (match_operand:HI 2 "immediate_operand" "i"))))
5639 + (clobber (match_scratch:HI 3 "=X"))]
5640 + ""
5641 + "ldx\t%2\;abx\;abx\;ld%0\t,x"
5642 + [(set_attr "length" "7")])
5643 +
5644 +
5645 +;;; Optimize the move of a byte to the stack using the pshs instruction
5646 +;;; instead of a store with pre-increment.
5647 +(define_insn "movhi_push"
5648 + [(set (match_operand:HI 0 "push_operand" "=m")
5649 + (match_operand:HI 1 "register_operand" "U"))]
5650 + ""
5651 + "pshs\t%1"
5652 + [(set_attr "length" "2")])
5653 +
5654 +
5655 +(define_insn "*movhi_pic_symbolref"
5656 + [(set (match_operand:HI 0 "register_operand" "=a")
5657 + (match_operand:HI 1 "symbolic_operand" ""))]
5658 + "flag_pic"
5659 + "lea%0\t%c1,pcr"
5660 + [(set_attr "length" "4")])
5661 +
5662 +
5663 +(define_insn "*movhi_1"
5664 + [(set (match_operand:HI 0 "nonimmediate_operand" "=a,d,a,ad,mu")
5665 + (match_operand:HI 1 "general_operand" " a,a,d,miu,ad"))]
5666 + ""
5667 + "@
5668 + lea%0\t,%1
5669 + tfr\t%1,%0
5670 + tfr\t%1,%0
5671 + ld%0\t%1
5672 + st%1\t%0"
5673 + [(set_attr "length" "2,2,2,*,*")])
5674 +
5675 +
5676 +;;; Generated by the combiner to merge an address calculation with
5677 +;;; a byte load. We can use the 'abx' instruction here.
5678 +(define_insn "*movqi_array_load"
5679 + [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
5680 + (mem:QI (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%B"))
5681 + (match_operand:HI 2 "immediate_operand" "i"))))
5682 + (clobber (match_scratch:HI 3 "=X"))]
5683 + ""
5684 + "ldx\t%2\;abx\;ld%0\t,x"
5685 + [(set_attr "length" "6")])
5686 +
5687 +
5688 +;;; Optimize the move of a byte to the stack using the pshs instruction
5689 +;;; instead of a store with pre-increment.
5690 +(define_insn "movqi_push"
5691 + [(set (match_operand:QI 0 "push_operand" "=m")
5692 + (match_operand:QI 1 "register_operand" " q"))]
5693 + ""
5694 + "pshs\t%1"
5695 + [(set_attr "length" "2")])
5696 +
5697 +
5698 +;;; Optimize the move of a byte from the stack using the puls instruction
5699 +;;; instead of a store with post-decrement.
5700 +(define_insn "movqi_pop"
5701 + [(set (match_operand:QI 0 "register_operand" "=q")
5702 + (match_operand:QI 1 "pop_operand" "m"))]
5703 + ""
5704 + "puls\t%0"
5705 + [(set_attr "length" "2")])
5706 +
5707 +
5708 +;;- load low byte of 16-bit data into 8-bit register/memory
5709 +(define_insn "*mov_lsb"
5710 + [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q,q,m,!q")
5711 + (subreg:QI (match_operand:HI 1 "general_operand" "d,m,a,d, U") 1))]
5712 + ""
5713 + "@
5714 + \t;movlsbqihi: D->B
5715 + ld%0\t%L1\t;movlsbqihi: msb:%1 -> R:%0
5716 + tfr\t%1,d\t;movlsbqihi: R:%1 -> R:%0
5717 + stb\t%0\t;movlsbqihi: R:%1 -> %0
5718 + pshs\t%1\t;movlsbqihi: R:%1 -> R:%0\;leas\t1,s\;puls\t%0"
5719 + [(set_attr "length" "0,*,2,*,6")])
5720 +
5721 +
5722 +;;- load high byte of 16-bit data into 8-bit register/memory
5723 +(define_insn "*mov_msb"
5724 + [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q,q,q,m,!q")
5725 + (subreg:QI (match_operand:HI 1 "general_operand" "d,O,a,m,d, U") 0))]
5726 + ""
5727 + "@
5728 + tfr\ta,b\t;movmsbqihi: D->B
5729 + clr%0\t\t;movmsbqihi: ZERO -> R:%0
5730 + tfr\t%1,d\t;movmsbqihi: R:%1 -> R:%0\;tfr\ta,b
5731 + ld%0\t%L1\t;movmsbqihi: lsb:%1 -> R:%0
5732 + sta\t%0\t;movmsbqihi: R:%1 -> %0
5733 + pshs\t%1\t;movmsbqihi: R:%1 -> R:%0\;puls\t%0\;leas\t1,s"
5734 + [(set_attr "length" "2,1,4,*,*,6")])
5735 +
5736 +
5737 +(define_insn "*movqi_boolean"
5738 + [(set (reg:QI HARD_Z_REGNUM)
5739 + (match_operand:QI 0 "general_operand" "q,O,i,m"))]
5740 + ""
5741 + "@
5742 + tst%0
5743 + andcc\t#~4
5744 + orcc\t#4
5745 + tst\t%0")
5746 +
5747 +
5748 +(define_insn "movqi"
5749 + [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q,m,q,m,q,z")
5750 + (match_operand:QI 1 "general_operand" " q,O,O,mi,q,z,q"))]
5751 + ""
5752 + "@
5753 + tfr\t%1,%0
5754 + clr%0
5755 + clr\t%0
5756 + ld%0\t%1
5757 + st%1\t%0
5758 + tfr\tcc,%0\;and%0\t#4
5759 + tst%0"
5760 + [(set_attr "length" "2,1,3,*,*,4,1")])
5761 +
5762 +
5763 +;;--------------------------------------------------------------------
5764 +;;- Swap registers
5765 +;;--------------------------------------------------------------------
5766 +
5767 +; Note: 8-bit swap is never needed so it is not defined.
5768 +
5769 +(define_insn "swaphi"
5770 + [(set (match_operand:HI 0 "register_operand" "+r")
5771 + (match_operand:HI 1 "register_operand" "+r"))
5772 + (set (match_dup 1) (match_dup 0))]
5773 + ""
5774 + "exg\t%1,%0"
5775 + [(set_attr "length" "2")
5776 + (set (attr "cycles") (const_int EXG_CYCLES))])
5777 +
5778 +
5779 +(define_insn "bswaphi2"
5780 + [(set (match_operand:HI 0 "register_operand" "=d")
5781 + (bswap:HI (match_operand:HI 1 "register_operand" "0")))]
5782 + ""
5783 + "exg\ta,b"
5784 + [(set_attr "length" "2")])
5785 +
5786 +
5787 +;;--------------------------------------------------------------------
5788 +;;- Extension and truncation insns.
5789 +;;--------------------------------------------------------------------
5790 +
5791 +(define_insn "extendqihi2"
5792 + [(set (match_operand:HI 0 "register_operand" "=d")
5793 + (sign_extend:HI (match_operand:QI 1 "general_operand" "B")))]
5794 + ""
5795 + "sex\t\t;extendqihi2: R:%1 -> R:%0"
5796 + [(set_attr "length" "1")])
5797 +
5798 +
5799 +(define_insn "zero_extendqihi2"
5800 + [(set (match_operand:HI 0 "register_operand" "=d")
5801 + (zero_extend:HI (match_operand:QI 1 "general_operand" "B")))]
5802 + ""
5803 + "clra\t\t;zero_extendqihi: R:%1 -> R:%0"
5804 + [(set_attr "length" "1")])
5805 +
5806 +
5807 +;;--------------------------------------------------------------------
5808 +;;- All kinds of add instructions.
5809 +;;--------------------------------------------------------------------
5810 +
5811 +
5812 +;;
5813 +;; gcc's automatic version of addsi3 doesn't know about adcb,adca
5814 +;; so it is MUCH less efficient. Define this one ourselves.
5815 +;;
5816 +;; TODO - can't always get 'd' for the clobber... allow other registers
5817 +;; as well and use exg d,R ... exg R,d around the code sequence to
5818 +;; use others, at a price. Also consider libcall for this when
5819 +;; optimizing for size.
5820 +;;
5821 +(define_insn "addsi3"
5822 + [(set (match_operand:SI 0 "nonimmediate_operand" "=o")
5823 + (plus:SI (match_operand:SI 1 "general_operand" "%o")
5824 + (match_operand:SI 2 "general_operand" " oi")))
5825 + (clobber (match_scratch:HI 3 "=d"))]
5826 + ""
5827 +{
5828 + m6809_output_addsi3 (PLUS, operands);
5829 + return "";
5830 +}
5831 + [(set_attr "length" "21")])
5832 +
5833 +
5834 +; Increment of a 16-bit MEM by 1 can be done without a register.
5835 +(define_insn "*addhi_mem_1"
5836 + [(set (match_operand:HI 0 "memory_operand" "=m")
5837 + (plus:HI (match_dup 0) (const_int 1)))]
5838 + "GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF"
5839 +{
5840 + rtx xoperands[2];
5841 +
5842 + xoperands[0] = operands[0];
5843 + xoperands[1] = adjust_address (operands[0], QImode, 1);
5844 +
5845 + output_asm_insn ("inc\t%1", xoperands);
5846 + output_asm_insn ("bne\t__IL%=", xoperands);
5847 + output_asm_insn ("inc\t%0\;__IL%=:", xoperands);
5848 + return "";
5849 +}
5850 + [(set_attr "length" "7")])
5851 +
5852 +
5853 +; Decrement of a 16-bit MEM by 1 can be done without a register.
5854 +(define_insn "*addhi_mem_minus1"
5855 + [(set (match_operand:HI 0 "memory_operand" "=m")
5856 + (plus:HI (match_dup 0) (const_int -1)))]
5857 + "GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF"
5858 +{
5859 + rtx xoperands[2];
5860 +
5861 + xoperands[0] = operands[0];
5862 + xoperands[1] = adjust_address (operands[0], QImode, 1);
5863 +
5864 + output_asm_insn ("tst\t%1", xoperands);
5865 + output_asm_insn ("bne\t__IL%=", xoperands);
5866 + output_asm_insn ("dec\t%0", xoperands);
5867 + output_asm_insn ("__IL%=:", xoperands);
5868 + output_asm_insn ("dec\t%1", xoperands);
5869 + return "";
5870 +}
5871 + [(set_attr "length" "7")])
5872 +
5873 +
5874 +; Allow the addition of an 8-bit quantity to a 16-bit quantity
5875 +; using the LEAX B,Y addressing mode, where X and Y are both
5876 +; index registers. This will only get generated via the peephole
5877 +; which removes a sign extension.
5878 +(define_insn "*addhi_b"
5879 + [(set (match_operand:HI 0 "index_register_operand" "=a")
5880 + (plus:HI(match_operand:HI 1 "index_register_operand" "%a")
5881 + (match_operand:QI 2 "register_operand" "q")
5882 + ))]
5883 + ""
5884 + "lea%0\t%2,%1\t;addhi_b: R:%0 = R:%2 + R:%1"
5885 + [(set_attr "length" "*")])
5886 +
5887 +
5888 +; Splitter for addhi pattern #5 below
5889 +(define_split
5890 + [(set (match_operand:HI 0 "index_register_operand" "")
5891 + (plus:HI (match_dup 0) (match_operand:HI 1 "memory_operand" "")))]
5892 + "reload_completed"
5893 + [
5894 + (parallel [(set (match_dup 0) (reg:HI HARD_D_REGNUM))
5895 + (set (reg:HI HARD_D_REGNUM) (match_dup 0))])
5896 + (set (reg:HI HARD_D_REGNUM)
5897 + (plus:HI (reg:HI HARD_D_REGNUM) (match_dup 1)))
5898 + (parallel [(set (match_dup 0) (reg:HI HARD_D_REGNUM))
5899 + (set (reg:HI HARD_D_REGNUM) (match_dup 0))])
5900 + ]
5901 +{
5902 +})
5903 +
5904 +
5905 +; Splitter for addhi pattern #7 below
5906 +(define_split
5907 + [(set (match_operand:HI 0 "index_register_operand" "")
5908 + (plus:HI (match_dup 0) (match_operand:HI 1 "index_register_operand" "")))]
5909 + "reload_completed"
5910 + [
5911 + (parallel [(set (match_dup 1) (reg:HI HARD_D_REGNUM))
5912 + (set (reg:HI HARD_D_REGNUM) (match_dup 1))])
5913 + (set (match_dup 0)
5914 + (plus:HI (reg:HI HARD_D_REGNUM) (match_dup 0)))
5915 + (parallel [(set (match_dup 1) (reg:HI HARD_D_REGNUM))
5916 + (set (reg:HI HARD_D_REGNUM) (match_dup 1))])
5917 + ]
5918 +{
5919 +})
5920 +
5921 +
5922 +; TODO - this is ugly. During RTL generation, we don't know what registers
5923 +; are available, so the multiple-insn sequences can only be solved
5924 +; via 'define_split's during matching. See andhi3 for an example.
5925 +; Keep the constraints with ? modifiers to help reload pick the right
5926 +; registers.
5927 +;
5928 +; The forms are:
5929 +; 1. D += D, expand this into a shift instead. (rtx costs should be corrected
5930 +; to avoid this even happening...)
5931 +; 2. D += U, require U to be pushed to memory. (Lots of patterns do this
5932 +; now, is this a better way?)
5933 +; 3. Best choice: 'addd'
5934 +; 4. Next best choice: 'lea'
5935 +; 5. Hybrid of 3 and 4
5936 +; 6. Same as 4, not bad
5937 +; 7. BAD, no D register at all
5938 +; 8. 'lea', as good as 4.
5939 +(define_insn "addhi3"
5940 + [(set (match_operand:HI 0 "nonimmediate_operand" "=d, d, d, a,?a, a,???T,a")
5941 + (plus:HI(match_operand:HI 1 "add_general_operand" "%0, 0, 0, d, 0, a, 0, a")
5942 + (match_operand:HI 2 "general_operand" " 0, !U, mi, a, m, d, T, i")
5943 + ))]
5944 + ""
5945 + "@
5946 + lslb\t\t;addhi: R:%0 += R:%2\;rola\t\t;also R:%0 *= 2
5947 + pshs\t%2\t;addhi: R:%0 += R:%2\;add%0\t,s++
5948 + add%0\t%2
5949 + lea%0\t%1,%2
5950 + #
5951 + lea%0\t%2,%1
5952 + #
5953 + lea%0\t%a2,%1"
5954 + [(set_attr "length" "2,6,*,*,7,*,7,*")])
5955 +
5956 +
5957 +(define_insn "addqi3_carry"
5958 + [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
5959 + (unspec:QI [
5960 + (match_operand:QI 1 "whole_general_operand" "%0")
5961 + (match_operand:QI 2 "whole_general_operand" "tmi")] UNSPEC_ADD_CARRY))]
5962 + ""
5963 + "adc%0\t%2\t;addqi_carry: R:%0 += %2"
5964 + [(set_attr "length" "*")])
5965 +
5966 +
5967 +; TODO: specifying 'A' for the first constraint, to force into the A register
5968 +; is not working because of the way registers are currently set up. This will
5969 +; take some work to get right. Thus the second alternative as a backup.
5970 +(define_insn "addqi3_decimal"
5971 + [(set (match_operand:QI 0 "nonimmediate_operand" "=A,?q")
5972 + (unspec:QI [
5973 + (match_operand:QI 1 "general_operand" "%0,0")
5974 + (match_operand:QI 2 "general_operand" "mi,mi")] UNSPEC_ADD_DECIMAL))]
5975 + ""
5976 + "@
5977 + adda\t%2\;daa
5978 + tfr\t%0,a\;adda\t%2\;daa\;tfr\ta,%0"
5979 + [(set_attr "length" "5,9")])
5980 +
5981 +
5982 +(define_insn "addqi3"
5983 + [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q,q,m,m,q")
5984 + (plus:QI (match_operand:QI 1 "whole_general_operand" "%0,0,0,0,0,0")
5985 + (match_operand:QI 2 "whole_general_operand" " 0,I,N,I,N,mi")))]
5986 + ""
5987 + "@
5988 + asl%0\t\t;addqi: R:%0 = R:%0 + R:%0
5989 + inc%0
5990 + dec%0
5991 + inc\t%0
5992 + dec\t%0
5993 + add%0\t%2"
5994 + [(set_attr "length" "1,1,1,3,3,*")])
5995 +
5996 +
5997 +;;--------------------------------------------------------------------
5998 +;;- Subtract instructions.
5999 +;;--------------------------------------------------------------------
6000 +
6001 +(define_insn "subsi3"
6002 + [(set (match_operand:SI 0 "nonimmediate_operand" "=o")
6003 + (minus:SI (match_operand:SI 1 "general_operand" " o")
6004 + (match_operand:SI 2 "general_operand" " oi")))
6005 + (clobber (match_scratch:HI 3 "=d"))]
6006 + ""
6007 +{
6008 + m6809_output_addsi3 (MINUS, operands);
6009 + return "";
6010 +}
6011 + [(set_attr "length" "21")])
6012 +
6013 +
6014 +(define_insn "subhi3"
6015 + [(set (match_operand:HI 0 "register_operand" "=d, d, a")
6016 + (minus:HI (match_operand:HI 1 "register_operand" "0, 0, 0")
6017 + (match_operand:HI 2 "general_operand" "mi, ?U,n")))]
6018 + ""
6019 + "@
6020 + sub%0\t%2\t;subhi: R:%0 -= %2
6021 + pshs\t%2\t;subhi: R:%0 -= R:%2\;sub%0\t,s++
6022 + lea%0\t%n2,%1\t;subhi: R:%0 = R:%1 + %n2"
6023 + [(set_attr "length" "*,5,3")])
6024 +
6025 +
6026 +(define_insn "subqi3_carry"
6027 + [(set (match_operand:QI 0 "register_operand" "=q")
6028 + (unspec:QI [
6029 + (match_operand:QI 1 "whole_general_operand" "%0")
6030 + (match_operand:QI 2 "whole_general_operand" "tmi")] UNSPEC_SUB_CARRY))]
6031 + ""
6032 + "sbc%0\t%2\t;subqi_carry: R:%0 += %2"
6033 + [(set_attr "length" "*")])
6034 +
6035 +
6036 +(define_insn "subqi3"
6037 + [(set (match_operand:QI 0 "register_operand" "=q, q, !q, q")
6038 + (minus:QI (match_operand:QI 1 "whole_register_operand" "0, 0, I, 0")
6039 + (match_operand:QI 2 "whole_general_operand" "I, mi, 0, t")))]
6040 + ""
6041 + "@
6042 + dec%0
6043 + sub%0\t%2
6044 + dec%0\;neg%0
6045 + sub%0\t%2"
6046 + [(set_attr "length" "1,3,2,3")])
6047 +
6048 +
6049 +;;--------------------------------------------------------------------
6050 +;;- Multiply instructions.
6051 +;;--------------------------------------------------------------------
6052 +
6053 +; TODO - merge these two instructions, using 'extend_operator' to match
6054 +; either signed or zero extension. Everything else is the same.
6055 +(define_insn "mulqihi3"
6056 + [(set (match_operand:HI 0 "register_operand" "=d")
6057 + (mult:HI (sign_extend:HI (match_operand:QI 1 "general_operand" "%q"))
6058 + (match_operand:QI 2 "general_operand" "tmK")))]
6059 + ""
6060 + "lda\t%2\t;mulqihi3\;mul"
6061 + [(set_attr "length" "3")])
6062 +
6063 +
6064 +(define_insn "umulqihi3"
6065 + [(set (match_operand:HI 0 "register_operand" "=d")
6066 + (mult:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "%q"))
6067 + (match_operand:QI 2 "general_operand" "tmK")))]
6068 + ""
6069 + "lda\t%2\t;umulqihi3\;mul"
6070 + [(set_attr "length" "3")])
6071 +
6072 +
6073 +; Expand a 16x16 multiplication into either a libcall or a shift.
6074 +; If the second operand is a small constant, use the above form.
6075 +; Otherwise, do a libcall.
6076 +(define_expand "mulhi3"
6077 + [(set (match_operand:HI 0 "nonimmediate_operand" "")
6078 + (mult:HI (match_operand:HI 1 "general_operand" "")
6079 + (match_operand:HI 2 "nonmemory_operand" "")))]
6080 + ""
6081 +{
6082 + emit_libcall_insns (HImode, "mulhi3", operands, 2);
6083 + DONE;
6084 +})
6085 +
6086 +
6087 +;;--------------------------------------------------------------------
6088 +;;- Divide instructions.
6089 +;;--------------------------------------------------------------------
6090 +
6091 +(define_expand "divhi3"
6092 + [(set (match_operand:HI 0 "register_operand" "")
6093 + (div:HI (match_operand:HI 1 "register_operand" "")
6094 + (match_operand:HI 2 "register_operand" "")))]
6095 + ""
6096 +{
6097 + emit_libcall_insns (HImode, "divhi3", operands, 2);
6098 + DONE;
6099 +})
6100 +
6101 +
6102 +(define_expand "divqi3"
6103 + [(set (match_operand:QI 0 "register_operand" "")
6104 + (div:QI (match_operand:QI 1 "register_operand" "")
6105 + (match_operand:QI 2 "register_operand" "")))]
6106 + ""
6107 +{
6108 + emit_libcall_insns (QImode, "divqi3", operands, 2);
6109 + DONE;
6110 +})
6111 +
6112 +
6113 +(define_expand "udivhi3"
6114 + [(set (match_operand:HI 0 "register_operand" "")
6115 + (udiv:HI (match_operand:HI 1 "register_operand" "")
6116 + (match_operand:HI 2 "register_operand" "")))]
6117 + ""
6118 +{
6119 + emit_libcall_insns (HImode, "udivhi3", operands, 2);
6120 + DONE;
6121 +})
6122 +
6123 +
6124 +;;--------------------------------------------------------------------
6125 +;;- mod
6126 +;;--------------------------------------------------------------------
6127 +
6128 +(define_expand "modhi3"
6129 + [(set (match_operand:HI 0 "register_operand" "")
6130 + (mod:HI (match_operand:HI 1 "register_operand" "")
6131 + (match_operand:HI 2 "register_operand" "")))]
6132 + ""
6133 +{
6134 + emit_libcall_insns (HImode, "modhi3", operands, 2);
6135 + DONE;
6136 +})
6137 +
6138 +
6139 +(define_expand "modqi3"
6140 + [(set (match_operand:QI 0 "register_operand" "")
6141 + (mod:QI (match_operand:QI 1 "register_operand" "")
6142 + (match_operand:QI 2 "register_operand" "")))]
6143 + ""
6144 +{
6145 + emit_libcall_insns (QImode, "modqi3", operands, 2);
6146 + DONE;
6147 +})
6148 +
6149 +
6150 +(define_expand "umodhi3"
6151 + [(set (match_operand:HI 0 "register_operand" "")
6152 + (umod:HI (match_operand:HI 1 "register_operand" "")
6153 + (match_operand:HI 2 "register_operand" "")))]
6154 + ""
6155 +{
6156 + emit_libcall_insns (HImode, "umodhi3", operands, 2);
6157 + DONE;
6158 +})
6159 +
6160 +
6161 +
6162 +;;--------------------------------------------------------------------
6163 +;;- and, or, xor common patterns
6164 +;;--------------------------------------------------------------------
6165 +
6166 +; Split a bitwise HImode into two QImode instructions, with one of
6167 +; the sources in a pushable register. The register is pushed onto
6168 +; the stack and memory pop operands (,s+) are used in the QI forms.
6169 +(define_split
6170 + [(set (match_operand:HI 0 "register_operand" "")
6171 + (match_operator:HI 3 "logical_bit_operator"
6172 + [(match_operand:HI 1 "register_operand" "")
6173 + (match_operand:HI 2 "register_operand" "")]))]
6174 + "reload_completed"
6175 + [(set (mem:HI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (match_dup 2))
6176 + (set (reg:QI HARD_A_REGNUM) (match_op_dup:QI 3
6177 + [(reg:QI HARD_A_REGNUM)
6178 + (mem:QI (post_inc:QI (reg:HI HARD_S_REGNUM)))]))
6179 + (set (reg:QI HARD_D_REGNUM) (match_op_dup:QI 3
6180 + [(reg:QI HARD_D_REGNUM)
6181 + (mem:QI (post_inc:QI (reg:HI HARD_S_REGNUM)))]))
6182 + (use (reg:QI HARD_A_REGNUM))]
6183 +{
6184 +})
6185 +
6186 +; Split a bitwise HImode into two QImode instructions, with one
6187 +; of the sources being a (MEM (MEM (...)); i.e. an indirect memory
6188 +; reference. This requires dereferencing the pointer into a
6189 +; temporary register (X), which must be saved/restored around the
6190 +; compute instructions.
6191 +(define_split
6192 + [(set (match_operand:HI 0 "register_operand" "")
6193 + (match_operator:HI 3 "logical_bit_operator"
6194 + [(match_operand:HI 1 "register_operand" "")
6195 + (mem:HI (match_operand:HI 2 "memory_operand" ""))]))]
6196 + "reload_completed"
6197 + [
6198 + (set (mem:HI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (match_dup 4))
6199 + (set (match_dup 4) (match_dup 2))
6200 + (set (match_dup 4) (mem:HI (match_dup 4)))
6201 + (set (reg:QI HARD_A_REGNUM) (match_op_dup:QI 3
6202 + [(reg:QI HARD_A_REGNUM)
6203 + (mem:QI (post_inc:QI (match_dup 4)))]))
6204 + (set (reg:QI HARD_D_REGNUM) (match_op_dup:QI 3
6205 + [(reg:QI HARD_D_REGNUM)
6206 + (mem:QI (post_inc:QI (match_dup 4)))]))
6207 + (use (reg:QI HARD_A_REGNUM))
6208 + (set (match_dup 4) (mem:HI (post_inc:HI (reg:HI HARD_S_REGNUM))))
6209 + ]
6210 +{
6211 + /* Use X for a temporary index register */
6212 + operands[4] = gen_rtx_REG (HImode, HARD_X_REGNUM);
6213 +})
6214 +
6215 +
6216 +; Split a bitwise HImode into two QImode instructions. This is
6217 +; the common case. This handles splitting when neither of the
6218 +; above two cases applies.
6219 +(define_split
6220 + [(set (match_operand:HI 0 "register_operand" "")
6221 + (match_operator:HI 3 "logical_bit_operator"
6222 + [(match_operand:HI 1 "register_operand" "")
6223 + (match_operand:HI 2 "general_operand" "")]))]
6224 + "reload_completed"
6225 + [(set (reg:QI HARD_A_REGNUM) (match_op_dup:QI 3
6226 + [(reg:QI HARD_A_REGNUM) (match_dup 4)]))
6227 + (set (reg:QI HARD_D_REGNUM) (match_op_dup:QI 3
6228 + [(reg:QI HARD_D_REGNUM) (match_dup 5)]))
6229 + (use (reg:QI HARD_A_REGNUM))]
6230 +{
6231 + if (GET_CODE (operands[2]) == CONST_INT)
6232 + {
6233 + operands[4] = gen_rtx_const_high (operands[2]);
6234 + operands[5] = gen_rtx_const_low (operands[2]);
6235 + }
6236 + else if ((GET_CODE (operands[2]) == MEM)
6237 + && (GET_CODE (XEXP (operands[2], 0)) == MEM))
6238 + {
6239 + FAIL;
6240 + }
6241 + else
6242 + {
6243 + operands[4] = gen_highpart (QImode, operands[2]);
6244 + operands[5] = gen_lowpart (QImode, operands[2]);
6245 + }
6246 +})
6247 +
6248 +; Below are the specific cases for each of the operators.
6249 +; The QImode versions are the simplest and can be implemented
6250 +; directly on the hardware. The HImode cases are all output
6251 +; using one of the above splitting techniques.
6252 +
6253 +;;--------------------------------------------------------------------
6254 +;;- and
6255 +;;--------------------------------------------------------------------
6256 +
6257 +(define_insn "andhi3"
6258 + [(set (match_operand:HI 0 "register_operand" "=d")
6259 + (and:HI (match_operand:HI 1 "register_operand" "%0")
6260 + (match_operand:HI 2 "general_operand" "mnU")))]
6261 + ""
6262 + "#")
6263 +
6264 +;; it is not clear that this is correct
6265 +(define_insn "*andqi_2"
6266 + [(set
6267 + (match_operand:QI 0 "register_operand" "=q")
6268 + (and:QI (match_operand:QI 1 "register_operand" "q")
6269 + (match_operand 2 "const_int_operand" "i")))]
6270 + ""
6271 +{
6272 + if (GET_CODE (operands[2]) == CONST_INT)
6273 + {
6274 + operands[3] = GEN_INT(INTVAL(operands[2]) & 0xff);
6275 + return "and%0 %3";
6276 + }
6277 +
6278 + return "and%0 %2";
6279 +}
6280 + [(set_attr "length" "2")])
6281 +
6282 +(define_insn "andqi3"
6283 + [(set (match_operand:QI 0 "register_operand" "=q,q,q,qc")
6284 + (and:QI (match_operand:QI 1 "whole_register_operand" "%0,0,0,0")
6285 + (match_operand:QI 2 "whole_general_operand" " O,N,m,i")))]
6286 + ""
6287 + "@
6288 + clr%0\t;andqi(ZERO)
6289 + \t;andqi(-1)
6290 + and%0\t%2
6291 + and%0\t%2"
6292 + [(set_attr "length" "1,0,3,2")])
6293 +
6294 +
6295 +;;--------------------------------------------------------------------
6296 +;;- or
6297 +;;--------------------------------------------------------------------
6298 +
6299 +(define_insn "iorhi3"
6300 + [(set (match_operand:HI 0 "register_operand" "=d")
6301 + (ior:HI (match_operand:HI 1 "register_operand" "%0")
6302 + (match_operand:HI 2 "general_operand" "mnU")))]
6303 + ""
6304 + "#")
6305 +
6306 +
6307 +(define_insn "iorqi3"
6308 + [(set (match_operand:QI 0 "register_operand" "=q,q, qc")
6309 + (ior:QI (match_operand:QI 1 "whole_register_operand" "%0,0, 0")
6310 + (match_operand:QI 2 "whole_general_operand" " O,m,i")))]
6311 + ""
6312 + "@
6313 + \t;iorqi(ZERO)
6314 + or%0\t%2
6315 + or%0\t%2"
6316 + [(set_attr "length" "0,3,2")])
6317 +
6318 +;;--------------------------------------------------------------------
6319 +;;- xor
6320 +;;--------------------------------------------------------------------
6321 +
6322 +(define_insn "xorhi3"
6323 + [(set (match_operand:HI 0 "register_operand" "=d")
6324 + (xor:HI (match_operand:HI 1 "register_operand" "%0")
6325 + (match_operand:HI 2 "general_operand" "mnU")))]
6326 + ""
6327 + "#")
6328 +
6329 +
6330 +(define_insn "xorqi3"
6331 + [(set (match_operand:QI 0 "register_operand" "=q,q,q,q")
6332 + (xor:QI (match_operand:QI 1 "whole_register_operand" "%0,0,0,0")
6333 + (match_operand:QI 2 "whole_general_operand" " O,N,m,i")))]
6334 + ""
6335 + "@
6336 + \t;xorqi(ZERO)
6337 + com%0\t;xorqi(-1)
6338 + eor%0\t%2
6339 + eor%0\t%2"
6340 + [(set_attr "length" "0,1,3,2")])
6341 +
6342 +;;--------------------------------------------------------------------
6343 +;;- Two's Complements
6344 +;;--------------------------------------------------------------------
6345 +
6346 +(define_insn "neghi2"
6347 + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,!a")
6348 + (neg:HI (match_operand:HI 1 "general_operand" "0, 0")))]
6349 + ""
6350 + "@
6351 + nega\;negb\;sbca\t#0
6352 + exg\td,%0\;nega\;negb\;sbca\t#0\;exg\td,%0"
6353 + [(set_attr "length" "5,9")])
6354 +
6355 +
6356 +(define_insn "negqi2"
6357 + [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m")
6358 + (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
6359 + ""
6360 + "@
6361 + neg%0
6362 + neg\t%0"
6363 + [(set_attr "length" "1,3")])
6364 +
6365 +
6366 +;;--------------------------------------------------------------------
6367 +;;- One's Complements
6368 +;;--------------------------------------------------------------------
6369 +
6370 +(define_insn "one_cmplhi2"
6371 + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,?tm,???a")
6372 + (not:HI (match_operand:HI 1 "general_operand" "0, 0, 0")))]
6373 + ""
6374 + "@
6375 + coma\;comb
6376 + com\t%0\;com\t%L0
6377 + exg\td,%0\;coma\;comb\;exg\td,%0"
6378 + [(set_attr "length" "2,6,6")])
6379 +
6380 +
6381 +(define_insn "one_cmplqi2"
6382 + [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m")
6383 + (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
6384 + ""
6385 + "@
6386 + com%0
6387 + com\t%0"
6388 + [(set_attr "length" "1,3")])
6389 +
6390 +;;--------------------------------------------------------------------
6391 +;;- Shifts/rotates
6392 +;;--------------------------------------------------------------------
6393 +
6394 +(define_code_iterator bit_code [ashift ashiftrt lshiftrt])
6395 +(define_code_attr bit_code_name [(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr")])
6396 +
6397 +(define_mode_iterator bit_mode [QI HI])
6398 +(define_mode_attr bit_mode_name [(QI "qi3") (HI "hi3")])
6399 +
6400 +;; Emit RTL for any shift (handles all 3 opcodes and 2 mode sizes)
6401 +
6402 +(define_expand "<bit_code:bit_code_name><bit_mode:bit_mode_name>"
6403 + [(set (match_operand:bit_mode 0 "nonimmediate_operand" "")
6404 + (bit_code:bit_mode (match_operand:bit_mode 1 "general_operand" "")
6405 + (match_operand:bit_mode 2 "nonmemory_operand" "")))]
6406 + ""
6407 +{
6408 +})
6409 +
6410 +; Individual instructions implemented in the CPU.
6411 +
6412 +
6413 +(define_insn "*ashift1"
6414 + [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
6415 + (ashift:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
6416 + ""
6417 + "@
6418 + asl\t%0
6419 + asl%0"
6420 + [(set_attr "length" "3,1")])
6421 +
6422 +(define_insn "*lshiftrt1"
6423 + [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
6424 + (lshiftrt:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
6425 + ""
6426 + "@
6427 + lsr\t%0
6428 + lsr%0"
6429 + [(set_attr "length" "3,1")])
6430 +
6431 +(define_insn "*ashiftrt1"
6432 + [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
6433 + (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
6434 + ""
6435 + "@
6436 + asr\t%0
6437 + asr%0"
6438 + [(set_attr "length" "3,1")])
6439 +
6440 +(define_insn "*rotate1"
6441 + [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
6442 + (rotate:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
6443 + ""
6444 + "@
6445 + rol\t%0
6446 + rol%0"
6447 + [(set_attr "length" "3,1")])
6448 +
6449 +
6450 +(define_insn "*rotatert1"
6451 + [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
6452 + (rotatert:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
6453 + ""
6454 + "@
6455 + ror\t%0
6456 + ror%0"
6457 + [(set_attr "length" "3,1")])
6458 +
6459 +
6460 +; A shift by 8 for D reg can be optimized by just moving
6461 +; between the A/B halves, and then zero/sign extending or
6462 +; filling in zeroes.
6463 +; Because GCC does not understand that 'A' and 'D' refer to
6464 +; the same storage location, we must use 'USE' throughout
6465 +; to prevent deletion of 'unnecessary' instructions.
6466 +; Similar optimization for MEM would require a scratch register
6467 +; so is not done here.
6468 +
6469 +(define_split
6470 + [(set (reg:HI HARD_D_REGNUM) (ashift:HI (reg:HI HARD_D_REGNUM) (const_int 8)))]
6471 + "reload_completed"
6472 + [
6473 + (use (reg:HI HARD_D_REGNUM))
6474 + (set (reg:QI HARD_A_REGNUM) (reg:QI HARD_D_REGNUM))
6475 + (use (reg:QI HARD_A_REGNUM))
6476 + (set (reg:QI HARD_D_REGNUM) (const_int 0))
6477 + ]
6478 + "")
6479 +
6480 +(define_split
6481 + [(set (reg:HI HARD_D_REGNUM) (lshiftrt:HI (reg:HI HARD_D_REGNUM) (const_int 8)))]
6482 + "reload_completed"
6483 + [
6484 + (use (reg:HI HARD_D_REGNUM))
6485 + (set (reg:QI HARD_D_REGNUM) (reg:QI HARD_A_REGNUM))
6486 + (use (reg:QI HARD_D_REGNUM))
6487 + (set (reg:HI HARD_D_REGNUM) (zero_extend:HI (reg:QI HARD_D_REGNUM)))
6488 + ]
6489 + "")
6490 +
6491 +(define_split
6492 + [(set (reg:HI HARD_D_REGNUM) (ashiftrt:HI (reg:HI HARD_D_REGNUM) (const_int 8)))]
6493 + "reload_completed"
6494 + [
6495 + (use (reg:HI HARD_D_REGNUM))
6496 + (set (reg:QI HARD_D_REGNUM) (reg:QI HARD_A_REGNUM))
6497 + (use (reg:QI HARD_D_REGNUM))
6498 + (set (reg:HI HARD_D_REGNUM) (sign_extend:HI (reg:QI HARD_D_REGNUM)))
6499 + ]
6500 + "")
6501 +
6502 +
6503 +; On the WPC hardware, there is a shift register that can be used
6504 +; to compute (1<<n) efficiently in two instructions. Note that this
6505 +; form only works when using -mint8 though, because C will promote
6506 +; to 'int' when doing this operation. TODO : we need a 16-bit form too.
6507 +(define_insn "ashlqi3_wpc"
6508 + [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
6509 + (ashift:QI (match_operand:QI 1 "immediate_operand" "I")
6510 + (match_operand:QI 2 "general_operand" "q")))]
6511 + "TARGET_WPC"
6512 + "st%2\t0x3FF7\;ld%0\t0x3FF7"
6513 + [(set_attr "length" "6")])
6514 +
6515 +
6516 +; Internal instructions for shifting by a constant.
6517 +; Two forms are provided, one for QImode, one for HImode.
6518 +; These are always split into the above instructions
6519 +; (except for QImode forms that directly match one of the
6520 +; above instructions, in which the condition will not
6521 +; allow the splitter to match).
6522 +
6523 +(define_insn_and_split "<bit_code:bit_code_name>hi3_const"
6524 + [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
6525 + (bit_code:HI (match_operand:HI 1 "general_operand" "0")
6526 + (match_operand:HI 2 "immediate_operand" "n")))]
6527 + ""
6528 + "#"
6529 + "reload_completed"
6530 + [(const_int 0)]
6531 +{
6532 + m6809_split_shift (<bit_code:CODE>, operands);
6533 + DONE;
6534 +})
6535 +
6536 +
6537 +(define_insn_and_split "<bit_code:bit_code_name>qi3_const"
6538 + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6539 + (bit_code:QI (match_operand:QI 1 "general_operand" "0")
6540 + (match_operand:QI 2 "immediate_operand" "n")))]
6541 + "INTVAL (operands[2]) > 1"
6542 + "#"
6543 + "&& reload_completed"
6544 + [(const_int 0)]
6545 +{
6546 + m6809_split_shift (<bit_code:CODE>, operands);
6547 + DONE;
6548 +})
6549 +
6550 +; Internal instructions for shifting by a nonconstant.
6551 +; These expand into complex assembly.
6552 +
6553 +(define_insn "<bit_code:bit_code_name>hi3_reg"
6554 + [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
6555 + (bit_code:HI (match_operand:HI 1 "general_operand" "0")
6556 + (match_operand:HI 2 "nonimmediate_operand" "v")))]
6557 + ""
6558 +{
6559 + m6809_output_shift_insn (<bit_code:CODE>, operands);
6560 + return "";
6561 +}
6562 + [(set_attr "length" "20")])
6563 +
6564 +
6565 +(define_insn "<bit_code:bit_code_name>qi3_reg"
6566 + [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
6567 + (bit_code:QI (match_operand:QI 1 "general_operand" "0")
6568 + (match_operand:QI 2 "nonimmediate_operand" "v")))]
6569 + ""
6570 +{
6571 + m6809_output_shift_insn (<bit_code:CODE>, operands);
6572 + return "";
6573 +}
6574 + [(set_attr "length" "16")])
6575 +
6576 +
6577 +
6578 +;;--------------------------------------------------------------------
6579 +;;- Jumps and transfers
6580 +;;--------------------------------------------------------------------
6581 +
6582 +;;; The casesi pattern is normally *not* defined; see 'tablejump' instead.
6583 +(define_expand "casesi"
6584 + [(match_operand:HI 0 "register_operand" "") ; index to jump on
6585 + (match_operand:HI 1 "immediate_operand" "") ; lower bound
6586 + (match_operand:HI 2 "immediate_operand" "") ; total range
6587 + (match_operand 3 "" "") ; table label
6588 + (match_operand 4 "" "")] ; out of range label
6589 + "TARGET_BYTE_INT && TARGET_CASESI"
6590 +{
6591 + m6809_do_casesi (operands[0], operands[1], operands[2],
6592 + operands[3], operands[4]);
6593 + DONE;
6594 +})
6595 +
6596 +(define_insn "tablejump_short_offset"
6597 + [(set (pc)
6598 + (mem:HI (plus:HI (match_operand:HI 1 "register_operand" "U")
6599 + (zero_extend:HI (match_operand:QI 0 "register_operand" "q")))))]
6600 + ""
6601 + "jmp\t[b,x]\t;tablejump_short_offset"
6602 + [(set_attr "length" "3")])
6603 +
6604 +(define_insn "tablejump_long_offset"
6605 + [(set (pc)
6606 + (mem:HI (plus:HI (match_operand:HI 1 "register_operand" "U")
6607 + (match_operand:HI 0 "register_operand" "d"))))]
6608 + ""
6609 + "jmp\t[d,x]\t;tablejump_long_offset"
6610 + [(set_attr "length" "3")])
6611 +
6612 +
6613 + ;; A tablejump operation gives the address in operand 0, with the
6614 + ;; CODE_LABEL for the table in operand 1. The 'define_expand'
6615 + ;; shows the arguments as GCC presents them. For a register
6616 + ;; operand, the assembly code is straightforward. For a MEM,
6617 + ;; assumed to be a SYMBOL_REF, two forms are given, one normal
6618 + ;; and one for PIC mode.
6619 + (define_expand "tablejump"
6620 + [(parallel [
6621 + (set (pc) (match_operand:HI 0 "" ""))
6622 + (use (label_ref (match_operand 1 "" "")))
6623 + (clobber (match_scratch:HI 2 ""))
6624 + ])]
6625 + ""
6626 + {
6627 + })
6628 +
6629 +
6630 +(define_insn "*tablejump_reg"
6631 + [(parallel [
6632 + (set (pc)
6633 + (match_operand:HI 0 "register_operand" "a"))
6634 + (use (label_ref (match_operand 1 "" "")))
6635 + (clobber (match_scratch:HI 2 ""))
6636 + ])]
6637 + ""
6638 + "jmp\t,%0"
6639 + [(set_attr "length" "3")])
6640 +
6641 +
6642 +(define_insn "*tablejump_symbol"
6643 + [(parallel [
6644 + (set (pc)
6645 + (mem:HI
6646 + (plus:HI (match_operand:HI 0 "register_operand" "a")
6647 + (label_ref (match_operand 1 "" "")))))
6648 + (use (label_ref (match_dup 1)))
6649 + (clobber (match_scratch:HI 2 ""))
6650 + ])]
6651 + "!flag_pic"
6652 +{
6653 + output_asm_insn ("jmp\t[%a1,%0]", operands);
6654 + return "";
6655 +}
6656 + [(set_attr "length" "4")])
6657 +
6658 +
6659 +(define_insn "*tablejump_symbol_pic"
6660 + [(parallel [
6661 + (set (pc)
6662 + (mem:HI
6663 + (plus:HI (match_operand:HI 0 "register_operand" "d")
6664 + (label_ref (match_operand 1 "" "")))))
6665 + (use (label_ref (match_dup 1)))
6666 + (clobber (match_scratch:HI 2 "=&a"))
6667 + ])]
6668 + "flag_pic"
6669 +{
6670 + output_asm_insn ("lea%2\t%a1,pcr", operands);
6671 + output_asm_insn ("ld%0\t%0,%2", operands);
6672 + output_asm_insn ("jmp\t%0,%2", operands);
6673 + return "";
6674 +}
6675 + [(set_attr "length" "8")])
6676 +
6677 +
6678 +(define_insn "indirect_jump"
6679 + [(set (pc)
6680 + (match_operand:HI 0 "register_operand" "a"))]
6681 + ""
6682 + "jmp\t,%0"
6683 + [(set_attr "length" "3")])
6684 +
6685 +
6686 +(define_insn "jump"
6687 + [(set (pc) (label_ref (match_operand 0 "" "")))]
6688 + ""
6689 +{
6690 + return output_branch_insn ( LABEL_REF, operands, get_attr_length (insn));
6691 +}
6692 + [(set (attr "type") (const_string "branch"))])
6693 +
6694 +; Output assembly for a condition branch instruction.
6695 +(define_insn "*cond_branch"
6696 + [(set (pc)
6697 + (if_then_else
6698 + (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
6699 + (label_ref (match_operand 0 "" "")) (pc)))]
6700 + ""
6701 +{
6702 + return output_branch_insn ( GET_CODE(operands[1]),
6703 + operands, get_attr_length (insn));
6704 +}
6705 + [(set (attr "type") (const_string "cbranch"))])
6706 +
6707 +
6708 +; Similar to above, but for a condition branch instruction that
6709 +; had its operands reversed at some point.
6710 +(define_insn "*cond_branch_reverse"
6711 + [(set (pc)
6712 + (if_then_else
6713 + (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
6714 + (pc) (label_ref (match_operand 0 "" ""))))]
6715 + ""
6716 +{
6717 + return output_branch_insn ( reverse_condition (GET_CODE(operands[1])),
6718 + operands, get_attr_length (insn));
6719 +}
6720 + [(set (attr "type") (const_string "cbranch"))])
6721 +
6722 +
6723 +
6724 +;;--------------------------------------------------------------------
6725 +;;- Calls
6726 +;;--------------------------------------------------------------------
6727 +
6728 +;; Generate a call instruction for a function that does not
6729 +;; return a value. The expander is used during RTL generation.
6730 +;; The instructions below are used during matching; only one
6731 +;; of them will be used, depending on the type of function
6732 +;; being called. The different conditions are:
6733 +;;
6734 +;; 1) far_functionp - is this a far function? Those need
6735 +;; to be output as indirect calls through a far-function
6736 +;; handler.
6737 +;;
6738 +;; 2) noreturn_functionp - if the function does not return,
6739 +;; we can use a 'jmp' instead of a 'jsr' to call it.
6740 +;;
6741 +;; 3) is PIC mode enabled? If so, we'll always use
6742 +;; relative calls (lbsr or lbra).
6743 +;;
6744 +;; Note: not all combinations are fully supported, especially
6745 +;; relating to PIC.
6746 +;;
6747 +;; The 'bsr' instruction is never generated.
6748 +
6749 +(define_expand "call"
6750 + [(call (match_operand:HI 0 "memory_operand" "")
6751 + (match_operand:HI 1 "general_operand" ""))]
6752 + ""
6753 + "")
6754 +
6755 +(define_insn "*call_nopic_far"
6756 + [(call (match_operand:HI 0 "memory_operand" "m")
6757 + (match_operand:HI 1 "general_operand" "g"))]
6758 + "far_functionp (operands[0])"
6759 +{
6760 + output_far_call_insn (operands, 0);
6761 + return "";
6762 +}
6763 + [(set_attr "length" "6")])
6764 +
6765 +
6766 +; PIC forms come first, and should only match
6767 +; (MEM (SYMBOL_REF)). Other MEM forms are treated as usual.
6768 +(define_insn "*call_pic"
6769 + [(call (mem:HI (match_operand:HI 0 "symbolic_operand" ""))
6770 + (match_operand:HI 1 "general_operand" "g"))]
6771 + "flag_pic && !noreturn_functionp (operands[0])"
6772 + "lbsr\t%C0"
6773 + [(set_attr "length" "4")])
6774 +
6775 +
6776 +(define_insn "*call_nopic"
6777 + [(call (match_operand:HI 0 "memory_operand" "m")
6778 + (match_operand:HI 1 "general_operand" "g"))]
6779 + "!noreturn_functionp (operands[0])"
6780 + "jsr\t%0"
6781 + [(set_attr "length" "3")
6782 + (set (attr "cycles") (const_int JSR_EXTENDED_CYCLES))])
6783 +
6784 +
6785 +(define_insn "*call_noreturn_pic"
6786 + [(call (mem:HI (match_operand:HI 0 "symbolic_operand" ""))
6787 + (match_operand:HI 1 "general_operand" "g"))]
6788 + "flag_pic && noreturn_functionp (operands[0])"
6789 + "lbra\t%C0"
6790 + [(set_attr "length" "4")])
6791 +
6792 +
6793 +(define_insn "*call_noreturn_nopic"
6794 + [(call (match_operand:HI 0 "memory_operand" "m")
6795 + (match_operand:HI 1 "general_operand" "g"))]
6796 + "noreturn_functionp (operands[0])"
6797 + "jmp\t%0"
6798 + [(set_attr "length" "3")])
6799 +
6800 +
6801 +;;
6802 +;; Same as above, but for functions that do return a value.
6803 +;;
6804 +(define_expand "call_value"
6805 + [(set (match_operand 0 "" "")
6806 + (call (match_operand:HI 1 "memory_operand" "")
6807 + (match_operand:HI 2 "general_operand" "")))]
6808 + ""
6809 + "")
6810 +
6811 +
6812 +(define_insn "*call_value_far"
6813 + [(set (match_operand 0 "" "=gz")
6814 + (call (match_operand:HI 1 "memory_operand" "m")
6815 + (match_operand:HI 2 "general_operand" "g")))]
6816 + "far_functionp (operands[1])"
6817 +{
6818 + output_far_call_insn (operands, 1);
6819 + return "";
6820 +}
6821 + [(set_attr "length" "6")])
6822 +
6823 +
6824 +(define_insn "*call_value_pic"
6825 + [(set (match_operand 0 "" "=gz")
6826 + (call (mem:HI (match_operand:HI 1 "symbolic_operand" ""))
6827 + (match_operand:HI 2 "general_operand" "g")))]
6828 + "flag_pic"
6829 + "lbsr\t%C1"
6830 + [(set_attr "length" "4")])
6831 +
6832 +
6833 +(define_insn "*call_value_nopic"
6834 + [(set (match_operand 0 "" "=gz")
6835 + (call (match_operand:HI 1 "memory_operand" "m")
6836 + (match_operand:HI 2 "general_operand" "g")))]
6837 + ""
6838 + "jsr\t%1"
6839 + [(set_attr "length" "3")
6840 + (set (attr "cycles") (const_int JSR_EXTENDED_CYCLES))])
6841 +
6842 +
6843 +
6844 +;;
6845 +;; How to generate an untyped call.
6846 +;;
6847 +(define_expand "untyped_call"
6848 + [(parallel [(call (match_operand 0 "" "")
6849 + (const_int 0))
6850 + (match_operand 1 "" "")
6851 + (match_operand 2 "" "")])]
6852 + ""
6853 +{
6854 + int i;
6855 +
6856 + emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6857 + for (i=0; i < XVECLEN (operands[2], 0); i++)
6858 + {
6859 + rtx set = XVECEXP (operands[2], 0, i);
6860 + emit_move_insn (SET_DEST (set), SET_SRC (set));
6861 + }
6862 + emit_insn (gen_blockage ());
6863 + DONE;
6864 +})
6865 +
6866 +
6867 +(define_expand "sibcall"
6868 + [(parallel
6869 + [(call (match_operand:HI 0 "memory_operand" "")
6870 + (match_operand:HI 1 "immediate_operand" ""))
6871 + (use (reg:HI HARD_PC_REGNUM))])]
6872 + ""
6873 + "")
6874 +
6875 +(define_insn "*sibcall_1"
6876 + [(parallel
6877 + [(call (match_operand:HI 0 "memory_operand" "m")
6878 + (match_operand:HI 1 "immediate_operand" "i"))
6879 + (use (reg:HI HARD_PC_REGNUM))])]
6880 + "SIBLING_CALL_P(insn)"
6881 + "jmp\t%0"
6882 + [(set_attr "length" "4")])
6883 +
6884 +
6885 +(define_expand "sibcall_value"
6886 + [(parallel
6887 + [(set (match_operand 0 "" "")
6888 + (call (match_operand:HI 1 "memory_operand" "")
6889 + (match_operand:HI 2 "immediate_operand" "")))
6890 + (use (reg:HI HARD_PC_REGNUM))])]
6891 + ""
6892 + "")
6893 +
6894 +(define_insn "*sibcall_value_1"
6895 + [(parallel
6896 + [(set (match_operand 0 "" "=gz")
6897 + (call (match_operand:HI 1 "memory_operand" "m")
6898 + (match_operand:HI 2 "immediate_operand" "i")))
6899 + (use (reg:HI HARD_PC_REGNUM))])]
6900 + "SIBLING_CALL_P(insn)"
6901 + "jmp\t%1"
6902 + [(set_attr "length" "4")])
6903 +
6904 +
6905 +;;--------------------------------------------------------------------
6906 +;;- Function Entry and Exit
6907 +;;--------------------------------------------------------------------
6908 +
6909 +;; On entry to a function, the stack frame looks as follows:
6910 +;; - return address (pushed by the caller)
6911 +;; - saved registers
6912 +;; - local variable storage
6913 +;;
6914 +;; If the function does not modify the stack after that, then
6915 +;; any of these can be accessed directly as an offset from
6916 +;; STACK_POINTER_REGNUM. Otherwise, a frame pointer is required.
6917 +;; In that case, the prologue must also initialize HARD_FRAME_POINTER_REGNUM
6918 +;; and all references to the stack frame will use that as a base instead.
6919 +;;
6920 +(define_expand "prologue"
6921 + [(const_int 0)]
6922 + "prologue_epilogue_required ()"
6923 +{
6924 + emit_prologue_insns ();
6925 + DONE;
6926 +})
6927 +
6928 +
6929 +;; The function epilogue does exactly the reverse of the prologue,
6930 +;; deallocating local variable space, restoring saved registers,
6931 +;; and returning.
6932 +;;
6933 +;; For the 6809, the return may be 'rti' if the function was
6934 +;; declared as an interrupt function, but is normally 'rts'.
6935 +;;
6936 +;; Also, as an optimization, the register restore and the 'rts'
6937 +;; can be combined into a single instruction, by adding 'PC' to the
6938 +;; list of registers to be restored. This is only done if there are
6939 +;; any saved registers, as 'rts' is more efficient by itself.
6940 +;;
6941 +(define_expand "epilogue"
6942 + [(const_int 0)]
6943 + "prologue_epilogue_required ()"
6944 +{
6945 + emit_epilogue_insns (false);
6946 + DONE;
6947 +})
6948 +
6949 +
6950 +(define_expand "sibcall_epilogue"
6951 + [(const_int 0)]
6952 + "prologue_epilogue_required ()"
6953 +{
6954 + emit_epilogue_insns (true);
6955 + DONE;
6956 +})
6957 +
6958 +
6959 +;; The RTS instruction
6960 +(define_insn "return_rts"
6961 + [(return)
6962 + (use (reg:HI HARD_PC_REGNUM))]
6963 + "!m6809_current_function_has_type_attr_p (\"interrupt\")
6964 + && m6809_get_live_regs () == 0"
6965 + "rts"
6966 + [(set_attr "length" "1")
6967 + (set (attr "cycles") (const_int RTS_CYCLES))])
6968 +
6969 +(define_insn "return_puls_pc"
6970 + [(return)
6971 + (use (reg:HI HARD_PC_REGNUM))]
6972 + "!m6809_current_function_has_type_attr_p (\"interrupt\")
6973 + && m6809_get_live_regs () != 0"
6974 + ""
6975 + [(set_attr "length" "1")
6976 + (set (attr "cycles") (const_int RTS_CYCLES))])
6977 +
6978 +;; The RTI instruction
6979 +(define_insn "return_rti"
6980 + [(return)
6981 + (use (reg:HI HARD_PC_REGNUM))]
6982 + "m6809_current_function_has_type_attr_p (\"interrupt\")"
6983 + "rti"
6984 + [(set_attr "length" "1")
6985 + (set (attr "cycles") (const_int RTI_CYCLES))])
6986 +
6987 +
6988 +;;--------------------------------------------------------------------
6989 +;;- Unspecified instructions
6990 +;;--------------------------------------------------------------------
6991 +
6992 +;; An instruction that has the effect of an unspec_volatile, but
6993 +;; which doesn't require emitting any assembly code.
6994 +(define_insn "blockage"
6995 + [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
6996 + ""
6997 + ""
6998 + [(set_attr "length" "0")
6999 + (set (attr "cycles") (const_int 0))])
7000 +
7001 +
7002 +;; Say how to push multiple registers onto the stack, using
7003 +;; the 6809 'pshs' instruction. The operand is a regset
7004 +;; specifying which registers to push.
7005 +;;
7006 +;; The operand mode is not given intentionally, so as to allow
7007 +;; any possible integer mode for the regset.
7008 +;;
7009 +;; See below for a peephole that can combine consecutive push
7010 +;; instructions that qualify for merging.
7011 +(define_insn "register_push"
7012 + [(use (reg:HI HARD_S_REGNUM))
7013 + (unspec_volatile
7014 + [(match_operand 0 "immediate_operand" "")] UNSPEC_PUSH_RS)
7015 + (clobber (reg:HI HARD_S_REGNUM))]
7016 + ""
7017 + "pshs\t%R0"
7018 + [(set_attr "length" "2")
7019 + (set (attr "cycles") (const_int PSH_PUL_CYCLES))])
7020 +
7021 +
7022 +;; Say how to pop multiple registers from the stack, using
7023 +;; the 6809 'puls' instruction. The operand is the register
7024 +;; bitset value.
7025 +(define_insn "register_pop"
7026 + [(use (reg:HI HARD_S_REGNUM))
7027 + (unspec_volatile
7028 + [(match_operand 0 "immediate_operand" "")] UNSPEC_POP_RS)
7029 + (clobber (reg:HI HARD_S_REGNUM))]
7030 + ""
7031 + "puls\t%R0"
7032 + [(set_attr "length" "2")
7033 + (set (attr "cycles") (const_int PSH_PUL_CYCLES))])
7034 +
7035 +
7036 +(define_insn "m6809_swi"
7037 + [(unspec_volatile
7038 + [(match_operand:QI 0 "immediate_operand" "I,n")] UNSPEC_SWI)]
7039 + ""
7040 + "@
7041 + swi
7042 + swi%c0"
7043 + [(set_attr "length" "1,2")
7044 + (set (attr "cycles") (const_int SWI_CYCLES))])
7045 +
7046 +
7047 +;; Generate the CWAI instruction
7048 +(define_insn "m6809_cwai"
7049 + [(unspec_volatile
7050 + [(match_operand:QI 0 "immediate_operand" "")] UNSPEC_CWAI)]
7051 + ""
7052 + "cwai\t%0"
7053 + [(set_attr "length" "2")
7054 + (set (attr "cycles") (const_int CWAI_CYCLES))])
7055 +
7056 +
7057 +;; Generate the SYNC instruction
7058 +(define_insn "m6809_sync"
7059 + [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
7060 + ""
7061 + "sync"
7062 + [(set_attr "length" "1")
7063 + (set (attr "cycles") (const_int SYNC_CYCLES))])
7064 +
7065 +
7066 +;; Generate the NOP instruction
7067 +(define_insn "nop"
7068 + [(const_int 0)]
7069 + ""
7070 + "nop"
7071 + [(set_attr "length" "1")
7072 + (set (attr "cycles") (const_int NOP_CYCLES))])
7073 +
7074 +
7075 +;;--------------------------------------------------------------------
7076 +;;- Peepholes
7077 +;;--------------------------------------------------------------------
7078 +
7079 +;;; Each peephole has an ID that is used for debugging.
7080 +;;; Each peephole condition is bracketed by calls to
7081 +;;; m6809_match_peephole2() also for debugging.
7082 +(define_constants [
7083 + (PEEP_END 0)
7084 + (PEEP_COND 1)
7085 +
7086 + (PEEP_STACK_STORE_INC 0)
7087 + (PEEP_STACK_CLEAR_INC 1)
7088 + (PEEP_LSRB_ADCB 2)
7089 + (PEEP_ABX 3)
7090 + (PEEP_ABX2 4)
7091 + (PEEP_INDEXED_INC 5)
7092 + (PEEP_MEM_DEC 6)
7093 + (PEEP_MEM_INC 7)
7094 + (PEEP_MEM_DEC_CMP 8)
7095 + (PEEP_PUSH2 9)
7096 + (PEEP_STORE_IMPLIES_CC 10)
7097 + (PEEP_DEC_IMPLIES_CC 11)
7098 + (PEEP_LEAB 12)
7099 + (PEEP_LDX_INDIRECT 13)
7100 + (PEEP_POP_JUNK 14)
7101 +])
7102 +
7103 +
7104 +;;; Optimize 'leas -1,s' followed by 'stb ,s'. This can happen if the
7105 +;;; function prologue needs to allocate stack space and 'b' is placed
7106 +;;; into that local right away. Combine the stack allocation with the
7107 +;;; store using preincrement mode.
7108 +(define_peephole2
7109 + [(set (reg:HI HARD_S_REGNUM)
7110 + (plus:HI (reg:HI HARD_S_REGNUM) (const_int -1)))
7111 + (set (mem:QI (reg:HI HARD_S_REGNUM))
7112 + (match_operand:QI 0 "register_operand" ""))]
7113 + "m6809_match_peephole2 (PEEP_STACK_STORE_INC, PEEP_END)"
7114 + [(set (mem:QI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (match_dup 0))]
7115 + "")
7116 +
7117 +
7118 +;;; Same as above, but for a 'clr ,s' that follows the prologue.
7119 +(define_peephole2
7120 + [(set (reg:HI HARD_S_REGNUM) (plus:HI (reg:HI HARD_S_REGNUM) (const_int -1)))
7121 + (set (mem:QI (reg:HI HARD_S_REGNUM)) (const_int 0))]
7122 + "m6809_match_peephole2 (PEEP_STACK_CLEAR_INC, PEEP_END)"
7123 + [(set (mem:QI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (const_int 0))]
7124 + "")
7125 +
7126 +
7127 +;;; Merge two consecutive push instructions into a single register_push.
7128 +(define_peephole2
7129 + [(set (match_operand 0 "push_operand" "")
7130 + (match_operand 1 "register_operand" ""))
7131 + (set (match_operand 2 "push_operand" "")
7132 + (match_operand 3 "register_operand" ""))]
7133 + "m6809_match_peephole2 (PEEP_PUSH2, PEEP_COND)
7134 + && reload_completed
7135 + && GET_MODE (operands[1]) == GET_MODE (operands[3])
7136 + && m6809_can_merge_pushpop_p (UNSPEC_PUSH_RS, 1 << REGNO (operands[1]), 1 << REGNO (operands[3]))
7137 + && m6809_match_peephole2 (PEEP_PUSH2, PEEP_END)"
7138 + [(parallel [
7139 + (use (reg:HI HARD_S_REGNUM))
7140 + (unspec_volatile [(match_dup 4)] UNSPEC_PUSH_RS)
7141 + (clobber (reg:HI HARD_S_REGNUM))])
7142 + (use (match_dup 1))
7143 + (use (match_dup 3))]
7144 +{
7145 + operands[4] = gen_rtx_CONST_INT (QImode,
7146 + (1 << REGNO (operands[1])) | (1 << REGNO (operands[3])));
7147 +})
7148 +
7149 +
7150 +;;; Convert 'stX ,--s' into a push instruction. Use the regset
7151 +;;; notation, so that it may be combined with an adjacent regset.
7152 +;;; TBD - this doesn't compile some code cleanly.
7153 +;(define_peephole2
7154 +; [(set (mem:HI (pre_dec:HI (reg:HI HARD_S_REGNUM)))
7155 +; (reg:HI HARD_X_REGNUM))]
7156 +; "reload_completed"
7157 +; [(parallel [
7158 +; (use (reg:HI HARD_S_REGNUM))
7159 +; (unspec_volatile [(match_dup 0)] UNSPEC_PUSH_RS)
7160 +; (clobber (reg:HI HARD_S_REGNUM))])]
7161 +;{
7162 +; operands[0] = gen_rtx_CONST_INT (HImode, X_REGBIT);
7163 +;})
7164 +
7165 +
7166 +;;;
7167 +;;; q = (q+1)/2 can be optimized as "lsrb; adcb". This also
7168 +;;; won't overflow when q=0xFF.
7169 +;;; TODO : this form isn't accounting for promotion when
7170 +;;; using 16-bit ints.
7171 +;;;
7172 +(define_peephole
7173 + [(set (reg:QI HARD_D_REGNUM)
7174 + (lshiftrt:QI (plus:HI (match_dup 0) (const_int 1)) (const_int 1)))]
7175 + "m6809_match_peephole2 (PEEP_LSRB_ADCB, PEEP_END)"
7176 + "lsrb\;adcb\t#0; peephole"
7177 + [(set_attr "length" "2")])
7178 +
7179 +
7180 +;;
7181 +;; Optimize the case of following a register store with a test
7182 +;; of reg or mem just moved.
7183 +;;
7184 +(define_peephole
7185 + [(set (match_operand:HI 0 "memory_operand" "=m")
7186 + (match_operand:HI 1 "register_operand" "r"))
7187 + (set (cc0) (match_operand:HI 2 "general_operand" "g"))]
7188 + "m6809_match_peephole2 (PEEP_STORE_IMPLIES_CC, PEEP_COND)
7189 + && (operands[2] == operands[0] || operands[2] == operands[1])
7190 + && m6809_match_peephole2 (PEEP_STORE_IMPLIES_CC, PEEP_END)"
7191 + "st%1\t%0\t;movhi: R:%1 -> %0 w/ implied test of %2"
7192 + [(set_attr "length" "4")])
7193 +
7194 +
7195 +;; Optimize a pair of SET instructions in which the second insn
7196 +;; is the reverse of the first one. I.e.
7197 +;;
7198 +;; A = B
7199 +;; ----> A = B
7200 +;; B = A
7201 +;;
7202 +;; The second insn is redundant. Define two patterns, one for QI, one for HI.
7203 +;; But don't do this if either is a VOLATILE MEM.
7204 +(define_peephole2
7205 + [(set (match_operand:HI 0 "nonimmediate_operand" "")
7206 + (match_operand:HI 1 "nonimmediate_operand" ""))
7207 + (set (match_dup 1) (match_dup 0))]
7208 + "!MEM_P (operands[0]) || !MEM_P (operands[1]) || (!MEM_VOLATILE_P (operands[0]) && !MEM_VOLATILE_P (operands[1]))"
7209 + [(set (match_dup 0) (match_dup 1))]
7210 + "")
7211 +
7212 +(define_peephole2
7213 + [(set (match_operand:QI 0 "nonimmediate_operand" "")
7214 + (match_operand:QI 1 "nonimmediate_operand" ""))
7215 + (set (match_dup 1) (match_dup 0))]
7216 + "!MEM_P (operands[0]) || !MEM_P (operands[1]) || (!MEM_VOLATILE_P (operands[0]) && !MEM_VOLATILE_P (operands[1]))"
7217 + [(set (match_dup 0) (match_dup 1))]
7218 + "")
7219 +
7220 +
7221 +;;
7222 +;; Optimize the sum of an 8-bit and 16-bit using the 'abx' instruction
7223 +;; if B and X can be used. Two patterns are provided to catch both
7224 +;; X=X+D and X=D+X.
7225 +;;
7226 +(define_peephole
7227 + [(set (reg:HI HARD_D_REGNUM)
7228 + (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
7229 + (set (reg:HI HARD_X_REGNUM)
7230 + (plus:HI (reg:HI HARD_D_REGNUM) (reg:HI HARD_X_REGNUM)))]
7231 + "m6809_match_peephole2 (PEEP_ABX, PEEP_END)"
7232 + "abx"
7233 + [(set_attr "length" "1")])
7234 +
7235 +(define_peephole
7236 + [(set (reg:HI HARD_D_REGNUM)
7237 + (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
7238 + (set (reg:HI HARD_X_REGNUM)
7239 + (plus:HI (reg:HI HARD_X_REGNUM) (reg:HI HARD_D_REGNUM)))]
7240 + "m6809_match_peephole2 (PEEP_ABX, PEEP_END)"
7241 + "abx"
7242 + [(set_attr "length" "1")])
7243 +
7244 +;;; Likewise, handle when B is scaled by 2 prior to the add.
7245 +;;; Instead of shifting B in 4 cycles, just do the ABX a second
7246 +;;; time, in only 3 cycles.
7247 +
7248 +(define_peephole
7249 + [(set (reg:HI HARD_D_REGNUM)
7250 + (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
7251 + (set (reg:HI HARD_D_REGNUM)
7252 + (ashift:HI (reg:HI HARD_D_REGNUM) (const_int 1)))
7253 + (set (reg:HI HARD_X_REGNUM)
7254 + (plus:HI (reg:HI HARD_D_REGNUM) (reg:HI HARD_X_REGNUM)))]
7255 + "m6809_match_peephole2 (PEEP_ABX2, PEEP_END)"
7256 + "abx\;abx"
7257 + [(set_attr "length" "2")])
7258 +
7259 +(define_peephole
7260 + [(set (reg:HI HARD_D_REGNUM)
7261 + (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
7262 + (set (reg:HI HARD_D_REGNUM)
7263 + (ashift:HI (reg:HI HARD_D_REGNUM) (const_int 1)))
7264 + (set (reg:HI HARD_X_REGNUM)
7265 + (plus:HI (reg:HI HARD_X_REGNUM) (reg:HI HARD_D_REGNUM)))]
7266 + "m6809_match_peephole2 (PEEP_ABX2, PEEP_END)"
7267 + "abx\;abx"
7268 + [(set_attr "length" "2")])
7269 +
7270 +
7271 +;;
7272 +;; Work around a compiler bug that generates bad code when copying
7273 +;; between 32-bit memory addresses after a libcall. The problem seen is
7274 +;; that the source is MEM (REG X), but X is used as the reload register.
7275 +;; The second half of the copy therefore fails.
7276 +;;
7277 +;; The solution is to switch the reload register to D, since that is guaranteed
7278 +;; not to be in use right after a libcall.
7279 +;;
7280 +(define_peephole2
7281 + [(set (reg:HI HARD_X_REGNUM) (mem:HI (reg:HI HARD_X_REGNUM)))
7282 + (set (match_operand:HI 0 "nonimmediate_operand" "") (reg:HI HARD_X_REGNUM))
7283 + (set (reg:HI HARD_X_REGNUM)
7284 + (mem:HI (plus:HI (reg:HI HARD_X_REGNUM) (const_int 2))))
7285 + (set (match_operand:HI 1 "nonimmediate_operand" "") (reg:HI HARD_X_REGNUM))]
7286 + "reload_completed"
7287 + [(set (reg:HI HARD_D_REGNUM) (mem:HI (reg:HI HARD_X_REGNUM)))
7288 + (set (match_dup 0) (reg:HI HARD_D_REGNUM))
7289 + (set (reg:HI HARD_X_REGNUM)
7290 + (mem:HI (plus:HI (reg:HI HARD_X_REGNUM) (const_int 2))))
7291 + (set (match_dup 1) (reg:HI HARD_X_REGNUM))]
7292 + "")
7293 +
7294 +
7295 +;; Turn "and then test" into a "bit test" operation.
7296 +;; Provide variants for immediate and memory sources
7297 +;; This is the most used peephople.
7298 +; (define_peephole
7299 +; [(set (match_operand:QI 0 "register_operand" "=q")
7300 +; (and:QI (match_operand:QI 1 "register_operand" "0")
7301 +; (match_operand:QI 2 "immediate_operand" "i")))
7302 +; (set (cc0) (match_dup 0))]
7303 +; ""
7304 +; "bit%0\t%2"
7305 +; [(set_attr "length" "3")])
7306 +;
7307 +; (define_peephole
7308 +; [(set (match_operand:QI 0 "register_operand" "=q")
7309 +; (and:QI (match_operand:QI 1 "register_operand" "0")
7310 +; (match_operand:QI 2 "memory_operand" "m")))
7311 +; (set (cc0) (match_dup 0))]
7312 +; ""
7313 +; "bit%0\t%2"
7314 +; [(set_attr "length" "4")])
7315 +
7316 +
7317 +;; Turn a "decrement, then test" sequence into just a "decrement".
7318 +;; The test can be omitted, since it is implicitly done.
7319 +(define_peephole2
7320 + [(set (match_operand:QI 0 "nonimmediate_operand" "")
7321 + (plus:QI (match_operand:QI 1 "whole_general_operand" "")
7322 + (match_operand:QI 2 "immediate_operand" "")))
7323 + (set (cc0) (match_dup 0))]
7324 + "m6809_match_peephole2 (PEEP_DEC_IMPLIES_CC, PEEP_END)"
7325 + [(set (match_dup 0) (plus:QI (match_dup 1) (match_dup 2)))]
7326 + "")
7327 +
7328 +
7329 +;; Merge an indexed register increment with a previous usage.
7330 +;; This is usually done automatically, but not always
7331 +;; The 'use' should be optional; in all cases where this has been
7332 +;; seen, it is required though.
7333 +(define_peephole2
7334 + [(set (match_operand:QI 0 "register_operand" "")
7335 + (mem:QI (match_operand:HI 1 "index_register_operand" "")))
7336 + (use (match_dup 0))
7337 + (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
7338 + "m6809_match_peephole2 (PEEP_INDEXED_INC, PEEP_END)"
7339 + [(set (match_dup 0) (mem:QI (post_inc:HI (match_dup 1))))
7340 + (use (match_dup 0))]
7341 + "")
7342 +
7343 +
7344 +;;; Merge "ldX MEM; ldX ,X" into a single instruction using
7345 +;;; the indirect mode.
7346 +(define_peephole2
7347 + [(set (reg:HI HARD_X_REGNUM)
7348 + (mem:HI (match_operand:HI 0 "general_operand" "")))
7349 + (set (reg:HI HARD_X_REGNUM) (mem:HI (reg:HI HARD_X_REGNUM)))]
7350 + "reload_completed && m6809_match_peephole2 (PEEP_LDX_INDIRECT, PEEP_END)"
7351 + [(set (reg:HI HARD_X_REGNUM)
7352 + (mem:HI (mem:HI (match_dup 0))))]
7353 + "")
7354 +
7355 +
7356 +;;; Reorder a store followed by a unary operation on that memory
7357 +;;; so that the unary is performed and then the store. Consider
7358 +;;; a binary shift operation, which will be decomposed into
7359 +;;; identical single shifts, also.
7360 +;;; TODO - recognize more than just 'ashift' here.
7361 +(define_peephole2
7362 + [(set (match_operand:QI 0 "memory_operand" "")
7363 + (match_operand:QI 1 "register_operand" ""))
7364 + (set (match_dup 0)
7365 + (ashift:QI (match_dup 0) (match_operand:QI 2 "immediate_operand")))]
7366 + "reload_completed"
7367 + [(set (match_dup 1)
7368 + (ashift:QI (match_dup 1) (match_operand:QI 2 "immediate_operand")))
7369 + (set (match_dup 0) (match_dup 1))]
7370 + "")
7371 +
7372 +;;; Likewise, reorder a unary MEM followed by a load, so that the load
7373 +;;; is done first, then use the REG instead of the MEM.
7374 +;;;(define_peephole2
7375 +;;; [(set (match_dup 0)
7376 +;;; (ashift:QI (match_dup 0) (match_operand:QI 2 "immediate_operand")))
7377 +;;; (set (match_operand:QI 0 "register_operand" "")
7378 +;;; (match_operand:QI 1 "memory_operand" ""))]
7379 +;;; "reload_completed"
7380 +;;; [(set (match_dup 0) (match_dup 1))
7381 +;;; (set (match_dup 0)
7382 +;;; (ashift:QI (match_dup 0) (match_operand:QI 2 "immediate_operand")))]
7383 +;;; "")
7384 +
7385 +
7386 +;;; Replace sex; leaX d,Y with leaX b,Y.
7387 +;;;
7388 +(define_peephole2
7389 + [(set (reg:HI HARD_D_REGNUM) (sign_extend:HI (reg:QI HARD_D_REGNUM)))
7390 + (set (match_operand:HI 0 "index_register_operand" "")
7391 + (plus:HI (match_operand:HI 1 "index_register_operand" "")
7392 + (reg:HI HARD_D_REGNUM)))]
7393 + "reload_completed && m6809_match_peephole2 (PEEP_LEAB, PEEP_END)"
7394 + [(set (match_dup 0)
7395 + (plus:HI (match_dup 1) (reg:QI HARD_D_REGNUM)))]
7396 + "")
7397 +
7398 +(define_peephole2
7399 + [(set (reg:HI HARD_D_REGNUM) (sign_extend:HI (reg:QI HARD_D_REGNUM)))
7400 + (set (match_operand:HI 0 "index_register_operand" "")
7401 + (plus:HI (reg:HI HARD_D_REGNUM)
7402 + (match_operand:HI 1 "index_register_operand" "")))]
7403 + "reload_completed && m6809_match_peephole2 (PEEP_LEAB, PEEP_END)"
7404 + [(set (match_dup 0)
7405 + (plus:HI (match_dup 1) (reg:QI HARD_D_REGNUM)))]
7406 + "")
7407 +
7408 +
7409 +;;; Replace ldb; decb; stb; tstb with dec(mem). If the
7410 +;;; register is not needed, then the load will get deleted
7411 +;;; automatically, but it may be needed for comparisons.
7412 +;;; Same for incb/inc.
7413 +(define_peephole2
7414 + [(set (match_operand:QI 0 "register_operand" "")
7415 + (match_operand:QI 1 "nonimmediate_operand" ""))
7416 + (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))
7417 + (set (match_dup 1) (match_dup 0))
7418 + (set (cc0) (match_dup 0))]
7419 + "m6809_match_peephole2 (PEEP_MEM_DEC_CMP, PEEP_END)"
7420 + [(set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))]
7421 + "")
7422 +
7423 +
7424 +;;; Replace ldb; decb; stb with dec(mem); ldb. If the
7425 +;;; register is not needed, then the load will get deleted
7426 +;;; automatically, but it may be needed for comparisons.
7427 +;;; Same for incb/inc.
7428 +(define_peephole2
7429 + [(set (match_operand:QI 0 "register_operand" "")
7430 + (match_operand:QI 1 "nonimmediate_operand" ""))
7431 + (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))
7432 + (set (match_dup 1) (match_dup 0))]
7433 + "m6809_match_peephole2 (PEEP_MEM_DEC, PEEP_END)"
7434 + [(set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))
7435 + (set (match_dup 0) (match_dup 1))]
7436 + "")
7437 +
7438 +(define_peephole2
7439 + [(set (match_operand:QI 0 "register_operand" "")
7440 + (match_operand:QI 1 "nonimmediate_operand" ""))
7441 + (set (match_dup 0) (plus:QI (match_dup 0) (const_int 1)))
7442 + (set (match_dup 1) (match_dup 0))]
7443 + "m6809_match_peephole2 (PEEP_MEM_INC, PEEP_END)"
7444 + [(set (match_dup 1) (plus:QI (match_dup 1) (const_int 1)))
7445 + (set (match_dup 0) (match_dup 1))]
7446 + "")
7447 +
7448 +
7449 +;;; Replace "andb #N; cmpb #N; bhi" with "andb #N", if it can be proven
7450 +;;; that the branch can never occur because of the limited range of B.
7451 +;;; N must be a power of two for this to make sense. This helps with
7452 +;;; the default cases of switch statements on a value (x & N).
7453 +(define_peephole2
7454 + [(set (match_operand:QI 0 "register_operand" "")
7455 + (and:QI (match_dup 0) (match_operand:QI 1 "immediate_operand" "")))
7456 + (set (cc0)
7457 + (compare (match_dup 0) (match_dup 1)))
7458 + (set (pc) (if_then_else (gtu (cc0) (const_int 0)) (match_operand 2 "" "") (match_operand 3 "" "")))
7459 + ]
7460 + "reload_completed && power_of_two_p (INTVAL (operands[1]) + 1)"
7461 + [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
7462 + "")
7463 +
7464 +;;; Replace ldd <mem>; addd #1; std <mem> with 16-bit increment
7465 +;;; of the mem, but only if D is dead. Same for 16-bit decrement.
7466 +;;; <mem> must be offsettable for the instruction to match.
7467 +(define_peephole2
7468 + [(set (match_operand:HI 0 "register_operand" "") (match_operand:HI 1 "memory_operand" ""))
7469 + (set (match_dup 0) (plus:HI (match_dup 0) (const_int 1)))
7470 + (set (match_dup 1) (match_dup 0))]
7471 + "reload_completed
7472 + && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7473 + && peep2_reg_dead_p (3, operands[0])"
7474 + [(set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
7475 + "")
7476 +
7477 +(define_peephole2
7478 + [(set (match_operand:HI 0 "register_operand" "") (match_operand:HI 1 "memory_operand" ""))
7479 + (set (match_dup 0) (plus:HI (match_dup 0) (const_int -1)))
7480 + (set (match_dup 1) (match_dup 0))]
7481 + "reload_completed
7482 + && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7483 + && peep2_reg_dead_p (3, operands[0])"
7484 + [(set (match_dup 1) (plus:HI (match_dup 1) (const_int -1)))]
7485 + "")
7486 +
7487 +
7488 +;;; Replace a load or store using an indexed register, followed by an increment of that
7489 +;;; register, with the combined form using autoincrement.
7490 +(define_peephole2
7491 + [(set (match_operand:QI 0 "register_operand" "")
7492 + (mem:QI (match_operand:HI 1 "index_register_operand" "")))
7493 + (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
7494 + "reload_completed"
7495 + [(set (match_dup 0) (mem:QI (post_inc (match_dup 1))))]
7496 + "")
7497 +
7498 +
7499 +;;- mode:emacs-lisp
7500 +;;- comment-start: ";;- "
7501 +;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
7502 +;;- eval: (modify-syntax-entry ?[ "(]")
7503 +;;- eval: (modify-syntax-entry ?] ")[")
7504 +;;- eval: (modify-syntax-entry ?{ "(}")
7505 +;;- eval: (modify-syntax-entry ?} "){")
7506 +;-; vim: set ts=2:
7507 +;-; vim: set expandtab:
7508 +;-; vim: set filetype=lisp:
7509 +;;- End:
7510 diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.opt gcc-4.6.4/gcc/config/m6809/m6809.opt
7511 --- gcc-4.6.4-clean/gcc/config/m6809/m6809.opt 1969-12-31 17:00:00.000000000 -0700
7512 +++ gcc-4.6.4/gcc/config/m6809/m6809.opt 2015-07-20 19:44:52.770843181 -0600
7513 @@ -0,0 +1,98 @@
7514 +; Options for the M6809 port of the compiler
7515 +;
7516 +; Copyright (C) 2005 Free Software Foundation, Inc.
7517 +;
7518 +; This file is part of GCC.
7519 +;
7520 +; GCC is free software; you can redistribute it and/or modify it under
7521 +; the terms of the GNU General Public License as published by the Free
7522 +; Software Foundation; either version 2, or (at your option) any later
7523 +; version.
7524 +;
7525 +; GCC is distributed in the hope that it will be useful, but WITHOUT
7526 +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
7527 +; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
7528 +; License for more details.
7529 +;
7530 +; You should have received a copy of the GNU General Public License
7531 +; along with GCC; see the file COPYING. If not, write to the Free
7532 +; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
7533 +; 02110-1301, USA.
7534 +
7535 +margcount
7536 +Target Mask(ARGCOUNT)
7537 +Push argument count
7538 +
7539 +mint8
7540 +Target RejectNegative Mask(BYTE_INT)
7541 +Use 8-bit integers
7542 +
7543 +mint16
7544 +Target RejectNegative
7545 +Use 16-bit integers InverseMask(BYTE_INT)
7546 +
7547 +mreg-args
7548 +Target Mask(REG_ARGS)
7549 +Use registers for function arguments
7550 +
7551 +mshort_size
7552 +Target RejectNegative Mask(SMALL_SIZE_T)
7553 +Use 8-bit size_t
7554 +
7555 +mlong_size
7556 +Target RejectNegative InverseMask(SMALL_SIZE_T)
7557 +Use 16-bit size_t
7558 +
7559 +mdirect
7560 +Target Mask(DIRECT)
7561 +Enable direct addressing
7562 +
7563 +mwpc
7564 +Target RejectNegative Mask(WPC)
7565 +Enable WPC platform extensions
7566 +
7567 +mexperiment
7568 +Target RejectNegative Mask(EXPERIMENT)
7569 +Enable current experimental feature
7570 +
7571 +m6309
7572 +Target RejectNegative Mask(6309)
7573 +Enable Hitachi 6309 extensions
7574 +
7575 +mcasesi
7576 +Target RejectNegative Mask(CASESI)
7577 +Enable the casesi pattern
7578 +
7579 +mfar-code-page=
7580 +Target RejectNegative Joined Var(far_code_page_option)
7581 +Sets the far code page value for this compilation unit
7582 +
7583 +mcode-section=
7584 +Target RejectNegative Joined Var(code_section_ptr)
7585 +Sets the name of the section for code
7586 +
7587 +mdata-section=
7588 +Target RejectNegative Joined Var(data_section_ptr)
7589 +Sets the name of the section for initialized data
7590 +
7591 +mbss-section=
7592 +Target RejectNegative Joined Var(bss_section_ptr)
7593 +Sets the name of the section for uninitialized data
7594 +
7595 +mabi_version=
7596 +Target RejectNegative Joined Var(m6809_abi_version_ptr)
7597 +Sets the calling convention
7598 +
7599 +msoft-reg-count=
7600 +Target RejectNegative Joined Var(m6809_soft_reg_count)
7601 +Sets the number of soft registers that can be used
7602 +
7603 +mdret
7604 +Target RejectNegative Mask(DRET)
7605 +Put function call results in D, not X
7606 +
7607 +mfar-stack-param
7608 +Target Mask(FAR_STACK_PARAM)
7609 +Enable stack parameters to a farcall
7610 +
7611 +
7612 diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809-protos.h gcc-4.6.4/gcc/config/m6809/m6809-protos.h
7613 --- gcc-4.6.4-clean/gcc/config/m6809/m6809-protos.h 1969-12-31 17:00:00.000000000 -0700
7614 +++ gcc-4.6.4/gcc/config/m6809/m6809-protos.h 2015-07-20 19:44:52.770843181 -0600
7615 @@ -0,0 +1,94 @@
7616 +/* GCC for 6809 : machine-specific function prototypes
7617 +
7618 +This file is part of GCC.
7619 +
7620 +GCC is free software; you can redistribute it and/or modify
7621 +it under the terms of the GNU General Public License as published by
7622 +the Free Software Foundation; either version 3, or (at your option)
7623 +any later version.
7624 +
7625 +GCC is distributed in the hope that it will be useful,
7626 +but WITHOUT ANY WARRANTY; without even the implied warranty of
7627 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7628 +GNU General Public License for more details.
7629 +
7630 +You should have received a copy of the GNU General Public License
7631 +along with GCC; see the file COPYING3. If not see
7632 +<http://www.gnu.org/licenses/>. */
7633 +
7634 +#ifndef __M6809_PROTOS_H__
7635 +#define __M6809_PROTOS_H__
7636 +
7637 +void print_options (FILE *file);
7638 +void m6809_cpu_cpp_builtins (void);
7639 +void m6809_override_options (void);
7640 +void m6809_init_builtins (void);
7641 +unsigned int m6809_get_live_regs (void);
7642 +const char * m6809_get_regs_printable (unsigned int regs);
7643 +unsigned int m6809_get_regs_size (unsigned int regs);
7644 +int m6809_function_has_type_attr_p (tree decl, const char *);
7645 +int m6809_current_function_has_type_attr_p (const char *);
7646 +int prologue_epilogue_required (void);
7647 +int noreturn_functionp (rtx x);
7648 +void output_function_prologue (FILE *file, int size);
7649 +void output_function_epilogue (FILE *file, int size);
7650 +int check_float_value (enum machine_mode mode, double *d, int overflow);
7651 +void m6809_asm_named_section (const char *name, unsigned int flags, tree decl);
7652 +void m6809_asm_file_start (void);
7653 +void m6809_output_ascii (FILE *fp, const char *str, unsigned long size);
7654 +void m6809_declare_function_name (FILE *asm_out_file, const char *name, tree decl);
7655 +void m6809_reorg (void);
7656 +int m6809_current_function_is_void (void);
7657 +int m6809_can_merge_pushpop_p (int op, int regs1, int regs2);
7658 +int m6809_function_value_regno_p (unsigned int regno);
7659 +void emit_prologue_insns (void);
7660 +void emit_epilogue_insns (bool);
7661 +void m6809_conditional_register_usage (void);
7662 +void m6809_output_quoted_string (FILE *asm_file, const char *string);
7663 +int m6809_match_peephole2 (unsigned int peephole_id, unsigned int stage);
7664 +int m6809_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode);
7665 +int power_of_two_p (unsigned int n);
7666 +void m6809_do_casesi (rtx index, rtx lower_bound, rtx range, rtx table_label, rtx default_label);
7667 +void m6809_output_addsi3 (int rtx_code, rtx *operands);
7668 +rtx m6809_function_arg_on_stack (CUMULATIVE_ARGS *cump);
7669 +void expand_constant_shift (int code, rtx dst, rtx src, rtx count);
7670 +int m6809_single_operand_operator (rtx exp);
7671 +
7672 +#ifdef TREE_CODE
7673 +int m6809_init_cumulative_args (CUMULATIVE_ARGS cum, tree fntype, rtx libname);
7674 +#endif /* TREE_CODE */
7675 +
7676 +#ifdef RTX_CODE
7677 +void print_direct_prefix (FILE *file, rtx addr);
7678 +void print_operand (FILE *file, rtx x, int code);
7679 +void print_operand_address (FILE *file, rtx addr);
7680 +void notice_update_cc (rtx exp, rtx insn);
7681 +enum reg_class m6809_preferred_reload_class (rtx x, enum reg_class regclass);
7682 +rtx gen_rtx_const_high (rtx r);
7683 +rtx gen_rtx_const_low (rtx r);
7684 +rtx gen_rtx_register_pushpop (int pop_flag, int regs);
7685 +void emit_libcall_insns (enum machine_mode mode, const char *name, rtx *operands, int count);
7686 +const char * output_branch_insn (enum rtx_code code, rtx *operands, int length);
7687 +void output_far_call_insn (rtx *operands, int has_return);
7688 +void m6809_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt);
7689 +rtx m6809_expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, int ignore);
7690 +const char * far_functionp (rtx x);
7691 +rtx m6809_function_value (const tree valtype, const tree func);
7692 +void m6809_output_shift_insn (int rtx_code, rtx *operands);
7693 +
7694 +const char * m6809_get_decl_bank (tree decl);
7695 +void output_branch_insn1 (const char *opcode, rtx *operands, int long_p);
7696 +rtx m6809_builtin_operand (tree arglist, enum machine_mode mode, int opnum);
7697 +const char * far_function_type_p (tree type);
7698 +void m6809_asm_trampoline_template(FILE *f);
7699 +bool m6809_frame_pointer_required (void);
7700 +int m6809_can_eliminate (int from, int to);
7701 +int m6809_initial_elimination_offset (int from, int to);
7702 +void m6809_emit_move_insn (rtx dst, rtx src);
7703 +void m6809_split_shift (enum rtx_code code, rtx *operands);
7704 +bool m6809_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED);
7705 +
7706 +
7707 +#endif /* RTX_CODE */
7708 +
7709 +#endif /* __M6809_PROTOS_H__ */
7710 diff -urN gcc-4.6.4-clean/gcc/config/m6809/predicates.md gcc-4.6.4/gcc/config/m6809/predicates.md
7711 --- gcc-4.6.4-clean/gcc/config/m6809/predicates.md 1969-12-31 17:00:00.000000000 -0700
7712 +++ gcc-4.6.4/gcc/config/m6809/predicates.md 2015-07-20 19:44:52.770843181 -0600
7713 @@ -0,0 +1,78 @@
7714 +;; Predicate definitions for Motorola 6809
7715 +;; Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
7716 +;;
7717 +;; This file is part of GCC.
7718 +;;
7719 +;; GCC is free software; you can redistribute it and/or modify
7720 +;; it under the terms of the GNU General Public License as published by
7721 +;; the Free Software Foundation; either version 3, or (at your option)
7722 +;; any later version.
7723 +;;
7724 +;; GCC is distributed in the hope that it will be useful,
7725 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
7726 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7727 +;; GNU General Public License for more details.
7728 +;;
7729 +;; You should have received a copy of the GNU General Public License
7730 +;; along with GCC; see the file COPYING3. If not see
7731 +;; <http://www.gnu.org/licenses/>.
7732 +
7733 +;; whole_register_operand is like register_operand, but it
7734 +;; does not allow SUBREGs.
7735 +(define_predicate "whole_register_operand"
7736 + (and (match_code "reg")
7737 + (match_operand 0 "register_operand")))
7738 +
7739 +
7740 +;; A predicate that matches any index register. This can be used in nameless
7741 +;; patterns and peepholes which need a 16-bit reg, but not D.
7742 +(define_predicate "index_register_operand"
7743 + (and (match_code "reg")
7744 + (match_test "REGNO (op) == HARD_X_REGNUM || REGNO (op) == HARD_Y_REGNUM || REGNO (op) == HARD_U_REGNUM")))
7745 +
7746 +
7747 +;; match only X
7748 +(define_predicate "register_operand_x"
7749 + (and (match_code "reg")
7750 + (match_test "REGNO (op) == HARD_X_REGNUM")))
7751 +
7752 +;; match only D
7753 +(define_predicate "register_operand_d"
7754 + (and (match_code "reg")
7755 + (match_test "REGNO (op) == HARD_D_REGNUM")))
7756 +
7757 +
7758 +;; Likwise, a replacement for general_operand which excludes
7759 +;; SUBREGs.
7760 +(define_predicate "whole_general_operand"
7761 + (and (match_code "const_int,const_double,const,symbol_ref,label_ref,reg,mem")
7762 + (match_operand 0 "general_operand")))
7763 +
7764 +
7765 +(define_predicate "add_general_operand"
7766 + (and (match_code "const_int,const_double,const,symbol_ref,label_ref,reg,mem")
7767 + (match_operand 0 "general_operand")
7768 + (match_test "REGNO (op) != SOFT_AP_REGNUM")))
7769 +
7770 +
7771 +(define_predicate "shift_count_operand"
7772 + (and (match_code "const_int")
7773 + (and (match_operand 0 "const_int_operand")
7774 + (match_test "INTVAL (op) == 1 || INTVAL (op) == 8"))))
7775 +
7776 +
7777 +;; A predicate that matches any bitwise logical operator. This
7778 +;; allows for a single RTL pattern to be used for multiple operations.
7779 +(define_predicate "logical_bit_operator"
7780 + (ior (match_code "and") (match_code "ior") (match_code "xor")))
7781 +
7782 +
7783 +;; A predicate that matches any shift or rotate operator. This
7784 +;; allows for a single RTL pattern to be used for multiple operations.
7785 +(define_predicate "shift_rotate_operator"
7786 + (ior (match_code "ashift") (match_code "ashiftrt") (match_code "lshiftrt")
7787 + (match_code "rotate") (match_code "rotatert")))
7788 +
7789 +
7790 +(define_predicate "symbolic_operand" (match_code "symbol_ref"))
7791 +
7792 diff -urN gcc-4.6.4-clean/gcc/config/m6809/t-coco gcc-4.6.4/gcc/config/m6809/t-coco
7793 --- gcc-4.6.4-clean/gcc/config/m6809/t-coco 1969-12-31 17:00:00.000000000 -0700
7794 +++ gcc-4.6.4/gcc/config/m6809/t-coco 2015-07-20 19:44:52.770843181 -0600
7795 @@ -0,0 +1,6 @@
7796 +# For a few minor differences in code generation on the CoCo...
7797 +T_CFLAGS = -DTARGET_COCO
7798 +
7799 +# For doing the startup differently on the CoCo...
7800 +CRT0STUFF_T_CFLAGS += -Wa,--globalize-symbols -DTARGET_COCO
7801 +# vim: set filetype=make:
7802 diff -urN gcc-4.6.4-clean/gcc/config/m6809/t-m6809 gcc-4.6.4/gcc/config/m6809/t-m6809
7803 --- gcc-4.6.4-clean/gcc/config/m6809/t-m6809 1969-12-31 17:00:00.000000000 -0700
7804 +++ gcc-4.6.4/gcc/config/m6809/t-m6809 2015-07-20 19:44:52.770843181 -0600
7805 @@ -0,0 +1,64 @@
7806 +
7807 +# ranlib doesn't exist, so define it to 'true' to make it a no-op
7808 +RANLIB_FOR_TARGET = true
7809 +
7810 +# Stubs for libgcc defined by m6809 are here
7811 +LIB1ASMSRC = m6809/libgcc1.s
7812 +
7813 +# Here are the functions that are implemented within libgcc1.s
7814 +LIB1ASMFUNCS = _mulhi3 _divhi3 _modhi3 _udivhi3 _umodhi3 \
7815 + _euclid _seuclid _clzsi2 _clzdi2 _ctzsi2 _ctzdi2 _softregs \
7816 + _ashlhi3 _ashrhi3 _lshrhi3
7817 +
7818 +# Flags to use when building libgcc. IN_GCC does not seem necessary,
7819 +# although the compile breaks without it. -DDF=SF is required to set
7820 +# the size of "double" to the same as the size of a "float".
7821 +TARGET_LIBGCC2_CFLAGS =-DIN_GCC -Dinhibit_libc -DDF=SF -DLIBGCC2_HAS_SF_MODE=0 -DLIBGCC2_HAS_DF_MODE=0
7822 +
7823 +LIB2ADDEH =
7824 +LIB2ADDEHSTATIC =
7825 +LIB2ADDEHSHARED =
7826 +
7827 +LIBGCC2_DEBUG_CFLAGS =
7828 +LIBGCC2_CFLAGS = -Os $(LIBGCC2_INCLUDES) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) -DIN_LIBGCC2
7829 +
7830 +# Multilib information
7831 +# This creates multiple versions of libgcc.a for each set of incompatible
7832 +# -mxxx options.
7833 +MULTILIB_OPTIONS = fpic mdret
7834 +MULTILIB_DIRNAMES =
7835 +MULTILIB_MATCHES =
7836 +MULTILIB_EXCEPTIONS =
7837 +EXTRA_MULTILIB_PARTS = crt0.o
7838 +
7839 +LIBGCC = stmp-multilib
7840 +INSTALL_LIBGCC = install-multilib
7841 +
7842 +# We want fine grained libraries, so use the new code to build the
7843 +# floating point emulation libraries.
7844 +FPBIT = fp-bit.c
7845 +
7846 +fp-bit.c: $(srcdir)/config/fp-bit.c
7847 + echo '#define FLOAT' > fp-bit.c
7848 + echo '#define FLOAT_ONLY' >> fp-bit.c
7849 + echo '#define CMPtype HItype' >> fp-bit.c
7850 + echo '#define SMALL_MACHINE' >> fp-bit.c
7851 + echo '#ifdef __LITTLE_ENDIAN__' >> fp-bit.c
7852 + echo '#define FLOAT_BIT_ORDER_MISMATCH' >>fp-bit.c
7853 + echo '#endif' >> fp-bit.c
7854 + echo '#define DI SI' >> fp-bit.c
7855 + cat $(srcdir)/config/fp-bit.c >> fp-bit.c
7856 +
7857 +# crt0.o is built from the following source file
7858 +CRT0_S = $(srcdir)/config/m6809/crt0.S
7859 +MCRT0_S = $(srcdir)/config/m6809/crt0.S
7860 +
7861 +# Flags to use when building crt0.o
7862 +CRT0STUFF_T_CFLAGS += -fno-builtin -nostartfiles -nostdlib
7863 +
7864 +# Assemble startup files.
7865 +$(T)crt0.o: $(CRT0_S) $(GCC_PASSES)
7866 + $(GCC_FOR_TARGET) $(CRT0STUFF_T_CFLAGS) $(MULTILIB_CFLAGS) -c -o $(T)crt0.o -x assembler-with-cpp $(CRT0_S)
7867 +
7868 +$(T)mcrt0.o: $(MCRT0_S) $(GCC_PASSES)
7869 + $(GCC_FOR_TARGET) $(CRT0STUFF_T_CFLAGS) $(MULTILIB_CFLAGS) -c -o $(T)mcrt0.o -x assembler-with-cpp $(MCRT0_S)
7870 diff -urN gcc-4.6.4-clean/gcc/config/m6809/t-sim gcc-4.6.4/gcc/config/m6809/t-sim
7871 --- gcc-4.6.4-clean/gcc/config/m6809/t-sim 1969-12-31 17:00:00.000000000 -0700
7872 +++ gcc-4.6.4/gcc/config/m6809/t-sim 2015-07-20 19:44:52.770843181 -0600
7873 @@ -0,0 +1 @@
7874 +CRT0STUFF_T_CFLAGS += -DTARGET_SIM
7875 diff -urN gcc-4.6.4-clean/gcc/config.gcc gcc-4.6.4/gcc/config.gcc
7876 --- gcc-4.6.4-clean/gcc/config.gcc 2013-03-06 10:40:07.000000000 -0700
7877 +++ gcc-4.6.4/gcc/config.gcc 2015-07-20 19:44:52.770843181 -0600
7878 @@ -375,6 +375,9 @@
7879 cpu_type=m32r
7880 extra_options="${extra_options} g.opt"
7881 ;;
7882 +m6809-*-*)
7883 + cpu_type=m6809
7884 + ;;
7885 m68k-*-*)
7886 extra_headers=math-68881.h
7887 ;;
7888 @@ -1706,6 +1709,12 @@
7889 thread_file='posix'
7890 fi
7891 ;;
7892 +m6809-coco-*)
7893 + tmake_file="${tmake_file} m6809/t-m6809 m6809/t-coco"
7894 + ;;
7895 +m6809-*-*)
7896 + tmake_file="${tmake_file} m6809/t-m6809 m6809/t-sim"
7897 + ;;
7898 # m68hc11 and m68hc12 share the same machine description.
7899 m68hc11-*-*|m6811-*-*)
7900 tm_file="dbxelf.h elfos.h usegas.h newlib-stdint.h m68hc11/m68hc11.h"
7901 diff -urN gcc-4.6.4-clean/gcc/gcse.c gcc-4.6.4/gcc/gcse.c
7902 --- gcc-4.6.4-clean/gcc/gcse.c 2011-02-02 23:04:04.000000000 -0700
7903 +++ gcc-4.6.4/gcc/gcse.c 2015-07-20 19:44:52.770843181 -0600
7904 @@ -833,7 +833,6 @@
7905 max_distance = (GCSE_COST_DISTANCE_RATIO * cost) / 10;
7906 if (max_distance == 0)
7907 return 0;
7908 -
7909 gcc_assert (max_distance > 0);
7910 }
7911 else
7912 diff -urN gcc-4.6.4-clean/gcc/libgcc2.c gcc-4.6.4/gcc/libgcc2.c
7913 --- gcc-4.6.4-clean/gcc/libgcc2.c 2011-01-03 13:52:22.000000000 -0700
7914 +++ gcc-4.6.4/gcc/libgcc2.c 2015-07-20 19:44:52.770843181 -0600
7915 @@ -485,6 +485,7 @@
7916 #endif
7917
7918 #ifdef L_bswapsi2
7919 +#if MIN_UNITS_PER_WORD > 1
7920 SItype
7921 __bswapsi2 (SItype u)
7922 {
7923 @@ -494,7 +495,9 @@
7924 | (((u) & 0x000000ff) << 24));
7925 }
7926 #endif
7927 +#endif
7928 #ifdef L_bswapdi2
7929 +#if LONG_LONG_TYPE_SIZE > 32
7930 DItype
7931 __bswapdi2 (DItype u)
7932 {
7933 @@ -508,6 +511,7 @@
7934 | (((u) & 0x00000000000000ffull) << 56));
7935 }
7936 #endif
7937 +#endif
7938 #ifdef L_ffssi2
7939 #undef int
7940 int
7941 @@ -1280,7 +1284,7 @@
7942 UDWtype
7943 __fixunssfDI (SFtype a)
7944 {
7945 -#if LIBGCC2_HAS_DF_MODE
7946 +#if LIBGCC2_HAS_DF_MODE || (FLT_MANT_DIG >= W_TYPE_SIZE)
7947 /* Convert the SFtype to a DFtype, because that is surely not going
7948 to lose any bits. Some day someone else can write a faster version
7949 that avoids converting to DFtype, and verify it really works right. */
7950 @@ -1298,7 +1302,7 @@
7951
7952 /* Assemble result from the two parts. */
7953 return ((UDWtype) hi << W_TYPE_SIZE) | lo;
7954 -#elif FLT_MANT_DIG < W_TYPE_SIZE
7955 +#else
7956 if (a < 1)
7957 return 0;
7958 if (a < Wtype_MAXp1_F)
7959 @@ -1334,8 +1338,6 @@
7960 return (DWtype)counter << shift;
7961 }
7962 return -1;
7963 -#else
7964 -# error
7965 #endif
7966 }
7967 #endif
7968 diff -urN gcc-4.6.4-clean/gcc/longlong.h gcc-4.6.4/gcc/longlong.h
7969 --- gcc-4.6.4-clean/gcc/longlong.h 2011-10-04 01:28:50.000000000 -0600
7970 +++ gcc-4.6.4/gcc/longlong.h 2015-07-20 19:44:52.770843181 -0600
7971 @@ -528,6 +528,11 @@
7972 : "cbit")
7973 #endif /* __M32R__ */
7974
7975 +#if defined (__m6309__) || defined (__m6809__)
7976 +#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X))
7977 +#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctz (X))
7978 +#endif
7979 +
7980 #if defined (__mc68000__) && W_TYPE_SIZE == 32
7981 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
7982 __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \
7983 diff -urN gcc-4.6.4-clean/gcc/Makefile.in gcc-4.6.4/gcc/Makefile.in
7984 --- gcc-4.6.4-clean/gcc/Makefile.in 2013-04-01 02:32:34.000000000 -0600
7985 +++ gcc-4.6.4/gcc/Makefile.in 2015-07-20 19:44:52.770843181 -0600
7986 @@ -2003,14 +2003,14 @@
7987
7988 # Compile the start modules crt0.o and mcrt0.o that are linked with
7989 # every program
7990 -$(T)crt0.o: s-crt0 ; @true
7991 -$(T)mcrt0.o: s-crt0; @true
7992 +crt0.o: s-crt0 ; @true
7993 +mcrt0.o: s-crt0; @true
7994
7995 s-crt0: $(CRT0_S) $(MCRT0_S) $(GCC_PASSES) $(CONFIG_H)
7996 $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \
7997 - -o $(T)crt0.o -c $(CRT0_S)
7998 + -o crt0.o -c $(CRT0_S)
7999 $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \
8000 - -o $(T)mcrt0.o -c $(MCRT0_S)
8001 + -o mcrt0.o -c $(MCRT0_S)
8002 $(STAMP) s-crt0
8003 #
8004 # Compiling object files from source files.
8005 diff -urN gcc-4.6.4-clean/gcc/opth-gen.awk gcc-4.6.4/gcc/opth-gen.awk
8006 --- gcc-4.6.4-clean/gcc/opth-gen.awk 2011-02-08 10:41:00.000000000 -0700
8007 +++ gcc-4.6.4/gcc/opth-gen.awk 2015-07-20 19:44:52.774843181 -0600
8008 @@ -121,7 +121,7 @@
8009 END {
8010 print "/* This file is auto-generated by opth-gen.awk. */"
8011 print ""
8012 -print "#ifndef OPTIONS_H"
8013 +print "#if !defined(OPTIONS_H) && !defined(IN_LIBGCC2)"
8014 print "#define OPTIONS_H"
8015 print ""
8016 print "#include \"flag-types.h\""
8017 @@ -432,18 +432,9 @@
8018
8019 for (i = 0; i < n_opts; i++) {
8020 opt = opt_args("InverseMask", flags[i])
8021 - if (opt ~ ",") {
8022 - vname = var_name(flags[i])
8023 - macro = "OPTION_"
8024 - mask = "OPTION_MASK_"
8025 - if (vname == "") {
8026 - vname = "target_flags"
8027 - macro = "TARGET_"
8028 - mask = "MASK_"
8029 - }
8030 - print "#define " macro nth_arg(1, opt) \
8031 - " ((" vname " & " mask nth_arg(0, opt) ") == 0)"
8032 - }
8033 + if (opt ~ ",")
8034 + print "#define TARGET_" nth_arg(1, opt) \
8035 + " ((target_flags & MASK_" nth_arg(0, opt) ") == 0)"
8036 }
8037 print ""
8038
8039 diff -urN gcc-4.6.4-clean/gcc/tree.h gcc-4.6.4/gcc/tree.h
8040 --- gcc-4.6.4-clean/gcc/tree.h 2011-10-06 13:57:52.000000000 -0600
8041 +++ gcc-4.6.4/gcc/tree.h 2015-07-20 19:44:52.774843181 -0600
8042 @@ -3563,6 +3563,8 @@
8043 TI_UINTDI_TYPE,
8044 TI_UINTTI_TYPE,
8045
8046 + TI_UINT8_TYPE,
8047 + TI_UINT16_TYPE,
8048 TI_UINT32_TYPE,
8049 TI_UINT64_TYPE,
8050
8051 diff -urN gcc-4.6.4-clean/gcc/version.c gcc-4.6.4/gcc/version.c
8052 --- gcc-4.6.4-clean/gcc/version.c 2009-04-21 13:03:23.000000000 -0600
8053 +++ gcc-4.6.4/gcc/version.c 2015-07-20 19:44:52.774843181 -0600
8054 @@ -21,16 +21,16 @@
8055
8056 /* This is the location of the online document giving instructions for
8057 reporting bugs. If you distribute a modified version of GCC,
8058 - please configure with --with-bugurl pointing to a document giving
8059 - instructions for reporting bugs to you, not us. (You are of course
8060 - welcome to forward us bugs reported to you, if you determine that
8061 - they are not bugs in your modifications.) */
8062 + please change this to refer to a document giving instructions for
8063 + reporting bugs to you, not us. (You are of course welcome to
8064 + forward us bugs reported to you, if you determine that they are
8065 + not bugs in your modifications.) */
8066
8067 -const char bug_report_url[] = BUGURL;
8068 +const char bug_report_url[] = "<URL:http://lost.l-w.ca/coco/lwtools/>";
8069
8070 /* The complete version string, assembled from several pieces.
8071 BASEVER, DATESTAMP, DEVPHASE, and REVISION are defined by the
8072 Makefile. */
8073
8074 -const char version_string[] = BASEVER DATESTAMP DEVPHASE REVISION;
8075 +const char version_string[] = BASEVER DATESTAMP DEVPHASE REVISION " (gcc6809lw pl6)";
8076 const char pkgversion_string[] = PKGVERSION;
8077 diff -urN gcc-4.6.4-clean/libgcc/config.host gcc-4.6.4/libgcc/config.host
8078 --- gcc-4.6.4-clean/libgcc/config.host 2011-11-23 15:15:54.000000000 -0700
8079 +++ gcc-4.6.4/libgcc/config.host 2015-07-20 19:44:52.774843181 -0600
8080 @@ -371,6 +371,8 @@
8081 ;;
8082 m32rle-*-linux*)
8083 ;;
8084 +m6809*)
8085 + ;;
8086 m68hc11-*-*|m6811-*-*)
8087 ;;
8088 m68hc12-*-*|m6812-*-*)
8089 diff -urN gcc-4.6.4-clean/libgcc/fixed-obj.mk gcc-4.6.4/libgcc/fixed-obj.mk
8090 --- gcc-4.6.4-clean/libgcc/fixed-obj.mk 2007-09-17 16:18:13.000000000 -0600
8091 +++ gcc-4.6.4/libgcc/fixed-obj.mk 2015-07-20 19:44:52.774843181 -0600
8092 @@ -23,7 +23,7 @@
8093 #$(info $o$(objext): -DL$($o-label) $($o-opt))
8094
8095 $o$(objext): %$(objext): $(gcc_srcdir)/config/fixed-bit.c
8096 - $(gcc_compile) -DL$($*-label) $($*-opt) -c $(gcc_srcdir)/config/fixed-bit.c $(vis_hide)
8097 + $(gcc_compile) -DL$($*-label) $($*-opt) -c $(gcc_srcdir)/config/fixed-bit.c $(vis_hide) -save-temps
8098
8099 ifeq ($(enable_shared),yes)
8100 $(o)_s$(objext): %_s$(objext): $(gcc_srcdir)/config/fixed-bit.c
8101 diff -urN gcc-4.6.4-clean/libgcc/Makefile.in gcc-4.6.4/libgcc/Makefile.in
8102 --- gcc-4.6.4-clean/libgcc/Makefile.in 2012-12-04 12:11:33.000000000 -0700
8103 +++ gcc-4.6.4/libgcc/Makefile.in 2015-07-20 19:44:52.774843181 -0600
8104 @@ -374,8 +374,8 @@
8105 # Build lib2funcs. For the static library also include LIB2FUNCS_ST.
8106 lib2funcs-o = $(patsubst %,%$(objext),$(lib2funcs) $(LIB2FUNCS_ST))
8107 $(lib2funcs-o): %$(objext): $(gcc_srcdir)/libgcc2.c
8108 - $(gcc_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \
8109 - $(vis_hide)
8110 + ln -sf $(gcc_srcdir)/libgcc2.c $*.c && \
8111 + $(gcc_compile) -DL$* -c $*.c $(vis_hide) -save-temps
8112 libgcc-objects += $(lib2funcs-o)
8113
8114 ifeq ($(enable_shared),yes)
8115 @@ -410,8 +410,9 @@
8116 # Build LIB2_DIVMOD_FUNCS.
8117 lib2-divmod-o = $(patsubst %,%$(objext),$(LIB2_DIVMOD_FUNCS))
8118 $(lib2-divmod-o): %$(objext): $(gcc_srcdir)/libgcc2.c
8119 - $(gcc_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \
8120 - -fexceptions -fnon-call-exceptions $(vis_hide)
8121 + ln -sf $(gcc_srcdir)/libgcc2.c $*.c && \
8122 + $(gcc_compile) -DL$* -c $*.c \
8123 + -fexceptions -fnon-call-exceptions $(vis_hide) -save-temps
8124 libgcc-objects += $(lib2-divmod-o)
8125
8126 ifeq ($(enable_shared),yes)
8127 @@ -443,7 +444,8 @@
8128 ifneq ($(FPBIT),)
8129 fpbit-o = $(patsubst %,%$(objext),$(FPBIT_FUNCS))
8130 $(fpbit-o): %$(objext): $(FPBIT)
8131 - $(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(FPBIT) $(vis_hide)
8132 + ln -sf $(FPBIT) $*.c && \
8133 + $(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $*.c $(vis_hide) -save-temps
8134 libgcc-objects += $(fpbit-o)
8135
8136 ifeq ($(enable_shared),yes)
8137 @@ -458,7 +460,8 @@
8138 ifneq ($(DPBIT),)
8139 dpbit-o = $(patsubst %,%$(objext),$(DPBIT_FUNCS))
8140 $(dpbit-o): %$(objext): $(DPBIT)
8141 - $(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(DPBIT) $(vis_hide)
8142 + ln -sf $(DPBIT) $*.c && \
8143 + $(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $*.c $(vis_hide) -save-temps
8144 libgcc-objects += $(dpbit-o)
8145
8146 ifeq ($(enable_shared),yes)
8147 diff -urN gcc-4.6.4-clean/README.LW gcc-4.6.4/README.LW
8148 --- gcc-4.6.4-clean/README.LW 1969-12-31 17:00:00.000000000 -0700
8149 +++ gcc-4.6.4/README.LW 2015-07-20 19:44:52.774843181 -0600
8150 @@ -0,0 +1,14 @@
8151 +This is a port of gcc6809 which is designed to work with the lwtools
8152 +cross-assembler and linker package. You will need several scripts from that
8153 +package, available at http://lost.l-w.ca/coco/lwtools/, in order to use
8154 +this. Instructions for building are present in the lwtools package.
8155 +
8156 +This work is based extensively on the gcc6809 4.3.4-3 release by Brian
8157 +Dominy (brian@oddchange.com) with some significant renovations to make it
8158 +work with gcc 4.6.1.
8159 +
8160 +There is no guarantee that it will work for any particular purpose you
8161 +choose to put it to.
8162 +
8163 +If you run into any problems, contact William Astle (lost@l-w.ca). DO NOT
8164 +contact the main GCC developers!