comparison extra/gcc6809lw-4.6.4-9.patch @ 447:639d19f5fb8e

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