]> oss.titaniummirror.com Git - msp430-gcc.git/commitdiff
Update patches and debian/changelog
authorR. Steve McKown <rsmckown@gmail.com>
Thu, 20 May 2010 22:26:12 +0000 (16:26 -0600)
committerR. Steve McKown <rsmckown@gmail.com>
Fri, 21 May 2010 00:02:10 +0000 (18:02 -0600)
debian/changelog
debian/patches/002-mspgcc-3.2.3-20080819.dpatch [deleted file]
debian/patches/003-mspgcc-3.2.3-20080819-FUNCTION.dpatch [deleted file]
debian/patches/00list
debian/patches/gcc-4.4.3.dpatch [new file with mode: 0755]
debian/patches/ports-gcc-4.x.dpatch [new file with mode: 0755]

index 3efb31894b385be40220fa96cc07b649ff1adda5..210d6fcdf53bf3a58bab235bd698a9b999c63185 100644 (file)
@@ -1,3 +1,9 @@
+msp430-gcc (4.4.3-1tm) hardy; urgency=low
+
+  * Update to gcc-4.4.3 from mspgcc4.sf.net
+
+ -- TMI Packages <pkgs@titaniummirror.com>  Thu, 20 May 2010 16:24:30 -0600
+
 msp430-gcc (3.2.3-1tmi) hardy; urgency=low
 
   * Sign the package, update the maintainer, minor doc changes.
diff --git a/debian/patches/002-mspgcc-3.2.3-20080819.dpatch b/debian/patches/002-mspgcc-3.2.3-20080819.dpatch
deleted file mode 100755 (executable)
index 3b50dc8..0000000
+++ /dev/null
@@ -1,19291 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 001-mspgcc-3.2.3-20080819.dpatch by <pkgs@titaniummirror.com>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Patch derived from mspgcc project gcc/3.3 directory, CVS 20080819
-
-@DPATCH@
-
-diff -urN -x CVS gcc-3.2.3.orig/configure.in gcc-3.2.3/configure.in
---- gcc-3.2.3.orig/configure.in        2002-07-08 04:00:57.000000000 -0600
-+++ gcc-3.2.3/configure.in     2008-08-22 09:17:00.000000000 -0600
-@@ -907,6 +907,9 @@
-          target_configdirs="${target_configdirs} target-bsp target-libstub target-cygmon"
-     fi
-     ;;
-+  msp430-*-*)
-+    noconfigdirs="$noconfigdirs target-libiberty ${libstdcxx_version} ${libgcj}"
-+    ;;
-   powerpc-*-aix*)
-     # copied from rs6000-*-* entry
-     # The configure and build of ld are currently disabled because
-diff -urN -x CVS gcc-3.2.3.orig/gcc/config/msp430/libgcc.c gcc-3.2.3/gcc/config/msp430/libgcc.c
---- gcc-3.2.3.orig/gcc/config/msp430/libgcc.c  1969-12-31 17:00:00.000000000 -0700
-+++ gcc-3.2.3/gcc/config/msp430/libgcc.c       2008-08-22 09:17:00.000000000 -0600
-@@ -0,0 +1,74 @@
-+
-+/*
-+      Stages of division:
-+      0. Clear carry flag, et all.
-+      1. Shift divident into divider. 
-+         Shift carry bit into divident.
-+      2. Check if the remainder >= divider
-+      3.      if yes, remainder -= divider
-+              this MUST set carry flag
-+      4.      if not, clear carry flag
-+      
-+      repeat from 1 sizeof(type) times
-+ */
-+
-+
-+typedef unsigned long __XX;
-+
-+__XX
-+__udivmodXI3 ( __XX a,  __XX b)
-+{
-+    __XX al = a;      // quotant
-+    __XX ah = 0;      // reminder
-+    __XX tmpf;
-+    int i;
-+
-+    for (i = sizeof(__XX)*8; i > 0; i--)
-+    {
-+        ah = (ah << 1) | (al >> (sizeof(__XX)*8-1) );
-+        tmpf = (ah >= b) ? 1 : 0;
-+        ah -= ((tmpf) ? b : 0);
-+        al = (al << 1) | tmpf;
-+    }
-+
-+    return al;    // for __udivXi3
-+    return ah;    // for __umodXi3
-+}
-+
-+/* Signed: */
-+
-+__XX
-+__divmodXI3 ( __XX a,  __XX b)
-+{
-+    unsigned at = abs(a);
-+    unsigned bt = abs(b);
-+    unsigned al, ah;
-+
-+    __udivmodXI3 (at, bt);
-+
-+    // now we get al, ah
-+
-+    if (a < 0)
-+        ah = -ah, al = -al;
-+
-+    if (b < 0)
-+        al = -al;
-+
-+    return al;
-+    return ah;
-+}
-+
-+#if 1
-+int main()
-+{
-+    __XX a,b, r;
-+
-+    a = 100;
-+    b = 0;
-+    r = __udivmodXI3(a,b);
-+    printf("R=%d\n",r);
-+
-+}
-+#endif
-+
-+
-diff -urN -x CVS gcc-3.2.3.orig/gcc/config/msp430/libgcc.S gcc-3.2.3/gcc/config/msp430/libgcc.S
---- gcc-3.2.3.orig/gcc/config/msp430/libgcc.S  1969-12-31 17:00:00.000000000 -0700
-+++ gcc-3.2.3/gcc/config/msp430/libgcc.S       2008-08-22 09:17:00.000000000 -0600
-@@ -0,0 +1,1326 @@
-+/*  -*- Mode: Asm -*-  */
-+
-+
-+      .section .text.libgcc, "ax", @progbits
-+
-+#if defined (L_cmpdi2)
-+      
-+      .global __cmpdi2
-+      .func   __cmpdi2
-+__cmpdi2:
-+      sub     2(r1), r12      ; a = a-b;
-+      subc    4(r1), r13
-+      subc    6(r1), r14
-+      subc    8(r1), r15
-+      
-+      tst     r15             ; c<0 ? return -1;
-+      jge     .L2
-+      
-+      mov     #-1, r15        ; yes, return -1
-+      ret
-+.L2:
-+      bis     r12, r14        ; check if zero
-+      bis     r13, r15
-+      bis     r14, r15
-+      tst     r15
-+      jeq     .L4             ; test result or or'ing all nibbles
-+      
-+      mov     #1, r15         ; no, positive, return 1
-+      ret
-+.L4:
-+      mov     #0, r15         ; return 0
-+      ret
-+.endfunc
-+#endif
-+
-+#if defined (L_cmpsf2)
-+      .global __cmpsf2
-+      .func   __cmpsf2
-+__cmpsf2:
-+/* prologue: frame size = 0; addenum 0; alloca:0, varargs:0 , fpr:0*/
-+.L__FrameSize___cmpsf2=0x0
-+.L__FrameOffset___cmpsf2=0x4
-+/* prologue end (size=2) */
-+        cmp     r12, r14      ;  11  cmpsi   [length = 3]
-+        jne     .L2
-+        cmp     r13, r15
-+        jne     .L2           ;  12  bne     [length = 1]
-+        mov     #llo(0), r15  ;  15  *movhi3/7       [length = 1]
-+      ret
-+.L2:
-+        tst     r15           ;  20  tstsi   [length = 1]
-+        jge     .L3           ;  21  bge     [length = 1]
-+        tst     r13           ;  22  tstsi   [length = 1]
-+        jge     .L3           ;  23  bge     [length = 1]
-+        xor     #lhi(-2147483648), r15                ;  27  *xorsi3_3       [length = 2]
-+        xor     #lhi(-2147483648), r13                ;  29  *xorsi3_3       [length = 2]
-+.L3:
-+        sub     r14, r12      ;  64  *subsi3_3       [length = 2]
-+        subc    r15, r13
-+        jge     .L4           ;  33  bge     [length = 1]
-+        mov     #llo(1), r15  ;  36  *movhi3/7       [length = 1]
-+      ret
-+.L4:
-+        mov     #llo(-1), r15 ;  43  *movhi3/7       [length = 1]
-+.L1:
-+/* epilogue: frame size=0 */
-+        ret
-+/* epilogue end (size=3) */
-+/* function __cmpsf2 size 25 (20) */
-+
-+.endfunc
-+
-+#endif
-+
-+
-+
-+/*******************************************************
-+               Multiplication  8 x 8
-+*******************************************************/
-+#if defined (L_mulqi3)
-+/* 
-+      a = reg:qi 10   clobber
-+      b = reg:qi 12   clobber
-+      res = reg:qi 14
-+*/
-+
-+      .global __mulqi3
-+      .func   __mulqi3
-+__mulqi3:
-+      clr     r14
-+.L__mulqiloop:
-+      tst.b   r10
-+      jz      .L__mulqiexit
-+      clrc
-+      rrc.b   r12
-+      jnc     +2
-+      add.b   r10, r14
-+      rla.b   r10
-+      tst.b   r12
-+      jne     .L__mulqiloop
-+.L__mulqiexit:
-+      ret
-+      .endfunc
-+#endif        /* defined (L_mulqi3) */
-+
-+
-+#if defined (L_mulqihi3)
-+      .global __mulqihi3
-+      .func   __mulqihi3
-+__mulqihi3:
-+      sxt     r10
-+      sxt     r12
-+      br      #__mulhi3
-+.endfunc
-+#endif /* defined (L_mulqihi3) */
-+
-+#if defined (L_umulqihi3)
-+      .global __umulqihi3
-+      .func   __umulqihi3
-+__umulqihi3:
-+      and.b   #-1, r10
-+      and.b   #-1, r12
-+      br      #__mulhi3
-+      .endfunc
-+#endif /* defined (L_umulqihi3) */
-+
-+/*******************************************************
-+               Multiplication  16 x 16
-+*******************************************************/
-+#if defined (L_mulhi3)
-+/* 
-+      a = reg:hi 10   clobber
-+      b = reg:hi 12   clobber
-+      res = reg:hi 14
-+*/
-+
-+      .global __mulhi3
-+      .func   __mulhi3
-+__mulhi3:
-+      clr     r14
-+.L__mulhiloop:
-+      tst     r10
-+      jz      .L__mulhiexit
-+      clrc
-+      rrc     r12
-+      jnc     +2
-+      add     r10, r14
-+      rla     r10
-+      tst     r12
-+      jne     .L__mulhiloop
-+.L__mulhiexit:
-+      ret
-+      .endfunc
-+#endif /* defined (L_mulhi3) */
-+
-+#if defined (L_mulhisi3)
-+/* clobber r11, r13 */
-+      .global __mulhisi3
-+      .func   __mulhisi3
-+__mulhisi3:
-+      br      #__mulsi3
-+      .endfunc
-+#endif /* defined (L_mulhisi3) */
-+
-+#if defined (L_umulhisi3)
-+      .global __umulhisi3
-+      .func   __umulhisi3
-+__umulhisi3:
-+      br      #__mulsi3
-+      .endfunc
-+#endif /* defined (L_umulhisi3) */
-+
-+#if defined (L_mulsi3)
-+/*******************************************************
-+               Multiplication  32 x 32
-+*******************************************************/
-+/*
-+res = a*b
-+      a - reg:SI 10 clobber
-+      b - reg:SI 12 clobber
-+      res - reg: SI 14
-+*/
-+      .global __mulsi3
-+      .func   __mulsi3
-+
-+__mulsi3:
-+      clr     r14
-+      clr     r15
-+      jmp     .L__mulsi3st
-+.L__mulsi3loop:
-+      clrc
-+      rrc     r13             ;       b >>= 1
-+      rrc     r12
-+      jnc     +4              ;       
-+      add     r10, r14        ;       res = res + a
-+      addc    r11, r15
-+      rla     r10
-+      rlc     r11             ;       a <<= 1
-+.L__mulsi3st:
-+      tst     r12             ; if b ne 0 goto L__mulsi3loop
-+      jne     .L__mulsi3loop
-+      tst     r13
-+      jne     .L__mulsi3loop
-+      ret
-+      .endfunc
-+
-+#endif
-+
-+#if defined (L_mulsi3hw)
-+      
-+__MPY=0x130
-+__MPYS=0x132
-+__MAC=0x134
-+__MACS=0x136
-+__OP2=0x138
-+__RESLO=0x13a
-+__RESHI=0x13c
-+__SUMEXT=0x13e
-+
-+      .global __umulsi3hw
-+      .func   __umulsi3hw
-+__umulsi3hw:
-+      mov     r12, &__MPY
-+      mov     r10, &__OP2
-+      mov     r12, &__MAC
-+      mov     &__RESLO, r14
-+      mov     &__RESHI, &__RESLO
-+      mov     r11, &__OP2
-+      mov     r13, &__MAC
-+      mov     r10, &__OP2
-+      mov     &__RESLO, r15
-+      ret
-+.endfunc
-+
-+#endif
-+
-+      
-+/*******************************************************
-+       Division 8 / 8 => (result + remainder)
-+*******************************************************/
-+
-+#define r_rem   r14   /* remainder */
-+#define r_arg1  r12   /* dividend, quotient */
-+#define r_arg2  r10   /* divisor */
-+#define r_cnt   r11   /* loop count */
-+#define r_tmp r13     /* save carry flag */
-+
-+
-+#if defined (L_udivmodqi4)
-+      .global __udivmodqi4
-+      .func   __udivmodqi4
-+__udivmodqi4:
-+      xor.b   r_rem, r_rem            ; clear reminder and carry
-+      mov.b   #9, r_cnt
-+      jmp     .L__udivmodqi4_ep
-+.L__udivmodqi4_loop:  
-+      rrc     r_tmp                   ; restore carry bit
-+      rlc.b   r_rem
-+      cmp.b   r_arg2, r_rem
-+      jlo     .L__udivmodqi4_ep
-+      sub.b   r_arg2, r_rem           ; FIXME: will this clobber carry ?
-+.L__udivmodqi4_ep:
-+      rlc.b   r_arg1                  ; shift divident
-+      rlc     r_tmp                   ; save carry bit
-+      dec.b   r_cnt                   ; this clobbers C bit.
-+      jnz     .L__udivmodqi4_loop
-+      ret
-+      .endfunc
-+#endif /* defined (L_udivmodqi4) */
-+
-+
-+#if defined (L_divmodqi4)
-+      .global __divmodqi4
-+      .func   __divmodqi4
-+__divmodqi4:
-+      clr     r_tmp
-+      bit     #0x80, r_arg1           ; save divident sign
-+      jnc     .L__divmodqi4arg1pos
-+      inv.b   r_arg1                  ; negate
-+      inc.b   r_arg1
-+      bis     #4, r_tmp
-+
-+.L__divmodqi4arg1pos:
-+      bit     #0x80, r_arg2           ; check divisor sign
-+      jnc     .L__divmodqi4arg2pos
-+      inv.b   r_arg2                  ; negate
-+      inc.b   r_arg2
-+      bis     #8, r_tmp
-+
-+.L__divmodqi4arg2pos:
-+      
-+      call    #__udivmodqi4           ; do unsigned division
-+      rrc     r_tmp                   ; restore carry and sign bits
-+
-+      bit     #4, r_tmp               ; is divident < 0 ?
-+      jnc     .L__divmodqi4rem        ; no. skip
-+      inv.b   r_rem                   ; negate remainder
-+      inc.b   r_rem
-+
-+;;    bit     #8, r_tmp
-+;;    jc      .L__divmodqi4end
-+      inv.b   r_arg1                  ; negate quotient
-+      inc.b   r_arg1
-+
-+.L__divmodqi4rem:
-+      bit     #8, r_tmp
-+      jnc     .L__divmodqi4end
-+      inv.b   r_arg1
-+      inc.b   r_arg1
-+
-+.L__divmodqi4end:
-+      ret
-+
-+      .endfunc
-+#endif /* defined (L_divmodqi4) */
-+
-+#undef r_rem
-+#undef r_arg1
-+#undef r_arg2
-+#undef r_cnt 
-+#undef r_tmp
-+
-+
-+/*******************************************************
-+       Division 16 / 16 => (result + remainder)
-+*******************************************************/
-+
-+#define r_rem   r14   /* remainder */
-+#define r_arg1  r12   /* dividend, quotient */
-+#define r_arg2  r10   /* divisor */
-+#define r_cnt   r11   /* loop count */
-+#define r_tmp r13
-+
-+
-+#if defined (L_udivmodhi4)
-+      .global __udivmodhi4
-+      .func   __udivmodhi4
-+__udivmodhi4:
-+      xor     r_rem, r_rem            ; clear reminder and carry
-+      mov     #17, r_cnt
-+      jmp     .L__udivmodhi4_ep
-+.L__udivmodhi4_loop:  
-+      rrc     r_tmp                   ; restore carry bit
-+      rlc     r_rem
-+      cmp     r_arg2, r_rem
-+      jlo     .L__udivmodhi4_ep
-+      sub     r_arg2, r_rem
-+.L__udivmodhi4_ep:
-+      rlc     r_arg1
-+      rlc     r_tmp                   ; save carry bit
-+      dec     r_cnt                   ; this clobbers C bit.
-+      jnz     .L__udivmodhi4_loop
-+      ret
-+      .endfunc
-+#endif /* defined (L_udivmodhi4) */
-+
-+
-+#if defined (L_divmodhi4)
-+#define r_rem   r14     /* remainder */
-+#define r_arg1  r12     /* dividend, quotient */
-+#define r_arg2  r10     /* divisor */   
-+#define r_cnt   r11     /* loop count */
-+#define r_tmp   r13
-+
-+
-+      .global __divmodhi4
-+      .func   __divmodhi4
-+__divmodhi4:
-+      clr     r_tmp                   ; clear reg is cheaper than clr 2 bits.
-+      bit     #0x8000, r_arg1         ; save divident sign
-+      jnc     .L__divmodhi4arg1pos
-+      inv     r_arg1                  ; negate
-+      inc     r_arg1
-+      bis     #4, r_tmp
-+
-+.L__divmodhi4arg1pos:
-+      bit     #0x8000, r_arg2         ; check divisor sign
-+      jnc     .L__divmodhi4arg2pos
-+      inv     r_arg2                  ; negate
-+      inc     r_arg2
-+      bis     #8, r_tmp
-+
-+.L__divmodhi4arg2pos: 
-+      call    #__udivmodhi4           ; do unsigned division
-+      rrc     r_tmp                   ; restore carry and sign bits
-+
-+      bit     #4, r_tmp               ; is divident < 0 ?
-+      jnc     .L__divmodhi4rem        ; no. skip
-+      inv     r_rem                   ; negate remainder
-+      inc     r_rem
-+
-+;;    bit     #8, r_tmp
-+;;    jc      .L__divmodhi4end
-+      inv     r_arg1                  ; negate quotient
-+      inc     r_arg1
-+
-+.L__divmodhi4rem:
-+      bit     #8, r_tmp
-+      jnc     .L__divmodhi4end
-+      inv     r_arg1
-+      inc     r_arg1
-+
-+.L__divmodhi4end:
-+      ret
-+      .endfunc
-+#endif /* defined (L_divmodhi4) */
-+
-+#undef r_rem
-+#undef r_arg1
-+#undef r_arg2
-+#undef r_cnt 
-+#undef r_tmp
-+
-+/*******************************************************
-+       Division 32 / 32 => (result + remainder)
-+*******************************************************/
-+
-+#if defined (L_udivmodsi4)
-+
-+#define r_remh  r15  
-+#define r_reml  r14   /* remainder */
-+#define r_arg1h r13
-+#define r_arg1l r12   /* dividend, quotient */
-+#define r_arg2h r11   
-+#define r_arg2l r10   /* divisor */
-+#define r_cnt   r9    /* loop count */
-+#define r_tmp   r8
-+
-+      .global __udivmodsi4
-+      .func   __udivmodsi4
-+__udivmodsi4:
-+      xor     r_remh, r_remh          ; clear reminder and carry
-+      xor     r_reml, r_reml
-+      mov     #33, r_cnt
-+      jmp     .L__udivmodsi4_ep
-+.L__udivmodsi4_loop:  
-+      rrc     r_tmp                   ; restore carry bit
-+      rlc     r_reml
-+      rlc     r_remh
-+
-+      cmp     r_arg2h, r_remh         ; is reminder < divisor ?
-+      jlo     .L__udivmodsi4_ep       ; yes, skip correction
-+      jne     +4
-+                                      ; they equal. check LSBytes
-+      cmp     r_arg2l, r_reml
-+      jlo     .L__udivmodsi4_ep       ; is reminder still < divisor ?
-+
-+      sub     r_arg2l, r_reml         ; adjust reminder
-+      subc    r_arg2h, r_remh
-+
-+.L__udivmodsi4_ep:
-+      rlc     r_arg1l
-+      rlc     r_arg1h
-+      rlc     r_tmp
-+      dec     r_cnt                   ; this clobbers C bit.
-+      jnz     .L__udivmodsi4_loop
-+      ret
-+      .endfunc
-+
-+#undef r_remh
-+#undef r_reml  
-+#undef r_arg1h
-+#undef r_arg1l
-+#undef r_arg2h
-+#undef r_arg2l
-+
-+#undef r_cnt
-+#undef r_tmp
-+
-+#endif /* defined (L_udivmodsi4) */
-+
-+
-+#if defined (L_divmodsi4)
-+#define r_remh  r15  
-+#define r_reml  r14     /* remainder */
-+#define r_arg1h r13
-+#define r_arg1l r12     /* dividend, quotient */
-+#define r_arg2h r11   
-+#define r_arg2l r10     /* divisor */   
-+#define r_cnt   r9      /* loop count */
-+#define r_tmp   r8
-+
-+      .global __divmodsi4
-+      .func   __divmodsi4
-+__divmodsi4:
-+      clr     r_tmp                   ; clear reg is cheaper than clr 2 bits.
-+      bit     #0x8000, r_arg1h                ; save divident sign
-+      jz      .L__divmodsi4arg1pos
-+      inv     r_arg1h                 ; negate
-+      inv     r_arg1l
-+      inc     r_arg1l
-+      adc     r_arg1h
-+      bis     #4, r_tmp
-+
-+.L__divmodsi4arg1pos:
-+      bit     #0x8000, r_arg2h                ; check divisor sign
-+      jz      .L__divmodsi4arg2pos
-+      inv     r_arg2h                 ; negate
-+      inv     r_arg2l
-+      inc     r_arg2l
-+      adc     r_arg2h
-+      bis     #8, r_tmp               ; save divisor sign
-+
-+.L__divmodsi4arg2pos:
-+      
-+      call    #__udivmodsi4           ; do unsigned division
-+      rrc     r_tmp                   ; restore carry and sign bits
-+
-+      bit     #4, r_tmp               ; is divident < 0 ?
-+      jz      .L__divmodsi4rem        ; no. skip
-+      inv     r_reml                  ; negate remainder
-+      inv     r_remh
-+      inc     r_reml
-+      adc     r_remh
-+
-+;;    bit     #8, r_tmp
-+;;    jc      .L__divmodsi4end
-+      inv     r_arg1l                 ; negate quotient
-+      inv     r_arg1h
-+      inc     r_arg1l
-+      adc     r_arg1h
-+
-+.L__divmodsi4rem:
-+      bit     #8, r_tmp
-+      jz      .L__divmodsi4end
-+      inv     r_arg1l
-+      inv     r_arg1h
-+      inc     r_arg1l
-+      adc     r_arg1h
-+
-+.L__divmodsi4end:
-+      ret
-+      .endfunc
-+
-+#undef r_remh  
-+#undef r_reml  
-+#undef r_arg1h 
-+#undef r_arg1l
-+#undef r_arg2h
-+#undef r_arg2l
-+
-+#undef r_cnt
-+#undef r_tmp
-+
-+#endif /* defined (L_divmodsi4) */
-+
-+
-+/******* CRT support functions *********/
-+
-+#if defined(L_reset_vector__)
-+/*****************************************************************
-+ * Program starts here.
-+ *   overwriting this label in the user program
-+ *   causes removing all strtup code except __do_global_ctors
-+ *****************************************************************/
-+      .section .init0, "ax", @progbits
-+
-+      .global _reset_vector__
-+      .weak   _reset_vector__
-+
-+      .func   _reset_vector__
-+
-+_reset_vector__:
-+
-+    /* link following functions if library _reset_vector__ used */
-+
-+;    actualy stack initialized in main() prologue, so don't link __init_stack
-+;     .global __init_stack
-+
-+      .global __low_level_init
-+      .global __do_copy_data
-+      .global __do_clear_bss
-+      .global __jump_to_main
-+
-+      .endfunc
-+#endif  /* defined(L_reset_vector__) */
-+    
-+#if defined(L__init_stack)
-+/*****************************************************************
-+ * Set stack pointer
-+ * can be overwriten
-+ *****************************************************************/
-+      .section .init2, "ax", @progbits
-+
-+      .global __init_stack
-+      .weak   __init_stack
-+
-+      .func   __init_stack
-+
-+set_stack_pointer:
-+      mov     #__stack, r1
-+
-+      .endfunc
-+#endif
-+
-+#if defined(L__low_level_init)
-+/*****************************************************************
-+ * Initialize peripherial, particularly disable watchdog
-+ * can be overwriten
-+ *****************************************************************/
-+      .section .init3, "ax", @progbits
-+
-+      .global __low_level_init
-+      .weak   __low_level_init
-+
-+      .func   __low_level_init
-+
-+__low_level_init:
-+      mov     #0x5a80, &0x120
-+
-+      .endfunc
-+#endif
-+
-+#if defined(L_copy_data)
-+/*****************************************************************
-+ * Initialize data: copy data 
-+ * from __data_load_start ( = _etext) to __data_start
-+ * can be overwriten
-+ *****************************************************************/
-+      .section .init4, "ax", @progbits
-+
-+      .global __do_copy_data
-+      .weak   __do_copy_data
-+
-+      .func   __do_copy_data
-+
-+__do_copy_data:
-+      mov     #__data_size, r15
-+      tst     r15
-+      jz      .L__copy_data_end
-+.L__copy_data_loop:
-+      decd    r15
-+      mov.w   __data_load_start(r15), __data_start(r15)    ; data section is word-aligned, so word transfer is acceptable
-+      jne     .L__copy_data_loop
-+.L__copy_data_end:
-+
-+      .endfunc
-+#endif /* defined(L_copy_data) */
-+    
-+#if defined(L_clear_bss)
-+/*****************************************************************
-+ * Initialize data: clear .bss
-+ * can be overwriten
-+ *****************************************************************/
-+      .section .init4, "ax", @progbits
-+
-+      .global __do_clear_bss
-+      .weak   __do_clear_bss
-+
-+      .func   __do_clear_bss
-+
-+__do_clear_bss:
-+      mov     #__bss_size, r15
-+      tst     r15
-+      jz      .L__clear_bss_end
-+.L__clear_bss_loop:
-+      dec     r15
-+      clr.b   __bss_start(r15)
-+      jne     .L__clear_bss_loop
-+.L__clear_bss_end:
-+
-+      .endfunc
-+#endif  /* defined(L_clear_bss) */
-+
-+#if defined(L_ctors)
-+/*****************************************************************
-+ * Call C++ global and static objects constructors
-+ * can be overwriten
-+ *****************************************************************/
-+      .section .init6, "ax", @progbits
-+      .global __do_global_ctors
-+      .weak   __do_global_ctors
-+    
-+      .func   __do_global_ctors
-+      .global __init_stack    ; stack has to be set before constructors calling
-+
-+
-+__do_global_ctors:
-+      mov     #__ctors_start, r11
-+      mov     #__ctors_end,   r10
-+.L__ctors_loop:
-+      call    @r11+   ; call constructor
-+      cmp     r10, r11
-+      jne     .L__ctors_loop
-+
-+      .endfunc
-+#endif
-+    
-+#if defined(L__jump_to_main)
-+/*****************************************************************
-+ * jump to main.
-+ * can be overwriten
-+ *****************************************************************/
-+      .section .init9, "ax", @progbits
-+
-+      .global __jump_to_main
-+      .weak   __jump_to_main
-+
-+      .func   __jump_to_main
-+
-+__jump_to_main:
-+      br      #main
-+      .endfunc
-+#endif
-+
-+#if defined(L__stop_progExec__)
-+/*****************************************************************
-+ * return from main.
-+ * can be overwriten
-+ *****************************************************************/
-+      .section .fini9, "ax", @progbits
-+      .global __stop_progExec__
-+      .weak   __stop_progExec__
-+
-+      .func  __stop_progExec__
-+
-+__stop_progExec__:
-+
-+      .endfunc
-+#endif
-+
-+#if defined(L_dtors)
-+/*****************************************************************
-+ * Call C++ global and static objects destructors
-+ * can be overwriten
-+ *****************************************************************/
-+      .section .fini6,"ax",@progbits
-+      .global __do_global_dtors
-+      .weak   __do_global_dtors
-+    
-+      .func   _dtors
-+
-+__do_global_dtors:
-+      mov     #__dtors_start, r11
-+      mov     #__dtors_end, r10
-+.L__dtors_loop:
-+      call    @r11+
-+      cmp     r10, r11
-+      jne     .L__dtors_loop
-+
-+      .endfunc
-+#endif
-+
-+#if defined(L__stop_progExec__)
-+/*****************************************************************
-+ * endless loop
-+ * can be overwriten
-+ *****************************************************************/
-+      .section .fini0, "ax", @progbits
-+
-+      .func   _endless_loop__
-+1:
-+      jmp  1b
-+
-+      .endfunc
-+#endif
-+
-+/********* PROLOGE / EPILOGUE aux routines ******************/
-+#if defined (L__prologue_saver)
-+      .global __prologue_saver
-+      .func   __prologue_saver
-+__prologue_saver:
-+      mov     r4, 0(r1)
-+      mov     r5, 2(r1)
-+      mov     r6, 4(r1)
-+      mov     r7, 6(r1)
-+      mov     r8, 8(r1)
-+      mov     r9, 10(r1)
-+      mov     r10, 12(r1)
-+      mov     r11, 14(r1)
-+      br      r12     ; now jump to the function body
-+.endfunc
-+
-+#endif
-+
-+
-+#if defined (L__epilogue_restorer)
-+      .global __epilogue_restorer
-+      .func   __epilogue_restorer
-+__epilogue_restorer:
-+      pop     r4
-+      pop     r5
-+      pop     r6
-+      pop     r7
-+      pop     r8
-+      pop     r9
-+      pop     r10
-+      pop     r11
-+      ret
-+.endfunc
-+
-+#endif
-+
-+
-+#if defined (L__epilogue_restorer_intr)
-+      .global __epilogue_restorer_intr
-+      .func   __epilogue_restorer_intr
-+__epilogue_restorer_intr:
-+      pop     r4
-+      pop     r5
-+      pop     r6
-+      pop     r7
-+      pop     r8
-+      pop     r9
-+      pop     r10
-+      pop     r11
-+      pop     r12
-+      pop     r13
-+      pop     r14
-+      pop     r15
-+      reti
-+.endfunc
-+
-+#endif
-+
-+/******************************************
-+ * quot/rem = 64/64
-+ ******************************************/
-+
-+#if defined (L_udivmoddi3_parts) || defined (L_udivdi3) || defined (L_umoddi3) || defined (L_divdi3) || defined (L_moddi3)
-+
-+#define r_remhh  r11          /* remainder */
-+#define r_remhl  r10
-+#define r_remlh        r9
-+#define r_remll        r8
-+
-+#define r_arg1hh r15  /* dividend, quotient */
-+#define r_arg1hl r14
-+#define r_arg1lh r13
-+#define r_arg1ll r12
-+
-+#define r_arg2hh r7   /* divisor */
-+#define r_arg2hl r6
-+#define r_arg2lh r5
-+#define r_arg2ll r4
-+
-+#define r_cnt   2(r1) /* loop count */
-+#define r_tmp   0(r1) /* we'll save carry and signs here */
-+
-+#endif
-+
-+
-+#if defined (L_udivmoddi3_parts)
-+
-+      .global __udivmoddi3_parts
-+      .func   __udivmoddi3_parts
-+__udivmoddi3_parts:
-+      xor     r_remhh, r_remhh        ; clear reminder and carry
-+      xor     r_remhl, r_remhl 
-+      xor     r_remlh, r_remlh
-+      xor     r_remll, r_remll
-+      
-+      mov     #65, 2+r_cnt
-+      jmp     .L__udivmoddi3_ep
-+
-+.L__udivmoddi3_loop:  
-+      rrc     2+r_tmp                 ; restore carry bit
-+      
-+      rlc     r_remll                 ; shift carry in.
-+      rlc     r_remlh
-+      rlc     r_remhl
-+      rlc     r_remhh
-+      
-+      cmp     r_arg2hh, r_remhh       ; is reminder < divisor ?
-+      jlo     .L__udivmoddi3_ep       ; yes, skip correction
-+      jne     .L_udmdcrt
-+                                      ; they equal. check LSBytes
-+      cmp     r_arg2hl, r_remhl
-+      jlo     .L__udivmoddi3_ep       ; is reminder still < divisor ?
-+      jne     .L_udmdcrt
-+
-+      cmp     r_arg2lh, r_remlh
-+      jlo     .L__udivmoddi3_ep
-+      jne     .L_udmdcrt
-+
-+      cmp     r_arg2ll, r_remll
-+      jlo     .L__udivmoddi3_ep
-+      jne     .L_udmdcrt
-+
-+.L_udmdcrt:
-+      sub     r_arg2ll, r_remll       ; adjust reminder
-+      subc    r_arg2lh, r_remlh
-+      subc    r_arg2hl, r_remhl
-+      subc    r_arg2hh, r_remhh
-+      
-+.L__udivmoddi3_ep:
-+      rlc     r_arg1ll                ; shift carry into arg1
-+      rlc     r_arg1lh
-+      rlc     r_arg1hl
-+      rlc     r_arg1hh
-+      
-+      rlc     2+r_tmp                 ; save carry
-+      dec     2+r_cnt                 ; this clobbers C bit.
-+      jnz     .L__udivmoddi3_loop
-+      
-+      ret
-+      .endfunc
-+
-+#endif /* defined (L_udivmoddi3_parts) */
-+
-+
-+#if defined (L_udivdi3)
-+
-+;;  First arg will be in r15:r12 
-+;;  next on stack
-+;;    return in r15:r12
-+;; rearrange them as:
-+;;    r15:r12         ->      r_arg1hh:r_arg1ll
-+;;    stack+8:stack+2 ->      r_arg2hh:r_arg2ll
-+
-+      .global __udivdi3
-+      .func   __udivdi3
-+__udivdi3:
-+      push    r4
-+      push    r5
-+      push    r6
-+      push    r7
-+      push    r8
-+      push    r9
-+      push    r10
-+      push    r11
-+      
-+      mov     18+0(r1), r_arg2ll      ; 18 is a stack offset
-+      mov     18+2(r1), r_arg2lh      ; so move arg 2 in.
-+      mov     18+4(r1), r_arg2hl
-+      mov     18+6(r1), r_arg2hh
-+      
-+      sub     #4, r1
-+      call    #__udivmoddi3_parts
-+      add     #4, r1
-+      
-+      pop     r11
-+      pop     r10
-+      pop     r9
-+      pop     r8
-+      pop     r7
-+      pop     r6
-+      pop     r5
-+      pop     r4
-+      ret
-+      .endfunc
-+#endif
-+
-+
-+#if defined (L_umoddi3)
-+      .global __umoddi3
-+      .func   __umoddi3
-+__umoddi3:
-+      push    r4
-+      push    r5
-+      push    r6
-+      push    r7
-+      push    r8
-+      push    r9
-+      push    r10
-+      push    r11
-+      
-+      mov     18+0(r1), r_arg2ll      
-+      mov     18+2(r1), r_arg2lh
-+      mov     18+4(r1), r_arg2hl
-+      mov     18+6(r1), r_arg2hh
-+
-+      sub     #4, r1
-+      call    #__udivmoddi3_parts
-+      add     #4, r1
-+      
-+      mov     r_remhh, r15    ; move reminder to (reg:DI 12)
-+      mov     r_remhl, r14
-+      mov     r_remlh, r13
-+      mov     r_remll, r12
-+      
-+      pop     r11
-+      pop     r10
-+      pop     r9
-+      pop     r8
-+      pop     r7
-+      pop     r6
-+      pop     r5
-+      pop     r4
-+      ret
-+      .endfunc
-+#endif
-+
-+
-+#if defined (L_divdi3)
-+      .global __divdi3
-+      .func   __divdi3
-+__divdi3:
-+      push    r4
-+      push    r5
-+      push    r6
-+      push    r7
-+      push    r8
-+      push    r9
-+      push    r10
-+      push    r11
-+      
-+      mov     18+0(r1), r_arg2ll      
-+      mov     18+2(r1), r_arg2lh
-+      mov     18+4(r1), r_arg2hl
-+      mov     18+6(r1), r_arg2hh
-+      
-+      sub     #4, r1
-+      
-+      clr     r_tmp
-+      bit     #0x8000, r_arg1hh
-+      jnc     .L__divdi3rempos
-+      inv     r_arg1hh
-+      inv     r_arg1hl
-+      inv     r_arg1lh
-+      inv     r_arg1ll
-+      inc     r_arg1ll
-+      adc     r_arg1lh
-+      adc     r_arg1hl
-+      adc     r_arg1hh
-+      bis     #4, r_tmp
-+      
-+.L__divdi3rempos:
-+      bit     #0x8000, r_arg2hh
-+      jnc     .L__divdi3arg2pos       
-+      inv     r_arg2hh
-+      inv     r_arg2hl
-+      inv     r_arg2lh
-+      inv     r_arg2ll
-+      inc     r_arg2ll
-+      adc     r_arg2lh
-+      adc     r_arg2hl
-+      adc     r_arg2hh
-+      xor     #4, r_tmp       ; this is a trick - invert bit 4 =>
-+                              ; do not perform double negation.
-+.L__divdi3arg2pos:
-+      call    #__udivmoddi3_parts
-+      
-+      rrc     r_tmp   ; restore sign bits
-+
-+      bit     #4, r_tmp
-+      jz      .L__divdi3end
-+      inv     r_arg1hh
-+      inv     r_arg1hl
-+      inv     r_arg1lh
-+      inv     r_arg1ll
-+      inc     r_arg1ll
-+      adc     r_arg1lh
-+      adc     r_arg1hl
-+      adc     r_arg1hh
-+      
-+.L__divdi3end:
-+      add     #4, r1
-+      pop     r11
-+      pop     r10
-+      pop     r9
-+      pop     r8
-+      pop     r7
-+      pop     r6
-+      pop     r5
-+      pop     r4
-+      ret
-+      .endfunc
-+#endif
-+
-+
-+#if defined (L_moddi3)
-+      .global __moddi3
-+      .func   __moddi3
-+__moddi3:
-+      push    r4
-+      push    r5
-+      push    r6
-+      push    r7
-+      push    r8
-+      push    r9
-+      push    r10
-+      push    r11
-+      
-+      mov     18+0(r1), r_arg2ll      
-+      mov     18+2(r1), r_arg2lh
-+      mov     18+4(r1), r_arg2hl
-+      mov     18+6(r1), r_arg2hh
-+      
-+      sub     #4, r1
-+      
-+      clr     r_tmp
-+      bit     #0x8000, r_arg1hh
-+      jnc     .L__moddi3rempos
-+      inv     r_arg1hh
-+      inv     r_arg1hl
-+      inv     r_arg1lh
-+      inv     r_arg1ll
-+      inc     r_arg1ll
-+      adc     r_arg1lh
-+      adc     r_arg1hl
-+      adc     r_arg1hh
-+      bis     #4, r_tmp
-+      
-+.L__moddi3rempos:
-+      bit     #0x8000, r_arg2hh
-+      jnc     .L__moddi3arg2pos       
-+      inv     r_arg2hh
-+      inv     r_arg2hl
-+      inv     r_arg2lh
-+      inv     r_arg2ll
-+      inc     r_arg2ll
-+      adc     r_arg2lh
-+      adc     r_arg2hl
-+      adc     r_arg2hh
-+
-+.L__moddi3arg2pos:
-+      call    #__udivmoddi3_parts
-+      
-+      rrc     r_tmp
-+
-+      bit     #4, r_tmp
-+      jz      .L__moddi3rem
-+      
-+      inv     r_remhh
-+      inv     r_remhl
-+      inv     r_remlh
-+      inv     r_remll
-+      inc     r_remll
-+      adc     r_remlh
-+      adc     r_remhl
-+      adc     r_remhh
-+
-+.L__moddi3rem:
-+      mov     r_remhh, r15
-+      mov     r_remhl, r14
-+      mov     r_remlh, r13
-+      mov     r_remll, r12
-+
-+      add     #4, r1
-+      pop     r11
-+      pop     r10
-+      pop     r9
-+      pop     r8
-+      pop     r7
-+      pop     r6
-+      pop     r5
-+      pop     r4
-+      ret
-+      .endfunc
-+#endif
-+
-+
-+/**************************************************************
-+ * Multiplication 64 = 64 x 64
-+ **************************************************************/
-+#if defined(L_muldi3) && !defined(MSP430_HAS_HWMUL)
-+
-+#define r_reshh  r11          /* res = arg1 * arg2 */
-+#define r_reshl  r10
-+#define r_reslh        r9
-+#define r_resll        r8
-+
-+#define r_arg1hh r15  /* arg1 */
-+#define r_arg1hl r14
-+#define r_arg1lh r13
-+#define r_arg1ll r12
-+
-+#define r_arg2hh r7   /* arg2 */
-+#define r_arg2hl r6
-+#define r_arg2lh r5
-+#define r_arg2ll r4
-+
-+      .global __muldi3
-+      .func   __muldi3
-+__muldi3:
-+      push    r4
-+      push    r5
-+      push    r6
-+      push    r7
-+      push    r8
-+      push    r9
-+      push    r10
-+      push    r11
-+      
-+      mov     18+0(r1), r_arg2ll      ; 18 is a stack offset
-+      mov     18+2(r1), r_arg2lh      ; so move arg 2 in.
-+      mov     18+4(r1), r_arg2hl
-+      mov     18+6(r1), r_arg2hh
-+
-+      clr     r_reshh
-+      clr     r_reshl
-+      clr     r_reslh
-+      clr     r_resll
-+      
-+.L_muldi3_loop:
-+      clrc
-+      rrc     r_arg2hh                ; arg2 >>= 1 (shift LSB into carry)
-+      rrc     r_arg2hl
-+      rrc     r_arg2lh
-+      rrc     r_arg2ll
-+      
-+      jnc     +8                      ; check if bit is set
-+                                      ; yes, it is.
-+      add     r_arg1ll, r_resll       ; res += arg1
-+      addc    r_arg1lh, r_reslh
-+      addc    r_arg1hl, r_reshl
-+      addc    r_arg1hh, r_reshh
-+      
-+      rla     r_arg1ll                ; arg1 <<= 1
-+      rlc     r_arg1lh
-+      rlc     r_arg1hl
-+      rlc     r_arg1hh
-+      
-+      tst     r_arg2ll                ; arg2 !=0 ?  loop again , exit otherwise.
-+      jne     .L_muldi3_loop
-+      tst     r_arg2lh
-+      jne     .L_muldi3_loop
-+      tst     r_arg2hl
-+      jne     .L_muldi3_loop
-+      tst     r_arg2hh
-+      jne     .L_muldi3_loop
-+
-+      ; move result to proper location
-+      mov     r_resll, r12
-+      mov     r_reslh, r13
-+      mov     r_reshl, r14
-+      mov     r_reshh, r15
-+
-+      pop     r11
-+      pop     r10
-+      pop     r9
-+      pop     r8
-+      pop     r7
-+      pop     r6
-+      pop     r5
-+      pop     r4
-+      ret
-+      .endfunc
-+#endif
-+
-+#if defined(L_muldi3) && defined(MSP430_HAS_HWMUL)
-+
-+__MPY=0x130
-+__MPYS=0x132
-+__MAC=0x134
-+__MACS=0x136
-+__OP2=0x138
-+__RESLO=0x13a
-+__RESHI=0x13c
-+__SUMEXT=0x13e
-+
-+#define r_reshh  r11    /* res = arg1 * arg2 */
-+#define r_reshl  r10
-+#define r_reslh  r9
-+#define r_resll  r8
-+
-+#define r_arg1hh r15    /* arg1 */
-+#define r_arg1hl r14
-+#define r_arg1lh r13
-+#define r_arg1ll r12
-+
-+#define r_arg2hh r7     /* arg2 */
-+#define r_arg2hl r6
-+#define r_arg2lh r5
-+#define r_arg2ll r4
-+
-+          .global __muldi3
-+          .func   __muldi3
-+__muldi3:
-+
-+        push    r4
-+        push    r5
-+        push    r6
-+        push    r7
-+        push    r8
-+        push    r9
-+        push    r10
-+        push    r11
-+
-+        mov     18+0(r1), r_arg2ll      ; 18 is a stack offset
-+        mov     18+2(r1), r_arg2lh      ; so move arg 2 in.
-+        mov     18+4(r1), r_arg2hl
-+        mov     18+6(r1), r_arg2hh
-+
-+;;      r15:r14:r13:r12 * r7:r6:r5:r4 -> r11:r10:r9:r8
-+;; actual code follows....
-+
-+        mov     r_arg1ll,&__MPY
-+        mov     r_arg2ll,&__OP2           ;;                      LL1xLL2
-+        mov     &__RESLO,r_resll
-+        mov     &__RESHI,&__RESLO
-+        mov     &__SUMEXT,&__RESHI
-+
-+        mov     r_arg1ll,&__MAC
-+        mov     r_arg2lh,&__OP2           ;;                  LL1xLH2
-+        mov     r_arg1lh,&__MAC
-+        mov     r_arg2ll,&__OP2           ;;                  LH1xLL2
-+        mov     &__RESLO,r_reslh
-+        mov     &__RESHI,&__RESLO
-+        mov     &__SUMEXT,&__RESHI
-+
-+        mov     r_arg2lh,&__OP2           ;;              LH1xLH2
-+        mov     r_arg1ll,&__MAC
-+        mov     r_arg2hl,&__OP2           ;;              LL1xHL2
-+        mov     r_arg1hl,&__MAC
-+        mov     r_arg2ll,&__OP2           ;;              HL1xLL2
-+        mov     &__RESLO,r_reshl
-+        mov     &__RESHI,&__RESLO
-+
-+        mov     r_arg2lh,&__OP2           ;;          HL1xLH2
-+        mov     r_arg1ll,&__MAC
-+        mov     r_arg2hh,&__OP2           ;;          LL1xHH2
-+        mov     r_arg1lh,&__MAC
-+        mov     r_arg2hl,&__OP2           ;;          LH1xHL2
-+        mov     r_arg1hh,&__MAC
-+        mov     r_arg2ll,&__OP2           ;;          HH1xLL2
-+        mov     &__RESLO,r_reshh
-+
-+;; reload result
-+        mov     r_resll, r12
-+        mov     r_reslh, r13
-+        mov     r_reshl, r14
-+        mov     r_reshh, r15
-+
-+        pop     r11
-+        pop     r10
-+        pop     r9
-+        pop     r8
-+        pop     r7
-+        pop     r6
-+        pop     r5
-+        pop     r4
-+        ret
-+.endfunc
-+#endif
-diff -urN -x CVS gcc-3.2.3.orig/gcc/config/msp430/msp430.c gcc-3.2.3/gcc/config/msp430/msp430.c
---- gcc-3.2.3.orig/gcc/config/msp430/msp430.c  1969-12-31 17:00:00.000000000 -0700
-+++ gcc-3.2.3/gcc/config/msp430/msp430.c       2008-08-22 09:17:00.000000000 -0600
-@@ -0,0 +1,9851 @@
-+/* Subroutines for insn-output.c for Texas Instruments MSP430 MCU
-+ Copyright (C) 2001, 2002 Free Software Foundation, Inc.
-+ Contributed by Dmitry Diky <diwil@mail.ru>
-+ 
-+ This file is part of GNU CC. 
-+ GNU CC is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2, or (at your option)
-+ any later version.
-+ 
-+ GNU CC is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ GNU General Public License for more details.
-+ 
-+ You should have received a copy of the GNU General Public License
-+ along with GNU CC; see the file COPYING.  If not, write to
-+ the Free Software Foundation, 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA.  */
-+
-+#include "config.h"
-+#include "system.h"
-+#include "rtl.h"
-+#include "regs.h"
-+#include "hard-reg-set.h"
-+#include "real.h"
-+#include "insn-config.h"
-+#include "conditions.h"
-+#include "output.h"
-+#include "insn-attr.h"
-+#include "flags.h"
-+#include "reload.h"
-+#include "tree.h"
-+#include "expr.h"
-+#include "toplev.h"
-+#include "obstack.h"
-+#include "function.h"
-+#include "recog.h"
-+#include "tm_p.h"
-+#include "target.h"
-+#include "target-def.h"
-+
-+
-+/* This holds the last insn address.  */
-+static int last_insn_address = 0;
-+
-+/* Commands count in the compiled file */
-+static int commands_in_file;
-+
-+/* Commands in the functions prologues in the compiled file */
-+static int commands_in_prologues;
-+
-+/* Commands in the functions epilogues in the compiled file */
-+static int commands_in_epilogues;
-+
-+/* Prologue/Epilogue size in words */
-+static int prologue_size;
-+static int epilogue_size;
-+
-+/* Size of all jump tables in the current function, in words.  */
-+static int jump_tables_size;
-+
-+/* the size of the stack space freed during mdr pass */
-+
-+/* actual frame offset */
-+static int msp430_current_frame_offset = 0;
-+
-+/* ret/reti issue indicator for _current_ function */
-+static int return_issued = 0;
-+
-+/* registers used for incoming funct arguments */
-+static char arg_register_used[16];
-+
-+/* push helper */
-+int self_push PARAMS ((rtx));
-+
-+
-+/* aux functions */
-+static int msp430_cc_source PARAMS ((rtx, enum rtx_code, rtx, rtx));
-+static int msp430_func_num_saved_regs PARAMS ((void));
-+static int noint_hwmul_function_p PARAMS ((tree func));
-+static int interrupt_function_p PARAMS ((tree func));
-+static int msp430_naked_function_p PARAMS ((tree func));
-+static int msp430_task_function_p PARAMS ((tree func));
-+static int signal_function_p PARAMS ((tree func));
-+static int wakeup_function_p PARAMS ((tree func));
-+static int msp430_num_arg_regs PARAMS ((enum machine_mode mode, tree type));
-+static int msp430_critical_function_p PARAMS ((tree func));
-+static int msp430_reentrant_function_p PARAMS ((tree func));
-+static int msp430_save_prologue_function_p PARAMS ((tree func));
-+
-+const char * msp430_emit_bltnoovfl PARAMS ((rtx *, int));
-+          
-+
-+
-+const char *msp430_init_stack = "__stack";
-+const char *msp430_endup = "__stop_progExec__";
-+
-+int msp430_case_values_threshold = 30000;
-+int msp430_has_hwmul = 0;
-+
-+struct rtx_def *msp430_compare_op0;
-+struct rtx_def *msp430_compare_op1;
-+
-+
-+const char *msp430_mcu_name = "msp430x110";
-+
-+enum msp430_arch
-+{
-+  MSP430_ISA_1 = 1,
-+  MSP430_ISA_2 = 2,
-+  MSP430_ISA_110 = 110,
-+  MSP430_ISA_11 = 11,
-+  MSP430_ISA_12 = 12,
-+  MSP430_ISA_13 = 13,
-+  MSP430_ISA_14 = 14,
-+  MSP430_ISA_15 = 15,
-+  MSP430_ISA_16 = 16,
-+  MSP430_ISA_20 = 20,
-+  MSP430_ISA_21 = 21,
-+  MSP430_ISA_22 = 22,
-+  MSP430_ISA_23 = 23,
-+  MSP430_ISA_24 = 24,
-+  MSP430_ISA_241 = 241,
-+  MSP430_ISA_26 = 26,
-+  MSP430_ISA_31 = 31,
-+  MSP430_ISA_32 = 32,
-+  MSP430_ISA_33 = 33,
-+  MSP430_ISA_41 = 41,
-+  MSP430_ISA_42 = 42,
-+  MSP430_ISA_43 = 43,
-+  MSP430_ISA_44 = 44,
-+  MSP430_ISA_46 = 46
-+};
-+
-+struct mcu_type_s
-+{
-+  const char *name;
-+  enum msp430_arch arch;
-+  int has_hwmul;
-+};
-+
-+static struct mcu_type_s msp430_mcu_types[] = {
-+  /* generic types */
-+  {"msp1",         MSP430_ISA_1, 0},
-+  {"msp2",         MSP430_ISA_2, 1},
-+
-+  /* F1xx family */
-+  {"msp430x110",   MSP430_ISA_11, 0},
-+  {"msp430x112",   MSP430_ISA_11, 0},
-+
-+  {"msp430x1101",  MSP430_ISA_110, 0},
-+  {"msp430x1111",  MSP430_ISA_110, 0},
-+  {"msp430x1121",  MSP430_ISA_110, 0},
-+  {"msp430x1122",  MSP430_ISA_110, 0},
-+  {"msp430x1132",  MSP430_ISA_110, 0},
-+
-+  {"msp430x122",   MSP430_ISA_12, 0},
-+  {"msp430x123",   MSP430_ISA_12, 0},
-+  {"msp430x1222",  MSP430_ISA_12, 0},
-+  {"msp430x1232",  MSP430_ISA_12, 0},
-+
-+  {"msp430x133",   MSP430_ISA_13, 0},
-+  {"msp430x135",   MSP430_ISA_13, 0},
-+  {"msp430x1331",  MSP430_ISA_13, 0},
-+  {"msp430x1351",  MSP430_ISA_13, 0},
-+
-+  {"msp430x147",   MSP430_ISA_14, 1},
-+  {"msp430x148",   MSP430_ISA_14, 1},
-+  {"msp430x149",   MSP430_ISA_14, 1},
-+  {"msp430x1471",  MSP430_ISA_14, 1},
-+  {"msp430x1481",  MSP430_ISA_14, 1},
-+  {"msp430x1491",  MSP430_ISA_14, 1},
-+
-+  {"msp430x155",   MSP430_ISA_15, 0},
-+  {"msp430x156",   MSP430_ISA_15, 0},
-+  {"msp430x157",   MSP430_ISA_15, 0},
-+
-+  {"msp430x167",   MSP430_ISA_16, 1},
-+  {"msp430x168",   MSP430_ISA_16, 1},
-+  {"msp430x169",   MSP430_ISA_16, 1},
-+  {"msp430x1610",  MSP430_ISA_16, 1},
-+  {"msp430x1611",  MSP430_ISA_16, 1},
-+  {"msp430x1612",  MSP430_ISA_16, 1},
-+
-+  /* F2xx family */
-+  {"msp430x2001",  MSP430_ISA_20, 0},
-+  {"msp430x2011",  MSP430_ISA_20, 0},
-+
-+  {"msp430x2002",  MSP430_ISA_20, 0},
-+  {"msp430x2012",  MSP430_ISA_20, 0},
-+
-+  {"msp430x2003",  MSP430_ISA_20, 0},
-+  {"msp430x2013",  MSP430_ISA_20, 0},
-+  
-+  {"msp430x2101",  MSP430_ISA_21, 0},
-+  {"msp430x2111",  MSP430_ISA_21, 0},
-+  {"msp430x2121",  MSP430_ISA_21, 0},
-+  {"msp430x2131",  MSP430_ISA_21, 0},
-+
-+  {"msp430x2112",  MSP430_ISA_22, 0},
-+  {"msp430x2122",  MSP430_ISA_22, 0},
-+  {"msp430x2132",  MSP430_ISA_22, 0},
-+
-+  {"msp430x2232",  MSP430_ISA_22, 0},
-+  {"msp430x2252",  MSP430_ISA_22, 0},
-+  {"msp430x2272",  MSP430_ISA_22, 0},
-+
-+  {"msp430x2234",  MSP430_ISA_22, 0},
-+  {"msp430x2254",  MSP430_ISA_22, 0},
-+  {"msp430x2274",  MSP430_ISA_22, 0},
-+
-+  {"msp430x233",   MSP430_ISA_23, 1},
-+  {"msp430x235",   MSP430_ISA_23, 1},
-+
-+  {"msp430x2330",  MSP430_ISA_23, 1},
-+  {"msp430x2350",  MSP430_ISA_23, 1},
-+  {"msp430x2370",  MSP430_ISA_23, 1},
-+
-+  {"msp430x247",   MSP430_ISA_24, 1},
-+  {"msp430x248",   MSP430_ISA_24, 1},
-+  {"msp430x249",   MSP430_ISA_24, 1},
-+  {"msp430x2410",  MSP430_ISA_24, 1},
-+  {"msp430x2471",  MSP430_ISA_24, 1},
-+  {"msp430x2481",  MSP430_ISA_24, 1},
-+  {"msp430x2491",  MSP430_ISA_24, 1},
-+
-+  {"msp430x2416",  MSP430_ISA_241, 1},
-+  {"msp430x2417",  MSP430_ISA_241, 1},
-+  {"msp430x2418",  MSP430_ISA_241, 1},
-+  {"msp430x2419",  MSP430_ISA_241, 1},
-+
-+  {"msp430x2616",  MSP430_ISA_26, 1},
-+  {"msp430x2617",  MSP430_ISA_26, 1},
-+  {"msp430x2618",  MSP430_ISA_26, 1},
-+  {"msp430x2619",  MSP430_ISA_26, 1},
-+
-+  /* 3xx family (ROM) */
-+  {"msp430x311",   MSP430_ISA_31, 0},
-+  {"msp430x312",   MSP430_ISA_31, 0},
-+  {"msp430x313",   MSP430_ISA_31, 0},
-+  {"msp430x314",   MSP430_ISA_31, 0},
-+  {"msp430x315",   MSP430_ISA_31, 0},
-+
-+  {"msp430x323",   MSP430_ISA_32, 0},
-+  {"msp430x325",   MSP430_ISA_32, 0},
-+
-+  {"msp430x336",   MSP430_ISA_33, 1},
-+  {"msp430x337",   MSP430_ISA_33, 1},
-+
-+  /* F4xx family */
-+  {"msp430x412",   MSP430_ISA_41, 0},
-+  {"msp430x413",   MSP430_ISA_41, 0},
-+  {"msp430x415",   MSP430_ISA_41, 0},
-+  {"msp430x417",   MSP430_ISA_41, 0},
-+
-+  {"msp430x423",   MSP430_ISA_42, 1},
-+  {"msp430x425",   MSP430_ISA_42, 1},
-+  {"msp430x427",   MSP430_ISA_42, 1},
-+
-+  {"msp430x4250",  MSP430_ISA_42, 0},
-+  {"msp430x4260",  MSP430_ISA_42, 0},
-+  {"msp430x4270",  MSP430_ISA_42, 0},
-+
-+  {"msp430xE423",  MSP430_ISA_42, 1},
-+  {"msp430xE425",  MSP430_ISA_42, 1},
-+  {"msp430xE427",  MSP430_ISA_42, 1},
-+
-+  {"msp430xW423",  MSP430_ISA_42, 0},
-+  {"msp430xW425",  MSP430_ISA_42, 0},
-+  {"msp430xW427",  MSP430_ISA_42, 0},
-+
-+  {"msp430xG437",  MSP430_ISA_43, 0},
-+  {"msp430xG438",  MSP430_ISA_43, 0},
-+  {"msp430xG439",  MSP430_ISA_43, 0},
-+
-+  {"msp430x435",   MSP430_ISA_43, 0},
-+  {"msp430x436",   MSP430_ISA_43, 0},
-+  {"msp430x437",   MSP430_ISA_43, 0},
-+
-+  {"msp430x447",   MSP430_ISA_44, 1},
-+  {"msp430x448",   MSP430_ISA_44, 1},
-+  {"msp430x449",   MSP430_ISA_44, 1},
-+
-+  {"msp430xG4616", MSP430_ISA_46, 1},
-+  {"msp430xG4617", MSP430_ISA_46, 1},
-+  {"msp430xG4618", MSP430_ISA_46, 1},
-+  {"msp430xG4619", MSP430_ISA_46, 1},
-+
-+  {NULL, 0, 0}
-+};
-+
-+
-+
-+const struct attribute_spec msp430_attribute_table[];
-+static tree msp430_handle_fndecl_attribute
-+PARAMS ((tree *, tree, tree, int, bool *));
-+
-+#undef TARGET_ASM_FUNCTION_PROLOGUE
-+#define TARGET_ASM_FUNCTION_PROLOGUE function_prologue
-+#undef TARGET_ASM_FUNCTION_EPILOGUE
-+#define TARGET_ASM_FUNCTION_EPILOGUE function_epilogue
-+#undef TARGET_ATTRIBUTE_TABLE
-+#define TARGET_ATTRIBUTE_TABLE msp430_attribute_table
-+#undef TARGET_SECTION_TYPE_FLAGS
-+#define TARGET_SECTION_TYPE_FLAGS msp430_section_type_flags
-+
-+
-+
-+struct gcc_target targetm = TARGET_INITIALIZER;
-+
-+/****** ATTRIBUTES TO FUNCTION *************************************/
-+const struct attribute_spec msp430_attribute_table[] = {
-+  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
-+  {"reserve", 1, 1, false, false, false, msp430_handle_fndecl_attribute},
-+  {"signal", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
-+  {"interrupt", 1, 1, true, false, false, msp430_handle_fndecl_attribute},
-+  {"naked", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
-+  {"task", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
-+  {"wakeup", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
-+  {"critical", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
-+  {"reentrant", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
-+  {"saveprologue", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
-+  {"noint_hwmul", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
-+  {NULL, 0, 0, false, false, false, NULL}
-+};
-+
-+unsigned int
-+msp430_section_type_flags (decl, name, reloc)
-+     tree decl;
-+     const char *name;
-+     int reloc;
-+{
-+  unsigned int flags = 0;
-+
-+  if (!strcmp (name, ".infomemnobits") || !strcmp (name, ".noinit"))
-+    flags = SECTION_BSS;
-+
-+  flags |= default_section_type_flags (decl, name, reloc);
-+  return flags;
-+}
-+
-+/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
-+   struct attribute_spec.handler.  */
-+static tree
-+msp430_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
-+     tree *node;
-+     tree name;
-+     tree args ATTRIBUTE_UNUSED;
-+     int flags ATTRIBUTE_UNUSED;
-+     bool *no_add_attrs;
-+{
-+  if (TREE_CODE (*node) != FUNCTION_DECL)
-+    {
-+      warning ("%s' attribute only applies to functions.",
-+             IDENTIFIER_POINTER (name));
-+      *no_add_attrs = true;
-+    }
-+  return NULL_TREE;
-+}
-+
-+
-+static int
-+msp430_naked_function_p (func)
-+     tree func;
-+{
-+  tree a;
-+  if (TREE_CODE (func) != FUNCTION_DECL)
-+    abort ();
-+  a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
-+  return a != NULL_TREE;
-+}
-+
-+static int
-+msp430_task_function_p (func)
-+     tree func;
-+{
-+  tree a;
-+  if (TREE_CODE (func) != FUNCTION_DECL)
-+    abort ();
-+  a = lookup_attribute ("task", DECL_ATTRIBUTES (func));
-+  return a != NULL_TREE;
-+}
-+static int
-+msp430_save_prologue_function_p (func)
-+     tree func;
-+{
-+  tree a;
-+  if (TREE_CODE (func) != FUNCTION_DECL)
-+    abort ();
-+  a = lookup_attribute ("saveprologue", DECL_ATTRIBUTES (func));
-+  return a != NULL_TREE;
-+}
-+
-+static int
-+interrupt_function_p (func)
-+     tree func;
-+{
-+  tree a;
-+  if (TREE_CODE (func) != FUNCTION_DECL)
-+    abort ();
-+  a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
-+  return a != NULL_TREE;
-+}
-+
-+static int
-+msp430_critical_function_p (func)
-+     tree func;
-+{
-+  tree a;
-+  if (TREE_CODE (func) != FUNCTION_DECL)
-+    abort ();
-+  a = lookup_attribute ("critical", DECL_ATTRIBUTES (func));
-+  return a != NULL_TREE;
-+
-+}
-+
-+static int
-+msp430_reentrant_function_p (func)
-+     tree func;
-+{
-+  tree a;
-+  if (TREE_CODE (func) != FUNCTION_DECL)
-+    abort ();
-+  a = lookup_attribute ("reentrant", DECL_ATTRIBUTES (func));
-+  return a != NULL_TREE;
-+
-+}
-+
-+static int
-+noint_hwmul_function_p (func)
-+     tree func;
-+{
-+  tree a;
-+  if (TREE_CODE (func) != FUNCTION_DECL)
-+    abort ();
-+  a = lookup_attribute ("noint_hwmul", DECL_ATTRIBUTES (func));
-+  return a != NULL_TREE;
-+}
-+
-+int
-+msp430_current_function_noint_hwmul_function_p (void)
-+{
-+  int rval;
-+  if (!current_function_decl)
-+    return (TARGET_NOINT_HWMUL);
-+  rval = noint_hwmul_function_p (current_function_decl);
-+
-+  return (TARGET_NOINT_HWMUL || rval);
-+}
-+
-+static int
-+signal_function_p (func)
-+     tree func;
-+{
-+  tree a;
-+  if (TREE_CODE (func) != FUNCTION_DECL)
-+    abort ();
-+  a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
-+  return a != NULL_TREE;
-+}
-+
-+
-+static int
-+wakeup_function_p (func)
-+     tree func;
-+{
-+  tree a;
-+  if (TREE_CODE (func) != FUNCTION_DECL)
-+    abort ();
-+  a = lookup_attribute ("wakeup", DECL_ATTRIBUTES (func));
-+  return a != NULL_TREE;
-+}
-+
-+enum msp430_arch
-+msp430_get_arch ()
-+{
-+  const struct mcu_type_s *t;
-+
-+  for (t = msp430_mcu_types; t->name; t++)
-+    {
-+      if (strcmp (t->name, msp430_mcu_name) == 0)
-+      break;
-+    }
-+
-+  if (!t->name)
-+    {
-+      error ("MCU %s not supported", msp430_mcu_name);
-+      fprintf (stderr, "Known MCU names:\n");
-+      for (t = msp430_mcu_types; t->name; t++)
-+      fprintf (stderr, "   %s\n", t->name);
-+      abort ();
-+      return -1;
-+    }
-+  return t->arch;
-+}
-+
-+int
-+msp430_is_xarch ()
-+{
-+      switch (msp430_get_arch())
-+      {
-+              case MSP430_ISA_241:
-+              case MSP430_ISA_26:
-+              case MSP430_ISA_46:
-+                      return TRUE;
-+      }
-+    return FALSE;
-+}
-+
-+void
-+msp430_override_options ()
-+{
-+  const struct mcu_type_s *t;
-+
-+  for (t = msp430_mcu_types; t->name; t++)
-+    {
-+      if (strcmp (t->name, msp430_mcu_name) == 0)
-+      break;
-+    }
-+
-+  if (!t->name)
-+    {
-+      error ("MCU %s not supported", msp430_mcu_name);
-+      fprintf (stderr, "Known MCU names:\n");
-+      for (t = msp430_mcu_types; t->name; t++)
-+      fprintf (stderr, "   %s\n", t->name);
-+      abort ();
-+      return;
-+    }
-+
-+  msp430_has_hwmul = t->has_hwmul || TARGET_HWMUL;
-+
-+  if (TARGET_NO_HWMUL)
-+    msp430_has_hwmul = 0;
-+
-+  msp430_case_values_threshold = 8;   /* ? or there is a better value ? */
-+}
-+
-+rtx mpy_rtx, mpys_rtx, mac_rtx, macs_rtx, op2_rtx, reslo_rtx, reshi_rtx,
-+    sumext_rtx, ressi_rtx;
-+
-+
-+static char __dummy[1024];
-+
-+rtx
-+sym_ref(mode, arg)
-+enum machine_mode mode;
-+const char *arg;
-+{
-+  rtx rt;
-+  static int i = 0;
-+  rt = (rtx) &__dummy[i];
-+  i += sizeof(*rt);
-+  memset(rt,0,4);
-+  PUT_CODE(rt,SYMBOL_REF);
-+  PUT_MODE(rt,mode);
-+  XSTR(rt,0) = arg;
-+
-+  return rt;
-+}
-+
-+
-+void
-+msp430_init_once ()
-+{
-+/******************************
-+
-+  __MPY=0x130
-+  __MPYS=0x132
-+  __MAC=0x134
-+  __MACS=0x136
-+  __OP2=0x138
-+  __RESLO=0x13a
-+  __RESHI=0x13c
-+  __SUMEXT=0x13e
-+  __RESSI     <- not natural 
-+ *****************************/
-+
-+  mpy_rtx = gen_rtx_MEM (HImode, sym_ref (HImode, "__MPY"));
-+  mpys_rtx = gen_rtx_MEM (HImode, sym_ref (HImode, "__MPYS"));
-+  mac_rtx = gen_rtx_MEM (HImode, sym_ref (HImode, "__MAC"));
-+  macs_rtx = gen_rtx_MEM (HImode, sym_ref (HImode, "__MACS"));
-+  op2_rtx = gen_rtx_MEM (HImode, sym_ref (HImode, "__OP2"));
-+  reslo_rtx = gen_rtx_MEM (HImode, sym_ref (HImode, "__RESLO"));
-+  reshi_rtx = gen_rtx_MEM (HImode, sym_ref (HImode, "__RESHI"));
-+  sumext_rtx = gen_rtx_MEM (HImode, sym_ref (HImode, "__SUMEXT"));
-+  ressi_rtx = gen_rtx_MEM (SImode, sym_ref (SImode, "__RESLO"));
-+  return;
-+}
-+
-+static int reg_class_tab[16] = {
-+  PC_REG, STACK_REGS, CG_REGS, CG_REGS,
-+  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
-+  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
-+  GENERAL_REGS, GENERAL_REGS  /* r0 - r15 */
-+};
-+
-+
-+int
-+msp430_regno_ok_for_base_p (r)
-+     int r;
-+{
-+
-+  if (r == 2)
-+    return 0;
-+  if (r == 3)
-+    return 0;
-+  if (r < FIRST_PSEUDO_REGISTER && r > 0)
-+    return 1;
-+  if (reg_renumber
-+      && reg_renumber[r] < FIRST_PSEUDO_REGISTER
-+      && reg_renumber[r] > 0 && reg_renumber[r] != 2 && reg_renumber[r] != 3)
-+    return 1;
-+
-+  return 0;
-+
-+}
-+
-+enum reg_class
-+msp430_regno_reg_class (r)
-+     int r;
-+{
-+  if (r < FIRST_PSEUDO_REGISTER)
-+    return reg_class_tab[r];
-+
-+  return NO_REGS;
-+}
-+
-+
-+enum reg_class
-+msp430_reg_class_from_letter (c)
-+     int c;
-+{
-+  switch (c)
-+    {
-+    case 'd':
-+      return SP_REG;
-+    default:
-+      break;
-+    }
-+
-+  return NO_REGS;
-+}
-+
-+
-+
-+#define NOVECTOR      0xff
-+
-+void
-+asm_declare_function_name (file, name, decl)
-+     FILE *file;
-+     char *name;
-+     tree decl ATTRIBUTE_UNUSED;
-+{
-+  int interrupt_func_p;
-+  tree ss = 0;
-+  int vector = -1;
-+  int vectors_start;
-+  int cfp = msp430_critical_function_p (current_function_decl);
-+  int ree = msp430_reentrant_function_p (current_function_decl);
-+
-+  interrupt_func_p = interrupt_function_p (current_function_decl);
-+
-+  if (interrupt_func_p)
-+    {
-+      /*
-+       * .global This_func1
-+       * .set vector11, This_func1
-+       * .type   This_func1,@function
-+       *
-+       */
-+      if (msp430_is_xarch())
-+        {
-+          vectors_start = 0xffc0;
-+        }
-+      else
-+        {
-+          vectors_start = 0xffe0;
-+        }
-+    
-+      ss = lookup_attribute ("interrupt",
-+                           DECL_ATTRIBUTES (current_function_decl));
-+      ss = TREE_VALUE (ss);
-+      if (ss)
-+      {
-+        ss = TREE_VALUE (ss);
-+        if (ss)
-+          vector = TREE_INT_CST_LOW (ss);
-+
-+        if (vector != NOVECTOR)
-+          vector += vectors_start;
-+      }
-+
-+      if (vector == -1)
-+      {
-+        warning ("No valid interrupt vector assigned to ISR `%s'.", name);
-+      }
-+
-+      if ((vector < vectors_start || vector > 0xfffe || (vector & 1))
-+        && (vector != NOVECTOR && vector != -1))
-+      {
-+        warning
-+            ("Interrupt vector 0x%x assigned to ISR `%s' is invalid.",
-+             vector, name);
-+      }
-+
-+      if (vector != NOVECTOR)
-+      {
-+        fprintf (file, ".global       vector_%04x\n", vector);
-+      }
-+      fprintf (file, "%s", TYPE_ASM_OP);
-+      assemble_name (file, name);
-+      putc (',', file);
-+      fprintf (file, TYPE_OPERAND_FMT, "function");
-+      putc ('\n', file);
-+      fprintf (file, "/***********************\n");
-+      fprintf (file, " * Interrupt %sRoutine `",
-+             (vector != NOVECTOR) ? "Service " : "Sub-");
-+      assemble_name (file, name);
-+      fprintf (file, "' at 0x%04x\n", vector);
-+      fprintf (file, " ***********************/\n");
-+
-+      if (vector != NOVECTOR)
-+      {
-+        fprintf (file, "vector_%04x:\n", vector);
-+      }
-+
-+      ASM_OUTPUT_LABEL (file, name);
-+    }
-+  else
-+    {
-+      fprintf (file, "%s", TYPE_ASM_OP);
-+      assemble_name (file, name);
-+      putc (',', file);
-+      fprintf (file, TYPE_OPERAND_FMT, "function");
-+      putc ('\n', file);
-+      fprintf (file, "/***********************\n");
-+      fprintf (file, " * Function `");
-+      assemble_name (file, name);
-+      fprintf (file, "' %s\n ***********************/\n",
-+             cfp ? "(OS critical)" : ree ? "(reentrant)" : "");
-+      ASM_OUTPUT_LABEL (file, name);
-+    }
-+}
-+
-+
-+static int
-+msp430_saved_regs_frame (void)
-+{
-+  int interrupt_func_p = interrupt_function_p (current_function_decl);
-+  int cfp = msp430_critical_function_p (current_function_decl);
-+  int leaf_func_p = leaf_function_p ();
-+  int offset = interrupt_func_p ? 0 : (cfp ? 2 : 0);
-+  int reg;
-+
-+  for (reg = 4; reg < 16; ++reg)
-+    {
-+      if ((!leaf_func_p && call_used_regs[reg] && (interrupt_func_p))
-+        || (regs_ever_live[reg]
-+            && (!call_used_regs[reg] || interrupt_func_p)))
-+      {
-+        offset += 2;
-+      }
-+    }
-+
-+  return offset;
-+}
-+
-+int
-+msp430_empty_epilogue ()
-+{
-+  int cfp = msp430_critical_function_p (current_function_decl);
-+  int ree = msp430_reentrant_function_p (current_function_decl);
-+  int nfp = msp430_naked_function_p (current_function_decl);
-+  int ifp = interrupt_function_p (current_function_decl);
-+  int wup = wakeup_function_p (current_function_decl);
-+  int size = msp430_saved_regs_frame ();
-+  int fs = get_frame_size ();
-+
-+  if (cfp && ree)
-+    ree = 0;
-+
-+  /* the following combination of attributes forces to issue
-+     some commands in function epilogue */
-+  if (ree
-+      || nfp || fs || wup || MAIN_NAME_P (DECL_NAME (current_function_decl)))
-+    return 0;
-+
-+  size += fs;
-+
-+  /* <= 2 necessary for first call */
-+  if (size <= 2 && cfp)
-+    return 2;
-+  if (size == 0 && !cfp && !ifp)
-+    return 1;
-+  if (size == 0 && ifp)
-+    return 2;
-+
-+  return 0;
-+}
-+
-+/* Returns a number of pushed registers */
-+static int
-+msp430_func_num_saved_regs ()
-+{
-+  int i;
-+  int saves = 0;
-+  int interrupt_func_p = interrupt_function_p (current_function_decl);
-+  int leaf_func_p = leaf_function_p ();
-+
-+  for (i = 4; i < 16; i++)
-+    {
-+      if ((regs_ever_live[i]
-+         && (!call_used_regs[i]
-+             || interrupt_func_p))
-+        || (!leaf_func_p && (call_used_regs[i] && interrupt_func_p)))
-+      {
-+        saves += 1;
-+      }
-+    }
-+
-+  return saves;
-+}
-+
-+
-+/* Output function prologue */
-+void
-+function_prologue (file, size)
-+     FILE *file;
-+     int size;
-+{
-+  int i;
-+  int interrupt_func_p = interrupt_function_p (current_function_decl);
-+  int signal_func_p = signal_function_p (current_function_decl);
-+  int leaf_func_p = leaf_function_p ();
-+  int main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
-+  int stack_reserve = 0;
-+  tree ss = 0;
-+  rtx x = DECL_RTL (current_function_decl);
-+  const char *fnname = XSTR (XEXP (x, 0), 0);
-+  int offset;
-+  int cfp = msp430_critical_function_p (current_function_decl);
-+  int tfp = msp430_task_function_p (current_function_decl);
-+  int ree = msp430_reentrant_function_p (current_function_decl);
-+  int save_prologue_p =
-+      msp430_save_prologue_function_p (current_function_decl);
-+  int num_saved_regs;
-+
-+  return_issued = 0;
-+  last_insn_address = 0;
-+  jump_tables_size = 0;
-+  prologue_size = 0;
-+
-+  /* check attributes compatibility */
-+
-+  if ((cfp && ree) || (ree && interrupt_func_p))
-+    {
-+      warning ("attribute 'reentrant' ignored");
-+      ree = 0;
-+    }
-+
-+  if (cfp && interrupt_func_p)
-+    {
-+      warning ("attribute 'critical' ignored");
-+      cfp = 0;
-+    }
-+
-+  if (signal_func_p && !interrupt_func_p)
-+    {
-+      warning ("attribute 'signal' does not make sense.");
-+      signal_func_p = 0;
-+    }
-+
-+  /* naked function discards everything */
-+  if (msp430_naked_function_p (current_function_decl))
-+    {
-+      fprintf (file, "\t/* prologue: naked */\n");
-+      fprintf (file, ".L__FrameSize_%s=0x%x\n", fnname, size);
-+      return;
-+    }
-+  ss = lookup_attribute ("reserve", DECL_ATTRIBUTES (current_function_decl));
-+  if (ss)
-+    {
-+      ss = TREE_VALUE (ss);
-+      if (ss)
-+      {
-+        ss = TREE_VALUE (ss);
-+        if (ss)
-+          stack_reserve = TREE_INT_CST_LOW (ss);
-+        stack_reserve++;
-+        stack_reserve &= ~1;
-+      }
-+    }
-+
-+  fprintf (file, "\t/* prologue: frame size = %d */\n", size);
-+  fprintf (file, ".L__FrameSize_%s=0x%x\n", fnname, size);
-+
-+
-+  offset = initial_elimination_offset (0, 0) - 2;
-+
-+  msp430_current_frame_offset = offset;
-+
-+  fprintf (file, ".L__FrameOffset_%s=0x%x\n", fnname, offset);
-+
-+  if (signal_func_p && interrupt_func_p)
-+    {
-+      prologue_size += 1;
-+      fprintf (file, "\teint\t; enable nested interrupt\n");
-+    }
-+
-+  if (main_p)
-+    {
-+      if (TARGET_NSI)
-+      {
-+        if (size || stack_reserve)
-+          fprintf (file, "\tsub\t#%d, r1\t", size + stack_reserve);
-+        if (frame_pointer_needed)
-+          {
-+            fprintf (file, "\tmov\tr1,r%d\n", FRAME_POINTER_REGNUM);
-+            prologue_size += 1;
-+          }
-+
-+        if (size)
-+          prologue_size += 2;
-+        if (size == 1 || size == 2 || size == 4 || size == 8)
-+          prologue_size--;
-+      }
-+      else
-+      {
-+        fprintf (file, "\tmov\t#(%s-%d), r1\n", msp430_init_stack,
-+                 size + stack_reserve);
-+
-+        if (frame_pointer_needed)
-+          {
-+            fprintf (file, "\tmov\tr1,r%d\n", FRAME_POINTER_REGNUM);
-+            prologue_size += 1;
-+          }
-+        prologue_size += 2;
-+      }
-+    }
-+  else
-+    {
-+      /* Here, we've got a chance to jump to prologue saver */
-+      num_saved_regs = msp430_func_num_saved_regs ();
-+
-+      if ((TARGET_SAVE_PROLOGUE || save_prologue_p)
-+        && !interrupt_func_p && !arg_register_used[12] && num_saved_regs > 4)
-+      {
-+        fprintf (file, "\tsub\t#16, r1\n");
-+        fprintf (file, "\tmov\tr0, r12\n");
-+        fprintf (file, "\tadd\t#8, r12\n");
-+        fprintf (file, "\tbr\t#__prologue_saver+%d\n",
-+                 (8 - num_saved_regs) * 4);
-+
-+        if (cfp && 8 - num_saved_regs)
-+          {
-+            int n = 16 - num_saved_regs * 2;
-+            fprintf (file, "\tadd\t#%d, r1\n", n);
-+            if (n != 0 && n != 1 && n != 2 && n != 4 && n != 8)
-+              prologue_size += 1;
-+          }
-+        else
-+          size -= 16 - num_saved_regs * 2;
-+
-+        prologue_size += 7;
-+      }
-+      else if(!tfp)
-+      {
-+        for (i = 15; i >= 4; i--)
-+          {
-+            if ((regs_ever_live[i]
-+                 && (!call_used_regs[i]
-+                     || interrupt_func_p))
-+                || (!leaf_func_p && (call_used_regs[i]
-+                                     && (interrupt_func_p))))
-+              {
-+                fprintf (file, "\tpush\tr%d\n", i);
-+                prologue_size += 1;
-+              }
-+          }
-+      }
-+
-+      if (!interrupt_func_p && cfp)
-+      {
-+        prologue_size += 3;
-+        fprintf (file, "\tpush\tr2\n");
-+        fprintf (file, "\tdint\n");
-+        if (!size)
-+          fprintf (file, "\tnop\n");
-+      }
-+
-+      if (size)
-+      {
-+        /* The next is a hack... I do not undestand why, but if there
-+           ARG_POINTER_REGNUM and FRAME/STACK are different, 
-+           the compiler fails to compute corresponding
-+           displacement */
-+        if (!optimize && !optimize_size
-+            && regs_ever_live[ARG_POINTER_REGNUM])
-+          {
-+            int o = initial_elimination_offset (0, 0) - size;
-+            fprintf (file, "\tmov\tr1, r%d\n", ARG_POINTER_REGNUM);
-+            fprintf (file, "\tadd\t#%d, r%d\n", o, ARG_POINTER_REGNUM);
-+            prologue_size += 2;
-+            if (o != 0 && o != 1 && o != 2 && o != 4 && o != 8)
-+              prologue_size += 1;
-+          }
-+
-+        /* adjust frame ptr... */
-+        if (size > 0)
-+          fprintf (file, "\tsub\t#%d, r1\t;   %d, fpn %d\n", (size + 1) & ~1,
-+                   size, frame_pointer_needed);
-+        else
-+          {
-+            size = -size;
-+            fprintf (file, "\tadd\t#%d, r1\t;    %d, fpn %d\n",
-+                     (size + 1) & ~1, size, frame_pointer_needed);
-+          }
-+
-+        if (frame_pointer_needed)
-+          {
-+            fprintf (file, "\tmov\tr1,r%d\n", FRAME_POINTER_REGNUM);
-+            prologue_size += 1;
-+          }
-+
-+        if (size == 1 || size == 2 || size == 4 || size == 8)
-+          prologue_size += 1;
-+        else
-+          prologue_size += 2;
-+      }
-+
-+      /* disable interrupt for reentrant function */
-+      if (!interrupt_func_p && ree)
-+      {
-+        prologue_size += 1;
-+        fprintf (file, "\tdint\n");
-+      }
-+    }
-+
-+  fprintf (file, "\t/* prologue end (size=%d) */\n\n", prologue_size);
-+}
-+
-+
-+/* Output function epilogue */
-+
-+void
-+function_epilogue (file, size)
-+     FILE *file;
-+     int size;
-+{
-+  int i;
-+  int interrupt_func_p = interrupt_function_p (current_function_decl);
-+  int leaf_func_p = leaf_function_p ();
-+  int main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
-+  int wakeup_func_p = wakeup_function_p (current_function_decl);
-+  int cfp = msp430_critical_function_p (current_function_decl);
-+  int ree = msp430_reentrant_function_p (current_function_decl);
-+  int save_prologue_p =
-+      msp430_save_prologue_function_p (current_function_decl);
-+  int still_return = 1;
-+  int function_size;
-+
-+
-+  last_insn_address = 0;
-+  jump_tables_size = 0;
-+  epilogue_size = 0;
-+  function_size = (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
-+                 - INSN_ADDRESSES (INSN_UID (get_insns ())));
-+
-+  if (msp430_task_function_p (current_function_decl))
-+    {
-+      fprintf (file, "\n\t/* epilogue: empty, task functions never return */\n");
-+      return;
-+    }
-+
-+  if (msp430_naked_function_p (current_function_decl))
-+    {
-+      fprintf (file, "\n\t/* epilogue: naked */\n");
-+      return;
-+    }
-+
-+  if (msp430_empty_epilogue ())
-+    {
-+      if (!return_issued)
-+      {
-+        fprintf (file, "\t%s\n", msp430_emit_return (NULL, NULL, NULL));
-+        epilogue_size++;
-+      }
-+      fprintf (file, "\n\t/* epilogue: not required */\n");
-+      goto done_epilogue;
-+    }
-+
-+  if ((cfp || interrupt_func_p) && ree)
-+    ree = 0;
-+  if (cfp && interrupt_func_p)
-+    cfp = 0;
-+
-+  fprintf (file, "\n\t/* epilogue: frame size=%d */\n", size);
-+
-+  if (main_p)
-+    {
-+      if (size)
-+      fprintf (file, "\tadd\t#%d, r1\n", (size + 1) & ~1);
-+      fprintf (file, "\tbr\t#%s\n", msp430_endup);
-+      epilogue_size += 4;
-+      if (size == 1 || size == 2 || size == 4 || size == 8)
-+      epilogue_size--;
-+    }
-+  else
-+    {
-+      if (ree)
-+      {
-+        fprintf (file, "\teint\n");
-+        epilogue_size += 1;
-+      }
-+
-+      if (size)
-+      {
-+        fprintf (file, "\tadd\t#%d, r1\n", (size + 1) & ~1);
-+        if (size == 1 || size == 2 || size == 4 || size == 8)
-+          epilogue_size += 1;
-+        else
-+          epilogue_size += 2;
-+      }
-+
-+      if (!interrupt_func_p && cfp)
-+      {
-+        epilogue_size += 1;
-+        if (msp430_saved_regs_frame () == 2)
-+          {
-+            fprintf (file, "\treti\n");
-+            still_return = 0;
-+          }
-+        else
-+          fprintf (file, "\tpop\tr2\n");
-+      }
-+
-+      if ((TARGET_SAVE_PROLOGUE || save_prologue_p)
-+        && !interrupt_func_p && msp430_func_num_saved_regs () > 2)
-+      {
-+        fprintf (file, "\tbr\t#__epilogue_restorer+%d\n",
-+                 (8 - msp430_func_num_saved_regs ()) * 2);
-+        epilogue_size += 2;
-+      }
-+      else if ((TARGET_SAVE_PROLOGUE || save_prologue_p) && interrupt_func_p)
-+      {
-+        fprintf (file, "\tbr\t#__epilogue_restorer_intr+%d\n",
-+                 (12 - msp430_func_num_saved_regs ()) * 2);
-+      }
-+      else
-+      {
-+        for (i = 4; i < 16; i++)
-+          {
-+            if ((regs_ever_live[i]
-+                 && (!call_used_regs[i]
-+                     || interrupt_func_p))
-+                || (!leaf_func_p && (call_used_regs[i] && interrupt_func_p)))
-+              {
-+                fprintf (file, "\tpop\tr%d\n", i);
-+                epilogue_size += 1;
-+              }
-+          }
-+
-+        if (interrupt_func_p)
-+          {
-+            if (wakeup_func_p)
-+              {
-+                fprintf (file, "\tbic\t#0xf0,0(r1)\n");
-+                epilogue_size += 3;
-+              }
-+
-+            fprintf (file, "\treti\n");
-+            epilogue_size += 1;
-+          }
-+        else
-+          {
-+            if (still_return)
-+              fprintf (file, "\tret\n");
-+            epilogue_size += 1;
-+          }
-+      }
-+    }
-+
-+  fprintf (file, "\t/* epilogue end (size=%d) */\n", epilogue_size);
-+done_epilogue:
-+  fprintf (file, "\t/* function %s size %d (%d) */\n", current_function_name,
-+         prologue_size + function_size + epilogue_size, function_size);
-+
-+  commands_in_file += prologue_size + function_size + epilogue_size;
-+  commands_in_prologues += prologue_size;
-+  commands_in_epilogues += epilogue_size;
-+}
-+
-+
-+/* Attempts to replace X with a valid
-+   memory address for an operand of mode MODE  */
-+/* FIXME: broken call */
-+rtx
-+legitimize_address (x, oldx, mode)
-+     rtx x;
-+     rtx oldx ATTRIBUTE_UNUSED;
-+     enum machine_mode mode ATTRIBUTE_UNUSED;
-+{
-+  /*    if (GET_CODE (oldx) == MEM
-+     && GET_CODE (XEXP(oldx,0)) == PLUS
-+     && GET_CODE (XEXP(XEXP(oldx,0),0)) == MEM)
-+     {
-+     x = force_operand (oldx,0);
-+     return x;
-+     }
-+
-+     return oldx;
-+   */
-+  return x;
-+}
-+
-+int
-+legitimate_address_p (mode, operand, strict)
-+     enum machine_mode mode ATTRIBUTE_UNUSED;
-+     rtx operand;
-+     int strict;
-+{
-+  rtx xfoob, x = operand;
-+
-+  xfoob = XEXP (operand, 0);
-+
-+  /* accept @Rn (Rn points to operand address ) */
-+  if (GET_CODE (operand) == REG
-+      && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
-+        : REG_OK_FOR_BASE_NOSTRICT_P (x)))
-+    goto granted;
-+
-+  /* accept address */
-+  if (CONSTANT_P (operand))
-+    goto granted;
-+
-+  /* accept X(Rn) Rn + X points to operand address */
-+  if (GET_CODE (operand) == PLUS
-+      && GET_CODE (XEXP (operand, 0)) == REG
-+      && CONSTANT_P (XEXP (operand, 1))
-+      && (strict ? (REG_OK_FOR_BASE_STRICT_P (xfoob))
-+        : (REG_OK_FOR_BASE_NOSTRICT_P (xfoob))))
-+    goto granted;
-+
-+  if (TARGET_ALL_DEBUG)
-+    fprintf (stderr, "Address Failed\n");
-+  return 0;
-+
-+granted:
-+  if (TARGET_ALL_DEBUG)
-+    fprintf (stderr, "Address granted\n");
-+  return 1;
-+}
-+
-+
-+void
-+print_operand_address (file, addr)
-+     FILE *file;
-+     rtx addr;
-+{
-+  /* hopefully will be never entered. */
-+  switch (GET_CODE (addr))
-+    {
-+    case REG:
-+      fprintf (file, "r%d", REGNO (addr));
-+      return;
-+    case POST_INC:
-+      fprintf (file, "@r%d+", REGNO (XEXP(addr,0)));
-+      return;
-+    case SYMBOL_REF:
-+    case LABEL_REF:
-+    case CONST:
-+      fprintf (file, "#");
-+      break;
-+    case CODE_LABEL:
-+      break;
-+    default:
-+      abort ();
-+      fprintf (file, "&");
-+    }
-+  output_addr_const (file, addr);
-+}
-+
-+void print_sub_operand PARAMS ((FILE *, rtx, int));
-+
-+const char *trim_array[] = { "llo", "lhi", "hlo", "hhi" };
-+
-+
-+
-+void
-+print_sub_operand (file, x, code)
-+     FILE *file;
-+     rtx x;
-+     int code;
-+{
-+
-+  if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
-+    {
-+      output_addr_const (file, x);
-+      return;
-+    }
-+  else if (GET_CODE (x) == CONST)
-+    {
-+      print_sub_operand (file, XEXP (x, 0), code);
-+      return;
-+    }
-+  else if (GET_CODE (x) == PLUS)
-+    {
-+      print_sub_operand (file, XEXP (x, 0), code);
-+      fprintf (file, "+");
-+      print_sub_operand (file, XEXP (x, 1), code);
-+      return;
-+    }
-+  else if (GET_CODE (x) == CONST_INT)
-+    {
-+      fprintf (file, "%d", INTVAL (x));
-+      return;
-+    }
-+  else
-+    abort ();
-+}
-+
-+void
-+print_operand (file, x, code)
-+     FILE *file;
-+     rtx x;
-+     int code;
-+{
-+  int shift = 0;
-+  int ml = GET_MODE_SIZE (x->mode);
-+  int source_reg = 0;
-+
-+
-+  if (ml > 1)
-+    ml = 2;
-+
-+  if (code >= 'A' && code <= 'D')
-+    shift = code - 'A';
-+
-+  if (code >= 'E' && code <= 'H')
-+    {
-+      shift = code - 'E';
-+      source_reg = 1;
-+    }
-+
-+  if (code >= 'I' && code <= 'L')
-+    {
-+      ml = 1;
-+      shift = code - 'I';
-+    }
-+
-+  if (GET_CODE (x) == PLUS)
-+    {
-+      fprintf (file, "add%s", shift ? "c" : "");
-+    }
-+  else if (GET_CODE (x) == MINUS)
-+    {
-+      fprintf (file, "sub%s", shift ? "c" : "");
-+    }
-+  else if (GET_CODE (x) == AND)
-+    {
-+      fprintf (file, "and");
-+    }
-+  else if (GET_CODE (x) == IOR)
-+    {
-+      fprintf (file, "bis");
-+    }
-+  else if (GET_CODE (x) == XOR)
-+    {
-+      fprintf (file, "xor");
-+    }
-+  else if (REG_P (x))
-+    {
-+      fprintf (file, reg_names[true_regnum (x) + shift]);
-+    }
-+  else if (GET_CODE (x) == CONST_INT)
-+    {
-+      if (code != 'F')
-+      fprintf (file, "#%s(%d)", trim_array[shift], INTVAL (x));
-+      else
-+      fprintf (file, "%d", INTVAL (x));
-+    }
-+  else if (GET_CODE (x) == MEM)
-+    {
-+      rtx addr = XEXP (x, 0);
-+
-+      if (GET_CODE (addr) == POST_INC)
-+      {
-+        fprintf (file, "@r%d+", REGNO (XEXP(addr,0)));
-+      }
-+      else if (GET_CODE (addr) == REG)
-+      {                       /* for X(Rn) */
-+        if (shift || !source_reg)
-+          {
-+            if (shift)
-+              fprintf (file, "%d(r%d)", shift * ml, REGNO (addr));
-+            else
-+              fprintf (file, "@r%d", REGNO (addr));
-+          }
-+        else if (source_reg)
-+          {
-+            fprintf (file, "r%d", REGNO (addr) + shift);
-+          }
-+        else
-+          {
-+            fprintf (file, "@r%d", REGNO (addr));
-+          }
-+      }
-+      else if (GET_CODE (addr) == SYMBOL_REF)
-+      {
-+        fprintf (file, "&");
-+        output_addr_const (file, addr);
-+        if (shift)
-+          fprintf (file, "+%d", shift * ml);
-+      }
-+      else if (GET_CODE (addr) == CONST || GET_CODE (addr) == CONST_INT)
-+      {
-+        fputc ('&', file);
-+        output_addr_const (file, addr);
-+        if (shift)
-+          fprintf (file, "+%d", shift * ml);
-+      }
-+      else if (GET_CODE (addr) == PLUS)
-+      {
-+
-+        print_sub_operand (file, XEXP (addr, 1), code);
-+
-+      /* shift if the indirect pointer register is the stack pointer */
-+      if ((code >= 'M' && code <= 'N') && (REGNO (XEXP (addr, 0)) == 1))
-+        shift = code - 'M';
-+
-+        if (shift)
-+          fprintf (file, "+%d", shift * ml);
-+
-+        if (REG_P (XEXP (addr, 0)))
-+          fprintf (file, "(r%d)", REGNO (XEXP (addr, 0)));
-+        else
-+          abort ();
-+      }
-+      else if (GET_CODE (addr) == MEM)
-+      {
-+        fprintf (file, "@(Invalid addressing mode)");
-+        print_operand (file, addr, code);
-+      }
-+      else
-+      {
-+        fprintf (file, "Unknown operand. Please check.");
-+      }
-+    }
-+  else if (GET_CODE (x) == SYMBOL_REF)
-+    {
-+      fprintf (file, "#");
-+      output_addr_const (file, x);
-+      if (shift)
-+      fprintf (file, "+%d", shift * ml);
-+    }
-+  else if (GET_CODE (x) == CONST_DOUBLE)
-+    {
-+      if (GET_MODE (x) == VOIDmode)   /* FIXME: may be long long?? */
-+      {
-+        if (shift < 2)
-+          fprintf (file, "#%s(%d)", trim_array[shift], CONST_DOUBLE_LOW (x));
-+        else
-+          fprintf (file, "#%s(%d)", trim_array[shift - 2],
-+                   CONST_DOUBLE_HIGH (x));
-+      }
-+      else if (GET_MODE (x) == SFmode || GET_MODE (x) == SImode)
-+      {
-+        long val;
-+        REAL_VALUE_TYPE rv;
-+        REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
-+        REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+        asm_fprintf (file, "#%s(0x%lx)", trim_array[shift], val);
-+      }
-+      else
-+      {
-+        fatal_insn ("Internal compiler bug. Unknown mode:", x);
-+      }
-+    }
-+  else
-+    print_operand_address (file, x);
-+}
-+
-+/* mode for branch instruction */
-+int
-+msp430_jump_dist (x, insn)
-+     rtx x;
-+     rtx insn;
-+{
-+  int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
-+                                          ? XEXP (x, 0) : x));
-+  int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
-+  int jump_distance = dest_addr - cur_addr;
-+
-+  return jump_distance;
-+}
-+
-+
-+
-+#define FIRST_CUM_REG 16
-+static CUMULATIVE_ARGS *cum_incoming = 0;
-+
-+/* Initializing the variable cum for the state at the beginning
-+   of the argument list.  */
-+void
-+init_cumulative_args (cum, fntype, libname, indirect)
-+     CUMULATIVE_ARGS *cum;
-+     tree fntype;
-+     rtx libname;
-+     int indirect ATTRIBUTE_UNUSED;
-+{
-+  cum->nregs = 4;
-+  cum->regno = FIRST_CUM_REG;
-+  if (!libname)
-+    {
-+      int stdarg = (TYPE_ARG_TYPES (fntype) != 0
-+                  && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
-+                      != void_type_node));
-+      if (stdarg)
-+      cum->nregs = 0;
-+    }
-+}
-+
-+/* the same in scope of the cum.args., buf usefull for a
-+   function call */
-+void
-+init_cumulative_incoming_args (cum, fntype, libname)
-+     CUMULATIVE_ARGS *cum;
-+     tree fntype;
-+     rtx libname;
-+{
-+  int i;
-+  cum->nregs = 4;
-+  cum->regno = FIRST_CUM_REG;
-+  if (!libname)
-+    {
-+      int stdarg = (TYPE_ARG_TYPES (fntype) != 0
-+                  && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
-+                      != void_type_node));
-+      if (stdarg)
-+      cum->nregs = 0;
-+    }
-+
-+  for (i = 0; i < 16; i++)
-+    arg_register_used[i] = 0;
-+
-+  cum_incoming = cum;
-+}
-+
-+rtx
-+msp430_libcall_value (mode)
-+     enum machine_mode mode;
-+{
-+  int offs = GET_MODE_SIZE (mode);
-+  offs >>= 1;
-+  if (offs < 1)
-+    offs = 1;
-+  return gen_rtx (REG, mode, (RET_REGISTER + 1 - offs));
-+}
-+
-+rtx
-+msp430_function_value (type, func)
-+     tree type;
-+     tree func ATTRIBUTE_UNUSED;
-+{
-+  int offs;
-+  if (TYPE_MODE (type) != BLKmode)
-+    return msp430_libcall_value (TYPE_MODE (type));
-+
-+  offs = int_size_in_bytes (type);
-+  offs >>= 1;
-+  if (offs < 1)
-+    offs = 1;
-+  if (offs > 1 && offs < (GET_MODE_SIZE (SImode) >> 1))
-+    offs = GET_MODE_SIZE (SImode) >> 1;
-+  else if (offs > (GET_MODE_SIZE (SImode) >> 1)
-+         && offs < (GET_MODE_SIZE (DImode) >> 1))
-+    offs = GET_MODE_SIZE (DImode) >> 1;
-+
-+  return gen_rtx (REG, BLKmode, (RET_REGISTER + 1 - offs));
-+}
-+
-+/* Returns the number of registers to allocate for a function argument.  */
-+static int
-+msp430_num_arg_regs (mode, type)
-+     enum machine_mode mode;
-+     tree type;
-+{
-+  int size;
-+
-+  if (mode == BLKmode)
-+    size = int_size_in_bytes (type);
-+  else
-+    size = GET_MODE_SIZE (mode);
-+
-+  if (size < 2)
-+    size = 2;
-+
-+  /* we do not care if argument is passed in odd register
-+     so, do not align the size ...
-+     BUT!!! even char argument passed in 16 bit register
-+     so, align the size */
-+  return ((size + 1) & ~1) >> 1;
-+}
-+
-+/* Controls whether a function argument is passed
-+   in a register, and which register. */
-+rtx
-+function_arg (cum, mode, type, named)
-+     CUMULATIVE_ARGS *cum;
-+     enum machine_mode mode;
-+     tree type;
-+     int named ATTRIBUTE_UNUSED;
-+{
-+  int regs = msp430_num_arg_regs (mode, type);
-+
-+  if (cum->nregs && regs <= cum->nregs)
-+    {
-+      int regnum = cum->regno - regs;
-+
-+      if (cum == cum_incoming)
-+      {
-+        arg_register_used[regnum] = 1;
-+        if (regs >= 2)
-+          arg_register_used[regnum + 1] = 1;
-+        if (regs >= 3)
-+          arg_register_used[regnum + 2] = 1;
-+        if (regs >= 4)
-+          arg_register_used[regnum + 3] = 1;
-+      }
-+
-+      return gen_rtx (REG, mode, regnum);
-+    }
-+  return NULL_RTX;
-+}
-+
-+
-+/* Update the summarizer variable CUM to advance past an argument
-+   in the argument list.  */
-+void
-+function_arg_advance (cum, mode, type, named)
-+     CUMULATIVE_ARGS *cum;
-+     enum machine_mode mode;
-+     tree type;
-+     int named ATTRIBUTE_UNUSED;
-+{
-+  int regs = msp430_num_arg_regs (mode, type);
-+
-+  cum->nregs -= regs;
-+  cum->regno -= regs;
-+
-+  if (cum->nregs <= 0)
-+    {
-+      cum->nregs = 0;
-+      cum->regno = FIRST_CUM_REG;
-+    }
-+}
-+
-+/* Workaround for volatile variables */
-+int
-+nonimmediate_operand_msp430 (op, mode)
-+     rtx op;
-+     enum machine_mode mode;
-+{
-+  int save_volatile_ok = volatile_ok;
-+  int niop = 0;
-+
-+  if (!TARGET_NVWA)
-+    volatile_ok = 1;
-+  niop = nonimmediate_operand (op, mode);
-+  volatile_ok = save_volatile_ok;
-+
-+  return niop;
-+}
-+
-+int
-+memory_operand_msp430 (op, mode)
-+     rtx op;
-+     enum machine_mode mode;
-+{
-+  int save_volatile_ok = volatile_ok;
-+  int mop = 0;
-+
-+  if (!TARGET_NVWA)
-+    volatile_ok = 1;
-+  mop = memory_operand (op, mode);
-+  volatile_ok = save_volatile_ok;
-+  return mop;
-+}
-+
-+int
-+general_operand_msp430 (op, mode)
-+     rtx op;
-+     enum machine_mode mode;
-+{
-+  int save_volatile_ok = volatile_ok;
-+  int gop = 0;
-+
-+  if (!TARGET_NVWA)
-+    volatile_ok = 1;
-+  gop = general_operand (op, mode);
-+  volatile_ok = save_volatile_ok;
-+  return gop;
-+}
-+
-+
-+int
-+halfnibble_integer (op, mode)
-+     rtx op;
-+     enum machine_mode mode;
-+{
-+  int hi, lo;
-+  int val;
-+
-+  if (!const_int_operand (op, mode))
-+    return 0;
-+
-+  /* this integer is the one of form:
-+     0xXXXX0000 or 0x0000XXXX,
-+     where XXXX not one of -1,1,2,4,8 
-+   */
-+  val = INTVAL (op);
-+  hi = ((val & 0xffff0000ul) >> 16) & 0xffff;
-+  lo = (val & 0xffff);
-+
-+  if (hi && lo)
-+    return 0;
-+
-+  if (hi && hi != 0xffff && hi != 1 && hi != 2 && hi != 4 && hi != 8)
-+    return 1;
-+  if (lo && lo != 0xffff && lo != 1 && lo != 2 && lo != 4 && lo != 8)
-+    return 1;
-+
-+  return 0;
-+}
-+
-+
-+int
-+halfnibble_constant (op, mode)
-+     rtx op;
-+     enum machine_mode mode;
-+{
-+  int hi, lo;
-+  int val;
-+
-+  if (!const_int_operand (op, mode))
-+    return 0;
-+
-+  /* this integer is the one of form:
-+     0xXXXX0000 or 0x0000XXXX,
-+     where XXXX one of -1,1,2,4,8 
-+   */
-+  val = INTVAL (op);
-+  hi = ((val & 0xffff0000ul) >> 16) & 0x0000ffff;
-+  lo = (val & 0x0000ffff);
-+
-+  if ((hi && lo) || (!hi && !lo))
-+    return 0;
-+
-+  if (hi == 0xffff || hi == 1 || hi == 2 || hi == 4 || hi == 8)
-+    return 1;
-+  if (lo == 0xffff || lo == 1 || lo == 2 || lo == 4 || lo == 8)
-+    return 1;
-+
-+  if (!(hi && lo))
-+    return 1;
-+
-+  return 0;
-+}
-+
-+
-+int
-+halfnibble_integer_shift (op, mode)
-+     rtx op;
-+     enum machine_mode mode;
-+{
-+  int hi, lo;
-+  int val;
-+
-+  if (!immediate_operand (op, mode))
-+    return 0;
-+
-+  /* this integer is the one of form:
-+     0xXXXX0000 or 0x0000XXXX,
-+     where XXXX not one of -1,1,2,4,8 
-+   */
-+  val = 1 << INTVAL (op);
-+  hi = ((val & 0xffff0000ul) >> 16) & 0x0000ffff;
-+  lo = (val & 0x0000ffff);
-+
-+  if (hi && lo)
-+    return 0;
-+
-+  if (hi && hi != 0xffff && hi != 1 && hi != 2 && hi != 4 && hi != 8)
-+    return 1;
-+  if (lo && lo != 0xffff && lo != 1 && lo != 2 && lo != 4 && lo != 8)
-+    return 1;
-+
-+  return 0;
-+}
-+
-+
-+int
-+halfnibble_constant_shift (op, mode)
-+     rtx op;
-+     enum machine_mode mode;
-+{
-+  int hi, lo;
-+  int val;
-+
-+  if (!immediate_operand (op, mode))
-+    return 0;
-+
-+  /* this integer is the one of form:
-+     0xXXXX0000 or 0x0000XXXX,
-+     where XXXX one of -1,1,2,4,8 
-+   */
-+  val = 1 << INTVAL (op);
-+  hi = ((val & 0xffff0000ul) >> 16) & 0x0000ffff;
-+  lo = (val & 0x0000ffff);
-+
-+  if (hi && lo)
-+    return 0;
-+
-+  if (hi && hi == 0xffff && hi == 1 && hi == 2 && hi == 4 && hi == 8)
-+    return 1;
-+  if (lo && lo == 0xffff && lo == 1 && lo == 2 && lo == 4 && lo == 8)
-+    return 1;
-+
-+  return 0;
-+}
-+
-+
-+int
-+which_nibble (val)
-+     int val;
-+{
-+  if (val & 0xffff0000ul)
-+    return 1;
-+  return 0;
-+}
-+
-+
-+int
-+which_nibble_shift (val)
-+     int val;
-+{
-+  if (val & 0xffff0000ul)
-+    return 1;
-+  return 0;
-+}
-+
-+
-+int
-+extra_constraint (x, c)
-+     rtx x;
-+     int c;
-+{
-+
-+  if (c == 'R')
-+    {
-+      if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == REG)
-+      {
-+        rtx xx = XEXP (x, 0);
-+        int regno = REGNO (xx);
-+        if (regno >= 4 || regno == 1)
-+          return 1;
-+      }
-+    }
-+  else if (c == 'Q')
-+    {
-+      if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == REG)
-+      {
-+        rtx xx = XEXP (x, 0);
-+        int regno = REGNO (xx);
-+        if (regno >= 4 || regno == 1)
-+          return 1;
-+      }
-+
-+      if (GET_CODE (x) == MEM
-+        && GET_CODE (XEXP (x, 0)) == PLUS
-+        && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
-+      {
-+        rtx xx = XEXP (XEXP (x, 0), 0);
-+        int regno = REGNO (xx);
-+        if (regno >= 4 || regno == 1)
-+          return 1;
-+      }
-+
-+      if (GET_CODE (x) == MEM
-+        && GET_CODE (XEXP (x, 0)) == PLUS && REG_P (XEXP (XEXP (x, 0), 0)))
-+      {
-+        return 1;
-+      }
-+
-+    }
-+  else if (c == 'S')
-+    {
-+      if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
-+      {
-+        return 1;
-+      }
-+    }
-+
-+  return 0;
-+}
-+
-+int
-+indexed_location (x)
-+     rtx x;
-+{
-+  int r = 0;
-+
-+  if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == REG)
-+    {
-+      r = 1;
-+    }
-+
-+  if (TARGET_ALL_DEBUG)
-+    {
-+      fprintf (stderr, "indexed_location %s: %s  \n",
-+             r ? "granted" : "failed",
-+             reload_completed ? "reload completed" : "reload in progress");
-+      debug_rtx (x);
-+    }
-+
-+  return r;
-+}
-+
-+
-+int
-+zero_shifted (x)
-+     rtx x;
-+{
-+  int r = 0;
-+
-+  if (GET_CODE (x) == MEM &&
-+      GET_CODE (XEXP (x, 0)) == REG
-+      && REGNO (XEXP (x, 0)) != STACK_POINTER_REGNUM
-+      && REGNO (XEXP (x, 0)) != FRAME_POINTER_REGNUM
-+      /* the following is Ok, cause we do not corrupt r4 within ISR */
-+      /*&& REGNO(XEXP (x,0)) != ARG_POINTER_REGNUM */ )
-+    {
-+      r = 1;
-+    }
-+  return r;
-+}
-+
-+
-+int
-+default_rtx_costs (X, code, outer_code)
-+     rtx X ATTRIBUTE_UNUSED;
-+     enum rtx_code code;
-+     enum rtx_code outer_code ATTRIBUTE_UNUSED;
-+{
-+  int cost = 0;
-+
-+  switch (code)
-+    {
-+    case SYMBOL_REF:
-+      cost = 1;
-+      break;
-+    case LABEL_REF:
-+      cost = 1;
-+      break;
-+    case MEM:
-+      cost += 1;
-+      break;
-+    case CONST_INT:
-+      cost = 1;
-+      break;
-+    case SIGN_EXTEND:
-+    case ZERO_EXTEND:
-+      cost += 2;
-+      break;
-+    default:
-+      break;
-+    }
-+  return cost;
-+}
-+
-+
-+void
-+order_regs_for_local_alloc ()
-+{
-+  unsigned int i;
-+
-+  if (TARGET_REORDER)
-+    {
-+      reg_alloc_order[0] = 12;
-+      reg_alloc_order[1] = 13;
-+      reg_alloc_order[2] = 14;
-+      reg_alloc_order[3] = 15;
-+      for (i = 4; i < 16; i++)
-+      reg_alloc_order[i] = 15 - i;
-+    }
-+  else
-+    {
-+      for (i = 0; i < 16; i++)
-+      reg_alloc_order[i] = 15 - i;
-+    }
-+
-+  return;
-+}
-+
-+/* Output rtx VALUE as .byte to file FILE */
-+void
-+asm_output_char (file, value)
-+     FILE *file;
-+     rtx value;
-+{
-+  fprintf (file, "\t.byte\t");
-+  output_addr_const (file, value);
-+  fprintf (file, "\n");
-+}
-+
-+/* Output VALUE as .byte to file FILE */
-+void
-+asm_output_byte (file, value)
-+     FILE *file;
-+     int value;
-+{
-+  fprintf (file, "\t.byte 0x%x\n", value & 0xff);
-+}
-+
-+/* Output rtx VALUE as .word to file FILE */
-+void
-+asm_output_short (file, value)
-+     FILE *file;
-+     rtx value;
-+{
-+  fprintf (file, "\t.word ");
-+  output_addr_const (file, (value));
-+  fprintf (file, "\n");
-+}
-+
-+/* Output real N to file FILE */
-+void
-+asm_output_float (file, n)
-+     FILE *file;
-+     REAL_VALUE_TYPE n;
-+{
-+  long val;
-+  char dstr[100];
-+
-+  REAL_VALUE_TO_TARGET_SINGLE (n, val);
-+  REAL_VALUE_TO_DECIMAL (n, "%g", dstr);
-+  fprintf (file, "\t.long 0x%08lx\t/* %s */\n", val, dstr);
-+}
-+
-+/* Sets section name for declaration DECL */
-+void
-+unique_section (decl, reloc)
-+     tree decl;
-+     int reloc ATTRIBUTE_UNUSED;
-+{
-+  int len;
-+  const char *name, *prefix;
-+  char *string;
-+  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-+  STRIP_NAME_ENCODING (name, name);
-+
-+  if ((TREE_CODE (decl) == FUNCTION_DECL) || DECL_READONLY_SECTION (decl, 0))
-+    prefix = ".text.";
-+  else if ((DECL_INITIAL (decl) == 0) || (DECL_INITIAL (decl) == error_mark_node))
-+    prefix = ".bss.";
-+  else
-+    prefix = ".data.";
-+
-+  len = strlen (name) + strlen (prefix);
-+  string = alloca (len + 1);
-+  sprintf (string, "%s%s", prefix, name);
-+  DECL_SECTION_NAME (decl) = build_string (len, string);
-+}
-+
-+
-+/* Output section name to file FILE
-+   We make the section read-only and executable for a function decl,
-+   read-only for a const data decl, and writable for a non-const data decl.  */
-+
-+void
-+asm_output_section_name (file, decl, name, reloc)
-+     FILE *file;
-+     tree decl;
-+     const char *name;
-+     int reloc ATTRIBUTE_UNUSED;
-+{
-+  fprintf (file, ".section %s, \"%s\", @progbits\n", name,
-+         decl && TREE_CODE (decl) == FUNCTION_DECL ? "ax" :
-+         decl && TREE_READONLY (decl) ? "a" : "aw");
-+}
-+
-+
-+/* The routine used to output NUL terminated strings.  We use a special
-+   version of this for most svr4 targets because doing so makes the
-+   generated assembly code more compact (and thus faster to assemble)
-+   as well as more readable, especially for targets like the i386
-+   (where the only alternative is to output character sequences as
-+   comma separated lists of numbers).   */
-+
-+void
-+gas_output_limited_string (file, str)
-+     FILE *file;
-+     const char *str;
-+{
-+  const unsigned char *_limited_str = (unsigned char *) str;
-+  unsigned ch;
-+  fprintf (file, "%s\"", STRING_ASM_OP);
-+  for (; (ch = *_limited_str); _limited_str++)
-+    {
-+      int escape;
-+      switch (escape = ESCAPES[ch])
-+      {
-+      case 0:
-+        putc (ch, file);
-+        break;
-+      case 1:
-+        fprintf (file, "\\%03o", ch);
-+        break;
-+      default:
-+        putc ('\\', file);
-+        putc (escape, file);
-+        break;
-+      }
-+    }
-+  fprintf (file, "\"\n");
-+}
-+
-+/* The routine used to output sequences of byte values.  We use a special
-+   version of this for most svr4 targets because doing so makes the
-+   generated assembly code more compact (and thus faster to assemble)
-+   as well as more readable.  Note that if we find subparts of the
-+   character sequence which end with NUL (and which are shorter than
-+   STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING.  */
-+
-+void
-+gas_output_ascii (file, str, length)
-+     FILE *file;
-+     const char *str;
-+     size_t length;
-+{
-+  const unsigned char *_ascii_bytes = (const unsigned char *) str;
-+  const unsigned char *limit = _ascii_bytes + length;
-+  unsigned bytes_in_chunk = 0;
-+  for (; _ascii_bytes < limit; _ascii_bytes++)
-+    {
-+      const unsigned char *p;
-+      if (bytes_in_chunk >= 60)
-+      {
-+        fprintf (file, "\"\n");
-+        bytes_in_chunk = 0;
-+      }
-+      for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
-+      continue;
-+      if (p < limit && (p - _ascii_bytes) <= (signed) STRING_LIMIT)
-+      {
-+        if (bytes_in_chunk > 0)
-+          {
-+            fprintf (file, "\"\n");
-+            bytes_in_chunk = 0;
-+          }
-+        gas_output_limited_string (file, (char *) _ascii_bytes);
-+        _ascii_bytes = p;
-+      }
-+      else
-+      {
-+        int escape;
-+        unsigned ch;
-+        if (bytes_in_chunk == 0)
-+          fprintf (file, "\t.ascii\t\"");
-+        switch (escape = ESCAPES[ch = *_ascii_bytes])
-+          {
-+          case 0:
-+            putc (ch, file);
-+            bytes_in_chunk++;
-+            break;
-+          case 1:
-+            fprintf (file, "\\%03o", ch);
-+            bytes_in_chunk += 4;
-+            break;
-+          default:
-+            putc ('\\', file);
-+            putc (escape, file);
-+            bytes_in_chunk += 2;
-+            break;
-+          }
-+      }
-+    }
-+  if (bytes_in_chunk > 0)
-+    fprintf (file, "\"\n");
-+}
-+
-+
-+
-+/* Outputs to the stdio stream FILE some
-+   appropriate text to go at the start of an assembler file.  */
-+
-+void
-+asm_file_start (file)
-+     FILE *file;
-+{
-+  output_file_directive (file, main_input_filename);
-+  fprintf (file, "\t.arch %s\n\n", msp430_mcu_name);
-+
-+  if (msp430_has_hwmul)
-+    {
-+      fprintf (file, "/* Hardware multiplier registers: */\n"
-+             "__MPY=0x130\n"
-+             "__MPYS=0x132\n"
-+             "__MAC=0x134\n"
-+             "__MACS=0x136\n"
-+             "__OP2=0x138\n"
-+             "__RESLO=0x13a\n" "__RESHI=0x13c\n" "__SUMEXT=0x13e\n" "\n");
-+
-+    }
-+
-+  commands_in_file = 0;
-+  commands_in_prologues = 0;
-+  commands_in_epilogues = 0;
-+}
-+
-+/* Outputs to the stdio stream FILE some
-+   appropriate text to go at the end of an assembler file.  */
-+
-+void
-+asm_file_end (file)
-+     FILE *file;
-+{
-+  fprintf (file,
-+         "\n"
-+         "/*********************************************************************\n"
-+         " * File %s: code size: %d words (0x%x)\n * incl. words in prologues: %d, epilogues: %d\n"
-+         " *********************************************************************/\n",
-+         main_input_filename,
-+         commands_in_file,
-+         commands_in_file, commands_in_prologues, commands_in_epilogues);
-+}
-+
-+int
-+msp430_hard_regno_mode_ok (regno, mode)
-+     int regno ATTRIBUTE_UNUSED;
-+     enum machine_mode mode ATTRIBUTE_UNUSED;
-+{
-+  return 1;
-+}
-+
-+int
-+frame_pointer_required_p ()
-+{
-+  return (current_function_calls_alloca
-+        /*            || current_function_args_info.nregs == 0 */
-+        || current_function_varargs);
-+
-+  /* || get_frame_size () > 0); */
-+}
-+
-+enum reg_class
-+preferred_reload_class (x, class)
-+     rtx x ATTRIBUTE_UNUSED;
-+     enum reg_class class;
-+{
-+  return class;
-+}
-+
-+/* cfp minds the fact that the function may save r2 */
-+int
-+initial_elimination_offset (from, to)
-+     int from;
-+     int to;
-+{
-+  int reg;
-+  if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-+    return 0;
-+  else
-+    {
-+      int interrupt_func_p = interrupt_function_p (current_function_decl);
-+      int cfp = msp430_critical_function_p (current_function_decl);
-+      int leaf_func_p = leaf_function_p ();
-+      int offset = interrupt_func_p ? 0 : (cfp ? 2 : 0);
-+
-+      for (reg = 4; reg < 16; ++reg)
-+      {
-+        if ((!leaf_func_p && call_used_regs[reg] && (interrupt_func_p))
-+            || (regs_ever_live[reg]
-+                && (!call_used_regs[reg] || interrupt_func_p)))
-+          {
-+            offset += 2;
-+          }
-+      }
-+      return get_frame_size () + offset + 2;
-+    }
-+  return 0;
-+}
-+
-+int
-+adjust_insn_length (insn, len)
-+     rtx insn;
-+     int len;
-+{
-+
-+  rtx patt = PATTERN (insn);
-+  rtx set;
-+
-+  set = single_set (insn);
-+
-+  if (GET_CODE (patt) == SET)
-+    {
-+      rtx op[10];
-+      op[1] = SET_SRC (patt);
-+      op[0] = SET_DEST (patt);
-+
-+      if (general_operand (op[1], VOIDmode)
-+        && general_operand (op[0], VOIDmode))
-+      {
-+        op[2] = SET_SRC (patt);
-+        switch (GET_MODE (op[0]))
-+          {
-+          case QImode:
-+          case HImode:
-+            if (indexed_location (op[1]))
-+              len--;
-+            break;
-+
-+          case SImode:
-+          case SFmode:
-+            /* get length first */
-+            msp430_movesi_code (insn, op, &len);
-+
-+            if (zero_shifted (op[1]) && regsi_ok_safe (op))
-+              {
-+                rtx reg = XEXP (op[1], 0);
-+                if (dead_or_set_p (insn, reg))
-+                  len -= 1;
-+              }
-+            else if (!zero_shifted (op[1]) && indexed_location (op[1]))
-+              {
-+                len -= 1;
-+              }
-+            break;
-+          case DImode:
-+            msp430_movedi_code (insn, op, &len);
-+            if (zero_shifted (op[1]) && regdi_ok_safe (op))
-+              {
-+                rtx reg = XEXP (op[1], 0);
-+                if (dead_or_set_p (insn, reg))
-+                  len -= 1;
-+              }
-+            else if (!zero_shifted (op[1]) && indexed_location (op[1]))
-+              {
-+                len -= 1;
-+              }
-+            break;
-+
-+          default:
-+            break;
-+          }
-+
-+        if (GET_CODE (op[2]) == CONST_INT)
-+          {
-+            if (GET_MODE (op[0]) == DImode)
-+              {
-+                int x = INTVAL (op[2]);
-+                int y = (x & 0xffff0000ul) >> 16;
-+                x = x & 0xffff;
-+
-+                len -= 2;
-+
-+                if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
-+                    || x == 0xffff)
-+                  len--;
-+                if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8
-+                    || y == 0xffff)
-+                  len--;
-+              }
-+            else if (GET_MODE (op[0]) == SImode)
-+              {
-+                int x = INTVAL (op[2]);
-+                int y = (x & 0xffff0000ul) >> 16;
-+                x = x & 0xffff;
-+
-+                if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
-+                    || x == 0xffff)
-+                  len--;
-+                if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8
-+                    || y == 0xffff)
-+                  len--;
-+              }
-+            else
-+              {
-+                /* mighr be hi or qi modes */
-+                int x = INTVAL (op[2]);
-+                x = x & 0xffff;
-+                if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
-+                    || x == 0xffff)
-+                  len--;
-+              }
-+          }
-+
-+        if (GET_CODE (op[2]) == CONST_DOUBLE)
-+          {
-+            if (GET_MODE (op[0]) == SFmode)
-+              {
-+                long val;
-+                int y, x;
-+                REAL_VALUE_TYPE rv;
-+                REAL_VALUE_FROM_CONST_DOUBLE (rv, op[2]);
-+                REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+
-+                y = (val & 0xffff0000ul) >> 16;
-+                x = val & 0xffff;
-+                if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
-+                    || x == 0xffff)
-+                  len--;
-+                if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8
-+                    || y == 0xffff)
-+                  len--;
-+              }
-+            else
-+              {
-+                int hi = CONST_DOUBLE_HIGH (op[2]);
-+                int lo = CONST_DOUBLE_LOW (op[2]);
-+                int x, y, z;
-+
-+                x = (hi & 0xffff0000ul) >> 16;
-+                y = hi & 0xffff;
-+                z = (lo & 0xffff0000ul) >> 16;
-+                if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
-+                    || x == 0xffff)
-+                  len--;
-+                if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8
-+                    || y == 0xffff)
-+                  len--;
-+                if (z == 0 || z == 1 || z == 2 || z == 4 || z == 8
-+                    || z == 0xffff)
-+                  len--;
-+                z = lo & 0xffff;
-+                if (z == 0 || z == 1 || z == 2 || z == 4 || z == 8
-+                    || z == 0xffff)
-+                  len--;
-+              }
-+          }
-+
-+        return len;
-+      }
-+      else if (GET_CODE (op[1]) == MULT)
-+      {
-+        rtx ops[10];
-+        ops[0] = op[0];
-+        ops[1] = XEXP (op[1], 0);
-+        ops[2] = XEXP (op[1], 1);
-+
-+        if (GET_MODE (ops[0]) != SImode
-+            && GET_MODE (ops[0]) != SFmode && GET_MODE (ops[0]) != DImode)
-+          {
-+            if (indexed_location (ops[1]))
-+              len--;
-+            if (indexed_location (ops[2]))
-+              len--;
-+          }
-+      }
-+      else if (GET_CODE (op[1]) == ASHIFT
-+             || GET_CODE (op[1]) == ASHIFTRT || GET_CODE (op[1]) == LSHIFTRT)
-+      {
-+        rtx ops[10];
-+        ops[0] = op[0];
-+        ops[1] = XEXP (op[1], 0);
-+        ops[2] = XEXP (op[1], 1);
-+
-+        switch (GET_CODE (op[1]))
-+          {
-+          case ASHIFT:
-+            switch (GET_MODE (op[0]))
-+              {
-+              case QImode:
-+                msp430_emit_ashlqi3 (insn, ops, &len);
-+                break;
-+              case HImode:
-+                msp430_emit_ashlhi3 (insn, ops, &len);
-+                break;
-+              case SImode:
-+                msp430_emit_ashlsi3 (insn, ops, &len);
-+                break;
-+              case DImode:
-+                msp430_emit_ashldi3 (insn, ops, &len);
-+                break;
-+              default:
-+                break;
-+              }
-+            break;
-+
-+          case ASHIFTRT:
-+            switch (GET_MODE (op[0]))
-+              {
-+              case QImode:
-+                msp430_emit_ashrqi3 (insn, ops, &len);
-+                break;
-+              case HImode:
-+                msp430_emit_ashrhi3 (insn, ops, &len);
-+                break;
-+              case SImode:
-+                msp430_emit_ashrsi3 (insn, ops, &len);
-+                break;
-+              case DImode:
-+                msp430_emit_ashrdi3 (insn, ops, &len);
-+                break;
-+              default:
-+                break;
-+              }
-+            break;
-+
-+          case LSHIFTRT:
-+            switch (GET_MODE (op[0]))
-+              {
-+              case QImode:
-+                msp430_emit_lshrqi3 (insn, ops, &len);
-+                break;
-+              case HImode:
-+                msp430_emit_lshrhi3 (insn, ops, &len);
-+                break;
-+              case SImode:
-+                msp430_emit_lshrsi3 (insn, ops, &len);
-+                break;
-+              case DImode:
-+                msp430_emit_lshrdi3 (insn, ops, &len);
-+                break;
-+              default:
-+                break;
-+              }
-+            break;
-+
-+          default:
-+            break;
-+          }
-+      }
-+      else if (GET_CODE (op[1]) == PLUS
-+             || GET_CODE (op[1]) == MINUS
-+             || GET_CODE (op[1]) == AND
-+             || GET_CODE (op[1]) == IOR || GET_CODE (op[1]) == XOR)
-+      {
-+        rtx ops[10];
-+        ops[0] = op[0];
-+        ops[1] = XEXP (op[1], 0);
-+        ops[2] = XEXP (op[1], 1);
-+
-+        if (GET_CODE (op[1]) == AND && !general_operand (ops[1], VOIDmode))
-+          return len;
-+
-+        switch (GET_MODE (ops[0]))
-+          {
-+          case QImode:
-+          case HImode:
-+            if (indexed_location (ops[2]))
-+              len--;
-+            break;
-+          case SImode:
-+          case SFmode:
-+
-+            if (GET_CODE (op[1]) == PLUS)
-+              msp430_addsi_code (insn, ops, &len);
-+            if (GET_CODE (op[1]) == MINUS)
-+              msp430_subsi_code (insn, ops, &len);
-+            if (GET_CODE (op[1]) == AND)
-+              msp430_andsi_code (insn, ops, &len);
-+            if (GET_CODE (op[1]) == IOR)
-+              msp430_iorsi_code (insn, ops, &len);
-+            if (GET_CODE (op[1]) == XOR)
-+              msp430_xorsi_code (insn, ops, &len);
-+
-+            if (zero_shifted (ops[2]) && regsi_ok_safe (ops))
-+              {
-+                rtx reg = XEXP (ops[2], 0);
-+                if (dead_or_set_p (insn, reg))
-+                  len -= 1;
-+              }
-+            else if (!zero_shifted (ops[2]) && indexed_location (ops[2]))
-+              {
-+                len -= 1;
-+              }
-+            break;
-+          case DImode:
-+
-+            if (GET_CODE (op[1]) == PLUS)
-+              msp430_adddi_code (insn, ops, &len);
-+            if (GET_CODE (op[1]) == MINUS)
-+              msp430_subdi_code (insn, ops, &len);
-+            if (GET_CODE (op[1]) == AND)
-+              msp430_anddi_code (insn, ops, &len);
-+            if (GET_CODE (op[1]) == IOR)
-+              msp430_iordi_code (insn, ops, &len);
-+            if (GET_CODE (op[1]) == XOR)
-+              msp430_xordi_code (insn, ops, &len);
-+
-+            if (zero_shifted (ops[2]) && regdi_ok_safe (ops))
-+              {
-+                rtx reg = XEXP (ops[2], 0);
-+                if (dead_or_set_p (insn, reg))
-+                  len -= 1;
-+              }
-+            else if (!zero_shifted (ops[2]) && indexed_location (ops[2]))
-+              {
-+                len -= 1;
-+              }
-+            break;
-+
-+          default:
-+            break;
-+          }
-+
-+        if (GET_MODE (ops[0]) == SImode)
-+          {
-+            if (GET_CODE (ops[2]) == CONST_INT)
-+              {
-+                if (GET_CODE (op[1]) == AND)
-+                  {
-+                    msp430_emit_immediate_and2 (insn, ops, &len);
-+                  }
-+                else if (GET_CODE (op[1]) == IOR)
-+                  {
-+                    msp430_emit_immediate_ior2 (insn, ops, &len);
-+                  }
-+                else
-+                  {
-+                    if (GET_MODE (ops[0]) == SImode)
-+                      {
-+                        int x = INTVAL (ops[2]);
-+                        int y = (x & 0xffff0000ul) >> 16;
-+                        x = x & 0xffff;
-+
-+                        if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
-+                            || x == 0xffff)
-+                          len--;
-+                        if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8
-+                            || y == 0xffff)
-+                          len--;
-+                      }
-+                  }
-+              }
-+          }
-+
-+        if (GET_MODE (ops[0]) == SFmode || GET_MODE (ops[0]) == DImode)
-+          {
-+            if (GET_CODE (ops[2]) == CONST_DOUBLE)
-+              {
-+
-+                if (GET_CODE (op[1]) == AND)
-+                  {
-+                    msp430_emit_immediate_and4 (insn, ops, &len);
-+                  }
-+                else if (GET_CODE (op[1]) == IOR)
-+                  {
-+                    msp430_emit_immediate_ior4 (insn, ops, &len);
-+                  }
-+                else if (GET_MODE (ops[0]) == SFmode)
-+                  {
-+                    long val;
-+                    int y, x;
-+                    REAL_VALUE_TYPE rv;
-+                    REAL_VALUE_FROM_CONST_DOUBLE (rv, ops[2]);
-+                    REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+
-+                    y = (val & 0xffff0000ul) >> 16;
-+                    x = val & 0xffff;
-+                    if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
-+                        || x == 0xffff)
-+                      len--;
-+                    if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8
-+                        || y == 0xffff)
-+                      len--;
-+                  }
-+                else
-+                  {
-+                    int hi = CONST_DOUBLE_HIGH (ops[2]);
-+                    int lo = CONST_DOUBLE_LOW (ops[2]);
-+                    int x, y, z;
-+
-+                    x = (hi & 0xffff0000ul) >> 16;
-+                    y = hi & 0xffff;
-+                    z = (lo & 0xffff0000ul) >> 16;
-+                    if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
-+                        || x == 0xffff)
-+                      len--;
-+                    if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8
-+                        || y == 0xffff)
-+                      len--;
-+                    if (z == 0 || z == 1 || z == 2 || z == 4 || z == 8
-+                        || z == 0xffff)
-+                      len--;
-+                  }
-+              }
-+          }
-+
-+        return len;
-+      }
-+      else if (GET_CODE (op[1]) == NOT
-+             || GET_CODE (op[1]) == ABS || GET_CODE (op[1]) == NEG)
-+      {
-+        if (GET_MODE (op[0]) == HImode || GET_MODE (op[0]) == QImode)
-+          if (indexed_location (XEXP (op[1], 0)))
-+            len--;
-+        /* consts handled by cpp */
-+        /* nothing... */
-+      }
-+      else if (GET_CODE (op[1]) == ZERO_EXTEND)
-+      {
-+        rtx ops[10];
-+        ops[0] = op[0];
-+        ops[1] = XEXP (op[1], 0);
-+
-+        if (GET_MODE (ops[1]) == QImode)
-+          {
-+            if (GET_MODE (ops[0]) == HImode)
-+              zeroextendqihi (insn, ops, &len);
-+            else if (GET_MODE (ops[0]) == SImode)
-+              zeroextendqisi (insn, ops, &len);
-+            else if (GET_MODE (ops[0]) == DImode)
-+              zeroextendqidi (insn, ops, &len);
-+          }
-+        else if (GET_MODE (ops[1]) == HImode)
-+          {
-+            if (GET_MODE (ops[0]) == SImode)
-+              zeroextendhisi (insn, ops, &len);
-+            else if (GET_MODE (ops[0]) == DImode)
-+              zeroextendhidi (insn, ops, &len);
-+          }
-+        else if (GET_MODE (ops[1]) == SImode)
-+          {
-+            if (GET_MODE (ops[1]) == DImode)
-+              zeroextendsidi (insn, ops, &len);
-+          }
-+      }
-+      else if (GET_CODE (op[1]) == SIGN_EXTEND)
-+      {
-+        rtx ops[10];
-+        ops[0] = op[0];       /* dest */
-+        ops[1] = XEXP (op[1], 0);     /* src */
-+
-+        if (GET_MODE (ops[1]) == QImode)
-+          {
-+            if (GET_MODE (ops[0]) == HImode)
-+              signextendqihi (insn, ops, &len);
-+            else if (GET_MODE (ops[0]) == SImode)
-+              signextendqisi (insn, ops, &len);
-+            else if (GET_MODE (ops[0]) == DImode)
-+              signextendqidi (insn, ops, &len);
-+          }
-+        else if (GET_MODE (ops[1]) == HImode)
-+          {
-+            if (GET_MODE (ops[0]) == SImode)
-+              signextendhisi (insn, ops, &len);
-+            else if (GET_MODE (ops[0]) == DImode)
-+              signextendhidi (insn, ops, &len);
-+          }
-+        else if (GET_MODE (ops[1]) == SImode)
-+          {
-+            if (GET_MODE (ops[0]) == DImode)
-+              signextendsidi (insn, ops, &len);
-+          }
-+      }
-+      else if (GET_CODE (op[1]) == IF_THEN_ELSE)
-+      {
-+        if (GET_CODE (op[0]) == PC)
-+          {
-+            rtx ops[5];
-+            ops[0] = XEXP (op[1], 1);
-+            ops[1] = XEXP (op[1], 0);
-+            ops[2] = XEXP (ops[1], 0);
-+            ops[3] = XEXP (ops[1], 1);
-+            msp430_cbranch (insn, ops, &len);
-+          }
-+      }
-+      else if (GET_CODE (op[0]) == MEM
-+             && GET_CODE (XEXP (op[0], 0)) == POST_DEC)
-+      {
-+        rtx ops[4];
-+        ops[0] = op[1];
-+        if (GET_MODE (op[0]) == QImode)
-+          msp430_pushqi (insn, ops, &len);
-+        if (GET_MODE (op[0]) == HImode)
-+          msp430_pushhi (insn, ops, &len);
-+        if (GET_MODE (op[0]) == SImode)
-+          msp430_pushsisf (insn, ops, &len);
-+        if (GET_MODE (op[0]) == DImode)
-+          msp430_pushdi (insn, ops, &len);
-+      }
-+    }
-+
-+  if (set)
-+    {
-+      rtx op[10];
-+      op[1] = SET_SRC (set);
-+      op[0] = SET_DEST (set);
-+
-+      if (GET_CODE (patt) == PARALLEL)
-+      {
-+        if (GET_CODE (op[0]) == PC && GET_CODE (op[1]) == IF_THEN_ELSE)
-+          {
-+            rtx ops[5];
-+            ops[0] = XEXP (op[1], 1);
-+            ops[1] = XEXP (op[1], 0);
-+            ops[2] = XEXP (ops[1], 0);
-+            ops[3] = XEXP (ops[1], 1);
-+            msp430_cbranch (insn, ops, &len);
-+          }
-+
-+        if (GET_CODE (op[1]) == ASHIFT
-+            || GET_CODE (op[1]) == ASHIFTRT || GET_CODE (op[1]) == LSHIFTRT)
-+          {
-+            rtx ops[10];
-+            ops[0] = op[0];
-+            ops[1] = XEXP (op[1], 0);
-+            ops[2] = XEXP (op[1], 1);
-+
-+            switch (GET_CODE (op[1]))
-+              {
-+              case ASHIFT:
-+                switch (GET_MODE (op[0]))
-+                  {
-+                  case QImode:
-+                    msp430_emit_ashlqi3 (insn, ops, &len);
-+                    break;
-+                  case HImode:
-+                    msp430_emit_ashlhi3 (insn, ops, &len);
-+                    break;
-+                  case SImode:
-+                    msp430_emit_ashlsi3 (insn, ops, &len);
-+                    break;
-+                  case DImode:
-+                    msp430_emit_ashldi3 (insn, ops, &len);
-+                    break;
-+                  default:
-+                    break;
-+                  }
-+                break;
-+
-+              case ASHIFTRT:
-+                switch (GET_MODE (op[0]))
-+                  {
-+                  case QImode:
-+                    msp430_emit_ashrqi3 (insn, ops, &len);
-+                    break;
-+                  case HImode:
-+                    msp430_emit_ashrhi3 (insn, ops, &len);
-+                    break;
-+                  case SImode:
-+                    msp430_emit_ashrsi3 (insn, ops, &len);
-+                    break;
-+                  case DImode:
-+                    msp430_emit_ashrdi3 (insn, ops, &len);
-+                    break;
-+                  default:
-+                    break;
-+                  }
-+                break;
-+
-+              case LSHIFTRT:
-+                switch (GET_MODE (op[0]))
-+                  {
-+                  case QImode:
-+                    msp430_emit_lshrqi3 (insn, ops, &len);
-+                    break;
-+                  case HImode:
-+                    msp430_emit_lshrhi3 (insn, ops, &len);
-+                    break;
-+                  case SImode:
-+                    msp430_emit_lshrsi3 (insn, ops, &len);
-+                    break;
-+                  case DImode:
-+                    msp430_emit_lshrdi3 (insn, ops, &len);
-+                    break;
-+                  default:
-+                    break;
-+                  }
-+                break;
-+
-+              default:
-+                break;
-+              }
-+          }
-+      }
-+    }
-+
-+  return len;
-+}
-+
-+
-+/* Output all insn addresses and their sizes into the assembly language
-+   output file.  This is helpful for debugging whether the length attributes
-+      in the md file are correct.
-+         Output insn cost for next insn.  */
-+
-+void
-+final_prescan_insn (insn, operand, num_operands)
-+     rtx insn, *operand ATTRIBUTE_UNUSED;
-+     int num_operands ATTRIBUTE_UNUSED;
-+{
-+  int uid = INSN_UID (insn);
-+
-+  if (TARGET_ALL_DEBUG)
-+    {
-+      fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
-+             INSN_ADDRESSES (uid),
-+             INSN_ADDRESSES (uid) - last_insn_address,
-+             rtx_cost (PATTERN (insn), INSN));
-+    }
-+  last_insn_address = INSN_ADDRESSES (uid);
-+}
-+
-+void
-+msp430_output_addr_vec_elt (stream, value)
-+     FILE *stream;
-+     int value;
-+{
-+  fprintf (stream, "\t.word   .L%d\n", value);
-+  jump_tables_size++;
-+}
-+
-+
-+void
-+machine_dependent_reorg (first_insn)
-+     rtx first_insn ATTRIBUTE_UNUSED;
-+{
-+  /* nothing to be done here this time */
-+  return;
-+}
-+
-+
-+int
-+test_hard_reg_class (class, x)
-+     enum reg_class class;
-+     rtx x;
-+{
-+  int regno = true_regnum (x);
-+  if (regno < 0)
-+    return 0;
-+  return TEST_HARD_REG_CLASS (class, regno);
-+}
-+
-+
-+/* Returns 1 if SCRATCH are safe to be allocated as a scratch
-+   registers (for a define_peephole2) in the current function.  */
-+/* UNUSED ... yet... */
-+int
-+msp430_peep2_scratch_safe (scratch)
-+     rtx scratch;
-+{
-+  if ((interrupt_function_p (current_function_decl)
-+       || signal_function_p (current_function_decl)) && leaf_function_p ())
-+    {
-+      int first_reg = true_regnum (scratch);
-+      int last_reg;
-+      int size = GET_MODE_SIZE (GET_MODE (scratch));
-+      int reg;
-+
-+      size >>= 1;
-+      if (!size)
-+      size = 1;
-+
-+      last_reg = first_reg + size - 1;
-+
-+      for (reg = first_reg; reg <= last_reg; reg++)
-+      {
-+        if (!regs_ever_live[reg])
-+          return 0;
-+      }
-+    }
-+
-+  return 1;
-+}
-+
-+
-+/* Update the condition code in the INSN.
-+  now mostly unused */
-+
-+void
-+notice_update_cc (body, insn)
-+     rtx body ATTRIBUTE_UNUSED;
-+     rtx insn ATTRIBUTE_UNUSED;
-+{
-+  CC_STATUS_INIT;
-+}
-+
-+
-+
-+/*********************************************************************/
-+
-+/*
-+     Next two return non zero for rtx as
-+     (set (reg:xx)
-+        (mem:xx (reg:xx))
-+ 
-+*/
-+
-+int
-+regsi_ok_safe (operands)
-+     rtx operands[];
-+{
-+  rtx dest = operands[0];
-+  rtx areg;
-+  int src_reg;
-+  int dst_reg;
-+
-+  if (operands[2])
-+    areg = XEXP (operands[2], 0);
-+  else
-+    areg = XEXP (operands[1], 0);
-+
-+  if (GET_CODE (dest) == MEM)
-+    {
-+      dest = XEXP (operands[0], 0);
-+      if (GET_CODE (dest) == PLUS && GET_CODE (XEXP (dest, 0)) == REG)
-+      {
-+        dest = XEXP (dest, 0);
-+      }
-+      else if (GET_CODE (dest) == REG)
-+      {
-+        ;                     /* register */
-+      }
-+      else
-+      return 1;
-+    }
-+
-+  if (REGNO (dest) >= FIRST_PSEUDO_REGISTER
-+      || REGNO (areg) >= FIRST_PSEUDO_REGISTER)
-+    return 1;
-+
-+  dst_reg = true_regnum (dest);
-+  src_reg = true_regnum (areg);
-+  if (dst_reg > src_reg || dst_reg + 1 < src_reg)
-+    {
-+      return 1;
-+    }
-+  return 0;
-+}
-+
-+int
-+regsi_ok_clobber (operands)
-+     rtx operands[];
-+{
-+  rtx dest = operands[0];
-+  rtx areg = XEXP (operands[2], 0);
-+  int src_reg;
-+  int dst_reg;
-+  int regno = REGNO (dest);
-+
-+
-+  if (GET_CODE (dest) == MEM)
-+    {
-+      dest = XEXP (operands[0], 0);
-+      if (GET_CODE (dest) == PLUS && GET_CODE (XEXP (dest, 0)) == REG)
-+      {
-+        dest = XEXP (dest, 0);
-+      }
-+      else if (GET_CODE (dest) == REG)
-+      {
-+        ;                     /* register */
-+      }
-+      else
-+      return 1;
-+    }
-+
-+  if (regno >= FIRST_PSEUDO_REGISTER || REGNO (areg) >= FIRST_PSEUDO_REGISTER)
-+    return 1;
-+
-+  dst_reg = true_regnum (dest);
-+  src_reg = true_regnum (areg);
-+  if (dst_reg + 1 == src_reg)
-+    return 1;
-+  return 0;
-+}
-+
-+int
-+regdi_ok_safe (operands)
-+     rtx operands[];
-+{
-+  rtx dest = operands[0];
-+  rtx areg = XEXP (operands[2], 0);
-+  int src_reg;
-+  int dst_reg;
-+
-+
-+  if (GET_CODE (dest) == MEM)
-+    {
-+      dest = XEXP (operands[0], 0);
-+      if (GET_CODE (dest) == PLUS && GET_CODE (XEXP (dest, 0)) == REG)
-+      {
-+        dest = XEXP (dest, 0);
-+      }
-+      else if (GET_CODE (dest) == REG)
-+      {
-+        ;                     /* register */
-+      }
-+      else
-+      return 1;
-+    }
-+
-+  if (REGNO (dest) >= FIRST_PSEUDO_REGISTER
-+      || REGNO (areg) >= FIRST_PSEUDO_REGISTER)
-+    return 1;
-+
-+  dst_reg = true_regnum (dest);
-+  src_reg = true_regnum (areg);
-+  if (dst_reg > src_reg || dst_reg + 3 < src_reg)
-+    {
-+      return 1;
-+    }
-+
-+  return 0;
-+}
-+
-+int
-+regdi_ok_clobber (operands)
-+     rtx operands[];
-+{
-+  rtx dest = operands[0];
-+  rtx areg = XEXP (operands[2], 0);
-+  int src_reg;
-+  int dst_reg;
-+  int regno = REGNO (dest);
-+
-+  if (GET_CODE (dest) == MEM)
-+    {
-+      dest = XEXP (operands[0], 0);
-+      if (GET_CODE (dest) == PLUS && GET_CODE (XEXP (dest, 0)) == REG)
-+      {
-+        dest = XEXP (dest, 0);
-+      }
-+      else if (GET_CODE (dest) == REG)
-+      {
-+        ;                     /* register */
-+      }
-+      else
-+      return 1;
-+    }
-+
-+  if (regno >= FIRST_PSEUDO_REGISTER || REGNO (areg) >= FIRST_PSEUDO_REGISTER)
-+    return 1;
-+
-+  dst_reg = true_regnum (dest);
-+  src_reg = true_regnum (areg);
-+  if (dst_reg + 3 == src_reg)
-+    return 1;
-+  return 0;
-+}
-+
-+
-+/***************** ARITHMETIC *******************/
-+
-+int
-+emit_indexed_arith (insn, operands, m, cmd, iscarry)
-+     rtx insn;
-+     rtx operands[];
-+     int m;
-+     const char *cmd;
-+     int iscarry;
-+{
-+  char template[256];
-+  register int i = 0;
-+  char *p;
-+  rtx reg = NULL;
-+  int len = m * 2;
-+  rtx x = operands[0];
-+  int havestop = 0;
-+  rtx pattern;
-+  rtx next = next_real_insn (insn);
-+
-+
-+  pattern = PATTERN (next);
-+
-+  if (pattern && GET_CODE (pattern) == PARALLEL)
-+    {
-+      pattern = XVECEXP (pattern, 0, 0);
-+    }
-+
-+  if (followed_compare_condition (insn) != UNKNOWN
-+      || GET_CODE(insn) == JUMP_INSN
-+      || (pattern
-+        && GET_CODE (pattern) == SET
-+        && SET_DEST (pattern) == cc0_rtx)
-+      || (pattern && GET_CODE (pattern) == SET
-+        && SET_DEST (pattern) == pc_rtx))
-+    {
-+      /* very exotic case */
-+
-+      snprintf (template, 255, "%s\t" "%%A%d, %%A0", cmd, operands[2] ? 2 : 1);
-+      output_asm_insn (template, operands);
-+      snprintf (template, 255, "%s%s\t" "%%B%d, %%B0", cmd, iscarry ? "c" : "",
-+              operands[2] ? 2 : 1);
-+      output_asm_insn (template, operands);
-+
-+      if (m == 2)
-+      return len;
-+
-+      snprintf (template, 255, "%s%s\t" "%%C%d, %%C0", cmd, iscarry ? "c" : "",
-+              operands[2] ? 2 : 1);
-+      output_asm_insn (template, operands);
-+      snprintf (template, 255, "%s%s\t" "%%D%d, %%D0", cmd, iscarry ? "c" : "",
-+              operands[2] ? 2 : 1);
-+      output_asm_insn (template, operands);
-+
-+      return len;
-+    }
-+
-+  if (operands[2])
-+    reg = XEXP (operands[2], 0);
-+  else
-+    reg = XEXP (operands[1], 0);
-+
-+  if (GET_CODE (x) == REG)
-+    {
-+      int src;
-+      int dst = REGNO (x);
-+
-+      if (!reg)
-+      {
-+        reg = XEXP (operands[1], 0);
-+      }
-+
-+      src = REGNO (reg);
-+
-+      /* check if registers overlap */
-+      if (dst > src || (dst + m - 1) < src)
-+      {
-+        ;                     /* fine ! */
-+      }
-+      else if ((dst + m - 1) == src)
-+      {
-+        havestop = 1;         /* worse */
-+      }
-+      else
-+      {
-+        /* cannot do reverse assigment */
-+        while (i < m)
-+          {
-+            p = (char *) (template + strlen (cmd));
-+            p += (i && iscarry) ? 3 : 2;
-+            strcpy (template, cmd);
-+            strcat (template, (i && iscarry) ? "c\t%" : "\t%");
-+            *p = 'A' + i;
-+            p++;
-+            *p = 0;
-+            strcat (template, "0, %");
-+            p += 2;
-+            *p = 'A' + i;
-+            p++;
-+            *p = 0;
-+            strcat (template, operands[2] ? "2" : "1");
-+            output_asm_insn (template, operands);
-+            i++;
-+          }
-+        return m * 3;
-+      }
-+    }
-+
-+  while (i < (m - havestop))
-+    {
-+      p = template + strlen (cmd);
-+
-+      strcpy (template, cmd);
-+
-+      if (i && iscarry)
-+      {
-+        strcat (template, "c\t");
-+        p += 2;
-+      }
-+      else
-+      {
-+        strcat (template, "\t");
-+        p += 1;
-+      }
-+      strcat (template, operands[2] ? "@%E2+, %" : "@%E1+, %");
-+      p += 8;
-+      *p = 'A' + i;
-+      p++;
-+      *p = 0;
-+      strcat (template, "0");
-+      p++;
-+      output_asm_insn (template, operands);
-+      i++;
-+    }
-+
-+  if (havestop)
-+    {
-+      len++;
-+      p = template + strlen (cmd);
-+      strcpy (template, cmd);
-+      if (i && iscarry)
-+      {
-+        strcat (template, "c\t");
-+        p += 2;
-+      }
-+      else
-+      {
-+        strcat (template, "\t");
-+        p += 1;
-+      }
-+      strcat (template, operands[2] ? "@%E2, %" : "@%E1, %");
-+      p += 8;
-+      *p = 'A' + i;
-+      p++;
-+      *p = 0;
-+      strcat (template, "0    ;       register won't die");
-+      p += 1;
-+      output_asm_insn (template, operands);
-+    }
-+
-+  if (!dead_or_set_p (insn, reg) && !havestop)
-+    {
-+      len++;
-+      p = template + 3;
-+      strcpy (template, "sub");
-+      strcat (template, "\t#");
-+      p += 2;
-+      *p = '0' + m * 2;
-+      p++;
-+      *p = 0;
-+
-+      if (operands[2])
-+      strcat (template, ",    %E2     ;       restore %E2");
-+      else
-+      strcat (template, ",    %E1     ;       restore %E1");
-+      output_asm_insn (template, operands);
-+    }
-+
-+  return len;
-+}
-+
-+static int sameoperand_p PARAMS ((rtx, rtx));
-+
-+int
-+sameoperand (operands, i)
-+     rtx operands[];
-+     int i;
-+{
-+  rtx dst = operands[0];
-+  rtx src = operands[i];
-+
-+  return sameoperand_p (src, dst);
-+}
-+
-+static int
-+sameoperand_p (src, dst)
-+     rtx src;
-+     rtx dst;
-+{
-+  enum rtx_code scode = GET_CODE (src);
-+  enum rtx_code dcode = GET_CODE (dst);
-+  /* cannot use standard functions here 
-+     cause operands have different modes:
-+   */
-+
-+  if (scode != dcode)
-+    return 0;
-+
-+  switch (scode)
-+    {
-+    case REG:
-+      return REGNO (src) == REGNO (dst);
-+      break;
-+    case MEM:
-+      return sameoperand_p (XEXP (src, 0), XEXP (dst, 0));
-+      break;
-+    case PLUS:
-+      return sameoperand_p (XEXP (src, 0), XEXP (dst, 0))
-+        && sameoperand_p (XEXP (src, 1), XEXP (dst, 1));
-+      break;
-+    case CONST_INT:
-+      return INTVAL (src) == INTVAL (dst);
-+      break;
-+    case SYMBOL_REF:
-+      return XSTR (src, 0) == XSTR (dst, 0);
-+      break;
-+    default:
-+      break;
-+    }
-+  return 0;
-+
-+}
-+
-+#define OUT_INSN(x,p,o) \
-+do {                            \
-+if(!x) output_asm_insn (p,o);   \
-+} while(0)
-+
-+
-+
-+/************** MOV CODE *********************************/
-+
-+const char *
-+movstrsi_insn (insn, operands, l)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+
-+  /* operands 0 and 1 are registers !!! */
-+  /* operand 2 is a cnt and not zero */
-+  output_asm_insn ("\n.Lmsn%=:", operands);
-+  output_asm_insn ("mov.b\t@%1+,0(%0)", operands);
-+  output_asm_insn ("inc\t%0", operands);
-+  output_asm_insn ("dec\t%2", operands);
-+  output_asm_insn ("jnz\t.Lmsn%=", operands);
-+
-+  return "";
-+}
-+
-+
-+const char *
-+clrstrsi_insn (insn, operands, l)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+
-+  /* operand 0 is a register !!! */
-+  /* operand 1 is a cnt and not zero */
-+  output_asm_insn ("\n.Lcsn%=:", operands);
-+  output_asm_insn ("clr.b\t0(%0)      ;       clr does not support @rn+",
-+                 operands);
-+  output_asm_insn ("inc\t%0", operands);
-+  output_asm_insn ("dec\t%1", operands);
-+  output_asm_insn ("jnz\t.Lcsn%=", operands);
-+  return "";
-+}
-+
-+const char *
-+movstrhi_insn (insn, operands, l)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+
-+  /* operands 0 and 1 are registers !!! */
-+  /* operand 2 is a cnt and not zero */
-+  output_asm_insn ("\n.Lmsn%=:", operands);
-+  output_asm_insn ("mov.b\t@%1+,0(%0)", operands);
-+  output_asm_insn ("inc\t%0", operands);
-+  output_asm_insn ("dec\t%2", operands);
-+  output_asm_insn ("jnz\t.Lmsn%=", operands);
-+  return "";
-+}
-+
-+const char *
-+clrstrhi_insn (insn, operands, l)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+
-+  /* operand 0 is a register !!! */
-+  /* operand 1 is a cnt and not zero */
-+  output_asm_insn ("\n.Lcsn%=:", operands);
-+  output_asm_insn ("clr.b\t0(%0)", operands);
-+  output_asm_insn ("inc\t%0", operands);
-+  output_asm_insn ("dec\t%1", operands);
-+  output_asm_insn ("jnz\t.Lcsn%=", operands);
-+  return "";
-+}
-+
-+int
-+msp430_emit_indexed_mov (insn, operands, m, cmd)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int m;
-+     const char *cmd;
-+{
-+  char template[256];
-+  register int i = 0;
-+  char *p;
-+  rtx reg = XEXP (operands[1], 0);
-+  int len = m * 2;
-+  rtx dst = 0;
-+  int sreg,dreg = 0;
-+
-+  if(memory_operand(operands[0], VOIDmode))
-+    {
-+      if(  REG_P(XEXP(operands[0],0)))
-+      dreg = REGNO(XEXP(operands[0],0));
-+      else if(GET_CODE(XEXP(operands[0],0)) == PLUS
-+        && REG_P(XEXP(XEXP(operands[0],0),0)) )
-+      dreg = REGNO(XEXP(XEXP(operands[0],0),0));
-+    }
-+
-+  
-+  sreg = REGNO(XEXP(operands[1],0));
-+  
-+  while (i < m)
-+    {
-+      p = template + strlen (cmd);
-+
-+      strcpy (template, cmd);
-+      strcat (template, "\t");
-+      p += 1;
-+      strcat (template, "@%E1+, ");
-+      p += 7;
-+      
-+      if(dreg==sreg)
-+      {
-+      *p = '-'; p++;
-+      *p = '2'; p++;
-+      *p = '+'; p++;
-+      }
-+
-+      *p = '%'; p++;
-+      *p = 'A' + ((dreg==sreg)?0:i);
-+      
-+      p++;
-+      *p = 0;
-+      strcat (template, "0");
-+      p += 1;
-+      output_asm_insn (template, operands);
-+      i++;
-+    }
-+
-+  if (!dead_or_set_p (insn, reg))
-+    {
-+      len++;
-+      p = template + 3;
-+      strcpy (template, "sub");
-+      strcat (template, "\t#");
-+      p += 2;
-+      *p = '0' + m * 2;
-+      p++;
-+      *p = 0;
-+      strcat (template, ",    %E1     ;       restore %E1");
-+      output_asm_insn (template, operands);
-+    }
-+
-+  return len;
-+}
-+
-+const char *
-+msp430_emit_indexed_mov2 (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+  msp430_emit_indexed_mov (insn, operands, 2, "mov");
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_indexed_mov4 (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+  msp430_emit_indexed_mov (insn, operands, 4, "mov");
-+  return "";
-+}
-+
-+const char *
-+movsisf_regmode (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+  rtx dest = operands[0];
-+  rtx src = operands[1];
-+  rtx areg = XEXP (src, 0);
-+  int src_reg = true_regnum (areg);
-+  int dst_reg = true_regnum (dest);
-+
-+
-+  if (dst_reg > src_reg || dst_reg + 1 < src_reg)
-+    {
-+      output_asm_insn ("mov\t@%E1+, %A0", operands);
-+      output_asm_insn ("mov\t@%E1+, %B0", operands);
-+      if (!dead_or_set_p (insn, areg))
-+      {
-+        output_asm_insn ("sub\t#4, %E1\t;\trestore %E1", operands);
-+      }
-+      return "";
-+    }
-+  else if (dst_reg + 1 == src_reg)
-+    {
-+      output_asm_insn ("mov\t@%E1+, %A0", operands);
-+      output_asm_insn ("mov\t@%E1, %B0", operands);
-+      return "";
-+    }
-+  else
-+    {
-+      /* destination overlaps with source.
-+         so, update destination in reverse way */
-+      output_asm_insn ("mov\t%B1, %B0", operands);
-+      output_asm_insn ("mov\t@%E1, %A0", operands);
-+    }
-+
-+  return "";                  /* make compiler happy */
-+}
-+
-+
-+/* From Max Behensky <maxb@twinlanes.com>  
-+   This function tells you what the index register in an operand is.  It
-+   returns the register number, or -1 if it is not an indexed operand */
-+static int get_indexed_reg PARAMS ((rtx));
-+static int
-+get_indexed_reg (x)
-+     rtx x;
-+{
-+  int code;
-+
-+  code = GET_CODE (x);
-+
-+  if (code != MEM)
-+    return (-1);
-+
-+  x = XEXP (x, 0);
-+  code = GET_CODE (x);
-+  if (code == REG)
-+    return (REGNO (x));
-+
-+  if (code != PLUS)
-+    return (-1);
-+
-+  x = XEXP (x, 0);
-+  code = GET_CODE (x);
-+  if (code != REG)
-+    return (-1);
-+
-+  return (REGNO (x));
-+}
-+
-+
-+const char *
-+msp430_movesi_code (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  rtx op0 = operands[0];
-+  rtx op1 = operands[1];
-+
-+
-+  if (memory_operand (op0, VOIDmode)
-+      && memory_operand (op1, VOIDmode) && zero_shifted (op1))
-+    {
-+      if (!len)
-+      msp430_emit_indexed_mov2 (insn, operands, NULL);
-+      else
-+      *len = 5;
-+      return "";
-+    }
-+  else if (register_operand (op0, VOIDmode)
-+         && memory_operand (op1, VOIDmode) && zero_shifted (op1))
-+    {
-+      if (!len)
-+      movsisf_regmode (insn, operands, NULL);
-+      else
-+      *len = 3;
-+      return "";
-+    }
-+
-+  if (!len)
-+    {
-+      if ((register_operand (op0, VOIDmode)
-+         && register_operand (op1, VOIDmode)
-+         && REGNO (op1) + 1 == REGNO (op0))
-+        || (register_operand (op0, VOIDmode)
-+            && memory_operand (op1, VOIDmode)
-+            && get_indexed_reg (op1) == true_regnum (op0)))
-+      {
-+        output_asm_insn ("mov\t%B1, %B0", operands);
-+        output_asm_insn ("mov\t%A1, %A0", operands);
-+      }
-+      else
-+      {
-+        output_asm_insn ("mov\t%A1, %A0", operands);
-+        output_asm_insn ("mov\t%B1, %B0", operands);
-+      }
-+    }
-+  else
-+    {
-+      *len = 2;                       /* base length */
-+
-+      if (register_operand (op0, VOIDmode))
-+      *len += 0;
-+      else if (memory_operand (op0, VOIDmode))
-+      *len += 2;
-+
-+      if (register_operand (op1, VOIDmode))
-+      *len += 0;
-+      else if (memory_operand (op1, VOIDmode))
-+      *len += 2;
-+      else if (immediate_operand (op1, VOIDmode))
-+      *len += 2;
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+movdidf_regmode (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+  rtx dest = operands[0];
-+  rtx src = operands[1];
-+  rtx areg = XEXP (src, 0);
-+
-+  int src_reg = true_regnum (areg);
-+  int dst_reg = true_regnum (dest);
-+
-+
-+  if (dst_reg > src_reg || dst_reg + 3 < src_reg)
-+    {
-+      output_asm_insn ("mov\t@%E1+, %A0", operands);
-+      output_asm_insn ("mov\t@%E1+, %B0", operands);
-+      output_asm_insn ("mov\t@%E1+, %C0", operands);
-+      output_asm_insn ("mov\t@%E1+, %D0", operands);
-+      if (!dead_or_set_p (insn, areg))
-+      {
-+        output_asm_insn ("sub\t#8, %E1\t;\trestore %E1", operands);
-+      }
-+    }
-+  else if (dst_reg + 3 == src_reg)
-+    {
-+      output_asm_insn ("mov\t@%E1+, %A0", operands);
-+      output_asm_insn ("mov\t@%E1+, %B0", operands);
-+      output_asm_insn ("mov\t@%E1+, %C0", operands);
-+      output_asm_insn ("mov\t@%E1,  %D0       ;       %E1 == %D0", operands);
-+    }
-+  else
-+    {
-+      /* destination overlaps source.
-+         so, update destination in reverse way */
-+      output_asm_insn ("mov\t%D1, %D0 ; %E1 overlaps wit one of %A0 - %D0",
-+                     operands);
-+      output_asm_insn ("mov\t%C1, %C0", operands);
-+      output_asm_insn ("mov\t%B1, %B0", operands);
-+      output_asm_insn ("mov\t@%E1, %A0", operands);
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_movedi_code (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  rtx op0 = operands[0];
-+  rtx op1 = operands[1];
-+
-+  if (memory_operand (op0, DImode)
-+      && memory_operand (op1, DImode) && zero_shifted (op1))
-+    {
-+      if (!len)
-+      msp430_emit_indexed_mov4 (insn, operands, NULL);
-+      else
-+      *len = 9;
-+      return "";
-+    }
-+  else if (register_operand (op0, DImode)
-+         && memory_operand (op1, DImode) && zero_shifted (op1))
-+    {
-+      if (!len)
-+      movdidf_regmode (insn, operands, NULL);
-+      else
-+      *len = 5;
-+      return "";
-+    }
-+
-+  if (!len)
-+    {
-+      if (register_operand (op0, SImode)
-+        && register_operand (op1, SImode) && REGNO (op1) + 3 == REGNO (op0))
-+      {
-+        output_asm_insn ("mov\t%D1, %D0", operands);
-+        output_asm_insn ("mov\t%C1, %C0", operands);
-+        output_asm_insn ("mov\t%B1, %B0", operands);
-+        output_asm_insn ("mov\t%A1, %A0", operands);
-+      }
-+      else
-+      {
-+        output_asm_insn ("mov\t%A1, %A0", operands);
-+        output_asm_insn ("mov\t%B1, %B0", operands);
-+        output_asm_insn ("mov\t%C1, %C0", operands);
-+        output_asm_insn ("mov\t%D1, %D0", operands);
-+      }
-+    }
-+  else
-+    {
-+      *len = 4;                       /* base length */
-+
-+      if (register_operand (op0, DImode))
-+      *len += 0;
-+      else if (memory_operand (op0, DImode))
-+      *len += 4;
-+
-+      if (register_operand (op1, DImode))
-+      *len += 0;
-+      else if (memory_operand (op1, DImode))
-+      *len += 4;
-+      else if (immediate_operand (op1, DImode))
-+      *len += 4;
-+    }
-+
-+  return "";
-+}
-+
-+
-+
-+
-+/**************       ADD CODE *********************************/
-+
-+
-+const char *
-+msp430_emit_indexed_add2 (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+  emit_indexed_arith (insn, operands, 2, "add", 1);
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_indexed_add4 (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+  emit_indexed_arith (insn, operands, 4, "add", 1);
-+  return "";
-+}
-+
-+const char *
-+msp430_addsi_code (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  rtx op0 = operands[0];
-+  rtx op2 = operands[2];
-+  rtx ops[4];
-+
-+  if (memory_operand (op2, SImode)
-+      && zero_shifted (operands[2]) && regsi_ok_safe (operands))
-+    {
-+      if (!len)
-+      msp430_emit_indexed_add2 (insn, operands, NULL);
-+      else
-+      {
-+        if (memory_operand (op0, SImode))
-+          *len = 5;
-+        else if (register_operand (op0, SImode))
-+          *len = 3;
-+      }
-+      return "";
-+    }
-+  else if (memory_operand (op2, SImode)
-+         && zero_shifted (operands[2]) && regsi_ok_clobber (operands))
-+    {
-+      if (!len)
-+      {
-+        output_asm_insn ("add\t@%E2+, %A0", operands);
-+        output_asm_insn ("addc\t@%E2+, %B0", operands);
-+      }
-+      else
-+      {
-+        if (register_operand (op0, SImode))
-+          *len = 2;
-+        else if (memory_operand (op0, SImode))
-+          *len = 4;
-+        else
-+          abort ();
-+      }
-+      return "";
-+    }
-+
-+  ops[0] = operands[0];
-+  ops[2] = operands[2];
-+
-+  if (!len)
-+    {
-+      output_asm_insn ("add\t%A2, %A0", ops);
-+      output_asm_insn ("addc\t%B2, %B0", ops);
-+    }
-+
-+  if (len)
-+    {
-+      *len = 2;                       /* base length */
-+
-+      if (register_operand (ops[0], SImode))
-+      *len += 0;
-+      else if (memory_operand (ops[0], SImode))
-+      *len += 2;
-+
-+      if (register_operand (ops[2], SImode))
-+      *len += 0;
-+      else if (memory_operand (ops[2], SImode))
-+      *len += 2;
-+      else if (immediate_operand (ops[2], SImode))
-+      {
-+        int x = INTVAL (ops[2]);
-+        if (x == -2 || x == -4 || x == -8)
-+          {
-+            *len += 1;
-+          }
-+        else
-+          *len += 2;
-+      }
-+    }
-+  return "";
-+}
-+
-+const char *
-+msp430_adddi_code (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  rtx op0 = operands[0];
-+  rtx op2 = operands[2];
-+
-+  if (memory_operand (op2, DImode)
-+      && zero_shifted (operands[2]) && regdi_ok_safe (operands))
-+    {
-+      if (!len)
-+      msp430_emit_indexed_add4 (insn, operands, NULL);
-+      else
-+      {
-+        if (memory_operand (op0, DImode))
-+          *len = 9;
-+        else if (register_operand (op0, DImode))
-+          *len = 5;
-+      }
-+
-+      return "";
-+    }
-+  else if (memory_operand (op2, DImode)
-+         && zero_shifted (operands[2]) && regdi_ok_clobber (operands))
-+    {
-+      if (!len)
-+      {
-+        output_asm_insn ("add\t@%E2+, %A0", operands);
-+        output_asm_insn ("addc\t@%E2+, %B0", operands);
-+        output_asm_insn ("addc\t@%E2+, %C0", operands);
-+        output_asm_insn ("addc\t@%E2+, %D0", operands);
-+      }
-+      else
-+      {
-+        if (register_operand (op0, DImode))
-+          *len = 4;
-+        else if (memory_operand (op0, DImode))
-+          *len = 8;
-+        else
-+          abort ();
-+      }
-+      return "";
-+    }
-+
-+  if (!len)
-+    {
-+      output_asm_insn ("add\t%A2, %A0", operands);
-+      output_asm_insn ("addc\t%B2, %B0", operands);
-+      output_asm_insn ("addc\t%C2, %C0", operands);
-+      output_asm_insn ("addc\t%D2, %D0", operands);
-+    }
-+  else
-+    {
-+      *len = 4;                       /* base length */
-+
-+      if (register_operand (op0, DImode))
-+      *len += 0;
-+      else if (memory_operand (op0, DImode))
-+      *len += 4;
-+
-+      if (register_operand (op2, DImode))
-+      *len += 0;
-+      else if (memory_operand (op2, DImode))
-+      *len += 4;
-+      else if (immediate_operand (op2, DImode))
-+      {
-+        int x = INTVAL (op2);
-+
-+        if (x == -2 || x == -4 || x == -8)
-+          *len += 0;
-+        else
-+          *len += 4;
-+      }
-+      else
-+      abort ();
-+    }
-+
-+  return "";
-+}
-+
-+
-+/**************       SUB CODE *********************************/
-+
-+const char *
-+msp430_emit_indexed_sub2 (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+  emit_indexed_arith (insn, operands, 2, "sub", 1);
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_indexed_sub4 (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+  emit_indexed_arith (insn, operands, 4, "sub", 1);
-+  return "";
-+}
-+
-+const char *
-+msp430_subsi_code (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  rtx op0 = operands[0];
-+  rtx op2 = operands[2];
-+
-+  if (memory_operand (op2, SImode)
-+      && zero_shifted (operands[2]) && regsi_ok_safe (operands))
-+    {
-+      if (!len)
-+      msp430_emit_indexed_sub2 (insn, operands, NULL);
-+      else
-+      {
-+        if (memory_operand (op0, SImode))
-+          *len = 5;
-+        else if (register_operand (op0, SImode))
-+          *len = 3;
-+      }
-+
-+      return "";
-+    }
-+  else if (memory_operand (op2, SImode)
-+         && zero_shifted (operands[2]) && regsi_ok_clobber (operands))
-+    {
-+      if (!len)
-+      {
-+        output_asm_insn ("sub\t@%E2+, %A0", operands);
-+        output_asm_insn ("subc\t@%E2+, %B0", operands);
-+      }
-+      else
-+      {
-+        if (register_operand (op0, SImode))
-+          *len = 2;
-+        else if (memory_operand (op0, SImode))
-+          *len = 4;
-+        else
-+          abort ();
-+      }
-+      return "";
-+    }
-+
-+  if (!len)
-+    {
-+      output_asm_insn ("sub\t%A2, %A0", operands);
-+      output_asm_insn ("subc\t%B2, %B0", operands);
-+    }
-+  else
-+    {
-+      *len = 2;                       /* base length */
-+
-+      if (register_operand (op0, SImode))
-+      *len += 0;
-+      else if (memory_operand (op0, SImode))
-+      *len += 2;
-+
-+      if (register_operand (op2, SImode))
-+      *len += 0;
-+      else if (memory_operand (op2, SImode))
-+      *len += 2;
-+      else if (immediate_operand (op2, SImode))
-+      *len += 2;
-+    }
-+
-+  return "";
-+}
-+
-+
-+const char *
-+msp430_subdi_code (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  rtx op0 = operands[0];
-+  rtx op2 = operands[2];
-+
-+  if (memory_operand (op2, DImode)
-+      && zero_shifted (operands[2]) && regdi_ok_safe (operands))
-+    {
-+      if (!len)
-+      msp430_emit_indexed_sub4 (insn, operands, NULL);
-+      else
-+      {
-+        if (memory_operand (op0, DImode))
-+          *len = 9;
-+        else if (register_operand (op0, DImode))
-+          *len = 5;
-+      }
-+
-+      return "";
-+    }
-+  else if (memory_operand (op2, DImode)
-+         && zero_shifted (operands[2]) && regdi_ok_clobber (operands))
-+    {
-+      if (!len)
-+      {
-+        output_asm_insn ("sub\t@%E2+, %A0", operands);
-+        output_asm_insn ("subc\t@%E2+, %B0", operands);
-+        output_asm_insn ("subc\t@%E2+, %C0", operands);
-+        output_asm_insn ("subc\t@%E2+, %D0", operands);
-+      }
-+      else
-+      {
-+        if (register_operand (op0, DImode))
-+          *len = 4;
-+        else if (memory_operand (op0, DImode))
-+          *len = 8;
-+        else
-+          abort ();
-+      }
-+      return "";
-+    }
-+
-+  if (!len)
-+    {
-+      output_asm_insn ("sub\t%A2, %A0", operands);
-+      output_asm_insn ("subc\t%B2, %B0", operands);
-+      output_asm_insn ("subc\t%C2, %C0", operands);
-+      output_asm_insn ("subc\t%D2, %D0", operands);
-+    }
-+  else
-+    {
-+      *len = 4;                       /* base length */
-+
-+      if (register_operand (op0, DImode))
-+      *len += 0;
-+      else if (memory_operand (op0, DImode))
-+      *len += 4;
-+
-+      if (register_operand (op2, DImode))
-+      *len += 0;
-+      else if (memory_operand (op2, DImode))
-+      *len += 4;
-+      else if (immediate_operand (op2, DImode))
-+      *len += 4;
-+      else
-+      abort ();
-+    }
-+
-+  return "";
-+}
-+
-+
-+/**************       AND CODE *********************************/
-+
-+const char *
-+msp430_emit_indexed_and2 (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+  emit_indexed_arith (insn, operands, 2, "and", 0);
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_indexed_and4 (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+  emit_indexed_arith (insn, operands, 4, "and", 0);
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_immediate_and2 (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int v;
-+  int l = INTVAL (operands[2]);
-+  int r = REG_P (operands[0]);
-+  int list1 = ((~1) & 0xffff);
-+  int list2 = ((~2) & 0xffff);
-+  int list4 = ((~4) & 0xffff);
-+  int list8 = ((~8) & 0xffff);
-+
-+  rtx op[4];
-+
-+  op[0] = operands[0];
-+  op[1] = operands[1];
-+  op[2] = operands[2];
-+
-+  /* check nibbles */
-+
-+  v = (l) & 0xffff;
-+  if (v != 0xffff)
-+    {
-+      if (v == list1 || v == list2 || v == list4 || v == list8)
-+      {
-+        op[2] = gen_rtx_CONST_INT (SImode, ~v);
-+        OUT_INSN (len, "bic\t%A2, %A0", op);
-+        dummy++;
-+        if (!r)
-+          dummy++;
-+      }
-+      else
-+      {
-+        op[2] = gen_rtx_CONST_INT (SImode, v);
-+        OUT_INSN (len, "and\t%A2, %A0", op);
-+        dummy++;
-+        dummy++;
-+        if (!r)
-+          dummy++;
-+        if (v == 0 || v == 1 || v == 2 || v == 4 || v == 8)
-+          dummy--;
-+      }
-+    }
-+
-+  v = (l >> 16) & 0xffff;
-+  if (v != 0xffff)
-+    {
-+      if (v == list1 || v == list2 || v == list4 || v == list8)
-+      {
-+        op[2] = gen_rtx_CONST_INT (SImode, ~v);
-+        OUT_INSN (len, "bic\t%A2, %B0", op);
-+        dummy++;
-+        if (!r)
-+          dummy++;
-+      }
-+      else
-+      {
-+        op[2] = gen_rtx_CONST_INT (SImode, v);
-+        OUT_INSN (len, "and\t%A2, %B0", op);
-+        dummy++;
-+        dummy++;
-+        if (!r)
-+          dummy++;
-+        if (v == 0 || v == 1 || v == 2 || v == 4 || v == 8)
-+          dummy--;
-+      }
-+    }
-+
-+  if (len)
-+    *len = dummy;
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_immediate_and4 (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int v;
-+  int l = CONST_DOUBLE_LOW (operands[2]);
-+  int h = CONST_DOUBLE_HIGH (operands[2]);
-+  int r = REG_P (operands[0]);
-+  int list1 = ((~1) & 0xffff);
-+  int list2 = ((~2) & 0xffff);
-+  int list4 = ((~4) & 0xffff);
-+  int list8 = ((~8) & 0xffff);
-+  rtx op[4];
-+
-+  op[0] = operands[0];
-+  op[1] = operands[1];
-+  op[2] = operands[2];
-+
-+  /* check if operand 2 is really const_double */
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+    {
-+      l = INTVAL (operands[2]);
-+      h = 0;
-+    }
-+
-+  /* check nibbles */
-+  v = (l) & 0xffff;
-+  if (v != 0xffff)
-+    {
-+      if (v == list1 || v == list2 || v == list4 || v == list8)
-+      {
-+        op[2] = gen_rtx_CONST_INT (SImode, ~v);
-+        OUT_INSN (len, "bic\t%A2, %A0", op);
-+        dummy++;
-+        if (!r)
-+          dummy++;
-+      }
-+      else
-+      {
-+        op[2] = gen_rtx_CONST_INT (SImode, v);
-+        OUT_INSN (len, "and\t%A2, %A0", op);
-+        dummy++;
-+        dummy++;
-+        if (!r)
-+          dummy++;
-+        if (v == 0 || v == 1 || v == 2 || v == 4 || v == 8)
-+          dummy--;
-+      }
-+    }
-+
-+  v = (l >> 16) & 0xffff;
-+  if (v != 0xffff)
-+    {
-+      if (v == list1 || v == list2 || v == list4 || v == list8)
-+      {
-+        op[2] = gen_rtx_CONST_INT (SImode, ~v);
-+        OUT_INSN (len, "bic\t%A2, %B0", op);
-+        dummy++;
-+        if (!r)
-+          dummy++;
-+      }
-+      else
-+      {
-+        op[2] = gen_rtx_CONST_INT (SImode, v);
-+        OUT_INSN (len, "and\t%A2, %B0", op);
-+        dummy++;
-+        dummy++;
-+        if (!r)
-+          dummy++;
-+        if (v == 0 || v == 1 || v == 2 || v == 4 || v == 8)
-+          dummy--;
-+      }
-+    }
-+
-+  v = (h) & 0xffff;
-+  if (v != 0xffff)
-+    {
-+      if (v == list1 || v == list2 || v == list4 || v == list8)
-+      {
-+        op[2] = gen_rtx_CONST_INT (SImode, ~v);
-+        OUT_INSN (len, "bic\t%A2, %C0", op);
-+        dummy++;
-+        if (!r)
-+          dummy++;
-+      }
-+      else
-+      {
-+        op[2] = gen_rtx_CONST_INT (SImode, v);
-+        OUT_INSN (len, "and\t%A2, %C0", op);
-+        dummy++;
-+        dummy++;
-+        if (!r)
-+          dummy++;
-+        if (v == 0 || v == 1 || v == 2 || v == 4 || v == 8)
-+          dummy--;
-+      }
-+    }
-+
-+  v = (h >> 16) & 0xffff;
-+  if (v != 0xffff)
-+    {
-+      if (v == list1 || v == list2 || v == list4 || v == list8)
-+      {
-+        op[2] = gen_rtx_CONST_INT (SImode, ~v);
-+        OUT_INSN (len, "bic\t%A2, %D0", op);
-+        dummy++;
-+        if (!r)
-+          dummy++;
-+      }
-+      else
-+      {
-+        op[2] = gen_rtx_CONST_INT (SImode, v);
-+        OUT_INSN (len, "and\t%A2, %D0", op);
-+        dummy++;
-+        dummy++;
-+        if (!r)
-+          dummy++;
-+        if (v == 0 || v == 1 || v == 2 || v == 4 || v == 8)
-+          dummy--;
-+      }
-+    }
-+
-+  if (len)
-+    *len = dummy;
-+  return "";
-+}
-+
-+const char *
-+msp430_andsi_code (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  rtx op0 = operands[0];
-+  rtx op2 = operands[2];
-+
-+  if (nonimmediate_operand (op0, SImode) && immediate_operand (op2, SImode))
-+    {
-+      if (!len)
-+      msp430_emit_immediate_and2 (insn, operands, NULL);
-+      return "";
-+    }
-+
-+  if (memory_operand (op2, SImode)
-+      && zero_shifted (operands[2]) && regsi_ok_safe (operands))
-+    {
-+      if (!len)
-+      msp430_emit_indexed_and2 (insn, operands, NULL);
-+      else
-+      {
-+        if (memory_operand (op0, SImode))
-+          *len = 5;
-+        else if (register_operand (op0, SImode))
-+          *len = 3;
-+      }
-+
-+      return "";
-+    }
-+  else if (memory_operand (op2, SImode)
-+         && zero_shifted (operands[2]) && regsi_ok_clobber (operands))
-+    {
-+      if (!len)
-+      {
-+        output_asm_insn ("and\t@%E2+, %A0", operands);
-+        output_asm_insn ("and\t@%E2+, %B0", operands);
-+      }
-+      else
-+      {
-+        if (register_operand (op0, SImode))
-+          *len = 2;
-+        else if (memory_operand (op0, SImode))
-+          *len = 4;
-+        else
-+          abort ();
-+      }
-+      return "";
-+    }
-+
-+  if (!len)
-+    {
-+      output_asm_insn ("and\t%A2, %A0", operands);
-+      output_asm_insn ("and\t%B2, %B0", operands);
-+    }
-+  else
-+    {
-+      *len = 2;                       /* base length */
-+
-+      if (register_operand (op0, SImode))
-+      *len += 0;
-+      else if (memory_operand (op0, SImode))
-+      *len += 2;
-+
-+      if (register_operand (op2, SImode))
-+      *len += 0;
-+      else if (memory_operand (op2, SImode))
-+      *len += 2;
-+      else if (immediate_operand (op2, SImode))
-+      *len += 2;
-+    }
-+
-+  return "";
-+}
-+
-+
-+const char *
-+msp430_anddi_code (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  rtx op0 = operands[0];
-+  rtx op2 = operands[2];
-+
-+  if (nonimmediate_operand (op0, DImode) && immediate_operand (op2, DImode))
-+    {
-+      if (!len)
-+      msp430_emit_immediate_and4 (insn, operands, NULL);
-+      return "";
-+    }
-+
-+  if (memory_operand (op2, DImode)
-+      && zero_shifted (operands[2]) && regdi_ok_safe (operands))
-+    {
-+      if (!len)
-+      msp430_emit_indexed_and4 (insn, operands, NULL);
-+      else
-+      {
-+        if (memory_operand (op0, DImode))
-+          *len = 9;
-+        else if (register_operand (op0, DImode))
-+          *len = 5;
-+      }
-+
-+      return "";
-+    }
-+  else if (memory_operand (op2, DImode)
-+         && zero_shifted (operands[2]) && regdi_ok_clobber (operands))
-+    {
-+      if (!len)
-+      {
-+        output_asm_insn ("and\t@%E2+, %A0", operands);
-+        output_asm_insn ("and\t@%E2+, %B0", operands);
-+        output_asm_insn ("and\t@%E2+, %C0", operands);
-+        output_asm_insn ("and\t@%E2+, %D0", operands);
-+      }
-+      else
-+      {
-+        if (register_operand (op0, DImode))
-+          *len = 4;
-+        else if (memory_operand (op0, DImode))
-+          *len = 8;
-+        else
-+          abort ();
-+      }
-+      return "";
-+    }
-+
-+  if (!len)
-+    {
-+      output_asm_insn ("and\t%A2, %A0", operands);
-+      output_asm_insn ("and\t%B2, %B0", operands);
-+      output_asm_insn ("and\t%C2, %C0", operands);
-+      output_asm_insn ("and\t%D2, %D0", operands);
-+    }
-+  else
-+    {
-+      *len = 4;                       /* base length */
-+
-+      if (register_operand (op0, DImode))
-+      *len += 0;
-+      else if (memory_operand (op0, DImode))
-+      *len += 4;
-+
-+      if (register_operand (op2, DImode))
-+      *len += 0;
-+      else if (memory_operand (op2, DImode))
-+      *len += 4;
-+      else if (immediate_operand (op2, DImode))
-+      *len += 4;
-+      else
-+      abort ();
-+    }
-+
-+  return "";
-+}
-+
-+/**************       IOR CODE *********************************/
-+
-+const char *
-+msp430_emit_indexed_ior2 (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+  emit_indexed_arith (insn, operands, 2, "bis", 0);
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_indexed_ior4 (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+  emit_indexed_arith (insn, operands, 4, "bis", 0);
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_immediate_ior2 (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int l = INTVAL (operands[2]);
-+  int r = REG_P (operands[0]);
-+  int v;
-+
-+
-+  v = l & 0xffff;
-+
-+  if (v)
-+    {
-+      OUT_INSN (len, "bis\t%A2,%A0", operands);
-+      dummy++;
-+      dummy++;
-+      if (v == 0xffff || v == 1 || v == 2 || v == 4 || v == 8)
-+      dummy--;
-+      if (!r)
-+      dummy++;
-+    }
-+
-+  v = (l >> 16) & 0xffff;
-+
-+  if (v)
-+    {
-+      OUT_INSN (len, "bis\t%B2,%B0", operands);
-+      dummy++;
-+      dummy++;
-+      if (v == 0xffff || v == 1 || v == 2 || v == 4 || v == 8)
-+      dummy--;
-+      if (!r)
-+      dummy++;
-+    }
-+
-+  if (len)
-+    *len = dummy;
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_immediate_ior4 (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int l = CONST_DOUBLE_LOW (operands[2]);
-+  int h = CONST_DOUBLE_HIGH (operands[2]);
-+  int r = REG_P (operands[0]);
-+  int v;
-+
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+    {
-+      l = INTVAL (operands[2]);
-+      h = 0;
-+    }
-+
-+  v = l & 0xffff;
-+
-+  if (v)
-+    {
-+      OUT_INSN (len, "bis\t%A2,%A0", operands);
-+      dummy++;
-+      dummy++;
-+      if (v == 0xffff || v == 1 || v == 2 || v == 4 || v == 8)
-+      dummy--;
-+      if (!r)
-+      dummy++;
-+    }
-+
-+  v = (l >> 16) & 0xffff;
-+
-+  if (v)
-+    {
-+      OUT_INSN (len, "bis\t%B2,%B0", operands);
-+      dummy++;
-+      dummy++;
-+      if (v == 0xffff || v == 1 || v == 2 || v == 4 || v == 8)
-+      dummy--;
-+      if (!r)
-+      dummy++;
-+    }
-+
-+  l = h;
-+  v = l & 0xffff;
-+
-+  if (v)
-+    {
-+      OUT_INSN (len, "bis\t%C2,%C0", operands);
-+      dummy++;
-+      dummy++;
-+      if (v == 0xffff || v == 1 || v == 2 || v == 4 || v == 8)
-+      dummy--;
-+      if (!r)
-+      dummy++;
-+    }
-+
-+  v = (l >> 16) & 0xffff;
-+
-+  if (v)
-+    {
-+      OUT_INSN (len, "bis\t%D2,%D0", operands);
-+      dummy++;
-+      dummy++;
-+      if (v == 0xffff || v == 1 || v == 2 || v == 4 || v == 8)
-+      dummy--;
-+      if (!r)
-+      dummy++;
-+    }
-+
-+  if (len)
-+    *len = dummy;
-+  return "";
-+}
-+
-+const char *
-+msp430_iorsi_code (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  rtx op0 = operands[0];
-+  rtx op2 = operands[2];
-+
-+  if (nonimmediate_operand (op0, SImode) && immediate_operand (op2, SImode))
-+    {
-+      if (!len)
-+      msp430_emit_immediate_ior2 (insn, operands, NULL);
-+      return "";
-+    }
-+
-+  if (memory_operand (op2, SImode)
-+      && zero_shifted (operands[2]) && regsi_ok_safe (operands))
-+    {
-+      if (!len)
-+      msp430_emit_indexed_ior2 (insn, operands, NULL);
-+      else
-+      {
-+        if (memory_operand (op0, SImode))
-+          *len = 5;
-+        else if (register_operand (op0, SImode))
-+          *len = 3;
-+      }
-+
-+      return "";
-+    }
-+  else if (memory_operand (op2, SImode)
-+         && zero_shifted (operands[2]) && regsi_ok_clobber (operands))
-+    {
-+      if (!len)
-+      {
-+        output_asm_insn ("bis\t@%E2+, %A0", operands);
-+        output_asm_insn ("bis\t@%E2+, %B0", operands);
-+      }
-+      else
-+      {
-+        if (register_operand (op0, SImode))
-+          *len = 2;
-+        else if (memory_operand (op0, SImode))
-+          *len = 4;
-+        else
-+          abort ();
-+      }
-+      return "";
-+    }
-+
-+  if (!len)
-+    {
-+      output_asm_insn ("bis\t%A2, %A0", operands);
-+      output_asm_insn ("bis\t%B2, %B0", operands);
-+    }
-+  else
-+    {
-+      *len = 2;                       /* base length */
-+
-+      if (register_operand (op0, SImode))
-+      *len += 0;
-+      else if (memory_operand (op0, SImode))
-+      *len += 2;
-+
-+      if (register_operand (op2, SImode))
-+      *len += 0;
-+      else if (memory_operand (op2, SImode))
-+      *len += 2;
-+      else if (immediate_operand (op2, SImode))
-+      *len += 2;
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_iordi_code (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  rtx op0 = operands[0];
-+  rtx op2 = operands[2];
-+
-+  if (nonimmediate_operand (op0, DImode) && immediate_operand (op2, DImode))
-+    {
-+      if (!len)
-+      msp430_emit_immediate_ior4 (insn, operands, NULL);
-+      return "";
-+    }
-+
-+  if (memory_operand (op2, DImode)
-+      && zero_shifted (operands[2]) && regdi_ok_safe (operands))
-+    {
-+      if (!len)
-+      msp430_emit_indexed_ior4 (insn, operands, NULL);
-+      else
-+      {
-+        if (memory_operand (op0, DImode))
-+          *len = 9;
-+        else if (register_operand (op0, DImode))
-+          *len = 5;
-+      }
-+
-+      return "";
-+    }
-+  else if (memory_operand (op2, DImode)
-+         && zero_shifted (operands[2]) && regdi_ok_clobber (operands))
-+    {
-+      if (!len)
-+      {
-+        output_asm_insn ("bis\t@%E2+, %A0", operands);
-+        output_asm_insn ("bis\t@%E2+, %B0", operands);
-+        output_asm_insn ("bis\t@%E2+, %C0", operands);
-+        output_asm_insn ("bis\t@%E2+, %D0", operands);
-+      }
-+      else
-+      {
-+        if (register_operand (op0, DImode))
-+          *len = 4;
-+        else if (memory_operand (op0, DImode))
-+          *len = 8;
-+        else
-+          abort ();
-+      }
-+      return "";
-+    }
-+
-+  if (!len)
-+    {
-+      output_asm_insn ("bis\t%A2, %A0", operands);
-+      output_asm_insn ("bis\t%B2, %B0", operands);
-+      output_asm_insn ("bis\t%C2, %C0", operands);
-+      output_asm_insn ("bis\t%D2, %D0", operands);
-+    }
-+  else
-+    {
-+      *len = 4;                       /* base length */
-+
-+      if (register_operand (op0, DImode))
-+      *len += 0;
-+      else if (memory_operand (op0, DImode))
-+      *len += 4;
-+
-+      if (register_operand (op2, DImode))
-+      *len += 0;
-+      else if (memory_operand (op2, DImode))
-+      *len += 4;
-+      else if (immediate_operand (op2, DImode))
-+      *len += 4;
-+      else
-+      abort ();
-+    }
-+
-+  return "";
-+}
-+
-+
-+/************************* XOR CODE *****************/
-+
-+const char *
-+msp430_emit_indexed_xor2 (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l;
-+{
-+  int dummy = emit_indexed_arith (insn, operands, 2, "xor", 0);
-+  if (!l)
-+    l = &dummy;
-+  *l = dummy;
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_indexed_xor4 (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l;
-+{
-+  int dummy = emit_indexed_arith (insn, operands, 4, "xor", 0);
-+  if (!l)
-+    l = &dummy;
-+  *l = dummy;
-+  return "";
-+}
-+
-+
-+const char *
-+msp430_emit_indexed_xor2_3 (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l;
-+{
-+  int dummy;
-+  rtx x = operands[2];
-+  if (zero_shifted (x))
-+    {
-+      dummy = emit_indexed_arith (insn, operands, 2, "xor", 0);
-+    }
-+  else
-+    {
-+      dummy = 6;
-+      output_asm_insn ("xor\t%A2, %A0", operands);
-+      output_asm_insn ("xor\t%B2, %B0", operands);
-+    }
-+
-+  if (!l)
-+    l = &dummy;
-+  *l = dummy;
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_indexed_xor4_3 (insn, operands, l)
-+     rtx insn;
-+     rtx operands[];
-+     int *l;
-+{
-+
-+  int dummy;
-+  rtx x = operands[2];
-+  if (zero_shifted (x))
-+    {
-+      dummy = emit_indexed_arith (insn, operands, 4, "xor", 0);
-+    }
-+  else
-+    {
-+      dummy = 8;
-+      output_asm_insn ("xor\t%A2, %A0", operands);
-+      output_asm_insn ("xor\t%B2, %B0", operands);
-+      output_asm_insn ("xor\t%C2, %C0", operands);
-+      output_asm_insn ("xor\t%D2, %D0", operands);
-+    }
-+
-+  if (!l)
-+    l = &dummy;
-+  *l = dummy;
-+  return "";
-+}
-+
-+const char *
-+msp430_xorsi_code (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  rtx op0 = operands[0];
-+  rtx op2 = operands[2];
-+
-+  if (memory_operand (op2, SImode)
-+      && zero_shifted (operands[2]) && regsi_ok_safe (operands))
-+    {
-+      if (!len)
-+      msp430_emit_indexed_xor2 (insn, operands, NULL);
-+      else
-+      {
-+        if (memory_operand (op0, SImode))
-+          *len = 5;
-+        else if (register_operand (op0, SImode))
-+          *len = 3;
-+      }
-+
-+      return "";
-+    }
-+  else if (memory_operand (op2, SImode)
-+         && zero_shifted (operands[2]) && regsi_ok_clobber (operands))
-+    {
-+      if (!len)
-+      {
-+        output_asm_insn ("xor\t@%E2+, %A0", operands);
-+        output_asm_insn ("xor\t@%E2+, %B0", operands);
-+      }
-+      else
-+      {
-+        if (register_operand (op0, SImode))
-+          *len = 2;
-+        else if (memory_operand (op0, SImode))
-+          *len = 4;
-+        else
-+          abort ();
-+      }
-+      return "";
-+    }
-+
-+  if (!len)
-+    {
-+
-+      if (immediate_operand (op2, SImode))
-+      {
-+        if (INTVAL (op2) & 0xfffful)
-+          output_asm_insn ("xor\t%A2, %A0", operands);
-+
-+        if (INTVAL (op2) & 0xffff0000ul)
-+          output_asm_insn ("xor\t%B2, %B0", operands);
-+      }
-+      else
-+      {
-+        output_asm_insn ("xor\t%A2, %A0", operands);
-+        output_asm_insn ("xor\t%B2, %B0", operands);
-+      }
-+
-+    }
-+  else
-+    {
-+      *len = 2;                       /* base length */
-+
-+      if (register_operand (op0, SImode))
-+      *len += 0;
-+      else if (memory_operand (op0, SImode))
-+      *len += 2;
-+
-+      if (register_operand (op2, SImode))
-+      *len += 0;
-+      else if (memory_operand (op2, SImode))
-+      *len += 2;
-+      else if (immediate_operand (op2, SImode))
-+      {
-+        if (INTVAL (op2) & 0xfffful)
-+          *len += 1;
-+        if (INTVAL (op2) & 0xffff0000ul)
-+          *len += 1;
-+      }
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_xordi_code (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  rtx op0 = operands[0];
-+  rtx op2 = operands[2];
-+
-+  if (memory_operand (op2, DImode)
-+      && zero_shifted (operands[2]) && regdi_ok_safe (operands))
-+    {
-+      if (!len)
-+      msp430_emit_indexed_xor4 (insn, operands, NULL);
-+      else
-+      {
-+        if (memory_operand (op0, DImode))
-+          *len = 9;
-+        else if (register_operand (op0, DImode))
-+          *len = 5;
-+      }
-+
-+      return "";
-+    }
-+  else if (memory_operand (op2, DImode)
-+         && zero_shifted (operands[2]) && regdi_ok_clobber (operands))
-+    {
-+      if (!len)
-+      {
-+        output_asm_insn ("xor\t@%E2+, %A0", operands);
-+        output_asm_insn ("xor\t@%E2+, %B0", operands);
-+        output_asm_insn ("xor\t@%E2+, %C0", operands);
-+        output_asm_insn ("xor\t@%E2+, %D0", operands);
-+      }
-+      else
-+      {
-+        if (register_operand (op0, DImode))
-+          *len = 4;
-+        else if (memory_operand (op0, DImode))
-+          *len = 8;
-+        else
-+          abort ();
-+      }
-+      return "";
-+    }
-+
-+  if (!len)
-+    {
-+      output_asm_insn ("xor\t%A2, %A0", operands);
-+      output_asm_insn ("xor\t%B2, %B0", operands);
-+      output_asm_insn ("xor\t%C2, %C0", operands);
-+      output_asm_insn ("xor\t%D2, %D0", operands);
-+    }
-+  else
-+    {
-+      *len = 4;                       /* base length */
-+
-+      if (register_operand (op0, DImode))
-+      *len += 0;
-+      else if (memory_operand (op0, DImode))
-+      *len += 4;
-+
-+      if (register_operand (op2, DImode))
-+      *len += 0;
-+      else if (memory_operand (op2, DImode))
-+      *len += 4;
-+      else if (immediate_operand (op2, DImode))
-+      *len += 4;
-+      else
-+      abort ();
-+    }
-+
-+  return "";
-+}
-+
-+
-+/********* ABS CODE ***************************************/
-+const char *
-+msp430_emit_abssi (insn, operands, l)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+  output_asm_insn ("tst\t%B0", operands);
-+  output_asm_insn ("jge\t.Lae%=", operands);
-+  output_asm_insn ("inv\t%A0", operands);
-+  output_asm_insn ("inv\t%B0", operands);
-+  output_asm_insn ("inc\t%A0", operands);
-+  output_asm_insn ("adc\t%B0", operands);
-+  output_asm_insn (".Lae%=:", operands);
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_absdi (insn, operands, l)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *l ATTRIBUTE_UNUSED;
-+{
-+  output_asm_insn ("tst\t%D0", operands);
-+  output_asm_insn ("jge\t.Lae%=", operands);
-+  output_asm_insn ("inv\t%A0", operands);
-+  output_asm_insn ("inv\t%B0", operands);
-+  output_asm_insn ("inv\t%C0", operands);
-+  output_asm_insn ("inv\t%D0", operands);
-+  output_asm_insn ("inc\t%A0", operands);
-+  output_asm_insn ("adc\t%B0", operands);
-+  output_asm_insn ("adc\t%C0", operands);
-+  output_asm_insn ("adc\t%D0", operands);
-+  output_asm_insn (".Lae%=:", operands);
-+  return "";
-+}
-+
-+
-+/***** SIGN EXTEND *********/
-+const char *
-+signextendqihi (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
-+
-+  if (!sameoperand (operands, 1))
-+    {
-+      OUT_INSN (len, "mov.b\t%A1, %A0", operands);
-+      dummy = 3;
-+      if (indexed_location (operands[1]))
-+      dummy = 2;
-+      if (GET_CODE (operands[0]) == REG)
-+      dummy--;
-+      if (GET_CODE (operands[1]) == REG)
-+      dummy--;
-+    }
-+
-+  OUT_INSN (len, "sxt\t%A0", operands);
-+  dummy += 2;
-+
-+  if (zs || GET_CODE (operands[0]) == REG)
-+    dummy -= 1;
-+
-+  if (len)
-+    *len = dummy;
-+
-+  return "";
-+}
-+
-+const char *
-+signextendqisi (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
-+
-+  if (!sameoperand (operands, 1))
-+    {
-+      OUT_INSN (len, "mov.b\t%A1, %A0", operands);
-+      dummy = 3;
-+      if (indexed_location (operands[1]))
-+      dummy = 2;
-+      if (GET_CODE (operands[0]) == REG)
-+      dummy--;
-+      if (GET_CODE (operands[1]) == REG)
-+      dummy--;
-+    }
-+
-+  OUT_INSN (len, "sxt\t%A0", operands);
-+  OUT_INSN (len, "mov\t%A0, %B0", operands);
-+  OUT_INSN (len, "rla\t%B0", operands);
-+  OUT_INSN (len, "subc\t%B0, %B0", operands);
-+  OUT_INSN (len, "inv\t%B0", operands);
-+
-+  if (GET_CODE (operands[0]) == REG)
-+    dummy += 5;
-+  else if (zs)
-+    dummy += 10;
-+  else
-+    dummy += 12;
-+
-+  if (len)
-+    *len = dummy;
-+
-+  return "";
-+}
-+
-+const char *
-+signextendqidi (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
-+
-+  if (!sameoperand (operands, 1))
-+    {
-+      OUT_INSN (len, "mov.b\t%A1, %A0", operands);
-+      dummy = 3;
-+      if (indexed_location (operands[1]))
-+      dummy = 2;
-+      if (GET_CODE (operands[0]) == REG)
-+      dummy--;
-+      if (GET_CODE (operands[1]) == REG)
-+      dummy--;
-+    }
-+
-+  OUT_INSN (len, "sxt\t%A0", operands);
-+  OUT_INSN (len, "mov\t%A0, %B0", operands);
-+  OUT_INSN (len, "rla\t%B0", operands);
-+  OUT_INSN (len, "subc\t%B0, %B0", operands);
-+  OUT_INSN (len, "inv\t%B0", operands);
-+  OUT_INSN (len, "mov\t%B0, %C0", operands);
-+  OUT_INSN (len, "mov\t%C0, %D0", operands);
-+
-+
-+  if (GET_CODE (operands[0]) == REG)
-+    dummy += 7;
-+  else if (zs)
-+    dummy += 16;
-+  else
-+    dummy += 18;
-+
-+  if (len)
-+    *len = dummy;
-+
-+  return "";
-+}
-+
-+const char *
-+signextendhisi (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
-+
-+  if (!sameoperand (operands, 1))
-+    {
-+      OUT_INSN (len, "mov\t%A1, %A0", operands);
-+      dummy = 3;
-+      if (indexed_location (operands[1]))
-+      dummy = 2;
-+      if (GET_CODE (operands[0]) == REG)
-+      dummy--;
-+      if (GET_CODE (operands[1]) == REG)
-+      dummy--;
-+    }
-+
-+  OUT_INSN (len, "mov\t%A0, %B0", operands);
-+  OUT_INSN (len, "rla\t%B0", operands);
-+  OUT_INSN (len, "subc\t%B0, %B0", operands);
-+  OUT_INSN (len, "inv\t%B0", operands);
-+
-+  if (GET_CODE (operands[0]) == REG)
-+    dummy += 4;
-+  else if (zs)
-+    dummy += 9;
-+  else
-+    dummy += 11;
-+
-+  if (len)
-+    *len = dummy;
-+
-+  return "";
-+}
-+
-+const char *
-+signextendhidi (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
-+
-+  if (!sameoperand (operands, 1))
-+    {
-+      OUT_INSN (len, "mov\t%A1, %A0", operands);
-+      dummy = 3;
-+      if (indexed_location (operands[1]))
-+      dummy = 2;
-+      if (GET_CODE (operands[0]) == REG)
-+      dummy--;
-+      if (GET_CODE (operands[1]) == REG)
-+      dummy--;
-+    }
-+
-+  OUT_INSN (len, "mov\t%A0, %B0", operands);
-+  OUT_INSN (len, "rla\t%B0", operands);
-+  OUT_INSN (len, "subc\t%B0, %B0", operands);
-+  OUT_INSN (len, "inv\t%B0", operands);
-+  OUT_INSN (len, "mov\t%B0, %C0", operands);
-+  OUT_INSN (len, "mov\t%C0, %D0", operands);
-+
-+  if (GET_CODE (operands[0]) == REG)
-+    dummy += 6;
-+  else if (zs)
-+    dummy += 13;
-+  else
-+    dummy += 14;
-+
-+  if (len)
-+    *len = dummy;
-+
-+  return "";
-+}
-+
-+const char *
-+signextendsidi (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+
-+  if (!sameoperand (operands, 1))
-+    {
-+      OUT_INSN (len, "mov\t%A1, %A0", operands);
-+      OUT_INSN (len, "mov\t%B1, %B0", operands);
-+      dummy = 6;
-+      if (indexed_location (operands[1]))
-+      dummy = 4;
-+      if (GET_CODE (operands[0]) == REG)
-+      dummy -= 2;
-+      if (GET_CODE (operands[1]) == REG)
-+      dummy -= 2;
-+    }
-+
-+  OUT_INSN (len, "mov\t%B0, %C0", operands);
-+  OUT_INSN (len, "rla\t%C0", operands);
-+  OUT_INSN (len, "subc\t%C0, %C0", operands);
-+  OUT_INSN (len, "inv\t%C0", operands);
-+  OUT_INSN (len, "mov\t%C0, %D0", operands);
-+
-+  if (GET_CODE (operands[0]) == REG)
-+    dummy += 5;
-+  else
-+    dummy += 13;
-+
-+  if (len)
-+    *len = dummy;
-+
-+  return "";
-+}
-+
-+
-+/**** ZERO EXTEND *****/
-+
-+const char *
-+zeroextendqihi (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[1]) || indexed_location (operands[1]);
-+
-+  if(operands[0] == op2_rtx)
-+  {
-+    OUT_INSN (len, "and       #0xff00, %0",operands);
-+    dummy = 3;
-+    return "";
-+  }
-+  if (!sameoperand (operands, 1))
-+    {
-+      OUT_INSN (len, "mov.b\t%A1, %A0", operands);
-+      dummy = 3;
-+      if (zs)
-+      dummy = 2;
-+      if (GET_CODE (operands[0]) == REG)
-+      dummy--;
-+      if (GET_CODE (operands[1]) == REG)
-+      dummy--;
-+    }
-+
-+  if (!REG_P (operands[0]))
-+    {
-+      OUT_INSN (len, "clr.b\t%J0", operands);
-+      dummy += 2;
-+    }
-+  else if (sameoperand (operands, 1))
-+    {
-+      OUT_INSN (len, "and.b\t#-1,%0", operands);
-+      dummy++;
-+    }
-+
-+  if (len)
-+    *len = dummy;
-+
-+  return "";
-+}
-+
-+const char *
-+zeroextendqisi (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[1]) || indexed_location (operands[1]);
-+
-+  if (!sameoperand (operands, 1) || REG_P (operands[0]))
-+    {
-+      OUT_INSN (len, "mov.b\t%A1, %A0", operands);
-+      dummy = 3;
-+      if (zs)
-+      dummy = 2;
-+      if (GET_CODE (operands[0]) == REG)
-+      dummy--;
-+      if (GET_CODE (operands[1]) == REG)
-+      dummy--;
-+    }
-+
-+
-+  if (!REG_P (operands[0]))
-+    {
-+      OUT_INSN (len, "clr.b\t%J0", operands);
-+    }
-+  else if (sameoperand (operands, 1))
-+    {
-+      OUT_INSN (len, "and.b\t#-1,%0", operands);
-+      dummy++;
-+    }
-+  OUT_INSN (len, "clr\t%B0", operands);
-+  dummy += 2;
-+  if (GET_CODE (operands[0]) == REG)
-+    dummy--;
-+
-+  if (len)
-+    *len = dummy;
-+
-+  return "";
-+}
-+
-+
-+const char *
-+zeroextendqidi (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[1]) || indexed_location (operands[1]);
-+
-+  if (!sameoperand (operands, 1) || REG_P (operands[0]))
-+    {
-+      OUT_INSN (len, "mov.b\t%A1, %A0", operands);
-+      dummy = 3;
-+      if (zs)
-+      dummy = 2;
-+      if (GET_CODE (operands[0]) == REG)
-+      dummy--;
-+      if (GET_CODE (operands[1]) == REG)
-+      dummy--;
-+    }
-+
-+  if (!REG_P (operands[0]))
-+    {
-+      OUT_INSN (len, "clr.b\t%J0", operands);
-+      dummy += 2;
-+    }
-+  else if (sameoperand (operands, 1))
-+    {
-+      OUT_INSN (len, "and.b\t#-1,%0", operands);
-+      dummy++;
-+    }
-+  dummy += 6;
-+  OUT_INSN (len, "clr\t%B0", operands);
-+  OUT_INSN (len, "clr\t%C0", operands);
-+  OUT_INSN (len, "clr\t%D0", operands);
-+
-+  if (GET_CODE (operands[0]) == REG && len)
-+    *len -= 3;
-+
-+  if (len)
-+    *len = dummy;
-+
-+  return "";
-+}
-+
-+const char *
-+zeroextendhisi (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[1]) || indexed_location (operands[1]);
-+
-+  if (!sameoperand (operands, 1))
-+    {
-+      OUT_INSN (len, "mov\t%A1, %A0", operands);
-+      dummy = 3;
-+      if (zs)
-+      dummy = 2;
-+      if (GET_CODE (operands[0]) == REG)
-+      dummy--;
-+      if (GET_CODE (operands[1]) == REG)
-+      dummy--;
-+    }
-+
-+  OUT_INSN (len, "clr\t%B0", operands);
-+  dummy += 2;
-+  if (GET_CODE (operands[0]) == REG)
-+    dummy--;
-+
-+  if (len)
-+    *len = dummy;
-+
-+  return "";
-+
-+}
-+
-+const char *
-+zeroextendhidi (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[1]) || indexed_location (operands[1]);
-+
-+  if (!sameoperand (operands, 1))
-+    {
-+      OUT_INSN (len, "mov\t%A1, %A0", operands);
-+      dummy = 3;
-+      if (zs)
-+      dummy = 2;
-+      if (GET_CODE (operands[0]) == REG)
-+      dummy--;
-+      if (GET_CODE (operands[1]) == REG)
-+      dummy--;
-+    }
-+
-+  dummy += 6;
-+  OUT_INSN (len, "clr\t%B0", operands);
-+  OUT_INSN (len, "clr\t%C0", operands);
-+  OUT_INSN (len, "clr\t%D0", operands);
-+
-+  if (GET_CODE (operands[0]) == REG)
-+    dummy -= 3;
-+
-+  if (len)
-+    *len = dummy;
-+
-+  return "";
-+}
-+
-+const char *
-+zeroextendsidi (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+
-+  if (!sameoperand (operands, 1))
-+    {
-+      if (zero_shifted (operands[1]))
-+      {
-+        rtx reg = XEXP (operands[1], 0);
-+
-+        OUT_INSN (len, "mov\t@%E1+, %A0", operands);
-+        OUT_INSN (len, "mov\t@%E1+, %B0", operands);
-+        dummy = 4;
-+        if (GET_CODE (operands[0]) == REG)
-+          dummy -= 2;
-+
-+        if (!dead_or_set_p (insn, reg))
-+          {
-+            OUT_INSN (len, "sub\t#4, %E1", operands);
-+            dummy += 1;
-+          }
-+      }
-+      else
-+      {
-+        OUT_INSN (len, "mov\t%A1, %A0", operands);
-+        OUT_INSN (len, "mov\t%B1, %B0", operands);
-+        dummy = 6;
-+        if (GET_CODE (operands[0]) == REG)
-+          dummy -= 2;
-+        if (GET_CODE (operands[1]) == REG)
-+          dummy -= 2;
-+        if (indexed_location (operands[1]))
-+          dummy--;
-+      }
-+    }
-+
-+  dummy += 4;
-+  OUT_INSN (len, "clr\t%C0", operands);
-+  OUT_INSN (len, "clr\t%D0", operands);
-+
-+  if (GET_CODE (operands[0]) == REG)
-+    dummy -= 2;
-+
-+  if (len)
-+    *len = dummy;
-+
-+  return "";
-+}
-+
-+/******************* TESTS AND JUMPS *********************/
-+
-+RTX_CODE
-+msp430_canonicalize_comparison (code, op0, op1)
-+     RTX_CODE code;
-+     rtx *op0;
-+     rtx *op1;
-+{
-+  RTX_CODE rc = code;
-+
-+  if ( CONSTANT_P(*op1) )
-+    {
-+      ;                               /* nothing to be done */
-+    }
-+  else
-+    {
-+      switch (code)
-+      {
-+      case GT:
-+      case LE:
-+      case GTU:
-+      case LEU:
-+        {
-+          rtx x;
-+          rc = swap_condition (code);
-+          x = *op0;
-+          *op0 = *op1;
-+          *op1 = x;
-+        }
-+        break;
-+      default:
-+        break;
-+      }
-+    }
-+  return rc;
-+}
-+
-+
-+void
-+msp430_emit_cbranch (code, loc)
-+     enum rtx_code code;
-+     rtx loc;
-+{
-+  rtx op0 = msp430_compare_op0;
-+  rtx op1 = msp430_compare_op1;
-+  rtx condition_rtx, loc_ref, branch;
-+  enum machine_mode mode;
-+  int mem_volatil=0;
-+  
-+  if (!msp430_compare_op0 && !msp430_compare_op1)
-+    {
-+      /* this is a branch upon previous insn issued */
-+      loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
-+      condition_rtx = gen_rtx (code, VOIDmode, cc0_rtx, const0_rtx);
-+
-+      branch = gen_rtx_SET (VOIDmode,
-+                          pc_rtx,
-+                          gen_rtx_IF_THEN_ELSE (VOIDmode,
-+                                                condition_rtx,
-+                                                loc_ref, pc_rtx));
-+      emit_jump_insn (branch);
-+      return;
-+    }
-+
-+  mode = GET_MODE (op0);
-+  if (mode != SImode && mode != HImode && mode != QImode)
-+    abort ();
-+
-+
-+  /* now convert codes */
-+  code = msp430_canonicalize_comparison (code, &op0, &op1);
-+
-+  /* for HI and QI modes everything is simple.
-+     Also, if code is eq or ne in SI mode, no clobbers required. */
-+
-+  if (mode == SImode && !(code == EQ || code == NE))
-+    {
-+      /* check if only high nibbles required */
-+      if (GET_CODE (op1) == CONST_INT
-+        && INTVAL (op1) == 0 && (code == LT || code == GE))
-+      {
-+        mem_volatil = MEM_VOLATILE_P(op0);
-+        MEM_VOLATILE_P(op0) = 0;
-+        op0 = gen_highpart (HImode, op0);
-+        MEM_VOLATILE_P(op0) = mem_volatil;
-+        mode = HImode;
-+        PUT_MODE (op1, VOIDmode);     /* paranoia ? */
-+      }
-+      else if (GET_CODE (op1) == CONST_INT
-+             && ((INTVAL (op1) + 1) & 0xffff) == 0
-+             && (code == GT || code == GTU || code == LE || code == LEU))
-+      {
-+        /* check if this can be done simple. 
-+           we will not clobber const operand. */
-+        int x = INTVAL (op1);
-+        x++;
-+        x >>= 16;
-+        MEM_VOLATILE_P(op0) = 0;
-+        op0 = gen_highpart (HImode, op0);
-+        MEM_VOLATILE_P(op0) = mem_volatil;
-+        mode = HImode;
-+        op1 = GEN_INT (trunc_int_for_mode (x, HImode));
-+
-+        if (code == GT)
-+          code = GE;
-+        else if (code == GTU)
-+          code = GEU;
-+        else if (code == LEU)
-+          code = LTU;
-+        else if (code == LE)
-+          code = LT;
-+      }
-+      else
-+      {
-+        rtvec vec;
-+        /* the redudant move will be deleted */
-+        op0 = copy_to_mode_reg (SImode, op0);
-+        condition_rtx = gen_rtx (code, mode, op0, op1);
-+        loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
-+        branch = gen_rtx_SET (VOIDmode, pc_rtx,
-+                              gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
-+                                                    loc_ref, pc_rtx));
-+        vec = gen_rtvec (2, branch, gen_rtx_CLOBBER (SImode, op0));
-+        emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, vec));
-+        msp430_compare_op0 = 0;
-+        msp430_compare_op1 = 0;
-+        return;
-+      }
-+    }
-+  else if(mode == SImode && code == NE
-+      && GET_CODE(op1)!= CONST_INT && op1 != const0_rtx)
-+  {
-+    rtx op0lo, op0hi, op1lo, op1hi;
-+    
-+    mem_volatil = MEM_VOLATILE_P(op0);
-+    op0lo = gen_lowpart(HImode, op0);
-+    op0hi = gen_highpart(HImode, op0);
-+    MEM_VOLATILE_P(op0) = mem_volatil;
-+
-+    mem_volatil = MEM_VOLATILE_P(op1);
-+    op1lo = gen_lowpart(HImode, op1);
-+    op1hi = gen_highpart(HImode, op1);
-+    MEM_VOLATILE_P(op1) = mem_volatil;
-+    
-+    condition_rtx = gen_rtx (NE,HImode,op0lo,op1lo);
-+    loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
-+    branch = gen_rtx_SET (VOIDmode, pc_rtx,
-+      gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
-+        loc_ref, pc_rtx));
-+    emit_jump_insn (branch);
-+    condition_rtx = gen_rtx (NE,HImode,op0hi,op1hi);
-+    branch = gen_rtx_SET (VOIDmode, pc_rtx,
-+      gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
-+        loc_ref, pc_rtx));
-+    emit_jump_insn (branch);
-+    msp430_compare_op0 = 0;
-+    msp430_compare_op1 = 0;
-+    return;
-+  }
-+  else if(mode == SImode && code == EQ && GET_CODE(op1)!= CONST_INT )
-+  {
-+    rtx tlabel = gen_label_rtx();
-+    rtx tloc_ref;
-+    rtx op0lo, op0hi, op1lo, op1hi;
-+    
-+    mem_volatil = MEM_VOLATILE_P(op0);
-+    op0lo = gen_lowpart(HImode, op0);
-+    op0hi = gen_highpart(HImode, op0);
-+    MEM_VOLATILE_P(op0) = mem_volatil;
-+    
-+    mem_volatil = MEM_VOLATILE_P(op1);
-+    op1lo = gen_lowpart(HImode, op1);
-+    op1hi = gen_highpart(HImode, op1);
-+    MEM_VOLATILE_P(op1) = mem_volatil;
-+
-+    condition_rtx = gen_rtx (NE,HImode,op0lo,op1lo);
-+    tloc_ref = gen_rtx_LABEL_REF (VOIDmode, tlabel);
-+    branch = gen_rtx_SET (VOIDmode, pc_rtx,
-+      gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
-+        tloc_ref, pc_rtx));
-+    emit_jump_insn (branch);
-+
-+    condition_rtx = gen_rtx (EQ,HImode,op0hi,op1hi);
-+    loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
-+    branch = gen_rtx_SET (VOIDmode, pc_rtx,
-+      gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
-+        loc_ref, pc_rtx));
-+    emit_jump_insn (branch);
-+    emit_label(tlabel);
-+    msp430_compare_op0 = 0;
-+    msp430_compare_op1 = 0;
-+    return ;
-+  }
-+
-+  condition_rtx = gen_rtx (code, mode, op0, op1);
-+  loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
-+  branch = gen_rtx_SET (VOIDmode, pc_rtx,
-+                      gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
-+                                            loc_ref, pc_rtx));
-+
-+  emit_jump_insn (branch);
-+
-+  msp430_compare_op0 = 0;
-+  msp430_compare_op1 = 0;
-+  return;
-+}
-+
-+
-+/*  x - dst
-+    y - src */
-+static int
-+msp430_cc_source (insn, code, x, y)
-+     rtx insn;
-+     enum rtx_code code ATTRIBUTE_UNUSED;
-+     rtx x;
-+     rtx y;
-+{
-+  rtx prev = insn;
-+  enum attr_cc cc;
-+  rtx set;
-+  rtx src, dst;
-+  rtx x1 = 0;
-+
-+  if(GET_CODE(x) == MEM)
-+  {
-+    x1 = XEXP(x,0);
-+    if(GET_CODE(x1) == PLUS)
-+    {
-+      x1 = XEXP(x1,0);
-+    }
-+    
-+    if(!REG_P(x1)) x1 = 0;
-+  }
-+
-+  while (0 != (prev = PREV_INSN (prev)))
-+    {
-+      if (GET_CODE (prev) == CODE_LABEL
-+        || GET_CODE (prev) == BARRIER || GET_CODE (prev) == CALL_INSN)
-+      return 0;
-+
-+      if (GET_CODE (prev) == INSN)
-+      {
-+        set = single_set (prev);
-+        
-+        if(!set)
-+          return 0;
-+
-+        cc = get_attr_cc (prev);
-+
-+        if (cc == CC_NONE)    /* does not change CC */
-+          {
-+            /*The one spot by Nick C. */
-+            dst = SET_DEST (set);
-+            if((dst && rtx_equal_p (x, dst)) ||
-+                (x1 && dst && rtx_equal_p (x1, dst)))
-+              return 0;
-+            else
-+              continue;
-+          }
-+
-+        if (cc == CC_CLOBBER) /* clobber */
-+          return 0;
-+
-+        if (cc == CC_OPER)    /* post-incremental stuff */
-+          {
-+            src = SET_SRC (set);
-+            if (GET_CODE (set) == IOR)        /* does not change CC */
-+              {
-+                dst = SET_DEST (set);
-+                if(dst && rtx_equal_p (x, dst))
-+                  return 0;
-+                else
-+                  continue;
-+              }
-+          }
-+
-+        /* all other attributes are bit messy.
-+           So, we'll record destination and check if 
-+           this matches 'x' and compare is against zero */
-+        dst = SET_DEST (set);
-+        if (rtx_equal_p (x, dst) && rtx_equal_p (y, const0_rtx))
-+          return 1;
-+        else
-+          return 0;
-+      }
-+      else if (GET_CODE (prev) == JUMP_INSN)
-+      {
-+        /* if 2 consequent jump insns were issued, this means
-+           that operands (more likely src) are different.
-+           however, some jumps optimization can equalize these operands
-+           and everything will be bad. Therefore, assume that
-+           any jump insn clobbers condition codes.*/
-+        return 0;
-+      }
-+    }
-+  return 0;
-+}
-+
-+
-+
-+const char *
-+msp430_cbranch (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  rtx ops[3];
-+  enum rtx_code code;
-+  rtx locs[3];
-+  int dummy = 0;
-+  enum machine_mode mode;
-+  int quater = 0;
-+  rtx loc = operands[0];
-+  int distance = msp430_jump_dist (loc, insn);
-+  int predist = get_attr_length (insn);
-+  int nooverflow = 0;
-+  
-+#define ECOND(f,x) do{if(!len)msp430_emit_b##f(locs,predist + x);dummy+=(predist + x);}while(0)
-+  locs[0] = operands[0];
-+  ops[0] = operands[2];
-+  ops[1] = operands[3];
-+
-+  if (ops[1] && ops[0])
-+    {
-+      mode = GET_MODE (operands[2]);
-+      code = GET_CODE (operands[1]);
-+      quater = (mode == QImode);
-+    }
-+  else
-+    {
-+      mode = HImode;
-+      code = GET_CODE (operands[1]);
-+    }
-+
-+  /* here check wiered conditions */
-+  if (ops[1] && GET_CODE (ops[1]) == CONST_INT
-+      && (code == GT || code == LE || code == GTU || code == LEU))
-+    {
-+      int x = INTVAL (ops[1]);
-+      switch (code)
-+      {
-+      case GT:
-+        ops[1] = GEN_INT (x + 1);
-+        code = GE;
-+        break;
-+      case LE:
-+        ops[1] = GEN_INT (x + 1);
-+        code = LT;
-+        break;
-+      case GTU:
-+        ops[1] = GEN_INT (x + 1);
-+        code = GEU;
-+        break;
-+      case LEU:
-+        ops[1] = GEN_INT (x + 1);
-+        code = LTU;
-+        break;
-+      default:
-+        break;
-+      }
-+    }
-+  else if (ops[1] && CONSTANT_P (ops[1]) && GET_MODE(ops[1]) == HImode
-+      && (code == GT || code == LE || code == GTU || code == LEU))
-+    {
-+      /* Handle pointers here */
-+      ops[1] = gen_rtx_CONST(HImode,gen_rtx_PLUS(HImode,ops[1],GEN_INT(1)));
-+      
-+      switch (code)
-+      {
-+      case GT:
-+        code = GE;
-+        break;
-+      case LE:
-+        code = LT;
-+        break;
-+      case GTU:
-+        code = GEU;
-+        break;
-+      case LEU:
-+        code = LTU;
-+        break;
-+      default:
-+        break;
-+      }
-+    }
-+
-+  if (ops[0] != cc0_rtx && ops[1] && ops[0])
-+    {
-+      if (code == NE || code == EQ)
-+      {
-+        /* check if op0 is zero shited - win 1 byte */
-+        if (indexed_location (ops[0]) && !CONSTANT_P (ops[1]))
-+          {
-+            rtx x = ops[0];
-+            ops[0] = ops[1];
-+            ops[1] = x;
-+          }
-+      }
-+
-+      /* check if compares were not issued */
-+      if ((mode == QImode || mode == HImode)
-+        && msp430_cc_source (insn, code, ops[0], ops[1]))
-+      {
-+        /* check if overflow can be usefull here. */
-+        if( ops[1] == const0_rtx 
-+            || (GET_CODE(ops[1]) == CONST_INT
-+                && INTVAL(ops[1]) == 0 ))
-+          {
-+            if(code == LT || code == GE)
-+              nooverflow = 1;
-+          }
-+      }
-+      else if (mode == QImode || mode == HImode)
-+      {
-+        /* check if previous insns did not set CC correctly */
-+        if (quater)
-+          OUT_INSN (len, "cmp.b\t%1, %0", ops);
-+        else
-+          OUT_INSN (len, "cmp\t%1, %0", ops);
-+        dummy += 3;
-+        if (REG_P (ops[0]))
-+          dummy--;
-+        if (REG_P (ops[1]))
-+          dummy--;
-+        if (indexed_location (ops[1]))
-+          dummy--;
-+        if (GET_CODE (ops[1]) == CONST_INT)
-+          {
-+            int x = INTVAL (ops[1]) & 0xffff;
-+            if (x == 0 || x == -1 || x == 1 || x == 2 || x == 4 || x == 8)
-+              dummy--;
-+          }
-+      }
-+
-+      /* adjust distance */
-+      distance -= dummy;
-+
-+      if (mode == SImode && (code == EQ || code == NE))
-+      {
-+        /* compare against zero and can we clobber source register ? */
-+        if (((GET_CODE (ops[1]) == CONST_INT
-+              && INTVAL (ops[1]) == 0)
-+             || ops[1] == const0_rtx)
-+            && REG_P (ops[0]) && dead_or_set_p (insn, ops[0]))
-+          {
-+            OUT_INSN (len, "bis\t%A0, %B0", ops);
-+            OUT_INSN (len, "tst\t%B0", ops);
-+            dummy += 2;
-+          }
-+        else
-+          {
-+            /* cannot clobber or something... */
-+            OUT_INSN (len, "cmp\t%A1, %A0", ops);
-+            dummy += 3;
-+            if (REG_P (ops[0]))
-+              dummy--;
-+            if (REG_P (ops[1]))
-+              dummy--;
-+            if (indexed_location (ops[1]))
-+              dummy--;
-+            if (GET_CODE (ops[1]) == CONST_INT)
-+              {
-+                int x = INTVAL (ops[1]) & 0xffff;
-+                if (x == 0 || x == 1 || x == -1 || x == 2 || x == 4
-+                    || x == 8)
-+                  dummy--;
-+              }
-+            distance -= dummy;
-+            if (distance > 500 || distance < -500)
-+              predist = 3;
-+            else
-+              predist = 1;
-+
-+            if (code == EQ)
-+              {
-+                OUT_INSN (len, "jne\t.LcmpSIe%=", ops);
-+                OUT_INSN (len, "cmp\t%B1, %B0", ops);
-+                dummy++;
-+              }
-+            else
-+              {
-+                ECOND (ne, 0);
-+                OUT_INSN (len, "cmp\t%B1, %B0", ops);
-+              }
-+
-+            dummy += 3;
-+            if (REG_P (ops[0]))
-+              dummy--;
-+            if (REG_P (ops[1]))
-+              dummy--;
-+            if (GET_CODE (ops[1]) == CONST_INT)
-+              {
-+                int x = (INTVAL (ops[1]) >> 16) & 0xffff;
-+                if (x == 0 || x == 0xffff || x == 1 || x == 2 || x == 4
-+                    || x == 8)
-+                  dummy--;
-+              }
-+          }
-+      }
-+      else if (mode == SImode)
-+      {
-+        int dl = 0;
-+        rtx oops[3];
-+        oops[0] = ops[0];
-+        oops[1] = ops[0];
-+        oops[2] = ops[1];
-+
-+        if (len)
-+          msp430_subsi_code (insn, oops, &dl);
-+        else
-+          msp430_subsi_code (insn, oops, NULL);
-+
-+        if (len)
-+          {
-+            /* not handeled by adjust_insn_len() */
-+            dummy += dl;
-+            if (GET_CODE (ops[1]) == CONST_INT)
-+              {
-+                int x = (INTVAL (ops[1]) >> 16) & 0xffff;
-+                if (x == 0 || x == 1 || x == -1 || x == 2 || x == 4
-+                    || x == 8)
-+                  dummy--;
-+                x = (INTVAL (ops[1]) >> 0) & 0xffff;
-+                if (x == 0 || x == 1 || x == -1 || x == 2 || x == 4
-+                    || x == 8)
-+                  dummy--;
-+              }
-+          }
-+      }
-+    }
-+
-+  distance -= dummy;
-+
-+  if (distance > 500 || distance < -500)
-+    predist = 3;
-+  else
-+    predist = 1;
-+
-+  /* out assembler commands if required */
-+  switch (code)
-+    {
-+    case EQ:
-+      ECOND (eq, 0);
-+      if (mode == SImode)
-+      {
-+        OUT_INSN (len, ".LcmpSIe%=:", operands);
-+      }
-+      break;
-+    case NE:
-+      ECOND (ne, 0);
-+      break;
-+    case LT:
-+      if(nooverflow)
-+      ECOND (ltnoovfl,0);
-+      else
-+      ECOND (lt, 0);
-+      break;
-+    case GE:
-+      if(nooverflow)
-+      {
-+        if(len) *len += 2;
-+        if(mode == QImode)
-+          OUT_INSN (len, "bit.b\t#0x80, %0",ops);
-+        else
-+          OUT_INSN (len, "bit\t#0x8000, %0",ops);
-+      }
-+      ECOND (ge, 0);
-+      break;
-+    case LTU:
-+      ECOND (ltu, 0);
-+      break;
-+    case GEU:
-+      ECOND (geu, 0);
-+      break;
-+      /* hopfully the following will not occure */
-+    case LEU:
-+      ECOND (leu, 1);
-+      break;
-+    case GT:
-+      ECOND (gt, 1);
-+      break;
-+    case GTU:
-+      ECOND (gtu, 1);
-+      break;
-+    case LE:
-+      ECOND (le, 1);
-+      break;
-+
-+    default:
-+      break;
-+    }
-+
-+  if (len)
-+    *len = dummy;
-+  return "";
-+}
-+
-+/*****************  AUXES FOR TESTS *********************/
-+
-+RTX_CODE
-+followed_compare_condition (insn)
-+     rtx insn;
-+{
-+  rtx next = next_real_insn (insn);
-+  RTX_CODE cond = UNKNOWN;
-+
-+  if (next && GET_CODE (next) == JUMP_INSN)
-+    {
-+      rtx pat = PATTERN (next);
-+      rtx src, t;
-+
-+      if (GET_CODE (pat) == RETURN)
-+      return UNKNOWN;
-+
-+      src = SET_SRC (pat);
-+      t = XEXP (src, 0);
-+      cond = GET_CODE (t);
-+    }
-+  else if (next && GET_CODE (next) == INSN)
-+    {
-+      /* here, two possible : sgeu ans sltu */
-+
-+      rtx pat = PATTERN (next);
-+      rtx src;
-+
-+      if (!pat || GET_CODE (pat) != SET)
-+      return UNKNOWN;
-+
-+      src = SET_SRC (pat);
-+      cond = GET_CODE (src);  /* this must be IF_THEN_ELSE */
-+      if (cond != IF_THEN_ELSE)
-+      return UNKNOWN;
-+    }
-+  return cond;
-+}
-+
-+/******** jumps ************/
-+
-+const char *
-+msp430_emit_blt0si (operands, len)
-+     rtx operands[];
-+     int len;
-+{
-+  output_asm_insn ("tst\t%B2", operands);
-+  switch (len)
-+    {
-+    case 2:
-+      output_asm_insn ("jl\t%0", operands);
-+      break;
-+    case 4:
-+      output_asm_insn ("jge\t+4", operands);
-+      output_asm_insn ("br\t#%0", operands);
-+      break;
-+    default:
-+      return "bug!!!";
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_beq (operands, len)
-+     rtx operands[];
-+     int len;
-+{
-+
-+  switch (len)
-+    {
-+    case 1:
-+    case 2:
-+      output_asm_insn ("jeq\t%0", operands);
-+      break;
-+    case 3:
-+    case 4:
-+      output_asm_insn ("jne\t+4", operands);
-+      output_asm_insn ("br\t#%0", operands);
-+      break;
-+    default:
-+      return "bug!!!";
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_bne (operands, len)
-+     rtx operands[];
-+     int len;
-+{
-+
-+  switch (len)
-+    {
-+    case 1:
-+    case 2:
-+      output_asm_insn ("jne\t%0", operands);
-+      break;
-+    case 3:
-+    case 4:
-+      output_asm_insn ("jeq\t+4", operands);
-+      output_asm_insn ("br\t#%0", operands);
-+      break;
-+    default:
-+      return "bug!!!";
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_bgt (operands, len)
-+     rtx operands[];
-+     int len;
-+{
-+  switch (len)
-+    {
-+    case 2:
-+      output_asm_insn ("jeq\t+2", operands);
-+      output_asm_insn ("jge\t%0", operands);
-+
-+      break;
-+    case 4:
-+      output_asm_insn ("jeq\t+6", operands);
-+      output_asm_insn ("jl\t+4", operands);
-+      output_asm_insn ("br\t#%0", operands);
-+      break;
-+    default:
-+      return "bug!!!";
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_bgtu (operands, len)
-+     rtx operands[];
-+     int len;
-+{
-+  switch (len)
-+    {
-+    case 2:
-+      output_asm_insn ("jeq\t+2", operands);
-+      output_asm_insn ("jhs\t%0", operands);
-+
-+      break;
-+    case 4:
-+      output_asm_insn ("jeq\t+6", operands);
-+      output_asm_insn ("jlo\t+4", operands);
-+      output_asm_insn ("br\t#%0", operands);
-+      break;
-+    default:
-+      return "bug!!!";
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_blt (operands, len)
-+     rtx operands[];
-+     int len;
-+{
-+  switch (len)
-+    {
-+    case 1:
-+    case 2:
-+      output_asm_insn ("jl\t%0", operands);
-+      break;
-+    case 3:
-+    case 4:
-+      output_asm_insn ("jge\t+4", operands);
-+      output_asm_insn ("br\t#%0", operands);
-+      break;
-+    default:
-+      return "bug!!!";
-+    }
-+
-+  return "";
-+}
-+
-+
-+const char *
-+msp430_emit_bltnoovfl (operands, len)
-+     rtx operands[];
-+     int len;
-+{
-+  switch (len)
-+    {
-+    case 1:
-+    case 2:
-+      output_asm_insn ("jn\t%0", operands);
-+      break;
-+    case 3:
-+    case 4:
-+      output_asm_insn ("jn\t+2",operands);
-+      output_asm_insn ("jmp\t+4", operands);
-+      output_asm_insn ("br\t#%0", operands);
-+      break;
-+    default:
-+      return "bug!!!";
-+    }
-+
-+  return "";
-+}
-+
-+
-+
-+const char *
-+msp430_emit_bltu (operands, len)
-+     rtx operands[];
-+     int len;
-+{
-+  switch (len)
-+    {
-+    case 1:
-+    case 2:
-+      output_asm_insn ("jlo\t%0", operands);
-+      break;
-+    case 3:
-+    case 4:
-+      output_asm_insn ("jhs\t+4", operands);
-+      output_asm_insn ("br\t#%0", operands);
-+      break;
-+    default:
-+      return "bug!!!";
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_bge (operands, len)
-+     rtx operands[];
-+     int len;
-+{
-+  switch (len)
-+    {
-+    case 1:
-+    case 2:
-+      output_asm_insn ("jge\t%l0", operands);
-+      break;
-+    case 3:
-+    case 4:
-+      output_asm_insn ("jl\t+4", operands);
-+      output_asm_insn ("br\t#%0", operands);
-+      break;
-+    default:
-+      return "bug!!!";
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_bgeu (operands, len)
-+     rtx operands[];
-+     int len;
-+{
-+  switch (len)
-+    {
-+    case 1:
-+    case 2:
-+      output_asm_insn ("jhs\t%l0", operands);
-+      break;
-+    case 3:
-+    case 4:
-+      output_asm_insn ("jlo\t+4", operands);
-+      output_asm_insn ("br\t#%0", operands);
-+      break;
-+    default:
-+      return "bug!!!";
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_ble (operands, len)
-+     rtx operands[];
-+     int len;
-+{
-+  switch (len)
-+    {
-+    case 2:
-+      output_asm_insn ("jeq\t%0", operands);
-+      output_asm_insn ("jl\t%0", operands);
-+      break;
-+    case 4:
-+      output_asm_insn ("jeq\t+2", operands);
-+      output_asm_insn ("jge\t+4", operands);
-+      output_asm_insn ("br\t#%0", operands);
-+      break;
-+    default:
-+      return "bug!!!";
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_bleu (operands, len)
-+     rtx operands[];
-+     int len;
-+{
-+  switch (len)
-+    {
-+    case 2:
-+      output_asm_insn ("jeq\t%0", operands);
-+      output_asm_insn ("jlo\t%0", operands);
-+      break;
-+    case 4:
-+      output_asm_insn ("jeq\t+2", operands);
-+      output_asm_insn ("jhs\t+4", operands);
-+      output_asm_insn ("br\t#%0", operands);
-+      break;
-+    default:
-+      return "bug!!!";
-+    }
-+
-+  return "";
-+}
-+
-+
-+/* SHIFT GUARDS */
-+int
-+msp430_ashlhi3 (operands)
-+     rtx operands[];
-+{
-+  int x;
-+  rtx set, shift;
-+  rtx dst;
-+
-+  if (!const_int_operand (operands[2], VOIDmode))
-+    {
-+      rtx op0, op1;
-+
-+      op0 = force_reg (HImode, operands[0]);
-+      op1 = force_reg (HImode, operands[1]);
-+      operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+      emit_insn (gen_ashlhi3_cnt (op0, op1, operands[2]));
-+      emit_move_insn (operands[0], op0);
-+      return 1;
-+    }
-+
-+  x = INTVAL (operands[2]);
-+
-+  if (x > 15 || x < 0)
-+    {
-+      emit_move_insn (operands[0], const0_rtx);
-+      return 1;
-+    }
-+
-+  if (x == 0)
-+    {
-+      emit_move_insn (operands[0], operands[1]);
-+      return 1;
-+    }
-+
-+  if (x < 3)
-+    {
-+      emit_move_insn (operands[0], operands[1]);
-+      dst = operands[0];
-+      shift = gen_rtx_ASHIFT (HImode, dst, const1_rtx);
-+      set = gen_rtx_SET (HImode, dst, shift);
-+      while (x--)
-+      emit_insn (set);
-+      return 1;
-+    }
-+
-+  if (x == 15)
-+    {
-+      shift = gen_rtx_ASHIFT (HImode, operands[1], GEN_INT (15));
-+      set = gen_rtx_SET (HImode, operands[0], shift);
-+      emit_insn (set);
-+      return 1;
-+    }
-+
-+  if (operands[0] != operands[1])
-+    dst = copy_to_mode_reg (HImode, operands[1]);
-+  else
-+    dst = operands[1];
-+  if (x > 7)
-+    {
-+      emit_insn (gen_andhi3 (dst, dst, GEN_INT (0xff)));
-+      emit_insn (gen_swpb (dst, dst));
-+      x -= 8;
-+    }
-+
-+  shift = gen_rtx_ASHIFT (HImode, dst, const1_rtx);
-+  set = gen_rtx_SET (HImode, dst, shift);
-+
-+  while (x--)
-+    emit_insn (set);
-+  if (dst != operands[0])
-+    emit_move_insn (operands[0], dst);
-+  return 1;
-+}
-+
-+int
-+msp430_ashlsi3 (operands)
-+     rtx operands[];
-+{
-+  int x;
-+  rtx shift, set, dst;
-+
-+  if (!const_int_operand (operands[2], VOIDmode))
-+    {
-+      rtx op0, op1;
-+
-+      op0 = force_reg (SImode, operands[0]);
-+      op1 = force_reg (SImode, operands[1]);
-+      operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+      emit_insn (gen_ashlsi3_cnt (op0, op1, operands[2]));
-+      emit_move_insn (operands[0], op0);
-+      return 1;
-+    }
-+
-+  x = INTVAL (operands[2]);
-+
-+  if (x >= 32 || x < 0)
-+    {
-+      emit_move_insn (operands[0], const0_rtx);
-+      return 1;
-+    }
-+
-+  if (x == 0)
-+    {
-+      emit_move_insn (operands[0], operands[1]);
-+      return 1;
-+    }
-+
-+  if (x == 1)
-+    {
-+      emit_move_insn (operands[0], operands[1]);
-+      dst = operands[0];
-+      shift = gen_rtx_ASHIFT (SImode, dst, operands[2]);
-+      set = gen_rtx_SET (SImode, dst, shift);
-+      emit_insn (set);
-+      return 1;
-+    }
-+
-+  if (operands[0] != operands[1])
-+    dst = copy_to_mode_reg (SImode, operands[1]);
-+  else
-+    dst = operands[1];
-+
-+  if (x == 31)
-+    {
-+      shift = gen_rtx_ASHIFT (SImode, operands[1], GEN_INT (31));
-+      set = gen_rtx_SET (SImode, operands[0], shift);
-+      emit_insn (set);
-+      return 1;
-+    }
-+
-+  if (x >= 16)
-+    {
-+      rtx dhi = gen_highpart (HImode, operands[0]);
-+      rtx dlo = gen_lowpart (HImode, operands[0]);
-+      rtx shi = gen_highpart (HImode, operands[1]);
-+      rtx slo = gen_lowpart (HImode, operands[1]);
-+      
-+      emit_move_insn (dhi, slo);
-+      emit_move_insn (dlo, const0_rtx); 
-+      x -= 16;
-+      if (x)
-+      {
-+        rtx ops[3];
-+        ops[0] = dhi;
-+        ops[1] = dhi;
-+        ops[2] = GEN_INT (x);
-+        msp430_ashlhi3 (ops);
-+      }
-+      return 1;
-+    }
-+
-+  if (x >= 8)
-+    {
-+      shift = gen_rtx_ASHIFT (SImode, dst, GEN_INT (8));
-+      set = gen_rtx_SET (SImode, dst, shift);
-+      emit_insn (set);
-+      x -= 8;
-+    }
-+
-+  shift = gen_rtx_ASHIFT (SImode, dst, GEN_INT (1));
-+  set = gen_rtx_SET (SImode, dst, shift);
-+
-+  while (x--)
-+    emit_insn (set);
-+  if (dst != operands[0])
-+    emit_move_insn (operands[0], dst);
-+  return 1;
-+}
-+
-+/* arithmetic right */
-+int
-+msp430_ashrhi3 (operands)
-+     rtx operands[];
-+{
-+  int x;
-+  rtx shift, set, dst;
-+
-+  if (!const_int_operand (operands[2], VOIDmode))
-+    {
-+      rtx op0, op1;
-+
-+      op0 = force_reg (HImode, operands[0]);
-+      op1 = force_reg (HImode, operands[1]);
-+      operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+      emit_insn (gen_ashrhi3_cnt (op0, op1, operands[2]));
-+      emit_move_insn (operands[0], op0);
-+      return 1;
-+    }
-+
-+  x = INTVAL (operands[2]);
-+  if (x >= 15 || x < 0)
-+    {
-+      dst = gen_lowpart (QImode, operands[0]);
-+      emit_move_insn (operands[0], operands[1]);
-+      emit_insn (gen_swpb (operands[0], operands[0]));
-+      emit_insn (gen_extendqihi2 (operands[0], dst));
-+      emit_insn (gen_swpb (operands[0], operands[0]));
-+      emit_insn (gen_extendqihi2 (operands[0], dst));
-+      return 1;
-+    }
-+
-+  if (x == 0)
-+    {
-+      emit_move_insn (operands[0], operands[1]);
-+      return 1;
-+    }
-+
-+  if (x < 3)
-+    {
-+      emit_move_insn (operands[0], operands[1]);
-+      dst = operands[0];
-+      shift = gen_rtx_ASHIFTRT (HImode, dst, const1_rtx);
-+      set = gen_rtx_SET (HImode, dst, shift);
-+
-+      while (x--)
-+      emit_insn (set);
-+      return 1;
-+    }
-+
-+  if (operands[0] != operands[1])
-+    dst = copy_to_mode_reg (HImode, operands[1]);
-+  else
-+    dst = operands[1];
-+
-+  if (x >= 8)
-+    {
-+      rtx dlo = gen_lowpart (QImode, dst);
-+      emit_insn (gen_swpb (dst, dst));
-+      emit_insn (gen_extendqihi2 (dst, dlo));
-+      x -= 8;
-+    }
-+
-+  shift = gen_rtx_ASHIFTRT (HImode, dst, const1_rtx);
-+  set = gen_rtx_SET (HImode, dst, shift);
-+
-+  while (x--)
-+    emit_insn (set);
-+
-+  if (dst != operands[0])
-+    emit_move_insn (operands[0], dst);
-+
-+  return 1;
-+}
-+
-+int
-+msp430_ashrsi3 (operands)
-+     rtx operands[];
-+{
-+  int x;
-+  rtx shift, set, dst;
-+
-+  if (!const_int_operand (operands[2], VOIDmode))
-+    {
-+      rtx op0, op1;
-+
-+      op0 = force_reg (SImode, operands[0]);
-+      op1 = force_reg (SImode, operands[1]);
-+      operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+      emit_insn (gen_ashrsi3_cnt (op0, op1, operands[2]));
-+      emit_move_insn (operands[0], op0);
-+      return 1;
-+    }
-+
-+  x = INTVAL (operands[2]);
-+
-+  if (x == 0)
-+    {
-+      emit_move_insn (operands[0], operands[1]);
-+      return 1;
-+    }
-+
-+  if (operands[0] != operands[1])
-+    dst = copy_to_mode_reg (SImode, operands[1]);
-+  else
-+    dst = operands[1];
-+
-+  if (x >= 31 || x < 0)
-+    {
-+
-+      shift = gen_rtx_ASHIFTRT (SImode, dst, GEN_INT (31));
-+      set = gen_rtx_SET (SImode, dst, shift);
-+      emit_insn (set);
-+
-+      if (dst != operands[0])
-+      emit_move_insn (operands[0], dst);
-+      return 1;
-+    }
-+
-+  if (x == 1)
-+    {
-+      emit_move_insn (operands[0], operands[1]);
-+      dst = operands[0];
-+      shift = gen_rtx_ASHIFTRT (SImode, dst, operands[2]);
-+      set = gen_rtx_SET (SImode, dst, shift);
-+      emit_insn (set);
-+      return 1;
-+    }
-+
-+  if (x >= 16)
-+    {
-+      rtx dlo = gen_lowpart (HImode, operands[0]);
-+      rtx shi = gen_highpart (HImode, dst);
-+
-+      emit_move_insn (gen_highpart (HImode, operands[0]), const0_rtx);
-+      emit_insn (gen_extendhisi2 (operands[0], shi));
-+      x -= 16;
-+      if (x)
-+      {
-+        rtx ops[3];
-+        ops[0] = dlo;
-+        ops[1] = dlo;
-+        ops[2] = GEN_INT (x);
-+        msp430_ashrhi3 (ops);
-+      }
-+      return 1;
-+    }
-+
-+  if (x >= 8)
-+    {
-+      shift = gen_rtx_ASHIFTRT (SImode, dst, GEN_INT (8));
-+      set = gen_rtx_SET (SImode, dst, shift);
-+      emit_insn (set);
-+      x -= 8;
-+    }
-+
-+  shift = gen_rtx_ASHIFTRT (SImode, dst, GEN_INT (1));
-+  set = gen_rtx_SET (SImode, dst, shift);
-+
-+  while (x--)
-+    emit_insn (set);
-+  if (dst != operands[0])
-+    emit_move_insn (operands[0], dst);
-+  return 1;
-+}
-+
-+/* logical right */
-+int
-+msp430_lshrhi3 (operands)
-+     rtx operands[];
-+{
-+  int x;
-+  rtx shift, set, dst;
-+
-+  if (!const_int_operand (operands[2], VOIDmode))
-+    {
-+      rtx op0, op1;
-+
-+      op0 = force_reg (HImode, operands[0]);
-+      op1 = force_reg (HImode, operands[1]);
-+      operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+      emit_insn (gen_lshrhi3_cnt (op0, op1, operands[2]));
-+      emit_move_insn (operands[0], op0);
-+      return 1;
-+    }
-+
-+  x = INTVAL (operands[2]);
-+  if (x > 15 || x < 0)
-+    {
-+      emit_move_insn (operands[0], const0_rtx);
-+      return 1;
-+    }
-+
-+  if (x == 0)
-+    {
-+      emit_move_insn (operands[0], operands[1]);
-+      return 1;
-+    }
-+
-+  if (x < 3)
-+    {
-+      emit_move_insn (operands[0], operands[1]);
-+      dst = operands[0];
-+      shift = gen_rtx_LSHIFTRT (HImode, dst, const1_rtx);
-+      set = gen_rtx_SET (HImode, dst, shift);
-+      emit_insn (set);
-+      x--;
-+
-+      if (x)
-+      {
-+        shift = gen_rtx_ASHIFTRT (HImode, dst, const1_rtx);
-+        set = gen_rtx_SET (HImode, dst, shift);
-+        emit_insn (set);
-+      }
-+      return 1;
-+    }
-+
-+  if (x == 15)
-+    {
-+      emit_move_insn (operands[0], operands[1]);
-+      dst = operands[0];
-+      shift = gen_rtx_LSHIFTRT (HImode, dst, GEN_INT (15));
-+      set = gen_rtx_SET (HImode, dst, shift);
-+      emit_insn (set);
-+      return 1;
-+    }
-+
-+  if (operands[0] != operands[1])
-+    dst = copy_to_mode_reg (HImode, operands[1]);
-+  else
-+    dst = operands[1];
-+
-+  if (x >= 8)
-+    {
-+      rtx dlo = gen_lowpart (QImode, dst);
-+      emit_insn (gen_swpb (dst, dst));
-+      emit_insn (gen_zero_extendqihi2 (dst, dlo));
-+      x -= 8;
-+    }
-+
-+  if (x)
-+    {
-+      shift = gen_rtx_LSHIFTRT (HImode, dst, const1_rtx);
-+      set = gen_rtx_SET (HImode, dst, shift);
-+      x--;
-+      emit_insn (set);
-+    }
-+  shift = gen_rtx_ASHIFTRT (HImode, dst, const1_rtx);
-+  set = gen_rtx_SET (HImode, dst, shift);
-+
-+  while (x--)
-+    emit_insn (set);
-+
-+  if (dst != operands[0])
-+    emit_move_insn (operands[0], dst);
-+
-+  return 1;
-+}
-+
-+int
-+msp430_lshrsi3 (operands)
-+     rtx operands[];
-+{
-+  int x;
-+  rtx shift, set, dst;
-+
-+  if (!const_int_operand (operands[2], VOIDmode))
-+    {
-+      rtx op0, op1;
-+
-+      op0 = force_reg (SImode, operands[0]);
-+      op1 = force_reg (SImode, operands[1]);
-+      operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+      emit_insn (gen_lshrsi3_cnt (op0, op1, operands[2]));
-+      emit_move_insn (operands[0], op0);
-+      return 1;
-+    }
-+
-+  x = INTVAL (operands[2]);
-+
-+  if (x == 0)
-+    {
-+      emit_move_insn (operands[0], operands[1]);
-+      return 1;
-+    }
-+
-+  if (x == 1)
-+    {
-+      emit_move_insn (operands[0], operands[1]);
-+      dst = operands[0];
-+      shift = gen_rtx_LSHIFTRT (SImode, dst, operands[2]);
-+      set = gen_rtx_SET (SImode, dst, shift);
-+      emit_insn (set);
-+      return 1;
-+    }
-+
-+  if (x > 31 || x < 0)
-+    {
-+      emit_move_insn (operands[0], const0_rtx);
-+      return 1;
-+    }
-+
-+  if (operands[0] != operands[1])
-+    dst = copy_to_mode_reg (SImode, operands[1]);
-+  else
-+    dst = operands[1];
-+
-+  if (x >= 16)
-+    {
-+      rtx dlo = gen_lowpart (HImode, operands[0]);
-+      rtx shi = gen_highpart (HImode, dst);
-+
-+      emit_move_insn (gen_highpart (HImode, operands[0]), const0_rtx);
-+      emit_insn (gen_zero_extendhisi2 (operands[0], shi));
-+      x -= 16;
-+      if (x)
-+      {
-+        rtx ops[3];
-+        ops[0] = dlo;
-+        ops[1] = dlo;
-+        ops[2] = GEN_INT (x);
-+        msp430_lshrhi3 (ops);
-+      }
-+      return 1;
-+    }
-+
-+  if (x >= 8)
-+    {
-+      shift = gen_rtx_LSHIFTRT (SImode, dst, GEN_INT (8));
-+      set = gen_rtx_SET (SImode, dst, shift);
-+      emit_insn (set);
-+      x -= 8;
-+    }
-+
-+  if (x)
-+    {
-+      shift = gen_rtx_LSHIFTRT (SImode, dst, const1_rtx);
-+      set = gen_rtx_SET (SImode, dst, shift);
-+      emit_insn (set);
-+      x--;
-+    }
-+
-+  shift = gen_rtx_ASHIFTRT (SImode, dst, GEN_INT (1));
-+  set = gen_rtx_SET (SImode, dst, shift);
-+
-+  while (x--)
-+    emit_insn (set);
-+  if (dst != operands[0])
-+    emit_move_insn (operands[0], dst);
-+  return 1;
-+}
-+
-+/******* COMMON SHIFT CODE ***************/
-+int
-+is_shift_better_in_reg (operands)
-+     rtx operands[];
-+{
-+  rtx x = operands[0];
-+  rtx cnt = operands[2];
-+  int size = GET_MODE_SIZE (x->mode);
-+  int icnt = -1;
-+  int r = 0;
-+
-+  if (!optimize)
-+    return 0;
-+
-+  if (GET_CODE (cnt) == CONST_INT)
-+    icnt = INTVAL (cnt);
-+  else
-+    return 1;
-+
-+  switch (size)
-+    {
-+    case 1:
-+      if (icnt != 1 && icnt != 2 && icnt != 7)
-+      r = 1;
-+      break;
-+    case 2:
-+      if (icnt != 1 && icnt != 2 && icnt != 8 && icnt != 15)
-+      r = 2;
-+      break;
-+    case 4:
-+      if (icnt != 1
-+        && icnt != 2 && icnt != 8 && icnt != 16 && icnt != 24 && icnt != 31)
-+      r = 4;
-+      break;
-+    case 8:
-+      if (icnt != 1
-+        && icnt != 2 && icnt != 16 && icnt != 32 && icnt != 48 && icnt != 63)
-+      r = 8;
-+      break;
-+    }
-+
-+  return r;
-+}
-+
-+
-+static int set_len PARAMS ((rtx, int, int));
-+/* for const operand2 and for SI, DI modes.*/
-+static int
-+set_len (x, bl, sc)
-+     rtx x;                   /* operand0 */
-+     int bl;                  /* base length in assumption of memory operand */
-+     int sc;                  /* shift count */
-+{
-+  int dummy;
-+  int zs = zero_shifted (x);
-+  int size = GET_MODE_SIZE (x->mode);
-+  int sshi = 0;
-+
-+  if (size == 4)
-+    sshi = 1;
-+  else if (size == 8)
-+    sshi = 2;
-+
-+  if (size == 1)
-+    size++;
-+
-+  if (GET_CODE (x) == REG)
-+    dummy = (bl >> 1) - sshi; /* bl / 2 is not fully correct */
-+  else if (zs)
-+    dummy = bl - (size >> 1) + 1;
-+  else if (indexed_location (x))
-+    dummy = bl - 1;
-+  else
-+    dummy = bl;
-+
-+  return dummy * sc;
-+}
-+
-+static int set_ren PARAMS ((rtx, int, int));
-+/* for const operand2 and for SI, DI modes.*/
-+static int
-+set_ren (x, bl, sc)
-+     rtx x;                   /* operand0 */
-+     int bl;                  /* base length in assumption of memory operand */
-+     int sc;                  /* shift count */
-+{
-+  int dummy;
-+
-+  bl *= sc;
-+  if (GET_CODE (x) == REG)
-+    dummy = bl / 2;
-+  else if (indexed_location (x))
-+    dummy = bl - sc;
-+  else
-+    dummy = bl;
-+  return dummy;
-+}
-+
-+static int set_rel PARAMS ((rtx, int, int));
-+/* for const operand2 and for SI, DI modes.*/
-+static int
-+set_rel (x, bl, sc)
-+     rtx x;                   /* operand0 */
-+     int bl;                  /* base length in assumption of memory operand */
-+     int sc;                  /* shift count */
-+{
-+  int dummy;
-+
-+  bl *= sc;
-+  if (GET_CODE (x) == REG)
-+    dummy = bl / 2;
-+  else if (indexed_location (x))
-+    dummy = bl - sc;
-+  else
-+    dummy = bl;
-+  dummy += sc;
-+  return dummy;
-+}
-+
-+
-+
-+#define INST_THRESHOLD  16
-+
-+int
-+msp430_emit_shift_cnt (set_len_fun, pattern, insn, operands, len, lsc)
-+     int (*set_len_fun) (rtx, int, int);
-+     const char *pattern;
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+     int lsc;
-+{
-+  rtx op[10];
-+  int dummy = 0;
-+
-+  op[0] = operands[0];
-+  op[1] = operands[1];
-+  op[2] = operands[2];
-+  op[3] = operands[3];
-+
-+
-+  OUT_INSN (len, "tst\t%2", op);
-+  OUT_INSN (len, "jz\t.Lsend%=\n.Lsst%=:", op);
-+  OUT_INSN (len, pattern, op);
-+  OUT_INSN (len, "dec\t%2", op);
-+  OUT_INSN (len, "jnz\t.Lsst%=\n.Lsend%=:", op);
-+  dummy = (set_len_fun) (op[0], lsc, 1) + 4;
-+  if (!REG_P (op[2]) && !indexed_location (op[2]))
-+    dummy += 2;
-+
-+
-+  if (len)
-+    *len = dummy;
-+  return 0;
-+}
-+
-+
-+/* <<<<<<<<<<<<< SHIFT LEFT CODE <<<<<<<<<<<<<<<<<     */
-+
-+const char *
-+msp430_emit_ashlqi3 (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
-+  const char *pattern;
-+  int shiftpos;
-+
-+  if (zs)
-+    pattern = "rla.b\t@%E0";
-+  else
-+    pattern = "rla.b\t%A0";
-+
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+    {
-+      shiftpos = INTVAL (operands[2]);
-+
-+      switch (shiftpos)
-+      {
-+      default:
-+        if (zs)
-+          OUT_INSN (len, "clr.b\t@%E0", operands);
-+        else
-+          OUT_INSN (len, "clr.b\t%A0", operands);
-+        dummy = 2;
-+        if (REG_P (operands[0]))
-+          dummy >>= 1;
-+        break;
-+
-+      case 0:         /* paranoia setting */
-+        dummy = 0;
-+        break;
-+
-+      case 1:
-+      case 2:
-+      case 3:
-+      case 4:
-+      case 5:
-+      case 6:
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += set_len (operands[0], 3, 1);
-+          }
-+        break;
-+
-+      case 7:
-+        if (zs)
-+          {
-+            OUT_INSN (len, "rra.b\t%0", operands);
-+            OUT_INSN (len, "clr.b\t%0", operands);
-+            OUT_INSN (len, "rrc.b\t%0", operands);
-+            dummy = 5;
-+          }
-+        else
-+          {
-+            OUT_INSN (len, "rra.b\t%0", operands);
-+            OUT_INSN (len, "clr.b\t%0", operands);
-+            OUT_INSN (len, "rrc.b\t%0", operands);
-+            dummy = 6;
-+            if (REG_P (operands[0]))
-+              dummy = 3;
-+          }
-+
-+        break;
-+      }
-+
-+      if (len)
-+      *len = dummy;
-+      return "";
-+
-+    }
-+  else
-+    {
-+      msp430_emit_shift_cnt (set_len, pattern, insn, operands, len, 3);
-+    }
-+
-+  return "";
-+}
-+
-+
-+const char *
-+msp430_emit_ashlhi3 (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs;
-+  const char *pattern;
-+  int shiftpos;
-+
-+  zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
-+
-+  if (zs)
-+    pattern = "rla\t@%E0";
-+  else
-+    pattern = "rla\t%A0";
-+
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+    {
-+      shiftpos = INTVAL (operands[2]);
-+
-+      switch (shiftpos)
-+      {
-+      case 0:         /* paranoia setting */
-+        dummy = 0;
-+        break;
-+
-+      case 1:
-+      case 2:
-+      case 3:
-+      case 4:
-+      case 5:
-+      case 6:
-+      case 7:
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += set_len (operands[0], 3, 1);
-+          }
-+        break;
-+
-+      case 8:
-+      case 9:
-+      case 10:
-+      case 11:
-+      case 12:
-+      case 13:
-+      case 14:
-+        if (zs)
-+          {
-+            dummy = 3;
-+            OUT_INSN (len, "and.b\t#0xffff, %A0", operands);
-+            OUT_INSN (len, "swpb\t@%E0", operands);
-+          }
-+        else
-+          {
-+            dummy = 4;
-+            OUT_INSN (len, "and.b\t#0xffff, %A0", operands);
-+            OUT_INSN (len, "swpb\t%A0", operands);
-+            if (REG_P (operands[0]))
-+              dummy = 2;
-+          }
-+
-+
-+        shiftpos -= 8;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += set_len (operands[0], 3, 1);
-+          }
-+        break;
-+
-+      case 15:
-+        if (zs)
-+          {
-+            OUT_INSN (len, "rra\t%0", operands);
-+            OUT_INSN (len, "clr\t%0", operands);
-+            OUT_INSN (len, "rrc\t%0", operands);
-+            dummy = 5;
-+          }
-+        else
-+          {
-+            OUT_INSN (len, "rra\t%0", operands);
-+            OUT_INSN (len, "clr\t%0", operands);
-+            OUT_INSN (len, "rrc\t%0", operands);
-+            dummy = 6;
-+            if (REG_P (operands[0]))
-+              dummy = 3;
-+          }
-+
-+        break;
-+
-+
-+      default:
-+
-+        OUT_INSN (len, "clr\t%A0", operands);
-+        dummy = 2;
-+        if (REG_P (operands[0]))
-+          dummy = 1;
-+        break;
-+      }
-+
-+      if (len)
-+      *len = dummy;
-+      return "";
-+    }
-+  else
-+    {
-+      msp430_emit_shift_cnt (set_len, pattern, insn, operands, len, 3);
-+    }
-+
-+  return "";
-+}
-+
-+
-+const char *
-+msp430_emit_ashlsi3 (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+
-+  int dummy = 0;
-+  int zs;
-+  const char *pattern;
-+
-+  zs = zero_shifted (operands[0]);
-+
-+  if (zs)
-+    pattern = "add\t@%E0+, -2(%E0)\n\taddc\t@%E0+, -2(%E0)\n\tsub\t#4, %E0";
-+  else
-+    pattern = "rla\t%A0\n\trlc\t%B0";
-+
-+
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+    {
-+      int shiftpos = INTVAL (operands[2]);
-+
-+      switch (shiftpos)
-+      {
-+
-+      case 0:
-+        dummy = 0;
-+        break;
-+      case 1:
-+      case 2:
-+      case 3:
-+      case 4:
-+      case 5:
-+      case 6:
-+      case 7:
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += set_len (operands[0], 6, 1);
-+          }
-+        break;
-+
-+      case 8:
-+      case 9:
-+      case 10:
-+      case 11:
-+      case 12:
-+      case 13:
-+      case 14:
-+      case 15:
-+
-+        if (zs || indexed_location (operands[0]))
-+          {
-+            OUT_INSN (len, "xor.b\t@%E0, %B0", operands);
-+            OUT_INSN (len, "xor\t@%E0, %B0", operands);
-+            OUT_INSN (len, "swpb\t%B0", operands);
-+            OUT_INSN (len, "and.b\t#-1, %A0", operands);
-+            OUT_INSN (len, "swpb\t@%E0", operands);
-+            dummy = 9;
-+          }
-+        else
-+          {
-+            OUT_INSN (len, "xor.b\t%A0, %B0", operands);
-+            OUT_INSN (len, "xor\t%A0, %B0", operands);
-+            OUT_INSN (len, "swpb\t%B0", operands);
-+            OUT_INSN (len, "and.b\t#-1, %A0", operands);
-+            OUT_INSN (len, "swpb\t%A0", operands);
-+            dummy = 12;
-+            if (REG_P (operands[0]))
-+              dummy = 5;
-+          }
-+
-+        shiftpos -= 8;
-+
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += set_len (operands[0], 6, 1);
-+          }
-+
-+        if (len)
-+          *len = dummy;
-+        return "";
-+
-+        break;
-+
-+      case 16:
-+      case 17:
-+      case 18:
-+      case 19:
-+      case 20:
-+      case 21:
-+      case 22:
-+      case 23:
-+
-+        if (zs || indexed_location (operands[0]))
-+          {
-+            OUT_INSN (len, "mov\t@%E0, %B0", operands);
-+            OUT_INSN (len, "clr\t%A0", operands);
-+            dummy = 4;
-+          }
-+        else
-+          {
-+            OUT_INSN (len, "mov\t%A0, %B0", operands);
-+            OUT_INSN (len, "clr\t%A0", operands);
-+            dummy = 5;
-+            if (REG_P (operands[0]))
-+              dummy = 3;
-+          }
-+
-+        shiftpos -= 16;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += set_len (operands[0], 6, 1);
-+          }
-+
-+        if (len)
-+          *len = dummy;
-+        return "";
-+        break;
-+
-+      case 24:
-+      case 25:
-+      case 26:
-+      case 27:
-+      case 28:
-+      case 29:
-+      case 30:
-+        if (zs || indexed_location (operands[0]))
-+          {
-+            OUT_INSN (len, "mov.b\t@%E0,%B0", operands);
-+            OUT_INSN (len, "swpb\t%B0", operands);
-+            OUT_INSN (len, "clr\t@%E0", operands);
-+            dummy = 6;
-+          }
-+        else
-+          {
-+            OUT_INSN (len, "mov.b\t%A0,%B0", operands);
-+            OUT_INSN (len, "swpb\t%B0", operands);
-+            OUT_INSN (len, "clr\t%A0", operands);
-+            dummy = 8;
-+            if (GET_CODE (operands[0]) == REG)
-+              dummy = 3;
-+          }
-+
-+        shiftpos -= 24;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += set_len (operands[0], 6, 1);
-+          }
-+
-+        if (len)
-+          *len = dummy;
-+        return "";
-+
-+        break;
-+
-+      case 31:
-+        if (zs || indexed_location (operands[0]))
-+          {
-+            OUT_INSN (len, "rra\t@%E0", operands);
-+            OUT_INSN (len, "clr\t%A0", operands);
-+            OUT_INSN (len, "clr\t%B0", operands);
-+            OUT_INSN (len, "rrc\t%B0", operands);
-+            dummy = 9;
-+
-+          }
-+        else
-+          {
-+            OUT_INSN (len, "rra\t%A0", operands);
-+            OUT_INSN (len, "clr\t%A0", operands);
-+            OUT_INSN (len, "clr\t%B0", operands);
-+            OUT_INSN (len, "rrc\t%B0", operands);
-+            dummy = 10;
-+            if (REG_P (operands[0]))
-+              dummy = 4;
-+          }
-+
-+        if (len)
-+          *len = dummy;
-+        return "";
-+        break;
-+
-+      default:
-+        OUT_INSN (len, "clr\t%A0", operands);
-+        OUT_INSN (len, "clr\t%B0", operands);
-+        if (len)
-+          *len = set_len (operands[0], 6, 1);
-+        return "";
-+        break;
-+
-+      }                       /* switch */
-+
-+      if (len)
-+      *len = dummy;
-+      return "";
-+    }
-+  else
-+    msp430_emit_shift_cnt (set_len, pattern, insn, operands, len, 6);
-+
-+  return "";
-+
-+}
-+
-+const char *
-+msp430_emit_ashldi3 (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+
-+  int dummy = 0;
-+  int zs;
-+  const char *pattern;
-+
-+  zs = zero_shifted (operands[0]);
-+
-+  if (zs)
-+    pattern =
-+      "add\t@%E0+,-2(%E0)\n\taddc\t@%E0+,-2(%E0)\n\taddc\t@%E0+,-2(%E0)\n\taddc\t@%E0+,-2(%E0)\n\tsub\t#8,%E0";
-+  else
-+    pattern = "rla\t%A0\n\trlc\t%B0\n\trlc\t%C0\n\trlc\t%D0";
-+
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+    {
-+      int shiftpos = INTVAL (operands[2]);
-+
-+      switch (shiftpos)
-+      {
-+      case 0:
-+        dummy = 0;
-+        if (len)
-+          *len = dummy;
-+        break;
-+
-+      case 1:
-+      case 2:
-+      case 3:
-+      case 4:
-+      case 5:
-+      case 6:
-+      case 7:
-+      case 8:
-+      case 9:
-+      case 10:
-+      case 11:
-+      case 12:
-+      case 13:
-+      case 14:
-+      case 15:
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += set_len (operands[0], 12, 1);
-+          }
-+        if (len)
-+          *len = dummy;
-+        break;
-+
-+      case 16:
-+      case 17:
-+      case 18:
-+      case 19:
-+      case 20:
-+      case 21:
-+      case 22:
-+      case 23:
-+        if (zs || indexed_location (operands[0]))
-+          {
-+            dummy = 10;
-+            OUT_INSN (len, "mov\t%C0, %D0", operands);
-+            OUT_INSN (len, "mov\t%B0, %C0", operands);
-+            OUT_INSN (len, "mov\t@%E0, %B0", operands);
-+            OUT_INSN (len, "clr\t@%E0", operands);
-+          }
-+        else
-+          {
-+            dummy = 11;
-+            OUT_INSN (len, "mov\t%C0, %D0", operands);
-+            OUT_INSN (len, "mov\t%B0, %C0", operands);
-+            OUT_INSN (len, "mov\t%A0, %B0", operands);
-+            OUT_INSN (len, "clr\t%A0", operands);
-+
-+          }
-+        if (GET_CODE (operands[0]) == REG)
-+          dummy = 4;
-+        shiftpos -= 16;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += set_len (operands[0], 12, 1);
-+          }
-+        if (len)
-+          *len = dummy;
-+        break;
-+
-+      case 24:
-+      case 25:
-+      case 26:
-+      case 27:
-+      case 28:
-+      case 29:
-+      case 30:
-+      case 31:
-+        if (zs)
-+          {
-+            dummy = 8;
-+            OUT_INSN (len, "mov\t@%E0, %D0", operands);
-+            OUT_INSN (len, "clr\t%A0", operands);
-+            OUT_INSN (len, "clr\t%B0", operands);
-+            OUT_INSN (len, "clr\t%C0", operands);
-+
-+          }
-+        else
-+          {
-+            dummy = 9;
-+            OUT_INSN (len, "mov\t%A0, %D0", operands);
-+            OUT_INSN (len, "clr\t%A0", operands);
-+            OUT_INSN (len, "clr\t%B0", operands);
-+            OUT_INSN (len, "clr\t%C0", operands);
-+          }
-+        if (GET_CODE (operands[0]) == REG)
-+          dummy = 4;
-+
-+        shiftpos -= 16;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += set_len (operands[0], 12, 1);
-+          }
-+
-+        if (len)
-+          *len = dummy;
-+        break;
-+
-+      case 32:
-+      case 33:
-+      case 34:
-+      case 35:
-+      case 36:
-+      case 37:
-+      case 38:
-+      case 39:
-+      case 40:
-+      case 41:
-+      case 42:
-+      case 43:
-+      case 44:
-+      case 45:
-+      case 46:
-+      case 47:
-+
-+        if (zs)
-+          {
-+            OUT_INSN (len, "mov\t@%E0+, %C0", operands);
-+            OUT_INSN (len, "mov\t@%E0+, %D0", operands);
-+            OUT_INSN (len, "sub\t#4, %E0", operands);
-+            OUT_INSN (len, "clr\t%A0", operands);
-+            OUT_INSN (len, "clr\t%B0", operands);
-+            dummy = 9;
-+          }
-+        else
-+          {
-+            dummy = 10;
-+            OUT_INSN (len, "mov\t%A0, %C0", operands);
-+            OUT_INSN (len, "mov\t%B0, %D0", operands);
-+            OUT_INSN (len, "clr\t%A0", operands);
-+            OUT_INSN (len, "clr\t%B0", operands);
-+          }
-+        if (GET_CODE (operands[0]) == REG)
-+          dummy = 4;
-+
-+        shiftpos -= 32;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += set_len (operands[0], 12, 1);
-+          }
-+
-+        if (len)
-+          *len = dummy;
-+        break;
-+
-+      case 48:
-+      case 49:
-+      case 50:
-+      case 51:
-+      case 52:
-+      case 53:
-+      case 54:
-+      case 55:
-+      case 56:
-+      case 57:
-+      case 58:
-+      case 59:
-+      case 60:
-+      case 61:
-+      case 62:
-+        if (zs)
-+          {
-+            dummy = 8;
-+            OUT_INSN (len, "mov\t@%E0, %D0", operands);
-+            OUT_INSN (len, "clr\t%A0", operands);
-+            OUT_INSN (len, "clr\t%B0", operands);
-+            OUT_INSN (len, "clr\t%C0", operands);
-+          }
-+        else
-+          {
-+            dummy = 9;
-+            OUT_INSN (len, "mov\t%A0, %D0", operands);
-+            OUT_INSN (len, "clr\t%A0", operands);
-+            OUT_INSN (len, "clr\t%B0", operands);
-+            OUT_INSN (len, "clr\t%C0", operands);
-+          }
-+
-+        shiftpos -= 48;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += set_len (operands[0], 12, 1);
-+          }
-+
-+        if (GET_CODE (operands[0]) == REG)
-+          dummy = 4;
-+        if (len)
-+          *len = dummy;
-+
-+        break;
-+
-+      case 63:
-+        if (zs || indexed_location (operands[0]))
-+          {
-+            OUT_INSN (len, "rra\t@%E0", operands);
-+            OUT_INSN (len, "clr\t%A0", operands);
-+            OUT_INSN (len, "clr\t%B0", operands);
-+            OUT_INSN (len, "clr\t%C0", operands);
-+            OUT_INSN (len, "clr\t%D0", operands);
-+            OUT_INSN (len, "rrc\t%D0", operands);
-+            dummy = 11;
-+          }
-+        else
-+          {
-+            OUT_INSN (len, "rra\t%A0", operands);
-+            OUT_INSN (len, "clr\t%A0", operands);
-+            OUT_INSN (len, "clr\t%B0", operands);
-+            OUT_INSN (len, "clr\t%C0", operands);
-+            OUT_INSN (len, "clr\t%D0", operands);
-+            OUT_INSN (len, "rrc\t%D0", operands);
-+            dummy = 12;
-+            if (REG_P (operands[0]))
-+              dummy = 6;
-+          }
-+
-+        if (len)
-+          *len = dummy;
-+
-+        break;                /* make compiler happy */
-+
-+      default:
-+        OUT_INSN (len, "clr\t%A0", operands);
-+        OUT_INSN (len, "clr\t%B0", operands);
-+        OUT_INSN (len, "clr\t%C0", operands);
-+        OUT_INSN (len, "clr\t%D0", operands);
-+        dummy = 8;
-+        if (zs)
-+          dummy--;
-+        if (REG_P (operands[0]))
-+          dummy = 4;
-+
-+        if (len)
-+          *len = dummy;
-+
-+      }                       /* switch */
-+
-+      return "";
-+    }
-+  else
-+    msp430_emit_shift_cnt (set_len, pattern, insn, operands, len, 12);
-+
-+  return "";                  /* make compiler happy */
-+}
-+
-+/********* SHIFT RIGHT CODE ***************************************/
-+const char *
-+msp430_emit_ashrqi3 (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
-+  const char *pattern;
-+  int shiftpos;
-+
-+  if (zs)
-+    pattern = "rra.b\t@%E0";
-+  else
-+    pattern = "rra.b\t%A0";
-+
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+    {
-+
-+      shiftpos = INTVAL (operands[2]);
-+
-+      switch (shiftpos)
-+      {
-+      case 0:         /* paranoia setting */
-+        dummy = 0;
-+        break;
-+
-+      case 1:
-+      case 2:
-+      case 3:
-+      case 4:
-+      case 5:
-+      case 6:
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += 2;
-+          }
-+        break;
-+
-+      case 7:
-+        if (zs)
-+          {
-+            OUT_INSN (len, "sxt\t@%E0", operands);
-+            OUT_INSN (len, "swpb\t@%E0", operands);
-+            OUT_INSN (len, "and.b\t#-1, %A0", operands);
-+            dummy = 4;
-+          }
-+        else
-+          {
-+            OUT_INSN (len, "sxt\t%A0", operands);
-+            OUT_INSN (len, "swpb\t%A0", operands);
-+            OUT_INSN (len, "and.b\t#-1, %A0", operands);
-+            dummy = 6;
-+          }
-+        if (REG_P (operands[0]))
-+          dummy = 3;
-+        if (len)
-+          *len = dummy;
-+        return "";
-+
-+        break;
-+
-+      default:
-+        OUT_INSN (len, "clr.b\t%A0", operands);
-+        dummy = 2;
-+        if (REG_P (operands[0]))
-+          dummy = 1;
-+      }
-+
-+      if (len)
-+      *len = dummy;
-+      return "";
-+    }
-+  else
-+    {
-+      msp430_emit_shift_cnt (set_ren, pattern, insn, operands, len, 2);
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_ashrhi3 (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
-+  const char *pattern;
-+  int shiftpos;
-+
-+  if (zs)
-+    pattern = "rra\t@%E0";
-+  else
-+    pattern = "rra\t%A0";
-+
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+    {
-+      shiftpos = INTVAL (operands[2]);
-+
-+      switch (shiftpos)
-+      {
-+      case 0:         /* paranoia setting */
-+        dummy = 0;
-+        break;
-+
-+      case 1:
-+      case 2:
-+      case 3:
-+      case 4:
-+      case 5:
-+      case 6:
-+      case 7:
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += 2;
-+          }
-+        if (zs || REG_P (operands[0]))
-+          dummy >>= 1;
-+        break;
-+
-+      case 8:
-+      case 9:
-+      case 10:
-+      case 11:
-+      case 12:
-+      case 13:
-+      case 14:
-+        if (zs)
-+          {
-+            OUT_INSN (len, "swpb\t@%E0", operands);
-+            OUT_INSN (len, "sxt\t@%E0", operands);
-+            dummy = 2;
-+          }
-+        else
-+          {
-+            OUT_INSN (len, "swpb\t%A0", operands);
-+            OUT_INSN (len, "sxt\t%A0", operands);
-+            dummy = 4;
-+            if (REG_P (operands[0]))
-+              dummy = 2;
-+          }
-+        shiftpos -= 8;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += (zs || REG_P (operands[0])) ? 1 : 2;
-+          }
-+        break;
-+
-+      case 15:
-+        if (zs)
-+          {
-+            OUT_INSN (len, "swpb\t@%E0", operands);
-+            OUT_INSN (len, "sxt\t@%E0", operands);
-+            OUT_INSN (len, "swpb\t@%E0", operands);
-+            OUT_INSN (len, "swpb\t@%E0", operands);
-+            dummy = 4;
-+          }
-+        else
-+          {
-+            OUT_INSN (len, "swpb\t%A0", operands);
-+            OUT_INSN (len, "sxt\t%A0", operands);
-+            OUT_INSN (len, "swpb\t%A0", operands);
-+            OUT_INSN (len, "sxt\t%A0", operands);
-+            dummy = 8;
-+          }
-+        if (REG_P (operands[0]))
-+          dummy = 4;
-+        break;
-+
-+      default:
-+        OUT_INSN (len, "clr\t%A0", operands);
-+        dummy = 2;
-+        if (REG_P (operands[0]))
-+          dummy = 1;
-+      }
-+
-+      if (len)
-+      *len = dummy;
-+      return "";
-+    }
-+  else
-+    {
-+      msp430_emit_shift_cnt (set_ren, pattern, insn, operands, len, 2);
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_ashrsi3 (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+
-+  int dummy = 0;
-+  const char *pattern;
-+  int zs = zero_shifted (operands[0]);
-+
-+  pattern = "rra\t%B0\n\trrc\t%A0";
-+
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+    {
-+      int shiftpos = INTVAL (operands[2]);
-+
-+      switch (shiftpos)
-+      {
-+      case 0:
-+        dummy = 0;
-+        break;
-+      case 1:
-+      case 2:
-+      case 3:
-+      case 4:
-+      case 5:
-+      case 6:
-+      case 7:
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += set_ren (operands[0], 4, 1);
-+          }
-+        break;
-+
-+      case 8:
-+      case 9:
-+      case 10:
-+      case 11:
-+      case 12:
-+      case 13:
-+      case 14:
-+      case 15:
-+        OUT_INSN (len, "swpb\t%A0", operands);
-+        OUT_INSN (len, "swpb\t%B0", operands);
-+        OUT_INSN (len, "xor.b\t%B0, %A0", operands);
-+        OUT_INSN (len, "xor\t%B0, %A0", operands);
-+        OUT_INSN (len, "sxt\t%B0", operands);
-+        dummy = 12;
-+
-+        if (REG_P (operands[0]))
-+          dummy = 5;
-+        shiftpos -= 8;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += set_ren (operands[0], 4, 1);
-+          }
-+        break;
-+
-+      case 16:
-+      case 17:
-+      case 18:
-+      case 19:
-+      case 20:
-+      case 21:
-+      case 22:
-+      case 23:
-+        OUT_INSN (len, "mov\t%B0, %A0", operands);
-+        OUT_INSN (len, "bit\t#0x8000, %B0", operands);
-+        OUT_INSN (len, "jz\t.Lsrc%=", operands);
-+        OUT_INSN (len, "bis\t#0xffff, %B0", operands);
-+        OUT_INSN (len, "jmp\t.Lsre%=\n.Lsrc%=:", operands);
-+        OUT_INSN (len, "clr\t%B0\n.Lsre%=:", operands);
-+        dummy = 12;
-+
-+        if (GET_CODE (operands[0]) == REG)
-+          dummy = 7;
-+
-+        shiftpos -= 16;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, "rra\t%A0", operands);
-+            dummy += 2;
-+            if (GET_CODE (operands[0]) == REG || zs)
-+              dummy--;
-+          }
-+
-+        break;
-+
-+      case 24:
-+      case 25:
-+      case 26:
-+      case 27:
-+      case 28:
-+      case 29:
-+      case 30:
-+        OUT_INSN (len, "swpb\t%B0", operands);
-+        OUT_INSN (len, "sxt\t%B0", operands);
-+        OUT_INSN (len, "mov\t%B0, %A0", operands);
-+        OUT_INSN (len, "swpb\t%B0", operands);
-+        OUT_INSN (len, "sxt\t%B0", operands);
-+        dummy = 11;
-+
-+        if (GET_CODE (operands[0]) == REG)
-+          dummy = 5;
-+
-+        shiftpos -= 24;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, "rra\t%A0", operands);
-+            dummy += 2;
-+            if (GET_CODE (operands[0]) == REG || zs)
-+              dummy--;
-+          }
-+        break;
-+
-+      case 31:
-+        OUT_INSN (len, "tst\t%B0", operands);
-+        OUT_INSN (len, "mov\t#-1,%B0", operands);
-+        OUT_INSN (len, "mov\t#-1,%A0", operands);
-+        if (GET_CODE (operands[0]) == REG)
-+          OUT_INSN (len, "jn\t+4", operands);
-+        else
-+          OUT_INSN (len, "jn\t+8", operands);
-+        OUT_INSN (len, "clr\t%A0", operands);
-+        OUT_INSN (len, "clr\t%B0", operands);
-+        dummy = 11;
-+        if (GET_CODE (operands[0]) == REG)
-+          dummy = 6;
-+        break;
-+
-+      default:
-+        dummy = 0;            /* leave it alone!!! */
-+        break;
-+
-+      }                       /* switch */
-+
-+      if (len)
-+      *len = dummy;
-+      return "";
-+    }
-+  else
-+    msp430_emit_shift_cnt (set_ren, pattern, insn, operands, len, 4);
-+
-+  return "";
-+
-+}
-+
-+const char *
-+msp430_emit_ashrdi3 (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+
-+  int dummy = 0;
-+  const char *pattern;
-+
-+  pattern = "rra\t%D0\n\trrc\t%C0\n\trrc\t%B0\n\trrc\t%A0";
-+
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+    {
-+      int shiftpos = INTVAL (operands[2]);
-+
-+      switch (shiftpos)
-+      {
-+      case 0:
-+        dummy = 0;
-+        break;
-+      case 1:
-+      case 2:
-+      case 3:
-+      case 4:
-+      case 5:
-+      case 6:
-+      case 7:
-+      case 8:
-+      case 9:
-+      case 10:
-+      case 11:
-+      case 12:
-+      case 13:
-+      case 14:
-+      case 15:
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, pattern, operands);
-+            dummy += set_ren (operands[0], 8, 1);
-+          }
-+        break;
-+
-+      case 16:
-+      case 17:
-+      case 18:
-+      case 19:
-+      case 20:
-+      case 21:
-+      case 22:
-+      case 23:
-+      case 24:
-+      case 25:
-+      case 26:
-+      case 27:
-+      case 28:
-+      case 29:
-+      case 30:
-+      case 31:
-+
-+        OUT_INSN (len, "mov\t%B0, %A0", operands);
-+        OUT_INSN (len, "mov\t%C0, %B0", operands);
-+        OUT_INSN (len, "mov\t%D0, %C0", operands);
-+        OUT_INSN (len, "swpb\t%D0", operands);
-+        OUT_INSN (len, "sxt\t%D0", operands);
-+        OUT_INSN (len, "swpb\t%D0", operands);
-+        OUT_INSN (len, "sxt\t%D0", operands);
-+
-+        dummy = 17;
-+        if (GET_CODE (operands[0]) == REG)
-+          dummy = 7;
-+        shiftpos -= 16;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, "rra\t%C0\n\trrc\t%B0\n\trrc\t%A0", operands);
-+            dummy += set_ren (operands[0], 6, 1);
-+          }
-+
-+        break;
-+
-+      case 32:
-+      case 33:
-+      case 34:
-+      case 35:
-+      case 36:
-+      case 37:
-+      case 38:
-+      case 39:
-+      case 40:
-+      case 41:
-+      case 42:
-+      case 43:
-+      case 44:
-+      case 45:
-+      case 46:
-+      case 47:
-+        OUT_INSN (len, "mov\t%C0, %A0", operands);
-+        OUT_INSN (len, "mov\t%D0, %B0", operands);
-+        OUT_INSN (len, "swpb\t%D0", operands);
-+        OUT_INSN (len, "sxt\t%D0", operands);
-+        OUT_INSN (len, "swpb\t%D0", operands);
-+        OUT_INSN (len, "sxt\t%D0", operands);
-+        OUT_INSN (len, "mov\t%D0, %C0", operands);
-+        dummy = 17;
-+        if (GET_CODE (operands[0]) == REG)
-+          dummy = 8;
-+        shiftpos -= 32;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, "rra\t%B0\n\trrc\t%A0", operands);
-+            dummy += set_ren (operands[0], 4, 1);
-+          }
-+        break;
-+
-+      case 48:
-+      case 49:
-+      case 50:
-+      case 51:
-+      case 52:
-+      case 53:
-+      case 54:
-+      case 55:
-+      case 56:
-+      case 57:
-+      case 58:
-+      case 59:
-+      case 60:
-+      case 61:
-+      case 62:
-+        OUT_INSN (len, "mov\t%D0, %A0", operands);
-+        OUT_INSN (len, "swpb\t%D0", operands);
-+        OUT_INSN (len, "sxt\t%D0", operands);
-+        OUT_INSN (len, "swpb\t%D0", operands);
-+        OUT_INSN (len, "sxt\t%D0", operands);
-+        OUT_INSN (len, "mov\t%D0, %C0", operands);
-+        OUT_INSN (len, "mov\t%D0, %B0", operands);
-+        dummy = 17;
-+        if (GET_CODE (operands[0]) == REG)
-+          dummy = 7;
-+        shiftpos -= 48;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, "rra\t%A0", operands);
-+            dummy += set_ren (operands[0], 2, 1);
-+          }
-+        break;
-+
-+      case 63:
-+        OUT_INSN (len, "swpb\t%D0", operands);
-+        OUT_INSN (len, "sxt\t%D0", operands);
-+        OUT_INSN (len, "swpb\t%D0", operands);
-+        OUT_INSN (len, "sxt\t%D0", operands);
-+        OUT_INSN (len, "mov\t%D0, %C0", operands);
-+        OUT_INSN (len, "mov\t%D0, %B0", operands);
-+        OUT_INSN (len, "mov\t%D0, %A0", operands);
-+        dummy = 17;
-+        if (GET_CODE (operands[0]) == REG)
-+          dummy = 7;
-+        break;
-+
-+      default:
-+        dummy = 0;
-+
-+      }                       /* case */
-+
-+      if (len)
-+      *len = dummy;
-+      return "";
-+    }
-+  else
-+    msp430_emit_shift_cnt (set_ren, pattern, insn, operands, len, 8);
-+  return "";
-+}
-+
-+/********* LOGICAL SHIFT RIGHT CODE ***************************************/
-+const char *
-+msp430_emit_lshrqi3 (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
-+  const char *pattern;
-+  const char *second_pat;
-+  int shiftpos;
-+
-+  if (zs)
-+    {
-+      pattern = "clrc\n\trrc.b\t@%E0";
-+      second_pat = "rra.b\t@%E0";
-+    }
-+  else
-+    {
-+      pattern = "clrc\n\trrc.b\t%A0";
-+      second_pat = "rra.b\t%A0";
-+    }
-+
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+    {
-+
-+      shiftpos = INTVAL (operands[2]);
-+
-+      if (shiftpos != 7 && shiftpos)
-+      {
-+        OUT_INSN (len, pattern, operands);
-+        dummy += set_rel (operands[0], 2, 1);
-+        shiftpos--;
-+      }
-+
-+      switch (shiftpos)
-+      {
-+      case 0:
-+        break;
-+
-+      case 1:
-+      case 2:
-+      case 3:
-+      case 4:
-+      case 5:
-+      case 6:
-+
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, second_pat, operands);
-+            dummy += set_rel (operands[0], 2, 1) - 1;
-+          }
-+
-+        break;
-+
-+      case 7:
-+        if (zs)
-+          {
-+            OUT_INSN (len, "rla.b\t@%E0", operands);
-+            OUT_INSN (len, "clr.b\t%A0", operands);
-+            OUT_INSN (len, "rlc.b\t@%E0", operands);
-+            dummy = 4;
-+          }
-+        else
-+          {
-+            OUT_INSN (len, "rla.b\t%A0", operands);
-+            OUT_INSN (len, "clr.b\t%A0", operands);
-+            OUT_INSN (len, "rlc.b\t%A0", operands);
-+            dummy = 6;
-+          }
-+        if (REG_P (operands[0]))
-+          dummy = 3;
-+        break;
-+
-+      default:
-+        OUT_INSN (len, "clr.b\t%A0", operands);
-+        dummy = 2;
-+        if (REG_P (operands[0]))
-+          dummy = 1;
-+        break;
-+      }
-+
-+      if (len)
-+      *len = dummy;
-+    }
-+  else
-+    {
-+      msp430_emit_shift_cnt (set_rel, pattern, insn, operands, len, 2);
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_lshrhi3 (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
-+  const char *pattern;
-+  const char *second_pat;
-+  int shiftpos;
-+
-+  if (zs)
-+    {
-+      pattern = "clrc\n\trrc\t@%E0";
-+      second_pat = "rra\t@%E0";
-+    }
-+  else
-+    {
-+      pattern = "clrc\n\trrc\t%A0";
-+      second_pat = "rra\t%A0";
-+    }
-+
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+    {
-+      shiftpos = INTVAL (operands[2]);
-+
-+      if (shiftpos < 8 && shiftpos)
-+      {
-+        OUT_INSN (len, pattern, operands);
-+        dummy += set_rel (operands[0], 2, 1);
-+        shiftpos--;
-+      }
-+
-+      switch (shiftpos)
-+      {
-+      case 0:
-+        break;
-+
-+      case 1:
-+      case 2:
-+      case 3:
-+      case 4:
-+      case 5:
-+      case 6:
-+      case 7:
-+
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, second_pat, operands);
-+            dummy += set_rel (operands[0], 2, 1) - 1;
-+          }
-+
-+        break;
-+
-+      case 8:
-+      case 9:
-+      case 10:
-+      case 11:
-+      case 12:
-+      case 13:
-+      case 14:
-+
-+        if (zs)
-+          {
-+            OUT_INSN (len, "swpb\t@%E0", operands);
-+            OUT_INSN (len, "and.b\t#-1, %A0", operands);
-+            dummy = 3;
-+          }
-+        else
-+          {
-+            OUT_INSN (len, "swpb\t%A0", operands);
-+            OUT_INSN (len, "and.b\t#-1, %A0", operands);
-+            dummy = 4;
-+          }
-+        if (REG_P (operands[0]))
-+          dummy = 2;
-+        shiftpos -= 8;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, second_pat, operands);
-+            dummy += set_rel (operands[0], 2, 1) - 1;
-+          }
-+        break;
-+
-+      case 15:
-+
-+        if (zs)
-+          {
-+            OUT_INSN (len, "rla\t@%E0", operands);
-+            OUT_INSN (len, "clr\t@%E0", operands);
-+            OUT_INSN (len, "rlc\t@%E0", operands);
-+            dummy = 3;
-+          }
-+        else
-+          {
-+            OUT_INSN (len, "rla\t%A0", operands);
-+            OUT_INSN (len, "clr\t%A0", operands);
-+            OUT_INSN (len, "rlc\t%A0", operands);
-+            dummy = 6;
-+          }
-+        if (REG_P (operands[0]))
-+          dummy = 3;
-+        break;
-+
-+      default:
-+        OUT_INSN (len, "clr\t%A0", operands);
-+        dummy = 2;
-+        if (REG_P (operands[0]))
-+          dummy = 1;
-+        break;
-+      }
-+
-+      if (len)
-+      *len = dummy;
-+      return "";
-+    }
-+  else
-+    {
-+      msp430_emit_shift_cnt (set_rel, pattern, insn, operands, len, 2);
-+    }
-+
-+  return "";
-+
-+}
-+
-+const char *
-+msp430_emit_lshrsi3 (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  const char *pattern;
-+  int dummy = 0;
-+  int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
-+  const char *second_pat = "rra\t%B0\n\trrc\t%A0";
-+
-+  pattern = "clrc\n\trrc\t%B0\n\trrc\t%A0";
-+
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+    {
-+      int shiftpos = INTVAL (operands[2]);
-+
-+      if (shiftpos < 8 && shiftpos)
-+      {
-+        OUT_INSN (len, pattern, operands);
-+        /* This function was underestimating the length by 1 for shifts from
-+           1 to 7.  I added one here - Max */
-+        dummy += set_rel (operands[0], 2, 1) + 1;
-+        shiftpos--;
-+      }
-+
-+      switch (shiftpos)
-+      {
-+      case 0:
-+        break;
-+
-+      case 1:
-+      case 2:
-+      case 3:
-+      case 4:
-+      case 5:
-+      case 6:
-+      case 7:
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, second_pat, operands);
-+            dummy += set_rel (operands[0], 4, 1) - 1;
-+          }
-+
-+        break;
-+
-+      case 8:
-+      case 9:
-+      case 10:
-+      case 11:
-+      case 12:
-+      case 13:
-+      case 14:
-+      case 15:
-+        OUT_INSN (len, "swpb\t%A0", operands);
-+        OUT_INSN (len, "swpb\t%B0", operands);
-+        OUT_INSN (len, "xor.b\t%B0, %A0", operands);
-+        OUT_INSN (len, "xor\t%B0, %A0", operands);
-+        OUT_INSN (len, "and.b\t#-1, %B0", operands);
-+        dummy = 12;
-+
-+        if (REG_P (operands[0]))
-+          dummy = 5;
-+        shiftpos -= 8;
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, second_pat, operands);
-+            dummy += set_rel (operands[0], 4, 1) - 1;
-+          }
-+        break;
-+
-+      case 16:
-+      case 17:
-+      case 18:
-+      case 19:
-+      case 20:
-+      case 21:
-+      case 22:
-+      case 23:
-+        OUT_INSN (len, "mov\t%B0, %A0", operands);
-+        OUT_INSN (len, "clr\t%B0", operands);
-+        dummy = 5;
-+        if (REG_P (operands[0]))
-+          dummy = 2;
-+
-+        shiftpos -= 16;
-+        if (shiftpos)
-+          {
-+            OUT_INSN (len, "clrc\n\trrc\t%A0", operands);
-+            dummy += 2;
-+            if (!zs && !REG_P (operands[0]))
-+              dummy++;
-+            shiftpos--;
-+          }
-+
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, "rra\t%A0", operands);
-+            dummy += 1;
-+            if (!zs && !REG_P (operands[0]))
-+              dummy++;
-+          }
-+        break;
-+
-+      case 24:
-+      case 25:
-+      case 26:
-+      case 27:
-+      case 28:
-+      case 29:
-+      case 30:
-+        OUT_INSN (len, "mov\t%B0, %A0", operands);
-+        OUT_INSN (len, "clr\t%B0", operands);
-+        OUT_INSN (len, "swpb\t%A0", operands);
-+        OUT_INSN (len, "and.b\t#-1, %A0", operands);
-+        dummy = 9;
-+        if (REG_P (operands[0]))
-+          dummy = 4;
-+        if (indexed_location (operands[0]))
-+          dummy -= 1;
-+        shiftpos -= 24;
-+
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, "rra\t%A0", operands);
-+            dummy += 1;
-+            if (!zs && !REG_P (operands[0]))
-+              dummy++;
-+          }
-+        break;
-+
-+      case 31:
-+        OUT_INSN (len, "rla\r%B0", operands);
-+        OUT_INSN (len, "clr\t%B0", operands);
-+        OUT_INSN (len, "clr\t%A0", operands);
-+        OUT_INSN (len, "rlc\t%A0", operands);
-+        dummy = 8;
-+        if (REG_P (operands[0]))
-+          dummy = 4;
-+        if (indexed_location (operands[0]))
-+          dummy -= 1;
-+        break;
-+
-+      default:
-+        OUT_INSN (len, "clr\t%B0", operands);
-+        OUT_INSN (len, "clr\t%A0", operands);
-+        dummy = 4;
-+        if (REG_P (operands[0]))
-+          dummy = 2;
-+        break;
-+
-+      }                       /* switch */
-+
-+      if (len)
-+      *len = dummy;
-+      return "";
-+    }
-+  else
-+    msp430_emit_shift_cnt (set_rel, pattern, insn, operands, len, 4);
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_emit_lshrdi3 (insn, operands, len)
-+     rtx insn;
-+     rtx operands[];
-+     int *len;
-+{
-+  int dummy = 0;
-+  const char *pattern;
-+  int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
-+  const char *secondary_pat = "rra\t%D0\n\trrc\t%C0\n\trrc\t%B0\n\trrc\t%A0";
-+
-+  pattern = "clrc\n\trrc\t%D0\n\trrc\t%C0\n\trrc\t%B0\n\trrc\t%A0";
-+
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+    {
-+      int shiftpos = INTVAL (operands[2]);
-+
-+      if (shiftpos < 16 && shiftpos)
-+      {
-+        OUT_INSN (len, pattern, operands);
-+        dummy += set_rel (operands[0], 2, 1);
-+        shiftpos--;
-+      }
-+
-+      switch (shiftpos)
-+      {
-+      case 0:
-+        break;
-+
-+      case 1:
-+      case 2:
-+      case 3:
-+      case 4:
-+      case 5:
-+      case 6:
-+      case 7:
-+      case 8:
-+      case 9:
-+      case 10:
-+      case 11:
-+      case 12:
-+      case 13:
-+      case 14:
-+      case 15:
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, secondary_pat, operands);
-+            dummy += set_rel (operands[0], 8, 1) - 1;
-+          }
-+
-+        break;
-+
-+      case 16:
-+      case 17:
-+      case 18:
-+      case 19:
-+      case 20:
-+      case 21:
-+      case 22:
-+      case 23:
-+      case 24:
-+      case 25:
-+      case 26:
-+      case 27:
-+      case 28:
-+      case 29:
-+      case 30:
-+      case 31:
-+        OUT_INSN (len, "mov\t%B0, %A0", operands);
-+        OUT_INSN (len, "mov\t%C0, %B0", operands);
-+        OUT_INSN (len, "mov\t%D0, %C0", operands);
-+        OUT_INSN (len, "clr\t%D0", operands);
-+        dummy = 11;
-+        if (REG_P (operands[0]))
-+          dummy = 4;
-+        shiftpos -= 16;
-+
-+        if (shiftpos)
-+          {
-+            OUT_INSN (len, secondary_pat, operands);
-+            dummy += set_rel (operands[0], 8, 1) - 1;
-+            shiftpos--;
-+          }
-+
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, "rra\t%C0\n\trrc\t%B0\n\trrc\t%A0", operands);
-+            if (REG_P (operands[0]))
-+              dummy = 3;
-+            else
-+              dummy += 6;
-+            if (zs)
-+              dummy--;
-+          }
-+
-+        break;
-+
-+      case 32:
-+      case 33:
-+      case 34:
-+      case 35:
-+      case 36:
-+      case 37:
-+      case 38:
-+      case 39:
-+      case 40:
-+      case 41:
-+      case 42:
-+      case 43:
-+      case 44:
-+      case 45:
-+      case 46:
-+      case 47:
-+        OUT_INSN (len, "mov\t%C0, %A0", operands);
-+        OUT_INSN (len, "mov\t%D0, %B0", operands);
-+        OUT_INSN (len, "clr\t%C0", operands);
-+        OUT_INSN (len, "clr\t%D0", operands);
-+
-+        dummy = 10;
-+        if (GET_CODE (operands[0]) == REG)
-+          dummy = 4;
-+
-+        shiftpos -= 32;
-+
-+        if (shiftpos)
-+          {
-+            OUT_INSN (len, "clrc\n\trrc\t%B0,rrc\t%A0", operands);
-+            if (REG_P (operands[0]))
-+              dummy += 3;
-+            else
-+              dummy += 5;
-+            if (zs)
-+              dummy--;
-+            shiftpos--;
-+          }
-+
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, "rra\t%B0,rrc\t%A0", operands);
-+            if (REG_P (operands[0]))
-+              dummy += 2;
-+            else
-+              dummy += 4;
-+            if (zs)
-+              dummy--;
-+          }
-+        break;
-+
-+      case 48:
-+      case 49:
-+      case 50:
-+      case 51:
-+      case 52:
-+      case 53:
-+      case 54:
-+      case 55:
-+      case 56:
-+      case 57:
-+      case 58:
-+      case 59:
-+      case 60:
-+      case 61:
-+      case 62:
-+        OUT_INSN (len, "mov\t%D0, %A0", operands);
-+        OUT_INSN (len, "clr\t%B0", operands);
-+        OUT_INSN (len, "clr\t%C0", operands);
-+        OUT_INSN (len, "clr\t%D0", operands);
-+        dummy = 9;
-+        if (GET_CODE (operands[0]) == REG)
-+          dummy = 4;
-+        shiftpos -= 48;
-+
-+        if (shiftpos)
-+          {
-+            OUT_INSN (len, "clrc\n\trrc\t%A0", operands);
-+            if (REG_P (operands[0]) || zs)
-+              dummy += 2;
-+            else
-+              dummy += 3;
-+
-+            shiftpos--;
-+          }
-+
-+        while (shiftpos--)
-+          {
-+            OUT_INSN (len, "rra\t%A0", operands);
-+            if (REG_P (operands[0]) || zs)
-+              dummy++;
-+            else
-+              dummy += 2;
-+          }
-+        break;
-+
-+      case 63:
-+
-+        OUT_INSN (len, "rla\t%D0", operands);
-+        OUT_INSN (len, "clr\t%D0", operands);
-+        OUT_INSN (len, "clr\t%C0", operands);
-+        OUT_INSN (len, "clr\t%B0", operands);
-+        OUT_INSN (len, "clr\t%A0", operands);
-+        OUT_INSN (len, "rlc\t%A0", operands);
-+        if (REG_P (operands[0]))
-+          dummy += 6;
-+        else
-+          dummy += 13;
-+
-+        if (zs)
-+          dummy--;
-+        break;
-+
-+      default:
-+        break;
-+      }                       /* case */
-+
-+      if (len)
-+      *len = dummy;
-+    }
-+  else
-+    msp430_emit_shift_cnt (set_rel, pattern, insn, operands, len, 8);
-+
-+  return "";
-+}
-+
-+/*
-+ *    Multiplication helpers
-+ *    1. As shifts, 2. the rest 
-+ */
-+
-+#define SOME_SHIFT_THRESHOLD_VAL      10
-+
-+int
-+msp430_easy_mul (operands, sext)
-+     rtx operands[];
-+     int sext;
-+{
-+  enum machine_mode op0mode = GET_MODE (operands[0]);
-+  enum machine_mode op1mode = GET_MODE (operands[1]);
-+  rtx op0 = operands[0];
-+  rtx op1 = operands[1];
-+  rtx insn;
-+  int m = INTVAL (operands[2]);
-+  int sign = (m < 0);
-+  int val = (m > 0 ? m : -m);
-+  int shift1 = 0, shift0 = 0;
-+  int add1 = 0, sub1 = 0;
-+  int t0, t1;
-+  int ops = 0;
-+
-+  m = val;
-+  /* 
-+     we can do: 
-+     const == single bit const +- N that (shift0 + add1/sub1 < 8 instructions) 
-+   */
-+  shift0 = 1;
-+  shift1 = 0;
-+
-+  for (t0 = 2;
-+       t0 <= val * 2 && shift0 < GET_MODE_SIZE (op0mode) * BITS_PER_UNIT;
-+       t0 <<= 1)
-+    {
-+      if (t0 == val)
-+      goto done;
-+
-+      for (t1 = 1; t1 < t0 && shift1 < GET_MODE_SIZE (op1mode) * BITS_PER_UNIT;
-+         t1 <<= 1)
-+      {
-+        add1 = 0;
-+        sub1 = 0;
-+        if (t0 + t1 == m)
-+          {
-+            add1 = 1;
-+            goto done;
-+          }
-+        if (t0 - t1 == m)
-+          {
-+            sub1 = 1;
-+            goto done;
-+          }
-+
-+        if (t0 + t1 * 3 == m)
-+          {
-+            add1 = 3;
-+            goto done;
-+          }
-+
-+        if (t0 - t1 * 3 == m)
-+          {
-+            sub1 = 3;
-+            goto done;
-+          }
-+
-+        add1 = 0;
-+        sub1 = 0;
-+        shift1++;
-+
-+      }
-+      shift1 = 0;
-+      shift0++;
-+    }
-+
-+  return 0;
-+done:
-+
-+  ops = shift0 * (op0mode == SImode ? 2 : 1);
-+  ops += shift1 + add1 + sub1;
-+  if (op0mode != op1mode)
-+    {
-+      ops += (op0mode == SImode ? 2 : 1) * ((add1 || sub1) ? 2 : 1);
-+    }
-+
-+  if (ops > SOME_SHIFT_THRESHOLD_VAL)
-+    return 0;
-+
-+  if (op0mode != op1mode)
-+    {
-+      rtx extend;
-+      if (sext)
-+      extend = gen_rtx_SIGN_EXTEND (op0mode, op1);
-+      else
-+      extend = gen_rtx_ZERO_EXTEND (op0mode, op1);
-+      insn = gen_rtx_SET (VOIDmode, op0, extend);
-+      emit_insn (insn);
-+    }
-+  else
-+    {
-+      emit_move_insn (op0, op1);
-+    }
-+
-+  /* shift0 */
-+  switch (op0mode)
-+    {
-+    case QImode:
-+      emit_insn (gen_ashlqi3 (op0, op0, GEN_INT (shift0)));
-+      break;
-+    case HImode:
-+      emit_insn (gen_ashlhi3 (op0, op0, GEN_INT (shift0)));
-+      break;
-+    case SImode:
-+      emit_insn (gen_ashlsi3 (op0, op0, GEN_INT (shift0)));
-+      break;
-+    case DImode:
-+      emit_insn (gen_ashldi3 (op0, op0, GEN_INT (shift0)));
-+      break;
-+    default:
-+      abort ();
-+    }
-+
-+  if (op0mode != op1mode && (add1 || sub1 || shift1))
-+    {
-+      /* equalize operands modes */
-+      rtx extend;
-+      rtx treg = gen_reg_rtx (op0mode);
-+
-+      if (sext)
-+      extend = gen_rtx_SIGN_EXTEND (op0mode, op1);
-+      else
-+      extend = gen_rtx_ZERO_EXTEND (op0mode, op1);
-+      insn = gen_rtx_SET (VOIDmode, treg, extend);
-+      emit_insn (insn);
-+      op1 = treg;
-+      op1mode = GET_MODE (treg);
-+    }
-+  else if (add1 || sub1 || shift1)
-+    {
-+      rtx treg = gen_reg_rtx (op0mode);
-+      emit_move_insn (treg, op1);
-+      op1 = treg;
-+    }
-+
-+  if (shift1 && (add1 || sub1))
-+    {
-+      switch (op1mode)
-+      {
-+      case QImode:
-+        emit_insn (gen_ashlqi3 (op1, op1, GEN_INT (shift1)));
-+        break;
-+      case HImode:
-+        emit_insn (gen_ashlhi3 (op1, op1, GEN_INT (shift1)));
-+        break;
-+      case SImode:
-+        emit_insn (gen_ashlsi3 (op1, op1, GEN_INT (shift1)));
-+        break;
-+      case DImode:
-+        emit_insn (gen_ashldi3 (op1, op1, GEN_INT (shift1)));
-+        break;
-+      default:
-+        abort ();
-+      }
-+    }
-+  else if (shift1)
-+    abort ();                 /* paranoia */
-+
-+  while (add1--)
-+    {
-+      insn =
-+        gen_rtx_SET (VOIDmode, op0, gen_rtx_PLUS (GET_MODE (op0), op0, op1));
-+      emit_insn (insn);
-+    }
-+
-+  while (sub1--)
-+    {
-+      insn =
-+        gen_rtx_SET (VOIDmode, op0,
-+                     gen_rtx_MINUS (GET_MODE (op0), op0, op1));
-+      emit_insn (insn);
-+    }
-+
-+  if (sign)
-+    {
-+      switch (op0mode)
-+      {
-+      case QImode:
-+        emit_insn (gen_negqi2 (op0, op0));
-+        break;
-+      case HImode:
-+        emit_insn (gen_neghi2 (op0, op0));
-+        break;
-+      case SImode:
-+        emit_insn (gen_negsi2 (op0, op0));
-+        break;
-+      case DImode:
-+        emit_insn (gen_negdi2 (op0, op0));
-+        break;
-+      default:
-+        abort ();
-+      }
-+    }
-+
-+  return 1;
-+}
-+
-+/* multiplication guards */
-+#define LOAD_MPY(x)   \
-+do{ \
-+  if(GET_MODE(x) == QImode)           \
-+    emit_insn(gen_load_mpyq(x));      \
-+  else                                        \
-+    emit_insn(gen_load_mpy(x));       \
-+}while(0)
-+
-+#define LOAD_MPYS(x)  \
-+do{ \
-+  if(GET_MODE(x) == QImode)           \
-+    emit_insn(gen_load_mpysq(x));     \
-+  else                                        \
-+    emit_insn(gen_load_mpys(x));      \
-+}while(0)
-+
-+#define LOAD_OP2(x)   \
-+do{ \
-+  if(GET_MODE(x) == QImode)           \
-+    emit_insn(gen_load_op2q(x));      \
-+  else                                        \
-+    emit_insn(gen_load_op2(x));       \
-+}while(0)
-+
-+int
-+msp430_mul3_guard (operands, sext)
-+     rtx operands[];
-+     int sext;
-+{
-+  rtx m_mpys = mpys_rtx;
-+  rtx m_op2 = op2_rtx;
-+  rtx m_reslo = reslo_rtx;
-+  enum machine_mode op0mode = GET_MODE (operands[0]);
-+  enum machine_mode op1mode = GET_MODE (operands[1]);
-+  rtx r12 = gen_rtx_REG (op1mode, 12);
-+  rtx r10 = gen_rtx_REG (op1mode, 10);
-+  rtx r14 = gen_rtx_REG (op0mode, 14);
-+
-+  if (const_int_operand (operands[2], VOIDmode) &&
-+      msp430_easy_mul (operands, sext))
-+    return 1;
-+
-+  if (!msp430_has_hwmul)
-+    {
-+      rtx clob1 = gen_rtx_CLOBBER (VOIDmode, r10);
-+      rtx clob2 = gen_rtx_CLOBBER (VOIDmode, r12);
-+      rtx set;
-+      rtx mult, op1, op2;
-+      rtvec vec;
-+      /* prepare 'call' pattern */
-+      if (sext==1)
-+      {
-+        op1 = gen_rtx_SIGN_EXTEND (op0mode, r10);
-+        op2 = gen_rtx_SIGN_EXTEND (op0mode, r12);
-+      }
-+      else
-+      {
-+        op1 = r10;
-+        op2 = r12;
-+      }
-+      mult = gen_rtx_MULT (op0mode, op1, op2);
-+      set = gen_rtx_SET (op0mode, r14, mult);
-+      vec = gen_rtvec (3, set, clob1, clob2);
-+
-+      emit_move_insn (r10, operands[1]);
-+      emit_move_insn (r12, operands[2]);
-+      emit (gen_rtx_PARALLEL (VOIDmode, vec));
-+      emit_move_insn (operands[0], r14);
-+      return 1;
-+    }
-+  if (op1mode == QImode)
-+    {
-+      m_mpys = gen_lowpart (QImode, mpys_rtx);
-+      m_op2 = gen_lowpart (QImode, op2_rtx);
-+    }
-+
-+  if (op0mode == QImode)
-+    m_reslo = gen_lowpart (QImode, reslo_rtx);
-+
-+  if (!MSP430_NOINT_HWMUL)
-+    emit_insn (gen_reent_in ());
-+
-+  LOAD_MPYS (operands[1]);
-+  if (sext)
-+    emit_insn (gen_extendqihi2 (mpys_rtx, m_mpys));
-+  LOAD_OP2 (operands[2]);
-+  if (sext)
-+    emit_insn (gen_extendqihi2 (op2_rtx, m_op2));
-+  
-+  if (MSP430_NOINT_HWMUL)
-+    {
-+      if (op0mode == HImode)
-+      emit_insn (gen_fetch_result_hi_nint (operands[0]));
-+      else
-+      emit_insn (gen_fetch_result_qi_nint (operands[0]));
-+    }
-+  else
-+    {
-+      if (op0mode == HImode)
-+      emit_insn (gen_fetch_result_hi (operands[0]));
-+      else
-+      emit_insn (gen_fetch_result_qi (operands[0]));
-+    }
-+
-+  return 1;
-+}
-+
-+
-+int
-+msp430_umul3_guard (operands, sext)
-+     rtx operands[];
-+     int sext ATTRIBUTE_UNUSED;
-+{
-+  rtx m_mpy = mpy_rtx;
-+  rtx m_op2 = op2_rtx;
-+  enum machine_mode op0mode = GET_MODE (operands[0]);
-+  enum machine_mode op1mode = GET_MODE (operands[1]);
-+  rtx r12 = gen_rtx_REG (op1mode, 12);
-+  rtx r10 = gen_rtx_REG (op1mode, 10);
-+  rtx r14 = gen_rtx_REG (op0mode, 14);
-+
-+  if (const_int_operand (operands[2], VOIDmode) &&
-+      msp430_easy_mul (operands, 0))
-+    return 1;
-+
-+  if (!msp430_has_hwmul)
-+    {
-+      rtx clob1 = gen_rtx_CLOBBER (VOIDmode, r10);
-+      rtx clob2 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (op1mode, 12));
-+      rtx set;
-+      rtx mult, op1, op2;
-+      rtvec vec;
-+      /* prepare 'call' pattern */
-+      op1 = gen_rtx_ZERO_EXTEND (op0mode, r10);
-+      op2 = gen_rtx_ZERO_EXTEND (op0mode, r12);
-+
-+      mult = gen_rtx_MULT (op0mode, op1, op2);
-+      set = gen_rtx_SET (op0mode, r14, mult);
-+      vec = gen_rtvec (3, set, clob1, clob2);
-+
-+      emit_move_insn (r10, operands[1]);
-+      emit_move_insn (r12, operands[2]);
-+      emit (gen_rtx_PARALLEL (VOIDmode, vec));
-+      emit_move_insn (operands[0], r14);
-+      return 1;
-+    }
-+
-+  m_mpy = gen_lowpart (QImode, mpy_rtx);
-+  m_op2 = gen_lowpart (QImode, op2_rtx);
-+
-+  if (!MSP430_NOINT_HWMUL)
-+    emit_insn (gen_reent_in ());
-+
-+  LOAD_MPY (gen_lowpart (QImode,operands[1]));
-+  //emit_insn (gen_zero_extendqihi2 (mpy_rtx, m_mpy));
-+  //LOAD_OP2 (gen_lowpart (QImode,operands[2]));
-+  //emit_insn (gen_zero_extendqihi2 (op2_rtx, m_op2));
-+  emit_move_insn(m_op2, gen_lowpart (QImode,operands[2]));
-+  
-+  if (MSP430_NOINT_HWMUL)
-+    emit_insn (gen_fetch_result_hi_nint (operands[0]));
-+  else
-+    emit_insn (gen_fetch_result_hi (operands[0]));
-+
-+  return 1;
-+}
-+
-+
-+int
-+msp430_mulhisi_guard (operands)
-+     rtx operands[];
-+{
-+  enum machine_mode op0mode = GET_MODE (operands[0]);
-+  enum machine_mode op1mode = GET_MODE (operands[1]);
-+  rtx r12 = gen_rtx_REG (op1mode, 12);
-+  rtx r10 = gen_rtx_REG (op1mode, 10);
-+  rtx r14 = gen_rtx_REG (op0mode, 14);
-+  rtx r11 = gen_rtx_REG (op1mode, 11);
-+  rtx r13 = gen_rtx_REG (op1mode, 13);
-+
-+  if (const_int_operand (operands[2], VOIDmode) &&
-+      msp430_easy_mul (operands, 1))
-+    return 1;
-+
-+  if (!msp430_has_hwmul)
-+    {
-+      rtx clob1 = gen_rtx_CLOBBER (VOIDmode, r10);
-+      rtx clob2 = gen_rtx_CLOBBER (VOIDmode, r11);
-+      rtx clob3 = gen_rtx_CLOBBER (VOIDmode, r12);
-+      rtx clob4 = gen_rtx_CLOBBER (VOIDmode, r13);
-+
-+      rtx set;
-+      rtx mult, op1, op2;
-+      rtvec vec;
-+      /* prepare 'call' pattern */
-+      op1 = gen_rtx_SIGN_EXTEND (op0mode, r10);
-+      op2 = gen_rtx_SIGN_EXTEND (op0mode, r12);
-+
-+      mult = gen_rtx_MULT (op0mode, op1, op2);
-+      set = gen_rtx_SET (op0mode, r14, mult);
-+      vec = gen_rtvec (5, set, clob1, clob2, clob3, clob4);
-+
-+      emit_move_insn (r10, operands[1]);
-+      emit_move_insn (r12, operands[2]);
-+      emit (gen_rtx_PARALLEL (VOIDmode, vec));
-+      emit_move_insn (operands[0], r14);
-+      return 1;
-+    }
-+  if (!MSP430_NOINT_HWMUL)
-+    emit_insn (gen_reent_in ());
-+
-+  LOAD_MPYS (operands[1]);
-+  LOAD_OP2 (operands[2]);
-+
-+  if (MSP430_NOINT_HWMUL)
-+    {
-+      emit_insn (gen_fetch_result_si_nint (operands[0]));
-+    }
-+  else
-+    emit_insn (gen_fetch_result_si (operands[0]));
-+
-+  return 1;
-+}
-+
-+
-+int
-+msp430_umulhisi_guard (operands)
-+     rtx operands[];
-+{
-+  enum machine_mode op0mode = GET_MODE (operands[0]);
-+  enum machine_mode op1mode = GET_MODE (operands[1]);
-+  rtx r12 = gen_rtx_REG (op1mode, 12);
-+  rtx r10 = gen_rtx_REG (op1mode, 10);
-+  rtx r14 = gen_rtx_REG (op0mode, 14);
-+  rtx r11 = gen_rtx_REG (op1mode, 11);
-+  rtx r13 = gen_rtx_REG (op1mode, 13);
-+
-+  if (const_int_operand (operands[2], VOIDmode) &&
-+      msp430_easy_mul (operands, 0))
-+    return 1;
-+
-+  if (!msp430_has_hwmul)
-+    {
-+      rtx clob1 = gen_rtx_CLOBBER (VOIDmode, r10);
-+      rtx clob2 = gen_rtx_CLOBBER (VOIDmode, r11);
-+      rtx clob3 = gen_rtx_CLOBBER (VOIDmode, r12);
-+      rtx clob4 = gen_rtx_CLOBBER (VOIDmode, r13);
-+
-+      rtx set;
-+      rtx mult, op1, op2;
-+      rtvec vec;
-+      /* prepare 'call' pattern */
-+      op1 = gen_rtx_ZERO_EXTEND (op0mode, r10);
-+      op2 = gen_rtx_ZERO_EXTEND (op0mode, r12);
-+
-+      mult = gen_rtx_MULT (op0mode, op1, op2);
-+      set = gen_rtx_SET (op0mode, r14, mult);
-+      vec = gen_rtvec (5, set, clob1, clob2, clob3, clob4);
-+
-+      emit_move_insn (r10, operands[1]);
-+      emit_move_insn (r12, operands[2]);
-+      emit (gen_rtx_PARALLEL (VOIDmode, vec));
-+      emit_move_insn (operands[0], r14);
-+      return 1;
-+    }
-+
-+  if (!MSP430_NOINT_HWMUL)
-+    emit_insn (gen_reent_in ());
-+
-+  LOAD_MPY (operands[1]);
-+  LOAD_OP2 (operands[2]);
-+
-+  if (MSP430_NOINT_HWMUL)
-+    {
-+      emit_insn (gen_fetch_result_si_nint (operands[0]));
-+    }
-+  else
-+    emit_insn (gen_fetch_result_si (operands[0]));
-+
-+  return 1;
-+}
-+
-+
-+/* something like 'push x(r1)' or 'push @r1' */
-+int
-+self_push (x)
-+     rtx x;
-+{
-+  rtx c;
-+  rtx r;
-+
-+  if (GET_CODE (x) != MEM)
-+    return 0;
-+
-+  c = XEXP (x, 0);
-+
-+  if (REG_P (c) && REGNO (c) == 1)
-+    return 1;
-+
-+  if (GET_CODE (c) == PLUS)
-+    {
-+      r = XEXP (c, 0);
-+      if (REG_P (r) && REGNO (r) == 1)
-+      return 1;
-+    }
-+  return 0;
-+}
-+
-+/* difficult pushes.
-+   if planets are not aligned, the combiner does not allocate
-+   r4 as a frame pointer. Instead, it uses stack pointer for frame.
-+   If there is a va_arg call and non-register local var has to be passed 
-+   as a function parameter, the push X(r1) in SI, SF and DI modes will
-+   corrupt passed var. The following minds this fact */
-+
-+
-+const char *
-+msp430_pushqi (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int sp = self_push (operands[0]);
-+  int dummy = 0;
-+
-+  if (sp)
-+    {
-+      rtx c;
-+      c = XEXP (operands[0], 0);
-+      if (REG_P (c))
-+      OUT_INSN (len, "push.b\t2(%E0)", operands);
-+      else
-+      OUT_INSN (len, "push.b\t2+%A0", operands);
-+      dummy = 2;
-+    }
-+  else
-+    {
-+      OUT_INSN (len, "push.b\t%A0", operands);
-+      dummy = 2;
-+
-+      if (GET_CODE (operands[0]) == CONST_INT)
-+      {
-+        int cval = INTVAL (operands[0]);
-+        int x = (cval) & 0x0fffful;
-+        if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8 || x == 0xffff)
-+          dummy--;
-+
-+      }
-+      else if (GET_CODE (operands[0]) == REG)
-+      dummy--;
-+      else if (GET_CODE (operands[0]) == MEM && REG_P (XEXP (operands[0], 0)))
-+      dummy--;
-+    }
-+
-+  return "";
-+}
-+
-+const char *
-+msp430_pushhi (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int sp = self_push (operands[0]);
-+  int dummy = 0;
-+
-+  if (sp)
-+    {
-+      rtx c;
-+      c = XEXP (operands[0], 0);
-+      if (REG_P (c))
-+      OUT_INSN (len, "push\t2(%E0)", operands);
-+      else
-+      OUT_INSN (len, "push\t2+%A0", operands);
-+      dummy = 2;
-+    }
-+  else
-+    {
-+      OUT_INSN (len, "push\t%A0", operands);
-+      dummy = 2;
-+
-+      if (GET_CODE (operands[0]) == CONST_INT)
-+      {
-+        int cval = INTVAL (operands[0]);
-+        int x = (cval) & 0x0fffful;
-+
-+        if (cval == 99999999)
-+          {
-+            if (len)
-+              *len = 3;
-+            return "";
-+          }
-+
-+        if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8 || x == 0xffff)
-+          dummy--;
-+
-+      }
-+      else if (GET_CODE (operands[0]) == REG)
-+      dummy--;
-+      else if (GET_CODE (operands[0]) == MEM && REG_P (XEXP (operands[0], 0)))
-+      dummy--;
-+    }
-+  if (len)
-+    *len = dummy;
-+  return "";
-+}
-+
-+const char *
-+msp430_pushsisf (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int sp = self_push (operands[0]);
-+  int dummy = 0;
-+
-+  if (!sp)
-+    {
-+      OUT_INSN (len, "push\t%B0", operands);
-+      OUT_INSN (len, "push\t%A0", operands);
-+      dummy = 4;
-+      if (indexed_location (operands[0]))
-+      dummy--;
-+      if (REG_P (operands[0]))
-+      dummy -= 2;
-+      if (GET_CODE (operands[0]) == CONST_INT)
-+      {
-+        int cval = INTVAL (operands[0]);
-+        int x = (cval) & 0x0fffful;
-+        int y = (((unsigned long) (cval)) & 0xffff0000ul >> 16);
-+        if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8 || x == 0xffff)
-+          dummy--;
-+        if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8 || y == 0xffff)
-+          dummy--;
-+      }
-+      else if (GET_CODE (operands[0]) == CONST_DOUBLE
-+             && GET_MODE (operands[0]) == SFmode)
-+      {
-+        long val;
-+        int y, x;
-+        REAL_VALUE_TYPE rv;
-+        REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[0]);
-+        REAL_VALUE_TO_TARGET_SINGLE (rv, val);
-+
-+        y = (val & 0xffff0000ul) >> 16;
-+        x = val & 0xffff;
-+        if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8 || x == 0xffff)
-+          dummy--;
-+        if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8 || y == 0xffff)
-+          dummy--;
-+      }
-+    }
-+  else
-+    {
-+      OUT_INSN (len, "push\t2+%B0", operands);
-+      OUT_INSN (len, "push\t2+%B0", operands);
-+      dummy = 4;
-+    }
-+
-+  if (len)
-+    *len = dummy;
-+
-+  return "";
-+}
-+
-+
-+const char *
-+msp430_pushdi (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[];
-+     int *len;
-+{
-+  int sp = self_push (operands[0]);
-+  int dummy = 0;
-+
-+  if (!sp)
-+    {
-+      OUT_INSN (len, "push\t%D0", operands);
-+      OUT_INSN (len, "push\t%C0", operands);
-+      OUT_INSN (len, "push\t%B0", operands);
-+      OUT_INSN (len, "push\t%A0", operands);
-+
-+      dummy = 8;
-+      if (indexed_location (operands[0]))
-+      dummy--;
-+      if (REG_P (operands[0]))
-+      dummy -= 4;
-+      if (GET_CODE (operands[0]) == CONST_DOUBLE)
-+      {
-+        int hi = CONST_DOUBLE_HIGH (operands[0]);
-+        int lo = CONST_DOUBLE_LOW (operands[0]);
-+        int x, y, z;
-+
-+        x = (hi & 0xffff0000ul) >> 16;
-+        y = hi & 0xffff;
-+        z = (lo & 0xffff0000ul) >> 16;
-+        if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8 || x == 0xffff)
-+          dummy--;
-+        if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8 || y == 0xffff)
-+          dummy--;
-+        if (z == 0 || z == 1 || z == 2 || z == 4 || z == 8 || z == 0xffff)
-+          dummy--;
-+        z = lo & 0xffff;
-+        if (z == 0 || z == 1 || z == 2 || z == 4 || z == 8 || z == 0xffff)
-+          dummy--;
-+      }
-+    }
-+  else
-+    {
-+      OUT_INSN (len, "push\t2+%D0", operands);
-+      OUT_INSN (len, "push\t2+%D0", operands);
-+      OUT_INSN (len, "push\t2+%D0", operands);
-+      OUT_INSN (len, "push\t2+%D0", operands);
-+      dummy = 8;
-+    }
-+
-+  if (len)
-+    *len = dummy;
-+
-+  return "";
-+}
-+
-+int
-+dead_or_set_in_peep (which, insn, x)
-+     int which;
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx x;
-+{
-+  rtx r;
-+  rtx next;
-+
-+  next = peep2_next_insn (which);
-+  if (!next)
-+    return 0;
-+  if (!REG_P (x))
-+    return 0;
-+  r = find_regno_note (next, REG_DEAD, REGNO (x));
-+
-+  if (!r)
-+    return 0;
-+
-+  r = XEXP (r, 0);
-+  return GET_MODE (r) == GET_MODE (x);
-+}
-+
-+void
-+msp430_trampoline_template (FILE * fd)
-+{
-+  fprintf (fd, "; TRAMPOLINE HERE\n"
-+         "; move context (either r1 or r4) to r6\n"
-+         "; call function (0xf0f0 will be changed)\n");
-+  fprintf (fd, "\tmov #0xf0f0, r6\n");
-+  fprintf (fd, "\tbr  #0xf0f0\n");
-+  fprintf (fd, "; END OF TRAMPOLINE\n\n");
-+}
-+
-+void
-+msp430_initialize_trampoline (tramp, fn, ctx)
-+     rtx tramp;
-+     rtx fn;
-+     rtx ctx;
-+{
-+  emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 2)), ctx);
-+  emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 6)), fn);
-+}
-+
-+const char *
-+msp430_emit_return (insn, operands, len)
-+     rtx insn ATTRIBUTE_UNUSED;
-+     rtx operands[] ATTRIBUTE_UNUSED;
-+     int *len ATTRIBUTE_UNUSED;
-+{
-+  return_issued = 1;
-+  if (msp430_empty_epilogue () == 1)
-+    return "ret";
-+
-+  return "reti";
-+}
-+
-+int
-+three_operands_msp430 (x, mode)
-+     rtx x;
-+     enum machine_mode mode;
-+{
-+  enum rtx_code code = GET_CODE (x);
-+  if (GET_MODE (x) != mode)
-+    return 0;
-+
-+  return (code == PLUS
-+        || code == MINUS || code == AND || code == IOR || code == XOR);
-+}
-+
-+int
-+equality_operator (op, mode)
-+     register rtx op;
-+     enum machine_mode mode;
-+{
-+  return ((mode == VOIDmode || GET_MODE (op) == mode)
-+        && (GET_CODE (op) == EQ || GET_CODE (op) == NE));
-+}
-+
-+/* Return 1 if this is a comparison operator but not an EQ or NE operator.  */
-+int
-+inequality_operator (op, mode)
-+     register rtx op;
-+     enum machine_mode mode;
-+{
-+  return comparison_operator (op, mode) && !equality_operator (op, mode);
-+}
-diff -urN -x CVS gcc-3.2.3.orig/gcc/config/msp430/msp430.h gcc-3.2.3/gcc/config/msp430/msp430.h
---- gcc-3.2.3.orig/gcc/config/msp430/msp430.h  1969-12-31 17:00:00.000000000 -0700
-+++ gcc-3.2.3/gcc/config/msp430/msp430.h       2008-08-22 09:17:00.000000000 -0600
-@@ -0,0 +1,3378 @@
-+
-+/* Definitions of target machine for GNU compiler,
-+   for Texas Instruments MSP430 microcontrollers.
-+   Copyright (C) 2001 Free Software Foundation, Inc.
-+   Contributed by Dmitry Diky <diwil@mail.ru>
-+
-+This file is part of GNU CC.
-+
-+GNU CC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GNU CC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GNU CC; see the file COPYING.  If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA.  */
-+
-+/* Names to predefine in the preprocessor for this target machine. */
-+
-+#define CPP_PREDEFINES "-DMSP430"
-+/* Define this to be a string constant containing `-D' options to
-+   define the predefined macros that identify this machine and system.
-+   These macros will be predefined unless the `-ansi' option is
-+   specified.
-+
-+   In addition, a parallel set of macros are predefined, whose names
-+   are made by appending `__' at the beginning and at the end.  These
-+   `__' macros are permitted by the ANSI standard, so they are
-+   predefined regardless of whether `-ansi' is specified.
-+
-+   For example, on the Sun, one can use the following value:
-+
-+   "-Dmc68000 -Dsun -Dunix"
-+
-+   The result is to define the macros `__mc68000__', `__sun__' and
-+   `__unix__' unconditionally, and the macros `mc68000', `sun' and
-+   `unix' provided `-ansi' is not specified.  */
-+
-+
-+/* This declaration should be present. */
-+/*
-+#include <stdio.h>
-+*/
-+
-+extern int target_flags;
-+
-+#define MASK_PROF_STD         0x00000001
-+#define MASK_PROF_LIB         0x00000002
-+#define MASK_PROF_STACK               0x00000004
-+
-+#define MASK_RTL_DUMP         0x00000010
-+#define MASK_ALL_DEBUG                0x00000FE0
-+#define MASK_FORCE_HWMUL      0x00001000
-+#define MASK_STRICT_ALIGN       0x00002000
-+#define MASK_IAR              0x00004000
-+#define MASK_NO_STACK_INIT    0x00008000
-+#define MASK_NO_VOLAT_WRKAR   0x00010000
-+#define MASK_REORDER          0x00020000
-+#define MASK_INLINESIHWMUL    0x00040000
-+#define MASK_NO_HWMUL         0x00100000
-+#define MASK_NOINT_HWMUL      0x00200000
-+#define MASK_SAVE_PROLOGUE    0x00400000
-+
-+
-+
-+#define TARGET_PROF_STD               (target_flags & MASK_PROF_STD)
-+#define TARGET_PROF_LIB               (target_flags & MASK_PROF_LIB)
-+#define TARGET_PROF_STACK     (target_flags & MASK_PROF_STACK)
-+#define TARGET_NO_HWMUL               (target_flags & MASK_NO_HWMUL)
-+#define TARGET_HWMUL          (target_flags & MASK_FORCE_HWMUL)
-+#define TARGET_NOINT_HWMUL    (target_flags & MASK_NOINT_HWMUL)
-+#define TARGET_RTL_DUMP               (target_flags & MASK_RTL_DUMP)
-+#define TARGET_ALL_DEBUG      (target_flags & MASK_ALL_DEBUG)
-+#define TARGET_STRICT_ALIGN     (target_flags & MASK_STRICT_ALIGN)
-+#define TARGET_IAR            (target_flags & MASK_IAR)
-+#define TARGET_NSI            (target_flags & MASK_NO_STACK_INIT)
-+#define TARGET_NVWA           (target_flags & MASK_NO_VOLAT_WRKAR)
-+#define TARGET_REORDER                (target_flags & MASK_REORDER)
-+#define TARGET_INLINESIHWMUL  (target_flags & MASK_INLINESIHWMUL)
-+#define TARGET_SAVE_PROLOGUE  (target_flags & MASK_SAVE_PROLOGUE)
-+
-+
-+#define TARGET_SWITCHES {                                             \
-+  { "pgs", MASK_PROF_STD, N_("Add ordinary profile information")}, \
-+  { "pgl", MASK_PROF_LIB, N_("Add library profile information")}, \
-+  { "pgr", MASK_PROF_STACK,N_("Add stack information to profiler") }, \
-+  { "rtl", MASK_RTL_DUMP, NULL },                                     \
-+  { "deb", MASK_ALL_DEBUG, NULL },                                    \
-+  { "strict-align", MASK_STRICT_ALIGN,N_("Strict alignment for all structures") }, \
-+  { "force-hwmul", MASK_FORCE_HWMUL,N_("Force hardware multiplier") },\
-+  { "disable-hwmul", MASK_NO_HWMUL, N_("Disable hardware multiplier") }, \
-+  { "inline-hwmul", MASK_INLINESIHWMUL, N_("Issue inline multiplication code for 32-bit integers") }, \
-+  { "noint-hwmul", MASK_NOINT_HWMUL, ("Assume interrupt routine does not do hardware multiply")}, \
-+  { "IAR",MASK_IAR,N_("Produce IAR assembler syntax") },              \
-+  { "no-stack-init",MASK_NO_STACK_INIT,N_("No stack init in main()") },       \
-+  { "no-volatile-workaround",MASK_NO_STACK_INIT,N_("Do not perform volatile workaround for bitwise operations") }, \
-+  { "save-prologue",MASK_SAVE_PROLOGUE, ("Use subroutine call for function prologue/epilogue when possible")}, \
-+  { "", 0, NULL } \
-+}
-+
-+extern const char *msp430_endup;
-+extern const char *msp430_init_stack;
-+extern const char *msp430_mcu_name;
-+extern int msp430_has_hwmul;
-+
-+
-+#define MSP430_HAS_HWMUL_INTERNAL (msp430_has_hwmul)
-+
-+int msp430_current_function_noint_hwmul_function_p(void);
-+#define MSP430_NOINT_HWMUL (msp430_current_function_noint_hwmul_function_p())
-+
-+#define TARGET_OPTIONS {                                                    \
-+ { "init-stack=", &msp430_init_stack, N_("Specify the initial stack address") }, \
-+ { "mcu=", &msp430_mcu_name, N_("Specify the MCU name") }, \
-+ { "endup-at=",&msp430_endup,N_("Jump to specified routine at the end of main()")} \
-+}
-+
-+
-+#define TARGET_VERSION fprintf (stderr, " (GNU assembler syntax)");
-+
-+#define OVERRIDE_OPTIONS msp430_override_options()
-+
-+#define CAN_DEBUG_WITHOUT_FP
-+/* Define this macro if debugging can be performed even without a
-+   frame pointer.  If this macro is defined, GNU CC will turn on the
-+   `-fomit-frame-pointer' option whenever `-O' is specified.  */
-+
-+#define BITS_BIG_ENDIAN 0
-+#define BYTES_BIG_ENDIAN 0
-+#define WORDS_BIG_ENDIAN 0
-+#define BITS_PER_UNIT 8
-+#define BITS_PER_WORD 16
-+
-+#ifdef IN_LIBGCC2
-+/* This is to get correct SI and DI modes in libgcc2.c (32 and 64 bits).  */
-+#define UNITS_PER_WORD 4
-+#else
-+/* Width of a word, in units (bytes). */
-+#define UNITS_PER_WORD 2
-+#endif
-+
-+/* Width in bits of a pointer.
-+   See also the macro `Pmode' defined below.  */
-+#define POINTER_SIZE 16
-+
-+
-+/* Maximum sized of reasonable data type
-+   DImode or Dfmode ...  */
-+#define MAX_FIXED_MODE_SIZE 32
-+
-+/* Allocation boundary (in *bits*) for storing arguments in argument list. */
-+#define PARM_BOUNDARY 16
-+
-+/* Allocation boundary (in *bits*) for the code of a function. */
-+#define FUNCTION_BOUNDARY 16
-+
-+/* Alignment of field after `int : 0' in a structure. */
-+#define EMPTY_FIELD_BOUNDARY 16
-+
-+/* No data type wants to be aligned rounder than this. */
-+#define BIGGEST_ALIGNMENT 16
-+
-+/* Define this if move instructions will actually fail to work
-+   when given unaligned data.  */
-+#define STRICT_ALIGNMENT TARGET_STRICT_ALIGN
-+
-+/* A C expression for the size in bits of the type `int' on the
-+     target machine.  If you don't define this, the default is one word.  */
-+#define INT_TYPE_SIZE ( 16)
-+
-+
-+/* A C expression for the size in bits of the type `short' on the
-+   target machine.  If you don't define this, the default is half a
-+   word.  (If this would be less than one storage unit, it is rounded
-+   up to one unit.)  */
-+#define SHORT_TYPE_SIZE (INT_TYPE_SIZE == 8 ? INT_TYPE_SIZE : 16)
-+
-+/* A C expression for the size in bits of the type `long' on the
-+   target machine.  If you don't define this, the default is one word.  */
-+#define LONG_TYPE_SIZE (INT_TYPE_SIZE == 8 ? 16 : 32)
-+
-+#define MAX_LONG_TYPE_SIZE 32
-+/* Maximum number for the size in bits of the type `long' on the
-+   target machine.  If this is undefined, the default is
-+   `LONG_TYPE_SIZE'.  Otherwise, it is the constant value that is the
-+   largest value that `LONG_TYPE_SIZE' can have at run-time.  This is
-+   used in `cpp'.  */
-+
-+
-+#define LONG_LONG_TYPE_SIZE 64
-+/* A C expression for the size in bits of the type `long long' on the
-+   target machine.  If you don't define this, the default is two
-+   words.  If you want to support GNU Ada on your machine, the value
-+   of macro must be at least 64.  */
-+
-+
-+#define  CHAR_TYPE_SIZE 8
-+/* A C expression for the size in bits of the type `char' on the
-+   target machine.  If you don't define this, the default is one
-+   quarter of a word.  (If this would be less than one storage unit,
-+   it is rounded up to one unit.)  */
-+
-+#define FLOAT_TYPE_SIZE 32
-+/* A C expression for the size in bits of the type `float' on the
-+   target machine.  If you don't define this, the default is one word.  */
-+
-+#define DOUBLE_TYPE_SIZE 32
-+/* A C expression for the size in bits of the type `double' on the
-+   target machine.  If you don't define this, the default is two
-+   words. */
-+
-+
-+#define LONG_DOUBLE_TYPE_SIZE 32
-+/* A C expression for the size in bits of the type `long double' on
-+   the target machine.  If you don't define this, the default is two
-+   words.  */
-+
-+#define DEFAULT_SIGNED_CHAR 1
-+/* An expression whose value is 1 or 0, according to whether the type
-+   `char' should be signed or unsigned by default.  The user can
-+   always override this default with the options `-fsigned-char' and
-+   `-funsigned-char'.  */
-+
-+/* `DEFAULT_SHORT_ENUMS'
-+   A C expression to determine whether to give an `enum' type only as
-+   many bytes as it takes to represent the range of possible values
-+   of that type.  A nonzero value means to do that; a zero value
-+   means all `enum' types should be allocated like `int'.
-+
-+   If you don't define the macro, the default is 0.  */
-+
-+#define SIZE_TYPE (INT_TYPE_SIZE == 8 ? "long unsigned int" : "unsigned int")
-+/* A C expression for a string describing the name of the data type
-+   to use for size values.  The typedef name `size_t' is defined
-+   using the contents of the string.
-+   
-+   The string can contain more than one keyword.  If so, separate
-+   them with spaces, and write first any length keyword, then
-+   `unsigned' if appropriate, and finally `int'.  The string must
-+   exactly match one of the data type names defined in the function
-+   `init_decl_processing' in the file `c-decl.c'.  You may not omit
-+   `int' or change the order--that would cause the compiler to crash
-+   on startup.
-+   
-+   If you don't define this macro, the default is `"long unsigned
-+   int"'.  */
-+
-+#define PTRDIFF_TYPE (INT_TYPE_SIZE == 8 ? "long int" :"int")
-+/* A C expression for a string describing the name of the data type
-+   to use for the result of subtracting two pointers.  The typedef
-+   name `ptrdiff_t' is defined using the contents of the string.  See
-+   `SIZE_TYPE' above for more information.
-+   
-+   If you don't define this macro, the default is `"long int"'.  */
-+
-+
-+#define WCHAR_TYPE_SIZE 16
-+/* A C expression for the size in bits of the data type for wide
-+   characters.  This is used in `cpp', which cannot make use of
-+   `WCHAR_TYPE'.  */
-+
-+#define FIRST_PSEUDO_REGISTER 16
-+/* Number of hardware registers known to the compiler.  They receive
-+   numbers 0 through `FIRST_PSEUDO_REGISTER-1'; thus, the first
-+   pseudo register's number really is assigned the number
-+   `FIRST_PSEUDO_REGISTER'.  */
-+
-+#define FIXED_REGISTERS {\
-+  1,1,/* r0 r1 == PC  SP */\
-+  1,1,/* r2 r3 == CG1(SR) CG2*/\
-+  0,0,/* r4 r5 */\
-+  0,0,/* r6 r7 */\
-+  0,0,/* r8 r9 */\
-+  0,0,/* r10 r11 */\
-+  0,0,/* r12 r13 */\
-+  0,0,/* r14 r15 */\
-+}
-+/* An initializer that says which registers are used for fixed
-+   purposes all throughout the compiled code and are therefore not
-+   available for general allocation.  These would include the stack
-+   pointer, the frame pointer (except on machines where that can be
-+   used as a general register when no frame pointer is needed), the
-+   program counter on machines where that is considered one of the
-+   addressable registers, and any other numbered register with a
-+   standard use.
-+
-+   This information is expressed as a sequence of numbers, separated
-+   by commas and surrounded by braces.  The Nth number is 1 if
-+   register N is fixed, 0 otherwise.
-+
-+   The table initialized from this macro, and the table initialized by
-+   the following one, may be overridden at run time either
-+   automatically, by the actions of the macro
-+   `CONDITIONAL_REGISTER_USAGE', or by the user with the command
-+   options `-ffixed-REG', `-fcall-used-REG' and `-fcall-saved-REG'.  */
-+
-+#define CALL_USED_REGISTERS {                 \
-+    1,1,/* r0 r1 */                           \
-+    1,1,/* r2 r3 */                           \
-+    0,0,/* r4 r5 */                           \
-+    0,0,/* r6 r7 */                           \
-+    0,0,/* r8 r9 */                           \
-+    0,0,/* r10 r11 */                         \
-+    1,1,/* r12 r13 */                         \
-+    1,1,/* r14 r15 */                         \
-+}
-+/* Like `FIXED_REGISTERS' but has 1 for each register that is
-+   clobbered (in general) by function calls as well as for fixed
-+   registers.  This macro therefore identifies the registers that are
-+   not available for general allocation of values that must live
-+   across function calls.
-+
-+   If a register has 0 in `CALL_USED_REGISTERS', the compiler
-+   automatically saves it on function entry and restores it on
-+   function exit, if the register is used within the function.  */
-+
-+#define NON_SAVING_SETJMP 0
-+/* If this macro is defined and has a nonzero value, it means that
-+   `setjmp' and related functions fail to save the registers, or that
-+   `longjmp' fails to restore them.  To compensate, the compiler
-+   avoids putting variables in registers in functions that use
-+   `setjmp'.  */
-+
-+#define REG_ALLOC_ORDER { 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 }
-+
-+/* If defined, an initializer for a vector of integers, containing the
-+   numbers of hard registers in the order in which GNU CC should
-+   prefer to use them (from most preferred to least).
-+   
-+   If this macro is not defined, registers are used lowest numbered
-+   first (all else being equal).
-+   
-+   One use of this macro is on machines where the highest numbered
-+   registers must always be saved and the save-multiple-registers
-+   instruction supports only sequences of consetionve registers.  On
-+   such machines, define `REG_ALLOC_ORDER' to be an initializer that
-+   lists the highest numbered allocatable register first. */
-+
-+#define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
-+/* ORDER_REGS_FOR_LOCAL_ALLOC'
-+   A C statement (sans semicolon) to choose the order in which to
-+   allocate hard registers for pseudo-registers local to a basic
-+   block.
-+
-+   Store the desired register order in the array `reg_alloc_order'.
-+   Element 0 should be the register to allocate first; element 1, the
-+   next register; and so on.
-+
-+   The macro body should not assume anything about the contents of
-+   `reg_alloc_order' before execution of the macro.
-+
-+   On most machines, it is not necessary to define this macro.  */
-+
-+
-+#define HARD_REGNO_NREGS(REGNO, MODE) \
-+((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-+
-+/* A C expression for the number of consecutive hard registers,
-+   starting at register number REGNO, required to hold a value of mode
-+   MODE.
-+
-+   On a machine where all registers are exactly one word, a suitable
-+   definition of this macro is
-+
-+   #define HARD_REGNO_NREGS(REGNO, MODE)            \
-+   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1)  \
-+   / UNITS_PER_WORD))  */
-+
-+#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
-+/*
-+msp430_hard_regno_mode_ok(REGNO, MODE)
-+*/
-+/* A C expression that is nonzero if it is permissible to store a
-+   value of mode MODE in hard register number REGNO (or in several
-+   registers starting with that one).  For a machine where all
-+   registers are equivalent, a suitable definition is
-+
-+   #define HARD_REGNO_MODE_OK(REGNO, MODE) 1
-+
-+   It is not necessary for this macro to check for the numbers of
-+   fixed registers, because the allocation mechanism considers them
-+   to be always occupied.
-+
-+   On some machines, double-precision values must be kept in even/odd
-+   register pairs.  The way to implement that is to define this macro
-+   to reject odd register numbers for such modes.
-+
-+   The minimum requirement for a mode to be OK in a register is that
-+   the `movMODE' instruction pattern support moves between the
-+   register and any other hard register for which the mode is OK; and
-+   that moving a value into the register and back out not alter it.
-+
-+   Since the same instruction used to move `SImode' will work for all
-+   narrower integer modes, it is not necessary on any machine for
-+   `HARD_REGNO_MODE_OK' to distinguish between these modes, provided
-+   you define patterns `movhi', etc., to take advantage of this.  This
-+   is useful because of the interaction between `HARD_REGNO_MODE_OK'
-+   and `MODES_TIEABLE_P'; it is very desirable for all integer modes
-+   to be tieable.
-+
-+   Many machines have special registers for floating point arithmetic.
-+   Often people assume that floating point machine modes are allowed
-+   only in floating point registers.  This is not true.  Any
-+   registers that can hold integers can safely *hold* a floating
-+   point machine mode, whether or not floating arithmetic can be done
-+   on it in those registers.  Integer move instructions can be used
-+   to move the values.
-+
-+   On some machines, though, the converse is true: fixed-point machine
-+   modes may not go in floating registers.  This is true if the
-+   floating registers normalize any value stored in them, because
-+   storing a non-floating value there would garble it.  In this case,
-+   `HARD_REGNO_MODE_OK' should reject fixed-point machine modes in
-+   floating registers.  But if the floating registers do not
-+   automatically normalize, if you can store any bit pattern in one
-+   and retrieve it unchanged without a trap, then any machine mode
-+   may go in a floating register, so you can define this macro to say
-+   so.
-+
-+   The primary significance of special floating registers is rather
-+   that they are the registers acceptable in floating point arithmetic
-+   instructions.  However, this is of no concern to
-+   `HARD_REGNO_MODE_OK'.  You handle it by writing the proper
-+   constraints for those instructions.
-+
-+   On some machines, the floating registers are especially slow to
-+   access, so that it is better to store a value in a stack frame
-+   than in such a register if floating point arithmetic is not being
-+   done.  As long as the floating registers are not in class
-+   `GENERAL_REGS', they will not be used unless some pattern's
-+   constraint asks for one.  */
-+
-+#define MODES_TIEABLE_P(MODE1, MODE2)                 \
-+0
-+/*
-+  ((MODE1) == (MODE2)                                 \
-+     || ((MODE1) == QImode && (MODE2) == HImode)      \
-+     || ((MODE1) == HImode && (MODE2) == QImode))
-+*/       
-+/* A C expression that is nonzero if it is desirable to choose
-+   register allocation so as to avoid move instructions between a
-+   value of mode MODE1 and a value of mode MODE2.
-+
-+   If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R,
-+   MODE2)' are ever different for any R, then `MODES_TIEABLE_P (MODE1,
-+   MODE2)' must be zero.  */
-+
-+
-+
-+
-+enum reg_class {
-+  NO_REGS,
-+  PC_REG,                     /* r0  - PC     */
-+  SP_REG,                     /* r1  - SP     */
-+  STACK_REGS,                 /* r2  - SR     */
-+  CG1_REG,                    /* r2  - CG1    */
-+  CG2_REG,                    /* r3  - CG2    */
-+  CG_REGS,                    /* r2, r3       */
-+  GENERAL_REGS,                       /* r4 - r15     */
-+  POINTER_REGS,
-+  FFOUR_REG,
-+  ALL_REGS, LIM_REG_CLASSES
-+};
-+  
-+/* An enumeral type that must be defined with all the register class
-+   names as enumeral values.  `NO_REGS' must be first.  `ALL_REGS'
-+   must be the last register class, followed by one more enumeral
-+   value, `LIM_REG_CLASSES', which is not a register class but rather
-+   tells how many classes there are.
-+
-+   Each register class has a number, which is the value of casting
-+   the class name to type `int'.  The number serves as an index in
-+   many of the tables described below.  */
-+
-+
-+#define N_REG_CLASSES (int) LIM_REG_CLASSES
-+/* The number of distinct register classes, defined as follows:
-+   #define N_REG_CLASSES (int) LIM_REG_CLASSES  */
-+
-+#define REG_CLASS_NAMES {             \
-+              "NO_REGS",              \
-+              "PC_REG",               \
-+              "SP_REG",               \
-+              "STACK_REGS",           \
-+              "CG1_REG",              \
-+              "CG2_REG",              \
-+              "CG_REGS",              \
-+              "GENERAL_REGS",         \
-+              "POINTER_REGS",         \
-+              "FFOUR_REG",            \
-+              "ALL_REGS"              \
-+}
-+
-+/* An initializer containing the names of the register classes as C
-+   string constants.  These names are used in writing some of the
-+   debugging dumps.  */
-+
-+#define REG_CLASS_CONTENTS {                          \
-+  {0x00000000ul},     /* NO_REGS      */      \
-+  {0x00000001ul},     /* PC_REG       */      \
-+  {0x00000002ul},     /* SP_REG       */      \
-+  {0x00000004ul},     /* r2           */      \
-+  {0x00000004ul},     /* r2           */      \
-+  {0x00000008ul},     /* r3           */      \
-+  {0x0000000cul},     /* r2,r3        */      \
-+  {0x0000fff2ul}, /* r4 - r15,r1  */      \
-+  {0x0000fff2ul}, /* r4 - r15,r1  */      \
-+  {0x0000fff0ul},     /* r4 - r15     */      \
-+  {0x0000fffful}      /* ALL_REGS */          \
-+}
-+/* An initializer containing the contents of the register classes, as
-+   integers which are bit masks.  The Nth integer specifies the
-+   contents of class N.  The way the integer MASK is interpreted is
-+   that register R is in the class if `MASK & (1 << R)' is 1.
-+
-+   When the machine has more than 32 registers, an integer does not
-+   suffice.  Then the integers are replaced by sub-initializers,
-+   braced groupings containing several integers.  Each
-+   sub-initializer must be suitable as an initializer for the type
-+   `HARD_REG_SET' which is defined in `hard-reg-set.h'.  */
-+
-+
-+enum reg_class msp430_regno_reg_class PARAMS ((int));
-+#define REGNO_REG_CLASS(R) msp430_regno_reg_class(R)
-+/* A C expression whose value is a register class containing hard
-+   register REGNO.  In general there is more than one such class;
-+   choose a class which is "minimal", meaning that no smaller class
-+   also contains the register.  */
-+
-+#define BASE_REG_CLASS POINTER_REGS
-+/* A macro whose definition is the name of the class to which a valid
-+   base register must belong.  A base register is one used in an
-+   address which is the register value plus a displacement.  */
-+
-+#define INDEX_REG_CLASS NO_REGS
-+/* A macro whose definition is the name of the class to which a valid
-+   index register must belong.  An index register is one used in an
-+   address where its value is either multiplied by a scale factor or
-+   added to another register (as well as added to a displacement).  */
-+
-+#define REG_CLASS_FROM_LETTER(C) msp430_reg_class_from_letter(C)
-+/* A C expression which defines the machine-dependent operand
-+   constraint letters for register classes.  If CHAR is such a
-+   letter, the value should be the register class corresponding to
-+   it.  Otherwise, the value should be `NO_REGS'.  The register
-+   letter `r', corresponding to class `GENERAL_REGS', will not be
-+   passed to this macro; you do not need to handle it.  */
-+
-+#define REGNO_OK_FOR_BASE_P(r) msp430_regno_ok_for_base_p(r) 
-+                                      
-+/* A C expression which is nonzero if register number NUM is suitable
-+   for use as a base register in operand addresses.  It may be either
-+   a suitable hard register or a pseudo register that has been
-+   allocated such a hard register.  */
-+
-+/* #define REGNO_MODE_OK_FOR_BASE_P(r, m) 
-+   A C expression that is just like `REGNO_OK_FOR_BASE_P', except that
-+   that expression may examine the mode of the memory reference in
-+   MODE.  You should define this macro if the mode of the memory
-+   reference affects whether a register may be used as a base
-+   register.  If you define this macro, the compiler will use it
-+   instead of `REGNO_OK_FOR_BASE_P'.  */
-+
-+#define REGNO_OK_FOR_INDEX_P(NUM) 0
-+/* A C expression which is nonzero if register number NUM is suitable
-+   for use as an index register in operand addresses.  It may be
-+   either a suitable hard register or a pseudo register that has been
-+   allocated such a hard register.
-+
-+   The difference between an index register and a base register is
-+   that the index register may be scaled.  If an address involves the
-+   sum of two registers, neither one of them scaled, then either one
-+   may be labeled the "base" and the other the "index"; but whichever
-+   labeling is used must fit the machine's constraints of which
-+   registers may serve in each capacity.  The compiler will try both
-+   labelings, looking for one that is valid, and will reload one or
-+   both registers only if neither labeling works.  */
-+
-+#define PREFERRED_RELOAD_CLASS(X, CLASS) FFOUR_REG
-+
-+/*
-+referred_reload_class(X,CLASS)
-+ A C expression that places additional restrictions on the register
-+   class to use when it is necessary to copy value X into a register
-+   in class CLASS.  The value is a register class; perhaps CLASS, or
-+   perhaps another, smaller class.  On many machines, the following
-+   definition is safe:
-+
-+   #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
-+
-+   Sometimes returning a more restrictive class makes better code.
-+   For example, on the 68000, when X is an integer constant that is
-+   in range for a `moveq' instruction, the value of this macro is
-+   always `DATA_REGS' as long as CLASS includes the data registers.
-+   Requiring a data register guarantees that a `moveq' will be used.
-+
-+   If X is a `const_double', by returning `NO_REGS' you can force X
-+   into a memory constant.  This is useful on certain machines where
-+   immediate floating values cannot be loaded into certain kinds of
-+   registers.  */
-+/* `PREFERRED_OUTPUT_RELOAD_CLASS (X, CLASS)'
-+   Like `PREFERRED_RELOAD_CLASS', but for output reloads instead of
-+   input reloads.  If you don't define this macro, the default is to
-+   use CLASS, unchanged.  */
-+
-+/* `LIMIT_RELOAD_CLASS (MODE, CLASS)'
-+   A C expression that places additional restrictions on the register
-+   class to use when it is necessary to be able to hold a value of
-+   mode MODE in a reload register for which class CLASS would
-+   ordinarily be used.
-+
-+   Unlike `PREFERRED_RELOAD_CLASS', this macro should be used when
-+   there are certain modes that simply can't go in certain reload
-+   classes.
-+
-+   The value is a register class; perhaps CLASS, or perhaps another,
-+   smaller class.
-+
-+   Don't define this macro unless the target machine has limitations
-+   which require the macro to do something nontrivial.  */
-+
-+/*
-+#define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) GENERAL_REGS
-+
-+
-+#define  SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) GENERAL_REGS
-+
-+
-+   `SECONDARY_RELOAD_CLASS (CLASS, MODE, X)'
-+   `SECONDARY_OUTPUT_RELOAD_CLASS (CLASS, MODE, X)'
-+   Many machines have some registers that cannot be copied directly
-+   to or from memory or even from other types of registers.  An
-+   example is the `MQ' register, which on most machines, can only be
-+   copied to or from general registers, but not memory.  Some
-+   machines allow copying all registers to and from memory, but
-+   require a scratch register for stores to some memory locations
-+   (e.g., those with symbolic address on the RT, and those with
-+   certain symbolic address on the Sparc when compiling PIC).  In
-+   some cases, both an intermediate and a scratch register are
-+   required.
-+
-+   You should define these macros to indicate to the reload phase
-+   that it may need to allocate at least one register for a reload in
-+   addition to the register to contain the data.  Specifically, if
-+   copying X to a register CLASS in MODE requires an intermediate
-+   register, you should define `SECONDARY_INPUT_RELOAD_CLASS' to
-+   return the largest register class all of whose registers can be
-+   used as intermediate registers or scratch registers.
-+
-+   If copying a register CLASS in MODE to X requires an intermediate
-+   or scratch register, `SECONDARY_OUTPUT_RELOAD_CLASS' should be
-+   defined to return the largest register class required.  If the
-+   requirements for input and output reloads are the same, the macro
-+   `SECONDARY_RELOAD_CLASS' should be used instead of defining both
-+   macros identically.
-+
-+   The values returned by these macros are often `GENERAL_REGS'.
-+   Return `NO_REGS' if no spare register is needed; i.e., if X can be
-+   directly copied to or from a register of CLASS in MODE without
-+   requiring a scratch register.  Do not define this macro if it
-+   would always return `NO_REGS'.
-+
-+   If a scratch register is required (either with or without an
-+   intermediate register), you should define patterns for
-+   `reload_inM' or `reload_outM', as required (*note Standard
-+   Names::..  These patterns, which will normally be implemented with
-+   a `define_expand', should be similar to the `movM' patterns,
-+   except that operand 2 is the scratch register.
-+
-+   Define constraints for the reload register and scratch register
-+   that contain a single register class.  If the original reload
-+   register (whose class is CLASS) can meet the constraint given in
-+   the pattern, the value returned by these macros is used for the
-+   class of the scratch register.  Otherwise, two additional reload
-+   registers are required.  Their classes are obtained from the
-+   constraints in the insn pattern.
-+
-+   X might be a pseudo-register or a `subreg' of a pseudo-register,
-+   which could either be in a hard register or in memory.  Use
-+   `true_regnum' to find out; it will return -1 if the pseudo is in
-+   memory and the hard register number if it is in a register.
-+
-+   These macros should not be used in the case where a particular
-+   class of registers can only be copied to memory and not to another
-+   class of registers.  In that case, secondary reload registers are
-+   not needed and would not be helpful.  Instead, a stack location
-+   must be used to perform the copy and the `movM' pattern should use
-+   memory as a intermediate storage.  This case often occurs between
-+   floating-point and general registers.  */
-+
-+/* `SECONDARY_MEMORY_NEEDED (CLASS1, CLASS2, M)'
-+   Certain machines have the property that some registers cannot be
-+   copied to some other registers without using memory.  Define this
-+   macro on those machines to be a C expression that is non-zero if
-+   objects of mode M in registers of CLASS1 can only be copied to
-+   registers of class CLASS2 by storing a register of CLASS1 into
-+   memory and loading that memory location into a register of CLASS2.
-+
-+   Do not define this macro if its value would always be zero.
-+
-+   `SECONDARY_MEMORY_NEEDED_RTX (MODE)'
-+   Normally when `SECONDARY_MEMORY_NEEDED' is defined, the compiler
-+   allocates a stack slot for a memory location needed for register
-+   copies.  If this macro is defined, the compiler instead uses the
-+   memory location defined by this macro.
-+
-+   Do not define this macro if you do not define
-+   `SECONDARY_MEMORY_NEEDED'.  */
-+
-+#define SMALL_REGISTER_CLASSES 1
-+/* Normally the compiler avoids choosing registers that have been
-+   explicitly mentioned in the rtl as spill registers (these
-+   registers are normally those used to pass parameters and return
-+   values).  However, some machines have so few registers of certain
-+   classes that there would not be enough registers to use as spill
-+   registers if this were done.
-+
-+   Define `SMALL_REGISTER_CLASSES' to be an expression with a non-zero
-+   value on these machines.  When this macro has a non-zero value, the
-+   compiler allows registers explicitly used in the rtl to be used as
-+   spill registers but avoids extending the lifetime of these
-+   registers.
-+
-+   It is always safe to define this macro with a non-zero value, but
-+   if you unnecessarily define it, you will reduce the amount of
-+   optimizations that can be performed in some cases.  If you do not
-+   define this macro with a non-zero value when it is required, the
-+   compiler will run out of spill registers and print a fatal error
-+   message.  For most machines, you should not define this macro at
-+   all.  */
-+
-+/*
-+#define CLASS_LIKELY_SPILLED_P(CLASS) \
-+      ( (CLASS) != ALL_REGS && (CLASS) != GENERAL_REGS)
-+ A C expression whose value is nonzero if pseudos that have been
-+   assigned to registers of class CLASS would likely be spilled
-+   because registers of CLASS are needed for spill registers.
-+
-+   The default value of this macro returns 1 if CLASS has exactly one
-+   register and zero otherwise.  On most machines, this default
-+   should be used.  Only define this macro to some other expression
-+   if pseudo allocated by `local-alloc.c' end up in memory because
-+   their hard registers were needed for spill registers.  If this
-+   macro returns nonzero for those classes, those pseudos will only
-+   be allocated by `global.c', which knows how to reallocate the
-+   pseudo to another register.  If there would not be another
-+   register available for reallocation, you should not change the
-+   definition of this macro since the only effect of such a
-+   definition would be to slow down register allocation.  */
-+
-+#define CLASS_MAX_NREGS(CLASS, MODE)  \
-+      ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-+/* A C expression for the maximum number of consecutive registers of
-+   class CLASS needed to hold a value of mode MODE.
-+
-+   This is closely related to the macro `HARD_REGNO_NREGS'.  In fact,
-+   the value of the macro `CLASS_MAX_NREGS (CLASS, MODE)' should be
-+   the maximum value of `HARD_REGNO_NREGS (REGNO, MODE)' for all
-+   REGNO values in the class CLASS.
-+
-+   This macro helps control the handling of multiple-word values in
-+   the reload pass.  */
-+
-+#define CONST_OK_FOR_LETTER_P(VALUE, C)                               \
-+  ((C) == 'I' ? (VALUE) >= -32767 && (VALUE) <= 32767 :               \
-+   (C) == 'J' ? (VALUE) <= 0 && (VALUE) >= -32767:            \
-+   (C) == 'K' ? (VALUE) >= 0 && (VALUE) <= 32767 :            \
-+   (C) == 'L' ? (VALUE) >= 0 && (VALUE) <= 0xff        :              \
-+   (C) == 'M' ? (VALUE) >= 0x10 && (VALUE) <= 0xff :          \
-+   (C) == 'N' ? (VALUE) >= 0x100 && (VALUE) <= 0x1ff :                \
-+   (C) == 'O' ? (VALUE)&1:                                    \
-+   (C) == 'P' ? ((VALUE)==-1||(VALUE)==1||(VALUE)==2||(VALUE)==4||(VALUE)==8 ||(VALUE)==0) : 0)
-+/* A C expression that defines the machine-dependent operand
-+   constraint letters (`I', `J', `K', ... `P') that specify
-+   particular ranges of integer values.  If C is one of those
-+   letters, the expression should check that VALUE, an integer, is in
-+   the appropriate range and return 1 if so, 0 otherwise.  If C is
-+   not one of those letters, the value should be 0 regardless of
-+   VALUE.  */
-+
-+
-+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
-+  ((C) == 'G' ? (VALUE) == CONST0_RTX (SFmode)        \
-+   : 0)
-+/* `CONST_DOUBLE_OK_FOR_LETTER_P (VALUE, C)'
-+   A C expression that defines the machine-dependent operand
-+   constraint letters that specify particular ranges of
-+   `const_double' values (`G' or `H').
-+
-+   If C is one of those letters, the expression should check that
-+   VALUE, an RTX of code `const_double', is in the appropriate range
-+   and return 1 if so, 0 otherwise.  If C is not one of those
-+   letters, the value should be 0 regardless of VALUE.
-+
-+   `const_double' is used for all floating-point constants and for
-+   `DImode' fixed-point constants.  A given letter can accept either
-+   or both kinds of values.  It can use `GET_MODE' to distinguish
-+   between these kinds.  */
-+
-+#define EXTRA_CONSTRAINT(x, c) extra_constraint(x, c)
-+/* A C expression that defines the optional machine-dependent
-+   constraint letters (``Q', `R', `S', `T', `U') that can'
-+   be used to segregate specific types of operands, usually memory
-+   references, for the target machine.  Normally this macro will not
-+   be defined.  If it is required for a particular target machine, it
-+   should return 1 if VALUE corresponds to the operand type
-+   represented by the constraint letter C.  If C is not defined as an
-+   extra constraint, the value returned should be 0 regardless of
-+   VALUE.
-+
-+   For example, on the ROMP, load instructions cannot have their
-+   output in r0 if the memory reference contains a symbolic address.
-+   Constraint letter `Q' is defined as representing a memory address
-+   that does *not* contain a symbolic address.  An alternative is
-+   specified with a `Q' constraint on the input and `r' on the
-+   output.  The next alternative specifies `m' on the input and a
-+   register class that does not include r0 on the output.  */
-+
-+/*  This is an undocumented variable which describes
-+    how GCC will push a data */
-+#define STACK_PUSH_CODE POST_DEC
-+
-+#define STACK_GROWS_DOWNWARD
-+/* Define this macro if pushing a word onto the stack moves the stack
-+   pointer to a smaller address.
-+
-+   When we say, "define this macro if ...," it means that the
-+   compiler checks this macro only with `#ifdef' so the precise
-+   definition used does not matter.  */
-+
-+#define STARTING_FRAME_OFFSET 0
-+/* Offset from the frame pointer to the first local variable slot to
-+   be allocated.
-+
-+   If `FRAME_GROWS_DOWNWARD', find the next slot's offset by
-+   subtracting the first slot's length from `STARTING_FRAME_OFFSET'.
-+   Otherwise, it is found by adding the length of the first slot to
-+   the value `STARTING_FRAME_OFFSET'.  */
-+
-+#define STACK_POINTER_OFFSET 0
-+/* Offset from the stack pointer register to the first location at
-+   which outgoing arguments are placed.  If not specified, the
-+   default value of zero is used.  This is the proper value for most
-+   machines.
-+
-+   If `ARGS_GROW_DOWNWARD', this is the offset to the location above
-+   the first location at which outgoing arguments are placed.  */
-+
-+#define FIRST_PARM_OFFSET(FUNDECL) 0
-+/* Offset from the argument pointer register to the first argument's
-+   address.  On some machines it may depend on the data type of the
-+   function.
-+
-+   If `ARGS_GROW_DOWNWARD', this is the offset to the location above
-+   the first argument's address.  */
-+
-+/* `STACK_DYNAMIC_OFFSET (FUNDECL)'
-+   Offset from the stack pointer register to an item dynamically
-+   allocated on the stack, e.g., by `alloca'.
-+
-+   The default value for this macro is `STACK_POINTER_OFFSET' plus the
-+   length of the outgoing arguments.  The default is correct for most
-+   machines.  See `function.c' for details.  */
-+
-+#define STACK_BOUNDARY 16
-+/* Define this macro if there is a guaranteed alignment for the stack
-+   pointer on this machine.  The definition is a C expression for the
-+   desired alignment (measured in bits).  This value is used as a
-+   default if PREFERRED_STACK_BOUNDARY is not defined.  */
-+
-+#define STACK_POINTER_REGNUM 1
-+/* The register number of the stack pointer register, which must also
-+   be a fixed register according to `FIXED_REGISTERS'.  On most
-+   machines, the hardware determines which register this is.  */
-+
-+#define FRAME_POINTER_REGNUM 4
-+/* The register number of the frame pointer register, which is used to
-+   access automatic variables in the stack frame.  On some machines,
-+   the hardware determines which register this is.  On other
-+   machines, you can choose any register you wish for this purpose.  */
-+
-+#define ARG_POINTER_REGNUM 5
-+/* The register number of the arg pointer register, which is used to
-+   access the function's argument list.  On some machines, this is
-+   the same as the frame pointer register.  On some machines, the
-+   hardware determines which register this is.  On other machines,
-+   you can choose any register you wish for this purpose.  If this is
-+   not the same register as the frame pointer register, then you must
-+   mark it as a fixed register according to `FIXED_REGISTERS', or
-+   arrange to be able to eliminate it (*note Elimination::.).  */
-+
-+#define STATIC_CHAIN_REGNUM 6
-+/* Register numbers used for passing a function's static chain
-+   pointer.  If register windows are used, the register number as
-+   seen by the called function is `STATIC_CHAIN_INCOMING_REGNUM',
-+   while the register number as seen by the calling function is
-+   `STATIC_CHAIN_REGNUM'.  If these registers are the same,
-+   `STATIC_CHAIN_INCOMING_REGNUM' need not be defined.
-+
-+   The static chain register need not be a fixed register.
-+
-+   If the static chain is passed in memory, these macros should not be
-+   defined; instead, the next two macros should be defined.  */
-+
-+#define FRAME_POINTER_REQUIRED   frame_pointer_required_p()
-+
-+/*
-+ A C expression which is nonzero if a function must have and use a
-+   frame pointer.  This expression is evaluated  in the reload pass.
-+   If its value is nonzero the function will have a frame pointer.
-+
-+   The expression can in principle examine the current function and
-+   decide according to the facts, but on most machines the constant 0
-+   or the constant 1 suffices.  Use 0 when the machine allows code to
-+   be generated with no frame pointer, and doing so saves some time
-+   or space.  Use 1 when there is no possible advantage to avoiding a
-+   frame pointer.
-+
-+   In certain cases, the compiler does not know how to produce valid
-+   code without a frame pointer.  The compiler recognizes those cases
-+   and automatically gives the function a frame pointer regardless of
-+   what `FRAME_POINTER_REQUIRED' says.  You don't need to worry about
-+   them.
-+
-+   In a function that does not require a frame pointer, the frame
-+   pointer register can be allocated for ordinary usage, unless you
-+   mark it as a fixed register.  See `FIXED_REGISTERS' for more
-+   information.  */
-+
-+#define ELIMINABLE_REGS {                     \
-+   {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
-+   {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM} \
-+}
-+/* If defined, this macro specifies a table of register pairs used to
-+   eliminate unneeded registers that point into the stack frame.  If
-+   it is not defined, the only elimination attempted by the compiler
-+   is to replace references to the frame pointer with references to
-+   the stack pointer.
-+
-+   The definition of this macro is a list of structure
-+   initializations, each of which specifies an original and
-+   replacement register.
-+
-+   On some machines, the position of the argument pointer is not
-+   known until the compilation is completed.  In such a case, a
-+   separate hard register must be used for the argument pointer.
-+   This register can be eliminated by replacing it with either the
-+   frame pointer or the argument pointer, depending on whether or not
-+   the frame pointer has been eliminated.
-+
-+   In this case, you might specify:
-+   #define ELIMINABLE_REGS  \
-+   {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
-+   {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
-+   {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
-+
-+   Note that the elimination of the argument pointer with the stack
-+   pointer is specified first since that is the preferred elimination.  */
-+
-+#define CAN_ELIMINATE(FROM, TO) 1
-+/* A C expression that returns non-zero if the compiler is allowed to
-+   try to replace register number FROM-REG with register number
-+   TO-REG.  This macro need only be defined if `ELIMINABLE_REGS' is
-+   defined, and will usually be the constant 1, since most of the
-+   cases preventing register elimination are things that the compiler
-+   already knows about.  */
-+
-+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                  \
-+     OFFSET = initial_elimination_offset (FROM, TO)
-+/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'.  It
-+   specifies the initial difference between the specified pair of
-+   registers.  This macro must be defined if `ELIMINABLE_REGS' is
-+   defined.  */
-+/*
-+#define RETURN_ADDR_RTX(count, x) \
-+  gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (tem, 1)))
-+*/
-+#define PUSH_ROUNDING(NPUSHED) ((NPUSHED+1) & ~1)
-+/* A C expression that is the number of bytes actually pushed onto the
-+   stack when an instruction attempts to push NPUSHED bytes.
-+
-+   If the target machine does not have a push instruction, do not
-+   define this macro.  That directs GNU CC to use an alternate
-+   strategy: to allocate the entire argument block and then store the
-+   arguments into it.
-+
-+   On some machines, the definition
-+
-+   #define PUSH_ROUNDING(BYTES) (BYTES)
-+
-+   will suffice.  But on other machines, instructions that appear to
-+   push one byte actually push two bytes in an attempt to maintain
-+   alignment.  Then the definition should be
-+
-+   #define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1)  */
-+
-+#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
-+/* A C expression that should indicate the number of bytes of its own
-+   arguments that a function pops on returning, or 0 if the function
-+   pops no arguments and the caller must therefore pop them all after
-+   the function returns.
-+
-+   FUNDECL is a C variable whose value is a tree node that describes
-+   the function in question.  Normally it is a node of type
-+   `FUNCTION_DECL' that describes the declaration of the function.
-+   From this you can obtain the DECL_MACHINE_ATTRIBUTES of the
-+   function.
-+
-+   FUNTYPE is a C variable whose value is a tree node that describes
-+   the function in question.  Normally it is a node of type
-+   `FUNCTION_TYPE' that describes the data type of the function.
-+   From this it is possible to obtain the data types of the value and
-+   arguments (if known).
-+
-+   When a call to a library function is being considered, FUNDECL
-+   will contain an identifier node for the library function.  Thus, if
-+   you need to distinguish among various library functions, you can
-+   do so by their names.  Note that "library function" in this
-+   context means a function used to perform arithmetic, whose name is
-+   known specially in the compiler and was not mentioned in the C
-+   code being compiled.
-+
-+   STACK-SIZE is the number of bytes of arguments passed on the
-+   stack.  If a variable number of bytes is passed, it is zero, and
-+   argument popping will always be the responsibility of the calling
-+   function.
-+
-+   On the Vax, all functions always pop their arguments, so the
-+   definition of this macro is STACK-SIZE.  On the 68000, using the
-+   standard calling convention, no functions pop their arguments, so
-+   the value of the macro is always 0 in this case.  But an
-+   alternative calling convention is available in which functions
-+   that take a fixed number of arguments pop them but other functions
-+   (such as `printf') pop nothing (the caller pops all).  When this
-+   convention is in use, FUNTYPE is examined to determine whether a
-+   function takes a fixed number of arguments.  */
-+
-+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-+(function_arg (&(CUM), MODE, TYPE, NAMED))
-+
-+/*
-+#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
-+(function_incoming_arg (&(CUM), MODE, TYPE, NAMED))
-+*/
-+/* A C expression that controls whether a function argument is passed
-+   in a register, and which register.
-+
-+   The arguments are CUM, which summarizes all the previous
-+   arguments; MODE, the machine mode of the argument; TYPE, the data
-+   type of the argument as a tree node or 0 if that is not known
-+   (which happens for C support library functions); and NAMED, which
-+   is 1 for an ordinary argument and 0 for nameless arguments that
-+   correspond to `...' in the called function's prototype.
-+
-+   The value of the expression is usually either a `reg' RTX for the
-+   hard register in which to pass the argument, or zero to pass the
-+   argument on the stack.
-+
-+   For machines like the Vax and 68000, where normally all arguments
-+   are pushed, zero suffices as a definition.
-+
-+   The value of the expression can also be a `parallel' RTX.  This is
-+   used when an argument is passed in multiple locations.  The mode
-+   of the of the `parallel' should be the mode of the entire
-+   argument.  The `parallel' holds any number of `expr_list' pairs;
-+   each one describes where part of the argument is passed.  In each
-+   `expr_list', the first operand can be either a `reg' RTX for the
-+   hard register in which to pass this part of the argument, or zero
-+   to pass the argument on the stack.  If this operand is a `reg',
-+   then the mode indicates how large this part of the argument is.
-+   The second operand of the `expr_list' is a `const_int' which gives
-+   the offset in bytes into the entire argument where this part
-+   starts.
-+
-+   The usual way to make the ANSI library `stdarg.h' work on a machine
-+   where some arguments are usually passed in registers, is to cause
-+   nameless arguments to be passed on the stack instead.  This is done
-+   by making `FUNCTION_ARG' return 0 whenever NAMED is 0.
-+
-+   You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
-+   definition of this macro to determine if this argument is of a
-+   type that must be passed in the stack.  If `REG_PARM_STACK_SPACE'
-+   is not defined and `FUNCTION_ARG' returns non-zero for such an
-+   argument, the compiler will abort.  If `REG_PARM_STACK_SPACE' is
-+   defined, the argument will be computed in the stack and then
-+   loaded into a register.  */
-+
-+typedef struct msp430_args {
-+  int nregs;                  /* # registers available for passing */
-+  int regno;                  /* next available register number */
-+} CUMULATIVE_ARGS;
-+/* A C type for declaring a variable that is used as the first
-+   argument of `FUNCTION_ARG' and other related values.  For some
-+   target machines, the type `int' suffices and can hold the number
-+   of bytes of argument so far.
-+
-+   There is no need to record in `CUMULATIVE_ARGS' anything about the
-+   arguments that have been passed on the stack.  The compiler has
-+   other variables to keep track of that.  For target machines on
-+   which all arguments are passed on the stack, there is no need to
-+   store anything in `CUMULATIVE_ARGS'; however, the data structure
-+   must exist and should not be empty, so use `int'.  */
-+
-+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
-+init_cumulative_args (&(CUM), FNTYPE, LIBNAME, INDIRECT)
-+
-+#define  INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
-+init_cumulative_incoming_args(&(CUM), FNTYPE, LIBNAME)
-+
-+/* A C statement (sans semicolon) for initializing the variable CUM
-+   for the state at the beginning of the argument list.  The variable
-+   has type `CUMULATIVE_ARGS'.  The value of FNTYPE is the tree node
-+   for the data type of the function which will receive the args, or 0
-+   if the args are to a compiler support library function.  The value
-+   of INDIRECT is nonzero when processing an indirect call, for
-+   example a call through a function pointer.  The value of INDIRECT
-+   is zero for a call to an explicitly named function, a library
-+   function call, or when `INIT_CUMULATIVE_ARGS' is used to find
-+   arguments for the function being compiled.
-+   
-+   When processing a call to a compiler support library function,
-+   LIBNAME identifies which one.  It is a `symbol_ref' rtx which
-+   contains the name of the function, as a string.  LIBNAME is 0 when
-+   an ordinary C function call is being processed.  Thus, each time
-+   this macro is called, either LIBNAME or FNTYPE is nonzero, but
-+   never both of them at once.   */
-+
-+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)  \
-+  (function_arg_advance (&CUM, MODE, TYPE, NAMED))
-+
-+/* A C statement (sans semicolon) to update the summarizer variable
-+   CUM to advance past an argument in the argument list.  The values
-+   MODE, TYPE and NAMED describe that argument.  Once this is done,
-+   the variable CUM is suitable for analyzing the *following*
-+   argument with `FUNCTION_ARG', etc.
-+   
-+   This macro need not do anything if the argument in question was
-+   passed on the stack.  The compiler knows how to track the amount
-+   of stack space used for arguments without any special help. */
-+
-+#define FUNCTION_ARG_REGNO_P(r) (r >= 12 && r <= 15)
-+/* A C expression that is nonzero if REGNO is the number of a hard
-+   register in which function arguments are sometimes passed.  This
-+   does *not* include implicit arguments such as the static chain and
-+   the structure-value address.  On many machines, no registers can be
-+   used for this purpose since all function arguments are pushed on
-+   the stack.  */
-+
-+extern int msp430_reg_order[];
-+
-+#define RET_REGISTER  15 /* msp430_ret_register ()*/
-+
-+#define FUNCTION_VALUE(VALTYPE, FUNC) msp430_function_value (VALTYPE, FUNC)
-+/* A C expression to create an RTX representing the place where a
-+   function returns a value of data type VALTYPE.  VALTYPE is a tree
-+   node representing a data type.  Write `TYPE_MODE (VALTYPE)' to get
-+   the machine mode used to represent that type.  On many machines,
-+   only the mode is relevant.  (Actually, on most machines, scalar
-+   values are returned in the same place regardless of mode).
-+
-+   The value of the expression is usually a `reg' RTX for the hard
-+   register where the return value is stored.  The value can also be a
-+   `parallel' RTX, if the return value is in multiple places.  See
-+   `FUNCTION_ARG' for an explanation of the `parallel' form.
-+
-+   If `PROMOTE_FUNCTION_RETURN' is defined, you must apply the same
-+   promotion rules specified in `PROMOTE_MODE' if VALTYPE is a scalar
-+   type.
-+
-+   If the precise function being called is known, FUNC is a tree node
-+   (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer.  This
-+   makes it possible to use a different value-returning convention
-+   for specific functions when all their calls are known.
-+
-+   `FUNCTION_VALUE' is not used for return vales with aggregate data
-+   types, because these are returned in another way.  See
-+   `STRUCT_VALUE_REGNUM' and related macros, below.  */
-+
-+#define LIBCALL_VALUE(MODE)  msp430_libcall_value (MODE)
-+/* A C expression to create an RTX representing the place where a
-+   library function returns a value of mode MODE.  If the precise
-+   function being called is known, FUNC is a tree node
-+   (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer.  This
-+   makes it possible to use a different value-returning convention
-+   for specific functions when all their calls are known.
-+
-+   Note that "library function" in this context means a compiler
-+   support routine, used to perform arithmetic, whose name is known
-+   specially by the compiler and was not mentioned in the C code being
-+   compiled.
-+
-+   The definition of `LIBRARY_VALUE' need not be concerned aggregate
-+   data types, because none of the library functions returns such
-+   types.  */
-+
-+#define FUNCTION_VALUE_REGNO_P(N) ((N) == RET_REGISTER)
-+/* A C expression that is nonzero if REGNO is the number of a hard
-+   register in which the values of called function may come back.
-+
-+   A register whose use for returning values is limited to serving as
-+   the second of a pair (for a value of type `double', say) need not
-+   be recognized by this macro.  So for most machines, this definition
-+   suffices:
-+
-+   #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
-+
-+   If the machine has register windows, so that the caller and the
-+   called function use different registers for the return value, this
-+   macro should recognize only the caller's register numbers.  */
-+
-+#define RETURN_IN_MEMORY(TYPE) ((TYPE_MODE (TYPE) == BLKmode) \
-+                              ? int_size_in_bytes (TYPE) > 8  \
-+                              : 0)
-+/* A C expression which can inhibit the returning of certain function
-+   values in registers, based on the type of value.  A nonzero value
-+   says to return the function value in memory, just as large
-+   structures are always returned.  Here TYPE will be a C expression
-+   of type `tree', representing the data type of the value.
-+
-+   Note that values of mode `BLKmode' must be explicitly handled by
-+   this macro.  Also, the option `-fpcc-struct-return' takes effect
-+   regardless of this macro.  On most systems, it is possible to
-+   leave the macro undefined; this causes a default definition to be
-+   used, whose value is the constant 1 for `BLKmode' values, and 0
-+   otherwise.
-+
-+   Do not use this macro to indicate that structures and unions
-+   should always be returned in memory.  You should instead use
-+   `DEFAULT_PCC_STRUCT_RETURN' to indicate this.  */
-+
-+#define DEFAULT_PCC_STRUCT_RETURN 0
-+/* Define this macro to be 1 if all structure and union return values
-+   must be in memory.  Since this results in slower code, this should
-+   be defined only if needed for compatibility with other compilers
-+   or with an ABI.  If you define this macro to be 0, then the
-+   conventions used for structure and union return values are decided
-+   by the `RETURN_IN_MEMORY' macro.
-+
-+   If not defined, this defaults to the value 1.  */
-+
-+#define STRUCT_VALUE 0
-+/* If the structure value address is not passed in a register, define
-+   `STRUCT_VALUE' as an expression returning an RTX for the place
-+   where the address is passed.  If it returns 0, the address is
-+   passed as an "invisible" first argument.  */
-+
-+#define STRUCT_VALUE_INCOMING 0
-+/* If the incoming location is not a register, then you should define
-+   `STRUCT_VALUE_INCOMING' as an expression for an RTX for where the
-+   called function should find the value.  If it should find the
-+   value on the stack, define this to create a `mem' which refers to
-+   the frame pointer.  A definition of 0 means that the address is
-+   passed as an "invisible" first argument.  */
-+
-+#define STRICT_ARGUMENT_NAMING 1
-+/* Define this macro if the location where a function argument is
-+   passed depends on whether or not it is a named argument.
-+
-+   This macro controls how the NAMED argument to `FUNCTION_ARG' is
-+   set for varargs and stdarg functions.  With this macro defined,
-+   the NAMED argument is always true for named arguments, and false
-+   for unnamed arguments.  If this is not defined, but
-+   `SETUP_INCOMING_VARARGS' is defined, then all arguments are
-+   treated as named.  Otherwise, all named arguments except the last
-+   are treated as named.  */
-+
-+
-+/*
-+#define HAVE_PRE_INCREMENT    1
-+*/
-+
-+#define HAVE_POST_INCREMENT   1
-+
-+/*
-+#define HAVE_PRE_DECREMENT    1
-+#define HAVE_PRE_INCREMENT    1
-+#define HAVE_POST_DECREMENT   1  
-+*/
-+/* Similar for other kinds of addressing.  */
-+
-+#define CONSTANT_ADDRESS_P(X) CONSTANT_P (X)
-+
-+/*
-+(GET_CODE (X) == LABEL_REF    \
-+|| GET_CODE (X) == SYMBOL_REF   \
-+|| GET_CODE (X) == CONST_INT    \
-+|| GET_CODE (X) == CONST)
-+*/
-+
-+/*
-+#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
-+do{CODE = msp430_canonicalize_comparison(CODE, &OP0, &OP1); }while(0)
-+*/
-+
-+/* A C expression that is 1 if the RTX X is a constant which is a
-+   valid address.  On most machines, this can be defined as
-+   `CONSTANT_P (X)', but a few machines are more restrictive in which
-+   constant addresses are supported.
-+
-+   `CONSTANT_P' accepts integer-values expressions whose values are
-+   not explicitly known, such as `symbol_ref', `label_ref', and
-+   `high' expressions and `const' arithmetic expressions, in addition
-+   to `const_int' and `const_double' expressions.  */
-+
-+#define MAX_REGS_PER_ADDRESS 1
-+/* A number, the maximum number of registers that can appear in a
-+   valid memory address.  Note that it is up to you to specify a
-+   value equal to the maximum number that `GO_IF_LEGITIMATE_ADDRESS'
-+   would ever accept.  */
-+
-+#ifdef REG_OK_STRICT
-+#  define GO_IF_LEGITIMATE_ADDRESS(mode, operand, ADDR)       \
-+{                                                     \
-+  if (legitimate_address_p (mode, operand, 1))                \
-+    goto ADDR;                                                \
-+}
-+#  else
-+#  define GO_IF_LEGITIMATE_ADDRESS(mode, operand, ADDR)       \
-+{                                                     \
-+  if (legitimate_address_p (mode, operand, 0))                \
-+    goto ADDR;                                                \
-+}
-+#endif
-+/* A C compound statement with a conditional `goto LABEL;' executed
-+   if X (an RTX) is a legitimate memory address on the target machine
-+   for a memory operand of mode MODE.
-+
-+   It usually pays to define several simpler macros to serve as
-+   subroutines for this one.  Otherwise it may be too complicated to
-+   understand.
-+
-+   This macro must exist in two variants: a strict variant and a
-+   non-strict one.  The strict variant is used in the reload pass.  It
-+   must be defined so that any pseudo-register that has not been
-+   allocated a hard register is considered a memory reference.  In
-+   contexts where some kind of register is required, a pseudo-register
-+   with no hard register must be rejected.
-+
-+   The non-strict variant is used in other passes.  It must be
-+   defined to accept all pseudo-registers in every context where some
-+   kind of register is required.
-+
-+   Compiler source files that want to use the strict variant of this
-+   macro define the macro `REG_OK_STRICT'.  You should use an `#ifdef
-+   REG_OK_STRICT' conditional to define the strict variant in that
-+   case and the non-strict variant otherwise.
-+
-+   Subroutines to check for acceptable registers for various purposes
-+   (one for base registers, one for index registers, and so on) are
-+   typically among the subroutines used to define
-+   `GO_IF_LEGITIMATE_ADDRESS'.  Then only these subroutine macros
-+   need have two variants; the higher levels of macros may be the
-+   same whether strict or not.
-+
-+   Normally, constant addresses which are the sum of a `symbol_ref'
-+   and an integer are stored inside a `const' RTX to mark them as
-+   constant.  Therefore, there is no need to recognize such sums
-+   specifically as legitimate addresses.  Normally you would simply
-+   recognize any `const' as legitimate.
-+
-+   Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant
-+   sums that are not marked with  `const'.  It assumes that a naked
-+   `plus' indicates indexing.  If so, then you *must* reject such
-+   naked constant sums as illegitimate addresses, so that none of
-+   them will be given to `PRINT_OPERAND_ADDRESS'.
-+
-+   On some machines, whether a symbolic address is legitimate depends
-+   on the section that the address refers to.  On these machines,
-+   define the macro `ENCODE_SECTION_INFO' to store the information
-+   into the `symbol_ref', and then check for it here.  When you see a
-+   `const', you will have to look inside it to find the `symbol_ref'
-+   in order to determine the section.  *Note Assembler Format::.
-+
-+   The best way to modify the name string is by adding text to the
-+   beginning, with suitable punctuation to prevent any ambiguity.
-+   Allocate the new name in `saveable_obstack'.  You will have to
-+   modify `ASM_OUTPUT_LABELREF' to remove and decode the added text
-+   and output the name accordingly, and define `STRIP_NAME_ENCODING'
-+   to access the original name string.
-+
-+   You can check the information stored here into the `symbol_ref' in
-+   the definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
-+   `PRINT_OPERAND_ADDRESS'. */
-+
-+/* `REG_OK_FOR_BASE_P (X)'
-+   A C expression that is nonzero if X (assumed to be a `reg' RTX) is
-+   valid for use as a base register.  For hard registers, it should
-+   always accept those which the hardware permits and reject the
-+   others.  Whether the macro accepts or rejects pseudo registers
-+   must be controlled by `REG_OK_STRICT' as described above.  This
-+   usually requires two variant definitions, of which `REG_OK_STRICT'
-+   controls the one actually used.  */
-+
-+#define REG_OK_FOR_BASE_NOSTRICT_P(X) \
-+  (REGNO (X) >= FIRST_PSEUDO_REGISTER || REG_OK_FOR_BASE_STRICT_P(X))
-+
-+#define REG_OK_FOR_BASE_STRICT_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
-+
-+#ifdef REG_OK_STRICT
-+#  define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_STRICT_P (X)
-+#else
-+#  define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_NOSTRICT_P (X)
-+#endif
-+
-+/* A C expression that is just like `REG_OK_FOR_BASE_P', except that
-+   that expression may examine the mode of the memory reference in
-+   MODE.  You should define this macro if the mode of the memory
-+   reference affects whether a register may be used as a base
-+   register.  If you define this macro, the compiler will use it
-+   instead of `REG_OK_FOR_BASE_P'.  */
-+
-+
-+#define REG_OK_FOR_INDEX_P(X) 0 /*( REGNO(X)!=3 && REGNO(X)!=2 &&REGNO(X)<=15) */
-+/*   A C expression that is nonzero if X (assumed to be a `reg' RTX) is
-+   valid for use as an index register.
-+
-+   The difference between an index register and a base register is
-+   that the index register may be scaled.  If an address involves the
-+   sum of two registers, neither one of them scaled, then either one
-+   may be labeled the "base" and the other the "index"; but whichever
-+   labeling is used must fit the machine's constraints of which
-+   registers may serve in each capacity.  The compiler will try both
-+   labelings, looking for one that is valid, and will reload one or
-+   both registers only if neither labeling works.  */
-+
-+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)                                \
-+GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN)
-+
-+/*{                                                                   \
-+                                                                      \
-+  (X) = legitimize_address (X, OLDX, MODE);                           \
-+  if (memory_address_p (MODE, X))                                     \
-+    goto WIN;                                                         \
-+                                                                      \
-+} */
-+
-+/* A C compound statement that attempts to replace X with a valid
-+   memory address for an operand of mode MODE.  WIN will be a C
-+   statement label elsewhere in the code; the macro definition may use
-+
-+   GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN);
-+
-+   to avoid further processing if the address has become legitimate.
-+
-+   X will always be the result of a call to `break_out_memory_refs',
-+   and OLDX will be the operand that was given to that function to
-+   produce X.
-+
-+   The code generated by this macro should not alter the substructure
-+   of X.  If it transforms X into a more legitimate form, it should
-+   assign X (which will always be a C variable) a new value.
-+
-+   It is not necessary for this macro to come up with a legitimate
-+   address.  The compiler has standard ways of doing so in all cases.
-+   In fact, it is safe for this macro to do nothing.  But often a
-+   machine-dependent strategy can generate better code.  */
-+
-+/* A C compound statement that attempts to replace X, which is an
-+   address that needs reloading, with a valid memory address for an
-+   operand of mode MODE.  WIN will be a C statement label elsewhere
-+   in the code.  It is not necessary to define this macro, but it
-+   might be useful for performance reasons.
-+
-+   For example, on the i386, it is sometimes possible to use a single
-+   reload register instead of two by reloading a sum of two pseudo
-+   registers into a register.  On the other hand, for number of RISC
-+   processors offsets are limited so that often an intermediate
-+   address needs to be generated in order to address a stack slot.
-+   By defining LEGITIMIZE_RELOAD_ADDRESS appropriately, the
-+   intermediate addresses generated for adjacent some stack slots can
-+   be made identical, and thus be shared.
-+
-+   *Note*: This macro should be used with caution.  It is necessary
-+   to know something of how reload works in order to effectively use
-+   this, and it is quite easy to produce macros that build in too
-+   much knowledge of reload internals.
-+
-+   *Note*: This macro must be able to reload an address created by a
-+   previous invocation of this macro.  If it fails to handle such
-+   addresses then the compiler may generate incorrect code or abort.
-+
-+   The macro definition should use `push_reload' to indicate parts
-+   that need reloading; OPNUM, TYPE and IND_LEVELS are usually
-+   suitable to be passed unaltered to `push_reload'.
-+
-+   The code generated by this macro must not alter the substructure of
-+   X.  If it transforms X into a more legitimate form, it should
-+   assign X (which will always be a C variable) a new value.  This
-+   also applies to parts that you change indirectly by calling
-+   `push_reload'.
-+
-+   The macro definition may use `strict_memory_address_p' to test if
-+   the address has become legitimate.
-+
-+   If you want to change only a part of X, one standard way of doing
-+   this is to use `copy_rtx'.  Note, however, that is unshares only a
-+   single level of rtl.  Thus, if the part to be changed is not at the
-+   top level, you'll need to replace first the top leve It is not
-+   necessary for this macro to come up with a legitimate address;
-+   but often a machine-dependent strategy can generate better code.  */
-+      
-+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)                      \
-+{}
-+/* A C statement or compound statement with a conditional `goto
-+   LABEL;' executed if memory address X (an RTX) can have different
-+   meanings depending on the machine mode of the memory reference it
-+   is used for or if the address is valid for some modes but not
-+   others.
-+
-+   Autoincrement and autodecrement addresses typically have
-+   mode-dependent effects because the amount of the increment or
-+   decrement is the size of the operand being addressed.  Some
-+   machines have other mode-dependent addresses.  Many RISC machines
-+   have no mode-dependent addresses.
-+
-+   You may assume that ADDR is a valid address for the machine.  */
-+
-+#define LEGITIMATE_CONSTANT_P(X) 1
-+/* A C expression that is nonzero if X is a legitimate constant for
-+   an immediate operand on the target machine.  You can assume that X
-+   satisfies `CONSTANT_P', so you need not check this.  In fact, `1'
-+   is a suitable definition for this macro on machines where anything
-+   `CONSTANT_P' is valid.  */
-+
-+#define CONST_COSTS(x,CODE,OUTER_CODE)                \
-+    case CONST_INT:                           \
-+      if (OUTER_CODE == PLUS                  \
-+        || OUTER_CODE == IOR                  \
-+        || OUTER_CODE == AND                  \
-+        || OUTER_CODE == MINUS                \
-+        || OUTER_CODE == SET                  \
-+        || INTVAL (x) == 0                    \
-+          || INTVAL (x) == 1                  \
-+          || INTVAL (x) == 2                  \
-+          || INTVAL (x) == 4                  \
-+          || INTVAL (x) == 8                  \
-+          || INTVAL (x) == -1)                        \
-+        return 0;                             \
-+    case CONST:                                       \
-+      return 0;                                       \
-+    case LABEL_REF:                           \
-+      return 1;                                       \
-+    case SYMBOL_REF:                          \
-+      return 2;                                       \
-+    case CONST_DOUBLE:                                \
-+      return 4;
-+
-+/* A part of a C `switch' statement that describes the relative costs
-+   of constant RTL expressions.  It must contain `case' labels for
-+   expression codes `const_int', `const', `symbol_ref', `label_ref'
-+   and `const_double'.  Each case must ultimately reach a `return'
-+   statement to return the relative cost of the use of that kind of
-+   constant value in an expression.  The cost may depend on the
-+   precise value of the constant, which is available for examination
-+   in X, and the rtx code of the expression in which it is contained,
-+   found in OUTER_CODE.
-+
-+   CODE is the expression code--redundant, since it can be obtained
-+   with `GET_CODE (X)'.  */
-+
-+#define DEFAULT_RTX_COSTS(x, code, outer_code)                \
-+{                                                     \
-+  int cst = default_rtx_costs (x, code, outer_code);  \
-+  if (cst>0)                                          \
-+    return cst;                                       \
-+  else if (cst<0)                                     \
-+    total += -cst;                                    \
-+  break;                                              \
-+}
-+
-+/* Like `CONST_COSTS' but applies to nonconstant RTL expressions.
-+   This can be used, for example, to indicate how costly a multiply
-+   instruction is.  In writing this macro, you can use the construct
-+   `COSTS_N_INSNS (N)' to specify a cost equal to N fast
-+   instructions.  OUTER_CODE is the code of the expression in which X
-+   is contained.
-+
-+   This macro is optional; do not define it if the default cost
-+   assumptions are adequate for the target machine.  */
-+
-+#define ADDRESS_COST(ADDRESS) 2
-+
-+/* An expression giving the cost of an addressing mode that contains
-+   ADDRESS.  If not defined, the cost is computed from the ADDRESS
-+   expression and the `CONST_COSTS' values.
-+
-+   For most CISC machines, the default cost is a good approximation
-+   of the true cost of the addressing mode.  However, on RISC
-+   machines, all instructions normally have the same length and
-+   execution time.  Hence all addresses will have equal costs.
-+
-+   In cases where more than one form of an address is known, the form
-+   with the lowest cost will be used.  If multiple forms have the
-+   same, lowest, cost, the one that is the most complex will be used.
-+
-+   For example, suppose an address that is equal to the sum of a
-+   register and a constant is used twice in the same basic block.
-+   When this macro is not defined, the address will be computed in a
-+   register and memory references will be indirect through that
-+   register.  On machines where the cost of the addressing mode
-+   containing the sum is no higher than that of a simple indirect
-+   reference, this will produce an additional instruction and
-+   possibly require an additional register.  Proper specification of
-+   this macro eliminates this overhead for such machines.
-+
-+   Similar use of this macro is made in strength reduction of loops.
-+
-+   ADDRESS need not be valid as an address.  In such a case, the cost
-+   is not relevant and can be any value; invalid addresses need not be
-+   assigned a different cost.
-+
-+   On machines where an address involving more than one register is as
-+   cheap as an address computation involving only one register,
-+   defining `ADDRESS_COST' to reflect this can cause two registers to
-+   be live over a region of code where only one would have been if
-+   `ADDRESS_COST' were not defined in that manner.  This effect should
-+   be considered in the definition of this macro.  Equivalent costs
-+   should probably only be given to addresses with different numbers
-+   of registers on machines with lots of registers.
-+
-+   This macro will normally either not be defined or be defined as a
-+   constant.  */
-+
-+#define REGISTER_MOVE_COST(MODE, FROM, TO) ((MODE)==QImode ? 1 :   \
-+                                          (MODE)==HImode ? 1 :   \
-+                                          (MODE)==SImode ? 2 :   \
-+                                          (MODE)==SFmode ? 2 : 4)
-+
-+/* A C expression for the cost of moving data from a register in class
-+   FROM to one in class TO.  The classes are expressed using the
-+   enumeration values such as `GENERAL_REGS'.  A value of 2 is the
-+   default; other values are interpreted relative to that.
-+
-+   It is not required that the cost always equal 2 when FROM is the
-+   same as TO; on some machines it is expensive to move between
-+   registers if they are not general registers.
-+
-+   If reload sees an insn consisting of a single `set' between two
-+   hard registers, and if `REGISTER_MOVE_COST' applied to their
-+   classes returns a value of 2, reload does not check to ensure that
-+   the constraints of the insn are met.  Setting a cost of other than
-+   2 will allow reload to verify that the constraints are met.  You
-+   should do this if the `movM' pattern's constraints do not allow
-+   such copying.  */
-+
-+#define MEMORY_MOVE_COST(MODE,CLASS,IN) ((MODE)==QImode ? 2 : \
-+                                       (MODE)==HImode ? 2 :   \
-+                                       (MODE)==SImode ? 4 :   \
-+                                       (MODE)==SFmode ? 4 : 8)
-+/* A C expression for the cost of moving data of mode M between a
-+   register and memory.  A value of 4 is the default; this cost is
-+   relative to those in `REGISTER_MOVE_COST'.
-+
-+   If moving between registers and memory is more expensive than
-+   between two registers, you should define this macro to express the
-+   relative cost.  */
-+
-+#define BRANCH_COST 0
-+/* A C expression for the cost of a branch instruction.  A value of 1
-+   is the default; other values are interpreted relative to that.
-+
-+   Here are additional macros which do not specify precise relative
-+   costs, but only that certain actions are more expensive than GCC would
-+   ordinarily expect.  */
-+
-+#define SLOW_BYTE_ACCESS 0
-+/* Define this macro as a C expression which is nonzero if accessing
-+   less than a word of memory (i.e. a `char' or a `short') is no
-+   faster than accessing a word of memory, i.e., if such access
-+   require more than one instruction or if there is no difference in
-+   cost between byte and (aligned) word loads.
-+
-+   When this macro is not defined, the compiler will access a field by
-+   finding the smallest containing object; when it is defined, a
-+   fullword load will be used if alignment permits.  Unless bytes
-+   accesses are faster than word accesses, using word accesses is
-+   preferable since it may eliminate subsequent memory access if
-+   subsequent accesses occur to other fields in the same word of the
-+   structure, but to different bytes.
-+
-+   `SLOW_ZERO_EXTEND'
-+   Define this macro if zero-extension (of a `char' or `short' to an
-+   `int') can be done faster if the destination is a register that is
-+   known to be zero.
-+
-+   If you define this macro, you must have instruction patterns that
-+   recognize RTL structures like this:
-+
-+   (set (strict_low_part (subreg:QI (reg:SI ...) 0)) ...)
-+
-+   and likewise for `HImode'.
-+
-+   `SLOW_UNALIGNED_ACCESS'
-+   Define this macro to be the value 1 if unaligned accesses have a
-+   cost many times greater than aligned accesses, for example if they
-+   are emulated in a trap handler.
-+
-+   When this macro is non-zero, the compiler will act as if
-+   `STRICT_ALIGNMENT' were non-zero when generating code for block
-+   moves.  This can cause significantly more instructions to be
-+   produced.  Therefore, do not set this macro non-zero if unaligned
-+   accesses only add a cycle or two to the time for a memory access.
-+
-+   If the value of this macro is always zero, it need not be defined.
-+
-+   `DONT_REDUCE_ADDR'
-+   Define this macro to inhibit strength reduction of memory
-+   addresses.  (On some machines, such strength reduction seems to do
-+   harm rather than good.)
-+
-+   `MOVE_RATIO'
-+   The number of scalar move insns which should be generated instead
-+   of a string move insn or a library call.  Increasing the value
-+   will always make code faster, but eventually incurs high cost in
-+   increased code size.
-+
-+   If you don't define this, a reasonable default is used.  */
-+
-+#define NO_FUNCTION_CSE
-+/* Define this macro if it is as good or better to call a constant
-+   function address than to call an address kept in a register.  */
-+
-+#define NO_RECURSIVE_FUNCTION_CSE
-+/* Define this macro if it is as good or better for a function to call
-+   itself with an explicit address than to call an address kept in a
-+   register.
-+
-+   `ADJUST_COST (INSN, LINK, DEP_INSN, COST)'
-+   A C statement (sans semicolon) to update the integer variable COST
-+   based on the relationship between INSN that is dependent on
-+   DEP_INSN through the dependence LINK.  The default is to make no
-+   adjustment to COST.  This can be used for example to specify to
-+   the scheduler that an output- or anti-dependence does not incur
-+   the same cost as a data-dependence.
-+
-+   `ADJUST_PRIORITY (INSN)'
-+   A C statement (sans semicolon) to update the integer scheduling
-+   priority `INSN_PRIORITY(INSN)'.  Reduce the priority to execute
-+   the INSN earlier, increase the priority to execute INSN later.
-+   Do not define this macro if you do not need to adjust the
-+   scheduling priorities of insns.  */
-+
-+
-+#define TEXT_SECTION_ASM_OP "\t.text"
-+/* A C expression whose value is a string containing the assembler
-+   operation that should precede instructions and read-only data.
-+   Normally `"\t.text"' is right.  */
-+
-+#define DATA_SECTION_ASM_OP "\t.data"
-+/* A C expression whose value is a string containing the assembler
-+   operation to identify the following data as writable initialized
-+   data.  Normally `"\t.data"' is right.  */
-+
-+#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
-+
-+#define EXTRA_SECTIONS in_bootloader, in_infomem
-+/* A list of names for sections other than the standard two, which are
-+   `in_text' and `in_data'.  You need not define this macro on a
-+   system with no other sections (that GCC needs to use).  */
-+
-+#define EXTRA_SECTION_FUNCTIONS                                                     \
-+                                                                            \
-+void                                                                        \
-+bootloader_section (void)                                                     \
-+{                                                                           \
-+  if (in_section != in_bootloader)                                            \
-+    {                                                                       \
-+      fprintf (asm_out_file,                                                \
-+             "\t.section .bootloader, \"ax\", @progbits\n");                  \
-+      /* Should already be aligned, this is just to be safe if it isn't.  */  \
-+      fprintf (asm_out_file, "\t.p2align 1\n");                                     \
-+      in_section = in_bootloader;                                             \
-+    }                                                                       \
-+}                                                                             \
-+                                                                            \
-+void                                                                        \
-+infomem_section (void)                                                              \
-+{                                                                           \
-+  if (in_section != in_infomem)                                                     \
-+    {                                                                       \
-+      fprintf (asm_out_file,                                                \
-+             "\t.section .infomem, \"a\", @progbits\n");                      \
-+      /* Should already be aligned, this is just to be safe if it isn't.  */  \
-+      fprintf (asm_out_file, "\t.p2align 1\n");                                     \
-+      in_section = in_infomem;                                                      \
-+    }                                                                       \
-+}
-+
-+
-+/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
-+   There are no shared libraries on this target, and these sections are
-+   placed in the read-only program memory, so they are not writable.  */
-+
-+#undef CTORS_SECTION_ASM_OP
-+#define CTORS_SECTION_ASM_OP "\t.global\t__do_global_ctors\n\t.section .ctors,\"a\",@progbits"
-+
-+#undef DTORS_SECTION_ASM_OP
-+#define DTORS_SECTION_ASM_OP "\t.global\t__do_global_dtors\n\t.section .dtors,\"a\",@progbits"
-+
-+#define TARGET_ASM_CONSTRUCTOR default_ctor_section_asm_out_constructor
-+
-+#define TARGET_ASM_DESTRUCTOR default_dtor_section_asm_out_destructor
-+
-+/* `EXTRA_SECTION_FUNCTIONS'
-+   One or more functions to be defined in `varasm.c'.  These
-+   functions should do jobs analogous to those of `text_section' and
-+   `data_section', for your additional sections.  Do not define this
-+   macro if you do not define `EXTRA_SECTIONS'.  */
-+
-+/*
-+#define READONLY_DATA_SECTION data_section
-+   On most machines, read-only variables, constants, and jump tables
-+   are placed in the text section.  If this is not the case on your
-+   machine, this macro should be defined to be the name of a function
-+   (either `data_section' or a function defined in `EXTRA_SECTIONS')
-+   that switches to the section to be used for read-only items.
-+
-+   If these items should be placed in the text section, this macro
-+   should not be defined.  */
-+
-+/* `SELECT_SECTION (EXP, RELOC)'
-+   A C statement or statements to switch to the appropriate section
-+   for output of EXP.  You can assume that EXP is either a `VAR_DECL'
-+   node or a constant of some sort.  RELOC indicates whether the
-+   initial value of EXP requires link-time relocations.  Select the
-+   section by calling `text_section' or one of the alternatives for
-+   other sections.
-+
-+   Do not define this macro if you put all read-only variables and
-+   constants in the read-only data section (usually the text section).  */
-+
-+/* `SELECT_RTX_SECTION (MODE, RTX)'
-+   A C statement or statements to switch to the appropriate section
-+   for output of RTX in mode MODE.  You can assume that RTX is some
-+   kind of constant in RTL.  The argument MODE is redundant except in
-+   the case of a `const_int' rtx.  Select the section by calling
-+   `text_section' or one of the alternatives for other sections.
-+
-+   Do not define this macro if you put all constants in the read-only
-+   data section.  */
-+
-+#define JUMP_TABLES_IN_TEXT_SECTION 0
-+/* Define this macro if jump tables (for `tablejump' insns) should be
-+   output in the text section, along with the assembler instructions.
-+   Otherwise, the readonly data section is used.
-+
-+   This macro is irrelevant if there is no separate readonly data
-+   section.  */
-+
-+/* ???? 
-+#define ENCODE_SECTION_INFO(DECL)  encode_section_info(DECL)
-+   Define this macro if references to a symbol must be treated
-+   differently depending on something about the variable or function
-+   named by the symbol (such as what section it is in).
-+
-+   The macro definition, if any, is executed immediately after the
-+   rtl for DECL has been created and stored in `DECL_RTL (DECL)'.
-+   The value of the rtl will be a `mem' whose address is a
-+   `symbol_ref'.
-+
-+   The usual thing for this macro to do is to record a flag in the
-+   `symbol_ref' (such as `SYMBOL_REF_FLAG') or to store a modified
-+   name string in the `symbol_ref' (if one bit is not enough
-+   information).  */
-+
-+
-+#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
-+  (VAR) = (SYMBOL_NAME) + ((SYMBOL_NAME)[0] == '*' || (SYMBOL_NAME)[0] == '@');
-+/* `STRIP_NAME_ENCODING (VAR, SYM_NAME)'
-+   Decode SYM_NAME and store the real name part in VAR, sans the
-+   characters that encode section info.  Define this macro if
-+   `ENCODE_SECTION_INFO' alters the symbol's name string.  */
-+/* `UNIQUE_SECTION_P (DECL)'
-+   A C expression which evaluates to true if DECL should be placed
-+   into a unique section for some target-specific reason.  If you do
-+   not define this macro, the default is `0'.  Note that the flag
-+   `-ffunction-sections' will also cause functions to be placed into
-+   unique sections.  */
-+
-+#define UNIQUE_SECTION(DECL, RELOC) unique_section (DECL, RELOC)
-+/* `UNIQUE_SECTION (DECL, RELOC)'
-+   A C statement to build up a unique section name, expressed as a
-+   STRING_CST node, and assign it to `DECL_SECTION_NAME (DECL)'.
-+   RELOC indicates whether the initial value of EXP requires
-+   link-time relocations.  If you do not define this macro, GNU CC
-+   will use the symbol name prefixed by `.' as the section name.  */
-+
-+
-+#define ASM_FILE_START(STREAM) asm_file_start (STREAM)
-+/* A C expression which outputs to the stdio stream STREAM some
-+   appropriate text to go at the start of an assembler file.
-+
-+   Normally this macro is defined to output a line containing
-+   `#NO_APP', which is a comment that has no effect on most
-+   assemblers but tells the GNU assembler that it can save time by not
-+   checking for certain assembler constructs.
-+
-+   On systems that use SDB, it is necessary to output certain
-+   commands; see `attasm.h'.  */
-+
-+#define ASM_FILE_END(STREAM) asm_file_end (STREAM)
-+/* A C expression which outputs to the stdio stream STREAM some
-+   appropriate text to go at the end of an assembler file.
-+
-+   If this macro is not defined, the default is to output nothing
-+   special at the end of the file.  Most systems don't require any
-+   definition.
-+
-+   On systems that use SDB, it is necessary to output certain
-+   commands; see `attasm.h'.  */
-+
-+#define ASM_COMMENT_START " ; "
-+/* A C string constant describing how to begin a comment in the target
-+   assembler language.  The compiler assumes that the comment will
-+   end at the end of the line.  */
-+
-+#define ASM_APP_ON "/* #APP */\n"
-+/* A C string constant for text to be output before each `asm'
-+   statement or group of consecutive ones.  Normally this is
-+   `"#APP"', which is a comment that has no effect on most assemblers
-+   but tells the GNU assembler that it must check the lines that
-+   follow for all valid assembler constructs.  */
-+
-+#define ASM_APP_OFF "/* #NOAPP */\n"
-+/* A C string constant for text to be output after each `asm'
-+   statement or group of consecutive ones.  Normally this is
-+   `"#NO_APP"', which tells the GNU assembler to resume making the
-+   time-saving assumptions that are valid for ordinary compiler
-+   output.  */
-+
-+#define ASM_OUTPUT_SOURCE_LINE(STREAM, LINE) fprintf (STREAM,"/* line: %d */\n",LINE)
-+/* A C statement to output DBX or SDB debugging information before
-+   code for line number LINE of the current source file to the stdio
-+   stream STREAM.
-+
-+   This macro need not be defined if the standard form of debugging
-+   information for the debugger in use is appropriate.  */
-+
-+#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
-+  asm_output_section_name(FILE, DECL, NAME, RELOC)
-+
-+/* `ASM_OUTPUT_SECTION_NAME (STREAM, DECL, NAME, RELOC)'
-+   A C statement to output something to the assembler file to switch
-+   to section NAME for object DECL which is either a `FUNCTION_DECL',
-+   a `VAR_DECL' or `NULL_TREE'.  RELOC indicates whether the initial
-+   value of EXP requires link-time relocations.  Some target formats
-+   do not support arbitrary sections.  Do not define this macro in
-+   such cases.
-+
-+   At present this macro is only used to support section attributes.
-+   When this macro is undefined, section attributes are disabled.  */
-+
-+#define OBJC_PROLOGUE {}
-+/* A C statement to output any assembler statements which are
-+   required to precede any Objective C object definitions or message
-+   sending.  The statement is executed only when compiling an
-+   Objective C program.  */
-+
-+
-+
-+#define ASM_OUTPUT_DOUBLE(STREAM, VALUE) fprintf (STREAM, "no double float %.20e\n", VALUE)
-+#define ASM_OUTPUT_FLOAT(STREAM, VALUE) asm_output_float (STREAM, VALUE)
-+/* `ASM_OUTPUT_LONG_DOUBLE (STREAM, VALUE)'
-+   `ASM_OUTPUT_THREE_QUARTER_FLOAT (STREAM, VALUE)'
-+   `ASM_OUTPUT_SHORT_FLOAT (STREAM, VALUE)'
-+   `ASM_OUTPUT_BYTE_FLOAT (STREAM, VALUE)'
-+   A C statement to output to the stdio stream STREAM an assembler
-+   instruction to assemble a floating-point constant of `TFmode',
-+   `DFmode', `SFmode', `TQFmode', `HFmode', or `QFmode',
-+   respectively, whose value is VALUE.  VALUE will be a C expression
-+   of type `REAL_VALUE_TYPE'.  Macros such as
-+   `REAL_VALUE_TO_TARGET_DOUBLE' are useful for writing these
-+   definitions.  */
-+
-+
-+#define ASM_OUTPUT_INT(FILE, VALUE)                   \
-+ ( fprintf (FILE, "\t.long "),                                \
-+   output_addr_const (FILE, (VALUE)),                 \
-+   fputs ("\n", FILE))
-+
-+ /* Likewise for `short' and `char' constants.   */
-+
-+#define ASM_OUTPUT_SHORT(FILE,VALUE) asm_output_short(FILE,VALUE)
-+#define ASM_OUTPUT_CHAR(FILE,VALUE) asm_output_char(FILE,VALUE)
-+
-+/* `ASM_OUTPUT_QUADRUPLE_INT (STREAM, EXP)'
-+   A C statement to output to the stdio stream STREAM an assembler
-+   instruction to assemble an integer of 16, 8, 4, 2 or 1 bytes,
-+   respectively, whose value is VALUE.  The argument EXP will be an
-+   RTL expression which represents a constant value.  Use
-+   `output_addr_const (STREAM, EXP)' to output this value as an
-+   assembler expression.
-+
-+   For sizes larger than `UNITS_PER_WORD', if the action of a macro
-+   would be identical to repeatedly calling the macro corresponding to
-+   a size of `UNITS_PER_WORD', once for each word, you need not define
-+   the macro.  */
-+
-+
-+#define ASM_OUTPUT_BYTE(FILE,VALUE) asm_output_byte (FILE,VALUE)
-+/* A C statement to output to the stdio stream STREAM an assembler
-+   instruction to assemble a single byte containing the number VALUE.  */
-+
-+#define ASM_BYTE_OP "\t.byte "
-+/* A C string constant giving the pseudo-op to use for a sequence of
-+   single-byte constants.  If this macro is not defined, the default
-+   is `"\t.byte\t"'.  */
-+
-+#define ASM_OUTPUT_ASCII(FILE, P, SIZE)        gas_output_ascii (FILE,P,SIZE)
-+/* `ASM_OUTPUT_ASCII (STREAM, PTR, LEN)'
-+   output_ascii (FILE, P, SIZE)
-+   A C statement to output to the stdio stream STREAM an assembler
-+   instruction to assemble a string constant containing the LEN bytes
-+   at PTR.  PTR will be a C expression of type `char *' and LEN a C
-+   expression of type `int'.
-+
-+   If the assembler has a `.ascii' pseudo-op as found in the Berkeley
-+   Unix assembler, do not define the macro `ASM_OUTPUT_ASCII'.  */
-+
-+#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == '\n')
-+/* Define this macro as a C expression which is nonzero if C is used
-+   as a logical line separator by the assembler.
-+
-+   If you do not define this macro, the default is that only the
-+   character `;' is treated as a logical line separator.  */
-+
-+/*
-+#define ASM_OPEN_PAREN "("
-+#define ASM_CLOSE_PAREN ")"
-+ These macros are defined as C string constant, describing the
-+   syntax in the assembler for grouping arithmetic expressions.  The
-+   following definitions are correct for most assemblers:
-+
-+   #define ASM_OPEN_PAREN "("
-+   #define ASM_CLOSE_PAREN ")"
-+
-+   These macros are provided by `real.h' for writing the definitions of
-+   `ASM_OUTPUT_DOUBLE' and the like:  */
-+
-+/* Here we much catch r0 - r15  variable names */
-+
-+#define ASM_OUTPUT_LABELREF(FILE,NAME)                        \
-+do{                                                   \
-+      char *p = NAME;                                 \
-+      while(*p == '_') p++;                           \
-+      if(*p == 'r' || *p == 'R')                      \
-+      {                                               \
-+          int val;                                    \
-+          char *endptr;                               \
-+          p++;                                        \
-+          val = strtol (p, &endptr, 10);              \
-+          if(val >= 0 && val <= 15 &&                 \
-+              *endptr == 0 )                          \
-+          {                                           \
-+              asm_fprintf ((FILE), "_%U%s", (NAME));  \
-+          }                                           \
-+          else                                        \
-+              asm_fprintf ((FILE), "%U%s", (NAME));   \
-+      }                                               \
-+      else                                            \
-+              asm_fprintf ((FILE), "%U%s", (NAME));   \
-+} while(0)
-+
-+/* macros to output uninitialized variable definitions */
-+
-+/* Return a non-zero value if DECL has a section attribute.  */
-+#define IN_NAMED_SECTION(DECL)                                           \
-+  ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL)    \
-+   && DECL_SECTION_NAME (DECL) != NULL_TREE)
-+
-+/* macro to output uninitialized varible in normal case where -fno-common is not specified */
-+ 
-+#undef  ASM_OUTPUT_ALIGNED_DECL_COMMON
-+#define ASM_OUTPUT_ALIGNED_DECL_COMMON(FILE, DECL, NAME, SIZE, ALIGN)   \
-+  do                                                                    \
-+    {                                                                   \
-+      char *p = NAME;                                                   \
-+      if(*p == '*' || *p == '@' ) p++;                                  \
-+      if(*p >= '0' && *p <= '9' ) break;                                \
-+      if (IN_NAMED_SECTION (DECL))                                      \
-+        {                                                               \
-+          /* case where -fdata-sections is specified */                 \
-+          named_section (DECL, NULL, 0);                                \
-+          ASM_GLOBALIZE_LABEL (FILE, NAME);                             \
-+          ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));  \
-+          last_assemble_variable_decl = DECL;                           \
-+          ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL);                   \
-+          ASM_OUTPUT_SKIP (FILE, SIZE ? SIZE : 1);                      \
-+        }                                                               \
-+      else                                                              \
-+        {                                                               \
-+          /* default case */                                            \
-+          fputs ("\t.comm ", (FILE));                                   \
-+          assemble_name ((FILE), (NAME));                               \
-+          fprintf ((FILE), ",%d%s", (SIZE), (SIZE)>1?",2\n":"\n");      \
-+        }                                                               \
-+    }                                                                   \
-+  while (0)
-+
-+
-+/* macro to output uninitialized variable when -fno-common _is_ specified */
-+#undef  ASM_OUTPUT_ALIGNED_BSS
-+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN)   \
-+  do                                                                    \
-+    {                                                                   \
-+      char *p = NAME;                                                   \
-+      if(*p == '*' || *p == '@' ) p++;                                  \
-+      if(*p >= '0' && *p <= '9' ) break;                                \
-+      if (IN_NAMED_SECTION (DECL))                                      \
-+        named_section (DECL, NULL, 0);                                  \
-+      else                                                              \
-+        bss_section ();                                                 \
-+                                                                        \
-+      ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));      \
-+                                                                        \
-+      last_assemble_variable_decl = DECL;                               \
-+      ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL);                       \
-+      ASM_OUTPUT_SKIP (FILE, SIZE ? SIZE : 1);                          \
-+    }                                                                   \
-+  while (0)
-+
-+
-+#undef  ASM_OUTPUT_ALIGNED_DECL_LOCAL
-+#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN)    \
-+  do                                                                    \
-+    {                                                                   \
-+      char *p = NAME;                                                   \
-+      if(*p == '*' || *p == '@' ) p++;                                  \
-+      if(*p >= '0' && *p <= '9' ) break;                                \
-+      if ((DECL) != NULL && IN_NAMED_SECTION (DECL))                    \
-+        named_section (DECL, NULL, 0);                                  \
-+      else                                                              \
-+        bss_section ();                                                 \
-+                                                                        \
-+      ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));      \
-+      ASM_OUTPUT_LABEL (FILE, NAME);                                    \
-+      fprintf (FILE, "\t.space\t%d\n", SIZE);                           \
-+    }                                                                   \
-+  while (0)
-+
-+#define BSS_SECTION_ASM_OP    "\t.section\t.bss"
-+/* If defined, a C expression whose value is a string containing the
-+   assembler operation to identify the following data as
-+   uninitialized global data.  If not defined, and neither
-+   'ASM_OUTPUT_BSS' nor 'ASM_OUTPUT_ALIGNED_BSS' are defined,
-+   uninitialized global data will be output in the data section if
-+   -fno-common' is passed, otherwise 'ASM_OUTPUT_COMMON' will be
-+   used.
-+*/
-+
-+
-+
-+#define ASM_OUTPUT_LABEL(STREAM, NAME)                \
-+{                                             \
-+  assemble_name (STREAM, NAME);                       \
-+  fprintf (STREAM, ":\n");                    \
-+}
-+/* A C statement (sans semicolon) to output to the stdio stream
-+   STREAM the assembler definition of a label named NAME.  Use the
-+   expression `assemble_name (STREAM, NAME)' to output the name
-+   itself; before and after that, output the additional assembler
-+   syntax for defining the name, and a newline.  */
-+
-+#undef TYPE_ASM_OP
-+#undef SIZE_ASM_OP
-+#undef WEAK_ASM_OP
-+#define TYPE_ASM_OP   "\t.type\t"
-+#define SIZE_ASM_OP   "\t.size\t"
-+#define WEAK_ASM_OP   "\t.weak\t"
-+/* Define the strings used for the special svr4 .type and .size directives.
-+   These strings generally do not vary from one system running svr4 to
-+   another, but if a given system (e.g. m88k running svr) needs to use
-+   different pseudo-op names for these, they may be overridden in the
-+   file which includes this one.  */
-+
-+
-+#undef TYPE_OPERAND_FMT
-+#define TYPE_OPERAND_FMT      "@%s"
-+/* The following macro defines the format used to output the second
-+   operand of the .type assembler directive.  Different svr4 assemblers
-+   expect various different forms for this operand.  The one given here
-+   is just a default.  You may need to override it in your machine-
-+   specific tm.h file (depending upon the particulars of your assembler).  */
-+
-+
-+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
-+asm_declare_function_name (FILE, NAME, DECL)
-+
-+
-+/* A C statement (sans semicolon) to output to the stdio stream
-+   STREAM any text necessary for declaring the name NAME of a
-+   function which is being defined.  This macro is responsible for
-+   outputting the label definition (perhaps using
-+   `ASM_OUTPUT_LABEL').  The argument DECL is the `FUNCTION_DECL'
-+   tree node representing the function.
-+
-+   If this macro is not defined, then the function name is defined in
-+   the usual manner as a label (by means of `ASM_OUTPUT_LABEL').  */
-+
-+#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)                  \
-+  do {                                                                        \
-+    if (!flag_inhibit_size_directive)                                 \
-+      {                                                                       \
-+        char label[256];                                              \
-+      static int labelno;                                             \
-+      labelno++;                                                      \
-+      ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno);            \
-+      ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno);               \
-+      fprintf (FILE, "%s", SIZE_ASM_OP);                              \
-+      assemble_name (FILE, (FNAME));                                  \
-+        fprintf (FILE, ",");                                          \
-+      assemble_name (FILE, label);                                    \
-+        fprintf (FILE, "-");                                          \
-+      assemble_name (FILE, (FNAME));                                  \
-+      fprintf (FILE,"\n/********* End of function ******/\n\n");      \
-+      }                                                                       \
-+  } while (0)
-+/* A C statement (sans semicolon) to output to the stdio stream
-+   STREAM any text necessary for declaring the size of a function
-+   which is being defined.  The argument NAME is the name of the
-+   function.  The argument DECL is the `FUNCTION_DECL' tree node
-+   representing the function.
-+
-+   If this macro is not defined, then the function size is not
-+   defined.  */
-+
-+#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL)                       \
-+do {                                                                    \
-+      fprintf (FILE, "%s", TYPE_ASM_OP);                                \
-+      assemble_name (FILE, NAME);                                       \
-+      putc (',', FILE);                                                         \
-+      fprintf (FILE, TYPE_OPERAND_FMT, "object");                       \
-+      putc ('\n', FILE);                                                \
-+      size_directive_output = 0;                                        \
-+      if (!flag_inhibit_size_directive && DECL_SIZE (DECL))             \
-+      {                                                                 \
-+        size_directive_output = 1;                                      \
-+        fprintf (FILE, "%s", SIZE_ASM_OP);                              \
-+        assemble_name (FILE, NAME);                                     \
-+        fprintf (FILE, ",%d\n",  int_size_in_bytes (TREE_TYPE (DECL))); \
-+    }                                                                   \
-+  ASM_OUTPUT_LABEL(FILE, NAME);                                                 \
-+} while (0)
-+/* A C statement (sans semicolon) to output to the stdio stream
-+   STREAM any text necessary for declaring the name NAME of an
-+   initialized variable which is being defined.  This macro must
-+   output the label definition (perhaps using `ASM_OUTPUT_LABEL').
-+   The argument DECL is the `VAR_DECL' tree node representing the
-+   variable.
-+
-+   If this macro is not defined, then the variable name is defined in
-+   the usual manner as a label (by means of `ASM_OUTPUT_LABEL').  */
-+
-+#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END)       \
-+do {                                                                   \
-+     const char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0);           \
-+     if (!flag_inhibit_size_directive && DECL_SIZE (DECL)              \
-+         && ! AT_END && TOP_LEVEL                                      \
-+       && DECL_INITIAL (DECL) == error_mark_node                       \
-+       && !size_directive_output)                                      \
-+       {                                                               \
-+       size_directive_output = 1;                                      \
-+       fprintf (FILE, "%s", SIZE_ASM_OP);                              \
-+       assemble_name (FILE, name);                                     \
-+       fprintf (FILE, ",%d\n",  int_size_in_bytes (TREE_TYPE (DECL))); \
-+       }                                                               \
-+   } while (0)
-+/* A C statement (sans semicolon) to finish up declaring a variable
-+   name once the compiler has processed its initializer fully and
-+   thus has had a chance to determine the size of an array when
-+   controlled by an initializer.  This is used on systems where it's
-+   necessary to declare something about the size of the object.
-+
-+   If you don't define this macro, that is equivalent to defining it
-+   to do nothing.  */
-+
-+
-+#define ESCAPES \
-+"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
-+\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\
-+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\
-+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
-+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
-+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
-+\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"
-+/* A table of bytes codes used by the ASM_OUTPUT_ASCII and
-+   ASM_OUTPUT_LIMITED_STRING macros.  Each byte in the table
-+   corresponds to a particular byte value [0..255].  For any
-+   given byte value, if the value in the corresponding table
-+   position is zero, the given character can be output directly.
-+   If the table value is 1, the byte must be output as a \ooo
-+   octal escape.  If the tables value is anything else, then the
-+   byte value should be output as a \ followed by the value
-+   in the table.  Note that we can use standard UN*X escape
-+   sequences for many control characters, but we don't use
-+   \a to represent BEL because some svr4 assemblers (e.g. on
-+   the i386) don't know about that.  Also, we don't use \v
-+   since some versions of gas, such as 2.2 did not accept it.  */
-+
-+#define STRING_LIMIT  ((unsigned) 64)
-+#define STRING_ASM_OP "\t.string\t"
-+/* Some svr4 assemblers have a limit on the number of characters which
-+   can appear in the operand of a .string directive.  If your assembler
-+   has such a limitation, you should define STRING_LIMIT to reflect that
-+   limit.  Note that at least some svr4 assemblers have a limit on the
-+   actual number of bytes in the double-quoted string, and that they
-+   count each character in an escape sequence as one byte.  Thus, an
-+   escape sequence like \377 would count as four bytes.
-+
-+   If your target assembler doesn't support the .string directive, you
-+   should define this to zero.  */
-+
-+#define ASM_GLOBALIZE_LABEL(STREAM, NAME)     \
-+do {                                          \
-+  char *p = NAME;                               \
-+  if(*p == '*' || *p == '@' ) p++;              \
-+  if(*p >= '0' && *p <= '9' ) break;            \
-+  fprintf (STREAM, ".global\t");              \
-+  assemble_name (STREAM, NAME);                       \
-+  fprintf (STREAM, "\n");                     \
-+}                                             \
-+while (0)
-+     
-+/* A C statement (sans semicolon) to output to the stdio stream
-+   STREAM some commands that will make the label NAME global; that
-+   is, available for reference from other files.  Use the expression
-+   `assemble_name (STREAM, NAME)' to output the name itself; before
-+   and after that, output the additional assembler syntax for making
-+   that name global, and a newline.  */
-+
-+#define ASM_WEAKEN_LABEL(FILE, NAME)  \
-+  do                                  \
-+    {                                 \
-+      fputs ("\t.weak\t", (FILE));    \
-+      assemble_name ((FILE), (NAME));         \
-+      fputc ('\n', (FILE));           \
-+    }                                 \
-+  while (0)
-+
-+/* A C statement (sans semicolon) to output to the stdio stream
-+   STREAM some commands that will make the label NAME weak; that is,
-+   available for reference from other files but only used if no other
-+   definition is available.  Use the expression `assemble_name
-+   (STREAM, NAME)' to output the name itself; before and after that,
-+   output the additional assembler syntax for making that name weak,
-+   and a newline.
-+
-+   If you don't define this macro, GNU CC will not support weak
-+   symbols and you should not define the `SUPPORTS_WEAK' macro.
-+*/
-+
-+#define SUPPORTS_WEAK 1
-+/* A C expression which evaluates to true if the target supports weak
-+   symbols.
-+
-+   If you don't define this macro, `defaults.h' provides a default
-+   definition.  If `ASM_WEAKEN_LABEL' is defined, the default
-+   definition is `1'; otherwise, it is `0'.  Define this macro if you
-+   want to control weak symbol support with a compiler flag such as
-+   `-melf'.
-+
-+   `MAKE_DECL_ONE_ONLY'
-+   A C statement (sans semicolon) to mark DECL to be emitted as a
-+   public symbol such that extra copies in multiple translation units
-+   will be discarded by the linker.  Define this macro if your object
-+   file format provides support for this concept, such as the `COMDAT'
-+   section flags in the Microsoft Windows PE/COFF format, and this
-+   support requires changes to DECL, such as putting it in a separate
-+   section.
-+
-+   `SUPPORTS_WEAK'
-+   A C expression which evaluates to true if the target supports
-+   one-only semantics.
-+
-+   If you don't define this macro, `varasm.c' provides a default
-+   definition.  If `MAKE_DECL_ONE_ONLY' is defined, the default
-+   definition is `1'; otherwise, it is `0'.  Define this macro if you
-+   want to control weak symbol support with a compiler flag, or if
-+   setting the `DECL_ONE_ONLY' flag is enough to mark a declaration to
-+   be emitted as one-only.  */
-+
-+#define ASM_OUTPUT_INTERNAL_LABEL(STREAM, PREFIX, NUM)        \
-+fprintf(STREAM, ".%s%d:\n", PREFIX, NUM)
-+/* A C statement to output to the stdio stream STREAM a label whose
-+   name is made from the string PREFIX and the number NUM.
-+
-+   It is absolutely essential that these labels be distinct from the
-+   labels used for user-level functions and variables.  Otherwise,
-+   certain programs will have name conflicts with internal labels.
-+
-+   It is desirable to exclude internal labels from the symbol table
-+   of the object file.  Most assemblers have a naming convention for
-+   labels that should be excluded; on many systems, the letter `L' at
-+   the beginning of a label has this effect.  You should find out what
-+   convention your system uses, and follow it.
-+
-+   The usual definition of this macro is as follows:
-+
-+   fprintf (STREAM, "L%s%d:\n", PREFIX, NUM)  */
-+
-+#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM)      \
-+sprintf (STRING, "*.%s%d", PREFIX, NUM)
-+/* A C statement to store into the string STRING a label whose name
-+   is made from the string PREFIX and the number NUM.
-+
-+   This string, when output subsequently by `assemble_name', should
-+   produce the output that `ASM_OUTPUT_INTERNAL_LABEL' would produce
-+   with the same PREFIX and NUM.
-+
-+   If the string begins with `*', then `assemble_name' will output
-+   the rest of the string unchanged.  It is often convenient for
-+   `ASM_GENERATE_INTERNAL_LABEL' to use `*' in this way.  If the
-+   string doesn't start with `*', then `ASM_OUTPUT_LABELREF' gets to
-+   output the string, and may change it.  (Of course,
-+   `ASM_OUTPUT_LABELREF' is also part of your machine description, so
-+   you should know what it does on your machine.)  */
-+
-+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)        \
-+( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),  \
-+  sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
-+
-+/* A C expression to assign to OUTVAR (which is a variable of type
-+   `char *') a newly allocated string made from the string NAME and
-+   the number NUMBER, with some suitable punctuation added.  Use
-+   `alloca' to get space for the string.
-+
-+   The string will be used as an argument to `ASM_OUTPUT_LABELREF' to
-+   produce an assembler label for an internal static variable whose
-+   name is NAME.  Therefore, the string must be such as to result in
-+   valid assembler code.  The argument NUMBER is different each time
-+   this macro is executed; it prevents conflicts between
-+   similarly-named internal static variables in different scopes.
-+
-+   Ideally this string should not be a valid C identifier, to prevent
-+   any conflict with the user's own symbols.  Most assemblers allow
-+   periods or percent signs in assembler symbols; putting at least
-+   one of these between the name and the number will suffice.  */
-+
-+/* `ASM_OUTPUT_WEAK_ALIAS (STREAM, NAME, VALUE)'
-+   A C statement to output to the stdio stream STREAM assembler code
-+   which defines (equates) the weak symbol NAME to have the value
-+   VALUE.
-+
-+   Define this macro if the target only supports weak aliases; define
-+   ASM_OUTPUT_DEF instead if possible.  */
-+
-+#define HAS_INIT_SECTION 1
-+/* If defined, `main' will not call `__main' as described above.
-+   This macro should be defined for systems that control the contents
-+   of the init section on a symbol-by-symbol basis, such as OSF/1,
-+   and should not be defined explicitly for systems that support
-+   `INIT_SECTION_ASM_OP'.  */
-+
-+#define REGISTER_NAMES {                              \
-+  "r0","r1","r2","r3","r4","r5","r6","r7",            \
-+  "r8","r9","r10","r11","r12","r13","r14","r15"               \
-+}
-+/* A C initializer containing the assembler's names for the machine
-+   registers, each one as a C string constant.  This is what
-+   translates register numbers in the compiler into assembler
-+   language.  */
-+
-+#define FINAL_PRESCAN_INSN(insn, operand, nop) final_prescan_insn (insn, operand,nop)
-+/* If defined, a C statement to be executed just prior to the output
-+   of assembler code for INSN, to modify the extracted operands so
-+   they will be output differently.
-+
-+   Here the argument OPVEC is the vector containing the operands
-+   extracted from INSN, and NOPERANDS is the number of elements of
-+   the vector which contain meaningful data for this insn.  The
-+   contents of this vector are what will be used to convert the insn
-+   template into assembler code, so you can change the assembler
-+   output by changing the contents of the vector.
-+
-+   This macro is useful when various assembler syntaxes share a single
-+   file of instruction patterns; by defining this macro differently,
-+   you can cause a large class of instructions to be output
-+   differently (such as with rearranged operands).  Naturally,
-+   variations in assembler syntax affecting individual insn patterns
-+   ought to be handled by writing conditional output routines in
-+   those patterns.
-+
-+   If this macro is not defined, it is equivalent to a null statement.  */
-+
-+#define PRINT_OPERAND(STREAM, X, CODE) print_operand (STREAM, X, CODE)
-+/* A C compound statement to output to stdio stream STREAM the
-+   assembler syntax for an instruction operand X.  X is an RTL
-+   expression.
-+
-+   CODE is a value that can be used to specify one of several ways of
-+   printing the operand.  It is used when identical operands must be
-+   printed differently depending on the context.  CODE comes from the
-+   `%' specification that was used to request printing of the
-+   operand.  If the specification was just `%DIGIT' then CODE is 0;
-+   if the specification was `%LTR DIGIT' then CODE is the ASCII code
-+   for LTR.
-+
-+   If X is a register, this macro should print the register's name.
-+   The names can be found in an array `reg_names' whose type is `char
-+   *[]'.  `reg_names' is initialized from `REGISTER_NAMES'.
-+
-+   When the machine description has a specification `%PUNCT' (a `%'
-+   followed by a punctuation character), this macro is called with a
-+   null pointer for X and the punctuation character for CODE.  */
-+
-+#define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '~')
-+/* A C expression which evaluates to true if CODE is a valid
-+   punctuation character for use in the `PRINT_OPERAND' macro.  If
-+   `PRINT_OPERAND_PUNCT_VALID_P' is not defined, it means that no
-+   punctuation characters (except for the standard one, `%') are used
-+   in this way.  */
-+
-+#define PRINT_OPERAND_ADDRESS(STREAM, X) print_operand_address(STREAM, X)
-+/* A C compound statement to output to stdio stream STREAM the
-+   assembler syntax for an instruction operand that is a memory
-+   reference whose address is X.  X is an RTL expression.
-+
-+   On some machines, the syntax for a symbolic address depends on the
-+   section that the address refers to.  On these machines, define the
-+   macro `ENCODE_SECTION_INFO' to store the information into the
-+   `symbol_ref', and then check for it here.  *Note Assembler
-+   Format::.  */
-+
-+#define USER_LABEL_PREFIX ""
-+/* `LOCAL_LABEL_PREFIX'
-+   `REGISTER_PREFIX'
-+   `IMMEDIATE_PREFIX'
-+   If defined, C string expressions to be used for the `%R', `%L',
-+   `%U', and `%I' options of `asm_fprintf' (see `final.c').  These
-+   are useful when a single `md' file must support multiple assembler
-+   formats.  In that case, the various `tm.h' files can define these
-+   macros differently.  */
-+
-+#define ASSEMBLER_DIALECT MSP430_HAS_HWMUL_INTERNAL
-+/* If your target supports multiple dialects of assembler language
-+  (such as different opcodes), define this macro as a C expression
-+  that gives the numeric index of the assembler language dialect to
-+  use, with zero as the first variant.
-+
-+  If this macro is defined, you may use constructs of the form
-+  `{option0|option1|option2...}' in the output templates of patterns
-+  (*note Output Template::.) or in the first argument of
-+  `asm_fprintf'.  This construct outputs `option0', `option1' or
-+  `option2', etc., if the value of `ASSEMBLER_DIALECT' is zero, one
-+  or two, etc.  Any special characters within these strings retain
-+  their usual meaning.
-+
-+  If you do not define this macro, the characters `{', `|' and `}'
-+  do not have any special meaning when used in templates or operands
-+  to `asm_fprintf'.
-+
-+  Define the macros `REGISTER_PREFIX', `LOCAL_LABEL_PREFIX',
-+  `USER_LABEL_PREFIX' and `IMMEDIATE_PREFIX' if you can express the
-+  variations in assembler language syntax with that mechanism.
-+  Define `ASSEMBLER_DIALECT' and use the `{option0|option1}' syntax
-+  if the syntax variant are larger and involve such things as
-+  different opcodes or operand order.  */
-+
-+#define ASM_OUTPUT_REG_PUSH(STREAM, REGNO)    \
-+{                                             \
-+  if (REGNO > 15)                             \
-+    abort ();                                 \
-+  fprintf (STREAM, "\tpush\tr%d", REGNO);     \
-+}
-+/* A C expression to output to STREAM some assembler code which will
-+   push hard register number REGNO onto the stack.  The code need not
-+   be optimal, since this macro is used only when profiling.  */
-+
-+#define ASM_OUTPUT_REG_POP(STREAM, REGNO)     \
-+{                                             \
-+  if (REGNO > 15)                             \
-+    abort ();                                 \
-+  fprintf (STREAM, "\tpop\tr%d", REGNO);      \
-+}
-+/* A C expression to output to STREAM some assembler code which will
-+   pop hard register number REGNO off of the stack.  The code need
-+   not be optimal, since this macro is used only when profiling.  */
-+
-+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE)                \
-+  msp430_output_addr_vec_elt(STREAM, VALUE)
-+/* This macro should be provided on machines where the addresses in a
-+   dispatch table are absolute.
-+
-+   The definition should be a C statement to output to the stdio
-+   stream STREAM an assembler pseudo-instruction to generate a
-+   reference to a label.  VALUE is the number of an internal label
-+   whose definition is output using `ASM_OUTPUT_INTERNAL_LABEL'.  For
-+   example,
-+
-+   fprintf (STREAM, "\t.word L%d\n", VALUE)  */
-+
-+/*
-+#define ASM_OUTPUT_CASE_LABEL(STREAM, PREFIX, NUM, TABLE) \
-+   progmem_section (), ASM_OUTPUT_INTERNAL_LABEL (STREAM, PREFIX, NUM)
-+
-+   `ASM_OUTPUT_CASE_LABEL (STREAM, PREFIX, NUM, TABLE)'
-+   Define this if the label before a jump-table needs to be output
-+   specially.  The first three arguments are the same as for
-+   `ASM_OUTPUT_INTERNAL_LABEL'; the fourth argument is the jump-table
-+   which follows (a `jump_insn' containing an `addr_vec' or
-+   `addr_diff_vec').
-+
-+   This feature is used on system V to output a `swbeg' statement for
-+   the table.
-+
-+   If this macro is not defined, these labels are output with
-+   `ASM_OUTPUT_INTERNAL_LABEL'.  */
-+
-+/* `ASM_OUTPUT_CASE_END (STREAM, NUM, TABLE)'
-+   Define this if something special must be output at the end of a
-+   jump-table.  The definition should be a C statement to be executed
-+   after the assembler code for the table is written.  It should write
-+   the appropriate code to stdio stream STREAM.  The argument TABLE
-+   is the jump-table insn, and NUM is the label-number of the
-+   preceding label.
-+
-+   If this macro is not defined, nothing special is output at the end
-+   of the jump-table.  */
-+
-+#ifndef SET_ASM_OP
-+#define SET_ASM_OP "\t.set\t"
-+#endif
-+  
-+#define ASM_OUTPUT_SKIP(STREAM, N)            \
-+fprintf (STREAM, "\t.skip %d,0\n", N)
-+/* A C statement to output to the stdio stream STREAM an assembler
-+   instruction to advance the location counter by NBYTES bytes.
-+   Those bytes should be zero when loaded.  NBYTES will be a C
-+   expression of type `int'.  */
-+
-+#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
-+fprintf (STREAM, "\t.p2align %d,0\n", POWER)
-+/* A C statement to output to the stdio stream STREAM an assembler
-+   command to advance the location counter to a multiple of 2 to the
-+   POWER bytes.  POWER will be a C expression of type `int'.  */
-+
-+#define CASE_VECTOR_MODE HImode
-+/* An alias for a machine mode name.  This is the machine mode that
-+   elements of a jump-table should have.  */
-+
-+
-+#define PREDICATE_CODES \
-+{"memory_operand_msp430", {SUBREG, MEM}},     \
-+{"nonimmediate_operand_msp430", {SUBREG, REG, MEM}},\
-+{"general_operand_msp430", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, LABEL_REF, SUBREG, REG, MEM}},\
-+{"three_operands_msp430", {PLUS, MINUS, AND, IOR, XOR}}, \
-+{"equality_operator", {EQ, NE }},                     \
-+{"inequality_operator", {GE, GT, LE, LT, GEU, GTU, LEU, LTU }},
-+    
-+
-+
-+
-+extern struct rtx_def *msp430_compare_op0, *msp430_compare_op1;
-+
-+
-+extern int msp430_case_values_threshold;
-+
-+#define CASE_VALUES_THRESHOLD msp430_case_values_threshold
-+/* `CASE_VALUES_THRESHOLD'
-+   Define this to be the smallest number of different values for
-+   which it is best to use a jump-table instead of a tree of
-+   conditional branches.  The default is four for machines with a
-+   `casesi' instruction and five otherwise.  This is best for most
-+   machines.  */
-+
-+#undef WORD_REGISTER_OPERATIONS
-+/* Define this macro if operations between registers with integral
-+   mode smaller than a word are always performed on the entire
-+   register.  Most RISC machines have this property and most CISC
-+   machines do not.  */
-+
-+/*
-+#define EASY_DIV_EXPR TRUNC_DIV_EXPR
-+ An alias for a tree code that is the easiest kind of division to
-+   compile code for in the general case.  It may be `TRUNC_DIV_EXPR',
-+   `FLOOR_DIV_EXPR', `CEIL_DIV_EXPR' or `ROUND_DIV_EXPR'.  These four
-+   division operators differ in how they round the result to an
-+   integer.  `EASY_DIV_EXPR' is used when it is permissible to use
-+   any of those kinds of division and the choice should be made on
-+   the basis of efficiency.  */
-+
-+#define MOVE_MAX 2
-+/* The maximum number of bytes that a single instruction can move
-+   quickly between memory and registers or between two memory
-+   locations.  */
-+
-+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-+/* A C expression which is nonzero if on this machine it is safe to
-+   "convert" an integer of INPREC bits to one of OUTPREC bits (where
-+   OUTPREC is smaller than INPREC) by merely operating on it as if it
-+   had only OUTPREC bits.
-+
-+   On many machines, this expression can be 1.
-+
-+   When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for
-+   modes for which `MODES_TIEABLE_P' is 0, suboptimal code can result.
-+   If this is the case, making `TRULY_NOOP_TRUNCATION' return 0 in
-+   such cases may improve things.  */
-+
-+#define Pmode HImode
-+/* An alias for the machine mode for pointers.  On most machines,
-+   define this to be the integer mode corresponding to the width of a
-+   hardware pointer; `SImode' on 32-bit machine or `DImode' on 64-bit
-+   machines.  On some machines you must define this to be one of the
-+   partial integer modes, such as `PSImode'.
-+
-+   The width of `Pmode' must be at least as large as the value of
-+   `POINTER_SIZE'.  If it is not equal, you must define the macro
-+   `POINTERS_EXTEND_UNSIGNED' to specify how pointers are extended to
-+   `Pmode'.  */
-+
-+#define FUNCTION_MODE HImode
-+/* An alias for the machine mode used for memory references to
-+   functions being called, in `call' RTL expressions.  On most
-+   machines this should be `QImode'.  */
-+     /*                            1        3 */
-+#define INTEGRATE_THRESHOLD(DECL) (1 + (3 * list_length (DECL_ARGUMENTS (DECL)) / 2))
-+
-+/* A C expression for the maximum number of instructions above which
-+   the function DECL should not be inlined.  DECL is a
-+   `FUNCTION_DECL' node.
-+
-+   The default definition of this macro is 64 plus 8 times the number
-+   of arguments that the function accepts.  Some people think a larger
-+   threshold should be used on RISC machines.  */
-+
-+/*
-+#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
-+valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
-+ `VALID_MACHINE_DECL_ATTRIBUTE (DECL, ATTRIBUTES, IDENTIFIER, ARGS)'
-+   If defined, a C expression whose value is nonzero if IDENTIFIER
-+   with arguments ARGS is a valid machine specific attribute for DECL.
-+   The attributes in ATTRIBUTES have previously been assigned to DECL.  */
-+
-+/*
-+#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, IDENTIFIER, ARGS) \
-+     valid_machine_type_attribute(TYPE, ATTRIBUTES, IDENTIFIER, ARGS)
-+   `VALID_MACHINE_TYPE_ATTRIBUTE (TYPE, ATTRIBUTES, IDENTIFIER, ARGS)'
-+   If defined, a C expression whose value is nonzero if IDENTIFIER
-+   with arguments ARGS is a valid machine specific attribute for TYPE.
-+   The attributes in ATTRIBUTES have previously been assigned to TYPE.  */
-+
-+#define DOLLARS_IN_IDENTIFIERS 0
-+/* Define this macro to control use of the character `$' in identifier
-+   names.  0 means `$' is not allowed by default; 1 means it is
-+   allowed.  1 is the default; there is no need to define this macro
-+   in that case.  This macro controls the compiler proper; it does
-+   not affect the preprocessor.  */
-+
-+#define NO_DOLLAR_IN_LABEL 1
-+/* Define this macro if the assembler does not accept the character
-+   `$' in label names.  By default constructors and destructors in
-+   G++ have `$' in the identifiers.  If this macro is defined, `.' is
-+   used instead.  */
-+
-+#define MACHINE_DEPENDENT_REORG(INSN) machine_dependent_reorg (INSN)
-+/* In rare cases, correct code generation requires extra machine
-+   dependent processing between the second jump optimization pass and
-+   delayed branch scheduling.  On those machines, define this macro
-+   as a C statement to act on the code starting at INSN.  */
-+
-+#define GIV_SORT_CRITERION(X, Y)      \
-+  if (GET_CODE ((X)->add_val) == CONST_INT            \
-+      && GET_CODE ((Y)->add_val) == CONST_INT)                \
-+    return INTVAL ((X)->add_val) - INTVAL ((Y)->add_val);
-+
-+/* `GIV_SORT_CRITERION(GIV1, GIV2)'
-+   In some cases, the strength reduction optimization pass can
-+   produce better code if this is defined.  This macro controls the
-+   order that induction variables are combined.  This macro is
-+   particularly useful if the target has limited addressing modes.
-+   For instance, the SH target has only positive offsets in
-+   addresses.  Thus sorting to put the smallest address first allows
-+   the most combinations to be found.  */
-+
-+/* Define results of standard character escape sequences.  */
-+#define TARGET_BELL 007
-+#define TARGET_BS 010
-+#define TARGET_TAB 011
-+#define TARGET_NEWLINE 012
-+#define TARGET_VT 013
-+#define TARGET_FF 014
-+#define TARGET_CR 015
-+#define TARGET_ESC 033
-+
-+#define TRAMPOLINE_TEMPLATE(FILE) msp430_trampoline_template((FILE))
-+
-+#define TRAMPOLINE_SIZE 8
-+#define TRAMPOLINE_ALIGNMENT 16
-+
-+
-+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT)     \
-+      msp430_initialize_trampoline (TRAMP, FNADDR, CXT)
-+
-+
-+/* Store in cc_status the expressions
-+   that the condition codes will describe
-+   after execution of an instruction whose pattern is EXP.
-+   Do not alter them if the instruction would not alter the cc's.  */
-+
-+#define NOTICE_UPDATE_CC(EXP, INSN) notice_update_cc(EXP, INSN)
-+
-+/* The add insns don't set overflow in a usable way.  */
-+#define CC_OVERFLOW_UNUSABLE 01000
-+/* The mov,and,or,xor insns don't set carry.  That's ok though as the
-+   Z bit is all we need when doing unsigned comparisons on the result of
-+   these insns (since they're always with 0).  However, conditions.h has
-+   CC_NO_OVERFLOW defined for this purpose.  Rename it to something more
-+   understandable.  */
-+#define CC_NO_CARRY CC_NO_OVERFLOW
-+
-+
-+/* Output assembler code to FILE to increment profiler label # LABELNO
-+   for profiling a function entry.  */
-+
-+#define FUNCTION_PROFILER(FILE, LABELNO)  \
-+  fprintf (FILE, "/* profiler %d */", (LABELNO))
-+
-+/* `FIRST_INSN_ADDRESS'
-+   When the `length' insn attribute is used, this macro specifies the
-+   value to be assigned to the address of the first insn in a
-+   function.  If not specified, 0 is used.  */
-+
-+#define ADJUST_INSN_LENGTH(INSN, LENGTH) (LENGTH =\
-+                                        adjust_insn_length (INSN, LENGTH))
-+/* If defined, modifies the length assigned to instruction INSN as a
-+   function of the context in which it is used.  LENGTH is an lvalue
-+   that contains the initially computed length of the insn and should
-+   be updated with the correct length of the insn.  If updating is
-+   required, INSN must not be a varying-length insn.
-+
-+   This macro will normally not be required.  A case in which it is
-+   required is the ROMP.  On this machine, the size of an `addr_vec'
-+   insn must be increased by two to compensate for the fact that
-+   alignment may be required.  */
-+
-+#define TARGET_MEM_FUNCTIONS
-+/* Define this macro if GNU CC should generate calls to the System V
-+   (and ANSI C) library functions `memcpy' and `memset' rather than
-+   the BSD functions `bcopy' and `bzero'.  */
-+
-+#define CPP_SPEC "\
-+%{!mmcu*|mmcu=msp1:%(cpp_msp1)} \
-+%{mmcu=msp2:%(cpp_msp2) -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x110:%(cpp_msp1) -D__MSP430_110__} \
-+%{mmcu=msp430x112:%(cpp_msp1) -D__MSP430_112__} \
-+%{mmcu=msp430x1101:%(cpp_msp1) -D__MSP430_1101__} \
-+%{mmcu=msp430x1111:%(cpp_msp1) -D__MSP430_1111__} \
-+%{mmcu=msp430x1121:%(cpp_msp1) -D__MSP430_1121__} \
-+%{mmcu=msp430x1122:%(cpp_msp1) -D__MSP430_1122__} \
-+%{mmcu=msp430x1132:%(cpp_msp1) -D__MSP430_1132__} \
-+%{mmcu=msp430x122:%(cpp_msp1) -D__MSP430_122__} \
-+%{mmcu=msp430x123:%(cpp_msp1) -D__MSP430_123__} \
-+%{mmcu=msp430x1222:%(cpp_msp1) -D__MSP430_1222__} \
-+%{mmcu=msp430x1232:%(cpp_msp1) -D__MSP430_1232__} \
-+%{mmcu=msp430x133:%(cpp_msp1) -D__MSP430_133__} \
-+%{mmcu=msp430x135:%(cpp_msp1) -D__MSP430_135__} \
-+%{mmcu=msp430x1331:%(cpp_msp1) -D__MSP430_1331__} \
-+%{mmcu=msp430x1351:%(cpp_msp1) -D__MSP430_1351__} \
-+%{mmcu=msp430x147:%(cpp_msp2) -D__MSP430_147__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x148:%(cpp_msp2) -D__MSP430_148__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x149:%(cpp_msp2) -D__MSP430_149__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x1471:%(cpp_msp2) -D__MSP430_1471__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x1481:%(cpp_msp2) -D__MSP430_1481__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x1491:%(cpp_msp2) -D__MSP430_1491__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x155:%(cpp_msp1) -D__MSP430_155__} \
-+%{mmcu=msp430x156:%(cpp_msp1) -D__MSP430_156__} \
-+%{mmcu=msp430x157:%(cpp_msp1) -D__MSP430_157__} \
-+%{mmcu=msp430x167:%(cpp_msp2) -D__MSP430_167__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x168:%(cpp_msp2) -D__MSP430_168__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x169:%(cpp_msp2) -D__MSP430_169__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x1610:%(cpp_msp2) -D__MSP430_1610__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x1611:%(cpp_msp2) -D__MSP430_1611__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x1612:%(cpp_msp2) -D__MSP430_1612__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2001:%(cpp_msp1) -D__MSP430_2001__} \
-+%{mmcu=msp430x2011:%(cpp_msp1) -D__MSP430_2011__} \
-+%{mmcu=msp430x2002:%(cpp_msp1) -D__MSP430_2002__} \
-+%{mmcu=msp430x2012:%(cpp_msp1) -D__MSP430_2012__} \
-+%{mmcu=msp430x2003:%(cpp_msp1) -D__MSP430_2003__} \
-+%{mmcu=msp430x2013:%(cpp_msp1) -D__MSP430_2013__} \
-+%{mmcu=msp430x2101:%(cpp_msp1) -D__MSP430_2101__} \
-+%{mmcu=msp430x2111:%(cpp_msp1) -D__MSP430_2111__} \
-+%{mmcu=msp430x2121:%(cpp_msp1) -D__MSP430_2121__} \
-+%{mmcu=msp430x2131:%(cpp_msp1) -D__MSP430_2131__} \
-+%{mmcu=msp430x2232:%(cpp_msp1) -D__MSP430_2232__} \
-+%{mmcu=msp430x2252:%(cpp_msp1) -D__MSP430_2252__} \
-+%{mmcu=msp430x2272:%(cpp_msp1) -D__MSP430_2272__} \
-+%{mmcu=msp430x2234:%(cpp_msp1) -D__MSP430_2234__} \
-+%{mmcu=msp430x2254:%(cpp_msp1) -D__MSP430_2254__} \
-+%{mmcu=msp430x2274:%(cpp_msp1) -D__MSP430_2274__} \
-+%{mmcu=msp430x233:%(cpp_msp2) -D__MSP430_233__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x235:%(cpp_msp2) -D__MSP430_235__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2330:%(cpp_msp2) -D__MSP430_2330__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2350:%(cpp_msp2) -D__MSP430_2350__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2370:%(cpp_msp2) -D__MSP430_2370__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x247:%(cpp_msp2) -D__MSP430_247__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x248:%(cpp_msp2) -D__MSP430_248__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x249:%(cpp_msp2) -D__MSP430_249__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2410:%(cpp_msp2) -D__MSP430_2410__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2471:%(cpp_msp2) -D__MSP430_2471__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2481:%(cpp_msp2) -D__MSP430_2481__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2491:%(cpp_msp2) -D__MSP430_2491__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2416:%(cpp_msp2) -D__MSP430_2416__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2417:%(cpp_msp2) -D__MSP430_2417__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2418:%(cpp_msp2) -D__MSP430_2418__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2419:%(cpp_msp2) -D__MSP430_2419__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2616:%(cpp_msp2) -D__MSP430_2616__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2617:%(cpp_msp2) -D__MSP430_2617__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2618:%(cpp_msp2) -D__MSP430_2618__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x2619:%(cpp_msp2) -D__MSP430_2619__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x311:%(cpp_msp1) -D__MSP430_311__} \
-+%{mmcu=msp430x312:%(cpp_msp1) -D__MSP430_312__} \
-+%{mmcu=msp430x313:%(cpp_msp1) -D__MSP430_313__} \
-+%{mmcu=msp430x314:%(cpp_msp1) -D__MSP430_314__} \
-+%{mmcu=msp430x315:%(cpp_msp1) -D__MSP430_315__} \
-+%{mmcu=msp430x323:%(cpp_msp1) -D__MSP430_323__} \
-+%{mmcu=msp430x325:%(cpp_msp1) -D__MSP430_325__} \
-+%{mmcu=msp430x336:%(cpp_msp2) -D__MSP430_336__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x337:%(cpp_msp2) -D__MSP430_337__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x412:%(cpp_msp1) -D__MSP430_412__} \
-+%{mmcu=msp430x413:%(cpp_msp1) -D__MSP430_413__} \
-+%{mmcu=msp430x415:%(cpp_msp1) -D__MSP430_415__} \
-+%{mmcu=msp430x417:%(cpp_msp1) -D__MSP430_417__} \
-+%{mmcu=msp430x423:%(cpp_msp2) -D__MSP430_423__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x425:%(cpp_msp2) -D__MSP430_425__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x427:%(cpp_msp2) -D__MSP430_427__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x4250:%(cpp_msp1) -D__MSP430_4250__} \
-+%{mmcu=msp430x4260:%(cpp_msp1) -D__MSP430_4260__} \
-+%{mmcu=msp430x4270:%(cpp_msp1) -D__MSP430_4270__} \
-+%{mmcu=msp430xE423:%(cpp_msp2) -D__MSP430_E423__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430xE425:%(cpp_msp2) -D__MSP430_E425__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430xE427:%(cpp_msp2) -D__MSP430_E427__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430xW423:%(cpp_msp1) -D__MSP430_W423__} \
-+%{mmcu=msp430xW425:%(cpp_msp1) -D__MSP430_W425__} \
-+%{mmcu=msp430xW427:%(cpp_msp1) -D__MSP430_W427__} \
-+%{mmcu=msp430xG437:%(cpp_msp1) -D__MSP430_G437__} \
-+%{mmcu=msp430xG438:%(cpp_msp1) -D__MSP430_G438__} \
-+%{mmcu=msp430xG439:%(cpp_msp1) -D__MSP430_G439__} \
-+%{mmcu=msp430x435:%(cpp_msp1) -D__MSP430_435__} \
-+%{mmcu=msp430x436:%(cpp_msp1) -D__MSP430_436__} \
-+%{mmcu=msp430x437:%(cpp_msp1) -D__MSP430_437__} \
-+%{mmcu=msp430x447:%(cpp_msp2) -D__MSP430_447__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x448:%(cpp_msp2) -D__MSP430_448__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430x449:%(cpp_msp2) -D__MSP430_449__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430xG4616:%(cpp_msp2) -D__MSP430_G4616__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430xG4617:%(cpp_msp2) -D__MSP430_G4617__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430xG4618:%(cpp_msp2) -D__MSP430_G4618__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
-+%{mmcu=msp430xG4619:%(cpp_msp2) -D__MSP430_G4619__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
-+%{mint8:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long -D__INT_MAX__=127} \
-+%{!mint*:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int -D__INT_MAX__=32767} \
-+%{posix:-D_POSIX_SOURCE} %{mIAR:-D_IAR_ASSEMBLER_}"
-+
-+/* A C string constant that tells the GNU CC driver program options to
-+   pass to CPP.  It can also specify how to translate options you
-+   give to GNU CC into options for GNU CC to pass to the CPP.
-+
-+   Do not define this macro if it does not need to do anything.  */
-+
-+#define NO_BUILTIN_SIZE_TYPE
-+/* If this macro is defined, the preprocessor will not define the
-+   builtin macro `__SIZE_TYPE__'.  The macro `__SIZE_TYPE__' must
-+   then be defined by `CPP_SPEC' instead.
-+
-+   This should be defined if `SIZE_TYPE' depends on target dependent
-+   flags which are not accessible to the preprocessor.  Otherwise, it
-+   should not be defined.  */
-+
-+#define NO_BUILTIN_PTRDIFF_TYPE
-+/* If this macro is defined, the preprocessor will not define the
-+   builtin macro `__PTRDIFF_TYPE__'.  The macro `__PTRDIFF_TYPE__'
-+   must then be defined by `CPP_SPEC' instead.
-+
-+   This should be defined if `PTRDIFF_TYPE' depends on target
-+   dependent flags which are not accessible to the preprocessor.
-+   Otherwise, it should not be defined.
-+
-+   `SIGNED_CHAR_SPEC'
-+   A C string constant that tells the GNU CC driver program options to
-+   pass to CPP.  By default, this macro is defined to pass the option
-+   `-D__CHAR_UNSIGNED__' to CPP if `char' will be treated as
-+   `unsigned char' by `cc1'.
-+
-+   Do not define this macro unless you need to override the default
-+   definition.  */
-+
-+#define CC1_SPEC "%{profile:-p}"
-+/* A C string constant that tells the GNU CC driver program options to
-+   pass to `cc1'.  It can also specify how to translate options you
-+   give to GNU CC into options for GNU CC to pass to the `cc1'.
-+
-+   Do not define this macro if it does not need to do anything.  */
-+
-+#define ASM_SPEC ""
-+/* A C string constant that tells the GNU CC driver program options to
-+   pass to the assembler.  It can also specify how to translate
-+   options you give to GNU CC into options for GNU CC to pass to the
-+   assembler.  See the file `sun3.h' for an example of this.
-+
-+   Do not define this macro if it does not need to do anything.  */
-+
-+#define ASM_FINAL_SPEC ""
-+/* A C string constant that tells the GNU CC driver program how to
-+   run any programs which cleanup after the normal assembler.
-+   Normally, this is not needed.  See the file `mips.h' for an
-+   example of this.
-+
-+   Do not define this macro if it does not need to do anything.  */
-+
-+#define LINK_SPEC "\
-+%{!mmcu*:-m msp430x110} \
-+%{mmcu=msp1:-m msp430x110} \
-+%{mmcu=msp2:-m msp430x336} \
-+%{mmcu=msp430x110:-m msp430x110 } \
-+%{mmcu=msp430x112:-m msp430x112 } \
-+%{mmcu=msp430x1101:-m msp430x1101 } \
-+%{mmcu=msp430x1111:-m msp430x1111 } \
-+%{mmcu=msp430x1121:-m msp430x1121 } \
-+%{mmcu=msp430x1122:-m msp430x1122 } \
-+%{mmcu=msp430x1132:-m msp430x1132 } \
-+%{mmcu=msp430x122:-m msp430x122 } \
-+%{mmcu=msp430x123:-m msp430x123 } \
-+%{mmcu=msp430x1222:-m msp430x1222 } \
-+%{mmcu=msp430x1232:-m msp430x1232 } \
-+%{mmcu=msp430x133:-m msp430x133 } \
-+%{mmcu=msp430x135:-m msp430x135 } \
-+%{mmcu=msp430x1331:-m msp430x1331 } \
-+%{mmcu=msp430x1351:-m msp430x1351 } \
-+%{mmcu=msp430x147:-m msp430x147 } \
-+%{mmcu=msp430x148:-m msp430x148 } \
-+%{mmcu=msp430x149:-m msp430x149 } \
-+%{mmcu=msp430x1471:-m msp430x1471 } \
-+%{mmcu=msp430x1481:-m msp430x1481 } \
-+%{mmcu=msp430x1491:-m msp430x1491 } \
-+%{mmcu=msp430x155:-m msp430x155 } \
-+%{mmcu=msp430x156:-m msp430x156 } \
-+%{mmcu=msp430x157:-m msp430x157 } \
-+%{mmcu=msp430x167:-m msp430x167 } \
-+%{mmcu=msp430x168:-m msp430x168 } \
-+%{mmcu=msp430x169:-m msp430x169 } \
-+%{mmcu=msp430x1610:-m msp430x1610 } \
-+%{mmcu=msp430x1611:-m msp430x1611 } \
-+%{mmcu=msp430x1612:-m msp430x1612 } \
-+%{mmcu=msp430x2001:-m msp430x2001 } \
-+%{mmcu=msp430x2011:-m msp430x2011 } \
-+%{mmcu=msp430x2002:-m msp430x2002 } \
-+%{mmcu=msp430x2012:-m msp430x2012 } \
-+%{mmcu=msp430x2003:-m msp430x2003 } \
-+%{mmcu=msp430x2013:-m msp430x2013 } \
-+%{mmcu=msp430x2101:-m msp430x2101 } \
-+%{mmcu=msp430x2111:-m msp430x2111 } \
-+%{mmcu=msp430x2121:-m msp430x2121 } \
-+%{mmcu=msp430x2131:-m msp430x2131 } \
-+%{mmcu=msp430x2232:-m msp430x2232 } \
-+%{mmcu=msp430x2252:-m msp430x2252 } \
-+%{mmcu=msp430x2272:-m msp430x2272 } \
-+%{mmcu=msp430x2234:-m msp430x2234 } \
-+%{mmcu=msp430x2254:-m msp430x2254 } \
-+%{mmcu=msp430x2274:-m msp430x2274 } \
-+%{mmcu=msp430x233:-m msp430x233 } \
-+%{mmcu=msp430x235:-m msp430x235 } \
-+%{mmcu=msp430x2330:-m msp430x2330 } \
-+%{mmcu=msp430x2350:-m msp430x2350 } \
-+%{mmcu=msp430x2370:-m msp430x2370 } \
-+%{mmcu=msp430x247:-m msp430x247 } \
-+%{mmcu=msp430x248:-m msp430x248 } \
-+%{mmcu=msp430x249:-m msp430x249 } \
-+%{mmcu=msp430x2410:-m msp430x2410 } \
-+%{mmcu=msp430x2471:-m msp430x2471 } \
-+%{mmcu=msp430x2481:-m msp430x2481 } \
-+%{mmcu=msp430x2491:-m msp430x2491 } \
-+%{mmcu=msp430x2416:-m msp430x2416 } \
-+%{mmcu=msp430x2417:-m msp430x2417 } \
-+%{mmcu=msp430x2418:-m msp430x2418 } \
-+%{mmcu=msp430x2419:-m msp430x2419 } \
-+%{mmcu=msp430x2616:-m msp430x2616 } \
-+%{mmcu=msp430x2617:-m msp430x2617 } \
-+%{mmcu=msp430x2618:-m msp430x2618 } \
-+%{mmcu=msp430x2619:-m msp430x2619 } \
-+%{mmcu=msp430x311:-m msp430x311 } \
-+%{mmcu=msp430x312:-m msp430x312 } \
-+%{mmcu=msp430x313:-m msp430x313 } \
-+%{mmcu=msp430x314:-m msp430x314 } \
-+%{mmcu=msp430x315:-m msp430x315 } \
-+%{mmcu=msp430x323:-m msp430x323 } \
-+%{mmcu=msp430x325:-m msp430x325 } \
-+%{mmcu=msp430x336:-m msp430x336 } \
-+%{mmcu=msp430x337:-m msp430x337 } \
-+%{mmcu=msp430x412:-m msp430x412 } \
-+%{mmcu=msp430x413:-m msp430x413 } \
-+%{mmcu=msp430x415:-m msp430x415 } \
-+%{mmcu=msp430x417:-m msp430x417 } \
-+%{mmcu=msp430x423:-m msp430x423 } \
-+%{mmcu=msp430x425:-m msp430x425 } \
-+%{mmcu=msp430x427:-m msp430x427 } \
-+%{mmcu=msp430x4250:-m msp430x4250 } \
-+%{mmcu=msp430x4260:-m msp430x4260 } \
-+%{mmcu=msp430x4270:-m msp430x4270 } \
-+%{mmcu=msp430xE423:-m msp430xE423 } \
-+%{mmcu=msp430xE425:-m msp430xE425 } \
-+%{mmcu=msp430xE427:-m msp430xE427 } \
-+%{mmcu=msp430xW423:-m msp430xW423 } \
-+%{mmcu=msp430xW425:-m msp430xW425 } \
-+%{mmcu=msp430xW427:-m msp430xW427 } \
-+%{mmcu=msp430xG437:-m msp430xG437 } \
-+%{mmcu=msp430xG438:-m msp430xG438 } \
-+%{mmcu=msp430xG439:-m msp430xG439 } \
-+%{mmcu=msp430x435:-m msp430x435 } \
-+%{mmcu=msp430x436:-m msp430x436 } \
-+%{mmcu=msp430x437:-m msp430x437 } \
-+%{mmcu=msp430x447:-m msp430x447 } \
-+%{mmcu=msp430x448:-m msp430x448 } \
-+%{mmcu=msp430x449:-m msp430x449 } \
-+%{mmcu=msp430xG4616:-m msp430xG4616 } \
-+%{mmcu=msp430xG4617:-m msp430xG4617 } \
-+%{mmcu=msp430xG4618:-m msp430xG4618 } \
-+%{mmcu=msp430xG4619:-m msp430xG4619 }"
-+
-+/* A C string constant that tells the GNU CC driver program options to
-+   pass to the linker.  It can also specify how to translate options
-+   you give to GNU CC into options for GNU CC to pass to the linker.
-+
-+   Do not define this macro if it does not need to do anything.  */
-+
-+#define LIB_SPEC \
-+  "%{*:-lc }"
-+/* Another C string constant used much like `LINK_SPEC'.  The
-+   difference between the two is that `LIB_SPEC' is used at the end
-+   of the command given to the linker.
-+
-+   If this macro is not defined, a default is provided that loads the
-+   standard C library from the usual place.  See `gcc.c'.  */
-+
-+#define LIBGCC_SPEC \
-+  "%{*: -lgcc }"
-+/* Another C string constant that tells the GNU CC driver program how
-+   and when to place a reference to `libgcc.a' into the linker
-+   command line.  This constant is placed both before and after the
-+   value of `LIB_SPEC'.
-+
-+   If this macro is not defined, the GNU CC driver provides a default
-+   that passes the string `-lgcc' to the linker unless the `-shared'
-+   option is specified.  */
-+
-+#define STARTFILE_SPEC "%(crt_binutils)"
-+/* Another C string constant used much like `LINK_SPEC'.  The
-+   difference between the two is that `STARTFILE_SPEC' is used at the
-+   very beginning of the command given to the linker.
-+
-+   If this macro is not defined, a default is provided that loads the
-+   standard C startup file from the usual place.  See `gcc.c'.  */
-+
-+#define ENDFILE_SPEC ""
-+/* Another C string constant used much like `LINK_SPEC'.  The
-+   difference between the two is that `ENDFILE_SPEC' is used at the
-+   very end of the command given to the linker.
-+
-+   Do not define this macro if it does not need to do anything.  */
-+
-+/* recently added:
-+1222 1232 */
-+
-+#define CRT_BINUTILS_SPECS "\
-+%{!mmcu=*|mmcu=msp430x110|mmcu=msp1:crt430x110.o%s} \
-+%{mmcu=msp430x112:crt430x112.o%s} \
-+%{mmcu=msp430x1101:crt430x1101.o%s} \
-+%{mmcu=msp430x1111:crt430x1111.o%s} \
-+%{mmcu=msp430x1121:crt430x1121.o%s} \
-+%{mmcu=msp430x1122:crt430x1122.o%s} \
-+%{mmcu=msp430x1132:crt430x1132.o%s} \
-+%{mmcu=msp430x122:crt430x122.o%s} \
-+%{mmcu=msp430x123:crt430x123.o%s} \
-+%{mmcu=msp430x1222:crt430x1222.o%s} \
-+%{mmcu=msp430x1232:crt430x1232.o%s} \
-+%{mmcu=msp430x133:crt430x133.o%s} \
-+%{mmcu=msp430x135:crt430x135.o%s} \
-+%{mmcu=msp430x1331:crt430x1331.o%s} \
-+%{mmcu=msp430x1351:crt430x1351.o%s} \
-+%{mmcu=msp430x147:crt430x147.o%s} \
-+%{mmcu=msp430x148:crt430x148.o%s} \
-+%{mmcu=msp430x149:crt430x149.o%s} \
-+%{mmcu=msp430x1471:crt430x1471.o%s} \
-+%{mmcu=msp430x1481:crt430x1481.o%s} \
-+%{mmcu=msp430x1491:crt430x1491.o%s} \
-+%{mmcu=msp430x155:crt430x155.o%s} \
-+%{mmcu=msp430x156:crt430x156.o%s} \
-+%{mmcu=msp430x157:crt430x157.o%s} \
-+%{mmcu=msp430x167:crt430x167.o%s} \
-+%{mmcu=msp430x168:crt430x168.o%s} \
-+%{mmcu=msp430x169:crt430x169.o%s} \
-+%{mmcu=msp430x1610:crt430x1610.o%s} \
-+%{mmcu=msp430x1611:crt430x1611.o%s} \
-+%{mmcu=msp430x1612:crt430x1612.o%s} \
-+%{mmcu=msp430x2001:crt430x2001.o%s} \
-+%{mmcu=msp430x2011:crt430x2011.o%s} \
-+%{mmcu=msp430x2002:crt430x2002.o%s} \
-+%{mmcu=msp430x2012:crt430x2012.o%s} \
-+%{mmcu=msp430x2003:crt430x2003.o%s} \
-+%{mmcu=msp430x2013:crt430x2013.o%s} \
-+%{mmcu=msp430x2101:crt430x2101.o%s} \
-+%{mmcu=msp430x2111:crt430x2111.o%s} \
-+%{mmcu=msp430x2121:crt430x2121.o%s} \
-+%{mmcu=msp430x2131:crt430x2131.o%s} \
-+%{mmcu=msp430x2232:crt430x2232.o%s} \
-+%{mmcu=msp430x2252:crt430x2252.o%s} \
-+%{mmcu=msp430x2272:crt430x2272.o%s} \
-+%{mmcu=msp430x2234:crt430x2234.o%s} \
-+%{mmcu=msp430x2254:crt430x2254.o%s} \
-+%{mmcu=msp430x2274:crt430x2274.o%s} \
-+%{mmcu=msp430x247:crt430x247.o%s} \
-+%{mmcu=msp430x248:crt430x248.o%s} \
-+%{mmcu=msp430x249:crt430x249.o%s} \
-+%{mmcu=msp430x2410:crt430x2410.o%s} \
-+%{mmcu=msp430x2471:crt430x2471.o%s} \
-+%{mmcu=msp430x2481:crt430x2481.o%s} \
-+%{mmcu=msp430x2491:crt430x2491.o%s} \
-+%{mmcu=msp430x2416:crt430x2416.o%s} \
-+%{mmcu=msp430x2417:crt430x2417.o%s} \
-+%{mmcu=msp430x2418:crt430x2418.o%s} \
-+%{mmcu=msp430x2419:crt430x2419.o%s} \
-+%{mmcu=msp430x2616:crt430x2616.o%s} \
-+%{mmcu=msp430x2617:crt430x2617.o%s} \
-+%{mmcu=msp430x2618:crt430x2618.o%s} \
-+%{mmcu=msp430x2619:crt430x2619.o%s} \
-+%{mmcu=msp430x311:crt430x311.o%s} \
-+%{mmcu=msp430x312:crt430x312.o%s} \
-+%{mmcu=msp430x313:crt430x313.o%s} \
-+%{mmcu=msp430x314:crt430x314.o%s} \
-+%{mmcu=msp430x315:crt430x315.o%s} \
-+%{mmcu=msp430x323:crt430x323.o%s} \
-+%{mmcu=msp430x325:crt430x325.o%s} \
-+%{mmcu=msp430x336|mmcu=msp2:crt430x336.o%s} \
-+%{mmcu=msp430x337:crt430x337.o%s} \
-+%{mmcu=msp430x412:crt430x412.o%s} \
-+%{mmcu=msp430x413:crt430x413.o%s} \
-+%{mmcu=msp430x415:crt430x415.o%s} \
-+%{mmcu=msp430x417:crt430x417.o%s} \
-+%{mmcu=msp430x423:crt430x423.o%s} \
-+%{mmcu=msp430x425:crt430x425.o%s} \
-+%{mmcu=msp430x427:crt430x427.o%s} \
-+%{mmcu=msp430x4250:crt430x4250.o%s} \
-+%{mmcu=msp430x4260:crt430x4260.o%s} \
-+%{mmcu=msp430x4270:crt430x4270.o%s} \
-+%{mmcu=msp430xE423:crt430xE423.o%s} \
-+%{mmcu=msp430xE425:crt430xE425.o%s} \
-+%{mmcu=msp430xE427:crt430xE427.o%s} \
-+%{mmcu=msp430xW423:crt430xW423.o%s} \
-+%{mmcu=msp430xW425:crt430xW425.o%s} \
-+%{mmcu=msp430xW427:crt430xW427.o%s} \
-+%{mmcu=msp430xG437:crt430xG437.o%s} \
-+%{mmcu=msp430xG438:crt430xG438.o%s} \
-+%{mmcu=msp430xG439:crt430xG439.o%s} \
-+%{mmcu=msp430x435:crt430x435.o%s} \
-+%{mmcu=msp430x436:crt430x436.o%s} \
-+%{mmcu=msp430x437:crt430x437.o%s} \
-+%{mmcu=msp430x447:crt430x447.o%s} \
-+%{mmcu=msp430x448:crt430x448.o%s} \
-+%{mmcu=msp430x449:crt430x449.o%s} \
-+%{mmcu=msp430xG4616:crt430xG4616.o%s} \
-+%{mmcu=msp430xG4617:crt430xG4617.o%s} \
-+%{mmcu=msp430xG4618:crt430xG4618.o%s} \
-+%{mmcu=msp430xG4619:crt430xG4619.o%s}"
-+
-+
-+
-+#define CPP_MSP1_SPEC " -DMSP430_NO_HW_MUL "
-+#define CPP_MSP2_SPEC " -DMSP430_HAS_HW_MUL "
-+
-+#define EXTRA_SPECS                                   \
-+{"cpp_msp1",CPP_MSP1_SPEC},                   \
-+{"cpp_msp2",CPP_MSP2_SPEC},                   \
-+{"crt_binutils", CRT_BINUTILS_SPECS},
-+
-+/* Define this macro to provide additional specifications to put in
-+   the `specs' file that can be used in various specifications like
-+   `CC1_SPEC'.
-+
-+   The definition should be an initializer for an array of structures,
-+   containing a string constant, that defines the specification name,
-+   and a string constant that provides the specification.
-+
-+   Do not define this macro if it does not need to do anything.
-+
-+   `EXTRA_SPECS' is useful when an architecture contains several
-+   related targets, which have various `..._SPECS' which are similar
-+   to each other, and the maintainer would like one central place to
-+   keep these definitions.
-+
-+   For example, the PowerPC System V.4 targets use `EXTRA_SPECS' to
-+   define either `_CALL_SYSV' when the System V calling sequence is
-+   used or `_CALL_AIX' when the older AIX-based calling sequence is
-+   used.
-+
-+   The `config/rs6000/rs6000.h' target file defines:
-+
-+   #define EXTRA_SPECS \
-+   { "cpp_sysv_default", CPP_SYSV_DEFAULT },
-+
-+   #define CPP_SYS_DEFAULT ""
-+
-+   The `config/rs6000/sysv.h' target file defines:
-+   #undef CPP_SPEC
-+   #define CPP_SPEC \
-+   "%{posix: -D_POSIX_SOURCE } \
-+   %{mcall-sysv: -D_CALL_SYSV } %{mcall-aix: -D_CALL_AIX } \
-+   %{!mcall-sysv: %{!mcall-aix: %(cpp_sysv_default) }} \
-+   %{msoft-float: -D_SOFT_FLOAT} %{mcpu=403: -D_SOFT_FLOAT}"
-+
-+   #undef CPP_SYSV_DEFAULT
-+   #define CPP_SYSV_DEFAULT "-D_CALL_SYSV"
-+
-+   while the `config/rs6000/eabiaix.h' target file defines
-+   `CPP_SYSV_DEFAULT' as:
-+
-+   #undef CPP_SYSV_DEFAULT
-+   #define CPP_SYSV_DEFAULT "-D_CALL_AIX"  */
-+
-+
-+#define MULTILIB_DEFAULTS { "mmcu=msp430x110" }
-+
-+/* This is undefined macro for collect2 disabling */
-+#define LINKER_NAME "msp430-ld"
-+
-+#define TEST_HARD_REG_CLASS(CLASS, REGNO) \
-+  TEST_HARD_REG_BIT (reg_class_contents[ (int) (CLASS)], REGNO)
-+
-+/* Note that the other files fail to use these
-+   in some of the places where they should.  */
-+
-+#if defined(__STDC__) || defined(ALMOST_STDC)
-+#define AS2(a,b,c) #a " " #b "," #c
-+#define AS2C(b,c) " " #b "," #c
-+#define AS3(a,b,c,d) #a " " #b "," #c "," #d
-+#define AS1(a,b) #a " " #b
-+#else
-+#define AS1(a,b) "a   b"
-+#define AS2(a,b,c) "a b,c"
-+#define AS2C(b,c) " b,c"
-+#define AS3(a,b,c,d) "a       b,c,d"
-+#endif
-+#define OUT_AS1(a,b) output_asm_insn (AS1(a,b), operands)
-+#define OUT_AS2(a,b,c) output_asm_insn (AS2(a,b,c), operands)
-+#define CR_TAB "\n\t"
-+
-+/* Define this macro as a C statement that declares additional library
-+   routines renames existing ones. `init_optabs' calls this macro
-+   after initializing all the normal library routines.  */
-+
-+#define INIT_TARGET_OPTABS                            \
-+{                                                     \
-+  msp430_init_once ();                                        \
-+}
-+
-+#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
-+
-+/* Define to use software floating point emulator for REAL_ARITHMETIC and
-+   decimal <-> binary conversion. */
-+
-+#ifndef REAL_ARITHMETIC
-+#define REAL_ARITHMETIC
-+#endif
-+
-+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
-+#define DWARF2_DEBUGGING_INFO 1
-+#define OBJECT_FORMAT_ELF
-+
-+#define DBX_REGISTER_NUMBER(r) (r)
-+
-+/* Get the standard ELF stabs definitions.  */
-+#include "dbxelf.h"
-+
-+
-diff -urN -x CVS gcc-3.2.3.orig/gcc/config/msp430/msp430.md gcc-3.2.3/gcc/config/msp430/msp430.md
---- gcc-3.2.3.orig/gcc/config/msp430/msp430.md 1969-12-31 17:00:00.000000000 -0700
-+++ gcc-3.2.3/gcc/config/msp430/msp430.md      2008-08-22 09:17:00.000000000 -0600
-@@ -0,0 +1,4079 @@
-+;; -*- Mode: Scheme -*-
-+;;   Machine description for GNU compiler,
-+;;   for Texas Instruments msp430 MCUs
-+;;   Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
-+;;   Contributed by Dmitry Diky <diwil@mail.ru>
-+
-+;; This file is part of GCC.
-+
-+;; GCC is free software; you can redistribute it and/or modify
-+;; it under the terms of the GNU General Public License as published by
-+;; the Free Software Foundation; either version 2, or (at your option)
-+;; any later version.
-+
-+;; GCC is distributed in the hope that it will be useful,
-+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+;; GNU General Public License for more details.
-+
-+;; You should have received a copy of the GNU General Public License
-+;; along with GCC; see the file COPYING.  If not, write to
-+;; the Free Software Foundation, 59 Temple Place - Suite 330,
-+;; Boston, MA 02111-1307, USA.
-+
-+;; Special characters after '%':
-+;;  A  No effect (add 0).
-+;;  B  Add 1 to REG number, 2 to MEM address or CONST_INT.
-+;;  C    2                4
-+;;  D    3                6
-+;;  E  adds nothing to reg but used only with (mem:hi (reg:hi))
-+;;  F  no trim array
-+;;  M  Add 0 to address if using stack pointer
-+;;  N  Add 2 to address if using stack pointer
-+;;  Extra constarains:
-+;;  P  hardware constants: -1,0,+1,+2,+4,+8
-+;;  Q  Indexed destination register as X(Rn)
-+;;  R  Indexed source register as @Rn+
-+;;  S  Symbol reference for 'C' like: a = *b;
-+;;
-+
-+;; Unspec usage:
-+;; 3 - strlen
-+;; 0  - addc_reg
-+;; 5  - addc_any
-+;; 1  - bittest_lo
-+;; 2  - bittest_hi
-+;; 6  - bittest
-+;; 4  - swpb
-+;; 7  - bittest_b
-+;; 8  - move SF to SI with no conversion
-+
-+
-+;; Condition code settings.
-+
-+
-+(define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber,further,oper,cbranch"
-+  (const_string "none"))
-+
-+(define_attr "type" "branch,branch1,arith"
-+  (const_string "arith"))
-+
-+(define_attr "msp430_has_hwmul" "yes,no"
-+  (const (if_then_else (symbol_ref "MSP430_HAS_HWMUL_INTERNAL")
-+                     (const_string "yes")
-+                     (const_string "no"))))
-+
-+(define_attr "msp430_noint_hwmul" "" (symbol_ref "MSP430_NOINT_HWMUL"))
-+
-+;; The size of instructions in bytes.
-+;; XXX may depend from "cc"
-+
-+;; for confitional branches
-+(define_attr "length" ""
-+  (cond [(eq_attr "type" "branch")
-+         (if_then_else  (and (ge (minus (pc) (match_dup 0)) 
-+                                      (const_int -508))
-+                             (le (minus (pc) (match_dup 0)) 
-+                                      (const_int  508)))
-+                        (const_int 1)
-+                      (const_int 2))]
-+      (const_int 2)
-+))
-+
-+
-+;;========================================================================
-+;;  PUSH/POP helper functions
-+;;
-+
-+
-+(define_insn "*pushqi_pre_mod"
-+[(set (mem:QI (pre_modify:HI (reg:HI 1)
-+                (plus:HI (reg:HI 1) (const_int -2))))
-+      (match_operand:QI 0 "general_operand" "rim"))]
-+""
-+"* return msp430_pushqi(insn, operands, NULL);"
-+[(set_attr "length" "2")])
-+
-+(define_insn "*pushqi"
-+  [(set (mem:QI (post_dec (reg:HI 1)))
-+        (match_operand:QI 0 "general_operand" "rim"))]
-+  ""
-+  "* return msp430_pushqi(insn, operands, NULL);"
-+  [(set_attr "length" "2")])
-+
-+(define_insn "*pushhi"
-+  [(set (mem:HI (post_dec (reg:HI 1))) 
-+        (match_operand:HI 0 "general_operand" "rim"))]
-+  ""
-+  "* return msp430_pushhi(insn, operands, NULL);"
-+  [(set_attr "length" "2")])
-+
-+(define_insn "*pushsi"
-+  [(set (mem:SI (post_dec (reg:HI 1))) 
-+        (match_operand:SI 0 "general_operand" "rmi"))]
-+  ""
-+  "* return msp430_pushsisf(insn, operands, NULL);"
-+  [(set_attr "length" "4")])
-+
-+
-+(define_insn "*pushdi"
-+  [(set (mem:DI (post_dec (reg:HI 1)))
-+        (match_operand:DI 0 "general_operand" "rmi"))]
-+  ""
-+  "* return msp430_pushdi(insn, operands, NULL);"
-+  [(set_attr "length" "8")])
-+
-+
-+(define_insn "*pushsf"
-+  [(set (mem:SF (post_dec (reg:HI 1)))
-+        (match_operand:SF 0 "general_operand" "rmi"))]
-+  ""
-+  "* return msp430_pushsisf(insn, operands, NULL);"
-+  [(set_attr "length" "4")])
-+
-+
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "") 
-+      (match_operand:HI 1 "general_operand" ""))
-+   (set (mem:HI (post_dec (reg:HI 1)))
-+      (match_dup 0))]
-+"dead_or_set_in_peep(1, insn, operands[0])"
-+  [(set (mem:HI (post_dec (reg:HI 1)))
-+      (match_dup 1))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "") 
-+      (match_operand:SI 1 "general_operand" ""))
-+   (set (mem:SI (post_dec (reg:HI 1)))
-+      (match_dup 0))]
-+"dead_or_set_in_peep(1, insn, operands[0])"
-+  [(set (mem:SI (post_dec (reg:HI 1)))
-+      (match_dup 1))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:SF 0 "register_operand" "") 
-+      (match_operand:SF 1 "general_operand" ""))
-+   (set (mem:SF (post_dec (reg:HI 1)))
-+      (match_dup 0))]
-+"dead_or_set_in_peep(1, insn, operands[0])"
-+  [(set (mem:SF (post_dec (reg:HI 1)))
-+      (match_dup 1))]
-+"")
-+
-+
-+;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+;; This instructin sets Z flag
-+
-+(define_insn "sez"
-+  [(set (cc0) (const_int 0))]
-+""
-+"setz"
-+  [(set_attr "length" "1")
-+   (set_attr "cc" "compare")])
-+
-+
-+
-+;;========================================================================
-+;; compare
-+
-+(define_expand "cmpqi"
-+  [(set (cc0)
-+        (compare:QI (match_operand:QI 0 "nonimmediate_operand_msp430" "rm")   
-+                    (match_operand:QI 1 "general_operand_msp430" "rmi")))]
-+ ""
-+"
-+  msp430_compare_op0 = operands[0];
-+  msp430_compare_op1 = operands[1];
-+  DONE;
-+")
-+
-+
-+(define_expand "cmphi"
-+  [(set (cc0)
-+        (compare:HI (match_operand:HI 0 "nonimmediate_operand_msp430" "rm")   
-+                    (match_operand:HI 1 "general_operand_msp430" "rmi")))]
-+ ""
-+"
-+  msp430_compare_op0 = operands[0];
-+  msp430_compare_op1 = operands[1];
-+  DONE;
-+")
-+
-+
-+(define_expand "cmpsi"
-+   [(set (cc0)
-+         (compare:SI (match_operand:SI 0 "nonimmediate_operand" "rm")
-+                     (match_operand:SI 1 "general_operand" "rmi")))]
-+   ""
-+"
-+  msp430_compare_op0 = operands[0];
-+  msp430_compare_op1 = operands[1];
-+  DONE;
-+")
-+
-+
-+(define_expand "beq"
-+   [(use (match_operand 0 "" ""))]
-+""
-+"{ msp430_emit_cbranch (EQ, operands[0]); DONE; }")
-+
-+(define_expand "bne"
-+   [(use (match_operand 0 "" ""))]
-+""
-+"{ msp430_emit_cbranch (NE, operands[0]); DONE; }")
-+
-+(define_expand "bge"
-+   [(use (match_operand 0 "" ""))]
-+""
-+"{ msp430_emit_cbranch (GE, operands[0]); DONE; }")
-+
-+(define_expand "bgt"
-+   [(use (match_operand 0 "" ""))]
-+""
-+"{ msp430_emit_cbranch (GT, operands[0]); DONE; }")
-+
-+(define_expand "ble"
-+   [(use (match_operand 0 "" ""))]
-+""
-+"{ msp430_emit_cbranch (LE, operands[0]); DONE; }")
-+
-+(define_expand "blt"
-+   [(use (match_operand 0 "" ""))]
-+""
-+"{ msp430_emit_cbranch (LT, operands[0]); DONE; }")
-+
-+(define_expand "bgeu"
-+   [(use (match_operand 0 "" ""))]
-+""
-+"{ msp430_emit_cbranch (GEU, operands[0]); DONE; }")
-+
-+(define_expand "bgtu"
-+   [(use (match_operand 0 "" ""))]
-+""
-+"{ msp430_emit_cbranch (GTU, operands[0]); DONE; }")
-+
-+(define_expand "bleu"
-+   [(use (match_operand 0 "" ""))]
-+""
-+"{ msp430_emit_cbranch (LEU, operands[0]); DONE; }")
-+
-+(define_expand "bltu"
-+   [(use (match_operand 0 "" ""))]
-+""
-+"{ msp430_emit_cbranch (LTU, operands[0]); DONE; }")
-+
-+
-+(define_insn "*cbranchqi"
-+  [(set (pc)
-+     (if_then_else (match_operator:QI 1 "comparison_operator"
-+                  [(match_operand:QI 2 "nonimmediate_operand_msp430" "rm")
-+                   (match_operand:QI 3 "general_operand" "rmi")])
-+      (label_ref (match_operand 0 "" ""))
-+      (pc)))]
-+""
-+"* return msp430_cbranch(insn, operands, NULL);"
-+ [(set_attr "length" "9") 
-+ (set_attr "cc" "cbranch")])
-+
-+
-+
-+(define_insn "*cbranchhi"
-+  [(set (pc)
-+     (if_then_else (match_operator:HI 1 "comparison_operator"
-+                  [(match_operand:HI 2 "nonimmediate_operand_msp430" "rm")
-+                   (match_operand:HI 3 "general_operand" "rmi")])
-+      (label_ref (match_operand 0 "" ""))
-+      (pc)))]
-+""
-+"* return msp430_cbranch(insn, operands, NULL);"
-+ [(set_attr "length" "9")
-+ (set_attr "cc" "cbranch")])
-+
-+
-+(define_insn "*cbranchsi_eqne"
-+  [(set (pc)
-+     (if_then_else (match_operator:SI 1 "equality_operator"
-+                  [(match_operand:SI 2 "nonimmediate_operand" "rm")
-+                   (match_operand:SI 3 "general_operand" "rmi")])
-+      (label_ref (match_operand 0 "" ""))
-+      (pc)))]
-+""
-+"* return msp430_cbranch(insn, operands, NULL);"
-+[(set_attr "length" "9")
-+ (set_attr "cc" "cbranch")])
-+
-+
-+(define_insn "*cbranchsi_others"
-+  [(parallel [(set (pc)
-+     (if_then_else (match_operator:SI 1 "inequality_operator"
-+                  [(match_operand:SI 2 "register_operand" "r")
-+                   (match_operand:SI 3 "general_operand" "rmi")])
-+      (label_ref (match_operand 0 "" ""))
-+      (pc)))
-+  (clobber (match_dup 2))])]
-+""
-+"* return msp430_cbranch(insn, operands, NULL);"
-+[(set_attr "length" "9")
-+ (set_attr "cc" "cbranch")])
-+
-+
-+(define_insn "*cbranch_uncoded"
-+  [(set (pc)
-+     (if_then_else (match_operator 1 "comparison_operator"
-+                  [(cc0)
-+                   (const_int 0)])
-+      (label_ref (match_operand 0 "" ""))
-+      (pc)))]
-+""
-+"* return msp430_cbranch(insn, operands, NULL);"
-+[(set_attr "length" "9")
-+(set_attr "cc" "cbranch")])
-+
-+
-+;;========================================================================
-+;; noop
-+(define_insn "nop"
-+  [(const_int 0)]
-+  ""
-+  "nop"
-+  [(set_attr "cc" "none")
-+   (set_attr "length" "1")])
-+
-+
-+;;============================================================================
-+;; call
-+;;
-+
-+(define_expand "call"
-+  [(call (match_operand:HI 0 "general_operand" "")
-+         (match_operand:HI 1 "general_operand" ""))]
-+  ""
-+  "")
-+
-+(define_insn "*call_insn"
-+  [(call (mem:HI (match_operand:HI 0 "general_operand" "r,P,mi"))
-+         (match_operand:HI 1 "general_operand" "X,X,X"))]
-+""
-+"call\\t%0"
-+[ (set_attr "length" "1,1,2")
-+   (set_attr "cc" "clobber")])
-+
-+
-+(define_expand "call_value"
-+  [(set (match_operand 0 "register_operand" "")
-+        (call (match_operand:HI 1 "general_operand" "")
-+              (match_operand:HI 2 "general_operand" "")))]
-+  ""
-+  "")
-+
-+(define_insn "*call_value_insn"
-+  [( set (match_operand 0 "register_operand" "=r,r,r")
-+   (call (mem:HI (match_operand:HI 1 "general_operand" "r,P,mi"))
-+       (match_operand:HI 2 "general_operand" "X,X,X")))]
-+""
-+ "call\\t%N1"
-+[ (set_attr "length" "1,1,2")
-+   (set_attr "cc" "clobber")])
-+
-+
-+
-+
-+
-+;;========================================================================
-+;;========================================================================
-+;; mult helpers
-+
-+(define_insn "reent_in"
-+  [(set (mem:HI (post_dec (reg:HI 1))) 
-+        (unspec_volatile:HI [(const_int 99999999)] 10))]
-+  ""
-+  "push\\tr2
-+\\tdint
-+\\tnop"
-+  [(set_attr "length" "4")
-+   (set_attr "cc" "clobber")])
-+
-+;;
-+;; Next three help to make sure, that
-+;; all instructions are 'in order'
-+
-+(define_insn "fetch_result_qi"
-+ [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=r,m") 
-+       (unspec_volatile:QI [(const_int 0)] 12))
-+  (set (mem:HI (post_inc (reg:HI 1)))
-+      (unspec_volatile:HI [(const_int 99999999)] 11))]
-+ ""
-+ "mov.b\\t&__RESLO, %0
-+\\tpop\\tr2"
-+ [(set_attr "length" "3,4")
-+  (set_attr "cc" "none")])
-+ 
-+(define_insn "fetch_result_hi"
-+ [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m") 
-+       (unspec_volatile:HI [(const_int 0)] 13))
-+  (set (mem:HI (post_inc (reg:HI 1)))
-+      (unspec_volatile:HI [(const_int 99999999)] 11))]
-+ ""
-+ "mov\\t&__RESLO, %0
-+\\tpop\\tr2"
-+ [(set_attr "length" "3,4")
-+  (set_attr "cc" "none")])
-+
-+(define_insn "fetch_result_si"
-+ [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "=r,m") 
-+       (unspec_volatile:SI [(const_int 0)] 14))
-+  (set (mem:HI (post_inc (reg:HI 1)))
-+      (unspec_volatile:HI [(const_int 99999999)] 11))]
-+ ""
-+ "mov\\t&__RESLO, %A0
-+\\tmov\\t&__RESHI, %B0
-+\\tpop\\tr2"
-+ [(set_attr "length" "5,7")
-+  (set_attr "cc" "none")])
-+
-+;; ===the same with no int
-+
-+(define_insn "fetch_result_qi_nint"
-+ [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=r,m") 
-+       (unspec_volatile:QI [(const_int 0)] 121))]
-+ ""
-+ "mov.b\\t&__RESLO, %0"
-+ [(set_attr "length" "2,3")
-+  (set_attr "cc" "none")])
-+ 
-+(define_insn "fetch_result_hi_nint"
-+ [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m") 
-+       (unspec_volatile:HI [(const_int 0)] 131))]
-+ ""
-+ "mov\\t&__RESLO, %0"
-+ [(set_attr "length" "2,3")
-+  (set_attr "cc" "none")])
-+
-+(define_insn "fetch_result_si_nint"
-+ [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "=r,m") 
-+       (unspec_volatile:SI [(const_int 0)] 141))]
-+ ""
-+ "mov\\t&__RESLO, %A0
-+\\tmov\\t&__RESHI, %B0"
-+ [(set_attr "length" "4,6")
-+  (set_attr "cc" "none")])
-+
-+(define_insn "addc_zero"
-+ [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m")
-+   (unspec_volatile:HI [(const_int 0 )] 15))]
-+ ""
-+ "addc\\t#0, %0"
-+[(set_attr "length" "1,2")
-+ (set_attr "cc" "none")])
-+
-+(define_insn "subc_zero"
-+ [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m")
-+   (unspec:HI [(const_int 0 )] 16))]
-+ ""
-+ "subc\\t#0, %0"
-+[(set_attr "length" "1,2")
-+ (set_attr "cc" "none")])
-+
-+(define_insn "load_mpy"
-+ [(unspec_volatile:HI [(const_int 0)] 17)
-+  (use (match_operand:HI 0 "general_operand_msp430" "rRP,mi"))]
-+""
-+"mov\\t%0, &__MPY"
-+[(set_attr "length" "2,3")
-+ (set_attr "cc" "none")])
-+
-+
-+(define_insn "load_mpys"
-+  [(unspec_volatile:HI [(const_int 0)] 18)
-+   (use (match_operand:HI 0 "general_operand_msp430" "rRP,mi"))]
-+""
-+"mov\\t%0, &__MPYS"
-+[(set_attr "length" "2,3")
-+ (set_attr "cc" "none")])
-+ 
-+ 
-+(define_insn "load_op2"
-+  [(unspec_volatile:HI [(const_int 0)] 19)
-+   (use (match_operand:HI 0 "general_operand_msp430" "rRP,mi"))]
-+""
-+"mov\\t%0, &__OP2"
-+[(set_attr "length" "2,3")
-+ (set_attr "cc" "none")])
-+ 
-+
-+(define_insn "load_mpyq"
-+  [(unspec_volatile:QI [(const_int 0 )] 20)
-+   (use (match_operand:QI 0 "general_operand_msp430" "rRP,mi"))]
-+""
-+"mov.b\\t%0, &__MPY"
-+[(set_attr "length" "2,3")
-+ (set_attr "cc" "none")])
-+
-+
-+(define_insn "load_mpysq"
-+  [(unspec_volatile:QI [(const_int 0 )] 21)
-+   (use (match_operand:QI 0 "general_operand_msp430" "rRP,mi"))]
-+""
-+"mov.b\\t%0, &__MPYS"
-+[(set_attr "length" "2,3")
-+ (set_attr "cc" "none")])
-+ 
-+(define_insn "load_op2q"
-+  [(unspec_volatile:QI [(const_int 0 )] 22)
-+  (use (match_operand:QI 0 "general_operand_msp430" "rRP,mi"))]
-+""
-+"mov.b\\t%0, &__OP2"
-+[(set_attr "length" "2,3")
-+ (set_attr "cc" "none")])
-+
-+
-+
-+
-+ 
-+
-+;;========================================================================
-+;;========================================================================
-+;;========================================================================
-+;;
-+;;  Multiplication 
-+
-+;;========================================================================
-+;; 8 = 8x8 and 16 = 8x8
-+
-+(define_expand "mulqi3"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
-+        (mult:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "")
-+                 (match_operand:QI 2 "general_operand_msp430" "")))]  
-+  ""             
-+"{ msp430_mul3_guard(operands,0); DONE; }")
-+
-+(define_insn "*mulqi3_call"
-+  [(set (reg:QI 14) (mult:QI (reg:QI 10) (reg:QI 12)))
-+      (clobber (reg:QI 10))
-+      (clobber (reg:QI 12))]
-+  "!MSP430_HAS_HWMUL_INTERNAL"
-+  "call       #__mulqi3"
-+  [(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-+
-+;; ============= qi -> hi =======================================================
-+(define_expand "mulqihi3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
-+        (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand_msp430" ""))
-+                 (sign_extend:HI (match_operand:QI 2 "general_operand_msp430" ""))))]
-+""
-+"{ msp430_mul3_guard(operands,1); DONE; }")
-+
-+(define_insn "*mulqihi3_call"
-+  [(set (reg:HI 14) (mult:HI (sign_extend:HI (reg:QI 10))
-+                           (sign_extend:HI (reg:QI 12))))
-+        (clobber (reg:QI 10))
-+        (clobber (reg:QI 12))]
-+  "!MSP430_HAS_HWMUL_INTERNAL"
-+  "call       #__mulqihi3"   
-+  [(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-+
-+;; ============ unsigned ones ===================================================
-+(define_expand "umulqihi3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
-+        (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand_msp430" ""))
-+                 (zero_extend:HI (match_operand:QI 2 "general_operand_msp430" ""))))]
-+  ""
-+  "{ msp430_umul3_guard(operands,0); DONE; }")  
-+
-+(define_insn "*umulqihi3_call"
-+  [(set (reg:HI 14) (mult:HI (zero_extend:HI (reg:QI 10))
-+                           (zero_extend:HI (reg:QI 12))))
-+        (clobber (reg:QI 10))
-+        (clobber (reg:QI 12))]
-+  "!MSP430_HAS_HWMUL_INTERNAL"
-+  "call       #__umulqihi3" 
-+  [(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-+
-+;;========================================================================
-+;; 16 = 16x16 and 32 = 16x16
-+
-+(define_expand "mulhi3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
-+        (mult:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "")
-+                 (match_operand:HI 2 "general_operand_msp430" "")))]  
-+  ""
-+"{msp430_mul3_guard(operands,0); DONE; } ")
-+
-+(define_insn "*mulhi3_call"
-+  [(set (reg:HI 14) (mult:HI (reg:HI 10) (reg:HI 12)))
-+      (clobber (reg:HI 10))
-+      (clobber (reg:HI 12))]
-+  "!MSP430_HAS_HWMUL_INTERNAL"
-+  "call       #__mulhi3"
-+  [(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-+
-+;; ========================== hi -> si =============================
-+(define_expand "mulhisi3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "")
-+        (mult:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand_msp430" ""))
-+                 (sign_extend:SI (match_operand:HI 2 "general_operand_msp430" ""))))]
-+""
-+  "{msp430_mulhisi_guard(operands); DONE;}"
-+)
-+
-+(define_insn "*mulhisi3_call"
-+  [(set (reg:SI 14) (mult:SI (sign_extend:SI (reg:HI 10))
-+                           (sign_extend:SI (reg:HI 12))))
-+        (clobber (reg:HI 10))
-+        (clobber (reg:HI 11))
-+      (clobber (reg:HI 12))  
-+      (clobber (reg:HI 13))]
-+  "!MSP430_HAS_HWMUL_INTERNAL"
-+  "mov        #0, r11
-+      tst     r10
-+      jge     +2
-+      mov     #-1, r11
-+      mov     #0, r13
-+      tst     r12
-+      jge     +2
-+      mov     #-1, r13
-+      call    #__mulhisi3"
-+  [(set_attr "length" "10")
-+   (set_attr "cc" "clobber")])
-+
-+;; ================== unsigned  hi -> si =============================
-+(define_expand "umulhisi3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "")
-+        (mult:SI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand_msp430" ""))
-+                 (zero_extend:SI (match_operand:HI 2 "general_operand_msp430" ""))))]
-+  ""
-+  "{msp430_umulhisi_guard(operands); DONE;}")
-+
-+(define_insn "*umulhisi3_call"
-+  [(set (reg:SI 14) (mult:SI (zero_extend:SI (reg:HI 10))
-+                           (zero_extend:SI (reg:HI 12))))
-+        (clobber (reg:HI 10))
-+        (clobber (reg:HI 11))
-+      (clobber (reg:HI 12))  
-+      (clobber (reg:HI 13))]
-+  "!MSP430_HAS_HWMUL_INTERNAL"
-+  "clr        r11
-+      clr     r13
-+      call    #__umulhisi3" 
-+  [(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-+
-+
-+;;========================================================================
-+;; 32 = 32x32.      64 = 32x32 <- via library calls only
-+
-+(define_expand "mulsi3"
-+  [(set (reg:SI 10) (match_operand:SI 1 "nonimmediate_operand_msp430" ""))
-+   (set (reg:SI 12) (match_operand:SI 2 "general_operand_msp430" ""))
-+   (set (reg:SI 14) (mult:SI (reg:SI 10) (reg:SI 12)))
-+   (set (match_operand:SI 0 "nonimmediate_operand_msp430" "") (reg:SI 14))]
-+""
-+"{
-+  if (!MSP430_HAS_HWMUL_INTERNAL)
-+    {
-+      emit_insn (gen_mulsi3_call (operands[0], operands[1], operands[2]));
-+      DONE;
-+    }
-+}")
-+
-+(define_insn "*mulsi3hw_call_ni"
-+  [(set (reg:SI 14) (mult:SI (reg:SI 10) (reg:SI 12)))]
-+  "(!TARGET_INLINESIHWMUL) && MSP430_NOINT_HWMUL"
-+  "call       #__umulsi3hw"
-+[(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "*mulsi3hw_call_ie"
-+  [(set (reg:SI 14) (mult:SI (reg:SI 10) (reg:SI 12)))]
-+  "(!TARGET_INLINESIHWMUL) && !MSP430_NOINT_HWMUL"
-+  "push       r2
-+      dint
-+      call    #__umulsi3hw
-+      pop     r2"
-+[(set_attr "length" "5")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "*mulsi3hw_inline_ni"
-+  [(set (reg:SI 14) (mult:SI (reg:SI 10) (reg:SI 12)))]
-+  "TARGET_INLINESIHWMUL && MSP430_HAS_HWMUL_INTERNAL && MSP430_NOINT_HWMUL"
-+  "mov        r12, &__MPY
-+      mov     r10, &__OP2
-+      mov     r12, &__MAC
-+      mov     &__RESLO, r14
-+      mov     &__RESHI, &__RESLO
-+      mov     r11, &__OP2
-+      mov     r13, &__MAC
-+      mov     r10, &__OP2
-+      mov     &__RESLO, r15"
-+[(set_attr "length" "19")  
-+   (set_attr "cc" "none")])
-+
-+(define_insn "*mulsi3hw_inline_ie"
-+  [(set (reg:SI 14) (mult:SI (reg:SI 10) (reg:SI 12)))]
-+  "TARGET_INLINESIHWMUL && MSP430_HAS_HWMUL_INTERNAL && !MSP430_NOINT_HWMUL"
-+  "push       r2
-+      dint
-+      nop
-+      mov     r12, &__MPY
-+      mov     r10, &__OP2
-+      mov     r12, &__MAC
-+      mov     &__RESLO, r14
-+      mov     &__RESHI, &__RESLO
-+      mov     r11, &__OP2
-+      mov     r13, &__MAC
-+      mov     r10, &__OP2
-+      mov     &__RESLO, r15
-+      pop     r2"
-+[(set_attr "length" "23")  
-+   (set_attr "cc" "none")])
-+
-+(define_expand "mulsi3_call"
-+  [(set (reg:SI 10) (match_operand:SI 1 "register_operand" ""))
-+   (set (reg:SI 12) (match_operand:SI 2 "register_operand" "")) 
-+   (parallel [(set (reg:SI 14) (mult:SI (reg:SI 10) (reg:SI 12)))
-+        (clobber (reg:SI 10))
-+        (clobber (reg:SI 12))])
-+   (set (match_operand:SI 0 "register_operand" "") (reg:SI 14))]
-+"!MSP430_HAS_HWMUL_INTERNAL"
-+"")
-+
-+(define_insn "*mulsi3_call"
-+  [(set (reg:SI 14) (mult:SI (reg:SI 10) (reg:SI 12)))
-+      (clobber (reg:SI 10))
-+      (clobber (reg:SI 12))]
-+  "!MSP430_HAS_HWMUL_INTERNAL"
-+  "call       #__mulsi3"
-+  [(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-+
-+
-+;; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % /
-+;; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % /
-+;; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % /
-+;; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % /
-+
-+(define_expand "divmodqi4"
-+  [(set (reg:QI 12) (match_operand:QI 1 "register_operand" ""))
-+   (set (reg:QI 10) (match_operand:QI 2 "register_operand" ""))
-+   (parallel [(set (reg:QI 12) (div:QI (reg:QI 12) (reg:QI 10)))
-+              (set (reg:QI 14) (mod:QI (reg:QI 12) (reg:QI 10)))
-+              (clobber (reg:QI 10))
-+              (clobber (reg:QI 11))
-+            (clobber (reg:QI 13))])
-+   (set (match_operand:QI 0 "register_operand" "") (reg:QI 12))
-+   (set (match_operand:QI 3 "register_operand" "") (reg:QI 14))]
-+  ""
-+  "")
-+
-+(define_insn "*divmodqi4_call"
-+  [(set (reg:QI 12) (div:QI (reg:QI 12) (reg:QI 10)))
-+   (set (reg:QI 14) (mod:QI (reg:QI 12) (reg:QI 10)))
-+   (clobber (reg:QI 10))
-+   (clobber (reg:QI 11))
-+   (clobber (reg:QI 13))]
-+  ""
-+  "call       #__divmodqi4"
-+   [(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-+
-+(define_expand "udivmodqi4"
-+  [(set (reg:QI 12) (match_operand:QI 1 "register_operand" ""))
-+   (set (reg:QI 10) (match_operand:QI 2 "register_operand" ""))
-+   (parallel [(set (reg:QI 12) (udiv:QI (reg:QI 12) (reg:QI 10)))
-+              (set (reg:QI 14) (umod:QI (reg:QI 12) (reg:QI 10)))
-+              (clobber (reg:QI 10))
-+              (clobber (reg:QI 11)) 
-+              (clobber (reg:QI 13))])
-+   (set (match_operand:QI 0 "register_operand" "") (reg:QI 12))
-+   (set (match_operand:QI 3 "register_operand" "") (reg:QI 14))]
-+  ""
-+  "")
-+
-+(define_insn "*udivmodqi4_call"
-+  [(set (reg:QI 12) (udiv:QI (reg:QI 12) (reg:QI 10)))
-+   (set (reg:QI 14) (umod:QI (reg:QI 12) (reg:QI 10)))
-+   (clobber (reg:QI 10))
-+   (clobber (reg:QI 11)) 
-+   (clobber (reg:QI 13))]
-+  ""
-+  "call       #__udivmodqi4"
-+   [(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-+
-+
-+(define_expand "divmodhi4"
-+  [(set (reg:HI 12) (match_operand:HI 1 "register_operand" ""))
-+   (set (reg:HI 10) (match_operand:HI 2 "register_operand" ""))
-+   (parallel [(set (reg:HI 12) (div:HI (reg:HI 12) (reg:HI 10)))
-+              (set (reg:HI 14) (mod:HI (reg:HI 12) (reg:HI 10)))
-+              (clobber (reg:HI 10))
-+              (clobber (reg:HI 11))
-+            (clobber (reg:HI 13))])
-+   (set (match_operand:HI 0 "register_operand" "") (reg:HI 12))
-+   (set (match_operand:HI 3 "register_operand" "") (reg:HI 14))]
-+  ""
-+  "")
-+
-+(define_insn "*divmodhi4_call"
-+  [(set (reg:HI 12) (div:HI (reg:HI 12) (reg:HI 10)))
-+   (set (reg:HI 14) (mod:HI (reg:HI 12) (reg:HI 10)))
-+   (clobber (reg:HI 10))
-+   (clobber (reg:HI 11))
-+   (clobber (reg:HI 13))]
-+  ""
-+  "call       #__divmodhi4"
-+   [(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-+
-+(define_expand "udivmodhi4"
-+  [(set (reg:HI 12) (match_operand:HI 1 "register_operand" ""))
-+   (set (reg:HI 10) (match_operand:HI 2 "register_operand" ""))
-+   (parallel [(set (reg:HI 12) (udiv:HI (reg:HI 12) (reg:HI 10)))
-+              (set (reg:HI 14) (umod:HI (reg:HI 12) (reg:HI 10)))
-+              (clobber (reg:HI 10))
-+              (clobber (reg:HI 11)) 
-+              (clobber (reg:HI 13))])
-+   (set (match_operand:HI 0 "register_operand" "") (reg:HI 12))
-+   (set (match_operand:HI 3 "register_operand" "") (reg:HI 14))]
-+  ""
-+  "")
-+
-+(define_insn "*udivmodhi4_call"
-+  [(set (reg:HI 12) (udiv:HI (reg:HI 12) (reg:HI 10)))
-+   (set (reg:HI 14) (umod:HI (reg:HI 12) (reg:HI 10)))
-+   (clobber (reg:HI 10))
-+   (clobber (reg:HI 11)) 
-+   (clobber (reg:HI 13))]
-+  ""
-+  "call       #__udivmodhi4"
-+   [(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-+
-+
-+;; ///////////////// SINGLE INTEGER %%%%%%%%%%%%%%%%%
-+
-+(define_expand "divmodsi4"
-+  [(set (reg:SI 12) (match_operand:SI 1 "register_operand" ""))
-+   (set (reg:SI 10) (match_operand:SI 2 "register_operand" ""))
-+   (parallel [(set (reg:SI 12) (div:SI (reg:SI 12) (reg:SI 10)))
-+              (set (reg:SI 14) (mod:SI (reg:SI 12) (reg:SI 10)))
-+              (clobber (reg:SI 10))
-+              (clobber (reg:HI 9))
-+            (clobber (reg:HI 8))])
-+   (set (match_operand:SI 0 "register_operand" "") (reg:SI 12))
-+   (set (match_operand:SI 3 "register_operand" "") (reg:SI 14))]
-+  ""
-+  "")
-+
-+(define_insn "*divmodsi4_call"
-+  [(set (reg:SI 12) (div:SI (reg:SI 12) (reg:SI 10)))
-+   (set (reg:SI 14) (mod:SI (reg:SI 12) (reg:SI 10)))
-+   (clobber (reg:SI 10))
-+   (clobber (reg:HI 9))
-+   (clobber (reg:HI 8))]
-+  ""
-+  "call       #__divmodsi4"
-+   [(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-+
-+(define_expand "udivmodsi4"
-+  [(set (reg:SI 12) (match_operand:SI 1 "register_operand" ""))
-+   (set (reg:SI 10) (match_operand:SI 2 "register_operand" ""))
-+   (parallel [(set (reg:SI 12) (udiv:SI (reg:SI 12) (reg:SI 10)))
-+              (set (reg:SI 14) (umod:SI (reg:SI 12) (reg:SI 10)))
-+              (clobber (reg:SI 10))
-+              (clobber (reg:HI 9)) 
-+              (clobber (reg:HI 8))])
-+   (set (match_operand:SI 0 "register_operand" "") (reg:SI 12))
-+   (set (match_operand:SI 3 "register_operand" "") (reg:SI 14))]
-+  ""
-+  "")
-+
-+(define_insn "*udivmodsi4_call"
-+  [(set (reg:SI 12) (udiv:SI (reg:SI 12) (reg:SI 10)))
-+   (set (reg:SI 14) (umod:SI (reg:SI 12) (reg:SI 10)))
-+   (clobber (reg:SI 10))
-+   (clobber (reg:HI 9)) 
-+   (clobber (reg:HI 8))]
-+  ""
-+  "call       #__udivmodsi4"
-+   [(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-+
-+
-+
-+
-+;;========================================================================
-+;; MOV STRING
-+;;   structures and stuff are word aligned.
-+;;   so, QI mode only defined (as HI actually)
-+;;
-+
-+(define_expand "movstrhi"
-+  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
-+                   (match_operand:BLK 1 "memory_operand" ""))
-+              (use (match_operand 2 "const_int_operand" ""))
-+              (use (match_operand 3 "const_int_operand" ""))
-+              (clobber (match_dup 4))
-+              (clobber (match_dup 5))
-+              (clobber (match_dup 6))])]
-+  ""
-+  " 
-+{   
-+  rtx addr0, addr1;
-+  rtx a0, a1;
-+  
-+  if (GET_CODE (operands[2]) != CONST_INT) FAIL;
-+
-+  addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
-+  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
-+  
-+  a0 = operands[0];
-+  a1 = operands[1];
-+  
-+  operands[5] = addr0;
-+  operands[6] = addr1;
-+
-+  operands[0] = gen_rtx (MEM, BLKmode, addr0);
-+  operands[1] = gen_rtx (MEM, BLKmode, addr1);
-+
-+  if(INTVAL (operands[2]) <= 10 && !(INTVAL(operands[3])&1))
-+  {
-+    int x = INTVAL (operands[2]);
-+    int y = (x&~1) >> 1;
-+    int i = 0;
-+     
-+    while(y--)
-+    {
-+      rtx dest = gen_rtx (MEM, HImode, gen_rtx_PLUS(HImode, addr0,GEN_INT(i)));
-+      emit_insn(gen_movstrhi5(dest,addr1));
-+      i+= 2;
-+    }
-+
-+    if(x & 1)
-+    {
-+      rtx real_dst = gen_rtx (MEM, HImode, gen_rtx_PLUS(HImode, addr0,GEN_INT(x-1)));
-+      emit_insn(gen_movstrqi5(real_dst,addr1));
-+    }
-+    DONE;
-+  }
-+  else if(INTVAL (operands[2]) <= 6 && (INTVAL(operands[3])&1))
-+  {
-+    int x = INTVAL (operands[2]);
-+    int i = 0;
-+    
-+    while(x--)
-+    {
-+      rtx dst = gen_rtx (MEM, HImode, gen_rtx_PLUS(HImode, addr0,GEN_INT(i)));
-+      emit_insn(gen_movstrqi5(dst,addr1));
-+      i++;
-+    }
-+    DONE;
-+  }
-+  else
-+  {
-+      operands[2] = copy_to_mode_reg (HImode, operands[2]);
-+      operands[4] = operands[2];
-+  }
-+}
-+")
-+
-+(define_insn "movstrqi5"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=m")
-+      (mem:HI (match_operand:HI 1 "register_operand" "+r")))
-+      (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
-+  ""
-+  "mov.b      @%1+, %0"
-+[(set_attr "length" "2")
-+ (set_attr "cc" "clobber")])
-+
-+(define_insn "movstrhi5"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=m")
-+      (mem:HI (match_operand:HI 1 "register_operand" "+r")))
-+      (set (match_dup 1) (plus:HI (match_dup 1) (const_int 2)))]
-+ ""
-+ "mov @%1+, %0"
-+ [(set_attr "length" "2")
-+ (set_attr "cc" "clobber")])
-+
-+(define_insn "*movstrhi_insn"
-+  [(set (mem:BLK (match_operand:HI 0 "register_operand" "r"))
-+        (mem:BLK (match_operand:HI 1 "register_operand" "r")))
-+   (use (match_operand:HI 2 "register_operand" "r"))
-+   (use (match_operand 3 "const_int_operand" "i"))
-+   (clobber (match_dup 2))
-+   (clobber (match_dup 0))
-+   (clobber (match_dup 1))]
-+  ""
-+  "* return movstrhi_insn(insn, operands, NULL);"
-+  [(set_attr "length" "6")
-+   (set_attr "cc" "clobber")])
-+
-+
-+(define_insn "*movstrqi_insn"
-+  [(set (mem:BLK (match_operand:HI 0 "register_operand" "r"))
-+        (mem:BLK (match_operand:HI 1 "register_operand" "r")))
-+   (use (match_operand:QI 2 "register_operand" "r"))
-+   (use (match_operand 3 "const_int_operand" "i"))
-+   (clobber (match_dup 2))
-+   (clobber (match_dup 0))
-+   (clobber (match_dup 1))]
-+  ""
-+  "* return movstrhi_insn(insn, operands, NULL);"
-+  [(set_attr "length" "6")
-+   (set_attr "cc" "clobber")])
-+
-+
-+
-+;;========================================================================
-+;; CLEAR STRING
-+
-+(define_expand "clrstrhi"
-+  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
-+                   (const_int 0))
-+              (use (match_operand 1 "const_int_operand" ""))
-+              (use (match_operand 2 "const_int_operand" "i"))
-+              (clobber (match_dup 3))
-+              (clobber (match_dup 4))])]
-+  ""
-+  " 
-+{
-+  rtx addr0;
-+
-+  if (GET_CODE (operands[1]) != CONST_INT) FAIL;
-+  operands[1] = copy_to_mode_reg (HImode, operands[1]);
-+  operands[3] = operands[1];
-+  addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
-+  operands[4] = addr0;
-+  operands[0] = gen_rtx (MEM, BLKmode, addr0);
-+}")
-+
-+
-+(define_insn "*clrstrhi_insn"
-+  [(set (mem:BLK (match_operand:HI 0 "register_operand" "r"))
-+        (const_int 0))
-+   (use (match_operand:HI 1 "register_operand" "r")) 
-+   (use (match_operand 2 "const_int_operand" "i"))
-+   (clobber (match_dup 1)) 
-+   (clobber (match_dup 0))]
-+  ""
-+  "* return clrstrhi_insn(insn, operands, NULL);"
-+[(set_attr "length" "6")
-+   (set_attr "cc" "clobber")])
-+
-+
-+;;========================================================================
-+;; %0 = strchr(%1,%2) - %1
-+
-+(define_expand "strlenhi"
-+  [(set (match_dup 4)
-+            (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
-+                        (match_operand 2 "const_int_operand" "")
-+                        (match_operand:HI 3 "immediate_operand" "")] 3))
-+     (set (match_operand:HI 0 "register_operand" "")
-+          (minus:HI (match_dup 4)
-+                    (match_dup 5)))]
-+
-+   ""
-+   "
-+{
-+  rtx addr;
-+
-+  if (! (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
-+      FAIL;
-+  addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
-+  operands[1] = gen_rtx (MEM, BLKmode, addr); 
-+  operands[5] = addr;
-+  operands[4] = gen_reg_rtx (HImode);
-+
-+}")
-+
-+
-+(define_insn "*strlenhi"
-+ [(set (match_operand:HI 0 "register_operand" "=r")
-+        (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
-+                    (const_int 0)
-+                  (match_operand:HI 2 "immediate_operand" "i") ] 3))]
-+  ""
-+"dec  %0
-+.L__strlenhi__%=:
-+      inc     %0
-+      tst.b   0(%0)
-+        jne   .L__strlenhi__%="
-+[(set_attr "length" "5")
-+   (set_attr "cc" "clobber")])
-+
-+
-+;;========================================================================
-+;; MOV code
-+;;
-+;;
-+
-+
-+;;========================================================================
-+;; move byte
-+;; nothing much special
-+;; all addressing modes allowed
-+;; fits perfectly into a single instruction 
-+
-+(define_expand "movqi" 
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
-+        (match_operand:QI 1 "general_operand" ""))]
-+  ""
-+  "")
-+
-+(define_insn "*movqi3"
-+  [(set (match_operand:QI 0 "nonimmediate_operand"    "=m,m,m,m,r,r,r,r")
-+      (match_operand:QI 1 "general_operand_msp430"    " m,r,P,i,m,r,P,i"))]
-+  ""
-+  "mov.b\\t%1, %0"
-+  [(set_attr "length" "3,2,3,3,2,1,2,2")
-+   (set_attr "cc" "none,none,none,none,none,none,none,none")])
-+
-+
-+(define_insn "movqipi"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=r,m")
-+      (mem:QI (post_inc:QI (match_operand:HI 1 "register_operand" "r,r"))))]
-+  ""
-+  "mov.b      @%1+, %0"
-+[(set_attr "length" "1,2")
-+   (set_attr "cc" "none,none")])
-+
-+
-+
-+;;============================================================================
-+;; move word (16 bit)
-+;; the same as above
-+
-+(define_expand "movhi" 
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
-+        (match_operand:HI 1 "general_operand_msp430" ""))]
-+  ""
-+  "")
-+
-+(define_insn "*movhi3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"     "=m,m,m,m,r,r,r,r")
-+      (match_operand:HI 1 "general_operand_msp430"            " r,m,P,i,r,m,P,i"))]
-+  ""
-+  "mov\\t%1, %0 "
-+  [(set_attr "length" "2,3,3,3,1,2,2,2")
-+   (set_attr "cc" "none")])
-+
-+(define_insn "movhipi"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m")
-+      (mem:HI (post_inc:HI (match_operand:HI 1 "register_operand" "r,r"))))]
-+  ""
-+  "mov        @%1+, %0"
-+[(set_attr "length" "1,2")
-+   (set_attr "cc" "none,none")])
-+
-+;;============================================================================
-+;; move long (32 bit)
-+;; the same as above
-+
-+(define_expand "movsi" 
-+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+        (match_operand:SI 1 "general_operand" ""))]
-+  ""
-+  "")
-+
-+(define_insn "*movsi3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand"    "=rm")
-+      (match_operand:SI 1 "general_operand"           " rmi"))]
-+""
-+"* return msp430_movesi_code(insn,operands,NULL);"
-+  [(set_attr "length" "6")
-+   (set_attr "cc" "none")])
-+
-+(define_insn "movsipi"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "=r,m")
-+      (mem:SI (post_inc (match_operand:HI 1 "register_operand" "r,r"))))]
-+  ""
-+  "mov        @%1+, %A0
-+      mov     @%1+, %B0"
-+[(set_attr "length" "2,4")
-+   (set_attr "cc" "none,none")])
-+
-+
-+
-+;;============================================================================
-+;; floats are the SI
-+
-+(define_expand "movsf" 
-+  [(set (match_operand:SF 0 "nonimmediate_operand" "")
-+        (match_operand:SF 1 "general_operand" ""))]
-+  ""
-+  "")
-+
-+(define_insn "*movsf3"
-+  [(set (match_operand:SF 0 "nonimmediate_operand"    "=rm")
-+      (match_operand:SF 1 "general_operand"           "rmi"))]
-+""
-+"* return msp430_movesi_code(insn,operands,NULL);"
-+  [(set_attr "length" "6")
-+   (set_attr "cc" "none")])
-+
-+
-+(define_insn "movsfpi"
-+  [(set (match_operand:SF 0 "nonimmediate_operand_msp430" "=r,m")
-+      (mem:SF (post_inc (match_operand:HI 1 "register_operand" "r,r"))))]
-+  ""
-+  "mov        @%1+, %A0
-+      mov     @%1+, %B0"
-+[(set_attr "length" "2,4")
-+   (set_attr "cc" "none,none")])
-+
-+;;============================================================================
-+;; move long long (64 bit)
-+;; the same as above
-+(define_expand "movdi" 
-+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+        (match_operand:DI 1 "general_operand" ""))]
-+  ""
-+  "")
-+
-+(define_insn "*movdi3"
-+  [(set (match_operand:DI 0 "nonimmediate_operand"    "=rm")
-+      (match_operand:DI 1 "general_operand"           "rmi"))]
-+""
-+"* return msp430_movedi_code(insn,operands,NULL);"
-+  [(set_attr "length" "12")
-+   (set_attr "cc" "none")])
-+
-+
-+(define_insn "movdipi"
-+  [(set (match_operand:DI 0 "nonimmediate_operand_msp430" "=r,m")
-+      (mem:DI (post_inc (match_operand:HI 1 "register_operand" "r,r"))))]
-+  ""
-+  "mov        @%1+, %A0
-+      mov     @%1+, %B0
-+      mov     @%1+, %C0
-+      mov     @%1+, %D0"
-+[(set_attr "length" "4,8")
-+   (set_attr "cc" "none,none")])
-+
-+
-+;;============================================================================
-+;;  ARITHMETIC CODE
-+;;
-+
-+
-+;;  random operations:
-+
-+(define_insn "*opqi3_pi"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"          "=r,m")
-+      (match_operator:QI 3 "three_operands_msp430"
-+       [(match_operand:QI 1 "nonimmediate_operand_msp430" "%0,0")
-+       (mem:QI (post_inc (match_operand:HI 2 "register_operand" "r,r")))]))]
-+""
-+"%3.b @%2+, %0"
-+  [(set_attr "length" "1,2")
-+   (set_attr "cc" "oper,oper")])
-+
-+(define_insn "*ophi3_pi"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"          "=r,m")
-+      (match_operator:HI 3 "three_operands_msp430"
-+       [(match_operand:HI 1 "nonimmediate_operand_msp430" "%0,0")
-+        (mem:HI (post_inc (match_operand:HI 2 "register_operand" "r,r")))]))]
-+""
-+"%3   @%2+, %0"
-+  [(set_attr "length" "1,2")
-+   (set_attr "cc" "oper,oper")])
-+
-+(define_insn "*opsi3_pi"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"          "=r,m")
-+      (match_operator:SI 3 "three_operands_msp430"
-+       [(match_operand:SI 1 "nonimmediate_operand_msp430" "%0,0")
-+        (mem:SI (post_inc (match_operand:HI 2 "register_operand" "r,r")))]))]
-+""
-+"%A3\\t@%2+, %A0
-+\\t%B3\\t@%2+, %B0"
-+  [(set_attr "length" "1,2")
-+   (set_attr "cc" "oper,oper")])
-+
-+(define_insn "*opdi3_pi"
-+  [(set (match_operand:DI 0 "nonimmediate_operand_msp430"          "=r,m")
-+      (match_operator:DI 3 "three_operands_msp430"
-+       [(match_operand:DI 1 "nonimmediate_operand_msp430" "%0,0")
-+        (mem:DI (post_inc (match_operand:HI 2 "register_operand" "r,r")))]))]
-+""
-+"%A3\\t@%2+, %A0
-+\\t%B3\\t@%2+, %B0
-+\\t%C3\\t@%2+, %C0
-+\\t%D3\\t@%2+, %D0"
-+  [(set_attr "length" "1,2")
-+   (set_attr "cc" "oper,oper")])
-+
-+
-+
-+
-+;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+;; add 1 byte 
-+
-+
-+(define_expand "addqi3" 
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
-+        (plus:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "")   
-+                 (match_operand:QI 2 "general_operand_msp430" "")))]
-+  "" 
-+  "")
-+
-+(define_insn "*addqi3_cg"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=m,r")
-+        (plus:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "%0,0")
-+               (match_operand 2 "const_int_operand"      "i,i")))]
-+"(INTVAL(operands[2]) == -2
-+  || INTVAL(operands[2]) == -4
-+  || INTVAL(operands[2]) == -8 )"
-+"* {
-+      operands[2] = gen_rtx_CONST_INT(QImode, -INTVAL(operands[2]));
-+      return \"sub.b\\t%2, %0\";
-+}"
-+[(set_attr "length" "2,1")
-+ (set_attr "cc" "set_czn,set_czn")])
-+
-+
-+(define_insn "*addqi3_3"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"          "=m,m,m,m,r,r,r,r")  
-+        (plus:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "%0,0,0,0,0,0,0,0")  
-+                 (match_operand:QI 2 "general_operand_msp430"      " m,r,P,i,m,r,P,i")))]  
-+""
-+  "add.b      %2, %0"
-+  [(set_attr "length" "3,2,2,3,2,1,1,2")
-+   (set_attr "cc" "set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
-+
-+
-+;;============================================================================
-+;; add 1 word (16 bits)
-+;; same as above
-+
-+
-+(define_expand "addhi3" 
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
-+        (plus:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "")
-+                 (match_operand:HI 2 "general_operand_msp430" "")))]
-+  ""
-+  "")
-+
-+(define_insn "*addhi3_cg"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=m,r")
-+      (plus:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "%0,0")
-+               (match_operand 2 "const_int_operand"      "i,i")))]
-+"(INTVAL(operands[2]) == -2
-+  || INTVAL(operands[2]) == -4
-+  || INTVAL(operands[2]) == -8 )"
-+"* {
-+      operands[2] = gen_rtx_CONST_INT(HImode, -INTVAL(operands[2]));
-+      return \"sub\\t%2, %0\" ;
-+}"
-+[(set_attr "length" "2,1")
-+ (set_attr "cc" "set_czn,set_czn")])
-+
-+(define_insn "*addhi3_3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"          "=m,m,m,m,r,r,r,r")
-+        (plus:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "%0,0,0,0,0,0,0,0")
-+                 (match_operand:HI 2 "general_operand_msp430"      " m,r,P,i,m,r,P,i")))]
-+""
-+  "add        %2, %0"
-+  [(set_attr "length" "3,2,2,3,2,1,1,2")
-+   (set_attr "cc"
-+"set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
-+
-+
-+;;============================================================================
-+;; add 2 words (32 bits)
-+;; same as above
-+
-+(define_expand "addsi3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "")
-+        (plus:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "")
-+                 (match_operand:SI 2 "general_operand_msp430" "")))]
-+  ""
-+  "")
-+
-+(define_insn "*addsi3_cg"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "=m,r")
-+      (plus:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "%0,0")
-+               (match_operand 2 "const_int_operand"      "i,i")))]
-+"(INTVAL(operands[2]) == -2
-+  || INTVAL(operands[2]) == -4
-+  || INTVAL(operands[2]) == -8 )"
-+"* {
-+     operands[2] = gen_rtx_CONST_INT(SImode, -INTVAL(operands[2]));
-+     return \"sub\\t%A2, %A0\\n\\tsubc\\t%B2, %B0\" ;
-+}"
-+[(set_attr "length" "4,2")
-+ (set_attr "cc" "further,further")])
-+
-+
-+(define_insn "*addsi3_3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"      "=rm")
-+        (plus:SI (match_operand:SI 1 "general_operand_msp430"  "%0")
-+                 (match_operand:SI 2 "general_operand_msp430"  " rmi")))]
-+""
-+"* return msp430_addsi_code(insn, operands, NULL);"
-+  [(set_attr "length" "6")
-+   (set_attr "cc" "further")])
-+
-+
-+;;============================================================================
-+;; add 4 words (64 bits)
-+;; same as above
-+
-+(define_expand "adddi3"
-+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+        (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")   
-+                 (match_operand:DI 2 "general_operand" "")))]
-+  "" 
-+  "")
-+
-+(define_insn "*adddi3_cg"
-+   [(set (match_operand:DI 0 "nonimmediate_operand_msp430" "=m,r")
-+                (plus:DI (match_operand:DI 1 "nonimmediate_operand_msp430" "%0,0")
-+                (match_operand:DI 2 "const_int_operand"      "i,i")))]
-+"(INTVAL(operands[2]) == -2
-+  || INTVAL(operands[2]) == -4
-+  || INTVAL(operands[2]) == -8 )"
-+"* {
-+     operands[2] = gen_rtx_CONST_INT(DImode, -INTVAL(operands[2]));
-+     return \"sub\\t%A2, %A0\\n\\tsubc\\t%B2, %B0\\n\\tsubc\\t%C2, %C0\\n\\tsubc\\t%D2, %D0\";
-+}"
-+[(set_attr "length" "4,2")
-+(set_attr "cc" "further,further")])
-+
-+(define_insn "*adddi3_3"
-+  [(set (match_operand:DI 0 "nonimmediate_operand"            "=rm")
-+        (plus:DI (match_operand:DI 1 "nonimmediate_operand"   "%0")
-+                 (match_operand:DI 2 "general_operand"        " rmi")))]
-+""
-+"* return msp430_adddi_code(insn, operands, NULL);"
-+  [(set_attr "length" "12")
-+   (set_attr "cc" "further")])
-+
-+
-+;;-----------------------------------------------------------------------
-+;;-----------------------------------------------------------------------
-+;;-----------------------------------------------------------------------
-+;;-----------------------------------------------------------------------
-+;;-----------------------------------------------------------------------
-+;; sub 1 byte 
-+
-+
-+(define_expand "subqi3" 
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
-+        (minus:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "")   
-+                  (match_operand:QI 2 "general_operand_msp430" "")))]
-+  "" 
-+  "")
-+
-+(define_insn "*subqi3_3"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"          "=m,m,m,m,r,r,r,r")  
-+        (minus:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "0,0,0,0,0,0,0,0")  
-+                 (match_operand:QI 2 "general_operand_msp430"      " m,r,P,i,m,r,P,i")))]  
-+""
-+  "sub.b      %2, %0"
-+  [(set_attr "length" "3,2,2,3,2,1,1,2")
-+   (set_attr "cc" "set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
-+
-+
-+;;============================================================================
-+;; sub 1 word (16 bits)
-+;; same as above
-+
-+
-+(define_expand "subhi3" 
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
-+        (minus:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "")
-+                  (match_operand:HI 2 "general_operand_msp430" "")))]
-+  ""
-+  "")
-+
-+(define_insn "*subhi3_3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"          "=m,m,m,m,r,r,r,r")
-+        (minus:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0,0,0,0,0,0,0,0")
-+                  (match_operand:HI 2 "general_operand_msp430"      "m,r,P,i,m,r,P,i")))]
-+""
-+  "sub        %2, %0"
-+  [(set_attr "length" "3,2,2,3,2,1,1,2")
-+   (set_attr "cc"
-+"set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
-+
-+
-+;;============================================================================
-+;; sub 2 words (32 bits)
-+;; same as above
-+
-+(define_expand "subsi3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+        (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+                 (match_operand:SI 2 "general_operand" "")))]
-+  "" 
-+  "")
-+
-+
-+(define_insn "*subsi3_3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand"      "=rm")
-+        (minus:SI (match_operand:SI 1 "general_operand"  "0")
-+                 (match_operand:SI 2 "general_operand"  " rmi")))]
-+""
-+"* return msp430_subsi_code(insn, operands, NULL);"
-+  [(set_attr "length" "6")
-+   (set_attr "cc" "further")])
-+
-+
-+;;============================================================================
-+;; sub 4 words (64 bits)
-+;; same as above
-+
-+(define_expand "subdi3"
-+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+        (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")   
-+                 (match_operand:DI 2 "general_operand" "")))]
-+  "" 
-+  "")
-+
-+(define_insn "*subdi3_3"
-+  [(set (match_operand:DI 0 "nonimmediate_operand"            "=rm")
-+        (minus:DI (match_operand:DI 1 "nonimmediate_operand"          "0")
-+                 (match_operand:DI 2 "general_operand"        " rmi")))]
-+""
-+"* return msp430_subdi_code(insn, operands,NULL);"
-+  [(set_attr "length" "12")
-+   (set_attr "cc" "set_n")])
-+
-+
-+
-+
-+
-+;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-+;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-+;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-+;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-+;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-+;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-+;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-+;; and 1 byte 
-+
-+
-+(define_expand "andqi3" 
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
-+        (and:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "")   
-+                 (match_operand:QI 2 "general_operand_msp430" "")))]
-+  "" 
-+  "")
-+
-+
-+(define_insn "*andqi3_inv"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"         "=r,m")   
-+        (and:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "%0,0")
-+                (match_operand:QI 2 "immediate_operand"    " i,i")))]
-+"(INTVAL(operands[2])==~1
-+  || INTVAL(operands[2])==~2
-+  || INTVAL(operands[2])==~4
-+  || INTVAL(operands[2])==~8)"
-+"* {
-+      operands[2] = gen_rtx_CONST_INT(QImode, ~(INTVAL(operands[2])));
-+      return \"bic.b  %2,%0\";
-+}"
-+  [(set_attr "length" "1,2")
-+   (set_attr "cc" "none,none")])
-+
-+
-+(define_insn "*andqi3_3"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"             "=r,m,r,m,r,m,m,r")
-+        (and:QI (match_operand:QI 1 "nonimmediate_operand_msp430"     "%0,0,0,0,0,0,0,0")
-+                (match_operand:QI 2 "general_operand_msp430"                  " r,m,P,P,m,r,i,i")))]
-+""
-+"and.b        %2, %0"
-+  [(set_attr "length" "1,3,1,2,2,2,3,2")
-+   (set_attr "cc" "set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
-+
-+
-+
-+
-+;;============================================================================
-+;; and 1 word (16 bits)
-+;; same as above
-+
-+(define_expand "andhi3" 
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
-+        (and:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "%0")   
-+                 (match_operand:HI 2 "general_operand_msp430" "")))]
-+  "" 
-+  "")
-+
-+
-+(define_insn "*andhi3_inv"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"         "=r,m")   
-+        (and:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "%0,0")   
-+                (match_operand:HI 2 "immediate_operand"    " i,i")))]
-+"(INTVAL(operands[2])==~1
-+  || INTVAL(operands[2])==~2
-+  || INTVAL(operands[2])==~4
-+  || INTVAL(operands[2])==~8)"
-+"* {
-+      operands[2] = gen_rtx_CONST_INT(HImode, ~(INTVAL(operands[2])));
-+      return \"bic    %2,%0\";
-+}"
-+  [(set_attr "length" "1,2")
-+   (set_attr "cc" "none,none")])
-+
-+(define_insn "*andhi3_clrup"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"         "=r,m")
-+        (and:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "%0,0")
-+                (match_operand:HI 2 "immediate_operand"    " i,i")))]
-+"INTVAL(operands[2])==255"
-+"* {
-+      if(which_alternative == 0)
-+      {
-+              return \"and.b  #-1, %0\";
-+      }
-+      else if(which_alternative == 1)
-+      {
-+              return \"clr.b  %J0\";
-+      }
-+
-+      return  \"bug\";
-+}"
-+  [(set_attr "length" "1,2")
-+   (set_attr "cc" "clobber,clobber")])
-+
-+(define_insn "*andhi3_clrlw"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"         "=m,r")
-+        (and:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "%0,0")
-+                (match_operand:HI 2 "immediate_operand"     " i,i")))]
-+"((0xffff&INTVAL(operands[2]))==0xff00)"
-+"@
-+clr.b %I0
-+and\\t#0xff00, %0"
-+  [(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-+
-+
-+(define_insn "*andhi3_3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"                     "=r,m,r,m,r,m,m,r")
-+        (and:HI (match_operand:HI 1 "nonimmediate_operand_msp430"     "%0,0,0,0,0,0,0,0")
-+                (match_operand:HI 2 "general_operand_msp430"                  " r,m,P,P,m,r,i,i")))]
-+""
-+"and  %2, %0"
-+  [(set_attr "length" "1,3,1,2,2,2,3,2")
-+   (set_attr "cc" "set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
-+
-+
-+
-+
-+
-+;;============================================================================
-+;; and 2 words (32 bits)
-+;; same as above
-+
-+(define_expand "andsi3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+        (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+                (match_operand:SI 2 "general_operand" "")))]
-+  "" 
-+  "")
-+
-+(define_insn "*andsi3_3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand"          "=rm")
-+        (and:SI (match_operand:SI 1 "nonimmediate_operand"  "%0")
-+                (match_operand:SI 2 "general_operand"       " rmi")))]
-+""
-+"* return msp430_andsi_code(insn, operands, NULL);"
-+  [(set_attr "length" "6")
-+   (set_attr "cc" "set_n")])
-+
-+
-+;;============================================================================
-+;; and 4 words (64 bits)
-+;; same as above
-+
-+(define_expand "anddi3"
-+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+        (and:DI (match_operand:DI 1 "nonimmediate_operand" "")   
-+                (match_operand:DI 2 "general_operand" "")))]
-+  "" 
-+  "")
-+
-+(define_insn "*anddi3_3"
-+  [(set (match_operand:DI 0 "nonimmediate_operand"         "=rm")
-+        (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
-+                (match_operand:DI 2 "general_operand"      " rmi")))]
-+""
-+"* return msp430_anddi_code(insn, operands, NULL);"
-+  [(set_attr "length" "14")
-+   (set_attr "cc" "clobber")])
-+
-+
-+
-+;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-+;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-+;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-+;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-+;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-+;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-+;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-+;; ior 1 byte 
-+;; looks like a 'mov' insn
-+
-+(define_expand "iorqi3" 
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
-+        (ior:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "")   
-+                 (match_operand:QI 2 "general_operand_msp430" "")))]
-+  "" 
-+  "")
-+
-+(define_insn "*iorqi3_3"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"             "=r,m,r,m,r,m,m,r")
-+        (ior:QI (match_operand:QI 1 "nonimmediate_operand_msp430"     "%0,0,0,0,0,0,0,0")
-+                (match_operand:QI 2 "general_operand_msp430"                  " r,m,P,P,m,r,i,i")))]
-+""
-+  "bis.b      %2, %0"
-+  [(set_attr "length" "1,3,1,2,2,2,3,2")
-+   (set_attr "cc" "none,none,none,none,none,none,none,none")])
-+
-+
-+
-+;;============================================================================
-+;; ior 1 word (16 bits)
-+;; same as above
-+
-+(define_expand "iorhi3" 
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
-+        (ior:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "")   
-+                 (match_operand:HI 2 "general_operand_msp430" "")))]
-+  "" 
-+  "
-+    if(const_int_operand(operands[2], VOIDmode))
-+    {
-+      int x = INTVAL(operands[2]) & 0xffff;
-+      if(!x) DONE;
-+    }
-+  ")
-+
-+(define_insn "*iorhi3_3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"             "=r,m,r,m,r,m,m,r")
-+        (ior:HI (match_operand:HI 1 "nonimmediate_operand_msp430"     "%0,0,0,0,0,0,0,0")
-+                (match_operand:HI 2 "general_operand_msp430"                  " r,m,P,P,m,r,i,i")))]
-+""
-+  "bis        %2, %0"
-+  [(set_attr "length" "1,3,1,2,2,2,3,2")
-+   (set_attr "cc" "none,none,none,none,none,none,none,none")])
-+
-+
-+
-+;;============================================================================
-+;; ior 2 words (32 bits)
-+;; same as above
-+
-+
-+(define_expand "iorsi3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+                 (match_operand:SI 2 "general_operand" "")))]
-+  "" 
-+  "")
-+
-+(define_insn "*iorsi3_3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand"      "=rm")
-+        (ior:SI (match_operand:SI 1 "nonimmediate_operand"   "%0")
-+                (match_operand:SI 2 "general_operand"   " rmi")))]
-+""
-+"* return msp430_iorsi_code(insn, operands, NULL);"
-+  [(set_attr "length" "6")
-+   (set_attr "cc" "none")])
-+
-+(define_split
-+ [(set (match_operand:SI 0 "nonimmediate_operand"          "")
-+       (ior:SI (match_operand:SI 1 "nonimmediate_operand"  "")
-+             (match_operand:SI 2 "const_int_operand"     "")))]
-+ "reload_completed
-+  && (halfnibble_integer(operands[2], VOIDmode)
-+       || halfnibble_constant(operands[2], VOIDmode))"
-+ [(set (match_dup 3) (ior:HI (match_dup 4) (match_dup 5)))]
-+ "{
-+      int lo = trunc_int_for_mode(INTVAL(operands[2]),HImode);
-+      int hi = trunc_int_for_mode(INTVAL(operands[2])>>16,HImode);
-+ 
-+      if(lo == -1)
-+      {
-+      rtx op = gen_lowpart(HImode, operands[0]);
-+      emit_insn(gen_rtx_SET(HImode, op, GEN_INT(-1)));
-+      DONE;
-+      }
-+      
-+      if(hi == -1)
-+      {
-+      rtx op = gen_highpart(HImode, operands[0]);
-+      emit_insn(gen_rtx_SET(HImode, op, GEN_INT(-1)));
-+      DONE;
-+      }
-+      
-+      if(lo)
-+      {
-+      operands[3] = gen_lowpart(HImode, operands[0]);
-+      operands[4] = gen_lowpart(HImode, operands[1]);
-+      operands[5] = GEN_INT(lo);
-+      }
-+      else if(hi)
-+      {
-+      operands[3] = gen_highpart(HImode, operands[0]);
-+      operands[4] = gen_highpart(HImode, operands[1]);
-+      operands[5] = GEN_INT(hi);
-+      }
-+ }")
-+
-+(define_peephole2
-+ [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "") 
-+       (const_int 0))
-+  (set (match_dup 0) (ior:HI (match_dup 0) 
-+                           (match_operand:HI 1 "const_int_operand" "")))]
-+ ""
-+ [(set (match_dup 0) (match_dup 1))]
-+ "")
-+ 
-+
-+;;============================================================================
-+;; ior 4 words (64 bits)
-+;; same as above
-+
-+(define_expand "iordi3"
-+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+        (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")   
-+                (match_operand:DI 2 "general_operand" "")))]
-+  "" 
-+  "")
-+
-+(define_insn "*iordi3_3"
-+  [(set (match_operand:DI 0 "nonimmediate_operand"          "=rm")
-+        (ior:DI (match_operand:DI 1 "nonimmediate_operand"  "%0")
-+                (match_operand:DI 2 "general_operand"  " rmi")))]
-+""
-+"* return msp430_iordi_code(insn, operands, NULL);"
-+  [(set_attr "length" "12")
-+   (set_attr "cc" "none")])
-+
-+
-+
-+;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+;; xor 1 byte 
-+;; looks like a 'mov' insn
-+
-+(define_expand "xorqi3" 
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
-+        (xor:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "")   
-+                 (match_operand:QI 2 "general_operand_msp430" "")))]
-+  "" 
-+  "")
-+
-+(define_insn "*xorqi3_3"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"             "=r,m,r,m,r,m,m,r")
-+        (xor:QI (match_operand:QI 1 "nonimmediate_operand_msp430"     "%0,0,0,0,0,0,0,0")
-+                (match_operand:QI 2 "general_operand_msp430"                  " r,m,P,P,m,r,i,i")))]
-+""
-+  "xor.b      %2, %0"
-+  [(set_attr "length" "1,3,1,2,2,2,3,2")
-+   (set_attr "cc" "set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
-+
-+
-+
-+;;============================================================================
-+;; xor 1 word (16 bits)
-+;; same as above
-+
-+(define_expand "xorhi3" 
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
-+        (xor:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "")   
-+                 (match_operand:HI 2 "general_operand_msp430" "")))]
-+  "" 
-+  "")
-+
-+(define_insn "*xorhi3_3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"             "=r,m,r,m,r,m,m,r")
-+        (xor:HI (match_operand:HI 1 "nonimmediate_operand_msp430"     "%0,0,0,0,0,0,0,0")
-+                (match_operand:HI 2 "general_operand_msp430"                  " r,m,P,P,m,r,i,i")))]
-+""
-+  "xor        %2, %0"
-+  [(set_attr "length" "1,3,1,2,2,2,3,2")
-+   (set_attr "cc" "set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
-+
-+
-+
-+;;============================================================================
-+;; xor 2 words (32 bits)
-+;; same as above
-+
-+(define_expand "xorsi3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+        (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+                 (match_operand:SI 2 "general_operand" "")))]
-+  "" 
-+  "")
-+
-+
-+(define_insn "*xorsi3_3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand"      "=rm")
-+        (xor:SI (match_operand:SI 1 "nonimmediate_operand"   "%0")
-+                 (match_operand:SI 2 "general_operand"  " rmi")))]
-+""
-+"* return msp430_xorsi_code(insn, operands, NULL);"
-+  [(set_attr "length" "6")
-+   (set_attr "cc" "set_n")])
-+
-+
-+(define_split
-+ [(set (match_operand:SI 0 "nonimmediate_operand"          "")
-+       (xor:SI (match_operand:SI 1 "nonimmediate_operand"  "")
-+             (match_operand:SI 2 "const_int_operand"     "")))]
-+ "reload_completed 
-+  && (halfnibble_integer(operands[2], VOIDmode)
-+       || halfnibble_constant(operands[2], VOIDmode))
-+  && INTVAL(operands[2])"
-+ [(set (match_dup 3) (xor:HI (match_dup 4) (match_dup 5)))]
-+ "{
-+      int lo = trunc_int_for_mode(INTVAL(operands[2]),HImode);
-+      int hi = trunc_int_for_mode(INTVAL(operands[2])>>16,HImode);
-+      
-+      if(lo)
-+      {
-+      operands[3] = gen_lowpart(HImode, operands[0]);
-+      operands[4] = gen_lowpart(HImode, operands[1]);
-+      operands[5] = GEN_INT(lo);
-+      }
-+      else if(hi)
-+      {
-+      operands[3] = gen_highpart(HImode, operands[0]);
-+      operands[4] = gen_highpart(HImode, operands[1]);
-+      operands[5] = GEN_INT(hi);
-+      }
-+ }")
-+
-+
-+(define_peephole2
-+ [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "") 
-+       (const_int 0))
-+  (set (match_dup 0) (xor:HI (match_dup 0) 
-+                           (const_int -1)))]
-+ ""
-+ [(set (match_dup 0) (const_int -1))]
-+ "")
-+ 
-+
-+;;============================================================================
-+;; xor 4 words (64 bits)
-+;; same as above
-+
-+(define_expand "xordi3"
-+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+        (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")   
-+                (match_operand:DI 2 "general_operand" "")))]
-+  "" 
-+  "")
-+
-+(define_insn "*xordi3_3"
-+  [(set (match_operand:DI 0 "nonimmediate_operand"          "=rm")
-+        (xor:DI (match_operand:DI 1 "nonimmediate_operand"  "%0")
-+                (match_operand:DI 2 "general_operand"             " rmi")))]
-+""
-+"* return msp430_xordi_code(insn, operands, NULL);"
-+  [(set_attr "length" "4")
-+   (set_attr "cc" "set_n")])
-+
-+
-+
-+
-+
-+;;============================================================================
-+;;============================================================================
-+;;============================================================================
-+;;============================================================================
-+;;============================================================================
-+;;============================================================================
-+;;============================================================================
-+;;============================================================================
-+;;============================================================================
-+;;============================================================================
-+;; neg
-+;; same as above
-+
-+(define_expand "negqi2"
-+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
-+ ""
-+ "{ emit_insn(gen_one_cmplqi2(operands[0],operands[1]));
-+ emit_insn(gen_addqi3(operands[0],operands[0],const1_rtx));
-+ DONE; }")
-+
-+(define_expand "neghi2"
-+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
-+ ""
-+ "{ emit_insn(gen_one_cmplhi2(operands[0],operands[1]));
-+ emit_insn(gen_addhi3(operands[0],operands[0],const1_rtx));
-+ DONE; }")
-+
-+(define_expand "negsi2"
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
-+ ""
-+
-+ "{ emit_insn(gen_one_cmplsi2(operands[0],operands[1]));
-+ emit_insn(gen_addsi3(operands[0],operands[0],const1_rtx));
-+ DONE; }")
-+
-+(define_expand "negdi2"
-+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
-+ ""
-+
-+ "{ emit_insn(gen_one_cmpldi2(operands[0],operands[1]));
-+ emit_insn(gen_adddi3(operands[0],operands[0],const1_rtx));
-+ DONE; }")
-+
-+(define_insn "negsf2"
-+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,m")
-+   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))]
-+ ""
-+ "xor  #0x8000, %B0"
-+ [(set_attr "length" "2,3")
-+ (set_attr "cc" "clobber,clobber")])
-+
-+;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+;; not        x = !x
-+;; ones component
-+
-+(define_expand "one_cmplqi2"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
-+        (not:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "")))]
-+  ""
-+  "")
-+
-+(define_insn "*one_cmplqi2_2"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"        "=r,m")
-+        (not:QI (match_operand:QI 1 "nonimmediate_operand_msp430" " 0, 0")))]
-+  ""
-+  "inv.b      %0"
-+  [(set_attr "length" "1,2")
-+   (set_attr "cc" "set_czn,set_czn")])
-+
-+
-+;;============================================================================
-+;; not HI     x = !x
-+;; - ones component
-+
-+(define_expand "one_cmplhi2"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
-+        (not:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0")))]
-+  ""
-+  "")
-+
-+(define_insn "*one_cmplhi2_2"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"        "=r, m")
-+        (not:HI (match_operand:HI 1 "nonimmediate_operand_msp430" " 0, 0")))]
-+  ""
-+  "inv        %0"
-+  [(set_attr "length" "1,2")
-+   (set_attr "cc" "set_czn,set_czn")])
-+
-+
-+
-+;;============================================================================
-+;; not SI     x = !x 
-+;; - ones component
-+
-+(define_expand "one_cmplsi2"
-+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+        (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
-+  ""
-+  "")
-+
-+(define_insn "*one_cmplsi2_2"
-+  [(set (match_operand:SI 0 "nonimmediate_operand"       "=r, m")
-+        (not:SI (match_operand:SI 1 "nonimmediate_operand" " 0, 0")))]
-+""
-+  "inv        %A0
-+      inv     %B0"
-+  [(set_attr "length" "2,4")
-+   (set_attr "cc" "set_n,set_n")])
-+
-+
-+;;============================================================================
-+;; not DI     x = !x
-+;; - ones component
-+
-+(define_expand "one_cmpldi2"
-+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+        (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
-+  ""
-+  "")
-+
-+(define_insn "*one_cmpldi2_2"
-+  [(set (match_operand:DI 0 "nonimmediate_operand"       "=r, m")
-+        (not:DI (match_operand:DI 1 "nonimmediate_operand" " 0, 0")))]
-+  ""
-+  "inv        %A0
-+      inv     %B0
-+      inv     %C0
-+      inv     %D0"
-+  [(set_attr "length" "4,8")
-+   (set_attr "cc" "set_n,set_n")])
-+
-+
-+
-+;;============================================================================
-+;;============================================================================
-+;;============================================================================
-+;;============================================================================
-+;;============================================================================
-+;;============================================================================
-+;;============================================================================
-+;;============================================================================
-+;;============================================================================
-+;; abs
-+;; x = |x|
-+
-+(define_expand "absqi2"
-+  [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+        (abs:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
-+  ""
-+  "")
-+
-+(define_insn "*absqi2_2"
-+  [(set (match_operand:QI 0 "nonimmediate_operand"       "=r,m")
-+        (abs:QI (match_operand:QI 1 "nonimmediate_operand" " 0, 0")))]
-+  ""
-+      "tst.b  %0
-+      jge     .Leaq%=
-+      inv.b   %0
-+      inc.b   %0
-+.Leaq%=:"
-+  [(set_attr "length" "4,7")
-+   (set_attr "cc" "set_czn,set_czn")])
-+
-+
-+;;============================================================================
-+;; abs HI     x = |x|
-+;; 
-+
-+(define_expand "abshi2"
-+  [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+        (abs:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
-+  ""
-+  "")
-+
-+
-+(define_insn "*abshi2_2"
-+  [(set (match_operand:HI 0 "nonimmediate_operand"       "=r, m")
-+        (abs:HI (match_operand:HI 1 "nonimmediate_operand" " 0, 0")))]
-+  ""
-+      "tst    %0
-+      jge     .Lae%=
-+      inv     %0
-+      inc     %0
-+.Lae%=:"
-+  [(set_attr "length" "4,7")
-+   (set_attr "cc" "set_czn,set_czn")])
-+
-+
-+;;============================================================================
-+;; abs SI     x = |x|
-+
-+(define_expand "abssi2"
-+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
-+        (abs:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
-+  ""
-+  "")
-+
-+(define_insn "*abssi2_2"
-+  [(set (match_operand:SI 0 "nonimmediate_operand"       "=r, m")
-+        (abs:SI (match_operand:SI 1 "nonimmediate_operand" " 0, 0")))]
-+  ""
-+  "* return msp430_emit_abssi(insn, operands,NULL);"
-+  [(set_attr "length" "7,13")
-+   (set_attr "cc" "clobber,clobber")])
-+
-+
-+;;============================================================================
-+;; abs DI     x = |x|
-+
-+(define_expand "absdi2"
-+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
-+        (abs:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
-+  ""
-+  "")
-+
-+(define_insn "*absdi2_2"
-+  [(set (match_operand:DI 0 "nonimmediate_operand"       "=r, m")
-+        (abs:DI (match_operand:DI 1 "nonimmediate_operand" " 0, 0")))]
-+  ""
-+  "* return msp430_emit_absdi(insn, operands,NULL);"
-+  [(set_attr "length" "11,23")
-+   (set_attr "cc" "clobber,clobber")])
-+
-+;;============================================================================
-+;; abs SF
-+
-+(define_insn "abssf2"
-+  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,m")
-+        (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))]
-+""
-+"and  #0x7fff, %B0"
-+  [(set_attr "length" "2,3")
-+   (set_attr "cc" "clobber,clobber")])
-+
-+
-+;; ==========================================================================
-+;; there are shift helpers
-+
-+(define_insn "trunchiqi"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=r,m") 
-+      (truncate:QI (match_operand:HI 1 "register_operand" "r,r")))]
-+""
-+"mov.b        %1, %0"
-+  [(set_attr "length" "1,2")
-+   (set_attr "cc" "none,none")])
-+
-+(define_insn "truncsihi"
-+  [(set (match_operand:HI 0 "register_operand" "=r") 
-+      (truncate:HI (match_operand:SI 1 "register_operand" "r")))]
-+""
-+"mov  %1, %0"
-+  [(set_attr "length" "1")
-+   (set_attr "cc" "none")])
-+
-+
-+(define_insn "truncsiqi"
-+  [(set (match_operand:QI 0 "register_operand" "=r") 
-+      (truncate:QI (match_operand:SI 1 "register_operand" "r")))]
-+""
-+"mov.b        %1, %0"
-+  [(set_attr "length" "1")
-+   (set_attr "cc" "none")])
-+
-+
-+(define_insn "truncdiqi"
-+  [(set (match_operand:QI 0 "register_operand" "=r") 
-+      (truncate:QI (match_operand:DI 1 "register_operand" "r")))]
-+""
-+"mov.b        %1, %0"
-+  [(set_attr "length" "1")
-+   (set_attr "cc" "none")])
-+
-+(define_insn "truncdisi"
-+  [(set (match_operand:SI 0 "register_operand" "=r") 
-+      (truncate:SI (match_operand:DI 1 "register_operand" "r")))]
-+""
-+"mov  %A1,%A0
-+      mov    %B1,%B0"
-+  [(set_attr "length" "2")
-+   (set_attr "cc" "none")])
-+
-+
-+(define_expand "rotlhi3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand"       "")
-+        (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+                   (match_operand:HI 2 "const_int_operand"  "")))]
-+""
-+"
-+  if(INTVAL(operands[2])!=8) FAIL;
-+")
-+
-+(define_insn "*rotlhi3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand"       "=rR,m")
-+        (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
-+                   (const_int 8)))]
-+""
-+"swpb\\t%0"
-+  [(set_attr "length" "1,2")
-+     (set_attr "cc" "none")])
-+
-+
-+;;<< << << << << << << << << << << << << << << << << << << << << << << << <<
-+;; << << << << << << << << << << << << << << << << << << << << << << << <<
-+;;<< << << << << << << << << << << << << << << << << << << << << << << << <<
-+;; << << << << << << << << << << << << << << << << << << << << << << << <<
-+;;<< << << << << << << << << << << << << << << << << << << << << << << << <<
-+;; arithmetic shift left
-+
-+(define_expand "ashlqi3"
-+  [(set (match_operand:QI 0 "nonimmediate_operand"       "")
-+        (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+                   (match_operand:QI 2 "general_operand"  "")))]
-+""
-+"{
-+   if(!const_int_operand(operands[2],VOIDmode))
-+   {
-+     rtx op0,op1;
-+     
-+     op0 = force_reg(QImode,operands[0]);
-+     op1 = force_reg(QImode,operands[1]);
-+     operands[2] = copy_to_mode_reg(QImode,operands[2]);
-+     emit_insn(gen_ashlqi3_cnt (op0, op1, operands[2]));
-+     emit_move_insn(operands[0],op0);
-+     /*emit_move_insn(operands[1],op1);*/ 
-+     DONE;
-+   }
-+   else if(!register_operand(operands[1], QImode) 
-+              && is_shift_better_in_reg(operands))
-+   {
-+      operands[1] = copy_to_mode_reg(QImode,operands[1]);
-+      emit_insn (gen_ashlqi3fnl(operands[0], operands[1], operands[2]));
-+      DONE;
-+   }
-+}")
-+
-+(define_insn "ashlqi3_cnt"
-+  [(parallel [(set (match_operand:QI 0 "register_operand"       "=r")
-+            (ashift:QI (match_operand:QI 1 "register_operand" "0")
-+                       (match_operand:QI 2 "register_operand" "")))
-+            (clobber (match_dup 2))])]
-+""
-+"* return msp430_emit_ashlqi3(insn, operands,NULL);"
-+  [(set_attr "length" "8")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "ashlqi3fnl"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"       "=rm")
-+        (ashift:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "0")
-+                   (match_operand 2 "const_int_operand"  "i")))]
-+  ""
-+  "* return msp430_emit_ashlqi3(insn, operands,NULL);"
-+  [(set_attr "length" "1")
-+   (set_attr "cc" "clobber")])
-+
-+;; HImode  ======================================
-+(define_expand "ashlhi3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand"       "")
-+        (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+                   (match_operand 2 "general_operand"  "")))]
-+""
-+"{ msp430_ashlhi3(operands); DONE; }")
-+
-+(define_insn "ashlhi3_cnt"
-+  [(parallel [(set (match_operand:HI 0 "register_operand"       "=r")
-+            (ashift:HI (match_operand:HI 1 "register_operand" "0")
-+                       (match_operand:HI 2 "register_operand" "r")))
-+            (clobber (match_dup 2))])]
-+  ""
-+  "* return msp430_emit_ashlhi3(insn, operands,NULL);"
-+  [(set_attr "length" "5")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "*ashlhi3_1"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"       "=r,R,m")
-+        (ashift:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0,0,0")
-+                   (const_int 1)))]
-+  ""
-+  "rla\\t%0"
-+  [(set_attr "length" "1,2,3")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "*ashlhi3_15"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"       "=r,R,m")
-+        (ashift:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0,0,0")
-+                   (const_int 15)))]
-+  ""
-+  "rra\\t%0
-+\\tclr\\t%0
-+\\trrc\\t%0"
-+  [(set_attr "length" "3,5,7")
-+   (set_attr "cc" "clobber")])
-+
-+
-+;; SImode ======================================
-+
-+(define_expand "ashlsi3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand"       "")
-+        (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+                   (match_operand:HI 2 "general_operand"  "")))]
-+""
-+"{ msp430_ashlsi3(operands); DONE; }")
-+
-+(define_insn "ashlsi3_cnt"
-+  [(parallel [(set (match_operand:SI 0 "register_operand"       "=r")
-+            (ashift:SI (match_operand:SI 1 "register_operand" "0")
-+                       (match_operand:HI 2 "register_operand" "")))
-+            (clobber (match_dup 2))])]
-+""
-+"* return msp430_emit_ashlsi3(insn, operands,NULL);"
-+  [(set_attr "length" "8")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "*ashlsi3_31"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,R,m")
-+        (ashift:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
-+                   (const_int 31)))]
-+  ""
-+"rra\\t%A0
-+\\tclr\\t%A0
-+\\tclr\\t%B0
-+\\trrc\\t%B0"
-+[(set_attr "length" "4,7,8")
-+  (set_attr "cc" "clobber")])
-+
-+
-+(define_insn "*ashlsi3_8"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,R,m")
-+        (ashift:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
-+                   (const_int 8)))]
-+  ""
-+"*{
-+    if(which_alternative==0)
-+    {
-+      return \"xor.b\\t%A0, %B0\\n\\txor\\t%A0, %B0\\n\\tswpb\\t%B0\\n\\tand.b\\t#-1, %A0\\n\\tswpb\\t%A0 \";
-+    }
-+    else
-+    {
-+      return \"xor.b\\t%A0, %B0\\n\\tclr.b\\t%L0\\n\\txor\\t%A0, %B0\\n\\tswpb\\t%B0\\n\\tclr.b\\t%J0\\n\\tswpb\\t%A0\";
-+    }
-+}"
-+  [(set_attr "length" "5,11,12")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "*ashlsi3_16"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,m,r,m")
-+        (ashift:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "rR,rR,m,m")
-+                   (const_int 16)))]
-+""
-+"mov  %A1, %B0
-+\tmov #0, %A0"
-+[(set_attr "length" "1,2,2,3")
-+  (set_attr "cc" "clobber")])
-+
-+(define_insn "*ashlsi3_1"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=m,R,r")
-+        (ashift:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
-+                   (const_int 1)))]
-+  ""
-+"rla\\t%A0
-+\\trlc\\t%B0"
-+[(set_attr "length" "6,5,2")
-+  (set_attr "cc" "clobber")])
-+
-+;; DImode ======================================
-+
-+(define_expand "ashldi3"
-+  [(set (match_operand:DI 0 "nonimmediate_operand"       "")
-+        (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+                   (match_operand:HI 2 "general_operand"  "")))]
-+""
-+"{
-+   if( !const_int_operand(operands[2],VOIDmode) ||
-+       INTVAL(operands[2]) > 1)
-+   {
-+     rtx op0,op1;
-+     
-+     op0 = force_reg(DImode,operands[0]);
-+     op1 = force_reg(DImode,operands[1]);
-+     operands[2] = copy_to_mode_reg(HImode,operands[2]);
-+     emit_insn(gen_ashldi3_cnt (op0, op1, operands[2]));
-+     emit_move_insn(operands[0],op0);
-+     /*emit_move_insn(operands[1],op1);*/ 
-+     DONE;
-+   }
-+   else if(!register_operand(operands[1], DImode) 
-+              && is_shift_better_in_reg(operands))
-+   {
-+      operands[1] = copy_to_mode_reg(DImode,operands[1]);
-+      emit_insn (gen_ashldi3fnl(operands[0], operands[1], operands[2]));
-+      DONE;
-+   }
-+}")
-+
-+(define_insn "ashldi3_cnt"
-+  [(parallel [(set (match_operand:DI 0 "register_operand"       "=r")
-+            (ashift:DI (match_operand:DI 1 "register_operand" "0")
-+                       (match_operand:HI 2 "register_operand" "")))
-+            (clobber (match_dup 2))])]
-+  ""
-+  "* return msp430_emit_ashldi3(insn, operands,NULL);"
-+  [(set_attr "length" "8")
-+   (set_attr "cc" "clobber")])
-+
-+
-+(define_insn "ashldi3fnl"
-+  [(set (match_operand:DI 0 "nonimmediate_operand"       "=rm")
-+        (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
-+                   (match_operand 2 "const_int_operand"  "i")))]
-+  ""
-+  "* return msp430_emit_ashldi3(insn, operands,NULL);"
-+  [(set_attr "length" "1")
-+   (set_attr "cc" "clobber")])
-+
-+;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
-+;;  >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>      
-+;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>      
-+;;  >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>      
-+;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>      
-+;;  >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>     
-+;; arithmetic shift right
-+
-+(define_expand "ashrqi3"
-+  [(set (match_operand:QI 0 "nonimmediate_operand"       "")
-+        (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+                   (match_operand:QI 2 "general_operand"  "")))]
-+""
-+"{
-+   if(!const_int_operand(operands[2],VOIDmode))
-+   {
-+     rtx op0,op1;
-+     
-+     op0 = force_reg(QImode,operands[0]);
-+     op1 = force_reg(QImode,operands[1]);
-+     operands[2] = copy_to_mode_reg(QImode,operands[2]);
-+     emit_insn(gen_ashrqi3_cnt (op0, op1, operands[2]));
-+     emit_move_insn(operands[0],op0);
-+     /*emit_move_insn(operands[1],op1);*/ 
-+     DONE;
-+   }
-+   else if(!register_operand(operands[1], QImode) 
-+              && INTVAL(operands[2])>2 
-+              && INTVAL(operands[2])!=7)
-+   {
-+      operands[1] = copy_to_mode_reg(QImode,operands[1]);
-+      emit_insn (gen_ashrqi3fnl(operands[0], operands[1], operands[2]));
-+      DONE;
-+   }
-+   else if(INTVAL(operands[2]) == 7)
-+   {
-+      /* to do it simple we need a register */
-+      rtx r1 = gen_reg_rtx(HImode);
-+      emit_insn(gen_extendqihi2(r1,operands[1]));
-+      emit_insn(gen_swpb(r1,r1));
-+      emit_insn(gen_trunchiqi(operands[0],r1));
-+      DONE;
-+   }
-+}")
-+
-+(define_insn "ashrqi3_cnt"
-+  [(parallel [(set (match_operand:QI 0 "register_operand"       "=r")
-+            (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
-+                       (match_operand:QI 2 "register_operand" "")))
-+            (clobber (match_dup 2))])]
-+""
-+"* return msp430_emit_ashrqi3(insn, operands,NULL);"
-+  [(set_attr "length" "8")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "ashrqi3fnl"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"       "=rm")
-+        (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "0")
-+                   (match_operand 2 "const_int_operand"  "i")))]
-+  ""
-+  "* return msp430_emit_ashrqi3(insn, operands,NULL);"
-+  [(set_attr "length" "1")
-+   (set_attr "cc" "clobber")])
-+
-+;; HImode  ======================================
-+(define_expand "ashrhi3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand"       "")
-+        (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+                   (match_operand 2 "general_operand"  "")))]
-+""
-+"{msp430_ashrhi3(operands); DONE; }")
-+
-+(define_insn "ashrhi3_cnt"
-+  [(parallel [(set (match_operand:HI 0 "register_operand"       "=r")
-+            (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
-+                       (match_operand:HI 2 "register_operand" "")))
-+            (clobber (match_dup 2))])]
-+""
-+"* return msp430_emit_ashrhi3(insn, operands,NULL);"
-+  [(set_attr "length" "5")
-+   (set_attr "cc" "clobber")])
-+
-+
-+(define_insn "*ashrhi3_1"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"       "=rR,m")
-+        (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0,0")
-+                   (const_int 1)))]
-+  ""
-+  "rra\\t%0"
-+  [(set_attr "length" "1,2")
-+   (set_attr "cc" "clobber")])
-+
-+
-+(define_insn "*ashrhi3_15"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"       "=rR,m")
-+        (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0,0")
-+                   (const_int 15)))]
-+  ""
-+  "swpb\\t%0
-+\\tsxt\\t%0
-+\\tswpb\\t%0
-+\\tsxt\\t%0"
-+  [(set_attr "length" "4,8")
-+   (set_attr "cc" "clobber")])
-+
-+
-+
-+;; SImode ======================================
-+
-+(define_expand "ashrsi3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand"       "")
-+        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+                   (match_operand:HI 2 "general_operand"  "")))]
-+""
-+"{msp430_ashrsi3(operands);DONE; }")
-+
-+(define_insn "ashrsi3_cnt"
-+  [(parallel [(set (match_operand:SI 0 "register_operand"       "=r")
-+            (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
-+                       (match_operand:HI 2 "register_operand" "")))
-+            (clobber (match_dup 2))])]
-+""
-+"* return msp430_emit_ashrsi3(insn, operands,NULL);"
-+  [(set_attr "length" "8")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "*ashrsi3_1"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=rR,m")
-+        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0")
-+                   (const_int 1)))]
-+  ""
-+  "rra\\t%B0
-+\\trrc\\t%A0"
-+  [(set_attr "length" "2,4")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "*ashrsi3_31"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,R,m")
-+        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
-+                   (const_int 31)))]
-+  ""
-+"swpb %B0
-+\\tsxt        %B0
-+\\tswpb       %B0
-+\\tsxt        %B0
-+\\tmov        %B0, %A0"
-+  [(set_attr "length" "5,10,10")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "*ashrsi3_8"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,R,m")
-+        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
-+                   (const_int 8)))]
-+  ""
-+"*{
-+    if(which_alternative==0)
-+    {
-+      return \" swpb\\t%A0\\n\\tswpb\\t%B0\\n\\txor.b\\t%B0, %A0\\n\\txor\\t%B0, %A0\\n\\tsxt\\t%B0\";
-+    }
-+    else
-+    {
-+      return \" swpb\\t%A0\\n\\tswpb\\t%B0\\n\\txor.b\\t%B0, %A0\\n\\tclr.b\\t%J0\\n\\txor\\t%B0, %A0\\n\\tsxt\\t%B0\";
-+    }
-+}"
-+  [(set_attr "length" "5,11,12")
-+   (set_attr "cc" "clobber")])
-+
-+;; DImode ======================================
-+
-+(define_expand "ashrdi3"
-+  [(set (match_operand:DI 0 "nonimmediate_operand"       "")
-+        (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+                   (match_operand:HI 2 "general_operand"  "")))]
-+""
-+"{
-+   if( !const_int_operand(operands[2],VOIDmode))
-+   {
-+     rtx op0,op1;
-+     
-+     op0 = force_reg(DImode,operands[0]);
-+     op1 = force_reg(DImode,operands[1]);
-+     operands[2] = copy_to_mode_reg(HImode,operands[2]);
-+     emit_insn(gen_ashrdi3_cnt (op0, op1, operands[2]));
-+     emit_move_insn(operands[0],op0);
-+     /*emit_move_insn(operands[1],op1);*/ 
-+     DONE;
-+   }
-+   else if(!register_operand(operands[1], DImode) 
-+              && is_shift_better_in_reg(operands))
-+   {
-+      operands[1] = copy_to_mode_reg(DImode,operands[1]);
-+      emit_insn (gen_ashrdi3fnl(operands[0], operands[1], operands[2]));
-+      DONE;
-+   }
-+}")
-+
-+(define_insn "ashrdi3_cnt"
-+  [(parallel [(set (match_operand:DI 0 "register_operand"       "=r")
-+            (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
-+                       (match_operand:HI 2 "register_operand" "")))
-+            (clobber (match_dup 2))])]
-+  ""
-+  "* return msp430_emit_ashrdi3(insn, operands,NULL);"
-+  [(set_attr "length" "8")
-+   (set_attr "cc" "clobber")])
-+
-+
-+(define_insn "ashrdi3fnl"
-+  [(set (match_operand:DI 0 "nonimmediate_operand"       "=rm")
-+        (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
-+                   (match_operand 2 "const_int_operand"  "i")))]
-+  ""
-+  "* return msp430_emit_ashrdi3(insn, operands,NULL);"
-+  [(set_attr "length" "1")
-+   (set_attr "cc" "clobber")])
-+
-+
-+
-+
-+
-+;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
-+;;  >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>   
-+;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>   
-+;;  >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>   
-+;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>   
-+;;  >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>   
-+;; logical shift right
-+
-+(define_expand "lshrqi3"
-+  [(set (match_operand:QI 0 "nonimmediate_operand"       "")
-+        (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
-+                   (match_operand:QI 2 "general_operand"  "")))]
-+""
-+"{
-+   if(!const_int_operand(operands[2],VOIDmode))
-+   {
-+     rtx op0,op1;
-+     
-+     op0 = force_reg(QImode,operands[0]);
-+     op1 = force_reg(QImode,operands[1]);
-+     operands[2] = copy_to_mode_reg(QImode,operands[2]);
-+     emit_insn(gen_lshrqi3_cnt (op0, op1, operands[2]));
-+     emit_move_insn(operands[0],op0);
-+     /*emit_move_insn(operands[1],op1);*/ 
-+     DONE;
-+   }
-+   else if(!register_operand(operands[1], QImode) 
-+              && is_shift_better_in_reg(operands))
-+   {
-+      operands[1] = copy_to_mode_reg(QImode,operands[1]);
-+      emit_insn (gen_lshrqi3fnl(operands[0], operands[1], operands[2]));
-+      DONE;
-+   }
-+}")
-+
-+(define_expand "lshrqi3_cnt"
-+  [(parallel [(set (match_operand:QI 0 "register_operand"       "=r")
-+            (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
-+                       (match_operand:QI 2 "register_operand" "")))
-+            (clobber (match_dup 2))])]
-+""
-+"")
-+
-+(define_insn "*lshrqi3_cnt"
-+  [(parallel [(set (match_operand:QI 0 "register_operand"       "=r")
-+            (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
-+                       (match_operand:QI 2 "register_operand" "")))
-+            (clobber (match_dup 2))])]
-+""
-+"* return msp430_emit_lshrqi3(insn, operands,NULL);"
-+  [(set_attr "length" "8")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "lshrqi3fnl"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"       "=rm")
-+        (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "0")
-+                   (match_operand 2 "const_int_operand"  "i")))]
-+  ""
-+  "* return msp430_emit_lshrqi3(insn, operands,NULL);"
-+  [(set_attr "length" "1")
-+   (set_attr "cc" "clobber")])
-+
-+;; HImode  ======================================
-+
-+(define_insn "clrc"
-+ [(unspec:HI [(const_int 123454321)] 30)]
-+""
-+ "clrc"
-+[(set_attr "length" "1")
-+  (set_attr "cc" "clobber")])
-+
-+ 
-+(define_expand "lshrhi3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand"       "")
-+        (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
-+                   (match_operand 2 "general_operand"  "")))]
-+""
-+"{msp430_lshrhi3(operands); DONE; }")
-+
-+(define_insn "lshrhi3_cnt"
-+  [(parallel [(set (match_operand:HI 0 "register_operand"       "=r")
-+            (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
-+                       (match_operand:HI 2 "register_operand" "")))
-+            (clobber (match_dup 2))])]
-+""
-+"* return msp430_emit_lshrhi3(insn, operands,NULL);"
-+  [(set_attr "length" "5")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "*lshrhi3_15"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"       "=r,R,m")
-+        (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0,0,0")
-+                   (const_int 15)))]
-+  ""
-+  "rla\\t%0
-+\\tclr\\t%0
-+\\trlc\\t%0"
-+  [(set_attr "length" "3,6,8")
-+   (set_attr "cc" "clobber")])
-+
-+
-+(define_insn "*lshrhi3_1"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"       "=rR,m")
-+        (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0,0")
-+                   (const_int 1)))]
-+  ""
-+"clrc
-+\\trrc\\t%0"
-+  [(set_attr "length" "2,3")
-+   (set_attr "cc" "clobber")])
-+
-+;; SImode ======================================
-+
-+(define_expand "lshrsi3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand"       "")
-+        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
-+                   (match_operand:HI 2 "general_operand"  "")))]
-+""
-+"{ msp430_lshrsi3(operands); DONE; }")
-+
-+(define_insn "lshrsi3_cnt"
-+  [(parallel [(set (match_operand:SI 0 "register_operand"       "=r")
-+            (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
-+                       (match_operand:HI 2 "register_operand" "")))
-+            (clobber (match_dup 2))])]
-+""
-+"* return msp430_emit_lshrsi3(insn, operands,NULL);"
-+  [(set_attr "length" "8")
-+   (set_attr "cc" "clobber")])
-+
-+
-+(define_insn "*lshrsi3_31"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,R,m")
-+        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
-+                   (const_int 31)))]
-+  ""
-+"rla  %B0
-+\\tclr        %B0
-+\\tclr        %A0
-+\\trlc        %A0"
-+  [(set_attr "length" "4,9,10")
-+   (set_attr "cc" "clobber")])
-+
-+
-+(define_insn "*lshrsi3_8"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,R,m")
-+        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
-+                   (const_int 8)))]
-+  ""
-+"*{
-+    if(which_alternative==0)
-+    {
-+      return \"swpb\\t%A0\\n\\tswpb\\t%B0\\n\\txor.b\\t%B0, %A0\\n\\txor\\t%B0, %A0\\n\\tand.b\\t#-1, %B0\";
-+    }
-+    else
-+    {
-+      return \"swpb\\t%A0\\n\\tswpb\\t%B0\\n\\txor.b\\t%B0, %A0\\n\\tclr.b\\t%J0\\n\\txor\\t%B0, %A0\\n\\tclr.b\\t%L0\";
-+    }
-+}"
-+  [(set_attr "length" "5,11,12")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "*lshrsi3_1"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,R,m")
-+        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
-+                   (const_int 1)))]
-+  ""
-+"clrc
-+\\trrc\\t%B0
-+\\trrc\\t%A0"
-+  [(set_attr "length" "3,4,5")
-+   (set_attr "cc" "clobber")])
-+
-+;; DImode ======================================
-+
-+(define_expand "lshrdi3"
-+  [(set (match_operand:DI 0 "nonimmediate_operand"       "")
-+        (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "")
-+                   (match_operand:HI 2 "general_operand"  "")))]
-+""
-+"{
-+   if( !const_int_operand(operands[2],VOIDmode))
-+   {
-+     rtx op0,op1;
-+     
-+     op0 = force_reg(DImode,operands[0]);
-+     op1 = force_reg(DImode,operands[1]);
-+     operands[2] = copy_to_mode_reg(HImode,operands[2]);
-+     emit_insn(gen_lshrdi3_cnt (op0, op1, operands[2]));
-+     emit_move_insn(operands[0],op0);
-+     /*emit_move_insn(operands[1],op1);*/ 
-+     DONE;
-+   }
-+   else if(!register_operand(operands[1], DImode) 
-+              && is_shift_better_in_reg(operands))
-+   {
-+      operands[1] = copy_to_mode_reg(DImode,operands[1]);
-+      emit_insn (gen_lshrdi3fnl(operands[0], operands[1], operands[2]));
-+      DONE;
-+   }
-+}")
-+
-+(define_insn "lshrdi3_cnt"
-+  [(parallel [(set (match_operand:DI 0 "register_operand"       "=r")
-+            (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
-+                       (match_operand:HI 2 "register_operand" "")))
-+            (clobber (match_dup 2))])]
-+  ""
-+  "* return msp430_emit_lshrdi3(insn, operands,NULL);"
-+  [(set_attr "length" "8")
-+   (set_attr "cc" "clobber")])
-+
-+
-+(define_insn "lshrdi3fnl"
-+  [(set (match_operand:DI 0 "nonimmediate_operand"       "=rm")
-+        (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
-+                   (match_operand 2 "const_int_operand"  "i")))]
-+  ""
-+  "* return msp430_emit_lshrdi3(insn, operands,NULL);"
-+  [(set_attr "length" "1")
-+   (set_attr "cc" "clobber")])
-+
-+
-+
-+
-+
-+
-+;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
-+;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
-+;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
-+;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
-+;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
-+;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
-+;; sign extend
-+
-+(define_insn "extendqihi2"
-+  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
-+        (sign_extend:HI (match_operand:QI 1 "general_operand" "0,*rmi")))]
-+  ""
-+  "* return signextendqihi(insn, operands,NULL);"
-+  [(set_attr "length" "2,2")
-+   (set_attr "cc" "set_n,set_n")])
-+
-+(define_insn "extendqisi2"
-+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+        (sign_extend:SI (match_operand:QI 1 "general_operand" "0,*rmi")))]
-+  ""
-+  "* return signextendqisi(insn, operands,NULL);"
-+  [(set_attr "length" "6,6")
-+   (set_attr "cc" "set_n,set_n")])
-+
-+(define_insn "extendqidi2"
-+  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
-+        (sign_extend:DI (match_operand:QI 1 "general_operand" "0,*rmi")))]
-+  ""
-+  "* return signextendqidi(insn, operands,NULL);"
-+  [(set_attr "length" "6,6")
-+   (set_attr "cc" "set_n,set_n")])
-+
-+(define_insn "extendhisi2"
-+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+        (sign_extend:SI (match_operand:HI 1 "general_operand" "0,*rmi")))] 
-+  ""
-+  "* return signextendhisi(insn, operands,NULL);"
-+  [(set_attr "length" "6,6")  
-+   (set_attr "cc" "set_n,set_n")])      
-+
-+(define_insn "extendhidi2"
-+  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
-+        (sign_extend:DI (match_operand:HI 1 "general_operand" "0,*rmi")))]
-+  ""
-+  "* return signextendhidi(insn, operands,NULL);"
-+  [(set_attr "length" "6,6")  
-+   (set_attr "cc" "set_n,set_n")])
-+
-+(define_insn "extendsidi2"
-+  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
-+        (sign_extend:DI (match_operand:SI 1 "general_operand" "0,*rmi")))]
-+  ""
-+  "* return signextendsidi(insn, operands,NULL);"
-+  [(set_attr "length" "6,6")
-+   (set_attr "cc" "set_n,set_n")])
-+
-+;; xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0
-+;; xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0
-+;; xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0
-+;; xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0
-+;; xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0
-+;; xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0
-+;; zero extend
-+
-+(define_insn "zero_extendqihi2"
-+  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
-+        (zero_extend:HI (match_operand:QI 1 "general_operand" "0,*rmi")))]
-+  ""
-+  "* return zeroextendqihi(insn, operands,NULL);"
-+  [(set_attr "length" "2,2")
-+   (set_attr "cc" "clobber,clobber")])
-+
-+(define_insn "zero_extendqisi2"
-+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+        (zero_extend:SI (match_operand:QI 1 "general_operand" "0,*rmi")))]
-+  ""
-+  "* return zeroextendqisi(insn, operands,NULL);"
-+  [(set_attr "length" "6,6")
-+   (set_attr "cc" "clobber,clobber")])
-+
-+(define_insn "zero_extendqidi2"
-+  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
-+        (zero_extend:DI (match_operand:QI 1 "general_operand" "0,*rmi")))]
-+  ""
-+  "* return zeroextendqidi(insn, operands,NULL);"
-+  [(set_attr "length" "6,6")
-+   (set_attr "cc" "clobber,clobber")])
-+
-+
-+(define_insn "zero_extendhisi2"
-+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-+        (zero_extend:SI (match_operand:HI 1 "general_operand" "0,*rmi")))] 
-+  ""
-+  "* return zeroextendhisi(insn, operands,NULL);"
-+  [(set_attr "length" "6,6")  
-+   (set_attr "cc" "clobber,clobber")])      
-+
-+(define_insn "zero_extendhidi2"
-+  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
-+        (zero_extend:DI (match_operand:HI 1 "general_operand" "0,*rmi")))]
-+  ""
-+  "* return zeroextendhidi(insn, operands,NULL);"
-+  [(set_attr "length" "6,6")  
-+   (set_attr "cc" "clobber,clobber")])
-+
-+(define_insn "zero_extendsidi2"
-+  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
-+        (zero_extend:DI (match_operand:SI 1 "general_operand" "0,*rmi")))]
-+  ""
-+  "* return zeroextendsidi(insn, operands,NULL);"
-+  [(set_attr "length" "6,6")  
-+   (set_attr "cc" "clobber,clobber")])
-+
-+;; =====================================================================
-+;; single bit extract
-+;; as soon as all operatoins performed on io registers
-+;; let use only QImode. 
-+
-+(define_expand "extv"
-+ [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
-+       (sign_extract:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "") 
-+                      (match_operand 2 "const_int_operand" "")
-+                      (match_operand 3 "const_int_operand" "")))]
-+""
-+"{
-+    if(INTVAL(operands[2]) != 1 || INTVAL(operands[3]) <= 0)
-+      FAIL;
-+}")
-+
-+(define_insn "*extv" 
-+ [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=r,r,r,r,m,m,m,m")
-+       (sign_extract:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "r,m,r,m,r,m,r,m") 
-+                      (const_int 1)
-+                      (match_operand 2 "const_int_operand" "P,P,i,i,P,P,i,i")))]
-+ ""
-+"* {
-+  operands[2] = GEN_INT(1<<INTVAL(operands[2]));
-+  return      \"bit.b\\t%2, %1\\n\"
-+              \"\\tclr.b\\t%0\\n\"
-+              \"\\tadc.b\\t%0\";
-+}"
-+  [(set_attr "length" "3,4,4,5,5,6,6,7")
-+     (set_attr "cc" "clobber")])
-+
-+(define_expand "extzv"
-+ [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
-+       (zero_extract:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "") 
-+                      (match_operand 2 "const_int_operand" "")
-+                      (match_operand 3 "const_int_operand" "")))]
-+""
-+"{
-+    if(INTVAL(operands[2]) != 1 || INTVAL(operands[3]) <= 0) 
-+      FAIL;
-+}")
-+
-+(define_insn "*extzv" 
-+ [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=r,r,r,r,m,m,m,m")
-+       (zero_extract:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "r,m,r,m,r,m,r,m")
-+                      (match_operand 2 "const_int_operand" "")
-+                      (match_operand 3 "const_int_operand" "P,P,i,i,P,P,i,i")))]
-+ "INTVAL(operands[2]) == 1"
-+"* {
-+  operands[3] = GEN_INT(1<<INTVAL(operands[3]));
-+  return      \"bit.b\\t%3, %1\\n\"
-+              \"\\tclr.b\\t%0\\n\"
-+              \"\\tadc.b\\t%0\";
-+}"
-+  [(set_attr "length" "3,4,4,5,5,6,6,7")
-+     (set_attr "cc" "clobber")])
-+
-+
-+
-+;;=======================================================================
-+;;  various BRANCH insns...
-+;;
-+;;
-+
-+;; return insn
-+(define_insn "return"
-+  [(return)]
-+  "reload_completed && msp430_empty_epilogue()"
-+  "* return msp430_emit_return(insn, operands, NULL);"
-+  [(set_attr "length" "1")
-+   (set_attr "cc" "clobber")]
-+
-+)
-+
-+
-+;; Unconditional jump instruction.
-+(define_insn "jump"
-+  [(set (pc) (label_ref (match_operand 0 "" "")))]
-+  ""
-+  "*
-+{
-+  int dist = msp430_jump_dist(operands[0],insn);
-+  if (dist<500 && dist>-500)
-+    return \"jmp      %0\";
-+  return \"br #%0\"; 
-+}"
-+  [(set_attr "length" "2")
-+   (set_attr "cc" "none")])
-+
-+
-+; indirect jump
-+(define_expand "indirect_jump"
-+  [(set (pc) (match_operand:HI 0 "nonimmediate_operand" ""))]
-+  ""
-+  "")
-+
-+(define_insn "*indirect_jump_idx"
-+  [(set (pc) (match_operand:HI 0 "memory_operand" "m"))]
-+  "indexed_location(operands[0])"
-+  "br @%E0"
-+  [(set_attr "length" "1")
-+   (set_attr "cc" "none")])
-+
-+(define_insn "*indirect_jump_mem"
-+  [(set (pc) (match_operand:HI 0 "memory_operand" "m"))]
-+  "!indexed_location(operands[0])"
-+  "br %0"
-+  [(set_attr "length" "2")
-+   (set_attr "cc" "none")])
-+
-+
-+(define_insn "*indirect_jump_reg"
-+  [(set (pc) (match_operand:HI 0 "register_operand" "r"))]
-+  ""
-+  "br %0"
-+  [(set_attr "length" "1")
-+   (set_attr "cc" "none")])
-+
-+
-+;;=======================================================================
-+;;=======================================================================
-+;;=======================================================================
-+;;=======================================================================
-+
-+
-+;;=======================================================================
-+;;
-+;;    CASE
-+;;
-+
-+/*
-+(define_expand "casesi"
-+  [(set (match_dup 6)  
-+        (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
-+                  (match_operand:HI 1 "register_operand" "")))
-+   (parallel [(set (cc0)
-+                   (compare (match_dup 6)
-+                            (match_operand:HI 2 "register_operand" "")))])
-+   (set (pc)
-+        (if_then_else (gtu (cc0)
-+                           (const_int 0))
-+                      (label_ref (match_operand 4 "" ""))
-+                      (pc)))
-+   (set (match_dup 6)
-+        (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
-+
-+   (parallel [(set (pc) (unspec:HI [(match_dup 6)] 1))
-+              (use (label_ref (match_dup 3)))
-+              (clobber (match_dup 6))])]
-+  ""
-+  " 
-+{   
-+  operands[6] = gen_reg_rtx (HImode);
-+}")
-+
-+*/ 
-+
-+;; Table helper
-+(define_insn "tablejump"
-+  [(set (pc) (match_operand:HI 0 "general_operand" "rRP,i,m"))
-+   (use (label_ref (match_operand 1 "" "")))]
-+  ""
-+  "br %0      ;       %1"
-+ [(set_attr "length" "1,2,2")   
-+   (set_attr "cc" "clobber")])
-+
-+
-+;; =============================================================
-+;; match De Morgan's law
-+(define_insn "nandqi"
-+  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=r,m,m,r")
-+             (and:QI (not:QI (match_operand:QI 1 "general_operand_msp430" "rRP,mi,rRP,mi"))
-+                           (match_operand:QI 2 "nonimmediate_operand_msp430" "0,0,0,0")))]
-+""
-+"bic.b       %1, %0"
-+[(set_attr "length" "1,3,2,2")
-+  (set_attr "cc" "none")])
-+
-+(define_insn "nandhi"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m,m,r")
-+             (and:HI (not:HI (match_operand:HI 1 "general_operand_msp430" "rRP,mi,rRP,mi"))
-+                           (match_operand:HI 2 "nonimmediate_operand_msp430" "0,0,0,0")))]
-+""
-+"bic %1, %0"
-+[(set_attr "length" "1,3,2,2")
-+  (set_attr "cc" "none")])
-+
-+(define_insn "nandsi"
-+  [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "=r,m,m,r,r,m")
-+            (and:SI (not:SI (match_operand:SI 1 "general_operand_msp430" "rP,mi,rP,mi,R,R"))
-+                          (match_operand:SI 2 "nonimmediate_operand_msp430" "0,0,0,0,0,0")))]
-+""
-+"bic    %A1, %A0
-+\\tbic  %B1, %B0"
-+[(set_attr "length" "2,6,4,4,3,5")
-+  (set_attr "cc" "none")])
-+
-+
-+
-+;; =============================================================
-+;; PEEPHOLES
-+
-+;; a &= ~b;
-+
-+(define_insn "*bit_clear"
-+ [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m,m,r") 
-+       (unspec_volatile:HI [(match_operand:HI 1 "general_operand_msp430" "rRP,mi,rRP,mi")] 40))]
-+""
-+"bic  %1, %0"
-+  [(set_attr "length" "1,3,2,2")
-+     (set_attr "cc" "none")])
-+
-+
-+;; these two for:
-+;; (ulong) x = (ulong) func() << 16;
-+;; x |= func();
-+;; func() is uint
-+;;
-+
-+;; do not check for zeros here, cause this insn already issued.
-+(define_peephole2
-+   [(set (match_operand:SI 1 "register_operand" "")
-+         (sign_extend:SI (match_operand:HI 0 "register_operand" "")))
-+    (set (match_dup 1) (ashift:SI (match_dup 1) (const_int 16)))]
-+""
-+  [(set (subreg:HI (match_dup 1) 2) (match_dup 0))]
-+"")
-+
-+(define_peephole2
-+   [(set (match_operand:SI 1 "register_operand" "")
-+         (zero_extend:SI (match_operand:HI 0 "register_operand" "")))
-+    (set (match_dup 1) (ashift:SI (match_dup 1) (const_int 16)))]
-+""
-+  [(set (subreg:HI (match_dup 1) 2) (match_dup 0))]
-+"")
-+
-+(define_peephole2
-+   [(set (match_operand:SI 0 "register_operand" "")
-+         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
-+    (set (match_operand:SI 2 "register_operand" "")
-+         (ior:SI (match_dup 2) (match_dup 0)))]
-+"dead_or_set_in_peep(1,insn, operands[0])"
-+  [(set (subreg:HI (match_dup 2) 0) 
-+        (ior:HI (subreg:HI (match_dup 2) 0) (match_dup 1)))]
-+"")
-+
-+(define_peephole2
-+   [(set (match_operand:HI 0 "register_operand" "")  
-+         (match_operand:HI 1 "general_operand_msp430" ""))
-+    (set (match_operand:SI 2 "register_operand" "")
-+         (zero_extend:SI (match_dup 0)))
-+    (set (match_operand:SI 3 "register_operand" "") 
-+         (ior:SI (match_dup 3) (match_dup 2)))]
-+"dead_or_set_in_peep(2,insn, operands[0])"
-+  [(set (subreg:HI (match_dup 3) 0) 
-+        (ior:HI (subreg:HI (match_dup 3) 0) (match_dup 1)))]
-+"")
-+
-+
-+;; (ulong) x = (ulong) f >> 16;
-+;;
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "") 
-+      (match_operand:SI 1 "register_operand" "")) 
-+   (set (match_dup 0) 
-+      (lshiftrt:SI (match_dup 0) 
-+                   (const_int 16)))]
-+""
-+[(set (subreg:HI (match_dup 0) 0) (subreg:HI (match_dup 1) 2))
-+ (set (subreg:HI (match_dup 0) 2) (const_int 0))]
-+"")
-+
-+
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "") 
-+      (match_operand:SI 1 "register_operand" ""))
-+   (set (match_operand:SI 2 "register_operand" "")
-+      (ior:SI (match_dup 2) (match_dup 0)))]
-+"dead_or_set_in_peep(1,insn, operands[0])"
-+  [(set (match_dup 2) (ior:SI (match_dup 2) 
-+                            (match_dup 1)))]
-+"")
-+
-+
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "") 
-+      (zero_extend:SI (match_operand:HI 1 "general_operand" "")))
-+   (set (match_dup 0) 
-+      (ashift:SI (match_dup 0) (const_int 16)))]
-+""
-+  [(set (subreg:HI (match_dup 0) 2) (match_dup 1))]
-+"")
-+
-+
-+;; shift right & set
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "") 
-+      (match_operand:HI 1 "register_operand" ""))
-+   (set (match_operand:HI 2 "register_operand" "")
-+      (match_dup 0))
-+   (set (match_dup 2) 
-+      (and:HI (match_dup 2) 
-+              (match_operand 3 "const_int_operand" "")))
-+   (set (match_dup 2) 
-+      (lshiftrt:HI (match_dup 2) 
-+                   (match_operand 4 "const_int_operand" ""))) 
-+   (set (match_dup 1) (match_dup 2))]
-+"dead_or_set_in_peep(4,insn, operands[2])"
-+  [(set (match_dup 0) (match_dup 1))
-+   (set (match_dup 1)  
-+      (and:HI (match_dup 1)  
-+              (match_dup 3))) 
-+   (set (match_dup 1) 
-+      (lshiftrt:HI (match_dup 1) 
-+                   (match_dup 4)))] 
-+"")
-+
-+;; shift left and set
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "") 
-+      (match_operand:HI 1 "register_operand" ""))
-+   (set (match_operand:HI 2 "register_operand" "")
-+      (match_dup 0))
-+   (set (match_dup 2) 
-+      (and:HI (match_dup 2) 
-+              (match_operand 3 "const_int_operand" "")))
-+   (set (match_dup 2) 
-+      (ashift:HI (match_dup 2) 
-+                 (match_operand 4 "const_int_operand" ""))) 
-+   (set (match_dup 1) (match_dup 2))]
-+"dead_or_set_in_peep(4,insn, operands[2])"
-+  [(set (match_dup 0) (match_dup 1))
-+   (set (match_dup 1)  
-+      (and:HI (match_dup 1)  
-+              (match_dup 3))) 
-+   (set (match_dup 1) 
-+      (ashift:HI (match_dup 1) 
-+                 (match_dup 4)))] 
-+"")
-+
-+
-+;;
-+;; these for some shifts and stuff.
-+;; every peephole saves up to 4 bytes.
-+;;
-+
-+(define_insn "*addc_reg"
-+  [(set (match_operand:HI 0 "register_operand" "=r,r") 
-+      (unspec:HI [(match_operand:HI 1 "register_operand" "%0,0") 
-+                  (match_operand:HI 2 "general_operand_msp430" "rP,mi")] 0))]
-+""
-+"addc %2, %0"
-+[(set_attr "length" "1,2")
-+   (set_attr "cc" "clobber,clobber")])
-+
-+
-+(define_insn "*addc_any"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=m,m") 
-+      (unspec:HI [(match_operand:HI 1 "nonimmediate_operand_msp430" "%0,0") 
-+                  (match_operand:HI 2 "general_operand_msp430" "rP,mi")] 5))]
-+""
-+"addc %2, %0"
-+[(set_attr "length" "2,3")
-+   (set_attr "cc" "clobber,clobber")])
-+
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "") 
-+      (match_operand:HI 1 "general_operand_msp430" ""))
-+   (set (match_operand:SI 2 "register_operand" "") 
-+      (zero_extend:SI (match_dup 0)))
-+   (set (match_operand:SI 3 "register_operand" "") 
-+      (plus:SI (match_dup 3) (match_dup 2)))]
-+"dead_or_set_in_peep(2,insn, operands[2])"
-+  [(set (subreg:HI (match_dup 3) 0) 
-+      (plus:HI (subreg:HI (match_dup 3) 0) 
-+               (match_dup 1)))
-+   (set (subreg:HI (match_dup 3) 2) 
-+      (unspec:HI [(subreg:HI (match_dup 3) 2) (const_int 0)] 0))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "") 
-+      (match_operand:HI 1 "general_operand_msp430" ""))
-+   (set (match_operand:SI 2 "register_operand" "") 
-+      (zero_extend:SI (match_dup 0)))
-+   (set (match_operand:SI 3 "nonimmediate_operand_msp430" "") 
-+      (plus:SI (match_dup 3) (match_dup 2)))]
-+"dead_or_set_in_peep(2,insn, operands[2])"
-+  [(set (subreg:HI (match_dup 3) 0) 
-+      (plus:HI (subreg:HI (match_dup 3) 0) 
-+               (match_dup 1)))
-+   (set (subreg:HI (match_dup 3) 2) 
-+      (unspec:HI [(subreg:HI (match_dup 3) 2) (const_int 0)] 5))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "")
-+        (match_operand:HI 1 "general_operand_msp430" ""))
-+   (set (match_operand:SI 2 "nonimmediate_operand_msp430" "")
-+        (zero_extend:SI (match_dup 0)))]
-+"dead_or_set_in_peep(1,insn, operands[0])"
-+  [(set (subreg:HI (match_dup 2) 0) (match_dup 1))
-+   (set (subreg:HI (match_dup 2) 2) (const_int 0))]
-+"")
-+
-+;;
-+;; these are for redudant moves.
-+;;
-+
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "") 
-+      (match_operand:SI 1 "nonimmediate_operand_msp430" ""))
-+   (set (match_operand:SI 2 "register_operand" "") 
-+      (ior:SI (match_dup 2) (match_dup 0)))
-+   (set (match_dup 1) (match_dup 2))]
-+"dead_or_set_in_peep(1,insn, operands[0])"
-+  [(set (match_dup 1) (ior:SI (match_dup 1) (match_dup 2)))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "")
-+      (ior:SI (match_dup 0) 
-+              (match_operand:SI 1 "register_operand" "")))
-+   (set (match_dup 1) (match_dup 0))]
-+"dead_or_set_in_peep(1,insn, operands[0])"
-+  [(set (match_dup 1) (ior:SI (match_dup 1) (match_dup 0)))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "") 
-+      (match_operand:HI 1 "register_operand" ""))
-+   (set (match_dup 0) 
-+      (not:HI (match_dup 0)))
-+   (set (match_operand:HI 2 "register_operand" "") 
-+      (match_dup 0))]
-+"dead_or_set_in_peep(2,insn, operands[0]) && dead_or_set_in_peep(0,insn, operands[1])"
-+  [(set (match_dup 1) (not:HI (match_dup 1)))
-+   (set (match_dup 2) (match_dup 1))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "") 
-+      (match_operand:SI 1 "register_operand" ""))
-+   (set (match_dup 0) 
-+      (not:SI (match_dup 0)))
-+   (set (match_operand:SI 2 "register_operand" "") 
-+      (match_dup 0))]
-+"dead_or_set_in_peep(2,insn, operands[0]) && dead_or_set_in_peep(0,insn, operands[1])"
-+  [(set (match_dup 1) (not:SI (match_dup 1)))
-+   (set (match_dup 2) (match_dup 1))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:SF 0 "register_operand" "")
-+      (match_operand:SF 1 "general_operand_msp430" ""))
-+   (set (match_operand:SF 2 "nonimmediate_operand_msp430" "") 
-+      (match_dup 0))]
-+"dead_or_set_in_peep(1,insn, operands[0])"
-+  [(set (match_dup 2) (match_dup 1))]
-+"")
-+
-+
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "")
-+      (match_operand:SI 1 "general_operand_msp430" ""))
-+   (set (match_operand:SI 2 "nonimmediate_operand_msp430" "") 
-+      (match_dup 0))]
-+"dead_or_set_in_peep(1,insn, operands[0])"
-+  [(set (match_dup 2) (match_dup 1))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "")
-+        (match_operand:HI 1 "general_operand_msp430" ""))
-+   (set (match_operand:HI 2 "nonimmediate_operand_msp430" "")
-+        (match_dup 0))]
-+"dead_or_set_in_peep(1,insn, operands[0])"
-+  [(set (match_dup 2) (match_dup 1))]
-+"")
-+
-+
-+
-+;; =========================================================================
-+;;  This one for bit tests like:
-+;;    volatile long a;
-+;;    while(a&CONST_HALFNIBBLE) ;
-+
-+(define_insn "*bittest_lo"
-+  [(set (cc0) 
-+      (unspec:SI [(match_operand:SI 0 "nonimmediate_operand_msp430" "r,r,m,m") 
-+                  (match_operand:SI 1 "general_operand_msp430" "rPR,mi,rPR,mi")] 1))]
-+""
-+"bit  %A1,%A0"
-+[(set_attr "length" "1,2,2,3")
-+   (set_attr "cc" "compare,compare,compare,compare")])
-+
-+(define_insn "*bittest_hi"
-+  [(set (cc0) 
-+      (unspec:SI [(match_operand:SI 0 "nonimmediate_operand_msp430" "r,r,m,m") 
-+                  (match_operand:SI 1 "general_operand_msp430" "rPR,mi,rPR,mi")] 2))]
-+""
-+"bit  %B1,%B0"
-+[(set_attr "length" "1,2,2,3")
-+   (set_attr "cc" "compare,compare,compare,compare")])
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+       (match_operand:SI 1 "nonimmediate_operand_msp430" ""))
-+  (set (match_dup 0) (and:SI (match_dup 0) 
-+                             (match_operand 2 "const_int_operand" "")))
-+  (set (pc) 
-+       (if_then_else (match_operator:SI 3 "equality_operator"
-+                    [(match_dup 0) (const_int 0)]) 
-+       (label_ref (match_operand 4 "" ""))
-+       (pc)))]
-+"(halfnibble_integer(operands[2], VOIDmode) 
-+   || halfnibble_constant(operands[2], VOIDmode))
-+        && dead_or_set_in_peep(2,insn, operands[0])
-+      && which_nibble(INTVAL(operands[2])) == 0"
-+  [(set (cc0) 
-+      (unspec:SI [(match_dup 1) (match_dup 2)] 1))
-+   (set (pc) (if_then_else (match_op_dup 3
-+                          [(cc0) (const_int 0)])
-+           (label_ref (match_dup 4))
-+           (pc)))]
-+"")
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+       (match_operand:SI 1 "nonimmediate_operand_msp430" ""))
-+  (set (match_dup 0) (and:SI (match_dup 0) 
-+                             (match_operand 2 "const_int_operand" "")))
-+  (set (pc) (if_then_else (match_operator:SI 3 "equality_operator"
-+                         [(match_dup 0) (const_int 0)])
-+          (label_ref (match_operand 4 "" ""))
-+          (pc)))]
-+"(halfnibble_integer(operands[2], VOIDmode) 
-+   || halfnibble_constant(operands[2], VOIDmode))
-+        && dead_or_set_in_peep(2,insn, operands[0])
-+      && which_nibble(INTVAL(operands[2])) == 1"
-+  [(set (cc0) 
-+      (unspec:SI [(match_dup 1) (match_dup 2)] 2))
-+   (set (pc) (if_then_else (match_op_dup 3
-+                          [(cc0) (const_int 0)])
-+           (label_ref (match_dup 4))
-+           (pc)))]
-+"")
-+
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+       (match_operand:SI 1 "nonimmediate_operand_msp430" ""))
-+  (set (match_dup 0) (and:SI (match_dup 0) 
-+                             (match_operand 2 "const_int_operand" "")))
-+  (set (pc) 
-+       (if_then_else (match_operator:HI 3 "equality_operator"
-+                    [(match_operand:HI 4 "register_operand" "") (const_int 0)]) 
-+       (label_ref (match_operand 5 "" ""))
-+       (pc)))]
-+"(halfnibble_integer(operands[2], VOIDmode) 
-+   || halfnibble_constant(operands[2], VOIDmode))
-+        && dead_or_set_in_peep(2,insn, operands[0])
-+      && which_nibble(INTVAL(operands[2])) == 1
-+      && REGNO(operands[4]) == REGNO(operands[0])+1"
-+  [(set (cc0) 
-+      (unspec:SI [(match_dup 1) (match_dup 2)] 1))
-+   (set (pc) (if_then_else (match_op_dup 3
-+                          [(cc0) (const_int 0)])
-+           (label_ref (match_dup 5))
-+           (pc)))]
-+"")
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+       (match_operand:SI 1 "nonimmediate_operand_msp430" ""))
-+  (set (match_dup 0) (and:SI (match_dup 0) 
-+                             (match_operand 2 "const_int_operand" "")))
-+  (set (pc) 
-+       (if_then_else (match_operator:HI 3 "equality_operator"
-+                    [(match_operand:HI 4 "register_operand" "") (const_int 0)]) 
-+       (label_ref (match_operand 5 "" ""))
-+       (pc)))]
-+"(halfnibble_integer(operands[2], VOIDmode) 
-+   || halfnibble_constant(operands[2], VOIDmode))
-+        && dead_or_set_in_peep(2,insn, operands[0])
-+      && which_nibble(INTVAL(operands[2])) == 0
-+      && REGNO(operands[4]) == REGNO(operands[0])"
-+  [(set (cc0) 
-+      (unspec:SI [(match_dup 1) (match_dup 2)] 1))
-+   (set (pc) (if_then_else (match_op_dup 3
-+                          [(cc0) (const_int 0)])
-+           (label_ref (match_dup 5))
-+           (pc)))]
-+"")
-+
-+;;
-+;;  The same for HI mode: while(smts&0xXXXX) ;
-+;;
-+(define_insn "*bittest"
-+  [(set (cc0)
-+        (unspec:HI [(match_operand:HI 0 "general_operand_msp430" "r,r,m,m")
-+                    (match_operand:HI 1 "general_operand_msp430" "rPR,mi,rPR,mi")] 6))]
-+""
-+"bit  %1,%0"
-+[(set_attr "length" "1,2,2,3")
-+   (set_attr "cc" "compare,compare,compare,compare")])
-+
-+
-+(define_peephole2
-+ [(set (match_operand:HI 0 "register_operand" "")
-+       (match_operand:HI 1 "nonimmediate_operand_msp430" ""))
-+  (set (match_dup 0) (and:HI (match_dup 0) 
-+                             (match_operand 2 "const_int_operand" "")))
-+  (set (pc) (if_then_else (match_operator:HI 3 "equality_operator"
-+                         [(match_dup 0) (const_int 0)])
-+          (label_ref (match_operand 4 "" "")) 
-+          (pc)))]
-+"dead_or_set_in_peep(2,insn, operands[0]) "
-+  [(set (cc0) 
-+      (unspec:HI [(match_dup 1) (match_dup 2)] 6))
-+   (set (pc) (if_then_else (match_op_dup 3
-+                          [(cc0) (const_int 0)])
-+           (label_ref (match_dup 4))
-+           (pc)))]
-+"")
-+
-+
-+;; The same for QI mode
-+
-+(define_insn "*bittest_b"
-+  [(set (cc0)
-+        (unspec:QI [(match_operand:QI 0 "general_operand_msp430" "r,r,m,m")
-+                    (match_operand:QI 1 "general_operand_msp430" "rPR,mi,rPR,mi")] 7))]
-+""
-+"bit.b        %1,%0"
-+[(set_attr "length" "1,2,2,3")
-+   (set_attr "cc" "compare,compare,compare,compare")])
-+
-+
-+(define_peephole2
-+ [(set (match_operand:QI 0 "register_operand" "")
-+       (match_operand:QI 1 "nonimmediate_operand_msp430" ""))
-+  (set (match_dup 0) (and:QI (match_dup 0) 
-+                             (match_operand 2 "const_int_operand" "")))
-+  (set (pc) (if_then_else (match_operator:QI 3 "equality_operator"
-+                         [(match_dup 0) (const_int 0)])
-+          (label_ref (match_operand 4 "" "")) 
-+          (pc)))]
-+"dead_or_set_in_peep(2,insn, operands[0]) "
-+  [(set (cc0) 
-+      (unspec:QI [(match_dup 1) (match_dup 2)] 7))
-+   (set (pc) (if_then_else (match_op_dup 3
-+                          [(cc0) (const_int 0)])
-+           (label_ref (match_dup 4))
-+           (pc)))]
-+"")
-+
-+
-+
-+;;===========================================================================
-+
-+(define_peephole2
-+  [(set (match_operand:QI 0 "register_operand" "")
-+        (match_operand:QI 1 "general_operand_msp430" ""))
-+   (set (match_dup 0)
-+      (minus:QI (match_dup 0) 
-+                (match_operand:QI 2 "general_operand_msp430" "")))
-+   (set (match_operand:QI 3 "register_operand" "")
-+      (match_dup 0))]
-+"dead_or_set_in_peep(2,insn, operands[0]) && 0"
-+  [(set (match_dup 3) (match_dup 1))
-+   (set (match_dup 3) (minus:QI (match_dup 3) (match_dup 2)))]
-+"")
-+
-+
-+(define_peephole2
-+  [(set (match_operand:QI 0 "register_operand" "")
-+        (match_operand:QI 1 "general_operand_msp430" ""))
-+   (set (match_dup 0)
-+      (plus:QI (match_dup 0) 
-+               (match_operand:QI 2 "general_operand_msp430" "")))
-+   (set (match_operand:QI 3 "register_operand" "")
-+      (match_dup 0))]
-+"dead_or_set_in_peep(2,insn, operands[0]) && 0"
-+  [(set (match_dup 3) (match_dup 1))
-+   (set (match_dup 3) (plus:QI (match_dup 3) (match_dup 2)))]
-+"")
-+
-+
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "")
-+        (match_operand:HI 1 "general_operand_msp430" ""))
-+   (set (match_dup 0)
-+      (minus:HI (match_dup 0) 
-+                (match_operand:HI 2 "general_operand_msp430" "")))
-+   (set (match_operand:HI 3 "register_operand" "")
-+      (match_dup 0))]
-+"dead_or_set_in_peep(2,insn, operands[0]) && 0"
-+  [(set (match_dup 3) (match_dup 1))
-+   (set (match_dup 3) (minus:HI (match_dup 3) (match_dup 2)))]
-+"")
-+
-+
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "")
-+        (match_operand:HI 1 "general_operand_msp430" ""))
-+   (set (match_dup 0)
-+      (plus:HI (match_dup 0) 
-+               (match_operand:HI 2 "general_operand_msp430" "")))
-+   (set (match_operand:HI 3 "register_operand" "")
-+      (match_dup 0))]
-+"dead_or_set_in_peep(2,insn, operands[0]) && 0"
-+  [(set (match_dup 3) (match_dup 1))
-+   (set (match_dup 3) (plus:HI (match_dup 3) (match_dup 2)))]
-+"")
-+
-+
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "")
-+        (match_operand:SI 1 "general_operand_msp430" ""))
-+   (set (match_dup 0)
-+      (minus:SI (match_dup 0) 
-+                (match_operand:SI 2 "general_operand_msp430" "")))
-+   (set (match_operand:SI 3 "register_operand" "")
-+      (match_dup 0))]
-+"dead_or_set_in_peep(2,insn, operands[0]) && 0"
-+  [(set (match_dup 3) (match_dup 1))
-+   (set (match_dup 3) (minus:SI (match_dup 3) (match_dup 2)))]
-+"")
-+
-+
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "")
-+        (match_operand:SI 1 "general_operand_msp430" ""))
-+   (set (match_dup 0)
-+      (plus:SI (match_dup 0) 
-+               (match_operand:SI 2 "general_operand_msp430" "")))
-+   (set (match_operand:SI 3 "register_operand" "")
-+      (match_dup 0))]
-+"dead_or_set_in_peep(2,insn, operands[0]) && 0"
-+  [(set (match_dup 3) (match_dup 1))
-+   (set (match_dup 3) (plus:SI (match_dup 3) (match_dup 2)))]
-+"")
-+
-+
-+;; =============================================================
-+;; 
-+;;  adjust frame pointer index
-+;;
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "") 
-+      (sign_extend:HI (match_operand:QI 1 "general_operand_msp430" "")))
-+   (set (match_dup 0) 
-+      (plus:HI (match_dup 0) (match_operand:HI 2 "general_operand_msp430" "")))
-+   (set (match_operand:HI 3 "register_operand" "")
-+      (match_dup 0))]
-+"dead_or_set_in_peep(2,insn, operands[0])"
-+  [(set (match_dup 3) (sign_extend:HI (match_dup 1)))
-+   (set (match_dup 3) (plus:HI (match_dup 3) (match_dup 2)))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "") 
-+      (sign_extend:SI (match_operand:HI 1 "general_operand_msp430" "")))
-+   (set (match_dup 0) 
-+      (plus:SI (match_dup 0) (match_operand:SI 2 "general_operand_msp430" "")))
-+   (set (match_operand:SI 3 "register_operand" "")
-+      (match_dup 0))]
-+"dead_or_set_in_peep(2,insn, operands[0])"
-+  [(set (match_dup 3) (sign_extend:SI (match_dup 1)))
-+   (set (match_dup 3) (plus:SI (match_dup 3) (match_dup 2)))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "") 
-+      (sign_extend:HI (match_operand:QI 1 "general_operand_msp430" "")))
-+   (set (match_dup 0) 
-+      (minus:HI (match_dup 0) (match_operand:HI 2 "general_operand_msp430" "")))
-+   (set (match_operand:HI 3 "register_operand" "")
-+      (match_dup 0))]
-+"dead_or_set_in_peep(2,insn, operands[0])"
-+  [(set (match_dup 3) (sign_extend:HI (match_dup 1)))
-+   (set (match_dup 3) (minus:HI (match_dup 3) (match_dup 2)))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "") 
-+      (sign_extend:SI (match_operand:HI 1 "general_operand_msp430" "")))
-+   (set (match_dup 0) 
-+      (minus:SI (match_dup 0) (match_operand:SI 2 "general_operand_msp430" "")))
-+   (set (match_operand:SI 3 "register_operand" "")
-+      (match_dup 0))]
-+"dead_or_set_in_peep(2,insn, operands[0])"
-+  [(set (match_dup 3) (sign_extend:SI (match_dup 1)))
-+   (set (match_dup 3) (minus:SI (match_dup 3) (match_dup 2)))]
-+"")
-+
-+;; =============================================================
-+;; mov & 'and'
-+
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "") 
-+      (match_operand:HI 1 "nonimmediate_operand_msp430" ""))
-+   (set (match_dup 0) 
-+      (and:HI (match_dup 0) 
-+              (match_operand:HI 2 "general_operand_msp430" ""))) 
-+   (set (match_dup 1) (match_dup 0))]
-+"dead_or_set_in_peep(2,insn, operands[0])"
-+  [(set (match_dup 1) 
-+      (and:HI (match_dup 1) (match_dup 2)))]
-+"")
-+
-+
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "") 
-+      (match_operand:SI 1 "nonimmediate_operand_msp430" ""))
-+   (set (match_dup 0) 
-+      (and:SI (match_dup 0) 
-+              (match_operand:SI 2 "general_operand_msp430" ""))) 
-+   (set (match_dup 1) (match_dup 0))]
-+"dead_or_set_in_peep(2,insn, operands[0])"
-+  [(set (match_dup 1) 
-+      (and:SI (match_dup 1) (match_dup 2)))]
-+"")
-+
-+
-+
-+;; =============================================================
-+;; SWAP BYTES (should be a pattern for:
-+;;   r = (a<<8)|(a>>8);
-+
-+(define_insn "swpb"
-+  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=rR,m") 
-+      (unspec:HI [(match_operand:HI 1 "nonimmediate_operand_msp430" "0,0")] 4))]
-+""
-+"swpb %0"
-+[(set_attr "length" "1,2")
-+   (set_attr "cc" "clobber,clobber")])
-+
-+;;
-+;; after mult and stuff
-+;;
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "") 
-+      (reg:SI 14))
-+   (set (match_operand:SI 1 "nonimmediate_operand_msp430" "") 
-+      (match_dup 0))]
-+"dead_or_set_in_peep(1,insn,operands[0])"
-+  [(set (match_dup 1) (reg:SI 14))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "") 
-+      (reg:HI 14))
-+   (set (match_operand:HI 1 "nonimmediate_operand_msp430" "") 
-+      (match_dup 0))]
-+"dead_or_set_in_peep(1,insn,operands[0])"
-+  [(set (match_dup 1) (reg:HI 14))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "") 
-+      (reg:SI 12))
-+   (set (match_operand:SI 1 "nonimmediate_operand_msp430" "") 
-+      (match_dup 0))]
-+"dead_or_set_in_peep(1,insn,operands[0])"
-+  [(set (match_dup 1) (reg:SI 12))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "") 
-+      (reg:HI 12))
-+   (set (match_operand:HI 1 "nonimmediate_operand_msp430" "") 
-+      (match_dup 0))]
-+"dead_or_set_in_peep(1,insn,operands[0])"
-+  [(set (match_dup 1) (reg:HI 12))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "") 
-+      (sign_extend:SI (match_operand:QI 1 "general_operand_msp430" "")))
-+   (set (match_operand:SI 2 "nonimmediate_operand_msp430" "") 
-+      (match_dup 0))]
-+"dead_or_set_in_peep(1,insn,operands[0])"
-+  [(set (match_dup 2) (sign_extend:SI (match_dup 1)))]
-+"")
-+
-+(define_peephole2
-+  [(set (match_operand:SI 0 "register_operand" "") 
-+      (sign_extend:SI (match_operand:HI 1 "general_operand_msp430" "")))
-+   (set (match_operand:SI 2 "nonimmediate_operand_msp430" "") 
-+      (match_dup 0))]
-+"dead_or_set_in_peep(1,insn,operands[0])"
-+  [(set (match_dup 2) (sign_extend:SI (match_dup 1)))]
-+"")
-+
-+
-+;; =============================================================
-+
-+(define_peephole 
-+  [(set (match_operand:HI 0 "register_operand" "") 
-+      (sign_extend:HI (match_operand:QI 1 "register_operand" ""))) 
-+   (set (match_operand:HI 2 "register_operand" "") 
-+      (plus:HI (match_dup 2) (match_dup 0)))]
-+"dead_or_set_in_peep(1,insn,operands[0])" 
-+"sxt  %1
-+      add     %1, %2"
-+[(set_attr "length" "3")
-+   (set_attr "cc" "clobber")])
-+
-+
-+(define_peephole 
-+  [(set (match_operand:HI 0 "register_operand" "") 
-+      (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand_msp430" ""))) 
-+   (set (match_operand:HI 2 "register_operand" "") (match_dup 0))]
-+"dead_or_set_in_peep(1,insn,operands[0])" 
-+"mov.b        %1, %2
-+      sxt     %2"
-+[(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-+
-+;; ============================================================= 
-+;; a = (uint16_t)( (uint8_t)SFR ) << 8;
-+;; (inderect_jump + 50)
-+(define_peephole 
-+  [(set (match_operand:QI 0 "register_operand" "") 
-+      (match_operand:QI 1 "memory_operand_msp430" "m"))
-+   (set (match_operand:HI 2 "register_operand" "")
-+      (ashift:HI (match_dup 2) (const_int 8)))]
-+  "REGNO(operands[0]) == REGNO(operands[2])"
-+"mov.b        %1, %0
-+      swpb    %2"
-+[(set_attr "length" "3")
-+   (set_attr "cc" "clobber")])
-+
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "") 
-+      (ior:HI (match_dup 0) 
-+              (match_operand:HI 1 "register_operand" "")))
-+   (set (match_operand:SI 2 "register_operand" "") 
-+      (match_operand:SI 3 "register_operand" ""))]
-+"(REGNO(operands[0]) == REGNO(operands[2])
-+  && REGNO(operands[3])+1 == REGNO(operands[0]))"
-+  [(set (match_dup 1) 
-+      (ior:HI (match_dup 1) 
-+              (match_dup 0)))
-+   (set (subreg:HI (match_dup 2) 0)
-+      (subreg:HI (match_dup 3) 0))]
-+"")
-+
-+
-+
-+;; =============================================================
-+;; combine ior and mov.
-+;;
-+(define_peephole2
-+[(set (match_operand:QI 0 "register_operand" "") 
-+      (ior:QI (match_dup 0) 
-+                    (match_operand:QI 1 "nonimmediate_operand_msp430" "")))
-+ (set (match_dup 1) (match_dup 0))]
-+"dead_or_set_in_peep(1,insn,operands[0])"
-+[(set (match_dup 1) (ior:QI (match_dup 1) (match_dup 0)))]
-+"")
-+
-+(define_peephole2
-+[(set (match_operand:HI 0 "register_operand" "") 
-+      (ior:HI (match_dup 0) 
-+                    (match_operand:HI 1 "nonimmediate_operand_msp430" "")))
-+ (set (match_dup 1) (match_dup 0))]
-+"dead_or_set_in_peep(1,insn,operands[0])"
-+[(set (match_dup 1) (ior:HI (match_dup 1) (match_dup 0)))]
-+"")
-+
-+(define_peephole2
-+[(set (match_operand:SI 0 "register_operand" "") 
-+      (ior:SI (match_dup 0) 
-+                    (match_operand:SI 1 "nonimmediate_operand_msp430" "")))
-+ (set (match_dup 1) (match_dup 0))]
-+"dead_or_set_in_peep(1,insn,operands[0])"
-+[(set (match_dup 1) (ior:SI (match_dup 1) (match_dup 0)))]
-+"")
-+
-+(define_peephole2
-+[(set (match_operand:DI 0 "register_operand" "") 
-+      (ior:DI (match_dup 0) 
-+                    (match_operand:DI 1 "nonimmediate_operand_msp430" "")))
-+ (set (match_dup 1) (match_dup 0))]
-+"dead_or_set_in_peep(1,insn,operands[0])"
-+[(set (match_dup 1) (ior:DI (match_dup 1) (match_dup 0)))]
-+"")
-+
-+
-+
-diff -urN -x CVS gcc-3.2.3.orig/gcc/config/msp430/msp430-protos.h gcc-3.2.3/gcc/config/msp430/msp430-protos.h
---- gcc-3.2.3.orig/gcc/config/msp430/msp430-protos.h   1969-12-31 17:00:00.000000000 -0700
-+++ gcc-3.2.3/gcc/config/msp430/msp430-protos.h        2008-08-22 09:17:00.000000000 -0600
-@@ -0,0 +1,301 @@
-+/* Prototypes for exported functions defined in msp430.c
-+   
-+   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
-+   Contributed by Dmitry Diky <diwil@mail.ru>
-+
-+   This file is part of GNU CC.
-+
-+   GNU CC is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; either version 2, or (at your option)
-+   any later version.
-+
-+   GNU CC is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+
-+   You should have received a copy of the GNU General Public License
-+   along with GNU CC; see the file COPYING.  If not, write to
-+   the Free Software Foundation, 59 Temple Place - Suite 330,
-+   Boston, MA 02111-1307, USA.  */
-+
-+
-+extern void   bootloader_section PARAMS ((void));
-+extern void   infomem_section PARAMS ((void));
-+
-+extern void   asm_file_start            PARAMS ((FILE *file));
-+extern void   asm_file_end              PARAMS ((FILE *file));
-+extern void   msp430_init_once          PARAMS ((void));
-+extern void   msp430_override_options   PARAMS ((void));
-+extern void   function_prologue         PARAMS ((FILE *file, int size));
-+extern void   function_epilogue         PARAMS ((FILE *file, int size));
-+extern void   gas_output_limited_string PARAMS ((FILE *file, const char *str));
-+extern void   gas_output_ascii          PARAMS ((FILE *file, const char *str,
-+                                                       size_t length));
-+extern void   order_regs_for_local_alloc PARAMS ((void));
-+extern void msp430_trampoline_template PARAMS ((FILE *fd));
-+
-+
-+extern int frame_pointer_required_p PARAMS ((void));
-+extern int msp430_empty_epilogue PARAMS ((void));
-+
-+int msp430_regno_ok_for_base_p PARAMS ((int));
-+
-+
-+#ifdef HAVE_MACHINE_MODES
-+extern int    msp430_hard_regno_mode_ok PARAMS ((int regno,
-+                                           enum machine_mode mode));
-+#endif
-+
-+extern int initial_elimination_offset PARAMS ((int, int));
-+
-+
-+
-+#ifdef TREE_CODE
-+extern void   asm_output_external          PARAMS ((FILE *file, tree decl,
-+                                                 char *name));
-+extern void   unique_section               PARAMS ((tree decl, int reloc));
-+extern void   encode_section_info          PARAMS ((tree decl));
-+extern void   asm_output_section_name      PARAMS ((FILE *file, tree decl,
-+                                                 const char *name,
-+                                                 int reloc));
-+extern int    valid_machine_type_attribute PARAMS ((tree type, tree attributes,
-+                                                 tree identifier,
-+                                                 tree args));
-+extern int    valid_machine_decl_attribute PARAMS ((tree decl, tree attributes,
-+                                                 tree attr, tree args));
-+extern void asm_declare_function_name PARAMS ((FILE *, char *, tree));
-+unsigned int msp430_section_type_flags PARAMS (( tree DECL, const char *NAME, int RELOC));
-+
-+
-+#ifdef RTX_CODE /* inside TREE_CODE */
-+extern rtx    msp430_function_value          PARAMS ((tree type, tree func));
-+extern void   init_cumulative_args           PARAMS ((CUMULATIVE_ARGS *cum,
-+                                                 tree fntype, rtx libname,
-+                                                 int indirect));
-+extern rtx    function_arg         PARAMS ((CUMULATIVE_ARGS *cum,
-+                                         enum machine_mode mode,
-+                                         tree type, int named));
-+extern void   init_cumulative_incoming_args           PARAMS ((CUMULATIVE_ARGS *cum,
-+                                                 tree fntype, rtx libname));
-+extern rtx    function_incoming_arg         PARAMS ((CUMULATIVE_ARGS *cum,
-+                                         enum machine_mode mode,
-+                                         tree type, int named));
-+
-+
-+
-+#endif /* RTX_CODE inside TREE_CODE */
-+
-+#ifdef HAVE_MACHINE_MODES /* inside TREE_CODE */
-+extern void   function_arg_advance PARAMS ((CUMULATIVE_ARGS *cum,
-+                                         enum machine_mode mode, tree type,
-+                                         int named));
-+#endif /* HAVE_MACHINE_MODES inside TREE_CODE*/
-+#endif /* TREE_CODE */
-+
-+#ifdef RTX_CODE
-+
-+
-+extern enum rtx_code msp430_canonicalize_comparison PARAMS ((enum rtx_code,rtx *,rtx *));
-+
-+
-+extern void msp430_emit_cbranch PARAMS ((enum rtx_code, rtx));
-+extern void msp430_emit_cset PARAMS ((enum rtx_code, rtx));
-+
-+extern int dead_or_set_in_peep PARAMS ((int, rtx, rtx));
-+extern void msp430_initialize_trampoline PARAMS ((rtx,rtx,rtx));   
-+
-+
-+extern enum reg_class msp430_reg_class_from_letter PARAMS ((int));
-+extern enum reg_class preferred_reload_class PARAMS ((rtx,enum reg_class));
-+enum reg_class msp430_regno_reg_class PARAMS ((int));
-+
-+extern RTX_CODE followed_compare_condition PARAMS ((rtx));
-+
-+extern const char * msp430_movesi_code PARAMS ((rtx insn, rtx operands[], int *l));
-+extern const char * msp430_movedi_code PARAMS ((rtx insn, rtx operands[], int *l));
-+extern const char * msp430_addsi_code PARAMS ((rtx insn, rtx operands[], int *l));
-+extern const char * msp430_subsi_code PARAMS ((rtx insn, rtx operands[], int *l));
-+extern const char * msp430_andsi_code PARAMS ((rtx insn, rtx operands[], int *l));
-+extern const char * msp430_iorsi_code PARAMS ((rtx insn, rtx operands[], int *l));
-+extern const char * msp430_xorsi_code PARAMS ((rtx insn, rtx operands[], int *l));
-+extern const char * msp430_adddi_code PARAMS ((rtx insn, rtx operands[], int *l));
-+extern const char * msp430_subdi_code PARAMS ((rtx insn, rtx operands[], int *l));
-+extern const char * msp430_anddi_code PARAMS ((rtx insn, rtx operands[], int *l));
-+extern const char * msp430_iordi_code PARAMS ((rtx insn, rtx operands[], int *l));
-+extern const char * msp430_xordi_code PARAMS ((rtx insn, rtx operands[], int *l));
-+
-+
-+extern int zero_shifted PARAMS ((rtx ));
-+extern int indexed_location PARAMS ((rtx ));
-+
-+
-+extern int regsi_ok_safe PARAMS ((rtx operands[]));
-+extern int regsi_ok_clobber PARAMS ((rtx operands[]));
-+extern int regdi_ok_safe PARAMS ((rtx operands[]));
-+extern int regdi_ok_clobber PARAMS ((rtx operands[]));
-+extern int sameoperand PARAMS ((rtx operands[], int));
-+
-+extern int general_operand_msp430 PARAMS ((rtx, enum machine_mode )); 
-+extern int nonimmediate_operand_msp430 PARAMS ((rtx, enum machine_mode ));
-+extern int memory_operand_msp430 PARAMS ((rtx, enum machine_mode ));
-+extern int halfnibble_constant PARAMS ((rtx, enum machine_mode ));
-+extern int halfnibble_integer PARAMS ((rtx, enum machine_mode ));
-+extern int halfnibble_constant_shift PARAMS ((rtx, enum machine_mode ));
-+extern int halfnibble_integer_shift PARAMS ((rtx, enum machine_mode ));
-+extern int which_nibble PARAMS ((int));
-+extern int which_nibble_shift PARAMS ((int));
-+
-+
-+extern void   asm_output_external_libcall PARAMS ((FILE *file, rtx symref));
-+extern int    legitimate_address_p    PARAMS ((enum machine_mode mode, rtx x,
-+                                      int strict));
-+extern int    compare_diff_p  PARAMS ((rtx insn));
-+
-+extern int    emit_indexed_arith PARAMS ((rtx insn, rtx operands[], int, const char *, int));
-+
-+extern const char * msp430_emit_abssi    PARAMS ((rtx insn, rtx operands[], int *l));
-+extern const char * msp430_emit_absdi    PARAMS ((rtx insn, rtx operands[], int *l));
-+
-+extern const char * msp430_emit_indexed_add2 PARAMS ((rtx insn, rtx op[], int *l));
-+extern const char * msp430_emit_indexed_add4 PARAMS ((rtx insn, rtx op[], int *l));
-+
-+extern const char * msp430_emit_indexed_sub2 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_indexed_sub4 PARAMS ((rtx insn, rtx operands[], int *len));
-+
-+extern const char * msp430_emit_indexed_and2 PARAMS ((rtx insn, rtx op[], int *l));
-+extern const char * msp430_emit_indexed_and4 PARAMS ((rtx insn, rtx op[], int *l));
-+extern const char * msp430_emit_immediate_and2 PARAMS ((rtx insn, rtx op[], int *l));
-+extern const char * msp430_emit_immediate_and4 PARAMS ((rtx insn, rtx op[], int *l));
-+
-+extern const char * msp430_emit_indexed_ior2 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_indexed_ior4 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_immediate_ior2 PARAMS ((rtx insn, rtx op[], int *l));
-+extern const char * msp430_emit_immediate_ior4 PARAMS ((rtx insn, rtx op[], int *l));
-+
-+
-+extern int msp430_emit_indexed_mov PARAMS ((rtx insn, rtx operands[], int len, const char *));       
-+extern const char * movstrsi_insn PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * clrstrsi_insn PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * movstrhi_insn PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * clrstrhi_insn PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_indexed_mov2 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_indexed_mov4 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * movsisf_regmode PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * movdidf_regmode PARAMS ((rtx insn, rtx operands[], int *len));
-+
-+
-+extern int is_shift_better_in_reg PARAMS ((rtx operands[]));
-+extern int msp430_emit_shift_cnt PARAMS ((int (*funct)(rtx, int, int), const char *, rtx insn, rtx operands[], int *len, int));
-+extern const char * msp430_emit_ashlqi3 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_ashlhi3 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_ashlsi3 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_ashldi3 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_ashrqi3 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_ashrhi3 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_ashrsi3 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_ashrdi3 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_lshrqi3 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_lshrhi3 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_lshrsi3 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_lshrdi3 PARAMS ((rtx insn, rtx operands[], int *len));
-+
-+extern const char * signextendqihi PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * signextendqisi PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * signextendqidi PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * signextendhisi PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * signextendhidi PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * signextendsidi PARAMS ((rtx insn, rtx operands[], int *len));
-+
-+extern const char * msp430_emit_indexed_sub2 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_indexed_sub4 PARAMS ((rtx insn, rtx operands[], int *len));
-+
-+extern const char * msp430_emit_indexed_xor2 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_indexed_xor4 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_indexed_xor2_3 PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_emit_indexed_xor4_3 PARAMS ((rtx insn, rtx operands[], int *len));
-+
-+extern const char * zeroextendqihi PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * zeroextendqisi PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * zeroextendqidi PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * zeroextendhisi PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * zeroextendhidi PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * zeroextendsidi PARAMS ((rtx insn, rtx operands[], int *len));
-+
-+extern const char * msp430_emit_blt0si PARAMS ((rtx operands[], int len));
-+extern const char * msp430_emit_beq PARAMS ((rtx operands[], int len));
-+extern const char * msp430_emit_bne PARAMS ((rtx operands[], int len));          
-+extern const char * msp430_emit_bgt PARAMS ((rtx operands[], int len));          
-+extern const char * msp430_emit_bgtu PARAMS ((rtx operands[], int len));          
-+extern const char * msp430_emit_blt PARAMS ((rtx operands[], int len));          
-+extern const char * msp430_emit_bltu PARAMS ((rtx operands[], int len));          
-+extern const char * msp430_emit_bge PARAMS ((rtx operands[], int len));          
-+extern const char * msp430_emit_bgeu PARAMS ((rtx operands[], int len));          
-+extern const char * msp430_emit_ble PARAMS ((rtx operands[], int len));          
-+extern const char * msp430_emit_bleu PARAMS ((rtx operands[], int len));          
-+
-+extern const char * msp430_pushsisf PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_pushdi   PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_pushhi   PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char * msp430_pushqi   PARAMS ((rtx insn, rtx operands[], int *len));
-+
-+extern const char * msp430_emit_return PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char *msp430_cbranch PARAMS ((rtx insn, rtx operands[], int *len));
-+extern const char *msp430_cset PARAMS ((rtx insn, rtx operands[], int *len));
-+
-+extern void   notice_update_cc       PARAMS ((rtx body, rtx insn));
-+extern int    msp430_peep2_scratch_safe PARAMS ((rtx reg_rtx));
-+extern int    test_hard_reg_class    PARAMS ((enum reg_class class, rtx x));
-+extern void   machine_dependent_reorg PARAMS ((rtx first_insn));
-+extern void msp430_output_addr_vec_elt PARAMS ((FILE *stream, int value));
-+extern void   final_prescan_insn     PARAMS ((rtx insn, rtx *operand,
-+                                                      int num_operands));
-+extern int    adjust_insn_length     PARAMS ((rtx insn, int len));
-+
-+
-+extern int    msp430_address_cost    PARAMS ((rtx x));
-+extern int    extra_constraint       PARAMS ((rtx x, int c));
-+extern rtx    legitimize_address     PARAMS ((rtx x, rtx oldx,
-+                                           enum machine_mode mode));
-+extern rtx    msp430_libcall_value   PARAMS ((enum machine_mode mode));
-+extern int    default_rtx_costs      PARAMS ((rtx X, RTX_CODE code,
-+                                           RTX_CODE outer_code));
-+extern void   asm_output_char        PARAMS ((FILE *file, rtx value));
-+extern void   asm_output_short       PARAMS ((FILE *file, rtx value));
-+extern void   asm_output_byte        PARAMS ((FILE *file, int value));
-+
-+extern void   print_operand          PARAMS ((FILE *file, rtx x, int code));
-+extern void   print_operand_address  PARAMS ((FILE *file, rtx addr));
-+extern int    reg_unused_after       PARAMS ((rtx insn, rtx reg));
-+extern int    msp430_jump_dist       PARAMS ((rtx x, rtx insn));
-+extern int    call_insn_operand      PARAMS ((rtx op, enum machine_mode mode));
-+extern int    msp430_branch_mode     PARAMS ((rtx x, rtx insn));
-+
-+extern int    msp430_easy_mul PARAMS ((rtx [],int));
-+extern int    msp430_mul3_guard       PARAMS ((rtx [], int ));
-+extern int      msp430_umul3_guard       PARAMS ((rtx [], int ));
-+extern int    msp430_mulhisi_guard PARAMS ((rtx [] ));
-+extern int    msp430_umulhisi_guard   PARAMS ((rtx [] ));
-+extern int    msp430_ashlhi3          PARAMS ((rtx [] ));
-+extern int      msp430_ashlsi3          PARAMS ((rtx [] ));
-+extern int      msp430_ashrhi3          PARAMS ((rtx [] ));
-+extern int      msp430_ashrsi3          PARAMS ((rtx [] ));
-+extern int      msp430_lshrhi3          PARAMS ((rtx [] ));
-+extern int      msp430_lshrsi3          PARAMS ((rtx [] ));
-+
-+
-+#endif /* RTX_CODE */
-+
-+#ifdef HAVE_MACHINE_MODES
-+extern int    class_max_nregs        PARAMS ((enum reg_class class,
-+                                           enum machine_mode mode));
-+#endif /* HAVE_MACHINE_MODES */
-+
-+#ifdef REAL_VALUE_TYPE
-+
-+extern void   asm_output_float       PARAMS ((FILE *file, REAL_VALUE_TYPE n));
-+
-+#endif
-+
-+
-diff -urN -x CVS gcc-3.2.3.orig/gcc/config/msp430/t-msp430 gcc-3.2.3/gcc/config/msp430/t-msp430
---- gcc-3.2.3.orig/gcc/config/msp430/t-msp430  1969-12-31 17:00:00.000000000 -0700
-+++ gcc-3.2.3/gcc/config/msp430/t-msp430       2008-08-22 09:17:00.000000000 -0600
-@@ -0,0 +1,116 @@
-+# Specific names for MSP430 tools
-+AR_FOR_TARGET = msp430-ar
-+RANLIB_FOR_TARGET = msp430-ranlib
-+NM_FOR_TARGET = msp430-nm
-+
-+CROSS_LIBGCC1 = libgcc1-asm.a
-+LIB1ASMSRC = msp430/libgcc.S
-+LIB1ASMFUNCS = _cmpdi2 \
-+      _cmpsf2 \
-+      __stop_progExec__ \
-+      _mulqi3 \
-+      _mulhi3 \
-+      _mulsi3 \
-+      _mulsi3hw \
-+      _umulqihi3 \
-+      _umulhisi3 \
-+      _mulqihi3 \
-+      _mulhisi3 \
-+      _udivmodqi4 \
-+      _divmodqi4 \
-+      _udivmodhi4 \
-+      _divmodhi4 \
-+      _udivmodsi4 \
-+      _divmodsi4 \
-+      _reset_vector__ \
-+      __prologue_saver \
-+      __epilogue_restorer \
-+      __epilogue_restorer_intr \
-+      _udivmoddi3_parts \
-+      _udivdi3 \
-+      _umoddi3 \
-+      _divdi3 \
-+      _moddi3 \
-+      _muldi3 \
-+      __low_level_init \
-+      __init_stack \
-+      _copy_data \
-+      _clear_bss \
-+      _ctors \
-+      __jump_to_main \
-+      _dtors
-+      
-+      
-+
-+# libgcc...
-+LIBGCC1_TEST =
-+
-+# We do not have the DF type.
-+# Most of the C functions in libgcc2 use almost all registers,
-+TARGET_LIBGCC2_CFLAGS = -DDF=SF -Dinhibit_libc -g
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c $(srcdir)/config/msp430/t-msp430
-+      echo '#define FLOAT' > fp-bit.c
-+      echo '#define FLOAT_ONLY' >> fp-bit.c
-+      echo '#define CMPtype HItype' >> fp-bit.c
-+      echo '#define DF SF' >> fp-bit.c
-+      echo '#define DI SI' >> fp-bit.c
-+      echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
-+      echo '#define SMALL_MACHINE' >> fp-bit.c
-+      cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+FPBIT = fp-bit.c
-+
-+MULTILIB_OPTIONS = mmcu=msp1/mmcu=msp2
-+MULTILIB_DIRNAMES = msp1 msp2
-+
-+
-+MULTILIB_MATCHES = \
-+      mmcu?msp1=mmcu?msp430x110   mmcu?msp1=mmcu?msp430x112 \
-+      mmcu?msp1=mmcu?msp430x1101  mmcu?msp1=mmcu?msp430x1111  mmcu?msp1=mmcu?msp430x1121 \
-+      mmcu?msp1=mmcu?msp430x1122  mmcu?msp1=mmcu?msp430x1132 \
-+      mmcu?msp1=mmcu?msp430x122   mmcu?msp1=mmcu?msp430x123 \
-+      mmcu?msp1=mmcu?msp430x1222  mmcu?msp1=mmcu?msp430x1232 \
-+      mmcu?msp1=mmcu?msp430x133   mmcu?msp1=mmcu?msp430x135 \
-+      mmcu?msp1=mmcu?msp430x1331  mmcu?msp1=mmcu?msp430x1351 \
-+      mmcu?msp2=mmcu?msp430x147   mmcu?msp2=mmcu?msp430x148   mmcu?msp2=mmcu?msp430x149 \
-+      mmcu?msp2=mmcu?msp430x1471  mmcu?msp2=mmcu?msp430x1481  mmcu?msp2=mmcu?msp430x1491 \
-+      mmcu?msp1=mmcu?msp430x155   mmcu?msp1=mmcu?msp430x156   mmcu?msp1=mmcu?msp430x157 \
-+      mmcu?msp2=mmcu?msp430x167   mmcu?msp2=mmcu?msp430x168   mmcu?msp2=mmcu?msp430x169 \
-+      mmcu?msp2=mmcu?msp430x1610  mmcu?msp2=mmcu?msp430x1611  mmcu?msp2=mmcu?msp430x1612 \
-+      mmcu?msp1=mmcu?msp430x2001  mmcu?msp1=mmcu?msp430x2011 \
-+      mmcu?msp1=mmcu?msp430x2002  mmcu?msp1=mmcu?msp430x2012 \
-+      mmcu?msp1=mmcu?msp430x2003  mmcu?msp1=mmcu?msp430x2013 \
-+      mmcu?msp1=mmcu?msp430x2101  mmcu?msp1=mmcu?msp430x2111  mmcu?msp1=mmcu?msp430x2121 \
-+      mmcu?msp1=mmcu?msp430x2131 \
-+      mmcu?msp1=mmcu?msp430x2232  mmcu?msp1=mmcu?msp430x2252  mmcu?msp1=mmcu?msp430x2272 \
-+      mmcu?msp1=mmcu?msp430x2234  mmcu?msp1=mmcu?msp430x2254  mmcu?msp1=mmcu?msp430x2274 \
-+      mmcu?msp2=mmcu?msp430x247   mmcu?msp2=mmcu?msp430x248   mmcu?msp2=mmcu?msp430x249 \
-+      mmcu?msp2=mmcu?msp430x2410 \
-+      mmcu?msp2=mmcu?msp430x2471  mmcu?msp2=mmcu?msp430x2481  mmcu?msp2=mmcu?msp430x2491 \
-+      mmcu?msp2=mmcu?msp430x2416  mmcu?msp2=mmcu?msp430x2417  mmcu?msp2=mmcu?msp430x2418 \
-+      mmcu?msp2=mmcu?msp430x2419 \
-+      mmcu?msp2=mmcu?msp430x2616  mmcu?msp2=mmcu?msp430x2617  mmcu?msp2=mmcu?msp430x2618 \
-+      mmcu?msp2=mmcu?msp430x2619 \
-+      mmcu?msp1=mmcu?msp430x311   mmcu?msp1=mmcu?msp430x312   mmcu?msp1=mmcu?msp430x313 \
-+      mmcu?msp1=mmcu?msp430x314   mmcu?msp1=mmcu?msp430x315 \
-+      mmcu?msp1=mmcu?msp430x323   mmcu?msp1=mmcu?msp430x325 \
-+      mmcu?msp2=mmcu?msp430x336   mmcu?msp2=mmcu?msp430x337 \
-+      mmcu?msp1=mmcu?msp430x412   mmcu?msp1=mmcu?msp430x413 \
-+      mmcu?msp1=mmcu?msp430x415   mmcu?msp1=mmcu?msp430x417 \
-+      mmcu?msp2=mmcu?msp430x423   mmcu?msp2=mmcu?msp430x425   mmcu?msp2=mmcu?msp430x427 \
-+      mmcu?msp1=mmcu?msp430x4250  mmcu?msp1=mmcu?msp430x4260  mmcu?msp1=mmcu?msp430x4270 \
-+      mmcu?msp2=mmcu?msp430xE423  mmcu?msp2=mmcu?msp430xE425  mmcu?msp2=mmcu?msp430xE427 \
-+      mmcu?msp1=mmcu?msp430xW423  mmcu?msp1=mmcu?msp430xW425  mmcu?msp1=mmcu?msp430xW427 \
-+      mmcu?msp1=mmcu?msp430xG437  mmcu?msp1=mmcu?msp430xG438  mmcu?msp1=mmcu?msp430xG439 \
-+      mmcu?msp1=mmcu?msp430x435   mmcu?msp1=mmcu?msp430x436   mmcu?msp1=mmcu?msp430x437 \
-+      mmcu?msp2=mmcu?msp430x447   mmcu?msp2=mmcu?msp430x448   mmcu?msp2=mmcu?msp430x449 \
-+      mmcu?msp2=mmcu?msp430xG4616 mmcu?msp2=mmcu?msp430xG4617 mmcu?msp2=mmcu?msp430xG4618 \
-+    mmcu?msp2=mmcu?msp430xG4619
-+
-+MULTILIB_EXCEPTIONS =
-+
-+LIBGCC = stmp-multilib
-+INSTALL_LIBGCC = install-multilib
-+
-+##STMP_FIXINC =
-diff -urN -x CVS gcc-3.2.3.orig/gcc/config/msp430/xm-msp430.h gcc-3.2.3/gcc/config/msp430/xm-msp430.h
---- gcc-3.2.3.orig/gcc/config/msp430/xm-msp430.h       1969-12-31 17:00:00.000000000 -0700
-+++ gcc-3.2.3/gcc/config/msp430/xm-msp430.h    2008-08-22 09:17:00.000000000 -0600
-@@ -0,0 +1 @@
-+#include "tm.h"
-diff -urN -x CVS gcc-3.2.3.orig/gcc/config.gcc gcc-3.2.3/gcc/config.gcc
---- gcc-3.2.3.orig/gcc/config.gcc      2003-02-28 11:38:19.000000000 -0700
-+++ gcc-3.2.3/gcc/config.gcc   2008-08-22 09:17:00.000000000 -0600
-@@ -2667,6 +2667,8 @@
-       ;;
- mmix-knuth-mmixware)
-       ;;
-+msp430-*-*)
-+        ;;
- mn10200-*-*)
-       float_format=i32
-       tm_file="dbxelf.h elfos.h svr4.h ${tm_file}"
-diff -urN -x CVS gcc-3.2.3.orig/gcc/cp/decl.c gcc-3.2.3/gcc/cp/decl.c
---- gcc-3.2.3.orig/gcc/cp/decl.c       2003-03-17 16:16:55.000000000 -0700
-+++ gcc-3.2.3/gcc/cp/decl.c    2008-08-22 09:17:00.000000000 -0600
-@@ -454,9 +454,9 @@
- /* The binding level currently in effect.  */
- #define current_binding_level                 \
--  (cfun && cp_function_chain->bindings                \
--   ? cp_function_chain->bindings              \
--   : scope_chain->bindings)
-+  (*(cfun && cp_function_chain->bindings      \
-+   ? &cp_function_chain->bindings             \
-+   : &scope_chain->bindings))
- /* The binding level of the current class, if any.  */
-diff -urN -x CVS gcc-3.2.3.orig/gcc-3.2.3-cygwin.patch gcc-3.2.3/gcc-3.2.3-cygwin.patch
---- gcc-3.2.3.orig/gcc-3.2.3-cygwin.patch      1969-12-31 17:00:00.000000000 -0700
-+++ gcc-3.2.3/gcc-3.2.3-cygwin.patch   2008-08-22 09:17:00.000000000 -0600
-@@ -0,0 +1,57 @@
-+--- gcc-3.2.3.orig/ggc/gcc-page.c       2003-05-06 15:37:04 +0800
-++++ gcc-3.2.3/gcc/ggc-page.c       2003-05-06 15:37:54 +0800
-+@@ -495,28 +495,35 @@
-+     }
-+   printf ("NULL\n");
-+   fflush (stdout);
-+ }
-+ 
-++static char *last_allocated_page = NULL;
-++
-+ #ifdef USING_MMAP
-+ /* Allocate SIZE bytes of anonymous memory, preferably near PREF,
-+    (if non-null).  The ifdef structure here is intended to cause a
-+    compile error unless exactly one of the HAVE_* is defined.  */
-+ 
-+ static inline char *
-+ alloc_anon (pref, size)
-+      char *pref ATTRIBUTE_UNUSED;
-+      size_t size;
-+ {
-++  char *page;
-++
-++  do {
-+ #ifdef HAVE_MMAP_ANON
-+-  char *page = (char *) mmap (pref, size, PROT_READ | PROT_WRITE,
-+-                           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-++  page = (char *) mmap (pref, size, PROT_READ | PROT_WRITE,
-++                     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-+ #endif
-+ #ifdef HAVE_MMAP_DEV_ZERO
-+-  char *page = (char *) mmap (pref, size, PROT_READ | PROT_WRITE,
-+-                           MAP_PRIVATE, G.dev_zero_fd, 0);
-++  page = (char *) mmap (pref, size, PROT_READ | PROT_WRITE,
-++                     MAP_PRIVATE, G.dev_zero_fd, 0);
-+ #endif
-++  } while (page == last_allocated_page);
-++  last_allocated_page = page;
-+ 
-+   if (page == (char *) MAP_FAILED)
-+     {
-+       perror ("virtual memory exhausted");
-+       exit (FATAL_EXIT_CODE);
-+--- gcc-3.2.3.orig/gcc/fixinc/gnu-regex.c     2003-05-06 15:37:04 +0800
-++++ gcc-3.2.3/gcc/fixinc/gnu-regex.c  2003-05-06 15:37:42 +0800
-+@@ -5718,11 +5718,11 @@
-+   if (errbuf_size != 0)
-+     {
-+       if (msg_size > errbuf_size)
-+         {
-+ #if defined HAVE_MEMPCPY || defined _LIBC
-+-       *((char *) __mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
-++       *((char *) mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
-+ #else
-+           memcpy (errbuf, msg, errbuf_size - 1);
-+           errbuf[errbuf_size - 1] = 0;
-+ #endif
-+         }
-diff -urN -x CVS gcc-3.2.3.orig/include/obstack.h gcc-3.2.3/include/obstack.h
---- gcc-3.2.3.orig/include/obstack.h   2001-03-14 12:44:38.000000000 -0700
-+++ gcc-3.2.3/include/obstack.h        2008-08-22 09:17:00.000000000 -0600
-@@ -423,7 +423,8 @@
- ({ struct obstack *__o = (OBSTACK);                                   \
-    if (__o->next_free + sizeof (void *) > __o->chunk_limit)           \
-      _obstack_newchunk (__o, sizeof (void *));                                \
--   *((void **)__o->next_free)++ = ((void *)datum);                    \
-+   *((void **)__o->next_free) = ((void *)datum);                      \
-+   __o->next_free += sizeof (void *);                                   \
-    (void) 0; })
- # define obstack_int_grow(OBSTACK,datum)                              \
-diff -urN -x CVS gcc-3.2.3.orig/THIS_ACTUALLY_WORKS_WITH_VERSION_3_2_AND_BELOW_2002_09_02 gcc-3.2.3/THIS_ACTUALLY_WORKS_WITH_VERSION_3_2_AND_BELOW_2002_09_02
---- gcc-3.2.3.orig/THIS_ACTUALLY_WORKS_WITH_VERSION_3_2_AND_BELOW_2002_09_02   1969-12-31 17:00:00.000000000 -0700
-+++ gcc-3.2.3/THIS_ACTUALLY_WORKS_WITH_VERSION_3_2_AND_BELOW_2002_09_02        2008-08-22 09:17:00.000000000 -0600
-@@ -0,0 +1,6 @@
-+-------------------------------------------------------------------
-+this directory works with gcc-3.2.x (tested with 3.2.3)
-+
-+The mismatch between the numbering of gcc and this directory is an
-+historical accident.
-+-------------------------------------------------------------------
diff --git a/debian/patches/003-mspgcc-3.2.3-20080819-FUNCTION.dpatch b/debian/patches/003-mspgcc-3.2.3-20080819-FUNCTION.dpatch
deleted file mode 100755 (executable)
index cacd3a0..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 002-mspgcc-3.2.3-20080819-FUNCTION.dpatch by pkgs@titaniummirror.com>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: __FUNCTION__ patch from mspgcc 3.2.3 CVS 20080819
-
-@DPATCH@
-
---- gcc-3.2.3.orig/gcc/c-common.c      2002-12-01 12:19:08.000000000 -0600
-+++ gcc-3.2.3/gcc/c-common.c   2006-03-18 22:08:27.000000000 -0600
-@@ -581,18 +581,20 @@
-         if (TREE_TYPE (t) == wchar_array_type_node)
-           {
-             wide_length += (TREE_STRING_LENGTH (t) - wchar_bytes);
-             wide_flag = 1;
-           }
-         else
-           {
-             length += (TREE_STRING_LENGTH (t) - 1);
-+#if 0              
-             if (C_ARTIFICIAL_STRING_P (t) && !in_system_header)
-               warning ("concatenation of string literals with __FUNCTION__ is deprecated"); 
-+#endif
-           }
-       }
-       /* If anything is wide, the non-wides will be converted,
-        which makes them take more space.  */
-       if (wide_flag)
-       length = length * wchar_bytes + wide_length;
index bc2568bac3693375aa7872eddc15885b1474d972..b4c04edf62b23c3aa48890d3b3d988dce74320f0 100644 (file)
@@ -1,2 +1,2 @@
-002-mspgcc-3.2.3-20080819.dpatch
-003-mspgcc-3.2.3-20080819-FUNCTION.dpatch
+ports-gcc-4.x
+gcc-4.4.3.dpatch
diff --git a/debian/patches/gcc-4.4.3.dpatch b/debian/patches/gcc-4.4.3.dpatch
new file mode 100755 (executable)
index 0000000..daf62f2
--- /dev/null
@@ -0,0 +1,153 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## gcc-4.4.3.dpatch by  R. Steve McKown <rsmckown@gmail.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: dpatch-ized version of gcc-4.4.3.patch from mspgcc4.
+
+@DPATCH@
+diff -urNad msp430-gcc~/configure msp430-gcc/configure
+--- msp430-gcc~/configure      2010-05-20 16:18:52.000000000 -0600
++++ msp430-gcc/configure       2010-05-20 16:20:02.000000000 -0600
+@@ -2360,6 +2360,9 @@
+   avr-*-*)
+     noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj} target-libssp"
+     ;;
++  msp430-*-*)
++    noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj} target-libssp"
++    ;;
+   bfin-*-*)
+     noconfigdirs="$noconfigdirs gdb"
+     if test x${is_cross_compiler} != xno ; then
+diff -urNad msp430-gcc~/gcc/config.gcc msp430-gcc/gcc/config.gcc
+--- msp430-gcc~/gcc/config.gcc 2010-05-20 16:18:52.000000000 -0600
++++ msp430-gcc/gcc/config.gcc  2010-05-20 16:20:02.000000000 -0600
+@@ -804,6 +804,12 @@
+ avr-*-*)
+       tm_file="avr/avr.h dbxelf.h"
+       ;;
++msp430-*-*)
++      tm_file="msp430/msp430.h dbxelf.h"
++      c_target_objs=`cat ${srcdir}/config/msp430/objs-extra`
++      cxx_target_objs=`cat ${srcdir}/config/msp430/objs-extra`
++      use_fixproto=yes
++      ;;
+ bfin*-elf*)
+       tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h"
+       tmake_file=bfin/t-bfin-elf
+diff -urNad msp430-gcc~/gcc/configure msp430-gcc/gcc/configure
+--- msp430-gcc~/gcc/configure  2010-05-20 16:18:52.000000000 -0600
++++ msp430-gcc/gcc/configure   2010-05-20 16:20:02.000000000 -0600
+@@ -1595,6 +1595,7 @@
+ gcc_version=`cat $srcdir/BASE-VER`
++echo $gcc_version | sed s/\\\([0-9]\\\)\.\\\([0-9]\\\)\.\\\([0-9]\\\)/\#define\ GCC_VERSION_INT\ 0x\\1\\2\\3/g > $srcdir/_gccver.h
+ # Determine the host, build, and target systems
+ ac_aux_dir=
+diff -urNad msp430-gcc~/gcc/expr.c msp430-gcc/gcc/expr.c
+--- msp430-gcc~/gcc/expr.c     2010-05-20 16:18:52.000000000 -0600
++++ msp430-gcc/gcc/expr.c      2010-05-20 16:20:02.000000000 -0600
+@@ -955,7 +955,7 @@
+         data.autinc_from = 1;
+         data.explicit_inc_from = -1;
+       }
+-      if (USE_LOAD_POST_INCREMENT (mode) && ! data.autinc_from)
++      if (USE_LOAD_POST_INCREMENT (mode) && !data.reverse && !data.autinc_from)
+       {
+         data.from_addr = copy_addr_to_reg (from_addr);
+         data.autinc_from = 1;
+diff -urNad msp430-gcc~/gcc/loop-invariant.c msp430-gcc/gcc/loop-invariant.c
+--- msp430-gcc~/gcc/loop-invariant.c   2010-05-20 16:18:52.000000000 -0600
++++ msp430-gcc/gcc/loop-invariant.c    2010-05-20 16:20:02.000000000 -0600
+@@ -1171,11 +1171,13 @@
+   rtx reg, set, dest, note;
+   struct use *use;
+   bitmap_iterator bi;
++  int n_validated;
+   if (inv->reg)
+     return true;
+   if (!repr->move)
+     return false;
++  n_validated = num_validated_changes ();
+   /* If this is a representative of the class of equivalent invariants,
+      really move the invariant.  Otherwise just replace its use with
+      the register used for the representative.  */
+@@ -1200,7 +1202,17 @@
+       reg = gen_reg_rtx_and_attrs (dest);
+       /* Try replacing the destination by a new pseudoregister.  */
+-      if (!validate_change (inv->insn, &SET_DEST (set), reg, false))
++      validate_change (inv->insn, &SET_DEST (set), reg, true);
++
++      /* Replace the uses we know to be dominated.  It saves work for copy
++       propagation, and also it is necessary so that dependent invariants
++       are computed right.  */
++      /* Note that we must test the changes for validity, lest we might
++       rip apart a match_dup between a use and a clobber.  */
++      if (inv->def)
++      for (use = inv->def->uses; use; use = use->next)
++        validate_change (use->insn, use->pos, reg, true);
++      if (!apply_change_group ())
+       goto fail;
+       df_insn_rescan (inv->insn);
+@@ -1219,9 +1231,23 @@
+     }
+   else
+     {
+-      if (!move_invariant_reg (loop, repr->invno))
+-      goto fail;
++      /* Replace the uses we know to be dominated.  It saves work for copy
++       propagation, and also it is necessary so that dependent invariants
++       are computed right.  */
+       reg = repr->reg;
++      if (inv->def)
++        for (use = inv->def->uses; use; use = use->next)
++        validate_change (use->insn, use->pos, reg, true);
++
++      if (verify_changes (n_validated)
++        && move_invariant_reg (loop, repr->invno))
++      confirm_change_group ();
++      else
++      {
++        cancel_changes (n_validated);
++        goto fail;
++      }
++
+       set = single_set (inv->insn);
+       emit_insn_after (gen_move_insn (SET_DEST (set), reg), inv->insn);
+       delete_insn (inv->insn);
+@@ -1230,17 +1256,9 @@
+   inv->reg = reg;
+-  /* Replace the uses we know to be dominated.  It saves work for copy
+-     propagation, and also it is necessary so that dependent invariants
+-     are computed right.  */
+   if (inv->def)
+-    {
+-      for (use = inv->def->uses; use; use = use->next)
+-      {
+-        *use->pos = reg;
+-        df_insn_rescan (use->insn);
+-      }      
+-    }
++    for (use = inv->def->uses; use; use = use->next)
++      df_insn_rescan (use->insn);
+   return true;
+diff -urNad msp430-gcc~/libgcc/config.host msp430-gcc/libgcc/config.host
+--- msp430-gcc~/libgcc/config.host     2010-05-20 16:18:52.000000000 -0600
++++ msp430-gcc/libgcc/config.host      2010-05-20 16:20:02.000000000 -0600
+@@ -224,6 +224,8 @@
+     # Make HImode functions for AVR
+     tmake_file=${cpu_type}/t-avr
+       ;;
++msp430-*-*)
++      ;;
+ bfin*-elf*)
+         ;;
+ bfin*-uclinux*)
diff --git a/debian/patches/ports-gcc-4.x.dpatch b/debian/patches/ports-gcc-4.x.dpatch
new file mode 100755 (executable)
index 0000000..b0d2a6a
--- /dev/null
@@ -0,0 +1,20092 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## ports-gcc-4.x.dpatch by  <smckown@stevex2>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+@DPATCH@
+diff -urNad msp430-gcc~/gcc/config/msp430/framehelpers.inl msp430-gcc/gcc/config/msp430/framehelpers.inl
+--- msp430-gcc~/gcc/config/msp430/framehelpers.inl     1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/framehelpers.inl      2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1,111 @@
++#pragma once
++
++extern void *ggc_alloc(size_t);
++
++/*
++This function is used to test, how certain generated INSNs are actually matched and written to the
++assembly file.
++The typical test scenario for msp430_codegen_test() is:
++1. Create a C file containing the following
++int test()
++{
++__msp430_codegen_test_entry();
++}
++2. Examine the output with "msp430-gcc -S 0.c -o 0.S && less 0.S"
++3. Compare the output in 0.S with the expected result of msp430_codegen_test() run
++*/
++
++/*
++Functions beginning with msp430_fh_ are prologue/epilogue (frame) helpers.
++*/
++static inline void msp430_fh_emit_push_reg(int reg_num)
++{
++      rtx pushword = gen_rtx_MEM (HImode, gen_rtx_PRE_DEC (HImode, stack_pointer_rtx));
++      //rtx insn = emit_insn(gen_rtx_SET(VOIDmode, pushword, gen_rtx_REG (HImode, reg_num)));
++      rtx insn = emit_insn(gen_pushhi_prologue(gen_rtx_REG (HImode, reg_num), pushword));
++      RTX_FRAME_RELATED_P(insn) = 1;
++}
++
++static inline void msp430_fh_emit_pop_reg(int reg_num)
++{
++      /*rtx popword  = gen_rtx_MEM (HImode, gen_rtx_POST_INC (HImode, stack_pointer_rtx));
++      rtx insn = emit_insn(gen_rtx_SET(VOIDmode, gen_rtx_REG (HImode, reg_num), popword));
++      RTX_FRAME_RELATED_P(insn) = 1;*/
++
++      rtx insn = emit_insn(gen_pophi_reg(gen_rtx_REG (HImode, reg_num)));
++}
++
++static inline void msp430_fh_sub_sp_const(int num_bytes)
++{
++      rtx insn = emit_move_insn (stack_pointer_rtx,
++//            gen_rtx_MINUS (HImode, stack_pointer_rtx, gen_int_mode (num_bytes, HImode)));
++              gen_rtx_PLUS (HImode, stack_pointer_rtx, gen_int_mode (-num_bytes, HImode)));
++      RTX_FRAME_RELATED_P(insn) = 1;
++}
++
++static inline void msp430_fh_add_sp_const(int num_bytes)
++{
++      rtx insn = emit_move_insn (stack_pointer_rtx,
++              gen_rtx_PLUS (HImode, stack_pointer_rtx, gen_int_mode (num_bytes, HImode)));
++      RTX_FRAME_RELATED_P(insn) = 1;
++}
++
++static inline void msp430_fh_add_reg_const(int reg_num, int num_bytes)
++{
++      rtx reg_rtx = gen_rtx_REG (HImode, reg_num);
++      rtx insn = emit_move_insn (reg_rtx,
++              gen_rtx_PLUS (HImode, reg_rtx, gen_int_mode (num_bytes, HImode)));
++      RTX_FRAME_RELATED_P(insn) = 1;
++}
++
++static inline void msp430_fh_gen_mov_r2r(int dest_reg, int src_reg)
++{
++      rtx insn = emit_move_insn (gen_rtx_REG (HImode, dest_reg), gen_rtx_REG (HImode, src_reg));
++      RTX_FRAME_RELATED_P(insn) = 1;
++}
++
++static inline void msp430_fh_gen_mov_pc_to_reg(int dest_reg)
++{
++      rtx insn = emit_insn(gen_save_pc_to_reg(gen_rtx_REG (HImode, dest_reg)));
++}
++
++static inline const char *msp430_format_sym_plus_off(const char *sym_name, int offset)
++{
++      char *pBuf;
++      if (!offset)
++              return sym_name;
++      pBuf = (char *)ggc_alloc(strlen(sym_name) + 20);
++      sprintf(pBuf, "(%s%s%d)", sym_name, (offset >= 0) ? "+" : "", offset);
++      return pBuf;
++}
++
++static inline void msp430_fh_load_sp_with_sym_plus_off(const char *sym_name, int offset)
++{
++      rtx insn;
++
++      insn = emit_move_insn (stack_pointer_rtx, gen_rtx_SYMBOL_REF(HImode, msp430_format_sym_plus_off(sym_name, offset)));
++}
++
++/*
++      WARNING! This function is called from 2 places:
++              * Prologue saver
++              * Exit from main()
++      As the "explicit_br" INSN does not report to be modifying PC, this may screw up DWARF2 frame info generation.
++      Optimally, the "explicit_br" INSN should be replaced by something similar to "call_prologue_saves" INSN from
++      the AVR implementation. As for return from main, the question is still open.
++*/
++static inline void msp430_fh_br_to_symbol_plus_offset(const char *sym_name, int offset)
++{
++      rtx insn;
++      insn = gen_explicit_br(gen_rtx_SYMBOL_REF(HImode, msp430_format_sym_plus_off(sym_name, offset)));
++      /*insn = gen_rtx_SET (VOIDmode,
++                                              pc_rtx,
++                                              gen_rtx_LABEL_REF(VOIDmode, gen_rtx_SYMBOL_REF(HImode, msp430_format_sym_plus_off(sym_name, offset))));*/
++      emit_insn (insn);
++}
++
++static inline void msp430_fh_bic_deref_sp(int mask)
++{
++      rtx insn, sp_deref = gen_rtx_MEM (HImode, stack_pointer_rtx);
++      insn = emit_insn(gen_nandhi(sp_deref, gen_int_mode(mask, HImode), sp_deref));
++}
+\ No newline at end of file
+diff -urNad msp430-gcc~/gcc/config/msp430/libgcc.S msp430-gcc/gcc/config/msp430/libgcc.S
+--- msp430-gcc~/gcc/config/msp430/libgcc.S     1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/libgcc.S      2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1,1342 @@
++/*  -*- Mode: Asm -*-  */
++
++
++      .section .text.libgcc, "ax", @progbits
++
++#if defined (L_cmpdi2)
++      
++      .global __cmpdi2
++      .func   __cmpdi2
++__cmpdi2:
++      sub     2(r1), r12      ; a = a-b;
++      subc    4(r1), r13
++      subc    6(r1), r14
++      subc    8(r1), r15
++      
++      tst     r15             ; c<0 ? return -1;
++      jge     .L2
++      
++      mov     #-1, r15        ; yes, return -1
++      ret
++.L2:
++      bis     r12, r14        ; check if zero
++      bis     r13, r15
++      bis     r14, r15
++      tst     r15
++      jeq     .L4             ; test result or or'ing all nibbles
++      
++      mov     #1, r15         ; no, positive, return 1
++      ret
++.L4:
++      mov     #0, r15         ; return 0
++      ret
++.endfunc
++#endif
++
++#if defined (L_cmpsf2)
++      .global __cmpsf2
++      .func   __cmpsf2
++__cmpsf2:
++/* prologue: frame size = 0; addenum 0; alloca:0, varargs:0 , fpr:0*/
++.L__FrameSize___cmpsf2=0x0
++.L__FrameOffset___cmpsf2=0x4
++/* prologue end (size=2) */
++        cmp     r12, r14      ;  11  cmpsi   [length = 3]
++        jne     .L2
++        cmp     r13, r15
++        jne     .L2           ;  12  bne     [length = 1]
++        mov     #llo(0), r15  ;  15  *movhi3/7       [length = 1]
++      ret
++.L2:
++        tst     r15           ;  20  tstsi   [length = 1]
++        jge     .L3           ;  21  bge     [length = 1]
++        tst     r13           ;  22  tstsi   [length = 1]
++        jge     .L3           ;  23  bge     [length = 1]
++        xor     #lhi(-2147483648), r15                ;  27  *xorsi3_3       [length = 2]
++        xor     #lhi(-2147483648), r13                ;  29  *xorsi3_3       [length = 2]
++.L3:
++        sub     r14, r12      ;  64  *subsi3_3       [length = 2]
++        subc    r15, r13
++        jge     .L4           ;  33  bge     [length = 1]
++        mov     #llo(1), r15  ;  36  *movhi3/7       [length = 1]
++      ret
++.L4:
++        mov     #llo(-1), r15 ;  43  *movhi3/7       [length = 1]
++.L1:
++/* epilogue: frame size=0 */
++        ret
++/* epilogue end (size=3) */
++/* function __cmpsf2 size 25 (20) */
++
++.endfunc
++
++#endif
++
++
++
++/*******************************************************
++               Multiplication  8 x 8
++*******************************************************/
++#if defined (L_mulqi3)
++/* 
++      a = reg:qi 10   clobber
++      b = reg:qi 12   clobber
++      res = reg:qi 14
++*/
++
++      .global __mulqi3
++      .func   __mulqi3
++__mulqi3:
++      clr     r14
++.L__mulqiloop:
++      tst.b   r10
++      jz      .L__mulqiexit
++      clrc
++      rrc.b   r12
++      jnc     +2
++      add.b   r10, r14
++      rla.b   r10
++      tst.b   r12
++      jne     .L__mulqiloop
++.L__mulqiexit:
++      ret
++      .endfunc
++#endif        /* defined (L_mulqi3) */
++
++
++#if defined (L_mulqihi3)
++      .global __mulqihi3
++      .func   __mulqihi3
++__mulqihi3:
++      sxt     r10
++      sxt     r12
++      br      #__mulhi3
++.endfunc
++#endif /* defined (L_mulqihi3) */
++
++#if defined (L_umulqihi3)
++      .global __umulqihi3
++      .func   __umulqihi3
++__umulqihi3:
++      and.b   #-1, r10
++      and.b   #-1, r12
++      br      #__mulhi3
++      .endfunc
++#endif /* defined (L_umulqihi3) */
++
++/*******************************************************
++               Multiplication  16 x 16
++*******************************************************/
++#if defined (L_mulhi3)
++/* 
++      a = reg:hi 10   clobber
++      b = reg:hi 12   clobber
++      res = reg:hi 14
++*/
++
++      .global __mulhi3
++      .func   __mulhi3
++__mulhi3:
++      clr     r14
++.L__mulhiloop:
++      tst     r10
++      jz      .L__mulhiexit
++      clrc
++      rrc     r12
++      jnc     +2
++      add     r10, r14
++      rla     r10
++      tst     r12
++      jne     .L__mulhiloop
++.L__mulhiexit:
++      ret
++      .endfunc
++#endif /* defined (L_mulhi3) */
++
++#if defined (L_mulhisi3)
++/* clobber r11, r13 */
++      .global __mulhisi3
++      .func   __mulhisi3
++__mulhisi3:
++      br      #__mulsi3
++      .endfunc
++#endif /* defined (L_mulhisi3) */
++
++#if defined (L_umulhisi3)
++      .global __umulhisi3
++      .func   __umulhisi3
++__umulhisi3:
++      br      #__mulsi3
++      .endfunc
++#endif /* defined (L_umulhisi3) */
++
++#if defined (L_mulsi3)
++/*******************************************************
++               Multiplication  32 x 32
++*******************************************************/
++/*
++res = a*b
++      a - reg:SI 10 clobber
++      b - reg:SI 12 clobber
++      res - reg: SI 14
++*/
++      .global __mulsi3
++      .func   __mulsi3
++
++__mulsi3:
++      clr     r14
++      clr     r15
++      jmp     .L__mulsi3st
++.L__mulsi3loop:
++      clrc
++      rrc     r13             ;       b >>= 1
++      rrc     r12
++      jnc     +4              ;       
++      add     r10, r14        ;       res = res + a
++      addc    r11, r15
++      rla     r10
++      rlc     r11             ;       a <<= 1
++.L__mulsi3st:
++      tst     r12             ; if b ne 0 goto L__mulsi3loop
++      jne     .L__mulsi3loop
++      tst     r13
++      jne     .L__mulsi3loop
++      ret
++      .endfunc
++
++#endif
++
++#if defined (L_mulsi3hw)
++      
++__MPY=0x130
++__MPYS=0x132
++__MAC=0x134
++__MACS=0x136
++__OP2=0x138
++__RESLO=0x13a
++__RESHI=0x13c
++__SUMEXT=0x13e
++
++      .global __umulsi3hw
++      .func   __umulsi3hw
++__umulsi3hw:
++      mov     r12, &__MPY
++      mov     r10, &__OP2
++      mov     r12, &__MAC
++      mov     &__RESLO, r14
++      mov     &__RESHI, &__RESLO
++      mov     r11, &__OP2
++      mov     r13, &__MAC
++      mov     r10, &__OP2
++      mov     &__RESLO, r15
++      ret
++.endfunc
++
++#endif
++
++      
++/*******************************************************
++       Division 8 / 8 => (result + remainder)
++*******************************************************/
++
++#define r_rem   r14   /* remainder */
++#define r_arg1  r12   /* dividend, quotient */
++#define r_arg2  r10   /* divisor */
++#define r_cnt   r11   /* loop count */
++#define r_tmp r13     /* save carry flag */
++
++
++#if defined (L_udivmodqi4)
++      .global __udivmodqi4
++      .func   __udivmodqi4
++__udivmodqi4:
++      xor.b   r_rem, r_rem            ; clear reminder and carry
++      mov.b   #9, r_cnt
++      jmp     .L__udivmodqi4_ep
++.L__udivmodqi4_loop:  
++      rrc     r_tmp                   ; restore carry bit
++      rlc.b   r_rem
++      cmp.b   r_arg2, r_rem
++      jlo     .L__udivmodqi4_ep
++      sub.b   r_arg2, r_rem           ; FIXME: will this clobber carry ?
++.L__udivmodqi4_ep:
++      rlc.b   r_arg1                  ; shift divident
++      rlc     r_tmp                   ; save carry bit
++      dec.b   r_cnt                   ; this clobbers C bit.
++      jnz     .L__udivmodqi4_loop
++      ret
++      .endfunc
++#endif /* defined (L_udivmodqi4) */
++
++
++#if defined (L_divmodqi4)
++      .global __divmodqi4
++      .func   __divmodqi4
++__divmodqi4:
++      clr     r_tmp
++      bit     #0x80, r_arg1           ; save divident sign
++      jnc     .L__divmodqi4arg1pos
++      inv.b   r_arg1                  ; negate
++      inc.b   r_arg1
++      bis     #4, r_tmp
++
++.L__divmodqi4arg1pos:
++      bit     #0x80, r_arg2           ; check divisor sign
++      jnc     .L__divmodqi4arg2pos
++      inv.b   r_arg2                  ; negate
++      inc.b   r_arg2
++      bis     #8, r_tmp
++
++.L__divmodqi4arg2pos:
++      
++      call    #__udivmodqi4           ; do unsigned division
++      rrc     r_tmp                   ; restore carry and sign bits
++
++      bit     #4, r_tmp               ; is divident < 0 ?
++      jnc     .L__divmodqi4rem        ; no. skip
++      inv.b   r_rem                   ; negate remainder
++      inc.b   r_rem
++
++;;    bit     #8, r_tmp
++;;    jc      .L__divmodqi4end
++      inv.b   r_arg1                  ; negate quotient
++      inc.b   r_arg1
++
++.L__divmodqi4rem:
++      bit     #8, r_tmp
++      jnc     .L__divmodqi4end
++      inv.b   r_arg1
++      inc.b   r_arg1
++
++.L__divmodqi4end:
++      ret
++
++      .endfunc
++#endif /* defined (L_divmodqi4) */
++
++#undef r_rem
++#undef r_arg1
++#undef r_arg2
++#undef r_cnt 
++#undef r_tmp
++
++
++/*******************************************************
++       Division 16 / 16 => (result + remainder)
++*******************************************************/
++
++#define r_rem   r14   /* remainder */
++#define r_arg1  r12   /* dividend, quotient */
++#define r_arg2  r10   /* divisor */
++#define r_cnt   r11   /* loop count */
++#define r_tmp r13
++
++
++#if defined (L_udivmodhi4)
++      .global __udivmodhi4
++      .func   __udivmodhi4
++__udivmodhi4:
++      xor     r_rem, r_rem            ; clear reminder and carry
++      mov     #17, r_cnt
++      jmp     .L__udivmodhi4_ep
++.L__udivmodhi4_loop:  
++      rrc     r_tmp                   ; restore carry bit
++      rlc     r_rem
++      cmp     r_arg2, r_rem
++      jlo     .L__udivmodhi4_ep
++      sub     r_arg2, r_rem
++.L__udivmodhi4_ep:
++      rlc     r_arg1
++      rlc     r_tmp                   ; save carry bit
++      dec     r_cnt                   ; this clobbers C bit.
++      jnz     .L__udivmodhi4_loop
++      ret
++      .endfunc
++#endif /* defined (L_udivmodhi4) */
++
++
++#if defined (L_divmodhi4)
++#define r_rem   r14     /* remainder */
++#define r_arg1  r12     /* dividend, quotient */
++#define r_arg2  r10     /* divisor */   
++#define r_cnt   r11     /* loop count */
++#define r_tmp   r13
++
++
++      .global __divmodhi4
++      .func   __divmodhi4
++__divmodhi4:
++      clr     r_tmp                   ; clear reg is cheaper than clr 2 bits.
++      bit     #0x8000, r_arg1         ; save divident sign
++      jnc     .L__divmodhi4arg1pos
++      inv     r_arg1                  ; negate
++      inc     r_arg1
++      bis     #4, r_tmp
++
++.L__divmodhi4arg1pos:
++      bit     #0x8000, r_arg2         ; check divisor sign
++      jnc     .L__divmodhi4arg2pos
++      inv     r_arg2                  ; negate
++      inc     r_arg2
++      bis     #8, r_tmp
++
++.L__divmodhi4arg2pos: 
++      call    #__udivmodhi4           ; do unsigned division
++      rrc     r_tmp                   ; restore carry and sign bits
++
++      bit     #4, r_tmp               ; is divident < 0 ?
++      jnc     .L__divmodhi4rem        ; no. skip
++      inv     r_rem                   ; negate remainder
++      inc     r_rem
++
++;;    bit     #8, r_tmp
++;;    jc      .L__divmodhi4end
++      inv     r_arg1                  ; negate quotient
++      inc     r_arg1
++
++.L__divmodhi4rem:
++      bit     #8, r_tmp
++      jnc     .L__divmodhi4end
++      inv     r_arg1
++      inc     r_arg1
++
++.L__divmodhi4end:
++      ret
++      .endfunc
++#endif /* defined (L_divmodhi4) */
++
++#undef r_rem
++#undef r_arg1
++#undef r_arg2
++#undef r_cnt 
++#undef r_tmp
++
++/*******************************************************
++       Division 32 / 32 => (result + remainder)
++*******************************************************/
++
++#if defined (L_udivmodsi4)
++
++#define r_remh  r15  
++#define r_reml  r14   /* remainder */
++#define r_arg1h r13
++#define r_arg1l r12   /* dividend, quotient */
++#define r_arg2h r11   
++#define r_arg2l r10   /* divisor */
++#define r_cnt   r9    /* loop count */
++#define r_tmp   r8
++
++      .global __udivmodsi4
++      .func   __udivmodsi4
++__udivmodsi4:
++      xor     r_remh, r_remh          ; clear reminder and carry
++      xor     r_reml, r_reml
++      mov     #33, r_cnt
++      jmp     .L__udivmodsi4_ep
++.L__udivmodsi4_loop:  
++      rrc     r_tmp                   ; restore carry bit
++      rlc     r_reml
++      rlc     r_remh
++
++      cmp     r_arg2h, r_remh         ; is reminder < divisor ?
++      jlo     .L__udivmodsi4_ep       ; yes, skip correction
++      jne     +4
++                                      ; they equal. check LSBytes
++      cmp     r_arg2l, r_reml
++      jlo     .L__udivmodsi4_ep       ; is reminder still < divisor ?
++
++      sub     r_arg2l, r_reml         ; adjust reminder
++      subc    r_arg2h, r_remh
++
++.L__udivmodsi4_ep:
++      rlc     r_arg1l
++      rlc     r_arg1h
++      rlc     r_tmp
++      dec     r_cnt                   ; this clobbers C bit.
++      jnz     .L__udivmodsi4_loop
++      ret
++      .endfunc
++
++#undef r_remh
++#undef r_reml  
++#undef r_arg1h
++#undef r_arg1l
++#undef r_arg2h
++#undef r_arg2l
++
++#undef r_cnt
++#undef r_tmp
++
++#endif /* defined (L_udivmodsi4) */
++
++
++#if defined (L_divmodsi4)
++#define r_remh  r15  
++#define r_reml  r14     /* remainder */
++#define r_arg1h r13
++#define r_arg1l r12     /* dividend, quotient */
++#define r_arg2h r11   
++#define r_arg2l r10     /* divisor */   
++#define r_cnt   r9      /* loop count */
++#define r_tmp   r8
++
++      .global __divmodsi4
++      .func   __divmodsi4
++__divmodsi4:
++      clr     r_tmp                   ; clear reg is cheaper than clr 2 bits.
++      bit     #0x8000, r_arg1h                ; save divident sign
++      jz      .L__divmodsi4arg1pos
++      inv     r_arg1h                 ; negate
++      inv     r_arg1l
++      inc     r_arg1l
++      adc     r_arg1h
++      bis     #4, r_tmp
++
++.L__divmodsi4arg1pos:
++      bit     #0x8000, r_arg2h                ; check divisor sign
++      jz      .L__divmodsi4arg2pos
++      inv     r_arg2h                 ; negate
++      inv     r_arg2l
++      inc     r_arg2l
++      adc     r_arg2h
++      bis     #8, r_tmp               ; save divisor sign
++
++.L__divmodsi4arg2pos:
++      
++      call    #__udivmodsi4           ; do unsigned division
++      rrc     r_tmp                   ; restore carry and sign bits
++
++      bit     #4, r_tmp               ; is divident < 0 ?
++      jz      .L__divmodsi4rem        ; no. skip
++      inv     r_reml                  ; negate remainder
++      inv     r_remh
++      inc     r_reml
++      adc     r_remh
++
++;;    bit     #8, r_tmp
++;;    jc      .L__divmodsi4end
++      inv     r_arg1l                 ; negate quotient
++      inv     r_arg1h
++      inc     r_arg1l
++      adc     r_arg1h
++
++.L__divmodsi4rem:
++      bit     #8, r_tmp
++      jz      .L__divmodsi4end
++      inv     r_arg1l
++      inv     r_arg1h
++      inc     r_arg1l
++      adc     r_arg1h
++
++.L__divmodsi4end:
++      ret
++      .endfunc
++
++#undef r_remh  
++#undef r_reml  
++#undef r_arg1h 
++#undef r_arg1l
++#undef r_arg2h
++#undef r_arg2l
++
++#undef r_cnt
++#undef r_tmp
++
++#endif /* defined (L_divmodsi4) */
++
++
++/******* CRT support functions *********/
++
++#if defined(L_reset_vector__)
++/*****************************************************************
++ * Program starts here.
++ *   overwriting this label in the user program
++ *   causes removing all strtup code except __do_global_ctors
++ *****************************************************************/
++      .section .init0, "ax", @progbits
++
++      .global _reset_vector__
++      .weak   _reset_vector__
++
++      .func   _reset_vector__
++
++_reset_vector__:
++
++    /* link following functions if library _reset_vector__ used */
++
++;    stack can be initialized in main() prologue,
++;    but setting stack pointer here allows to call subroutines 
++;    from startup code and call constructors of statically allocated C++ objects.
++;    Stack pointer will have the same value entering main() as here,
++;    so -mno-stack-init can be used to reduce code size.
++;    initial stack value can be set in ld script as __stack symbol 
++;    (end of RAM by default), or via -defsym __stack=<address> ld option
++;    or via -Wl,defsym,__stack=<address> gcc option, or by redefining
++;    __init_stack function as fololws:
++;
++;#if defined (__cplusplus)
++;extern "C" 
++;#endif
++;__attribute__((__naked__)) __attribute__((section(".init2"))) void __init_stack()
++;{
++;    asm volatile("\tmov\t#stack_addr, r1\n");
++;}
++;
++
++      .global __init_stack
++
++      .global __low_level_init
++      .global __do_copy_data
++      .global __do_clear_bss
++      .global __jump_to_main
++
++      .endfunc
++#endif  /* defined(L_reset_vector__) */
++    
++#if defined(L__init_stack)
++/*****************************************************************
++ * Set stack pointer
++ * can be overwriten
++ *****************************************************************/
++      .section .init2, "ax", @progbits
++
++      .global __init_stack
++      .weak   __init_stack
++
++      .func   __init_stack
++
++__init_stack:
++      mov     #__stack, r1
++
++      .endfunc
++#endif
++
++#if defined(L__low_level_init)
++/*****************************************************************
++ * Initialize peripherial, particularly disable watchdog
++ * can be overwriten
++ *****************************************************************/
++      .section .init3, "ax", @progbits
++
++      .global __low_level_init
++      .weak   __low_level_init
++
++      .func   __low_level_init
++
++__low_level_init:
++      mov     #0x5a80, &0x120
++
++      .endfunc
++#endif
++
++#if defined(L_copy_data)
++/*****************************************************************
++ * Initialize data: copy data 
++ * from __data_load_start ( = _etext) to __data_start
++ * can be overwriten
++ *****************************************************************/
++      .section .init4, "ax", @progbits
++
++      .global __do_copy_data
++      .weak   __do_copy_data
++
++      .func   __do_copy_data
++
++__do_copy_data:
++      mov     #__data_size, r15
++      tst     r15
++      jz      .L__copy_data_end
++.L__copy_data_loop:
++      decd    r15
++      mov.w   __data_load_start(r15), __data_start(r15)    ; data section is word-aligned, so word transfer is acceptable
++      jne     .L__copy_data_loop
++.L__copy_data_end:
++
++      .endfunc
++#endif /* defined(L_copy_data) */
++    
++#if defined(L_clear_bss)
++/*****************************************************************
++ * Initialize data: clear .bss
++ * can be overwriten
++ *****************************************************************/
++      .section .init4, "ax", @progbits
++
++      .global __do_clear_bss
++      .weak   __do_clear_bss
++
++      .func   __do_clear_bss
++
++__do_clear_bss:
++      mov     #__bss_size, r15
++      tst     r15
++      jz      .L__clear_bss_end
++.L__clear_bss_loop:
++      dec     r15
++      clr.b   __bss_start(r15)
++      jne     .L__clear_bss_loop
++.L__clear_bss_end:
++
++      .endfunc
++#endif  /* defined(L_clear_bss) */
++
++#if defined(L_ctors)
++/*****************************************************************
++ * Call C++ global and static objects constructors
++ * can be overwriten
++ *****************************************************************/
++      .section .init6, "ax", @progbits
++      .global __do_global_ctors
++      .weak   __do_global_ctors
++    
++      .func   __do_global_ctors
++
++__do_global_ctors:
++      mov     #__ctors_start, r11
++      mov     #__ctors_end,   r10
++.L__ctors_loop:
++      call    @r11+   ; call constructor
++      cmp     r10, r11
++      jne     .L__ctors_loop
++
++      .endfunc
++#endif
++    
++#if defined(L__jump_to_main)
++/*****************************************************************
++ * jump to main.
++ * can be overwriten
++ *****************************************************************/
++      .section .init9, "ax", @progbits
++
++      .global __jump_to_main
++      .weak   __jump_to_main
++
++      .func   __jump_to_main
++
++__jump_to_main:
++      br      #main
++      .endfunc
++#endif
++
++#if defined(L__stop_progExec__)
++/*****************************************************************
++ * return from main.
++ * can be overwriten
++ *****************************************************************/
++      .section .fini9, "ax", @progbits
++      .global __stop_progExec__
++      .weak   __stop_progExec__
++
++      .func  __stop_progExec__
++
++__stop_progExec__:
++
++      .endfunc
++#endif
++
++#if defined(L_dtors)
++/*****************************************************************
++ * Call C++ global and static objects destructors
++ * can be overwriten
++ *****************************************************************/
++      .section .fini6,"ax",@progbits
++      .global __do_global_dtors
++      .weak   __do_global_dtors
++    
++      .func   _dtors
++
++__do_global_dtors:
++      mov     #__dtors_start, r11
++      mov     #__dtors_end, r10
++.L__dtors_loop:
++      call    @r11+
++      cmp     r10, r11
++      jne     .L__dtors_loop
++
++      .endfunc
++#endif
++
++#if defined(L__stop_progExec__)
++/*****************************************************************
++ * endless loop
++ * can be overwriten
++ *****************************************************************/
++      .section .fini0, "ax", @progbits
++
++      .func   _endless_loop__
++1:
++      jmp  1b
++
++      .endfunc
++#endif
++
++/********* PROLOGE / EPILOGUE aux routines ******************/
++#if defined (L__prologue_saver)
++      .global __prologue_saver
++      .func   __prologue_saver
++__prologue_saver:
++      mov     r4, 0(r1)
++      mov     r5, 2(r1)
++      mov     r6, 4(r1)
++      mov     r7, 6(r1)
++      mov     r8, 8(r1)
++      mov     r9, 10(r1)
++      mov     r10, 12(r1)
++      mov     r11, 14(r1)
++      br      r12     ; now jump to the function body
++.endfunc
++
++#endif
++
++
++#if defined (L__epilogue_restorer)
++      .global __epilogue_restorer
++      .func   __epilogue_restorer
++__epilogue_restorer:
++      pop     r4
++      pop     r5
++      pop     r6
++      pop     r7
++      pop     r8
++      pop     r9
++      pop     r10
++      pop     r11
++      ret
++.endfunc
++
++#endif
++
++
++#if defined (L__epilogue_restorer_intr)
++      .global __epilogue_restorer_intr
++      .func   __epilogue_restorer_intr
++__epilogue_restorer_intr:
++      pop     r4
++      pop     r5
++      pop     r6
++      pop     r7
++      pop     r8
++      pop     r9
++      pop     r10
++      pop     r11
++      pop     r12
++      pop     r13
++      pop     r14
++      pop     r15
++      reti
++.endfunc
++
++#endif
++
++/******************************************
++ * quot/rem = 64/64
++ ******************************************/
++
++#if defined (L_udivmoddi3_parts) || defined (L_udivdi3) || defined (L_umoddi3) || defined (L_divdi3) || defined (L_moddi3)
++
++#define r_remhh  r11          /* remainder */
++#define r_remhl  r10
++#define r_remlh        r9
++#define r_remll        r8
++
++#define r_arg1hh r15  /* dividend, quotient */
++#define r_arg1hl r14
++#define r_arg1lh r13
++#define r_arg1ll r12
++
++#define r_arg2hh r7   /* divisor */
++#define r_arg2hl r6
++#define r_arg2lh r5
++#define r_arg2ll r4
++
++#define r_cnt   2(r1) /* loop count */
++#define r_tmp   0(r1) /* we'll save carry and signs here */
++
++#endif
++
++
++#if defined (L_udivmoddi3_parts)
++
++      .global __udivmoddi3_parts
++      .func   __udivmoddi3_parts
++__udivmoddi3_parts:
++      xor     r_remhh, r_remhh        ; clear reminder and carry
++      xor     r_remhl, r_remhl 
++      xor     r_remlh, r_remlh
++      xor     r_remll, r_remll
++      
++      mov     #65, 2+r_cnt
++      jmp     .L__udivmoddi3_ep
++
++.L__udivmoddi3_loop:  
++      rrc     2+r_tmp                 ; restore carry bit
++      
++      rlc     r_remll                 ; shift carry in.
++      rlc     r_remlh
++      rlc     r_remhl
++      rlc     r_remhh
++      
++      cmp     r_arg2hh, r_remhh       ; is reminder < divisor ?
++      jlo     .L__udivmoddi3_ep       ; yes, skip correction
++      jne     .L_udmdcrt
++                                      ; they equal. check LSBytes
++      cmp     r_arg2hl, r_remhl
++      jlo     .L__udivmoddi3_ep       ; is reminder still < divisor ?
++      jne     .L_udmdcrt
++
++      cmp     r_arg2lh, r_remlh
++      jlo     .L__udivmoddi3_ep
++      jne     .L_udmdcrt
++
++      cmp     r_arg2ll, r_remll
++      jlo     .L__udivmoddi3_ep
++      jne     .L_udmdcrt
++
++.L_udmdcrt:
++      sub     r_arg2ll, r_remll       ; adjust reminder
++      subc    r_arg2lh, r_remlh
++      subc    r_arg2hl, r_remhl
++      subc    r_arg2hh, r_remhh
++      
++.L__udivmoddi3_ep:
++      rlc     r_arg1ll                ; shift carry into arg1
++      rlc     r_arg1lh
++      rlc     r_arg1hl
++      rlc     r_arg1hh
++      
++      rlc     2+r_tmp                 ; save carry
++      dec     2+r_cnt                 ; this clobbers C bit.
++      jnz     .L__udivmoddi3_loop
++      
++      ret
++      .endfunc
++
++#endif /* defined (L_udivmoddi3_parts) */
++
++
++#if defined (L_udivdi3)
++
++;;  First arg will be in r15:r12 
++;;  next on stack
++;;    return in r15:r12
++;; rearrange them as:
++;;    r15:r12         ->      r_arg1hh:r_arg1ll
++;;    stack+8:stack+2 ->      r_arg2hh:r_arg2ll
++
++      .global __udivdi3
++      .func   __udivdi3
++__udivdi3:
++      push    r4
++      push    r5
++      push    r6
++      push    r7
++      push    r8
++      push    r9
++      push    r10
++      push    r11
++      
++      mov     18+0(r1), r_arg2ll      ; 18 is a stack offset
++      mov     18+2(r1), r_arg2lh      ; so move arg 2 in.
++      mov     18+4(r1), r_arg2hl
++      mov     18+6(r1), r_arg2hh
++      
++      sub     #4, r1
++      call    #__udivmoddi3_parts
++      add     #4, r1
++      
++      pop     r11
++      pop     r10
++      pop     r9
++      pop     r8
++      pop     r7
++      pop     r6
++      pop     r5
++      pop     r4
++      ret
++      .endfunc
++#endif
++
++
++#if defined (L_umoddi3)
++      .global __umoddi3
++      .func   __umoddi3
++__umoddi3:
++      push    r4
++      push    r5
++      push    r6
++      push    r7
++      push    r8
++      push    r9
++      push    r10
++      push    r11
++      
++      mov     18+0(r1), r_arg2ll      
++      mov     18+2(r1), r_arg2lh
++      mov     18+4(r1), r_arg2hl
++      mov     18+6(r1), r_arg2hh
++
++      sub     #4, r1
++      call    #__udivmoddi3_parts
++      add     #4, r1
++      
++      mov     r_remhh, r15    ; move reminder to (reg:DI 12)
++      mov     r_remhl, r14
++      mov     r_remlh, r13
++      mov     r_remll, r12
++      
++      pop     r11
++      pop     r10
++      pop     r9
++      pop     r8
++      pop     r7
++      pop     r6
++      pop     r5
++      pop     r4
++      ret
++      .endfunc
++#endif
++
++
++#if defined (L_divdi3)
++      .global __divdi3
++      .func   __divdi3
++__divdi3:
++      push    r4
++      push    r5
++      push    r6
++      push    r7
++      push    r8
++      push    r9
++      push    r10
++      push    r11
++      
++      mov     18+0(r1), r_arg2ll      
++      mov     18+2(r1), r_arg2lh
++      mov     18+4(r1), r_arg2hl
++      mov     18+6(r1), r_arg2hh
++      
++      sub     #4, r1
++      
++      clr     r_tmp
++      bit     #0x8000, r_arg1hh
++      jnc     .L__divdi3rempos
++      inv     r_arg1hh
++      inv     r_arg1hl
++      inv     r_arg1lh
++      inv     r_arg1ll
++      inc     r_arg1ll
++      adc     r_arg1lh
++      adc     r_arg1hl
++      adc     r_arg1hh
++      bis     #4, r_tmp
++      
++.L__divdi3rempos:
++      bit     #0x8000, r_arg2hh
++      jnc     .L__divdi3arg2pos       
++      inv     r_arg2hh
++      inv     r_arg2hl
++      inv     r_arg2lh
++      inv     r_arg2ll
++      inc     r_arg2ll
++      adc     r_arg2lh
++      adc     r_arg2hl
++      adc     r_arg2hh
++      xor     #4, r_tmp       ; this is a trick - invert bit 4 =>
++                              ; do not perform double negation.
++.L__divdi3arg2pos:
++      call    #__udivmoddi3_parts
++      
++      rrc     r_tmp   ; restore sign bits
++
++      bit     #4, r_tmp
++      jz      .L__divdi3end
++      inv     r_arg1hh
++      inv     r_arg1hl
++      inv     r_arg1lh
++      inv     r_arg1ll
++      inc     r_arg1ll
++      adc     r_arg1lh
++      adc     r_arg1hl
++      adc     r_arg1hh
++      
++.L__divdi3end:
++      add     #4, r1
++      pop     r11
++      pop     r10
++      pop     r9
++      pop     r8
++      pop     r7
++      pop     r6
++      pop     r5
++      pop     r4
++      ret
++      .endfunc
++#endif
++
++
++#if defined (L_moddi3)
++      .global __moddi3
++      .func   __moddi3
++__moddi3:
++      push    r4
++      push    r5
++      push    r6
++      push    r7
++      push    r8
++      push    r9
++      push    r10
++      push    r11
++      
++      mov     18+0(r1), r_arg2ll      
++      mov     18+2(r1), r_arg2lh
++      mov     18+4(r1), r_arg2hl
++      mov     18+6(r1), r_arg2hh
++      
++      sub     #4, r1
++      
++      clr     r_tmp
++      bit     #0x8000, r_arg1hh
++      jnc     .L__moddi3rempos
++      inv     r_arg1hh
++      inv     r_arg1hl
++      inv     r_arg1lh
++      inv     r_arg1ll
++      inc     r_arg1ll
++      adc     r_arg1lh
++      adc     r_arg1hl
++      adc     r_arg1hh
++      bis     #4, r_tmp
++      
++.L__moddi3rempos:
++      bit     #0x8000, r_arg2hh
++      jnc     .L__moddi3arg2pos       
++      inv     r_arg2hh
++      inv     r_arg2hl
++      inv     r_arg2lh
++      inv     r_arg2ll
++      inc     r_arg2ll
++      adc     r_arg2lh
++      adc     r_arg2hl
++      adc     r_arg2hh
++
++.L__moddi3arg2pos:
++      call    #__udivmoddi3_parts
++      
++      rrc     r_tmp
++
++      bit     #4, r_tmp
++      jz      .L__moddi3rem
++      
++      inv     r_remhh
++      inv     r_remhl
++      inv     r_remlh
++      inv     r_remll
++      inc     r_remll
++      adc     r_remlh
++      adc     r_remhl
++      adc     r_remhh
++
++.L__moddi3rem:
++      mov     r_remhh, r15
++      mov     r_remhl, r14
++      mov     r_remlh, r13
++      mov     r_remll, r12
++
++      add     #4, r1
++      pop     r11
++      pop     r10
++      pop     r9
++      pop     r8
++      pop     r7
++      pop     r6
++      pop     r5
++      pop     r4
++      ret
++      .endfunc
++#endif
++
++
++/**************************************************************
++ * Multiplication 64 = 64 x 64
++ **************************************************************/
++#if defined(L_muldi3) && !defined(MSP430_HAS_HWMUL)
++
++#define r_reshh  r11          /* res = arg1 * arg2 */
++#define r_reshl  r10
++#define r_reslh        r9
++#define r_resll        r8
++
++#define r_arg1hh r15  /* arg1 */
++#define r_arg1hl r14
++#define r_arg1lh r13
++#define r_arg1ll r12
++
++#define r_arg2hh r7   /* arg2 */
++#define r_arg2hl r6
++#define r_arg2lh r5
++#define r_arg2ll r4
++
++      .global __muldi3
++      .func   __muldi3
++__muldi3:
++      push    r4
++      push    r5
++      push    r6
++      push    r7
++      push    r8
++      push    r9
++      push    r10
++      push    r11
++      
++      mov     18+0(r1), r_arg2ll      ; 18 is a stack offset
++      mov     18+2(r1), r_arg2lh      ; so move arg 2 in.
++      mov     18+4(r1), r_arg2hl
++      mov     18+6(r1), r_arg2hh
++
++      clr     r_reshh
++      clr     r_reshl
++      clr     r_reslh
++      clr     r_resll
++      
++.L_muldi3_loop:
++      clrc
++      rrc     r_arg2hh                ; arg2 >>= 1 (shift LSB into carry)
++      rrc     r_arg2hl
++      rrc     r_arg2lh
++      rrc     r_arg2ll
++      
++      jnc     +8                      ; check if bit is set
++                                      ; yes, it is.
++      add     r_arg1ll, r_resll       ; res += arg1
++      addc    r_arg1lh, r_reslh
++      addc    r_arg1hl, r_reshl
++      addc    r_arg1hh, r_reshh
++      
++      rla     r_arg1ll                ; arg1 <<= 1
++      rlc     r_arg1lh
++      rlc     r_arg1hl
++      rlc     r_arg1hh
++      
++      tst     r_arg2ll                ; arg2 !=0 ?  loop again , exit otherwise.
++      jne     .L_muldi3_loop
++      tst     r_arg2lh
++      jne     .L_muldi3_loop
++      tst     r_arg2hl
++      jne     .L_muldi3_loop
++      tst     r_arg2hh
++      jne     .L_muldi3_loop
++
++      ; move result to proper location
++      mov     r_resll, r12
++      mov     r_reslh, r13
++      mov     r_reshl, r14
++      mov     r_reshh, r15
++
++      pop     r11
++      pop     r10
++      pop     r9
++      pop     r8
++      pop     r7
++      pop     r6
++      pop     r5
++      pop     r4
++      ret
++      .endfunc
++#endif
++
++#if defined(L_muldi3) && defined(MSP430_HAS_HWMUL)
++
++__MPY=0x130
++__MPYS=0x132
++__MAC=0x134
++__MACS=0x136
++__OP2=0x138
++__RESLO=0x13a
++__RESHI=0x13c
++__SUMEXT=0x13e
++
++#define r_reshh  r11    /* res = arg1 * arg2 */
++#define r_reshl  r10
++#define r_reslh  r9
++#define r_resll  r8
++
++#define r_arg1hh r15    /* arg1 */
++#define r_arg1hl r14
++#define r_arg1lh r13
++#define r_arg1ll r12
++
++#define r_arg2hh r7     /* arg2 */
++#define r_arg2hl r6
++#define r_arg2lh r5
++#define r_arg2ll r4
++
++          .global __muldi3
++          .func   __muldi3
++__muldi3:
++
++        push    r4
++        push    r5
++        push    r6
++        push    r7
++        push    r8
++        push    r9
++        push    r10
++        push    r11
++
++        mov     18+0(r1), r_arg2ll      ; 18 is a stack offset
++        mov     18+2(r1), r_arg2lh      ; so move arg 2 in.
++        mov     18+4(r1), r_arg2hl
++        mov     18+6(r1), r_arg2hh
++
++;;      r15:r14:r13:r12 * r7:r6:r5:r4 -> r11:r10:r9:r8
++;; actual code follows....
++
++        mov     r_arg1ll,&__MPY
++        mov     r_arg2ll,&__OP2           ;;                      LL1xLL2
++        mov     &__RESLO,r_resll
++        mov     &__RESHI,&__RESLO
++        mov     &__SUMEXT,&__RESHI
++
++        mov     r_arg1ll,&__MAC
++        mov     r_arg2lh,&__OP2           ;;                  LL1xLH2
++        mov     r_arg1lh,&__MAC
++        mov     r_arg2ll,&__OP2           ;;                  LH1xLL2
++        mov     &__RESLO,r_reslh
++        mov     &__RESHI,&__RESLO
++        mov     &__SUMEXT,&__RESHI
++
++        mov     r_arg2lh,&__OP2           ;;              LH1xLH2
++        mov     r_arg1ll,&__MAC
++        mov     r_arg2hl,&__OP2           ;;              LL1xHL2
++        mov     r_arg1hl,&__MAC
++        mov     r_arg2ll,&__OP2           ;;              HL1xLL2
++        mov     &__RESLO,r_reshl
++        mov     &__RESHI,&__RESLO
++
++        mov     r_arg2lh,&__OP2           ;;          HL1xLH2
++        mov     r_arg1ll,&__MAC
++        mov     r_arg2hh,&__OP2           ;;          LL1xHH2
++        mov     r_arg1lh,&__MAC
++        mov     r_arg2hl,&__OP2           ;;          LH1xHL2
++        mov     r_arg1hh,&__MAC
++        mov     r_arg2ll,&__OP2           ;;          HH1xLL2
++        mov     &__RESLO,r_reshh
++
++;; reload result
++        mov     r_resll, r12
++        mov     r_reslh, r13
++        mov     r_reshl, r14
++        mov     r_reshh, r15
++
++        pop     r11
++        pop     r10
++        pop     r9
++        pop     r8
++        pop     r7
++        pop     r6
++        pop     r5
++        pop     r4
++        ret
++.endfunc
++#endif
+diff -urNad msp430-gcc~/gcc/config/msp430/libgcc.c msp430-gcc/gcc/config/msp430/libgcc.c
+--- msp430-gcc~/gcc/config/msp430/libgcc.c     1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/libgcc.c      2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1,73 @@
++/*
++      Stages of division:
++      0. Clear carry flag, et all.
++      1. Shift divident into divider. 
++         Shift carry bit into divident.
++      2. Check if the remainder >= divider
++      3.      if yes, remainder -= divider
++              this MUST set carry flag
++      4.      if not, clear carry flag
++      
++      repeat from 1 sizeof(type) times
++ */
++
++
++typedef unsigned long __XX;
++
++__XX
++__udivmodXI3 ( __XX a,  __XX b)
++{
++    __XX al = a;      // quotant
++    __XX ah = 0;      // reminder
++    __XX tmpf;
++    int i;
++
++    for (i = sizeof(__XX)*8; i > 0; i--)
++    {
++        ah = (ah << 1) | (al >> (sizeof(__XX)*8-1) );
++        tmpf = (ah >= b) ? 1 : 0;
++        ah -= ((tmpf) ? b : 0);
++        al = (al << 1) | tmpf;
++    }
++
++    return al;    // for __udivXi3
++    return ah;    // for __umodXi3
++}
++
++/* Signed: */
++
++__XX
++__divmodXI3 ( __XX a,  __XX b)
++{
++    unsigned at = abs(a);
++    unsigned bt = abs(b);
++    unsigned al, ah;
++
++    __udivmodXI3 (at, bt);
++
++    // now we get al, ah
++
++    if (a < 0)
++        ah = -ah, al = -al;
++
++    if (b < 0)
++        al = -al;
++
++    return al;
++    return ah;
++}
++
++#if 1
++int main()
++{
++    __XX a,b, r;
++
++    a = 100;
++    b = 0;
++    r = __udivmodXI3(a,b);
++    printf("R=%d\n",r);
++
++}
++#endif
++
++
+diff -urNad msp430-gcc~/gcc/config/msp430/msp430-builtins.c msp430-gcc/gcc/config/msp430/msp430-builtins.c
+--- msp430-gcc~/gcc/config/msp430/msp430-builtins.c    1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/msp430-builtins.c     2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1,190 @@
++/* This work is partially financed by the European Commission under the
++* Framework 6 Information Society Technologies Project
++* "Wirelessly Accessible Sensor Populations (WASP)".
++*/
++
++/*
++GCC 4.x port by Ivan Shcherbakov <mspgcc@sysprogs.org>
++*/
++
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++#include "rtl.h"
++#include "regs.h"
++#include "hard-reg-set.h"
++#include "real.h"
++#include "insn-config.h"
++#include "conditions.h"
++#include "insn-attr.h"
++#include "flags.h"
++#include "reload.h"
++#include "tree.h"
++#include "output.h"
++#include "expr.h"
++#include "toplev.h"
++#include "obstack.h"
++#include "function.h"
++#include "recog.h"
++#include "tm_p.h"
++#include "target.h"
++#include "target-def.h"
++#include "insn-codes.h"
++#include "ggc.h"
++#include "langhooks.h"
++
++#if GCC_VERSION_INT < 0x430
++#define add_builtin_function lang_hooks.builtin_function
++#endif
++
++
++/* The following functions are defined in this file and used by msp430.c */
++void msp430_init_builtins (void);
++rtx msp430_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
++
++
++static const struct {
++      const char *name;
++      int md_code;
++} msp430builtins[4] = {
++      {"__bic_sr_irq", CODE_FOR_bic_sr_irq},
++      {"__bis_sr_irq", CODE_FOR_bis_sr_irq},
++      {"__get_frame_address", CODE_FOR_get_frame_address},
++      {0, 0}
++};
++
++static int msp430_codegen_test_entry_idx = 3; /* Still redefined later */
++
++void msp430_init_builtins(void)
++{
++      tree args;
++      int builtin_idx = 0;
++
++      args = tree_cons (NULL_TREE, integer_type_node, void_list_node);
++
++      add_builtin_function (msp430builtins[builtin_idx].name, 
++              build_function_type (void_type_node, args),
++              builtin_idx, BUILT_IN_MD, NULL, NULL_TREE);
++
++      builtin_idx++;
++
++      add_builtin_function (msp430builtins[builtin_idx].name, 
++              build_function_type (void_type_node, args),
++              builtin_idx, BUILT_IN_MD, NULL, NULL_TREE);
++
++      builtin_idx++;
++
++      args = tree_cons (NULL_TREE, void_type_node, void_list_node);
++      add_builtin_function (msp430builtins[builtin_idx].name, 
++              build_function_type (ptr_type_node, args),
++              builtin_idx, BUILT_IN_MD, NULL, NULL_TREE);
++
++      builtin_idx++;
++
++      args = tree_cons (NULL_TREE, void_type_node, void_list_node);
++      add_builtin_function ("__msp430_codegen_test_entry", 
++              build_function_type (void_type_node, args),
++              builtin_idx, BUILT_IN_MD, NULL, NULL_TREE);
++
++      msp430_codegen_test_entry_idx = builtin_idx;
++
++      builtin_idx++;
++}
++
++#include "framehelpers.inl"
++
++static void msp430_codegen_test(void)
++{
++      emit_insn(gen_nop());
++
++      /*
++      msp430_fh_emit_push_reg(7);
++      msp430_fh_sub_sp_const(6);
++      msp430_fh_gen_mov_r2r(7, 6);
++      */
++      //msp430_fh_load_sp_with_sym_plus_off("__stack", -10);
++      //msp430_fh_br_to_symbol_plus_offset("some_jump_target", -10);
++      msp430_fh_bic_deref_sp(0x0f);
++      /*
++      msp430_fh_add_sp_const(6);
++      msp430_fh_emit_pop_reg(7);
++      */
++
++      emit_insn(gen_nop());
++}
++
++rtx msp430_expand_builtin(tree exp, rtx target ATTRIBUTE_UNUSED, 
++                                        rtx subtarget ATTRIBUTE_UNUSED, 
++                                        enum machine_mode mode ATTRIBUTE_UNUSED, 
++                                        int ignore ATTRIBUTE_UNUSED)
++{
++      rtx arg=0, retval = 0;
++      rtx frame_offset_n;
++      rtx insn=0;
++      rtx symb, plus, con;
++      char *pos;
++      tree fndecl, argtree;
++      int i,  code;
++      rtx x = DECL_RTL (current_function_decl);
++      const char *fnname = XSTR (XEXP (x, 0), 0);
++
++#if GCC_VERSION_INT < 0x430
++      fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
++#else
++      fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
++#endif
++
++      argtree = TREE_OPERAND (exp, 1);
++      i = DECL_FUNCTION_CODE (fndecl);
++
++      if (i == msp430_codegen_test_entry_idx)
++      {
++              msp430_codegen_test();
++              return NULL;
++      }
++
++      code = msp430builtins[i].md_code;
++
++      pos = (char*)ggc_alloc(16+strlen(fnname)+1);
++      snprintf(pos,16+strlen(fnname)+1,".L__FrameOffset_%s",fnname);
++
++      symb = gen_rtx_REG(HImode,1);
++      con = gen_rtx_SYMBOL_REF(HImode, pos);
++      plus = gen_rtx_PLUS(HImode, symb, con);  
++      frame_offset_n = gen_rtx_MEM(HImode, plus);
++
++      if(code == CODE_FOR_bic_sr_irq || code == CODE_FOR_bis_sr_irq)
++      {
++#if GCC_VERSION_INT < 0x430
++              arg = expand_expr (TREE_VALUE (argtree), NULL_RTX, VOIDmode, 0);
++#else
++              arg = expand_expr (CALL_EXPR_ARG(exp, 0), NULL_RTX, VOIDmode, 0);
++#endif
++      }
++
++      if(code == CODE_FOR_bic_sr_irq)
++              insn = gen_rtx_SET(HImode, frame_offset_n,
++              gen_rtx_UNSPEC_VOLATILE(HImode,
++              gen_rtvec(2,arg, GEN_INT(4100001)),41));
++      else if(code == CODE_FOR_bis_sr_irq)
++              insn = gen_rtx_SET(HImode, frame_offset_n,
++              gen_rtx_UNSPEC_VOLATILE(HImode,
++              gen_rtvec(2,arg, GEN_INT(4200002)),42));
++      else if(code == CODE_FOR_get_frame_address)
++      {
++              retval = gen_reg_rtx(HImode);
++              insn = gen_rtx_SET(HImode, retval, 
++                      gen_rtx_UNSPEC_VOLATILE(HImode,
++                      gen_rtvec(2,frame_offset_n, GEN_INT(4300003)),43));
++      }
++      else
++              error("Unknown built-in function");
++
++      if(insn)
++              emit_insn(insn);
++      else
++              error("Unknown built-in function");
++
++      return retval;
++}
+\ No newline at end of file
+diff -urNad msp430-gcc~/gcc/config/msp430/msp430-cbranch.c msp430-gcc/gcc/config/msp430/msp430-cbranch.c
+--- msp430-gcc~/gcc/config/msp430/msp430-cbranch.c     1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/msp430-cbranch.c      2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1,680 @@
++/* This work is partially financed by the European Commission under the
++* Framework 6 Information Society Technologies Project
++* "Wirelessly Accessible Sensor Populations (WASP)".
++*/
++
++/*
++GCC 4.x port by Ivan Shcherbakov <mspgcc@sysprogs.org>
++*/
++
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++#include "rtl.h"
++#include "regs.h"
++#include "hard-reg-set.h"
++#include "real.h"
++#include "insn-config.h"
++#include "conditions.h"
++#include "insn-attr.h"
++#include "flags.h"
++#include "reload.h"
++#include "tree.h"
++#include "output.h"
++#include "expr.h"
++#include "toplev.h"
++#include "obstack.h"
++#include "function.h"
++#include "recog.h"
++#include "tm_p.h"
++#include "target.h"
++#include "target-def.h"
++#include "insn-codes.h"
++#include "ggc.h"
++#include "langhooks.h"
++
++static const char *msp430_emit_blt0si (rtx operands[], int len);
++static const char *msp430_emit_beq (rtx operands[], int len);
++static const char *msp430_emit_bne (rtx operands[], int len);
++static const char *msp430_emit_bgt (rtx operands[], int len);
++static const char *msp430_emit_bgtu (rtx operands[], int len);
++static const char *msp430_emit_blt (rtx operands[], int len);
++static const char *msp430_emit_bltnoovfl (rtx operands[], int len);
++static const char *msp430_emit_bltu (rtx operands[], int len);
++static const char *msp430_emit_bge (rtx operands[], int len);
++static const char *msp430_emit_bgeu (rtx operands[], int len);
++static const char *msp430_emit_ble (rtx operands[], int len);
++static const char *msp430_emit_bleu (rtx operands[], int len);
++
++static int msp430_cc_source (rtx, enum rtx_code, rtx, rtx);
++
++#define OUT_INSN(x,p,o) \
++      do {                            \
++      if(!x) output_asm_insn (p,o);   \
++      } while(0)
++
++
++const char *msp430_cbranch (rtx insn, rtx operands[], int *len, int is_cc0_branch)
++{
++      rtx ops[3];
++      enum rtx_code code;
++      rtx locs[3];
++      int dummy = 0;
++      enum machine_mode mode;
++      int quater = 0;
++      rtx loc = operands[0];
++      int distance = msp430_jump_dist (loc, insn);
++      int predist = 0;
++      int nooverflow = 0;
++
++#define ECOND(f,x) do{if(!len)msp430_emit_b##f(locs,predist + x);dummy+=(predist + x);}while(0)
++      locs[0] = operands[0];
++      ops[0] = operands[2];
++      ops[1] = operands[3];
++
++      if (ops[1] && ops[0])
++      {
++              mode = GET_MODE (operands[2]);
++              code = GET_CODE (operands[1]);
++              quater = (mode == QImode);
++      }
++      else
++      {
++              mode = HImode;
++              code = GET_CODE (operands[1]);
++      }
++
++      /* here check wiered conditions */
++      if (ops[1] && GET_CODE (ops[1]) == CONST_INT
++              && (code == GT || code == LE || code == GTU || code == LEU))
++      {
++              int x = INTVAL (ops[1]);
++              switch (code)
++              {
++              case GT:
++                      ops[1] = GEN_INT (x + 1);
++                      code = GE;
++                      break;
++              case LE:
++                      ops[1] = GEN_INT (x + 1);
++                      code = LT;
++                      break;
++              case GTU:
++                      ops[1] = GEN_INT (x + 1);
++                      code = GEU;
++                      break;
++              case LEU:
++                      ops[1] = GEN_INT (x + 1);
++                      code = LTU;
++                      break;
++              default:
++                      break;
++              }
++      }
++      else if (ops[1] && CONSTANT_P (ops[1]) && GET_MODE(ops[1]) == HImode
++              && (code == GT || code == LE || code == GTU || code == LEU))
++      {
++              /* Handle pointers here */
++              ops[1] = gen_rtx_CONST(HImode,gen_rtx_PLUS(HImode,ops[1],GEN_INT(1)));
++
++              switch (code)
++              {
++              case GT:
++                      code = GE;
++                      break;
++              case LE:
++                      code = LT;
++                      break;
++              case GTU:
++                      code = GEU;
++                      break;
++              case LEU:
++                      code = LTU;
++                      break;
++              default:
++                      break;
++              }
++      }
++
++      if (!is_cc0_branch && ops[0] != cc0_rtx && ops[1] && ops[0])
++      {
++              if (code == NE || code == EQ)
++              {
++                      /* check if op0 is zero shited - win 1 byte */
++                      if (indexed_location (ops[0]) && !CONSTANT_P (ops[1]))
++                      {
++                              rtx x = ops[0];
++                              ops[0] = ops[1];
++                              ops[1] = x;
++                      }
++              }
++
++              /* check if compares were not issued */
++              if ((mode == QImode || mode == HImode)
++                      && msp430_cc_source (insn, code, ops[0], ops[1]))
++              {
++                      /* check if overflow can be usefull here. */
++                      if( ops[1] == const0_rtx 
++                              || (GET_CODE(ops[1]) == CONST_INT
++                              && INTVAL(ops[1]) == 0 ))
++                      {
++                              if(code == LT || code == GE)
++                                      nooverflow = 1;
++                      }
++              }
++              else if (mode == QImode || mode == HImode)
++              {
++                      /* check if previous insns did not set CC correctly */
++                      if (quater)
++                              OUT_INSN (len, "cmp.b\t%1, %0", ops);
++                      else
++                              OUT_INSN (len, "cmp\t%1, %0", ops);
++                      dummy += 3;
++                      if (REG_P (ops[0]))
++                              dummy--;
++                      if (REG_P (ops[1]))
++                              dummy--;
++                      if (indexed_location (ops[1]))
++                              dummy--;
++                      if (GET_CODE (ops[1]) == CONST_INT)
++                      {
++                              int x = INTVAL (ops[1]) & 0xffff;
++                              if (x == 0 || x == -1 || x == 1 || x == 2 || x == 4 || x == 8)
++                                      dummy--;
++                      }
++              }
++
++              /* adjust distance */
++              distance -= dummy;
++
++              if (mode == SImode && (code == EQ || code == NE))
++              {
++                      /* compare against zero and can we clobber source register ? */
++                      if (((GET_CODE (ops[1]) == CONST_INT
++                              && INTVAL (ops[1]) == 0)
++                              || ops[1] == const0_rtx)
++                              && REG_P (ops[0]) && dead_or_set_p (insn, ops[0]))
++                      {
++                              OUT_INSN (len, "bis\t%A0, %B0", ops);
++                              OUT_INSN (len, "tst\t%B0", ops);
++                              dummy += 2;
++                      }
++                      else
++                      {
++                              /* cannot clobber or something... */
++                              OUT_INSN (len, "cmp\t%A1, %A0", ops);
++                              dummy += 3;
++                              if (REG_P (ops[0]))
++                                      dummy--;
++                              if (REG_P (ops[1]))
++                                      dummy--;
++                              if (indexed_location (ops[1]))
++                                      dummy--;
++                              if (GET_CODE (ops[1]) == CONST_INT)
++                              {
++                                      int x = INTVAL (ops[1]) & 0xffff;
++                                      if (x == 0 || x == 1 || x == -1 || x == 2 || x == 4
++                                              || x == 8)
++                                              dummy--;
++                              }
++                              distance -= dummy;
++                              if (distance > 500 || distance < -500)
++                                      predist = 3;
++                              else
++                                      predist = 1;
++
++                              if (code == EQ)
++                              {
++                                      OUT_INSN (len, "jne\t.LcmpSIe%=", ops);
++                                      OUT_INSN (len, "cmp\t%B1, %B0", ops);
++                                      dummy++;
++                              }
++                              else
++                              {
++                                      ECOND (ne, 0);
++                                      OUT_INSN (len, "cmp\t%B1, %B0", ops);
++                              }
++
++                              dummy += 3;
++                              if (REG_P (ops[0]))
++                                      dummy--;
++                              if (REG_P (ops[1]))
++                                      dummy--;
++                              if (GET_CODE (ops[1]) == CONST_INT)
++                              {
++                                      int x = (INTVAL (ops[1]) >> 16) & 0xffff;
++                                      if (x == 0 || x == 0xffff || x == 1 || x == 2 || x == 4
++                                              || x == 8)
++                                              dummy--;
++                              }
++                      }
++              }
++              else if (mode == SImode)
++              {
++                      int dl = 0;
++                      rtx oops[3];
++                      oops[0] = ops[0];
++                      oops[1] = ops[0];
++                      oops[2] = ops[1];
++
++                      if (len)
++                              msp430_subsi_code (insn, oops, &dl);
++                      else
++                              msp430_subsi_code (insn, oops, NULL);
++
++                      if (len)
++                      {
++                              /* not handeled by adjust_insn_len() */
++                              dummy += dl;
++                              if (GET_CODE (ops[1]) == CONST_INT)
++                              {
++                                      int x = (INTVAL (ops[1]) >> 16) & 0xffff;
++                                      if (x == 0 || x == 1 || x == -1 || x == 2 || x == 4
++                                              || x == 8)
++                                              dummy--;
++                                      x = (INTVAL (ops[1]) >> 0) & 0xffff;
++                                      if (x == 0 || x == 1 || x == -1 || x == 2 || x == 4
++                                              || x == 8)
++                                              dummy--;
++                              }
++                      }
++              }
++      }
++
++      distance -= dummy;
++
++      if (distance > 500 || distance < -500)
++              predist = 3;
++      else
++              predist = 1;
++
++      /* out assembler commands if required */
++      switch (code)
++      {
++      case EQ:
++              ECOND (eq, 0);
++              if (mode == SImode)
++              {
++                      OUT_INSN (len, ".LcmpSIe%=:", operands);
++              }
++              break;
++      case NE:
++              ECOND (ne, 0);
++              break;
++      case LT:
++              if(nooverflow)
++                      ECOND (ltnoovfl,0);
++              else
++                      ECOND (lt, 0);
++              break;
++      case GE:
++              if(nooverflow)
++              {
++                      if(len) *len += 2;
++                      if(mode == QImode)
++                              OUT_INSN (len, "bit.b\t#0x80, %0",ops);
++                      else
++                              OUT_INSN (len, "bit\t#0x8000, %0",ops);
++              }
++              ECOND (ge, 0);
++              break;
++      case LTU:
++              ECOND (ltu, 0);
++              break;
++      case GEU:
++              ECOND (geu, 0);
++              break;
++              /* hopfully the following will not occure */
++      case LEU:
++              ECOND (leu, 1);
++              break;
++      case GT:
++              ECOND (gt, 1);
++              break;
++      case GTU:
++              ECOND (gtu, 1);
++              break;
++      case LE:
++              ECOND (le, 1);
++              break;
++
++      default:
++              break;
++      }
++
++      if (len)
++              *len = dummy;
++      return "";
++}
++
++
++static const char *msp430_emit_blt0si (rtx operands[], int len)
++{
++      output_asm_insn ("tst\t%B2", operands);
++      switch (len)
++      {
++      case 2:
++              output_asm_insn ("jl\t%0", operands);
++              break;
++      case 4:
++              output_asm_insn ("jge\t+4", operands);
++              output_asm_insn ("br\t#%0", operands);
++              break;
++      default:
++              return "bug!!!";
++      }
++
++      return "";
++}
++
++static const char *msp430_emit_beq (rtx operands[], int len)
++{
++
++      switch (len)
++      {
++      case 1:
++      case 2:
++              output_asm_insn ("jeq\t%0", operands);
++              break;
++      case 3:
++      case 4:
++              output_asm_insn ("jne\t+4", operands);
++              output_asm_insn ("br\t#%0", operands);
++              break;
++      default:
++              return "bug!!!";
++      }
++
++      return "";
++}
++
++static const char *msp430_emit_bne (rtx operands[], int len)
++{
++
++      switch (len)
++      {
++      case 1:
++      case 2:
++              output_asm_insn ("jne\t%0", operands);
++              break;
++      case 3:
++      case 4:
++              output_asm_insn ("jeq\t+4", operands);
++              output_asm_insn ("br\t#%0", operands);
++              break;
++      default:
++              return "bug!!!";
++      }
++
++      return "";
++}
++
++static const char *msp430_emit_bgt (rtx operands[], int len)
++{
++      switch (len)
++      {
++      case 2:
++              output_asm_insn ("jeq\t+2", operands);
++              output_asm_insn ("jge\t%0", operands);
++
++              break;
++      case 4:
++              output_asm_insn ("jeq\t+6", operands);
++              output_asm_insn ("jl\t+4", operands);
++              output_asm_insn ("br\t#%0", operands);
++              break;
++      default:
++              return "bug!!!";
++      }
++
++      return "";
++}
++
++static const char *msp430_emit_bgtu (rtx operands[], int len)
++{
++      switch (len)
++      {
++      case 2:
++              output_asm_insn ("jeq\t+2", operands);
++              output_asm_insn ("jhs\t%0", operands);
++
++              break;
++      case 4:
++              output_asm_insn ("jeq\t+6", operands);
++              output_asm_insn ("jlo\t+4", operands);
++              output_asm_insn ("br\t#%0", operands);
++              break;
++      default:
++              return "bug!!!";
++      }
++
++      return "";
++}
++
++static const char *msp430_emit_blt (rtx operands[], int len)
++{
++      switch (len)
++      {
++      case 1:
++      case 2:
++              output_asm_insn ("jl\t%0", operands);
++              break;
++      case 3:
++      case 4:
++              output_asm_insn ("jge\t+4", operands);
++              output_asm_insn ("br\t#%0", operands);
++              break;
++      default:
++              return "bug!!!";
++      }
++
++      return "";
++}
++
++
++static const char *msp430_emit_bltnoovfl (rtx operands[], int len)
++{
++      switch (len)
++      {
++      case 1:
++      case 2:
++              output_asm_insn ("jn\t%0", operands);
++              break;
++      case 3:
++      case 4:
++              output_asm_insn ("jn\t+2",operands);
++              output_asm_insn ("jmp\t+4", operands);
++              output_asm_insn ("br\t#%0", operands);
++              break;
++      default:
++              return "bug!!!";
++      }
++
++      return "";
++}
++
++static const char *msp430_emit_bltu (rtx operands[], int len)
++{
++      switch (len)
++      {
++      case 1:
++      case 2:
++              output_asm_insn ("jlo\t%0", operands);
++              break;
++      case 3:
++      case 4:
++              output_asm_insn ("jhs\t+4", operands);
++              output_asm_insn ("br\t#%0", operands);
++              break;
++      default:
++              return "bug!!!";
++      }
++
++      return "";
++}
++
++static const char *msp430_emit_bge (rtx operands[], int len)
++{
++      switch (len)
++      {
++      case 1:
++      case 2:
++              output_asm_insn ("jge\t%l0", operands);
++              break;
++      case 3:
++      case 4:
++              output_asm_insn ("jl\t+4", operands);
++              output_asm_insn ("br\t#%0", operands);
++              break;
++      default:
++              return "bug!!!";
++      }
++
++      return "";
++}
++
++static const char *msp430_emit_bgeu (rtx operands[], int len)
++{
++      switch (len)
++      {
++      case 1:
++      case 2:
++              output_asm_insn ("jhs\t%l0", operands);
++              break;
++      case 3:
++      case 4:
++              output_asm_insn ("jlo\t+4", operands);
++              output_asm_insn ("br\t#%0", operands);
++              break;
++      default:
++              return "bug!!!";
++      }
++
++      return "";
++}
++
++static const char *msp430_emit_ble (rtx operands[], int len)
++{
++      switch (len)
++      {
++      case 2:
++              output_asm_insn ("jeq\t%0", operands);
++              output_asm_insn ("jl\t%0", operands);
++              break;
++      case 4:
++              output_asm_insn ("jeq\t+2", operands);
++              output_asm_insn ("jge\t+4", operands);
++              output_asm_insn ("br\t#%0", operands);
++              break;
++      default:
++              return "bug!!!";
++      }
++
++      return "";
++}
++
++static const char *msp430_emit_bleu (rtx operands[], int len)
++{
++      switch (len)
++      {
++      case 2:
++              output_asm_insn ("jeq\t%0", operands);
++              output_asm_insn ("jlo\t%0", operands);
++              break;
++      case 4:
++              output_asm_insn ("jeq\t+2", operands);
++              output_asm_insn ("jhs\t+4", operands);
++              output_asm_insn ("br\t#%0", operands);
++              break;
++      default:
++              return "bug!!!";
++      }
++
++      return "";
++}
++
++/*  x - dst
++y - src */
++static int msp430_cc_source (rtx insn, enum rtx_code code, rtx x, rtx y)
++{
++      rtx prev = insn;
++      enum attr_cc cc;
++      rtx set;
++      rtx src, dst;
++      rtx x1 = 0;
++
++      if(GET_CODE(x) == MEM)
++      {
++              x1 = XEXP(x,0);
++              if(GET_CODE(x1) == PLUS)
++              {
++                      x1 = XEXP(x1,0);
++              }
++
++              if(!REG_P(x1)) x1 = 0;
++      }
++
++      while (0 != (prev = PREV_INSN (prev)))
++      {
++              if (GET_CODE (prev) == CODE_LABEL
++                      || GET_CODE (prev) == BARRIER || GET_CODE (prev) == CALL_INSN)
++                      return 0;
++
++              if (GET_CODE (prev) == INSN)
++              {
++                      set = single_set (prev);
++
++                      if(!set)
++                              return 0;
++
++                      cc = get_attr_cc (prev);
++
++                      if (cc == CC_NONE)      /* does not change CC */
++                      {
++                              /*The one spot by Nick C. */
++                              dst = SET_DEST (set);
++                              if((dst && rtx_equal_p (x, dst)) ||
++                                      (x1 && dst && rtx_equal_p (x1, dst)))
++                                      return 0;
++                              else
++                                      continue;
++                      }
++
++                      if (cc == CC_CLOBBER)   /* clobber */
++                              return 0;
++
++                      if (cc == CC_OPER)      /* post-incremental stuff */
++                      {
++                              src = SET_SRC (set);
++                              if (GET_CODE (set) == IOR)      /* does not change CC */
++                              {
++                                      dst = SET_DEST (set);
++                                      if(dst && rtx_equal_p (x, dst))
++                                              return 0;
++                                      else
++                                              continue;
++                              }
++                      }
++
++                      /* all other attributes are bit messy.
++                      So, we'll record destination and check if 
++                      this matches 'x' and compare is against zero */
++                      dst = SET_DEST (set);
++                      if (rtx_equal_p (x, dst) && rtx_equal_p (y, const0_rtx))
++                              return 1;
++                      else
++                              return 0;
++              }
++              else if (GET_CODE (prev) == JUMP_INSN)
++              {
++                      /* if 2 consequent jump insns were issued, this means
++                      that operands (more likely src) are different.
++                      however, some jumps optimization can equalize these operands
++                      and everything will be bad. Therefore, assume that
++                      any jump insn clobbers condition codes.*/
++                      return 0;
++              }
++      }
++      return 0;
++}
+diff -urNad msp430-gcc~/gcc/config/msp430/msp430-emit-cbranch.c msp430-gcc/gcc/config/msp430/msp430-emit-cbranch.c
+--- msp430-gcc~/gcc/config/msp430/msp430-emit-cbranch.c        1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/msp430-emit-cbranch.c 2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1,235 @@
++/* This work is partially financed by the European Commission under the
++* Framework 6 Information Society Technologies Project
++* "Wirelessly Accessible Sensor Populations (WASP)".
++*/
++
++/*
++GCC 4.x port by Ivan Shcherbakov <mspgcc@sysprogs.org>
++*/
++
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++#include "rtl.h"
++#include "regs.h"
++#include "hard-reg-set.h"
++#include "real.h"
++#include "insn-config.h"
++#include "conditions.h"
++#include "insn-attr.h"
++#include "flags.h"
++#include "reload.h"
++#include "tree.h"
++#include "output.h"
++#include "expr.h"
++#include "toplev.h"
++#include "obstack.h"
++#include "function.h"
++#include "recog.h"
++#include "tm_p.h"
++#include "target.h"
++#include "target-def.h"
++#include "insn-codes.h"
++#include "ggc.h"
++#include "langhooks.h"
++
++struct rtx_def *msp430_compare_op0;
++struct rtx_def *msp430_compare_op1;
++
++void msp430_emit_cbranch (enum rtx_code code, rtx loc)
++{
++      rtx op0 = msp430_compare_op0;
++      rtx op1 = msp430_compare_op1;
++      rtx condition_rtx, loc_ref, branch;
++      enum machine_mode mode;
++      int mem_volatil=0;
++
++      if (!msp430_compare_op0 && !msp430_compare_op1)
++      {
++              /* this is a branch upon previous insn issued */
++              loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
++              condition_rtx = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
++
++              branch = gen_rtx_SET (VOIDmode,
++                      pc_rtx,
++                      gen_rtx_IF_THEN_ELSE (VOIDmode,
++                      condition_rtx,
++                      loc_ref, pc_rtx));
++              emit_jump_insn (branch);
++              return;
++      }
++
++      mode = GET_MODE (op0);
++      if (mode != SImode && mode != HImode && mode != QImode)
++              abort ();
++
++
++      /* now convert codes */
++      code = msp430_canonicalize_comparison (code, &op0, &op1);
++
++      /* for HI and QI modes everything is simple.
++      Also, if code is eq or ne in SI mode, no clobbers required. */
++
++      if (mode == SImode && !(code == EQ || code == NE))
++      {
++              /* check if only high nibbles required */
++              if (GET_CODE (op1) == CONST_INT
++                      && INTVAL (op1) == 0 && (code == LT || code == GE))
++              {
++                      mem_volatil = MEM_VOLATILE_P(op0);
++                      MEM_VOLATILE_P(op0) = 0;
++                      op0 = gen_highpart (HImode, op0);
++                      MEM_VOLATILE_P(op0) = mem_volatil;
++                      mode = HImode;
++                      PUT_MODE (op1, VOIDmode);       /* paranoia ? */
++              }
++              else if (GET_CODE (op1) == CONST_INT
++                      && ((INTVAL (op1) + 1) & 0xffff) == 0
++                      && (code == GT || code == GTU || code == LE || code == LEU))
++              {
++                      /* check if this can be done simple. 
++                      we will not clobber const operand. */
++                      int x = INTVAL (op1);
++                      x++;
++                      x >>= 16;
++                      MEM_VOLATILE_P(op0) = 0;
++                      op0 = gen_highpart (HImode, op0);
++                      MEM_VOLATILE_P(op0) = mem_volatil;
++                      mode = HImode;
++                      op1 = GEN_INT (trunc_int_for_mode (x, HImode));
++
++                      if (code == GT)
++                              code = GE;
++                      else if (code == GTU)
++                              code = GEU;
++                      else if (code == LEU)
++                              code = LTU;
++                      else if (code == LE)
++                              code = LT;
++              }
++              else
++              {
++                      rtvec vec;
++                      /* the redudant move will be deleted */
++                      op0 = copy_to_mode_reg (SImode, op0);
++                      condition_rtx = gen_rtx_fmt_ee (code, mode, op0, op1);
++                      loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
++                      branch = gen_rtx_SET (VOIDmode, pc_rtx,
++                              gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
++                              loc_ref, pc_rtx));
++                      vec = gen_rtvec (2, branch, gen_rtx_CLOBBER (SImode, op0));
++                      emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, vec));
++                      msp430_compare_op0 = 0;
++                      msp430_compare_op1 = 0;
++                      return;
++              }
++      }
++      else if(mode == SImode && code == NE
++              && GET_CODE(op1)!= CONST_INT && op1 != const0_rtx)
++      {
++              rtx op0lo, op0hi, op1lo, op1hi;
++
++              mem_volatil = MEM_VOLATILE_P(op0);
++              op0lo = gen_lowpart(HImode, op0);
++              op0hi = gen_highpart(HImode, op0);
++              MEM_VOLATILE_P(op0) = mem_volatil;
++
++              mem_volatil = MEM_VOLATILE_P(op1);
++              op1lo = gen_lowpart(HImode, op1);
++              op1hi = gen_highpart(HImode, op1);
++              MEM_VOLATILE_P(op1) = mem_volatil;
++
++              condition_rtx = gen_rtx_fmt_ee (NE,HImode,op0lo,op1lo);
++              loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
++              branch = gen_rtx_SET (VOIDmode, pc_rtx,
++                      gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
++                      loc_ref, pc_rtx));
++              emit_jump_insn (branch);
++              condition_rtx = gen_rtx_fmt_ee (NE,HImode,op0hi,op1hi);
++              branch = gen_rtx_SET (VOIDmode, pc_rtx,
++                      gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
++                      loc_ref, pc_rtx));
++              emit_jump_insn (branch);
++              msp430_compare_op0 = 0;
++              msp430_compare_op1 = 0;
++              return;
++      }
++      else if(mode == SImode && code == EQ && GET_CODE(op1)!= CONST_INT )
++      {
++              rtx tlabel = gen_label_rtx();
++              rtx tloc_ref;
++              rtx op0lo, op0hi, op1lo, op1hi;
++
++              mem_volatil = MEM_VOLATILE_P(op0);
++              op0lo = gen_lowpart(HImode, op0);
++              op0hi = gen_highpart(HImode, op0);
++              MEM_VOLATILE_P(op0) = mem_volatil;
++
++              mem_volatil = MEM_VOLATILE_P(op1);
++              op1lo = gen_lowpart(HImode, op1);
++              op1hi = gen_highpart(HImode, op1);
++              MEM_VOLATILE_P(op1) = mem_volatil;
++
++              condition_rtx = gen_rtx_fmt_ee (NE,HImode,op0lo,op1lo);
++              tloc_ref = gen_rtx_LABEL_REF (VOIDmode, tlabel);
++              branch = gen_rtx_SET (VOIDmode, pc_rtx,
++                      gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
++                      tloc_ref, pc_rtx));
++              emit_jump_insn (branch);
++
++              condition_rtx = gen_rtx_fmt_ee (EQ,HImode,op0hi,op1hi);
++              loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
++              branch = gen_rtx_SET (VOIDmode, pc_rtx,
++                      gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
++                      loc_ref, pc_rtx));
++              emit_jump_insn (branch);
++              emit_label(tlabel);
++              msp430_compare_op0 = 0;
++              msp430_compare_op1 = 0;
++              return ;
++      }
++
++      condition_rtx = gen_rtx_fmt_ee (code, mode, op0, op1);
++      loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
++      branch = gen_rtx_SET (VOIDmode, pc_rtx,
++              gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
++              loc_ref, pc_rtx));
++
++      emit_jump_insn (branch);
++
++      msp430_compare_op0 = 0;
++      msp430_compare_op1 = 0;
++      return;
++}
++
++RTX_CODE msp430_canonicalize_comparison (RTX_CODE code, rtx *op0, rtx *op1)
++{
++      RTX_CODE rc = code;
++
++      if ( CONSTANT_P(*op1) )
++      {
++              ;                               /* nothing to be done */
++      }
++      else
++      {
++              switch (code)
++              {
++              case GT:
++              case LE:
++              case GTU:
++              case LEU:
++                      {
++                              rtx x;
++                              rc = swap_condition (code);
++                              x = *op0;
++                              *op0 = *op1;
++                              *op1 = x;
++                      }
++                      break;
++              default:
++                      break;
++              }
++      }
++      return rc;
++}
+\ No newline at end of file
+diff -urNad msp430-gcc~/gcc/config/msp430/msp430-function.c msp430-gcc/gcc/config/msp430/msp430-function.c
+--- msp430-gcc~/gcc/config/msp430/msp430-function.c    1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/msp430-function.c     2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1,781 @@
++/* This work is partially financed by the European Commission under the
++* Framework 6 Information Society Technologies Project
++* "Wirelessly Accessible Sensor Populations (WASP)".
++*/
++
++/*
++GCC 4.x port by Ivan Shcherbakov <mspgcc@sysprogs.org>
++*/
++
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++#include "rtl.h"
++#include "regs.h"
++#include "hard-reg-set.h"
++#include "real.h"
++#include "insn-config.h"
++#include "conditions.h"
++#include "insn-attr.h"
++#include "flags.h"
++#include "reload.h"
++#include "tree.h"
++#include "output.h"
++#include "expr.h"
++#include "toplev.h"
++#include "obstack.h"
++#include "function.h"
++#include "recog.h"
++#include "tm_p.h"
++#include "target.h"
++#include "target-def.h"
++#include "insn-codes.h"
++#include "ggc.h"
++#include "langhooks.h"
++#include "msp430-predicates.inl"
++
++#if GCC_VERSION_INT < 0x430
++static inline int df_regs_ever_live_p(int reg)
++{
++      return regs_ever_live[reg];
++}
++#endif
++
++extern int msp430_commands_in_file;
++extern int msp430_commands_in_prologues;
++extern int msp430_commands_in_epilogues;
++
++/* ret/reti issue indicator for _current_ function */
++static int return_issued = 0;
++
++/* Prologue/Epilogue size in words */
++static int prologue_size;
++static int epilogue_size;
++
++/* Size of all jump tables in the current function, in words.  */
++static int jump_tables_size;
++
++/* This holds the last insn address.  */
++static int last_insn_address = 0;
++
++static int msp430_func_num_saved_regs (void);
++
++/* actual frame offset */
++static int msp430_current_frame_offset = 0;
++
++/* registers used for incoming funct arguments */
++static char arg_register_used[16];
++
++#define FIRST_CUM_REG 16
++static CUMULATIVE_ARGS *cum_incoming = 0;
++
++static int msp430_num_arg_regs (enum machine_mode mode, tree type);
++static int msp430_saved_regs_frame (void);
++
++void msp430_function_end_prologue (FILE * file);
++void msp430_function_begin_epilogue (FILE * file);
++
++int msp430_epilogue_uses (int regno ATTRIBUTE_UNUSED)
++{
++      if (reload_completed 
++              && cfun->machine
++              && (cfun->machine->is_interrupt || cfun->machine->is_signal))
++              return 1;
++      return 0;
++}
++
++
++void msp430_function_end_prologue (FILE * file)
++{
++      HOST_WIDE_INT frameSize = get_frame_size();
++      rtx functionExp = DECL_RTL (current_function_decl);
++      const char *functionName = XSTR (XEXP (functionExp, 0), 0);
++
++      if (cfun->machine->is_naked)
++      {
++              fprintf (file, "\t/* prologue: naked */\n");
++              fprintf (file, ".L__FrameSize_%s=0x%x\n", functionName, (unsigned)frameSize);
++      }
++      else
++      {
++              int offset = initial_elimination_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM) - 2;
++              fprintf (file, "\t/* prologue ends here (frame size = %d) */\n", (unsigned)frameSize);
++              fprintf (file, ".L__FrameSize_%s=0x%x\n", functionName, (unsigned)frameSize);
++              fprintf (file, ".L__FrameOffset_%s=0x%x\n", functionName, (unsigned)offset);
++      }
++}
++
++void msp430_function_begin_epilogue (FILE * file)
++{
++      if (cfun->machine->is_OS_task)
++              fprintf (file, "\n\t/* epilogue: empty, task functions never return */\n");
++      else if (cfun->machine->is_naked)
++              fprintf (file, "\n\t/* epilogue: naked */\n");
++      else if (msp430_empty_epilogue ())
++              fprintf (file, "\n\t/* epilogue: not required */\n");
++      else
++              fprintf (file, "\n\t/* epilogue: frame size = %d */\n", (unsigned)get_frame_size());
++}
++
++static int msp430_get_stack_reserve(void);
++
++static int msp430_get_stack_reserve(void)
++{
++      int stack_reserve = 0;
++      tree ss = lookup_attribute ("reserve", DECL_ATTRIBUTES (current_function_decl));
++      if (ss)
++      {
++              ss = TREE_VALUE (ss);
++              if (ss)
++              {
++                      ss = TREE_VALUE (ss);
++                      if (ss)
++                              stack_reserve = TREE_INT_CST_LOW (ss);
++                      stack_reserve++;
++                      stack_reserve &= ~1;
++              }
++      }
++      return stack_reserve;
++}
++
++#include "framehelpers.inl"
++
++void expand_prologue (void)
++{
++      int i;
++      int main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
++      int stack_reserve = 0;
++      int offset;
++      int save_prologue_p = msp430_save_prologue_function_p (current_function_decl);
++      int num_saved_regs;
++      HOST_WIDE_INT size = get_frame_size();
++
++      rtx insn;       /* Last generated instruction */
++
++      return_issued = 0;
++      last_insn_address = 0;
++      jump_tables_size = 0;
++      prologue_size = 0;
++
++      cfun->machine->is_naked = msp430_naked_function_p (current_function_decl);
++      cfun->machine->is_interrupt = interrupt_function_p (current_function_decl);
++      cfun->machine->is_OS_task = msp430_task_function_p (current_function_decl);
++      
++      cfun->machine->is_noint_hwmul = noint_hwmul_function_p (current_function_decl);
++      cfun->machine->is_critical = msp430_critical_function_p(current_function_decl);
++      cfun->machine->is_reenterant = msp430_reentrant_function_p(current_function_decl);
++      cfun->machine->is_wakeup = wakeup_function_p (current_function_decl);
++      cfun->machine->is_signal = signal_function_p (current_function_decl);
++
++
++      /* check attributes compatibility */
++
++      if ((cfun->machine->is_critical && cfun->machine->is_reenterant) || (cfun->machine->is_reenterant && cfun->machine->is_interrupt))
++      {
++              warning (OPT_Wattributes, "attribute 'reentrant' ignored");
++              cfun->machine->is_reenterant = 0;
++      }
++
++      if (cfun->machine->is_critical && cfun->machine->is_interrupt)
++      {
++              warning (OPT_Wattributes, "attribute 'critical' ignored");
++              cfun->machine->is_critical = 0;
++      }
++
++      if (cfun->machine->is_signal && !cfun->machine->is_interrupt)
++      {
++              warning (OPT_Wattributes, "attribute 'signal' has no meaning on MSP430 without 'interrupt' attribute.");
++              cfun->machine->is_signal = 0;
++      }
++
++      /* naked function discards everything */
++      if (cfun->machine->is_naked)
++              return;
++
++      stack_reserve = msp430_get_stack_reserve();
++      offset = initial_elimination_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM) - 2;
++
++      msp430_current_frame_offset = offset;
++
++      if (cfun->machine->is_signal && cfun->machine->is_interrupt)
++      {
++              prologue_size += 1;
++
++              insn = emit_insn (gen_enable_interrupt());
++              /* fprintf (file, "\teint\t; enable nested interrupt\n"); */
++      }
++
++      if (main_p)
++      {
++              if (TARGET_NO_STACK_INIT)
++              {
++                      if (size || stack_reserve)
++                      {
++                              /* fprintf (file, "\tsub\t#%d, r1\t", size + stack_reserve); */
++
++                              msp430_fh_sub_sp_const(size + stack_reserve);
++                      }
++                      
++                      if (frame_pointer_needed)
++                      {
++                              /* fprintf (file, "\tmov\tr1,r%d\n", FRAME_POINTER_REGNUM); */
++                              insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
++                              RTX_FRAME_RELATED_P (insn) = 1;
++
++                              prologue_size += 1;
++                      }
++                      
++                      if (size)
++                              prologue_size += 2;
++                      if (size == 1 || size == 2 || size == 4 || size == 8)
++                              prologue_size--;
++              }
++              else
++              {
++                      /*fprintf (file, "\tmov\t#(%s-%d), r1\n", msp430_init_stack, size + stack_reserve);*/
++                      msp430_fh_load_sp_with_sym_plus_off(msp430_init_stack, -(size + stack_reserve));
++
++                      if (frame_pointer_needed)
++                      {
++                              /* fprintf (file, "\tmov\tr1,r%d\n", FRAME_POINTER_REGNUM); */
++
++                              insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
++                              RTX_FRAME_RELATED_P (insn) = 1;
++
++                              prologue_size += 1;
++                      }
++                      prologue_size += 2;
++              }
++              if ((ACCUMULATE_OUTGOING_ARGS) && (!cfun->machine->is_leaf || cfun->calls_alloca) && crtl->outgoing_args_size)
++                      msp430_fh_sub_sp_const(crtl->outgoing_args_size);
++      }
++      else    /* not a main() function */
++      {
++              /* Here, we've got a chance to jump to prologue saver */
++              num_saved_regs = msp430_func_num_saved_regs ();
++
++              if (!cfun->machine->is_interrupt && cfun->machine->is_critical)
++              {
++                      prologue_size += 3;
++                      /*fprintf (file, "\tpush\tr2\n");
++                      fprintf (file, "\tdint\n");
++                      if (!size)
++                              fprintf (file, "\tnop\n");*/
++
++                      insn = emit_insn (gen_push_sreg()); /* Pushing R2 using normal push creates a faulty INSN */
++                      RTX_FRAME_RELATED_P (insn) = 1;
++                      
++                      insn = emit_insn (gen_disable_interrupt());
++                      if (!size)
++                              insn = emit_insn (gen_nop());
++              }
++
++              if ((TARGET_SAVE_PROLOGUE || save_prologue_p)
++                      && !cfun->machine->is_interrupt && !arg_register_used[12] && num_saved_regs > 4)
++              {
++                      /* TODO: Expand this as a separate INSN called "call prologue saver", having a meaning of pushing the registers and decreasing SP, 
++                              so that the debug info generation code will handle this correctly */
++                      
++                      /*fprintf (file, "\tsub\t#16, r1\n");
++                      fprintf (file, "\tmov\tr0, r12\n");
++                      fprintf (file, "\tadd\t#8, r12\n");
++                      fprintf (file, "\tbr\t#__prologue_saver+%d\n", (8 - num_saved_regs) * 4);*/
++
++                      msp430_fh_sub_sp_const(16);
++                      msp430_fh_gen_mov_pc_to_reg(12);
++                      msp430_fh_add_reg_const(12, 8);
++                      msp430_fh_br_to_symbol_plus_offset("__prologue_saver", (8 - num_saved_regs) * 4);
++
++                      if (cfun->machine->is_critical && 8 - num_saved_regs)
++                      {
++                              int n = 16 - num_saved_regs * 2;
++                              /*fprintf (file, "\tadd\t#%d, r1\n", n);*/
++                              msp430_fh_add_sp_const(n);
++                              if (n != 0 && n != 1 && n != 2 && n != 4 && n != 8)
++                                      prologue_size += 1;
++                      }
++                      else
++                              size -= 16 - num_saved_regs * 2;
++
++                      prologue_size += 7;
++              }
++              else if(!cfun->machine->is_OS_task)
++              {
++                      for (i = 15; i >= 4; i--)
++                      {
++                              if ((df_regs_ever_live_p(i) && (!call_used_regs[i] || cfun->machine->is_interrupt)) || 
++                                      (!cfun->machine->is_leaf && (call_used_regs[i] && (cfun->machine->is_interrupt))))
++                              {
++                                      /*fprintf (file, "\tpush\tr%d\n", i);*/
++                                      msp430_fh_emit_push_reg(i);
++                                      prologue_size += 1;
++                              }
++                      }
++              }
++
++              if (size)
++              {
++                      /* The next is a hack... I do not understand why, but if there
++                      ARG_POINTER_REGNUM and FRAME/STACK are different, 
++                      the compiler fails to compute corresponding
++                      displacement */
++                      if (!optimize && !optimize_size
++                              && df_regs_ever_live_p(ARG_POINTER_REGNUM))
++                      {
++                              int o = initial_elimination_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM) - size;
++                              
++                              /* fprintf (file, "\tmov\tr1, r%d\n", ARG_POINTER_REGNUM);
++                              fprintf (file, "\tadd\t#%d, r%d\n", o, ARG_POINTER_REGNUM); */
++
++                              insn = emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
++                              RTX_FRAME_RELATED_P (insn) = 1;
++                              msp430_fh_add_reg_const(ARG_POINTER_REGNUM, o);
++
++                              prologue_size += 2;
++                              if (o != 0 && o != 1 && o != 2 && o != 4 && o != 8)
++                                      prologue_size += 1;
++                      }
++
++                      /* adjust frame ptr... */
++                      if (size < 0)
++                      {
++                              int subtracted = (size + 1) & ~1;
++                              /*fprintf (file, "\tsub\t#%d, r1\t;     %d, fpn %d\n", subtracted, size, frame_pointer_needed);*/
++                              msp430_fh_sub_sp_const(subtracted);
++                              
++                      }
++                      else
++                      {
++                              int added;
++                              size = -size;
++                              added = (size + 1) & ~1;
++                              /*fprintf (file, "\tadd\t#%d, r1\t;    %d, fpn %d\n", (size + 1) & ~1, size, frame_pointer_needed);*/
++                              msp430_fh_add_sp_const(added);
++                      }
++
++                      if (size == 1 || size == 2 || size == 4 || size == 8)
++                              prologue_size += 1;
++                      else
++                              prologue_size += 2;
++              }
++
++              if (frame_pointer_needed)
++              {
++                      /*fprintf (file, "\tmov\tr1,r%d\n", FRAME_POINTER_REGNUM);*/
++
++                      insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
++                      RTX_FRAME_RELATED_P (insn) = 1;
++
++                      prologue_size += 1;
++              }
++
++              if ((ACCUMULATE_OUTGOING_ARGS) && (!cfun->machine->is_leaf || cfun->calls_alloca) && crtl->outgoing_args_size)
++                      msp430_fh_sub_sp_const(crtl->outgoing_args_size);
++
++                      /* disable interrupt for reentrant function */
++              if (!cfun->machine->is_interrupt && cfun->machine->is_reenterant)
++              {
++                      prologue_size += 1;
++                      /*fprintf (file, "\tdint\n");*/
++                      insn = emit_insn (gen_disable_interrupt());
++              }
++      }
++
++      /*fprintf (file, "\t/ * prologue end (size=%d) * /\n\n", prologue_size);*/
++}
++
++
++/* Output function epilogue */
++
++void expand_epilogue (void)
++{
++      int i;
++      int interrupt_func_p = cfun->machine->is_interrupt;
++      int main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
++      int wakeup_func_p = cfun->machine->is_wakeup;
++      int cfp = cfun->machine->is_critical;
++      int ree = cfun->machine->is_reenterant;
++      int save_prologue_p = msp430_save_prologue_function_p (current_function_decl);
++      /*int function_size;*/
++      HOST_WIDE_INT size = get_frame_size();
++
++      rtx insn;
++
++
++      last_insn_address = 0;
++      jump_tables_size = 0;
++      epilogue_size = 0;
++      /*function_size = (INSN_ADDRESSES (INSN_UID (get_last_insn ())) - INSN_ADDRESSES (INSN_UID (get_insns ())));*/
++
++      if (cfun->machine->is_OS_task || cfun->machine->is_naked)
++      {
++              emit_jump_insn (gen_return ()); /* Otherwise, epilogue with 0 instruction causes a segmentation fault */
++              return;
++      }
++
++      if (msp430_empty_epilogue ())
++      {
++              if (!return_issued)
++              {
++                      /*fprintf (file, "\t%s\n", msp430_emit_return (NULL, NULL, NULL));*/
++                      emit_jump_insn (gen_return ());
++                      epilogue_size++;
++              }
++              /*fprintf (file, "\n\t/ * epilogue: not required * /\n");*/
++              goto done_epilogue;
++      }
++
++      if ((cfp || interrupt_func_p) && ree)
++              ree = 0;
++      if (cfp && interrupt_func_p)
++              cfp = 0;
++
++      /*fprintf (file, "\n\t/ * epilogue : frame size = %d * /\n", size);*/
++
++      if (main_p)
++      {
++              int totalsize = (size + 1) & ~1;
++              if ((ACCUMULATE_OUTGOING_ARGS) && (!cfun->machine->is_leaf || cfun->calls_alloca) && crtl->outgoing_args_size)
++                      totalsize += crtl->outgoing_args_size;
++              if (totalsize)
++              {
++                      msp430_fh_add_sp_const(totalsize);
++                      /*fprintf (file, "\tadd\t#%d, r1\n", (size + 1) & ~1);*/
++              }
++              /*fprintf (file, "\tbr\t#%s\n", msp430_endup);*/
++              msp430_fh_br_to_symbol_plus_offset(msp430_endup, 0);
++              epilogue_size += 4;
++              if (size == 1 || size == 2 || size == 4 || size == 8)
++                      epilogue_size--;
++      }
++      else
++      {
++              int totalsize = (size + 1) & ~1;
++              if ((ACCUMULATE_OUTGOING_ARGS) && (!cfun->machine->is_leaf || cfun->calls_alloca) && crtl->outgoing_args_size)
++                      totalsize += crtl->outgoing_args_size;
++
++                      if (ree)
++              {
++                      /*fprintf (file, "\teint\n");*/
++
++                      insn = emit_insn (gen_enable_interrupt());
++
++                      epilogue_size += 1;
++              }
++
++              if (totalsize)
++              {
++                      /*fprintf (file, "\tadd\t#%d, r1\n", (size + 1) & ~1);*/
++                      msp430_fh_add_sp_const(totalsize);
++
++                      if (size == 1 || size == 2 || size == 4 || size == 8)
++                              epilogue_size += 1;
++                      else
++                              epilogue_size += 2;
++              }
++
++              if ((TARGET_SAVE_PROLOGUE || save_prologue_p)
++                      && !interrupt_func_p && msp430_func_num_saved_regs () > 2)
++              {
++                      /*fprintf (file, "\tbr\t#__epilogue_restorer+%d\n",(8 - msp430_func_num_saved_regs ()) * 2);*/
++
++                      msp430_fh_br_to_symbol_plus_offset("__epilogue_restorer", (8 - msp430_func_num_saved_regs ()) * 2);
++
++                      epilogue_size += 2;
++              }
++              else if ((TARGET_SAVE_PROLOGUE || save_prologue_p) && interrupt_func_p)
++              {
++                      /*fprintf (file, "\tbr\t#__epilogue_restorer_intr+%d\n", (12 - msp430_func_num_saved_regs ()) * 2);*/
++                      msp430_fh_br_to_symbol_plus_offset("__epilogue_restorer_intr", (12 - msp430_func_num_saved_regs ()) * 2);
++              }
++              else
++              {
++                      for (i = 4; i < 16; i++)
++                      {
++                              if ((df_regs_ever_live_p(i)
++                                      && (!call_used_regs[i]
++                              || interrupt_func_p))
++                                      || (!cfun->machine->is_leaf && (call_used_regs[i] && interrupt_func_p)))
++                              {
++                                      /*fprintf (file, "\tpop\tr%d\n", i);*/
++                                      msp430_fh_emit_pop_reg(i);
++                                      epilogue_size += 1;
++                              }
++                      }
++
++                      if (interrupt_func_p && wakeup_func_p)
++                      {
++                              /*fprintf (file, "\tbic\t#0xf0,0(r1)\n");*/
++                              msp430_fh_bic_deref_sp(0xF0);
++                              epilogue_size += 3;
++                      }
++                      emit_jump_insn (gen_return ());
++                      /*fprintf (file, "\tret\n");*/
++                      epilogue_size += 1;
++              }
++      }
++
++      /*fprintf (file, "\t/ * epilogue end (size=%d) * /\n", epilogue_size);*/
++done_epilogue:
++      /*fprintf (file, "\t/ * function %s size %d (%d) * /\n", current_function_name, prologue_size + function_size + epilogue_size, function_size);*/
++
++      msp430_commands_in_file += prologue_size + /*function_size +*/ epilogue_size;
++      msp430_commands_in_prologues += prologue_size;
++      msp430_commands_in_epilogues += epilogue_size;
++}
++
++/* Returns a number of pushed registers */
++static int msp430_func_num_saved_regs (void)
++{
++      int i;
++      int saves = 0;
++      int interrupt_func_p = interrupt_function_p (current_function_decl);
++
++      for (i = 4; i < 16; i++)
++      {
++              if ((df_regs_ever_live_p(i)
++                      && (!call_used_regs[i]
++              || interrupt_func_p))
++                      || (!cfun->machine->is_leaf && (call_used_regs[i] && interrupt_func_p)))
++              {
++                      saves += 1;
++              }
++      }
++
++      return saves;
++}
++
++const char *msp430_emit_return (rtx insn ATTRIBUTE_UNUSED, rtx operands[] ATTRIBUTE_UNUSED, int *len ATTRIBUTE_UNUSED)
++{
++      return_issued = 1;
++      if (msp430_critical_function_p (current_function_decl) || interrupt_function_p(current_function_decl))
++              return "reti";
++
++      return "ret";
++}
++
++void msp430_output_addr_vec_elt (FILE *stream, int value)
++{
++      fprintf (stream, "\t.word       .L%d\n", value);
++      jump_tables_size++;
++}
++
++/* Output all insn addresses and their sizes into the assembly language
++output file.  This is helpful for debugging whether the length attributes
++in the md file are correct.
++Output insn cost for next insn.  */
++
++void final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED, int num_operands ATTRIBUTE_UNUSED)
++{
++      int uid = INSN_UID (insn);
++
++      if (TARGET_ALL_DEBUG)
++      {
++              fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
++                      INSN_ADDRESSES (uid),
++                      INSN_ADDRESSES (uid) - last_insn_address,
++                      rtx_cost (PATTERN (insn), INSN, !optimize_size));
++      }
++      last_insn_address = INSN_ADDRESSES (uid);
++}
++
++/* Controls whether a function argument is passed
++in a register, and which register. */
++rtx function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, int named ATTRIBUTE_UNUSED)
++{
++      int regs = msp430_num_arg_regs (mode, type);
++
++      if (cum->nregs && regs <= cum->nregs)
++      {
++              int regnum = cum->regno - regs;
++
++              if (cum == cum_incoming)
++              {
++                      arg_register_used[regnum] = 1;
++                      if (regs >= 2)
++                              arg_register_used[regnum + 1] = 1;
++                      if (regs >= 3)
++                              arg_register_used[regnum + 2] = 1;
++                      if (regs >= 4)
++                              arg_register_used[regnum + 3] = 1;
++              }
++
++              return gen_rtx_REG (mode, regnum);
++      }
++      return NULL_RTX;
++}
++
++/* the same in scope of the cum.args., buf usefull for a
++function call */
++void init_cumulative_incoming_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname)
++{
++      int i;
++      cum->nregs = 4;
++      cum->regno = FIRST_CUM_REG;
++      if (!libname)
++      {
++              int stdarg = (TYPE_ARG_TYPES (fntype) != 0
++                      && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
++                      != void_type_node));
++              if (stdarg)
++                      cum->nregs = 0;
++      }
++
++      for (i = 0; i < 16; i++)
++              arg_register_used[i] = 0;
++
++      cum_incoming = cum;
++}
++
++/* Initializing the variable cum for the state at the beginning
++of the argument list.  */
++void init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname, int indirect ATTRIBUTE_UNUSED)
++{
++      cum->nregs = 4;
++      cum->regno = FIRST_CUM_REG;
++      if (!libname)
++      {
++              int stdarg = (TYPE_ARG_TYPES (fntype) != 0
++                      && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
++                      != void_type_node));
++              if (stdarg)
++                      cum->nregs = 0;
++      }
++}
++
++
++/* Update the summarizer variable CUM to advance past an argument
++in the argument list.  */
++void function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, int named ATTRIBUTE_UNUSED)
++{
++      int regs = msp430_num_arg_regs (mode, type);
++
++      cum->nregs -= regs;
++      cum->regno -= regs;
++
++      if (cum->nregs <= 0)
++      {
++              cum->nregs = 0;
++              cum->regno = FIRST_CUM_REG;
++      }
++}
++
++/* Returns the number of registers to allocate for a function argument.  */
++static int msp430_num_arg_regs (enum machine_mode mode, tree type)
++{
++      int size;
++
++      if (mode == BLKmode)
++              size = int_size_in_bytes (type);
++      else
++              size = GET_MODE_SIZE (mode);
++
++      if (size < 2)
++              size = 2;
++
++      /* we do not care if argument is passed in odd register
++      so, do not align the size ...
++      BUT!!! even char argument passed in 16 bit register
++      so, align the size */
++      return ((size + 1) & ~1) >> 1;
++}
++
++static int msp430_saved_regs_frame (void)
++{
++      int interrupt_func_p = interrupt_function_p (current_function_decl);
++      int cfp = msp430_critical_function_p (current_function_decl);
++      int offset = interrupt_func_p ? 0 : (cfp ? 2 : 0);
++      int reg;
++
++      for (reg = 4; reg < 16; ++reg)
++      {
++              if ((!cfun->machine->is_leaf && call_used_regs[reg] && (interrupt_func_p))
++                      || (df_regs_ever_live_p(reg)
++                      && (!call_used_regs[reg] || interrupt_func_p)))
++              {
++                      offset += 2;
++              }
++      }
++
++      return offset;
++}
++
++int msp430_empty_epilogue (void)
++{
++      int cfp = msp430_critical_function_p (current_function_decl);
++      int ree = msp430_reentrant_function_p (current_function_decl);
++      int nfp = msp430_naked_function_p (current_function_decl);
++      int ifp = interrupt_function_p (current_function_decl);
++      int wup = wakeup_function_p (current_function_decl);
++      int size = msp430_saved_regs_frame ();
++      int fs = get_frame_size ();
++
++      if (cfp && ree)
++              ree = 0;
++
++      /* the following combination of attributes forces to issue
++      some commands in function epilogue */
++      if (ree
++              || nfp || fs || wup || MAIN_NAME_P (DECL_NAME (current_function_decl)))
++              return 0;
++
++      size += fs;
++
++      /* <= 2 necessary for first call */
++      if (size <= 2 && cfp)
++              return 2;
++      if (size == 0 && !cfp && !ifp)
++              return 1;
++      if (size == 0 && ifp)
++              return 2;
++
++      return 0;
++}
++
++/* cfp minds the fact that the function may save r2 */
++int initial_elimination_offset (int from, int to)
++{
++      int outgoingArgsSize = 0;
++      if((ACCUMULATE_OUTGOING_ARGS) && (!cfun->machine->is_leaf || cfun->calls_alloca) && crtl->outgoing_args_size)
++              outgoingArgsSize = crtl->outgoing_args_size;
++
++      /*
++              'Reloading' is mapping pseudo-registers into hardware registers and stack slots.
++              More information here: http://gcc.gnu.org/onlinedocs/gccint/RTL-passes.html
++              
++              Apparently the leaf_function_p() can erroneously return 1 if called after the reload has 
++              completed. To handle this, we use the AVR port behavior, caching the is_leaf flag before
++              reload and using it from cache afterwards.
++      */
++
++      if (!reload_completed)
++              cfun->machine->is_leaf = leaf_function_p();
++
++      int reg;
++      if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
++              return outgoingArgsSize;
++      else if (from == ARG_POINTER_REGNUM)
++      {
++              int interrupt_func_p = interrupt_function_p (current_function_decl);
++              int cfp = msp430_critical_function_p (current_function_decl);
++              int offset = interrupt_func_p ? 0 : (cfp ? 2 : 0);
++              
++              gcc_assert((to == FRAME_POINTER_REGNUM) || (to == STACK_POINTER_REGNUM));
++
++              for (reg = 4; reg < 16; ++reg)
++              {
++                      if ((!cfun->machine->is_leaf && call_used_regs[reg] && (interrupt_func_p))
++                              || (df_regs_ever_live_p(reg)
++                              && (!call_used_regs[reg] || interrupt_func_p)))
++                      {
++                              offset += 2;
++                      }
++              }
++              if (to == FRAME_POINTER_REGNUM)
++                      return get_frame_size () + offset + 2;
++              else
++                      return get_frame_size () + offset + 2 + outgoingArgsSize;
++      }
++      gcc_unreachable();
++}
+diff -urNad msp430-gcc~/gcc/config/msp430/msp430-predicates.inl msp430-gcc/gcc/config/msp430/msp430-predicates.inl
+--- msp430-gcc~/gcc/config/msp430/msp430-predicates.inl        1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/msp430-predicates.inl 2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1,52 @@
++#pragma once
++
++static inline int msp430_attribute_exists(tree func, const char *attr_name)
++{
++      gcc_assert(TREE_CODE (func) == FUNCTION_DECL);
++      return lookup_attribute (attr_name, DECL_ATTRIBUTES (func)) != NULL_TREE;
++}
++
++static inline int msp430_naked_function_p(tree func)
++{
++      return msp430_attribute_exists(func, "naked");
++}
++
++static inline int msp430_task_function_p (tree func)
++{
++      return msp430_attribute_exists(func, "task");
++}
++
++static inline int msp430_save_prologue_function_p (tree func)
++{
++      return msp430_attribute_exists(func, "saveprologue");
++}
++
++static inline int interrupt_function_p (tree func)
++{
++      return msp430_attribute_exists(func, "interrupt");
++}
++
++static inline int msp430_critical_function_p (tree func)
++{
++      return msp430_attribute_exists(func, "critical");
++}
++
++static inline int msp430_reentrant_function_p (tree func)
++{
++      return msp430_attribute_exists(func, "reentrant");
++}
++
++static inline int noint_hwmul_function_p (tree func)
++{
++      return msp430_attribute_exists(func, "noint_hwmul");
++}
++
++static inline int signal_function_p (tree func)
++{
++      return msp430_attribute_exists(func, "signal");
++}
++
++static inline int wakeup_function_p (tree func)
++{
++      return msp430_attribute_exists(func, "wakeup");
++}
+diff -urNad msp430-gcc~/gcc/config/msp430/msp430-protos.h msp430-gcc/gcc/config/msp430/msp430-protos.h
+--- msp430-gcc~/gcc/config/msp430/msp430-protos.h      1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/msp430-protos.h       2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1,293 @@
++/* Prototypes for exported functions defined in msp430.c
++   
++   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
++   Contributed by Dmitry Diky <diwil@mail.ru>
++
++   This file is part of GNU CC.
++
++   GNU CC is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 2, or (at your option)
++   any later version.
++
++   GNU CC is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with GNU CC; see the file COPYING.  If not, write to
++   the Free Software Foundation, 59 Temple Place - Suite 330,
++   Boston, MA 02111-1307, USA.  */
++
++
++extern void   bootloader_section PARAMS ((void));
++extern void   infomem_section PARAMS ((void));
++
++extern void   asm_file_start            PARAMS ((FILE *file));
++extern void   asm_file_end              PARAMS ((FILE *file));
++extern void   msp430_init_once          PARAMS ((void));
++extern void   msp430_override_options   PARAMS ((void));
++/*extern void   function_prologue         PARAMS ((FILE *file, int size));
++extern void   function_epilogue         PARAMS ((FILE *file, int size));*/
++extern void   gas_output_limited_string PARAMS ((FILE *file, const char *str));
++extern void   gas_output_ascii          PARAMS ((FILE *file, const char *str,
++                                                       size_t length));
++extern void   order_regs_for_local_alloc PARAMS ((void));
++extern void msp430_trampoline_template PARAMS ((FILE *fd));
++
++
++extern int frame_pointer_required_p PARAMS ((void));
++extern int msp430_empty_epilogue PARAMS ((void));
++
++int msp430_regno_ok_for_base_p PARAMS ((int));
++
++
++#ifdef HAVE_MACHINE_MODES
++extern int    msp430_hard_regno_mode_ok PARAMS ((int regno,
++                                           enum machine_mode mode));
++#endif
++
++extern int initial_elimination_offset PARAMS ((int, int));
++
++
++
++#ifdef TREE_CODE
++extern void   asm_output_external          PARAMS ((FILE *file, tree decl,
++                                                 char *name));
++extern void   unique_section               PARAMS ((tree decl, int reloc));
++extern void   encode_section_info          PARAMS ((tree decl));
++extern void   asm_output_section_name      PARAMS ((FILE *file, tree decl,
++                                                 const char *name,
++                                                 int reloc));
++extern int    valid_machine_type_attribute PARAMS ((tree type, tree attributes,
++                                                 tree identifier,
++                                                 tree args));
++extern int    valid_machine_decl_attribute PARAMS ((tree decl, tree attributes,
++                                                 tree attr, tree args));
++extern void asm_declare_function_name PARAMS ((FILE *, const char *, tree));
++unsigned int msp430_section_type_flags PARAMS (( tree DECL, const char *NAME, int RELOC));
++
++
++#ifdef RTX_CODE /* inside TREE_CODE */
++extern rtx    msp430_function_value          PARAMS ((tree type, tree func));
++extern void   init_cumulative_args           PARAMS ((CUMULATIVE_ARGS *cum,
++                                                 tree fntype, rtx libname,
++                                                 int indirect));
++extern rtx    function_arg         PARAMS ((CUMULATIVE_ARGS *cum,
++                                         enum machine_mode mode,
++                                         tree type, int named));
++extern void   init_cumulative_incoming_args           PARAMS ((CUMULATIVE_ARGS *cum,
++                                                 tree fntype, rtx libname));
++extern rtx    function_incoming_arg         PARAMS ((CUMULATIVE_ARGS *cum,
++                                         enum machine_mode mode,
++                                         tree type, int named));
++
++
++
++#endif /* RTX_CODE inside TREE_CODE */
++
++#ifdef HAVE_MACHINE_MODES /* inside TREE_CODE */
++extern void   function_arg_advance PARAMS ((CUMULATIVE_ARGS *cum,
++                                         enum machine_mode mode, tree type,
++                                         int named));
++#endif /* HAVE_MACHINE_MODES inside TREE_CODE*/
++#endif /* TREE_CODE */
++
++#ifdef RTX_CODE
++
++
++extern enum rtx_code msp430_canonicalize_comparison PARAMS ((enum rtx_code,rtx *,rtx *));
++
++
++extern void msp430_emit_cbranch PARAMS ((enum rtx_code, rtx));
++extern void msp430_emit_cset PARAMS ((enum rtx_code, rtx));
++
++extern int dead_or_set_in_peep PARAMS ((int, rtx, rtx));
++extern void msp430_initialize_trampoline PARAMS ((rtx,rtx,rtx));   
++
++
++extern enum reg_class msp430_reg_class_from_letter PARAMS ((int));
++extern enum reg_class preferred_reload_class PARAMS ((rtx,enum reg_class));
++enum reg_class msp430_regno_reg_class PARAMS ((int));
++
++extern RTX_CODE followed_compare_condition PARAMS ((rtx));
++
++extern const char * msp430_movesi_code PARAMS ((rtx insn, rtx operands[], int *l));
++extern const char * msp430_movedi_code PARAMS ((rtx insn, rtx operands[], int *l));
++extern const char * msp430_addsi_code PARAMS ((rtx insn, rtx operands[], int *l));
++extern const char * msp430_subsi_code PARAMS ((rtx insn, rtx operands[], int *l));
++extern const char * msp430_andsi_code PARAMS ((rtx insn, rtx operands[], int *l));
++extern const char * msp430_iorsi_code PARAMS ((rtx insn, rtx operands[], int *l));
++extern const char * msp430_xorsi_code PARAMS ((rtx insn, rtx operands[], int *l));
++extern const char * msp430_adddi_code PARAMS ((rtx insn, rtx operands[], int *l));
++extern const char * msp430_subdi_code PARAMS ((rtx insn, rtx operands[], int *l));
++extern const char * msp430_anddi_code PARAMS ((rtx insn, rtx operands[], int *l));
++extern const char * msp430_iordi_code PARAMS ((rtx insn, rtx operands[], int *l));
++extern const char * msp430_xordi_code PARAMS ((rtx insn, rtx operands[], int *l));
++
++
++extern int zero_shifted PARAMS ((rtx ));
++extern int indexed_location PARAMS ((rtx ));
++
++
++extern int regsi_ok_safe PARAMS ((rtx operands[]));
++extern int regsi_ok_clobber PARAMS ((rtx operands[]));
++extern int regdi_ok_safe PARAMS ((rtx operands[]));
++extern int regdi_ok_clobber PARAMS ((rtx operands[]));
++extern int sameoperand PARAMS ((rtx operands[], int));
++
++extern int general_operand_msp430 PARAMS ((rtx, enum machine_mode )); 
++extern int nonimmediate_operand_msp430 PARAMS ((rtx, enum machine_mode ));
++extern int memory_operand_msp430 PARAMS ((rtx, enum machine_mode ));
++extern int halfnibble_constant PARAMS ((rtx, enum machine_mode ));
++extern int halfnibble_integer PARAMS ((rtx, enum machine_mode ));
++extern int halfnibble_constant_shift PARAMS ((rtx, enum machine_mode ));
++extern int halfnibble_integer_shift PARAMS ((rtx, enum machine_mode ));
++extern int which_nibble PARAMS ((int));
++extern int which_nibble_shift PARAMS ((int));
++
++
++extern void   asm_output_external_libcall PARAMS ((FILE *file, rtx symref));
++extern int    legitimate_address_p    PARAMS ((enum machine_mode mode, rtx x,
++                                      int strict));
++extern int    compare_diff_p  PARAMS ((rtx insn));
++
++extern int    emit_indexed_arith PARAMS ((rtx insn, rtx operands[], int, const char *, int));
++
++extern const char * msp430_emit_abssi    PARAMS ((rtx insn, rtx operands[], int *l));
++extern const char * msp430_emit_absdi    PARAMS ((rtx insn, rtx operands[], int *l));
++
++extern const char * msp430_emit_indexed_add2 PARAMS ((rtx insn, rtx op[], int *l));
++extern const char * msp430_emit_indexed_add4 PARAMS ((rtx insn, rtx op[], int *l));
++
++extern const char * msp430_emit_indexed_sub2 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_indexed_sub4 PARAMS ((rtx insn, rtx operands[], int *len));
++
++extern const char * msp430_emit_indexed_and2 PARAMS ((rtx insn, rtx op[], int *l));
++extern const char * msp430_emit_indexed_and4 PARAMS ((rtx insn, rtx op[], int *l));
++extern const char * msp430_emit_immediate_and2 PARAMS ((rtx insn, rtx op[], int *l));
++extern const char * msp430_emit_immediate_and4 PARAMS ((rtx insn, rtx op[], int *l));
++
++extern const char * msp430_emit_indexed_ior2 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_indexed_ior4 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_immediate_ior2 PARAMS ((rtx insn, rtx op[], int *l));
++extern const char * msp430_emit_immediate_ior4 PARAMS ((rtx insn, rtx op[], int *l));
++
++
++extern int msp430_emit_indexed_mov PARAMS ((rtx insn, rtx operands[], int len, const char *));       
++extern const char * movstrsi_insn PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * clrstrsi_insn PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * movstrhi_insn PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * clrstrhi_insn PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_indexed_mov2 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_indexed_mov4 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * movsisf_regmode PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * movdidf_regmode PARAMS ((rtx insn, rtx operands[], int *len));
++
++
++extern int is_shift_better_in_reg PARAMS ((rtx operands[]));
++extern int msp430_emit_shift_cnt PARAMS ((int (*funct)(rtx, int, int), const char *, rtx insn, rtx operands[], int *len, int));
++extern const char * msp430_emit_ashlqi3 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_ashlhi3 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_ashlsi3 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_ashldi3 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_ashrqi3 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_ashrhi3 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_ashrsi3 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_ashrdi3 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_lshrqi3 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_lshrhi3 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_lshrsi3 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_lshrdi3 PARAMS ((rtx insn, rtx operands[], int *len));
++
++extern const char * signextendqihi PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * signextendqisi PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * signextendqidi PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * signextendhisi PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * signextendhidi PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * signextendsidi PARAMS ((rtx insn, rtx operands[], int *len));
++
++extern const char * msp430_emit_indexed_sub2 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_indexed_sub4 PARAMS ((rtx insn, rtx operands[], int *len));
++
++extern const char * msp430_emit_indexed_xor2 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_indexed_xor4 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_indexed_xor2_3 PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_indexed_xor4_3 PARAMS ((rtx insn, rtx operands[], int *len));
++
++extern const char * zeroextendqihi PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * zeroextendqisi PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * zeroextendqidi PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * zeroextendhisi PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * zeroextendhidi PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * zeroextendsidi PARAMS ((rtx insn, rtx operands[], int *len));
++
++extern const char * msp430_pushsisf PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_pushdi   PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_pushhi   PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_pushqi   PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char * msp430_emit_call (rtx operands[]);
++
++extern const char * msp430_emit_return PARAMS ((rtx insn, rtx operands[], int *len));
++extern const char *msp430_cbranch PARAMS ((rtx insn, rtx operands[], int *len, int is_cc0_branch));
++extern const char *msp430_cset PARAMS ((rtx insn, rtx operands[], int *len));
++
++extern void   notice_update_cc       PARAMS ((rtx body, rtx insn));
++extern int    msp430_peep2_scratch_safe PARAMS ((rtx reg_rtx));
++extern int    test_hard_reg_class    PARAMS ((enum reg_class class, rtx x));
++extern void   machine_dependent_reorg PARAMS ((rtx first_insn));
++extern void msp430_output_addr_vec_elt PARAMS ((FILE *stream, int value));
++extern void   final_prescan_insn     PARAMS ((rtx insn, rtx *operand,
++                                                      int num_operands));
++extern int    adjust_insn_length     PARAMS ((rtx insn, int len));
++
++
++extern int    msp430_address_cost    PARAMS ((rtx x));
++extern int    extra_constraint       PARAMS ((rtx x, int c));
++extern rtx    legitimize_address     PARAMS ((rtx x, rtx oldx,
++                                           enum machine_mode mode));
++extern rtx    msp430_libcall_value   PARAMS ((enum machine_mode mode));
++extern int    default_rtx_costs      PARAMS ((rtx X, RTX_CODE code,
++                                           RTX_CODE outer_code));
++extern void   asm_output_char        PARAMS ((FILE *file, rtx value));
++extern void   asm_output_short       PARAMS ((FILE *file, rtx value));
++extern void   asm_output_byte        PARAMS ((FILE *file, int value));
++
++extern void   print_operand          PARAMS ((FILE *file, rtx x, int code));
++extern void   print_operand_address  PARAMS ((FILE *file, rtx addr));
++extern int    reg_unused_after       PARAMS ((rtx insn, rtx reg));
++extern int    msp430_jump_dist       PARAMS ((rtx x, rtx insn));
++extern int    call_insn_operand      PARAMS ((rtx op, enum machine_mode mode));
++extern int    msp430_branch_mode     PARAMS ((rtx x, rtx insn));
++
++extern int    msp430_easy_mul PARAMS ((rtx [],int));
++extern int    msp430_mul3_guard       PARAMS ((rtx [], int ));
++extern int      msp430_umul3_guard       PARAMS ((rtx [], int ));
++extern int    msp430_mulhisi_guard PARAMS ((rtx [] ));
++extern int    msp430_umulhisi_guard   PARAMS ((rtx [] ));
++extern int    msp430_ashlhi3          PARAMS ((rtx [] ));
++extern int      msp430_ashlsi3          PARAMS ((rtx [] ));
++extern int      msp430_ashrhi3          PARAMS ((rtx [] ));
++extern int      msp430_ashrsi3          PARAMS ((rtx [] ));
++extern int      msp430_lshrhi3          PARAMS ((rtx [] ));
++extern int      msp430_lshrsi3          PARAMS ((rtx [] ));
++
++extern void expand_prologue (void);
++extern void expand_epilogue (void);
++extern int msp430_epilogue_uses (int regno);
++
++#endif /* RTX_CODE */
++
++#ifdef HAVE_MACHINE_MODES
++extern int    class_max_nregs        PARAMS ((enum reg_class class,
++                                           enum machine_mode mode));
++#endif /* HAVE_MACHINE_MODES */
++
++#ifdef REAL_VALUE_TYPE
++
++extern void   asm_output_float       PARAMS ((FILE *file, REAL_VALUE_TYPE n));
++
++#endif
++
++
+diff -urNad msp430-gcc~/gcc/config/msp430/msp430.c msp430-gcc/gcc/config/msp430/msp430.c
+--- msp430-gcc~/gcc/config/msp430/msp430.c     1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/msp430.c      2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1,8514 @@
++/* This work is partially financed by the European Commission under the
++* Framework 6 Information Society Technologies Project
++* "Wirelessly Accessible Sensor Populations (WASP)".
++*/
++
++/*
++      GCC 4.x port by Ivan Shcherbakov <mspgcc@sysprogs.org>
++*/
++
++/* Subroutines for insn-output.c for Texas Instruments MSP430 MCU
++Copyright (C) 2001, 2002 Free Software Foundation, Inc.
++Contributed by Dmitry Diky <diwil@mail.ru>
++
++This file is part of GNU CC. 
++GNU CC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 2, or (at your option)
++any later version.
++
++GNU CC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GNU CC; see the file COPYING.  If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA.  */
++
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++#include "rtl.h"
++#include "regs.h"
++#include "hard-reg-set.h"
++#include "real.h"
++#include "insn-config.h"
++#include "conditions.h"
++#include "insn-attr.h"
++#include "flags.h"
++#include "reload.h"
++#include "tree.h"
++#include "output.h"
++#include "expr.h"
++#include "toplev.h"
++#include "obstack.h"
++#include "function.h"
++#include "recog.h"
++#include "tm_p.h"
++#include "target.h"
++#include "target-def.h"
++#include "insn-codes.h"
++#include "ggc.h"
++#include "langhooks.h"
++#include "msp430-predicates.inl"
++
++#define TARGET_REORDER 0
++
++#if GCC_VERSION_INT < 0x430
++static inline int df_regs_ever_live_p(int reg)
++{
++      return regs_ever_live[reg];
++}
++
++#endif
++
++
++/* Commands count in the compiled file */
++int msp430_commands_in_file;
++
++/* Commands in the functions prologues in the compiled file */
++int msp430_commands_in_prologues;
++
++/* Commands in the functions epilogues in the compiled file */
++int msp430_commands_in_epilogues;
++
++/* the size of the stack space freed during mdr pass */
++
++/* push helper */
++int self_push(rtx);
++
++int msp430_case_values_threshold = 30000;
++int msp430_has_hwmul = 0;
++
++enum msp430_arch
++{
++      MSP430_ISA_1 = 1,
++      MSP430_ISA_2 = 2,
++      MSP430_ISA_110 = 110,
++      MSP430_ISA_11 = 11,
++      MSP430_ISA_12 = 12,
++      MSP430_ISA_13 = 13,
++      MSP430_ISA_14 = 14,
++      MSP430_ISA_15 = 15,
++      MSP430_ISA_16 = 16,
++      MSP430_ISA_20 = 20,
++      MSP430_ISA_21 = 21,
++      MSP430_ISA_22 = 22,
++      MSP430_ISA_23 = 23,
++      MSP430_ISA_24 = 24,
++      MSP430_ISA_241 = 241,
++      MSP430_ISA_26 = 26,
++      MSP430_ISA_31 = 31,
++      MSP430_ISA_32 = 32,
++      MSP430_ISA_33 = 33,
++      MSP430_ISA_41 = 41,
++      MSP430_ISA_42 = 42,
++      MSP430_ISA_43 = 43,
++      MSP430_ISA_44 = 44,
++      MSP430_ISA_46 = 46,
++      MSP430_ISA_47 = 47,
++      MSP430_ISA_471 = 471,
++      MSP430_ISA_54 = 54,
++};
++
++struct mcu_type_s
++{
++      const char *name;
++      enum msp430_arch arch;
++      int has_hwmul;
++};
++
++static struct mcu_type_s msp430_mcu_types[] = {
++      /* generic types */
++      {"msp1",         MSP430_ISA_1, 0},
++      {"msp2",         MSP430_ISA_2, 1},
++
++      /* F1xx family */
++      {"msp430x110",   MSP430_ISA_11, 0},
++      {"msp430x112",   MSP430_ISA_11, 0},
++
++      {"msp430x1101",  MSP430_ISA_110, 0},
++      {"msp430x1111",  MSP430_ISA_110, 0},
++      {"msp430x1121",  MSP430_ISA_110, 0},
++      {"msp430x1122",  MSP430_ISA_110, 0},
++      {"msp430x1132",  MSP430_ISA_110, 0},
++
++      {"msp430x122",   MSP430_ISA_12, 0},
++      {"msp430x123",   MSP430_ISA_12, 0},
++      {"msp430x1222",  MSP430_ISA_12, 0},
++      {"msp430x1232",  MSP430_ISA_12, 0},
++
++      {"msp430x133",   MSP430_ISA_13, 0},
++      {"msp430x135",   MSP430_ISA_13, 0},
++      {"msp430x1331",  MSP430_ISA_13, 0},
++      {"msp430x1351",  MSP430_ISA_13, 0},
++
++      {"msp430x147",   MSP430_ISA_14, 1},
++      {"msp430x148",   MSP430_ISA_14, 1},
++      {"msp430x149",   MSP430_ISA_14, 1},
++      {"msp430x1471",  MSP430_ISA_14, 1},
++      {"msp430x1481",  MSP430_ISA_14, 1},
++      {"msp430x1491",  MSP430_ISA_14, 1},
++
++      {"msp430x155",   MSP430_ISA_15, 0},
++      {"msp430x156",   MSP430_ISA_15, 0},
++      {"msp430x157",   MSP430_ISA_15, 0},
++
++      {"msp430x167",   MSP430_ISA_16, 1},
++      {"msp430x168",   MSP430_ISA_16, 1},
++      {"msp430x169",   MSP430_ISA_16, 1},
++      {"msp430x1610",  MSP430_ISA_16, 1},
++      {"msp430x1611",  MSP430_ISA_16, 1},
++      {"msp430x1612",  MSP430_ISA_16, 1},
++
++      /* F2xx family */
++      {"msp430x2001",  MSP430_ISA_20, 0},
++      {"msp430x2011",  MSP430_ISA_20, 0},
++
++      {"msp430x2002",  MSP430_ISA_20, 0},
++      {"msp430x2012",  MSP430_ISA_20, 0},
++
++      {"msp430x2003",  MSP430_ISA_20, 0},
++      {"msp430x2013",  MSP430_ISA_20, 0},
++
++      {"msp430x2101",  MSP430_ISA_21, 0},
++      {"msp430x2111",  MSP430_ISA_21, 0},
++      {"msp430x2121",  MSP430_ISA_21, 0},
++      {"msp430x2131",  MSP430_ISA_21, 0},
++
++      {"msp430x2112",  MSP430_ISA_22, 0},
++      {"msp430x2122",  MSP430_ISA_22, 0},
++      {"msp430x2132",  MSP430_ISA_22, 0},
++
++      {"msp430x2232",  MSP430_ISA_22, 0},
++      {"msp430x2252",  MSP430_ISA_22, 0},
++      {"msp430x2272",  MSP430_ISA_22, 0},
++
++      {"msp430x2234",  MSP430_ISA_22, 0},
++      {"msp430x2254",  MSP430_ISA_22, 0},
++      {"msp430x2274",  MSP430_ISA_22, 0},
++
++      {"msp430x233",   MSP430_ISA_23, 1},
++      {"msp430x235",   MSP430_ISA_23, 1},
++
++      {"msp430x2330",  MSP430_ISA_23, 1},
++      {"msp430x2350",  MSP430_ISA_23, 1},
++      {"msp430x2370",  MSP430_ISA_23, 1},
++
++      {"msp430x247",   MSP430_ISA_24, 1},
++      {"msp430x248",   MSP430_ISA_24, 1},
++      {"msp430x249",   MSP430_ISA_24, 1},
++      {"msp430x2410",  MSP430_ISA_24, 1},
++      {"msp430x2471",  MSP430_ISA_24, 1},
++      {"msp430x2481",  MSP430_ISA_24, 1},
++      {"msp430x2491",  MSP430_ISA_24, 1},
++
++      {"msp430x2416",  MSP430_ISA_241, 1},
++      {"msp430x2417",  MSP430_ISA_241, 1},
++      {"msp430x2418",  MSP430_ISA_241, 1},
++      {"msp430x2419",  MSP430_ISA_241, 1},
++
++      {"msp430x2616",  MSP430_ISA_26, 1},
++      {"msp430x2617",  MSP430_ISA_26, 1},
++      {"msp430x2618",  MSP430_ISA_26, 1},
++      {"msp430x2619",  MSP430_ISA_26, 1},
++
++      /* 3xx family (ROM) */
++      {"msp430x311",   MSP430_ISA_31, 0},
++      {"msp430x312",   MSP430_ISA_31, 0},
++      {"msp430x313",   MSP430_ISA_31, 0},
++      {"msp430x314",   MSP430_ISA_31, 0},
++      {"msp430x315",   MSP430_ISA_31, 0},
++
++      {"msp430x323",   MSP430_ISA_32, 0},
++      {"msp430x325",   MSP430_ISA_32, 0},
++
++      {"msp430x336",   MSP430_ISA_33, 1},
++      {"msp430x337",   MSP430_ISA_33, 1},
++
++      /* F4xx family */
++      {"msp430x412",   MSP430_ISA_41, 0},
++      {"msp430x413",   MSP430_ISA_41, 0},
++      {"msp430x415",   MSP430_ISA_41, 0},
++      {"msp430x417",   MSP430_ISA_41, 0},
++
++      {"msp430x423",   MSP430_ISA_42, 1},
++      {"msp430x425",   MSP430_ISA_42, 1},
++      {"msp430x427",   MSP430_ISA_42, 1},
++
++      {"msp430x4250",  MSP430_ISA_42, 0},
++      {"msp430x4260",  MSP430_ISA_42, 0},
++      {"msp430x4270",  MSP430_ISA_42, 0},
++
++      {"msp430xG4250", MSP430_ISA_42, 0},
++      {"msp430xG4260", MSP430_ISA_42, 0},
++      {"msp430xG4270", MSP430_ISA_42, 0},
++
++      {"msp430xE423",  MSP430_ISA_42, 1},
++      {"msp430xE425",  MSP430_ISA_42, 1},
++      {"msp430xE427",  MSP430_ISA_42, 1},
++
++      {"msp430xE4232", MSP430_ISA_42, 1},
++      {"msp430xE4242", MSP430_ISA_42, 1},
++      {"msp430xE4252", MSP430_ISA_42, 1},
++      {"msp430xE4272", MSP430_ISA_42, 1},
++
++      {"msp430xW423",  MSP430_ISA_42, 0},
++      {"msp430xW425",  MSP430_ISA_42, 0},
++      {"msp430xW427",  MSP430_ISA_42, 0},
++
++      {"msp430xG437",  MSP430_ISA_43, 0},
++      {"msp430xG438",  MSP430_ISA_43, 0},
++      {"msp430xG439",  MSP430_ISA_43, 0},
++
++      {"msp430x435",   MSP430_ISA_43, 0},
++      {"msp430x436",   MSP430_ISA_43, 0},
++      {"msp430x437",   MSP430_ISA_43, 0},
++
++      {"msp430x4351",  MSP430_ISA_43, 0},
++      {"msp430x4361",  MSP430_ISA_43, 0},
++      {"msp430x4371",  MSP430_ISA_43, 0},
++
++      {"msp430x447",   MSP430_ISA_44, 1},
++      {"msp430x448",   MSP430_ISA_44, 1},
++      {"msp430x449",   MSP430_ISA_44, 1},
++
++      {"msp430xG4616", MSP430_ISA_46, 1},
++      {"msp430xG4617", MSP430_ISA_46, 1},
++      {"msp430xG4618", MSP430_ISA_46, 1},
++      {"msp430xG4619", MSP430_ISA_46, 1},
++
++      {"msp430x4783",  MSP430_ISA_47, 1},
++      {"msp430x4784",  MSP430_ISA_47, 1},
++      {"msp430x4793",  MSP430_ISA_47, 1},
++      {"msp430x4794",  MSP430_ISA_47, 1},
++        
++      {"msp430x47166", MSP430_ISA_471, 1},
++      {"msp430x47176", MSP430_ISA_471, 1},
++      {"msp430x47186", MSP430_ISA_471, 1},
++      {"msp430x47196", MSP430_ISA_471, 1},
++
++      {"msp430x47167", MSP430_ISA_471, 1},
++      {"msp430x47177", MSP430_ISA_471, 1},
++      {"msp430x47187", MSP430_ISA_471, 1},
++      {"msp430x47197", MSP430_ISA_471, 1},
++
++      /* F5xxx family */
++      {"msp430x5418",  MSP430_ISA_54, 1},
++      {"msp430x5419",  MSP430_ISA_54, 1},
++      {"msp430x5435",  MSP430_ISA_54, 1},
++      {"msp430x5436",  MSP430_ISA_54, 1},
++      {"msp430x5437",  MSP430_ISA_54, 1},
++      {"msp430x5438",  MSP430_ISA_54, 1},
++
++      /* CC430 family */
++      {"cc430x5123",   MSP430_ISA_54, 1},
++      {"cc430x5125",   MSP430_ISA_54, 1},
++      {"cc430x6125",   MSP430_ISA_54, 1},
++      {"cc430x6135",   MSP430_ISA_54, 1},
++      {"cc430x6126",   MSP430_ISA_54, 1},
++      {"cc430x5137",   MSP430_ISA_54, 1},
++      {"cc430x6127",   MSP430_ISA_54, 1},
++      {"cc430x6137",   MSP430_ISA_54, 1},
++
++      {NULL, 0, 0}
++};
++
++static void msp430_globalize_label (FILE *, const char *);
++static void msp430_file_start (void);
++static void msp430_file_end (void);
++static bool msp430_function_ok_for_sibcall PARAMS((tree, tree));
++static bool msp430_rtx_costs (rtx, int, int, int *);
++int msp430_address_costs (rtx);
++
++/* Defined in msp430-builtins.c */
++void msp430_init_builtins (void);
++rtx msp430_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
++
++/* Defined in msp430-function.c */
++void msp430_function_end_prologue (FILE * file);
++void msp430_function_begin_epilogue (FILE * file);
++
++static struct machine_function *msp430_init_machine_status (void)
++{
++      return ((struct machine_function *) ggc_alloc_cleared (sizeof (struct machine_function)));
++}
++
++
++const struct attribute_spec msp430_attribute_table[];
++static tree msp430_handle_fndecl_attribute
++PARAMS ((tree *, tree, tree, int, bool *));
++
++/* Initialize the GCC target structure.  */
++#undef TARGET_ASM_ALIGNED_HI_OP
++#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
++
++#undef TARGET_ASM_FILE_START
++#define TARGET_ASM_FILE_START msp430_file_start
++#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
++#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
++#undef TARGET_ASM_FILE_END
++#define TARGET_ASM_FILE_END msp430_file_end
++
++/* Hardcoded prologue/epilogue was replaced by flexible expand_prologue()/expand_epilogue() */
++/*#undef      TARGET_ASM_FUNCTION_PROLOGUE
++#define TARGET_ASM_FUNCTION_PROLOGUE msp430_function_prologue
++#undef        TARGET_ASM_FUNCTION_EPILOGUE
++#define TARGET_ASM_FUNCTION_EPILOGUE msp430_function_epilogue*/
++
++#undef TARGET_ASM_FUNCTION_END_PROLOGUE
++#define TARGET_ASM_FUNCTION_END_PROLOGUE msp430_function_end_prologue
++#undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
++#define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE msp430_function_begin_epilogue
++
++#undef        TARGET_ATTRIBUTE_TABLE
++#define TARGET_ATTRIBUTE_TABLE msp430_attribute_table
++#undef        TARGET_SECTION_TYPE_FLAGS
++#define TARGET_SECTION_TYPE_FLAGS msp430_section_type_flags
++#undef        TARGET_RTX_COSTS
++#define TARGET_RTX_COSTS msp430_rtx_costs
++#undef        TARGET_ADDRESS_COST
++#define       TARGET_ADDRESS_COST msp430_address_costs
++#undef  TARGET_FUNCTION_OK_FOR_SIBCALL
++#define TARGET_FUNCTION_OK_FOR_SIBCALL msp430_function_ok_for_sibcall
++#undef  TARGET_ASM_GLOBALIZE_LABEL
++#define TARGET_ASM_GLOBALIZE_LABEL msp430_globalize_label
++#undef  TARGET_INIT_BUILTINS
++#define TARGET_INIT_BUILTINS msp430_init_builtins
++#undef  TARGET_EXPAND_BUILTIN
++#define TARGET_EXPAND_BUILTIN msp430_expand_builtin
++#undef TARGET_INIT_LIBFUNCS
++#define TARGET_INIT_LIBFUNCS msp430_init_once
++
++struct gcc_target targetm = TARGET_INITIALIZER;
++
++/****** ATTRIBUTES TO FUNCTION *************************************/
++const struct attribute_spec msp430_attribute_table[] = {
++      /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
++      {"reserve", 1, 1, false, false, false, msp430_handle_fndecl_attribute},
++      {"signal", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
++      {"interrupt", 1, 1, true, false, false, msp430_handle_fndecl_attribute},
++      {"naked", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
++      {"task", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
++      {"wakeup", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
++      {"critical", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
++      {"reentrant", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
++      {"saveprologue", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
++      {"noint_hwmul", 0, 0, true, false, false, msp430_handle_fndecl_attribute},
++      {NULL, 0, 0, false, false, false, NULL}
++};
++
++int msp430_current_function_noint_hwmul_function_p (void)
++{
++      int rval;
++      if (!current_function_decl)
++              return (TARGET_NOINT_HWMUL);
++      rval = noint_hwmul_function_p (current_function_decl);
++
++      return (TARGET_NOINT_HWMUL || rval);
++}
++
++unsigned int
++msp430_section_type_flags (tree decl, const char *name, int reloc)
++
++{
++      unsigned int flags = 0;
++
++      if (!strcmp (name, ".infomemnobits") || !strcmp (name, ".noinit"))
++              flags = SECTION_BSS;
++
++      flags |= default_section_type_flags (decl, name, reloc);
++      return flags;
++}
++
++/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
++struct attribute_spec.handler.  */
++static tree
++msp430_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
++{
++      if (TREE_CODE (*node) != FUNCTION_DECL)
++      {
++              warning (OPT_Wattributes, "%s' attribute only applies to functions.",
++                      IDENTIFIER_POINTER (name));
++              *no_add_attrs = true;
++      }
++      return NULL_TREE;
++}
++
++enum msp430_arch msp430_get_arch (void);
++
++enum msp430_arch
++msp430_get_arch (void)
++{
++      const struct mcu_type_s *t;
++
++      for (t = msp430_mcu_types; t->name; t++)
++      {
++              if (strcmp (t->name, msp430_mcu_name) == 0)
++                      break;
++      }
++
++      if (!t->name)
++      {
++              error ("MCU %s not supported", msp430_mcu_name);
++              fprintf (stderr, "Known MCU names:\n");
++              for (t = msp430_mcu_types; t->name; t++)
++                      fprintf (stderr, "   %s\n", t->name);
++              abort ();
++              return -1;
++      }
++      return t->arch;
++}
++
++void
++msp430_override_options (void)
++{
++      const struct mcu_type_s *t;
++
++      for (t = msp430_mcu_types; t->name; t++)
++      {
++              if (strcmp (t->name, msp430_mcu_name) == 0)
++                      break;
++      }
++
++      if (!t->name)
++      {
++              error ("MCU %s not supported", msp430_mcu_name);
++              fprintf (stderr, "Known MCU names:\n");
++              for (t = msp430_mcu_types; t->name; t++)
++                      fprintf (stderr, "   %s\n", t->name);
++              abort ();
++              return;
++      }
++
++      msp430_has_hwmul = t->has_hwmul || TARGET_FORCE_HWMUL;
++
++      if (TARGET_NO_HWMUL)
++              msp430_has_hwmul = 0;
++
++      msp430_case_values_threshold = 8;       /* ? or there is a better value ? */
++      init_machine_status = msp430_init_machine_status;
++}
++
++rtx mpy_rtx, mpys_rtx, mac_rtx, macs_rtx, op2_rtx, reslo_rtx, reshi_rtx,
++sumext_rtx, ressi_rtx;
++
++
++static char __dummy[1024];
++rtx sym_ref(enum machine_mode mode,  char *arg);
++
++rtx sym_ref(enum machine_mode mode,  char *arg)
++{
++      rtx rt;
++      static int i = 0;
++      rt = (rtx) &__dummy[i];
++      i += sizeof(*rt);
++      memset(rt,0,4);
++      PUT_CODE(rt,SYMBOL_REF);
++      PUT_MODE(rt,mode);
++      XSTR(rt,0) = arg;
++
++      return rt;
++}
++
++
++rtx gen_rtx_HWREG(const char *name);
++
++rtx gen_rtx_HWREG(const char *name)
++{
++      rtx ret = gen_rtx_MEM (HImode, sym_ref (HImode, name));
++      //MEM_VOLATILE_P(ret) = 1;
++      return ret;
++}
++
++void msp430_init_once (void)
++{
++      /******************************
++
++      __MPY=0x130
++      __MPYS=0x132
++      __MAC=0x134
++      __MACS=0x136
++      __OP2=0x138
++      __RESLO=0x13a
++      __RESHI=0x13c
++      __SUMEXT=0x13e
++      __RESSI <- not natural 
++      *****************************/
++
++      mpy_rtx         = gen_rtx_HWREG ("__MPY");
++      mpys_rtx        = gen_rtx_HWREG ("__MPYS");
++      mac_rtx         = gen_rtx_HWREG ("__MAC");
++      macs_rtx        = gen_rtx_HWREG ("__MACS");
++      op2_rtx         = gen_rtx_HWREG ("__OP2");
++      reslo_rtx = gen_rtx_HWREG ("__RESLO");
++      reshi_rtx = gen_rtx_HWREG ("__RESHI");
++      sumext_rtx = gen_rtx_HWREG ("__SUMEXT");
++      ressi_rtx = gen_rtx_HWREG ("__RESLO");
++      return;
++}
++
++static char error_here_if_register_count_invalid[(FIRST_VIRTUAL_REGISTER == 17) ? 1 : -1];
++static int reg_class_tab[FIRST_VIRTUAL_REGISTER] = {
++      PC_REG, STACK_REGS, CG_REGS, CG_REGS,
++      GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, 
++      GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
++      GENERAL_REGS, GENERAL_REGS,     GENERAL_REGS, GENERAL_REGS,     /* r0 - r15 */
++      GENERAL_REGS,   /* regp */
++};
++
++
++int msp430_regno_ok_for_base_p (int r)
++{
++
++      if (r == 2)
++              return 0;
++      if (r == 3)
++              return 0;
++      if (r < FIRST_PSEUDO_REGISTER && r > 0)
++              return 1;
++      if (reg_renumber
++              && reg_renumber[r] < FIRST_PSEUDO_REGISTER
++              && reg_renumber[r] > 0 && reg_renumber[r] != 2 && reg_renumber[r] != 3)
++              return 1;
++
++      return 0;
++
++}
++
++enum reg_class
++msp430_regno_reg_class (int r)
++{
++      if (r < (sizeof(reg_class_tab) / sizeof(reg_class_tab[0])))
++              return reg_class_tab[r];
++
++      return NO_REGS;
++}
++
++
++enum reg_class
++msp430_reg_class_from_letter (
++                                                        int c)
++{
++      switch (c)
++      {
++      case 'd':
++              return SP_REG;
++      default:
++              break;
++      }
++
++      return NO_REGS;
++}
++
++
++
++#define NOVECTOR      0xff
++
++void
++asm_declare_function_name (
++                                                 FILE *file,
++                                                 const char *name,
++                                                 tree decl ATTRIBUTE_UNUSED)
++{
++      int interrupt_func_p;
++      tree ss = 0;
++      int vector = -1;
++      int vectors_start;
++      int cfp = msp430_critical_function_p (current_function_decl);
++      int ree = msp430_reentrant_function_p (current_function_decl);
++
++      interrupt_func_p = interrupt_function_p (current_function_decl);
++
++      if (interrupt_func_p)
++      {
++              /*
++              * .global This_func1
++              * .set vector11, This_func1
++              * .type   This_func1,@function
++              *
++              */
++              switch (msp430_get_arch())
++              {
++              case MSP430_ISA_241:
++              case MSP430_ISA_26:
++              case MSP430_ISA_46:
++                      vectors_start = 0xffc0;
++                      break;
++              case MSP430_ISA_54:
++                      vectors_start = 0xff80;
++                      break;
++              default:
++                      vectors_start = 0xffe0;
++              }
++
++              ss = lookup_attribute ("interrupt",
++                      DECL_ATTRIBUTES (current_function_decl));
++              ss = TREE_VALUE (ss);
++              if (ss)
++              {
++                      ss = TREE_VALUE (ss);
++                      if (ss)
++                              vector = TREE_INT_CST_LOW (ss);
++
++                      if (vector != NOVECTOR)
++                              vector += vectors_start;
++              }
++
++              if (vector == -1)
++              {
++                      warning (OPT_Wattributes, "No valid interrupt vector assigned to ISR `%s'.", name);
++              }
++
++              if ((vector < vectors_start || vector > 0xfffe || (vector & 1))
++                      && (vector != NOVECTOR && vector != -1))
++              {
++                      warning
++                              (0, "Interrupt vector 0x%x assigned to ISR `%s' is invalid.",
++                              vector, name);
++              }
++
++              if (vector != NOVECTOR)
++              {
++                      fprintf (file, ".global vector_%04x\n", vector);
++              }
++              fprintf (file, "%s", TYPE_ASM_OP);
++              assemble_name (file, name);
++              putc (',', file);
++              fprintf (file, TYPE_OPERAND_FMT, "function");
++              putc ('\n', file);
++              fprintf (file, "/***********************\n");
++              fprintf (file, " * Interrupt %sRoutine `",
++                      (vector != NOVECTOR) ? "Service " : "Sub-");
++              assemble_name (file, name);
++              fprintf (file, "' at 0x%04x\n", vector);
++              fprintf (file, " ***********************/\n");
++
++              if (vector != NOVECTOR)
++              {
++                      fprintf (file, "vector_%04x:\n", vector);
++              }
++
++              ASM_OUTPUT_LABEL (file, name);
++      }
++      else
++      {
++              fprintf (file, "%s", TYPE_ASM_OP);
++              assemble_name (file, name);
++              putc (',', file);
++              fprintf (file, TYPE_OPERAND_FMT, "function");
++              putc ('\n', file);
++              fprintf (file, "/***********************\n");
++              fprintf (file, " * Function `");
++              assemble_name (file, name);
++              fprintf (file, "' %s\n ***********************/\n",
++                      cfp ? "(OS critical)" : ree ? "(reentrant)" : "");
++              ASM_OUTPUT_LABEL (file, name);
++      }
++}
++
++
++/* Attempts to replace X with a valid
++memory address for an operand of mode MODE  */
++/* FIXME: broken call */
++rtx
++legitimize_address (x, oldx, mode)
++rtx x;
++rtx oldx ATTRIBUTE_UNUSED;
++enum machine_mode mode ATTRIBUTE_UNUSED;
++{
++      /*    if (GET_CODE (oldx) == MEM
++      && GET_CODE (XEXP(oldx,0)) == PLUS
++      && GET_CODE (XEXP(XEXP(oldx,0),0)) == MEM)
++      {
++      x = force_operand (oldx,0);
++      return x;
++      }
++
++      return oldx;
++      */
++      return x;
++}
++
++int
++legitimate_address_p (mode, operand, strict)
++enum machine_mode mode ATTRIBUTE_UNUSED;
++rtx operand;
++int strict;
++{
++      rtx xfoob, x = operand;
++
++      xfoob = XEXP (operand, 0);
++
++      /* accept @Rn (Rn points to operand address ) */
++      if (GET_CODE (operand) == REG
++              && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
++              : REG_OK_FOR_BASE_NOSTRICT_P (x)))
++              goto granted;
++
++      /* accept address */
++      if (CONSTANT_P (operand))
++              goto granted;
++
++      /* accept X(Rn) Rn + X points to operand address */
++      if (GET_CODE (operand) == PLUS
++              && GET_CODE (XEXP (operand, 0)) == REG
++              && CONSTANT_P (XEXP (operand, 1))
++              && (strict ? (REG_OK_FOR_BASE_STRICT_P (xfoob))
++              : (REG_OK_FOR_BASE_NOSTRICT_P (xfoob))))
++              goto granted;
++
++      if (TARGET_ALL_DEBUG)
++              fprintf (stderr, "Address Failed\n");
++      return 0;
++
++granted:
++      if (TARGET_ALL_DEBUG)
++              fprintf (stderr, "Address granted\n");
++      return 1;
++}
++
++
++void
++print_operand_address (file, addr)
++FILE *file;
++rtx addr;
++{
++      /* hopefully will be never entered. */
++      switch (GET_CODE (addr))
++      {
++      case REG:
++              fprintf (file, "r%d", REGNO (addr));
++              return;
++      case POST_INC:
++              fprintf (file, "@r%d+", REGNO (XEXP(addr,0)));
++              return;
++      case SYMBOL_REF:
++      case LABEL_REF:
++      case CONST:
++              fprintf (file, "#");
++              break;
++      case CODE_LABEL:
++              break;
++      default:
++              abort ();
++              fprintf (file, "&");
++      }
++      output_addr_const (file, addr);
++}
++
++void print_sub_operand PARAMS ((FILE *, rtx, int));
++
++const char *trim_array[] = { "llo", "lhi", "hlo", "hhi" };
++
++
++
++void
++print_sub_operand (file, x, code)
++FILE *file;
++rtx x;
++int code;
++{
++
++      if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
++      {
++              output_addr_const (file, x);
++              return;
++      }
++      else if (GET_CODE (x) == CONST)
++      {
++              print_sub_operand (file, XEXP (x, 0), code);
++              return;
++      }
++      else if (GET_CODE (x) == PLUS)
++      {
++              print_sub_operand (file, XEXP (x, 0), code);
++              fprintf (file, "+");
++              print_sub_operand (file, XEXP (x, 1), code);
++              return;
++      }
++      else if (GET_CODE (x) == CONST_INT)
++      {
++              fprintf (file, "%d", INTVAL (x));
++              return;
++      }
++      else
++              abort ();
++}
++
++void print_operand (FILE *file, rtx x, int code)
++{
++      int shift = 0;
++      int ml = GET_MODE_SIZE (x->mode);
++      int source_reg = 0;
++
++
++      if (ml > 1)
++              ml = 2;
++
++      if (code >= 'A' && code <= 'D')
++              shift = code - 'A';
++
++      if (code >= 'E' && code <= 'H')
++      {
++              shift = code - 'E';
++              source_reg = 1;
++      }
++
++      if (code >= 'I' && code <= 'L')
++      {
++              ml = 1;
++              shift = code - 'I';
++      }
++
++      if (GET_CODE (x) == PLUS)
++      {
++              fprintf (file, "add%s", shift ? "c" : "");
++      }
++      else if (GET_CODE (x) == MINUS)
++      {
++              fprintf (file, "sub%s", shift ? "c" : "");
++      }
++      else if (GET_CODE (x) == AND)
++      {
++              fprintf (file, "and");
++      }
++      else if (GET_CODE (x) == IOR)
++      {
++              fprintf (file, "bis");
++      }
++      else if (GET_CODE (x) == XOR)
++      {
++              fprintf (file, "xor");
++      }
++      else if (REG_P (x))
++      {
++              fprintf (file, reg_names[true_regnum (x) + shift]);
++      }
++      else if (GET_CODE (x) == CONST_INT)
++      {
++              if (code != 'F')
++              {
++                      int intval = INTVAL (x);
++                      if (!shift && !(intval & ~0xFFFF)) /* For improved ASM readability, omit #llo(const) for small constants*/
++                              fprintf (file, "#%d", intval);  
++                      else
++                              fprintf (file, "#%s(%d)", trim_array[shift], intval);
++              }
++              else
++                      fprintf (file, "%d", INTVAL (x));
++      }
++      else if (GET_CODE (x) == MEM)
++      {
++              rtx addr = XEXP (x, 0);
++
++              if (GET_CODE (addr) == POST_INC)
++              {
++                      fprintf (file, "@r%d+", REGNO (XEXP(addr,0)));
++              }
++              else if (GET_CODE (addr) == REG)
++              {                       /* for X(Rn) */
++                      if (shift || !source_reg)
++                      {
++                              if (shift)
++                                      fprintf (file, "%d(r%d)", shift * ml, REGNO (addr));
++                              else
++                                      fprintf (file, "@r%d", REGNO (addr));
++                      }
++                      else if (source_reg)
++                      {
++                              fprintf (file, "r%d", REGNO (addr) + shift);
++                      }
++                      else
++                      {
++                              fprintf (file, "@r%d", REGNO (addr));
++                      }
++              }
++              else if (GET_CODE (addr) == SYMBOL_REF)
++              {
++                      fprintf (file, "&");
++                      output_addr_const (file, addr);
++                      if (shift)
++                              fprintf (file, "+%d", shift * ml);
++              }
++              else if (GET_CODE (addr) == CONST || GET_CODE (addr) == CONST_INT)
++              {
++                      fputc ('&', file);
++                      output_addr_const (file, addr);
++                      if (shift)
++                              fprintf (file, "+%d", shift * ml);
++              }
++              else if (GET_CODE (addr) == PLUS)
++              {
++
++                      print_sub_operand (file, XEXP (addr, 1), code);
++
++                      /* shift if the indirect pointer register is the stack pointer */
++                      if ((code >= 'M' && code <= 'N') && (REGNO (XEXP (addr, 0)) == 1))
++                              shift = code - 'M';
++
++                      if (shift)
++                              fprintf (file, "+%d", shift * ml);
++
++                      if (REG_P (XEXP (addr, 0)))
++                              fprintf (file, "(r%d)", REGNO (XEXP (addr, 0)));
++                      else
++                              abort ();
++              }
++              else if (GET_CODE (addr) == MEM)
++              {
++                      fprintf (file, "@(Invalid addressing mode)");
++                      print_operand (file, addr, code);
++              }
++              else
++              {
++                      fprintf (file, "Unknown operand. Please check.");
++              }
++      }
++      else if (GET_CODE (x) == SYMBOL_REF)
++      {
++              fprintf (file, "#");
++              output_addr_const (file, x);
++              if (shift)
++                      fprintf (file, "+%d", shift * ml);
++      }
++      else if (GET_CODE (x) == CONST_DOUBLE)
++      {
++              if (GET_MODE (x) == VOIDmode)   /* FIXME: may be long long?? */
++              {
++                      if (shift < 2)
++                              fprintf (file, "#%s(%d)", trim_array[shift], CONST_DOUBLE_LOW (x));
++                      else
++                              fprintf (file, "#%s(%d)", trim_array[shift - 2],
++                              CONST_DOUBLE_HIGH (x));
++              }
++              else if (GET_MODE (x) == SFmode || GET_MODE (x) == SImode)
++              {
++                      long val;
++                      REAL_VALUE_TYPE rv;
++                      REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
++                      REAL_VALUE_TO_TARGET_SINGLE (rv, val);
++                      asm_fprintf (file, "#%s(0x%lx)", trim_array[shift], val);
++              }
++              else
++              {
++                      fatal_insn ("Internal compiler bug. Unknown mode:", x);
++              }
++      }
++      else
++              print_operand_address (file, x);
++}
++
++/* mode for branch instruction */
++int
++msp430_jump_dist (rtx x, rtx insn)
++{
++      if(insn_addresses_)
++      {
++              int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
++                      ? XEXP (x, 0) : x));
++              int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
++              int jump_distance = dest_addr - cur_addr;
++
++              return jump_distance;
++      }
++      else
++              return 1024;
++}
++
++
++rtx
++msp430_libcall_value (mode)
++enum machine_mode mode;
++{
++      int offs = GET_MODE_SIZE (mode);
++      offs >>= 1;
++      if (offs < 1)
++              offs = 1;
++      return gen_rtx_REG (mode, (RET_REGISTER + 1 - offs));
++}
++
++rtx
++msp430_function_value (type, func)
++tree type;
++tree func ATTRIBUTE_UNUSED;
++{
++      int offs;
++      if (TYPE_MODE (type) != BLKmode)
++              return msp430_libcall_value (TYPE_MODE (type));
++
++      offs = int_size_in_bytes (type);
++      offs >>= 1;
++      if (offs < 1)
++              offs = 1;
++      if (offs > 1 && offs < (GET_MODE_SIZE (SImode) >> 1))
++              offs = GET_MODE_SIZE (SImode) >> 1;
++      else if (offs > (GET_MODE_SIZE (SImode) >> 1)
++              && offs < (GET_MODE_SIZE (DImode) >> 1))
++              offs = GET_MODE_SIZE (DImode) >> 1;
++
++      return gen_rtx_REG (BLKmode, (RET_REGISTER + 1 - offs));
++}
++
++int
++halfnibble_integer (op, mode)
++rtx op;
++enum machine_mode mode;
++{
++      int hi, lo;
++      int val;
++
++      if (!const_int_operand (op, mode))
++              return 0;
++
++      /* this integer is the one of form:
++      0xXXXX0000 or 0x0000XXXX,
++      where XXXX not one of -1,1,2,4,8 
++      */
++      val = INTVAL (op);
++      hi = ((val & 0xffff0000ul) >> 16) & 0xffff;
++      lo = (val & 0xffff);
++
++      if (hi && lo)
++              return 0;
++
++      if (hi && hi != 0xffff && hi != 1 && hi != 2 && hi != 4 && hi != 8)
++              return 1;
++      if (lo && lo != 0xffff && lo != 1 && lo != 2 && lo != 4 && lo != 8)
++              return 1;
++
++      return 0;
++}
++
++
++int
++halfnibble_constant (op, mode)
++rtx op;
++enum machine_mode mode;
++{
++      int hi, lo;
++      int val;
++
++      if (!const_int_operand (op, mode))
++              return 0;
++
++      /* this integer is the one of form:
++      0xXXXX0000 or 0x0000XXXX,
++      where XXXX one of -1,1,2,4,8 
++      */
++      val = INTVAL (op);
++      hi = ((val & 0xffff0000ul) >> 16) & 0x0000ffff;
++      lo = (val & 0x0000ffff);
++
++      if ((hi && lo) || (!hi && !lo))
++              return 0;
++
++      if (hi == 0xffff || hi == 1 || hi == 2 || hi == 4 || hi == 8)
++              return 1;
++      if (lo == 0xffff || lo == 1 || lo == 2 || lo == 4 || lo == 8)
++              return 1;
++
++      if (!(hi && lo))
++              return 1;
++
++      return 0;
++}
++
++
++int
++halfnibble_integer_shift (op, mode)
++rtx op;
++enum machine_mode mode;
++{
++      int hi, lo;
++      int val;
++
++      if (!immediate_operand (op, mode))
++              return 0;
++
++      /* this integer is the one of form:
++      0xXXXX0000 or 0x0000XXXX,
++      where XXXX not one of -1,1,2,4,8 
++      */
++      val = 1 << INTVAL (op);
++      hi = ((val & 0xffff0000ul) >> 16) & 0x0000ffff;
++      lo = (val & 0x0000ffff);
++
++      if (hi && lo)
++              return 0;
++
++      if (hi && hi != 0xffff && hi != 1 && hi != 2 && hi != 4 && hi != 8)
++              return 1;
++      if (lo && lo != 0xffff && lo != 1 && lo != 2 && lo != 4 && lo != 8)
++              return 1;
++
++      return 0;
++}
++
++
++int
++halfnibble_constant_shift (op, mode)
++rtx op;
++enum machine_mode mode;
++{
++      int hi, lo;
++      int val;
++
++      if (!immediate_operand (op, mode))
++              return 0;
++
++      /* this integer is the one of form:
++      0xXXXX0000 or 0x0000XXXX,
++      where XXXX one of -1,1,2,4,8 
++      */
++      val = 1 << INTVAL (op);
++      hi = ((val & 0xffff0000ul) >> 16) & 0x0000ffff;
++      lo = (val & 0x0000ffff);
++
++      if (hi && lo)
++              return 0;
++
++      if (hi && hi == 0xffff && hi == 1 && hi == 2 && hi == 4 && hi == 8)
++              return 1;
++      if (lo && lo == 0xffff && lo == 1 && lo == 2 && lo == 4 && lo == 8)
++              return 1;
++
++      return 0;
++}
++
++
++int
++which_nibble (val)
++int val;
++{
++      if (val & 0xffff0000ul)
++              return 1;
++      return 0;
++}
++
++
++int
++which_nibble_shift (val)
++int val;
++{
++      if (val & 0xffff0000ul)
++              return 1;
++      return 0;
++}
++
++
++int
++extra_constraint (x, c)
++rtx x;
++int c;
++{
++
++      if (c == 'R')
++      {
++              if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == REG)
++              {
++                      rtx xx = XEXP (x, 0);
++                      int regno = REGNO (xx);
++                      if (regno >= 4 || regno == 1)
++                              return 1;
++              }
++      }
++      else if (c == 'Q')
++      {
++              if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == REG)
++              {
++                      rtx xx = XEXP (x, 0);
++                      int regno = REGNO (xx);
++                      if (regno >= 4 || regno == 1)
++                              return 1;
++              }
++
++              if (GET_CODE (x) == MEM
++                      && GET_CODE (XEXP (x, 0)) == PLUS
++                      && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
++              {
++                      rtx xx = XEXP (XEXP (x, 0), 0);
++                      int regno = REGNO (xx);
++                      if (regno >= 4 || regno == 1)
++                              return 1;
++              }
++
++              if (GET_CODE (x) == MEM
++                      && GET_CODE (XEXP (x, 0)) == PLUS && REG_P (XEXP (XEXP (x, 0), 0)))
++              {
++                      return 1;
++              }
++
++      }
++      else if (c == 'S')
++      {
++              if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
++              {
++                      return 1;
++              }
++      }
++
++      return 0;
++}
++
++int
++indexed_location (x)
++rtx x;
++{
++      int r = 0;
++
++      if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == REG)
++      {
++              r = 1;
++      }
++
++      if (TARGET_ALL_DEBUG)
++      {
++              fprintf (stderr, "indexed_location %s: %s  \n",
++                      r ? "granted" : "failed",
++                      reload_completed ? "reload completed" : "reload in progress");
++              debug_rtx (x);
++      }
++
++      return r;
++}
++
++
++int
++zero_shifted (x)
++rtx x;
++{
++      int r = 0;
++
++      if (GET_CODE (x) == MEM &&
++              GET_CODE (XEXP (x, 0)) == REG
++              && REGNO (XEXP (x, 0)) != STACK_POINTER_REGNUM
++              && REGNO (XEXP (x, 0)) != FRAME_POINTER_REGNUM
++              /* the following is Ok, cause we do not corrupt r4 within ISR */
++              /*&& REGNO(XEXP (x,0)) != ARG_POINTER_REGNUM */ )
++      {
++              r = 1;
++      }
++      return r;
++}
++
++
++
++void
++order_regs_for_local_alloc ()
++{
++      unsigned int i;
++
++      if (TARGET_REORDER)
++      {
++              reg_alloc_order[0] = 12;
++              reg_alloc_order[1] = 13;
++              reg_alloc_order[2] = 14;
++              reg_alloc_order[3] = 15;
++              for (i = 4; i < 16; i++)
++                      reg_alloc_order[i] = 15 - i;
++      }
++      else
++      {
++              for (i = 0; i < 16; i++)
++                      reg_alloc_order[i] = 15 - i;
++      }
++
++      return;
++}
++
++/* Output rtx VALUE as .byte to file FILE */
++void
++asm_output_char (file, value)
++FILE *file;
++rtx value;
++{
++      fprintf (file, "\t.byte\t");
++      output_addr_const (file, value);
++      fprintf (file, "\n");
++}
++
++/* Output VALUE as .byte to file FILE */
++void
++asm_output_byte (file, value)
++FILE *file;
++int value;
++{
++      fprintf (file, "\t.byte 0x%x\n", value & 0xff);
++}
++
++/* Output rtx VALUE as .word to file FILE */
++void
++asm_output_short (file, value)
++FILE *file;
++rtx value;
++{
++      fprintf (file, "\t.word ");
++      output_addr_const (file, (value));
++      fprintf (file, "\n");
++}
++
++#if 0
++/* Output real N to file FILE */
++void
++asm_output_float (file, n)
++FILE *file;
++REAL_VALUE_TYPE n;
++{
++      long val;
++      char dstr[100];
++
++      REAL_VALUE_TO_TARGET_SINGLE (n, val);
++      REAL_VALUE_TO_DECIMAL (n, "%g", dstr);
++      fprintf (file, "\t.long 0x%08lx\t/* %s */\n", val, dstr);
++}
++#endif
++
++/* Output section name to file FILE
++We make the section read-only and executable for a function decl,
++read-only for a const data decl, and writable for a non-const data decl.  */
++
++void
++asm_output_section_name (file, decl, name, reloc)
++FILE *file;
++tree decl;
++const char *name;
++int reloc ATTRIBUTE_UNUSED;
++{
++      fprintf (file, ".section %s, \"%s\", @progbits\n", name,
++              decl && TREE_CODE (decl) == FUNCTION_DECL ? "ax" :
++              decl && TREE_READONLY (decl) ? "a" : "aw");
++}
++
++
++/* The routine used to output NUL terminated strings.  We use a special
++version of this for most svr4 targets because doing so makes the
++generated assembly code more compact (and thus faster to assemble)
++as well as more readable, especially for targets like the i386
++(where the only alternative is to output character sequences as
++comma separated lists of numbers).   */
++
++void
++gas_output_limited_string (file, str)
++FILE *file;
++const char *str;
++{
++      const unsigned char *_limited_str = (unsigned char *) str;
++      unsigned ch;
++      fprintf (file, "%s\"", STRING_ASM_OP);
++      for (; (ch = *_limited_str); _limited_str++)
++      {
++              int escape;
++              switch (escape = ESCAPES[ch])
++              {
++              case 0:
++                      putc (ch, file);
++                      break;
++              case 1:
++                      fprintf (file, "\\%03o", ch);
++                      break;
++              default:
++                      putc ('\\', file);
++                      putc (escape, file);
++                      break;
++              }
++      }
++      fprintf (file, "\"\n");
++}
++
++/* The routine used to output sequences of byte values.  We use a special
++version of this for most svr4 targets because doing so makes the
++generated assembly code more compact (and thus faster to assemble)
++as well as more readable.  Note that if we find subparts of the
++character sequence which end with NUL (and which are shorter than
++STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING.  */
++
++void
++gas_output_ascii (file, str, length)
++FILE *file;
++const char *str;
++size_t length;
++{
++      const unsigned char *_ascii_bytes = (const unsigned char *) str;
++      const unsigned char *limit = _ascii_bytes + length;
++      unsigned bytes_in_chunk = 0;
++      for (; _ascii_bytes < limit; _ascii_bytes++)
++      {
++              const unsigned char *p;
++              if (bytes_in_chunk >= 60)
++              {
++                      fprintf (file, "\"\n");
++                      bytes_in_chunk = 0;
++              }
++              for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
++                      continue;
++              if (p < limit && (p - _ascii_bytes) <= (signed) STRING_LIMIT)
++              {
++                      if (bytes_in_chunk > 0)
++                      {
++                              fprintf (file, "\"\n");
++                              bytes_in_chunk = 0;
++                      }
++                      gas_output_limited_string (file, (char *) _ascii_bytes);
++                      _ascii_bytes = p;
++              }
++              else
++              {
++                      int escape;
++                      unsigned ch;
++                      if (bytes_in_chunk == 0)
++                              fprintf (file, "\t.ascii\t\"");
++                      switch (escape = ESCAPES[ch = *_ascii_bytes])
++                      {
++                      case 0:
++                              putc (ch, file);
++                              bytes_in_chunk++;
++                              break;
++                      case 1:
++                              fprintf (file, "\\%03o", ch);
++                              bytes_in_chunk += 4;
++                              break;
++                      default:
++                              putc ('\\', file);
++                              putc (escape, file);
++                              bytes_in_chunk += 2;
++                              break;
++                      }
++              }
++      }
++      if (bytes_in_chunk > 0)
++              fprintf (file, "\"\n");
++}
++
++
++
++/* Outputs to the stdio stream FILE some
++appropriate text to go at the start of an assembler file.  */
++
++static void msp430_file_start (void)
++{
++      FILE *file = asm_out_file;
++      output_file_directive (file, main_input_filename);
++      fprintf (file, "\t.arch %s\n\n", msp430_mcu_name);
++
++      if (msp430_has_hwmul)
++      {
++              switch (msp430_get_arch())
++              {
++              case MSP430_ISA_471:
++              case MSP430_ISA_47:
++                      fprintf (file, "/* Hardware multiplier registers: */\n"
++                              "__MPY=0x130\n"
++                              "__MPYS=0x132\n"
++                              "__MAC=0x134\n"
++                              "__MACS=0x136\n"
++                              "__OP2=0x138\n"
++                              "__RESLO=0x13a\n"
++                              "__RESHI=0x13c\n"
++                              "__SUMEXT=0x13e\n"
++                              "__MPY32L=0x140\n"
++                              "__MPY32H=0x142\n"
++                              "__MPYS32L=0x144\n"
++                              "__MPYS32H=0x146\n"
++                              "__MAC32L=0x148\n"
++                              "__MAC32H=0x14a\n"
++                              "__MACS32L=0x14c\n"
++                              "__MACS32H=0x14e\n"
++                              "__OP2L=0x150\n"
++                              "__OP2H=0x152\n"
++                              "__RES0=0x154\n"
++                              "__RES1=0x156\n"
++                              "__RES2=0x158\n"
++                              "__RES3=0x15a\n"
++                              "__MPY32CTL0=0x15c\n"
++                              "\n");
++                      break;
++              case MSP430_ISA_54:
++                      fprintf (file, "/* Hardware multiplier registers: */\n"
++                              "__MPY=0x4c0\n"
++                              "__MPYS=0x4c2\n"
++                              "__MAC=0x4c4\n"
++                              "__MACS=0x4c6\n"
++                              "__OP2=0x4c8\n"
++                              "__RESLO=0x4ca\n"
++                              "__RESHI=0x4cc\n"
++                              "__SUMEXT=0x4ce\n"
++                              "__MPY32L=0x4d0\n"
++                              "__MPY32H=0x4d2\n"
++                              "__MPYS32L=0x4d4\n"
++                              "__MPYS32H=0x4d6\n"
++                              "__MAC32L=0x4d8\n"
++                              "__MAC32H=0x4da\n"
++                              "__MACS32L=0x4dc\n"
++                              "__MACS32H=0x4de\n"
++                              "__OP2L=0x4e0\n"
++                              "__OP2H=0x4e2\n"
++                              "__RES0=0x4e4\n"
++                              "__RES1=0x4e6\n"
++                              "__RES2=0x4e8\n"
++                              "__RES3=0x4ea\n"
++                              "__MPY32CTL0=0x4ec\n"
++                              "\n");
++                      break;
++              default:
++                      fprintf (file, "/* Hardware multiplier registers: */\n"
++                              "__MPY=0x130\n"
++                              "__MPYS=0x132\n"
++                              "__MAC=0x134\n"
++                              "__MACS=0x136\n"
++                              "__OP2=0x138\n"
++                              "__RESLO=0x13a\n" 
++                              "__RESHI=0x13c\n" 
++                              "__SUMEXT=0x13e\n" 
++                              "\n");
++              }
++
++      }
++
++      msp430_commands_in_file = 0;
++      msp430_commands_in_prologues = 0;
++      msp430_commands_in_epilogues = 0;
++}
++
++/* Outputs to the stdio stream FILE some
++appropriate text to go at the end of an assembler file.  */
++
++static void msp430_file_end (void)
++{
++      fprintf (asm_out_file,
++              "\n"
++              "/*********************************************************************\n"
++              " * File %s: code size: %d words (0x%x)\n * incl. words in prologues: %d, epilogues: %d\n"
++              " *********************************************************************/\n",
++              main_input_filename,
++              msp430_commands_in_file,
++              msp430_commands_in_file, msp430_commands_in_prologues, msp430_commands_in_epilogues);
++}
++
++int
++msp430_hard_regno_mode_ok (regno, mode)
++int regno ATTRIBUTE_UNUSED;
++enum machine_mode mode ATTRIBUTE_UNUSED;
++{
++      return 1;
++}
++
++#if GCC_VERSION_INT >= 0x440
++#define current_function_calls_alloca cfun->calls_alloca
++#endif
++
++int
++frame_pointer_required_p ()
++{
++      return (current_function_calls_alloca
++              /*            || current_function_args_info.nregs == 0 */
++              /*|| current_function_varargs*/);
++
++      /* || get_frame_size () > 0); */
++}
++
++enum reg_class
++preferred_reload_class (x, class)
++rtx x ATTRIBUTE_UNUSED;
++enum reg_class class;
++{
++      return class;
++}
++
++int
++adjust_insn_length (insn, len)
++rtx insn;
++int len;
++{
++
++      rtx patt = PATTERN (insn);
++      rtx set;
++
++      set = single_set (insn);
++
++      if (GET_CODE (patt) == SET)
++      {
++              rtx op[10];
++              op[1] = SET_SRC (patt);
++              op[0] = SET_DEST (patt);
++
++              if (general_operand (op[1], VOIDmode)
++                      && general_operand (op[0], VOIDmode))
++              {
++                      op[2] = SET_SRC (patt);
++                      switch (GET_MODE (op[0]))
++                      {
++                      case QImode:
++                      case HImode:
++                              if (indexed_location (op[1]))
++                                      len--;
++                              break;
++
++                      case SImode:
++                      case SFmode:
++                              /* get length first */
++                              msp430_movesi_code (insn, op, &len);
++
++                              if (zero_shifted (op[1]) && regsi_ok_safe (op))
++                              {
++                                      rtx reg = XEXP (op[1], 0);
++                                      if (dead_or_set_p (insn, reg))
++                                              len -= 1;
++                              }
++                              else if (!zero_shifted (op[1]) && indexed_location (op[1]))
++                              {
++                                      len -= 1;
++                              }
++                              break;
++                      case DImode:
++                              msp430_movedi_code (insn, op, &len);
++                              if (zero_shifted (op[1]) && regdi_ok_safe (op))
++                              {
++                                      rtx reg = XEXP (op[1], 0);
++                                      if (dead_or_set_p (insn, reg))
++                                              len -= 1;
++                              }
++                              else if (!zero_shifted (op[1]) && indexed_location (op[1]))
++                              {
++                                      len -= 1;
++                              }
++                              break;
++
++                      default:
++                              break;
++                      }
++
++                      if (GET_CODE (op[2]) == CONST_INT)
++                      {
++                              if (GET_MODE (op[0]) == DImode)
++                              {
++                                      int x = INTVAL (op[2]);
++                                      int y = (x & 0xffff0000ul) >> 16;
++                                      x = x & 0xffff;
++
++                                      len -= 2;
++
++                                      if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
++                                              || x == 0xffff)
++                                              len--;
++                                      if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8
++                                              || y == 0xffff)
++                                              len--;
++                              }
++                              else if (GET_MODE (op[0]) == SImode)
++                              {
++                                      int x = INTVAL (op[2]);
++                                      int y = (x & 0xffff0000ul) >> 16;
++                                      x = x & 0xffff;
++
++                                      if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
++                                              || x == 0xffff)
++                                              len--;
++                                      if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8
++                                              || y == 0xffff)
++                                              len--;
++                              }
++                              else
++                              {
++                                      /* mighr be hi or qi modes */
++                                      int x = INTVAL (op[2]);
++                                      x = x & 0xffff;
++                                      if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
++                                              || x == 0xffff)
++                                              len--;
++                              }
++                      }
++
++                      if (GET_CODE (op[2]) == CONST_DOUBLE)
++                      {
++                              if (GET_MODE (op[0]) == SFmode)
++                              {
++                                      long val;
++                                      int y, x;
++                                      REAL_VALUE_TYPE rv;
++                                      REAL_VALUE_FROM_CONST_DOUBLE (rv, op[2]);
++                                      REAL_VALUE_TO_TARGET_SINGLE (rv, val);
++
++                                      y = (val & 0xffff0000ul) >> 16;
++                                      x = val & 0xffff;
++                                      if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
++                                              || x == 0xffff)
++                                              len--;
++                                      if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8
++                                              || y == 0xffff)
++                                              len--;
++                              }
++                              else
++                              {
++                                      int hi = CONST_DOUBLE_HIGH (op[2]);
++                                      int lo = CONST_DOUBLE_LOW (op[2]);
++                                      int x, y, z;
++
++                                      x = (hi & 0xffff0000ul) >> 16;
++                                      y = hi & 0xffff;
++                                      z = (lo & 0xffff0000ul) >> 16;
++                                      if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
++                                              || x == 0xffff)
++                                              len--;
++                                      if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8
++                                              || y == 0xffff)
++                                              len--;
++                                      if (z == 0 || z == 1 || z == 2 || z == 4 || z == 8
++                                              || z == 0xffff)
++                                              len--;
++                                      z = lo & 0xffff;
++                                      if (z == 0 || z == 1 || z == 2 || z == 4 || z == 8
++                                              || z == 0xffff)
++                                              len--;
++                              }
++                      }
++
++                      return len;
++              }
++              else if (GET_CODE (op[1]) == MULT)
++              {
++                      rtx ops[10];
++                      ops[0] = op[0];
++                      ops[1] = XEXP (op[1], 0);
++                      ops[2] = XEXP (op[1], 1);
++
++                      if (GET_MODE (ops[0]) != SImode
++                              && GET_MODE (ops[0]) != SFmode && GET_MODE (ops[0]) != DImode)
++                      {
++                              if (indexed_location (ops[1]))
++                                      len--;
++                              if (indexed_location (ops[2]))
++                                      len--;
++                      }
++              }
++              else if (GET_CODE (op[1]) == ASHIFT
++                      || GET_CODE (op[1]) == ASHIFTRT || GET_CODE (op[1]) == LSHIFTRT)
++              {
++                      rtx ops[10];
++                      ops[0] = op[0];
++                      ops[1] = XEXP (op[1], 0);
++                      ops[2] = XEXP (op[1], 1);
++
++                      switch (GET_CODE (op[1]))
++                      {
++                      case ASHIFT:
++                              switch (GET_MODE (op[0]))
++                              {
++                              case QImode:
++                                      msp430_emit_ashlqi3 (insn, ops, &len);
++                                      break;
++                              case HImode:
++                                      msp430_emit_ashlhi3 (insn, ops, &len);
++                                      break;
++                              case SImode:
++                                      msp430_emit_ashlsi3 (insn, ops, &len);
++                                      break;
++                              case DImode:
++                                      msp430_emit_ashldi3 (insn, ops, &len);
++                                      break;
++                              default:
++                                      break;
++                              }
++                              break;
++
++                      case ASHIFTRT:
++                              switch (GET_MODE (op[0]))
++                              {
++                              case QImode:
++                                      msp430_emit_ashrqi3 (insn, ops, &len);
++                                      break;
++                              case HImode:
++                                      msp430_emit_ashrhi3 (insn, ops, &len);
++                                      break;
++                              case SImode:
++                                      msp430_emit_ashrsi3 (insn, ops, &len);
++                                      break;
++                              case DImode:
++                                      msp430_emit_ashrdi3 (insn, ops, &len);
++                                      break;
++                              default:
++                                      break;
++                              }
++                              break;
++
++                      case LSHIFTRT:
++                              switch (GET_MODE (op[0]))
++                              {
++                              case QImode:
++                                      msp430_emit_lshrqi3 (insn, ops, &len);
++                                      break;
++                              case HImode:
++                                      msp430_emit_lshrhi3 (insn, ops, &len);
++                                      break;
++                              case SImode:
++                                      msp430_emit_lshrsi3 (insn, ops, &len);
++                                      break;
++                              case DImode:
++                                      msp430_emit_lshrdi3 (insn, ops, &len);
++                                      break;
++                              default:
++                                      break;
++                              }
++                              break;
++
++                      default:
++                              break;
++                      }
++              }
++              else if (GET_CODE (op[1]) == PLUS
++                      || GET_CODE (op[1]) == MINUS
++                      || GET_CODE (op[1]) == AND
++                      || GET_CODE (op[1]) == IOR || GET_CODE (op[1]) == XOR)
++              {
++                      rtx ops[10];
++                      ops[0] = op[0];
++                      ops[1] = XEXP (op[1], 0);
++                      ops[2] = XEXP (op[1], 1);
++
++                      if (GET_CODE (op[1]) == AND && !general_operand (ops[1], VOIDmode))
++                              return len;
++
++                      switch (GET_MODE (ops[0]))
++                      {
++                      case QImode:
++                      case HImode:
++                              if (indexed_location (ops[2]))
++                                      len--;
++                              break;
++                      case SImode:
++                      case SFmode:
++
++                              if (GET_CODE (op[1]) == PLUS)
++                                      msp430_addsi_code (insn, ops, &len);
++                              if (GET_CODE (op[1]) == MINUS)
++                                      msp430_subsi_code (insn, ops, &len);
++                              if (GET_CODE (op[1]) == AND)
++                                      msp430_andsi_code (insn, ops, &len);
++                              if (GET_CODE (op[1]) == IOR)
++                                      msp430_iorsi_code (insn, ops, &len);
++                              if (GET_CODE (op[1]) == XOR)
++                                      msp430_xorsi_code (insn, ops, &len);
++
++                              if (zero_shifted (ops[2]) && regsi_ok_safe (ops))
++                              {
++                                      rtx reg = XEXP (ops[2], 0);
++                                      if (dead_or_set_p (insn, reg))
++                                              len -= 1;
++                              }
++                              else if (!zero_shifted (ops[2]) && indexed_location (ops[2]))
++                              {
++                                      len -= 1;
++                              }
++                              break;
++                      case DImode:
++
++                              if (GET_CODE (op[1]) == PLUS)
++                                      msp430_adddi_code (insn, ops, &len);
++                              if (GET_CODE (op[1]) == MINUS)
++                                      msp430_subdi_code (insn, ops, &len);
++                              if (GET_CODE (op[1]) == AND)
++                                      msp430_anddi_code (insn, ops, &len);
++                              if (GET_CODE (op[1]) == IOR)
++                                      msp430_iordi_code (insn, ops, &len);
++                              if (GET_CODE (op[1]) == XOR)
++                                      msp430_xordi_code (insn, ops, &len);
++
++                              if (zero_shifted (ops[2]) && regdi_ok_safe (ops))
++                              {
++                                      rtx reg = XEXP (ops[2], 0);
++                                      if (dead_or_set_p (insn, reg))
++                                              len -= 1;
++                              }
++                              else if (!zero_shifted (ops[2]) && indexed_location (ops[2]))
++                              {
++                                      len -= 1;
++                              }
++                              break;
++
++                      default:
++                              break;
++                      }
++
++                      if (GET_MODE (ops[0]) == SImode)
++                      {
++                              if (GET_CODE (ops[2]) == CONST_INT)
++                              {
++                                      if (GET_CODE (op[1]) == AND)
++                                      {
++                                              msp430_emit_immediate_and2 (insn, ops, &len);
++                                      }
++                                      else if (GET_CODE (op[1]) == IOR)
++                                      {
++                                              msp430_emit_immediate_ior2 (insn, ops, &len);
++                                      }
++                                      else
++                                      {
++                                              if (GET_MODE (ops[0]) == SImode)
++                                              {
++                                                      int x = INTVAL (ops[2]);
++                                                      int y = (x & 0xffff0000ul) >> 16;
++                                                      x = x & 0xffff;
++
++                                                      if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
++                                                              || x == 0xffff)
++                                                              len--;
++                                                      if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8
++                                                              || y == 0xffff)
++                                                              len--;
++                                              }
++                                      }
++                              }
++                      }
++
++                      if (GET_MODE (ops[0]) == SFmode || GET_MODE (ops[0]) == DImode)
++                      {
++                              if (GET_CODE (ops[2]) == CONST_DOUBLE)
++                              {
++
++                                      if (GET_CODE (op[1]) == AND)
++                                      {
++                                              msp430_emit_immediate_and4 (insn, ops, &len);
++                                      }
++                                      else if (GET_CODE (op[1]) == IOR)
++                                      {
++                                              msp430_emit_immediate_ior4 (insn, ops, &len);
++                                      }
++                                      else if (GET_MODE (ops[0]) == SFmode)
++                                      {
++                                              long val;
++                                              int y, x;
++                                              REAL_VALUE_TYPE rv;
++                                              REAL_VALUE_FROM_CONST_DOUBLE (rv, ops[2]);
++                                              REAL_VALUE_TO_TARGET_SINGLE (rv, val);
++
++                                              y = (val & 0xffff0000ul) >> 16;
++                                              x = val & 0xffff;
++                                              if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
++                                                      || x == 0xffff)
++                                                      len--;
++                                              if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8
++                                                      || y == 0xffff)
++                                                      len--;
++                                      }
++                                      else
++                                      {
++                                              int hi = CONST_DOUBLE_HIGH (ops[2]);
++                                              int lo = CONST_DOUBLE_LOW (ops[2]);
++                                              int x, y, z;
++
++                                              x = (hi & 0xffff0000ul) >> 16;
++                                              y = hi & 0xffff;
++                                              z = (lo & 0xffff0000ul) >> 16;
++                                              if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8
++                                                      || x == 0xffff)
++                                                      len--;
++                                              if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8
++                                                      || y == 0xffff)
++                                                      len--;
++                                              if (z == 0 || z == 1 || z == 2 || z == 4 || z == 8
++                                                      || z == 0xffff)
++                                                      len--;
++                                      }
++                              }
++                      }
++
++                      return len;
++              }
++              else if (GET_CODE (op[1]) == NOT
++                      || GET_CODE (op[1]) == ABS || GET_CODE (op[1]) == NEG)
++              {
++                      if (GET_MODE (op[0]) == HImode || GET_MODE (op[0]) == QImode)
++                              if (indexed_location (XEXP (op[1], 0)))
++                                      len--;
++                      /* consts handled by cpp */
++                      /* nothing... */
++              }
++              else if (GET_CODE (op[1]) == ZERO_EXTEND)
++              {
++                      rtx ops[10];
++                      ops[0] = op[0];
++                      ops[1] = XEXP (op[1], 0);
++
++                      if (GET_MODE (ops[1]) == QImode)
++                      {
++                              if (GET_MODE (ops[0]) == HImode)
++                                      zeroextendqihi (insn, ops, &len);
++                              else if (GET_MODE (ops[0]) == SImode)
++                                      zeroextendqisi (insn, ops, &len);
++                              else if (GET_MODE (ops[0]) == DImode)
++                                      zeroextendqidi (insn, ops, &len);
++                      }
++                      else if (GET_MODE (ops[1]) == HImode)
++                      {
++                              if (GET_MODE (ops[0]) == SImode)
++                                      zeroextendhisi (insn, ops, &len);
++                              else if (GET_MODE (ops[0]) == DImode)
++                                      zeroextendhidi (insn, ops, &len);
++                      }
++                      else if (GET_MODE (ops[1]) == SImode)
++                      {
++                              if (GET_MODE (ops[1]) == DImode)
++                                      zeroextendsidi (insn, ops, &len);
++                      }
++              }
++              else if (GET_CODE (op[1]) == SIGN_EXTEND)
++              {
++                      rtx ops[10];
++                      ops[0] = op[0]; /* dest */
++                      ops[1] = XEXP (op[1], 0);       /* src */
++
++                      if (GET_MODE (ops[1]) == QImode)
++                      {
++                              if (GET_MODE (ops[0]) == HImode)
++                                      signextendqihi (insn, ops, &len);
++                              else if (GET_MODE (ops[0]) == SImode)
++                                      signextendqisi (insn, ops, &len);
++                              else if (GET_MODE (ops[0]) == DImode)
++                                      signextendqidi (insn, ops, &len);
++                      }
++                      else if (GET_MODE (ops[1]) == HImode)
++                      {
++                              if (GET_MODE (ops[0]) == SImode)
++                                      signextendhisi (insn, ops, &len);
++                              else if (GET_MODE (ops[0]) == DImode)
++                                      signextendhidi (insn, ops, &len);
++                      }
++                      else if (GET_MODE (ops[1]) == SImode)
++                      {
++                              if (GET_MODE (ops[0]) == DImode)
++                                      signextendsidi (insn, ops, &len);
++                      }
++              }
++              else if (GET_CODE (op[1]) == IF_THEN_ELSE)
++              {
++                      if (GET_CODE (op[0]) == PC)
++                      {
++                              rtx ops[5];
++                              ops[0] = XEXP (op[1], 1);
++                              ops[1] = XEXP (op[1], 0);
++                              ops[2] = XEXP (ops[1], 0);
++                              ops[3] = XEXP (ops[1], 1);
++                              msp430_cbranch (insn, ops, &len, 0);
++                      }
++              }
++              else if (GET_CODE (op[0]) == MEM
++                      && GET_CODE (XEXP (op[0], 0)) == POST_DEC)
++              {
++                      rtx ops[4];
++                      ops[0] = op[1];
++                      if (GET_MODE (op[0]) == QImode)
++                              msp430_pushqi (insn, ops, &len);
++                      if (GET_MODE (op[0]) == HImode)
++                              msp430_pushhi (insn, ops, &len);
++                      if (GET_MODE (op[0]) == SImode)
++                              msp430_pushsisf (insn, ops, &len);
++                      if (GET_MODE (op[0]) == DImode)
++                              msp430_pushdi (insn, ops, &len);
++              }
++      }
++
++      if (set)
++      {
++              rtx op[10];
++              op[1] = SET_SRC (set);
++              op[0] = SET_DEST (set);
++
++              if (GET_CODE (patt) == PARALLEL)
++              {
++                      if (GET_CODE (op[0]) == PC && GET_CODE (op[1]) == IF_THEN_ELSE)
++                      {
++                              rtx ops[5];
++                              ops[0] = XEXP (op[1], 1);
++                              ops[1] = XEXP (op[1], 0);
++                              ops[2] = XEXP (ops[1], 0);
++                              ops[3] = XEXP (ops[1], 1);
++                              msp430_cbranch (insn, ops, &len, 0);
++                      }
++
++                      if (GET_CODE (op[1]) == ASHIFT
++                              || GET_CODE (op[1]) == ASHIFTRT || GET_CODE (op[1]) == LSHIFTRT)
++                      {
++                              rtx ops[10];
++                              ops[0] = op[0];
++                              ops[1] = XEXP (op[1], 0);
++                              ops[2] = XEXP (op[1], 1);
++
++                              switch (GET_CODE (op[1]))
++                              {
++                              case ASHIFT:
++                                      switch (GET_MODE (op[0]))
++                                      {
++                                      case QImode:
++                                              msp430_emit_ashlqi3 (insn, ops, &len);
++                                              break;
++                                      case HImode:
++                                              msp430_emit_ashlhi3 (insn, ops, &len);
++                                              break;
++                                      case SImode:
++                                              msp430_emit_ashlsi3 (insn, ops, &len);
++                                              break;
++                                      case DImode:
++                                              msp430_emit_ashldi3 (insn, ops, &len);
++                                              break;
++                                      default:
++                                              break;
++                                      }
++                                      break;
++
++                              case ASHIFTRT:
++                                      switch (GET_MODE (op[0]))
++                                      {
++                                      case QImode:
++                                              msp430_emit_ashrqi3 (insn, ops, &len);
++                                              break;
++                                      case HImode:
++                                              msp430_emit_ashrhi3 (insn, ops, &len);
++                                              break;
++                                      case SImode:
++                                              msp430_emit_ashrsi3 (insn, ops, &len);
++                                              break;
++                                      case DImode:
++                                              msp430_emit_ashrdi3 (insn, ops, &len);
++                                              break;
++                                      default:
++                                              break;
++                                      }
++                                      break;
++
++                              case LSHIFTRT:
++                                      switch (GET_MODE (op[0]))
++                                      {
++                                      case QImode:
++                                              msp430_emit_lshrqi3 (insn, ops, &len);
++                                              break;
++                                      case HImode:
++                                              msp430_emit_lshrhi3 (insn, ops, &len);
++                                              break;
++                                      case SImode:
++                                              msp430_emit_lshrsi3 (insn, ops, &len);
++                                              break;
++                                      case DImode:
++                                              msp430_emit_lshrdi3 (insn, ops, &len);
++                                              break;
++                                      default:
++                                              break;
++                                      }
++                                      break;
++
++                              default:
++                                      break;
++                              }
++                      }
++              }
++      }
++
++      return len;
++}
++
++void
++machine_dependent_reorg (first_insn)
++rtx first_insn ATTRIBUTE_UNUSED;
++{
++      /* nothing to be done here this time */
++      return;
++}
++
++
++int
++test_hard_reg_class (class, x)
++enum reg_class class;
++rtx x;
++{
++      int regno = true_regnum (x);
++      if (regno < 0)
++              return 0;
++      return TEST_HARD_REG_CLASS (class, regno);
++}
++
++
++/* Returns 1 if SCRATCH are safe to be allocated as a scratch
++registers (for a define_peephole2) in the current function.  */
++/* UNUSED ... yet... */
++int
++msp430_peep2_scratch_safe (scratch)
++rtx scratch;
++{
++      if ((interrupt_function_p (current_function_decl)
++              || signal_function_p (current_function_decl)) && cfun->machine->is_leaf)
++      {
++              int first_reg = true_regnum (scratch);
++              int last_reg;
++              int size = GET_MODE_SIZE (GET_MODE (scratch));
++              int reg;
++
++              size >>= 1;
++              if (!size)
++                      size = 1;
++
++              last_reg = first_reg + size - 1;
++
++              for (reg = first_reg; reg <= last_reg; reg++)
++              {
++                      if (!df_regs_ever_live_p(reg))
++                              return 0;
++              }
++      }
++
++      return 1;
++}
++
++
++/* Update the condition code in the INSN.
++now mostly unused */
++
++void
++notice_update_cc (body, insn)
++rtx body ATTRIBUTE_UNUSED;
++rtx insn ATTRIBUTE_UNUSED;
++{
++      CC_STATUS_INIT;
++}
++
++
++
++/*********************************************************************/
++
++/*
++Next two return non zero for rtx as
++(set (reg:xx)
++(mem:xx (reg:xx))
++
++*/
++
++int
++regsi_ok_safe (operands)
++rtx operands[];
++{
++      rtx dest = operands[0];
++      rtx areg;
++      int src_reg;
++      int dst_reg;
++
++      if (operands[2])
++              areg = XEXP (operands[2], 0);
++      else
++              areg = XEXP (operands[1], 0);
++
++      if (GET_CODE (dest) == MEM)
++      {
++              dest = XEXP (operands[0], 0);
++              if (GET_CODE (dest) == PLUS && GET_CODE (XEXP (dest, 0)) == REG)
++              {
++                      dest = XEXP (dest, 0);
++              }
++              else if (GET_CODE (dest) == REG)
++              {
++                      ;                       /* register */
++              }
++              else
++                      return 1;
++      }
++
++      if (REGNO (dest) >= FIRST_PSEUDO_REGISTER
++              || REGNO (areg) >= FIRST_PSEUDO_REGISTER)
++              return 1;
++
++      dst_reg = true_regnum (dest);
++      src_reg = true_regnum (areg);
++      if (dst_reg > src_reg || dst_reg + 1 < src_reg)
++      {
++              return 1;
++      }
++      return 0;
++}
++
++int
++regsi_ok_clobber (operands)
++rtx operands[];
++{
++      rtx dest = operands[0];
++      rtx areg = XEXP (operands[2], 0);
++      int src_reg;
++      int dst_reg;
++      int regno = REGNO (dest);
++
++
++      if (GET_CODE (dest) == MEM)
++      {
++              dest = XEXP (operands[0], 0);
++              if (GET_CODE (dest) == PLUS && GET_CODE (XEXP (dest, 0)) == REG)
++              {
++                      dest = XEXP (dest, 0);
++              }
++              else if (GET_CODE (dest) == REG)
++              {
++                      ;                       /* register */
++              }
++              else
++                      return 1;
++      }
++
++      if (regno >= FIRST_PSEUDO_REGISTER || REGNO (areg) >= FIRST_PSEUDO_REGISTER)
++              return 1;
++
++      dst_reg = true_regnum (dest);
++      src_reg = true_regnum (areg);
++      if (dst_reg + 1 == src_reg)
++              return 1;
++      return 0;
++}
++
++int
++regdi_ok_safe (operands)
++rtx operands[];
++{
++      rtx dest = operands[0];
++      rtx areg = XEXP (operands[2], 0);
++      int src_reg;
++      int dst_reg;
++
++
++      if (GET_CODE (dest) == MEM)
++      {
++              dest = XEXP (operands[0], 0);
++              if (GET_CODE (dest) == PLUS && GET_CODE (XEXP (dest, 0)) == REG)
++              {
++                      dest = XEXP (dest, 0);
++              }
++              else if (GET_CODE (dest) == REG)
++              {
++                      ;                       /* register */
++              }
++              else
++                      return 1;
++      }
++
++      if (REGNO (dest) >= FIRST_PSEUDO_REGISTER
++              || REGNO (areg) >= FIRST_PSEUDO_REGISTER)
++              return 1;
++
++      dst_reg = true_regnum (dest);
++      src_reg = true_regnum (areg);
++      if (dst_reg > src_reg || dst_reg + 3 < src_reg)
++      {
++              return 1;
++      }
++
++      return 0;
++}
++
++int
++regdi_ok_clobber (operands)
++rtx operands[];
++{
++      rtx dest = operands[0];
++      rtx areg = XEXP (operands[2], 0);
++      int src_reg;
++      int dst_reg;
++      int regno = REGNO (dest);
++
++      if (GET_CODE (dest) == MEM)
++      {
++              dest = XEXP (operands[0], 0);
++              if (GET_CODE (dest) == PLUS && GET_CODE (XEXP (dest, 0)) == REG)
++              {
++                      dest = XEXP (dest, 0);
++              }
++              else if (GET_CODE (dest) == REG)
++              {
++                      ;                       /* register */
++              }
++              else
++                      return 1;
++      }
++
++      if (regno >= FIRST_PSEUDO_REGISTER || REGNO (areg) >= FIRST_PSEUDO_REGISTER)
++              return 1;
++
++      dst_reg = true_regnum (dest);
++      src_reg = true_regnum (areg);
++      if (dst_reg + 3 == src_reg)
++              return 1;
++      return 0;
++}
++
++
++/***************** ARITHMETIC *******************/
++
++int
++emit_indexed_arith (insn, operands, m, cmd, iscarry)
++rtx insn;
++rtx operands[];
++int m;
++const char *cmd;
++int iscarry;
++{
++      char template[256];
++      register int i = 0;
++      char *p;
++      rtx reg = NULL;
++      int len = m * 2;
++      rtx x = operands[0];
++      int havestop = 0;
++      rtx pattern;
++      rtx next = next_real_insn (insn);
++
++
++      pattern = PATTERN (next);
++
++      if (pattern && GET_CODE (pattern) == PARALLEL)
++      {
++              pattern = XVECEXP (pattern, 0, 0);
++      }
++
++      if (followed_compare_condition (insn) != UNKNOWN
++              || GET_CODE(insn) == JUMP_INSN
++              || (pattern
++              && GET_CODE (pattern) == SET
++              && SET_DEST (pattern) == cc0_rtx)
++              || (pattern && GET_CODE (pattern) == SET
++              && SET_DEST (pattern) == pc_rtx))
++      {
++              /* very exotic case */
++
++              snprintf (template, 255, "%s\t" "%%A%d, %%A0", cmd, operands[2] ? 2 : 1);
++              output_asm_insn (template, operands);
++              snprintf (template, 255, "%s%s\t" "%%B%d, %%B0", cmd, iscarry ? "c" : "",
++                      operands[2] ? 2 : 1);
++              output_asm_insn (template, operands);
++
++              if (m == 2)
++                      return len;
++
++              snprintf (template, 255, "%s%s\t" "%%C%d, %%C0", cmd, iscarry ? "c" : "",
++                      operands[2] ? 2 : 1);
++              output_asm_insn (template, operands);
++              snprintf (template, 255, "%s%s\t" "%%D%d, %%D0", cmd, iscarry ? "c" : "",
++                      operands[2] ? 2 : 1);
++              output_asm_insn (template, operands);
++
++              return len;
++      }
++
++      if (operands[2])
++              reg = XEXP (operands[2], 0);
++      else
++              reg = XEXP (operands[1], 0);
++
++      if (GET_CODE (x) == REG)
++      {
++              int src;
++              int dst = REGNO (x);
++
++              if (!reg)
++              {
++                      reg = XEXP (operands[1], 0);
++              }
++
++              src = REGNO (reg);
++
++              /* check if registers overlap */
++              if (dst > src || (dst + m - 1) < src)
++              {
++                      ;                       /* fine ! */
++              }
++              else if ((dst + m - 1) == src)
++              {
++                      havestop = 1;           /* worse */
++              }
++              else
++              {
++                      /* cannot do reverse assigment */
++                      while (i < m)
++                      {
++                              p = (char *) (template + strlen (cmd));
++                              p += (i && iscarry) ? 3 : 2;
++                              strcpy (template, cmd);
++                              strcat (template, (i && iscarry) ? "c\t%" : "\t%");
++                              *p = 'A' + i;
++                              p++;
++                              *p = 0;
++                              strcat (template, "0, %");
++                              p += 2;
++                              *p = 'A' + i;
++                              p++;
++                              *p = 0;
++                              strcat (template, operands[2] ? "2" : "1");
++                              output_asm_insn (template, operands);
++                              i++;
++                      }
++                      return m * 3;
++              }
++      }
++
++      while (i < (m - havestop))
++      {
++              p = template + strlen (cmd);
++
++              strcpy (template, cmd);
++
++              if (i && iscarry)
++              {
++                      strcat (template, "c\t");
++                      p += 2;
++              }
++              else
++              {
++                      strcat (template, "\t");
++                      p += 1;
++              }
++              strcat (template, operands[2] ? "@%E2+, %" : "@%E1+, %");
++              p += 8;
++              *p = 'A' + i;
++              p++;
++              *p = 0;
++              strcat (template, "0");
++              p++;
++              output_asm_insn (template, operands);
++              i++;
++      }
++
++      if (havestop)
++      {
++              len++;
++              p = template + strlen (cmd);
++              strcpy (template, cmd);
++              if (i && iscarry)
++              {
++                      strcat (template, "c\t");
++                      p += 2;
++              }
++              else
++              {
++                      strcat (template, "\t");
++                      p += 1;
++              }
++              strcat (template, operands[2] ? "@%E2, %" : "@%E1, %");
++              p += 8;
++              *p = 'A' + i;
++              p++;
++              *p = 0;
++              strcat (template, "0    ;       register won't die");
++              p += 1;
++              output_asm_insn (template, operands);
++      }
++
++      if (!dead_or_set_p (insn, reg) && !havestop)
++      {
++              len++;
++              p = template + 3;
++              strcpy (template, "sub");
++              strcat (template, "\t#");
++              p += 2;
++              *p = '0' + m * 2;
++              p++;
++              *p = 0;
++
++              if (operands[2])
++                      strcat (template, ",    %E2     ;       restore %E2");
++              else
++                      strcat (template, ",    %E1     ;       restore %E1");
++              output_asm_insn (template, operands);
++      }
++
++      return len;
++}
++
++static int sameoperand_p PARAMS ((rtx, rtx));
++
++int
++sameoperand (operands, i)
++rtx operands[];
++int i;
++{
++      rtx dst = operands[0];
++      rtx src = operands[i];
++
++      return sameoperand_p (src, dst);
++}
++
++static int
++sameoperand_p (src, dst)
++rtx src;
++rtx dst;
++{
++      enum rtx_code scode = GET_CODE (src);
++      enum rtx_code dcode = GET_CODE (dst);
++      /* cannot use standard functions here 
++      cause operands have different modes:
++      */
++
++      if (scode != dcode)
++              return 0;
++
++      switch (scode)
++      {
++      case REG:
++              return REGNO (src) == REGNO (dst);
++              break;
++      case MEM:
++              return sameoperand_p (XEXP (src, 0), XEXP (dst, 0));
++              break;
++      case PLUS:
++              return sameoperand_p (XEXP (src, 0), XEXP (dst, 0))
++                      && sameoperand_p (XEXP (src, 1), XEXP (dst, 1));
++              break;
++      case CONST_INT:
++              return INTVAL (src) == INTVAL (dst);
++              break;
++      case SYMBOL_REF:
++              return XSTR (src, 0) == XSTR (dst, 0);
++              break;
++      default:
++              break;
++      }
++      return 0;
++
++}
++
++#define OUT_INSN(x,p,o) \
++      do {                            \
++      if(!x) output_asm_insn (p,o);   \
++      } while(0)
++
++
++
++/************** MOV CODE *********************************/
++
++const char *
++movstrsi_insn (insn, operands, l)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++
++      /* operands 0 and 1 are registers !!! */
++      /* operand 2 is a cnt and not zero */
++      output_asm_insn ("\n.Lmsn%=:", operands);
++      output_asm_insn ("mov.b\t@%1+,0(%0)", operands);
++      output_asm_insn ("inc\t%0", operands);
++      output_asm_insn ("dec\t%2", operands);
++      output_asm_insn ("jnz\t.Lmsn%=", operands);
++
++      return "";
++}
++
++
++const char *
++clrstrsi_insn (insn, operands, l)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++
++      /* operand 0 is a register !!! */
++      /* operand 1 is a cnt and not zero */
++      output_asm_insn ("\n.Lcsn%=:", operands);
++      output_asm_insn ("clr.b\t0(%0)  ;       clr does not support @rn+",
++              operands);
++      output_asm_insn ("inc\t%0", operands);
++      output_asm_insn ("dec\t%1", operands);
++      output_asm_insn ("jnz\t.Lcsn%=", operands);
++      return "";
++}
++
++const char *
++movstrhi_insn (insn, operands, l)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++
++      /* operands 0 and 1 are registers !!! */
++      /* operand 2 is a cnt and not zero */
++      output_asm_insn ("\n.Lmsn%=:", operands);
++      output_asm_insn ("mov.b\t@%1+,0(%0)", operands);
++      output_asm_insn ("inc\t%0", operands);
++      output_asm_insn ("dec\t%2", operands);
++      output_asm_insn ("jnz\t.Lmsn%=", operands);
++      return "";
++}
++
++const char *
++clrstrhi_insn (insn, operands, l)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++
++      /* operand 0 is a register !!! */
++      /* operand 1 is a cnt and not zero */
++      output_asm_insn ("\n.Lcsn%=:", operands);
++      output_asm_insn ("clr.b\t0(%0)", operands);
++      output_asm_insn ("inc\t%0", operands);
++      output_asm_insn ("dec\t%1", operands);
++      output_asm_insn ("jnz\t.Lcsn%=", operands);
++      return "";
++}
++
++int
++msp430_emit_indexed_mov (insn, operands, m, cmd)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int m;
++const char *cmd;
++{
++      char template[256];
++      register int i = 0;
++      char *p;
++      rtx reg = XEXP (operands[1], 0);
++      int len = m * 2;
++      rtx dst = 0;
++      int sreg,dreg = 0;
++
++      if(memory_operand(operands[0], VOIDmode))
++      {
++              if(  REG_P(XEXP(operands[0],0)))
++                      dreg = REGNO(XEXP(operands[0],0));
++              else if(GET_CODE(XEXP(operands[0],0)) == PLUS
++                      && REG_P(XEXP(XEXP(operands[0],0),0)) )
++                      dreg = REGNO(XEXP(XEXP(operands[0],0),0));
++      }
++
++
++      sreg = REGNO(XEXP(operands[1],0));
++
++      while (i < m)
++      {
++              p = template + strlen (cmd);
++
++              strcpy (template, cmd);
++              strcat (template, "\t");
++              p += 1;
++              strcat (template, "@%E1+, ");
++              p += 7;
++
++              if(dreg==sreg)
++              {
++                      *p = '-'; p++;
++                      *p = '2'; p++;
++                      *p = '+'; p++;
++              }
++
++              *p = '%'; p++;
++              *p = 'A' + ((dreg==sreg)?0:i);
++
++              p++;
++              *p = 0;
++              strcat (template, "0");
++              p += 1;
++              output_asm_insn (template, operands);
++              i++;
++      }
++
++      if (!dead_or_set_p (insn, reg))
++      {
++              len++;
++              p = template + 3;
++              strcpy (template, "sub");
++              strcat (template, "\t#");
++              p += 2;
++              *p = '0' + m * 2;
++              p++;
++              *p = 0;
++              strcat (template, ",    %E1     ;       restore %E1");
++              output_asm_insn (template, operands);
++      }
++
++      return len;
++}
++
++const char *
++msp430_emit_indexed_mov2 (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++      msp430_emit_indexed_mov (insn, operands, 2, "mov");
++      return "";
++}
++
++const char *
++msp430_emit_indexed_mov4 (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++      msp430_emit_indexed_mov (insn, operands, 4, "mov");
++      return "";
++}
++
++const char *
++movsisf_regmode (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++      rtx dest = operands[0];
++      rtx src = operands[1];
++      rtx areg = XEXP (src, 0);
++      int src_reg = true_regnum (areg);
++      int dst_reg = true_regnum (dest);
++
++
++      if (dst_reg > src_reg || dst_reg + 1 < src_reg)
++      {
++              output_asm_insn ("mov\t@%E1+, %A0", operands);
++              output_asm_insn ("mov\t@%E1+, %B0", operands);
++              if (!dead_or_set_p (insn, areg))
++              {
++                      output_asm_insn ("sub\t#4, %E1\t;\trestore %E1", operands);
++              }
++              return "";
++      }
++      else if (dst_reg + 1 == src_reg)
++      {
++              output_asm_insn ("mov\t@%E1+, %A0", operands);
++              output_asm_insn ("mov\t@%E1, %B0", operands);
++              return "";
++      }
++      else
++      {
++              /* destination overlaps with source.
++              so, update destination in reverse way */
++              output_asm_insn ("mov\t%B1, %B0", operands);
++              output_asm_insn ("mov\t@%E1, %A0", operands);
++      }
++
++      return "";                      /* make compiler happy */
++}
++
++
++/* From Max Behensky <maxb@twinlanes.com>  
++This function tells you what the index register in an operand is.  It
++returns the register number, or -1 if it is not an indexed operand */
++static int get_indexed_reg PARAMS ((rtx));
++static int
++get_indexed_reg (x)
++rtx x;
++{
++      int code;
++
++      code = GET_CODE (x);
++
++      if (code != MEM)
++              return (-1);
++
++      x = XEXP (x, 0);
++      code = GET_CODE (x);
++      if (code == REG)
++              return (REGNO (x));
++
++      if (code != PLUS)
++              return (-1);
++
++      x = XEXP (x, 0);
++      code = GET_CODE (x);
++      if (code != REG)
++              return (-1);
++
++      return (REGNO (x));
++}
++
++
++const char *
++msp430_movesi_code (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      rtx op0 = operands[0];
++      rtx op1 = operands[1];
++
++
++      if (memory_operand (op0, VOIDmode)
++              && memory_operand (op1, VOIDmode) && zero_shifted (op1))
++      {
++              if (!len)
++                      msp430_emit_indexed_mov2 (insn, operands, NULL);
++              else
++                      *len = 5;
++              return "";
++      }       
++      else if (register_operand (op0, VOIDmode)
++              && memory_operand (op1, VOIDmode) && zero_shifted (op1))
++      {
++              if (!len)
++                      movsisf_regmode (insn, operands, NULL);
++              else
++                      *len = 3;
++              return "";
++      }
++
++      if (!len)
++      {
++              if ((register_operand (op0, VOIDmode)
++                      && register_operand (op1, VOIDmode)
++                      && REGNO (op1) + 1 == REGNO (op0))
++                      || (register_operand (op0, VOIDmode)
++                      && memory_operand (op1, VOIDmode)
++                      && get_indexed_reg (op1) == true_regnum (op0)))
++              {
++                      output_asm_insn ("mov\t%B1, %B0", operands);
++                      output_asm_insn ("mov\t%A1, %A0", operands);
++              }
++              else
++              {
++                      output_asm_insn ("mov\t%A1, %A0", operands);
++                      output_asm_insn ("mov\t%B1, %B0", operands);
++              }
++      }
++      else
++      {
++              *len = 2;                       /* base length */
++
++              if (register_operand (op0, VOIDmode))
++                      *len += 0;
++              else if (memory_operand (op0, VOIDmode))
++                      *len += 2;
++
++              if (register_operand (op1, VOIDmode))
++                      *len += 0;
++              else if (memory_operand (op1, VOIDmode))
++                      *len += 2;
++              else if (immediate_operand (op1, VOIDmode))
++                      *len += 2;
++      }
++
++      return "";
++}
++
++const char *
++movdidf_regmode (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++      rtx dest = operands[0];
++      rtx src = operands[1];
++      rtx areg = XEXP (src, 0);
++
++      int src_reg = true_regnum (areg);
++      int dst_reg = true_regnum (dest);
++
++
++      if (dst_reg > src_reg || dst_reg + 3 < src_reg)
++      {
++              output_asm_insn ("mov\t@%E1+, %A0", operands);
++              output_asm_insn ("mov\t@%E1+, %B0", operands);
++              output_asm_insn ("mov\t@%E1+, %C0", operands);
++              output_asm_insn ("mov\t@%E1+, %D0", operands);
++              if (!dead_or_set_p (insn, areg))
++              {
++                      output_asm_insn ("sub\t#8, %E1\t;\trestore %E1", operands);
++              }
++      }
++      else if (dst_reg + 3 == src_reg)
++      {
++              output_asm_insn ("mov\t@%E1+, %A0", operands);
++              output_asm_insn ("mov\t@%E1+, %B0", operands);
++              output_asm_insn ("mov\t@%E1+, %C0", operands);
++              output_asm_insn ("mov\t@%E1,  %D0       ;       %E1 == %D0", operands);
++      }
++      else
++      {
++              /* destination overlaps source.
++              so, update destination in reverse way */
++              output_asm_insn ("mov\t%D1, %D0 ; %E1 overlaps wit one of %A0 - %D0",
++                      operands);
++              output_asm_insn ("mov\t%C1, %C0", operands);
++              output_asm_insn ("mov\t%B1, %B0", operands);
++              output_asm_insn ("mov\t@%E1, %A0", operands);
++      }
++
++      return "";
++}
++
++const char *
++msp430_movedi_code (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      rtx op0 = operands[0];
++      rtx op1 = operands[1];
++
++      if (memory_operand (op0, DImode)
++              && memory_operand (op1, DImode) && zero_shifted (op1))
++      {
++              if (!len)
++                      msp430_emit_indexed_mov4 (insn, operands, NULL);
++              else
++                      *len = 9;
++              return "";
++      }
++      else if (register_operand (op0, DImode)
++              && memory_operand (op1, DImode) && zero_shifted (op1))
++      {
++              if (!len)
++                      movdidf_regmode (insn, operands, NULL);
++              else
++                      *len = 5;
++              return "";
++      }
++
++      if (!len)
++      {
++              if (register_operand (op0, SImode)
++                      && register_operand (op1, SImode) && REGNO (op1) + 3 == REGNO (op0))
++              {
++                      output_asm_insn ("mov\t%D1, %D0", operands);
++                      output_asm_insn ("mov\t%C1, %C0", operands);
++                      output_asm_insn ("mov\t%B1, %B0", operands);
++                      output_asm_insn ("mov\t%A1, %A0", operands);
++              }
++              else
++              {
++                      output_asm_insn ("mov\t%A1, %A0", operands);
++                      output_asm_insn ("mov\t%B1, %B0", operands);
++                      output_asm_insn ("mov\t%C1, %C0", operands);
++                      output_asm_insn ("mov\t%D1, %D0", operands);
++              }
++      }
++      else
++      {
++              *len = 4;                       /* base length */
++
++              if (register_operand (op0, DImode))
++                      *len += 0;
++              else if (memory_operand (op0, DImode))
++                      *len += 4;
++
++              if (register_operand (op1, DImode))
++                      *len += 0;
++              else if (memory_operand (op1, DImode))
++                      *len += 4;
++              else if (immediate_operand (op1, DImode))
++                      *len += 4;
++      }
++
++      return "";
++}
++
++
++
++
++/**************       ADD CODE *********************************/
++
++
++const char *
++msp430_emit_indexed_add2 (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++      emit_indexed_arith (insn, operands, 2, "add", 1);
++      return "";
++}
++
++const char *
++msp430_emit_indexed_add4 (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++      emit_indexed_arith (insn, operands, 4, "add", 1);
++      return "";
++}
++
++const char *
++msp430_addsi_code (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      rtx op0 = operands[0];
++      rtx op2 = operands[2];
++      rtx ops[4];
++
++      if (memory_operand (op2, SImode)
++              && zero_shifted (operands[2]) && regsi_ok_safe (operands))
++      {
++              if (!len)
++                      msp430_emit_indexed_add2 (insn, operands, NULL);
++              else
++              {
++                      if (memory_operand (op0, SImode))
++                              *len = 5;
++                      else if (register_operand (op0, SImode))
++                              *len = 3;
++              }
++              return "";
++      }
++      else if (memory_operand (op2, SImode)
++              && zero_shifted (operands[2]) && regsi_ok_clobber (operands))
++      {
++              if (!len)
++              {
++                      output_asm_insn ("add\t@%E2+, %A0", operands);
++                      output_asm_insn ("addc\t@%E2+, %B0", operands);
++              }
++              else
++              {
++                      if (register_operand (op0, SImode))
++                              *len = 2;
++                      else if (memory_operand (op0, SImode))
++                              *len = 4;
++                      else
++                              abort ();
++              }
++              return "";
++      }
++
++      ops[0] = operands[0];
++      ops[2] = operands[2];
++
++      if (!len)
++      {
++              output_asm_insn ("add\t%A2, %A0", ops);
++              output_asm_insn ("addc\t%B2, %B0", ops);
++      }
++
++      if (len)
++      {
++              *len = 2;                       /* base length */
++
++              if (register_operand (ops[0], SImode))
++                      *len += 0;
++              else if (memory_operand (ops[0], SImode))
++                      *len += 2;
++
++              if (register_operand (ops[2], SImode))
++                      *len += 0;
++              else if (memory_operand (ops[2], SImode))
++                      *len += 2;
++              else if (immediate_operand (ops[2], SImode))
++              {
++                      int x = INTVAL (ops[2]);
++                      if (x == -2 || x == -4 || x == -8)
++                      {
++                              *len += 1;
++                      }
++                      else
++                              *len += 2;
++              }
++      }
++      return "";
++}
++
++const char *
++msp430_adddi_code (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      rtx op0 = operands[0];
++      rtx op2 = operands[2];
++
++      if (memory_operand (op2, DImode)
++              && zero_shifted (operands[2]) && regdi_ok_safe (operands))
++      {
++              if (!len)
++                      msp430_emit_indexed_add4 (insn, operands, NULL);
++              else
++              {
++                      if (memory_operand (op0, DImode))
++                              *len = 9;
++                      else if (register_operand (op0, DImode))
++                              *len = 5;
++              }
++
++              return "";
++      }
++      else if (memory_operand (op2, DImode)
++              && zero_shifted (operands[2]) && regdi_ok_clobber (operands))
++      {
++              if (!len)
++              {
++                      output_asm_insn ("add\t@%E2+, %A0", operands);
++                      output_asm_insn ("addc\t@%E2+, %B0", operands);
++                      output_asm_insn ("addc\t@%E2+, %C0", operands);
++                      output_asm_insn ("addc\t@%E2+, %D0", operands);
++              }
++              else
++              {
++                      if (register_operand (op0, DImode))
++                              *len = 4;
++                      else if (memory_operand (op0, DImode))
++                              *len = 8;
++                      else
++                              abort ();
++              }
++              return "";
++      }
++
++      if (!len)
++      {
++              output_asm_insn ("add\t%A2, %A0", operands);
++              output_asm_insn ("addc\t%B2, %B0", operands);
++              output_asm_insn ("addc\t%C2, %C0", operands);
++              output_asm_insn ("addc\t%D2, %D0", operands);
++      }
++      else
++      {
++              *len = 4;                       /* base length */
++
++              if (register_operand (op0, DImode))
++                      *len += 0;
++              else if (memory_operand (op0, DImode))
++                      *len += 4;
++
++              if (register_operand (op2, DImode))
++                      *len += 0;
++              else if (memory_operand (op2, DImode))
++                      *len += 4;
++              else if (immediate_operand (op2, DImode))
++              {
++                      int x = INTVAL (op2);
++
++                      if (x == -2 || x == -4 || x == -8)
++                              *len += 0;
++                      else
++                              *len += 4;
++              }
++              else
++                      abort ();
++      }
++
++      return "";
++}
++
++
++/**************       SUB CODE *********************************/
++
++const char *
++msp430_emit_indexed_sub2 (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++      emit_indexed_arith (insn, operands, 2, "sub", 1);
++      return "";
++}
++
++const char *
++msp430_emit_indexed_sub4 (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++      emit_indexed_arith (insn, operands, 4, "sub", 1);
++      return "";
++}
++
++const char *
++msp430_subsi_code (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      rtx op0 = operands[0];
++      rtx op2 = operands[2];
++
++      if (memory_operand (op2, SImode)
++              && zero_shifted (operands[2]) && regsi_ok_safe (operands))
++      {
++              if (!len)
++                      msp430_emit_indexed_sub2 (insn, operands, NULL);
++              else
++              {
++                      if (memory_operand (op0, SImode))
++                              *len = 5;
++                      else if (register_operand (op0, SImode))
++                              *len = 3;
++              }
++
++              return "";
++      }
++      else if (memory_operand (op2, SImode)
++              && zero_shifted (operands[2]) && regsi_ok_clobber (operands))
++      {
++              if (!len)
++              {
++                      output_asm_insn ("sub\t@%E2+, %A0", operands);
++                      output_asm_insn ("subc\t@%E2+, %B0", operands);
++              }
++              else
++              {
++                      if (register_operand (op0, SImode))
++                              *len = 2;
++                      else if (memory_operand (op0, SImode))
++                              *len = 4;
++                      else
++                              abort ();
++              }
++              return "";
++      }
++
++      if (!len)
++      {
++              output_asm_insn ("sub\t%A2, %A0", operands);
++              output_asm_insn ("subc\t%B2, %B0", operands);
++      }
++      else
++      {
++              *len = 2;                       /* base length */
++
++              if (register_operand (op0, SImode))
++                      *len += 0;
++              else if (memory_operand (op0, SImode))
++                      *len += 2;
++
++              if (register_operand (op2, SImode))
++                      *len += 0;
++              else if (memory_operand (op2, SImode))
++                      *len += 2;
++              else if (immediate_operand (op2, SImode))
++                      *len += 2;
++      }
++
++      return "";
++}
++
++
++const char *
++msp430_subdi_code (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      rtx op0 = operands[0];
++      rtx op2 = operands[2];
++
++      if (memory_operand (op2, DImode)
++              && zero_shifted (operands[2]) && regdi_ok_safe (operands))
++      {
++              if (!len)
++                      msp430_emit_indexed_sub4 (insn, operands, NULL);
++              else
++              {
++                      if (memory_operand (op0, DImode))
++                              *len = 9;
++                      else if (register_operand (op0, DImode))
++                              *len = 5;
++              }
++
++              return "";
++      }
++      else if (memory_operand (op2, DImode)
++              && zero_shifted (operands[2]) && regdi_ok_clobber (operands))
++      {
++              if (!len)
++              {
++                      output_asm_insn ("sub\t@%E2+, %A0", operands);
++                      output_asm_insn ("subc\t@%E2+, %B0", operands);
++                      output_asm_insn ("subc\t@%E2+, %C0", operands);
++                      output_asm_insn ("subc\t@%E2+, %D0", operands);
++              }
++              else
++              {
++                      if (register_operand (op0, DImode))
++                              *len = 4;
++                      else if (memory_operand (op0, DImode))
++                              *len = 8;
++                      else
++                              abort ();
++              }
++              return "";
++      }
++
++      if (!len)
++      {
++              output_asm_insn ("sub\t%A2, %A0", operands);
++              output_asm_insn ("subc\t%B2, %B0", operands);
++              output_asm_insn ("subc\t%C2, %C0", operands);
++              output_asm_insn ("subc\t%D2, %D0", operands);
++      }
++      else
++      {
++              *len = 4;                       /* base length */
++
++              if (register_operand (op0, DImode))
++                      *len += 0;
++              else if (memory_operand (op0, DImode))
++                      *len += 4;
++
++              if (register_operand (op2, DImode))
++                      *len += 0;
++              else if (memory_operand (op2, DImode))
++                      *len += 4;
++              else if (immediate_operand (op2, DImode))
++                      *len += 4;
++              else
++                      abort ();
++      }
++
++      return "";
++}
++
++
++/**************       AND CODE *********************************/
++
++const char *
++msp430_emit_indexed_and2 (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++      emit_indexed_arith (insn, operands, 2, "and", 0);
++      return "";
++}
++
++const char *
++msp430_emit_indexed_and4 (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++      emit_indexed_arith (insn, operands, 4, "and", 0);
++      return "";
++}
++
++const char *
++msp430_emit_immediate_and2 (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int v;
++      int l = INTVAL (operands[2]);
++      int r = REG_P (operands[0]);
++      int list1 = ((~1) & 0xffff);
++      int list2 = ((~2) & 0xffff);
++      int list4 = ((~4) & 0xffff);
++      int list8 = ((~8) & 0xffff);
++
++      rtx op[4];
++
++      op[0] = operands[0];
++      op[1] = operands[1];
++      op[2] = operands[2];
++
++      /* check nibbles */
++
++      v = (l) & 0xffff;
++      if (v != 0xffff)
++      {
++              if (v == list1 || v == list2 || v == list4 || v == list8)
++              {
++                      op[2] = gen_rtx_CONST_INT (SImode, ~v);
++                      OUT_INSN (len, "bic\t%A2, %A0", op);
++                      dummy++;
++                      if (!r)
++                              dummy++;
++              }
++              else
++              {
++                      op[2] = gen_rtx_CONST_INT (SImode, v);
++                      OUT_INSN (len, "and\t%A2, %A0", op);
++                      dummy++;
++                      dummy++;
++                      if (!r)
++                              dummy++;
++                      if (v == 0 || v == 1 || v == 2 || v == 4 || v == 8)
++                              dummy--;
++              }
++      }
++
++      v = (l >> 16) & 0xffff;
++      if (v != 0xffff)
++      {
++              if (v == list1 || v == list2 || v == list4 || v == list8)
++              {
++                      op[2] = gen_rtx_CONST_INT (SImode, ~v);
++                      OUT_INSN (len, "bic\t%A2, %B0", op);
++                      dummy++;
++                      if (!r)
++                              dummy++;
++              }
++              else
++              {
++                      op[2] = gen_rtx_CONST_INT (SImode, v);
++                      OUT_INSN (len, "and\t%A2, %B0", op);
++                      dummy++;
++                      dummy++;
++                      if (!r)
++                              dummy++;
++                      if (v == 0 || v == 1 || v == 2 || v == 4 || v == 8)
++                              dummy--;
++              }
++      }
++
++      if (len)
++              *len = dummy;
++      return "";
++}
++
++const char *
++msp430_emit_immediate_and4 (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int v;
++      int l = CONST_DOUBLE_LOW (operands[2]);
++      int h = CONST_DOUBLE_HIGH (operands[2]);
++      int r = REG_P (operands[0]);
++      int list1 = ((~1) & 0xffff);
++      int list2 = ((~2) & 0xffff);
++      int list4 = ((~4) & 0xffff);
++      int list8 = ((~8) & 0xffff);
++      rtx op[4];
++
++      op[0] = operands[0];
++      op[1] = operands[1];
++      op[2] = operands[2];
++
++      /* check if operand 2 is really const_double */
++      if (GET_CODE (operands[2]) == CONST_INT)
++      {
++              l = INTVAL (operands[2]);
++              h = 0;
++      }
++
++      /* check nibbles */
++      v = (l) & 0xffff;
++      if (v != 0xffff)
++      {
++              if (v == list1 || v == list2 || v == list4 || v == list8)
++              {
++                      op[2] = gen_rtx_CONST_INT (SImode, ~v);
++                      OUT_INSN (len, "bic\t%A2, %A0", op);
++                      dummy++;
++                      if (!r)
++                              dummy++;
++              }
++              else
++              {
++                      op[2] = gen_rtx_CONST_INT (SImode, v);
++                      OUT_INSN (len, "and\t%A2, %A0", op);
++                      dummy++;
++                      dummy++;
++                      if (!r)
++                              dummy++;
++                      if (v == 0 || v == 1 || v == 2 || v == 4 || v == 8)
++                              dummy--;
++              }
++      }
++
++      v = (l >> 16) & 0xffff;
++      if (v != 0xffff)
++      {
++              if (v == list1 || v == list2 || v == list4 || v == list8)
++              {
++                      op[2] = gen_rtx_CONST_INT (SImode, ~v);
++                      OUT_INSN (len, "bic\t%A2, %B0", op);
++                      dummy++;
++                      if (!r)
++                              dummy++;
++              }
++              else
++              {
++                      op[2] = gen_rtx_CONST_INT (SImode, v);
++                      OUT_INSN (len, "and\t%A2, %B0", op);
++                      dummy++;
++                      dummy++;
++                      if (!r)
++                              dummy++;
++                      if (v == 0 || v == 1 || v == 2 || v == 4 || v == 8)
++                              dummy--;
++              }
++      }
++
++      v = (h) & 0xffff;
++      if (v != 0xffff)
++      {
++              if (v == list1 || v == list2 || v == list4 || v == list8)
++              {
++                      op[2] = gen_rtx_CONST_INT (SImode, ~v);
++                      OUT_INSN (len, "bic\t%A2, %C0", op);
++                      dummy++;
++                      if (!r)
++                              dummy++;
++              }
++              else
++              {
++                      op[2] = gen_rtx_CONST_INT (SImode, v);
++                      OUT_INSN (len, "and\t%A2, %C0", op);
++                      dummy++;
++                      dummy++;
++                      if (!r)
++                              dummy++;
++                      if (v == 0 || v == 1 || v == 2 || v == 4 || v == 8)
++                              dummy--;
++              }
++      }
++
++      v = (h >> 16) & 0xffff;
++      if (v != 0xffff)
++      {
++              if (v == list1 || v == list2 || v == list4 || v == list8)
++              {
++                      op[2] = gen_rtx_CONST_INT (SImode, ~v);
++                      OUT_INSN (len, "bic\t%A2, %D0", op);
++                      dummy++;
++                      if (!r)
++                              dummy++;
++              }
++              else
++              {
++                      op[2] = gen_rtx_CONST_INT (SImode, v);
++                      OUT_INSN (len, "and\t%A2, %D0", op);
++                      dummy++;
++                      dummy++;
++                      if (!r)
++                              dummy++;
++                      if (v == 0 || v == 1 || v == 2 || v == 4 || v == 8)
++                              dummy--;
++              }
++      }
++
++      if (len)
++              *len = dummy;
++      return "";
++}
++
++const char *
++msp430_andsi_code (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      rtx op0 = operands[0];
++      rtx op2 = operands[2];
++
++      if (nonimmediate_operand (op0, SImode) && immediate_operand (op2, SImode))
++      {
++              if (!len)
++                      msp430_emit_immediate_and2 (insn, operands, NULL);
++              return "";
++      }
++
++      if (memory_operand (op2, SImode)
++              && zero_shifted (operands[2]) && regsi_ok_safe (operands))
++      {
++              if (!len)
++                      msp430_emit_indexed_and2 (insn, operands, NULL);
++              else
++              {
++                      if (memory_operand (op0, SImode))
++                              *len = 5;
++                      else if (register_operand (op0, SImode))
++                              *len = 3;
++              }
++
++              return "";
++      }
++      else if (memory_operand (op2, SImode)
++              && zero_shifted (operands[2]) && regsi_ok_clobber (operands))
++      {
++              if (!len)
++              {
++                      output_asm_insn ("and\t@%E2+, %A0", operands);
++                      output_asm_insn ("and\t@%E2+, %B0", operands);
++              }
++              else
++              {
++                      if (register_operand (op0, SImode))
++                              *len = 2;
++                      else if (memory_operand (op0, SImode))
++                              *len = 4;
++                      else
++                              abort ();
++              }
++              return "";
++      }
++
++      if (!len)
++      {
++              output_asm_insn ("and\t%A2, %A0", operands);
++              output_asm_insn ("and\t%B2, %B0", operands);
++      }
++      else
++      {
++              *len = 2;                       /* base length */
++
++              if (register_operand (op0, SImode))
++                      *len += 0;
++              else if (memory_operand (op0, SImode))
++                      *len += 2;
++
++              if (register_operand (op2, SImode))
++                      *len += 0;
++              else if (memory_operand (op2, SImode))
++                      *len += 2;
++              else if (immediate_operand (op2, SImode))
++                      *len += 2;
++      }
++
++      return "";
++}
++
++
++const char *
++msp430_anddi_code (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      rtx op0 = operands[0];
++      rtx op2 = operands[2];
++
++      if (nonimmediate_operand (op0, DImode) && immediate_operand (op2, DImode))
++      {
++              if (!len)
++                      msp430_emit_immediate_and4 (insn, operands, NULL);
++              return "";
++      }
++
++      if (memory_operand (op2, DImode)
++              && zero_shifted (operands[2]) && regdi_ok_safe (operands))
++      {
++              if (!len)
++                      msp430_emit_indexed_and4 (insn, operands, NULL);
++              else
++              {
++                      if (memory_operand (op0, DImode))
++                              *len = 9;
++                      else if (register_operand (op0, DImode))
++                              *len = 5;
++              }
++
++              return "";
++      }
++      else if (memory_operand (op2, DImode)
++              && zero_shifted (operands[2]) && regdi_ok_clobber (operands))
++      {
++              if (!len)
++              {
++                      output_asm_insn ("and\t@%E2+, %A0", operands);
++                      output_asm_insn ("and\t@%E2+, %B0", operands);
++                      output_asm_insn ("and\t@%E2+, %C0", operands);
++                      output_asm_insn ("and\t@%E2+, %D0", operands);
++              }
++              else
++              {
++                      if (register_operand (op0, DImode))
++                              *len = 4;
++                      else if (memory_operand (op0, DImode))
++                              *len = 8;
++                      else
++                              abort ();
++              }
++              return "";
++      }
++
++      if (!len)
++      {
++              output_asm_insn ("and\t%A2, %A0", operands);
++              output_asm_insn ("and\t%B2, %B0", operands);
++              output_asm_insn ("and\t%C2, %C0", operands);
++              output_asm_insn ("and\t%D2, %D0", operands);
++      }
++      else
++      {
++              *len = 4;                       /* base length */
++
++              if (register_operand (op0, DImode))
++                      *len += 0;
++              else if (memory_operand (op0, DImode))
++                      *len += 4;
++
++              if (register_operand (op2, DImode))
++                      *len += 0;
++              else if (memory_operand (op2, DImode))
++                      *len += 4;
++              else if (immediate_operand (op2, DImode))
++                      *len += 4;
++              else
++                      abort ();
++      }
++
++      return "";
++}
++
++/**************       IOR CODE *********************************/
++
++const char *
++msp430_emit_indexed_ior2 (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++      emit_indexed_arith (insn, operands, 2, "bis", 0);
++      return "";
++}
++
++const char *
++msp430_emit_indexed_ior4 (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++      emit_indexed_arith (insn, operands, 4, "bis", 0);
++      return "";
++}
++
++const char *
++msp430_emit_immediate_ior2 (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int l = INTVAL (operands[2]);
++      int r = REG_P (operands[0]);
++      int v;
++
++
++      v = l & 0xffff;
++
++      if (v)
++      {
++              OUT_INSN (len, "bis\t%A2,%A0", operands);
++              dummy++;
++              dummy++;
++              if (v == 0xffff || v == 1 || v == 2 || v == 4 || v == 8)
++                      dummy--;
++              if (!r)
++                      dummy++;
++      }
++
++      v = (l >> 16) & 0xffff;
++
++      if (v)
++      {
++              OUT_INSN (len, "bis\t%B2,%B0", operands);
++              dummy++;
++              dummy++;
++              if (v == 0xffff || v == 1 || v == 2 || v == 4 || v == 8)
++                      dummy--;
++              if (!r)
++                      dummy++;
++      }
++
++      if (len)
++              *len = dummy;
++      return "";
++}
++
++const char *
++msp430_emit_immediate_ior4 (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int l = CONST_DOUBLE_LOW (operands[2]);
++      int h = CONST_DOUBLE_HIGH (operands[2]);
++      int r = REG_P (operands[0]);
++      int v;
++
++      if (GET_CODE (operands[2]) == CONST_INT)
++      {
++              l = INTVAL (operands[2]);
++              h = 0;
++      }
++
++      v = l & 0xffff;
++
++      if (v)
++      {
++              OUT_INSN (len, "bis\t%A2,%A0", operands);
++              dummy++;
++              dummy++;
++              if (v == 0xffff || v == 1 || v == 2 || v == 4 || v == 8)
++                      dummy--;
++              if (!r)
++                      dummy++;
++      }
++
++      v = (l >> 16) & 0xffff;
++
++      if (v)
++      {
++              OUT_INSN (len, "bis\t%B2,%B0", operands);
++              dummy++;
++              dummy++;
++              if (v == 0xffff || v == 1 || v == 2 || v == 4 || v == 8)
++                      dummy--;
++              if (!r)
++                      dummy++;
++      }
++
++      l = h;
++      v = l & 0xffff;
++
++      if (v)
++      {
++              OUT_INSN (len, "bis\t%C2,%C0", operands);
++              dummy++;
++              dummy++;
++              if (v == 0xffff || v == 1 || v == 2 || v == 4 || v == 8)
++                      dummy--;
++              if (!r)
++                      dummy++;
++      }
++
++      v = (l >> 16) & 0xffff;
++
++      if (v)
++      {
++              OUT_INSN (len, "bis\t%D2,%D0", operands);
++              dummy++;
++              dummy++;
++              if (v == 0xffff || v == 1 || v == 2 || v == 4 || v == 8)
++                      dummy--;
++              if (!r)
++                      dummy++;
++      }
++
++      if (len)
++              *len = dummy;
++      return "";
++}
++
++const char *
++msp430_iorsi_code (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      rtx op0 = operands[0];
++      rtx op2 = operands[2];
++
++      if (nonimmediate_operand (op0, SImode) && immediate_operand (op2, SImode))
++      {
++              if (!len)
++                      msp430_emit_immediate_ior2 (insn, operands, NULL);
++              return "";
++      }
++
++      if (memory_operand (op2, SImode)
++              && zero_shifted (operands[2]) && regsi_ok_safe (operands))
++      {
++              if (!len)
++                      msp430_emit_indexed_ior2 (insn, operands, NULL);
++              else
++              {
++                      if (memory_operand (op0, SImode))
++                              *len = 5;
++                      else if (register_operand (op0, SImode))
++                              *len = 3;
++              }
++
++              return "";
++      }
++      else if (memory_operand (op2, SImode)
++              && zero_shifted (operands[2]) && regsi_ok_clobber (operands))
++      {
++              if (!len)
++              {
++                      output_asm_insn ("bis\t@%E2+, %A0", operands);
++                      output_asm_insn ("bis\t@%E2+, %B0", operands);
++              }
++              else
++              {
++                      if (register_operand (op0, SImode))
++                              *len = 2;
++                      else if (memory_operand (op0, SImode))
++                              *len = 4;
++                      else
++                              abort ();
++              }
++              return "";
++      }
++
++      if (!len)
++      {
++              output_asm_insn ("bis\t%A2, %A0", operands);
++              output_asm_insn ("bis\t%B2, %B0", operands);
++      }
++      else
++      {
++              *len = 2;                       /* base length */
++
++              if (register_operand (op0, SImode))
++                      *len += 0;
++              else if (memory_operand (op0, SImode))
++                      *len += 2;
++
++              if (register_operand (op2, SImode))
++                      *len += 0;
++              else if (memory_operand (op2, SImode))
++                      *len += 2;
++              else if (immediate_operand (op2, SImode))
++                      *len += 2;
++      }
++
++      return "";
++}
++
++const char *
++msp430_iordi_code (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      rtx op0 = operands[0];
++      rtx op2 = operands[2];
++
++      if (nonimmediate_operand (op0, DImode) && immediate_operand (op2, DImode))
++      {
++              if (!len)
++                      msp430_emit_immediate_ior4 (insn, operands, NULL);
++              return "";
++      }
++
++      if (memory_operand (op2, DImode)
++              && zero_shifted (operands[2]) && regdi_ok_safe (operands))
++      {
++              if (!len)
++                      msp430_emit_indexed_ior4 (insn, operands, NULL);
++              else
++              {
++                      if (memory_operand (op0, DImode))
++                              *len = 9;
++                      else if (register_operand (op0, DImode))
++                              *len = 5;
++              }
++
++              return "";
++      }
++      else if (memory_operand (op2, DImode)
++              && zero_shifted (operands[2]) && regdi_ok_clobber (operands))
++      {
++              if (!len)
++              {
++                      output_asm_insn ("bis\t@%E2+, %A0", operands);
++                      output_asm_insn ("bis\t@%E2+, %B0", operands);
++                      output_asm_insn ("bis\t@%E2+, %C0", operands);
++                      output_asm_insn ("bis\t@%E2+, %D0", operands);
++              }
++              else
++              {
++                      if (register_operand (op0, DImode))
++                              *len = 4;
++                      else if (memory_operand (op0, DImode))
++                              *len = 8;
++                      else
++                              abort ();
++              }
++              return "";
++      }
++
++      if (!len)
++      {
++              output_asm_insn ("bis\t%A2, %A0", operands);
++              output_asm_insn ("bis\t%B2, %B0", operands);
++              output_asm_insn ("bis\t%C2, %C0", operands);
++              output_asm_insn ("bis\t%D2, %D0", operands);
++      }
++      else
++      {
++              *len = 4;                       /* base length */
++
++              if (register_operand (op0, DImode))
++                      *len += 0;
++              else if (memory_operand (op0, DImode))
++                      *len += 4;
++
++              if (register_operand (op2, DImode))
++                      *len += 0;
++              else if (memory_operand (op2, DImode))
++                      *len += 4;
++              else if (immediate_operand (op2, DImode))
++                      *len += 4;
++              else
++                      abort ();
++      }
++
++      return "";
++}
++
++
++/************************* XOR CODE *****************/
++
++const char *
++msp430_emit_indexed_xor2 (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l;
++{
++      int dummy = emit_indexed_arith (insn, operands, 2, "xor", 0);
++      if (!l)
++              l = &dummy;
++      *l = dummy;
++      return "";
++}
++
++const char *
++msp430_emit_indexed_xor4 (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l;
++{
++      int dummy = emit_indexed_arith (insn, operands, 4, "xor", 0);
++      if (!l)
++              l = &dummy;
++      *l = dummy;
++      return "";
++}
++
++
++const char *
++msp430_emit_indexed_xor2_3 (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l;
++{
++      int dummy;
++      rtx x = operands[2];
++      if (zero_shifted (x))
++      {
++              dummy = emit_indexed_arith (insn, operands, 2, "xor", 0);
++      }
++      else
++      {
++              dummy = 6;
++              output_asm_insn ("xor\t%A2, %A0", operands);
++              output_asm_insn ("xor\t%B2, %B0", operands);
++      }
++
++      if (!l)
++              l = &dummy;
++      *l = dummy;
++      return "";
++}
++
++const char *
++msp430_emit_indexed_xor4_3 (insn, operands, l)
++rtx insn;
++rtx operands[];
++int *l;
++{
++
++      int dummy;
++      rtx x = operands[2];
++      if (zero_shifted (x))
++      {
++              dummy = emit_indexed_arith (insn, operands, 4, "xor", 0);
++      }
++      else
++      {
++              dummy = 8;
++              output_asm_insn ("xor\t%A2, %A0", operands);
++              output_asm_insn ("xor\t%B2, %B0", operands);
++              output_asm_insn ("xor\t%C2, %C0", operands);
++              output_asm_insn ("xor\t%D2, %D0", operands);
++      }
++
++      if (!l)
++              l = &dummy;
++      *l = dummy;
++      return "";
++}
++
++const char *
++msp430_xorsi_code (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      rtx op0 = operands[0];
++      rtx op2 = operands[2];
++
++      if (memory_operand (op2, SImode)
++              && zero_shifted (operands[2]) && regsi_ok_safe (operands))
++      {
++              if (!len)
++                      msp430_emit_indexed_xor2 (insn, operands, NULL);
++              else
++              {
++                      if (memory_operand (op0, SImode))
++                              *len = 5;
++                      else if (register_operand (op0, SImode))
++                              *len = 3;
++              }
++
++              return "";
++      }
++      else if (memory_operand (op2, SImode)
++              && zero_shifted (operands[2]) && regsi_ok_clobber (operands))
++      {
++              if (!len)
++              {
++                      output_asm_insn ("xor\t@%E2+, %A0", operands);
++                      output_asm_insn ("xor\t@%E2+, %B0", operands);
++              }
++              else
++              {
++                      if (register_operand (op0, SImode))
++                              *len = 2;
++                      else if (memory_operand (op0, SImode))
++                              *len = 4;
++                      else
++                              abort ();
++              }
++              return "";
++      }
++
++      if (!len)
++      {
++
++              if (immediate_operand (op2, SImode))
++              {
++                      if (INTVAL (op2) & 0xfffful)
++                              output_asm_insn ("xor\t%A2, %A0", operands);
++
++                      if (INTVAL (op2) & 0xffff0000ul)
++                              output_asm_insn ("xor\t%B2, %B0", operands);
++              }
++              else
++              {
++                      output_asm_insn ("xor\t%A2, %A0", operands);
++                      output_asm_insn ("xor\t%B2, %B0", operands);
++              }
++
++      }
++      else
++      {
++              *len = 2;                       /* base length */
++
++              if (register_operand (op0, SImode))
++                      *len += 0;
++              else if (memory_operand (op0, SImode))
++                      *len += 2;
++
++              if (register_operand (op2, SImode))
++                      *len += 0;
++              else if (memory_operand (op2, SImode))
++                      *len += 2;
++              else if (immediate_operand (op2, SImode))
++              {
++                      if (INTVAL (op2) & 0xfffful)
++                              *len += 1;
++                      if (INTVAL (op2) & 0xffff0000ul)
++                              *len += 1;
++              }
++      }
++
++      return "";
++}
++
++const char *
++msp430_xordi_code (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      rtx op0 = operands[0];
++      rtx op2 = operands[2];
++
++      if (memory_operand (op2, DImode)
++              && zero_shifted (operands[2]) && regdi_ok_safe (operands))
++      {
++              if (!len)
++                      msp430_emit_indexed_xor4 (insn, operands, NULL);
++              else
++              {
++                      if (memory_operand (op0, DImode))
++                              *len = 9;
++                      else if (register_operand (op0, DImode))
++                              *len = 5;
++              }
++
++              return "";
++      }
++      else if (memory_operand (op2, DImode)
++              && zero_shifted (operands[2]) && regdi_ok_clobber (operands))
++      {
++              if (!len)
++              {
++                      output_asm_insn ("xor\t@%E2+, %A0", operands);
++                      output_asm_insn ("xor\t@%E2+, %B0", operands);
++                      output_asm_insn ("xor\t@%E2+, %C0", operands);
++                      output_asm_insn ("xor\t@%E2+, %D0", operands);
++              }
++              else
++              {
++                      if (register_operand (op0, DImode))
++                              *len = 4;
++                      else if (memory_operand (op0, DImode))
++                              *len = 8;
++                      else
++                              abort ();
++              }
++              return "";
++      }
++
++      if (!len)
++      {
++              output_asm_insn ("xor\t%A2, %A0", operands);
++              output_asm_insn ("xor\t%B2, %B0", operands);
++              output_asm_insn ("xor\t%C2, %C0", operands);
++              output_asm_insn ("xor\t%D2, %D0", operands);
++      }
++      else
++      {
++              *len = 4;                       /* base length */
++
++              if (register_operand (op0, DImode))
++                      *len += 0;
++              else if (memory_operand (op0, DImode))
++                      *len += 4;
++
++              if (register_operand (op2, DImode))
++                      *len += 0;
++              else if (memory_operand (op2, DImode))
++                      *len += 4;
++              else if (immediate_operand (op2, DImode))
++                      *len += 4;
++              else
++                      abort ();
++      }
++
++      return "";
++}
++
++
++/********* ABS CODE ***************************************/
++const char *
++msp430_emit_abssi (insn, operands, l)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++      output_asm_insn ("tst\t%B0", operands);
++      output_asm_insn ("jge\t.Lae%=", operands);
++      output_asm_insn ("inv\t%A0", operands);
++      output_asm_insn ("inv\t%B0", operands);
++      output_asm_insn ("inc\t%A0", operands);
++      output_asm_insn ("adc\t%B0", operands);
++      output_asm_insn (".Lae%=:", operands);
++      return "";
++}
++
++const char *
++msp430_emit_absdi (insn, operands, l)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *l ATTRIBUTE_UNUSED;
++{
++      output_asm_insn ("tst\t%D0", operands);
++      output_asm_insn ("jge\t.Lae%=", operands);
++      output_asm_insn ("inv\t%A0", operands);
++      output_asm_insn ("inv\t%B0", operands);
++      output_asm_insn ("inv\t%C0", operands);
++      output_asm_insn ("inv\t%D0", operands);
++      output_asm_insn ("inc\t%A0", operands);
++      output_asm_insn ("adc\t%B0", operands);
++      output_asm_insn ("adc\t%C0", operands);
++      output_asm_insn ("adc\t%D0", operands);
++      output_asm_insn (".Lae%=:", operands);
++      return "";
++}
++
++
++/***** SIGN EXTEND *********/
++const char *
++signextendqihi (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
++
++      if (!sameoperand (operands, 1))
++      {
++              OUT_INSN (len, "mov.b\t%A1, %A0", operands);
++              dummy = 3;
++              if (indexed_location (operands[1]))
++                      dummy = 2;
++              if (GET_CODE (operands[0]) == REG)
++                      dummy--;
++              if (GET_CODE (operands[1]) == REG)
++                      dummy--;
++      }
++
++      OUT_INSN (len, "sxt\t%A0", operands);
++      dummy += 2;
++
++      if (zs || GET_CODE (operands[0]) == REG)
++              dummy -= 1;
++
++      if (len)
++              *len = dummy;
++
++      return "";
++}
++
++const char *
++signextendqisi (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
++
++      if (!sameoperand (operands, 1))
++      {
++              OUT_INSN (len, "mov.b\t%A1, %A0", operands);
++              dummy = 3;
++              if (indexed_location (operands[1]))
++                      dummy = 2;
++              if (GET_CODE (operands[0]) == REG)
++                      dummy--;
++              if (GET_CODE (operands[1]) == REG)
++                      dummy--;
++      }
++
++      OUT_INSN (len, "sxt\t%A0", operands);
++      OUT_INSN (len, "mov\t%A0, %B0", operands);
++      OUT_INSN (len, "rla\t%B0", operands);
++      OUT_INSN (len, "subc\t%B0, %B0", operands);
++      OUT_INSN (len, "inv\t%B0", operands);
++
++      if (GET_CODE (operands[0]) == REG)
++              dummy += 5;
++      else if (zs)
++              dummy += 10;
++      else
++              dummy += 12;
++
++      if (len)
++              *len = dummy;
++
++      return "";
++}
++
++const char *
++signextendqidi (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
++
++      if (!sameoperand (operands, 1))
++      {
++              OUT_INSN (len, "mov.b\t%A1, %A0", operands);
++              dummy = 3;
++              if (indexed_location (operands[1]))
++                      dummy = 2;
++              if (GET_CODE (operands[0]) == REG)
++                      dummy--;
++              if (GET_CODE (operands[1]) == REG)
++                      dummy--;
++      }
++
++      OUT_INSN (len, "sxt\t%A0", operands);
++      OUT_INSN (len, "mov\t%A0, %B0", operands);
++      OUT_INSN (len, "rla\t%B0", operands);
++      OUT_INSN (len, "subc\t%B0, %B0", operands);
++      OUT_INSN (len, "inv\t%B0", operands);
++      OUT_INSN (len, "mov\t%B0, %C0", operands);
++      OUT_INSN (len, "mov\t%C0, %D0", operands);
++
++
++      if (GET_CODE (operands[0]) == REG)
++              dummy += 7;
++      else if (zs)
++              dummy += 16;
++      else
++              dummy += 18;
++
++      if (len)
++              *len = dummy;
++
++      return "";
++}
++
++const char *
++signextendhisi (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
++
++      if (!sameoperand (operands, 1))
++      {
++              OUT_INSN (len, "mov\t%A1, %A0", operands);
++              dummy = 3;
++              if (indexed_location (operands[1]))
++                      dummy = 2;
++              if (GET_CODE (operands[0]) == REG)
++                      dummy--;
++              if (GET_CODE (operands[1]) == REG)
++                      dummy--;
++      }
++
++      OUT_INSN (len, "mov\t%A0, %B0", operands);
++      OUT_INSN (len, "rla\t%B0", operands);
++      OUT_INSN (len, "subc\t%B0, %B0", operands);
++      OUT_INSN (len, "inv\t%B0", operands);
++
++      if (GET_CODE (operands[0]) == REG)
++              dummy += 4;
++      else if (zs)
++              dummy += 9;
++      else
++              dummy += 11;
++
++      if (len)
++              *len = dummy;
++
++      return "";
++}
++
++const char *
++signextendhidi (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
++
++      if (!sameoperand (operands, 1))
++      {
++              OUT_INSN (len, "mov\t%A1, %A0", operands);
++              dummy = 3;
++              if (indexed_location (operands[1]))
++                      dummy = 2;
++              if (GET_CODE (operands[0]) == REG)
++                      dummy--;
++              if (GET_CODE (operands[1]) == REG)
++                      dummy--;
++      }
++
++      OUT_INSN (len, "mov\t%A0, %B0", operands);
++      OUT_INSN (len, "rla\t%B0", operands);
++      OUT_INSN (len, "subc\t%B0, %B0", operands);
++      OUT_INSN (len, "inv\t%B0", operands);
++      OUT_INSN (len, "mov\t%B0, %C0", operands);
++      OUT_INSN (len, "mov\t%C0, %D0", operands);
++
++      if (GET_CODE (operands[0]) == REG)
++              dummy += 6;
++      else if (zs)
++              dummy += 13;
++      else
++              dummy += 14;
++
++      if (len)
++              *len = dummy;
++
++      return "";
++}
++
++const char *
++signextendsidi (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++
++      if (!sameoperand (operands, 1))
++      {
++              OUT_INSN (len, "mov\t%A1, %A0", operands);
++              OUT_INSN (len, "mov\t%B1, %B0", operands);
++              dummy = 6;
++              if (indexed_location (operands[1]))
++                      dummy = 4;
++              if (GET_CODE (operands[0]) == REG)
++                      dummy -= 2;
++              if (GET_CODE (operands[1]) == REG)
++                      dummy -= 2;
++      }
++
++      OUT_INSN (len, "mov\t%B0, %C0", operands);
++      OUT_INSN (len, "rla\t%C0", operands);
++      OUT_INSN (len, "subc\t%C0, %C0", operands);
++      OUT_INSN (len, "inv\t%C0", operands);
++      OUT_INSN (len, "mov\t%C0, %D0", operands);
++
++      if (GET_CODE (operands[0]) == REG)
++              dummy += 5;
++      else
++              dummy += 13;
++
++      if (len)
++              *len = dummy;
++
++      return "";
++}
++
++
++/**** ZERO EXTEND *****/
++
++const char *
++zeroextendqihi (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs = zero_shifted (operands[1]) || indexed_location (operands[1]);
++
++      if(operands[0] == op2_rtx)
++      {
++              OUT_INSN (len, "and     #0xff00, %0",operands);
++              dummy = 3;
++              return "";
++      }
++      if (!sameoperand (operands, 1))
++      {
++              OUT_INSN (len, "mov.b\t%A1, %A0", operands);
++              dummy = 3;
++              if (zs)
++                      dummy = 2;
++              if (GET_CODE (operands[0]) == REG)
++                      dummy--;
++              if (GET_CODE (operands[1]) == REG)
++                      dummy--;
++      }
++
++      if (!REG_P (operands[0]))
++      {
++              OUT_INSN (len, "clr.b\t%J0", operands);
++              dummy += 2;
++      }
++      else if (sameoperand (operands, 1))
++      {
++              OUT_INSN (len, "and.b\t#-1,%0", operands);
++              dummy++;
++      }
++
++      if (len)
++              *len = dummy;
++
++      return "";
++}
++
++const char *
++zeroextendqisi (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs = zero_shifted (operands[1]) || indexed_location (operands[1]);
++
++      if (!sameoperand (operands, 1) || REG_P (operands[0]))
++      {
++              OUT_INSN (len, "mov.b\t%A1, %A0", operands);
++              dummy = 3;
++              if (zs)
++                      dummy = 2;
++              if (GET_CODE (operands[0]) == REG)
++                      dummy--;
++              if (GET_CODE (operands[1]) == REG)
++                      dummy--;
++      }
++
++
++      if (!REG_P (operands[0]))
++      {
++              OUT_INSN (len, "clr.b\t%J0", operands);
++      }
++      else if (sameoperand (operands, 1))
++      {
++              OUT_INSN (len, "and.b\t#-1,%0", operands);
++              dummy++;
++      }
++      OUT_INSN (len, "clr\t%B0", operands);
++      dummy += 2;
++      if (GET_CODE (operands[0]) == REG)
++              dummy--;
++
++      if (len)
++              *len = dummy;
++
++      return "";
++}
++
++
++const char *
++zeroextendqidi (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs = zero_shifted (operands[1]) || indexed_location (operands[1]);
++
++      if (!sameoperand (operands, 1) || REG_P (operands[0]))
++      {
++              OUT_INSN (len, "mov.b\t%A1, %A0", operands);
++              dummy = 3;
++              if (zs)
++                      dummy = 2;
++              if (GET_CODE (operands[0]) == REG)
++                      dummy--;
++              if (GET_CODE (operands[1]) == REG)
++                      dummy--;
++      }
++
++      if (!REG_P (operands[0]))
++      {
++              OUT_INSN (len, "clr.b\t%J0", operands);
++              dummy += 2;
++      }
++      else if (sameoperand (operands, 1))
++      {
++              OUT_INSN (len, "and.b\t#-1,%0", operands);
++              dummy++;
++      }
++      dummy += 6;
++      OUT_INSN (len, "clr\t%B0", operands);
++      OUT_INSN (len, "clr\t%C0", operands);
++      OUT_INSN (len, "clr\t%D0", operands);
++
++      if (GET_CODE (operands[0]) == REG && len)
++              *len -= 3;
++
++      if (len)
++              *len = dummy;
++
++      return "";
++}
++
++const char *
++zeroextendhisi (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs = zero_shifted (operands[1]) || indexed_location (operands[1]);
++
++      if (!sameoperand (operands, 1))
++      {
++              OUT_INSN (len, "mov\t%A1, %A0", operands);
++              dummy = 3;
++              if (zs)
++                      dummy = 2;
++              if (GET_CODE (operands[0]) == REG)
++                      dummy--;
++              if (GET_CODE (operands[1]) == REG)
++                      dummy--;
++      }
++
++      OUT_INSN (len, "clr\t%B0", operands);
++      dummy += 2;
++      if (GET_CODE (operands[0]) == REG)
++              dummy--;
++
++      if (len)
++              *len = dummy;
++
++      return "";
++
++}
++
++const char *
++zeroextendhidi (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs = zero_shifted (operands[1]) || indexed_location (operands[1]);
++
++      if (!sameoperand (operands, 1))
++      {
++              OUT_INSN (len, "mov\t%A1, %A0", operands);
++              dummy = 3;
++              if (zs)
++                      dummy = 2;
++              if (GET_CODE (operands[0]) == REG)
++                      dummy--;
++              if (GET_CODE (operands[1]) == REG)
++                      dummy--;
++      }
++
++      dummy += 6;
++      OUT_INSN (len, "clr\t%B0", operands);
++      OUT_INSN (len, "clr\t%C0", operands);
++      OUT_INSN (len, "clr\t%D0", operands);
++
++      if (GET_CODE (operands[0]) == REG)
++              dummy -= 3;
++
++      if (len)
++              *len = dummy;
++
++      return "";
++}
++
++const char *
++zeroextendsidi (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++
++      if (!sameoperand (operands, 1))
++      {
++              if (zero_shifted (operands[1]))
++              {
++                      rtx reg = XEXP (operands[1], 0);
++
++                      OUT_INSN (len, "mov\t@%E1+, %A0", operands);
++                      OUT_INSN (len, "mov\t@%E1+, %B0", operands);
++                      dummy = 4;
++                      if (GET_CODE (operands[0]) == REG)
++                              dummy -= 2;
++
++                      if (!dead_or_set_p (insn, reg))
++                      {
++                              OUT_INSN (len, "sub\t#4, %E1", operands);
++                              dummy += 1;
++                      }
++              }
++              else
++              {
++                      OUT_INSN (len, "mov\t%A1, %A0", operands);
++                      OUT_INSN (len, "mov\t%B1, %B0", operands);
++                      dummy = 6;
++                      if (GET_CODE (operands[0]) == REG)
++                              dummy -= 2;
++                      if (GET_CODE (operands[1]) == REG)
++                              dummy -= 2;
++                      if (indexed_location (operands[1]))
++                              dummy--;
++              }
++      }
++
++      dummy += 4;
++      OUT_INSN (len, "clr\t%C0", operands);
++      OUT_INSN (len, "clr\t%D0", operands);
++
++      if (GET_CODE (operands[0]) == REG)
++              dummy -= 2;
++
++      if (len)
++              *len = dummy;
++
++      return "";
++}
++
++/******************* TESTS AND JUMPS *********************/
++
++
++/*****************  AUXES FOR TESTS *********************/
++
++RTX_CODE
++followed_compare_condition (insn)
++rtx insn;
++{
++      rtx next = next_real_insn (insn);
++      RTX_CODE cond = UNKNOWN;
++
++      if (next && GET_CODE (next) == JUMP_INSN)
++      {
++              rtx pat = PATTERN (next);
++              rtx src, t;
++
++              if (GET_CODE (pat) == RETURN)
++                      return UNKNOWN;
++
++              src = SET_SRC (pat);
++              t = XEXP (src, 0);
++              cond = GET_CODE (t);
++      }
++      else if (next && GET_CODE (next) == INSN)
++      {
++              /* here, two possible : sgeu ans sltu */
++
++              rtx pat = PATTERN (next);
++              rtx src;
++
++              if (!pat || GET_CODE (pat) != SET)
++                      return UNKNOWN;
++
++              src = SET_SRC (pat);
++              cond = GET_CODE (src);  /* this must be IF_THEN_ELSE */
++              if (cond != IF_THEN_ELSE)
++                      return UNKNOWN;
++      }
++      return cond;
++}
++
++
++/* SHIFT GUARDS */
++int
++msp430_ashlhi3 (operands)
++rtx operands[];
++{
++      int x;
++      rtx set, shift;
++      rtx dst;
++
++      if (!const_int_operand (operands[2], VOIDmode))
++      {
++              rtx op0, op1;
++
++              op0 = force_reg (HImode, operands[0]);
++              op1 = force_reg (HImode, operands[1]);
++              operands[2] = copy_to_mode_reg (HImode, operands[2]);
++              emit_insn (gen_ashlhi3_cnt (op0, op1, operands[2]));
++              emit_move_insn (operands[0], op0);
++              return 1;
++      }
++
++      x = INTVAL (operands[2]);
++
++      if (x > 15 || x < 0)
++      {
++              emit_move_insn (operands[0], const0_rtx);
++              return 1;
++      }
++
++      if (x == 0)
++      {
++              emit_move_insn (operands[0], operands[1]);
++              return 1;
++      }
++
++      if (x < 3)
++      {
++              emit_move_insn (operands[0], operands[1]);
++              dst = operands[0];
++              shift = gen_rtx_ASHIFT (HImode, dst, const1_rtx);
++              set = gen_rtx_SET (HImode, dst, shift);
++              while (x--)
++                      emit_insn (set);
++              return 1;
++      }
++
++      if (x == 15)
++      {
++              shift = gen_rtx_ASHIFT (HImode, operands[1], GEN_INT (15));
++              set = gen_rtx_SET (HImode, operands[0], shift);
++              emit_insn (set);
++              return 1;
++      }
++
++      if (operands[0] != operands[1])
++              dst = copy_to_mode_reg (HImode, operands[1]);
++      else
++              dst = operands[1];
++      if (x > 7)
++      {
++              emit_insn (gen_andhi3 (dst, dst, GEN_INT (0xff)));
++              emit_insn (gen_swpb (dst, dst));
++              x -= 8;
++      }
++
++      shift = gen_rtx_ASHIFT (HImode, dst, const1_rtx);
++      set = gen_rtx_SET (HImode, dst, shift);
++
++      while (x--)
++              emit_insn (set);
++      if (dst != operands[0])
++              emit_move_insn (operands[0], dst);
++      return 1;
++}
++
++int
++msp430_ashlsi3 (operands)
++rtx operands[];
++{
++      int x;
++      rtx shift, set, dst;
++
++      if (!const_int_operand (operands[2], VOIDmode))
++      {
++              rtx op0, op1;
++
++              op0 = force_reg (SImode, operands[0]);
++              op1 = force_reg (SImode, operands[1]);
++              operands[2] = copy_to_mode_reg (HImode, operands[2]);
++              emit_insn (gen_ashlsi3_cnt (op0, op1, operands[2]));
++              emit_move_insn (operands[0], op0);
++              return 1;
++      }
++
++      x = INTVAL (operands[2]);
++
++      if (x >= 32 || x < 0)
++      {
++              emit_move_insn (operands[0], const0_rtx);
++              return 1;
++      }
++
++      if (x == 0)
++      {
++              emit_move_insn (operands[0], operands[1]);
++              return 1;
++      }
++
++      if (x == 1)
++      {
++              emit_move_insn (operands[0], operands[1]);
++              dst = operands[0];
++              shift = gen_rtx_ASHIFT (SImode, dst, operands[2]);
++              set = gen_rtx_SET (SImode, dst, shift);
++              emit_insn (set);
++              return 1;
++      }
++
++      if (operands[0] != operands[1])
++              dst = copy_to_mode_reg (SImode, operands[1]);
++      else
++              dst = operands[1];
++
++      if (x == 31)
++      {
++              shift = gen_rtx_ASHIFT (SImode, operands[1], GEN_INT (31));
++              set = gen_rtx_SET (SImode, operands[0], shift);
++              emit_insn (set);
++              return 1;
++      }
++
++      if (x >= 16)
++      {
++              rtx dhi = gen_highpart (HImode, operands[0]);
++              rtx dlo = gen_lowpart (HImode, operands[0]);
++              rtx shi = gen_highpart (HImode, operands[1]);
++              rtx slo = gen_lowpart (HImode, operands[1]);
++
++              emit_move_insn (dhi, slo);
++              emit_move_insn (dlo, const0_rtx); 
++              x -= 16;
++              if (x)
++              {
++                      rtx ops[3];
++                      ops[0] = dhi;
++                      ops[1] = dhi;
++                      ops[2] = GEN_INT (x);
++                      msp430_ashlhi3 (ops);
++              }
++              return 1;
++      }
++
++      if (x >= 8)
++      {
++              shift = gen_rtx_ASHIFT (SImode, dst, GEN_INT (8));
++              set = gen_rtx_SET (SImode, dst, shift);
++              emit_insn (set);
++              x -= 8;
++      }
++
++      shift = gen_rtx_ASHIFT (SImode, dst, GEN_INT (1));
++      set = gen_rtx_SET (SImode, dst, shift);
++
++      while (x--)
++              emit_insn (set);
++      if (dst != operands[0])
++              emit_move_insn (operands[0], dst);
++      return 1;
++}
++
++/* arithmetic right */
++int
++msp430_ashrhi3 (operands)
++rtx operands[];
++{
++      int x;
++      rtx shift, set, dst;
++
++      if (!const_int_operand (operands[2], VOIDmode))
++      {
++              rtx op0, op1;
++
++              op0 = force_reg (HImode, operands[0]);
++              op1 = force_reg (HImode, operands[1]);
++              operands[2] = copy_to_mode_reg (HImode, operands[2]);
++              emit_insn (gen_ashrhi3_cnt (op0, op1, operands[2]));
++              emit_move_insn (operands[0], op0);
++              return 1;
++      }
++
++      x = INTVAL (operands[2]);
++      if (x >= 15 || x < 0)
++      {
++              dst = gen_lowpart (QImode, operands[0]);
++              emit_move_insn (operands[0], operands[1]);
++              emit_insn (gen_swpb (operands[0], operands[0]));
++              emit_insn (gen_extendqihi2 (operands[0], dst));
++              emit_insn (gen_swpb (operands[0], operands[0]));
++              emit_insn (gen_extendqihi2 (operands[0], dst));
++              return 1;
++      }
++
++      if (x == 0)
++      {
++              emit_move_insn (operands[0], operands[1]);
++              return 1;
++      }
++
++      if (x < 3)
++      {
++              emit_move_insn (operands[0], operands[1]);
++              dst = operands[0];
++              shift = gen_rtx_ASHIFTRT (HImode, dst, const1_rtx);
++              set = gen_rtx_SET (HImode, dst, shift);
++
++              while (x--)
++                      emit_insn (set);
++              return 1;
++      }
++
++      if (operands[0] != operands[1])
++              dst = copy_to_mode_reg (HImode, operands[1]);
++      else
++              dst = operands[1];
++
++      if (x >= 8)
++      {
++              rtx dlo = gen_lowpart (QImode, dst);
++              emit_insn (gen_swpb (dst, dst));
++              emit_insn (gen_extendqihi2 (dst, dlo));
++              x -= 8;
++      }
++
++      shift = gen_rtx_ASHIFTRT (HImode, dst, const1_rtx);
++      set = gen_rtx_SET (HImode, dst, shift);
++
++      while (x--)
++              emit_insn (set);
++
++      if (dst != operands[0])
++              emit_move_insn (operands[0], dst);
++
++      return 1;
++}
++
++int
++msp430_ashrsi3 (operands)
++rtx operands[];
++{
++      int x;
++      rtx shift, set, dst;
++
++      if (!const_int_operand (operands[2], VOIDmode))
++      {
++              rtx op0, op1;
++
++              op0 = force_reg (SImode, operands[0]);
++              op1 = force_reg (SImode, operands[1]);
++              operands[2] = copy_to_mode_reg (HImode, operands[2]);
++              emit_insn (gen_ashrsi3_cnt (op0, op1, operands[2]));
++              emit_move_insn (operands[0], op0);
++              return 1;
++      }
++
++      x = INTVAL (operands[2]);
++
++      if (x == 0)
++      {
++              emit_move_insn (operands[0], operands[1]);
++              return 1;
++      }
++
++      if (operands[0] != operands[1])
++              dst = copy_to_mode_reg (SImode, operands[1]);
++      else
++              dst = operands[1];
++
++      if (x >= 31 || x < 0)
++      {
++
++              shift = gen_rtx_ASHIFTRT (SImode, dst, GEN_INT (31));
++              set = gen_rtx_SET (SImode, dst, shift);
++              emit_insn (set);
++
++              if (dst != operands[0])
++                      emit_move_insn (operands[0], dst);
++              return 1;
++      }
++
++      if (x == 1)
++      {
++              emit_move_insn (operands[0], operands[1]);
++              dst = operands[0];
++              shift = gen_rtx_ASHIFTRT (SImode, dst, operands[2]);
++              set = gen_rtx_SET (SImode, dst, shift);
++              emit_insn (set);
++              return 1;
++      }
++
++      if (x >= 16)
++      {
++              rtx dlo = gen_lowpart (HImode, operands[0]);
++              rtx shi = gen_highpart (HImode, dst);
++
++              emit_move_insn (gen_highpart (HImode, operands[0]), const0_rtx);
++              emit_insn (gen_extendhisi2 (operands[0], shi));
++              x -= 16;
++              if (x)
++              {
++                      rtx ops[3];
++                      ops[0] = dlo;
++                      ops[1] = dlo;
++                      ops[2] = GEN_INT (x);
++                      msp430_ashrhi3 (ops);
++              }
++              return 1;
++      }
++
++      if (x >= 8)
++      {
++              shift = gen_rtx_ASHIFTRT (SImode, dst, GEN_INT (8));
++              set = gen_rtx_SET (SImode, dst, shift);
++              emit_insn (set);
++              x -= 8;
++      }
++
++      shift = gen_rtx_ASHIFTRT (SImode, dst, GEN_INT (1));
++      set = gen_rtx_SET (SImode, dst, shift);
++
++      while (x--)
++              emit_insn (set);
++      if (dst != operands[0])
++              emit_move_insn (operands[0], dst);
++      return 1;
++}
++
++/* logical right */
++int
++msp430_lshrhi3 (operands)
++rtx operands[];
++{
++      int x;
++      rtx shift, set, dst;
++
++      if (!const_int_operand (operands[2], VOIDmode))
++      {
++              rtx op0, op1;
++
++              op0 = force_reg (HImode, operands[0]);
++              op1 = force_reg (HImode, operands[1]);
++              operands[2] = copy_to_mode_reg (HImode, operands[2]);
++              emit_insn (gen_lshrhi3_cnt (op0, op1, operands[2]));
++              emit_move_insn (operands[0], op0);
++              return 1;
++      }
++
++      x = INTVAL (operands[2]);
++      if (x > 15 || x < 0)
++      {
++              emit_move_insn (operands[0], const0_rtx);
++              return 1;
++      }
++
++      if (x == 0)
++      {
++              emit_move_insn (operands[0], operands[1]);
++              return 1;
++      }
++
++      if (x < 3)
++      {
++              emit_move_insn (operands[0], operands[1]);
++              dst = operands[0];
++              shift = gen_rtx_LSHIFTRT (HImode, dst, const1_rtx);
++              set = gen_rtx_SET (HImode, dst, shift);
++              emit_insn (set);
++              x--;
++
++              if (x)
++              {
++                      shift = gen_rtx_ASHIFTRT (HImode, dst, const1_rtx);
++                      set = gen_rtx_SET (HImode, dst, shift);
++                      emit_insn (set);
++              }
++              return 1;
++      }
++
++      if (x == 15)
++      {
++              emit_move_insn (operands[0], operands[1]);
++              dst = operands[0];
++              shift = gen_rtx_LSHIFTRT (HImode, dst, GEN_INT (15));
++              set = gen_rtx_SET (HImode, dst, shift);
++              emit_insn (set);
++              return 1;
++      }
++
++      if (operands[0] != operands[1])
++              dst = copy_to_mode_reg (HImode, operands[1]);
++      else
++              dst = operands[1];
++
++      if (x >= 8)
++      {
++              rtx dlo = gen_lowpart (QImode, dst);
++              emit_insn (gen_swpb (dst, dst));
++              emit_insn (gen_zero_extendqihi2 (dst, dlo));
++              x -= 8;
++      }
++
++      if (x)
++      {
++              shift = gen_rtx_LSHIFTRT (HImode, dst, const1_rtx);
++              set = gen_rtx_SET (HImode, dst, shift);
++              x--;
++              emit_insn (set);
++      }
++      shift = gen_rtx_ASHIFTRT (HImode, dst, const1_rtx);
++      set = gen_rtx_SET (HImode, dst, shift);
++
++      while (x--)
++              emit_insn (set);
++
++      if (dst != operands[0])
++              emit_move_insn (operands[0], dst);
++
++      return 1;
++}
++
++int
++msp430_lshrsi3 (operands)
++rtx operands[];
++{
++      int x;
++      rtx shift, set, dst;
++
++      if (!const_int_operand (operands[2], VOIDmode))
++      {
++              rtx op0, op1;
++
++              op0 = force_reg (SImode, operands[0]);
++              op1 = force_reg (SImode, operands[1]);
++              operands[2] = copy_to_mode_reg (HImode, operands[2]);
++              emit_insn (gen_lshrsi3_cnt (op0, op1, operands[2]));
++              emit_move_insn (operands[0], op0);
++              return 1;
++      }
++
++      x = INTVAL (operands[2]);
++
++      if (x == 0)
++      {
++              emit_move_insn (operands[0], operands[1]);
++              return 1;
++      }
++
++      if (x == 1)
++      {
++              emit_move_insn (operands[0], operands[1]);
++              dst = operands[0];
++              shift = gen_rtx_LSHIFTRT (SImode, dst, operands[2]);
++              set = gen_rtx_SET (SImode, dst, shift);
++              emit_insn (set);
++              return 1;
++      }
++
++      if (x > 31 || x < 0)
++      {
++              emit_move_insn (operands[0], const0_rtx);
++              return 1;
++      }
++
++      if (operands[0] != operands[1])
++              dst = copy_to_mode_reg (SImode, operands[1]);
++      else
++              dst = operands[1];
++
++      if (x >= 16)
++      {
++              rtx dlo = gen_lowpart (HImode, operands[0]);
++              rtx shi = gen_highpart (HImode, dst);
++
++              emit_move_insn (gen_highpart (HImode, operands[0]), const0_rtx);
++              emit_insn (gen_zero_extendhisi2 (operands[0], shi));
++              x -= 16;
++              if (x)
++              {
++                      rtx ops[3];
++                      ops[0] = dlo;
++                      ops[1] = dlo;
++                      ops[2] = GEN_INT (x);
++                      msp430_lshrhi3 (ops);
++              }
++              return 1;
++      }
++
++      if (x >= 8)
++      {
++              shift = gen_rtx_LSHIFTRT (SImode, dst, GEN_INT (8));
++              set = gen_rtx_SET (SImode, dst, shift);
++              emit_insn (set);
++              x -= 8;
++      }
++
++      if (x)
++      {
++              shift = gen_rtx_LSHIFTRT (SImode, dst, const1_rtx);
++              set = gen_rtx_SET (SImode, dst, shift);
++              emit_insn (set);
++              x--;
++      }
++
++      shift = gen_rtx_ASHIFTRT (SImode, dst, GEN_INT (1));
++      set = gen_rtx_SET (SImode, dst, shift);
++
++      while (x--)
++              emit_insn (set);
++      if (dst != operands[0])
++              emit_move_insn (operands[0], dst);
++      return 1;
++}
++
++/******* COMMON SHIFT CODE ***************/
++int
++is_shift_better_in_reg (operands)
++rtx operands[];
++{
++      rtx x = operands[0];
++      rtx cnt = operands[2];
++      int size = GET_MODE_SIZE (x->mode);
++      int icnt = -1;
++      int r = 0;
++
++      if (!optimize)
++              return 0;
++
++      if (GET_CODE (cnt) == CONST_INT)
++              icnt = INTVAL (cnt);
++      else
++              return 1;
++
++      switch (size)
++      {
++      case 1:
++              if (icnt != 1 && icnt != 2 && icnt != 7)
++                      r = 1;
++              break;
++      case 2:
++              if (icnt != 1 && icnt != 2 && icnt != 8 && icnt != 15)
++                      r = 2;
++              break;
++      case 4:
++              if (icnt != 1
++                      && icnt != 2 && icnt != 8 && icnt != 16 && icnt != 24 && icnt != 31)
++                      r = 4;
++              break;
++      case 8:
++              if (icnt != 1
++                      && icnt != 2 && icnt != 16 && icnt != 32 && icnt != 48 && icnt != 63)
++                      r = 8;
++              break;
++      }
++
++      return r;
++}
++
++
++static int set_len PARAMS ((rtx, int, int));
++/* for const operand2 and for SI, DI modes.*/
++static int
++set_len (x, bl, sc)
++rtx x;                        /* operand0 */
++int bl;                       /* base length in assumption of memory operand */
++int sc;                       /* shift count */
++{
++      int dummy;
++      int zs = zero_shifted (x);
++      int size = GET_MODE_SIZE (x->mode);
++      int sshi = 0;
++
++      if (size == 4)
++              sshi = 1;
++      else if (size == 8)
++              sshi = 2;
++
++      if (size == 1)
++              size++;
++
++      if (GET_CODE (x) == REG)
++              dummy = (bl >> 1) - sshi;       /* bl / 2 is not fully correct */
++      else if (zs)
++              dummy = bl - (size >> 1) + 1;
++      else if (indexed_location (x))
++              dummy = bl - 1;
++      else
++              dummy = bl;
++
++      return dummy * sc;
++}
++
++static int set_ren PARAMS ((rtx, int, int));
++/* for const operand2 and for SI, DI modes.*/
++static int
++set_ren (x, bl, sc)
++rtx x;                        /* operand0 */
++int bl;                       /* base length in assumption of memory operand */
++int sc;                       /* shift count */
++{
++      int dummy;
++
++      bl *= sc;
++      if (GET_CODE (x) == REG)
++              dummy = bl / 2;
++      else if (indexed_location (x))
++              dummy = bl - sc;
++      else
++              dummy = bl;
++      return dummy;
++}
++
++static int set_rel PARAMS ((rtx, int, int));
++/* for const operand2 and for SI, DI modes.*/
++static int
++set_rel (x, bl, sc)
++rtx x;                        /* operand0 */
++int bl;                       /* base length in assumption of memory operand */
++int sc;                       /* shift count */
++{
++      int dummy;
++
++      bl *= sc;
++      if (GET_CODE (x) == REG)
++              dummy = bl / 2;
++      else if (indexed_location (x))
++              dummy = bl - sc;
++      else
++              dummy = bl;
++      dummy += sc;
++      return dummy;
++}
++
++
++
++#define INST_THRESHOLD  16
++
++int
++msp430_emit_shift_cnt (set_len_fun, pattern, insn, operands, len, lsc)
++int (*set_len_fun) (rtx, int, int);
++const char *pattern;
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++int lsc;
++{
++      rtx op[10];
++      int dummy = 0;
++
++      op[0] = operands[0];
++      op[1] = operands[1];
++      op[2] = operands[2];
++      op[3] = operands[3];
++
++
++      OUT_INSN (len, "tst\t%2", op);
++      OUT_INSN (len, "jz\t.Lsend%=\n.Lsst%=:", op);
++      OUT_INSN (len, pattern, op);
++      OUT_INSN (len, "dec\t%2", op);
++      OUT_INSN (len, "jnz\t.Lsst%=\n.Lsend%=:", op);
++      dummy = (set_len_fun) (op[0], lsc, 1) + 4;
++      if (!REG_P (op[2]) && !indexed_location (op[2]))
++              dummy += 2;
++
++
++      if (len)
++              *len = dummy;
++      return 0;
++}
++
++
++/* <<<<<<<<<<<<< SHIFT LEFT CODE <<<<<<<<<<<<<<<<<     */
++
++const char *
++msp430_emit_ashlqi3 (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
++      const char *pattern;
++      int shiftpos;
++
++      if (zs)
++              pattern = "rla.b\t@%E0";
++      else
++              pattern = "rla.b\t%A0";
++
++      if (GET_CODE (operands[2]) == CONST_INT)
++      {
++              shiftpos = INTVAL (operands[2]);
++
++              switch (shiftpos)
++              {
++              default:
++                      if (zs)
++                              OUT_INSN (len, "clr.b\t@%E0", operands);
++                      else
++                              OUT_INSN (len, "clr.b\t%A0", operands);
++                      dummy = 2;
++                      if (REG_P (operands[0]))
++                              dummy >>= 1;
++                      break;
++
++              case 0:         /* paranoia setting */
++                      dummy = 0;
++                      break;
++
++              case 1:
++              case 2:
++              case 3:
++              case 4:
++              case 5:
++              case 6:
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += set_len (operands[0], 3, 1);
++                      }
++                      break;
++
++              case 7:
++                      if (zs)
++                      {
++                              OUT_INSN (len, "rra.b\t%0", operands);
++                              OUT_INSN (len, "clr.b\t%0", operands);
++                              OUT_INSN (len, "rrc.b\t%0", operands);
++                              dummy = 5;
++                      }
++                      else
++                      {
++                              OUT_INSN (len, "rra.b\t%0", operands);
++                              OUT_INSN (len, "clr.b\t%0", operands);
++                              OUT_INSN (len, "rrc.b\t%0", operands);
++                              dummy = 6;
++                              if (REG_P (operands[0]))
++                                      dummy = 3;
++                      }
++
++                      break;
++              }
++
++              if (len)
++                      *len = dummy;
++              return "";
++
++      }
++      else
++      {
++              msp430_emit_shift_cnt (set_len, pattern, insn, operands, len, 3);
++      }
++
++      return "";
++}
++
++
++const char *
++msp430_emit_ashlhi3 (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs;
++      const char *pattern;
++      int shiftpos;
++
++      zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
++
++      if (zs)
++              pattern = "rla\t@%E0";
++      else
++              pattern = "rla\t%A0";
++
++      if (GET_CODE (operands[2]) == CONST_INT)
++      {
++              shiftpos = INTVAL (operands[2]);
++
++              switch (shiftpos)
++              {
++              case 0:         /* paranoia setting */
++                      dummy = 0;
++                      break;
++
++              case 1:
++              case 2:
++              case 3:
++              case 4:
++              case 5:
++              case 6:
++              case 7:
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += set_len (operands[0], 3, 1);
++                      }
++                      break;
++
++              case 8:
++              case 9:
++              case 10:
++              case 11:
++              case 12:
++              case 13:
++              case 14:
++                      if (zs)
++                      {
++                              dummy = 3;
++                              OUT_INSN (len, "and.b\t#0xffff, %A0", operands);
++                              OUT_INSN (len, "swpb\t@%E0", operands);
++                      }
++                      else
++                      {
++                              dummy = 4;
++                              OUT_INSN (len, "and.b\t#0xffff, %A0", operands);
++                              OUT_INSN (len, "swpb\t%A0", operands);
++                              if (REG_P (operands[0]))
++                                      dummy = 2;
++                      }
++
++
++                      shiftpos -= 8;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += set_len (operands[0], 3, 1);
++                      }
++                      break;
++
++              case 15:
++                      if (zs)
++                      {
++                              OUT_INSN (len, "rra\t%0", operands);
++                              OUT_INSN (len, "clr\t%0", operands);
++                              OUT_INSN (len, "rrc\t%0", operands);
++                              dummy = 5;
++                      }
++                      else
++                      {
++                              OUT_INSN (len, "rra\t%0", operands);
++                              OUT_INSN (len, "clr\t%0", operands);
++                              OUT_INSN (len, "rrc\t%0", operands);
++                              dummy = 6;
++                              if (REG_P (operands[0]))
++                                      dummy = 3;
++                      }
++
++                      break;
++
++
++              default:
++
++                      OUT_INSN (len, "clr\t%A0", operands);
++                      dummy = 2;
++                      if (REG_P (operands[0]))
++                              dummy = 1;
++                      break;
++              }
++
++              if (len)
++                      *len = dummy;
++              return "";
++      }
++      else
++      {
++              msp430_emit_shift_cnt (set_len, pattern, insn, operands, len, 3);
++      }
++
++      return "";
++}
++
++
++const char *
++msp430_emit_ashlsi3 (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++
++      int dummy = 0;
++      int zs;
++      const char *pattern;
++
++      zs = zero_shifted (operands[0]);
++
++      if (zs)
++              pattern = "add\t@%E0+, -2(%E0)\n\taddc\t@%E0+, -2(%E0)\n\tsub\t#4, %E0";
++      else
++              pattern = "rla\t%A0\n\trlc\t%B0";
++
++
++      if (GET_CODE (operands[2]) == CONST_INT)
++      {
++              int shiftpos = INTVAL (operands[2]);
++
++              switch (shiftpos)
++              {
++
++              case 0:
++                      dummy = 0;
++                      break;
++              case 1:
++              case 2:
++              case 3:
++              case 4:
++              case 5:
++              case 6:
++              case 7:
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += set_len (operands[0], 6, 1);
++                      }
++                      break;
++
++              case 8:
++              case 9:
++              case 10:
++              case 11:
++              case 12:
++              case 13:
++              case 14:
++              case 15:
++
++                      if (zs || indexed_location (operands[0]))
++                      {
++                              OUT_INSN (len, "xor.b\t@%E0, %B0", operands);
++                              OUT_INSN (len, "xor\t@%E0, %B0", operands);
++                              OUT_INSN (len, "swpb\t%B0", operands);
++                              OUT_INSN (len, "and.b\t#-1, %A0", operands);
++                              OUT_INSN (len, "swpb\t@%E0", operands);
++                              dummy = 9;
++                      }
++                      else
++                      {
++                              OUT_INSN (len, "xor.b\t%A0, %B0", operands);
++                              OUT_INSN (len, "xor\t%A0, %B0", operands);
++                              OUT_INSN (len, "swpb\t%B0", operands);
++                              OUT_INSN (len, "and.b\t#-1, %A0", operands);
++                              OUT_INSN (len, "swpb\t%A0", operands);
++                              dummy = 12;
++                              if (REG_P (operands[0]))
++                                      dummy = 5;
++                      }
++
++                      shiftpos -= 8;
++
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += set_len (operands[0], 6, 1);
++                      }
++
++                      if (len)
++                              *len = dummy;
++                      return "";
++
++                      break;
++
++              case 16:
++              case 17:
++              case 18:
++              case 19:
++              case 20:
++              case 21:
++              case 22:
++              case 23:
++
++                      if (zs || indexed_location (operands[0]))
++                      {
++                              OUT_INSN (len, "mov\t@%E0, %B0", operands);
++                              OUT_INSN (len, "clr\t%A0", operands);
++                              dummy = 4;
++                      }
++                      else
++                      {
++                              OUT_INSN (len, "mov\t%A0, %B0", operands);
++                              OUT_INSN (len, "clr\t%A0", operands);
++                              dummy = 5;
++                              if (REG_P (operands[0]))
++                                      dummy = 3;
++                      }
++
++                      shiftpos -= 16;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += set_len (operands[0], 6, 1);
++                      }
++
++                      if (len)
++                              *len = dummy;
++                      return "";
++                      break;
++
++              case 24:
++              case 25:
++              case 26:
++              case 27:
++              case 28:
++              case 29:
++              case 30:
++                      if (zs || indexed_location (operands[0]))
++                      {
++                              OUT_INSN (len, "mov.b\t@%E0,%B0", operands);
++                              OUT_INSN (len, "swpb\t%B0", operands);
++                              OUT_INSN (len, "clr\t@%E0", operands);
++                              dummy = 6;
++                      }
++                      else
++                      {
++                              OUT_INSN (len, "mov.b\t%A0,%B0", operands);
++                              OUT_INSN (len, "swpb\t%B0", operands);
++                              OUT_INSN (len, "clr\t%A0", operands);
++                              dummy = 8;
++                              if (GET_CODE (operands[0]) == REG)
++                                      dummy = 3;
++                      }
++
++                      shiftpos -= 24;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += set_len (operands[0], 6, 1);
++                      }
++
++                      if (len)
++                              *len = dummy;
++                      return "";
++
++                      break;
++
++              case 31:
++                      if (zs || indexed_location (operands[0]))
++                      {
++                              OUT_INSN (len, "rra\t@%E0", operands);
++                              OUT_INSN (len, "clr\t%A0", operands);
++                              OUT_INSN (len, "clr\t%B0", operands);
++                              OUT_INSN (len, "rrc\t%B0", operands);
++                              dummy = 9;
++
++                      }
++                      else
++                      {
++                              OUT_INSN (len, "rra\t%A0", operands);
++                              OUT_INSN (len, "clr\t%A0", operands);
++                              OUT_INSN (len, "clr\t%B0", operands);
++                              OUT_INSN (len, "rrc\t%B0", operands);
++                              dummy = 10;
++                              if (REG_P (operands[0]))
++                                      dummy = 4;
++                      }
++
++                      if (len)
++                              *len = dummy;
++                      return "";
++                      break;
++
++              default:
++                      OUT_INSN (len, "clr\t%A0", operands);
++                      OUT_INSN (len, "clr\t%B0", operands);
++                      if (len)
++                              *len = set_len (operands[0], 6, 1);
++                      return "";
++                      break;
++
++              }                       /* switch */
++
++              if (len)
++                      *len = dummy;
++              return "";
++      }
++      else
++              msp430_emit_shift_cnt (set_len, pattern, insn, operands, len, 6);
++
++      return "";
++
++}
++
++const char *
++msp430_emit_ashldi3 (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++
++      int dummy = 0;
++      int zs;
++      const char *pattern;
++
++      zs = zero_shifted (operands[0]);
++
++      if (zs)
++              pattern =
++              "add\t@%E0+,-2(%E0)\n\taddc\t@%E0+,-2(%E0)\n\taddc\t@%E0+,-2(%E0)\n\taddc\t@%E0+,-2(%E0)\n\tsub\t#8,%E0";
++      else
++              pattern = "rla\t%A0\n\trlc\t%B0\n\trlc\t%C0\n\trlc\t%D0";
++
++      if (GET_CODE (operands[2]) == CONST_INT)
++      {
++              int shiftpos = INTVAL (operands[2]);
++
++              switch (shiftpos)
++              {
++              case 0:
++                      dummy = 0;
++                      if (len)
++                              *len = dummy;
++                      break;
++
++              case 1:
++              case 2:
++              case 3:
++              case 4:
++              case 5:
++              case 6:
++              case 7:
++              case 8:
++              case 9:
++              case 10:
++              case 11:
++              case 12:
++              case 13:
++              case 14:
++              case 15:
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += set_len (operands[0], 12, 1);
++                      }
++                      if (len)
++                              *len = dummy;
++                      break;
++
++              case 16:
++              case 17:
++              case 18:
++              case 19:
++              case 20:
++              case 21:
++              case 22:
++              case 23:
++                      if (zs || indexed_location (operands[0]))
++                      {
++                              dummy = 10;
++                              OUT_INSN (len, "mov\t%C0, %D0", operands);
++                              OUT_INSN (len, "mov\t%B0, %C0", operands);
++                              OUT_INSN (len, "mov\t@%E0, %B0", operands);
++                              OUT_INSN (len, "clr\t@%E0", operands);
++                      }
++                      else
++                      {
++                              dummy = 11;
++                              OUT_INSN (len, "mov\t%C0, %D0", operands);
++                              OUT_INSN (len, "mov\t%B0, %C0", operands);
++                              OUT_INSN (len, "mov\t%A0, %B0", operands);
++                              OUT_INSN (len, "clr\t%A0", operands);
++
++                      }
++                      if (GET_CODE (operands[0]) == REG)
++                              dummy = 4;
++                      shiftpos -= 16;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += set_len (operands[0], 12, 1);
++                      }
++                      if (len)
++                              *len = dummy;
++                      break;
++
++              case 24:
++              case 25:
++              case 26:
++              case 27:
++              case 28:
++              case 29:
++              case 30:
++              case 31:
++                      if (zs)
++                      {
++                              dummy = 8;
++                              OUT_INSN (len, "mov\t@%E0, %D0", operands);
++                              OUT_INSN (len, "clr\t%A0", operands);
++                              OUT_INSN (len, "clr\t%B0", operands);
++                              OUT_INSN (len, "clr\t%C0", operands);
++
++                      }
++                      else
++                      {
++                              dummy = 9;
++                              OUT_INSN (len, "mov\t%A0, %D0", operands);
++                              OUT_INSN (len, "clr\t%A0", operands);
++                              OUT_INSN (len, "clr\t%B0", operands);
++                              OUT_INSN (len, "clr\t%C0", operands);
++                      }
++                      if (GET_CODE (operands[0]) == REG)
++                              dummy = 4;
++
++                      shiftpos -= 16;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += set_len (operands[0], 12, 1);
++                      }
++
++                      if (len)
++                              *len = dummy;
++                      break;
++
++              case 32:
++              case 33:
++              case 34:
++              case 35:
++              case 36:
++              case 37:
++              case 38:
++              case 39:
++              case 40:
++              case 41:
++              case 42:
++              case 43:
++              case 44:
++              case 45:
++              case 46:
++              case 47:
++
++                      if (zs)
++                      {
++                              OUT_INSN (len, "mov\t@%E0+, %C0", operands);
++                              OUT_INSN (len, "mov\t@%E0+, %D0", operands);
++                              OUT_INSN (len, "sub\t#4, %E0", operands);
++                              OUT_INSN (len, "clr\t%A0", operands);
++                              OUT_INSN (len, "clr\t%B0", operands);
++                              dummy = 9;
++                      }
++                      else
++                      {
++                              dummy = 10;
++                              OUT_INSN (len, "mov\t%A0, %C0", operands);
++                              OUT_INSN (len, "mov\t%B0, %D0", operands);
++                              OUT_INSN (len, "clr\t%A0", operands);
++                              OUT_INSN (len, "clr\t%B0", operands);
++                      }
++                      if (GET_CODE (operands[0]) == REG)
++                              dummy = 4;
++
++                      shiftpos -= 32;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += set_len (operands[0], 12, 1);
++                      }
++
++                      if (len)
++                              *len = dummy;
++                      break;
++
++              case 48:
++              case 49:
++              case 50:
++              case 51:
++              case 52:
++              case 53:
++              case 54:
++              case 55:
++              case 56:
++              case 57:
++              case 58:
++              case 59:
++              case 60:
++              case 61:
++              case 62:
++                      if (zs)
++                      {
++                              dummy = 8;
++                              OUT_INSN (len, "mov\t@%E0, %D0", operands);
++                              OUT_INSN (len, "clr\t%A0", operands);
++                              OUT_INSN (len, "clr\t%B0", operands);
++                              OUT_INSN (len, "clr\t%C0", operands);
++                      }
++                      else
++                      {
++                              dummy = 9;
++                              OUT_INSN (len, "mov\t%A0, %D0", operands);
++                              OUT_INSN (len, "clr\t%A0", operands);
++                              OUT_INSN (len, "clr\t%B0", operands);
++                              OUT_INSN (len, "clr\t%C0", operands);
++                      }
++
++                      shiftpos -= 48;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += set_len (operands[0], 12, 1);
++                      }
++
++                      if (GET_CODE (operands[0]) == REG)
++                              dummy = 4;
++                      if (len)
++                              *len = dummy;
++
++                      break;
++
++              case 63:
++                      if (zs || indexed_location (operands[0]))
++                      {
++                              OUT_INSN (len, "rra\t@%E0", operands);
++                              OUT_INSN (len, "clr\t%A0", operands);
++                              OUT_INSN (len, "clr\t%B0", operands);
++                              OUT_INSN (len, "clr\t%C0", operands);
++                              OUT_INSN (len, "clr\t%D0", operands);
++                              OUT_INSN (len, "rrc\t%D0", operands);
++                              dummy = 11;
++                      }
++                      else
++                      {
++                              OUT_INSN (len, "rra\t%A0", operands);
++                              OUT_INSN (len, "clr\t%A0", operands);
++                              OUT_INSN (len, "clr\t%B0", operands);
++                              OUT_INSN (len, "clr\t%C0", operands);
++                              OUT_INSN (len, "clr\t%D0", operands);
++                              OUT_INSN (len, "rrc\t%D0", operands);
++                              dummy = 12;
++                              if (REG_P (operands[0]))
++                                      dummy = 6;
++                      }
++
++                      if (len)
++                              *len = dummy;
++
++                      break;          /* make compiler happy */
++
++              default:
++                      OUT_INSN (len, "clr\t%A0", operands);
++                      OUT_INSN (len, "clr\t%B0", operands);
++                      OUT_INSN (len, "clr\t%C0", operands);
++                      OUT_INSN (len, "clr\t%D0", operands);
++                      dummy = 8;
++                      if (zs)
++                              dummy--;
++                      if (REG_P (operands[0]))
++                              dummy = 4;
++
++                      if (len)
++                              *len = dummy;
++
++              }                       /* switch */
++
++              return "";
++      }
++      else
++              msp430_emit_shift_cnt (set_len, pattern, insn, operands, len, 12);
++
++      return "";                      /* make compiler happy */
++}
++
++/********* SHIFT RIGHT CODE ***************************************/
++const char *
++msp430_emit_ashrqi3 (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
++      const char *pattern;
++      int shiftpos;
++
++      if (zs)
++              pattern = "rra.b\t@%E0";
++      else
++              pattern = "rra.b\t%A0";
++
++      if (GET_CODE (operands[2]) == CONST_INT)
++      {
++
++              shiftpos = INTVAL (operands[2]);
++
++              switch (shiftpos)
++              {
++              case 0:         /* paranoia setting */
++                      dummy = 0;
++                      break;
++
++              case 1:
++              case 2:
++              case 3:
++              case 4:
++              case 5:
++              case 6:
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += 2;
++                      }
++                      break;
++
++              case 7:
++                      if (zs)
++                      {
++                              OUT_INSN (len, "sxt\t@%E0", operands);
++                              OUT_INSN (len, "swpb\t@%E0", operands);
++                              OUT_INSN (len, "and.b\t#-1, %A0", operands);
++                              dummy = 4;
++                      }
++                      else
++                      {
++                              OUT_INSN (len, "sxt\t%A0", operands);
++                              OUT_INSN (len, "swpb\t%A0", operands);
++                              OUT_INSN (len, "and.b\t#-1, %A0", operands);
++                              dummy = 6;
++                      }
++                      if (REG_P (operands[0]))
++                              dummy = 3;
++                      if (len)
++                              *len = dummy;
++                      return "";
++
++                      break;
++
++              default:
++                      OUT_INSN (len, "clr.b\t%A0", operands);
++                      dummy = 2;
++                      if (REG_P (operands[0]))
++                              dummy = 1;
++              }
++
++              if (len)
++                      *len = dummy;
++              return "";
++      }
++      else
++      {
++              msp430_emit_shift_cnt (set_ren, pattern, insn, operands, len, 2);
++      }
++
++      return "";
++}
++
++const char *
++msp430_emit_ashrhi3 (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
++      const char *pattern;
++      int shiftpos;
++
++      if (zs)
++              pattern = "rra\t@%E0";
++      else
++              pattern = "rra\t%A0";
++
++      if (GET_CODE (operands[2]) == CONST_INT)
++      {
++              shiftpos = INTVAL (operands[2]);
++
++              switch (shiftpos)
++              {
++              case 0:         /* paranoia setting */
++                      dummy = 0;
++                      break;
++
++              case 1:
++              case 2:
++              case 3:
++              case 4:
++              case 5:
++              case 6:
++              case 7:
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += 2;
++                      }
++                      if (zs || REG_P (operands[0]))
++                              dummy >>= 1;
++                      break;
++
++              case 8:
++              case 9:
++              case 10:
++              case 11:
++              case 12:
++              case 13:
++              case 14:
++                      if (zs)
++                      {
++                              OUT_INSN (len, "swpb\t@%E0", operands);
++                              OUT_INSN (len, "sxt\t@%E0", operands);
++                              dummy = 2;
++                      }
++                      else
++                      {
++                              OUT_INSN (len, "swpb\t%A0", operands);
++                              OUT_INSN (len, "sxt\t%A0", operands);
++                              dummy = 4;
++                              if (REG_P (operands[0]))
++                                      dummy = 2;
++                      }
++                      shiftpos -= 8;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += (zs || REG_P (operands[0])) ? 1 : 2;
++                      }
++                      break;
++
++              case 15:
++                      if (zs)
++                      {
++                              OUT_INSN (len, "swpb\t@%E0", operands);
++                              OUT_INSN (len, "sxt\t@%E0", operands);
++                              OUT_INSN (len, "swpb\t@%E0", operands);
++                              OUT_INSN (len, "swpb\t@%E0", operands);
++                              dummy = 4;
++                      }
++                      else
++                      {
++                              OUT_INSN (len, "swpb\t%A0", operands);
++                              OUT_INSN (len, "sxt\t%A0", operands);
++                              OUT_INSN (len, "swpb\t%A0", operands);
++                              OUT_INSN (len, "sxt\t%A0", operands);
++                              dummy = 8;
++                      }
++                      if (REG_P (operands[0]))
++                              dummy = 4;
++                      break;
++
++              default:
++                      OUT_INSN (len, "clr\t%A0", operands);
++                      dummy = 2;
++                      if (REG_P (operands[0]))
++                              dummy = 1;
++              }
++
++              if (len)
++                      *len = dummy;
++              return "";
++      }
++      else
++      {
++              msp430_emit_shift_cnt (set_ren, pattern, insn, operands, len, 2);
++      }
++
++      return "";
++}
++
++const char *
++msp430_emit_ashrsi3 (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++
++      int dummy = 0;
++      const char *pattern;
++      int zs = zero_shifted (operands[0]);
++
++      pattern = "rra\t%B0\n\trrc\t%A0";
++
++      if (GET_CODE (operands[2]) == CONST_INT)
++      {
++              int shiftpos = INTVAL (operands[2]);
++
++              switch (shiftpos)
++              {
++              case 0:
++                      dummy = 0;
++                      break;
++              case 1:
++              case 2:
++              case 3:
++              case 4:
++              case 5:
++              case 6:
++              case 7:
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += set_ren (operands[0], 4, 1);
++                      }
++                      break;
++
++              case 8:
++              case 9:
++              case 10:
++              case 11:
++              case 12:
++              case 13:
++              case 14:
++              case 15:
++                      OUT_INSN (len, "swpb\t%A0", operands);
++                      OUT_INSN (len, "swpb\t%B0", operands);
++                      OUT_INSN (len, "xor.b\t%B0, %A0", operands);
++                      OUT_INSN (len, "xor\t%B0, %A0", operands);
++                      OUT_INSN (len, "sxt\t%B0", operands);
++                      dummy = 12;
++
++                      if (REG_P (operands[0]))
++                              dummy = 5;
++                      shiftpos -= 8;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += set_ren (operands[0], 4, 1);
++                      }
++                      break;
++
++              case 16:
++              case 17:
++              case 18:
++              case 19:
++              case 20:
++              case 21:
++              case 22:
++              case 23:
++                      OUT_INSN (len, "mov\t%B0, %A0", operands);
++                      OUT_INSN (len, "bit\t#0x8000, %B0", operands);
++                      OUT_INSN (len, "jz\t.Lsrc%=", operands);
++                      OUT_INSN (len, "bis\t#0xffff, %B0", operands);
++                      OUT_INSN (len, "jmp\t.Lsre%=\n.Lsrc%=:", operands);
++                      OUT_INSN (len, "clr\t%B0\n.Lsre%=:", operands);
++                      dummy = 12;
++
++                      if (GET_CODE (operands[0]) == REG)
++                              dummy = 7;
++
++                      shiftpos -= 16;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, "rra\t%A0", operands);
++                              dummy += 2;
++                              if (GET_CODE (operands[0]) == REG || zs)
++                                      dummy--;
++                      }
++
++                      break;
++
++              case 24:
++              case 25:
++              case 26:
++              case 27:
++              case 28:
++              case 29:
++              case 30:
++                      OUT_INSN (len, "swpb\t%B0", operands);
++                      OUT_INSN (len, "sxt\t%B0", operands);
++                      OUT_INSN (len, "mov\t%B0, %A0", operands);
++                      OUT_INSN (len, "swpb\t%B0", operands);
++                      OUT_INSN (len, "sxt\t%B0", operands);
++                      dummy = 11;
++
++                      if (GET_CODE (operands[0]) == REG)
++                              dummy = 5;
++
++                      shiftpos -= 24;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, "rra\t%A0", operands);
++                              dummy += 2;
++                              if (GET_CODE (operands[0]) == REG || zs)
++                                      dummy--;
++                      }
++                      break;
++
++              case 31:
++                      OUT_INSN (len, "tst\t%B0", operands);
++                      OUT_INSN (len, "mov\t#-1,%B0", operands);
++                      OUT_INSN (len, "mov\t#-1,%A0", operands);
++                      if (GET_CODE (operands[0]) == REG)
++                              OUT_INSN (len, "jn\t+4", operands);
++                      else
++                              OUT_INSN (len, "jn\t+8", operands);
++                      OUT_INSN (len, "clr\t%A0", operands);
++                      OUT_INSN (len, "clr\t%B0", operands);
++                      dummy = 11;
++                      if (GET_CODE (operands[0]) == REG)
++                              dummy = 6;
++                      break;
++
++              default:
++                      dummy = 0;              /* leave it alone!!! */
++                      break;
++
++              }                       /* switch */
++
++              if (len)
++                      *len = dummy;
++              return "";
++      }
++      else
++              msp430_emit_shift_cnt (set_ren, pattern, insn, operands, len, 4);
++
++      return "";
++
++}
++
++const char *
++msp430_emit_ashrdi3 (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++
++      int dummy = 0;
++      const char *pattern;
++
++      pattern = "rra\t%D0\n\trrc\t%C0\n\trrc\t%B0\n\trrc\t%A0";
++
++      if (GET_CODE (operands[2]) == CONST_INT)
++      {
++              int shiftpos = INTVAL (operands[2]);
++
++              switch (shiftpos)
++              {
++              case 0:
++                      dummy = 0;
++                      break;
++              case 1:
++              case 2:
++              case 3:
++              case 4:
++              case 5:
++              case 6:
++              case 7:
++              case 8:
++              case 9:
++              case 10:
++              case 11:
++              case 12:
++              case 13:
++              case 14:
++              case 15:
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, pattern, operands);
++                              dummy += set_ren (operands[0], 8, 1);
++                      }
++                      break;
++
++              case 16:
++              case 17:
++              case 18:
++              case 19:
++              case 20:
++              case 21:
++              case 22:
++              case 23:
++              case 24:
++              case 25:
++              case 26:
++              case 27:
++              case 28:
++              case 29:
++              case 30:
++              case 31:
++
++                      OUT_INSN (len, "mov\t%B0, %A0", operands);
++                      OUT_INSN (len, "mov\t%C0, %B0", operands);
++                      OUT_INSN (len, "mov\t%D0, %C0", operands);
++                      OUT_INSN (len, "swpb\t%D0", operands);
++                      OUT_INSN (len, "sxt\t%D0", operands);
++                      OUT_INSN (len, "swpb\t%D0", operands);
++                      OUT_INSN (len, "sxt\t%D0", operands);
++
++                      dummy = 17;
++                      if (GET_CODE (operands[0]) == REG)
++                              dummy = 7;
++                      shiftpos -= 16;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, "rra\t%C0\n\trrc\t%B0\n\trrc\t%A0", operands);
++                              dummy += set_ren (operands[0], 6, 1);
++                      }
++
++                      break;
++
++              case 32:
++              case 33:
++              case 34:
++              case 35:
++              case 36:
++              case 37:
++              case 38:
++              case 39:
++              case 40:
++              case 41:
++              case 42:
++              case 43:
++              case 44:
++              case 45:
++              case 46:
++              case 47:
++                      OUT_INSN (len, "mov\t%C0, %A0", operands);
++                      OUT_INSN (len, "mov\t%D0, %B0", operands);
++                      OUT_INSN (len, "swpb\t%D0", operands);
++                      OUT_INSN (len, "sxt\t%D0", operands);
++                      OUT_INSN (len, "swpb\t%D0", operands);
++                      OUT_INSN (len, "sxt\t%D0", operands);
++                      OUT_INSN (len, "mov\t%D0, %C0", operands);
++                      dummy = 17;
++                      if (GET_CODE (operands[0]) == REG)
++                              dummy = 8;
++                      shiftpos -= 32;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, "rra\t%B0\n\trrc\t%A0", operands);
++                              dummy += set_ren (operands[0], 4, 1);
++                      }
++                      break;
++
++              case 48:
++              case 49:
++              case 50:
++              case 51:
++              case 52:
++              case 53:
++              case 54:
++              case 55:
++              case 56:
++              case 57:
++              case 58:
++              case 59:
++              case 60:
++              case 61:
++              case 62:
++                      OUT_INSN (len, "mov\t%D0, %A0", operands);
++                      OUT_INSN (len, "swpb\t%D0", operands);
++                      OUT_INSN (len, "sxt\t%D0", operands);
++                      OUT_INSN (len, "swpb\t%D0", operands);
++                      OUT_INSN (len, "sxt\t%D0", operands);
++                      OUT_INSN (len, "mov\t%D0, %C0", operands);
++                      OUT_INSN (len, "mov\t%D0, %B0", operands);
++                      dummy = 17;
++                      if (GET_CODE (operands[0]) == REG)
++                              dummy = 7;
++                      shiftpos -= 48;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, "rra\t%A0", operands);
++                              dummy += set_ren (operands[0], 2, 1);
++                      }
++                      break;
++
++              case 63:
++                      OUT_INSN (len, "swpb\t%D0", operands);
++                      OUT_INSN (len, "sxt\t%D0", operands);
++                      OUT_INSN (len, "swpb\t%D0", operands);
++                      OUT_INSN (len, "sxt\t%D0", operands);
++                      OUT_INSN (len, "mov\t%D0, %C0", operands);
++                      OUT_INSN (len, "mov\t%D0, %B0", operands);
++                      OUT_INSN (len, "mov\t%D0, %A0", operands);
++                      dummy = 17;
++                      if (GET_CODE (operands[0]) == REG)
++                              dummy = 7;
++                      break;
++
++              default:
++                      dummy = 0;
++
++              }                       /* case */
++
++              if (len)
++                      *len = dummy;
++              return "";
++      }
++      else
++              msp430_emit_shift_cnt (set_ren, pattern, insn, operands, len, 8);
++      return "";
++}
++
++/********* LOGICAL SHIFT RIGHT CODE ***************************************/
++const char *
++msp430_emit_lshrqi3 (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
++      const char *pattern;
++      const char *second_pat;
++      int shiftpos;
++
++      if (zs)
++      {
++              pattern = "clrc\n\trrc.b\t@%E0";
++              second_pat = "rra.b\t@%E0";
++      }
++      else
++      {
++              pattern = "clrc\n\trrc.b\t%A0";
++              second_pat = "rra.b\t%A0";
++      }
++
++      if (GET_CODE (operands[2]) == CONST_INT)
++      {
++
++              shiftpos = INTVAL (operands[2]);
++
++              if (shiftpos != 7 && shiftpos)
++              {
++                      OUT_INSN (len, pattern, operands);
++                      dummy += set_rel (operands[0], 2, 1);
++                      shiftpos--;
++              }
++
++              switch (shiftpos)
++              {
++              case 0:
++                      break;
++
++              case 1:
++              case 2:
++              case 3:
++              case 4:
++              case 5:
++              case 6:
++
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, second_pat, operands);
++                              dummy += set_rel (operands[0], 2, 1) - 1;
++                      }
++
++                      break;
++
++              case 7:
++                      if (zs)
++                      {
++                              OUT_INSN (len, "rla.b\t@%E0", operands);
++                              OUT_INSN (len, "clr.b\t%A0", operands);
++                              OUT_INSN (len, "rlc.b\t@%E0", operands);
++                              dummy = 4;
++                      }
++                      else
++                      {
++                              OUT_INSN (len, "rla.b\t%A0", operands);
++                              OUT_INSN (len, "clr.b\t%A0", operands);
++                              OUT_INSN (len, "rlc.b\t%A0", operands);
++                              dummy = 6;
++                      }
++                      if (REG_P (operands[0]))
++                              dummy = 3;
++                      break;
++
++              default:
++                      OUT_INSN (len, "clr.b\t%A0", operands);
++                      dummy = 2;
++                      if (REG_P (operands[0]))
++                              dummy = 1;
++                      break;
++              }
++
++              if (len)
++                      *len = dummy;
++      }
++      else
++      {
++              msp430_emit_shift_cnt (set_rel, pattern, insn, operands, len, 2);
++      }
++
++      return "";
++}
++
++const char *
++msp430_emit_lshrhi3 (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
++      const char *pattern;
++      const char *second_pat;
++      int shiftpos;
++
++      if (zs)
++      {
++              pattern = "clrc\n\trrc\t@%E0";
++              second_pat = "rra\t@%E0";
++      }
++      else
++      {
++              pattern = "clrc\n\trrc\t%A0";
++              second_pat = "rra\t%A0";
++      }
++
++      if (GET_CODE (operands[2]) == CONST_INT)
++      {
++              shiftpos = INTVAL (operands[2]);
++
++              if (shiftpos < 8 && shiftpos)
++              {
++                      OUT_INSN (len, pattern, operands);
++                      dummy += set_rel (operands[0], 2, 1);
++                      shiftpos--;
++              }
++
++              switch (shiftpos)
++              {
++              case 0:
++                      break;
++
++              case 1:
++              case 2:
++              case 3:
++              case 4:
++              case 5:
++              case 6:
++              case 7:
++
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, second_pat, operands);
++                              dummy += set_rel (operands[0], 2, 1) - 1;
++                      }
++
++                      break;
++
++              case 8:
++              case 9:
++              case 10:
++              case 11:
++              case 12:
++              case 13:
++              case 14:
++
++                      if (zs)
++                      {
++                              OUT_INSN (len, "swpb\t@%E0", operands);
++                              OUT_INSN (len, "and.b\t#-1, %A0", operands);
++                              dummy = 3;
++                      }
++                      else
++                      {
++                              OUT_INSN (len, "swpb\t%A0", operands);
++                              OUT_INSN (len, "and.b\t#-1, %A0", operands);
++                              dummy = 4;
++                      }
++                      if (REG_P (operands[0]))
++                              dummy = 2;
++                      shiftpos -= 8;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, second_pat, operands);
++                              dummy += set_rel (operands[0], 2, 1) - 1;
++                      }
++                      break;
++
++              case 15:
++
++                      if (zs)
++                      {
++                              OUT_INSN (len, "rla\t@%E0", operands);
++                              OUT_INSN (len, "clr\t@%E0", operands);
++                              OUT_INSN (len, "rlc\t@%E0", operands);
++                              dummy = 3;
++                      }
++                      else
++                      {
++                              OUT_INSN (len, "rla\t%A0", operands);
++                              OUT_INSN (len, "clr\t%A0", operands);
++                              OUT_INSN (len, "rlc\t%A0", operands);
++                              dummy = 6;
++                      }
++                      if (REG_P (operands[0]))
++                              dummy = 3;
++                      break;
++
++              default:
++                      OUT_INSN (len, "clr\t%A0", operands);
++                      dummy = 2;
++                      if (REG_P (operands[0]))
++                              dummy = 1;
++                      break;
++              }
++
++              if (len)
++                      *len = dummy;
++              return "";
++      }
++      else
++      {
++              msp430_emit_shift_cnt (set_rel, pattern, insn, operands, len, 2);
++      }
++
++      return "";
++
++}
++
++const char *
++msp430_emit_lshrsi3 (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      const char *pattern;
++      int dummy = 0;
++      int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
++      const char *second_pat = "rra\t%B0\n\trrc\t%A0";
++
++      pattern = "clrc\n\trrc\t%B0\n\trrc\t%A0";
++
++      if (GET_CODE (operands[2]) == CONST_INT)
++      {
++              int shiftpos = INTVAL (operands[2]);
++
++              if (shiftpos < 8 && shiftpos)
++              {
++                      OUT_INSN (len, pattern, operands);
++                      /* This function was underestimating the length by 1 for shifts from
++                      1 to 7.  I added one here - Max */
++                      dummy += set_rel (operands[0], 2, 1) + 1;
++                      shiftpos--;
++              }
++
++              switch (shiftpos)
++              {
++              case 0:
++                      break;
++
++              case 1:
++              case 2:
++              case 3:
++              case 4:
++              case 5:
++              case 6:
++              case 7:
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, second_pat, operands);
++                              dummy += set_rel (operands[0], 4, 1) - 1;
++                      }
++
++                      break;
++
++              case 8:
++              case 9:
++              case 10:
++              case 11:
++              case 12:
++              case 13:
++              case 14:
++              case 15:
++                      OUT_INSN (len, "swpb\t%A0", operands);
++                      OUT_INSN (len, "swpb\t%B0", operands);
++                      OUT_INSN (len, "xor.b\t%B0, %A0", operands);
++                      OUT_INSN (len, "xor\t%B0, %A0", operands);
++                      OUT_INSN (len, "and.b\t#-1, %B0", operands);
++                      dummy = 12;
++
++                      if (REG_P (operands[0]))
++                              dummy = 5;
++                      shiftpos -= 8;
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, second_pat, operands);
++                              dummy += set_rel (operands[0], 4, 1) - 1;
++                      }
++                      break;
++
++              case 16:
++              case 17:
++              case 18:
++              case 19:
++              case 20:
++              case 21:
++              case 22:
++              case 23:
++                      OUT_INSN (len, "mov\t%B0, %A0", operands);
++                      OUT_INSN (len, "clr\t%B0", operands);
++                      dummy = 5;
++                      if (REG_P (operands[0]))
++                              dummy = 2;
++
++                      shiftpos -= 16;
++                      if (shiftpos)
++                      {
++                              OUT_INSN (len, "clrc\n\trrc\t%A0", operands);
++                              dummy += 2;
++                              if (!zs && !REG_P (operands[0]))
++                                      dummy++;
++                              shiftpos--;
++                      }
++
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, "rra\t%A0", operands);
++                              dummy += 1;
++                              if (!zs && !REG_P (operands[0]))
++                                      dummy++;
++                      }
++                      break;
++
++              case 24:
++              case 25:
++              case 26:
++              case 27:
++              case 28:
++              case 29:
++              case 30:
++                      OUT_INSN (len, "mov\t%B0, %A0", operands);
++                      OUT_INSN (len, "clr\t%B0", operands);
++                      OUT_INSN (len, "swpb\t%A0", operands);
++                      OUT_INSN (len, "and.b\t#-1, %A0", operands);
++                      dummy = 9;
++                      if (REG_P (operands[0]))
++                              dummy = 4;
++                      if (indexed_location (operands[0]))
++                              dummy -= 1;
++                      shiftpos -= 24;
++
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, "rra\t%A0", operands);
++                              dummy += 1;
++                              if (!zs && !REG_P (operands[0]))
++                                      dummy++;
++                      }
++                      break;
++
++              case 31:
++                      OUT_INSN (len, "rla\r%B0", operands);
++                      OUT_INSN (len, "clr\t%B0", operands);
++                      OUT_INSN (len, "clr\t%A0", operands);
++                      OUT_INSN (len, "rlc\t%A0", operands);
++                      dummy = 8;
++                      if (REG_P (operands[0]))
++                              dummy = 4;
++                      if (indexed_location (operands[0]))
++                              dummy -= 1;
++                      break;
++
++              default:
++                      OUT_INSN (len, "clr\t%B0", operands);
++                      OUT_INSN (len, "clr\t%A0", operands);
++                      dummy = 4;
++                      if (REG_P (operands[0]))
++                              dummy = 2;
++                      break;
++
++              }                       /* switch */
++
++              if (len)
++                      *len = dummy;
++              return "";
++      }
++      else
++              msp430_emit_shift_cnt (set_rel, pattern, insn, operands, len, 4);
++
++      return "";
++}
++
++const char *
++msp430_emit_lshrdi3 (insn, operands, len)
++rtx insn;
++rtx operands[];
++int *len;
++{
++      int dummy = 0;
++      const char *pattern;
++      int zs = zero_shifted (operands[0]) || indexed_location (operands[0]);
++      const char *secondary_pat = "rra\t%D0\n\trrc\t%C0\n\trrc\t%B0\n\trrc\t%A0";
++
++      pattern = "clrc\n\trrc\t%D0\n\trrc\t%C0\n\trrc\t%B0\n\trrc\t%A0";
++
++      if (GET_CODE (operands[2]) == CONST_INT)
++      {
++              int shiftpos = INTVAL (operands[2]);
++
++              if (shiftpos < 16 && shiftpos)
++              {
++                      OUT_INSN (len, pattern, operands);
++                      dummy += set_rel (operands[0], 2, 1);
++                      shiftpos--;
++              }
++
++              switch (shiftpos)
++              {
++              case 0:
++                      break;
++
++              case 1:
++              case 2:
++              case 3:
++              case 4:
++              case 5:
++              case 6:
++              case 7:
++              case 8:
++              case 9:
++              case 10:
++              case 11:
++              case 12:
++              case 13:
++              case 14:
++              case 15:
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, secondary_pat, operands);
++                              dummy += set_rel (operands[0], 8, 1) - 1;
++                      }
++
++                      break;
++
++              case 16:
++              case 17:
++              case 18:
++              case 19:
++              case 20:
++              case 21:
++              case 22:
++              case 23:
++              case 24:
++              case 25:
++              case 26:
++              case 27:
++              case 28:
++              case 29:
++              case 30:
++              case 31:
++                      OUT_INSN (len, "mov\t%B0, %A0", operands);
++                      OUT_INSN (len, "mov\t%C0, %B0", operands);
++                      OUT_INSN (len, "mov\t%D0, %C0", operands);
++                      OUT_INSN (len, "clr\t%D0", operands);
++                      dummy = 11;
++                      if (REG_P (operands[0]))
++                              dummy = 4;
++                      shiftpos -= 16;
++
++                      if (shiftpos)
++                      {
++                              OUT_INSN (len, secondary_pat, operands);
++                              dummy += set_rel (operands[0], 8, 1) - 1;
++                              shiftpos--;
++                      }
++
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, "rra\t%C0\n\trrc\t%B0\n\trrc\t%A0", operands);
++                              if (REG_P (operands[0]))
++                                      dummy = 3;
++                              else
++                                      dummy += 6;
++                              if (zs)
++                                      dummy--;
++                      }
++
++                      break;
++
++              case 32:
++              case 33:
++              case 34:
++              case 35:
++              case 36:
++              case 37:
++              case 38:
++              case 39:
++              case 40:
++              case 41:
++              case 42:
++              case 43:
++              case 44:
++              case 45:
++              case 46:
++              case 47:
++                      OUT_INSN (len, "mov\t%C0, %A0", operands);
++                      OUT_INSN (len, "mov\t%D0, %B0", operands);
++                      OUT_INSN (len, "clr\t%C0", operands);
++                      OUT_INSN (len, "clr\t%D0", operands);
++
++                      dummy = 10;
++                      if (GET_CODE (operands[0]) == REG)
++                              dummy = 4;
++
++                      shiftpos -= 32;
++
++                      if (shiftpos)
++                      {
++                              OUT_INSN (len, "clrc\n\trrc\t%B0,rrc\t%A0", operands);
++                              if (REG_P (operands[0]))
++                                      dummy += 3;
++                              else
++                                      dummy += 5;
++                              if (zs)
++                                      dummy--;
++                              shiftpos--;
++                      }
++
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, "rra\t%B0,rrc\t%A0", operands);
++                              if (REG_P (operands[0]))
++                                      dummy += 2;
++                              else
++                                      dummy += 4;
++                              if (zs)
++                                      dummy--;
++                      }
++                      break;
++
++              case 48:
++              case 49:
++              case 50:
++              case 51:
++              case 52:
++              case 53:
++              case 54:
++              case 55:
++              case 56:
++              case 57:
++              case 58:
++              case 59:
++              case 60:
++              case 61:
++              case 62:
++                      OUT_INSN (len, "mov\t%D0, %A0", operands);
++                      OUT_INSN (len, "clr\t%B0", operands);
++                      OUT_INSN (len, "clr\t%C0", operands);
++                      OUT_INSN (len, "clr\t%D0", operands);
++                      dummy = 9;
++                      if (GET_CODE (operands[0]) == REG)
++                              dummy = 4;
++                      shiftpos -= 48;
++
++                      if (shiftpos)
++                      {
++                              OUT_INSN (len, "clrc\n\trrc\t%A0", operands);
++                              if (REG_P (operands[0]) || zs)
++                                      dummy += 2;
++                              else
++                                      dummy += 3;
++
++                              shiftpos--;
++                      }
++
++                      while (shiftpos--)
++                      {
++                              OUT_INSN (len, "rra\t%A0", operands);
++                              if (REG_P (operands[0]) || zs)
++                                      dummy++;
++                              else
++                                      dummy += 2;
++                      }
++                      break;
++
++              case 63:
++
++                      OUT_INSN (len, "rla\t%D0", operands);
++                      OUT_INSN (len, "clr\t%D0", operands);
++                      OUT_INSN (len, "clr\t%C0", operands);
++                      OUT_INSN (len, "clr\t%B0", operands);
++                      OUT_INSN (len, "clr\t%A0", operands);
++                      OUT_INSN (len, "rlc\t%A0", operands);
++                      if (REG_P (operands[0]))
++                              dummy += 6;
++                      else
++                              dummy += 13;
++
++                      if (zs)
++                              dummy--;
++                      break;
++
++              default:
++                      break;
++              }                       /* case */
++
++              if (len)
++                      *len = dummy;
++      }
++      else
++              msp430_emit_shift_cnt (set_rel, pattern, insn, operands, len, 8);
++
++      return "";
++}
++
++/*
++*     Multiplication helpers
++*     1. As shifts, 2. the rest 
++*/
++
++#define SOME_SHIFT_THRESHOLD_VAL      10
++
++int
++msp430_easy_mul (operands, sext)
++rtx operands[];
++int sext;
++{
++      enum machine_mode op0mode = GET_MODE (operands[0]);
++      enum machine_mode op1mode = GET_MODE (operands[1]);
++      rtx op0 = operands[0];
++      rtx op1 = operands[1];
++      rtx insn;
++      int m = INTVAL (operands[2]);
++      int sign = (m < 0);
++      int val = (m > 0 ? m : -m);
++      int shift1 = 0, shift0 = 0;
++      int add1 = 0, sub1 = 0;
++      int t0, t1;
++      int ops = 0;
++
++      m = val;
++      /* 
++      we can do: 
++      const == single bit const +- N that (shift0 + add1/sub1 < 8 instructions) 
++      */
++      shift0 = 1;
++      shift1 = 0;
++
++      for (t0 = 2;
++              t0 <= val * 2 && shift0 < GET_MODE_SIZE (op0mode) * BITS_PER_UNIT;
++              t0 <<= 1)
++      {
++              if (t0 == val)
++                      goto done;
++
++              for (t1 = 1; t1 < t0 && shift1 < GET_MODE_SIZE (op1mode) * BITS_PER_UNIT;
++                      t1 <<= 1)
++              {
++                      add1 = 0;
++                      sub1 = 0;
++                      if (t0 + t1 == m)
++                      {
++                              add1 = 1;
++                              goto done;
++                      }
++                      if (t0 - t1 == m)
++                      {
++                              sub1 = 1;
++                              goto done;
++                      }
++
++                      if (t0 + t1 * 3 == m)
++                      {
++                              add1 = 3;
++                              goto done;
++                      }
++
++                      if (t0 - t1 * 3 == m)
++                      {
++                              sub1 = 3;
++                              goto done;
++                      }
++
++                      add1 = 0;
++                      sub1 = 0;
++                      shift1++;
++
++              }
++              shift1 = 0;
++              shift0++;
++      }
++
++      return 0;
++done:
++
++      ops = shift0 * (op0mode == SImode ? 2 : 1);
++      ops += shift1 + add1 + sub1;
++      if (op0mode != op1mode)
++      {
++              ops += (op0mode == SImode ? 2 : 1) * ((add1 || sub1) ? 2 : 1);
++      }
++
++      if (ops > SOME_SHIFT_THRESHOLD_VAL)
++              return 0;
++
++      if (op0mode != op1mode)
++      {
++              rtx extend;
++              if (sext)
++                      extend = gen_rtx_SIGN_EXTEND (op0mode, op1);
++              else
++                      extend = gen_rtx_ZERO_EXTEND (op0mode, op1);
++              insn = gen_rtx_SET (VOIDmode, op0, extend);
++              emit_insn (insn);
++      }
++      else
++      {
++              emit_move_insn (op0, op1);
++      }
++
++      /* shift0 */
++      switch (op0mode)
++      {
++      case QImode:
++              emit_insn (gen_ashlqi3 (op0, op0, GEN_INT (shift0)));
++              break;
++      case HImode:
++              emit_insn (gen_ashlhi3 (op0, op0, GEN_INT (shift0)));
++              break;
++      case SImode:
++              emit_insn (gen_ashlsi3 (op0, op0, GEN_INT (shift0)));
++              break;
++      case DImode:
++              emit_insn (gen_ashldi3 (op0, op0, GEN_INT (shift0)));
++              break;
++      default:
++              abort ();
++      }
++
++      if (op0mode != op1mode && (add1 || sub1 || shift1))
++      {
++              /* equalize operands modes */
++              rtx extend;
++              rtx treg = gen_reg_rtx (op0mode);
++
++              if (sext)
++                      extend = gen_rtx_SIGN_EXTEND (op0mode, op1);
++              else
++                      extend = gen_rtx_ZERO_EXTEND (op0mode, op1);
++              insn = gen_rtx_SET (VOIDmode, treg, extend);
++              emit_insn (insn);
++              op1 = treg;
++              op1mode = GET_MODE (treg);
++      }
++      else if (add1 || sub1 || shift1)
++      {
++              rtx treg = gen_reg_rtx (op0mode);
++              emit_move_insn (treg, op1);
++              op1 = treg;
++      }
++
++      if (shift1 && (add1 || sub1))
++      {
++              switch (op1mode)
++              {
++              case QImode:
++                      emit_insn (gen_ashlqi3 (op1, op1, GEN_INT (shift1)));
++                      break;
++              case HImode:
++                      emit_insn (gen_ashlhi3 (op1, op1, GEN_INT (shift1)));
++                      break;
++              case SImode:
++                      emit_insn (gen_ashlsi3 (op1, op1, GEN_INT (shift1)));
++                      break;
++              case DImode:
++                      emit_insn (gen_ashldi3 (op1, op1, GEN_INT (shift1)));
++                      break;
++              default:
++                      abort ();
++              }
++      }
++      else if (shift1)
++              abort ();                       /* paranoia */
++
++      while (add1--)
++      {
++              insn =
++                      gen_rtx_SET (VOIDmode, op0, gen_rtx_PLUS (GET_MODE (op0), op0, op1));
++              emit_insn (insn);
++      }
++
++      while (sub1--)
++      {
++              insn =
++                      gen_rtx_SET (VOIDmode, op0,
++                      gen_rtx_MINUS (GET_MODE (op0), op0, op1));
++              emit_insn (insn);
++      }
++
++      if (sign)
++      {
++              switch (op0mode)
++              {
++              case QImode:
++                      emit_insn (gen_negqi2 (op0, op0));
++                      break;
++              case HImode:
++                      emit_insn (gen_neghi2 (op0, op0));
++                      break;
++              case SImode:
++                      emit_insn (gen_negsi2 (op0, op0));
++                      break;
++              case DImode:
++                      emit_insn (gen_negdi2 (op0, op0));
++                      break;
++              default:
++                      abort ();
++              }
++      }
++
++      return 1;
++}
++
++/* multiplication guards */
++#define LOAD_MPY(x)   \
++      do{ \
++      if(GET_MODE(x) == QImode)               \
++      emit_insn(gen_load_mpyq(x));    \
++  else                                        \
++  emit_insn(gen_load_mpy(x)); \
++      }while(0)
++
++#define LOAD_MPYS(x)  \
++      do{ \
++      if(GET_MODE(x) == QImode)               \
++      emit_insn(gen_load_mpysq(x));   \
++  else                                        \
++  emit_insn(gen_load_mpys(x));        \
++      }while(0)
++
++#define LOAD_OP2(x)   \
++      do{ \
++      if(GET_MODE(x) == QImode)               \
++      emit_insn(gen_load_op2q(x));    \
++  else                                        \
++  emit_insn(gen_load_op2(x)); \
++      }while(0)
++
++int
++msp430_mul3_guard (operands, sext)
++rtx operands[];
++int sext;
++{
++      rtx m_mpys = mpys_rtx;
++      rtx m_op2 = op2_rtx;
++      rtx m_reslo = reslo_rtx;
++      enum machine_mode op0mode = GET_MODE (operands[0]);
++      enum machine_mode op1mode = GET_MODE (operands[1]);
++      rtx r12 = gen_rtx_REG (op1mode, 12);
++      rtx r10 = gen_rtx_REG (op1mode, 10);
++      rtx r14 = gen_rtx_REG (op0mode, 14);
++
++      if (const_int_operand (operands[2], VOIDmode) &&
++              msp430_easy_mul (operands, sext))
++              return 1;
++
++      if (!msp430_has_hwmul)
++      {
++              rtx clob1 = gen_rtx_CLOBBER (VOIDmode, r10);
++              rtx clob2 = gen_rtx_CLOBBER (VOIDmode, r12);
++              rtx set;
++              rtx mult, op1, op2;
++              rtvec vec;
++              /* prepare 'call' pattern */
++              if (sext==1)
++              {
++                      op1 = gen_rtx_SIGN_EXTEND (op0mode, r10);
++                      op2 = gen_rtx_SIGN_EXTEND (op0mode, r12);
++              }
++              else
++              {
++                      op1 = r10;
++                      op2 = r12;
++              }
++              mult = gen_rtx_MULT (op0mode, op1, op2);
++              set = gen_rtx_SET (op0mode, r14, mult);
++              vec = gen_rtvec (3, set, clob1, clob2);
++
++              emit_move_insn (r10, operands[1]);
++              emit_move_insn (r12, operands[2]);
++              emit (gen_rtx_PARALLEL (VOIDmode, vec));
++              emit_move_insn (operands[0], r14);
++              return 1;
++      }
++      if (op1mode == QImode)
++      {
++              m_mpys = gen_lowpart (QImode, mpys_rtx);
++              m_op2 = gen_lowpart (QImode, op2_rtx);
++      }
++
++      if (op0mode == QImode)
++              m_reslo = gen_lowpart (QImode, reslo_rtx);
++
++      if (!MSP430_NOINT_HWMUL)
++              emit_insn (gen_reent_in ());
++
++      LOAD_MPYS (operands[1]);
++      if (sext)
++              emit_insn (gen_extendqihi2 (mpys_rtx, m_mpys));
++      LOAD_OP2 (operands[2]);
++      if (sext)
++              emit_insn (gen_extendqihi2 (op2_rtx, m_op2));
++
++      if (MSP430_NOINT_HWMUL)
++      {
++              if (op0mode == HImode)
++                      emit_insn (gen_fetch_result_hi_nint (operands[0]));
++              else
++                      emit_insn (gen_fetch_result_qi_nint (operands[0]));
++      }
++      else
++      {
++              if (op0mode == HImode)
++                      emit_insn (gen_fetch_result_hi (operands[0]));
++              else
++                      emit_insn (gen_fetch_result_qi (operands[0]));
++      }
++
++      return 1;
++}
++
++
++int
++msp430_umul3_guard (operands, sext)
++rtx operands[];
++int sext ATTRIBUTE_UNUSED;
++{
++      rtx m_mpy = mpy_rtx;
++      rtx m_op2 = op2_rtx;
++      enum machine_mode op0mode = GET_MODE (operands[0]);
++      enum machine_mode op1mode = GET_MODE (operands[1]);
++      rtx r12 = gen_rtx_REG (op1mode, 12);
++      rtx r10 = gen_rtx_REG (op1mode, 10);
++      rtx r14 = gen_rtx_REG (op0mode, 14);
++
++      if (const_int_operand (operands[2], VOIDmode) &&
++              msp430_easy_mul (operands, 0))
++              return 1;
++
++      if (!msp430_has_hwmul)
++      {
++              rtx clob1 = gen_rtx_CLOBBER (VOIDmode, r10);
++              rtx clob2 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (op1mode, 12));
++              rtx set;
++              rtx mult, op1, op2;
++              rtvec vec;
++              /* prepare 'call' pattern */
++              op1 = gen_rtx_ZERO_EXTEND (op0mode, r10);
++              op2 = gen_rtx_ZERO_EXTEND (op0mode, r12);
++
++              mult = gen_rtx_MULT (op0mode, op1, op2);
++              set = gen_rtx_SET (op0mode, r14, mult);
++              vec = gen_rtvec (3, set, clob1, clob2);
++
++              emit_move_insn (r10, operands[1]);
++              emit_move_insn (r12, operands[2]);
++              emit (gen_rtx_PARALLEL (VOIDmode, vec));
++              emit_move_insn (operands[0], r14);
++              return 1;
++      }
++
++      m_mpy = gen_lowpart (QImode, mpy_rtx);
++      m_op2 = gen_lowpart (QImode, op2_rtx);
++
++      if (!MSP430_NOINT_HWMUL)
++              emit_insn (gen_reent_in ());
++
++      /*  LOAD_MPY (gen_lowpart (QImode,operands[1]));
++      //emit_insn (gen_zero_extendqihi2 (mpy_rtx, m_mpy));
++      //LOAD_OP2 (gen_lowpart (QImode,operands[2]));
++      //emit_insn (gen_zero_extendqihi2 (op2_rtx, m_op2));
++      emit_move_insn(m_op2, gen_lowpart (QImode,operands[2]));*/
++
++      //The code above does not work on GCC v4, as the optimizer removes the move INSN
++      LOAD_MPY (operands[1]);
++      //emit_insn (gen_zero_extendqihi2 (mpy_rtx, m_mpy)); // No need for extension, as the HWMUL recognizes the operand width
++      LOAD_OP2 (operands[2]);
++      //emit_insn (gen_zero_extendqihi2 (op2_rtx, m_op2));
++
++
++      if (MSP430_NOINT_HWMUL)
++              emit_insn (gen_fetch_result_hi_nint (operands[0]));
++      else
++              emit_insn (gen_fetch_result_hi (operands[0]));
++
++      return 1;
++}
++
++
++int
++msp430_mulhisi_guard (operands)
++rtx operands[];
++{
++      enum machine_mode op0mode = GET_MODE (operands[0]);
++      enum machine_mode op1mode = GET_MODE (operands[1]);
++      rtx r12 = gen_rtx_REG (op1mode, 12);
++      rtx r10 = gen_rtx_REG (op1mode, 10);
++      rtx r14 = gen_rtx_REG (op0mode, 14);
++      rtx r11 = gen_rtx_REG (op1mode, 11);
++      rtx r13 = gen_rtx_REG (op1mode, 13);
++
++      if (const_int_operand (operands[2], VOIDmode) &&
++              msp430_easy_mul (operands, 1))
++              return 1;
++
++      if (!msp430_has_hwmul)
++      {
++              rtx clob1 = gen_rtx_CLOBBER (VOIDmode, r10);
++              rtx clob2 = gen_rtx_CLOBBER (VOIDmode, r11);
++              rtx clob3 = gen_rtx_CLOBBER (VOIDmode, r12);
++              rtx clob4 = gen_rtx_CLOBBER (VOIDmode, r13);
++
++              rtx set;
++              rtx mult, op1, op2;
++              rtvec vec;
++              /* prepare 'call' pattern */
++              op1 = gen_rtx_SIGN_EXTEND (op0mode, r10);
++              op2 = gen_rtx_SIGN_EXTEND (op0mode, r12);
++
++              mult = gen_rtx_MULT (op0mode, op1, op2);
++              set = gen_rtx_SET (op0mode, r14, mult);
++              vec = gen_rtvec (5, set, clob1, clob2, clob3, clob4);
++
++              emit_move_insn (r10, operands[1]);
++              emit_move_insn (r12, operands[2]);
++              emit (gen_rtx_PARALLEL (VOIDmode, vec));
++              emit_move_insn (operands[0], r14);
++              return 1;
++      }
++      if (!MSP430_NOINT_HWMUL)
++              emit_insn (gen_reent_in ());
++
++      LOAD_MPYS (operands[1]);
++      LOAD_OP2 (operands[2]);
++
++      if (MSP430_NOINT_HWMUL)
++      {
++              emit_insn (gen_fetch_result_si_nint (operands[0]));
++      }
++      else
++              emit_insn (gen_fetch_result_si (operands[0]));
++
++      return 1;
++}
++
++
++int
++msp430_umulhisi_guard (operands)
++rtx operands[];
++{
++      enum machine_mode op0mode = GET_MODE (operands[0]);
++      enum machine_mode op1mode = GET_MODE (operands[1]);
++      rtx r12 = gen_rtx_REG (op1mode, 12);
++      rtx r10 = gen_rtx_REG (op1mode, 10);
++      rtx r14 = gen_rtx_REG (op0mode, 14);
++      rtx r11 = gen_rtx_REG (op1mode, 11);
++      rtx r13 = gen_rtx_REG (op1mode, 13);
++
++      if (const_int_operand (operands[2], VOIDmode) &&
++              msp430_easy_mul (operands, 0))
++              return 1;
++
++      if (!msp430_has_hwmul)
++      {
++              rtx clob1 = gen_rtx_CLOBBER (VOIDmode, r10);
++              rtx clob2 = gen_rtx_CLOBBER (VOIDmode, r11);
++              rtx clob3 = gen_rtx_CLOBBER (VOIDmode, r12);
++              rtx clob4 = gen_rtx_CLOBBER (VOIDmode, r13);
++
++              rtx set;
++              rtx mult, op1, op2;
++              rtvec vec;
++              /* prepare 'call' pattern */
++              op1 = gen_rtx_ZERO_EXTEND (op0mode, r10);
++              op2 = gen_rtx_ZERO_EXTEND (op0mode, r12);
++
++              mult = gen_rtx_MULT (op0mode, op1, op2);
++              set = gen_rtx_SET (op0mode, r14, mult);
++              vec = gen_rtvec (5, set, clob1, clob2, clob3, clob4);
++
++              emit_move_insn (r10, operands[1]);
++              emit_move_insn (r12, operands[2]);
++              emit (gen_rtx_PARALLEL (VOIDmode, vec));
++              emit_move_insn (operands[0], r14);
++              return 1;
++      }
++
++      if (!MSP430_NOINT_HWMUL)
++              emit_insn (gen_reent_in ());
++
++      LOAD_MPY (operands[1]);
++      LOAD_OP2 (operands[2]);
++
++      if (MSP430_NOINT_HWMUL)
++      {
++              emit_insn (gen_fetch_result_si_nint (operands[0]));
++      }
++      else
++              emit_insn (gen_fetch_result_si (operands[0]));
++
++      return 1;
++}
++
++
++/* something like 'push x(r1)' or 'push @r1' */
++int self_push (rtx x)
++{
++      rtx c;
++      rtx r;
++
++      if (GET_CODE (x) != MEM)
++              return 0;
++
++      c = XEXP (x, 0);
++
++      if (REG_P (c) && REGNO (c) == 1)
++              return 1;
++
++      if (GET_CODE (c) == PLUS)
++      {
++              r = XEXP (c, 0);
++              if (REG_P (r) && REGNO (r) == 1)
++                      return 1;
++      }
++      return 0;
++}
++
++const char * msp430_emit_call (rtx operands[])
++{
++      rtx x = operands[0];
++      rtx c;
++      rtx r;
++
++      if (GET_CODE (x) == MEM)
++      {
++              c = XEXP (x, 0);
++
++              if (REG_P (c) && REGNO (c) == 1)
++              {
++                      OUT_INSN (NULL, "call\t2(%E0)", operands);
++                      return "";
++              }
++
++              if (GET_CODE (c) == PLUS)
++              {
++                      r = XEXP (c, 0);
++                      if (REG_P (r) && REGNO (r) == 1)
++                      {
++                              OUT_INSN (NULL, "call\t2+%A0", operands);
++                              return "";
++                      }
++              }
++      }
++
++      OUT_INSN(NULL, "call\t%0", operands);
++      return "";
++}
++
++/* difficult pushes.
++if planets are not aligned, the combiner does not allocate
++r4 as a frame pointer. Instead, it uses stack pointer for frame.
++If there is a va_arg call and non-register local var has to be passed 
++as a function parameter, the push X(r1) in SI, SF and DI modes will
++corrupt passed var. The following minds this fact */
++
++const char *
++msp430_pushqi (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int sp = self_push (operands[0]);
++      int dummy = 0;
++
++      if (sp)
++      {
++              rtx c;
++              c = XEXP (operands[0], 0);
++              if (REG_P (c))
++                      OUT_INSN (len, "push.b\t2(%E0)", operands);
++              else
++                      OUT_INSN (len, "push.b\t2+%A0", operands);
++              dummy = 2;
++      }
++      else
++      {
++              OUT_INSN (len, "push.b\t%A0", operands);
++              dummy = 2;
++
++              if (GET_CODE (operands[0]) == CONST_INT)
++              {
++                      int cval = INTVAL (operands[0]);
++                      int x = (cval) & 0x0fffful;
++                      if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8 || x == 0xffff)
++                              dummy--;
++
++              }
++              else if (GET_CODE (operands[0]) == REG)
++                      dummy--;
++              else if (GET_CODE (operands[0]) == MEM && REG_P (XEXP (operands[0], 0)))
++                      dummy--;
++      }
++
++      return "";
++}
++
++const char *
++msp430_pushhi (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int sp = self_push (operands[0]);
++      int dummy = 0;
++
++      if (sp)
++      {
++              rtx c;
++              c = XEXP (operands[0], 0);
++              if (REG_P (c))
++                      OUT_INSN (len, "push\t2(%E0)", operands);
++              else
++                      OUT_INSN (len, "push\t2+%A0", operands);
++              dummy = 2;
++      }
++      else
++      {
++              OUT_INSN (len, "push\t%A0", operands);
++              dummy = 2;
++
++              if (GET_CODE (operands[0]) == CONST_INT)
++              {
++                      int cval = INTVAL (operands[0]);
++                      int x = (cval) & 0x0fffful;
++
++                      if (cval == 99999999)
++                      {
++                              if (len)
++                                      *len = 3;
++                              return "";
++                      }
++
++                      if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8 || x == 0xffff)
++                              dummy--;
++
++              }
++              else if (GET_CODE (operands[0]) == REG)
++                      dummy--;
++              else if (GET_CODE (operands[0]) == MEM && REG_P (XEXP (operands[0], 0)))
++                      dummy--;
++      }
++      if (len)
++              *len = dummy;
++      return "";
++}
++
++const char *
++msp430_pushsisf (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int sp = self_push (operands[0]);
++      int dummy = 0;
++
++      if (!sp)
++      {
++              OUT_INSN (len, "push\t%B0", operands);
++              OUT_INSN (len, "push\t%A0", operands);
++              dummy = 4;
++              if (indexed_location (operands[0]))
++                      dummy--;
++              if (REG_P (operands[0]))
++                      dummy -= 2;
++              if (GET_CODE (operands[0]) == CONST_INT)
++              {
++                      int cval = INTVAL (operands[0]);
++                      int x = (cval) & 0x0fffful;
++                      int y = (((unsigned long) (cval)) & 0xffff0000ul >> 16);
++                      if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8 || x == 0xffff)
++                              dummy--;
++                      if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8 || y == 0xffff)
++                              dummy--;
++              }
++              else if (GET_CODE (operands[0]) == CONST_DOUBLE
++                      && GET_MODE (operands[0]) == SFmode)
++              {
++                      long val;
++                      int y, x;
++                      REAL_VALUE_TYPE rv;
++                      REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[0]);
++                      REAL_VALUE_TO_TARGET_SINGLE (rv, val);
++
++                      y = (val & 0xffff0000ul) >> 16;
++                      x = val & 0xffff;
++                      if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8 || x == 0xffff)
++                              dummy--;
++                      if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8 || y == 0xffff)
++                              dummy--;
++              }
++      }
++      else
++      {
++              OUT_INSN (len, "push\t2+%B0", operands);
++              OUT_INSN (len, "push\t2+%B0", operands);
++              dummy = 4;
++      }
++
++      if (len)
++              *len = dummy;
++
++      return "";
++}
++
++
++const char *
++msp430_pushdi (insn, operands, len)
++rtx insn ATTRIBUTE_UNUSED;
++rtx operands[];
++int *len;
++{
++      int sp = self_push (operands[0]);
++      int dummy = 0;
++
++      if (!sp)
++      {
++              OUT_INSN (len, "push\t%D0", operands);
++              OUT_INSN (len, "push\t%C0", operands);
++              OUT_INSN (len, "push\t%B0", operands);
++              OUT_INSN (len, "push\t%A0", operands);
++
++              dummy = 8;
++              if (indexed_location (operands[0]))
++                      dummy--;
++              if (REG_P (operands[0]))
++                      dummy -= 4;
++              if (GET_CODE (operands[0]) == CONST_DOUBLE)
++              {
++                      int hi = CONST_DOUBLE_HIGH (operands[0]);
++                      int lo = CONST_DOUBLE_LOW (operands[0]);
++                      int x, y, z;
++
++                      x = (hi & 0xffff0000ul) >> 16;
++                      y = hi & 0xffff;
++                      z = (lo & 0xffff0000ul) >> 16;
++                      if (x == 0 || x == 1 || x == 2 || x == 4 || x == 8 || x == 0xffff)
++                              dummy--;
++                      if (y == 0 || y == 1 || y == 2 || y == 4 || y == 8 || y == 0xffff)
++                              dummy--;
++                      if (z == 0 || z == 1 || z == 2 || z == 4 || z == 8 || z == 0xffff)
++                              dummy--;
++                      z = lo & 0xffff;
++                      if (z == 0 || z == 1 || z == 2 || z == 4 || z == 8 || z == 0xffff)
++                              dummy--;
++              }
++      }
++      else
++      {
++              OUT_INSN (len, "push\t2+%D0", operands);
++              OUT_INSN (len, "push\t2+%D0", operands);
++              OUT_INSN (len, "push\t2+%D0", operands);
++              OUT_INSN (len, "push\t2+%D0", operands);
++              dummy = 8;
++      }
++
++      if (len)
++              *len = dummy;
++
++      return "";
++}
++
++int dead_or_set_in_peep (int which, rtx insn ATTRIBUTE_UNUSED, rtx x)
++{
++      extern int peep2_current_count;
++      rtx r;
++      rtx next;
++
++      if (which > peep2_current_count)
++              return 0;
++
++      next = peep2_next_insn (which);
++      if (!next)
++              return 0;
++      if (!REG_P (x))
++              return 0;
++      r = find_regno_note (next, REG_DEAD, REGNO (x));
++
++      if (!r)
++              return 0;
++
++      r = XEXP (r, 0);
++      return GET_MODE (r) == GET_MODE (x);
++}
++
++void
++msp430_trampoline_template (FILE * fd)
++{
++      fprintf (fd, "; TRAMPOLINE HERE\n"
++              "; move context (either r1 or r4) to r6\n"
++              "; call function (0xf0f0 will be changed)\n");
++      fprintf (fd, "\tmov     #0xf0f0, r6\n");
++      fprintf (fd, "\tbr      #0xf0f0\n");
++      fprintf (fd, "; END OF TRAMPOLINE\n\n");
++}
++
++void
++msp430_initialize_trampoline (tramp, fn, ctx)
++rtx tramp;
++rtx fn;
++rtx ctx;
++{
++      emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 2)), ctx);
++      emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 6)), fn);
++}
++
++//----------------------------------------------------------------------------------------------------------------------------------------------
++
++static bool
++msp430_rtx_costs (rtx x, int code, int outer_code, int *total)
++{
++      int cst;
++      rtx op0, op1;
++      /***
++      [(outer:mode1 (inner:mode (op1) (op2))]
++
++
++      inner           outer   mode1   op1   op2
++      --------------------------
++      CONST_INT       UNKNOWN VOID
++      PLUS            SET     HI      reg + reg
++      ASHIFT  SET     HI      reg << 1
++      ASHIFT  SET     HI      reg << 15
++      NEG             SET     HI      reg
++      DIV             SET     HI      reg / 32
++      MOD             SET     HI      reg % 32
++      UDIV            SET     QI      reg / reg
++      MULT            SET     QI      reg * reg
++      MULT            SET     HI      0<-reg * 0<-reg
++      TRUNCATE        SET     QI      HI -> QI
++      UDIV            SET     HI      reg / reg
++      MULT            SET     HI      reg * reg
++      MULT            SET     SI      0<-reg * 0<-reg
++      TRUNCATE        SET     HI      SI -> HI
++      UDIV            SET     SI      reg / reg
++      MULT            SET     SI      reg * reg
++      MULT            SET     DI      0<-reg * 0<-reg
++      TRUNCATE        SET     SI      DI -> SI
++      UDIV            SET     DI      reg / reg
++      MULT            SET     DI      reg * reg
++      MULT            SET     TI      0<-reg * 0<-reg
++      TRUNCATE        SET     DI      TI -> DI
++      UDIV            SET     TI      reg / reg
++      MULT            SET     TI      reg * reg
++      MULT            SET     OI      reg * reg
++      TRUNCATE        SET     TI      OI -> TI
++      UDIV            SET     OI      reg / reg
++      MULT            SET     OI      reg * reg
++      CONST_INT       COMPARE VOID    
++      ...
++      CONST_INT       PLUS    HI      reg + const
++      PLUS            MEM     HI      X(rn)
++      PLUS            CONST_INT       ???????? ?????
++      MEM             SET     any
++      PLUS            MEM     HI      reg + const
++
++      ***/
++      cst = COSTS_N_INSNS (5);
++      if (outer_code == SET)
++      {
++              op0 = XEXP (x, 0);
++              op1 = XEXP (x, 1);
++              switch (code)
++              {
++              case CONST_INT: /* source only !!! */
++                      {
++                              int i = INTVAL (x);
++                              if (i == -1 || i == 0 || i == 2 || i == 4 || i == 8)
++                                      cst = COSTS_N_INSNS (1);
++                              else
++                                      cst = COSTS_N_INSNS (2);
++                      }
++                      break;
++              case PLUS:
++              case MINUS:
++              case AND:
++              case IOR:
++              case XOR:
++              case UNSPEC:
++              case UNSPEC_VOLATILE:
++                      cst = COSTS_N_INSNS (((GET_MODE_SIZE (GET_MODE (x)) + 1) & ~1) >> 1);
++                      break;
++              case ASHIFT:
++              case LSHIFTRT:
++              case ASHIFTRT:
++                      /* cst = COSTS_N_INSNS(10);
++                      break; */
++                      if (CONSTANT_P (op1) && INTVAL (op1) == 1)
++                              cst =
++                              COSTS_N_INSNS (((GET_MODE_SIZE (GET_MODE (x)) + 1) & ~1) >> 1);
++                      else if (CONSTANT_P (op1) && INTVAL (op1) == 15)
++                              cst =
++                              3 *
++                              COSTS_N_INSNS (((GET_MODE_SIZE (GET_MODE (x)) + 1) & ~1) >> 1);
++                      else if (CONSTANT_P (op1) && INTVAL (op1) == 8)
++                              cst =
++                              2 *
++                              COSTS_N_INSNS (((GET_MODE_SIZE (GET_MODE (x)) + 1) & ~1) >> 1);
++                      else if (CONSTANT_P (op1) && INTVAL (op1) == 16)
++                              cst =
++                              COSTS_N_INSNS (((GET_MODE_SIZE (GET_MODE (x)) + 1) & ~1) >> 1);
++                      else if (CONSTANT_P (op1) && INTVAL (op1) == 24)
++                              cst =
++                              4 *
++                              COSTS_N_INSNS (((GET_MODE_SIZE (GET_MODE (x)) + 1) & ~1) >> 1);
++                      else if (CONSTANT_P (op1) && INTVAL (op1) == 31)
++                              cst =
++                              3 *
++                              COSTS_N_INSNS (((GET_MODE_SIZE (GET_MODE (x)) + 1) & ~1) >> 1);
++                      if (code == ASHIFTRT)
++                              cst += COSTS_N_INSNS (1);
++                      break;
++
++              case NEG:
++                      cst =
++                              2 *
++                              COSTS_N_INSNS (((GET_MODE_SIZE (GET_MODE (x)) + 1) & ~1) >> 1);
++                      break;
++              case DIV:
++              case MOD:
++              case MULT:
++              case UDIV:
++                      cst = COSTS_N_INSNS (64);
++                      break;
++              case TRUNCATE:
++                      cst = COSTS_N_INSNS (((GET_MODE_SIZE (GET_MODE (x)) + 1) & ~1) >> 1);
++                      break;
++              case ZERO_EXTEND:
++                      cst =
++                              2 *
++                              COSTS_N_INSNS (((GET_MODE_SIZE (GET_MODE (x)) + 1) & ~1) >> 1);
++                      break;
++              case SIGN_EXTEND:
++              case ABS:
++                      cst =
++                              2 *
++                              COSTS_N_INSNS (((GET_MODE_SIZE (GET_MODE (x)) + 1) & ~1) >> 1);
++                      cst += COSTS_N_INSNS (2);
++                      break;
++              default:
++                      cst = 0;
++              }
++      }
++      else if (outer_code == COMPARE)
++      {
++              cst = COSTS_N_INSNS (((GET_MODE_SIZE (GET_MODE (x)) + 1) & ~1) >> 1);
++              cst += COSTS_N_INSNS (2);
++      }
++      else if (outer_code == JUMP_INSN)
++      {
++              cst = COSTS_N_INSNS (2);
++      }
++      else if (outer_code == CALL_INSN)
++      {
++              cst = COSTS_N_INSNS (4);
++      }
++      else
++              return false;
++
++      *total = cst;
++      if (cst)
++              return true;
++      return false;
++}
++
++int
++default_rtx_costs (rtx X ATTRIBUTE_UNUSED, enum rtx_code code, enum rtx_code outer_code ATTRIBUTE_UNUSED)
++{
++      int cost = 4;
++
++      switch (code)
++      {
++      case SYMBOL_REF:
++              cost += 2;
++              break;
++      case LABEL_REF:
++              cost += 2;
++              break;
++      case MEM:
++              cost += 2;
++              break;
++      case CONST_INT:
++              cost += 2;
++              break;
++      case SIGN_EXTEND:
++      case ZERO_EXTEND:
++              cost += 2;
++              break;
++      default:
++              break;
++      }
++      return cost;
++}
++
++
++static void 
++msp430_globalize_label(FILE *stream, const char *name)
++{
++      if(*name == '*' || *name == '@') name++;
++      if(*name >='0' && *name <='9') return;
++      fputs (GLOBAL_ASM_OP, stream);
++      assemble_name (stream, name);
++      putc ('\n', stream);
++}
++
++static bool msp430_function_ok_for_sibcall(tree decl ATTRIBUTE_UNUSED, tree exp ATTRIBUTE_UNUSED)
++{
++      int cfp = msp430_critical_function_p (current_function_decl);
++      int ree = msp430_reentrant_function_p (current_function_decl);
++      int nfp = msp430_naked_function_p (current_function_decl);
++      int ifp = interrupt_function_p (current_function_decl);
++      int wup = wakeup_function_p (current_function_decl);
++      int fee = msp430_empty_epilogue ();
++
++      /*
++      function must be:
++      - not critical
++      - not reentrant
++      - not naked
++      - not interrupt
++      - nor wakeup
++      - must have empty epilogue
++      */
++
++      if(nfp || ifp || wup || ree || cfp || !fee)
++              return false;
++      return true;
++}
++
++int
++msp430_address_costs (rtx x)
++{
++      enum rtx_code code = GET_CODE (x);
++      rtx op0, op1;
++
++      switch (code)
++      {
++      case PLUS:                      /* X(rn), addr + X */
++              op0 = XEXP (x, 0);
++              op1 = XEXP (x, 1);
++              if (REG_P (op0))
++              {
++                      if (INTVAL (op1) == 0)
++                              return COSTS_N_INSNS (2);
++                      else
++                              return COSTS_N_INSNS (3);
++              }
++              break;
++      case REG:
++              return COSTS_N_INSNS (2);
++              break;
++      default:
++              break;
++      }
++      return COSTS_N_INSNS (3);
++}
++
++void msp430_expand_mov_intptr (rtx dest, rtx src)
++{
++  if (push_operand (dest, HImode) && ! general_no_elim_operand (src, HImode))
++      src = copy_to_mode_reg (HImode, src);
++
++  emit_insn (gen_rtx_SET (VOIDmode, dest, src));
++}
+diff -urNad msp430-gcc~/gcc/config/msp430/msp430.h msp430-gcc/gcc/config/msp430/msp430.h
+--- msp430-gcc~/gcc/config/msp430/msp430.h     1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/msp430.h      2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1,3118 @@
++/* This work is partially financed by the European Commission under the
++ * Framework 6 Information Society Technologies Project
++ * "Wirelessly Accessible Sensor Populations (WASP)".
++ */
++
++/* Definitions of target machine for GNU compiler,
++   for Texas Instruments MSP430 microcontrollers.
++   Copyright (C) 2001-2009 Free Software Foundation, Inc.
++   Contributed by Dmitry Diky <diwil@mail.ru>
++
++This file is part of GNU CC.
++
++GNU CC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 2, or (at your option)
++any later version.
++
++GNU CC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GNU CC; see the file COPYING.  If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA.  */
++
++
++/* This declaration should be present. */
++/*
++#include <stdio.h>
++*/
++
++#include "_gccver.h"
++
++#define TARGET_CPU_CPP_BUILTINS()                       \
++do{                                                   \
++  builtin_define_std ("MSP430");                      \
++  builtin_define_std ("__MSP430__");                  \
++  if(msp430_has_hwmul)                                        \
++    builtin_define ("MSP430_HAS_HWMUL");              \
++  else                                                        \
++    builtin_define ("MSP430_NO_HWMUL");                       \
++}while(0)
++
++
++extern int target_flags;
++
++extern const char *msp430_endup;
++extern const char *msp430_init_stack;
++extern const char *msp430_mcu_name;
++extern int msp430_has_hwmul;
++
++
++#define MSP430_HAS_HWMUL_INTERNAL (msp430_has_hwmul)
++
++int msp430_current_function_noint_hwmul_function_p(void);
++#define MSP430_NOINT_HWMUL (msp430_current_function_noint_hwmul_function_p())
++
++
++#define TARGET_VERSION fprintf (stderr, " (GNU assembler syntax)");
++
++#define OVERRIDE_OPTIONS msp430_override_options()
++
++/*#define FRAME_POINTER_CFA_OFFSET(FNDECL) 0*/
++#define CAN_DEBUG_WITHOUT_FP
++/* Define this macro if debugging can be performed even without a
++   frame pointer.  If this macro is defined, GNU CC will turn on the
++   `-fomit-frame-pointer' option whenever `-O' is specified.  */
++
++#define BITS_BIG_ENDIAN 0
++#define BYTES_BIG_ENDIAN 0
++#define WORDS_BIG_ENDIAN 0
++#define BITS_PER_UNIT 8
++#define BITS_PER_WORD 16
++
++#ifdef IN_LIBGCC2
++/* This is to get correct SI and DI modes in libgcc2.c (32 and 64 bits).  */
++#define UNITS_PER_WORD 4
++#else
++/* Width of a word, in units (bytes). */
++#define UNITS_PER_WORD 2
++#endif
++
++/* Width in bits of a pointer.
++   See also the macro `Pmode' defined below.  */
++#define POINTER_SIZE 16
++
++
++/* Maximum sized of reasonable data type
++   DImode or Dfmode ...  */
++#define MAX_FIXED_MODE_SIZE 32
++
++/* Allocation boundary (in *bits*) for storing arguments in argument list. */
++#define PARM_BOUNDARY 16
++
++/* Allocation boundary (in *bits*) for the code of a function. */
++#define FUNCTION_BOUNDARY 16
++
++/* Alignment of field after `int : 0' in a structure. */
++#define EMPTY_FIELD_BOUNDARY 16
++
++/* No data type wants to be aligned rounder than this. */
++#define BIGGEST_ALIGNMENT 16
++
++/* Every structure's size must be a multiple of this.  */
++#define STRUCTURE_SIZE_BOUNDARY 16
++
++/* Define this if move instructions will actually fail to work
++   when given unaligned data.  */
++#define STRICT_ALIGNMENT 1
++
++/* A C expression for the size in bits of the type `int' on the
++     target machine.  If you don't define this, the default is one word.  */
++#define INT_TYPE_SIZE ( 16)
++
++
++/* A C expression for the size in bits of the type `short' on the
++   target machine.  If you don't define this, the default is half a
++   word.  (If this would be less than one storage unit, it is rounded
++   up to one unit.)  */
++#define SHORT_TYPE_SIZE (INT_TYPE_SIZE == 8 ? INT_TYPE_SIZE : 16)
++
++/* A C expression for the size in bits of the type `long' on the
++   target machine.  If you don't define this, the default is one word.  */
++#define LONG_TYPE_SIZE (INT_TYPE_SIZE == 8 ? 16 : 32)
++
++#define LONG_LONG_TYPE_SIZE 64
++/* A C expression for the size in bits of the type `long long' on the
++   target machine.  If you don't define this, the default is two
++   words.  If you want to support GNU Ada on your machine, the value
++   of macro must be at least 64.  */
++
++
++#define  CHAR_TYPE_SIZE 8
++/* A C expression for the size in bits of the type `char' on the
++   target machine.  If you don't define this, the default is one
++   quarter of a word.  (If this would be less than one storage unit,
++   it is rounded up to one unit.)  */
++
++#define FLOAT_TYPE_SIZE 32
++/* A C expression for the size in bits of the type `float' on the
++   target machine.  If you don't define this, the default is one word.  */
++
++#define DOUBLE_TYPE_SIZE 32
++/* A C expression for the size in bits of the type `double' on the
++   target machine.  If you don't define this, the default is two
++   words. */
++
++
++#define LONG_DOUBLE_TYPE_SIZE 32
++/* A C expression for the size in bits of the type `long double' on
++   the target machine.  If you don't define this, the default is two
++   words.  */
++
++#define DEFAULT_SIGNED_CHAR 1
++/* An expression whose value is 1 or 0, according to whether the type
++   `char' should be signed or unsigned by default.  The user can
++   always override this default with the options `-fsigned-char' and
++   `-funsigned-char'.  */
++
++/* `DEFAULT_SHORT_ENUMS'
++   A C expression to determine whether to give an `enum' type only as
++   many bytes as it takes to represent the range of possible values
++   of that type.  A nonzero value means to do that; a zero value
++   means all `enum' types should be allocated like `int'.
++
++   If you don't define the macro, the default is 0.  */
++
++#define SIZE_TYPE (INT_TYPE_SIZE == 8 ? "long unsigned int" : "unsigned int")
++/* A C expression for a string describing the name of the data type
++   to use for size values.  The typedef name `size_t' is defined
++   using the contents of the string.
++   
++   The string can contain more than one keyword.  If so, separate
++   them with spaces, and write first any length keyword, then
++   `unsigned' if appropriate, and finally `int'.  The string must
++   exactly match one of the data type names defined in the function
++   `init_decl_processing' in the file `c-decl.c'.  You may not omit
++   `int' or change the order--that would cause the compiler to crash
++   on startup.
++   
++   If you don't define this macro, the default is `"long unsigned
++   int"'.  */
++
++#define PTRDIFF_TYPE (INT_TYPE_SIZE == 8 ? "long int" :"int")
++/* A C expression for a string describing the name of the data type
++   to use for the result of subtracting two pointers.  The typedef
++   name `ptrdiff_t' is defined using the contents of the string.  See
++   `SIZE_TYPE' above for more information.
++   
++   If you don't define this macro, the default is `"long int"'.  */
++
++
++#define WCHAR_TYPE_SIZE 16
++/* A C expression for the size in bits of the data type for wide
++   characters.  This is used in `cpp', which cannot make use of
++   `WCHAR_TYPE'.  */
++
++#define FIRST_PSEUDO_REGISTER 17
++/* Number of hardware registers known to the compiler.  They receive
++   numbers 0 through `FIRST_PSEUDO_REGISTER-1'; thus, the first
++   pseudo register's number really is assigned the number
++   `FIRST_PSEUDO_REGISTER'.  */
++
++/*#define DWARF_FRAME_REGISTERS 16*/
++
++#define FIXED_REGISTERS {\
++  1,1,/* r0 r1 == PC  SP */\
++  1,1,/* r2 r3 == CG1(SR) CG2*/\
++  0,0,/* r4 r5 */\
++  0,0,/* r6 r7 */\
++  0,0,/* r8 r9 */\
++  0,0,/* r10 r11 */\
++  0,0,/* r12 r13 */\
++  0,0,/* r14 r15 */\
++  1, /* argp register */\
++}
++/* An initializer that says which registers are used for fixed
++   purposes all throughout the compiled code and are therefore not
++   available for general allocation.  These would include the stack
++   pointer, the frame pointer (except on machines where that can be
++   used as a general register when no frame pointer is needed), the
++   program counter on machines where that is considered one of the
++   addressable registers, and any other numbered register with a
++   standard use.
++
++   This information is expressed as a sequence of numbers, separated
++   by commas and surrounded by braces.  The Nth number is 1 if
++   register N is fixed, 0 otherwise.
++
++   The table initialized from this macro, and the table initialized by
++   the following one, may be overridden at run time either
++   automatically, by the actions of the macro
++   `CONDITIONAL_REGISTER_USAGE', or by the user with the command
++   options `-ffixed-REG', `-fcall-used-REG' and `-fcall-saved-REG'.  */
++
++#define CALL_USED_REGISTERS {                 \
++    1,1,/* r0 r1 */                           \
++    1,1,/* r2 r3 */                           \
++    0,0,/* r4 r5 */                           \
++    0,0,/* r6 r7 */                           \
++    0,0,/* r8 r9 */                           \
++    0,0,/* r10 r11 */                         \
++    1,1,/* r12 r13 */                         \
++    1,1,/* r14 r15 */                         \
++      1, \
++}
++/* Like `FIXED_REGISTERS' but has 1 for each register that is
++   clobbered (in general) by function calls as well as for fixed
++   registers.  This macro therefore identifies the registers that are
++   not available for general allocation of values that must live
++   across function calls.
++
++   If a register has 0 in `CALL_USED_REGISTERS', the compiler
++   automatically saves it on function entry and restores it on
++   function exit, if the register is used within the function.  */
++
++#define REG_ALLOC_ORDER { 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 }
++
++/* If defined, an initializer for a vector of integers, containing the
++   numbers of hard registers in the order in which GNU CC should
++   prefer to use them (from most preferred to least).
++   
++   If this macro is not defined, registers are used lowest numbered
++   first (all else being equal).
++   
++   One use of this macro is on machines where the highest numbered
++   registers must always be saved and the save-multiple-registers
++   instruction supports only sequences of consetionve registers.  On
++   such machines, define `REG_ALLOC_ORDER' to be an initializer that
++   lists the highest numbered allocatable register first. */
++
++#define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
++/* ORDER_REGS_FOR_LOCAL_ALLOC'
++   A C statement (sans semicolon) to choose the order in which to
++   allocate hard registers for pseudo-registers local to a basic
++   block.
++
++   Store the desired register order in the array `reg_alloc_order'.
++   Element 0 should be the register to allocate first; element 1, the
++   next register; and so on.
++
++   The macro body should not assume anything about the contents of
++   `reg_alloc_order' before execution of the macro.
++
++   On most machines, it is not necessary to define this macro.  */
++
++
++#define HARD_REGNO_NREGS(REGNO, MODE) \
++((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
++
++/* A C expression for the number of consecutive hard registers,
++   starting at register number REGNO, required to hold a value of mode
++   MODE.
++
++   On a machine where all registers are exactly one word, a suitable
++   definition of this macro is
++
++   #define HARD_REGNO_NREGS(REGNO, MODE)            \
++   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1)  \
++   / UNITS_PER_WORD))  */
++
++#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
++/*
++msp430_hard_regno_mode_ok(REGNO, MODE)
++*/
++/* A C expression that is nonzero if it is permissible to store a
++   value of mode MODE in hard register number REGNO (or in several
++   registers starting with that one).  For a machine where all
++   registers are equivalent, a suitable definition is
++
++   #define HARD_REGNO_MODE_OK(REGNO, MODE) 1
++
++   It is not necessary for this macro to check for the numbers of
++   fixed registers, because the allocation mechanism considers them
++   to be always occupied.
++
++   On some machines, double-precision values must be kept in even/odd
++   register pairs.  The way to implement that is to define this macro
++   to reject odd register numbers for such modes.
++
++   The minimum requirement for a mode to be OK in a register is that
++   the `movMODE' instruction pattern support moves between the
++   register and any other hard register for which the mode is OK; and
++   that moving a value into the register and back out not alter it.
++
++   Since the same instruction used to move `SImode' will work for all
++   narrower integer modes, it is not necessary on any machine for
++   `HARD_REGNO_MODE_OK' to distinguish between these modes, provided
++   you define patterns `movhi', etc., to take advantage of this.  This
++   is useful because of the interaction between `HARD_REGNO_MODE_OK'
++   and `MODES_TIEABLE_P'; it is very desirable for all integer modes
++   to be tieable.
++
++   Many machines have special registers for floating point arithmetic.
++   Often people assume that floating point machine modes are allowed
++   only in floating point registers.  This is not true.  Any
++   registers that can hold integers can safely *hold* a floating
++   point machine mode, whether or not floating arithmetic can be done
++   on it in those registers.  Integer move instructions can be used
++   to move the values.
++
++   On some machines, though, the converse is true: fixed-point machine
++   modes may not go in floating registers.  This is true if the
++   floating registers normalize any value stored in them, because
++   storing a non-floating value there would garble it.  In this case,
++   `HARD_REGNO_MODE_OK' should reject fixed-point machine modes in
++   floating registers.  But if the floating registers do not
++   automatically normalize, if you can store any bit pattern in one
++   and retrieve it unchanged without a trap, then any machine mode
++   may go in a floating register, so you can define this macro to say
++   so.
++
++   The primary significance of special floating registers is rather
++   that they are the registers acceptable in floating point arithmetic
++   instructions.  However, this is of no concern to
++   `HARD_REGNO_MODE_OK'.  You handle it by writing the proper
++   constraints for those instructions.
++
++   On some machines, the floating registers are especially slow to
++   access, so that it is better to store a value in a stack frame
++   than in such a register if floating point arithmetic is not being
++   done.  As long as the floating registers are not in class
++   `GENERAL_REGS', they will not be used unless some pattern's
++   constraint asks for one.  */
++
++#define MODES_TIEABLE_P(MODE1, MODE2)                 \
++0
++/*
++  ((MODE1) == (MODE2)                                 \
++     || ((MODE1) == QImode && (MODE2) == HImode)      \
++     || ((MODE1) == HImode && (MODE2) == QImode))
++*/       
++/* A C expression that is nonzero if it is desirable to choose
++   register allocation so as to avoid move instructions between a
++   value of mode MODE1 and a value of mode MODE2.
++
++   If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R,
++   MODE2)' are ever different for any R, then `MODES_TIEABLE_P (MODE1,
++   MODE2)' must be zero.  */
++
++
++enum reg_class {
++  NO_REGS,
++  PC_REG,                     /* r0  - PC     */
++  SP_REG,                     /* r1  - SP     */
++  STACK_REGS,                 /* r2  - SR     */
++  CG1_REG,                    /* r2  - CG1    */
++  CG2_REG,                    /* r3  - CG2    */
++  CG_REGS,                    /* r2, r3       */
++  GENERAL_REGS,                       /* r4 - r15     */
++  POINTER_REGS,
++  FFOUR_REG,
++  ALL_REGS, LIM_REG_CLASSES
++};
++  
++/* An enumeral type that must be defined with all the register class
++   names as enumeral values.  `NO_REGS' must be first.  `ALL_REGS'
++   must be the last register class, followed by one more enumeral
++   value, `LIM_REG_CLASSES', which is not a register class but rather
++   tells how many classes there are.
++
++   Each register class has a number, which is the value of casting
++   the class name to type `int'.  The number serves as an index in
++   many of the tables described below.  */
++
++
++#define N_REG_CLASSES (int) LIM_REG_CLASSES
++/* The number of distinct register classes, defined as follows:
++   #define N_REG_CLASSES (int) LIM_REG_CLASSES  */
++
++#define REG_CLASS_NAMES {             \
++              "NO_REGS",              \
++              "PC_REG",               \
++              "SP_REG",               \
++              "STACK_REGS",           \
++              "CG1_REG",              \
++              "CG2_REG",              \
++              "CG_REGS",              \
++              "GENERAL_REGS",         \
++              "POINTER_REGS",         \
++              "FFOUR_REG",            \
++              "ALL_REGS"              \
++}
++
++/* An initializer containing the names of the register classes as C
++   string constants.  These names are used in writing some of the
++   debugging dumps.  */
++
++#define REG_CLASS_CONTENTS {                          \
++  {0x00000000ul},     /* NO_REGS      */      \
++  {0x00000001ul},     /* PC_REG       */      \
++  {0x00000002ul},     /* SP_REG       */      \
++  {0x00000004ul},     /* r2           */      \
++  {0x00000004ul},     /* r2           */      \
++  {0x00000008ul},     /* r3           */      \
++  {0x0000000cul},     /* r2,r3        */      \
++  {0x0001fff2ul}, /* r4 - r15,r1  */      \
++  {0x0001fff2ul}, /* r4 - r15,r1  */      \
++  {0x0001fff0ul},     /* r4 - r15     */      \
++  {0x0001fffful}      /* ALL_REGS */          \
++}
++/* An initializer containing the contents of the register classes, as
++   integers which are bit masks.  The Nth integer specifies the
++   contents of class N.  The way the integer MASK is interpreted is
++   that register R is in the class if `MASK & (1 << R)' is 1.
++
++   When the machine has more than 32 registers, an integer does not
++   suffice.  Then the integers are replaced by sub-initializers,
++   braced groupings containing several integers.  Each
++   sub-initializer must be suitable as an initializer for the type
++   `HARD_REG_SET' which is defined in `hard-reg-set.h'.  */
++
++
++enum reg_class msp430_regno_reg_class PARAMS ((int));
++#define REGNO_REG_CLASS(R) msp430_regno_reg_class(R)
++/* A C expression whose value is a register class containing hard
++   register REGNO.  In general there is more than one such class;
++   choose a class which is "minimal", meaning that no smaller class
++   also contains the register.  */
++
++#define BASE_REG_CLASS POINTER_REGS
++/* A macro whose definition is the name of the class to which a valid
++   base register must belong.  A base register is one used in an
++   address which is the register value plus a displacement.  */
++
++#define INDEX_REG_CLASS NO_REGS
++/* A macro whose definition is the name of the class to which a valid
++   index register must belong.  An index register is one used in an
++   address where its value is either multiplied by a scale factor or
++   added to another register (as well as added to a displacement).  */
++
++#define REG_CLASS_FROM_LETTER(C) msp430_reg_class_from_letter(C)
++/* A C expression which defines the machine-dependent operand
++   constraint letters for register classes.  If CHAR is such a
++   letter, the value should be the register class corresponding to
++   it.  Otherwise, the value should be `NO_REGS'.  The register
++   letter `r', corresponding to class `GENERAL_REGS', will not be
++   passed to this macro; you do not need to handle it.  */
++
++#define REGNO_OK_FOR_BASE_P(r) msp430_regno_ok_for_base_p(r) 
++                                      
++/* A C expression which is nonzero if register number NUM is suitable
++   for use as a base register in operand addresses.  It may be either
++   a suitable hard register or a pseudo register that has been
++   allocated such a hard register.  */
++
++/* #define REGNO_MODE_OK_FOR_BASE_P(r, m) 
++   A C expression that is just like `REGNO_OK_FOR_BASE_P', except that
++   that expression may examine the mode of the memory reference in
++   MODE.  You should define this macro if the mode of the memory
++   reference affects whether a register may be used as a base
++   register.  If you define this macro, the compiler will use it
++   instead of `REGNO_OK_FOR_BASE_P'.  */
++
++#define REGNO_OK_FOR_INDEX_P(NUM) 0
++/* A C expression which is nonzero if register number NUM is suitable
++   for use as an index register in operand addresses.  It may be
++   either a suitable hard register or a pseudo register that has been
++   allocated such a hard register.
++
++   The difference between an index register and a base register is
++   that the index register may be scaled.  If an address involves the
++   sum of two registers, neither one of them scaled, then either one
++   may be labeled the "base" and the other the "index"; but whichever
++   labeling is used must fit the machine's constraints of which
++   registers may serve in each capacity.  The compiler will try both
++   labelings, looking for one that is valid, and will reload one or
++   both registers only if neither labeling works.  */
++
++#define PREFERRED_RELOAD_CLASS(X, CLASS) FFOUR_REG
++
++/*
++referred_reload_class(X,CLASS)
++ A C expression that places additional restrictions on the register
++   class to use when it is necessary to copy value X into a register
++   in class CLASS.  The value is a register class; perhaps CLASS, or
++   perhaps another, smaller class.  On many machines, the following
++   definition is safe:
++
++   #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
++
++   Sometimes returning a more restrictive class makes better code.
++   For example, on the 68000, when X is an integer constant that is
++   in range for a `moveq' instruction, the value of this macro is
++   always `DATA_REGS' as long as CLASS includes the data registers.
++   Requiring a data register guarantees that a `moveq' will be used.
++
++   If X is a `const_double', by returning `NO_REGS' you can force X
++   into a memory constant.  This is useful on certain machines where
++   immediate floating values cannot be loaded into certain kinds of
++   registers.  */
++/* `PREFERRED_OUTPUT_RELOAD_CLASS (X, CLASS)'
++   Like `PREFERRED_RELOAD_CLASS', but for output reloads instead of
++   input reloads.  If you don't define this macro, the default is to
++   use CLASS, unchanged.  */
++
++/* `LIMIT_RELOAD_CLASS (MODE, CLASS)'
++   A C expression that places additional restrictions on the register
++   class to use when it is necessary to be able to hold a value of
++   mode MODE in a reload register for which class CLASS would
++   ordinarily be used.
++
++   Unlike `PREFERRED_RELOAD_CLASS', this macro should be used when
++   there are certain modes that simply can't go in certain reload
++   classes.
++
++   The value is a register class; perhaps CLASS, or perhaps another,
++   smaller class.
++
++   Don't define this macro unless the target machine has limitations
++   which require the macro to do something nontrivial.  */
++
++/*
++#define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) GENERAL_REGS
++
++
++#define  SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) GENERAL_REGS
++
++
++   `SECONDARY_RELOAD_CLASS (CLASS, MODE, X)'
++   `SECONDARY_OUTPUT_RELOAD_CLASS (CLASS, MODE, X)'
++   Many machines have some registers that cannot be copied directly
++   to or from memory or even from other types of registers.  An
++   example is the `MQ' register, which on most machines, can only be
++   copied to or from general registers, but not memory.  Some
++   machines allow copying all registers to and from memory, but
++   require a scratch register for stores to some memory locations
++   (e.g., those with symbolic address on the RT, and those with
++   certain symbolic address on the Sparc when compiling PIC).  In
++   some cases, both an intermediate and a scratch register are
++   required.
++
++   You should define these macros to indicate to the reload phase
++   that it may need to allocate at least one register for a reload in
++   addition to the register to contain the data.  Specifically, if
++   copying X to a register CLASS in MODE requires an intermediate
++   register, you should define `SECONDARY_INPUT_RELOAD_CLASS' to
++   return the largest register class all of whose registers can be
++   used as intermediate registers or scratch registers.
++
++   If copying a register CLASS in MODE to X requires an intermediate
++   or scratch register, `SECONDARY_OUTPUT_RELOAD_CLASS' should be
++   defined to return the largest register class required.  If the
++   requirements for input and output reloads are the same, the macro
++   `SECONDARY_RELOAD_CLASS' should be used instead of defining both
++   macros identically.
++
++   The values returned by these macros are often `GENERAL_REGS'.
++   Return `NO_REGS' if no spare register is needed; i.e., if X can be
++   directly copied to or from a register of CLASS in MODE without
++   requiring a scratch register.  Do not define this macro if it
++   would always return `NO_REGS'.
++
++   If a scratch register is required (either with or without an
++   intermediate register), you should define patterns for
++   `reload_inM' or `reload_outM', as required (*note Standard
++   Names::..  These patterns, which will normally be implemented with
++   a `define_expand', should be similar to the `movM' patterns,
++   except that operand 2 is the scratch register.
++
++   Define constraints for the reload register and scratch register
++   that contain a single register class.  If the original reload
++   register (whose class is CLASS) can meet the constraint given in
++   the pattern, the value returned by these macros is used for the
++   class of the scratch register.  Otherwise, two additional reload
++   registers are required.  Their classes are obtained from the
++   constraints in the insn pattern.
++
++   X might be a pseudo-register or a `subreg' of a pseudo-register,
++   which could either be in a hard register or in memory.  Use
++   `true_regnum' to find out; it will return -1 if the pseudo is in
++   memory and the hard register number if it is in a register.
++
++   These macros should not be used in the case where a particular
++   class of registers can only be copied to memory and not to another
++   class of registers.  In that case, secondary reload registers are
++   not needed and would not be helpful.  Instead, a stack location
++   must be used to perform the copy and the `movM' pattern should use
++   memory as a intermediate storage.  This case often occurs between
++   floating-point and general registers.  */
++
++/* `SECONDARY_MEMORY_NEEDED (CLASS1, CLASS2, M)'
++   Certain machines have the property that some registers cannot be
++   copied to some other registers without using memory.  Define this
++   macro on those machines to be a C expression that is non-zero if
++   objects of mode M in registers of CLASS1 can only be copied to
++   registers of class CLASS2 by storing a register of CLASS1 into
++   memory and loading that memory location into a register of CLASS2.
++
++   Do not define this macro if its value would always be zero.
++
++   `SECONDARY_MEMORY_NEEDED_RTX (MODE)'
++   Normally when `SECONDARY_MEMORY_NEEDED' is defined, the compiler
++   allocates a stack slot for a memory location needed for register
++   copies.  If this macro is defined, the compiler instead uses the
++   memory location defined by this macro.
++
++   Do not define this macro if you do not define
++   `SECONDARY_MEMORY_NEEDED'.  */
++
++#define SMALL_REGISTER_CLASSES 1
++/* Normally the compiler avoids choosing registers that have been
++   explicitly mentioned in the rtl as spill registers (these
++   registers are normally those used to pass parameters and return
++   values).  However, some machines have so few registers of certain
++   classes that there would not be enough registers to use as spill
++   registers if this were done.
++
++   Define `SMALL_REGISTER_CLASSES' to be an expression with a non-zero
++   value on these machines.  When this macro has a non-zero value, the
++   compiler allows registers explicitly used in the rtl to be used as
++   spill registers but avoids extending the lifetime of these
++   registers.
++
++   It is always safe to define this macro with a non-zero value, but
++   if you unnecessarily define it, you will reduce the amount of
++   optimizations that can be performed in some cases.  If you do not
++   define this macro with a non-zero value when it is required, the
++   compiler will run out of spill registers and print a fatal error
++   message.  For most machines, you should not define this macro at
++   all.  */
++
++/*
++#define CLASS_LIKELY_SPILLED_P(CLASS) \
++      ( (CLASS) != ALL_REGS && (CLASS) != GENERAL_REGS)
++ A C expression whose value is nonzero if pseudos that have been
++   assigned to registers of class CLASS would likely be spilled
++   because registers of CLASS are needed for spill registers.
++
++   The default value of this macro returns 1 if CLASS has exactly one
++   register and zero otherwise.  On most machines, this default
++   should be used.  Only define this macro to some other expression
++   if pseudo allocated by `local-alloc.c' end up in memory because
++   their hard registers were needed for spill registers.  If this
++   macro returns nonzero for those classes, those pseudos will only
++   be allocated by `global.c', which knows how to reallocate the
++   pseudo to another register.  If there would not be another
++   register available for reallocation, you should not change the
++   definition of this macro since the only effect of such a
++   definition would be to slow down register allocation.  */
++
++#define CLASS_MAX_NREGS(CLASS, MODE)  \
++      ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
++/* A C expression for the maximum number of consecutive registers of
++   class CLASS needed to hold a value of mode MODE.
++
++   This is closely related to the macro `HARD_REGNO_NREGS'.  In fact,
++   the value of the macro `CLASS_MAX_NREGS (CLASS, MODE)' should be
++   the maximum value of `HARD_REGNO_NREGS (REGNO, MODE)' for all
++   REGNO values in the class CLASS.
++
++   This macro helps control the handling of multiple-word values in
++   the reload pass.  */
++
++#define CONST_OK_FOR_LETTER_P(VALUE, C)                               \
++  ((C) == 'I' ? (VALUE) >= -32767 && (VALUE) <= 32767 :               \
++   (C) == 'J' ? (VALUE) <= 0 && (VALUE) >= -32767:            \
++   (C) == 'K' ? (VALUE) >= 0 && (VALUE) <= 32767 :            \
++   (C) == 'L' ? (VALUE) >= 0 && (VALUE) <= 0xff        :              \
++   (C) == 'M' ? (VALUE) >= 0x10 && (VALUE) <= 0xff :          \
++   (C) == 'N' ? (VALUE) >= 0x100 && (VALUE) <= 0x1ff :                \
++   (C) == 'O' ? (VALUE)&1:                                    \
++   (C) == 'P' ? ((VALUE)==-1||(VALUE)==1||(VALUE)==2||(VALUE)==4||(VALUE)==8 ||(VALUE)==0) : 0)
++/* A C expression that defines the machine-dependent operand
++   constraint letters (`I', `J', `K', ... `P') that specify
++   particular ranges of integer values.  If C is one of those
++   letters, the expression should check that VALUE, an integer, is in
++   the appropriate range and return 1 if so, 0 otherwise.  If C is
++   not one of those letters, the value should be 0 regardless of
++   VALUE.  */
++
++
++#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
++  ((C) == 'G' ? (VALUE) == CONST0_RTX (SFmode)        \
++   : 0)
++/* `CONST_DOUBLE_OK_FOR_LETTER_P (VALUE, C)'
++   A C expression that defines the machine-dependent operand
++   constraint letters that specify particular ranges of
++   `const_double' values (`G' or `H').
++
++   If C is one of those letters, the expression should check that
++   VALUE, an RTX of code `const_double', is in the appropriate range
++   and return 1 if so, 0 otherwise.  If C is not one of those
++   letters, the value should be 0 regardless of VALUE.
++
++   `const_double' is used for all floating-point constants and for
++   `DImode' fixed-point constants.  A given letter can accept either
++   or both kinds of values.  It can use `GET_MODE' to distinguish
++   between these kinds.  */
++
++#define EXTRA_CONSTRAINT(x, c) extra_constraint(x, c)
++/* A C expression that defines the optional machine-dependent
++   constraint letters (``Q', `R', `S', `T', `U') that can'
++   be used to segregate specific types of operands, usually memory
++   references, for the target machine.  Normally this macro will not
++   be defined.  If it is required for a particular target machine, it
++   should return 1 if VALUE corresponds to the operand type
++   represented by the constraint letter C.  If C is not defined as an
++   extra constraint, the value returned should be 0 regardless of
++   VALUE.
++
++   For example, on the ROMP, load instructions cannot have their
++   output in r0 if the memory reference contains a symbolic address.
++   Constraint letter `Q' is defined as representing a memory address
++   that does *not* contain a symbolic address.  An alternative is
++   specified with a `Q' constraint on the input and `r' on the
++   output.  The next alternative specifies `m' on the input and a
++   register class that does not include r0 on the output.  */
++
++/*  This is an undocumented variable which describes
++    how GCC will push a data */
++#define STACK_PUSH_CODE PRE_DEC
++
++#define PUSH_ARGS !TARGET_ACCUMULATE_OUTGOING_ARGS
++#define ACCUMULATE_OUTGOING_ARGS TARGET_ACCUMULATE_OUTGOING_ARGS
++
++#define STACK_GROWS_DOWNWARD
++/* Define this macro if pushing a word onto the stack moves the stack
++   pointer to a smaller address.
++
++   When we say, "define this macro if ...," it means that the
++   compiler checks this macro only with `#ifdef' so the precise
++   definition used does not matter.  */
++
++#define STARTING_FRAME_OFFSET 0
++/* Offset from the frame pointer to the first local variable slot to
++   be allocated.
++
++   If `FRAME_GROWS_DOWNWARD', find the next slot's offset by
++   subtracting the first slot's length from `STARTING_FRAME_OFFSET'.
++   Otherwise, it is found by adding the length of the first slot to
++   the value `STARTING_FRAME_OFFSET'.  */
++
++#define STACK_POINTER_OFFSET 0
++/* Offset from the stack pointer register to the first location at
++   which outgoing arguments are placed.  If not specified, the
++   default value of zero is used.  This is the proper value for most
++   machines.
++
++   If `ARGS_GROW_DOWNWARD', this is the offset to the location above
++   the first location at which outgoing arguments are placed.  */
++
++#define FIRST_PARM_OFFSET(FUNDECL) 0
++/* Offset from the argument pointer register to the first argument's
++   address.  On some machines it may depend on the data type of the
++   function.
++
++   If `ARGS_GROW_DOWNWARD', this is the offset to the location above
++   the first argument's address.  */
++
++/* `STACK_DYNAMIC_OFFSET (FUNDECL)'
++   Offset from the stack pointer register to an item dynamically
++   allocated on the stack, e.g., by `alloca'.
++
++   The default value for this macro is `STACK_POINTER_OFFSET' plus the
++   length of the outgoing arguments.  The default is correct for most
++   machines.  See `function.c' for details.  */
++
++#define STACK_BOUNDARY 16
++/* Define this macro if there is a guaranteed alignment for the stack
++   pointer on this machine.  The definition is a C expression for the
++   desired alignment (measured in bits).  This value is used as a
++   default if PREFERRED_STACK_BOUNDARY is not defined.  */
++
++#define STACK_POINTER_REGNUM 1
++/* The register number of the stack pointer register, which must also
++   be a fixed register according to `FIXED_REGISTERS'.  On most
++   machines, the hardware determines which register this is.  */
++
++#define FRAME_POINTER_REGNUM 4
++/* The register number of the frame pointer register, which is used to
++   access automatic variables in the stack frame.  On some machines,
++   the hardware determines which register this is.  On other
++   machines, you can choose any register you wish for this purpose.  */
++
++/* We use a pseudo-register called "argp" to represent argument pointer.
++      As the register is marked as fixed, it will always be eliminated
++      (replaced by sp + offset).*/
++#define ARG_POINTER_REGNUM 16
++/* The register number of the arg pointer register, which is used to
++   access the function's argument list.  On some machines, this is
++   the same as the frame pointer register.  On some machines, the
++   hardware determines which register this is.  On other machines,
++   you can choose any register you wish for this purpose.  If this is
++   not the same register as the frame pointer register, then you must
++   mark it as a fixed register according to `FIXED_REGISTERS', or
++   arrange to be able to eliminate it (*note Elimination::.).  */
++
++#define STATIC_CHAIN_REGNUM 6
++/* Register numbers used for passing a function's static chain
++   pointer.  If register windows are used, the register number as
++   seen by the called function is `STATIC_CHAIN_INCOMING_REGNUM',
++   while the register number as seen by the calling function is
++   `STATIC_CHAIN_REGNUM'.  If these registers are the same,
++   `STATIC_CHAIN_INCOMING_REGNUM' need not be defined.
++
++   The static chain register need not be a fixed register.
++
++   If the static chain is passed in memory, these macros should not be
++   defined; instead, the next two macros should be defined.  */
++
++#define FRAME_POINTER_REQUIRED   frame_pointer_required_p()
++
++/*
++ A C expression which is nonzero if a function must have and use a
++   frame pointer.  This expression is evaluated  in the reload pass.
++   If its value is nonzero the function will have a frame pointer.
++
++   The expression can in principle examine the current function and
++   decide according to the facts, but on most machines the constant 0
++   or the constant 1 suffices.  Use 0 when the machine allows code to
++   be generated with no frame pointer, and doing so saves some time
++   or space.  Use 1 when there is no possible advantage to avoiding a
++   frame pointer.
++
++   In certain cases, the compiler does not know how to produce valid
++   code without a frame pointer.  The compiler recognizes those cases
++   and automatically gives the function a frame pointer regardless of
++   what `FRAME_POINTER_REQUIRED' says.  You don't need to worry about
++   them.
++
++   In a function that does not require a frame pointer, the frame
++   pointer register can be allocated for ordinary usage, unless you
++   mark it as a fixed register.  See `FIXED_REGISTERS' for more
++   information.  */
++
++#define ELIMINABLE_REGS {                     \
++   {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
++   {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
++   {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
++}
++/* If defined, this macro specifies a table of register pairs used to
++   eliminate unneeded registers that point into the stack frame.  If
++   it is not defined, the only elimination attempted by the compiler
++   is to replace references to the frame pointer with references to
++   the stack pointer.
++
++   The definition of this macro is a list of structure
++   initializations, each of which specifies an original and
++   replacement register.
++
++   On some machines, the position of the argument pointer is not
++   known until the compilation is completed.  In such a case, a
++   separate hard register must be used for the argument pointer.
++   This register can be eliminated by replacing it with either the
++   frame pointer or the argument pointer, depending on whether or not
++   the frame pointer has been eliminated.
++
++   In this case, you might specify:
++   #define ELIMINABLE_REGS  \
++   {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
++   {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
++   {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
++
++   Note that the elimination of the argument pointer with the stack
++   pointer is specified first since that is the preferred elimination.  */
++
++#define CAN_ELIMINATE(FROM, TO) 1
++/*#define CAN_ELIMINATE(FROM, TO) (((FROM) == ARG_POINTER_REGNUM                 \
++                                && (TO) == FRAME_POINTER_REGNUM)         \
++                               || (((FROM) == FRAME_POINTER_REGNUM)      \
++                                   && ! FRAME_POINTER_REQUIRED           \
++                                   ))*/
++/* A C expression that returns non-zero if the compiler is allowed to
++   try to replace register number FROM-REG with register number
++   TO-REG.  This macro need only be defined if `ELIMINABLE_REGS' is
++   defined, and will usually be the constant 1, since most of the
++   cases preventing register elimination are things that the compiler
++   already knows about.  */
++
++#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                  \
++     OFFSET = initial_elimination_offset (FROM, TO)
++/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'.  It
++   specifies the initial difference between the specified pair of
++   registers.  This macro must be defined if `ELIMINABLE_REGS' is
++   defined.  */
++/*
++#define RETURN_ADDR_RTX(count, x) \
++  gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (tem, 1)))
++*/
++#define PUSH_ROUNDING(NPUSHED) ((NPUSHED+1) & ~1)
++/* A C expression that is the number of bytes actually pushed onto the
++   stack when an instruction attempts to push NPUSHED bytes.
++
++   If the target machine does not have a push instruction, do not
++   define this macro.  That directs GNU CC to use an alternate
++   strategy: to allocate the entire argument block and then store the
++   arguments into it.
++
++   On some machines, the definition
++
++   #define PUSH_ROUNDING(BYTES) (BYTES)
++
++   will suffice.  But on other machines, instructions that appear to
++   push one byte actually push two bytes in an attempt to maintain
++   alignment.  Then the definition should be
++
++   #define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1)  */
++
++#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
++/* A C expression that should indicate the number of bytes of its own
++   arguments that a function pops on returning, or 0 if the function
++   pops no arguments and the caller must therefore pop them all after
++   the function returns.
++
++   FUNDECL is a C variable whose value is a tree node that describes
++   the function in question.  Normally it is a node of type
++   `FUNCTION_DECL' that describes the declaration of the function.
++   From this you can obtain the DECL_MACHINE_ATTRIBUTES of the
++   function.
++
++   FUNTYPE is a C variable whose value is a tree node that describes
++   the function in question.  Normally it is a node of type
++   `FUNCTION_TYPE' that describes the data type of the function.
++   From this it is possible to obtain the data types of the value and
++   arguments (if known).
++
++   When a call to a library function is being considered, FUNDECL
++   will contain an identifier node for the library function.  Thus, if
++   you need to distinguish among various library functions, you can
++   do so by their names.  Note that "library function" in this
++   context means a function used to perform arithmetic, whose name is
++   known specially in the compiler and was not mentioned in the C
++   code being compiled.
++
++   STACK-SIZE is the number of bytes of arguments passed on the
++   stack.  If a variable number of bytes is passed, it is zero, and
++   argument popping will always be the responsibility of the calling
++   function.
++
++   On the Vax, all functions always pop their arguments, so the
++   definition of this macro is STACK-SIZE.  On the 68000, using the
++   standard calling convention, no functions pop their arguments, so
++   the value of the macro is always 0 in this case.  But an
++   alternative calling convention is available in which functions
++   that take a fixed number of arguments pop them but other functions
++   (such as `printf') pop nothing (the caller pops all).  When this
++   convention is in use, FUNTYPE is examined to determine whether a
++   function takes a fixed number of arguments.  */
++
++#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
++(function_arg (&(CUM), MODE, TYPE, NAMED))
++
++/*
++#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
++(function_incoming_arg (&(CUM), MODE, TYPE, NAMED))
++*/
++/* A C expression that controls whether a function argument is passed
++   in a register, and which register.
++
++   The arguments are CUM, which summarizes all the previous
++   arguments; MODE, the machine mode of the argument; TYPE, the data
++   type of the argument as a tree node or 0 if that is not known
++   (which happens for C support library functions); and NAMED, which
++   is 1 for an ordinary argument and 0 for nameless arguments that
++   correspond to `...' in the called function's prototype.
++
++   The value of the expression is usually either a `reg' RTX for the
++   hard register in which to pass the argument, or zero to pass the
++   argument on the stack.
++
++   For machines like the Vax and 68000, where normally all arguments
++   are pushed, zero suffices as a definition.
++
++   The value of the expression can also be a `parallel' RTX.  This is
++   used when an argument is passed in multiple locations.  The mode
++   of the of the `parallel' should be the mode of the entire
++   argument.  The `parallel' holds any number of `expr_list' pairs;
++   each one describes where part of the argument is passed.  In each
++   `expr_list', the first operand can be either a `reg' RTX for the
++   hard register in which to pass this part of the argument, or zero
++   to pass the argument on the stack.  If this operand is a `reg',
++   then the mode indicates how large this part of the argument is.
++   The second operand of the `expr_list' is a `const_int' which gives
++   the offset in bytes into the entire argument where this part
++   starts.
++
++   The usual way to make the ANSI library `stdarg.h' work on a machine
++   where some arguments are usually passed in registers, is to cause
++   nameless arguments to be passed on the stack instead.  This is done
++   by making `FUNCTION_ARG' return 0 whenever NAMED is 0.
++
++   You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
++   definition of this macro to determine if this argument is of a
++   type that must be passed in the stack.  If `REG_PARM_STACK_SPACE'
++   is not defined and `FUNCTION_ARG' returns non-zero for such an
++   argument, the compiler will abort.  If `REG_PARM_STACK_SPACE' is
++   defined, the argument will be computed in the stack and then
++   loaded into a register.  */
++
++typedef struct msp430_args {
++  int nregs;                  /* # registers available for passing */
++  int regno;                  /* next available register number */
++} CUMULATIVE_ARGS;
++/* A C type for declaring a variable that is used as the first
++   argument of `FUNCTION_ARG' and other related values.  For some
++   target machines, the type `int' suffices and can hold the number
++   of bytes of argument so far.
++
++   There is no need to record in `CUMULATIVE_ARGS' anything about the
++   arguments that have been passed on the stack.  The compiler has
++   other variables to keep track of that.  For target machines on
++   which all arguments are passed on the stack, there is no need to
++   store anything in `CUMULATIVE_ARGS'; however, the data structure
++   must exist and should not be empty, so use `int'.  */
++
++
++/*
++      Correct DWARF2 unwind info generation requires prologue and epilogue
++      to be expanded into series of INSNs, so that DWARF2 info generator
++      can analyze those INSNs. Currently, prologue and epilogue are printed
++      to the output file as raw text, so, unwind info cannot be generated.
++*/
++
++#define DWARF2_UNWIND_INFO 1
++#define INCOMING_RETURN_ADDR_RTX gen_rtx_MEM (VOIDmode, gen_rtx_REG (VOIDmode, STACK_POINTER_REGNUM))
++
++#define INCOMING_FRAME_SP_OFFSET ((cfun && cfun->machine->is_interrupt) ? 4 : 2)
++
++#define EPILOGUE_USES(REGNO) msp430_epilogue_uses(REGNO)
++   
++#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS ) \
++init_cumulative_args (&(CUM), FNTYPE, LIBNAME, FNDECL)
++
++#define  INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
++init_cumulative_incoming_args(&(CUM), FNTYPE, LIBNAME)
++
++#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)  \
++  (function_arg_advance (&CUM, MODE, TYPE, NAMED))
++
++#define FUNCTION_ARG_REGNO_P(r) (r >= 12 && r <= 15)
++
++/* A C statement (sans semicolon) for initializing the variable CUM
++   for the state at the beginning of the argument list.  The variable
++   has type `CUMULATIVE_ARGS'.  The value of FNTYPE is the tree node
++   for the data type of the function which will receive the args, or 0
++   if the args are to a compiler support library function.  The value
++   of INDIRECT is nonzero when processing an indirect call, for
++   example a call through a function pointer.  The value of INDIRECT
++   is zero for a call to an explicitly named function, a library
++   function call, or when `INIT_CUMULATIVE_ARGS' is used to find
++   arguments for the function being compiled.
++   
++   When processing a call to a compiler support library function,
++   LIBNAME identifies which one.  It is a `symbol_ref' rtx which
++   contains the name of the function, as a string.  LIBNAME is 0 when
++   an ordinary C function call is being processed.  Thus, each time
++   this macro is called, either LIBNAME or FNTYPE is nonzero, but
++   never both of them at once.   */
++
++#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)  \
++  (function_arg_advance (&CUM, MODE, TYPE, NAMED))
++
++/* A C statement (sans semicolon) to update the summarizer variable
++   CUM to advance past an argument in the argument list.  The values
++   MODE, TYPE and NAMED describe that argument.  Once this is done,
++   the variable CUM is suitable for analyzing the *following*
++   argument with `FUNCTION_ARG', etc.
++   
++   This macro need not do anything if the argument in question was
++   passed on the stack.  The compiler knows how to track the amount
++   of stack space used for arguments without any special help. */
++
++#define FUNCTION_ARG_REGNO_P(r) (r >= 12 && r <= 15)
++/* A C expression that is nonzero if REGNO is the number of a hard
++   register in which function arguments are sometimes passed.  This
++   does *not* include implicit arguments such as the static chain and
++   the structure-value address.  On many machines, no registers can be
++   used for this purpose since all function arguments are pushed on
++   the stack.  */
++
++extern int msp430_reg_order[];
++
++#define RET_REGISTER  15 /* msp430_ret_register ()*/
++
++#define FUNCTION_VALUE(VALTYPE, FUNC) msp430_function_value (VALTYPE, FUNC)
++/* A C expression to create an RTX representing the place where a
++   function returns a value of data type VALTYPE.  VALTYPE is a tree
++   node representing a data type.  Write `TYPE_MODE (VALTYPE)' to get
++   the machine mode used to represent that type.  On many machines,
++   only the mode is relevant.  (Actually, on most machines, scalar
++   values are returned in the same place regardless of mode).
++
++   The value of the expression is usually a `reg' RTX for the hard
++   register where the return value is stored.  The value can also be a
++   `parallel' RTX, if the return value is in multiple places.  See
++   `FUNCTION_ARG' for an explanation of the `parallel' form.
++
++   If `PROMOTE_FUNCTION_RETURN' is defined, you must apply the same
++   promotion rules specified in `PROMOTE_MODE' if VALTYPE is a scalar
++   type.
++
++   If the precise function being called is known, FUNC is a tree node
++   (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer.  This
++   makes it possible to use a different value-returning convention
++   for specific functions when all their calls are known.
++
++   `FUNCTION_VALUE' is not used for return vales with aggregate data
++   types, because these are returned in another way.  See
++   `STRUCT_VALUE_REGNUM' and related macros, below.  */
++
++#define LIBCALL_VALUE(MODE)  msp430_libcall_value (MODE)
++/* A C expression to create an RTX representing the place where a
++   library function returns a value of mode MODE.  If the precise
++   function being called is known, FUNC is a tree node
++   (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer.  This
++   makes it possible to use a different value-returning convention
++   for specific functions when all their calls are known.
++
++   Note that "library function" in this context means a compiler
++   support routine, used to perform arithmetic, whose name is known
++   specially by the compiler and was not mentioned in the C code being
++   compiled.
++
++   The definition of `LIBRARY_VALUE' need not be concerned aggregate
++   data types, because none of the library functions returns such
++   types.  */
++
++#define FUNCTION_VALUE_REGNO_P(N) ((N) == RET_REGISTER)
++/* A C expression that is nonzero if REGNO is the number of a hard
++   register in which the values of called function may come back.
++
++   A register whose use for returning values is limited to serving as
++   the second of a pair (for a value of type `double', say) need not
++   be recognized by this macro.  So for most machines, this definition
++   suffices:
++
++   #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
++
++   If the machine has register windows, so that the caller and the
++   called function use different registers for the return value, this
++   macro should recognize only the caller's register numbers.  */
++
++#define RETURN_IN_MEMORY(TYPE) ((TYPE_MODE (TYPE) == BLKmode) \
++                              ? int_size_in_bytes (TYPE) > 8  \
++                              : 0)
++/* A C expression which can inhibit the returning of certain function
++   values in registers, based on the type of value.  A nonzero value
++   says to return the function value in memory, just as large
++   structures are always returned.  Here TYPE will be a C expression
++   of type `tree', representing the data type of the value.
++
++   Note that values of mode `BLKmode' must be explicitly handled by
++   this macro.  Also, the option `-fpcc-struct-return' takes effect
++   regardless of this macro.  On most systems, it is possible to
++   leave the macro undefined; this causes a default definition to be
++   used, whose value is the constant 1 for `BLKmode' values, and 0
++   otherwise.
++
++   Do not use this macro to indicate that structures and unions
++   should always be returned in memory.  You should instead use
++   `DEFAULT_PCC_STRUCT_RETURN' to indicate this.  */
++
++#define DEFAULT_PCC_STRUCT_RETURN 0
++/* Define this macro to be 1 if all structure and union return values
++   must be in memory.  Since this results in slower code, this should
++   be defined only if needed for compatibility with other compilers
++   or with an ABI.  If you define this macro to be 0, then the
++   conventions used for structure and union return values are decided
++   by the `RETURN_IN_MEMORY' macro.
++
++   If not defined, this defaults to the value 1.  */
++
++#define STRUCT_VALUE 0
++/* If the structure value address is not passed in a register, define
++   `STRUCT_VALUE' as an expression returning an RTX for the place
++   where the address is passed.  If it returns 0, the address is
++   passed as an "invisible" first argument.  */
++
++/*
++#define HAVE_PRE_INCREMENT    1
++*/
++
++#define HAVE_POST_INCREMENT   1
++
++/*
++#define HAVE_PRE_DECREMENT    1
++#define HAVE_PRE_INCREMENT    1
++#define HAVE_POST_DECREMENT   1  
++*/
++/* Similar for other kinds of addressing.  */
++
++#define CONSTANT_ADDRESS_P(X) CONSTANT_P (X)
++
++/*
++(GET_CODE (X) == LABEL_REF    \
++|| GET_CODE (X) == SYMBOL_REF   \
++|| GET_CODE (X) == CONST_INT    \
++|| GET_CODE (X) == CONST)
++*/
++
++/*
++#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
++do{CODE = msp430_canonicalize_comparison(CODE, &OP0, &OP1); }while(0)
++*/
++
++/* A C expression that is 1 if the RTX X is a constant which is a
++   valid address.  On most machines, this can be defined as
++   `CONSTANT_P (X)', but a few machines are more restrictive in which
++   constant addresses are supported.
++
++   `CONSTANT_P' accepts integer-values expressions whose values are
++   not explicitly known, such as `symbol_ref', `label_ref', and
++   `high' expressions and `const' arithmetic expressions, in addition
++   to `const_int' and `const_double' expressions.  */
++
++#define MAX_REGS_PER_ADDRESS 1
++/* A number, the maximum number of registers that can appear in a
++   valid memory address.  Note that it is up to you to specify a
++   value equal to the maximum number that `GO_IF_LEGITIMATE_ADDRESS'
++   would ever accept.  */
++
++#ifdef REG_OK_STRICT
++#  define GO_IF_LEGITIMATE_ADDRESS(mode, operand, ADDR)       \
++{                                                     \
++  if (legitimate_address_p (mode, operand, 1))                \
++    goto ADDR;                                                \
++}
++#  else
++#  define GO_IF_LEGITIMATE_ADDRESS(mode, operand, ADDR)       \
++{                                                     \
++  if (legitimate_address_p (mode, operand, 0))                \
++    goto ADDR;                                                \
++}
++#endif
++/* A C compound statement with a conditional `goto LABEL;' executed
++   if X (an RTX) is a legitimate memory address on the target machine
++   for a memory operand of mode MODE.
++
++   It usually pays to define several simpler macros to serve as
++   subroutines for this one.  Otherwise it may be too complicated to
++   understand.
++
++   This macro must exist in two variants: a strict variant and a
++   non-strict one.  The strict variant is used in the reload pass.  It
++   must be defined so that any pseudo-register that has not been
++   allocated a hard register is considered a memory reference.  In
++   contexts where some kind of register is required, a pseudo-register
++   with no hard register must be rejected.
++
++   The non-strict variant is used in other passes.  It must be
++   defined to accept all pseudo-registers in every context where some
++   kind of register is required.
++
++   Compiler source files that want to use the strict variant of this
++   macro define the macro `REG_OK_STRICT'.  You should use an `#ifdef
++   REG_OK_STRICT' conditional to define the strict variant in that
++   case and the non-strict variant otherwise.
++
++   Subroutines to check for acceptable registers for various purposes
++   (one for base registers, one for index registers, and so on) are
++   typically among the subroutines used to define
++   `GO_IF_LEGITIMATE_ADDRESS'.  Then only these subroutine macros
++   need have two variants; the higher levels of macros may be the
++   same whether strict or not.
++
++   Normally, constant addresses which are the sum of a `symbol_ref'
++   and an integer are stored inside a `const' RTX to mark them as
++   constant.  Therefore, there is no need to recognize such sums
++   specifically as legitimate addresses.  Normally you would simply
++   recognize any `const' as legitimate.
++
++   Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant
++   sums that are not marked with  `const'.  It assumes that a naked
++   `plus' indicates indexing.  If so, then you *must* reject such
++   naked constant sums as illegitimate addresses, so that none of
++   them will be given to `PRINT_OPERAND_ADDRESS'.
++
++   On some machines, whether a symbolic address is legitimate depends
++   on the section that the address refers to.  On these machines,
++   define the macro `ENCODE_SECTION_INFO' to store the information
++   into the `symbol_ref', and then check for it here.  When you see a
++   `const', you will have to look inside it to find the `symbol_ref'
++   in order to determine the section.  *Note Assembler Format::.
++
++   The best way to modify the name string is by adding text to the
++   beginning, with suitable punctuation to prevent any ambiguity.
++   Allocate the new name in `saveable_obstack'.  You will have to
++   modify `ASM_OUTPUT_LABELREF' to remove and decode the added text
++   and output the name accordingly, and define `STRIP_NAME_ENCODING'
++   to access the original name string.
++
++   You can check the information stored here into the `symbol_ref' in
++   the definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
++   `PRINT_OPERAND_ADDRESS'. */
++
++/* `REG_OK_FOR_BASE_P (X)'
++   A C expression that is nonzero if X (assumed to be a `reg' RTX) is
++   valid for use as a base register.  For hard registers, it should
++   always accept those which the hardware permits and reject the
++   others.  Whether the macro accepts or rejects pseudo registers
++   must be controlled by `REG_OK_STRICT' as described above.  This
++   usually requires two variant definitions, of which `REG_OK_STRICT'
++   controls the one actually used.  */
++
++#define REG_OK_FOR_BASE_NOSTRICT_P(X) \
++  (REGNO (X) >= FIRST_PSEUDO_REGISTER || REG_OK_FOR_BASE_STRICT_P(X))
++
++#define REG_OK_FOR_BASE_STRICT_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
++
++#ifdef REG_OK_STRICT
++#  define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_STRICT_P (X)
++#else
++#  define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_NOSTRICT_P (X)
++#endif
++
++/* A C expression that is just like `REG_OK_FOR_BASE_P', except that
++   that expression may examine the mode of the memory reference in
++   MODE.  You should define this macro if the mode of the memory
++   reference affects whether a register may be used as a base
++   register.  If you define this macro, the compiler will use it
++   instead of `REG_OK_FOR_BASE_P'.  */
++
++
++#define REG_OK_FOR_INDEX_P(X) 0 /*( REGNO(X)!=3 && REGNO(X)!=2 &&REGNO(X)<=15) */
++/*   A C expression that is nonzero if X (assumed to be a `reg' RTX) is
++   valid for use as an index register.
++
++   The difference between an index register and a base register is
++   that the index register may be scaled.  If an address involves the
++   sum of two registers, neither one of them scaled, then either one
++   may be labeled the "base" and the other the "index"; but whichever
++   labeling is used must fit the machine's constraints of which
++   registers may serve in each capacity.  The compiler will try both
++   labelings, looking for one that is valid, and will reload one or
++   both registers only if neither labeling works.  */
++
++#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)                                \
++GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN)
++
++/*{                                                                   \
++                                                                      \
++  (X) = legitimize_address (X, OLDX, MODE);                           \
++  if (memory_address_p (MODE, X))                                     \
++    goto WIN;                                                         \
++                                                                      \
++} */
++
++/* A C compound statement that attempts to replace X with a valid
++   memory address for an operand of mode MODE.  WIN will be a C
++   statement label elsewhere in the code; the macro definition may use
++
++   GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN);
++
++   to avoid further processing if the address has become legitimate.
++
++   X will always be the result of a call to `break_out_memory_refs',
++   and OLDX will be the operand that was given to that function to
++   produce X.
++
++   The code generated by this macro should not alter the substructure
++   of X.  If it transforms X into a more legitimate form, it should
++   assign X (which will always be a C variable) a new value.
++
++   It is not necessary for this macro to come up with a legitimate
++   address.  The compiler has standard ways of doing so in all cases.
++   In fact, it is safe for this macro to do nothing.  But often a
++   machine-dependent strategy can generate better code.  */
++
++/* A C compound statement that attempts to replace X, which is an
++   address that needs reloading, with a valid memory address for an
++   operand of mode MODE.  WIN will be a C statement label elsewhere
++   in the code.  It is not necessary to define this macro, but it
++   might be useful for performance reasons.
++
++   For example, on the i386, it is sometimes possible to use a single
++   reload register instead of two by reloading a sum of two pseudo
++   registers into a register.  On the other hand, for number of RISC
++   processors offsets are limited so that often an intermediate
++   address needs to be generated in order to address a stack slot.
++   By defining LEGITIMIZE_RELOAD_ADDRESS appropriately, the
++   intermediate addresses generated for adjacent some stack slots can
++   be made identical, and thus be shared.
++
++   *Note*: This macro should be used with caution.  It is necessary
++   to know something of how reload works in order to effectively use
++   this, and it is quite easy to produce macros that build in too
++   much knowledge of reload internals.
++
++   *Note*: This macro must be able to reload an address created by a
++   previous invocation of this macro.  If it fails to handle such
++   addresses then the compiler may generate incorrect code or abort.
++
++   The macro definition should use `push_reload' to indicate parts
++   that need reloading; OPNUM, TYPE and IND_LEVELS are usually
++   suitable to be passed unaltered to `push_reload'.
++
++   The code generated by this macro must not alter the substructure of
++   X.  If it transforms X into a more legitimate form, it should
++   assign X (which will always be a C variable) a new value.  This
++   also applies to parts that you change indirectly by calling
++   `push_reload'.
++
++   The macro definition may use `strict_memory_address_p' to test if
++   the address has become legitimate.
++
++   If you want to change only a part of X, one standard way of doing
++   this is to use `copy_rtx'.  Note, however, that is unshares only a
++   single level of rtl.  Thus, if the part to be changed is not at the
++   top level, you'll need to replace first the top leve It is not
++   necessary for this macro to come up with a legitimate address;
++   but often a machine-dependent strategy can generate better code.  */
++      
++#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)                      \
++{}
++/* A C statement or compound statement with a conditional `goto
++   LABEL;' executed if memory address X (an RTX) can have different
++   meanings depending on the machine mode of the memory reference it
++   is used for or if the address is valid for some modes but not
++   others.
++
++   Autoincrement and autodecrement addresses typically have
++   mode-dependent effects because the amount of the increment or
++   decrement is the size of the operand being addressed.  Some
++   machines have other mode-dependent addresses.  Many RISC machines
++   have no mode-dependent addresses.
++
++   You may assume that ADDR is a valid address for the machine.  */
++
++#define LEGITIMATE_CONSTANT_P(X) 1
++/* A C expression that is nonzero if X is a legitimate constant for
++   an immediate operand on the target machine.  You can assume that X
++   satisfies `CONSTANT_P', so you need not check this.  In fact, `1'
++   is a suitable definition for this macro on machines where anything
++   `CONSTANT_P' is valid.  */
++
++/*#define CONST_COSTS(x,CODE,OUTER_CODE)              \
++    case CONST_INT:                           \
++      if (OUTER_CODE == PLUS                  \
++        || OUTER_CODE == IOR                  \
++        || OUTER_CODE == AND                  \
++        || OUTER_CODE == MINUS                \
++        || OUTER_CODE == SET                  \
++        || INTVAL (x) == 0                    \
++          || INTVAL (x) == 1                  \
++          || INTVAL (x) == 2                  \
++          || INTVAL (x) == 4                  \
++          || INTVAL (x) == 8                  \
++          || INTVAL (x) == -1)                        \
++        return 0;                             \
++    case CONST:                                       \
++      return 0;                                       \
++    case LABEL_REF:                           \
++      return 1;                                       \
++    case SYMBOL_REF:                          \
++      return 2;                                       \
++    case CONST_DOUBLE:                                \
++      return 4;*/
++
++/* Like `CONST_COSTS' but applies to nonconstant RTL expressions.
++   This can be used, for example, to indicate how costly a multiply
++   instruction is.  In writing this macro, you can use the construct
++   `COSTS_N_INSNS (N)' to specify a cost equal to N fast
++   instructions.  OUTER_CODE is the code of the expression in which X
++   is contained.
++
++   This macro is optional; do not define it if the default cost
++   assumptions are adequate for the target machine.  */
++
++#define REGISTER_MOVE_COST(MODE, FROM, TO) ((MODE)==QImode ? 1 :   \
++                                          (MODE)==HImode ? 1 :   \
++                                          (MODE)==SImode ? 2 :   \
++                                          (MODE)==SFmode ? 2 : 4)
++
++/* A C expression for the cost of moving data from a register in class
++   FROM to one in class TO.  The classes are expressed using the
++   enumeration values such as `GENERAL_REGS'.  A value of 2 is the
++   default; other values are interpreted relative to that.
++
++   It is not required that the cost always equal 2 when FROM is the
++   same as TO; on some machines it is expensive to move between
++   registers if they are not general registers.
++
++   If reload sees an insn consisting of a single `set' between two
++   hard registers, and if `REGISTER_MOVE_COST' applied to their
++   classes returns a value of 2, reload does not check to ensure that
++   the constraints of the insn are met.  Setting a cost of other than
++   2 will allow reload to verify that the constraints are met.  You
++   should do this if the `movM' pattern's constraints do not allow
++   such copying.  */
++
++#define MEMORY_MOVE_COST(MODE,CLASS,IN) ((MODE)==QImode ? 2 : \
++                                       (MODE)==HImode ? 2 :   \
++                                       (MODE)==SImode ? 4 :   \
++                                       (MODE)==SFmode ? 4 : 8)
++/* A C expression for the cost of moving data of mode M between a
++   register and memory.  A value of 4 is the default; this cost is
++   relative to those in `REGISTER_MOVE_COST'.
++
++   If moving between registers and memory is more expensive than
++   between two registers, you should define this macro to express the
++   relative cost.  */
++
++#if GCC_VERSION_INT >= 0x440
++#define BRANCH_COST(a,b) 0
++#else
++#define BRANCH_COST 0
++#endif
++
++/* A C expression for the cost of a branch instruction.  A value of 1
++   is the default; other values are interpreted relative to that.
++
++   Here are additional macros which do not specify precise relative
++   costs, but only that certain actions are more expensive than GCC would
++   ordinarily expect.  */
++
++#define SLOW_BYTE_ACCESS 0
++/* Define this macro as a C expression which is nonzero if accessing
++   less than a word of memory (i.e. a `char' or a `short') is no
++   faster than accessing a word of memory, i.e., if such access
++   require more than one instruction or if there is no difference in
++   cost between byte and (aligned) word loads.
++
++   When this macro is not defined, the compiler will access a field by
++   finding the smallest containing object; when it is defined, a
++   fullword load will be used if alignment permits.  Unless bytes
++   accesses are faster than word accesses, using word accesses is
++   preferable since it may eliminate subsequent memory access if
++   subsequent accesses occur to other fields in the same word of the
++   structure, but to different bytes.
++
++   `SLOW_ZERO_EXTEND'
++   Define this macro if zero-extension (of a `char' or `short' to an
++   `int') can be done faster if the destination is a register that is
++   known to be zero.
++
++   If you define this macro, you must have instruction patterns that
++   recognize RTL structures like this:
++
++   (set (strict_low_part (subreg:QI (reg:SI ...) 0)) ...)
++
++   and likewise for `HImode'.
++
++   `SLOW_UNALIGNED_ACCESS'
++   Define this macro to be the value 1 if unaligned accesses have a
++   cost many times greater than aligned accesses, for example if they
++   are emulated in a trap handler.
++
++   When this macro is non-zero, the compiler will act as if
++   `STRICT_ALIGNMENT' were non-zero when generating code for block
++   moves.  This can cause significantly more instructions to be
++   produced.  Therefore, do not set this macro non-zero if unaligned
++   accesses only add a cycle or two to the time for a memory access.
++
++   If the value of this macro is always zero, it need not be defined.
++
++   `DONT_REDUCE_ADDR'
++   Define this macro to inhibit strength reduction of memory
++   addresses.  (On some machines, such strength reduction seems to do
++   harm rather than good.)
++
++   `MOVE_RATIO'
++   The number of scalar move insns which should be generated instead
++   of a string move insn or a library call.  Increasing the value
++   will always make code faster, but eventually incurs high cost in
++   increased code size.
++
++   If you don't define this, a reasonable default is used.  */
++
++#define NO_FUNCTION_CSE
++/* Define this macro if it is as good or better to call a constant
++   function address than to call an address kept in a register.  */
++
++#define TEXT_SECTION_ASM_OP "\t.text"
++/* A C expression whose value is a string containing the assembler
++   operation that should precede instructions and read-only data.
++   Normally `"\t.text"' is right.  */
++
++#define DATA_SECTION_ASM_OP "\t.data"
++/* A C expression whose value is a string containing the assembler
++   operation to identify the following data as writable initialized
++   data.  Normally `"\t.data"' is right.  */
++
++#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
++
++/*#define EXTRA_SECTIONS in_bootloader, in_infomem*/
++/* A list of names for sections other than the standard two, which are
++   `in_text' and `in_data'.  You need not define this macro on a
++   system with no other sections (that GCC needs to use).  */
++
++#if 0
++#define EXTRA_SECTION_FUNCTIONS                                                     \
++                                                                            \
++void                                                                        \
++bootloader_section (void)                                                     \
++{                                                                           \
++  if (in_section != in_bootloader)                                            \
++    {                                                                       \
++      fprintf (asm_out_file,                                                \
++             "\t.section .bootloader, \"ax\", @progbits\n");                  \
++      /* Should already be aligned, this is just to be safe if it isn't.  */  \
++      fprintf (asm_out_file, "\t.p2align 1\n");                                     \
++      in_section = in_bootloader;                                             \
++    }                                                                       \
++}                                                                             \
++                                                                            \
++void                                                                        \
++infomem_section (void)                                                              \
++{                                                                           \
++  if (in_section != in_infomem)                                                     \
++    {                                                                       \
++      fprintf (asm_out_file,                                                \
++             "\t.section .infomem, \"a\", @progbits\n");                      \
++      /* Should already be aligned, this is just to be safe if it isn't.  */  \
++      fprintf (asm_out_file, "\t.p2align 1\n");                                     \
++      in_section = in_infomem;                                                      \
++    }                                                                       \
++}
++#endif
++
++/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
++   There are no shared libraries on this target, and these sections are
++   placed in the read-only program memory, so they are not writable.  */
++
++#undef CTORS_SECTION_ASM_OP
++#define CTORS_SECTION_ASM_OP "\t.global\t__do_global_ctors\n\t.section .ctors,\"a\",@progbits"
++
++#undef DTORS_SECTION_ASM_OP
++#define DTORS_SECTION_ASM_OP "\t.global\t__do_global_dtors\n\t.section .dtors,\"a\",@progbits"
++
++#define TARGET_ASM_CONSTRUCTOR default_ctor_section_asm_out_constructor
++
++#define TARGET_ASM_DESTRUCTOR default_dtor_section_asm_out_destructor
++
++/* `EXTRA_SECTION_FUNCTIONS'
++   One or more functions to be defined in `varasm.c'.  These
++   functions should do jobs analogous to those of `text_section' and
++   `data_section', for your additional sections.  Do not define this
++   macro if you do not define `EXTRA_SECTIONS'.  */
++
++/*
++#define READONLY_DATA_SECTION data_section
++   On most machines, read-only variables, constants, and jump tables
++   are placed in the text section.  If this is not the case on your
++   machine, this macro should be defined to be the name of a function
++   (either `data_section' or a function defined in `EXTRA_SECTIONS')
++   that switches to the section to be used for read-only items.
++
++   If these items should be placed in the text section, this macro
++   should not be defined.  */
++
++/* `SELECT_SECTION (EXP, RELOC)'
++   A C statement or statements to switch to the appropriate section
++   for output of EXP.  You can assume that EXP is either a `VAR_DECL'
++   node or a constant of some sort.  RELOC indicates whether the
++   initial value of EXP requires link-time relocations.  Select the
++   section by calling `text_section' or one of the alternatives for
++   other sections.
++
++   Do not define this macro if you put all read-only variables and
++   constants in the read-only data section (usually the text section).  */
++
++/* `SELECT_RTX_SECTION (MODE, RTX)'
++   A C statement or statements to switch to the appropriate section
++   for output of RTX in mode MODE.  You can assume that RTX is some
++   kind of constant in RTL.  The argument MODE is redundant except in
++   the case of a `const_int' rtx.  Select the section by calling
++   `text_section' or one of the alternatives for other sections.
++
++   Do not define this macro if you put all constants in the read-only
++   data section.  */
++
++#define JUMP_TABLES_IN_TEXT_SECTION 0
++/* Define this macro if jump tables (for `tablejump' insns) should be
++   output in the text section, along with the assembler instructions.
++   Otherwise, the readonly data section is used.
++
++   This macro is irrelevant if there is no separate readonly data
++   section.  */
++
++/* ???? 
++#define ENCODE_SECTION_INFO(DECL)  encode_section_info(DECL)
++   Define this macro if references to a symbol must be treated
++   differently depending on something about the variable or function
++   named by the symbol (such as what section it is in).
++
++   The macro definition, if any, is executed immediately after the
++   rtl for DECL has been created and stored in `DECL_RTL (DECL)'.
++   The value of the rtl will be a `mem' whose address is a
++   `symbol_ref'.
++
++   The usual thing for this macro to do is to record a flag in the
++   `symbol_ref' (such as `SYMBOL_REF_FLAG') or to store a modified
++   name string in the `symbol_ref' (if one bit is not enough
++   information).  */
++
++
++/* `UNIQUE_SECTION_P (DECL)'
++   A C expression which evaluates to true if DECL should be placed
++   into a unique section for some target-specific reason.  If you do
++   not define this macro, the default is `0'.  Note that the flag
++   `-ffunction-sections' will also cause functions to be placed into
++   unique sections.  */
++
++#define ASM_COMMENT_START " ; "
++/* A C string constant describing how to begin a comment in the target
++   assembler language.  The compiler assumes that the comment will
++   end at the end of the line.  */
++
++#define ASM_APP_ON "/* #APP */\n"
++/* A C string constant for text to be output before each `asm'
++   statement or group of consecutive ones.  Normally this is
++   `"#APP"', which is a comment that has no effect on most assemblers
++   but tells the GNU assembler that it must check the lines that
++   follow for all valid assembler constructs.  */
++
++#define ASM_APP_OFF "/* #NOAPP */\n"
++/* A C string constant for text to be output after each `asm'
++   statement or group of consecutive ones.  Normally this is
++   `"#NO_APP"', which tells the GNU assembler to resume making the
++   time-saving assumptions that are valid for ordinary compiler
++   output.  */
++
++#define ASM_OUTPUT_DOUBLE(STREAM, VALUE) fprintf (STREAM, "no double float %.20e\n", VALUE)
++#define ASM_OUTPUT_FLOAT(STREAM, VALUE) asm_output_float (STREAM, VALUE)
++/* `ASM_OUTPUT_LONG_DOUBLE (STREAM, VALUE)'
++   `ASM_OUTPUT_THREE_QUARTER_FLOAT (STREAM, VALUE)'
++   `ASM_OUTPUT_SHORT_FLOAT (STREAM, VALUE)'
++   `ASM_OUTPUT_BYTE_FLOAT (STREAM, VALUE)'
++   A C statement to output to the stdio stream STREAM an assembler
++   instruction to assemble a floating-point constant of `TFmode',
++   `DFmode', `SFmode', `TQFmode', `HFmode', or `QFmode',
++   respectively, whose value is VALUE.  VALUE will be a C expression
++   of type `REAL_VALUE_TYPE'.  Macros such as
++   `REAL_VALUE_TO_TARGET_DOUBLE' are useful for writing these
++   definitions.  */
++
++
++#define ASM_OUTPUT_INT(FILE, VALUE)                   \
++ ( fprintf (FILE, "\t.long "),                                \
++   output_addr_const (FILE, (VALUE)),                 \
++   fputs ("\n", FILE))
++
++ /* Likewise for `short' and `char' constants.   */
++
++#define ASM_OUTPUT_SHORT(FILE,VALUE) asm_output_short(FILE,VALUE)
++#define ASM_OUTPUT_CHAR(FILE,VALUE) asm_output_char(FILE,VALUE)
++
++/* `ASM_OUTPUT_QUADRUPLE_INT (STREAM, EXP)'
++   A C statement to output to the stdio stream STREAM an assembler
++   instruction to assemble an integer of 16, 8, 4, 2 or 1 bytes,
++   respectively, whose value is VALUE.  The argument EXP will be an
++   RTL expression which represents a constant value.  Use
++   `output_addr_const (STREAM, EXP)' to output this value as an
++   assembler expression.
++
++   For sizes larger than `UNITS_PER_WORD', if the action of a macro
++   would be identical to repeatedly calling the macro corresponding to
++   a size of `UNITS_PER_WORD', once for each word, you need not define
++   the macro.  */
++
++
++#define ASM_OUTPUT_BYTE(FILE,VALUE) asm_output_byte (FILE,VALUE)
++/* A C statement to output to the stdio stream STREAM an assembler
++   instruction to assemble a single byte containing the number VALUE.  */
++
++#define ASM_BYTE_OP "\t.byte "
++/* A C string constant giving the pseudo-op to use for a sequence of
++   single-byte constants.  If this macro is not defined, the default
++   is `"\t.byte\t"'.  */
++
++#define ASM_OUTPUT_ASCII(FILE, P, SIZE)        gas_output_ascii (FILE,P,SIZE)
++/* `ASM_OUTPUT_ASCII (STREAM, PTR, LEN)'
++   output_ascii (FILE, P, SIZE)
++   A C statement to output to the stdio stream STREAM an assembler
++   instruction to assemble a string constant containing the LEN bytes
++   at PTR.  PTR will be a C expression of type `char *' and LEN a C
++   expression of type `int'.
++
++   If the assembler has a `.ascii' pseudo-op as found in the Berkeley
++   Unix assembler, do not define the macro `ASM_OUTPUT_ASCII'.  */
++
++#if GCC_VERSION_INT >= 0x430
++#define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) ((C) == '\n')
++#else
++#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == '\n')
++#endif
++/* Define this macro as a C expression which is nonzero if C is used
++   as a logical line separator by the assembler.
++
++   If you do not define this macro, the default is that only the
++   character `;' is treated as a logical line separator.  */
++
++/*
++#define ASM_OPEN_PAREN "("
++#define ASM_CLOSE_PAREN ")"
++ These macros are defined as C string constant, describing the
++   syntax in the assembler for grouping arithmetic expressions.  The
++   following definitions are correct for most assemblers:
++
++   #define ASM_OPEN_PAREN "("
++   #define ASM_CLOSE_PAREN ")"
++
++   These macros are provided by `real.h' for writing the definitions of
++   `ASM_OUTPUT_DOUBLE' and the like:  */
++
++/* Here we much catch r0 - r15  variable names */
++
++#define ASM_OUTPUT_LABELREF(FILE,NAME)                        \
++do{                                                   \
++      char *p = NAME;                                 \
++      while(*p == '_') p++;                           \
++      if(*p == 'r' || *p == 'R')                      \
++      {                                               \
++          int val;                                    \
++          char *endptr;                               \
++          p++;                                        \
++          val = strtol (p, &endptr, 10);              \
++          if(val >= 0 && val <= 15 &&                 \
++              *endptr == 0 )                          \
++          {                                           \
++              asm_fprintf ((FILE), "_%U%s", (NAME));  \
++          }                                           \
++          else                                        \
++              asm_fprintf ((FILE), "%U%s", (NAME));   \
++      }                                               \
++      else                                            \
++              asm_fprintf ((FILE), "%U%s", (NAME));   \
++} while(0)
++
++
++#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED)        \
++do {                                                  \
++     const char *p = NAME;                                    \
++     if(*p == '*' || *p == '@' ) p++;                 \
++     if(*p >= '0' && *p <= '9' ) break;                       \
++     fputs ("\t.comm ", (STREAM));                    \
++     assemble_name ((STREAM), (NAME));                        \
++     fprintf ((STREAM), ",%d%s", (SIZE), (SIZE)>1?",2\n":"\n");\
++} while (0)
++
++#define ASM_OUTPUT_LOCAL(STREAM, NAME, SIZE, ROUNDED) \
++do {                                                  \
++     const char *p = NAME;                                    \
++     if(*p == '*' || *p == '@' ) p++;                 \
++     if(*p >= '0' && *p <= '9' ) break;                       \
++     fputs ("\t.local ", (STREAM));                   \
++     assemble_name ((STREAM), (NAME));                        \
++     fputs ("\n",(STREAM));                           \
++     fputs ("\t.comm ", (STREAM));                            \
++     assemble_name ((STREAM), (NAME));                        \
++     fprintf ((STREAM), ",%d%s", (SIZE),(SIZE)>1?",2\n":"\n");\
++} while (0)
++
++#define ASM_OUTPUT_BSS(FILE, DECL, NAME, SIZE, ROUNDED)                 \
++do { \
++  const char *p = (NAME); \
++  if(*p == '*' || *p == '@' ) p++; \
++  if(*p >= '0' && *p <= '9' ) break; \
++  asm_output_bss ((FILE), (DECL), (NAME), (SIZE), (ROUNDED)); \
++} while(0)
++
++/* macros to output uninitialized variable definitions */
++
++/* Return a non-zero value if DECL has a section attribute.  */
++#define IN_NAMED_SECTION(DECL)                                           \
++  ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL)    \
++   && DECL_SECTION_NAME (DECL) != NULL_TREE)
++
++#define BSS_SECTION_ASM_OP    "\t.section\t.bss"
++/* If defined, a C expression whose value is a string containing the
++   assembler operation to identify the following data as
++   uninitialized global data.  If not defined, and neither
++   'ASM_OUTPUT_BSS' nor 'ASM_OUTPUT_ALIGNED_BSS' are defined,
++   uninitialized global data will be output in the data section if
++   -fno-common' is passed, otherwise 'ASM_OUTPUT_COMMON' will be
++   used.
++*/
++
++
++#define ASM_OUTPUT_LABEL(STREAM, NAME)                \
++{                                             \
++  int __msp430_data_name_workaround = (((NAME)[0] == '*') && ((NAME)[1] == '0'));  \
++  if (__msp430_data_name_workaround) \
++  { \
++    static int repeatable_pseudolabels_resolver = 0;\
++      fprintf (STREAM, "__");                 \
++    assemble_name (STREAM, NAME);                     \
++      fprintf (STREAM, "_%d", ++repeatable_pseudolabels_resolver);                    \
++  } \
++  else \
++    assemble_name (STREAM, NAME);                     \
++  fprintf (STREAM, ":\n");                    \
++}
++/* A C statement (sans semicolon) to output to the stdio stream
++   STREAM the assembler definition of a label named NAME.  Use the
++   expression `assemble_name (STREAM, NAME)' to output the name
++   itself; before and after that, output the additional assembler
++   syntax for defining the name, and a newline.  */
++
++#undef TYPE_ASM_OP
++#undef SIZE_ASM_OP
++#undef WEAK_ASM_OP
++#define TYPE_ASM_OP   "\t.type\t"
++#define SIZE_ASM_OP   "\t.size\t"
++#define WEAK_ASM_OP   "\t.weak\t"
++/* Define the strings used for the special svr4 .type and .size directives.
++   These strings generally do not vary from one system running svr4 to
++   another, but if a given system (e.g. m88k running svr) needs to use
++   different pseudo-op names for these, they may be overridden in the
++   file which includes this one.  */
++
++
++#undef TYPE_OPERAND_FMT
++#define TYPE_OPERAND_FMT      "@%s"
++/* The following macro defines the format used to output the second
++   operand of the .type assembler directive.  Different svr4 assemblers
++   expect various different forms for this operand.  The one given here
++   is just a default.  You may need to override it in your machine-
++   specific tm.h file (depending upon the particulars of your assembler).  */
++
++
++#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
++asm_declare_function_name (FILE, NAME, DECL)
++
++
++/* A C statement (sans semicolon) to output to the stdio stream
++   STREAM any text necessary for declaring the name NAME of a
++   function which is being defined.  This macro is responsible for
++   outputting the label definition (perhaps using
++   `ASM_OUTPUT_LABEL').  The argument DECL is the `FUNCTION_DECL'
++   tree node representing the function.
++
++   If this macro is not defined, then the function name is defined in
++   the usual manner as a label (by means of `ASM_OUTPUT_LABEL').  */
++
++
++#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)                  \
++  do {                                                                        \
++    if (!flag_inhibit_size_directive)                                 \
++      {                                                                       \
++        char label[256];                                              \
++      static int labelno;                                             \
++      labelno++;                                                      \
++      ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno);            \
++      fprintf(FILE, ".%s%d:\n", "Lfe", labelno) ;             \
++      fprintf (FILE, "%s", SIZE_ASM_OP);                              \
++      assemble_name (FILE, (FNAME));                                  \
++        fprintf (FILE, ",");                                          \
++      assemble_name (FILE, label);                                    \
++        fprintf (FILE, "-");                                          \
++      assemble_name (FILE, (FNAME));                                  \
++      fprintf (FILE,"\n;; End of function \n\n");     \
++      }                                                                       \
++  } while (0)
++
++#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL)                       \
++do {                                                                    \
++      int __msp430_data_name_workaround = (((NAME)[0] == '*') && ((NAME)[1] == '0'));  \
++        if (__msp430_data_name_workaround) \
++          fprintf (FILE, "#"); \
++      fprintf (FILE, "%s", TYPE_ASM_OP);                                \
++      assemble_name (FILE, NAME);                                       \
++      putc (',', FILE);                                                         \
++      fprintf (FILE, TYPE_OPERAND_FMT, "object");                       \
++      putc ('\n', FILE);                                                \
++      size_directive_output = 0;                                        \
++      if (!flag_inhibit_size_directive && DECL_SIZE (DECL))             \
++      {                                                                 \
++        size_directive_output = 1;                                      \
++        if (__msp430_data_name_workaround) \
++          fprintf (FILE, "#"); \
++        fprintf (FILE, "%s", SIZE_ASM_OP);                              \
++        assemble_name (FILE, NAME);                                     \
++        fprintf (FILE, ",%ld\n",  int_size_in_bytes (TREE_TYPE (DECL))); \
++    }                                                                   \
++  ASM_OUTPUT_LABEL(FILE, NAME);                                                 \
++} while (0)
++
++#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END)       \
++do {                                                                   \
++     const char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0);           \
++     if (!flag_inhibit_size_directive && DECL_SIZE (DECL)              \
++         && ! AT_END && TOP_LEVEL                                      \
++       && DECL_INITIAL (DECL) == error_mark_node                       \
++       && !size_directive_output)                                      \
++       {                                                               \
++       size_directive_output = 1;                                      \
++       fprintf (FILE, "%s", SIZE_ASM_OP);                              \
++       assemble_name (FILE, name);                                     \
++       fprintf (FILE, ",%d\n",  int_size_in_bytes (TREE_TYPE (DECL))); \
++       }                                                               \
++   } while (0)
++
++
++#define ESCAPES \
++"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
++\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
++\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\
++\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\
++\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
++\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
++\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
++\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"
++/* A table of bytes codes used by the ASM_OUTPUT_ASCII and
++   ASM_OUTPUT_LIMITED_STRING macros.  Each byte in the table
++   corresponds to a particular byte value [0..255].  For any
++   given byte value, if the value in the corresponding table
++   position is zero, the given character can be output directly.
++   If the table value is 1, the byte must be output as a \ooo
++   octal escape.  If the tables value is anything else, then the
++   byte value should be output as a \ followed by the value
++   in the table.  Note that we can use standard UN*X escape
++   sequences for many control characters, but we don't use
++   \a to represent BEL because some svr4 assemblers (e.g. on
++   the i386) don't know about that.  Also, we don't use \v
++   since some versions of gas, such as 2.2 did not accept it.  */
++
++#define STRING_LIMIT  ((unsigned) 64)
++#define STRING_ASM_OP "\t.string\t"
++/* Some svr4 assemblers have a limit on the number of characters which
++   can appear in the operand of a .string directive.  If your assembler
++   has such a limitation, you should define STRING_LIMIT to reflect that
++   limit.  Note that at least some svr4 assemblers have a limit on the
++   actual number of bytes in the double-quoted string, and that they
++   count each character in an escape sequence as one byte.  Thus, an
++   escape sequence like \377 would count as four bytes.
++
++   If your target assembler doesn't support the .string directive, you
++   should define this to zero.  */
++
++#define GLOBAL_ASM_OP ".global\t"
++     
++#define ASM_WEAKEN_LABEL(FILE, NAME)  \
++  do                                  \
++    {                                 \
++      fputs ("\t.weak\t", (FILE));    \
++      assemble_name ((FILE), (NAME));         \
++      fputc ('\n', (FILE));           \
++    }                                 \
++  while (0)
++
++/* A C statement (sans semicolon) to output to the stdio stream
++   STREAM some commands that will make the label NAME weak; that is,
++   available for reference from other files but only used if no other
++   definition is available.  Use the expression `assemble_name
++   (STREAM, NAME)' to output the name itself; before and after that,
++   output the additional assembler syntax for making that name weak,
++   and a newline.
++
++   If you don't define this macro, GNU CC will not support weak
++   symbols and you should not define the `SUPPORTS_WEAK' macro.
++*/
++
++#define SUPPORTS_WEAK 1
++/* A C expression which evaluates to true if the target supports weak
++   symbols.
++
++   If you don't define this macro, `defaults.h' provides a default
++   definition.  If `ASM_WEAKEN_LABEL' is defined, the default
++   definition is `1'; otherwise, it is `0'.  Define this macro if you
++   want to control weak symbol support with a compiler flag such as
++   `-melf'.
++
++   `MAKE_DECL_ONE_ONLY'
++   A C statement (sans semicolon) to mark DECL to be emitted as a
++   public symbol such that extra copies in multiple translation units
++   will be discarded by the linker.  Define this macro if your object
++   file format provides support for this concept, such as the `COMDAT'
++   section flags in the Microsoft Windows PE/COFF format, and this
++   support requires changes to DECL, such as putting it in a separate
++   section.
++
++   `SUPPORTS_WEAK'
++   A C expression which evaluates to true if the target supports
++   one-only semantics.
++
++   If you don't define this macro, `varasm.c' provides a default
++   definition.  If `MAKE_DECL_ONE_ONLY' is defined, the default
++   definition is `1'; otherwise, it is `0'.  Define this macro if you
++   want to control weak symbol support with a compiler flag, or if
++   setting the `DECL_ONE_ONLY' flag is enough to mark a declaration to
++   be emitted as one-only.  */
++
++/* A C statement to output to the stdio stream STREAM a label whose
++   name is made from the string PREFIX and the number NUM.
++
++   It is absolutely essential that these labels be distinct from the
++   labels used for user-level functions and variables.  Otherwise,
++   certain programs will have name conflicts with internal labels.
++
++   It is desirable to exclude internal labels from the symbol table
++   of the object file.  Most assemblers have a naming convention for
++   labels that should be excluded; on many systems, the letter `L' at
++   the beginning of a label has this effect.  You should find out what
++   convention your system uses, and follow it.
++
++   The usual definition of this macro is as follows:
++
++   fprintf (STREAM, "L%s%d:\n", PREFIX, NUM)  */
++
++#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM)      \
++sprintf (STRING, "*.%s%d", PREFIX, NUM)
++/* A C statement to store into the string STRING a label whose name
++   is made from the string PREFIX and the number NUM.
++
++   This string, when output subsequently by `assemble_name', should
++   produce the output that `ASM_OUTPUT_INTERNAL_LABEL' would produce
++   with the same PREFIX and NUM.
++
++   If the string begins with `*', then `assemble_name' will output
++   the rest of the string unchanged.  It is often convenient for
++   `ASM_GENERATE_INTERNAL_LABEL' to use `*' in this way.  If the
++   string doesn't start with `*', then `ASM_OUTPUT_LABELREF' gets to
++   output the string, and may change it.  (Of course,
++   `ASM_OUTPUT_LABELREF' is also part of your machine description, so
++   you should know what it does on your machine.)  */
++
++#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)        \
++( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),  \
++  sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
++
++/* A C expression to assign to OUTVAR (which is a variable of type
++   `char *') a newly allocated string made from the string NAME and
++   the number NUMBER, with some suitable punctuation added.  Use
++   `alloca' to get space for the string.
++
++   The string will be used as an argument to `ASM_OUTPUT_LABELREF' to
++   produce an assembler label for an internal static variable whose
++   name is NAME.  Therefore, the string must be such as to result in
++   valid assembler code.  The argument NUMBER is different each time
++   this macro is executed; it prevents conflicts between
++   similarly-named internal static variables in different scopes.
++
++   Ideally this string should not be a valid C identifier, to prevent
++   any conflict with the user's own symbols.  Most assemblers allow
++   periods or percent signs in assembler symbols; putting at least
++   one of these between the name and the number will suffice.  */
++
++/* `ASM_OUTPUT_WEAK_ALIAS (STREAM, NAME, VALUE)'
++   A C statement to output to the stdio stream STREAM assembler code
++   which defines (equates) the weak symbol NAME to have the value
++   VALUE.
++
++   Define this macro if the target only supports weak aliases; define
++   ASM_OUTPUT_DEF instead if possible.  */
++
++#define HAS_INIT_SECTION 1
++/* If defined, `main' will not call `__main' as described above.
++   This macro should be defined for systems that control the contents
++   of the init section on a symbol-by-symbol basis, such as OSF/1,
++   and should not be defined explicitly for systems that support
++   `INIT_SECTION_ASM_OP'.  */
++
++#define REGISTER_NAMES {                              \
++  "r0","r1","r2","r3","r4","r5","r6","r7",            \
++  "r8","r9","r10","r11","r12","r13","r14","r15","argp"                \
++}
++/* A C initializer containing the assembler's names for the machine
++   registers, each one as a C string constant.  This is what
++   translates register numbers in the compiler into assembler
++   language.  */
++
++#define FINAL_PRESCAN_INSN(insn, operand, nop) final_prescan_insn (insn, operand,nop)
++/* If defined, a C statement to be executed just prior to the output
++   of assembler code for INSN, to modify the extracted operands so
++   they will be output differently.
++
++   Here the argument OPVEC is the vector containing the operands
++   extracted from INSN, and NOPERANDS is the number of elements of
++   the vector which contain meaningful data for this insn.  The
++   contents of this vector are what will be used to convert the insn
++   template into assembler code, so you can change the assembler
++   output by changing the contents of the vector.
++
++   This macro is useful when various assembler syntaxes share a single
++   file of instruction patterns; by defining this macro differently,
++   you can cause a large class of instructions to be output
++   differently (such as with rearranged operands).  Naturally,
++   variations in assembler syntax affecting individual insn patterns
++   ought to be handled by writing conditional output routines in
++   those patterns.
++
++   If this macro is not defined, it is equivalent to a null statement.  */
++
++#define PRINT_OPERAND(STREAM, X, CODE) print_operand (STREAM, X, CODE)
++/* A C compound statement to output to stdio stream STREAM the
++   assembler syntax for an instruction operand X.  X is an RTL
++   expression.
++
++   CODE is a value that can be used to specify one of several ways of
++   printing the operand.  It is used when identical operands must be
++   printed differently depending on the context.  CODE comes from the
++   `%' specification that was used to request printing of the
++   operand.  If the specification was just `%DIGIT' then CODE is 0;
++   if the specification was `%LTR DIGIT' then CODE is the ASCII code
++   for LTR.
++
++   If X is a register, this macro should print the register's name.
++   The names can be found in an array `reg_names' whose type is `char
++   *[]'.  `reg_names' is initialized from `REGISTER_NAMES'.
++
++   When the machine description has a specification `%PUNCT' (a `%'
++   followed by a punctuation character), this macro is called with a
++   null pointer for X and the punctuation character for CODE.  */
++
++#define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '~')
++/* A C expression which evaluates to true if CODE is a valid
++   punctuation character for use in the `PRINT_OPERAND' macro.  If
++   `PRINT_OPERAND_PUNCT_VALID_P' is not defined, it means that no
++   punctuation characters (except for the standard one, `%') are used
++   in this way.  */
++
++#define PRINT_OPERAND_ADDRESS(STREAM, X) print_operand_address(STREAM, X)
++/* A C compound statement to output to stdio stream STREAM the
++   assembler syntax for an instruction operand that is a memory
++   reference whose address is X.  X is an RTL expression.
++
++   On some machines, the syntax for a symbolic address depends on the
++   section that the address refers to.  On these machines, define the
++   macro `ENCODE_SECTION_INFO' to store the information into the
++   `symbol_ref', and then check for it here.  *Note Assembler
++   Format::.  */
++
++#define USER_LABEL_PREFIX ""
++/* `LOCAL_LABEL_PREFIX'
++   `REGISTER_PREFIX'
++   `IMMEDIATE_PREFIX'
++   If defined, C string expressions to be used for the `%R', `%L',
++   `%U', and `%I' options of `asm_fprintf' (see `final.c').  These
++   are useful when a single `md' file must support multiple assembler
++   formats.  In that case, the various `tm.h' files can define these
++   macros differently.  */
++
++#define ASSEMBLER_DIALECT MSP430_HAS_HWMUL_INTERNAL
++/* If your target supports multiple dialects of assembler language
++  (such as different opcodes), define this macro as a C expression
++  that gives the numeric index of the assembler language dialect to
++  use, with zero as the first variant.
++
++  If this macro is defined, you may use constructs of the form
++  `{option0|option1|option2...}' in the output templates of patterns
++  (*note Output Template::.) or in the first argument of
++  `asm_fprintf'.  This construct outputs `option0', `option1' or
++  `option2', etc., if the value of `ASSEMBLER_DIALECT' is zero, one
++  or two, etc.  Any special characters within these strings retain
++  their usual meaning.
++
++  If you do not define this macro, the characters `{', `|' and `}'
++  do not have any special meaning when used in templates or operands
++  to `asm_fprintf'.
++
++  Define the macros `REGISTER_PREFIX', `LOCAL_LABEL_PREFIX',
++  `USER_LABEL_PREFIX' and `IMMEDIATE_PREFIX' if you can express the
++  variations in assembler language syntax with that mechanism.
++  Define `ASSEMBLER_DIALECT' and use the `{option0|option1}' syntax
++  if the syntax variant are larger and involve such things as
++  different opcodes or operand order.  */
++
++#define ASM_OUTPUT_REG_PUSH(STREAM, REGNO)    \
++{                                             \
++  if (REGNO > 15)                             \
++    abort ();                                 \
++  fprintf (STREAM, "\tpush\tr%d", REGNO);     \
++}
++/* A C expression to output to STREAM some assembler code which will
++   push hard register number REGNO onto the stack.  The code need not
++   be optimal, since this macro is used only when profiling.  */
++
++#define ASM_OUTPUT_REG_POP(STREAM, REGNO)     \
++{                                             \
++  if (REGNO > 15)                             \
++    abort ();                                 \
++  fprintf (STREAM, "\tpop\tr%d", REGNO);      \
++}
++/* A C expression to output to STREAM some assembler code which will
++   pop hard register number REGNO off of the stack.  The code need
++   not be optimal, since this macro is used only when profiling.  */
++
++#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE)                \
++  msp430_output_addr_vec_elt(STREAM, VALUE)
++/* This macro should be provided on machines where the addresses in a
++   dispatch table are absolute.
++
++   The definition should be a C statement to output to the stdio
++   stream STREAM an assembler pseudo-instruction to generate a
++   reference to a label.  VALUE is the number of an internal label
++   whose definition is output using `ASM_OUTPUT_INTERNAL_LABEL'.  For
++   example,
++
++   fprintf (STREAM, "\t.word L%d\n", VALUE)  */
++
++/*
++#define ASM_OUTPUT_CASE_LABEL(STREAM, PREFIX, NUM, TABLE) \
++   progmem_section (), ASM_OUTPUT_INTERNAL_LABEL (STREAM, PREFIX, NUM)
++
++   `ASM_OUTPUT_CASE_LABEL (STREAM, PREFIX, NUM, TABLE)'
++   Define this if the label before a jump-table needs to be output
++   specially.  The first three arguments are the same as for
++   `ASM_OUTPUT_INTERNAL_LABEL'; the fourth argument is the jump-table
++   which follows (a `jump_insn' containing an `addr_vec' or
++   `addr_diff_vec').
++
++   This feature is used on system V to output a `swbeg' statement for
++   the table.
++
++   If this macro is not defined, these labels are output with
++   `ASM_OUTPUT_INTERNAL_LABEL'.  */
++
++/* `ASM_OUTPUT_CASE_END (STREAM, NUM, TABLE)'
++   Define this if something special must be output at the end of a
++   jump-table.  The definition should be a C statement to be executed
++   after the assembler code for the table is written.  It should write
++   the appropriate code to stdio stream STREAM.  The argument TABLE
++   is the jump-table insn, and NUM is the label-number of the
++   preceding label.
++
++   If this macro is not defined, nothing special is output at the end
++   of the jump-table.  */
++
++#ifndef SET_ASM_OP
++#define SET_ASM_OP "\t.set\t"
++#endif
++  
++#define ASM_OUTPUT_SKIP(STREAM, N)            \
++fprintf (STREAM, "\t.skip %d,0\n", N)
++/* A C statement to output to the stdio stream STREAM an assembler
++   instruction to advance the location counter by NBYTES bytes.
++   Those bytes should be zero when loaded.  NBYTES will be a C
++   expression of type `int'.  */
++
++#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
++fprintf (STREAM, "\t.p2align %d,0\n", POWER)
++/* A C statement to output to the stdio stream STREAM an assembler
++   command to advance the location counter to a multiple of 2 to the
++   POWER bytes.  POWER will be a C expression of type `int'.  */
++
++#define CASE_VECTOR_MODE HImode
++/* An alias for a machine mode name.  This is the machine mode that
++   elements of a jump-table should have.  */
++
++extern struct rtx_def *msp430_compare_op0, *msp430_compare_op1;
++
++
++extern int msp430_case_values_threshold;
++
++#define CASE_VALUES_THRESHOLD msp430_case_values_threshold
++/* `CASE_VALUES_THRESHOLD'
++   Define this to be the smallest number of different values for
++   which it is best to use a jump-table instead of a tree of
++   conditional branches.  The default is four for machines with a
++   `casesi' instruction and five otherwise.  This is best for most
++   machines.  */
++
++#undef WORD_REGISTER_OPERATIONS
++/* Define this macro if operations between registers with integral
++   mode smaller than a word are always performed on the entire
++   register.  Most RISC machines have this property and most CISC
++   machines do not.  */
++
++/*
++#define EASY_DIV_EXPR TRUNC_DIV_EXPR
++ An alias for a tree code that is the easiest kind of division to
++   compile code for in the general case.  It may be `TRUNC_DIV_EXPR',
++   `FLOOR_DIV_EXPR', `CEIL_DIV_EXPR' or `ROUND_DIV_EXPR'.  These four
++   division operators differ in how they round the result to an
++   integer.  `EASY_DIV_EXPR' is used when it is permissible to use
++   any of those kinds of division and the choice should be made on
++   the basis of efficiency.  */
++
++#define MOVE_MAX 2
++/* The maximum number of bytes that a single instruction can move
++   quickly between memory and registers or between two memory
++   locations.  */
++
++#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
++/* A C expression which is nonzero if on this machine it is safe to
++   "convert" an integer of INPREC bits to one of OUTPREC bits (where
++   OUTPREC is smaller than INPREC) by merely operating on it as if it
++   had only OUTPREC bits.
++
++   On many machines, this expression can be 1.
++
++   When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for
++   modes for which `MODES_TIEABLE_P' is 0, suboptimal code can result.
++   If this is the case, making `TRULY_NOOP_TRUNCATION' return 0 in
++   such cases may improve things.  */
++
++#define Pmode HImode
++/* An alias for the machine mode for pointers.  On most machines,
++   define this to be the integer mode corresponding to the width of a
++   hardware pointer; `SImode' on 32-bit machine or `DImode' on 64-bit
++   machines.  On some machines you must define this to be one of the
++   partial integer modes, such as `PSImode'.
++
++   The width of `Pmode' must be at least as large as the value of
++   `POINTER_SIZE'.  If it is not equal, you must define the macro
++   `POINTERS_EXTEND_UNSIGNED' to specify how pointers are extended to
++   `Pmode'.  */
++
++#define FUNCTION_MODE HImode
++/* An alias for the machine mode used for memory references to
++   functions being called, in `call' RTL expressions.  On most
++   machines this should be `QImode'.  */
++     /*                            1        3 */
++/*
++#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
++valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
++ `VALID_MACHINE_DECL_ATTRIBUTE (DECL, ATTRIBUTES, IDENTIFIER, ARGS)'
++   If defined, a C expression whose value is nonzero if IDENTIFIER
++   with arguments ARGS is a valid machine specific attribute for DECL.
++   The attributes in ATTRIBUTES have previously been assigned to DECL.  */
++
++/*
++#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, IDENTIFIER, ARGS) \
++     valid_machine_type_attribute(TYPE, ATTRIBUTES, IDENTIFIER, ARGS)
++   `VALID_MACHINE_TYPE_ATTRIBUTE (TYPE, ATTRIBUTES, IDENTIFIER, ARGS)'
++   If defined, a C expression whose value is nonzero if IDENTIFIER
++   with arguments ARGS is a valid machine specific attribute for TYPE.
++   The attributes in ATTRIBUTES have previously been assigned to TYPE.  */
++
++#define DOLLARS_IN_IDENTIFIERS 0
++/* Define this macro to control use of the character `$' in identifier
++   names.  0 means `$' is not allowed by default; 1 means it is
++   allowed.  1 is the default; there is no need to define this macro
++   in that case.  This macro controls the compiler proper; it does
++   not affect the preprocessor.  */
++
++#define NO_DOLLAR_IN_LABEL 1
++/* Define this macro if the assembler does not accept the character
++   `$' in label names.  By default constructors and destructors in
++   G++ have `$' in the identifiers.  If this macro is defined, `.' is
++   used instead.  */
++
++#define TRAMPOLINE_TEMPLATE(FILE) msp430_trampoline_template((FILE))
++
++#define TRAMPOLINE_SIZE 8
++#define TRAMPOLINE_ALIGNMENT 16
++
++
++#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT)     \
++      msp430_initialize_trampoline (TRAMP, FNADDR, CXT)
++
++
++/* Store in cc_status the expressions
++   that the condition codes will describe
++   after execution of an instruction whose pattern is EXP.
++   Do not alter them if the instruction would not alter the cc's.  */
++
++#define NOTICE_UPDATE_CC(EXP, INSN) notice_update_cc(EXP, INSN)
++
++/* The add insns don't set overflow in a usable way.  */
++#define CC_OVERFLOW_UNUSABLE 01000
++/* The mov,and,or,xor insns don't set carry.  That's ok though as the
++   Z bit is all we need when doing unsigned comparisons on the result of
++   these insns (since they're always with 0).  However, conditions.h has
++   CC_NO_OVERFLOW defined for this purpose.  Rename it to something more
++   understandable.  */
++#define CC_NO_CARRY CC_NO_OVERFLOW
++
++
++/* Output assembler code to FILE to increment profiler label # LABELNO
++   for profiling a function entry.  */
++
++#define FUNCTION_PROFILER(FILE, LABELNO)  \
++  fprintf (FILE, "/* profiler %d */", (LABELNO))
++
++/* `FIRST_INSN_ADDRESS'
++   When the `length' insn attribute is used, this macro specifies the
++   value to be assigned to the address of the first insn in a
++   function.  If not specified, 0 is used.  */
++
++#define ADJUST_INSN_LENGTH(INSN, LENGTH) (LENGTH =\
++                                        adjust_insn_length (INSN, LENGTH))
++/* If defined, modifies the length assigned to instruction INSN as a
++   function of the context in which it is used.  LENGTH is an lvalue
++   that contains the initially computed length of the insn and should
++   be updated with the correct length of the insn.  If updating is
++   required, INSN must not be a varying-length insn.
++
++   This macro will normally not be required.  A case in which it is
++   required is the ROMP.  On this machine, the size of an `addr_vec'
++   insn must be increased by two to compensate for the fact that
++   alignment may be required.  */
++
++#define CPP_SPEC "\
++%{!mmcu*|mmcu=msp1:%(cpp_msp1)} \
++%{mmcu=msp2:%(cpp_msp2) -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x110:%(cpp_msp1) -D__MSP430_110__} \
++%{mmcu=msp430x112:%(cpp_msp1) -D__MSP430_112__} \
++%{mmcu=msp430x1101:%(cpp_msp1) -D__MSP430_1101__} \
++%{mmcu=msp430x1111:%(cpp_msp1) -D__MSP430_1111__} \
++%{mmcu=msp430x1121:%(cpp_msp1) -D__MSP430_1121__} \
++%{mmcu=msp430x1122:%(cpp_msp1) -D__MSP430_1122__} \
++%{mmcu=msp430x1132:%(cpp_msp1) -D__MSP430_1132__} \
++%{mmcu=msp430x122:%(cpp_msp1) -D__MSP430_122__} \
++%{mmcu=msp430x123:%(cpp_msp1) -D__MSP430_123__} \
++%{mmcu=msp430x1222:%(cpp_msp1) -D__MSP430_1222__} \
++%{mmcu=msp430x1232:%(cpp_msp1) -D__MSP430_1232__} \
++%{mmcu=msp430x133:%(cpp_msp1) -D__MSP430_133__} \
++%{mmcu=msp430x135:%(cpp_msp1) -D__MSP430_135__} \
++%{mmcu=msp430x1331:%(cpp_msp1) -D__MSP430_1331__} \
++%{mmcu=msp430x1351:%(cpp_msp1) -D__MSP430_1351__} \
++%{mmcu=msp430x147:%(cpp_msp2) -D__MSP430_147__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x148:%(cpp_msp2) -D__MSP430_148__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x149:%(cpp_msp2) -D__MSP430_149__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x1471:%(cpp_msp2) -D__MSP430_1471__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x1481:%(cpp_msp2) -D__MSP430_1481__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x1491:%(cpp_msp2) -D__MSP430_1491__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x155:%(cpp_msp1) -D__MSP430_155__} \
++%{mmcu=msp430x156:%(cpp_msp1) -D__MSP430_156__} \
++%{mmcu=msp430x157:%(cpp_msp1) -D__MSP430_157__} \
++%{mmcu=msp430x167:%(cpp_msp2) -D__MSP430_167__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x168:%(cpp_msp2) -D__MSP430_168__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x169:%(cpp_msp2) -D__MSP430_169__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x1610:%(cpp_msp2) -D__MSP430_1610__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x1611:%(cpp_msp2) -D__MSP430_1611__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x1612:%(cpp_msp2) -D__MSP430_1612__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2001:%(cpp_msp1) -D__MSP430_2001__} \
++%{mmcu=msp430x2011:%(cpp_msp1) -D__MSP430_2011__} \
++%{mmcu=msp430x2002:%(cpp_msp1) -D__MSP430_2002__} \
++%{mmcu=msp430x2012:%(cpp_msp1) -D__MSP430_2012__} \
++%{mmcu=msp430x2003:%(cpp_msp1) -D__MSP430_2003__} \
++%{mmcu=msp430x2013:%(cpp_msp1) -D__MSP430_2013__} \
++%{mmcu=msp430x2101:%(cpp_msp1) -D__MSP430_2101__} \
++%{mmcu=msp430x2111:%(cpp_msp1) -D__MSP430_2111__} \
++%{mmcu=msp430x2121:%(cpp_msp1) -D__MSP430_2121__} \
++%{mmcu=msp430x2131:%(cpp_msp1) -D__MSP430_2131__} \
++%{mmcu=msp430x2112:%(cpp_msp1) -D__MSP430_2112__} \
++%{mmcu=msp430x2122:%(cpp_msp1) -D__MSP430_2122__} \
++%{mmcu=msp430x2132:%(cpp_msp1) -D__MSP430_2132__} \
++%{mmcu=msp430x2232:%(cpp_msp1) -D__MSP430_2232__} \
++%{mmcu=msp430x2252:%(cpp_msp1) -D__MSP430_2252__} \
++%{mmcu=msp430x2272:%(cpp_msp1) -D__MSP430_2272__} \
++%{mmcu=msp430x2234:%(cpp_msp1) -D__MSP430_2234__} \
++%{mmcu=msp430x2254:%(cpp_msp1) -D__MSP430_2254__} \
++%{mmcu=msp430x2274:%(cpp_msp1) -D__MSP430_2274__} \
++%{mmcu=msp430x233:%(cpp_msp2) -D__MSP430_233__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x235:%(cpp_msp2) -D__MSP430_235__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2330:%(cpp_msp2) -D__MSP430_2330__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2350:%(cpp_msp2) -D__MSP430_2350__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2370:%(cpp_msp2) -D__MSP430_2370__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x247:%(cpp_msp2) -D__MSP430_247__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x248:%(cpp_msp2) -D__MSP430_248__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x249:%(cpp_msp2) -D__MSP430_249__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2410:%(cpp_msp2) -D__MSP430_2410__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2471:%(cpp_msp2) -D__MSP430_2471__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2481:%(cpp_msp2) -D__MSP430_2481__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2491:%(cpp_msp2) -D__MSP430_2491__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2416:%(cpp_msp2) -D__MSP430_2416__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2417:%(cpp_msp2) -D__MSP430_2417__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2418:%(cpp_msp2) -D__MSP430_2418__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2419:%(cpp_msp2) -D__MSP430_2419__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2616:%(cpp_msp2) -D__MSP430_2616__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2617:%(cpp_msp2) -D__MSP430_2617__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2618:%(cpp_msp2) -D__MSP430_2618__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x2619:%(cpp_msp2) -D__MSP430_2619__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x311:%(cpp_msp1) -D__MSP430_311__} \
++%{mmcu=msp430x312:%(cpp_msp1) -D__MSP430_312__} \
++%{mmcu=msp430x313:%(cpp_msp1) -D__MSP430_313__} \
++%{mmcu=msp430x314:%(cpp_msp1) -D__MSP430_314__} \
++%{mmcu=msp430x315:%(cpp_msp1) -D__MSP430_315__} \
++%{mmcu=msp430x323:%(cpp_msp1) -D__MSP430_323__} \
++%{mmcu=msp430x325:%(cpp_msp1) -D__MSP430_325__} \
++%{mmcu=msp430x336:%(cpp_msp2) -D__MSP430_336__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x337:%(cpp_msp2) -D__MSP430_337__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x412:%(cpp_msp1) -D__MSP430_412__} \
++%{mmcu=msp430x413:%(cpp_msp1) -D__MSP430_413__} \
++%{mmcu=msp430x415:%(cpp_msp1) -D__MSP430_415__} \
++%{mmcu=msp430x417:%(cpp_msp1) -D__MSP430_417__} \
++%{mmcu=msp430x423:%(cpp_msp2) -D__MSP430_423__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x425:%(cpp_msp2) -D__MSP430_425__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x427:%(cpp_msp2) -D__MSP430_427__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x4250:%(cpp_msp1) -D__MSP430_4250__} \
++%{mmcu=msp430x4260:%(cpp_msp1) -D__MSP430_4260__} \
++%{mmcu=msp430x4270:%(cpp_msp1) -D__MSP430_4270__} \
++%{mmcu=msp430xG4250:%(cpp_msp1) -D__MSP430_G4250__} \
++%{mmcu=msp430xG4260:%(cpp_msp1) -D__MSP430_G4260__} \
++%{mmcu=msp430xG4270:%(cpp_msp1) -D__MSP430_G4270__} \
++%{mmcu=msp430xE423:%(cpp_msp2) -D__MSP430_E423__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430xE425:%(cpp_msp2) -D__MSP430_E425__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430xE427:%(cpp_msp2) -D__MSP430_E427__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430xE4232:%(cpp_msp2) -D__MSP430_E4232__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430xE4242:%(cpp_msp2) -D__MSP430_E4242__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430xE4252:%(cpp_msp2) -D__MSP430_E4252__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430xE4272:%(cpp_msp2) -D__MSP430_E4272__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430xW423:%(cpp_msp1) -D__MSP430_W423__} \
++%{mmcu=msp430xW425:%(cpp_msp1) -D__MSP430_W425__} \
++%{mmcu=msp430xW427:%(cpp_msp1) -D__MSP430_W427__} \
++%{mmcu=msp430xG437:%(cpp_msp1) -D__MSP430_G437__} \
++%{mmcu=msp430xG438:%(cpp_msp1) -D__MSP430_G438__} \
++%{mmcu=msp430xG439:%(cpp_msp1) -D__MSP430_G439__} \
++%{mmcu=msp430x435:%(cpp_msp1) -D__MSP430_435__} \
++%{mmcu=msp430x436:%(cpp_msp1) -D__MSP430_436__} \
++%{mmcu=msp430x437:%(cpp_msp1) -D__MSP430_437__} \
++%{mmcu=msp430x4351:%(cpp_msp1) -D__MSP430_4351__} \
++%{mmcu=msp430x4361:%(cpp_msp1) -D__MSP430_4361__} \
++%{mmcu=msp430x4371:%(cpp_msp1) -D__MSP430_4371__} \
++%{mmcu=msp430x447:%(cpp_msp2) -D__MSP430_447__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x448:%(cpp_msp2) -D__MSP430_448__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x449:%(cpp_msp2) -D__MSP430_449__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430xG4616:%(cpp_msp2) -D__MSP430_G4616__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430xG4617:%(cpp_msp2) -D__MSP430_G4617__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430xG4618:%(cpp_msp2) -D__MSP430_G4618__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430xG4619:%(cpp_msp2) -D__MSP430_G4619__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x4783:%(cpp_msp2) -D__MSP430_4783__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x4784:%(cpp_msp2) -D__MSP430_4784__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x4793:%(cpp_msp2) -D__MSP430_4793__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x4794:%(cpp_msp2) -D__MSP430_4794__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x47166:%(cpp_msp2) -D__MSP430_47166__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x47176:%(cpp_msp2) -D__MSP430_47176__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x47186:%(cpp_msp2) -D__MSP430_47186__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x47196:%(cpp_msp2) -D__MSP430_47196__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x47167:%(cpp_msp2) -D__MSP430_47167__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x47177:%(cpp_msp2) -D__MSP430_47177__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x47187:%(cpp_msp2) -D__MSP430_47187__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x47197:%(cpp_msp2) -D__MSP430_47197__ -D__MSP430X__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x5418:%(cpp_msp2) -D__MSP430_5418__ -D__MSP430X2__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x5419:%(cpp_msp2) -D__MSP430_5419__ -D__MSP430X2__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x5435:%(cpp_msp2) -D__MSP430_5435__ -D__MSP430X2__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x5436:%(cpp_msp2) -D__MSP430_5436__ -D__MSP430X2__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x5437:%(cpp_msp2) -D__MSP430_5437__ -D__MSP430X2__ -DMSP430_HAS_HWMUL} \
++%{mmcu=msp430x5438:%(cpp_msp2) -D__MSP430_5438__ -D__MSP430X2__ -DMSP430_HAS_HWMUL} \
++%{mmcu=cc430x5123:%(cpp_msp2) -D__CC430_5123__ -D__MSP430X2__ -DMSP430_HAS_HWMUL} \
++%{mmcu=cc430x5125:%(cpp_msp2) -D__CC430_5125__ -D__MSP430X2__ -DMSP430_HAS_HWMUL} \
++%{mmcu=cc430x6125:%(cpp_msp2) -D__CC430_6125__ -D__MSP430X2__ -DMSP430_HAS_HWMUL} \
++%{mmcu=cc430x6135:%(cpp_msp2) -D__CC430_6135__ -D__MSP430X2__ -DMSP430_HAS_HWMUL} \
++%{mmcu=cc430x6126:%(cpp_msp2) -D__CC430_6126__ -D__MSP430X2__ -DMSP430_HAS_HWMUL} \
++%{mmcu=cc430x5137:%(cpp_msp2) -D__CC430_5137__ -D__MSP430X2__ -DMSP430_HAS_HWMUL} \
++%{mmcu=cc430x6127:%(cpp_msp2) -D__CC430_6127__ -D__MSP430X2__ -DMSP430_HAS_HWMUL} \
++%{mmcu=cc430x6137:%(cpp_msp2) -D__CC430_6137__ -D__MSP430X2__ -DMSP430_HAS_HWMUL} \
++%{posix:-D_POSIX_SOURCE} %{mIAR:-D_IAR_ASSEMBLER_}"
++
++/* A C string constant that tells the GNU CC driver program options to
++   pass to CPP.  It can also specify how to translate options you
++   give to GNU CC into options for GNU CC to pass to the CPP.
++
++   Do not define this macro if it does not need to do anything.  */
++
++#define CC1_SPEC "%{profile:-p}"
++
++#define CC1PLUS_SPEC "-fno-rtti -fno-exceptions"
++
++/* A C string constant that tells the GNU CC driver program options to
++   pass to `cc1'.  It can also specify how to translate options you
++   give to GNU CC into options for GNU CC to pass to the `cc1'.
++
++   Do not define this macro if it does not need to do anything.  */
++
++#define ASM_SPEC "%{mmcu=*:-mmcu=%*}"
++/* A C string constant that tells the GNU CC driver program options to
++   pass to the assembler.  It can also specify how to translate
++   options you give to GNU CC into options for GNU CC to pass to the
++   assembler.  See the file `sun3.h' for an example of this.
++
++   Do not define this macro if it does not need to do anything.  */
++
++#define ASM_FINAL_SPEC ""
++/* A C string constant that tells the GNU CC driver program how to
++   run any programs which cleanup after the normal assembler.
++   Normally, this is not needed.  See the file `mips.h' for an
++   example of this.
++
++   Do not define this macro if it does not need to do anything.  */
++
++#define LINK_SPEC "\
++%{!mmcu*:-m msp430x110} \
++%{mmcu=msp1:-m msp430x110} \
++%{mmcu=msp2:-m msp430x336} \
++%{mmcu=msp430x110:-m msp430x110 } \
++%{mmcu=msp430x112:-m msp430x112 } \
++%{mmcu=msp430x1101:-m msp430x1101 } \
++%{mmcu=msp430x1111:-m msp430x1111 } \
++%{mmcu=msp430x1121:-m msp430x1121 } \
++%{mmcu=msp430x1122:-m msp430x1122 } \
++%{mmcu=msp430x1132:-m msp430x1132 } \
++%{mmcu=msp430x122:-m msp430x122 } \
++%{mmcu=msp430x123:-m msp430x123 } \
++%{mmcu=msp430x1222:-m msp430x1222 } \
++%{mmcu=msp430x1232:-m msp430x1232 } \
++%{mmcu=msp430x133:-m msp430x133 } \
++%{mmcu=msp430x135:-m msp430x135 } \
++%{mmcu=msp430x1331:-m msp430x1331 } \
++%{mmcu=msp430x1351:-m msp430x1351 } \
++%{mmcu=msp430x147:-m msp430x147 } \
++%{mmcu=msp430x148:-m msp430x148 } \
++%{mmcu=msp430x149:-m msp430x149 } \
++%{mmcu=msp430x1471:-m msp430x1471 } \
++%{mmcu=msp430x1481:-m msp430x1481 } \
++%{mmcu=msp430x1491:-m msp430x1491 } \
++%{mmcu=msp430x155:-m msp430x155 } \
++%{mmcu=msp430x156:-m msp430x156 } \
++%{mmcu=msp430x157:-m msp430x157 } \
++%{mmcu=msp430x167:-m msp430x167 } \
++%{mmcu=msp430x168:-m msp430x168 } \
++%{mmcu=msp430x169:-m msp430x169 } \
++%{mmcu=msp430x1610:-m msp430x1610 } \
++%{mmcu=msp430x1611:-m msp430x1611 } \
++%{mmcu=msp430x1612:-m msp430x1612 } \
++%{mmcu=msp430x2001:-m msp430x2001 } \
++%{mmcu=msp430x2011:-m msp430x2011 } \
++%{mmcu=msp430x2002:-m msp430x2002 } \
++%{mmcu=msp430x2012:-m msp430x2012 } \
++%{mmcu=msp430x2003:-m msp430x2003 } \
++%{mmcu=msp430x2013:-m msp430x2013 } \
++%{mmcu=msp430x2101:-m msp430x2101 } \
++%{mmcu=msp430x2111:-m msp430x2111 } \
++%{mmcu=msp430x2121:-m msp430x2121 } \
++%{mmcu=msp430x2131:-m msp430x2131 } \
++%{mmcu=msp430x2112:-m msp430x2112 } \
++%{mmcu=msp430x2122:-m msp430x2122 } \
++%{mmcu=msp430x2132:-m msp430x2132 } \
++%{mmcu=msp430x2232:-m msp430x2232 } \
++%{mmcu=msp430x2252:-m msp430x2252 } \
++%{mmcu=msp430x2272:-m msp430x2272 } \
++%{mmcu=msp430x2234:-m msp430x2234 } \
++%{mmcu=msp430x2254:-m msp430x2254 } \
++%{mmcu=msp430x2274:-m msp430x2274 } \
++%{mmcu=msp430x233:-m msp430x233 } \
++%{mmcu=msp430x235:-m msp430x235 } \
++%{mmcu=msp430x2330:-m msp430x2330 } \
++%{mmcu=msp430x2350:-m msp430x2350 } \
++%{mmcu=msp430x2370:-m msp430x2370 } \
++%{mmcu=msp430x247:-m msp430x247 } \
++%{mmcu=msp430x248:-m msp430x248 } \
++%{mmcu=msp430x249:-m msp430x249 } \
++%{mmcu=msp430x2410:-m msp430x2410 } \
++%{mmcu=msp430x2471:-m msp430x2471 } \
++%{mmcu=msp430x2481:-m msp430x2481 } \
++%{mmcu=msp430x2491:-m msp430x2491 } \
++%{mmcu=msp430x2416:-m msp430x2416 } \
++%{mmcu=msp430x2417:-m msp430x2417 } \
++%{mmcu=msp430x2418:-m msp430x2418 } \
++%{mmcu=msp430x2419:-m msp430x2419 } \
++%{mmcu=msp430x2616:-m msp430x2616 } \
++%{mmcu=msp430x2617:-m msp430x2617 } \
++%{mmcu=msp430x2618:-m msp430x2618 } \
++%{mmcu=msp430x2619:-m msp430x2619 } \
++%{mmcu=msp430x311:-m msp430x311 } \
++%{mmcu=msp430x312:-m msp430x312 } \
++%{mmcu=msp430x313:-m msp430x313 } \
++%{mmcu=msp430x314:-m msp430x314 } \
++%{mmcu=msp430x315:-m msp430x315 } \
++%{mmcu=msp430x323:-m msp430x323 } \
++%{mmcu=msp430x325:-m msp430x325 } \
++%{mmcu=msp430x336:-m msp430x336 } \
++%{mmcu=msp430x337:-m msp430x337 } \
++%{mmcu=msp430x412:-m msp430x412 } \
++%{mmcu=msp430x413:-m msp430x413 } \
++%{mmcu=msp430x415:-m msp430x415 } \
++%{mmcu=msp430x417:-m msp430x417 } \
++%{mmcu=msp430x423:-m msp430x423 } \
++%{mmcu=msp430x425:-m msp430x425 } \
++%{mmcu=msp430x427:-m msp430x427 } \
++%{mmcu=msp430x4250:-m msp430x4250 } \
++%{mmcu=msp430x4260:-m msp430x4260 } \
++%{mmcu=msp430x4270:-m msp430x4270 } \
++%{mmcu=msp430xG4250:-m msp430xG4250 } \
++%{mmcu=msp430xG4260:-m msp430xG4260 } \
++%{mmcu=msp430xG4270:-m msp430xG4270 } \
++%{mmcu=msp430xE423:-m msp430xE423 } \
++%{mmcu=msp430xE425:-m msp430xE425 } \
++%{mmcu=msp430xE427:-m msp430xE427 } \
++%{mmcu=msp430xE4232:-m msp430xE4232 } \
++%{mmcu=msp430xE4242:-m msp430xE4242 } \
++%{mmcu=msp430xE4252:-m msp430xE4252 } \
++%{mmcu=msp430xE4272:-m msp430xE4272 } \
++%{mmcu=msp430xW423:-m msp430xW423 } \
++%{mmcu=msp430xW425:-m msp430xW425 } \
++%{mmcu=msp430xW427:-m msp430xW427 } \
++%{mmcu=msp430xG437:-m msp430xG437 } \
++%{mmcu=msp430xG438:-m msp430xG438 } \
++%{mmcu=msp430xG439:-m msp430xG439 } \
++%{mmcu=msp430x435:-m msp430x435 } \
++%{mmcu=msp430x436:-m msp430x436 } \
++%{mmcu=msp430x437:-m msp430x437 } \
++%{mmcu=msp430x447:-m msp430x447 } \
++%{mmcu=msp430x448:-m msp430x448 } \
++%{mmcu=msp430x449:-m msp430x449 } \
++%{mmcu=msp430xG4616:-m msp430xG4616 } \
++%{mmcu=msp430xG4617:-m msp430xG4617 } \
++%{mmcu=msp430xG4618:-m msp430xG4618 } \
++%{mmcu=msp430xG4619:-m msp430xG4619 } \
++%{mmcu=msp430x4783:-m msp430x4783 } \
++%{mmcu=msp430x4784:-m msp430x4784 } \
++%{mmcu=msp430x4793:-m msp430x4793 } \
++%{mmcu=msp430x4794:-m msp430x4794 } \
++%{mmcu=msp430x47166:-m msp430x47166 } \
++%{mmcu=msp430x47176:-m msp430x47176 } \
++%{mmcu=msp430x47186:-m msp430x47186 } \
++%{mmcu=msp430x47196:-m msp430x47196 } \
++%{mmcu=msp430x47167:-m msp430x47167 } \
++%{mmcu=msp430x47177:-m msp430x47177 } \
++%{mmcu=msp430x47187:-m msp430x47187 } \
++%{mmcu=msp430x47197:-m msp430x47197 } \
++%{mmcu=msp430x5418:-m msp430x5418 } \
++%{mmcu=msp430x5419:-m msp430x5419 } \
++%{mmcu=msp430x5435:-m msp430x5435 } \
++%{mmcu=msp430x5436:-m msp430x5436 } \
++%{mmcu=msp430x5437:-m msp430x5437 } \
++%{mmcu=msp430x5438:-m msp430x5438 } \
++%{mmcu=cc430x5123: -m cc430x5123 } \
++%{mmcu=cc430x5125: -m cc430x5125 } \
++%{mmcu=cc430x6125: -m cc430x6125 } \
++%{mmcu=cc430x6135: -m cc430x6135 } \
++%{mmcu=cc430x6126: -m cc430x6126 } \
++%{mmcu=cc430x5137: -m cc430x5137 } \
++%{mmcu=cc430x6127: -m cc430x6127 } \
++%{mmcu=cc430x6137: -m cc430x6137 } \
++"
++
++#define LIB_SPEC "-lc"
++#define LIBGCC_SPEC "-lgcc"
++#define LIBSTDCXX "-lgcc"
++
++#define STARTFILE_SPEC "%(crt_binutils)"
++/* Another C string constant used much like `LINK_SPEC'.  The
++   difference between the two is that `STARTFILE_SPEC' is used at the
++   very beginning of the command given to the linker.
++
++   If this macro is not defined, a default is provided that loads the
++   standard C startup file from the usual place.  See `gcc.c'.  */
++
++#define ENDFILE_SPEC ""
++/* Another C string constant used much like `LINK_SPEC'.  The
++   difference between the two is that `ENDFILE_SPEC' is used at the
++   very end of the command given to the linker.
++
++   Do not define this macro if it does not need to do anything.  */
++
++#define CRT_BINUTILS_SPECS "\
++%{!mmcu=*|mmcu=msp430x110|mmcu=msp1:crt430x110.o%s} \
++%{mmcu=msp430x112:crt430x112.o%s} \
++%{mmcu=msp430x1101:crt430x1101.o%s} \
++%{mmcu=msp430x1111:crt430x1111.o%s} \
++%{mmcu=msp430x1121:crt430x1121.o%s} \
++%{mmcu=msp430x1122:crt430x1122.o%s} \
++%{mmcu=msp430x1132:crt430x1132.o%s} \
++%{mmcu=msp430x122:crt430x122.o%s} \
++%{mmcu=msp430x123:crt430x123.o%s} \
++%{mmcu=msp430x1222:crt430x1222.o%s} \
++%{mmcu=msp430x1232:crt430x1232.o%s} \
++%{mmcu=msp430x133:crt430x133.o%s} \
++%{mmcu=msp430x135:crt430x135.o%s} \
++%{mmcu=msp430x1331:crt430x1331.o%s} \
++%{mmcu=msp430x1351:crt430x1351.o%s} \
++%{mmcu=msp430x147:crt430x147.o%s} \
++%{mmcu=msp430x148:crt430x148.o%s} \
++%{mmcu=msp430x149:crt430x149.o%s} \
++%{mmcu=msp430x1471:crt430x1471.o%s} \
++%{mmcu=msp430x1481:crt430x1481.o%s} \
++%{mmcu=msp430x1491:crt430x1491.o%s} \
++%{mmcu=msp430x155:crt430x155.o%s} \
++%{mmcu=msp430x156:crt430x156.o%s} \
++%{mmcu=msp430x157:crt430x157.o%s} \
++%{mmcu=msp430x167:crt430x167.o%s} \
++%{mmcu=msp430x168:crt430x168.o%s} \
++%{mmcu=msp430x169:crt430x169.o%s} \
++%{mmcu=msp430x1610:crt430x1610.o%s} \
++%{mmcu=msp430x1611:crt430x1611.o%s} \
++%{mmcu=msp430x1612:crt430x1612.o%s} \
++%{mmcu=msp430x2001:crt430x2001.o%s} \
++%{mmcu=msp430x2011:crt430x2011.o%s} \
++%{mmcu=msp430x2002:crt430x2002.o%s} \
++%{mmcu=msp430x2012:crt430x2012.o%s} \
++%{mmcu=msp430x2003:crt430x2003.o%s} \
++%{mmcu=msp430x2013:crt430x2013.o%s} \
++%{mmcu=msp430x2101:crt430x2101.o%s} \
++%{mmcu=msp430x2111:crt430x2111.o%s} \
++%{mmcu=msp430x2121:crt430x2121.o%s} \
++%{mmcu=msp430x2131:crt430x2131.o%s} \
++%{mmcu=msp430x2112:crt430x2112.o%s} \
++%{mmcu=msp430x2122:crt430x2122.o%s} \
++%{mmcu=msp430x2132:crt430x2132.o%s} \
++%{mmcu=msp430x2232:crt430x2232.o%s} \
++%{mmcu=msp430x2252:crt430x2252.o%s} \
++%{mmcu=msp430x2272:crt430x2272.o%s} \
++%{mmcu=msp430x2234:crt430x2234.o%s} \
++%{mmcu=msp430x2254:crt430x2254.o%s} \
++%{mmcu=msp430x2274:crt430x2274.o%s} \
++%{mmcu=msp430x233:crt430x233.o%s} \
++%{mmcu=msp430x235:crt430x235.o%s} \
++%{mmcu=msp430x2330:crt430x2330.o%s} \
++%{mmcu=msp430x2350:crt430x2350.o%s} \
++%{mmcu=msp430x2370:crt430x2370.o%s} \
++%{mmcu=msp430x247:crt430x247.o%s} \
++%{mmcu=msp430x248:crt430x248.o%s} \
++%{mmcu=msp430x249:crt430x249.o%s} \
++%{mmcu=msp430x2410:crt430x2410.o%s} \
++%{mmcu=msp430x2471:crt430x2471.o%s} \
++%{mmcu=msp430x2481:crt430x2481.o%s} \
++%{mmcu=msp430x2491:crt430x2491.o%s} \
++%{mmcu=msp430x2416:crt430x2416.o%s} \
++%{mmcu=msp430x2417:crt430x2417.o%s} \
++%{mmcu=msp430x2418:crt430x2418.o%s} \
++%{mmcu=msp430x2419:crt430x2419.o%s} \
++%{mmcu=msp430x2616:crt430x2616.o%s} \
++%{mmcu=msp430x2617:crt430x2617.o%s} \
++%{mmcu=msp430x2618:crt430x2618.o%s} \
++%{mmcu=msp430x2619:crt430x2619.o%s} \
++%{mmcu=msp430x311:crt430x311.o%s} \
++%{mmcu=msp430x312:crt430x312.o%s} \
++%{mmcu=msp430x313:crt430x313.o%s} \
++%{mmcu=msp430x314:crt430x314.o%s} \
++%{mmcu=msp430x315:crt430x315.o%s} \
++%{mmcu=msp430x323:crt430x323.o%s} \
++%{mmcu=msp430x325:crt430x325.o%s} \
++%{mmcu=msp430x336|mmcu=msp2:crt430x336.o%s} \
++%{mmcu=msp430x337:crt430x337.o%s} \
++%{mmcu=msp430x412:crt430x412.o%s} \
++%{mmcu=msp430x413:crt430x413.o%s} \
++%{mmcu=msp430x415:crt430x415.o%s} \
++%{mmcu=msp430x417:crt430x417.o%s} \
++%{mmcu=msp430x423:crt430x423.o%s} \
++%{mmcu=msp430x425:crt430x425.o%s} \
++%{mmcu=msp430x427:crt430x427.o%s} \
++%{mmcu=msp430x4250:crt430x4250.o%s} \
++%{mmcu=msp430x4260:crt430x4260.o%s} \
++%{mmcu=msp430x4270:crt430x4270.o%s} \
++%{mmcu=msp430xG4250:crt430xG4250.o%s} \
++%{mmcu=msp430xG4260:crt430xG4260.o%s} \
++%{mmcu=msp430xG4270:crt430xG4270.o%s} \
++%{mmcu=msp430xE423:crt430xE423.o%s} \
++%{mmcu=msp430xE425:crt430xE425.o%s} \
++%{mmcu=msp430xE427:crt430xE427.o%s} \
++%{mmcu=msp430xE4232:crt430xE4232.o%s} \
++%{mmcu=msp430xE4242:crt430xE4242.o%s} \
++%{mmcu=msp430xE4252:crt430xE4252.o%s} \
++%{mmcu=msp430xE4272:crt430xE4272.o%s} \
++%{mmcu=msp430xW423:crt430xW423.o%s} \
++%{mmcu=msp430xW425:crt430xW425.o%s} \
++%{mmcu=msp430xW427:crt430xW427.o%s} \
++%{mmcu=msp430xG437:crt430xG437.o%s} \
++%{mmcu=msp430xG438:crt430xG438.o%s} \
++%{mmcu=msp430xG439:crt430xG439.o%s} \
++%{mmcu=msp430x435:crt430x435.o%s} \
++%{mmcu=msp430x436:crt430x436.o%s} \
++%{mmcu=msp430x437:crt430x437.o%s} \
++%{mmcu=msp430x4351:crt430x4351.o%s} \
++%{mmcu=msp430x4361:crt430x4361.o%s} \
++%{mmcu=msp430x4371:crt430x4371.o%s} \
++%{mmcu=msp430x447:crt430x447.o%s} \
++%{mmcu=msp430x448:crt430x448.o%s} \
++%{mmcu=msp430x449:crt430x449.o%s} \
++%{mmcu=msp430xG4616:crt430xG4616.o%s} \
++%{mmcu=msp430xG4617:crt430xG4617.o%s} \
++%{mmcu=msp430xG4618:crt430xG4618.o%s} \
++%{mmcu=msp430xG4619:crt430xG4619.o%s}\
++%{mmcu=msp430x4783:crt430x4783.o%s} \
++%{mmcu=msp430x4784:crt430x4784.o%s} \
++%{mmcu=msp430x4793:crt430x4793.o%s} \
++%{mmcu=msp430x4794:crt430x4794.o%s} \
++%{mmcu=msp430x5418:crt430x5418.o%s} \
++%{mmcu=msp430x5419:crt430x5419.o%s}\
++%{mmcu=msp430x5435:crt430x5435.o%s} \
++%{mmcu=msp430x5436:crt430x5436.o%s} \
++%{mmcu=msp430x5437:crt430x5437.o%s} \
++%{mmcu=msp430x5438:crt430x5438.o%s} \
++%{mmcu=cc430x5123:crtcc430x5123.o%s} \
++%{mmcu=cc430x5125:crtcc430x5125.o%s} \
++%{mmcu=cc430x6125:crtcc430x6125.o%s} \
++%{mmcu=cc430x6135:crtcc430x6135.o%s} \
++%{mmcu=cc430x6126:crtcc430x6126.o%s} \
++%{mmcu=cc430x5137:crtcc430x5137.o%s} \
++%{mmcu=cc430x6127:crtcc430x6127.o%s} \
++%{mmcu=cc430x6137:crtcc430x6137.o%s} \
++"
++
++
++
++#define CPP_MSP1_SPEC " -DMSP430_NO_HW_MUL "
++#define CPP_MSP2_SPEC " -DMSP430_HAS_HW_MUL "
++
++#define EXTRA_SPECS                                   \
++{"cpp_msp1",CPP_MSP1_SPEC},                   \
++{"cpp_msp2",CPP_MSP2_SPEC},                   \
++{"crt_binutils", CRT_BINUTILS_SPECS},
++
++/* Define this macro to provide additional specifications to put in
++   the `specs' file that can be used in various specifications like
++   `CC1_SPEC'.
++
++   The definition should be an initializer for an array of structures,
++   containing a string constant, that defines the specification name,
++   and a string constant that provides the specification.
++
++   Do not define this macro if it does not need to do anything.
++
++   `EXTRA_SPECS' is useful when an architecture contains several
++   related targets, which have various `..._SPECS' which are similar
++   to each other, and the maintainer would like one central place to
++   keep these definitions.
++
++   For example, the PowerPC System V.4 targets use `EXTRA_SPECS' to
++   define either `_CALL_SYSV' when the System V calling sequence is
++   used or `_CALL_AIX' when the older AIX-based calling sequence is
++   used.
++
++   The `config/rs6000/rs6000.h' target file defines:
++
++   #define EXTRA_SPECS \
++   { "cpp_sysv_default", CPP_SYSV_DEFAULT },
++
++   #define CPP_SYS_DEFAULT ""
++
++   The `config/rs6000/sysv.h' target file defines:
++   #undef CPP_SPEC
++   #define CPP_SPEC \
++   "%{posix: -D_POSIX_SOURCE } \
++   %{mcall-sysv: -D_CALL_SYSV } %{mcall-aix: -D_CALL_AIX } \
++   %{!mcall-sysv: %{!mcall-aix: %(cpp_sysv_default) }} \
++   %{msoft-float: -D_SOFT_FLOAT} %{mcpu=403: -D_SOFT_FLOAT}"
++
++   #undef CPP_SYSV_DEFAULT
++   #define CPP_SYSV_DEFAULT "-D_CALL_SYSV"
++
++   while the `config/rs6000/eabiaix.h' target file defines
++   `CPP_SYSV_DEFAULT' as:
++
++   #undef CPP_SYSV_DEFAULT
++   #define CPP_SYSV_DEFAULT "-D_CALL_AIX"  */
++
++
++#define MULTILIB_DEFAULTS { "mmcu=msp430x110" }
++
++#define TEST_HARD_REG_CLASS(CLASS, REGNO) \
++  TEST_HARD_REG_BIT (reg_class_contents[ (int) (CLASS)], REGNO)
++
++/* Note that the other files fail to use these
++   in some of the places where they should.  */
++
++#if defined(__STDC__) || defined(ALMOST_STDC)
++#define AS2(a,b,c) #a " " #b "," #c
++#define AS2C(b,c) " " #b "," #c
++#define AS3(a,b,c,d) #a " " #b "," #c "," #d
++#define AS1(a,b) #a " " #b
++#else
++#define AS1(a,b) "a   b"
++#define AS2(a,b,c) "a b,c"
++#define AS2C(b,c) " b,c"
++#define AS3(a,b,c,d) "a       b,c,d"
++#endif
++#define OUT_AS1(a,b) output_asm_insn (AS1(a,b), operands)
++#define OUT_AS2(a,b,c) output_asm_insn (AS2(a,b,c), operands)
++#define CR_TAB "\n\t"
++
++#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
++
++#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
++#define DWARF2_DEBUGGING_INFO 1
++#define OBJECT_FORMAT_ELF
++
++#define DBX_REGISTER_NUMBER(r) (r)
++
++/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
++
++struct machine_function GTY(())
++{
++  /* 'true' - if the current function is a leaf function.  */
++  int is_leaf;
++
++  /* 'true' - if current function is a naked function.  */
++  int is_naked;
++
++  /* 'true' - if current function is an interrupt function 
++     as specified by the "interrupt" attribute.  */
++  int is_interrupt;
++
++  /* 'true' - if current function is a 'task' function 
++     as specified by the "OS_task" attribute.  */
++  int is_OS_task;
++ 
++  int is_noint_hwmul;
++  
++  int is_critical;
++  
++  int is_reenterant;
++  
++  int is_wakeup;
++  
++  int is_signal;
++};
++
++#ifdef RTX_CODE
++extern int default_rtx_costs (rtx X ATTRIBUTE_UNUSED, enum rtx_code code, enum rtx_code outer_code ATTRIBUTE_UNUSED);
++#endif
+diff -urNad msp430-gcc~/gcc/config/msp430/msp430.md msp430-gcc/gcc/config/msp430/msp430.md
+--- msp430-gcc~/gcc/config/msp430/msp430.md    1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/msp430.md     2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1,4281 @@
++;; -*- Mode: Scheme -*-
++;;   Machine description for GNU compiler,
++;;   for Texas Instruments msp430 MCUs
++;;   Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
++;;   Contributed by Dmitry Diky <diwil@mail.ru>
++;;     GCC 4.x port by Ivan Shcherbakov <mspgcc@sysprogs.org>
++
++;; This work is partially financed by the European Commission under the
++;; Framework 6 Information Society Technologies Project
++;; "Wirelessly Accessible Sensor Populations (WASP)".
++
++;
++
++; This file is part of GCC.
++
++;; GCC is free software; you can redistribute it and/or modify
++;; it under the terms of the GNU General Public License as published by
++;; the Free Software Foundation; either version 2, or (at your option)
++;; any later version.
++
++;; GCC is distributed in the hope that it will be useful,
++;; but WITHOUT ANY WARRANTY; without even the implied warranty of
++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++;; GNU General Public License for more details.
++
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING.  If not, write to
++;; the Free Software Foundation, 59 Temple Place - Suite 330,
++;; Boston, MA 02111-1307, USA.
++
++(include "predicates.md")
++
++;; Special characters after '%':
++;;  A  No effect (add 0).
++;;  B  Add 1 to REG number, 2 to MEM address or CONST_INT.
++;;  C    2                4
++;;  D    3                6
++;;  E  adds nothing to reg but used only with (mem:hi (reg:hi))
++;;  F  no trim array
++;;  M  Add 0 to address if using stack pointer
++;;  N  Add 2 to address if using stack pointer
++;;  Extra constarains:
++;;  P  hardware constants: -1,0,+1,+2,+4,+8
++;;  Q  Indexed destination register as X(Rn)
++;;  R  Indexed source register as @Rn+
++;;  S  Symbol reference for 'C' like: a = *b;
++;;
++
++;; Unspec usage:
++;; 3 - strlen
++;; 0  - addc_reg
++;; 5  - addc_any
++;; 1  - bittest_lo
++;; 2  - bittest_hi
++;; 6  - bittest
++;; 4  - swpb
++;; 7  - bittest_b
++;; 8  - move SF to SI with no conversion
++
++(define_constants
++  [(REG_PC                    0)
++   (REG_SP                    1)
++   (UNSPEC_EINT               100)
++   (UNSPEC_DINT               101)
++   (UNSPEC_EXPLICIT_BR 102)
++   (UNSPEC_PUSH_SREG 103)
++   (UNSPEC_SAVE_PC_TO_REG 104)
++   (UNSPEC_LOAD_SP    105)
++   (UNSPEC_PROLOGUE_PUSH 106)
++   (UNSPEC_POP_R2     107)
++   ]
++)
++
++;; Condition code settings.
++
++
++(define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber,further,oper,cbranch"
++  (const_string "none"))
++
++(define_attr "type" "branch,branch1,arith"
++  (const_string "arith"))
++
++(define_attr "msp430_has_hwmul" "yes,no"
++  (const (if_then_else (symbol_ref "MSP430_HAS_HWMUL_INTERNAL")
++                     (const_string "yes")
++                     (const_string "no"))))
++
++(define_attr "msp430_noint_hwmul" "" (symbol_ref "MSP430_NOINT_HWMUL"))
++
++;; The size of instructions in bytes.
++;; XXX may depend from "cc"
++
++;; for confitional branches
++(define_attr "length" ""
++  (cond [(eq_attr "type" "branch")
++         (if_then_else  (and (ge (minus (pc) (match_dup 0)) 
++                                      (const_int -508))
++                             (le (minus (pc) (match_dup 0)) 
++                                      (const_int  508)))
++                        (const_int 1)
++                      (const_int 2))]
++      (const_int 2)
++))
++
++
++;;========================================================================
++;;  PUSH/POP helper functions
++;;
++
++
++(define_insn "*pushqi_pre_mod"
++[(set (mem:QI (pre_modify:HI (reg:HI 1)
++                (plus:HI (reg:HI 1) (const_int -2))))
++      (match_operand:QI 0 "general_operand" "rim"))]
++""
++"* return msp430_pushqi(insn, operands, NULL);"
++[(set_attr "length" "2")])
++
++(define_insn "*pushqi"
++  [(set (match_operand:QI 1 "push_operand" "=<")
++;;  [(set (mem:QI (post_dec (reg:HI 1)))      ;PRE_DEC!
++        (match_operand:QI 0 "general_operand" "rim"))]
++  ""
++  "* return msp430_pushqi(insn, operands, NULL);"
++  [(set_attr "length" "2")])
++
++(define_insn "*pushhi"
++  [(set (match_operand:HI 1 "push_operand" "=<")
++        (match_operand:HI 0 "general_no_elim_operand" "rim"))]
++  ""
++  "* return msp430_pushhi(insn, operands, NULL);"
++  [(set_attr "length" "2")])
++
++(define_insn "pushhi_prologue"
++  [(set (match_operand:HI 1 "push_operand" "=<")
++        (match_operand:HI 0 "general_operand" "rim"))
++      (unspec_volatile:HI [(const_int 0)] UNSPEC_PROLOGUE_PUSH)]
++  ""
++  "* return msp430_pushhi(insn, operands, NULL);"
++  [(set_attr "length" "2")])
++
++  
++;(define_insn_and_split "*pushhi"
++;  [(set (match_operand:HI 1 "push_operand" "=<")
++;        (match_operand:HI 0 "general_operand" "rim"))]
++;  ""
++;  "* return msp430_pushhi(insn, operands, NULL);"
++;  "(GET_CODE(operands[0]) == REG) && ((REGNO(operands[0]) == REG_SP) || (operands[0] == arg_pointer_rtx) || (operands[0] == frame_pointer_rtx) || IN_RANGE (REGNO (operands[0]), FIRST_PSEUDO_REGISTER, LAST_VIRTUAL_REGISTER))"
++;  [
++;     (set (match_dup 2) (match_dup 0))
++;     (set (match_dup 1) (match_dup 2))
++;  ]
++;  "operands[2] = gen_rtx_reg(SImode);"
++;  [(set_attr "length" "2")]
++; )
++
++ 
++
++(define_insn "*pushsi"
++  [(set (match_operand:SI 1 "push_operand" "=<")
++;;  [(set (mem:SI (post_dec (reg:HI 1))) ;PRE_DEC!
++        (match_operand:SI 0 "general_operand" "rmi"))]
++  ""
++  "* return msp430_pushsisf(insn, operands, NULL);"
++  [(set_attr "length" "4")])
++
++
++(define_insn "*pushdi"
++  [(set (match_operand:DI 1 "push_operand" "=<")
++;;  [(set (mem:DI (post_dec (reg:HI 1)))      ;PRE_DEC!
++        (match_operand:DI 0 "general_operand" "rmi"))]
++  ""
++  "* return msp430_pushdi(insn, operands, NULL);"
++  [(set_attr "length" "8")])
++
++
++(define_insn "*pushsf"
++  [(set (match_operand:SF 1 "push_operand" "=<")
++;;  [(set (mem:SF (post_dec (reg:HI 1)))      ;PRE+DEC
++        (match_operand:SF 0 "general_operand" "rmi"))]
++  ""
++  "* return msp430_pushsisf(insn, operands, NULL);"
++  [(set_attr "length" "4")])
++  
++(define_insn "push_sreg"
++  [(unspec_volatile:HI [(const_int 0)] UNSPEC_PUSH_SREG)
++   (set (reg:HI REG_SP) (minus:HI 
++                           (reg:HI REG_SP)
++                           (const_int 2)))]
++  ""
++  "push r2"
++  [(set_attr "length" "2")])
++
++
++;; =========================================== POP register instruction ====================================
++
++;; The POP instruction is used only by expand_epilogue() function.
++;; As present implementation of DWARF2 CFA generator (gcc 4.4.2) does
++;; not recognize pop_operand-based or post_inc-based operations,
++;; the short and neat definition (first one) cannot be used.
++;; Instead, we use a longer PARALLEL format to define the action of
++;; "pop", so the DWARF2 generator will be happy.
++
++;;(define_insn "pophi_reg"
++;;  [(set (match_operand:HI 0 "register_operand" "=r")
++;;            (match_operand:HI 1 "pop_operand" ">"))]
++;;  ""
++;;  "pop %0"
++;;  [(set_attr "length" "1")])
++
++(define_insn "pophi_reg"
++  [(parallel [
++    (set (reg:HI REG_SP) (plus:HI (reg:HI REG_SP) (const_int 2)))                             ;;This goes first, so the DWARF2 generator can recognize it
++      (set (match_operand:HI 0 "register_operand" "=r") (mem:HI (reg:HI REG_SP)))     ;;This goes second with RTX_FRAME_RELATED_P() set to 0
++      ]
++      )]
++  ""
++  "pop\t%0"
++  [(set_attr "length" "1")])
++
++(define_insn "pop_r2"
++  [(set (reg:HI REG_SP) (plus:HI (reg:HI REG_SP) (const_int 2)))
++      (unspec_volatile:HI [(const_int 0)] UNSPEC_POP_R2)]
++  ""
++  "pop\tr2"
++  [(set_attr "length" "2")])
++
++(define_insn "save_pc_to_reg"
++  [(unspec_volatile:HI [(const_int 0)] UNSPEC_SAVE_PC_TO_REG)
++   (set (match_operand:HI 0 "register_operand" "=r") (reg:HI REG_PC))]
++  ""
++  "mov\tr0, %0"
++  [(set_attr "length" "2")])
++  
++;; =================================================================================================
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") 
++      (match_operand:HI 1 "general_operand" ""))
++   (set (mem:HI (post_dec (reg:HI 1)))
++      (match_dup 0))]
++"dead_or_set_in_peep(1, insn, operands[0])"
++  [(set (mem:HI (post_dec (reg:HI 1)))
++      (match_dup 1))]
++"")
++
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "") 
++      (match_operand:SI 1 "general_operand" ""))
++   (set (mem:SI (post_dec (reg:HI 1)))
++      (match_dup 0))]
++"dead_or_set_in_peep(1, insn, operands[0])"
++  [(set (mem:SI (post_dec (reg:HI 1)))
++      (match_dup 1))]
++"")
++
++(define_peephole2
++  [(set (match_operand:SF 0 "register_operand" "") 
++      (match_operand:SF 1 "general_operand" ""))
++   (set (mem:SF (post_dec (reg:HI 1)))
++      (match_dup 0))]
++"dead_or_set_in_peep(1, insn, operands[0])"
++  [(set (mem:SF (post_dec (reg:HI 1)))
++      (match_dup 1))]
++"")
++
++
++;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
++;; This instructin sets Z flag
++
++(define_insn "sez"
++  [(set (cc0) (const_int 0))]
++""
++"setz"
++  [(set_attr "length" "1")
++   (set_attr "cc" "compare")])
++
++
++
++;;========================================================================
++;; compare
++
++(define_expand "cmpqi"
++  [(set (cc0)
++        (compare:QI (match_operand:QI 0 "nonimmediate_operand_msp430" "rm")   
++                    (match_operand:QI 1 "general_operand_msp430" "rmi")))]
++ ""
++"
++  msp430_compare_op0 = operands[0];
++  msp430_compare_op1 = operands[1];
++  DONE;
++")
++
++
++(define_expand "cmphi"
++  [(set (cc0)
++        (compare:HI (match_operand:HI 0 "nonimmediate_operand_msp430" "rm")   
++                    (match_operand:HI 1 "general_operand_msp430" "rmi")))]
++ ""
++"
++  msp430_compare_op0 = operands[0];
++  msp430_compare_op1 = operands[1];
++  DONE;
++")
++
++
++(define_expand "cmpsi"
++   [(set (cc0)
++         (compare:SI (match_operand:SI 0 "nonimmediate_operand" "rm")
++                     (match_operand:SI 1 "general_operand" "rmi")))]
++   ""
++"
++  msp430_compare_op0 = operands[0];
++  msp430_compare_op1 = operands[1];
++  DONE;
++")
++
++
++(define_expand "beq"
++   [(use (match_operand 0 "" ""))]
++""
++"{ msp430_emit_cbranch (EQ, operands[0]); DONE; }")
++
++(define_expand "bne"
++   [(use (match_operand 0 "" ""))]
++""
++"{ msp430_emit_cbranch (NE, operands[0]); DONE; }")
++
++(define_expand "bge"
++   [(use (match_operand 0 "" ""))]
++""
++"{ msp430_emit_cbranch (GE, operands[0]); DONE; }")
++
++(define_expand "bgt"
++   [(use (match_operand 0 "" ""))]
++""
++"{ msp430_emit_cbranch (GT, operands[0]); DONE; }")
++
++(define_expand "ble"
++   [(use (match_operand 0 "" ""))]
++""
++"{ msp430_emit_cbranch (LE, operands[0]); DONE; }")
++
++(define_expand "blt"
++   [(use (match_operand 0 "" ""))]
++""
++"{ msp430_emit_cbranch (LT, operands[0]); DONE; }")
++
++(define_expand "bgeu"
++   [(use (match_operand 0 "" ""))]
++""
++"{ msp430_emit_cbranch (GEU, operands[0]); DONE; }")
++
++(define_expand "bgtu"
++   [(use (match_operand 0 "" ""))]
++""
++"{ msp430_emit_cbranch (GTU, operands[0]); DONE; }")
++
++(define_expand "bleu"
++   [(use (match_operand 0 "" ""))]
++""
++"{ msp430_emit_cbranch (LEU, operands[0]); DONE; }")
++
++(define_expand "bltu"
++   [(use (match_operand 0 "" ""))]
++""
++"{ msp430_emit_cbranch (LTU, operands[0]); DONE; }")
++
++
++(define_insn "*cbranchqi"
++  [(set (pc)
++     (if_then_else (match_operator:QI 1 "comparison_operator"
++                  [(match_operand:QI 2 "nonimmediate_operand_msp430" "rm")
++                   (match_operand:QI 3 "general_operand" "rmi")])
++      (label_ref (match_operand 0 "" ""))
++      (pc)))]
++""
++"* return msp430_cbranch(insn, operands, NULL, 0);"
++ [(set_attr "length" "9") 
++ (set_attr "cc" "cbranch")])
++
++
++
++(define_insn "*cbranchhi"
++  [(set (pc)
++     (if_then_else (match_operator:HI 1 "comparison_operator"
++                  [(match_operand:HI 2 "nonimmediate_operand_msp430" "rm")
++                   (match_operand:HI 3 "general_operand" "rmi")])
++      (label_ref (match_operand 0 "" ""))
++      (pc)))]
++""
++"* return msp430_cbranch(insn, operands, NULL, 0);"
++ [(set_attr "length" "9")
++ (set_attr "cc" "cbranch")])
++
++
++(define_insn "*cbranchsi_eqne"
++  [(set (pc)
++     (if_then_else (match_operator:SI 1 "equality_operator"
++                  [(match_operand:SI 2 "nonimmediate_operand" "rm")
++                   (match_operand:SI 3 "general_operand" "rmi")])
++      (label_ref (match_operand 0 "" ""))
++      (pc)))]
++""
++"* return msp430_cbranch(insn, operands, NULL, 0);"
++[(set_attr "length" "9")
++ (set_attr "cc" "cbranch")])
++
++
++(define_insn "*cbranchsi_others"
++  [(parallel [(set (pc)
++     (if_then_else (match_operator:SI 1 "inequality_operator"
++                  [(match_operand:SI 2 "register_operand" "r")
++                   (match_operand:SI 3 "general_operand" "rmi")])
++      (label_ref (match_operand 0 "" ""))
++      (pc)))
++  (clobber (match_dup 2))])]
++""
++"* return msp430_cbranch(insn, operands, NULL, 0);"
++[(set_attr "length" "9")
++ (set_attr "cc" "cbranch")])
++
++
++(define_insn "*cbranch_uncoded"
++  [(set (pc)
++     (if_then_else (match_operator 1 "comparison_operator"
++                  [(cc0)
++                   (const_int 0)])
++      (label_ref (match_operand 0 "" ""))
++      (pc)))]
++""
++"* return msp430_cbranch(insn, operands, NULL, 1);"
++[(set_attr "length" "9")
++(set_attr "cc" "cbranch")])
++
++
++;;========================================================================
++;; noop
++(define_insn "nop"
++  [(const_int 0)]
++  ""
++  "nop"
++  [(set_attr "cc" "none")
++   (set_attr "length" "1")])
++
++
++;;============================================================================
++;; call
++;;
++
++(define_expand "call"
++  [(call (match_operand:HI 0 "general_operand" "")
++         (match_operand:HI 1 "general_operand" ""))]
++  ""
++  "")
++
++(define_insn "*call_insn"
++  [(call (mem:HI (match_operand:HI 0 "general_operand" "r,P,mi"))
++         (match_operand:HI 1 "general_operand" "X,X,X"))]
++""
++"* return msp430_emit_call(operands);"
++[ (set_attr "length" "1,1,2")
++   (set_attr "cc" "clobber")])
++
++
++(define_expand "call_value"
++  [(set (match_operand 0 "register_operand" "")
++        (call (match_operand:HI 1 "general_operand" "")
++              (match_operand:HI 2 "general_operand" "")))]
++  ""
++  "")
++
++(define_insn "*call_value_insn"
++  [( set (match_operand 0 "register_operand" "=r,r,r")
++   (call (mem:HI (match_operand:HI 1 "general_operand" "r,P,mi"))
++       (match_operand:HI 2 "general_operand" "X,X,X")))]
++""
++ "call\\t%N1"
++[ (set_attr "length" "1,1,2")
++   (set_attr "cc" "clobber")])
++
++
++
++
++
++;;========================================================================
++;;========================================================================
++;; mult helpers
++
++(define_insn "reent_in"
++  [(set (mem:HI (post_dec (reg:HI 1))) 
++        (unspec_volatile:HI [(const_int 99999999)] 10))]
++  ""
++  "push\\tr2
++\\tdint
++\\tnop"
++  [(set_attr "length" "4")
++   (set_attr "cc" "clobber")])
++
++;;
++;; Next three help to make sure, that
++;; all instructions are 'in order'
++
++(define_insn "fetch_result_qi"
++ [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=r,m") 
++       (unspec_volatile:QI [(const_int 0)] 12))
++  (set (mem:HI (post_inc (reg:HI 1)))
++      (unspec_volatile:HI [(const_int 99999999)] 11))]
++ ""
++ "mov.b\\t&__RESLO, %0
++\\tpop\\tr2"
++ [(set_attr "length" "3,4")
++  (set_attr "cc" "none")])
++ 
++(define_insn "fetch_result_hi"
++ [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m") 
++       (unspec_volatile:HI [(const_int 0)] 13))
++  (set (mem:HI (post_inc (reg:HI 1)))
++      (unspec_volatile:HI [(const_int 99999999)] 11))]
++ ""
++ "mov\\t&__RESLO, %0
++\\tpop\\tr2"
++ [(set_attr "length" "3,4")
++  (set_attr "cc" "none")])
++
++(define_insn "fetch_result_si"
++ [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "=r,m") 
++       (unspec_volatile:SI [(const_int 0)] 14))
++  (set (mem:HI (post_inc (reg:HI 1)))
++      (unspec_volatile:HI [(const_int 99999999)] 11))]
++ ""
++ "mov\\t&__RESLO, %A0
++\\tmov\\t&__RESHI, %B0
++\\tpop\\tr2"
++ [(set_attr "length" "5,7")
++  (set_attr "cc" "none")])
++
++;; ===the same with no int
++
++(define_insn "fetch_result_qi_nint"
++ [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=r,m") 
++       (unspec_volatile:QI [(const_int 0)] 121))]
++ ""
++ "mov.b\\t&__RESLO, %0"
++ [(set_attr "length" "2,3")
++  (set_attr "cc" "none")])
++ 
++(define_insn "fetch_result_hi_nint"
++ [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m") 
++       (unspec_volatile:HI [(const_int 0)] 131))]
++ ""
++ "mov\\t&__RESLO, %0"
++ [(set_attr "length" "2,3")
++  (set_attr "cc" "none")])
++
++(define_insn "fetch_result_si_nint"
++ [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "=r,m") 
++       (unspec_volatile:SI [(const_int 0)] 141))]
++ ""
++ "mov\\t&__RESLO, %A0
++\\tmov\\t&__RESHI, %B0"
++ [(set_attr "length" "4,6")
++  (set_attr "cc" "none")])
++
++(define_insn "addc_zero"
++ [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m")
++   (unspec_volatile:HI [(const_int 0 )] 15))]
++ ""
++ "addc\\t#0, %0"
++[(set_attr "length" "1,2")
++ (set_attr "cc" "none")])
++
++(define_insn "subc_zero"
++ [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m")
++   (unspec:HI [(const_int 0 )] 16))]
++ ""
++ "subc\\t#0, %0"
++[(set_attr "length" "1,2")
++ (set_attr "cc" "none")])
++
++(define_insn "load_mpy"
++ [(unspec_volatile:HI [(const_int 0)] 17)
++  (use (match_operand:HI 0 "general_operand_msp430" "rRP,mi"))]
++""
++"mov\\t%0, &__MPY"
++[(set_attr "length" "2,3")
++ (set_attr "cc" "none")])
++
++
++(define_insn "load_mpys"
++  [(unspec_volatile:HI [(const_int 0)] 18)
++   (use (match_operand:HI 0 "general_operand_msp430" "rRP,mi"))]
++""
++"mov\\t%0, &__MPYS"
++[(set_attr "length" "2,3")
++ (set_attr "cc" "none")])
++ 
++ 
++(define_insn "load_op2"
++  [(unspec_volatile:HI [(const_int 0)] 19)
++   (use (match_operand:HI 0 "general_operand_msp430" "rRP,mi"))]
++""
++"mov\\t%0, &__OP2"
++[(set_attr "length" "2,3")
++ (set_attr "cc" "none")])
++ 
++
++(define_insn "load_mpyq"
++  [(unspec_volatile:QI [(const_int 0 )] 20)
++   (use (match_operand:QI 0 "general_operand_msp430" "rRP,mi"))]
++""
++"mov.b\\t%0, &__MPY"
++[(set_attr "length" "2,3")
++ (set_attr "cc" "none")])
++
++
++(define_insn "load_mpysq"
++  [(unspec_volatile:QI [(const_int 0 )] 21)
++   (use (match_operand:QI 0 "general_operand_msp430" "rRP,mi"))]
++""
++"mov.b\\t%0, &__MPYS"
++[(set_attr "length" "2,3")
++ (set_attr "cc" "none")])
++ 
++(define_insn "load_op2q"
++  [(unspec_volatile:QI [(const_int 0 )] 22)
++  (use (match_operand:QI 0 "general_operand_msp430" "rRP,mi"))]
++""
++"mov.b\\t%0, &__OP2"
++[(set_attr "length" "2,3")
++ (set_attr "cc" "none")])
++
++
++
++
++ 
++
++;;========================================================================
++;;========================================================================
++;;========================================================================
++;;
++;;  Multiplication 
++
++;;========================================================================
++;; 8 = 8x8 and 16 = 8x8
++
++(define_expand "mulqi3"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
++        (mult:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "")
++                 (match_operand:QI 2 "general_operand_msp430" "")))]  
++  ""             
++"{ msp430_mul3_guard(operands,0); DONE; }")
++
++(define_insn "*mulqi3_call"
++  [(set (reg:QI 14) (mult:QI (reg:QI 10) (reg:QI 12)))
++      (clobber (reg:QI 10))
++      (clobber (reg:QI 12))]
++  "!MSP430_HAS_HWMUL_INTERNAL"
++  "call       #__mulqi3"
++  [(set_attr "length" "2")
++   (set_attr "cc" "clobber")])
++
++;; ============= qi -> hi =======================================================
++(define_expand "mulqihi3"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
++        (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand_msp430" ""))
++                 (sign_extend:HI (match_operand:QI 2 "general_operand_msp430" ""))))]
++""
++"{ msp430_mul3_guard(operands,1); DONE; }")
++
++(define_insn "*mulqihi3_call"
++  [(set (reg:HI 14) (mult:HI (sign_extend:HI (reg:QI 10))
++                           (sign_extend:HI (reg:QI 12))))
++        (clobber (reg:QI 10))
++        (clobber (reg:QI 12))]
++  "!MSP430_HAS_HWMUL_INTERNAL"
++  "call       #__mulqihi3"   
++  [(set_attr "length" "2")
++   (set_attr "cc" "clobber")])
++
++;; ============ unsigned ones ===================================================
++(define_expand "umulqihi3"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
++        (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand_msp430" ""))
++                 (zero_extend:HI (match_operand:QI 2 "general_operand_msp430" ""))))]
++  ""
++  "{ msp430_umul3_guard(operands,0); DONE; }")  
++
++(define_insn "*umulqihi3_call"
++  [(set (reg:HI 14) (mult:HI (zero_extend:HI (reg:QI 10))
++                           (zero_extend:HI (reg:QI 12))))
++        (clobber (reg:QI 10))
++        (clobber (reg:QI 12))]
++  "!MSP430_HAS_HWMUL_INTERNAL"
++  "call       #__umulqihi3" 
++  [(set_attr "length" "2")
++   (set_attr "cc" "clobber")])
++
++;;========================================================================
++;; 16 = 16x16 and 32 = 16x16
++
++(define_expand "mulhi3"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
++        (mult:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "")
++                 (match_operand:HI 2 "general_operand_msp430" "")))]  
++  ""
++"{msp430_mul3_guard(operands,0); DONE; } ")
++
++(define_insn "*mulhi3_call"
++  [(set (reg:HI 14) (mult:HI (reg:HI 10) (reg:HI 12)))
++      (clobber (reg:HI 10))
++      (clobber (reg:HI 12))]
++  "!MSP430_HAS_HWMUL_INTERNAL"
++  "call       #__mulhi3"
++  [(set_attr "length" "2")
++   (set_attr "cc" "clobber")])
++
++;; ========================== hi -> si =============================
++(define_expand "mulhisi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "")
++        (mult:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand_msp430" ""))
++                 (sign_extend:SI (match_operand:HI 2 "general_operand_msp430" ""))))]
++""
++  "{msp430_mulhisi_guard(operands); DONE;}"
++)
++
++(define_insn "*mulhisi3_call"
++  [(set (reg:SI 14) (mult:SI (sign_extend:SI (reg:HI 10))
++                           (sign_extend:SI (reg:HI 12))))
++        (clobber (reg:HI 10))
++        (clobber (reg:HI 11))
++      (clobber (reg:HI 12))  
++      (clobber (reg:HI 13))]
++  "!MSP430_HAS_HWMUL_INTERNAL"
++  "mov        #0, r11
++      tst     r10
++      jge     +2
++      mov     #-1, r11
++      mov     #0, r13
++      tst     r12
++      jge     +2
++      mov     #-1, r13
++      call    #__mulhisi3"
++  [(set_attr "length" "10")
++   (set_attr "cc" "clobber")])
++
++;; ================== unsigned  hi -> si =============================
++(define_expand "umulhisi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "")
++        (mult:SI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand_msp430" ""))
++                 (zero_extend:SI (match_operand:HI 2 "general_operand_msp430" ""))))]
++  ""
++  "{msp430_umulhisi_guard(operands); DONE;}")
++
++(define_insn "*umulhisi3_call"
++  [(set (reg:SI 14) (mult:SI (zero_extend:SI (reg:HI 10))
++                           (zero_extend:SI (reg:HI 12))))
++        (clobber (reg:HI 10))
++        (clobber (reg:HI 11))
++      (clobber (reg:HI 12))  
++      (clobber (reg:HI 13))]
++  "!MSP430_HAS_HWMUL_INTERNAL"
++  "clr        r11
++      clr     r13
++      call    #__umulhisi3" 
++  [(set_attr "length" "2")
++   (set_attr "cc" "clobber")])
++
++
++;;========================================================================
++;; 32 = 32x32.      64 = 32x32 <- via library calls only
++
++(define_expand "mulsi3"
++  [(set (reg:SI 10) (match_operand:SI 1 "nonimmediate_operand_msp430" ""))
++   (set (reg:SI 12) (match_operand:SI 2 "general_operand_msp430" ""))
++   (set (reg:SI 14) (mult:SI (reg:SI 10) (reg:SI 12)))
++   (set (match_operand:SI 0 "nonimmediate_operand_msp430" "") (reg:SI 14))]
++""
++"{
++  if (!MSP430_HAS_HWMUL_INTERNAL)
++    {
++      emit_insn (gen_mulsi3_call (operands[0], operands[1], operands[2]));
++      DONE;
++    }
++}")
++
++(define_insn "*mulsi3hw_call_ni"
++  [(set (reg:SI 14) (mult:SI (reg:SI 10) (reg:SI 12)))]
++  "(!TARGET_INLINESIHWMUL) && MSP430_NOINT_HWMUL"
++  "call       #__umulsi3hw"
++[(set_attr "length" "2")
++   (set_attr "cc" "clobber")])
++
++(define_insn "*mulsi3hw_call_ie"
++  [(set (reg:SI 14) (mult:SI (reg:SI 10) (reg:SI 12)))]
++  "(!TARGET_INLINESIHWMUL) && !MSP430_NOINT_HWMUL"
++  "push       r2
++      dint
++      call    #__umulsi3hw
++      pop     r2"
++[(set_attr "length" "5")
++   (set_attr "cc" "clobber")])
++
++(define_insn "*mulsi3hw_inline_ni"
++  [(set (reg:SI 14) (mult:SI (reg:SI 10) (reg:SI 12)))]
++  "TARGET_INLINESIHWMUL && MSP430_HAS_HWMUL_INTERNAL && MSP430_NOINT_HWMUL"
++  "mov        r12, &__MPY
++      mov     r10, &__OP2
++      mov     r12, &__MAC
++      mov     &__RESLO, r14
++      mov     &__RESHI, &__RESLO
++      mov     r11, &__OP2
++      mov     r13, &__MAC
++      mov     r10, &__OP2
++      mov     &__RESLO, r15"
++[(set_attr "length" "19")  
++   (set_attr "cc" "none")])
++
++(define_insn "*mulsi3hw_inline_ie"
++  [(set (reg:SI 14) (mult:SI (reg:SI 10) (reg:SI 12)))]
++  "TARGET_INLINESIHWMUL && MSP430_HAS_HWMUL_INTERNAL && !MSP430_NOINT_HWMUL"
++  "push       r2
++      dint
++      nop
++      mov     r12, &__MPY
++      mov     r10, &__OP2
++      mov     r12, &__MAC
++      mov     &__RESLO, r14
++      mov     &__RESHI, &__RESLO
++      mov     r11, &__OP2
++      mov     r13, &__MAC
++      mov     r10, &__OP2
++      mov     &__RESLO, r15
++      pop     r2"
++[(set_attr "length" "23")  
++   (set_attr "cc" "none")])
++
++(define_expand "mulsi3_call"
++  [(set (reg:SI 10) (match_operand:SI 1 "register_operand" ""))
++   (set (reg:SI 12) (match_operand:SI 2 "register_operand" "")) 
++   (parallel [(set (reg:SI 14) (mult:SI (reg:SI 10) (reg:SI 12)))
++        (clobber (reg:SI 10))
++        (clobber (reg:SI 12))])
++   (set (match_operand:SI 0 "register_operand" "") (reg:SI 14))]
++"!MSP430_HAS_HWMUL_INTERNAL"
++"")
++
++(define_insn "*mulsi3_call"
++  [(set (reg:SI 14) (mult:SI (reg:SI 10) (reg:SI 12)))
++      (clobber (reg:SI 10))
++      (clobber (reg:SI 12))]
++  "!MSP430_HAS_HWMUL_INTERNAL"
++  "call       #__mulsi3"
++  [(set_attr "length" "2")
++   (set_attr "cc" "clobber")])
++
++
++;; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % /
++;; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % /
++;; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % /
++;; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % /
++
++(define_expand "divmodqi4"
++  [(set (reg:QI 12) (match_operand:QI 1 "register_operand" ""))
++   (set (reg:QI 10) (match_operand:QI 2 "register_operand" ""))
++   (parallel [(set (reg:QI 12) (div:QI (reg:QI 12) (reg:QI 10)))
++              (set (reg:QI 14) (mod:QI (reg:QI 12) (reg:QI 10)))
++              (clobber (reg:QI 10))
++              (clobber (reg:QI 11))
++            (clobber (reg:QI 13))])
++   (set (match_operand:QI 0 "register_operand" "") (reg:QI 12))
++   (set (match_operand:QI 3 "register_operand" "") (reg:QI 14))]
++  ""
++  "")
++
++(define_insn "*divmodqi4_call"
++  [(set (reg:QI 12) (div:QI (reg:QI 12) (reg:QI 10)))
++   (set (reg:QI 14) (mod:QI (reg:QI 12) (reg:QI 10)))
++   (clobber (reg:QI 10))
++   (clobber (reg:QI 11))
++   (clobber (reg:QI 13))]
++  ""
++  "call       #__divmodqi4"
++   [(set_attr "length" "2")
++   (set_attr "cc" "clobber")])
++
++(define_expand "udivmodqi4"
++  [(set (reg:QI 12) (match_operand:QI 1 "register_operand" ""))
++   (set (reg:QI 10) (match_operand:QI 2 "register_operand" ""))
++   (parallel [(set (reg:QI 12) (udiv:QI (reg:QI 12) (reg:QI 10)))
++              (set (reg:QI 14) (umod:QI (reg:QI 12) (reg:QI 10)))
++              (clobber (reg:QI 10))
++              (clobber (reg:QI 11)) 
++              (clobber (reg:QI 13))])
++   (set (match_operand:QI 0 "register_operand" "") (reg:QI 12))
++   (set (match_operand:QI 3 "register_operand" "") (reg:QI 14))]
++  ""
++  "")
++
++(define_insn "*udivmodqi4_call"
++  [(set (reg:QI 12) (udiv:QI (reg:QI 12) (reg:QI 10)))
++   (set (reg:QI 14) (umod:QI (reg:QI 12) (reg:QI 10)))
++   (clobber (reg:QI 10))
++   (clobber (reg:QI 11)) 
++   (clobber (reg:QI 13))]
++  ""
++  "call       #__udivmodqi4"
++   [(set_attr "length" "2")
++   (set_attr "cc" "clobber")])
++
++
++(define_expand "divmodhi4"
++  [(set (reg:HI 12) (match_operand:HI 1 "register_operand" ""))
++   (set (reg:HI 10) (match_operand:HI 2 "register_operand" ""))
++   (parallel [(set (reg:HI 12) (div:HI (reg:HI 12) (reg:HI 10)))
++              (set (reg:HI 14) (mod:HI (reg:HI 12) (reg:HI 10)))
++              (clobber (reg:HI 10))
++              (clobber (reg:HI 11))
++            (clobber (reg:HI 13))])
++   (set (match_operand:HI 0 "register_operand" "") (reg:HI 12))
++   (set (match_operand:HI 3 "register_operand" "") (reg:HI 14))]
++  ""
++  "")
++
++(define_insn "*divmodhi4_call"
++  [(set (reg:HI 12) (div:HI (reg:HI 12) (reg:HI 10)))
++   (set (reg:HI 14) (mod:HI (reg:HI 12) (reg:HI 10)))
++   (clobber (reg:HI 10))
++   (clobber (reg:HI 11))
++   (clobber (reg:HI 13))]
++  ""
++  "call       #__divmodhi4"
++   [(set_attr "length" "2")
++   (set_attr "cc" "clobber")])
++
++(define_expand "udivmodhi4"
++  [(set (reg:HI 12) (match_operand:HI 1 "register_operand" ""))
++   (set (reg:HI 10) (match_operand:HI 2 "register_operand" ""))
++   (parallel [(set (reg:HI 12) (udiv:HI (reg:HI 12) (reg:HI 10)))
++              (set (reg:HI 14) (umod:HI (reg:HI 12) (reg:HI 10)))
++              (clobber (reg:HI 10))
++              (clobber (reg:HI 11)) 
++              (clobber (reg:HI 13))])
++   (set (match_operand:HI 0 "register_operand" "") (reg:HI 12))
++   (set (match_operand:HI 3 "register_operand" "") (reg:HI 14))]
++  ""
++  "")
++
++(define_insn "*udivmodhi4_call"
++  [(set (reg:HI 12) (udiv:HI (reg:HI 12) (reg:HI 10)))
++   (set (reg:HI 14) (umod:HI (reg:HI 12) (reg:HI 10)))
++   (clobber (reg:HI 10))
++   (clobber (reg:HI 11)) 
++   (clobber (reg:HI 13))]
++  ""
++  "call       #__udivmodhi4"
++   [(set_attr "length" "2")
++   (set_attr "cc" "clobber")])
++
++
++;; ///////////////// SINGLE INTEGER %%%%%%%%%%%%%%%%%
++
++(define_expand "divmodsi4"
++  [(set (reg:SI 12) (match_operand:SI 1 "register_operand" ""))
++   (set (reg:SI 10) (match_operand:SI 2 "register_operand" ""))
++   (parallel [(set (reg:SI 12) (div:SI (reg:SI 12) (reg:SI 10)))
++              (set (reg:SI 14) (mod:SI (reg:SI 12) (reg:SI 10)))
++              (clobber (reg:SI 10))
++              (clobber (reg:HI 9))
++            (clobber (reg:HI 8))])
++   (set (match_operand:SI 0 "register_operand" "") (reg:SI 12))
++   (set (match_operand:SI 3 "register_operand" "") (reg:SI 14))]
++  ""
++  "")
++
++(define_insn "*divmodsi4_call"
++  [(set (reg:SI 12) (div:SI (reg:SI 12) (reg:SI 10)))
++   (set (reg:SI 14) (mod:SI (reg:SI 12) (reg:SI 10)))
++   (clobber (reg:SI 10))
++   (clobber (reg:HI 9))
++   (clobber (reg:HI 8))]
++  ""
++  "call       #__divmodsi4"
++   [(set_attr "length" "2")
++   (set_attr "cc" "clobber")])
++
++(define_expand "udivmodsi4"
++  [(set (reg:SI 12) (match_operand:SI 1 "register_operand" ""))
++   (set (reg:SI 10) (match_operand:SI 2 "register_operand" ""))
++   (parallel [(set (reg:SI 12) (udiv:SI (reg:SI 12) (reg:SI 10)))
++              (set (reg:SI 14) (umod:SI (reg:SI 12) (reg:SI 10)))
++              (clobber (reg:SI 10))
++              (clobber (reg:HI 9)) 
++              (clobber (reg:HI 8))])
++   (set (match_operand:SI 0 "register_operand" "") (reg:SI 12))
++   (set (match_operand:SI 3 "register_operand" "") (reg:SI 14))]
++  ""
++  "")
++
++(define_insn "*udivmodsi4_call"
++  [(set (reg:SI 12) (udiv:SI (reg:SI 12) (reg:SI 10)))
++   (set (reg:SI 14) (umod:SI (reg:SI 12) (reg:SI 10)))
++   (clobber (reg:SI 10))
++   (clobber (reg:HI 9)) 
++   (clobber (reg:HI 8))]
++  ""
++  "call       #__udivmodsi4"
++   [(set_attr "length" "2")
++   (set_attr "cc" "clobber")])
++
++
++
++
++;;========================================================================
++;; MOV STRING
++;;   structures and stuff are word aligned.
++;;   so, QI mode only defined (as HI actually)
++;;
++
++(define_expand "movstrhi"
++  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
++                   (match_operand:BLK 1 "memory_operand" ""))
++              (use (match_operand 2 "const_int_operand" ""))
++              (use (match_operand 3 "const_int_operand" ""))
++              (clobber (match_dup 4))
++              (clobber (match_dup 5))
++              (clobber (match_dup 6))])]
++  ""
++  " 
++{   
++  rtx addr0, addr1;
++  rtx a0, a1;
++  
++  if (GET_CODE (operands[2]) != CONST_INT) FAIL;
++
++  addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
++  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
++  
++  a0 = operands[0];
++  a1 = operands[1];
++  
++  operands[5] = addr0;
++  operands[6] = addr1;
++
++  operands[0] = gen_rtx_MEM (BLKmode, addr0);
++  operands[1] = gen_rtx_MEM (BLKmode, addr1);
++
++  if(INTVAL (operands[2]) <= 10 && !(INTVAL(operands[3])&1))
++  {
++    int x = INTVAL (operands[2]);
++    int y = (x&~1) >> 1;
++    int i = 0;
++     
++    while(y--)
++    {
++      rtx dest = gen_rtx_MEM (HImode, gen_rtx_PLUS(HImode, addr0,GEN_INT(i)));
++      emit_insn(gen_movstrhi5(dest,addr1));
++      i+= 2;
++    }
++
++    if(x & 1)
++    {
++      rtx real_dst = gen_rtx_MEM (HImode, gen_rtx_PLUS(HImode, addr0,GEN_INT(x-1)));
++      emit_insn(gen_movstrqi5(real_dst,addr1));
++    }
++    DONE;
++  }
++  else if(INTVAL (operands[2]) <= 6 && (INTVAL(operands[3])&1))
++  {
++    int x = INTVAL (operands[2]);
++    int i = 0;
++    
++    while(x--)
++    {
++      rtx dst = gen_rtx_MEM (HImode, gen_rtx_PLUS(HImode, addr0,GEN_INT(i)));
++      emit_insn(gen_movstrqi5(dst,addr1));
++      i++;
++    }
++    DONE;
++  }
++  else
++  {
++      operands[2] = copy_to_mode_reg (HImode, operands[2]);
++      operands[4] = operands[2];
++  }
++}
++")
++
++(define_insn "movstrqi5"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=m")
++      (mem:HI (match_operand:HI 1 "register_operand" "+r")))
++      (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
++  ""
++  "mov.b      @%1+, %0"
++[(set_attr "length" "2")
++ (set_attr "cc" "clobber")])
++
++(define_insn "movstrhi5"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=m")
++      (mem:HI (match_operand:HI 1 "register_operand" "+r")))
++      (set (match_dup 1) (plus:HI (match_dup 1) (const_int 2)))]
++ ""
++ "mov @%1+, %0"
++ [(set_attr "length" "2")
++ (set_attr "cc" "clobber")])
++
++(define_insn "*movstrhi_insn"
++  [(set (mem:BLK (match_operand:HI 0 "register_operand" "r"))
++        (mem:BLK (match_operand:HI 1 "register_operand" "r")))
++   (use (match_operand:HI 2 "register_operand" "r"))
++   (use (match_operand 3 "const_int_operand" "i"))
++   (clobber (match_dup 2))
++   (clobber (match_dup 0))
++   (clobber (match_dup 1))]
++  ""
++  "* return movstrhi_insn(insn, operands, NULL);"
++  [(set_attr "length" "6")
++   (set_attr "cc" "clobber")])
++
++
++(define_insn "*movstrqi_insn"
++  [(set (mem:BLK (match_operand:HI 0 "register_operand" "r"))
++        (mem:BLK (match_operand:HI 1 "register_operand" "r")))
++   (use (match_operand:QI 2 "register_operand" "r"))
++   (use (match_operand 3 "const_int_operand" "i"))
++   (clobber (match_dup 2))
++   (clobber (match_dup 0))
++   (clobber (match_dup 1))]
++  ""
++  "* return movstrhi_insn(insn, operands, NULL);"
++  [(set_attr "length" "6")
++   (set_attr "cc" "clobber")])
++
++
++
++;;========================================================================
++;; CLEAR STRING
++
++(define_expand "clrstrhi"
++  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
++                   (const_int 0))
++              (use (match_operand 1 "const_int_operand" ""))
++              (use (match_operand 2 "const_int_operand" "i"))
++              (clobber (match_dup 3))
++              (clobber (match_dup 4))])]
++  ""
++  " 
++{
++  rtx addr0;
++
++  if (GET_CODE (operands[1]) != CONST_INT) FAIL;
++  operands[1] = copy_to_mode_reg (HImode, operands[1]);
++  operands[3] = operands[1];
++  addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
++  operands[4] = addr0;
++  operands[0] = gen_rtx_MEM (BLKmode, addr0);
++}")
++
++
++(define_insn "*clrstrhi_insn"
++  [(set (mem:BLK (match_operand:HI 0 "register_operand" "r"))
++        (const_int 0))
++   (use (match_operand:HI 1 "register_operand" "r")) 
++   (use (match_operand 2 "const_int_operand" "i"))
++   (clobber (match_dup 1)) 
++   (clobber (match_dup 0))]
++  ""
++  "* return clrstrhi_insn(insn, operands, NULL);"
++[(set_attr "length" "6")
++   (set_attr "cc" "clobber")])
++
++
++;;========================================================================
++;; %0 = strchr(%1,%2) - %1
++
++(define_expand "strlenhi"
++  [(set (match_dup 4)
++            (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
++                        (match_operand 2 "const_int_operand" "")
++                        (match_operand:HI 3 "immediate_operand" "")] 3))
++     (set (match_operand:HI 0 "register_operand" "")
++          (minus:HI (match_dup 4)
++                    (match_dup 5)))]
++
++   ""
++   "
++{
++  rtx addr;
++
++  if (! (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
++      FAIL;
++  addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
++  operands[1] = gen_rtx_MEM (BLKmode, addr); 
++  operands[5] = addr;
++  operands[4] = gen_reg_rtx (HImode);
++
++}")
++
++
++(define_insn "*strlenhi"
++ [(set (match_operand:HI 0 "register_operand" "=r")
++        (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
++                    (const_int 0)
++                  (match_operand:HI 2 "immediate_operand" "i") ] 3))]
++  ""
++"dec  %0
++.L__strlenhi__%=:
++      inc     %0
++      tst.b   0(%0)
++        jne   .L__strlenhi__%="
++[(set_attr "length" "5")
++   (set_attr "cc" "clobber")])
++
++
++;;========================================================================
++;; MOV code
++;;
++;;
++
++
++;;========================================================================
++;; move byte
++;; nothing much special
++;; all addressing modes allowed
++;; fits perfectly into a single instruction 
++
++(define_expand "movqi" 
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
++        (match_operand:QI 1 "general_operand" ""))]
++  ""
++  "")
++
++(define_insn "*movqi3"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=m,m,m,m,r,r,r,r")
++      (match_operand:QI 1 "general_operand_msp430"    " m,r,P,i,m,r,P,i"))]
++  ""
++  "mov.b\\t%1, %0"
++  [(set_attr "length" "3,2,3,3,2,1,2,2")
++   (set_attr "cc" "none,none,none,none,none,none,none,none")])
++
++
++(define_insn "movqipi"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=r,m")
++      (mem:QI (post_inc:QI (match_operand:HI 1 "register_operand" "r,r"))))]
++  ""
++  "mov.b      @%1+, %0"
++[(set_attr "length" "1,2")
++   (set_attr "cc" "none,none")])
++
++
++
++;;============================================================================
++;; move word (16 bit)
++;; the same as above
++
++(define_expand "movhi" 
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
++        (match_operand:HI 1 "general_operand_msp430" ""))]
++  ""
++  "msp430_expand_mov_intptr (operands[0], operands[1]); DONE;")
++
++(define_insn "*movhi3"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"     "=m,m,m,m,r,r,r,r")
++      (match_operand:HI 1 "general_operand_msp430"            " r,m,P,i,r,m,P,i"))]
++  ""
++  "mov\\t%1, %0 "
++  [(set_attr "length" "2,3,3,3,1,2,2,2")
++   (set_attr "cc" "none")])
++
++(define_insn "movhipi"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m")
++      (mem:HI (post_inc:HI (match_operand:HI 1 "register_operand" "r,r"))))]
++  ""
++  "mov        @%1+, %0"
++[(set_attr "length" "1,2")
++   (set_attr "cc" "none,none")])
++
++;;============================================================================
++;; move long (32 bit)
++;; the same as above
++
++(define_expand "movsi" 
++  [(set (match_operand:SI 0 "nonimmediate_operand" "")
++        (match_operand:SI 1 "general_operand" ""))]
++  ""
++  "")
++
++(define_insn "*movsi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand"    "=rm")
++      (match_operand:SI 1 "general_operand"           " rmi"))]
++""
++"* return msp430_movesi_code(insn,operands,NULL);"
++  [(set_attr "length" "6")
++   (set_attr "cc" "none")])
++
++(define_insn "movsipi"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "=r,m")
++      (mem:SI (post_inc (match_operand:HI 1 "register_operand" "r,r"))))]
++  ""
++  "mov        @%1+, %A0
++      mov     @%1+, %B0"
++[(set_attr "length" "2,4")
++   (set_attr "cc" "none,none")])
++
++
++
++;;============================================================================
++;; floats are the SI
++
++(define_expand "movsf" 
++  [(set (match_operand:SF 0 "nonimmediate_operand" "")
++        (match_operand:SF 1 "general_operand" ""))]
++  ""
++  "")
++
++(define_insn "*movsf3"
++  [(set (match_operand:SF 0 "nonimmediate_operand"    "=rm")
++      (match_operand:SF 1 "general_operand"           "rmi"))]
++""
++"* return msp430_movesi_code(insn,operands,NULL);"
++  [(set_attr "length" "6")
++   (set_attr "cc" "none")])
++
++
++(define_insn "movsfpi"
++  [(set (match_operand:SF 0 "nonimmediate_operand_msp430" "=r,m")
++      (mem:SF (post_inc (match_operand:HI 1 "register_operand" "r,r"))))]
++  ""
++  "mov        @%1+, %A0
++      mov     @%1+, %B0"
++[(set_attr "length" "2,4")
++   (set_attr "cc" "none,none")])
++
++;;============================================================================
++;; move long long (64 bit)
++;; the same as above
++(define_expand "movdi" 
++  [(set (match_operand:DI 0 "nonimmediate_operand" "")
++        (match_operand:DI 1 "general_operand" ""))]
++  ""
++  "")
++
++(define_insn "*movdi3"
++  [(set (match_operand:DI 0 "nonimmediate_operand"    "=rm")
++      (match_operand:DI 1 "general_operand"           "rmi"))]
++""
++"* return msp430_movedi_code(insn,operands,NULL);"
++  [(set_attr "length" "12")
++   (set_attr "cc" "none")])
++
++
++(define_insn "movdipi"
++  [(set (match_operand:DI 0 "nonimmediate_operand_msp430" "=r,m")
++      (mem:DI (post_inc (match_operand:HI 1 "register_operand" "r,r"))))]
++  ""
++  "mov        @%1+, %A0
++      mov     @%1+, %B0
++      mov     @%1+, %C0
++      mov     @%1+, %D0"
++[(set_attr "length" "4,8")
++   (set_attr "cc" "none,none")])
++
++
++;;============================================================================
++;;  ARITHMETIC CODE
++;;
++
++
++;;  random operations:
++
++(define_insn "*opqi3_pi"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"          "=r,m")
++      (match_operator:QI 3 "three_operands_msp430"
++       [(match_operand:QI 1 "nonimmediate_operand_msp430" "%0,0")
++       (mem:QI (post_inc (match_operand:HI 2 "register_operand" "r,r")))]))]
++""
++"%3.b @%2+, %0"
++  [(set_attr "length" "1,2")
++   (set_attr "cc" "oper,oper")])
++
++(define_insn "*ophi3_pi"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"          "=r,m")
++      (match_operator:HI 3 "three_operands_msp430"
++       [(match_operand:HI 1 "nonimmediate_operand_msp430" "%0,0")
++        (mem:HI (post_inc (match_operand:HI 2 "register_operand" "r,r")))]))]
++""
++"%3   @%2+, %0"
++  [(set_attr "length" "1,2")
++   (set_attr "cc" "oper,oper")])
++
++(define_insn "*opsi3_pi"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"          "=r,m")
++      (match_operator:SI 3 "three_operands_msp430"
++       [(match_operand:SI 1 "nonimmediate_operand_msp430" "%0,0")
++        (mem:SI (post_inc (match_operand:HI 2 "register_operand" "r,r")))]))]
++""
++"%A3\\t@%2+, %A0
++\\t%B3\\t@%2+, %B0"
++  [(set_attr "length" "1,2")
++   (set_attr "cc" "oper,oper")])
++
++(define_insn "*opdi3_pi"
++  [(set (match_operand:DI 0 "nonimmediate_operand_msp430"          "=r,m")
++      (match_operator:DI 3 "three_operands_msp430"
++       [(match_operand:DI 1 "nonimmediate_operand_msp430" "%0,0")
++        (mem:DI (post_inc (match_operand:HI 2 "register_operand" "r,r")))]))]
++""
++"%A3\\t@%2+, %A0
++\\t%B3\\t@%2+, %B0
++\\t%C3\\t@%2+, %C0
++\\t%D3\\t@%2+, %D0"
++  [(set_attr "length" "1,2")
++   (set_attr "cc" "oper,oper")])
++
++
++
++
++;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++;; add 1 byte 
++
++
++(define_expand "addqi3" 
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
++        (plus:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "")   
++                 (match_operand:QI 2 "general_operand_msp430" "")))]
++  "" 
++  "")
++
++(define_insn "*addqi3_cg"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=m,r")
++        (plus:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "%0,0")
++               (match_operand 2 "const_int_operand"      "i,i")))]
++"(INTVAL(operands[2]) == -2
++  || INTVAL(operands[2]) == -4
++  || INTVAL(operands[2]) == -8 )"
++"* {
++      operands[2] = gen_rtx_CONST_INT(QImode, -INTVAL(operands[2]));
++      return \"sub.b\\t%2, %0\";
++}"
++[(set_attr "length" "2,1")
++ (set_attr "cc" "set_czn,set_czn")])
++
++
++(define_insn "*addqi3_3"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"          "=m,m,m,m,r,r,r,r")  
++        (plus:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "%0,0,0,0,0,0,0,0")  
++                 (match_operand:QI 2 "general_operand_msp430"      " m,r,P,i,m,r,P,i")))]  
++""
++  "add.b      %2, %0"
++  [(set_attr "length" "3,2,2,3,2,1,1,2")
++   (set_attr "cc" "set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
++
++
++;;============================================================================
++;; add 1 word (16 bits)
++;; same as above
++
++
++(define_expand "addhi3" 
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
++        (plus:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "")
++                 (match_operand:HI 2 "general_operand_msp430" "")))]
++  ""
++  "")
++
++(define_insn "*addhi3_cg"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=m,r")
++      (plus:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "%0,0")
++               (match_operand 2 "const_int_operand"      "i,i")))]
++"(INTVAL(operands[2]) == -2
++  || INTVAL(operands[2]) == -4
++  || INTVAL(operands[2]) == -8 )"
++"* {
++      operands[2] = gen_rtx_CONST_INT(HImode, -INTVAL(operands[2]));
++      return \"sub\\t%2, %0\" ;
++}"
++[(set_attr "length" "2,1")
++ (set_attr "cc" "set_czn,set_czn")])
++
++(define_insn "*addhi3_3"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"          "=m,m,m,m,r,r,r,r")
++        (plus:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "%0,0,0,0,0,0,0,0")
++                 (match_operand:HI 2 "general_operand_msp430"      " m,r,P,i,m,r,P,i")))]
++""
++  "add        %2, %0"
++  [(set_attr "length" "3,2,2,3,2,1,1,2")
++   (set_attr "cc"
++"set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
++
++
++;;============================================================================
++;; add 2 words (32 bits)
++;; same as above
++
++(define_expand "addsi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "")
++        (plus:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "")
++                 (match_operand:SI 2 "general_operand_msp430" "")))]
++  ""
++  "")
++
++(define_insn "*addsi3_cg"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "=m,r")
++      (plus:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "%0,0")
++               (match_operand 2 "const_int_operand"      "i,i")))]
++"(INTVAL(operands[2]) == -2
++  || INTVAL(operands[2]) == -4
++  || INTVAL(operands[2]) == -8 )"
++"* {
++     operands[2] = gen_rtx_CONST_INT(SImode, -INTVAL(operands[2]));
++     return \"sub\\t%A2, %A0\\n\\tsubc\\t%B2, %B0\" ;
++}"
++[(set_attr "length" "4,2")
++ (set_attr "cc" "further,further")])
++
++
++(define_insn "*addsi3_3"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"      "=rm")
++        (plus:SI (match_operand:SI 1 "general_operand_msp430"  "%0")
++                 (match_operand:SI 2 "general_operand_msp430"  " rmi")))]
++""
++"* return msp430_addsi_code(insn, operands, NULL);"
++  [(set_attr "length" "6")
++   (set_attr "cc" "further")])
++
++
++;;============================================================================
++;; add 4 words (64 bits)
++;; same as above
++
++(define_expand "adddi3"
++  [(set (match_operand:DI 0 "nonimmediate_operand" "")
++        (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")   
++                 (match_operand:DI 2 "general_operand" "")))]
++  "" 
++  "")
++
++(define_insn "*adddi3_cg"
++   [(set (match_operand:DI 0 "nonimmediate_operand_msp430" "=m,r")
++                (plus:DI (match_operand:DI 1 "nonimmediate_operand_msp430" "%0,0")
++                (match_operand:DI 2 "const_int_operand"      "i,i")))]
++"(INTVAL(operands[2]) == -2
++  || INTVAL(operands[2]) == -4
++  || INTVAL(operands[2]) == -8 )"
++"* {
++     operands[2] = gen_rtx_CONST_INT(DImode, -INTVAL(operands[2]));
++     return \"sub\\t%A2, %A0\\n\\tsubc\\t%B2, %B0\\n\\tsubc\\t%C2, %C0\\n\\tsubc\\t%D2, %D0\";
++}"
++[(set_attr "length" "4,2")
++(set_attr "cc" "further,further")])
++
++(define_insn "*adddi3_3"
++  [(set (match_operand:DI 0 "nonimmediate_operand"            "=rm")
++        (plus:DI (match_operand:DI 1 "nonimmediate_operand"   "%0")
++                 (match_operand:DI 2 "general_operand"        " rmi")))]
++""
++"* return msp430_adddi_code(insn, operands, NULL);"
++  [(set_attr "length" "12")
++   (set_attr "cc" "further")])
++
++
++;;-----------------------------------------------------------------------
++;;-----------------------------------------------------------------------
++;;-----------------------------------------------------------------------
++;;-----------------------------------------------------------------------
++;;-----------------------------------------------------------------------
++;; sub 1 byte 
++
++
++(define_expand "subqi3" 
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
++        (minus:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "")   
++                  (match_operand:QI 2 "general_operand_msp430" "")))]
++  "" 
++  "")
++
++(define_insn "*subqi3_3"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"          "=m,m,m,m,r,r,r,r")  
++        (minus:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "0,0,0,0,0,0,0,0")  
++                 (match_operand:QI 2 "general_operand_msp430"      " m,r,P,i,m,r,P,i")))]  
++""
++  "sub.b      %2, %0"
++  [(set_attr "length" "3,2,2,3,2,1,1,2")
++   (set_attr "cc" "set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
++
++
++;;============================================================================
++;; sub 1 word (16 bits)
++;; same as above
++
++
++(define_expand "subhi3" 
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
++        (minus:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "")
++                  (match_operand:HI 2 "general_operand_msp430" "")))]
++  ""
++  "")
++
++(define_insn "*subhi3_3"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"          "=m,m,m,m,r,r,r,r")
++        (minus:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0,0,0,0,0,0,0,0")
++                  (match_operand:HI 2 "general_operand_msp430"      "m,r,P,i,m,r,P,i")))]
++""
++  "sub        %2, %0"
++  [(set_attr "length" "3,2,2,3,2,1,1,2")
++   (set_attr "cc"
++"set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
++
++
++;;============================================================================
++;; sub 2 words (32 bits)
++;; same as above
++
++(define_expand "subsi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand" "")
++        (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
++                 (match_operand:SI 2 "general_operand" "")))]
++  "" 
++  "")
++
++
++(define_insn "*subsi3_3"
++  [(set (match_operand:SI 0 "nonimmediate_operand"      "=rm")
++        (minus:SI (match_operand:SI 1 "general_operand"  "0")
++                 (match_operand:SI 2 "general_operand"  " rmi")))]
++""
++"* return msp430_subsi_code(insn, operands, NULL);"
++  [(set_attr "length" "6")
++   (set_attr "cc" "further")])
++
++
++;;============================================================================
++;; sub 4 words (64 bits)
++;; same as above
++
++(define_expand "subdi3"
++  [(set (match_operand:DI 0 "nonimmediate_operand" "")
++        (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")   
++                 (match_operand:DI 2 "general_operand" "")))]
++  "" 
++  "")
++
++(define_insn "*subdi3_3"
++  [(set (match_operand:DI 0 "nonimmediate_operand"            "=rm")
++        (minus:DI (match_operand:DI 1 "nonimmediate_operand"          "0")
++                 (match_operand:DI 2 "general_operand"        " rmi")))]
++""
++"* return msp430_subdi_code(insn, operands,NULL);"
++  [(set_attr "length" "12")
++   (set_attr "cc" "set_n")])
++
++
++
++
++
++;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
++;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
++;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
++;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
++;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
++;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
++;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
++;; and 1 byte 
++
++
++(define_expand "andqi3" 
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
++        (and:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "")   
++                 (match_operand:QI 2 "general_operand_msp430" "")))]
++  "" 
++  "")
++
++
++(define_insn "*andqi3_inv"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"         "=r,m")   
++        (and:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "%0,0")
++                (match_operand:QI 2 "immediate_operand"    " i,i")))]
++"(INTVAL(operands[2])==~1
++  || INTVAL(operands[2])==~2
++  || INTVAL(operands[2])==~4
++  || INTVAL(operands[2])==~8)"
++"* {
++      operands[2] = gen_rtx_CONST_INT(QImode, ~(INTVAL(operands[2])));
++      return \"bic.b  %2,%0\";
++}"
++  [(set_attr "length" "1,2")
++   (set_attr "cc" "none,none")])
++
++
++(define_insn "*andqi3_3"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"             "=r,m,r,m,r,m,m,r")
++        (and:QI (match_operand:QI 1 "nonimmediate_operand_msp430"     "%0,0,0,0,0,0,0,0")
++                (match_operand:QI 2 "general_operand_msp430"                  " r,m,P,P,m,r,i,i")))]
++""
++"and.b        %2, %0"
++  [(set_attr "length" "1,3,1,2,2,2,3,2")
++   (set_attr "cc" "set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
++
++
++
++
++;;============================================================================
++;; and 1 word (16 bits)
++;; same as above
++
++(define_expand "andhi3" 
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
++        (and:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "%0")   
++                 (match_operand:HI 2 "general_operand_msp430" "")))]
++  "" 
++  "")
++
++
++(define_insn "*andhi3_inv"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"         "=r,m")   
++        (and:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "%0,0")   
++                (match_operand:HI 2 "immediate_operand"    " i,i")))]
++"(INTVAL(operands[2])==~1
++  || INTVAL(operands[2])==~2
++  || INTVAL(operands[2])==~4
++  || INTVAL(operands[2])==~8)"
++"* {
++      operands[2] = gen_rtx_CONST_INT(HImode, ~(INTVAL(operands[2])));
++      return \"bic    %2,%0\";
++}"
++  [(set_attr "length" "1,2")
++   (set_attr "cc" "none,none")])
++
++(define_insn "*andhi3_clrup"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"         "=r,m")
++        (and:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "%0,0")
++                (match_operand:HI 2 "immediate_operand"    " i,i")))]
++"INTVAL(operands[2])==255"
++"* {
++      if(which_alternative == 0)
++      {
++              return \"and.b  #-1, %0\";
++      }
++      else if(which_alternative == 1)
++      {
++              return \"clr.b  %J0\";
++      }
++
++      return  \"bug\";
++}"
++  [(set_attr "length" "1,2")
++   (set_attr "cc" "clobber,clobber")])
++
++(define_insn "*andhi3_clrlw"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"         "=m,r")
++        (and:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "%0,0")
++                (match_operand:HI 2 "immediate_operand"     " i,i")))]
++"((0xffff&INTVAL(operands[2]))==0xff00)"
++"@
++clr.b %I0
++and\\t#0xff00, %0"
++  [(set_attr "length" "2")
++   (set_attr "cc" "clobber")])
++
++
++(define_insn "*andhi3_3"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"                     "=r,m,r,m,r,m,m,r")
++        (and:HI (match_operand:HI 1 "nonimmediate_operand_msp430"     "%0,0,0,0,0,0,0,0")
++                (match_operand:HI 2 "general_operand_msp430"                  " r,m,P,P,m,r,i,i")))]
++""
++"and  %2, %0"
++  [(set_attr "length" "1,3,1,2,2,2,3,2")
++   (set_attr "cc" "set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
++
++
++
++
++
++;;============================================================================
++;; and 2 words (32 bits)
++;; same as above
++
++(define_expand "andsi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand" "")
++        (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
++                (match_operand:SI 2 "general_operand" "")))]
++  "" 
++  "")
++
++(define_insn "*andsi3_3"
++  [(set (match_operand:SI 0 "nonimmediate_operand"          "=rm")
++        (and:SI (match_operand:SI 1 "nonimmediate_operand"  "%0")
++                (match_operand:SI 2 "general_operand"       " rmi")))]
++""
++"* return msp430_andsi_code(insn, operands, NULL);"
++  [(set_attr "length" "6")
++   (set_attr "cc" "set_n")])
++
++
++;;============================================================================
++;; and 4 words (64 bits)
++;; same as above
++
++(define_expand "anddi3"
++  [(set (match_operand:DI 0 "nonimmediate_operand" "")
++        (and:DI (match_operand:DI 1 "nonimmediate_operand" "")   
++                (match_operand:DI 2 "general_operand" "")))]
++  "" 
++  "")
++
++(define_insn "*anddi3_3"
++  [(set (match_operand:DI 0 "nonimmediate_operand"         "=rm")
++        (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
++                (match_operand:DI 2 "general_operand"      " rmi")))]
++""
++"* return msp430_anddi_code(insn, operands, NULL);"
++  [(set_attr "length" "14")
++   (set_attr "cc" "clobber")])
++
++
++
++;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++;; ior 1 byte 
++;; looks like a 'mov' insn
++
++(define_expand "iorqi3" 
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
++        (ior:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "")   
++                 (match_operand:QI 2 "general_operand_msp430" "")))]
++  "" 
++  "")
++
++(define_insn "*iorqi3_3"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"             "=r,m,r,m,r,m,m,r")
++        (ior:QI (match_operand:QI 1 "nonimmediate_operand_msp430"     "%0,0,0,0,0,0,0,0")
++                (match_operand:QI 2 "general_operand_msp430"                  " r,m,P,P,m,r,i,i")))]
++""
++  "bis.b      %2, %0"
++  [(set_attr "length" "1,3,1,2,2,2,3,2")
++   (set_attr "cc" "none,none,none,none,none,none,none,none")])
++
++
++
++;;============================================================================
++;; ior 1 word (16 bits)
++;; same as above
++
++(define_expand "iorhi3" 
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
++        (ior:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "")   
++                 (match_operand:HI 2 "general_operand_msp430" "")))]
++  "" 
++  "
++    if(const_int_operand(operands[2], VOIDmode))
++    {
++      int x = INTVAL(operands[2]) & 0xffff;
++      if(!x) DONE;
++    }
++  ")
++
++(define_insn "*iorhi3_3"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"             "=r,m,r,m,r,m,m,r")
++        (ior:HI (match_operand:HI 1 "nonimmediate_operand_msp430"     "%0,0,0,0,0,0,0,0")
++                (match_operand:HI 2 "general_operand_msp430"                  " r,m,P,P,m,r,i,i")))]
++""
++  "bis        %2, %0"
++  [(set_attr "length" "1,3,1,2,2,2,3,2")
++   (set_attr "cc" "none,none,none,none,none,none,none,none")])
++
++
++
++;;============================================================================
++;; ior 2 words (32 bits)
++;; same as above
++
++
++(define_expand "iorsi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand" "")
++        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
++                 (match_operand:SI 2 "general_operand" "")))]
++  "" 
++  "")
++
++(define_insn "*iorsi3_3"
++  [(set (match_operand:SI 0 "nonimmediate_operand"      "=rm")
++        (ior:SI (match_operand:SI 1 "nonimmediate_operand"   "%0")
++                (match_operand:SI 2 "general_operand"   " rmi")))]
++""
++"* return msp430_iorsi_code(insn, operands, NULL);"
++  [(set_attr "length" "6")
++   (set_attr "cc" "none")])
++
++(define_split
++ [(set (match_operand:SI 0 "nonimmediate_operand"          "")
++       (ior:SI (match_operand:SI 1 "nonimmediate_operand"  "")
++             (match_operand:SI 2 "const_int_operand"     "")))]
++ "reload_completed
++  && (halfnibble_integer(operands[2], VOIDmode)
++       || halfnibble_constant(operands[2], VOIDmode))"
++ [(set (match_dup 3) (ior:HI (match_dup 4) (match_dup 5)))]
++ "{
++      int lo = trunc_int_for_mode(INTVAL(operands[2]),HImode);
++      int hi = trunc_int_for_mode(INTVAL(operands[2])>>16,HImode);
++ 
++      if(lo == -1)
++      {
++      rtx op = gen_lowpart(HImode, operands[0]);
++      emit_insn(gen_rtx_SET(HImode, op, GEN_INT(-1)));
++      DONE;
++      }
++      
++      if(hi == -1)
++      {
++      rtx op = gen_highpart(HImode, operands[0]);
++      emit_insn(gen_rtx_SET(HImode, op, GEN_INT(-1)));
++      DONE;
++      }
++      
++      if(lo)
++      {
++      operands[3] = gen_lowpart(HImode, operands[0]);
++      operands[4] = gen_lowpart(HImode, operands[1]);
++      operands[5] = GEN_INT(lo);
++      }
++      else if(hi)
++      {
++      operands[3] = gen_highpart(HImode, operands[0]);
++      operands[4] = gen_highpart(HImode, operands[1]);
++      operands[5] = GEN_INT(hi);
++      }
++ }")
++
++(define_peephole2
++ [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "") 
++       (const_int 0))
++  (set (match_dup 0) (ior:HI (match_dup 0) 
++                           (match_operand:HI 1 "const_int_operand" "")))]
++ ""
++ [(set (match_dup 0) (match_dup 1))]
++ "")
++ 
++
++;;============================================================================
++;; ior 4 words (64 bits)
++;; same as above
++
++(define_expand "iordi3"
++  [(set (match_operand:DI 0 "nonimmediate_operand" "")
++        (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")   
++                (match_operand:DI 2 "general_operand" "")))]
++  "" 
++  "")
++
++(define_insn "*iordi3_3"
++  [(set (match_operand:DI 0 "nonimmediate_operand"          "=rm")
++        (ior:DI (match_operand:DI 1 "nonimmediate_operand"  "%0")
++                (match_operand:DI 2 "general_operand"  " rmi")))]
++""
++"* return msp430_iordi_code(insn, operands, NULL);"
++  [(set_attr "length" "12")
++   (set_attr "cc" "none")])
++
++
++
++;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
++;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
++;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
++;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
++;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
++;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
++;; xor 1 byte 
++;; looks like a 'mov' insn
++
++(define_expand "xorqi3" 
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
++        (xor:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "")   
++                 (match_operand:QI 2 "general_operand_msp430" "")))]
++  "" 
++  "")
++
++(define_insn "*xorqi3_3"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"             "=r,m,r,m,r,m,m,r")
++        (xor:QI (match_operand:QI 1 "nonimmediate_operand_msp430"     "%0,0,0,0,0,0,0,0")
++                (match_operand:QI 2 "general_operand_msp430"                  " r,m,P,P,m,r,i,i")))]
++""
++  "xor.b      %2, %0"
++  [(set_attr "length" "1,3,1,2,2,2,3,2")
++   (set_attr "cc" "set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
++
++
++
++;;============================================================================
++;; xor 1 word (16 bits)
++;; same as above
++
++(define_expand "xorhi3" 
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
++        (xor:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "")   
++                 (match_operand:HI 2 "general_operand_msp430" "")))]
++  "" 
++  "")
++
++(define_insn "*xorhi3_3"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"             "=r,m,r,m,r,m,m,r")
++        (xor:HI (match_operand:HI 1 "nonimmediate_operand_msp430"     "%0,0,0,0,0,0,0,0")
++                (match_operand:HI 2 "general_operand_msp430"                  " r,m,P,P,m,r,i,i")))]
++""
++  "xor        %2, %0"
++  [(set_attr "length" "1,3,1,2,2,2,3,2")
++   (set_attr "cc" "set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn,set_czn")])
++
++
++
++;;============================================================================
++;; xor 2 words (32 bits)
++;; same as above
++
++(define_expand "xorsi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand" "")
++        (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
++                 (match_operand:SI 2 "general_operand" "")))]
++  "" 
++  "")
++
++
++(define_insn "*xorsi3_3"
++  [(set (match_operand:SI 0 "nonimmediate_operand"      "=rm")
++        (xor:SI (match_operand:SI 1 "nonimmediate_operand"   "%0")
++                 (match_operand:SI 2 "general_operand"  " rmi")))]
++""
++"* return msp430_xorsi_code(insn, operands, NULL);"
++  [(set_attr "length" "6")
++   (set_attr "cc" "set_n")])
++
++
++(define_split
++ [(set (match_operand:SI 0 "nonimmediate_operand"          "")
++       (xor:SI (match_operand:SI 1 "nonimmediate_operand"  "")
++             (match_operand:SI 2 "const_int_operand"     "")))]
++ "reload_completed 
++  && (halfnibble_integer(operands[2], VOIDmode)
++       || halfnibble_constant(operands[2], VOIDmode))
++  && INTVAL(operands[2])"
++ [(set (match_dup 3) (xor:HI (match_dup 4) (match_dup 5)))]
++ "{
++      int lo = trunc_int_for_mode(INTVAL(operands[2]),HImode);
++      int hi = trunc_int_for_mode(INTVAL(operands[2])>>16,HImode);
++      
++      if(lo)
++      {
++      operands[3] = gen_lowpart(HImode, operands[0]);
++      operands[4] = gen_lowpart(HImode, operands[1]);
++      operands[5] = GEN_INT(lo);
++      }
++      else if(hi)
++      {
++      operands[3] = gen_highpart(HImode, operands[0]);
++      operands[4] = gen_highpart(HImode, operands[1]);
++      operands[5] = GEN_INT(hi);
++      }
++ }")
++
++
++(define_peephole2
++ [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "") 
++       (const_int 0))
++  (set (match_dup 0) (xor:HI (match_dup 0) 
++                           (const_int -1)))]
++ ""
++ [(set (match_dup 0) (const_int -1))]
++ "")
++ 
++
++;;============================================================================
++;; xor 4 words (64 bits)
++;; same as above
++
++(define_expand "xordi3"
++  [(set (match_operand:DI 0 "nonimmediate_operand" "")
++        (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")   
++                (match_operand:DI 2 "general_operand" "")))]
++  "" 
++  "")
++
++(define_insn "*xordi3_3"
++  [(set (match_operand:DI 0 "nonimmediate_operand"          "=rm")
++        (xor:DI (match_operand:DI 1 "nonimmediate_operand"  "%0")
++                (match_operand:DI 2 "general_operand"             " rmi")))]
++""
++"* return msp430_xordi_code(insn, operands, NULL);"
++  [(set_attr "length" "4")
++   (set_attr "cc" "set_n")])
++
++
++
++
++
++;;============================================================================
++;;============================================================================
++;;============================================================================
++;;============================================================================
++;;============================================================================
++;;============================================================================
++;;============================================================================
++;;============================================================================
++;;============================================================================
++;;============================================================================
++;; neg
++;; same as above
++
++(define_expand "negqi2"
++ [(set (match_operand:QI 0 "nonimmediate_operand" "")
++   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
++ ""
++ "{ emit_insn(gen_one_cmplqi2(operands[0],operands[1]));
++ emit_insn(gen_addqi3(operands[0],operands[0],const1_rtx));
++ DONE; }")
++
++(define_expand "neghi2"
++ [(set (match_operand:HI 0 "nonimmediate_operand" "")
++   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
++ ""
++ "{ emit_insn(gen_one_cmplhi2(operands[0],operands[1]));
++ emit_insn(gen_addhi3(operands[0],operands[0],const1_rtx));
++ DONE; }")
++
++(define_expand "negsi2"
++ [(set (match_operand:SI 0 "nonimmediate_operand" "")
++   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
++ ""
++
++ "{ emit_insn(gen_one_cmplsi2(operands[0],operands[1]));
++ emit_insn(gen_addsi3(operands[0],operands[0],const1_rtx));
++ DONE; }")
++
++(define_expand "negdi2"
++ [(set (match_operand:DI 0 "nonimmediate_operand" "")
++   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
++ ""
++
++ "{ emit_insn(gen_one_cmpldi2(operands[0],operands[1]));
++ emit_insn(gen_adddi3(operands[0],operands[0],const1_rtx));
++ DONE; }")
++
++(define_insn "negsf2"
++ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,m")
++   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))]
++ ""
++ "xor  #0x8000, %B0"
++ [(set_attr "length" "2,3")
++ (set_attr "cc" "clobber,clobber")])
++
++;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
++;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
++;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
++;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
++;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
++;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
++;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
++;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
++;; not        x = !x
++;; ones component
++
++(define_expand "one_cmplqi2"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
++        (not:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "")))]
++  ""
++  "")
++
++(define_insn "*one_cmplqi2_2"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"        "=r,m")
++        (not:QI (match_operand:QI 1 "nonimmediate_operand_msp430" " 0, 0")))]
++  ""
++  "inv.b      %0"
++  [(set_attr "length" "1,2")
++   (set_attr "cc" "set_czn,set_czn")])
++
++
++;;============================================================================
++;; not HI     x = !x
++;; - ones component
++
++(define_expand "one_cmplhi2"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "")
++        (not:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0")))]
++  ""
++  "")
++
++(define_insn "*one_cmplhi2_2"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"        "=r, m")
++        (not:HI (match_operand:HI 1 "nonimmediate_operand_msp430" " 0, 0")))]
++  ""
++  "inv        %0"
++  [(set_attr "length" "1,2")
++   (set_attr "cc" "set_czn,set_czn")])
++
++
++
++;;============================================================================
++;; not SI     x = !x 
++;; - ones component
++
++(define_expand "one_cmplsi2"
++  [(set (match_operand:SI 0 "nonimmediate_operand" "")
++        (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
++  ""
++  "")
++
++(define_insn "*one_cmplsi2_2"
++  [(set (match_operand:SI 0 "nonimmediate_operand"       "=r, m")
++        (not:SI (match_operand:SI 1 "nonimmediate_operand" " 0, 0")))]
++""
++  "inv        %A0
++      inv     %B0"
++  [(set_attr "length" "2,4")
++   (set_attr "cc" "set_n,set_n")])
++
++
++;;============================================================================
++;; not DI     x = !x
++;; - ones component
++
++(define_expand "one_cmpldi2"
++  [(set (match_operand:DI 0 "nonimmediate_operand" "")
++        (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
++  ""
++  "")
++
++(define_insn "*one_cmpldi2_2"
++  [(set (match_operand:DI 0 "nonimmediate_operand"       "=r, m")
++        (not:DI (match_operand:DI 1 "nonimmediate_operand" " 0, 0")))]
++  ""
++  "inv        %A0
++      inv     %B0
++      inv     %C0
++      inv     %D0"
++  [(set_attr "length" "4,8")
++   (set_attr "cc" "set_n,set_n")])
++
++
++
++;;============================================================================
++;;============================================================================
++;;============================================================================
++;;============================================================================
++;;============================================================================
++;;============================================================================
++;;============================================================================
++;;============================================================================
++;;============================================================================
++;; abs
++;; x = |x|
++
++(define_expand "absqi2"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "")
++        (abs:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
++  ""
++  "")
++
++(define_insn "*absqi2_2"
++  [(set (match_operand:QI 0 "nonimmediate_operand"       "=r,m")
++        (abs:QI (match_operand:QI 1 "nonimmediate_operand" " 0, 0")))]
++  ""
++      "tst.b  %0
++      jge     .Leaq%=
++      inv.b   %0
++      inc.b   %0
++.Leaq%=:"
++  [(set_attr "length" "4,7")
++   (set_attr "cc" "set_czn,set_czn")])
++
++
++;;============================================================================
++;; abs HI     x = |x|
++;; 
++
++(define_expand "abshi2"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "")
++        (abs:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
++  ""
++  "")
++
++
++(define_insn "*abshi2_2"
++  [(set (match_operand:HI 0 "nonimmediate_operand"       "=r, m")
++        (abs:HI (match_operand:HI 1 "nonimmediate_operand" " 0, 0")))]
++  ""
++      "tst    %0
++      jge     .Lae%=
++      inv     %0
++      inc     %0
++.Lae%=:"
++  [(set_attr "length" "4,7")
++   (set_attr "cc" "set_czn,set_czn")])
++
++
++;;============================================================================
++;; abs SI     x = |x|
++
++(define_expand "abssi2"
++  [(set (match_operand:SI 0 "nonimmediate_operand" "")
++        (abs:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
++  ""
++  "")
++
++(define_insn "*abssi2_2"
++  [(set (match_operand:SI 0 "nonimmediate_operand"       "=r, m")
++        (abs:SI (match_operand:SI 1 "nonimmediate_operand" " 0, 0")))]
++  ""
++  "* return msp430_emit_abssi(insn, operands,NULL);"
++  [(set_attr "length" "7,13")
++   (set_attr "cc" "clobber,clobber")])
++
++
++;;============================================================================
++;; abs DI     x = |x|
++
++(define_expand "absdi2"
++  [(set (match_operand:DI 0 "nonimmediate_operand" "")
++        (abs:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
++  ""
++  "")
++
++(define_insn "*absdi2_2"
++  [(set (match_operand:DI 0 "nonimmediate_operand"       "=r, m")
++        (abs:DI (match_operand:DI 1 "nonimmediate_operand" " 0, 0")))]
++  ""
++  "* return msp430_emit_absdi(insn, operands,NULL);"
++  [(set_attr "length" "11,23")
++   (set_attr "cc" "clobber,clobber")])
++
++;;============================================================================
++;; abs SF
++
++(define_insn "abssf2"
++  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,m")
++        (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))]
++""
++"and  #0x7fff, %B0"
++  [(set_attr "length" "2,3")
++   (set_attr "cc" "clobber,clobber")])
++
++
++;; ==========================================================================
++;; there are shift helpers
++
++(define_insn "trunchiqi"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=r,m") 
++      (truncate:QI (match_operand:HI 1 "register_operand" "r,r")))]
++""
++"mov.b        %1, %0"
++  [(set_attr "length" "1,2")
++   (set_attr "cc" "none,none")])
++
++(define_insn "truncsihi"
++  [(set (match_operand:HI 0 "register_operand" "=r") 
++      (truncate:HI (match_operand:SI 1 "register_operand" "r")))]
++""
++"mov  %1, %0"
++  [(set_attr "length" "1")
++   (set_attr "cc" "none")])
++
++
++(define_insn "truncsiqi"
++  [(set (match_operand:QI 0 "register_operand" "=r") 
++      (truncate:QI (match_operand:SI 1 "register_operand" "r")))]
++""
++"mov.b        %1, %0"
++  [(set_attr "length" "1")
++   (set_attr "cc" "none")])
++
++
++(define_insn "truncdiqi"
++  [(set (match_operand:QI 0 "register_operand" "=r") 
++      (truncate:QI (match_operand:DI 1 "register_operand" "r")))]
++""
++"mov.b        %1, %0"
++  [(set_attr "length" "1")
++   (set_attr "cc" "none")])
++
++(define_insn "truncdisi"
++  [(set (match_operand:SI 0 "register_operand" "=r") 
++      (truncate:SI (match_operand:DI 1 "register_operand" "r")))]
++""
++"mov  %A1,%A0
++      mov    %B1,%B0"
++  [(set_attr "length" "2")
++   (set_attr "cc" "none")])
++
++
++(define_expand "rotlhi3"
++  [(set (match_operand:HI 0 "nonimmediate_operand"       "")
++        (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
++                   (match_operand:HI 2 "const_int_operand"  "")))]
++""
++"
++  if(INTVAL(operands[2])!=8) FAIL;
++")
++
++(define_insn "*rotlhi3"
++  [(set (match_operand:HI 0 "nonimmediate_operand"       "=rR,m")
++        (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
++                   (const_int 8)))]
++""
++"swpb\\t%0"
++  [(set_attr "length" "1,2")
++     (set_attr "cc" "none")])
++
++
++;;<< << << << << << << << << << << << << << << << << << << << << << << << <<
++;; << << << << << << << << << << << << << << << << << << << << << << << <<
++;;<< << << << << << << << << << << << << << << << << << << << << << << << <<
++;; << << << << << << << << << << << << << << << << << << << << << << << <<
++;;<< << << << << << << << << << << << << << << << << << << << << << << << <<
++;; arithmetic shift left
++
++(define_expand "ashlqi3"
++  [(set (match_operand:QI 0 "nonimmediate_operand"       "")
++        (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
++                   (match_operand:QI 2 "general_operand"  "")))]
++""
++"{
++   if(!const_int_operand(operands[2],VOIDmode))
++   {
++     rtx op0,op1;
++     
++     op0 = force_reg(QImode,operands[0]);
++     op1 = force_reg(QImode,operands[1]);
++     operands[2] = copy_to_mode_reg(QImode,operands[2]);
++     emit_insn(gen_ashlqi3_cnt (op0, op1, operands[2]));
++     emit_move_insn(operands[0],op0);
++     /*emit_move_insn(operands[1],op1);*/ 
++     DONE;
++   }
++   else if(!register_operand(operands[1], QImode) 
++              && is_shift_better_in_reg(operands))
++   {
++      operands[1] = copy_to_mode_reg(QImode,operands[1]);
++      emit_insn (gen_ashlqi3fnl(operands[0], operands[1], operands[2]));
++      DONE;
++   }
++}")
++
++(define_insn "ashlqi3_cnt"
++  [(parallel [(set (match_operand:QI 0 "register_operand"       "=r")
++            (ashift:QI (match_operand:QI 1 "register_operand" "0")
++                       (match_operand:QI 2 "register_operand" "")))
++            (clobber (match_dup 2))])]
++""
++"* return msp430_emit_ashlqi3(insn, operands,NULL);"
++  [(set_attr "length" "8")
++   (set_attr "cc" "clobber")])
++
++(define_insn "ashlqi3fnl"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"       "=rm")
++        (ashift:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "0")
++                   (match_operand 2 "const_int_operand"  "i")))]
++  ""
++  "* return msp430_emit_ashlqi3(insn, operands,NULL);"
++  [(set_attr "length" "1")
++   (set_attr "cc" "clobber")])
++
++;; HImode  ======================================
++(define_expand "ashlhi3"
++  [(set (match_operand:HI 0 "nonimmediate_operand"       "")
++        (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
++                   (match_operand 2 "general_operand"  "")))]
++""
++"{ msp430_ashlhi3(operands); DONE; }")
++
++(define_insn "ashlhi3_cnt"
++  [(parallel [(set (match_operand:HI 0 "register_operand"       "=r")
++            (ashift:HI (match_operand:HI 1 "register_operand" "0")
++                       (match_operand:HI 2 "register_operand" "r")))
++            (clobber (match_dup 2))])]
++  ""
++  "* return msp430_emit_ashlhi3(insn, operands,NULL);"
++  [(set_attr "length" "5")
++   (set_attr "cc" "clobber")])
++
++(define_insn "*ashlhi3_1"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"       "=r,R,m")
++        (ashift:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0,0,0")
++                   (const_int 1)))]
++  ""
++  "rla\\t%0"
++  [(set_attr "length" "1,2,3")
++   (set_attr "cc" "clobber")])
++
++(define_insn "*ashlhi3_15"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"       "=r,R,m")
++        (ashift:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0,0,0")
++                   (const_int 15)))]
++  ""
++  "rra\\t%0
++\\tclr\\t%0
++\\trrc\\t%0"
++  [(set_attr "length" "3,5,7")
++   (set_attr "cc" "clobber")])
++
++
++;; SImode ======================================
++
++(define_expand "ashlsi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand"       "")
++        (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
++                   (match_operand:HI 2 "general_operand"  "")))]
++""
++"{ msp430_ashlsi3(operands); DONE; }")
++
++(define_insn "ashlsi3_cnt"
++  [(parallel [(set (match_operand:SI 0 "register_operand"       "=r")
++            (ashift:SI (match_operand:SI 1 "register_operand" "0")
++                       (match_operand:HI 2 "register_operand" "")))
++            (clobber (match_dup 2))])]
++""
++"* return msp430_emit_ashlsi3(insn, operands,NULL);"
++  [(set_attr "length" "8")
++   (set_attr "cc" "clobber")])
++
++(define_insn "*ashlsi3_31"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,R,m")
++        (ashift:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
++                   (const_int 31)))]
++  ""
++"rra\\t%A0
++\\tclr\\t%A0
++\\tclr\\t%B0
++\\trrc\\t%B0"
++[(set_attr "length" "4,7,8")
++  (set_attr "cc" "clobber")])
++
++
++(define_insn "*ashlsi3_8"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,R,m")
++        (ashift:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
++                   (const_int 8)))]
++  ""
++"*{
++    if(which_alternative==0)
++    {
++      return \"xor.b\\t%A0, %B0\\n\\txor\\t%A0, %B0\\n\\tswpb\\t%B0\\n\\tand.b\\t#-1, %A0\\n\\tswpb\\t%A0 \";
++    }
++    else
++    {
++      return \"xor.b\\t%A0, %B0\\n\\tclr.b\\t%L0\\n\\txor\\t%A0, %B0\\n\\tswpb\\t%B0\\n\\tclr.b\\t%J0\\n\\tswpb\\t%A0\";
++    }
++}"
++  [(set_attr "length" "5,11,12")
++   (set_attr "cc" "clobber")])
++
++(define_insn "*ashlsi3_16"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,m,r,m")
++        (ashift:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "rR,rR,m,m")
++                   (const_int 16)))]
++""
++"mov  %A1, %B0
++\tmov #0, %A0"
++[(set_attr "length" "1,2,2,3")
++  (set_attr "cc" "clobber")])
++
++(define_insn "*ashlsi3_1"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=m,R,r")
++        (ashift:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
++                   (const_int 1)))]
++  ""
++"rla\\t%A0
++\\trlc\\t%B0"
++[(set_attr "length" "6,5,2")
++  (set_attr "cc" "clobber")])
++
++;; DImode ======================================
++
++(define_expand "ashldi3"
++  [(set (match_operand:DI 0 "nonimmediate_operand"       "")
++        (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "")
++                   (match_operand:HI 2 "general_operand"  "")))]
++""
++"{
++   if( !const_int_operand(operands[2],VOIDmode) ||
++       INTVAL(operands[2]) > 1)
++   {
++     rtx op0,op1;
++     
++     op0 = force_reg(DImode,operands[0]);
++     op1 = force_reg(DImode,operands[1]);
++     operands[2] = copy_to_mode_reg(HImode,operands[2]);
++     emit_insn(gen_ashldi3_cnt (op0, op1, operands[2]));
++     emit_move_insn(operands[0],op0);
++     /*emit_move_insn(operands[1],op1);*/ 
++     DONE;
++   }
++   else if(!register_operand(operands[1], DImode) 
++              && is_shift_better_in_reg(operands))
++   {
++      operands[1] = copy_to_mode_reg(DImode,operands[1]);
++      emit_insn (gen_ashldi3fnl(operands[0], operands[1], operands[2]));
++      DONE;
++   }
++}")
++
++(define_insn "ashldi3_cnt"
++  [(parallel [(set (match_operand:DI 0 "register_operand"       "=r")
++            (ashift:DI (match_operand:DI 1 "register_operand" "0")
++                       (match_operand:HI 2 "register_operand" "")))
++            (clobber (match_dup 2))])]
++  ""
++  "* return msp430_emit_ashldi3(insn, operands,NULL);"
++  [(set_attr "length" "8")
++   (set_attr "cc" "clobber")])
++
++
++(define_insn "ashldi3fnl"
++  [(set (match_operand:DI 0 "nonimmediate_operand"       "=rm")
++        (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
++                   (match_operand 2 "const_int_operand"  "i")))]
++  ""
++  "* return msp430_emit_ashldi3(insn, operands,NULL);"
++  [(set_attr "length" "1")
++   (set_attr "cc" "clobber")])
++
++;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
++;;  >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>      
++;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>      
++;;  >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>      
++;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>      
++;;  >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>     
++;; arithmetic shift right
++
++(define_expand "ashrqi3"
++  [(set (match_operand:QI 0 "nonimmediate_operand"       "")
++        (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
++                   (match_operand:QI 2 "general_operand"  "")))]
++""
++"{
++   if(!const_int_operand(operands[2],VOIDmode))
++   {
++     rtx op0,op1;
++     
++     op0 = force_reg(QImode,operands[0]);
++     op1 = force_reg(QImode,operands[1]);
++     operands[2] = copy_to_mode_reg(QImode,operands[2]);
++     emit_insn(gen_ashrqi3_cnt (op0, op1, operands[2]));
++     emit_move_insn(operands[0],op0);
++     /*emit_move_insn(operands[1],op1);*/ 
++     DONE;
++   }
++   else if(!register_operand(operands[1], QImode) 
++              && INTVAL(operands[2])>2 
++              && INTVAL(operands[2])!=7)
++   {
++      operands[1] = copy_to_mode_reg(QImode,operands[1]);
++      emit_insn (gen_ashrqi3fnl(operands[0], operands[1], operands[2]));
++      DONE;
++   }
++   else if(INTVAL(operands[2]) == 7)
++   {
++      /* to do it simple we need a register */
++      rtx r1 = gen_reg_rtx(HImode);
++      emit_insn(gen_extendqihi2(r1,operands[1]));
++      emit_insn(gen_swpb(r1,r1));
++      emit_insn(gen_trunchiqi(operands[0],r1));
++      DONE;
++   }
++}")
++
++(define_insn "ashrqi3_cnt"
++  [(parallel [(set (match_operand:QI 0 "register_operand"       "=r")
++            (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
++                       (match_operand:QI 2 "register_operand" "")))
++            (clobber (match_dup 2))])]
++""
++"* return msp430_emit_ashrqi3(insn, operands,NULL);"
++  [(set_attr "length" "8")
++   (set_attr "cc" "clobber")])
++
++(define_insn "ashrqi3fnl"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"       "=rm")
++        (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "0")
++                   (match_operand 2 "const_int_operand"  "i")))]
++  ""
++  "* return msp430_emit_ashrqi3(insn, operands,NULL);"
++  [(set_attr "length" "1")
++   (set_attr "cc" "clobber")])
++
++;; HImode  ======================================
++(define_expand "ashrhi3"
++  [(set (match_operand:HI 0 "nonimmediate_operand"       "")
++        (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
++                   (match_operand 2 "general_operand"  "")))]
++""
++"{msp430_ashrhi3(operands); DONE; }")
++
++(define_insn "ashrhi3_cnt"
++  [(parallel [(set (match_operand:HI 0 "register_operand"       "=r")
++            (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
++                       (match_operand:HI 2 "register_operand" "")))
++            (clobber (match_dup 2))])]
++""
++"* return msp430_emit_ashrhi3(insn, operands,NULL);"
++  [(set_attr "length" "5")
++   (set_attr "cc" "clobber")])
++
++
++(define_insn "*ashrhi3_1"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"       "=rR,m")
++        (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0,0")
++                   (const_int 1)))]
++  ""
++  "rra\\t%0"
++  [(set_attr "length" "1,2")
++   (set_attr "cc" "clobber")])
++
++
++(define_insn "*ashrhi3_15"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"       "=rR,m")
++        (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0,0")
++                   (const_int 15)))]
++  ""
++  "swpb\\t%0
++\\tsxt\\t%0
++\\tswpb\\t%0
++\\tsxt\\t%0"
++  [(set_attr "length" "4,8")
++   (set_attr "cc" "clobber")])
++
++
++
++;; SImode ======================================
++
++(define_expand "ashrsi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand"       "")
++        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
++                   (match_operand:HI 2 "general_operand"  "")))]
++""
++"{msp430_ashrsi3(operands);DONE; }")
++
++(define_insn "ashrsi3_cnt"
++  [(parallel [(set (match_operand:SI 0 "register_operand"       "=r")
++            (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
++                       (match_operand:HI 2 "register_operand" "")))
++            (clobber (match_dup 2))])]
++""
++"* return msp430_emit_ashrsi3(insn, operands,NULL);"
++  [(set_attr "length" "8")
++   (set_attr "cc" "clobber")])
++
++(define_insn "*ashrsi3_1"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=rR,m")
++        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0")
++                   (const_int 1)))]
++  ""
++  "rra\\t%B0
++\\trrc\\t%A0"
++  [(set_attr "length" "2,4")
++   (set_attr "cc" "clobber")])
++
++(define_insn "*ashrsi3_31"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,R,m")
++        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
++                   (const_int 31)))]
++  ""
++"swpb %B0
++\\tsxt        %B0
++\\tswpb       %B0
++\\tsxt        %B0
++\\tmov        %B0, %A0"
++  [(set_attr "length" "5,10,10")
++   (set_attr "cc" "clobber")])
++
++(define_insn "*ashrsi3_8"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,R,m")
++        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
++                   (const_int 8)))]
++  ""
++"*{
++    if(which_alternative==0)
++    {
++      return \" swpb\\t%A0\\n\\tswpb\\t%B0\\n\\txor.b\\t%B0, %A0\\n\\txor\\t%B0, %A0\\n\\tsxt\\t%B0\";
++    }
++    else
++    {
++      return \" swpb\\t%A0\\n\\tswpb\\t%B0\\n\\txor.b\\t%B0, %A0\\n\\tclr.b\\t%J0\\n\\txor\\t%B0, %A0\\n\\tsxt\\t%B0\";
++    }
++}"
++  [(set_attr "length" "5,11,12")
++   (set_attr "cc" "clobber")])
++
++;; DImode ======================================
++
++(define_expand "ashrdi3"
++  [(set (match_operand:DI 0 "nonimmediate_operand"       "")
++        (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "")
++                   (match_operand:HI 2 "general_operand"  "")))]
++""
++"{
++   if( !const_int_operand(operands[2],VOIDmode))
++   {
++     rtx op0,op1;
++     
++     op0 = force_reg(DImode,operands[0]);
++     op1 = force_reg(DImode,operands[1]);
++     operands[2] = copy_to_mode_reg(HImode,operands[2]);
++     emit_insn(gen_ashrdi3_cnt (op0, op1, operands[2]));
++     emit_move_insn(operands[0],op0);
++     /*emit_move_insn(operands[1],op1);*/ 
++     DONE;
++   }
++   else if(!register_operand(operands[1], DImode) 
++              && is_shift_better_in_reg(operands))
++   {
++      operands[1] = copy_to_mode_reg(DImode,operands[1]);
++      emit_insn (gen_ashrdi3fnl(operands[0], operands[1], operands[2]));
++      DONE;
++   }
++}")
++
++(define_insn "ashrdi3_cnt"
++  [(parallel [(set (match_operand:DI 0 "register_operand"       "=r")
++            (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
++                       (match_operand:HI 2 "register_operand" "")))
++            (clobber (match_dup 2))])]
++  ""
++  "* return msp430_emit_ashrdi3(insn, operands,NULL);"
++  [(set_attr "length" "8")
++   (set_attr "cc" "clobber")])
++
++
++(define_insn "ashrdi3fnl"
++  [(set (match_operand:DI 0 "nonimmediate_operand"       "=rm")
++        (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
++                   (match_operand 2 "const_int_operand"  "i")))]
++  ""
++  "* return msp430_emit_ashrdi3(insn, operands,NULL);"
++  [(set_attr "length" "1")
++   (set_attr "cc" "clobber")])
++
++
++
++
++
++;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
++;;  >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>   
++;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>   
++;;  >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>   
++;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>   
++;;  >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>   
++;; logical shift right
++
++(define_expand "lshrqi3"
++  [(set (match_operand:QI 0 "nonimmediate_operand"       "")
++        (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
++                   (match_operand:QI 2 "general_operand"  "")))]
++""
++"{
++   if(!const_int_operand(operands[2],VOIDmode))
++   {
++     rtx op0,op1;
++     
++     op0 = force_reg(QImode,operands[0]);
++     op1 = force_reg(QImode,operands[1]);
++     operands[2] = copy_to_mode_reg(QImode,operands[2]);
++     emit_insn(gen_lshrqi3_cnt (op0, op1, operands[2]));
++     emit_move_insn(operands[0],op0);
++     /*emit_move_insn(operands[1],op1);*/ 
++     DONE;
++   }
++   else if(!register_operand(operands[1], QImode) 
++              && is_shift_better_in_reg(operands))
++   {
++      operands[1] = copy_to_mode_reg(QImode,operands[1]);
++      emit_insn (gen_lshrqi3fnl(operands[0], operands[1], operands[2]));
++      DONE;
++   }
++}")
++
++(define_expand "lshrqi3_cnt"
++  [(parallel [(set (match_operand:QI 0 "register_operand"       "=r")
++            (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
++                       (match_operand:QI 2 "register_operand" "")))
++            (clobber (match_dup 2))])]
++""
++"")
++
++(define_insn "*lshrqi3_cnt"
++  [(parallel [(set (match_operand:QI 0 "register_operand"       "=r")
++            (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
++                       (match_operand:QI 2 "register_operand" "")))
++            (clobber (match_dup 2))])]
++""
++"* return msp430_emit_lshrqi3(insn, operands,NULL);"
++  [(set_attr "length" "8")
++   (set_attr "cc" "clobber")])
++
++(define_insn "lshrqi3fnl"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430"       "=rm")
++        (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "0")
++                   (match_operand 2 "const_int_operand"  "i")))]
++  ""
++  "* return msp430_emit_lshrqi3(insn, operands,NULL);"
++  [(set_attr "length" "1")
++   (set_attr "cc" "clobber")])
++
++;; HImode  ======================================
++
++(define_insn "clrc"
++ [(unspec:HI [(const_int 123454321)] 30)]
++""
++ "clrc"
++[(set_attr "length" "1")
++  (set_attr "cc" "clobber")])
++
++ 
++(define_expand "lshrhi3"
++  [(set (match_operand:HI 0 "nonimmediate_operand"       "")
++        (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
++                   (match_operand 2 "general_operand"  "")))]
++""
++"{msp430_lshrhi3(operands); DONE; }")
++
++(define_insn "lshrhi3_cnt"
++  [(parallel [(set (match_operand:HI 0 "register_operand"       "=r")
++            (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
++                       (match_operand:HI 2 "register_operand" "")))
++            (clobber (match_dup 2))])]
++""
++"* return msp430_emit_lshrhi3(insn, operands,NULL);"
++  [(set_attr "length" "5")
++   (set_attr "cc" "clobber")])
++
++(define_insn "*lshrhi3_15"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"       "=r,R,m")
++        (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0,0,0")
++                   (const_int 15)))]
++  ""
++  "rla\\t%0
++\\tclr\\t%0
++\\trlc\\t%0"
++  [(set_attr "length" "3,6,8")
++   (set_attr "cc" "clobber")])
++
++
++(define_insn "*lshrhi3_1"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430"       "=rR,m")
++        (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand_msp430" "0,0")
++                   (const_int 1)))]
++  ""
++"clrc
++\\trrc\\t%0"
++  [(set_attr "length" "2,3")
++   (set_attr "cc" "clobber")])
++
++;; SImode ======================================
++
++(define_expand "lshrsi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand"       "")
++        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
++                   (match_operand:HI 2 "general_operand"  "")))]
++""
++"{ msp430_lshrsi3(operands); DONE; }")
++
++(define_insn "lshrsi3_cnt"
++  [(parallel [(set (match_operand:SI 0 "register_operand"       "=r")
++            (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
++                       (match_operand:HI 2 "register_operand" "")))
++            (clobber (match_dup 2))])]
++""
++"* return msp430_emit_lshrsi3(insn, operands,NULL);"
++  [(set_attr "length" "8")
++   (set_attr "cc" "clobber")])
++
++
++(define_insn "*lshrsi3_31"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,R,m")
++        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
++                   (const_int 31)))]
++  ""
++"rla  %B0
++\\tclr        %B0
++\\tclr        %A0
++\\trlc        %A0"
++  [(set_attr "length" "4,9,10")
++   (set_attr "cc" "clobber")])
++
++
++(define_insn "*lshrsi3_8"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,R,m")
++        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
++                   (const_int 8)))]
++  ""
++"*{
++    if(which_alternative==0)
++    {
++      return \"swpb\\t%A0\\n\\tswpb\\t%B0\\n\\txor.b\\t%B0, %A0\\n\\txor\\t%B0, %A0\\n\\tand.b\\t#-1, %B0\";
++    }
++    else
++    {
++      return \"swpb\\t%A0\\n\\tswpb\\t%B0\\n\\txor.b\\t%B0, %A0\\n\\tclr.b\\t%J0\\n\\txor\\t%B0, %A0\\n\\tclr.b\\t%L0\";
++    }
++}"
++  [(set_attr "length" "5,11,12")
++   (set_attr "cc" "clobber")])
++
++(define_insn "*lshrsi3_1"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430"       "=r,R,m")
++        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand_msp430" "0,0,0")
++                   (const_int 1)))]
++  ""
++"clrc
++\\trrc\\t%B0
++\\trrc\\t%A0"
++  [(set_attr "length" "3,4,5")
++   (set_attr "cc" "clobber")])
++
++;; DImode ======================================
++
++(define_expand "lshrdi3"
++  [(set (match_operand:DI 0 "nonimmediate_operand"       "")
++        (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "")
++                   (match_operand:HI 2 "general_operand"  "")))]
++""
++"{
++   if( !const_int_operand(operands[2],VOIDmode))
++   {
++     rtx op0,op1;
++     
++     op0 = force_reg(DImode,operands[0]);
++     op1 = force_reg(DImode,operands[1]);
++     operands[2] = copy_to_mode_reg(HImode,operands[2]);
++     emit_insn(gen_lshrdi3_cnt (op0, op1, operands[2]));
++     emit_move_insn(operands[0],op0);
++     /*emit_move_insn(operands[1],op1);*/ 
++     DONE;
++   }
++   else if(!register_operand(operands[1], DImode) 
++              && is_shift_better_in_reg(operands))
++   {
++      operands[1] = copy_to_mode_reg(DImode,operands[1]);
++      emit_insn (gen_lshrdi3fnl(operands[0], operands[1], operands[2]));
++      DONE;
++   }
++}")
++
++(define_insn "lshrdi3_cnt"
++  [(parallel [(set (match_operand:DI 0 "register_operand"       "=r")
++            (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
++                       (match_operand:HI 2 "register_operand" "")))
++            (clobber (match_dup 2))])]
++  ""
++  "* return msp430_emit_lshrdi3(insn, operands,NULL);"
++  [(set_attr "length" "8")
++   (set_attr "cc" "clobber")])
++
++
++(define_insn "lshrdi3fnl"
++  [(set (match_operand:DI 0 "nonimmediate_operand"       "=rm")
++        (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
++                   (match_operand 2 "const_int_operand"  "i")))]
++  ""
++  "* return msp430_emit_lshrdi3(insn, operands,NULL);"
++  [(set_attr "length" "1")
++   (set_attr "cc" "clobber")])
++
++
++
++
++
++
++;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
++;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
++;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
++;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
++;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
++;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
++;; sign extend
++
++(define_insn "extendqihi2"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
++        (sign_extend:HI (match_operand:QI 1 "general_operand" "0,*rmi")))]
++  ""
++  "* return signextendqihi(insn, operands,NULL);"
++  [(set_attr "length" "2,2")
++   (set_attr "cc" "set_n,set_n")])
++
++(define_insn "extendqisi2"
++  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
++        (sign_extend:SI (match_operand:QI 1 "general_operand" "0,*rmi")))]
++  ""
++  "* return signextendqisi(insn, operands,NULL);"
++  [(set_attr "length" "6,6")
++   (set_attr "cc" "set_n,set_n")])
++
++(define_insn "extendqidi2"
++  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
++        (sign_extend:DI (match_operand:QI 1 "general_operand" "0,*rmi")))]
++  ""
++  "* return signextendqidi(insn, operands,NULL);"
++  [(set_attr "length" "6,6")
++   (set_attr "cc" "set_n,set_n")])
++
++(define_insn "extendhisi2"
++  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
++        (sign_extend:SI (match_operand:HI 1 "general_operand" "0,*rmi")))] 
++  ""
++  "* return signextendhisi(insn, operands,NULL);"
++  [(set_attr "length" "6,6")  
++   (set_attr "cc" "set_n,set_n")])      
++
++(define_insn "extendhidi2"
++  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
++        (sign_extend:DI (match_operand:HI 1 "general_operand" "0,*rmi")))]
++  ""
++  "* return signextendhidi(insn, operands,NULL);"
++  [(set_attr "length" "6,6")  
++   (set_attr "cc" "set_n,set_n")])
++
++(define_insn "extendsidi2"
++  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
++        (sign_extend:DI (match_operand:SI 1 "general_operand" "0,*rmi")))]
++  ""
++  "* return signextendsidi(insn, operands,NULL);"
++  [(set_attr "length" "6,6")
++   (set_attr "cc" "set_n,set_n")])
++
++;; xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0
++;; xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0
++;; xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0
++;; xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0
++;; xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0
++;; xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0 xx<---0
++;; zero extend
++
++(define_insn "zero_extendqihi2"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
++        (zero_extend:HI (match_operand:QI 1 "general_operand" "0,*rmi")))]
++  ""
++  "* return zeroextendqihi(insn, operands,NULL);"
++  [(set_attr "length" "2,2")
++   (set_attr "cc" "clobber,clobber")])
++
++(define_insn "zero_extendqisi2"
++  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
++        (zero_extend:SI (match_operand:QI 1 "general_operand" "0,*rmi")))]
++  ""
++  "* return zeroextendqisi(insn, operands,NULL);"
++  [(set_attr "length" "6,6")
++   (set_attr "cc" "clobber,clobber")])
++
++(define_insn "zero_extendqidi2"
++  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
++        (zero_extend:DI (match_operand:QI 1 "general_operand" "0,*rmi")))]
++  ""
++  "* return zeroextendqidi(insn, operands,NULL);"
++  [(set_attr "length" "6,6")
++   (set_attr "cc" "clobber,clobber")])
++
++
++(define_insn "zero_extendhisi2"
++  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
++        (zero_extend:SI (match_operand:HI 1 "general_operand" "0,*rmi")))] 
++  ""
++  "* return zeroextendhisi(insn, operands,NULL);"
++  [(set_attr "length" "6,6")  
++   (set_attr "cc" "clobber,clobber")])      
++
++(define_insn "zero_extendhidi2"
++  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
++        (zero_extend:DI (match_operand:HI 1 "general_operand" "0,*rmi")))]
++  ""
++  "* return zeroextendhidi(insn, operands,NULL);"
++  [(set_attr "length" "6,6")  
++   (set_attr "cc" "clobber,clobber")])
++
++(define_insn "zero_extendsidi2"
++  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
++        (zero_extend:DI (match_operand:SI 1 "general_operand" "0,*rmi")))]
++  ""
++  "* return zeroextendsidi(insn, operands,NULL);"
++  [(set_attr "length" "6,6")  
++   (set_attr "cc" "clobber,clobber")])
++
++;; =====================================================================
++;; single bit extract
++;; as soon as all operatoins performed on io registers
++;; let use only QImode. 
++
++(define_expand "extv"
++ [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
++       (sign_extract:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "") 
++                      (match_operand 2 "const_int_operand" "")
++                      (match_operand 3 "const_int_operand" "")))]
++""
++"{
++    if(INTVAL(operands[2]) != 1 || INTVAL(operands[3]) <= 0)
++      FAIL;
++}")
++
++(define_insn "*extv" 
++ [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=r,r,r,r,m,m,m,m")
++       (sign_extract:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "r,m,r,m,r,m,r,m") 
++                      (const_int 1)
++                      (match_operand 2 "const_int_operand" "P,P,i,i,P,P,i,i")))]
++ ""
++"* {
++  operands[2] = GEN_INT(1<<INTVAL(operands[2]));
++  return      \"bit.b\\t%2, %1\\n\"
++              \"\\tclr.b\\t%0\\n\"
++              \"\\tadc.b\\t%0\";
++}"
++  [(set_attr "length" "3,4,4,5,5,6,6,7")
++     (set_attr "cc" "clobber")])
++
++(define_expand "extzv"
++ [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "")
++       (zero_extract:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "") 
++                      (match_operand 2 "const_int_operand" "")
++                      (match_operand 3 "const_int_operand" "")))]
++""
++"{
++    if(INTVAL(operands[2]) != 1 || INTVAL(operands[3]) <= 0) 
++      FAIL;
++}")
++
++(define_insn "*extzv" 
++ [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=r,r,r,r,m,m,m,m")
++       (zero_extract:QI (match_operand:QI 1 "nonimmediate_operand_msp430" "r,m,r,m,r,m,r,m")
++                      (match_operand 2 "const_int_operand" "")
++                      (match_operand 3 "const_int_operand" "P,P,i,i,P,P,i,i")))]
++ "INTVAL(operands[2]) == 1"
++"* {
++  operands[3] = GEN_INT(1<<INTVAL(operands[3]));
++  return      \"bit.b\\t%3, %1\\n\"
++              \"\\tclr.b\\t%0\\n\"
++              \"\\tadc.b\\t%0\";
++}"
++  [(set_attr "length" "3,4,4,5,5,6,6,7")
++     (set_attr "cc" "clobber")])
++
++
++
++;;=======================================================================
++;;  various BRANCH insns...
++;;
++;;
++
++;; Unconditional jump instruction.
++(define_insn "jump"
++  [(set (pc) (label_ref (match_operand 0 "" "")))]
++  ""
++  "*
++{
++  int dist = msp430_jump_dist(operands[0],insn);
++  if (dist<500 && dist>-500)
++    return \"jmp      %0\";
++  return \"br #%0\"; 
++}"
++  [(set_attr "length" "2")
++   (set_attr "cc" "none")])
++
++
++(define_insn "explicit_br"
++  [(unspec_volatile:HI [(const_int 0)] UNSPEC_EXPLICIT_BR)
++   (match_operand:HI 0 "immediate_operand" "")]
++   ""
++   "br        %0"
++  [(set_attr "length" "2")
++   (set_attr "cc" "none")]
++)
++
++   
++; indirect jump
++(define_expand "indirect_jump"
++  [(set (pc) (match_operand:HI 0 "nonimmediate_operand" ""))]
++  ""
++  "")
++
++(define_insn "*indirect_jump_idx"
++  [(set (pc) (match_operand:HI 0 "memory_operand" "m"))]
++  "indexed_location(operands[0])"
++  "br @%E0"
++  [(set_attr "length" "1")
++   (set_attr "cc" "none")])
++
++(define_insn "*indirect_jump_mem"
++  [(set (pc) (match_operand:HI 0 "memory_operand" "m"))]
++  "!indexed_location(operands[0])"
++  "br %0"
++  [(set_attr "length" "2")
++   (set_attr "cc" "none")])
++
++
++(define_insn "*indirect_jump_reg"
++  [(set (pc) (match_operand:HI 0 "register_operand" "r"))]
++  ""
++  "br %0"
++  [(set_attr "length" "1")
++   (set_attr "cc" "none")])
++
++
++;;=======================================================================
++;;=======================================================================
++;;=======================================================================
++;;=======================================================================
++
++
++;;=======================================================================
++;;
++;;    CASE
++;;
++
++/*
++(define_expand "casesi"
++  [(set (match_dup 6)  
++        (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
++                  (match_operand:HI 1 "register_operand" "")))
++   (parallel [(set (cc0)
++                   (compare (match_dup 6)
++                            (match_operand:HI 2 "register_operand" "")))])
++   (set (pc)
++        (if_then_else (gtu (cc0)
++                           (const_int 0))
++                      (label_ref (match_operand 4 "" ""))
++                      (pc)))
++   (set (match_dup 6)
++        (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
++
++   (parallel [(set (pc) (unspec:HI [(match_dup 6)] 1))
++              (use (label_ref (match_dup 3)))
++              (clobber (match_dup 6))])]
++  ""
++  " 
++{   
++  operands[6] = gen_reg_rtx (HImode);
++}")
++
++*/ 
++
++;; Table helper
++(define_insn "tablejump"
++  [(set (pc) (match_operand:HI 0 "general_operand" "rRP,i,m"))
++   (use (label_ref (match_operand 1 "" "")))]
++  ""
++  "br %0      ;       %1"
++ [(set_attr "length" "1,2,2")   
++   (set_attr "cc" "clobber")])
++
++
++;; =============================================================
++;; match De Morgan's law
++(define_insn "nandqi"
++  [(set (match_operand:QI 0 "nonimmediate_operand_msp430" "=r,m,m,r")
++             (and:QI (not:QI (match_operand:QI 1 "general_operand_msp430" "rRP,mi,rRP,mi"))
++                           (match_operand:QI 2 "nonimmediate_operand_msp430" "0,0,0,0")))]
++""
++"bic.b       %1, %0"
++[(set_attr "length" "1,3,2,2")
++  (set_attr "cc" "none")])
++
++(define_insn "nandhi"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m,m,r")
++             (and:HI (not:HI (match_operand:HI 1 "general_operand_msp430" "rRP,mi,rRP,mi"))
++                           (match_operand:HI 2 "nonimmediate_operand_msp430" "0,0,0,0")))]
++""
++"bic %1, %0"
++[(set_attr "length" "1,3,2,2")
++  (set_attr "cc" "none")])
++
++(define_insn "nandsi"
++  [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "=r,m,m,r,r,m")
++            (and:SI (not:SI (match_operand:SI 1 "general_operand_msp430" "rP,mi,rP,mi,R,R"))
++                          (match_operand:SI 2 "nonimmediate_operand_msp430" "0,0,0,0,0,0")))]
++""
++"bic    %A1, %A0
++\\tbic  %B1, %B0"
++[(set_attr "length" "2,6,4,4,3,5")
++  (set_attr "cc" "none")])
++
++
++
++;; =============================================================
++;; PEEPHOLES
++
++;; a &= ~b;
++
++(define_insn "*bit_clear"
++ [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m,m,r") 
++       (unspec_volatile:HI [(match_operand:HI 1 "general_operand_msp430" "rRP,mi,rRP,mi")] 40))]
++""
++"bic  %1, %0"
++  [(set_attr "length" "1,3,2,2")
++     (set_attr "cc" "none")])
++
++(define_insn "bic_sr_irq"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m,m,r")
++           (unspec_volatile:HI [(match_operand:HI 1 "general_operand_msp430" "rRP,mi,rRP,mi")
++                              (const_int 4100001)] 41))]
++  ""
++  "bic    %1, %0"
++    [(set_attr "length" "1,3,2,2")
++         (set_attr "cc" "none")])
++
++(define_insn "bis_sr_irq"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m,m,r")
++           (unspec_volatile:HI [(match_operand:HI 1 "general_operand_msp430" "rRP,mi,rRP,mi")
++                               (const_int 4200002)] 42))]
++  ""
++  "bis    %1, %0"
++    [(set_attr "length" "1,3,2,2")
++         (set_attr "cc" "none")])
++
++(define_insn "get_frame_address"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=r,m,m,r")
++           (unspec_volatile:HI [(match_operand:HI 1 "general_operand_msp430" "rRP,mi,rRP,mi")
++                               (const_int 4300003)] 43))]
++  ""
++  "mov        %1, %0"
++    [(set_attr "length" "1,3,2,2")
++         (set_attr "cc" "none")])
++
++;; these two for:
++;; (ulong) x = (ulong) func() << 16;
++;; x |= func();
++;; func() is uint
++;;
++
++;; do not check for zeros here, cause this insn already issued.
++(define_peephole2
++   [(set (match_operand:SI 1 "register_operand" "")
++         (sign_extend:SI (match_operand:HI 0 "register_operand" "")))
++    (set (match_dup 1) (ashift:SI (match_dup 1) (const_int 16)))]
++""
++  [(set (subreg:HI (match_dup 1) 2) (match_dup 0))]
++"")
++
++(define_peephole2
++   [(set (match_operand:SI 1 "register_operand" "")
++         (zero_extend:SI (match_operand:HI 0 "register_operand" "")))
++    (set (match_dup 1) (ashift:SI (match_dup 1) (const_int 16)))]
++""
++  [(set (subreg:HI (match_dup 1) 2) (match_dup 0))]
++"")
++
++(define_peephole2
++   [(set (match_operand:SI 0 "register_operand" "")
++         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
++    (set (match_operand:SI 2 "register_operand" "")
++         (ior:SI (match_dup 2) (match_dup 0)))]
++"dead_or_set_in_peep(1,insn, operands[0])"
++  [(set (subreg:HI (match_dup 2) 0) 
++        (ior:HI (subreg:HI (match_dup 2) 0) (match_dup 1)))]
++"")
++
++(define_peephole2
++   [(set (match_operand:HI 0 "register_operand" "")  
++         (match_operand:HI 1 "general_operand_msp430" ""))
++    (set (match_operand:SI 2 "register_operand" "")
++         (zero_extend:SI (match_dup 0)))
++    (set (match_operand:SI 3 "register_operand" "") 
++         (ior:SI (match_dup 3) (match_dup 2)))]
++"dead_or_set_in_peep(2,insn, operands[0])"
++  [(set (subreg:HI (match_dup 3) 0) 
++        (ior:HI (subreg:HI (match_dup 3) 0) (match_dup 1)))]
++"")
++
++
++;; (ulong) x = (ulong) f >> 16;
++;;
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "") 
++      (match_operand:SI 1 "register_operand" "")) 
++   (set (match_dup 0) 
++      (lshiftrt:SI (match_dup 0) 
++                   (const_int 16)))]
++""
++[(set (subreg:HI (match_dup 0) 0) (subreg:HI (match_dup 1) 2))
++ (set (subreg:HI (match_dup 0) 2) (const_int 0))]
++"")
++
++
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "") 
++      (match_operand:SI 1 "register_operand" ""))
++   (set (match_operand:SI 2 "register_operand" "")
++      (ior:SI (match_dup 2) (match_dup 0)))]
++"dead_or_set_in_peep(1,insn, operands[0])"
++  [(set (match_dup 2) (ior:SI (match_dup 2) 
++                            (match_dup 1)))]
++"")
++
++
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "") 
++      (zero_extend:SI (match_operand:HI 1 "general_operand" "")))
++   (set (match_dup 0) 
++      (ashift:SI (match_dup 0) (const_int 16)))]
++""
++  [(set (subreg:HI (match_dup 0) 2) (match_dup 1))]
++"")
++
++
++;; shift right & set
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") 
++      (match_operand:HI 1 "register_operand" ""))
++   (set (match_operand:HI 2 "register_operand" "")
++      (match_dup 0))
++   (set (match_dup 2) 
++      (and:HI (match_dup 2) 
++              (match_operand 3 "const_int_operand" "")))
++   (set (match_dup 2) 
++      (lshiftrt:HI (match_dup 2) 
++                   (match_operand 4 "const_int_operand" ""))) 
++   (set (match_dup 1) (match_dup 2))]
++"dead_or_set_in_peep(4,insn, operands[2])"
++  [(set (match_dup 0) (match_dup 1))
++   (set (match_dup 1)  
++      (and:HI (match_dup 1)  
++              (match_dup 3))) 
++   (set (match_dup 1) 
++      (lshiftrt:HI (match_dup 1) 
++                   (match_dup 4)))] 
++"")
++
++;; shift left and set
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") 
++      (match_operand:HI 1 "register_operand" ""))
++   (set (match_operand:HI 2 "register_operand" "")
++      (match_dup 0))
++   (set (match_dup 2) 
++      (and:HI (match_dup 2) 
++              (match_operand 3 "const_int_operand" "")))
++   (set (match_dup 2) 
++      (ashift:HI (match_dup 2) 
++                 (match_operand 4 "const_int_operand" ""))) 
++   (set (match_dup 1) (match_dup 2))]
++"dead_or_set_in_peep(4,insn, operands[2])"
++  [(set (match_dup 0) (match_dup 1))
++   (set (match_dup 1)  
++      (and:HI (match_dup 1)  
++              (match_dup 3))) 
++   (set (match_dup 1) 
++      (ashift:HI (match_dup 1) 
++                 (match_dup 4)))] 
++"")
++
++
++;;
++;; these for some shifts and stuff.
++;; every peephole saves up to 4 bytes.
++;;
++
++(define_insn "*addc_reg"
++  [(set (match_operand:HI 0 "register_operand" "=r,r") 
++      (unspec:HI [(match_operand:HI 1 "register_operand" "%0,0") 
++                  (match_operand:HI 2 "general_operand_msp430" "rP,mi")] 0))]
++""
++"addc %2, %0"
++[(set_attr "length" "1,2")
++   (set_attr "cc" "clobber,clobber")])
++
++
++(define_insn "*addc_any"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=m,m") 
++      (unspec:HI [(match_operand:HI 1 "nonimmediate_operand_msp430" "%0,0") 
++                  (match_operand:HI 2 "general_operand_msp430" "rP,mi")] 5))]
++""
++"addc %2, %0"
++[(set_attr "length" "2,3")
++   (set_attr "cc" "clobber,clobber")])
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") 
++      (match_operand:HI 1 "general_operand_msp430" ""))
++   (set (match_operand:SI 2 "register_operand" "") 
++      (zero_extend:SI (match_dup 0)))
++   (set (match_operand:SI 3 "register_operand" "") 
++      (plus:SI (match_dup 3) (match_dup 2)))]
++"dead_or_set_in_peep(2,insn, operands[2])"
++  [(set (subreg:HI (match_dup 3) 0) 
++      (plus:HI (subreg:HI (match_dup 3) 0) 
++               (match_dup 1)))
++   (set (subreg:HI (match_dup 3) 2) 
++      (unspec:HI [(subreg:HI (match_dup 3) 2) (const_int 0)] 0))]
++"")
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") 
++      (match_operand:HI 1 "general_operand_msp430" ""))
++   (set (match_operand:SI 2 "register_operand" "") 
++      (zero_extend:SI (match_dup 0)))
++   (set (match_operand:SI 3 "nonimmediate_operand_msp430" "") 
++      (plus:SI (match_dup 3) (match_dup 2)))]
++"dead_or_set_in_peep(2,insn, operands[2])"
++  [(set (subreg:HI (match_dup 3) 0) 
++      (plus:HI (subreg:HI (match_dup 3) 0) 
++               (match_dup 1)))
++   (set (subreg:HI (match_dup 3) 2) 
++      (unspec:HI [(subreg:HI (match_dup 3) 2) (const_int 0)] 5))]
++"")
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "")
++        (match_operand:HI 1 "general_operand_msp430" ""))
++   (set (match_operand:SI 2 "nonimmediate_operand_msp430" "")
++        (zero_extend:SI (match_dup 0)))]
++"dead_or_set_in_peep(1,insn, operands[0])"
++  [(set (subreg:HI (match_dup 2) 0) (match_dup 1))
++   (set (subreg:HI (match_dup 2) 2) (const_int 0))]
++"")
++
++;;
++;; these are for redudant moves.
++;;
++
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "") 
++      (match_operand:SI 1 "nonimmediate_operand_msp430" ""))
++   (set (match_operand:SI 2 "register_operand" "") 
++      (ior:SI (match_dup 2) (match_dup 0)))
++   (set (match_dup 1) (match_dup 2))]
++"dead_or_set_in_peep(1,insn, operands[0])"
++  [(set (match_dup 1) (ior:SI (match_dup 1) (match_dup 2)))]
++"")
++
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "")
++      (ior:SI (match_dup 0) 
++              (match_operand:SI 1 "register_operand" "")))
++   (set (match_dup 1) (match_dup 0))]
++"dead_or_set_in_peep(1,insn, operands[0])"
++  [(set (match_dup 1) (ior:SI (match_dup 1) (match_dup 0)))]
++"")
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") 
++      (match_operand:HI 1 "register_operand" ""))
++   (set (match_dup 0) 
++      (not:HI (match_dup 0)))
++   (set (match_operand:HI 2 "register_operand" "") 
++      (match_dup 0))]
++"dead_or_set_in_peep(2,insn, operands[0]) && dead_or_set_in_peep(0,insn, operands[1])"
++  [(set (match_dup 1) (not:HI (match_dup 1)))
++   (set (match_dup 2) (match_dup 1))]
++"")
++
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "") 
++      (match_operand:SI 1 "register_operand" ""))
++   (set (match_dup 0) 
++      (not:SI (match_dup 0)))
++   (set (match_operand:SI 2 "register_operand" "") 
++      (match_dup 0))]
++"dead_or_set_in_peep(2,insn, operands[0]) && dead_or_set_in_peep(0,insn, operands[1])"
++  [(set (match_dup 1) (not:SI (match_dup 1)))
++   (set (match_dup 2) (match_dup 1))]
++"")
++
++(define_peephole2
++  [(set (match_operand:SF 0 "register_operand" "")
++      (match_operand:SF 1 "general_operand_msp430" ""))
++   (set (match_operand:SF 2 "nonimmediate_operand_msp430" "") 
++      (match_dup 0))]
++"dead_or_set_in_peep(1,insn, operands[0])"
++  [(set (match_dup 2) (match_dup 1))]
++"")
++
++
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "")
++      (match_operand:SI 1 "general_operand_msp430" ""))
++   (set (match_operand:SI 2 "nonimmediate_operand_msp430" "") 
++      (match_dup 0))]
++"dead_or_set_in_peep(1,insn, operands[0])"
++  [(set (match_dup 2) (match_dup 1))]
++"")
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "")
++        (match_operand:HI 1 "general_operand_msp430" ""))
++   (set (match_operand:HI 2 "nonimmediate_operand_msp430" "")
++        (match_dup 0))]
++"dead_or_set_in_peep(1,insn, operands[0])"
++  [(set (match_dup 2) (match_dup 1))]
++"")
++
++
++
++;; =========================================================================
++;;  This one for bit tests like:
++;;    volatile long a;
++;;    while(a&CONST_HALFNIBBLE) ;
++
++(define_insn "*bittest_lo"
++  [(set (cc0) 
++      (unspec:SI [(match_operand:SI 0 "nonimmediate_operand_msp430" "r,r,m,m") 
++                  (match_operand:SI 1 "general_operand_msp430" "rPR,mi,rPR,mi")] 1))]
++""
++"bit  %A1,%A0"
++[(set_attr "length" "1,2,2,3")
++   (set_attr "cc" "compare,compare,compare,compare")])
++
++(define_insn "*bittest_hi"
++  [(set (cc0) 
++      (unspec:SI [(match_operand:SI 0 "nonimmediate_operand_msp430" "r,r,m,m") 
++                  (match_operand:SI 1 "general_operand_msp430" "rPR,mi,rPR,mi")] 2))]
++""
++"bit  %B1,%B0"
++[(set_attr "length" "1,2,2,3")
++   (set_attr "cc" "compare,compare,compare,compare")])
++
++(define_peephole2
++ [(set (match_operand:SI 0 "register_operand" "")
++       (match_operand:SI 1 "nonimmediate_operand_msp430" ""))
++  (set (match_dup 0) (and:SI (match_dup 0) 
++                             (match_operand 2 "const_int_operand" "")))
++  (set (pc) 
++       (if_then_else (match_operator:SI 3 "equality_operator"
++                    [(match_dup 0) (const_int 0)]) 
++       (label_ref (match_operand 4 "" ""))
++       (pc)))]
++"(halfnibble_integer(operands[2], VOIDmode) 
++   || halfnibble_constant(operands[2], VOIDmode))
++        && dead_or_set_in_peep(2,insn, operands[0])
++      && which_nibble(INTVAL(operands[2])) == 0"
++  [(set (cc0) 
++      (unspec:SI [(match_dup 1) (match_dup 2)] 1))
++   (set (pc) (if_then_else (match_op_dup 3
++                          [(cc0) (const_int 0)])
++           (label_ref (match_dup 4))
++           (pc)))]
++"")
++
++(define_peephole2
++ [(set (match_operand:SI 0 "register_operand" "")
++       (match_operand:SI 1 "nonimmediate_operand_msp430" ""))
++  (set (match_dup 0) (and:SI (match_dup 0) 
++                             (match_operand 2 "const_int_operand" "")))
++  (set (pc) (if_then_else (match_operator:SI 3 "equality_operator"
++                         [(match_dup 0) (const_int 0)])
++          (label_ref (match_operand 4 "" ""))
++          (pc)))]
++"(halfnibble_integer(operands[2], VOIDmode) 
++   || halfnibble_constant(operands[2], VOIDmode))
++        && dead_or_set_in_peep(2,insn, operands[0])
++      && which_nibble(INTVAL(operands[2])) == 1"
++  [(set (cc0) 
++      (unspec:SI [(match_dup 1) (match_dup 2)] 2))
++   (set (pc) (if_then_else (match_op_dup 3
++                          [(cc0) (const_int 0)])
++           (label_ref (match_dup 4))
++           (pc)))]
++"")
++
++
++(define_peephole2
++ [(set (match_operand:SI 0 "register_operand" "")
++       (match_operand:SI 1 "nonimmediate_operand_msp430" ""))
++  (set (match_dup 0) (and:SI (match_dup 0) 
++                             (match_operand 2 "const_int_operand" "")))
++  (set (pc) 
++       (if_then_else (match_operator:HI 3 "equality_operator"
++                    [(match_operand:HI 4 "register_operand" "") (const_int 0)]) 
++       (label_ref (match_operand 5 "" ""))
++       (pc)))]
++"(halfnibble_integer(operands[2], VOIDmode) 
++   || halfnibble_constant(operands[2], VOIDmode))
++        && dead_or_set_in_peep(2,insn, operands[0])
++      && which_nibble(INTVAL(operands[2])) == 1
++      && REGNO(operands[4]) == REGNO(operands[0])+1"
++  [(set (cc0) 
++      (unspec:SI [(match_dup 1) (match_dup 2)] 1))
++   (set (pc) (if_then_else (match_op_dup 3
++                          [(cc0) (const_int 0)])
++           (label_ref (match_dup 5))
++           (pc)))]
++"")
++
++(define_peephole2
++ [(set (match_operand:SI 0 "register_operand" "")
++       (match_operand:SI 1 "nonimmediate_operand_msp430" ""))
++  (set (match_dup 0) (and:SI (match_dup 0) 
++                             (match_operand 2 "const_int_operand" "")))
++  (set (pc) 
++       (if_then_else (match_operator:HI 3 "equality_operator"
++                    [(match_operand:HI 4 "register_operand" "") (const_int 0)]) 
++       (label_ref (match_operand 5 "" ""))
++       (pc)))]
++"(halfnibble_integer(operands[2], VOIDmode) 
++   || halfnibble_constant(operands[2], VOIDmode))
++        && dead_or_set_in_peep(2,insn, operands[0])
++      && which_nibble(INTVAL(operands[2])) == 0
++      && REGNO(operands[4]) == REGNO(operands[0])"
++  [(set (cc0) 
++      (unspec:SI [(match_dup 1) (match_dup 2)] 1))
++   (set (pc) (if_then_else (match_op_dup 3
++                          [(cc0) (const_int 0)])
++           (label_ref (match_dup 5))
++           (pc)))]
++"")
++
++;;
++;;  The same for HI mode: while(smts&0xXXXX) ;
++;;
++(define_insn "*bittest"
++  [(set (cc0)
++        (unspec:HI [(match_operand:HI 0 "general_operand_msp430" "r,r,m,m")
++                    (match_operand:HI 1 "general_operand_msp430" "rPR,mi,rPR,mi")] 6))]
++""
++"bit  %1,%0"
++[(set_attr "length" "1,2,2,3")
++   (set_attr "cc" "compare,compare,compare,compare")])
++
++
++(define_peephole2
++ [(set (match_operand:HI 0 "register_operand" "")
++       (match_operand:HI 1 "nonimmediate_operand_msp430" ""))
++  (set (match_dup 0) (and:HI (match_dup 0) 
++                             (match_operand 2 "const_int_operand" "")))
++  (set (pc) (if_then_else (match_operator:HI 3 "equality_operator"
++                         [(match_dup 0) (const_int 0)])
++          (label_ref (match_operand 4 "" "")) 
++          (pc)))]
++"dead_or_set_in_peep(2,insn, operands[0]) "
++  [(set (cc0) 
++      (unspec:HI [(match_dup 1) (match_dup 2)] 6))
++   (set (pc) (if_then_else (match_op_dup 3
++                          [(cc0) (const_int 0)])
++           (label_ref (match_dup 4))
++           (pc)))]
++"")
++
++
++;; The same for QI mode
++
++(define_insn "*bittest_b"
++  [(set (cc0)
++        (unspec:QI [(match_operand:QI 0 "general_operand_msp430" "r,r,m,m")
++                    (match_operand:QI 1 "general_operand_msp430" "rPR,mi,rPR,mi")] 7))]
++""
++"bit.b        %1,%0"
++[(set_attr "length" "1,2,2,3")
++   (set_attr "cc" "compare,compare,compare,compare")])
++
++
++(define_peephole2
++ [(set (match_operand:QI 0 "register_operand" "")
++       (match_operand:QI 1 "nonimmediate_operand_msp430" ""))
++  (set (match_dup 0) (and:QI (match_dup 0) 
++                             (match_operand 2 "const_int_operand" "")))
++  (set (pc) (if_then_else (match_operator:QI 3 "equality_operator"
++                         [(match_dup 0) (const_int 0)])
++          (label_ref (match_operand 4 "" "")) 
++          (pc)))]
++"dead_or_set_in_peep(2,insn, operands[0]) "
++  [(set (cc0) 
++      (unspec:QI [(match_dup 1) (match_dup 2)] 7))
++   (set (pc) (if_then_else (match_op_dup 3
++                          [(cc0) (const_int 0)])
++           (label_ref (match_dup 4))
++           (pc)))]
++"")
++
++
++
++;;===========================================================================
++
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++        (match_operand:QI 1 "general_operand_msp430" ""))
++   (set (match_dup 0)
++      (minus:QI (match_dup 0) 
++                (match_operand:QI 2 "general_operand_msp430" "")))
++   (set (match_operand:QI 3 "register_operand" "")
++      (match_dup 0))]
++"dead_or_set_in_peep(2,insn, operands[0]) && 0"
++  [(set (match_dup 3) (match_dup 1))
++   (set (match_dup 3) (minus:QI (match_dup 3) (match_dup 2)))]
++"")
++
++
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++        (match_operand:QI 1 "general_operand_msp430" ""))
++   (set (match_dup 0)
++      (plus:QI (match_dup 0) 
++               (match_operand:QI 2 "general_operand_msp430" "")))
++   (set (match_operand:QI 3 "register_operand" "")
++      (match_dup 0))]
++"dead_or_set_in_peep(2,insn, operands[0]) && 0"
++  [(set (match_dup 3) (match_dup 1))
++   (set (match_dup 3) (plus:QI (match_dup 3) (match_dup 2)))]
++"")
++
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "")
++        (match_operand:HI 1 "general_operand_msp430" ""))
++   (set (match_dup 0)
++      (minus:HI (match_dup 0) 
++                (match_operand:HI 2 "general_operand_msp430" "")))
++   (set (match_operand:HI 3 "register_operand" "")
++      (match_dup 0))]
++"dead_or_set_in_peep(2,insn, operands[0]) && 0"
++  [(set (match_dup 3) (match_dup 1))
++   (set (match_dup 3) (minus:HI (match_dup 3) (match_dup 2)))]
++"")
++
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "")
++        (match_operand:HI 1 "general_operand_msp430" ""))
++   (set (match_dup 0)
++      (plus:HI (match_dup 0) 
++               (match_operand:HI 2 "general_operand_msp430" "")))
++   (set (match_operand:HI 3 "register_operand" "")
++      (match_dup 0))]
++"dead_or_set_in_peep(2,insn, operands[0]) && 0"
++  [(set (match_dup 3) (match_dup 1))
++   (set (match_dup 3) (plus:HI (match_dup 3) (match_dup 2)))]
++"")
++
++
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "")
++        (match_operand:SI 1 "general_operand_msp430" ""))
++   (set (match_dup 0)
++      (minus:SI (match_dup 0) 
++                (match_operand:SI 2 "general_operand_msp430" "")))
++   (set (match_operand:SI 3 "register_operand" "")
++      (match_dup 0))]
++"dead_or_set_in_peep(2,insn, operands[0]) && 0"
++  [(set (match_dup 3) (match_dup 1))
++   (set (match_dup 3) (minus:SI (match_dup 3) (match_dup 2)))]
++"")
++
++
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "")
++        (match_operand:SI 1 "general_operand_msp430" ""))
++   (set (match_dup 0)
++      (plus:SI (match_dup 0) 
++               (match_operand:SI 2 "general_operand_msp430" "")))
++   (set (match_operand:SI 3 "register_operand" "")
++      (match_dup 0))]
++"dead_or_set_in_peep(2,insn, operands[0]) && 0"
++  [(set (match_dup 3) (match_dup 1))
++   (set (match_dup 3) (plus:SI (match_dup 3) (match_dup 2)))]
++"")
++
++
++;; =============================================================
++;; 
++;;  adjust frame pointer index
++;;
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") 
++      (sign_extend:HI (match_operand:QI 1 "general_operand_msp430" "")))
++   (set (match_dup 0) 
++      (plus:HI (match_dup 0) (match_operand:HI 2 "general_operand_msp430" "")))
++   (set (match_operand:HI 3 "register_operand" "")
++      (match_dup 0))]
++"dead_or_set_in_peep(2,insn, operands[0])"
++  [(set (match_dup 3) (sign_extend:HI (match_dup 1)))
++   (set (match_dup 3) (plus:HI (match_dup 3) (match_dup 2)))]
++"")
++
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "") 
++      (sign_extend:SI (match_operand:HI 1 "general_operand_msp430" "")))
++   (set (match_dup 0) 
++      (plus:SI (match_dup 0) (match_operand:SI 2 "general_operand_msp430" "")))
++   (set (match_operand:SI 3 "register_operand" "")
++      (match_dup 0))]
++"dead_or_set_in_peep(2,insn, operands[0])"
++  [(set (match_dup 3) (sign_extend:SI (match_dup 1)))
++   (set (match_dup 3) (plus:SI (match_dup 3) (match_dup 2)))]
++"")
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") 
++      (sign_extend:HI (match_operand:QI 1 "general_operand_msp430" "")))
++   (set (match_dup 0) 
++      (minus:HI (match_dup 0) (match_operand:HI 2 "general_operand_msp430" "")))
++   (set (match_operand:HI 3 "register_operand" "")
++      (match_dup 0))]
++"dead_or_set_in_peep(2,insn, operands[0])"
++  [(set (match_dup 3) (sign_extend:HI (match_dup 1)))
++   (set (match_dup 3) (minus:HI (match_dup 3) (match_dup 2)))]
++"")
++
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "") 
++      (sign_extend:SI (match_operand:HI 1 "general_operand_msp430" "")))
++   (set (match_dup 0) 
++      (minus:SI (match_dup 0) (match_operand:SI 2 "general_operand_msp430" "")))
++   (set (match_operand:SI 3 "register_operand" "")
++      (match_dup 0))]
++"dead_or_set_in_peep(2,insn, operands[0])"
++  [(set (match_dup 3) (sign_extend:SI (match_dup 1)))
++   (set (match_dup 3) (minus:SI (match_dup 3) (match_dup 2)))]
++"")
++
++;; =============================================================
++;; mov & 'and'
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") 
++      (match_operand:HI 1 "nonimmediate_operand_msp430" ""))
++   (set (match_dup 0) 
++      (and:HI (match_dup 0) 
++              (match_operand:HI 2 "general_operand_msp430" ""))) 
++   (set (match_dup 1) (match_dup 0))]
++"dead_or_set_in_peep(2,insn, operands[0])"
++  [(set (match_dup 1) 
++      (and:HI (match_dup 1) (match_dup 2)))]
++"")
++
++
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "") 
++      (match_operand:SI 1 "nonimmediate_operand_msp430" ""))
++   (set (match_dup 0) 
++      (and:SI (match_dup 0) 
++              (match_operand:SI 2 "general_operand_msp430" ""))) 
++   (set (match_dup 1) (match_dup 0))]
++"dead_or_set_in_peep(2,insn, operands[0])"
++  [(set (match_dup 1) 
++      (and:SI (match_dup 1) (match_dup 2)))]
++"")
++
++
++
++;; =============================================================
++;; SWAP BYTES (should be a pattern for:
++;;   r = (a<<8)|(a>>8);
++
++(define_insn "swpb"
++  [(set (match_operand:HI 0 "nonimmediate_operand_msp430" "=rR,m") 
++      (unspec:HI [(match_operand:HI 1 "nonimmediate_operand_msp430" "0,0")] 4))]
++""
++"swpb %0"
++[(set_attr "length" "1,2")
++   (set_attr "cc" "clobber,clobber")])
++
++;;
++;; after mult and stuff
++;;
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "") 
++      (reg:SI 14))
++   (set (match_operand:SI 1 "nonimmediate_operand_msp430" "") 
++      (match_dup 0))]
++"dead_or_set_in_peep(1,insn,operands[0])"
++  [(set (match_dup 1) (reg:SI 14))]
++"")
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") 
++      (reg:HI 14))
++   (set (match_operand:HI 1 "nonimmediate_operand_msp430" "") 
++      (match_dup 0))]
++"dead_or_set_in_peep(1,insn,operands[0])"
++  [(set (match_dup 1) (reg:HI 14))]
++"")
++
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "") 
++      (reg:SI 12))
++   (set (match_operand:SI 1 "nonimmediate_operand_msp430" "") 
++      (match_dup 0))]
++"dead_or_set_in_peep(1,insn,operands[0])"
++  [(set (match_dup 1) (reg:SI 12))]
++"")
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") 
++      (reg:HI 12))
++   (set (match_operand:HI 1 "nonimmediate_operand_msp430" "") 
++      (match_dup 0))]
++"dead_or_set_in_peep(1,insn,operands[0])"
++  [(set (match_dup 1) (reg:HI 12))]
++"")
++
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "") 
++      (sign_extend:SI (match_operand:QI 1 "general_operand_msp430" "")))
++   (set (match_operand:SI 2 "nonimmediate_operand_msp430" "") 
++      (match_dup 0))]
++"dead_or_set_in_peep(1,insn,operands[0])"
++  [(set (match_dup 2) (sign_extend:SI (match_dup 1)))]
++"")
++
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "") 
++      (sign_extend:SI (match_operand:HI 1 "general_operand_msp430" "")))
++   (set (match_operand:SI 2 "nonimmediate_operand_msp430" "") 
++      (match_dup 0))]
++"dead_or_set_in_peep(1,insn,operands[0])"
++  [(set (match_dup 2) (sign_extend:SI (match_dup 1)))]
++"")
++
++
++;; =============================================================
++
++(define_peephole 
++  [(set (match_operand:HI 0 "register_operand" "") 
++      (sign_extend:HI (match_operand:QI 1 "register_operand" ""))) 
++   (set (match_operand:HI 2 "register_operand" "") 
++      (plus:HI (match_dup 2) (match_dup 0)))]
++"dead_or_set_in_peep(1,insn,operands[0])" 
++"sxt  %1
++      add     %1, %2"
++[(set_attr "length" "3")
++   (set_attr "cc" "clobber")])
++
++
++(define_peephole 
++  [(set (match_operand:HI 0 "register_operand" "") 
++      (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand_msp430" ""))) 
++   (set (match_operand:HI 2 "register_operand" "") (match_dup 0))]
++"dead_or_set_in_peep(1,insn,operands[0])" 
++"mov.b        %1, %2
++      sxt     %2"
++[(set_attr "length" "2")
++   (set_attr "cc" "clobber")])
++
++;; ============================================================= 
++;; a = (uint16_t)( (uint8_t)SFR ) << 8;
++;; (inderect_jump + 50)
++(define_peephole 
++  [(set (match_operand:QI 0 "register_operand" "") 
++      (match_operand:QI 1 "memory_operand_msp430" "m"))
++   (set (match_operand:HI 2 "register_operand" "")
++      (ashift:HI (match_dup 2) (const_int 8)))]
++  "REGNO(operands[0]) == REGNO(operands[2])"
++"mov.b        %1, %0
++      swpb    %2"
++[(set_attr "length" "3")
++   (set_attr "cc" "clobber")])
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") 
++      (ior:HI (match_dup 0) 
++              (match_operand:HI 1 "register_operand" "")))
++   (set (match_operand:SI 2 "register_operand" "") 
++      (match_operand:SI 3 "register_operand" ""))]
++"(REGNO(operands[0]) == REGNO(operands[2])
++  && REGNO(operands[3])+1 == REGNO(operands[0]))"
++  [(set (match_dup 1) 
++      (ior:HI (match_dup 1) 
++              (match_dup 0)))
++   (set (subreg:HI (match_dup 2) 0)
++      (subreg:HI (match_dup 3) 0))]
++"")
++
++
++
++;; =============================================================
++;; combine ior and mov.
++;;
++(define_peephole2
++[(set (match_operand:QI 0 "register_operand" "") 
++      (ior:QI (match_dup 0) 
++                    (match_operand:QI 1 "nonimmediate_operand_msp430" "")))
++ (set (match_dup 1) (match_dup 0))]
++"dead_or_set_in_peep(1,insn,operands[0])"
++[(set (match_dup 1) (ior:QI (match_dup 1) (match_dup 0)))]
++"")
++
++(define_peephole2
++[(set (match_operand:HI 0 "register_operand" "") 
++      (ior:HI (match_dup 0) 
++                    (match_operand:HI 1 "nonimmediate_operand_msp430" "")))
++ (set (match_dup 1) (match_dup 0))]
++"dead_or_set_in_peep(1,insn,operands[0])"
++[(set (match_dup 1) (ior:HI (match_dup 1) (match_dup 0)))]
++"")
++
++(define_peephole2
++[(set (match_operand:SI 0 "register_operand" "") 
++      (ior:SI (match_dup 0) 
++                    (match_operand:SI 1 "nonimmediate_operand_msp430" "")))
++ (set (match_dup 1) (match_dup 0))]
++"dead_or_set_in_peep(1,insn,operands[0])"
++[(set (match_dup 1) (ior:SI (match_dup 1) (match_dup 0)))]
++"")
++
++(define_peephole2
++[(set (match_operand:DI 0 "register_operand" "") 
++      (ior:DI (match_dup 0) 
++                    (match_operand:DI 1 "nonimmediate_operand_msp430" "")))
++ (set (match_dup 1) (match_dup 0))]
++"dead_or_set_in_peep(1,insn,operands[0])"
++[(set (match_dup 1) (ior:DI (match_dup 1) (match_dup 0)))]
++"")
++
++
++;; ======================================================================
++
++;; Enable Interrupts
++(define_insn "enable_interrupt"
++  [(unspec [(const_int 0)] UNSPEC_EINT)]
++  ""
++  "eint"
++  [(set_attr "length" "1")
++  (set_attr "cc" "none")
++  ])
++
++;; Disable Interrupts
++(define_insn "disable_interrupt"
++  [(unspec [(const_int 0)] UNSPEC_DINT)]
++  ""
++  "dint"
++  [(set_attr "length" "1")
++  (set_attr "cc" "none")
++  ])
++
++
++;; return insn
++(define_insn "return"
++  [(return)]
++  "reload_completed && msp430_empty_epilogue()"
++  "* return msp430_emit_return(insn, operands, NULL);"
++  [(set_attr "length" "1")
++   (set_attr "cc" "clobber")]
++)
++
++(define_insn "return_from_epilogue"
++  [(return)]
++  "(reload_completed 
++    && cfun->machine 
++    && !(cfun->machine->is_interrupt || cfun->machine->is_critical)
++    && !cfun->machine->is_naked)"
++  "ret"
++  [(set_attr "cc" "none")
++   (set_attr "length" "1")])
++
++(define_insn "return_from_interrupt_epilogue"
++  [(return)]
++  "(reload_completed 
++    && cfun->machine 
++    && (cfun->machine->is_interrupt || cfun->machine->is_critical)
++    && !cfun->machine->is_naked)"
++  "reti"
++  [(set_attr "cc" "none")
++   (set_attr "length" "1")])
++
++(define_insn "return_from_naked_epilogue"
++  [(return)]
++  "(reload_completed 
++    && cfun->machine 
++    && cfun->machine->is_naked)"
++  ""
++  [(set_attr "cc" "none")
++   (set_attr "length" "0")])
++
++(define_expand "prologue"
++  [(const_int 0)]
++  ""
++  "
++  {
++    expand_prologue (); 
++    DONE;
++  }")
++
++(define_expand "epilogue"
++  [(const_int 0)]
++  ""
++  "
++  {
++    expand_epilogue (); 
++    DONE;
++  }")
+diff -urNad msp430-gcc~/gcc/config/msp430/msp430.opt msp430-gcc/gcc/config/msp430/msp430.opt
+--- msp430-gcc~/gcc/config/msp430/msp430.opt   1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/msp430.opt    2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1,81 @@
++; Options for the MSP430 port of the compiler.
++; Converted from msp430.c (gcc 3.2.3 port)
++
++; For every option from this file (such as PROF_STD), a corresponding command-line option is checked and an internal GCC flag is set.
++; To check such flag one should use the TARGET_xxx macro (such as TARGET_PROF_STD).
++; This replaces the deprecated #define TARGET_SWITCHES syntax
++; String options are defined similarily and replace the #define TARGET_OPTIONS syntax
++
++;; This work is partially financed by the European Commission under the
++;; Framework 6 Information Society Technologies Project
++;; "Wirelessly Accessible Sensor Populations (WASP)".
++
++mpgs
++Target Report Mask(PROF_STD)
++Add ordinary profile information
++
++mpgl
++Target Report Mask(PROF_LIB)
++Add ordinary profile information
++
++mpgr
++Target Report Mask(PROF_STACK)
++Add stack information to profiler
++
++mrtl
++Target Report Mask(RTL_DUMP)
++Dump RTL
++
++mdeb
++Target Report Mask(ALL_DEBUG)
++Dump all debug info
++
++mforce-hwmul
++Target Report Mask(FORCE_HWMUL)
++Force hardware multiplier
++
++mdisable-hwmul
++Target Report Mask(NO_HWMUL)
++Disable hardware multiplier
++
++minline-hwmul
++Target Report Mask(INLINESIHWMUL)
++Issue inline multiplication code for 32-bit integers
++
++mnoint-hwmul
++Target Report Mask(NOINT_HWMUL)
++Assume interrupt routine does not do hardware multiply
++
++mIAR
++Target Report Mask(IAR)
++Produce IAR assembler syntax
++
++mno-stack-init
++Target Report Mask(NO_STACK_INIT)
++No stack init in main()
++
++mno-volatile-workaround
++Target Report Mask(NVWA)
++Do not perform volatile workaround for bitwise operations
++
++msave-prologue
++Target Report Mask(SAVE_PROLOGUE)
++Use subroutine call for function prologue/epilogue when possible
++
++; ---------------------------------------- Here start the string options imported from TARGET_OPTIONS macro ----------------------------------------
++
++mmcu=
++Target RejectNegative Joined Var(msp430_mcu_name) Init("msp430x169")
++-mmcu=MCU     Select the target MCU
++
++mendup-at=
++Target RejectNegative Joined Var(msp430_endup) Init("__stop_progExec__")
++-mendup-at=ENDUP      Jump to specified routine at the end of main()
++
++minit-stack=
++Target RejectNegative Joined Var(msp430_init_stack) Init("__stack")
++-minit-stack=STACK    Use STACK as the initial value of the stack pointer
++
++maccumulate-outgoing-args
++Target Report Mask(ACCUMULATE_OUTGOING_ARGS) Save
++Reserve space for outgoing arguments in the function prologue
+diff -urNad msp430-gcc~/gcc/config/msp430/objs-extra msp430-gcc/gcc/config/msp430/objs-extra
+--- msp430-gcc~/gcc/config/msp430/objs-extra   1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/objs-extra    2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1 @@
++msp430-emit-cbranch.o msp430-cbranch.o msp430-builtins.o msp430-function.o
+\ No newline at end of file
+diff -urNad msp430-gcc~/gcc/config/msp430/predicates.md msp430-gcc/gcc/config/msp430/predicates.md
+--- msp430-gcc~/gcc/config/msp430/predicates.md        1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/predicates.md 2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1,106 @@
++;; Predicate definitions for MSP430
++;; Copyright (C) 2006 Free Software Foundation, Inc.
++
++;; This file is part of GCC.
++
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published
++;; by the Free Software Foundation; either version 2, or (at your
++;; option) any later version.
++
++;; GCC is distributed in the hope that it will be useful, but WITHOUT
++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
++;; License for more details.
++
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING.  If not, write to
++;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++;; Boston, MA 02110-1301, USA.
++
++;; This work is partially financed by the European Commission under the
++;; Framework 6 Information Society Technologies Project
++;; "Wirelessly Accessible Sensor Populations (WASP)".
++
++;; <==== Comment by Ivan Shcherbakov ====>
++;; All predicates here were checked againist latest port of GCC 3.2.3
++(define_special_predicate "equality_operator"
++  (match_code "eq,ne")
++{
++  return ((mode == VOIDmode || GET_MODE (op) == mode) && (GET_CODE (op) == EQ || GET_CODE (op) == NE));
++})
++
++(define_special_predicate "inequality_operator"
++  (match_code "ge,gt,le,lt,geu,gtu,leu,ltu")
++{
++  return comparison_operator (op, mode) && !equality_operator (op, mode);
++})
++
++(define_predicate "nonimmediate_operand_msp430"
++  (match_code "reg,subreg,mem")
++{
++  int save_volatile_ok = volatile_ok;
++  int niop = 0;
++
++  if (!TARGET_NVWA)
++    volatile_ok = 1;
++  niop = nonimmediate_operand (op, mode);
++  volatile_ok = save_volatile_ok;
++
++  return niop;
++})
++
++(define_predicate "memory_operand_msp430"
++  (match_code "subreg,mem")
++{
++  int save_volatile_ok = volatile_ok;
++  int mop = 0;
++
++  if (!TARGET_NVWA)
++    volatile_ok = 1;
++  mop = memory_operand (op, mode);
++  volatile_ok = save_volatile_ok;
++  return mop;
++})
++
++(define_predicate "general_operand_msp430"
++  (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem")
++{
++  int save_volatile_ok = volatile_ok;
++  int gop = 0;
++
++  if (!TARGET_NVWA)
++    volatile_ok = 1;
++  gop = general_operand (op, mode);
++  volatile_ok = save_volatile_ok;
++  return gop;
++})
++
++(define_predicate "three_operands_msp430"
++  (match_code "plus,minus,and,ior,xor")
++{
++  enum rtx_code code = GET_CODE (op);
++  if (GET_MODE (op) != mode)
++    return 0;
++
++  return (code == PLUS || code == MINUS || code == AND || code == IOR || code == XOR);
++})
++
++;; True for any non-virtual or eliminable register.  Used in places where
++;; instantiation of such a register may cause the pattern to not be recognized.
++(define_predicate "register_no_elim_operand"
++  (match_operand 0 "register_operand")
++{
++  if (GET_CODE (op) == SUBREG)
++    op = SUBREG_REG (op);
++  return !(op == arg_pointer_rtx
++         || op == frame_pointer_rtx
++         || IN_RANGE (REGNO (op),
++                      FIRST_PSEUDO_REGISTER, LAST_VIRTUAL_REGISTER));
++})
++
++;; Return false if this is any eliminable register.  Otherwise general_operand.
++(define_predicate "general_no_elim_operand"
++  (if_then_else (match_code "reg,subreg")
++    (match_operand 0 "register_no_elim_operand")
++    (match_operand 0 "general_operand")))
+diff -urNad msp430-gcc~/gcc/config/msp430/t-msp430 msp430-gcc/gcc/config/msp430/t-msp430
+--- msp430-gcc~/gcc/config/msp430/t-msp430     1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/t-msp430      2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1,153 @@
++# Specific names for MSP430 tools
++AR_FOR_TARGET = msp430-ar
++RANLIB_FOR_TARGET = msp430-ranlib
++NM_FOR_TARGET = msp430-nm
++
++CROSS_LIBGCC1 = libgcc1-asm.a
++LIB1ASMSRC = msp430/libgcc.S
++LIB1ASMFUNCS = _cmpdi2 \
++      _cmpsf2 \
++      __stop_progExec__ \
++      _mulqi3 \
++      _mulhi3 \
++      _mulsi3 \
++      _mulsi3hw \
++      _umulqihi3 \
++      _umulhisi3 \
++      _mulqihi3 \
++      _mulhisi3 \
++      _udivmodqi4 \
++      _divmodqi4 \
++      _udivmodhi4 \
++      _divmodhi4 \
++      _udivmodsi4 \
++      _divmodsi4 \
++      _reset_vector__ \
++      __prologue_saver \
++      __epilogue_restorer \
++      __epilogue_restorer_intr \
++      _udivmoddi3_parts \
++      _udivdi3 \
++      _umoddi3 \
++      _divdi3 \
++      _moddi3 \
++      _muldi3 \
++      __low_level_init \
++      __init_stack \
++      _copy_data \
++      _clear_bss \
++      _ctors \
++      __jump_to_main \
++      _dtors
++      
++      
++
++# libgcc...
++LIBGCC1_TEST =
++
++# We do not have the DF type.
++# Most of the C functions in libgcc2 use almost all registers,
++TARGET_LIBGCC2_CFLAGS = -DDF=SF -Dinhibit_libc -g
++
++fp-bit.c: $(srcdir)/config/fp-bit.c $(srcdir)/config/msp430/t-msp430
++      echo '#define FLOAT' > fp-bit.c
++      echo '#define FLOAT_ONLY' >> fp-bit.c
++      echo '#define CMPtype HItype' >> fp-bit.c
++      echo '#define DF SF' >> fp-bit.c
++      echo '#define DI SI' >> fp-bit.c
++      echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
++      echo '#define SMALL_MACHINE' >> fp-bit.c
++      cat $(srcdir)/config/fp-bit.c >> fp-bit.c
++
++FPBIT = fp-bit.c
++
++MULTILIB_OPTIONS = mmcu=msp1/mmcu=msp2
++MULTILIB_DIRNAMES = msp1 msp2
++
++
++MULTILIB_MATCHES = \
++      mmcu?msp1=mmcu?msp430x110   mmcu?msp1=mmcu?msp430x112 \
++      mmcu?msp1=mmcu?msp430x1101  mmcu?msp1=mmcu?msp430x1111  mmcu?msp1=mmcu?msp430x1121 \
++      mmcu?msp1=mmcu?msp430x1122  mmcu?msp1=mmcu?msp430x1132 \
++      mmcu?msp1=mmcu?msp430x122   mmcu?msp1=mmcu?msp430x123 \
++      mmcu?msp1=mmcu?msp430x1222  mmcu?msp1=mmcu?msp430x1232 \
++      mmcu?msp1=mmcu?msp430x133   mmcu?msp1=mmcu?msp430x135 \
++      mmcu?msp1=mmcu?msp430x1331  mmcu?msp1=mmcu?msp430x1351 \
++      mmcu?msp2=mmcu?msp430x147   mmcu?msp2=mmcu?msp430x148   mmcu?msp2=mmcu?msp430x149 \
++      mmcu?msp2=mmcu?msp430x1471  mmcu?msp2=mmcu?msp430x1481  mmcu?msp2=mmcu?msp430x1491 \
++      mmcu?msp1=mmcu?msp430x155   mmcu?msp1=mmcu?msp430x156   mmcu?msp1=mmcu?msp430x157 \
++      mmcu?msp2=mmcu?msp430x167   mmcu?msp2=mmcu?msp430x168   mmcu?msp2=mmcu?msp430x169 \
++      mmcu?msp2=mmcu?msp430x1610  mmcu?msp2=mmcu?msp430x1611  mmcu?msp2=mmcu?msp430x1612 \
++      mmcu?msp1=mmcu?msp430x2001  mmcu?msp1=mmcu?msp430x2011 \
++      mmcu?msp1=mmcu?msp430x2002  mmcu?msp1=mmcu?msp430x2012 \
++      mmcu?msp1=mmcu?msp430x2003  mmcu?msp1=mmcu?msp430x2013 \
++      mmcu?msp1=mmcu?msp430x2101  mmcu?msp1=mmcu?msp430x2111  mmcu?msp1=mmcu?msp430x2121 \
++      mmcu?msp1=mmcu?msp430x2131 \
++      mmcu?msp1=mmcu?msp430x2112  mmcu?msp1=mmcu?msp430x2122 \
++      mmcu?msp1=mmcu?msp430x2232  mmcu?msp1=mmcu?msp430x2252  mmcu?msp1=mmcu?msp430x2272 \
++      mmcu?msp1=mmcu?msp430x2234  mmcu?msp1=mmcu?msp430x2254  mmcu?msp1=mmcu?msp430x2274 \
++      mmcu?msp2=mmcu?msp430x233   mmcu?msp2=mmcu?msp430x235 \
++      mmcu?msp2=mmcu?msp430x2330  mmcu?msp2=mmcu?msp430x2350  mmcu?msp2=mmcu?msp430x2370 \
++      mmcu?msp2=mmcu?msp430x247   mmcu?msp2=mmcu?msp430x248   mmcu?msp2=mmcu?msp430x249 \
++      mmcu?msp2=mmcu?msp430x2410 \
++      mmcu?msp2=mmcu?msp430x2471  mmcu?msp2=mmcu?msp430x2481  mmcu?msp2=mmcu?msp430x2491 \
++      mmcu?msp2=mmcu?msp430x2416  mmcu?msp2=mmcu?msp430x2417  mmcu?msp2=mmcu?msp430x2418 \
++      mmcu?msp2=mmcu?msp430x2419 \
++      mmcu?msp2=mmcu?msp430x2616  mmcu?msp2=mmcu?msp430x2617  mmcu?msp2=mmcu?msp430x2618 \
++      mmcu?msp2=mmcu?msp430x2619 \
++      mmcu?msp1=mmcu?msp430x311   mmcu?msp1=mmcu?msp430x312   mmcu?msp1=mmcu?msp430x313 \
++      mmcu?msp1=mmcu?msp430x314   mmcu?msp1=mmcu?msp430x315 \
++      mmcu?msp1=mmcu?msp430x323   mmcu?msp1=mmcu?msp430x325 \
++      mmcu?msp2=mmcu?msp430x336   mmcu?msp2=mmcu?msp430x337 \
++      mmcu?msp1=mmcu?msp430x412   mmcu?msp1=mmcu?msp430x413 \
++      mmcu?msp1=mmcu?msp430x415   mmcu?msp1=mmcu?msp430x417 \
++      mmcu?msp2=mmcu?msp430x423   mmcu?msp2=mmcu?msp430x425   mmcu?msp2=mmcu?msp430x427 \
++      mmcu?msp1=mmcu?msp430x4250  mmcu?msp1=mmcu?msp430x4260  mmcu?msp1=mmcu?msp430x4270 \
++      mmcu?msp1=mmcu?msp430xG4250 mmcu?msp1=mmcu?msp430xG4260 mmcu?msp1=mmcu?msp430xG4270 \
++      mmcu?msp2=mmcu?msp430xE423  mmcu?msp2=mmcu?msp430xE425  mmcu?msp2=mmcu?msp430xE427 \
++      mmcu?msp2=mmcu?msp430xE4232 mmcu?msp2=mmcu?msp430xE4242 mmcu?msp2=mmcu?msp430xE4252 \
++      mmcu?msp2=mmcu?msp430xE4272 \
++      mmcu?msp1=mmcu?msp430xW423  mmcu?msp1=mmcu?msp430xW425  mmcu?msp1=mmcu?msp430xW427 \
++      mmcu?msp1=mmcu?msp430xG437  mmcu?msp1=mmcu?msp430xG438  mmcu?msp1=mmcu?msp430xG439 \
++      mmcu?msp1=mmcu?msp430x435   mmcu?msp1=mmcu?msp430x436   mmcu?msp1=mmcu?msp430x437 \
++      mmcu?msp1=mmcu?msp430x4351  mmcu?msp1=mmcu?msp430x4361  mmcu?msp1=mmcu?msp430x4371 \
++      mmcu?msp2=mmcu?msp430x447   mmcu?msp2=mmcu?msp430x448   mmcu?msp2=mmcu?msp430x449 \
++      mmcu?msp2=mmcu?msp430xG4616 mmcu?msp2=mmcu?msp430xG4617 mmcu?msp2=mmcu?msp430xG4618 \
++      mmcu?msp2=mmcu?msp430xG4619 \
++      mmcu?msp2=mmcu?msp430x4783  mmcu?msp2=mmcu?msp430x4784  mmcu?msp2=mmcu?msp430x4793 \
++      mmcu?msp2=mmcu?msp430x4794 \
++      mmcu?msp2=mmcu?msp430x5418 mmcu?msp2=mmcu?msp430x5419 \
++      mmcu?msp2=mmcu?msp430x5435 mmcu?msp2=mmcu?msp430x5436 mmcu?msp2=mmcu?msp430x5437 \
++      mmcu?msp2=mmcu?msp430x5438 \
++      mmcu?msp2=mmcu?cc430x5123 \
++      mmcu?msp2=mmcu?cc430x5125 mmcu?msp2=mmcu?cc430x6125 mmcu?msp2=mmcu?cc430x6135 \
++      mmcu?msp2=mmcu?cc430x6126 \
++      mmcu?msp2=mmcu?cc430x5137 mmcu?msp2=mmcu?cc430x6127 mmcu?msp2=mmcu?cc430x6137
++#todo: 47xx has 32*32 HW MUL
++#todo: 54xx has 32*32 HW MUL
++
++MULTILIB_EXCEPTIONS =
++
++LIBGCC = stmp-multilib
++INSTALL_LIBGCC = install-multilib
++
++##STMP_FIXINC =
++
++msp430-cbranch.o: $(srcdir)/config/msp430/msp430-cbranch.c $(CONFIG_H) $(SYSTEM_H) \
++    coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H)
++      $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/msp430/msp430-cbranch.c
++
++msp430-emit-cbranch.o: $(srcdir)/config/msp430/msp430-cbranch.c $(CONFIG_H) $(SYSTEM_H) \
++    coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H)
++      $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/msp430/msp430-emit-cbranch.c
++
++msp430-builtins.o: $(srcdir)/config/msp430/msp430-builtins.c $(CONFIG_H) $(SYSTEM_H) \
++    coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H)
++      $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/msp430/msp430-builtins.c
++
++msp430-function.o: $(srcdir)/config/msp430/msp430-function.c $(CONFIG_H) $(SYSTEM_H) \
++    coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H)
++      $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/msp430/msp430-function.c
++
++
++      
+\ No newline at end of file
+diff -urNad msp430-gcc~/gcc/config/msp430/xm-msp430.h msp430-gcc/gcc/config/msp430/xm-msp430.h
+--- msp430-gcc~/gcc/config/msp430/xm-msp430.h  1969-12-31 17:00:00.000000000 -0700
++++ msp430-gcc/gcc/config/msp430/xm-msp430.h   2010-05-20 16:31:52.000000000 -0600
+@@ -0,0 +1 @@
++#include "tm.h"