X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=debian%2Fpatches%2F002-mspgcc-3.2.3-20080819.dpatch;fp=debian%2Fpatches%2F002-mspgcc-3.2.3-20080819.dpatch;h=0000000000000000000000000000000000000000;hb=ed54066d0752082b14a3f96c251fbc04edd411ec;hp=3b50dc813d97db41447dd6ac86a022b9006d4522;hpb=37aa8acf60b5c7701cab3d702d2900ca69af7853;p=msp430-gcc.git 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 index 3b50dc81..00000000 --- a/debian/patches/002-mspgcc-3.2.3-20080819.dpatch +++ /dev/null @@ -1,19291 +0,0 @@ -#! /bin/sh /usr/share/dpatch/dpatch-run -## 001-mspgcc-3.2.3-20080819.dpatch by -## -## 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 -+ -+ 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 -+ 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 -+ -+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 -+*/ -+ -+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 &®NO(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 -+ -+;; 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<-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 -+ -+ 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. -+-------------------------------------------------------------------