comparison extra/gcc6809lw-4.6.4-3.patch @ 409:c8ae69cdb5a9

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