comparison extra/gcc6809lw-4.6.4-2.patch @ 396:d0c0fede5021

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