diff -ru gcc-4.1.2/boehm-gc/configure gcc-4.1.2-futaris/boehm-gc/configure --- gcc-4.1.2/boehm-gc/configure 2007-02-14 05:17:22.000000000 +0000 +++ gcc-4.1.2-futaris/boehm-gc/configure 2007-08-27 13:21:53.000000000 +0100 @@ -4320,6 +4320,11 @@ lt_cv_deplibs_check_method=pass_all ;; +linux-uclibc*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` + ;; + netbsd* | knetbsd*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' diff -ru gcc-4.1.2/boehm-gc/include/gc.h gcc-4.1.2-futaris/boehm-gc/include/gc.h --- gcc-4.1.2/boehm-gc/include/gc.h 2005-01-02 03:35:57.000000000 +0000 +++ gcc-4.1.2-futaris/boehm-gc/include/gc.h 2007-08-27 13:21:53.000000000 +0100 @@ -500,7 +500,7 @@ #ifdef __linux__ # include # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \ - && !defined(__ia64__) + && !defined(__ia64__) && !defined(__UCLIBC__) # ifndef GC_HAVE_BUILTIN_BACKTRACE # define GC_HAVE_BUILTIN_BACKTRACE # endif diff -ru gcc-4.1.2/configure gcc-4.1.2-futaris/configure --- gcc-4.1.2/configure 2006-11-21 17:48:36.000000000 +0000 +++ gcc-4.1.2-futaris/configure 2007-08-27 13:21:53.000000000 +0100 @@ -1133,7 +1133,7 @@ ;; "") case "${target}" in - *-*-linux*-gnu | *-*-gnu* | *-*-k*bsd*-gnu) + *-*-linux*-gnu | *-*-gnu* | *-*-k*bsd*-gnu | *-*-linux-uclibc*) # Enable libmudflap by default in GNU and friends. ;; *-*-freebsd*) @@ -3196,7 +3196,7 @@ # for target_alias and gcc doesn't manage it consistently. target_configargs="--cache-file=./config.cache --build=${build_alias} --host=${target_alias} --target=${target_alias} ${target_configargs}" -FLAGS_FOR_TARGET= +FLAGS_FOR_TARGET="$ARCH_FLAGS_FOR_TARGET" case " $target_configdirs " in *" newlib "*) case " $target_configargs " in diff -ru gcc-4.1.2/configure.in gcc-4.1.2-futaris/configure.in --- gcc-4.1.2/configure.in 2006-11-21 17:48:36.000000000 +0000 +++ gcc-4.1.2-futaris/configure.in 2007-08-27 13:21:53.000000000 +0100 @@ -341,7 +341,7 @@ ;; "") case "${target}" in - *-*-linux*-gnu | *-*-gnu* | *-*-k*bsd*-gnu) + *-*-linux*-gnu | *-*-gnu* | *-*-k*bsd*-gnu | *-*-linux-uclibc*) # Enable libmudflap by default in GNU and friends. ;; *-*-freebsd*) @@ -1985,7 +1985,7 @@ # for target_alias and gcc doesn't manage it consistently. target_configargs="--cache-file=./config.cache --build=${build_alias} --host=${target_alias} --target=${target_alias} ${target_configargs}" -FLAGS_FOR_TARGET= +FLAGS_FOR_TARGET="$ARCH_FLAGS_FOR_TARGET" case " $target_configdirs " in *" newlib "*) case " $target_configargs " in Only in gcc-4.1.2-futaris: configure.in.orig Only in gcc-4.1.2-futaris: configure.orig diff -ru gcc-4.1.2/contrib/regression/objs-gcc.sh gcc-4.1.2-futaris/contrib/regression/objs-gcc.sh --- gcc-4.1.2/contrib/regression/objs-gcc.sh 2005-08-15 01:41:31.000000000 +0100 +++ gcc-4.1.2-futaris/contrib/regression/objs-gcc.sh 2007-08-27 13:21:53.000000000 +0100 @@ -105,6 +105,10 @@ then make all-gdb all-dejagnu all-ld || exit 1 make install-gdb install-dejagnu install-ld || exit 1 +elif [ $H_REAL_TARGET = $H_REAL_HOST -a $H_REAL_TARGET = i686-pc-linux-uclibc ] + then + make all-gdb all-dejagnu all-ld || exit 1 + make install-gdb install-dejagnu install-ld || exit 1 elif [ $H_REAL_TARGET = $H_REAL_HOST ] ; then make bootstrap || exit 1 make install || exit 1 diff -ru gcc-4.1.2/gcc/config/alpha/linux-elf.h gcc-4.1.2-futaris/gcc/config/alpha/linux-elf.h --- gcc-4.1.2/gcc/config/alpha/linux-elf.h 2005-06-25 02:22:41.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/config/alpha/linux-elf.h 2007-08-27 13:21:53.000000000 +0100 @@ -27,7 +27,11 @@ #define SUBTARGET_EXTRA_SPECS \ { "elf_dynamic_linker", ELF_DYNAMIC_LINKER }, +#if defined USE_UCLIBC +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" +#else #define ELF_DYNAMIC_LINKER "/lib/ld-linux.so.2" +#endif #define LINK_SPEC "-m elf64alpha %{G*} %{relax:-relax} \ %{O*:-O3} %{!O*:-O1} \ diff -ru gcc-4.1.2/gcc/config/arm/arm.c gcc-4.1.2-futaris/gcc/config/arm/arm.c --- gcc-4.1.2/gcc/config/arm/arm.c 2006-10-17 02:04:38.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/config/arm/arm.c 2007-08-27 13:21:54.000000000 +0100 @@ -4,6 +4,7 @@ Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) and Martin Simmons (@harleqn.co.uk). More major hacks by Richard Earnshaw (rearnsha@arm.com). + Cirrus Crunch bugfixes by Vladimir Ivanov (vladit@nucleusys.com) This file is part of GCC. @@ -131,9 +132,17 @@ static bool arm_xscale_rtx_costs (rtx, int, int, int *); static bool arm_9e_rtx_costs (rtx, int, int, int *); static int arm_address_cost (rtx); -static bool arm_memory_load_p (rtx); +// static bool arm_memory_load_p (rtx); static bool arm_cirrus_insn_p (rtx); -static void cirrus_reorg (rtx); +// static void cirrus_reorg (rtx); +static bool arm_mem_access_p (rtx); +static bool cirrus_dest_regn_p (rtx, int); +static rtx cirrus_prev_next_mach_insn (rtx, int *, int); +static rtx cirrus_prev_mach_insn (rtx, int *); +static rtx cirrus_next_mach_insn (rtx, int *); +static void cirrus_reorg_branch (rtx); +static void cirrus_reorg_bug1 (rtx); +static void cirrus_reorg_bug10_12 (rtx); static void arm_init_builtins (void); static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int); static void arm_init_iwmmxt_builtins (void); @@ -426,7 +435,7 @@ #define FL_STRONG (1 << 8) /* StrongARM */ #define FL_ARCH5E (1 << 9) /* DSP extensions to v5 */ #define FL_XSCALE (1 << 10) /* XScale */ -#define FL_CIRRUS (1 << 11) /* Cirrus/DSP. */ +#define FL_CIRRUS (1 << 11) /* Cirrus Crunch coprocessor. */ #define FL_ARCH6 (1 << 12) /* Architecture rel 6. Adds media instructions. */ #define FL_VFPV2 (1 << 13) /* Vector Floating Point V2. */ @@ -490,7 +499,7 @@ /* Nonzero if this chip is a StrongARM. */ int arm_tune_strongarm = 0; -/* Nonzero if this chip is a Cirrus variant. */ +/* Nonzero if this chip supports Cirrus Crunch coprocessor. */ int arm_arch_cirrus = 0; /* Nonzero if this chip supports Intel Wireless MMX technology. */ @@ -1184,7 +1193,8 @@ else */ if (arm_arch_cirrus) - arm_fpu_arch = FPUTYPE_MAVERICK; + /* Cirrus crunch coprocessor still requires soft-float division. */ + arm_fpu_arch = FPUTYPE_MAVERICK; else arm_fpu_arch = FPUTYPE_FPA_EMU2; #endif @@ -1567,6 +1577,9 @@ if (regs_ever_live[regno] && !call_used_regs[regno]) return 0; + if (TARGET_MAVERICK) + return 0; + if (TARGET_REALLY_IWMMXT) for (regno = FIRST_IWMMXT_REGNUM; regno <= LAST_IWMMXT_REGNUM; regno++) if (regs_ever_live[regno] && ! call_used_regs [regno]) @@ -3460,7 +3473,7 @@ use_ldrd = (TARGET_LDRD && (mode == DImode - || (mode == DFmode && (TARGET_SOFT_FLOAT || TARGET_VFP)))); + || (mode == DFmode && (TARGET_SOFT_FLOAT || TARGET_MAVERICK || TARGET_VFP)))); if (code == POST_INC || code == PRE_DEC || ((code == PRE_INC || code == POST_DEC) @@ -3960,7 +3973,7 @@ /* VFP addressing modes actually allow greater offsets, but for now we just stick with the lowest common denominator. */ if (mode == DImode - || ((TARGET_SOFT_FLOAT || TARGET_VFP) && mode == DFmode)) + || ((TARGET_SOFT_FLOAT || TARGET_MAVERICK || TARGET_VFP) && mode == DFmode)) { low_n = n & 0x0f; n &= ~0x0f; @@ -5205,7 +5218,9 @@ int i; REAL_VALUE_TYPE r; - if (TARGET_VFP) + if (TARGET_MAVERICK) + fp_consts_inited = 0; + else if (TARGET_VFP) fp_consts_inited = 1; else fp_consts_inited = 8; @@ -5399,41 +5414,6 @@ || TREE_CODE (valtype) == COMPLEX_TYPE)); } -/* Returns TRUE if INSN is an "LDR REG, ADDR" instruction. - Use by the Cirrus Maverick code which has to workaround - a hardware bug triggered by such instructions. */ -static bool -arm_memory_load_p (rtx insn) -{ - rtx body, lhs, rhs;; - - if (insn == NULL_RTX || GET_CODE (insn) != INSN) - return false; - - body = PATTERN (insn); - - if (GET_CODE (body) != SET) - return false; - - lhs = XEXP (body, 0); - rhs = XEXP (body, 1); - - lhs = REG_OR_SUBREG_RTX (lhs); - - /* If the destination is not a general purpose - register we do not have to worry. */ - if (GET_CODE (lhs) != REG - || REGNO_REG_CLASS (REGNO (lhs)) != GENERAL_REGS) - return false; - - /* As well as loads from memory we also have to react - to loads of invalid constants which will be turned - into loads from the minipool. */ - return (GET_CODE (rhs) == MEM - || GET_CODE (rhs) == SYMBOL_REF - || note_invalid_constants (insn, -1, false)); -} - /* Return TRUE if INSN is a Cirrus instruction. */ static bool arm_cirrus_insn_p (rtx insn) @@ -5452,124 +5432,218 @@ return attr != CIRRUS_NOT; } -/* Cirrus reorg for invalid instruction combinations. */ -static void -cirrus_reorg (rtx first) +/* Return TRUE if ISN does memory access. */ +static bool +arm_mem_access_p (rtx insn) { - enum attr_cirrus attr; - rtx body = PATTERN (first); - rtx t; - int nops; + enum attr_type attr; - /* Any branch must be followed by 2 non Cirrus instructions. */ - if (GET_CODE (first) == JUMP_INSN && GET_CODE (body) != RETURN) - { - nops = 0; - t = next_nonnote_insn (first); + /* get_attr aborts on USE and CLOBBER. */ + if (!insn + || GET_CODE (insn) != INSN + || GET_CODE (PATTERN (insn)) == USE + || GET_CODE (PATTERN (insn)) == CLOBBER) + return 0; - if (arm_cirrus_insn_p (t)) - ++ nops; + attr = get_attr_type (insn); - if (arm_cirrus_insn_p (next_nonnote_insn (t))) - ++ nops; + return attr == TYPE_LOAD_BYTE + || attr == TYPE_LOAD1 || attr == TYPE_LOAD2 || attr == TYPE_LOAD3 || attr == TYPE_LOAD4 + || attr == TYPE_F_CVT + || attr == TYPE_F_MEM_R || attr == TYPE_R_MEM_F || attr == TYPE_F_2_R || attr == TYPE_R_2_F + || attr == TYPE_F_LOAD || attr == TYPE_F_LOADS || attr == TYPE_F_LOADD + || attr == TYPE_F_STORE || attr == TYPE_F_STORES || attr == TYPE_F_STORED + || attr == TYPE_STORE1 || attr == TYPE_STORE2 || attr == TYPE_STORE3 || attr == TYPE_STORE4; - while (nops --) - emit_insn_after (gen_nop (), first); +} - return; - } +/* Return TRUE if destination is certain Cirrus register. */ +static bool +cirrus_dest_regn_p (rtx body, int regn) +{ + rtx lhs; + int reg; + lhs = XEXP (body, 0); + if (GET_CODE (lhs) != REG) + return 0; - /* (float (blah)) is in parallel with a clobber. */ - if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0) - body = XVECEXP (body, 0, 0); + reg = REGNO (lhs); + if (REGNO_REG_CLASS (reg) != CIRRUS_REGS) + return 0; - if (GET_CODE (body) == SET) - { - rtx lhs = XEXP (body, 0), rhs = XEXP (body, 1); + return reg == regn; +} - /* cfldrd, cfldr64, cfstrd, cfstr64 must - be followed by a non Cirrus insn. */ - if (get_attr_cirrus (first) == CIRRUS_DOUBLE) - { - if (arm_cirrus_insn_p (next_nonnote_insn (first))) - emit_insn_after (gen_nop (), first); +/* Get previous/next machine instruction during Cirrus workaround scans. + Assume worst case (for the purpose of Cirrus workarounds) + for JUMP / CALL instructions. */ +static rtx +cirrus_prev_next_mach_insn (rtx insn, int *len, int next) +{ + rtx t; + int l = 0; - return; - } - else if (arm_memory_load_p (first)) - { - unsigned int arm_regno; + /* It seems that we can count only on INSN length. */ + for ( ; ; ) + { + if (next) + insn = NEXT_INSN (insn); + else + insn = PREV_INSN (insn); + if (!insn) + break; - /* Any ldr/cfmvdlr, ldr/cfmvdhr, ldr/cfmvsr, ldr/cfmv64lr, - ldr/cfmv64hr combination where the Rd field is the same - in both instructions must be split with a non Cirrus - insn. Example: - - ldr r0, blah - nop - cfmvsr mvf0, r0. */ - - /* Get Arm register number for ldr insn. */ - if (GET_CODE (lhs) == REG) - arm_regno = REGNO (lhs); - else - { - gcc_assert (GET_CODE (rhs) == REG); - arm_regno = REGNO (rhs); - } + if (GET_CODE (insn) == INSN) + { + l = get_attr_length (insn) / 4; + if (l) + break; + } + else if (GET_CODE (insn) == JUMP_INSN) + { + l = 1; + t = is_jump_table (insn); + if (t) + l += get_jump_table_size (t) / 4; + break; + } + else if (GET_CODE (insn) == CALL_INSN) + { + l = 1; + break; + } + } - /* Next insn. */ - first = next_nonnote_insn (first); + if (len) + *len = l; - if (! arm_cirrus_insn_p (first)) - return; + return insn; +} - body = PATTERN (first); +static rtx +cirrus_prev_mach_insn (rtx insn, int *len) +{ + return cirrus_prev_next_mach_insn (insn, len, 0); +} - /* (float (blah)) is in parallel with a clobber. */ - if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0)) - body = XVECEXP (body, 0, 0); - - if (GET_CODE (body) == FLOAT) - body = XEXP (body, 0); - - if (get_attr_cirrus (first) == CIRRUS_MOVE - && GET_CODE (XEXP (body, 1)) == REG - && arm_regno == REGNO (XEXP (body, 1))) - emit_insn_after (gen_nop (), first); +static rtx +cirrus_next_mach_insn (rtx insn, int *len) +{ + return cirrus_prev_next_mach_insn (insn, len, 1); +} - return; - } - } +/* Cirrus reorg for branch slots. */ +static void +cirrus_reorg_branch (rtx insn) +{ + rtx t; + int nops, l; - /* get_attr cannot accept USE or CLOBBER. */ - if (!first - || GET_CODE (first) != INSN - || GET_CODE (PATTERN (first)) == USE - || GET_CODE (PATTERN (first)) == CLOBBER) + /* TODO: handle jump-tables. */ + t = is_jump_table (insn); + if (t) return; - attr = get_attr_cirrus (first); - - /* Any coprocessor compare instruction (cfcmps, cfcmpd, ...) - must be followed by a non-coprocessor instruction. */ - if (attr == CIRRUS_COMPARE) + /* Any branch must be followed by 2 non Cirrus instructions. */ + t = insn; + for (nops = 2; nops > 0; ) { - nops = 0; + if (!cirrus_next_mach_insn (t, 0)) + { + insn = t; + break; + } + t = cirrus_next_mach_insn (t, &l); + if (arm_cirrus_insn_p (t)) + break; + nops -= l; - t = next_nonnote_insn (first); + } - if (arm_cirrus_insn_p (t)) - ++ nops; + while (nops-- > 0) + emit_insn_after (gen_nop (), insn); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */ +} - if (arm_cirrus_insn_p (next_nonnote_insn (t))) - ++ nops; +/* Cirrus reorg for bug #1 (cirrus + cfcmpxx). */ +static void +cirrus_reorg_bug1 (rtx insn) +{ + rtx body = PATTERN (insn), body2; + rtx t; + int i, nops, l; + enum attr_cirrus attr; - while (nops --) - emit_insn_after (gen_nop (), first); + /* Check if destination or clobber is Cirrus register. */ + if (GET_CODE (body) == PARALLEL) + { + for (i = 0; i < XVECLEN (body, 0); i++) + { + body2 = XVECEXP (body, 0, i); + if (GET_CODE (body2) == SET) + { + if (cirrus_dest_regn_p (body2, LAST_CIRRUS_FP_REGNUM)) + { + nops = 5; + goto fix; + } + } + else if (GET_CODE (body2) == CLOBBER) + { + if (cirrus_dest_regn_p (body2, LAST_CIRRUS_FP_REGNUM)) + { + nops = 4; + goto fix; + } + } + } + } + else if (GET_CODE (body) == SET) + { + if (cirrus_dest_regn_p (body, LAST_CIRRUS_FP_REGNUM)) + { + nops = 5; + goto fix; + } + } + return; - return; +fix: + t = insn; + for ( ; nops > 0; ) + { + t = cirrus_next_mach_insn (t, &l); + if (!t) + break; + if (GET_CODE (t) == JUMP_INSN + || GET_CODE (t) == CALL_INSN) + { + nops -= l; + break; + } + else if (arm_cirrus_insn_p (t)) + { + attr = get_attr_cirrus (t); + if (attr == CIRRUS_COMPARE) + break; + } + nops -= l; } + + while (nops-- > 0) + emit_insn_after (gen_nop (), insn); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */ +} + +/* Cirrus reorg for bugs #10 and #12 (data aborts). */ +static void +cirrus_reorg_bug10_12 (rtx insn) +{ + rtx t; + + t = cirrus_next_mach_insn (insn, 0); + if (arm_cirrus_insn_p (t)) + if (TARGET_CIRRUS_D0 || + get_attr_cirrus (t) == CIRRUS_DOUBLE) + emit_insn_after (gen_nop (), insn); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */ } /* Return TRUE if X references a SYMBOL_REF. */ @@ -7727,7 +7801,7 @@ { Mnode * mp; Mnode * nmp; - int align64 = 0; + int align64 = 0, stuffnop = 0; if (ARM_DOUBLEWORD_ALIGN) for (mp = minipool_vector_head; mp != NULL; mp = mp->next) @@ -7742,8 +7816,27 @@ ";; Emitting minipool after insn %u; address %ld; align %d (bytes)\n", INSN_UID (scan), (unsigned long) minipool_barrier->address, align64 ? 8 : 4); + /* Check if branch before minipool is already stuffed with nops. */ + if (TARGET_CIRRUS_D0 || TARGET_CIRRUS_D1) + { + rtx t; + + t = prev_active_insn (scan); + if (GET_CODE (t) != INSN + || PATTERN (t) != const0_rtx) + stuffnop = 1; + } scan = emit_label_after (gen_label_rtx (), scan); scan = emit_insn_after (align64 ? gen_align_8 () : gen_align_4 (), scan); + /* Last instruction was branch, so put two non-Cirrus opcodes. */ + if (stuffnop) + { +#if TARGET_CIRRUS /* This is doubling up on nops, so I don't think this is a good idea */ + emit_insn_before (gen_nop (), scan); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */ + emit_insn_before (gen_nop (), scan); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */ +#endif + } + scan = emit_label_after (minipool_vector_label, scan); for (mp = minipool_vector_head; mp != NULL; mp = nmp) @@ -8151,15 +8244,38 @@ gcc_assert (GET_CODE (insn) == NOTE); minipool_pad = 0; +#if TARGET_CIRRUS /* I think this is a double-up */ + /* Scan all the insn and fix Cirrus issues. */ + if (TARGET_CIRRUS_D0 || TARGET_CIRRUS_D1) + { + rtx t, s; + + for (t = cirrus_next_mach_insn (insn, 0); t; t = cirrus_next_mach_insn (t, 0)) + if (arm_mem_access_p (t)) + cirrus_reorg_bug10_12 (t); + + if (TARGET_CIRRUS_D0) + for (t = cirrus_next_mach_insn (insn, 0); t; t = cirrus_next_mach_insn (t, 0)) + if (arm_cirrus_insn_p (t)) + cirrus_reorg_bug1 (t); + + /* Find last insn. */ + for (t = insn; ; t = s) + { + s = cirrus_next_mach_insn (t, 0); + if (!s) + break; + } + /* Scan backward and fix branches. - WARNING: appears to cause "bad immediate value for offset" problems! */ + for ( ; t; t = cirrus_prev_mach_insn (t, 0)) + if (GET_CODE (t) == JUMP_INSN + || GET_CODE (t) == CALL_INSN) + cirrus_reorg_branch (t); + } +#endif /* Scan all the insns and record the operands that will need fixing. */ for (insn = next_nonnote_insn (insn); insn; insn = next_nonnote_insn (insn)) { - if (TARGET_CIRRUS_FIX_INVALID_INSNS - && (arm_cirrus_insn_p (insn) - || GET_CODE (insn) == JUMP_INSN - || arm_memory_load_p (insn))) - cirrus_reorg (insn); - if (GET_CODE (insn) == BARRIER) push_minipool_barrier (insn, address); else if (INSN_P (insn)) @@ -9775,7 +9891,19 @@ /* This variable is for the Virtual Frame Pointer, not VFP regs. */ int vfp_offset = offsets->frame; - if (arm_fpu_arch == FPUTYPE_FPA_EMU2) + if (arm_fpu_arch == FPUTYPE_MAVERICK) + { + for (reg = LAST_CIRRUS_FP_REGNUM; reg >= FIRST_CIRRUS_FP_REGNUM; reg--) + if (regs_ever_live[reg] && !call_used_regs[reg]) + { + floats_offset += 8; /* more problems - futaris? */ + /* if (TARGET_CIRRUS_D0 || TARGET_CIRRUS_D1) */ + asm_fprintf (f, "\tnop\n"); + asm_fprintf (f, "\tcfldrd\tmvd%d, [%r, #-%d]\n", + reg - FIRST_CIRRUS_FP_REGNUM, FP_REGNUM, floats_offset - vfp_offset); + } + } + else if (arm_fpu_arch == FPUTYPE_FPA_EMU2) { for (reg = LAST_FPA_REGNUM; reg >= FIRST_FPA_REGNUM; reg--) if (regs_ever_live[reg] && !call_used_regs[reg]) @@ -9924,7 +10052,18 @@ output_add_immediate (operands); } - if (arm_fpu_arch == FPUTYPE_FPA_EMU2) + if (arm_fpu_arch == FPUTYPE_MAVERICK) + { /* order changed - futaris */ + for (reg = FIRST_CIRRUS_FP_REGNUM; reg <= LAST_CIRRUS_FP_REGNUM; reg++) + if (regs_ever_live[reg] && !call_used_regs[reg]) + { + /* if (TARGET_CIRRUS_D0 || TARGET_CIRRUS_D1) */ + asm_fprintf (f, "\tnop\n"); + asm_fprintf (f, "\tcfldrd\tmvd%u, [%r], #8\n", + reg - FIRST_CIRRUS_FP_REGNUM, SP_REGNUM); + } /* reg problems - futaris */ + } + else if (arm_fpu_arch == FPUTYPE_FPA_EMU2) { for (reg = FIRST_FPA_REGNUM; reg <= LAST_FPA_REGNUM; reg++) if (regs_ever_live[reg] && !call_used_regs[reg]) @@ -10428,10 +10567,20 @@ func_type = arm_current_func_type (); if (! IS_VOLATILE (func_type)) { + /* Space for saved MAVERICK registers. */ + if (arm_fpu_arch == FPUTYPE_MAVERICK) + { + for (regno = FIRST_CIRRUS_FP_REGNUM; regno <= LAST_CIRRUS_FP_REGNUM; regno++) + if (regs_ever_live[regno] && !call_used_regs[regno]) + saved += 8; // 8 in 3.4.3 patch - futaris; + } + else /* Space for saved FPA registers. */ + { for (regno = FIRST_FPA_REGNUM; regno <= LAST_FPA_REGNUM; regno++) if (regs_ever_live[regno] && ! call_used_regs[regno]) saved += 12; + } /* Space for saved VFP registers. */ if (TARGET_HARD_FLOAT && TARGET_VFP) @@ -10739,7 +10888,19 @@ /* Save any floating point call-saved registers used by this function. */ - if (arm_fpu_arch == FPUTYPE_FPA_EMU2) + if (arm_fpu_arch == FPUTYPE_MAVERICK) + { + for (reg = LAST_CIRRUS_FP_REGNUM; reg >= FIRST_CIRRUS_FP_REGNUM; reg--) + if (regs_ever_live[reg] && !call_used_regs[reg]) + { + insn = gen_rtx_PRE_DEC (DFmode, stack_pointer_rtx); /* think these causes problems */ + insn = gen_rtx_MEM (DFmode, insn); + insn = emit_insn (gen_rtx_SET (VOIDmode, insn, + gen_rtx_REG (DFmode, reg))); + RTX_FRAME_RELATED_P (insn) = 1; saved_regs += 8; /* added by futaris */ + } + } + else if (arm_fpu_arch == FPUTYPE_FPA_EMU2) { for (reg = LAST_FPA_REGNUM; reg >= FIRST_FPA_REGNUM; reg--) if (regs_ever_live[reg] && !call_used_regs[reg]) @@ -11422,26 +11583,53 @@ /* These encodings assume that AC=1 in the FPA system control byte. This allows us to handle all cases except UNEQ and LTGT. */ - switch (comp_code) - { - case GE: return ARM_GE; - case GT: return ARM_GT; - case LE: return ARM_LS; - case LT: return ARM_MI; - case NE: return ARM_NE; - case EQ: return ARM_EQ; - case ORDERED: return ARM_VC; - case UNORDERED: return ARM_VS; - case UNLT: return ARM_LT; - case UNLE: return ARM_LE; - case UNGT: return ARM_HI; - case UNGE: return ARM_PL; - /* UNEQ and LTGT do not have a representation. */ - case UNEQ: /* Fall through. */ - case LTGT: /* Fall through. */ - default: gcc_unreachable (); - } - + if (!TARGET_MAVERICK) + { + switch (comp_code) + { + case GE: return ARM_GE; + case GT: return ARM_GT; + case LE: return ARM_LS; + case LT: return ARM_MI; + case NE: return ARM_NE; + case EQ: return ARM_EQ; + case ORDERED: return ARM_VC; + case UNORDERED: return ARM_VS; + case UNLT: return ARM_LT; + case UNLE: return ARM_LE; + case UNGT: return ARM_HI; + case UNGE: return ARM_PL; + /* UNEQ and LTGT do not have a representation. */ + case UNEQ: /* Fall through. */ + case LTGT: /* Fall through. */ + default: gcc_unreachable (); + } + } + else + { + /* CIRRUS */ + switch (comp_code) + { +#if 1 + case GT: return ARM_VS; + case LE: return ARM_LE; + case LT: return ARM_LT; + case NE: return ARM_NE; + case EQ: return ARM_EQ; + case UNLE: return ARM_VC; + case UNGT: return ARM_GT; + case UNGE: return ARM_GE; + case UNEQ: return ARM_PL; + case LTGT: return ARM_MI; + /* These do not have a representation. */ + case GE: /* Fall through. -UNGE wrong atm */ + case UNLT: /* Fall through. -LT wrong atm */ + case ORDERED: /* Fall through. -AL wrong atm */ + case UNORDERED: /* Fall through. -AL wrong atm */ +#endif + default: gcc_unreachable (); + } + } case CC_SWPmode: switch (comp_code) { @@ -11755,16 +11943,10 @@ || get_attr_conds (this_insn) != CONDS_NOCOND) fail = TRUE; - /* A conditional cirrus instruction must be followed by - a non Cirrus instruction. However, since we - conditionalize instructions in this function and by - the time we get here we can't add instructions - (nops), because shorten_branches() has already been - called, we will disable conditionalizing Cirrus - instructions to be safe. */ - if (GET_CODE (scanbody) != USE - && GET_CODE (scanbody) != CLOBBER - && get_attr_cirrus (this_insn) != CIRRUS_NOT) + /* To avoid erratic behaviour, we avoid conditional Cirrus + instructions when doing workarounds. */ + if (arm_cirrus_insn_p(this_insn) + && (TARGET_CIRRUS_D0 || TARGET_CIRRUS_D1)) fail = TRUE; break; @@ -11854,7 +12036,7 @@ upper 32 bits. This causes gcc all sorts of grief. We can't even split the registers into pairs because Cirrus SI values get sign extended to 64bits-- aldyh. */ - return (GET_MODE_CLASS (mode) == MODE_FLOAT) || (mode == DImode); + return (GET_MODE_CLASS (mode) == MODE_FLOAT); if (TARGET_HARD_FLOAT && TARGET_VFP && IS_VFP_REGNUM (regno)) @@ -15179,6 +15361,9 @@ if (IS_FPA_REGNUM (regno)) return (TARGET_AAPCS_BASED ? 96 : 16) + regno - FIRST_FPA_REGNUM; + if (IS_CIRRUS_REGNUM (regno)) + return 28 + regno - FIRST_CIRRUS_FP_REGNUM; + if (IS_VFP_REGNUM (regno)) return 64 + regno - FIRST_VFP_REGNUM; @@ -15371,6 +15556,15 @@ /* Move from sp to reg. */ asm_fprintf (asm_out_file, "\t.movsp %r\n", REGNO (e0)); } + else if (GET_CODE (e1) == PLUS + && GET_CODE (XEXP (e1, 0)) == REG + && REGNO (XEXP (e1, 0)) == SP_REGNUM + && GET_CODE (XEXP (e1, 1)) == CONST_INT) + { + /* Set reg to offset from sp. */ + asm_fprintf (asm_out_file, "\t.movsp %r, #%d\n", + REGNO (e0), (int)INTVAL(XEXP (e1, 1))); + } else abort (); break; Only in gcc-4.1.2-futaris/gcc/config/arm: arm.c.orig diff -ru gcc-4.1.2/gcc/config/arm/arm.h gcc-4.1.2-futaris/gcc/config/arm/arm.h --- gcc-4.1.2/gcc/config/arm/arm.h 2005-11-04 15:02:51.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/config/arm/arm.h 2007-08-27 13:21:54.000000000 +0100 @@ -5,6 +5,7 @@ and Martin Simmons (@harleqn.co.uk). More major hacks by Richard Earnshaw (rearnsha@arm.com) Minor hacks by Nick Clifton (nickc@cygnus.com) + Cirrus Crunch fixes by Vladimir Ivanov (vladitx@nucleusys.com) This file is part of GCC. @@ -140,7 +141,9 @@ %{msoft-float:%{mhard-float: \ %e-msoft-float and -mhard_float may not be used together}} \ %{mbig-endian:%{mlittle-endian: \ - %e-mbig-endian and -mlittle-endian may not be used together}}" + %e-mbig-endian and -mlittle-endian may not be used together}} \ +%{mfix-crunch-d0:%{mfix-crunch-d1: \ + %e-mfix-crunch-d0 and -mfix-crunch-d1 may not be used together}}" #ifndef CC1_SPEC #define CC1_SPEC "" @@ -179,6 +182,9 @@ #define TARGET_HARD_FLOAT_ABI (arm_float_abi == ARM_FLOAT_ABI_HARD) #define TARGET_FPA (arm_fp_model == ARM_FP_MODEL_FPA) #define TARGET_MAVERICK (arm_fp_model == ARM_FP_MODEL_MAVERICK) +#define TARGET_CIRRUS (arm_arch_cirrus) +#define TARGET_CIRRUS_D0 0 /* (target_flags & ARM_FLAG_CIRRUS_D0) */ +#define TARGET_CIRRUS_D1 1 /* (target_flags & ARM_FLAG_CIRRUS_D1) */ #define TARGET_VFP (arm_fp_model == ARM_FP_MODEL_VFP) #define TARGET_IWMMXT (arm_arch_iwmmxt) #define TARGET_REALLY_IWMMXT (TARGET_IWMMXT && TARGET_ARM) diff -ru gcc-4.1.2/gcc/config/arm/arm.md gcc-4.1.2-futaris/gcc/config/arm/arm.md --- gcc-4.1.2/gcc/config/arm/arm.md 2006-09-27 18:10:22.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/config/arm/arm.md 2007-08-27 13:21:54.000000000 +0100 @@ -357,7 +357,7 @@ (clobber (reg:CC CC_REGNUM))])] "TARGET_EITHER" " - if (TARGET_HARD_FLOAT && TARGET_MAVERICK) + if (TARGET_HARD_FLOAT && TARGET_MAVERICK && 0) { if (!cirrus_fp_register (operands[0], DImode)) operands[0] = force_reg (DImode, operands[0]); @@ -393,7 +393,7 @@ (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0") (match_operand:DI 2 "s_register_operand" "r, 0"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)" + "TARGET_ARM" "#" "TARGET_ARM && reload_completed" [(parallel [(set (reg:CC_C CC_REGNUM) @@ -421,7 +421,7 @@ (match_operand:SI 2 "s_register_operand" "r,r")) (match_operand:DI 1 "s_register_operand" "r,0"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)" + "TARGET_ARM" "#" "TARGET_ARM && reload_completed" [(parallel [(set (reg:CC_C CC_REGNUM) @@ -450,7 +450,7 @@ (match_operand:SI 2 "s_register_operand" "r,r")) (match_operand:DI 1 "s_register_operand" "r,0"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)" + "TARGET_ARM" "#" "TARGET_ARM && reload_completed" [(parallel [(set (reg:CC_C CC_REGNUM) @@ -778,18 +778,18 @@ [(set_attr "conds" "use")] ) -(define_insn "incscc" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (plus:SI (match_operator:SI 2 "arm_comparison_operator" - [(match_operand:CC 3 "cc_register" "") (const_int 0)]) - (match_operand:SI 1 "s_register_operand" "0,?r")))] - "TARGET_ARM" - "@ - add%d2\\t%0, %1, #1 - mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1" - [(set_attr "conds" "use") - (set_attr "length" "4,8")] -) +;(define_insn "incscc" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (plus:SI (match_operator:SI 2 "arm_comparison_operator" +; [(match_operand:CC 3 "cc_register" "") (const_int 0)]) +; (match_operand:SI 1 "s_register_operand" "0,?r")))] +; "TARGET_ARM" +; "@ +; add%d2\\t%0, %1, #1 +; mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1" +; [(set_attr "conds" "use") +; (set_attr "length" "4,8")] +;) ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant. (define_split @@ -838,7 +838,7 @@ if (TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_ARM && cirrus_fp_register (operands[0], DImode) - && cirrus_fp_register (operands[1], DImode)) + && cirrus_fp_register (operands[1], DImode) && 0) { emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2])); DONE; @@ -1015,18 +1015,18 @@ [(set_attr "conds" "set")] ) -(define_insn "decscc" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") - (match_operator:SI 2 "arm_comparison_operator" - [(match_operand 3 "cc_register" "") (const_int 0)])))] - "TARGET_ARM" - "@ - sub%d2\\t%0, %1, #1 - mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1" - [(set_attr "conds" "use") - (set_attr "length" "*,8")] -) +;(define_insn "decscc" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") +; (match_operator:SI 2 "arm_comparison_operator" +; [(match_operand 3 "cc_register" "") (const_int 0)])))] +; "TARGET_ARM" +; "@ +; sub%d2\\t%0, %1, #1 +; mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1" +; [(set_attr "conds" "use") +; (set_attr "length" "*,8")] +;) (define_expand "subsf3" [(set (match_operand:SF 0 "s_register_operand" "") @@ -2599,7 +2599,7 @@ values to iwmmxt regs and back. */ FAIL; } - else if (!TARGET_REALLY_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)) + else if (!TARGET_REALLY_IWMMXT) FAIL; " ) @@ -3125,34 +3125,37 @@ ;; Fixed <--> Floating conversion insns +;; Maverick Crunch floatsisf2 is buggy - see cirrus.md (define_expand "floatsisf2" [(set (match_operand:SF 0 "s_register_operand" "") (float:SF (match_operand:SI 1 "s_register_operand" "")))] - "TARGET_ARM && TARGET_HARD_FLOAT" + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" " - if (TARGET_MAVERICK) + if (TARGET_MAVERICK && 0) { emit_insn (gen_cirrus_floatsisf2 (operands[0], operands[1])); DONE; } ") +;; Maverick Crunch floatsidf2 is buggy - see cirrus.md (define_expand "floatsidf2" [(set (match_operand:DF 0 "s_register_operand" "") (float:DF (match_operand:SI 1 "s_register_operand" "")))] - "TARGET_ARM && TARGET_HARD_FLOAT" + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" " - if (TARGET_MAVERICK) + if (TARGET_MAVERICK && 0) { emit_insn (gen_cirrus_floatsidf2 (operands[0], operands[1])); DONE; } ") +; appears to be buggy for MAVERICK (define_expand "fix_truncsfsi2" [(set (match_operand:SI 0 "s_register_operand" "") (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))] - "TARGET_ARM && TARGET_HARD_FLOAT" + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" " if (TARGET_MAVERICK) { @@ -3165,10 +3168,11 @@ } ") +; appears to be buggy for MAVERICK (define_expand "fix_truncdfsi2" [(set (match_operand:SI 0 "s_register_operand" "") (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))] - "TARGET_ARM && TARGET_HARD_FLOAT" + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" " if (TARGET_MAVERICK) { @@ -3181,11 +3185,12 @@ ;; Truncation insns +;; Maverick Crunch truncdfsf2 is buggy - see cirrus.md (define_expand "truncdfsf2" [(set (match_operand:SF 0 "s_register_operand" "") (float_truncate:SF (match_operand:DF 1 "s_register_operand" "")))] - "TARGET_ARM && TARGET_HARD_FLOAT" + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" "" ) @@ -4097,7 +4102,7 @@ [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m") (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))] "TARGET_ARM - && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP)) + && !(TARGET_HARD_FLOAT && (TARGET_VFP)) && !TARGET_IWMMXT" "* switch (which_alternative) @@ -4215,7 +4220,6 @@ [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r") (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))] "TARGET_THUMB - && !(TARGET_HARD_FLOAT && TARGET_MAVERICK) && ( register_operand (operands[0], DImode) || register_operand (operands[1], DImode))" "* @@ -5725,1132 +5729,1132 @@ ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048). ;; For a 'b' pos_range = 254, neg_range = -256 giving (-250 ->256). -(define_expand "cbranchsi4" - [(set (pc) (if_then_else - (match_operator 0 "arm_comparison_operator" - [(match_operand:SI 1 "s_register_operand" "") - (match_operand:SI 2 "nonmemory_operand" "")]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "TARGET_THUMB" - " - if (thumb_cmpneg_operand (operands[2], SImode)) - { - emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2], - operands[3], operands[0])); - DONE; - } - if (!thumb_cmp_operand (operands[2], SImode)) - operands[2] = force_reg (SImode, operands[2]); - ") +;(define_expand "cbranchsi4" +; [(set (pc) (if_then_else +; (match_operator 0 "arm_comparison_operator" +; [(match_operand:SI 1 "s_register_operand" "") +; (match_operand:SI 2 "nonmemory_operand" "")]) +; (label_ref (match_operand 3 "" "")) +; (pc)))] +; "TARGET_THUMB" +; " +; if (thumb_cmpneg_operand (operands[2], SImode)) +; { +; emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2], +; operands[3], operands[0])); +; DONE; +; } +; if (!thumb_cmp_operand (operands[2], SImode)) +; operands[2] = force_reg (SImode, operands[2]); +; ") + +;(define_insn "*cbranchsi4_insn" +; [(set (pc) (if_then_else +; (match_operator 0 "arm_comparison_operator" +; [(match_operand:SI 1 "s_register_operand" "l,*h") +; (match_operand:SI 2 "thumb_cmp_operand" "lI*h,*r")]) +; (label_ref (match_operand 3 "" "")) +; (pc)))] +; "TARGET_THUMB" +; "* +; output_asm_insn (\"cmp\\t%1, %2\", operands); +; +; switch (get_attr_length (insn)) +; { +; case 4: return \"b%d0\\t%l3\"; +; case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; +; default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; +; } +; " +; [(set (attr "far_jump") +; (if_then_else +; (eq_attr "length" "8") +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -250)) +; (le (minus (match_dup 3) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) +; (le (minus (match_dup 3) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))))] +;) + +;(define_insn "cbranchsi4_scratch" +; [(set (pc) (if_then_else +; (match_operator 4 "arm_comparison_operator" +; [(match_operand:SI 1 "s_register_operand" "l,0") +; (match_operand:SI 2 "thumb_cmpneg_operand" "L,J")]) +; (label_ref (match_operand 3 "" "")) +; (pc))) +; (clobber (match_scratch:SI 0 "=l,l"))] +; "TARGET_THUMB" +; "* +; output_asm_insn (\"add\\t%0, %1, #%n2\", operands); +; +; switch (get_attr_length (insn)) +; { +; case 4: return \"b%d4\\t%l3\"; +; case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; +; default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; +; } +; " +; [(set (attr "far_jump") +; (if_then_else +; (eq_attr "length" "8") +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -250)) +; (le (minus (match_dup 3) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) +; (le (minus (match_dup 3) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))))] +;) +;(define_insn "*movsi_cbranchsi4" +; [(set (pc) +; (if_then_else +; (match_operator 3 "arm_comparison_operator" +; [(match_operand:SI 1 "s_register_operand" "0,l,l,l") +; (const_int 0)]) +; (label_ref (match_operand 2 "" "")) +; (pc))) +; (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*h,*m") +; (match_dup 1))] +; "TARGET_THUMB" +; "*{ +; if (which_alternative == 0) +; output_asm_insn (\"cmp\t%0, #0\", operands); +; else if (which_alternative == 1) +; output_asm_insn (\"sub\t%0, %1, #0\", operands); +; else +; { +; output_asm_insn (\"cmp\t%1, #0\", operands); +; if (which_alternative == 2) +; output_asm_insn (\"mov\t%0, %1\", operands); +; else +; output_asm_insn (\"str\t%1, %0\", operands); +; } +; switch (get_attr_length (insn) - ((which_alternative > 1) ? 2 : 0)) +; { +; case 4: return \"b%d3\\t%l2\"; +; case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\"; +; default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\"; +; } +; }" +; [(set (attr "far_jump") +; (if_then_else +; (ior (and (gt (symbol_ref ("which_alternative")) +; (const_int 1)) +; (eq_attr "length" "8")) +; (eq_attr "length" "10")) +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (le (symbol_ref ("which_alternative")) +; (const_int 1)) +; (if_then_else +; (and (ge (minus (match_dup 2) (pc)) (const_int -250)) +; (le (minus (match_dup 2) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 2) (pc)) (const_int -2040)) +; (le (minus (match_dup 2) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))) +; (if_then_else +; (and (ge (minus (match_dup 2) (pc)) (const_int -248)) +; (le (minus (match_dup 2) (pc)) (const_int 256))) +; (const_int 6) +; (if_then_else +; (and (ge (minus (match_dup 2) (pc)) (const_int -2038)) +; (le (minus (match_dup 2) (pc)) (const_int 2048))) +; (const_int 8) +; (const_int 10)))))] +;) + +;(define_insn "*negated_cbranchsi4" +; [(set (pc) +; (if_then_else +; (match_operator 0 "equality_operator" +; [(match_operand:SI 1 "s_register_operand" "l") +; (neg:SI (match_operand:SI 2 "s_register_operand" "l"))]) +; (label_ref (match_operand 3 "" "")) +; (pc)))] +; "TARGET_THUMB" +; "* +; output_asm_insn (\"cmn\\t%1, %2\", operands); +; switch (get_attr_length (insn)) +; { +; case 4: return \"b%d0\\t%l3\"; +; case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; +; default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; +; } +; " +; [(set (attr "far_jump") +; (if_then_else +; (eq_attr "length" "8") +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -250)) +; (le (minus (match_dup 3) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) +; (le (minus (match_dup 3) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))))] +;) + +;(define_insn "*tbit_cbranch" +; [(set (pc) +; (if_then_else +; (match_operator 0 "equality_operator" +; [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l") +; (const_int 1) +; (match_operand:SI 2 "const_int_operand" "i")) +; (const_int 0)]) +; (label_ref (match_operand 3 "" "")) +; (pc))) +; (clobber (match_scratch:SI 4 "=l"))] +; "TARGET_THUMB" +; "* +; { +; rtx op[3]; +; op[0] = operands[4]; +; op[1] = operands[1]; +; op[2] = GEN_INT (32 - 1 - INTVAL (operands[2])); +; +; output_asm_insn (\"lsl\\t%0, %1, %2\", op); +; switch (get_attr_length (insn)) +; { +; case 4: return \"b%d0\\t%l3\"; +; case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; +; default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; +; } +; }" +; [(set (attr "far_jump") +; (if_then_else +; (eq_attr "length" "8") +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -250)) +; (le (minus (match_dup 3) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) +; (le (minus (match_dup 3) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))))] +;) + +;(define_insn "*tstsi3_cbranch" +; [(set (pc) +; (if_then_else +; (match_operator 3 "equality_operator" +; [(and:SI (match_operand:SI 0 "s_register_operand" "%l") +; (match_operand:SI 1 "s_register_operand" "l")) +; (const_int 0)]) +; (label_ref (match_operand 2 "" "")) +; (pc)))] +; "TARGET_THUMB" +; "* +; { +; output_asm_insn (\"tst\\t%0, %1\", operands); +; switch (get_attr_length (insn)) +; { +; case 4: return \"b%d3\\t%l2\"; +; case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\"; +; default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\"; +; } +; }" +; [(set (attr "far_jump") +; (if_then_else +; (eq_attr "length" "8") +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (and (ge (minus (match_dup 2) (pc)) (const_int -250)) +; (le (minus (match_dup 2) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 2) (pc)) (const_int -2040)) +; (le (minus (match_dup 2) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))))] +;) + +;(define_insn "*andsi3_cbranch" +; [(set (pc) +; (if_then_else +; (match_operator 5 "equality_operator" +; [(and:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1") +; (match_operand:SI 3 "s_register_operand" "l,l,l,l")) +; (const_int 0)]) +; (label_ref (match_operand 4 "" "")) +; (pc))) +; (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m") +; (and:SI (match_dup 2) (match_dup 3))) +; (clobber (match_scratch:SI 1 "=X,l,&l,&l"))] +; "TARGET_THUMB" +; "* +; { +; if (which_alternative == 0) +; output_asm_insn (\"and\\t%0, %3\", operands); +; else if (which_alternative == 1) +; { +; output_asm_insn (\"and\\t%1, %3\", operands); +; output_asm_insn (\"mov\\t%0, %1\", operands); +; } +; else +; { +; output_asm_insn (\"and\\t%1, %3\", operands); +; output_asm_insn (\"str\\t%1, %0\", operands); +; } +; +; switch (get_attr_length (insn) - (which_alternative ? 2 : 0)) +; { +; case 4: return \"b%d5\\t%l4\"; +; case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\"; +; default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\"; +; } +; }" +; [(set (attr "far_jump") +; (if_then_else +; (ior (and (eq (symbol_ref ("which_alternative")) +; (const_int 0)) +; (eq_attr "length" "8")) +; (eq_attr "length" "10")) +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (eq (symbol_ref ("which_alternative")) +; (const_int 0)) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -250)) +; (le (minus (match_dup 4) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -2040)) +; (le (minus (match_dup 4) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -248)) +; (le (minus (match_dup 4) (pc)) (const_int 256))) +; (const_int 6) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -2038)) +; (le (minus (match_dup 4) (pc)) (const_int 2048))) +; (const_int 8) +; (const_int 10)))))] +;) + +;(define_insn "*orrsi3_cbranch_scratch" +; [(set (pc) +; (if_then_else +; (match_operator 4 "equality_operator" +; [(ior:SI (match_operand:SI 1 "s_register_operand" "%0") +; (match_operand:SI 2 "s_register_operand" "l")) +; (const_int 0)]) +; (label_ref (match_operand 3 "" "")) +; (pc))) +; (clobber (match_scratch:SI 0 "=l"))] +; "TARGET_THUMB" +; "* +; { +; output_asm_insn (\"orr\\t%0, %2\", operands); +; switch (get_attr_length (insn)) +; { +; case 4: return \"b%d4\\t%l3\"; +; case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; +; default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; +; } +; }" +; [(set (attr "far_jump") +; (if_then_else +; (eq_attr "length" "8") +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -250)) +; (le (minus (match_dup 3) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) +; (le (minus (match_dup 3) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))))] +;) + +;(define_insn "*orrsi3_cbranch" +; [(set (pc) +; (if_then_else +; (match_operator 5 "equality_operator" +; [(ior:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1") +; (match_operand:SI 3 "s_register_operand" "l,l,l,l")) +; (const_int 0)]) +; (label_ref (match_operand 4 "" "")) +; (pc))) +; (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m") +; (ior:SI (match_dup 2) (match_dup 3))) +; (clobber (match_scratch:SI 1 "=X,l,&l,&l"))] +; "TARGET_THUMB" +; "* +; { +; if (which_alternative == 0) +; output_asm_insn (\"orr\\t%0, %3\", operands); +; else if (which_alternative == 1) +; { +; output_asm_insn (\"orr\\t%1, %3\", operands); +; output_asm_insn (\"mov\\t%0, %1\", operands); +; } +; else +; { +; output_asm_insn (\"orr\\t%1, %3\", operands); +; output_asm_insn (\"str\\t%1, %0\", operands); +; } +; +; switch (get_attr_length (insn) - (which_alternative ? 2 : 0)) +; { +; case 4: return \"b%d5\\t%l4\"; +; case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\"; +; default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\"; +; } +; }" +; [(set (attr "far_jump") +; (if_then_else +; (ior (and (eq (symbol_ref ("which_alternative")) +; (const_int 0)) +; (eq_attr "length" "8")) +; (eq_attr "length" "10")) +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (eq (symbol_ref ("which_alternative")) +; (const_int 0)) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -250)) +; (le (minus (match_dup 4) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -2040)) +; (le (minus (match_dup 4) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -248)) +; (le (minus (match_dup 4) (pc)) (const_int 256))) +; (const_int 6) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -2038)) +; (le (minus (match_dup 4) (pc)) (const_int 2048))) +; (const_int 8) +; (const_int 10)))))] +;) + +;(define_insn "*xorsi3_cbranch_scratch" +; [(set (pc) +; (if_then_else +; (match_operator 4 "equality_operator" +; [(xor:SI (match_operand:SI 1 "s_register_operand" "%0") +; (match_operand:SI 2 "s_register_operand" "l")) +; (const_int 0)]) +; (label_ref (match_operand 3 "" "")) +; (pc))) +; (clobber (match_scratch:SI 0 "=l"))] +; "TARGET_THUMB" +; "* +; { +; output_asm_insn (\"eor\\t%0, %2\", operands); +; switch (get_attr_length (insn)) +; { +; case 4: return \"b%d4\\t%l3\"; +; case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; +; default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; +; } +; }" +; [(set (attr "far_jump") +; (if_then_else +; (eq_attr "length" "8") +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -250)) +; (le (minus (match_dup 3) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) +; (le (minus (match_dup 3) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))))] +;) + +;(define_insn "*xorsi3_cbranch" +; [(set (pc) +; (if_then_else +; (match_operator 5 "equality_operator" +; [(xor:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1") +; (match_operand:SI 3 "s_register_operand" "l,l,l,l")) +; (const_int 0)]) +; (label_ref (match_operand 4 "" "")) +; (pc))) +; (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m") +; (xor:SI (match_dup 2) (match_dup 3))) +; (clobber (match_scratch:SI 1 "=X,l,&l,&l"))] +; "TARGET_THUMB" +; "* +; { +; if (which_alternative == 0) +; output_asm_insn (\"eor\\t%0, %3\", operands); +; else if (which_alternative == 1) +; { +; output_asm_insn (\"eor\\t%1, %3\", operands); +; output_asm_insn (\"mov\\t%0, %1\", operands); +; } +; else +; { +; output_asm_insn (\"eor\\t%1, %3\", operands); +; output_asm_insn (\"str\\t%1, %0\", operands); +; } +; +; switch (get_attr_length (insn) - (which_alternative ? 2 : 0)) +; { +; case 4: return \"b%d5\\t%l4\"; +; case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\"; +; default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\"; +; } +; }" +; [(set (attr "far_jump") +; (if_then_else +; (ior (and (eq (symbol_ref ("which_alternative")) +; (const_int 0)) +; (eq_attr "length" "8")) +; (eq_attr "length" "10")) +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (eq (symbol_ref ("which_alternative")) +; (const_int 0)) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -250)) +; (le (minus (match_dup 4) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -2040)) +; (le (minus (match_dup 4) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -248)) +; (le (minus (match_dup 4) (pc)) (const_int 256))) +; (const_int 6) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -2038)) +; (le (minus (match_dup 4) (pc)) (const_int 2048))) +; (const_int 8) +; (const_int 10)))))] +;) + +;(define_insn "*bicsi3_cbranch_scratch" +; [(set (pc) +; (if_then_else +; (match_operator 4 "equality_operator" +; [(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "l")) +; (match_operand:SI 1 "s_register_operand" "0")) +; (const_int 0)]) +; (label_ref (match_operand 3 "" "")) +; (pc))) +; (clobber (match_scratch:SI 0 "=l"))] +; "TARGET_THUMB" +; "* +; { +; output_asm_insn (\"bic\\t%0, %2\", operands); +; switch (get_attr_length (insn)) +; { +; case 4: return \"b%d4\\t%l3\"; +; case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; +; default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; +; } +; }" +; [(set (attr "far_jump") +; (if_then_else +; (eq_attr "length" "8") +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -250)) +; (le (minus (match_dup 3) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) +; (le (minus (match_dup 3) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))))] +;) + +;(define_insn "*bicsi3_cbranch" +; [(set (pc) +; (if_then_else +; (match_operator 5 "equality_operator" +; [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l,l")) +; (match_operand:SI 2 "s_register_operand" "0,1,1,1,1")) +; (const_int 0)]) +; (label_ref (match_operand 4 "" "")) +; (pc))) +; (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=!l,l,*?h,*?m,*?m") +; (and:SI (not:SI (match_dup 3)) (match_dup 2))) +; (clobber (match_scratch:SI 1 "=X,l,l,&l,&l"))] +; "TARGET_THUMB" +; "* +; { +; if (which_alternative == 0) +; output_asm_insn (\"bic\\t%0, %3\", operands); +; else if (which_alternative <= 2) +; { +; output_asm_insn (\"bic\\t%1, %3\", operands); +; /* It's ok if OP0 is a lo-reg, even though the mov will set the +; conditions again, since we're only testing for equality. */ +; output_asm_insn (\"mov\\t%0, %1\", operands); +; } +; else +; { +; output_asm_insn (\"bic\\t%1, %3\", operands); +; output_asm_insn (\"str\\t%1, %0\", operands); +; } +; +; switch (get_attr_length (insn) - (which_alternative ? 2 : 0)) +; { +; case 4: return \"b%d5\\t%l4\"; +; case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\"; +; default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\"; +; } +; }" +; [(set (attr "far_jump") +; (if_then_else +; (ior (and (eq (symbol_ref ("which_alternative")) +; (const_int 0)) +; (eq_attr "length" "8")) +; (eq_attr "length" "10")) +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (eq (symbol_ref ("which_alternative")) +; (const_int 0)) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -250)) +; (le (minus (match_dup 4) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -2040)) +; (le (minus (match_dup 4) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -248)) +; (le (minus (match_dup 4) (pc)) (const_int 256))) +; (const_int 6) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -2038)) +; (le (minus (match_dup 4) (pc)) (const_int 2048))) +; (const_int 8) +; (const_int 10)))))] +;) + +;(define_insn "*cbranchne_decr1" +; [(set (pc) +; (if_then_else (match_operator 3 "equality_operator" +; [(match_operand:SI 2 "s_register_operand" "l,l,1,l") +; (const_int 0)]) +; (label_ref (match_operand 4 "" "")) +; (pc))) +; (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m") +; (plus:SI (match_dup 2) (const_int -1))) +; (clobber (match_scratch:SI 1 "=X,l,&l,&l"))] +; "TARGET_THUMB" +; "* +; { +; rtx cond[2]; +; cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE +; ? GEU : LTU), +; VOIDmode, operands[2], const1_rtx); +; cond[1] = operands[4]; +; +; if (which_alternative == 0) +; output_asm_insn (\"sub\\t%0, %2, #1\", operands); +; else if (which_alternative == 1) +; { +; /* We must provide an alternative for a hi reg because reload +; cannot handle output reloads on a jump instruction, but we +; can't subtract into that. Fortunately a mov from lo to hi +; does not clobber the condition codes. */ +; output_asm_insn (\"sub\\t%1, %2, #1\", operands); +; output_asm_insn (\"mov\\t%0, %1\", operands); +; } +; else +; { +; /* Similarly, but the target is memory. */ +; output_asm_insn (\"sub\\t%1, %2, #1\", operands); +; output_asm_insn (\"str\\t%1, %0\", operands); +; } +; +; switch (get_attr_length (insn) - (which_alternative ? 2 : 0)) +; { +; case 4: +; output_asm_insn (\"b%d0\\t%l1\", cond); +; return \"\"; +; case 6: +; output_asm_insn (\"b%D0\\t.LCB%=\", cond); +; return \"b\\t%l4\\t%@long jump\\n.LCB%=:\"; +; default: +; output_asm_insn (\"b%D0\\t.LCB%=\", cond); +; return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\"; +; } +; } +; " +; [(set (attr "far_jump") +; (if_then_else +; (ior (and (eq (symbol_ref ("which_alternative")) +; (const_int 0)) +; (eq_attr "length" "8")) +; (eq_attr "length" "10")) +; (const_string "yes") +; (const_string "no"))) +; (set_attr_alternative "length" +; [ +; ;; Alternative 0 +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -250)) +; (le (minus (match_dup 4) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -2040)) +; (le (minus (match_dup 4) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))) +; ;; Alternative 1 +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -248)) +; (le (minus (match_dup 4) (pc)) (const_int 256))) +; (const_int 6) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -2038)) +; (le (minus (match_dup 4) (pc)) (const_int 2048))) +; (const_int 8) +; (const_int 10))) +; ;; Alternative 2 +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -248)) +; (le (minus (match_dup 4) (pc)) (const_int 256))) +; (const_int 6) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -2038)) +; (le (minus (match_dup 4) (pc)) (const_int 2048))) +; (const_int 8) +; (const_int 10))) +; ;; Alternative 3 +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -248)) +; (le (minus (match_dup 4) (pc)) (const_int 256))) +; (const_int 6) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -2038)) +; (le (minus (match_dup 4) (pc)) (const_int 2048))) +; (const_int 8) +; (const_int 10)))])] +;) + +;(define_insn "*addsi3_cbranch" +; [(set (pc) +; (if_then_else +; (match_operator 4 "comparison_operator" +; [(plus:SI +; (match_operand:SI 2 "s_register_operand" "%l,0,*0,1,1,1") +; (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*r,lIJ,lIJ,lIJ")) +; (const_int 0)]) +; (label_ref (match_operand 5 "" "")) +; (pc))) +; (set +; (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m") +; (plus:SI (match_dup 2) (match_dup 3))) +; (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))] +; "TARGET_THUMB +; && (GET_CODE (operands[4]) == EQ +; || GET_CODE (operands[4]) == NE +; || GET_CODE (operands[4]) == GE +; || GET_CODE (operands[4]) == LT)" +; "* +; { +; rtx cond[3]; +; +; +; cond[0] = (which_alternative < 3) ? operands[0] : operands[1]; +; cond[1] = operands[2]; +; cond[2] = operands[3]; +; +; if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0) +; output_asm_insn (\"sub\\t%0, %1, #%n2\", cond); +; else +; output_asm_insn (\"add\\t%0, %1, %2\", cond); +; +; if (which_alternative >= 3 +; && which_alternative < 4) +; output_asm_insn (\"mov\\t%0, %1\", operands); +; else if (which_alternative >= 4) +; output_asm_insn (\"str\\t%1, %0\", operands); +; +; switch (get_attr_length (insn) - ((which_alternative >= 3) ? 2 : 0)) +; { +; case 4: +; return \"b%d4\\t%l5\"; +; case 6: +; return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\"; +; default: +; return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\"; +; } +; } +; " +; [(set (attr "far_jump") +; (if_then_else +; (ior (and (lt (symbol_ref ("which_alternative")) +; (const_int 3)) +; (eq_attr "length" "8")) +; (eq_attr "length" "10")) +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (lt (symbol_ref ("which_alternative")) +; (const_int 3)) +; (if_then_else +; (and (ge (minus (match_dup 5) (pc)) (const_int -250)) +; (le (minus (match_dup 5) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 5) (pc)) (const_int -2040)) +; (le (minus (match_dup 5) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))) +; (if_then_else +; (and (ge (minus (match_dup 5) (pc)) (const_int -248)) +; (le (minus (match_dup 5) (pc)) (const_int 256))) +; (const_int 6) +; (if_then_else +; (and (ge (minus (match_dup 5) (pc)) (const_int -2038)) +; (le (minus (match_dup 5) (pc)) (const_int 2048))) +; (const_int 8) +; (const_int 10)))))] +;) + +;(define_insn "*addsi3_cbranch_scratch" +; [(set (pc) +; (if_then_else +; (match_operator 3 "comparison_operator" +; [(plus:SI +; (match_operand:SI 1 "s_register_operand" "%l,l,l,0") +; (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ")) +; (const_int 0)]) +; (label_ref (match_operand 4 "" "")) +; (pc))) +; (clobber (match_scratch:SI 0 "=X,X,l,l"))] +; "TARGET_THUMB +; && (GET_CODE (operands[3]) == EQ +; || GET_CODE (operands[3]) == NE +; || GET_CODE (operands[3]) == GE +; || GET_CODE (operands[3]) == LT)" +; "* +; { +; switch (which_alternative) +; { +; case 0: +; output_asm_insn (\"cmp\t%1, #%n2\", operands); +; break; +; case 1: +; output_asm_insn (\"cmn\t%1, %2\", operands); +; break; +; case 2: +; if (INTVAL (operands[2]) < 0) +; output_asm_insn (\"sub\t%0, %1, %2\", operands); +; else +; output_asm_insn (\"add\t%0, %1, %2\", operands); +; break; +; case 3: +; if (INTVAL (operands[2]) < 0) +; output_asm_insn (\"sub\t%0, %0, %2\", operands); +; else +; output_asm_insn (\"add\t%0, %0, %2\", operands); +; break; +; } +; +; switch (get_attr_length (insn)) +; { +; case 4: +; return \"b%d3\\t%l4\"; +; case 6: +; return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\"; +; default: +; return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\"; +; } +; } +; " +; [(set (attr "far_jump") +; (if_then_else +; (eq_attr "length" "8") +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -250)) +; (le (minus (match_dup 4) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 4) (pc)) (const_int -2040)) +; (le (minus (match_dup 4) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))))] +;) + +;(define_insn "*subsi3_cbranch" +; [(set (pc) +; (if_then_else +; (match_operator 4 "comparison_operator" +; [(minus:SI +; (match_operand:SI 2 "s_register_operand" "l,l,1,l") +; (match_operand:SI 3 "s_register_operand" "l,l,l,l")) +; (const_int 0)]) +; (label_ref (match_operand 5 "" "")) +; (pc))) +; (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m") +; (minus:SI (match_dup 2) (match_dup 3))) +; (clobber (match_scratch:SI 1 "=X,l,&l,&l"))] +; "TARGET_THUMB +; && (GET_CODE (operands[4]) == EQ +; || GET_CODE (operands[4]) == NE +; || GET_CODE (operands[4]) == GE +; || GET_CODE (operands[4]) == LT)" +; "* +; { +; if (which_alternative == 0) +; output_asm_insn (\"sub\\t%0, %2, %3\", operands); +; else if (which_alternative == 1) +; { +; /* We must provide an alternative for a hi reg because reload +; cannot handle output reloads on a jump instruction, but we +; can't subtract into that. Fortunately a mov from lo to hi +; does not clobber the condition codes. */ +; output_asm_insn (\"sub\\t%1, %2, %3\", operands); +; output_asm_insn (\"mov\\t%0, %1\", operands); +; } +; else +; { +; /* Similarly, but the target is memory. */ +; output_asm_insn (\"sub\\t%1, %2, %3\", operands); +; output_asm_insn (\"str\\t%1, %0\", operands); +; } +; +; switch (get_attr_length (insn) - ((which_alternative != 0) ? 2 : 0)) +; { +; case 4: +; return \"b%d4\\t%l5\"; +; case 6: +; return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\"; +; default: +; return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\"; +; } +; } +; " +; [(set (attr "far_jump") +; (if_then_else +; (ior (and (eq (symbol_ref ("which_alternative")) +; (const_int 0)) +; (eq_attr "length" "8")) +; (eq_attr "length" "10")) +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (eq (symbol_ref ("which_alternative")) +; (const_int 0)) +; (if_then_else +; (and (ge (minus (match_dup 5) (pc)) (const_int -250)) +; (le (minus (match_dup 5) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 5) (pc)) (const_int -2040)) +; (le (minus (match_dup 5) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))) +; (if_then_else +; (and (ge (minus (match_dup 5) (pc)) (const_int -248)) +; (le (minus (match_dup 5) (pc)) (const_int 256))) +; (const_int 6) +; (if_then_else +; (and (ge (minus (match_dup 5) (pc)) (const_int -2038)) +; (le (minus (match_dup 5) (pc)) (const_int 2048))) +; (const_int 8) +; (const_int 10)))))] +;) + +;(define_insn "*subsi3_cbranch_scratch" +; [(set (pc) +; (if_then_else +; (match_operator 0 "arm_comparison_operator" +; [(minus:SI (match_operand:SI 1 "register_operand" "l") +; (match_operand:SI 2 "nonmemory_operand" "l")) +; (const_int 0)]) +; (label_ref (match_operand 3 "" "")) +; (pc)))] +; "TARGET_THUMB +; && (GET_CODE (operands[0]) == EQ +; || GET_CODE (operands[0]) == NE +; || GET_CODE (operands[0]) == GE +; || GET_CODE (operands[0]) == LT)" +; "* +; output_asm_insn (\"cmp\\t%1, %2\", operands); +; switch (get_attr_length (insn)) +; { +; case 4: return \"b%d0\\t%l3\"; +; case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; +; default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; +; } +; " +; [(set (attr "far_jump") +; (if_then_else +; (eq_attr "length" "8") +; (const_string "yes") +; (const_string "no"))) +; (set (attr "length") +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -250)) +; (le (minus (match_dup 3) (pc)) (const_int 256))) +; (const_int 4) +; (if_then_else +; (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) +; (le (minus (match_dup 3) (pc)) (const_int 2048))) +; (const_int 6) +; (const_int 8))))] +;) -(define_insn "*cbranchsi4_insn" - [(set (pc) (if_then_else - (match_operator 0 "arm_comparison_operator" - [(match_operand:SI 1 "s_register_operand" "l,*h") - (match_operand:SI 2 "thumb_cmp_operand" "lI*h,*r")]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "TARGET_THUMB" - "* - output_asm_insn (\"cmp\\t%1, %2\", operands); +;; Comparison and test insns - switch (get_attr_length (insn)) - { - case 4: return \"b%d0\\t%l3\"; - case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; - } - " - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -250)) - (le (minus (match_dup 3) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) - (le (minus (match_dup 3) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))))] -) - -(define_insn "cbranchsi4_scratch" - [(set (pc) (if_then_else - (match_operator 4 "arm_comparison_operator" - [(match_operand:SI 1 "s_register_operand" "l,0") - (match_operand:SI 2 "thumb_cmpneg_operand" "L,J")]) - (label_ref (match_operand 3 "" "")) - (pc))) - (clobber (match_scratch:SI 0 "=l,l"))] - "TARGET_THUMB" - "* - output_asm_insn (\"add\\t%0, %1, #%n2\", operands); +(define_expand "cmpsi" + [(match_operand:SI 0 "s_register_operand" "") + (match_operand:SI 1 "arm_add_operand" "")] + "TARGET_ARM" + "{ + arm_compare_op0 = operands[0]; + arm_compare_op1 = operands[1]; + DONE; + }" +) - switch (get_attr_length (insn)) - { - case 4: return \"b%d4\\t%l3\"; - case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; - } +(define_expand "cmpsf" + [(match_operand:SF 0 "s_register_operand" "") + (match_operand:SF 1 "arm_float_compare_operand" "")] + "TARGET_ARM && TARGET_HARD_FLOAT" + " + arm_compare_op0 = operands[0]; + arm_compare_op1 = operands[1]; + DONE; " - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -250)) - (le (minus (match_dup 3) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) - (le (minus (match_dup 3) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))))] -) -(define_insn "*movsi_cbranchsi4" - [(set (pc) - (if_then_else - (match_operator 3 "arm_comparison_operator" - [(match_operand:SI 1 "s_register_operand" "0,l,l,l") - (const_int 0)]) - (label_ref (match_operand 2 "" "")) - (pc))) - (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*h,*m") - (match_dup 1))] - "TARGET_THUMB" - "*{ - if (which_alternative == 0) - output_asm_insn (\"cmp\t%0, #0\", operands); - else if (which_alternative == 1) - output_asm_insn (\"sub\t%0, %1, #0\", operands); - else - { - output_asm_insn (\"cmp\t%1, #0\", operands); - if (which_alternative == 2) - output_asm_insn (\"mov\t%0, %1\", operands); - else - output_asm_insn (\"str\t%1, %0\", operands); - } - switch (get_attr_length (insn) - ((which_alternative > 1) ? 2 : 0)) - { - case 4: return \"b%d3\\t%l2\"; - case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\"; - } - }" - [(set (attr "far_jump") - (if_then_else - (ior (and (gt (symbol_ref ("which_alternative")) - (const_int 1)) - (eq_attr "length" "8")) - (eq_attr "length" "10")) - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (le (symbol_ref ("which_alternative")) - (const_int 1)) - (if_then_else - (and (ge (minus (match_dup 2) (pc)) (const_int -250)) - (le (minus (match_dup 2) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 2) (pc)) (const_int -2040)) - (le (minus (match_dup 2) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))) - (if_then_else - (and (ge (minus (match_dup 2) (pc)) (const_int -248)) - (le (minus (match_dup 2) (pc)) (const_int 256))) - (const_int 6) - (if_then_else - (and (ge (minus (match_dup 2) (pc)) (const_int -2038)) - (le (minus (match_dup 2) (pc)) (const_int 2048))) - (const_int 8) - (const_int 10)))))] ) -(define_insn "*negated_cbranchsi4" - [(set (pc) - (if_then_else - (match_operator 0 "equality_operator" - [(match_operand:SI 1 "s_register_operand" "l") - (neg:SI (match_operand:SI 2 "s_register_operand" "l"))]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "TARGET_THUMB" - "* - output_asm_insn (\"cmn\\t%1, %2\", operands); - switch (get_attr_length (insn)) - { - case 4: return \"b%d0\\t%l3\"; - case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; - } +(define_expand "cmpdf" + [(match_operand:DF 0 "s_register_operand" "") + (match_operand:DF 1 "arm_float_compare_operand" "")] + "TARGET_ARM && TARGET_HARD_FLOAT" + " + arm_compare_op0 = operands[0]; + arm_compare_op1 = operands[1]; + DONE; " - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -250)) - (le (minus (match_dup 3) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) - (le (minus (match_dup 3) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))))] ) -(define_insn "*tbit_cbranch" - [(set (pc) - (if_then_else - (match_operator 0 "equality_operator" - [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l") - (const_int 1) - (match_operand:SI 2 "const_int_operand" "i")) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc))) - (clobber (match_scratch:SI 4 "=l"))] - "TARGET_THUMB" - "* - { - rtx op[3]; - op[0] = operands[4]; - op[1] = operands[1]; - op[2] = GEN_INT (32 - 1 - INTVAL (operands[2])); - - output_asm_insn (\"lsl\\t%0, %1, %2\", op); - switch (get_attr_length (insn)) - { - case 4: return \"b%d0\\t%l3\"; - case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; - } - }" - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -250)) - (le (minus (match_dup 3) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) - (le (minus (match_dup 3) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))))] +(define_insn "*arm_cmpsi_insn" + [(set (reg:CC CC_REGNUM) + (compare:CC (match_operand:SI 0 "s_register_operand" "r,r") + (match_operand:SI 1 "arm_add_operand" "rI,L")))] + "TARGET_ARM" + "@ + cmp%?\\t%0, %1 + cmn%?\\t%0, #%n1" + [(set_attr "conds" "set")] ) - -(define_insn "*tstsi3_cbranch" - [(set (pc) - (if_then_else - (match_operator 3 "equality_operator" - [(and:SI (match_operand:SI 0 "s_register_operand" "%l") - (match_operand:SI 1 "s_register_operand" "l")) - (const_int 0)]) - (label_ref (match_operand 2 "" "")) - (pc)))] - "TARGET_THUMB" - "* - { - output_asm_insn (\"tst\\t%0, %1\", operands); - switch (get_attr_length (insn)) - { - case 4: return \"b%d3\\t%l2\"; - case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\"; - } - }" - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 2) (pc)) (const_int -250)) - (le (minus (match_dup 2) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 2) (pc)) (const_int -2040)) - (le (minus (match_dup 2) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))))] + +(define_insn "*cmpsi_shiftsi" + [(set (reg:CC CC_REGNUM) + (compare:CC (match_operand:SI 0 "s_register_operand" "r") + (match_operator:SI 3 "shift_operator" + [(match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "arm_rhs_operand" "rM")])))] + "TARGET_ARM" + "cmp%?\\t%0, %1%S3" + [(set_attr "conds" "set") + (set_attr "shift" "1") + (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "") + (const_string "alu_shift") + (const_string "alu_shift_reg")))] ) - -(define_insn "*andsi3_cbranch" - [(set (pc) - (if_then_else - (match_operator 5 "equality_operator" - [(and:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1") - (match_operand:SI 3 "s_register_operand" "l,l,l,l")) - (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc))) - (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m") - (and:SI (match_dup 2) (match_dup 3))) - (clobber (match_scratch:SI 1 "=X,l,&l,&l"))] - "TARGET_THUMB" - "* - { - if (which_alternative == 0) - output_asm_insn (\"and\\t%0, %3\", operands); - else if (which_alternative == 1) - { - output_asm_insn (\"and\\t%1, %3\", operands); - output_asm_insn (\"mov\\t%0, %1\", operands); - } - else - { - output_asm_insn (\"and\\t%1, %3\", operands); - output_asm_insn (\"str\\t%1, %0\", operands); - } - switch (get_attr_length (insn) - (which_alternative ? 2 : 0)) - { - case 4: return \"b%d5\\t%l4\"; - case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\"; - } - }" - [(set (attr "far_jump") - (if_then_else - (ior (and (eq (symbol_ref ("which_alternative")) - (const_int 0)) - (eq_attr "length" "8")) - (eq_attr "length" "10")) - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (eq (symbol_ref ("which_alternative")) - (const_int 0)) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -250)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -2040)) - (le (minus (match_dup 4) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -248)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 6) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -2038)) - (le (minus (match_dup 4) (pc)) (const_int 2048))) - (const_int 8) - (const_int 10)))))] +(define_insn "*cmpsi_shiftsi_swp" + [(set (reg:CC_SWP CC_REGNUM) + (compare:CC_SWP (match_operator:SI 3 "shift_operator" + [(match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "reg_or_int_operand" "rM")]) + (match_operand:SI 0 "s_register_operand" "r")))] + "TARGET_ARM" + "cmp%?\\t%0, %1%S3" + [(set_attr "conds" "set") + (set_attr "shift" "1") + (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "") + (const_string "alu_shift") + (const_string "alu_shift_reg")))] ) -(define_insn "*orrsi3_cbranch_scratch" - [(set (pc) - (if_then_else - (match_operator 4 "equality_operator" - [(ior:SI (match_operand:SI 1 "s_register_operand" "%0") - (match_operand:SI 2 "s_register_operand" "l")) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc))) - (clobber (match_scratch:SI 0 "=l"))] - "TARGET_THUMB" - "* - { - output_asm_insn (\"orr\\t%0, %2\", operands); - switch (get_attr_length (insn)) - { - case 4: return \"b%d4\\t%l3\"; - case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; - } - }" - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -250)) - (le (minus (match_dup 3) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) - (le (minus (match_dup 3) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))))] +(define_insn "*cmpsi_negshiftsi_si" + [(set (reg:CC_Z CC_REGNUM) + (compare:CC_Z + (neg:SI (match_operator:SI 1 "shift_operator" + [(match_operand:SI 2 "s_register_operand" "r") + (match_operand:SI 3 "reg_or_int_operand" "rM")])) + (match_operand:SI 0 "s_register_operand" "r")))] + "TARGET_ARM" + "cmn%?\\t%0, %2%S1" + [(set_attr "conds" "set") + (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") + (const_string "alu_shift") + (const_string "alu_shift_reg")))] ) - -(define_insn "*orrsi3_cbranch" - [(set (pc) - (if_then_else - (match_operator 5 "equality_operator" - [(ior:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1") - (match_operand:SI 3 "s_register_operand" "l,l,l,l")) - (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc))) - (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m") - (ior:SI (match_dup 2) (match_dup 3))) - (clobber (match_scratch:SI 1 "=X,l,&l,&l"))] - "TARGET_THUMB" - "* - { - if (which_alternative == 0) - output_asm_insn (\"orr\\t%0, %3\", operands); - else if (which_alternative == 1) - { - output_asm_insn (\"orr\\t%1, %3\", operands); - output_asm_insn (\"mov\\t%0, %1\", operands); - } - else - { - output_asm_insn (\"orr\\t%1, %3\", operands); - output_asm_insn (\"str\\t%1, %0\", operands); - } - switch (get_attr_length (insn) - (which_alternative ? 2 : 0)) - { - case 4: return \"b%d5\\t%l4\"; - case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\"; - } - }" - [(set (attr "far_jump") - (if_then_else - (ior (and (eq (symbol_ref ("which_alternative")) - (const_int 0)) - (eq_attr "length" "8")) - (eq_attr "length" "10")) - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (eq (symbol_ref ("which_alternative")) - (const_int 0)) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -250)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -2040)) - (le (minus (match_dup 4) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -248)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 6) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -2038)) - (le (minus (match_dup 4) (pc)) (const_int 2048))) - (const_int 8) - (const_int 10)))))] -) - -(define_insn "*xorsi3_cbranch_scratch" - [(set (pc) - (if_then_else - (match_operator 4 "equality_operator" - [(xor:SI (match_operand:SI 1 "s_register_operand" "%0") - (match_operand:SI 2 "s_register_operand" "l")) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc))) - (clobber (match_scratch:SI 0 "=l"))] - "TARGET_THUMB" - "* - { - output_asm_insn (\"eor\\t%0, %2\", operands); - switch (get_attr_length (insn)) - { - case 4: return \"b%d4\\t%l3\"; - case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; - } - }" - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -250)) - (le (minus (match_dup 3) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) - (le (minus (match_dup 3) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))))] -) - -(define_insn "*xorsi3_cbranch" - [(set (pc) - (if_then_else - (match_operator 5 "equality_operator" - [(xor:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1") - (match_operand:SI 3 "s_register_operand" "l,l,l,l")) - (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc))) - (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m") - (xor:SI (match_dup 2) (match_dup 3))) - (clobber (match_scratch:SI 1 "=X,l,&l,&l"))] - "TARGET_THUMB" - "* - { - if (which_alternative == 0) - output_asm_insn (\"eor\\t%0, %3\", operands); - else if (which_alternative == 1) - { - output_asm_insn (\"eor\\t%1, %3\", operands); - output_asm_insn (\"mov\\t%0, %1\", operands); - } - else - { - output_asm_insn (\"eor\\t%1, %3\", operands); - output_asm_insn (\"str\\t%1, %0\", operands); - } - - switch (get_attr_length (insn) - (which_alternative ? 2 : 0)) - { - case 4: return \"b%d5\\t%l4\"; - case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\"; - } - }" - [(set (attr "far_jump") - (if_then_else - (ior (and (eq (symbol_ref ("which_alternative")) - (const_int 0)) - (eq_attr "length" "8")) - (eq_attr "length" "10")) - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (eq (symbol_ref ("which_alternative")) - (const_int 0)) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -250)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -2040)) - (le (minus (match_dup 4) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -248)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 6) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -2038)) - (le (minus (match_dup 4) (pc)) (const_int 2048))) - (const_int 8) - (const_int 10)))))] -) - -(define_insn "*bicsi3_cbranch_scratch" - [(set (pc) - (if_then_else - (match_operator 4 "equality_operator" - [(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "l")) - (match_operand:SI 1 "s_register_operand" "0")) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc))) - (clobber (match_scratch:SI 0 "=l"))] - "TARGET_THUMB" - "* - { - output_asm_insn (\"bic\\t%0, %2\", operands); - switch (get_attr_length (insn)) - { - case 4: return \"b%d4\\t%l3\"; - case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; - } - }" - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -250)) - (le (minus (match_dup 3) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) - (le (minus (match_dup 3) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))))] -) - -(define_insn "*bicsi3_cbranch" - [(set (pc) - (if_then_else - (match_operator 5 "equality_operator" - [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l,l")) - (match_operand:SI 2 "s_register_operand" "0,1,1,1,1")) - (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc))) - (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=!l,l,*?h,*?m,*?m") - (and:SI (not:SI (match_dup 3)) (match_dup 2))) - (clobber (match_scratch:SI 1 "=X,l,l,&l,&l"))] - "TARGET_THUMB" - "* - { - if (which_alternative == 0) - output_asm_insn (\"bic\\t%0, %3\", operands); - else if (which_alternative <= 2) - { - output_asm_insn (\"bic\\t%1, %3\", operands); - /* It's ok if OP0 is a lo-reg, even though the mov will set the - conditions again, since we're only testing for equality. */ - output_asm_insn (\"mov\\t%0, %1\", operands); - } - else - { - output_asm_insn (\"bic\\t%1, %3\", operands); - output_asm_insn (\"str\\t%1, %0\", operands); - } - - switch (get_attr_length (insn) - (which_alternative ? 2 : 0)) - { - case 4: return \"b%d5\\t%l4\"; - case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\"; - } - }" - [(set (attr "far_jump") - (if_then_else - (ior (and (eq (symbol_ref ("which_alternative")) - (const_int 0)) - (eq_attr "length" "8")) - (eq_attr "length" "10")) - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (eq (symbol_ref ("which_alternative")) - (const_int 0)) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -250)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -2040)) - (le (minus (match_dup 4) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -248)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 6) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -2038)) - (le (minus (match_dup 4) (pc)) (const_int 2048))) - (const_int 8) - (const_int 10)))))] -) - -(define_insn "*cbranchne_decr1" - [(set (pc) - (if_then_else (match_operator 3 "equality_operator" - [(match_operand:SI 2 "s_register_operand" "l,l,1,l") - (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc))) - (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m") - (plus:SI (match_dup 2) (const_int -1))) - (clobber (match_scratch:SI 1 "=X,l,&l,&l"))] - "TARGET_THUMB" - "* - { - rtx cond[2]; - cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE - ? GEU : LTU), - VOIDmode, operands[2], const1_rtx); - cond[1] = operands[4]; - - if (which_alternative == 0) - output_asm_insn (\"sub\\t%0, %2, #1\", operands); - else if (which_alternative == 1) - { - /* We must provide an alternative for a hi reg because reload - cannot handle output reloads on a jump instruction, but we - can't subtract into that. Fortunately a mov from lo to hi - does not clobber the condition codes. */ - output_asm_insn (\"sub\\t%1, %2, #1\", operands); - output_asm_insn (\"mov\\t%0, %1\", operands); - } - else - { - /* Similarly, but the target is memory. */ - output_asm_insn (\"sub\\t%1, %2, #1\", operands); - output_asm_insn (\"str\\t%1, %0\", operands); - } - - switch (get_attr_length (insn) - (which_alternative ? 2 : 0)) - { - case 4: - output_asm_insn (\"b%d0\\t%l1\", cond); - return \"\"; - case 6: - output_asm_insn (\"b%D0\\t.LCB%=\", cond); - return \"b\\t%l4\\t%@long jump\\n.LCB%=:\"; - default: - output_asm_insn (\"b%D0\\t.LCB%=\", cond); - return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\"; - } - } - " - [(set (attr "far_jump") - (if_then_else - (ior (and (eq (symbol_ref ("which_alternative")) - (const_int 0)) - (eq_attr "length" "8")) - (eq_attr "length" "10")) - (const_string "yes") - (const_string "no"))) - (set_attr_alternative "length" - [ - ;; Alternative 0 - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -250)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -2040)) - (le (minus (match_dup 4) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))) - ;; Alternative 1 - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -248)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 6) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -2038)) - (le (minus (match_dup 4) (pc)) (const_int 2048))) - (const_int 8) - (const_int 10))) - ;; Alternative 2 - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -248)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 6) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -2038)) - (le (minus (match_dup 4) (pc)) (const_int 2048))) - (const_int 8) - (const_int 10))) - ;; Alternative 3 - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -248)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 6) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -2038)) - (le (minus (match_dup 4) (pc)) (const_int 2048))) - (const_int 8) - (const_int 10)))])] -) - -(define_insn "*addsi3_cbranch" - [(set (pc) - (if_then_else - (match_operator 4 "comparison_operator" - [(plus:SI - (match_operand:SI 2 "s_register_operand" "%l,0,*0,1,1,1") - (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*r,lIJ,lIJ,lIJ")) - (const_int 0)]) - (label_ref (match_operand 5 "" "")) - (pc))) - (set - (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m") - (plus:SI (match_dup 2) (match_dup 3))) - (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))] - "TARGET_THUMB - && (GET_CODE (operands[4]) == EQ - || GET_CODE (operands[4]) == NE - || GET_CODE (operands[4]) == GE - || GET_CODE (operands[4]) == LT)" - "* - { - rtx cond[3]; - - - cond[0] = (which_alternative < 3) ? operands[0] : operands[1]; - cond[1] = operands[2]; - cond[2] = operands[3]; - - if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0) - output_asm_insn (\"sub\\t%0, %1, #%n2\", cond); - else - output_asm_insn (\"add\\t%0, %1, %2\", cond); - - if (which_alternative >= 3 - && which_alternative < 4) - output_asm_insn (\"mov\\t%0, %1\", operands); - else if (which_alternative >= 4) - output_asm_insn (\"str\\t%1, %0\", operands); - - switch (get_attr_length (insn) - ((which_alternative >= 3) ? 2 : 0)) - { - case 4: - return \"b%d4\\t%l5\"; - case 6: - return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\"; - default: - return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\"; - } - } - " - [(set (attr "far_jump") - (if_then_else - (ior (and (lt (symbol_ref ("which_alternative")) - (const_int 3)) - (eq_attr "length" "8")) - (eq_attr "length" "10")) - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (lt (symbol_ref ("which_alternative")) - (const_int 3)) - (if_then_else - (and (ge (minus (match_dup 5) (pc)) (const_int -250)) - (le (minus (match_dup 5) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 5) (pc)) (const_int -2040)) - (le (minus (match_dup 5) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))) - (if_then_else - (and (ge (minus (match_dup 5) (pc)) (const_int -248)) - (le (minus (match_dup 5) (pc)) (const_int 256))) - (const_int 6) - (if_then_else - (and (ge (minus (match_dup 5) (pc)) (const_int -2038)) - (le (minus (match_dup 5) (pc)) (const_int 2048))) - (const_int 8) - (const_int 10)))))] -) - -(define_insn "*addsi3_cbranch_scratch" - [(set (pc) - (if_then_else - (match_operator 3 "comparison_operator" - [(plus:SI - (match_operand:SI 1 "s_register_operand" "%l,l,l,0") - (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ")) - (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc))) - (clobber (match_scratch:SI 0 "=X,X,l,l"))] - "TARGET_THUMB - && (GET_CODE (operands[3]) == EQ - || GET_CODE (operands[3]) == NE - || GET_CODE (operands[3]) == GE - || GET_CODE (operands[3]) == LT)" - "* - { - switch (which_alternative) - { - case 0: - output_asm_insn (\"cmp\t%1, #%n2\", operands); - break; - case 1: - output_asm_insn (\"cmn\t%1, %2\", operands); - break; - case 2: - if (INTVAL (operands[2]) < 0) - output_asm_insn (\"sub\t%0, %1, %2\", operands); - else - output_asm_insn (\"add\t%0, %1, %2\", operands); - break; - case 3: - if (INTVAL (operands[2]) < 0) - output_asm_insn (\"sub\t%0, %0, %2\", operands); - else - output_asm_insn (\"add\t%0, %0, %2\", operands); - break; - } - - switch (get_attr_length (insn)) - { - case 4: - return \"b%d3\\t%l4\"; - case 6: - return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\"; - default: - return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\"; - } - } - " - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -250)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -2040)) - (le (minus (match_dup 4) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))))] -) - -(define_insn "*subsi3_cbranch" - [(set (pc) - (if_then_else - (match_operator 4 "comparison_operator" - [(minus:SI - (match_operand:SI 2 "s_register_operand" "l,l,1,l") - (match_operand:SI 3 "s_register_operand" "l,l,l,l")) - (const_int 0)]) - (label_ref (match_operand 5 "" "")) - (pc))) - (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m") - (minus:SI (match_dup 2) (match_dup 3))) - (clobber (match_scratch:SI 1 "=X,l,&l,&l"))] - "TARGET_THUMB - && (GET_CODE (operands[4]) == EQ - || GET_CODE (operands[4]) == NE - || GET_CODE (operands[4]) == GE - || GET_CODE (operands[4]) == LT)" - "* - { - if (which_alternative == 0) - output_asm_insn (\"sub\\t%0, %2, %3\", operands); - else if (which_alternative == 1) - { - /* We must provide an alternative for a hi reg because reload - cannot handle output reloads on a jump instruction, but we - can't subtract into that. Fortunately a mov from lo to hi - does not clobber the condition codes. */ - output_asm_insn (\"sub\\t%1, %2, %3\", operands); - output_asm_insn (\"mov\\t%0, %1\", operands); - } - else - { - /* Similarly, but the target is memory. */ - output_asm_insn (\"sub\\t%1, %2, %3\", operands); - output_asm_insn (\"str\\t%1, %0\", operands); - } - - switch (get_attr_length (insn) - ((which_alternative != 0) ? 2 : 0)) - { - case 4: - return \"b%d4\\t%l5\"; - case 6: - return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\"; - default: - return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\"; - } - } - " - [(set (attr "far_jump") - (if_then_else - (ior (and (eq (symbol_ref ("which_alternative")) - (const_int 0)) - (eq_attr "length" "8")) - (eq_attr "length" "10")) - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (eq (symbol_ref ("which_alternative")) - (const_int 0)) - (if_then_else - (and (ge (minus (match_dup 5) (pc)) (const_int -250)) - (le (minus (match_dup 5) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 5) (pc)) (const_int -2040)) - (le (minus (match_dup 5) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))) - (if_then_else - (and (ge (minus (match_dup 5) (pc)) (const_int -248)) - (le (minus (match_dup 5) (pc)) (const_int 256))) - (const_int 6) - (if_then_else - (and (ge (minus (match_dup 5) (pc)) (const_int -2038)) - (le (minus (match_dup 5) (pc)) (const_int 2048))) - (const_int 8) - (const_int 10)))))] -) - -(define_insn "*subsi3_cbranch_scratch" - [(set (pc) - (if_then_else - (match_operator 0 "arm_comparison_operator" - [(minus:SI (match_operand:SI 1 "register_operand" "l") - (match_operand:SI 2 "nonmemory_operand" "l")) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "TARGET_THUMB - && (GET_CODE (operands[0]) == EQ - || GET_CODE (operands[0]) == NE - || GET_CODE (operands[0]) == GE - || GET_CODE (operands[0]) == LT)" - "* - output_asm_insn (\"cmp\\t%1, %2\", operands); - switch (get_attr_length (insn)) - { - case 4: return \"b%d0\\t%l3\"; - case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; - } - " - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -250)) - (le (minus (match_dup 3) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) - (le (minus (match_dup 3) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))))] -) - -;; Comparison and test insns - -(define_expand "cmpsi" - [(match_operand:SI 0 "s_register_operand" "") - (match_operand:SI 1 "arm_add_operand" "")] - "TARGET_ARM" - "{ - arm_compare_op0 = operands[0]; - arm_compare_op1 = operands[1]; - DONE; - }" -) - -(define_expand "cmpsf" - [(match_operand:SF 0 "s_register_operand" "") - (match_operand:SF 1 "arm_float_compare_operand" "")] - "TARGET_ARM && TARGET_HARD_FLOAT" - " - arm_compare_op0 = operands[0]; - arm_compare_op1 = operands[1]; - DONE; - " -) - -(define_expand "cmpdf" - [(match_operand:DF 0 "s_register_operand" "") - (match_operand:DF 1 "arm_float_compare_operand" "")] - "TARGET_ARM && TARGET_HARD_FLOAT" - " - arm_compare_op0 = operands[0]; - arm_compare_op1 = operands[1]; - DONE; - " -) - -(define_insn "*arm_cmpsi_insn" - [(set (reg:CC CC_REGNUM) - (compare:CC (match_operand:SI 0 "s_register_operand" "r,r") - (match_operand:SI 1 "arm_add_operand" "rI,L")))] - "TARGET_ARM" - "@ - cmp%?\\t%0, %1 - cmn%?\\t%0, #%n1" - [(set_attr "conds" "set")] -) - -(define_insn "*cmpsi_shiftsi" - [(set (reg:CC CC_REGNUM) - (compare:CC (match_operand:SI 0 "s_register_operand" "r") - (match_operator:SI 3 "shift_operator" - [(match_operand:SI 1 "s_register_operand" "r") - (match_operand:SI 2 "arm_rhs_operand" "rM")])))] - "TARGET_ARM" - "cmp%?\\t%0, %1%S3" - [(set_attr "conds" "set") - (set_attr "shift" "1") - (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "") - (const_string "alu_shift") - (const_string "alu_shift_reg")))] -) - -(define_insn "*cmpsi_shiftsi_swp" - [(set (reg:CC_SWP CC_REGNUM) - (compare:CC_SWP (match_operator:SI 3 "shift_operator" - [(match_operand:SI 1 "s_register_operand" "r") - (match_operand:SI 2 "reg_or_int_operand" "rM")]) - (match_operand:SI 0 "s_register_operand" "r")))] - "TARGET_ARM" - "cmp%?\\t%0, %1%S3" - [(set_attr "conds" "set") - (set_attr "shift" "1") - (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "") - (const_string "alu_shift") - (const_string "alu_shift_reg")))] -) - -(define_insn "*cmpsi_negshiftsi_si" - [(set (reg:CC_Z CC_REGNUM) - (compare:CC_Z - (neg:SI (match_operator:SI 1 "shift_operator" - [(match_operand:SI 2 "s_register_operand" "r") - (match_operand:SI 3 "reg_or_int_operand" "rM")])) - (match_operand:SI 0 "s_register_operand" "r")))] - "TARGET_ARM" - "cmn%?\\t%0, %2%S1" - [(set_attr "conds" "set") - (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") - (const_string "alu_shift") - (const_string "alu_shift_reg")))] -) - -;; Cirrus SF compare instruction -(define_insn "*cirrus_cmpsf" - [(set (reg:CCFP CC_REGNUM) - (compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v") - (match_operand:SF 1 "cirrus_fp_register" "v")))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" - "cfcmps%?\\tr15, %V0, %V1" - [(set_attr "type" "mav_farith") - (set_attr "cirrus" "compare")] +;; Cirrus SF compare instruction +(define_insn "*cirrus_cmpsf" + [(set (reg:CCFP CC_REGNUM) + (compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v") + (match_operand:SF 1 "cirrus_fp_register" "v")))] + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "cfcmps%?\\tr15, %V0, %V1" + [(set_attr "type" "mav_farith") + (set_attr "cirrus" "compare")] ) ;; Cirrus DF compare instruction @@ -6865,10 +6869,12 @@ ) ;; Cirrus DI compare instruction +;; This is disabled and left go through ARM core registers, because currently +;; Crunch coprocessor does only signed comparison. (define_expand "cmpdi" [(match_operand:DI 0 "cirrus_fp_register" "") (match_operand:DI 1 "cirrus_fp_register" "")] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK & 0" "{ arm_compare_op0 = operands[0]; arm_compare_op1 = operands[1]; @@ -6879,7 +6885,7 @@ [(set (reg:CC CC_REGNUM) (compare:CC (match_operand:DI 0 "cirrus_fp_register" "v") (match_operand:DI 1 "cirrus_fp_register" "v")))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK & 0" "cfcmp64%?\\tr15, %V0, %V1" [(set_attr "type" "mav_farith") (set_attr "cirrus" "compare")] @@ -6938,12 +6944,13 @@ "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);" ) +;broken on cirrus (define_expand "bge" [(set (pc) (if_then_else (ge (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] - "TARGET_ARM" + "TARGET_ARM" ;; && !(TARGET_HARD_FLOAT && TARGET_MAVERICK) "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);" ) @@ -6974,6 +6981,7 @@ "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);" ) +; broken on cirrus? (define_expand "bgeu" [(set (pc) (if_then_else (geu (match_dup 1) (const_int 0)) @@ -6997,7 +7005,7 @@ (if_then_else (unordered (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] - "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP || TARGET_MAVERICK)" "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0, arm_compare_op1);" ) @@ -7007,7 +7015,7 @@ (if_then_else (ordered (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] - "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP || TARGET_MAVERICK)" "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0, arm_compare_op1);" ) @@ -7017,16 +7025,17 @@ (if_then_else (ungt (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] - "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP || TARGET_MAVERICK)" "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, arm_compare_op1);" ) +; broken for cirrus (define_expand "bunlt" [(set (pc) (if_then_else (unlt (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] - "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP || TARGET_MAVERICK)" "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, arm_compare_op1);" ) @@ -7035,7 +7044,7 @@ (if_then_else (unge (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] - "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP || TARGET_MAVERICK)" "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, arm_compare_op1);" ) @@ -7044,7 +7053,7 @@ (if_then_else (unle (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] - "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP || TARGET_MAVERICK)" "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, arm_compare_op1);" ) @@ -7055,7 +7064,7 @@ (if_then_else (uneq (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] - "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" ;; || TARGET_MAVERICK)" "operands[1] = arm_gen_compare_reg (UNEQ, arm_compare_op0, arm_compare_op1);" ) @@ -7064,7 +7073,7 @@ (if_then_else (ltgt (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] - "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" ;; || TARGET_MAVERICK)" "operands[1] = arm_gen_compare_reg (LTGT, arm_compare_op0, arm_compare_op1);" ) @@ -7072,7 +7081,7 @@ ;; Patterns to match conditional branch insns. ;; -; Special pattern to match UNEQ. +; Special pattern to match UNEQ for FPA and VFP. (define_insn "*arm_buneq" [(set (pc) (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0)) @@ -7088,7 +7097,7 @@ (set_attr "length" "8")] ) -; Special pattern to match LTGT. +; Special pattern to match LTGT for FPA and VFP. (define_insn "*arm_bltgt" [(set (pc) (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0)) @@ -7104,26 +7113,90 @@ (set_attr "length" "8")] ) -(define_insn "*arm_cond_branch" +; Special pattern to match GE for MAVERICK. +(define_insn "*arm_bge" [(set (pc) - (if_then_else (match_operator 1 "arm_comparison_operator" - [(match_operand 2 "cc_register" "") (const_int 0)]) + (if_then_else (ge (match_operand:CCFP 1 "cc_register" "") (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] - "TARGET_ARM" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" "* - if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) - { - arm_ccfsm_state += 2; - return \"\"; - } + gcc_assert (!arm_ccfsm_state); + + return \"beq\\t%l0\;bvs\\t%l0\"; + " + [(set_attr "conds" "jump_clob") + (set_attr "length" "8")] +) + +; Special pattern to match UNLT for MAVERICK - UGLY since we need to test for Z=0 && V=0. +(define_insn "*arm_bunlt" + [(set (pc) + (if_then_else (unlt (match_operand:CCFP 1 "cc_register" "") (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "* + gcc_assert (!arm_ccfsm_state); + + return \"beq\\t.+12\;bvs\\t.+8\;b\\t%l0\"; + " + [(set_attr "conds" "jump_clob") + (set_attr "length" "12")] +) + +; Special pattern to match UNORDERED for MAVERICK - UGLY since we need to test for Z=0 && N=0. +(define_insn "*arm_bunordered" + [(set (pc) + (if_then_else (unordered (match_operand:CCFP 1 "cc_register" "") (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_MAVERICK)" + "* + gcc_assert (!arm_ccfsm_state); + + return \"beq\\t.+12\;bmi\\t.+8\;b\\t%l0\"; + " + [(set_attr "conds" "jump_clob") + (set_attr "length" "12")] +) + +; Special pattern to match ORDERED for MAVERICK. +(define_insn "*arm_bordered" + [(set (pc) + (if_then_else (ordered (match_operand:CCFP 1 "cc_register" "") (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_MAVERICK)" + "* + gcc_assert (!arm_ccfsm_state); + + return \"beq\\t%l0\;bmi\\t%l0\"; + " + [(set_attr "conds" "jump_clob") + (set_attr "length" "8")] +) + +(define_insn "*arm_cond_branch" + [(set (pc) + (if_then_else (match_operator 1 "arm_comparison_operator" + [(match_operand 2 "cc_register" "") (const_int 0)]) + (label_ref (match_operand 0 "" "")) + (pc)))] + "TARGET_ARM" + "* + if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) + { + arm_ccfsm_state += 2; + return \"\"; + } return \"b%d1\\t%l0\"; " [(set_attr "conds" "use") (set_attr "type" "branch")] ) -; Special pattern to match reversed UNEQ. +; Special pattern to match reversed UNEQ for FPA and VFP. (define_insn "*arm_buneq_reversed" [(set (pc) (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0)) @@ -7139,7 +7212,7 @@ (set_attr "length" "8")] ) -; Special pattern to match reversed LTGT. +; Special pattern to match reversed LTGT for FPA and VFP. (define_insn "*arm_bltgt_reversed" [(set (pc) (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0)) @@ -7155,6 +7228,70 @@ (set_attr "length" "8")] ) +; Special pattern to match reversed GE for MAVERICK - UGLY since we need to tst for Z=0 && N=0. +(define_insn "*arm_bge_reversed" + [(set (pc) + (if_then_else (ge (match_operand:CCFP 1 "cc_register" "") (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "* + gcc_assert (!arm_ccfsm_state); + + return \"beq\\t.+12\;bvs\\t.+8\;b\\t%l0\"; + " + [(set_attr "conds" "jump_clob") + (set_attr "length" "12")] +) + +; Special pattern to match reversed UNLT for MAVERICK. +(define_insn "*arm_bunlt_reversed" + [(set (pc) + (if_then_else (unlt (match_operand:CCFP 1 "cc_register" "") (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "* + gcc_assert (!arm_ccfsm_state); + + return \"beq\\t%l0\;bvs\\t%l0\"; + " + [(set_attr "conds" "jump_clob") + (set_attr "length" "8")] +) + +; Special pattern to match reversed UNORDERED for MAVERICK. +(define_insn "*arm_bunordered_reversed" + [(set (pc) + (if_then_else (unordered (match_operand:CCFP 1 "cc_register" "") (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_MAVERICK)" + "* + gcc_assert (!arm_ccfsm_state); + + return \"beq\\t%l0\;bmi\\t%l0\"; + " + [(set_attr "conds" "jump_clob") + (set_attr "length" "8")] +) + +; Special pattern to match reversed ORDERED for MAVERICK - UGLY since we need to test for Z=0 && N=0. +(define_insn "*arm_bordered_reversed" + [(set (pc) + (if_then_else (ordered (match_operand:CCFP 1 "cc_register" "") (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_MAVERICK)" + "* + gcc_assert (!arm_ccfsm_state); + + return \"beq\\t.+12\;bmi\\t.+8\;b\\t%l0\"; + " + [(set_attr "conds" "jump_clob") + (set_attr "length" "12")] +) + (define_insn "*arm_cond_branch_reversed" [(set (pc) (if_then_else (match_operator 1 "arm_comparison_operator" @@ -7178,123 +7315,166 @@ ; scc insns -(define_expand "seq" - [(set (match_operand:SI 0 "s_register_operand" "") - (eq:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM" - "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);" -) - -(define_expand "sne" - [(set (match_operand:SI 0 "s_register_operand" "") - (ne:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM" - "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);" -) - -(define_expand "sgt" - [(set (match_operand:SI 0 "s_register_operand" "") - (gt:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM" - "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);" -) - -(define_expand "sle" - [(set (match_operand:SI 0 "s_register_operand" "") - (le:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM" - "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);" -) - -(define_expand "sge" - [(set (match_operand:SI 0 "s_register_operand" "") - (ge:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM" - "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);" -) - -(define_expand "slt" - [(set (match_operand:SI 0 "s_register_operand" "") - (lt:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM" - "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);" -) - -(define_expand "sgtu" - [(set (match_operand:SI 0 "s_register_operand" "") - (gtu:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM" - "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);" -) - -(define_expand "sleu" - [(set (match_operand:SI 0 "s_register_operand" "") - (leu:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM" - "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);" -) - -(define_expand "sgeu" - [(set (match_operand:SI 0 "s_register_operand" "") - (geu:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM" - "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);" -) - -(define_expand "sltu" - [(set (match_operand:SI 0 "s_register_operand" "") - (ltu:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM" - "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);" -) - -(define_expand "sunordered" - [(set (match_operand:SI 0 "s_register_operand" "") - (unordered:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" - "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0, - arm_compare_op1);" -) +;(define_expand "seq" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (eq:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM" +; "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);" +;) + +;(define_expand "sne" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (ne:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM" +; "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);" +;) + +;(define_expand "sgt" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (gt:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM" +; "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);" +;) + +;(define_expand "sle" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (le:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM" +; "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);" +;) + +;; broken for cirrus - definitely +;(define_expand "sge" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (ge:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)" +; "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);" +;) -(define_expand "sordered" - [(set (match_operand:SI 0 "s_register_operand" "") - (ordered:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" - "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0, - arm_compare_op1);" -) +;;; DO NOT add patterns for SGE these can not be represented with MAVERICK +; (define_expand "sge" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (ge:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM && (TARGET_MAVERICK)" +; "gcc_unreachable ();" +; ) -(define_expand "sungt" - [(set (match_operand:SI 0 "s_register_operand" "") - (ungt:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" - "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, - arm_compare_op1);" -) +;(define_expand "slt" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (lt:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM" +; "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);" +;) + +;(define_expand "sgtu" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (gtu:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM" +; "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);" +;) + +;(define_expand "sleu" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (leu:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM" +; "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);" +;) + +;; broken for cirrus - maybe +;(define_expand "sgeu" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (geu:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM" +; "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);" +;) + +;;; DO NOT add patterns for SGEU these may not be represented with MAVERICK? +; (define_expand "sgeu" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (ge:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM && (TARGET_MAVERICK)" +; "gcc_unreachable ();" +; ) -(define_expand "sunge" - [(set (match_operand:SI 0 "s_register_operand" "") - (unge:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" - "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, - arm_compare_op1);" -) +;(define_expand "sltu" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (ltu:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM" +; "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);" +;) + +;(define_expand "sunordered" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (unordered:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" +; "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0, +; arm_compare_op1);" +;) + +;(define_expand "sordered" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (ordered:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" +; "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0, +; arm_compare_op1);" +;) + +;(define_expand "sungt" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (ungt:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP || TARGET_MAVERICK)" +; "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, +; arm_compare_op1);" +;) + +;(define_expand "sunge" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (unge:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP || TARGET_MAVERICK)" +; "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, +; arm_compare_op1);" +;) + +; broken for cirrus +;(define_expand "sunlt" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (unlt:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" +; "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, +; arm_compare_op1);" +;) -(define_expand "sunlt" - [(set (match_operand:SI 0 "s_register_operand" "") - (unlt:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" - "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, - arm_compare_op1);" -) +;;; DO NOT add patterns for SUNLT these can't be represented with MAVERICK +; (define_expand "sunlt" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (unlt:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM && (TARGET_MAVERICK)" +; "gcc_unreachable ();" +; ) -(define_expand "sunle" - [(set (match_operand:SI 0 "s_register_operand" "") - (unle:SI (match_dup 1) (const_int 0)))] - "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" - "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, - arm_compare_op1);" -) +;(define_expand "sunle" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (unle:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP || TARGET_MAVERICK)" +; "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, +; arm_compare_op1);" +;) + +;(define_expand "suneq" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (uneq:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_MAVERICK)" +; "operands[1] = arm_gen_compare_reg (UNEQ, arm_compare_op0, +; arm_compare_op1);" +;) + +;(define_expand "sltgt" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (ltgt:SI (match_dup 1) (const_int 0)))] +; "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_MAVERICK)" +; "operands[1] = arm_gen_compare_reg (LTGT, arm_compare_op0, +; arm_compare_op1);" +;) ;;; DO NOT add patterns for SUNEQ or SLTGT, these can't be represented with ;;; simple ARM instructions. @@ -7313,135 +7493,136 @@ ; "gcc_unreachable ();" ; ) -(define_insn "*mov_scc" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (match_operator:SI 1 "arm_comparison_operator" - [(match_operand 2 "cc_register" "") (const_int 0)]))] - "TARGET_ARM" - "mov%D1\\t%0, #0\;mov%d1\\t%0, #1" - [(set_attr "conds" "use") - (set_attr "length" "8")] -) - -(define_insn "*mov_negscc" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (neg:SI (match_operator:SI 1 "arm_comparison_operator" - [(match_operand 2 "cc_register" "") (const_int 0)])))] - "TARGET_ARM" - "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0" - [(set_attr "conds" "use") - (set_attr "length" "8")] -) - -(define_insn "*mov_notscc" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (not:SI (match_operator:SI 1 "arm_comparison_operator" - [(match_operand 2 "cc_register" "") (const_int 0)])))] - "TARGET_ARM" - "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1" - [(set_attr "conds" "use") - (set_attr "length" "8")] -) +;(define_insn "*mov_scc" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (match_operator:SI 1 "arm_comparison_operator" +; [(match_operand 2 "cc_register" "") (const_int 0)]))] +; "TARGET_ARM" +; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1" +; [(set_attr "conds" "use") +; (set_attr "length" "8")] +;) + +;(define_insn "*mov_negscc" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (neg:SI (match_operator:SI 1 "arm_comparison_operator" +; [(match_operand 2 "cc_register" "") (const_int 0)])))] +; "TARGET_ARM" +; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0" +; [(set_attr "conds" "use") +; (set_attr "length" "8")] +;) + +;(define_insn "*mov_notscc" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (not:SI (match_operator:SI 1 "arm_comparison_operator" +; [(match_operand 2 "cc_register" "") (const_int 0)])))] +; "TARGET_ARM" +; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1" +; [(set_attr "conds" "use") +; (set_attr "length" "8")] +;) ;; Conditional move insns -(define_expand "movsicc" - [(set (match_operand:SI 0 "s_register_operand" "") - (if_then_else:SI (match_operand 1 "arm_comparison_operator" "") - (match_operand:SI 2 "arm_not_operand" "") - (match_operand:SI 3 "arm_not_operand" "")))] - "TARGET_ARM" - " - { - enum rtx_code code = GET_CODE (operands[1]); - rtx ccreg; - - if (code == UNEQ || code == LTGT) - FAIL; - - ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1); - operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); - }" -) - -(define_expand "movsfcc" - [(set (match_operand:SF 0 "s_register_operand" "") - (if_then_else:SF (match_operand 1 "arm_comparison_operator" "") - (match_operand:SF 2 "s_register_operand" "") - (match_operand:SF 3 "nonmemory_operand" "")))] - "TARGET_ARM" - " - { - enum rtx_code code = GET_CODE (operands[1]); - rtx ccreg; - - if (code == UNEQ || code == LTGT) - FAIL; - - /* When compiling for SOFT_FLOAT, ensure both arms are in registers. - Otherwise, ensure it is a valid FP add operand */ - if ((!(TARGET_HARD_FLOAT && TARGET_FPA)) - || (!arm_float_add_operand (operands[3], SFmode))) - operands[3] = force_reg (SFmode, operands[3]); - - ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1); - operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); - }" -) - -(define_expand "movdfcc" - [(set (match_operand:DF 0 "s_register_operand" "") - (if_then_else:DF (match_operand 1 "arm_comparison_operator" "") - (match_operand:DF 2 "s_register_operand" "") - (match_operand:DF 3 "arm_float_add_operand" "")))] - "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" - " - { - enum rtx_code code = GET_CODE (operands[1]); - rtx ccreg; - - if (code == UNEQ || code == LTGT) - FAIL; - - ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1); - operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); - }" -) - -(define_insn "*movsicc_insn" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r") - (if_then_else:SI - (match_operator 3 "arm_comparison_operator" - [(match_operand 4 "cc_register" "") (const_int 0)]) - (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K") - (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))] - "TARGET_ARM" - "@ - mov%D3\\t%0, %2 - mvn%D3\\t%0, #%B2 - mov%d3\\t%0, %1 - mvn%d3\\t%0, #%B1 - mov%d3\\t%0, %1\;mov%D3\\t%0, %2 - mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2 - mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2 - mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2" - [(set_attr "length" "4,4,4,4,8,8,8,8") - (set_attr "conds" "use")] -) - -(define_insn "*movsfcc_soft_insn" - [(set (match_operand:SF 0 "s_register_operand" "=r,r") - (if_then_else:SF (match_operator 3 "arm_comparison_operator" - [(match_operand 4 "cc_register" "") (const_int 0)]) - (match_operand:SF 1 "s_register_operand" "0,r") - (match_operand:SF 2 "s_register_operand" "r,0")))] - "TARGET_ARM && TARGET_SOFT_FLOAT" - "@ - mov%D3\\t%0, %2 - mov%d3\\t%0, %1" - [(set_attr "conds" "use")] -) +;(define_expand "movsicc" +; [(set (match_operand:SI 0 "s_register_operand" "") +; (if_then_else:SI (match_operand 1 "arm_comparison_operator" "") +; (match_operand:SI 2 "arm_not_operand" "") +; (match_operand:SI 3 "arm_not_operand" "")))] +; "TARGET_ARM" +; " +; { +; enum rtx_code code = GET_CODE (operands[1]); +; rtx ccreg; +; +; if ((code == UNEQ || code == LTGT) || (TARGET_MAVERICK && (code == GE || code == UNLT || code == ORDERED || code == UNORDERED))) +; FAIL; +; +; ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1); +; operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); +; }" +;) + +;(define_expand "movsfcc" +; [(set (match_operand:SF 0 "s_register_operand" "") +; (if_then_else:SF (match_operand 1 "arm_comparison_operator" "") +; (match_operand:SF 2 "s_register_operand" "") +; (match_operand:SF 3 "nonmemory_operand" "")))] +; "TARGET_ARM" +; " +; { +; enum rtx_code code = GET_CODE (operands[1]); +; rtx ccreg; +; +; if ((code == UNEQ || code == LTGT) || (TARGET_MAVERICK && (code == GE || code == UNLT || code == ORDERED || code == UNORDERED))) +; +; FAIL; +; +; /* When compiling for SOFT_FLOAT, ensure both arms are in registers. +; Otherwise, ensure it is a valid FP add operand */ +; if ((!(TARGET_HARD_FLOAT && TARGET_FPA)) +; || (!arm_float_add_operand (operands[3], SFmode))) +; operands[3] = force_reg (SFmode, operands[3]); +; +; ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1); +; operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); +; }" +;) + +;(define_expand "movdfcc" +; [(set (match_operand:DF 0 "s_register_operand" "") +; (if_then_else:DF (match_operand 1 "arm_comparison_operator" "") +; (match_operand:DF 2 "s_register_operand" "") +; (match_operand:DF 3 "arm_float_add_operand" "")))] +; "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP || TARGET_MAVERICK)" +; " +; { +; enum rtx_code code = GET_CODE (operands[1]); +; rtx ccreg; +; +; if ((code == UNEQ || code == LTGT) || (TARGET_MAVERICK && (code==GE || code == UNLT || code == ORDERED || code == UNORDERED))) +; FAIL; +; +; ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1); +; operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); +; }" +;) + +;(define_insn "*movsicc_insn" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r") +; (if_then_else:SI +; (match_operator 3 "arm_comparison_operator" +; [(match_operand 4 "cc_register" "") (const_int 0)]) +; (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K") +; (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))] +; "TARGET_ARM" +; "@ +; mov%D3\\t%0, %2 +; mvn%D3\\t%0, #%B2 +; mov%d3\\t%0, %1 +; mvn%d3\\t%0, #%B1 +; mov%d3\\t%0, %1\;mov%D3\\t%0, %2 +; mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2 +; mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2 +; mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2" +; [(set_attr "length" "4,4,4,4,8,8,8,8") +; (set_attr "conds" "use")] +;) + +;(define_insn "*movsfcc_soft_insn" +; [(set (match_operand:SF 0 "s_register_operand" "=r,r") +; (if_then_else:SF (match_operator 3 "arm_comparison_operator" +; [(match_operand 4 "cc_register" "") (const_int 0)]) +; (match_operand:SF 1 "s_register_operand" "0,r") +; (match_operand:SF 2 "s_register_operand" "r,0")))] +; "TARGET_ARM && TARGET_SOFT_FLOAT" +; "@ +; mov%D3\\t%0, %2 +; mov%d3\\t%0, %1" +; [(set_attr "conds" "use")] +;) ;; Jump and linkage insns @@ -7822,47 +8003,47 @@ (set_attr "predicable" "yes")] ) -(define_insn "*cond_return" - [(set (pc) - (if_then_else (match_operator 0 "arm_comparison_operator" - [(match_operand 1 "cc_register" "") (const_int 0)]) - (return) - (pc)))] - "TARGET_ARM && USE_RETURN_INSN (TRUE)" - "* - { - if (arm_ccfsm_state == 2) - { - arm_ccfsm_state += 2; - return \"\"; - } - return output_return_instruction (operands[0], TRUE, FALSE); - }" - [(set_attr "conds" "use") - (set_attr "length" "12") - (set_attr "type" "load1")] -) - -(define_insn "*cond_return_inverted" - [(set (pc) - (if_then_else (match_operator 0 "arm_comparison_operator" - [(match_operand 1 "cc_register" "") (const_int 0)]) - (pc) - (return)))] - "TARGET_ARM && USE_RETURN_INSN (TRUE)" - "* - { - if (arm_ccfsm_state == 2) - { - arm_ccfsm_state += 2; - return \"\"; - } - return output_return_instruction (operands[0], TRUE, TRUE); - }" - [(set_attr "conds" "use") - (set_attr "length" "12") - (set_attr "type" "load1")] -) +;(define_insn "*cond_return" +; [(set (pc) +; (if_then_else (match_operator 0 "arm_comparison_operator" +; [(match_operand 1 "cc_register" "") (const_int 0)]) +; (return) +; (pc)))] +; "TARGET_ARM && USE_RETURN_INSN (TRUE)" +; "* +; { +; if (arm_ccfsm_state == 2) +; { +; arm_ccfsm_state += 2; +; return \"\"; +; } +; return output_return_instruction (operands[0], TRUE, FALSE); +; }" +; [(set_attr "conds" "use") +; (set_attr "length" "12") +; (set_attr "type" "load1")] +;) + +;(define_insn "*cond_return_inverted" +; [(set (pc) +; (if_then_else (match_operator 0 "arm_comparison_operator" +; [(match_operand 1 "cc_register" "") (const_int 0)]) +; (pc) +; (return)))] +; "TARGET_ARM && USE_RETURN_INSN (TRUE)" +; "* +; { +; if (arm_ccfsm_state == 2) +; { +; arm_ccfsm_state += 2; +; return \"\"; +; } +; return output_return_instruction (operands[0], TRUE, TRUE); +; }" +; [(set_attr "conds" "use") +; (set_attr "length" "12") +; (set_attr "type" "load1")] +;) ;; Generate a sequence of instructions to determine if the processor is ;; in 26-bit or 32-bit mode, and return the appropriate return address @@ -8178,1282 +8359,1282 @@ "TARGET_ARM" "%i1%?s\\t%0, %2, %4%S3" [(set_attr "conds" "set") - (set_attr "shift" "4") - (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "") - (const_string "alu_shift") - (const_string "alu_shift_reg")))] -) - -(define_insn "*arith_shiftsi_compare0_scratch" - [(set (reg:CC_NOOV CC_REGNUM) - (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator" - [(match_operator:SI 3 "shift_operator" - [(match_operand:SI 4 "s_register_operand" "r") - (match_operand:SI 5 "reg_or_int_operand" "rI")]) - (match_operand:SI 2 "s_register_operand" "r")]) - (const_int 0))) - (clobber (match_scratch:SI 0 "=r"))] - "TARGET_ARM" - "%i1%?s\\t%0, %2, %4%S3" - [(set_attr "conds" "set") - (set_attr "shift" "4") - (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "") - (const_string "alu_shift") - (const_string "alu_shift_reg")))] -) - -(define_insn "*sub_shiftsi" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (minus:SI (match_operand:SI 1 "s_register_operand" "r") - (match_operator:SI 2 "shift_operator" - [(match_operand:SI 3 "s_register_operand" "r") - (match_operand:SI 4 "reg_or_int_operand" "rM")])))] - "TARGET_ARM" - "sub%?\\t%0, %1, %3%S2" - [(set_attr "predicable" "yes") - (set_attr "shift" "3") - (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") - (const_string "alu_shift") - (const_string "alu_shift_reg")))] -) - -(define_insn "*sub_shiftsi_compare0" - [(set (reg:CC_NOOV CC_REGNUM) - (compare:CC_NOOV - (minus:SI (match_operand:SI 1 "s_register_operand" "r") - (match_operator:SI 2 "shift_operator" - [(match_operand:SI 3 "s_register_operand" "r") - (match_operand:SI 4 "reg_or_int_operand" "rM")])) - (const_int 0))) - (set (match_operand:SI 0 "s_register_operand" "=r") - (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) - (match_dup 4)])))] - "TARGET_ARM" - "sub%?s\\t%0, %1, %3%S2" - [(set_attr "conds" "set") - (set_attr "shift" "3") - (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") - (const_string "alu_shift") - (const_string "alu_shift_reg")))] -) - -(define_insn "*sub_shiftsi_compare0_scratch" - [(set (reg:CC_NOOV CC_REGNUM) - (compare:CC_NOOV - (minus:SI (match_operand:SI 1 "s_register_operand" "r") - (match_operator:SI 2 "shift_operator" - [(match_operand:SI 3 "s_register_operand" "r") - (match_operand:SI 4 "reg_or_int_operand" "rM")])) - (const_int 0))) - (clobber (match_scratch:SI 0 "=r"))] - "TARGET_ARM" - "sub%?s\\t%0, %1, %3%S2" - [(set_attr "conds" "set") - (set_attr "shift" "3") - (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") - (const_string "alu_shift") - (const_string "alu_shift_reg")))] -) - - - -(define_insn "*and_scc" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (and:SI (match_operator:SI 1 "arm_comparison_operator" - [(match_operand 3 "cc_register" "") (const_int 0)]) - (match_operand:SI 2 "s_register_operand" "r")))] - "TARGET_ARM" - "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1" - [(set_attr "conds" "use") - (set_attr "length" "8")] -) - -(define_insn "*ior_scc" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (ior:SI (match_operator:SI 2 "arm_comparison_operator" - [(match_operand 3 "cc_register" "") (const_int 0)]) - (match_operand:SI 1 "s_register_operand" "0,?r")))] - "TARGET_ARM" - "@ - orr%d2\\t%0, %1, #1 - mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1" - [(set_attr "conds" "use") - (set_attr "length" "4,8")] -) - -(define_insn "*compare_scc" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (match_operator:SI 1 "arm_comparison_operator" - [(match_operand:SI 2 "s_register_operand" "r,r") - (match_operand:SI 3 "arm_add_operand" "rI,L")])) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "* - if (operands[3] == const0_rtx) - { - if (GET_CODE (operands[1]) == LT) - return \"mov\\t%0, %2, lsr #31\"; - - if (GET_CODE (operands[1]) == GE) - return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\"; - - if (GET_CODE (operands[1]) == EQ) - return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\"; - } - - if (GET_CODE (operands[1]) == NE) - { - if (which_alternative == 1) - return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\"; - return \"subs\\t%0, %2, %3\;movne\\t%0, #1\"; - } - if (which_alternative == 1) - output_asm_insn (\"cmn\\t%2, #%n3\", operands); - else - output_asm_insn (\"cmp\\t%2, %3\", operands); - return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\"; - " - [(set_attr "conds" "clob") - (set_attr "length" "12")] -) - -(define_insn "*cond_move" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") - (if_then_else:SI (match_operator 3 "equality_operator" - [(match_operator 4 "arm_comparison_operator" - [(match_operand 5 "cc_register" "") (const_int 0)]) - (const_int 0)]) - (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") - (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))] - "TARGET_ARM" - "* - if (GET_CODE (operands[3]) == NE) - { - if (which_alternative != 1) - output_asm_insn (\"mov%D4\\t%0, %2\", operands); - if (which_alternative != 0) - output_asm_insn (\"mov%d4\\t%0, %1\", operands); - return \"\"; - } - if (which_alternative != 0) - output_asm_insn (\"mov%D4\\t%0, %1\", operands); - if (which_alternative != 1) - output_asm_insn (\"mov%d4\\t%0, %2\", operands); - return \"\"; - " - [(set_attr "conds" "use") - (set_attr "length" "4,4,8")] -) - -(define_insn "*cond_arith" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (match_operator:SI 5 "shiftable_operator" - [(match_operator:SI 4 "arm_comparison_operator" - [(match_operand:SI 2 "s_register_operand" "r,r") - (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) - (match_operand:SI 1 "s_register_operand" "0,?r")])) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "* - if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx) - return \"%i5\\t%0, %1, %2, lsr #31\"; - - output_asm_insn (\"cmp\\t%2, %3\", operands); - if (GET_CODE (operands[5]) == AND) - output_asm_insn (\"mov%D4\\t%0, #0\", operands); - else if (GET_CODE (operands[5]) == MINUS) - output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands); - else if (which_alternative != 0) - output_asm_insn (\"mov%D4\\t%0, %1\", operands); - return \"%i5%d4\\t%0, %1, #1\"; - " - [(set_attr "conds" "clob") - (set_attr "length" "12")] -) - -(define_insn "*cond_sub" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") - (match_operator:SI 4 "arm_comparison_operator" - [(match_operand:SI 2 "s_register_operand" "r,r") - (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "* - output_asm_insn (\"cmp\\t%2, %3\", operands); - if (which_alternative != 0) - output_asm_insn (\"mov%D4\\t%0, %1\", operands); - return \"sub%d4\\t%0, %1, #1\"; - " - [(set_attr "conds" "clob") - (set_attr "length" "8,12")] -) - -(define_insn "*cmp_ite0" - [(set (match_operand 6 "dominant_cc_register" "") - (compare - (if_then_else:SI - (match_operator 4 "arm_comparison_operator" - [(match_operand:SI 0 "s_register_operand" "r,r,r,r") - (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) - (match_operator:SI 5 "arm_comparison_operator" - [(match_operand:SI 2 "s_register_operand" "r,r,r,r") - (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]) - (const_int 0)) - (const_int 0)))] - "TARGET_ARM" - "* - { - static const char * const opcodes[4][2] = - { - {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\", - \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"}, - {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\", - \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"}, - {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\", - \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"}, - {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\", - \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"} - }; - int swap = - comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); - - return opcodes[which_alternative][swap]; - }" - [(set_attr "conds" "set") - (set_attr "length" "8")] -) - -(define_insn "*cmp_ite1" - [(set (match_operand 6 "dominant_cc_register" "") - (compare - (if_then_else:SI - (match_operator 4 "arm_comparison_operator" - [(match_operand:SI 0 "s_register_operand" "r,r,r,r") - (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) - (match_operator:SI 5 "arm_comparison_operator" - [(match_operand:SI 2 "s_register_operand" "r,r,r,r") - (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]) - (const_int 1)) - (const_int 0)))] - "TARGET_ARM" - "* - { - static const char * const opcodes[4][2] = - { - {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\", - \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"}, - {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\", - \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"}, - {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\", - \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"}, - {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\", - \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"} - }; - int swap = - comparison_dominates_p (GET_CODE (operands[5]), - reverse_condition (GET_CODE (operands[4]))); - - return opcodes[which_alternative][swap]; - }" - [(set_attr "conds" "set") - (set_attr "length" "8")] -) - -(define_insn "*cmp_and" - [(set (match_operand 6 "dominant_cc_register" "") - (compare - (and:SI - (match_operator 4 "arm_comparison_operator" - [(match_operand:SI 0 "s_register_operand" "r,r,r,r") - (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) - (match_operator:SI 5 "arm_comparison_operator" - [(match_operand:SI 2 "s_register_operand" "r,r,r,r") - (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])) - (const_int 0)))] - "TARGET_ARM" - "* - { - static const char *const opcodes[4][2] = - { - {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\", - \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"}, - {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\", - \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"}, - {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\", - \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"}, - {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\", - \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"} - }; - int swap = - comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); - - return opcodes[which_alternative][swap]; - }" - [(set_attr "conds" "set") - (set_attr "predicable" "no") - (set_attr "length" "8")] -) - -(define_insn "*cmp_ior" - [(set (match_operand 6 "dominant_cc_register" "") - (compare - (ior:SI - (match_operator 4 "arm_comparison_operator" - [(match_operand:SI 0 "s_register_operand" "r,r,r,r") - (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) - (match_operator:SI 5 "arm_comparison_operator" - [(match_operand:SI 2 "s_register_operand" "r,r,r,r") - (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])) - (const_int 0)))] - "TARGET_ARM" - "* -{ - static const char *const opcodes[4][2] = - { - {\"cmp\\t%0, %1\;cmp%D4\\t%2, %3\", - \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"}, - {\"cmn\\t%0, #%n1\;cmp%D4\\t%2, %3\", - \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"}, - {\"cmp\\t%0, %1\;cmn%D4\\t%2, #%n3\", - \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"}, - {\"cmn\\t%0, #%n1\;cmn%D4\\t%2, #%n3\", - \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"} - }; - int swap = - comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); - - return opcodes[which_alternative][swap]; -} -" - [(set_attr "conds" "set") - (set_attr "length" "8")] -) - -(define_insn_and_split "*ior_scc_scc" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (ior:SI (match_operator:SI 3 "arm_comparison_operator" - [(match_operand:SI 1 "s_register_operand" "r") - (match_operand:SI 2 "arm_add_operand" "rIL")]) - (match_operator:SI 6 "arm_comparison_operator" - [(match_operand:SI 4 "s_register_operand" "r") - (match_operand:SI 5 "arm_add_operand" "rIL")]))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM - && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y) - != CCmode)" - "#" - "TARGET_ARM && reload_completed" - [(set (match_dup 7) - (compare - (ior:SI - (match_op_dup 3 [(match_dup 1) (match_dup 2)]) - (match_op_dup 6 [(match_dup 4) (match_dup 5)])) - (const_int 0))) - (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))] - "operands[7] - = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6], - DOM_CC_X_OR_Y), - CC_REGNUM);" - [(set_attr "conds" "clob") - (set_attr "length" "16")]) - -; If the above pattern is followed by a CMP insn, then the compare is -; redundant, since we can rework the conditional instruction that follows. -(define_insn_and_split "*ior_scc_scc_cmp" - [(set (match_operand 0 "dominant_cc_register" "") - (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator" - [(match_operand:SI 1 "s_register_operand" "r") - (match_operand:SI 2 "arm_add_operand" "rIL")]) - (match_operator:SI 6 "arm_comparison_operator" - [(match_operand:SI 4 "s_register_operand" "r") - (match_operand:SI 5 "arm_add_operand" "rIL")])) - (const_int 0))) - (set (match_operand:SI 7 "s_register_operand" "=r") - (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) - (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] - "TARGET_ARM" - "#" - "TARGET_ARM && reload_completed" - [(set (match_dup 0) - (compare - (ior:SI - (match_op_dup 3 [(match_dup 1) (match_dup 2)]) - (match_op_dup 6 [(match_dup 4) (match_dup 5)])) - (const_int 0))) - (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))] - "" - [(set_attr "conds" "set") - (set_attr "length" "16")]) - -(define_insn_and_split "*and_scc_scc" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (and:SI (match_operator:SI 3 "arm_comparison_operator" - [(match_operand:SI 1 "s_register_operand" "r") - (match_operand:SI 2 "arm_add_operand" "rIL")]) - (match_operator:SI 6 "arm_comparison_operator" - [(match_operand:SI 4 "s_register_operand" "r") - (match_operand:SI 5 "arm_add_operand" "rIL")]))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM - && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) - != CCmode)" - "#" - "TARGET_ARM && reload_completed - && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) - != CCmode)" - [(set (match_dup 7) - (compare - (and:SI - (match_op_dup 3 [(match_dup 1) (match_dup 2)]) - (match_op_dup 6 [(match_dup 4) (match_dup 5)])) - (const_int 0))) - (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))] - "operands[7] - = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6], - DOM_CC_X_AND_Y), - CC_REGNUM);" - [(set_attr "conds" "clob") - (set_attr "length" "16")]) - -; If the above pattern is followed by a CMP insn, then the compare is -; redundant, since we can rework the conditional instruction that follows. -(define_insn_and_split "*and_scc_scc_cmp" - [(set (match_operand 0 "dominant_cc_register" "") - (compare (and:SI (match_operator:SI 3 "arm_comparison_operator" - [(match_operand:SI 1 "s_register_operand" "r") - (match_operand:SI 2 "arm_add_operand" "rIL")]) - (match_operator:SI 6 "arm_comparison_operator" - [(match_operand:SI 4 "s_register_operand" "r") - (match_operand:SI 5 "arm_add_operand" "rIL")])) - (const_int 0))) - (set (match_operand:SI 7 "s_register_operand" "=r") - (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) - (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] - "TARGET_ARM" - "#" - "TARGET_ARM && reload_completed" - [(set (match_dup 0) - (compare - (and:SI - (match_op_dup 3 [(match_dup 1) (match_dup 2)]) - (match_op_dup 6 [(match_dup 4) (match_dup 5)])) - (const_int 0))) - (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))] - "" - [(set_attr "conds" "set") - (set_attr "length" "16")]) - -;; If there is no dominance in the comparison, then we can still save an -;; instruction in the AND case, since we can know that the second compare -;; need only zero the value if false (if true, then the value is already -;; correct). -(define_insn_and_split "*and_scc_scc_nodom" - [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r") - (and:SI (match_operator:SI 3 "arm_comparison_operator" - [(match_operand:SI 1 "s_register_operand" "r,r,0") - (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")]) - (match_operator:SI 6 "arm_comparison_operator" - [(match_operand:SI 4 "s_register_operand" "r,r,r") - (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")]))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM - && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) - == CCmode)" - "#" - "TARGET_ARM && reload_completed" - [(parallel [(set (match_dup 0) - (match_op_dup 3 [(match_dup 1) (match_dup 2)])) - (clobber (reg:CC CC_REGNUM))]) - (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)])) - (set (match_dup 0) - (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)]) - (match_dup 0) - (const_int 0)))] - "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]), - operands[4], operands[5]), - CC_REGNUM); - operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4], - operands[5]);" - [(set_attr "conds" "clob") - (set_attr "length" "20")]) - -(define_split - [(set (reg:CC_NOOV CC_REGNUM) - (compare:CC_NOOV (ior:SI - (and:SI (match_operand:SI 0 "s_register_operand" "") - (const_int 1)) - (match_operator:SI 1 "comparison_operator" - [(match_operand:SI 2 "s_register_operand" "") - (match_operand:SI 3 "arm_add_operand" "")])) - (const_int 0))) - (clobber (match_operand:SI 4 "s_register_operand" ""))] - "TARGET_ARM" - [(set (match_dup 4) - (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)]) - (match_dup 0))) - (set (reg:CC_NOOV CC_REGNUM) - (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1)) - (const_int 0)))] - "") - -(define_split - [(set (reg:CC_NOOV CC_REGNUM) - (compare:CC_NOOV (ior:SI - (match_operator:SI 1 "comparison_operator" - [(match_operand:SI 2 "s_register_operand" "") - (match_operand:SI 3 "arm_add_operand" "")]) - (and:SI (match_operand:SI 0 "s_register_operand" "") - (const_int 1))) - (const_int 0))) - (clobber (match_operand:SI 4 "s_register_operand" ""))] - "TARGET_ARM" - [(set (match_dup 4) - (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)]) - (match_dup 0))) - (set (reg:CC_NOOV CC_REGNUM) - (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1)) - (const_int 0)))] - "") - -(define_insn "*negscc" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (neg:SI (match_operator 3 "arm_comparison_operator" - [(match_operand:SI 1 "s_register_operand" "r") - (match_operand:SI 2 "arm_rhs_operand" "rI")]))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "* - if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx) - return \"mov\\t%0, %1, asr #31\"; - - if (GET_CODE (operands[3]) == NE) - return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\"; - - if (GET_CODE (operands[3]) == GT) - return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\"; - - output_asm_insn (\"cmp\\t%1, %2\", operands); - output_asm_insn (\"mov%D3\\t%0, #0\", operands); - return \"mvn%d3\\t%0, #0\"; - " - [(set_attr "conds" "clob") - (set_attr "length" "12")] -) - -(define_insn "movcond" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") - (if_then_else:SI - (match_operator 5 "arm_comparison_operator" - [(match_operand:SI 3 "s_register_operand" "r,r,r") - (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")]) - (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") - (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "* - if (GET_CODE (operands[5]) == LT - && (operands[4] == const0_rtx)) - { - if (which_alternative != 1 && GET_CODE (operands[1]) == REG) - { - if (operands[2] == const0_rtx) - return \"and\\t%0, %1, %3, asr #31\"; - return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\"; - } - else if (which_alternative != 0 && GET_CODE (operands[2]) == REG) - { - if (operands[1] == const0_rtx) - return \"bic\\t%0, %2, %3, asr #31\"; - return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\"; - } - /* The only case that falls through to here is when both ops 1 & 2 - are constants. */ - } - - if (GET_CODE (operands[5]) == GE - && (operands[4] == const0_rtx)) - { - if (which_alternative != 1 && GET_CODE (operands[1]) == REG) - { - if (operands[2] == const0_rtx) - return \"bic\\t%0, %1, %3, asr #31\"; - return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\"; - } - else if (which_alternative != 0 && GET_CODE (operands[2]) == REG) - { - if (operands[1] == const0_rtx) - return \"and\\t%0, %2, %3, asr #31\"; - return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\"; - } - /* The only case that falls through to here is when both ops 1 & 2 - are constants. */ - } - if (GET_CODE (operands[4]) == CONST_INT - && !const_ok_for_arm (INTVAL (operands[4]))) - output_asm_insn (\"cmn\\t%3, #%n4\", operands); - else - output_asm_insn (\"cmp\\t%3, %4\", operands); - if (which_alternative != 0) - output_asm_insn (\"mov%d5\\t%0, %1\", operands); - if (which_alternative != 1) - output_asm_insn (\"mov%D5\\t%0, %2\", operands); - return \"\"; - " - [(set_attr "conds" "clob") - (set_attr "length" "8,8,12")] -) - -(define_insn "*ifcompare_plus_move" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (if_then_else:SI (match_operator 6 "arm_comparison_operator" - [(match_operand:SI 4 "s_register_operand" "r,r") - (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) - (plus:SI - (match_operand:SI 2 "s_register_operand" "r,r") - (match_operand:SI 3 "arm_add_operand" "rIL,rIL")) - (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "#" - [(set_attr "conds" "clob") - (set_attr "length" "8,12")] -) - -(define_insn "*if_plus_move" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r") - (if_then_else:SI - (match_operator 4 "arm_comparison_operator" - [(match_operand 5 "cc_register" "") (const_int 0)]) - (plus:SI - (match_operand:SI 2 "s_register_operand" "r,r,r,r") - (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L")) - (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))] - "TARGET_ARM" - "@ - add%d4\\t%0, %2, %3 - sub%d4\\t%0, %2, #%n3 - add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1 - sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1" - [(set_attr "conds" "use") - (set_attr "length" "4,4,8,8") - (set_attr "type" "*,*,*,*")] -) - -(define_insn "*ifcompare_move_plus" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (if_then_else:SI (match_operator 6 "arm_comparison_operator" - [(match_operand:SI 4 "s_register_operand" "r,r") - (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) - (match_operand:SI 1 "arm_rhs_operand" "0,?rI") - (plus:SI - (match_operand:SI 2 "s_register_operand" "r,r") - (match_operand:SI 3 "arm_add_operand" "rIL,rIL")))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "#" - [(set_attr "conds" "clob") - (set_attr "length" "8,12")] -) - -(define_insn "*if_move_plus" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r") - (if_then_else:SI - (match_operator 4 "arm_comparison_operator" - [(match_operand 5 "cc_register" "") (const_int 0)]) - (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI") - (plus:SI - (match_operand:SI 2 "s_register_operand" "r,r,r,r") - (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))] - "TARGET_ARM" - "@ - add%D4\\t%0, %2, %3 - sub%D4\\t%0, %2, #%n3 - add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1 - sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1" - [(set_attr "conds" "use") - (set_attr "length" "4,4,8,8") - (set_attr "type" "*,*,*,*")] -) - -(define_insn "*ifcompare_arith_arith" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (if_then_else:SI (match_operator 9 "arm_comparison_operator" - [(match_operand:SI 5 "s_register_operand" "r") - (match_operand:SI 6 "arm_add_operand" "rIL")]) - (match_operator:SI 8 "shiftable_operator" - [(match_operand:SI 1 "s_register_operand" "r") - (match_operand:SI 2 "arm_rhs_operand" "rI")]) - (match_operator:SI 7 "shiftable_operator" - [(match_operand:SI 3 "s_register_operand" "r") - (match_operand:SI 4 "arm_rhs_operand" "rI")]))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "#" - [(set_attr "conds" "clob") - (set_attr "length" "12")] -) - -(define_insn "*if_arith_arith" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (if_then_else:SI (match_operator 5 "arm_comparison_operator" - [(match_operand 8 "cc_register" "") (const_int 0)]) - (match_operator:SI 6 "shiftable_operator" - [(match_operand:SI 1 "s_register_operand" "r") - (match_operand:SI 2 "arm_rhs_operand" "rI")]) - (match_operator:SI 7 "shiftable_operator" - [(match_operand:SI 3 "s_register_operand" "r") - (match_operand:SI 4 "arm_rhs_operand" "rI")])))] - "TARGET_ARM" - "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4" - [(set_attr "conds" "use") - (set_attr "length" "8")] -) - -(define_insn "*ifcompare_arith_move" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (if_then_else:SI (match_operator 6 "arm_comparison_operator" - [(match_operand:SI 2 "s_register_operand" "r,r") - (match_operand:SI 3 "arm_add_operand" "rIL,rIL")]) - (match_operator:SI 7 "shiftable_operator" - [(match_operand:SI 4 "s_register_operand" "r,r") - (match_operand:SI 5 "arm_rhs_operand" "rI,rI")]) - (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "* - /* If we have an operation where (op x 0) is the identity operation and - the conditional operator is LT or GE and we are comparing against zero and - everything is in registers then we can do this in two instructions. */ - if (operands[3] == const0_rtx - && GET_CODE (operands[7]) != AND - && GET_CODE (operands[5]) == REG - && GET_CODE (operands[1]) == REG - && REGNO (operands[1]) == REGNO (operands[4]) - && REGNO (operands[4]) != REGNO (operands[0])) - { - if (GET_CODE (operands[6]) == LT) - return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\"; - else if (GET_CODE (operands[6]) == GE) - return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\"; - } - if (GET_CODE (operands[3]) == CONST_INT - && !const_ok_for_arm (INTVAL (operands[3]))) - output_asm_insn (\"cmn\\t%2, #%n3\", operands); - else - output_asm_insn (\"cmp\\t%2, %3\", operands); - output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands); - if (which_alternative != 0) - return \"mov%D6\\t%0, %1\"; - return \"\"; - " - [(set_attr "conds" "clob") - (set_attr "length" "8,12")] -) - -(define_insn "*if_arith_move" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (if_then_else:SI (match_operator 4 "arm_comparison_operator" - [(match_operand 6 "cc_register" "") (const_int 0)]) - (match_operator:SI 5 "shiftable_operator" - [(match_operand:SI 2 "s_register_operand" "r,r") - (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) - (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))] - "TARGET_ARM" - "@ - %I5%d4\\t%0, %2, %3 - %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1" - [(set_attr "conds" "use") - (set_attr "length" "4,8") - (set_attr "type" "*,*")] -) - -(define_insn "*ifcompare_move_arith" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (if_then_else:SI (match_operator 6 "arm_comparison_operator" - [(match_operand:SI 4 "s_register_operand" "r,r") - (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) - (match_operand:SI 1 "arm_rhs_operand" "0,?rI") - (match_operator:SI 7 "shiftable_operator" - [(match_operand:SI 2 "s_register_operand" "r,r") - (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "* - /* If we have an operation where (op x 0) is the identity operation and - the conditional operator is LT or GE and we are comparing against zero and - everything is in registers then we can do this in two instructions */ - if (operands[5] == const0_rtx - && GET_CODE (operands[7]) != AND - && GET_CODE (operands[3]) == REG - && GET_CODE (operands[1]) == REG - && REGNO (operands[1]) == REGNO (operands[2]) - && REGNO (operands[2]) != REGNO (operands[0])) - { - if (GET_CODE (operands[6]) == GE) - return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\"; - else if (GET_CODE (operands[6]) == LT) - return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\"; - } - - if (GET_CODE (operands[5]) == CONST_INT - && !const_ok_for_arm (INTVAL (operands[5]))) - output_asm_insn (\"cmn\\t%4, #%n5\", operands); - else - output_asm_insn (\"cmp\\t%4, %5\", operands); - - if (which_alternative != 0) - output_asm_insn (\"mov%d6\\t%0, %1\", operands); - return \"%I7%D6\\t%0, %2, %3\"; - " - [(set_attr "conds" "clob") - (set_attr "length" "8,12")] -) - -(define_insn "*if_move_arith" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (if_then_else:SI - (match_operator 4 "arm_comparison_operator" - [(match_operand 6 "cc_register" "") (const_int 0)]) - (match_operand:SI 1 "arm_rhs_operand" "0,?rI") - (match_operator:SI 5 "shiftable_operator" - [(match_operand:SI 2 "s_register_operand" "r,r") - (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))] - "TARGET_ARM" - "@ - %I5%D4\\t%0, %2, %3 - %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1" - [(set_attr "conds" "use") - (set_attr "length" "4,8") - (set_attr "type" "*,*")] -) - -(define_insn "*ifcompare_move_not" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (if_then_else:SI - (match_operator 5 "arm_comparison_operator" - [(match_operand:SI 3 "s_register_operand" "r,r") - (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) - (match_operand:SI 1 "arm_not_operand" "0,?rIK") - (not:SI - (match_operand:SI 2 "s_register_operand" "r,r")))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "#" - [(set_attr "conds" "clob") - (set_attr "length" "8,12")] -) - -(define_insn "*if_move_not" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") - (if_then_else:SI - (match_operator 4 "arm_comparison_operator" - [(match_operand 3 "cc_register" "") (const_int 0)]) - (match_operand:SI 1 "arm_not_operand" "0,?rI,K") - (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))] - "TARGET_ARM" - "@ - mvn%D4\\t%0, %2 - mov%d4\\t%0, %1\;mvn%D4\\t%0, %2 - mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2" - [(set_attr "conds" "use") - (set_attr "length" "4,8,8")] -) - -(define_insn "*ifcompare_not_move" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (if_then_else:SI - (match_operator 5 "arm_comparison_operator" - [(match_operand:SI 3 "s_register_operand" "r,r") - (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) - (not:SI - (match_operand:SI 2 "s_register_operand" "r,r")) - (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "#" - [(set_attr "conds" "clob") - (set_attr "length" "8,12")] -) - -(define_insn "*if_not_move" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") - (if_then_else:SI - (match_operator 4 "arm_comparison_operator" - [(match_operand 3 "cc_register" "") (const_int 0)]) - (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r")) - (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] - "TARGET_ARM" - "@ - mvn%d4\\t%0, %2 - mov%D4\\t%0, %1\;mvn%d4\\t%0, %2 - mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2" - [(set_attr "conds" "use") - (set_attr "length" "4,8,8")] -) - -(define_insn "*ifcompare_shift_move" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (if_then_else:SI - (match_operator 6 "arm_comparison_operator" - [(match_operand:SI 4 "s_register_operand" "r,r") - (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) - (match_operator:SI 7 "shift_operator" - [(match_operand:SI 2 "s_register_operand" "r,r") - (match_operand:SI 3 "arm_rhs_operand" "rM,rM")]) - (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "#" - [(set_attr "conds" "clob") - (set_attr "length" "8,12")] -) - -(define_insn "*if_shift_move" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") - (if_then_else:SI - (match_operator 5 "arm_comparison_operator" - [(match_operand 6 "cc_register" "") (const_int 0)]) - (match_operator:SI 4 "shift_operator" - [(match_operand:SI 2 "s_register_operand" "r,r,r") - (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")]) - (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] - "TARGET_ARM" - "@ - mov%d5\\t%0, %2%S4 - mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4 - mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4" - [(set_attr "conds" "use") - (set_attr "shift" "2") - (set_attr "length" "4,8,8") - (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") - (const_string "alu_shift") - (const_string "alu_shift_reg")))] -) - -(define_insn "*ifcompare_move_shift" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (if_then_else:SI - (match_operator 6 "arm_comparison_operator" - [(match_operand:SI 4 "s_register_operand" "r,r") - (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) - (match_operand:SI 1 "arm_not_operand" "0,?rIK") - (match_operator:SI 7 "shift_operator" - [(match_operand:SI 2 "s_register_operand" "r,r") - (match_operand:SI 3 "arm_rhs_operand" "rM,rM")]))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "#" - [(set_attr "conds" "clob") - (set_attr "length" "8,12")] -) - -(define_insn "*if_move_shift" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") - (if_then_else:SI - (match_operator 5 "arm_comparison_operator" - [(match_operand 6 "cc_register" "") (const_int 0)]) - (match_operand:SI 1 "arm_not_operand" "0,?rI,K") - (match_operator:SI 4 "shift_operator" - [(match_operand:SI 2 "s_register_operand" "r,r,r") - (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))] - "TARGET_ARM" - "@ - mov%D5\\t%0, %2%S4 - mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4 - mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4" - [(set_attr "conds" "use") - (set_attr "shift" "2") - (set_attr "length" "4,8,8") - (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") - (const_string "alu_shift") - (const_string "alu_shift_reg")))] -) - -(define_insn "*ifcompare_shift_shift" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (if_then_else:SI - (match_operator 7 "arm_comparison_operator" - [(match_operand:SI 5 "s_register_operand" "r") - (match_operand:SI 6 "arm_add_operand" "rIL")]) - (match_operator:SI 8 "shift_operator" - [(match_operand:SI 1 "s_register_operand" "r") - (match_operand:SI 2 "arm_rhs_operand" "rM")]) - (match_operator:SI 9 "shift_operator" - [(match_operand:SI 3 "s_register_operand" "r") - (match_operand:SI 4 "arm_rhs_operand" "rM")]))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "#" - [(set_attr "conds" "clob") - (set_attr "length" "12")] -) - -(define_insn "*if_shift_shift" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (if_then_else:SI - (match_operator 5 "arm_comparison_operator" - [(match_operand 8 "cc_register" "") (const_int 0)]) - (match_operator:SI 6 "shift_operator" - [(match_operand:SI 1 "s_register_operand" "r") - (match_operand:SI 2 "arm_rhs_operand" "rM")]) - (match_operator:SI 7 "shift_operator" - [(match_operand:SI 3 "s_register_operand" "r") - (match_operand:SI 4 "arm_rhs_operand" "rM")])))] - "TARGET_ARM" - "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7" - [(set_attr "conds" "use") - (set_attr "shift" "1") - (set_attr "length" "8") - (set (attr "type") (if_then_else - (and (match_operand 2 "const_int_operand" "") - (match_operand 4 "const_int_operand" "")) + (set_attr "shift" "4") + (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "") (const_string "alu_shift") (const_string "alu_shift_reg")))] ) -(define_insn "*ifcompare_not_arith" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (if_then_else:SI - (match_operator 6 "arm_comparison_operator" - [(match_operand:SI 4 "s_register_operand" "r") - (match_operand:SI 5 "arm_add_operand" "rIL")]) - (not:SI (match_operand:SI 1 "s_register_operand" "r")) - (match_operator:SI 7 "shiftable_operator" - [(match_operand:SI 2 "s_register_operand" "r") - (match_operand:SI 3 "arm_rhs_operand" "rI")]))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "#" - [(set_attr "conds" "clob") - (set_attr "length" "12")] -) - -(define_insn "*if_not_arith" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (if_then_else:SI - (match_operator 5 "arm_comparison_operator" - [(match_operand 4 "cc_register" "") (const_int 0)]) - (not:SI (match_operand:SI 1 "s_register_operand" "r")) - (match_operator:SI 6 "shiftable_operator" - [(match_operand:SI 2 "s_register_operand" "r") - (match_operand:SI 3 "arm_rhs_operand" "rI")])))] - "TARGET_ARM" - "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3" - [(set_attr "conds" "use") - (set_attr "length" "8")] -) - -(define_insn "*ifcompare_arith_not" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (if_then_else:SI - (match_operator 6 "arm_comparison_operator" - [(match_operand:SI 4 "s_register_operand" "r") - (match_operand:SI 5 "arm_add_operand" "rIL")]) - (match_operator:SI 7 "shiftable_operator" - [(match_operand:SI 2 "s_register_operand" "r") - (match_operand:SI 3 "arm_rhs_operand" "rI")]) - (not:SI (match_operand:SI 1 "s_register_operand" "r")))) - (clobber (reg:CC CC_REGNUM))] +(define_insn "*arith_shiftsi_compare0_scratch" + [(set (reg:CC_NOOV CC_REGNUM) + (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator" + [(match_operator:SI 3 "shift_operator" + [(match_operand:SI 4 "s_register_operand" "r") + (match_operand:SI 5 "reg_or_int_operand" "rI")]) + (match_operand:SI 2 "s_register_operand" "r")]) + (const_int 0))) + (clobber (match_scratch:SI 0 "=r"))] "TARGET_ARM" - "#" - [(set_attr "conds" "clob") - (set_attr "length" "12")] + "%i1%?s\\t%0, %2, %4%S3" + [(set_attr "conds" "set") + (set_attr "shift" "4") + (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "") + (const_string "alu_shift") + (const_string "alu_shift_reg")))] ) -(define_insn "*if_arith_not" +(define_insn "*sub_shiftsi" [(set (match_operand:SI 0 "s_register_operand" "=r") - (if_then_else:SI - (match_operator 5 "arm_comparison_operator" - [(match_operand 4 "cc_register" "") (const_int 0)]) - (match_operator:SI 6 "shiftable_operator" - [(match_operand:SI 2 "s_register_operand" "r") - (match_operand:SI 3 "arm_rhs_operand" "rI")]) - (not:SI (match_operand:SI 1 "s_register_operand" "r"))))] - "TARGET_ARM" - "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3" - [(set_attr "conds" "use") - (set_attr "length" "8")] -) - -(define_insn "*ifcompare_neg_move" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (if_then_else:SI - (match_operator 5 "arm_comparison_operator" - [(match_operand:SI 3 "s_register_operand" "r,r") - (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) - (neg:SI (match_operand:SI 2 "s_register_operand" "r,r")) - (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "#" - [(set_attr "conds" "clob") - (set_attr "length" "8,12")] -) - -(define_insn "*if_neg_move" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") - (if_then_else:SI - (match_operator 4 "arm_comparison_operator" - [(match_operand 3 "cc_register" "") (const_int 0)]) - (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r")) - (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] + (minus:SI (match_operand:SI 1 "s_register_operand" "r") + (match_operator:SI 2 "shift_operator" + [(match_operand:SI 3 "s_register_operand" "r") + (match_operand:SI 4 "reg_or_int_operand" "rM")])))] "TARGET_ARM" - "@ - rsb%d4\\t%0, %2, #0 - mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0 - mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0" - [(set_attr "conds" "use") - (set_attr "length" "4,8,8")] + "sub%?\\t%0, %1, %3%S2" + [(set_attr "predicable" "yes") + (set_attr "shift" "3") + (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") + (const_string "alu_shift") + (const_string "alu_shift_reg")))] ) -(define_insn "*ifcompare_move_neg" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (if_then_else:SI - (match_operator 5 "arm_comparison_operator" - [(match_operand:SI 3 "s_register_operand" "r,r") - (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) - (match_operand:SI 1 "arm_not_operand" "0,?rIK") - (neg:SI (match_operand:SI 2 "s_register_operand" "r,r")))) - (clobber (reg:CC CC_REGNUM))] +(define_insn "*sub_shiftsi_compare0" + [(set (reg:CC_NOOV CC_REGNUM) + (compare:CC_NOOV + (minus:SI (match_operand:SI 1 "s_register_operand" "r") + (match_operator:SI 2 "shift_operator" + [(match_operand:SI 3 "s_register_operand" "r") + (match_operand:SI 4 "reg_or_int_operand" "rM")])) + (const_int 0))) + (set (match_operand:SI 0 "s_register_operand" "=r") + (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) + (match_dup 4)])))] "TARGET_ARM" - "#" - [(set_attr "conds" "clob") - (set_attr "length" "8,12")] + "sub%?s\\t%0, %1, %3%S2" + [(set_attr "conds" "set") + (set_attr "shift" "3") + (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") + (const_string "alu_shift") + (const_string "alu_shift_reg")))] ) -(define_insn "*if_move_neg" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") - (if_then_else:SI - (match_operator 4 "arm_comparison_operator" - [(match_operand 3 "cc_register" "") (const_int 0)]) - (match_operand:SI 1 "arm_not_operand" "0,?rI,K") - (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))] +(define_insn "*sub_shiftsi_compare0_scratch" + [(set (reg:CC_NOOV CC_REGNUM) + (compare:CC_NOOV + (minus:SI (match_operand:SI 1 "s_register_operand" "r") + (match_operator:SI 2 "shift_operator" + [(match_operand:SI 3 "s_register_operand" "r") + (match_operand:SI 4 "reg_or_int_operand" "rM")])) + (const_int 0))) + (clobber (match_scratch:SI 0 "=r"))] "TARGET_ARM" - "@ - rsb%D4\\t%0, %2, #0 - mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0 - mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0" - [(set_attr "conds" "use") - (set_attr "length" "4,8,8")] + "sub%?s\\t%0, %1, %3%S2" + [(set_attr "conds" "set") + (set_attr "shift" "3") + (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") + (const_string "alu_shift") + (const_string "alu_shift_reg")))] ) -(define_insn "*arith_adjacentmem" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (match_operator:SI 1 "shiftable_operator" - [(match_operand:SI 2 "memory_operand" "m") - (match_operand:SI 3 "memory_operand" "m")])) - (clobber (match_scratch:SI 4 "=r"))] - "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])" - "* - { - rtx ldm[3]; - rtx arith[4]; - rtx base_reg; - HOST_WIDE_INT val1 = 0, val2 = 0; - - if (REGNO (operands[0]) > REGNO (operands[4])) - { - ldm[1] = operands[4]; - ldm[2] = operands[0]; - } - else - { - ldm[1] = operands[0]; - ldm[2] = operands[4]; - } - - base_reg = XEXP (operands[2], 0); - - if (!REG_P (base_reg)) - { - val1 = INTVAL (XEXP (base_reg, 1)); - base_reg = XEXP (base_reg, 0); - } - - if (!REG_P (XEXP (operands[3], 0))) - val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1)); - - arith[0] = operands[0]; - arith[3] = operands[1]; - - if (val1 < val2) - { - arith[1] = ldm[1]; - arith[2] = ldm[2]; - } - else - { - arith[1] = ldm[2]; - arith[2] = ldm[1]; - } + - ldm[0] = base_reg; - if (val1 !=0 && val2 != 0) - { - rtx ops[3]; +;(define_insn "*and_scc" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (and:SI (match_operator:SI 1 "arm_comparison_operator" +; [(match_operand 3 "cc_register" "") (const_int 0)]) +; (match_operand:SI 2 "s_register_operand" "r")))] +; "TARGET_ARM" +; "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1" +; [(set_attr "conds" "use") +; (set_attr "length" "8")] +;) + +;(define_insn "*ior_scc" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (ior:SI (match_operator:SI 2 "arm_comparison_operator" +; [(match_operand 3 "cc_register" "") (const_int 0)]) +; (match_operand:SI 1 "s_register_operand" "0,?r")))] +; "TARGET_ARM" +; "@ +; orr%d2\\t%0, %1, #1 +; mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1" +; [(set_attr "conds" "use") +; (set_attr "length" "4,8")] +;) + +;(define_insn "*compare_scc" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (match_operator:SI 1 "arm_comparison_operator" +; [(match_operand:SI 2 "s_register_operand" "r,r") +; (match_operand:SI 3 "arm_add_operand" "rI,L")])) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "* +; if (operands[3] == const0_rtx) +; { +; if (GET_CODE (operands[1]) == LT) +; return \"mov\\t%0, %2, lsr #31\"; +; +; if (GET_CODE (operands[1]) == GE) +; return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\"; +; +; if (GET_CODE (operands[1]) == EQ) +; return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\"; +; } +; +; if (GET_CODE (operands[1]) == NE) +; { +; if (which_alternative == 1) +; return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\"; +; return \"subs\\t%0, %2, %3\;movne\\t%0, #1\"; +; } +; if (which_alternative == 1) +; output_asm_insn (\"cmn\\t%2, #%n3\", operands); +; else +; output_asm_insn (\"cmp\\t%2, %3\", operands); +; return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\"; +; " +; [(set_attr "conds" "clob") +; (set_attr "length" "12")] +;) + +;(define_insn "*cond_move" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") +; (if_then_else:SI (match_operator 3 "equality_operator" +; [(match_operator 4 "arm_comparison_operator" +; [(match_operand 5 "cc_register" "") (const_int 0)]) +; (const_int 0)]) +; (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") +; (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))] +; "TARGET_ARM" +; "* +; if (GET_CODE (operands[3]) == NE) +; { +; if (which_alternative != 1) +; output_asm_insn (\"mov%D4\\t%0, %2\", operands); +; if (which_alternative != 0) +; output_asm_insn (\"mov%d4\\t%0, %1\", operands); +; return \"\"; +; } +; if (which_alternative != 0) +; output_asm_insn (\"mov%D4\\t%0, %1\", operands); +; if (which_alternative != 1) +; output_asm_insn (\"mov%d4\\t%0, %2\", operands); +; return \"\"; +; " +; [(set_attr "conds" "use") +; (set_attr "length" "4,4,8")] +;) + +;(define_insn "*cond_arith" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (match_operator:SI 5 "shiftable_operator" +; [(match_operator:SI 4 "arm_comparison_operator" +; [(match_operand:SI 2 "s_register_operand" "r,r") +; (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) +; (match_operand:SI 1 "s_register_operand" "0,?r")])) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "* +; if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx) +; return \"%i5\\t%0, %1, %2, lsr #31\"; +; +; output_asm_insn (\"cmp\\t%2, %3\", operands); +; if (GET_CODE (operands[5]) == AND) +; output_asm_insn (\"mov%D4\\t%0, #0\", operands); +; else if (GET_CODE (operands[5]) == MINUS) +; output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands); +; else if (which_alternative != 0) +; output_asm_insn (\"mov%D4\\t%0, %1\", operands); +; return \"%i5%d4\\t%0, %1, #1\"; +; " +; [(set_attr "conds" "clob") +; (set_attr "length" "12")] +;) + +;(define_insn "*cond_sub" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") +; (match_operator:SI 4 "arm_comparison_operator" +; [(match_operand:SI 2 "s_register_operand" "r,r") +; (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "* +; output_asm_insn (\"cmp\\t%2, %3\", operands); +; if (which_alternative != 0) +; output_asm_insn (\"mov%D4\\t%0, %1\", operands); +; return \"sub%d4\\t%0, %1, #1\"; +; " +; [(set_attr "conds" "clob") +; (set_attr "length" "8,12")] +;) + +;(define_insn "*cmp_ite0" +; [(set (match_operand 6 "dominant_cc_register" "") +; (compare +; (if_then_else:SI +; (match_operator 4 "arm_comparison_operator" +; [(match_operand:SI 0 "s_register_operand" "r,r,r,r") +; (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) +; (match_operator:SI 5 "arm_comparison_operator" +; [(match_operand:SI 2 "s_register_operand" "r,r,r,r") +; (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]) +; (const_int 0)) +; (const_int 0)))] +; "TARGET_ARM" +; "* +; { +; static const char * const opcodes[4][2] = +; { +; {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\", +; \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"}, +; {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\", +; \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"}, +; {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\", +; \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"}, +; {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\", +; \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"} +; }; +; int swap = +; comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); +; +; return opcodes[which_alternative][swap]; +; }" +; [(set_attr "conds" "set") +; (set_attr "length" "8")] +;) + +;(define_insn "*cmp_ite1" +; [(set (match_operand 6 "dominant_cc_register" "") +; (compare +; (if_then_else:SI +; (match_operator 4 "arm_comparison_operator" +; [(match_operand:SI 0 "s_register_operand" "r,r,r,r") +; (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) +; (match_operator:SI 5 "arm_comparison_operator" +; [(match_operand:SI 2 "s_register_operand" "r,r,r,r") +; (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]) +; (const_int 1)) +; (const_int 0)))] +; "TARGET_ARM" +; "* +; { +; static const char * const opcodes[4][2] = +; { +; {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\", +; \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"}, +; {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\", +; \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"}, +; {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\", +; \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"}, +; {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\", +; \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"} +; }; +; int swap = +; comparison_dominates_p (GET_CODE (operands[5]), +; reverse_condition (GET_CODE (operands[4]))); +; +; return opcodes[which_alternative][swap]; +; }" +; [(set_attr "conds" "set") +; (set_attr "length" "8")] +;) + +;(define_insn "*cmp_and" +; [(set (match_operand 6 "dominant_cc_register" "") +; (compare +; (and:SI +; (match_operator 4 "arm_comparison_operator" +; [(match_operand:SI 0 "s_register_operand" "r,r,r,r") +; (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) +; (match_operator:SI 5 "arm_comparison_operator" +; [(match_operand:SI 2 "s_register_operand" "r,r,r,r") +; (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])) +; (const_int 0)))] +; "TARGET_ARM" +; "* +; { +; static const char *const opcodes[4][2] = +; { +; {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\", +; \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"}, +; {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\", +; \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"}, +; {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\", +; \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"}, +; {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\", +; \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"} +; }; +; int swap = +; comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); +; +; return opcodes[which_alternative][swap]; +; }" +; [(set_attr "conds" "set") +; (set_attr "predicable" "no") +; (set_attr "length" "8")] +;) + +;(define_insn "*cmp_ior" +; [(set (match_operand 6 "dominant_cc_register" "") +; (compare +; (ior:SI +; (match_operator 4 "arm_comparison_operator" +; [(match_operand:SI 0 "s_register_operand" "r,r,r,r") +; (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) +; (match_operator:SI 5 "arm_comparison_operator" +; [(match_operand:SI 2 "s_register_operand" "r,r,r,r") +; (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])) +; (const_int 0)))] +; "TARGET_ARM" +; "* +;{ +; static const char *const opcodes[4][2] = +; { +; {\"cmp\\t%0, %1\;cmp%D4\\t%2, %3\", +; \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"}, +; {\"cmn\\t%0, #%n1\;cmp%D4\\t%2, %3\", +; \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"}, +; {\"cmp\\t%0, %1\;cmn%D4\\t%2, #%n3\", +; \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"}, +; {\"cmn\\t%0, #%n1\;cmn%D4\\t%2, #%n3\", +; \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"} +; }; +; int swap = +; comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); +; +; return opcodes[which_alternative][swap]; +;} +;" +; [(set_attr "conds" "set") +; (set_attr "length" "8")] +;) + +;(define_insn_and_split "*ior_scc_scc" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (ior:SI (match_operator:SI 3 "arm_comparison_operator" +; [(match_operand:SI 1 "s_register_operand" "r") +; (match_operand:SI 2 "arm_add_operand" "rIL")]) +; (match_operator:SI 6 "arm_comparison_operator" +; [(match_operand:SI 4 "s_register_operand" "r") +; (match_operand:SI 5 "arm_add_operand" "rIL")]))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM +; && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y) +; != CCmode)" +; "#" +; "TARGET_ARM && reload_completed" +; [(set (match_dup 7) +; (compare +; (ior:SI +; (match_op_dup 3 [(match_dup 1) (match_dup 2)]) +; (match_op_dup 6 [(match_dup 4) (match_dup 5)])) +; (const_int 0))) +; (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))] +; "operands[7] +; = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6], +; DOM_CC_X_OR_Y), +; CC_REGNUM);" +; [(set_attr "conds" "clob") +; (set_attr "length" "16")]) +; +;; If the above pattern is followed by a CMP insn, then the compare is +; redundant, since we can rework the conditional instruction that follows. +;(define_insn_and_split "*ior_scc_scc_cmp" +; [(set (match_operand 0 "dominant_cc_register" "") +; (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator" +; [(match_operand:SI 1 "s_register_operand" "r") +; (match_operand:SI 2 "arm_add_operand" "rIL")]) +; (match_operator:SI 6 "arm_comparison_operator" +; [(match_operand:SI 4 "s_register_operand" "r") +; (match_operand:SI 5 "arm_add_operand" "rIL")])) +; (const_int 0))) +; (set (match_operand:SI 7 "s_register_operand" "=r") +; (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) +; (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] +; "TARGET_ARM" +; "#" +; "TARGET_ARM && reload_completed" +; [(set (match_dup 0) +; (compare +; (ior:SI +; (match_op_dup 3 [(match_dup 1) (match_dup 2)]) +; (match_op_dup 6 [(match_dup 4) (match_dup 5)])) +; (const_int 0))) +; (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))] +; "" +; [(set_attr "conds" "set") +; (set_attr "length" "16")]) + +;(define_insn_and_split "*and_scc_scc" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (and:SI (match_operator:SI 3 "arm_comparison_operator" +; [(match_operand:SI 1 "s_register_operand" "r") +; (match_operand:SI 2 "arm_add_operand" "rIL")]) +; (match_operator:SI 6 "arm_comparison_operator" +; [(match_operand:SI 4 "s_register_operand" "r") +; (match_operand:SI 5 "arm_add_operand" "rIL")]))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM +; && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) +; != CCmode)" +; "#" +; "TARGET_ARM && reload_completed +; && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) +; != CCmode)" +; [(set (match_dup 7) +; (compare +; (and:SI +; (match_op_dup 3 [(match_dup 1) (match_dup 2)]) +; (match_op_dup 6 [(match_dup 4) (match_dup 5)])) +; (const_int 0))) +; (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))] +; "operands[7] +; = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6], +; DOM_CC_X_AND_Y), +; CC_REGNUM);" +; [(set_attr "conds" "clob") +; (set_attr "length" "16")]) - if (val1 == 4 || val2 == 4) - /* Other val must be 8, since we know they are adjacent and neither - is zero. */ - output_asm_insn (\"ldm%?ib\\t%0, {%1, %2}\", ldm); - else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1)) - { - ldm[0] = ops[0] = operands[4]; - ops[1] = base_reg; - ops[2] = GEN_INT (val1); - output_add_immediate (ops); - if (val1 < val2) - output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm); - else - output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm); - } - else - { - /* Offset is out of range for a single add, so use two ldr. */ - ops[0] = ldm[1]; - ops[1] = base_reg; - ops[2] = GEN_INT (val1); - output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops); - ops[0] = ldm[2]; - ops[2] = GEN_INT (val2); - output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops); - } - } - else if (val1 != 0) - { - if (val1 < val2) - output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm); - else - output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm); - } - else - { - if (val1 < val2) - output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm); - else - output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm); - } - output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith); - return \"\"; - }" - [(set_attr "length" "12") - (set_attr "predicable" "yes") - (set_attr "type" "load1")] -) +; If the above pattern is followed by a CMP insn, then the compare is +; redundant, since we can rework the conditional instruction that follows. +;(define_insn_and_split "*and_scc_scc_cmp" +; [(set (match_operand 0 "dominant_cc_register" "") +; (compare (and:SI (match_operator:SI 3 "arm_comparison_operator" +; [(match_operand:SI 1 "s_register_operand" "r") +; (match_operand:SI 2 "arm_add_operand" "rIL")]) +; (match_operator:SI 6 "arm_comparison_operator" +; [(match_operand:SI 4 "s_register_operand" "r") +; (match_operand:SI 5 "arm_add_operand" "rIL")])) +; (const_int 0))) +; (set (match_operand:SI 7 "s_register_operand" "=r") +; (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) +; (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] +; "TARGET_ARM" +; "#" +; "TARGET_ARM && reload_completed" +; [(set (match_dup 0) +; (compare +; (and:SI +; (match_op_dup 3 [(match_dup 1) (match_dup 2)]) +; (match_op_dup 6 [(match_dup 4) (match_dup 5)])) +; (const_int 0))) +; (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))] +; "" +; [(set_attr "conds" "set") +; (set_attr "length" "16")]) +; +;;; If there is no dominance in the comparison, then we can still save an +;;; instruction in the AND case, since we can know that the second compare +;;; need only zero the value if false (if true, then the value is already +;;; correct). +;(define_insn_and_split "*and_scc_scc_nodom" +; [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r") +; (and:SI (match_operator:SI 3 "arm_comparison_operator" +; [(match_operand:SI 1 "s_register_operand" "r,r,0") +; (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")]) +; (match_operator:SI 6 "arm_comparison_operator" +; [(match_operand:SI 4 "s_register_operand" "r,r,r") +; (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")]))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM +; ;&& (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) +; == CCmode)" +; "#" +; "TARGET_ARM && reload_completed" +; [(parallel [(set (match_dup 0) +; (match_op_dup 3 [(match_dup 1) (match_dup 2)])) +; (clobber (reg:CC CC_REGNUM))]) +; (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)])) +; (set (match_dup 0) +; (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)]) +; (match_dup 0) +; (const_int 0)))] +; "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]), +; operands[4], operands[5]), +; CC_REGNUM); +; operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4], +; operands[5]);" +; [(set_attr "conds" "clob") +; (set_attr "length" "20")]) + +;(define_split +; [(set (reg:CC_NOOV CC_REGNUM) +; (compare:CC_NOOV (ior:SI +; (and:SI (match_operand:SI 0 "s_register_operand" "") +; (const_int 1)) +; (match_operator:SI 1 "comparison_operator" +; [(match_operand:SI 2 "s_register_operand" "") +; (match_operand:SI 3 "arm_add_operand" "")])) +; (const_int 0))) +; (clobber (match_operand:SI 4 "s_register_operand" ""))] +; "TARGET_ARM" +; [(set (match_dup 4) +; (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)]) +; (match_dup 0))) +; (set (reg:CC_NOOV CC_REGNUM) +; (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1)) +; (const_int 0)))] +; "") + +;(define_split +; [(set (reg:CC_NOOV CC_REGNUM) +; (compare:CC_NOOV (ior:SI +; (match_operator:SI 1 "comparison_operator" +; [(match_operand:SI 2 "s_register_operand" "") +; (match_operand:SI 3 "arm_add_operand" "")]) +; (and:SI (match_operand:SI 0 "s_register_operand" "") +; (const_int 1))) +; (const_int 0))) +; (clobber (match_operand:SI 4 "s_register_operand" ""))] +; "TARGET_ARM" +; [(set (match_dup 4) +; (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)]) +; (match_dup 0))) +; (set (reg:CC_NOOV CC_REGNUM) +; (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1)) +; (const_int 0)))] +; "") + +;(define_insn "*negscc" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (neg:SI (match_operator 3 "arm_comparison_operator" +; [(match_operand:SI 1 "s_register_operand" "r") +; (match_operand:SI 2 "arm_rhs_operand" "rI")]))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "* +; if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx) +; return \"mov\\t%0, %1, asr #31\"; +; +; if (GET_CODE (operands[3]) == NE) +; return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\"; +; +; if (GET_CODE (operands[3]) == GT) +; return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\"; +; +; output_asm_insn (\"cmp\\t%1, %2\", operands); +; output_asm_insn (\"mov%D3\\t%0, #0\", operands); +; return \"mvn%d3\\t%0, #0\"; +; " +; [(set_attr "conds" "clob") +; (set_attr "length" "12")] +;) + +;(define_insn "movcond" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") +; (if_then_else:SI +; (match_operator 5 "arm_comparison_operator" +; [(match_operand:SI 3 "s_register_operand" "r,r,r") +; (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")]) +; (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") +; (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "* +; if (GET_CODE (operands[5]) == LT +; && (operands[4] == const0_rtx)) +; { +; if (which_alternative != 1 && GET_CODE (operands[1]) == REG) +; { +; if (operands[2] == const0_rtx) +; return \"and\\t%0, %1, %3, asr #31\"; +; return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\"; +; } +; else if (which_alternative != 0 && GET_CODE (operands[2]) == REG) +; { +; if (operands[1] == const0_rtx) +; return \"bic\\t%0, %2, %3, asr #31\"; +; return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\"; +; } +; /* The only case that falls through to here is when both ops 1 & 2 +; are constants. */ +; } +; +; if (GET_CODE (operands[5]) == GE +; && (operands[4] == const0_rtx)) +; { +; if (which_alternative != 1 && GET_CODE (operands[1]) == REG) +; { +; if (operands[2] == const0_rtx) +; return \"bic\\t%0, %1, %3, asr #31\"; +; return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\"; +; } +; else if (which_alternative != 0 && GET_CODE (operands[2]) == REG) +; { +; if (operands[1] == const0_rtx) +; return \"and\\t%0, %2, %3, asr #31\"; +; return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\"; +; } +; /* The only case that falls through to here is when both ops 1 & 2 +; are constants. */ +; } +; if (GET_CODE (operands[4]) == CONST_INT +; && !const_ok_for_arm (INTVAL (operands[4]))) +; output_asm_insn (\"cmn\\t%3, #%n4\", operands); +; else +; output_asm_insn (\"cmp\\t%3, %4\", operands); +; if (which_alternative != 0) +; output_asm_insn (\"mov%d5\\t%0, %1\", operands); +; if (which_alternative != 1) +; output_asm_insn (\"mov%D5\\t%0, %2\", operands); +; return \"\"; +; " +; [(set_attr "conds" "clob") +; (set_attr "length" "8,8,12")] +;) + +;(define_insn "*ifcompare_plus_move" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (if_then_else:SI (match_operator 6 "arm_comparison_operator" +; [(match_operand:SI 4 "s_register_operand" "r,r") +; (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) +; (plus:SI +; (match_operand:SI 2 "s_register_operand" "r,r") +; (match_operand:SI 3 "arm_add_operand" "rIL,rIL")) +; (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "#" +; [(set_attr "conds" "clob") +; (set_attr "length" "8,12")] +;) + +;(define_insn "*if_plus_move" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r") +; (if_then_else:SI +; (match_operator 4 "arm_comparison_operator" +; [(match_operand 5 "cc_register" "") (const_int 0)]) +; (plus:SI +; (match_operand:SI 2 "s_register_operand" "r,r,r,r") +; (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L")) +; (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))] +; "TARGET_ARM" +; "@ +; add%d4\\t%0, %2, %3 +; sub%d4\\t%0, %2, #%n3 +; add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1 +; sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1" +; [(set_attr "conds" "use") +; (set_attr "length" "4,4,8,8") +; (set_attr "type" "*,*,*,*")] +;) + +;(define_insn "*ifcompare_move_plus" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (if_then_else:SI (match_operator 6 "arm_comparison_operator" +; [(match_operand:SI 4 "s_register_operand" "r,r") +; (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) +; (match_operand:SI 1 "arm_rhs_operand" "0,?rI") +; (plus:SI +; (match_operand:SI 2 "s_register_operand" "r,r") +; (match_operand:SI 3 "arm_add_operand" "rIL,rIL")))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "#" +; [(set_attr "conds" "clob") +; (set_attr "length" "8,12")] +;) + +;(define_insn "*if_move_plus" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r") +; (if_then_else:SI +; (match_operator 4 "arm_comparison_operator" +; [(match_operand 5 "cc_register" "") (const_int 0)]) +; (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI") +; (plus:SI +; (match_operand:SI 2 "s_register_operand" "r,r,r,r") +; (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))] +; "TARGET_ARM" +; "@ +; add%D4\\t%0, %2, %3 +; sub%D4\\t%0, %2, #%n3 +; add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1 +; sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1" +; [(set_attr "conds" "use") +; (set_attr "length" "4,4,8,8") +; (set_attr "type" "*,*,*,*")] +;) + +;(define_insn "*ifcompare_arith_arith" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (if_then_else:SI (match_operator 9 "arm_comparison_operator" +; [(match_operand:SI 5 "s_register_operand" "r") +; (match_operand:SI 6 "arm_add_operand" "rIL")]) +; (match_operator:SI 8 "shiftable_operator" +; [(match_operand:SI 1 "s_register_operand" "r") +; (match_operand:SI 2 "arm_rhs_operand" "rI")]) +; (match_operator:SI 7 "shiftable_operator" +; [(match_operand:SI 3 "s_register_operand" "r") +; (match_operand:SI 4 "arm_rhs_operand" "rI")]))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "#" +; [(set_attr "conds" "clob") +; (set_attr "length" "12")] +;) + +;(define_insn "*if_arith_arith" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (if_then_else:SI (match_operator 5 "arm_comparison_operator" +; [(match_operand 8 "cc_register" "") (const_int 0)]) +; (match_operator:SI 6 "shiftable_operator" +; [(match_operand:SI 1 "s_register_operand" "r") +; (match_operand:SI 2 "arm_rhs_operand" "rI")]) +; (match_operator:SI 7 "shiftable_operator" +; [(match_operand:SI 3 "s_register_operand" "r") +; (match_operand:SI 4 "arm_rhs_operand" "rI")])))] +; "TARGET_ARM" +; "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4" +; [(set_attr "conds" "use") +; (set_attr "length" "8")] +;) + +;(define_insn "*ifcompare_arith_move" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (if_then_else:SI (match_operator 6 "arm_comparison_operator" +; [(match_operand:SI 2 "s_register_operand" "r,r") +; (match_operand:SI 3 "arm_add_operand" "rIL,rIL")]) +; (match_operator:SI 7 "shiftable_operator" +; [(match_operand:SI 4 "s_register_operand" "r,r") +; (match_operand:SI 5 "arm_rhs_operand" "rI,rI")]) +; (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "* +; /* If we have an operation where (op x 0) is the identity operation and +; the conditional operator is LT or GE and we are comparing against zero and +; everything is in registers then we can do this in two instructions. */ +; if (operands[3] == const0_rtx +; && GET_CODE (operands[7]) != AND +; && GET_CODE (operands[5]) == REG +; && GET_CODE (operands[1]) == REG +; && REGNO (operands[1]) == REGNO (operands[4]) +; && REGNO (operands[4]) != REGNO (operands[0])) +; { +; if (GET_CODE (operands[6]) == LT) +; return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\"; +; else if (GET_CODE (operands[6]) == GE) +; return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\"; +; } +; if (GET_CODE (operands[3]) == CONST_INT +; && !const_ok_for_arm (INTVAL (operands[3]))) +; output_asm_insn (\"cmn\\t%2, #%n3\", operands); +; else +; output_asm_insn (\"cmp\\t%2, %3\", operands); +; output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands); +; if (which_alternative != 0) +; return \"mov%D6\\t%0, %1\"; +; return \"\"; +; " +; [(set_attr "conds" "clob") +; (set_attr "length" "8,12")] +;) + +;(define_insn "*if_arith_move" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (if_then_else:SI (match_operator 4 "arm_comparison_operator" +; [(match_operand 6 "cc_register" "") (const_int 0)]) +; (match_operator:SI 5 "shiftable_operator" +; [(match_operand:SI 2 "s_register_operand" "r,r") +; (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) +; (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))] +; "TARGET_ARM" +; "@ +; %I5%d4\\t%0, %2, %3 +; %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1" +; [(set_attr "conds" "use") +; (set_attr "length" "4,8") +; (set_attr "type" "*,*")] +;) + +;(define_insn "*ifcompare_move_arith" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (if_then_else:SI (match_operator 6 "arm_comparison_operator" +; [(match_operand:SI 4 "s_register_operand" "r,r") +; (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) +; (match_operand:SI 1 "arm_rhs_operand" "0,?rI") +; (match_operator:SI 7 "shiftable_operator" +; [(match_operand:SI 2 "s_register_operand" "r,r") +; (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "* +; /* If we have an operation where (op x 0) is the identity operation and +; the conditional operator is LT or GE and we are comparing against zero and +; everything is in registers then we can do this in two instructions */ +; if (operands[5] == const0_rtx +; && GET_CODE (operands[7]) != AND +; && GET_CODE (operands[3]) == REG +; && GET_CODE (operands[1]) == REG +; && REGNO (operands[1]) == REGNO (operands[2]) +; && REGNO (operands[2]) != REGNO (operands[0])) +; { +; if (GET_CODE (operands[6]) == GE) +; return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\"; +; else if (GET_CODE (operands[6]) == LT) +; return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\"; +; } +; +; if (GET_CODE (operands[5]) == CONST_INT +; && !const_ok_for_arm (INTVAL (operands[5]))) +; output_asm_insn (\"cmn\\t%4, #%n5\", operands); +; else +; output_asm_insn (\"cmp\\t%4, %5\", operands); +; +; if (which_alternative != 0) +; output_asm_insn (\"mov%d6\\t%0, %1\", operands); +; return \"%I7%D6\\t%0, %2, %3\"; +; " +; [(set_attr "conds" "clob") +; (set_attr "length" "8,12")] +;) + +;(define_insn "*if_move_arith" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (if_then_else:SI +; (match_operator 4 "arm_comparison_operator" +; [(match_operand 6 "cc_register" "") (const_int 0)]) +; (match_operand:SI 1 "arm_rhs_operand" "0,?rI") +; (match_operator:SI 5 "shiftable_operator" +; [(match_operand:SI 2 "s_register_operand" "r,r") +; (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))] +; "TARGET_ARM" +; "@ +; %I5%D4\\t%0, %2, %3 +; %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1" +; [(set_attr "conds" "use") +; (set_attr "length" "4,8") +; (set_attr "type" "*,*")] +;) + +;(define_insn "*ifcompare_move_not" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (if_then_else:SI +; (match_operator 5 "arm_comparison_operator" +; [(match_operand:SI 3 "s_register_operand" "r,r") +; (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) +; (match_operand:SI 1 "arm_not_operand" "0,?rIK") +; (not:SI +; (match_operand:SI 2 "s_register_operand" "r,r")))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "#" +; [(set_attr "conds" "clob") +; (set_attr "length" "8,12")] +;) + +;(define_insn "*if_move_not" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") +; (if_then_else:SI +; (match_operator 4 "arm_comparison_operator" +; [(match_operand 3 "cc_register" "") (const_int 0)]) +; (match_operand:SI 1 "arm_not_operand" "0,?rI,K") +; (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))] +; "TARGET_ARM" +; "@ +; mvn%D4\\t%0, %2 +; mov%d4\\t%0, %1\;mvn%D4\\t%0, %2 +; mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2" +; [(set_attr "conds" "use") +; (set_attr "length" "4,8,8")] +;) + +;(define_insn "*ifcompare_not_move" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (if_then_else:SI +; (match_operator 5 "arm_comparison_operator" +; [(match_operand:SI 3 "s_register_operand" "r,r") +; (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) +; (not:SI +; (match_operand:SI 2 "s_register_operand" "r,r")) +; (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "#" +; [(set_attr "conds" "clob") +; (set_attr "length" "8,12")] +;) + +;(define_insn "*if_not_move" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") +; (if_then_else:SI +; (match_operator 4 "arm_comparison_operator" +; [(match_operand 3 "cc_register" "") (const_int 0)]) +; (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r")) +; (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] +; "TARGET_ARM" +; "@ +; mvn%d4\\t%0, %2 +; mov%D4\\t%0, %1\;mvn%d4\\t%0, %2 +; mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2" +; [(set_attr "conds" "use") +; (set_attr "length" "4,8,8")] +;) + +;(define_insn "*ifcompare_shift_move" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (if_then_else:SI +; (match_operator 6 "arm_comparison_operator" +; [(match_operand:SI 4 "s_register_operand" "r,r") +; (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) +; (match_operator:SI 7 "shift_operator" +; [(match_operand:SI 2 "s_register_operand" "r,r") +; (match_operand:SI 3 "arm_rhs_operand" "rM,rM")]) +; (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "#" +; [(set_attr "conds" "clob") +; (set_attr "length" "8,12")] +;) + +;(define_insn "*if_shift_move" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") +; (if_then_else:SI +; (match_operator 5 "arm_comparison_operator" +; [(match_operand 6 "cc_register" "") (const_int 0)]) +; (match_operator:SI 4 "shift_operator" +; [(match_operand:SI 2 "s_register_operand" "r,r,r") +; (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")]) +; (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] +; "TARGET_ARM" +; "@ +; mov%d5\\t%0, %2%S4 +; mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4 +; mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4" +; [(set_attr "conds" "use") +; (set_attr "shift" "2") +; (set_attr "length" "4,8,8") +; (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") +; (const_string "alu_shift") +; (const_string "alu_shift_reg")))] +;) + +;(define_insn "*ifcompare_move_shift" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (if_then_else:SI +; (match_operator 6 "arm_comparison_operator" +; [(match_operand:SI 4 "s_register_operand" "r,r") +; (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) +; (match_operand:SI 1 "arm_not_operand" "0,?rIK") +; (match_operator:SI 7 "shift_operator" +; [(match_operand:SI 2 "s_register_operand" "r,r") +; (match_operand:SI 3 "arm_rhs_operand" "rM,rM")]))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "#" +; [(set_attr "conds" "clob") +; (set_attr "length" "8,12")] +;) + +;(define_insn "*if_move_shift" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") +; (if_then_else:SI +; (match_operator 5 "arm_comparison_operator" +; [(match_operand 6 "cc_register" "") (const_int 0)]) +; (match_operand:SI 1 "arm_not_operand" "0,?rI,K") +; (match_operator:SI 4 "shift_operator" +; [(match_operand:SI 2 "s_register_operand" "r,r,r") +; (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))] +; "TARGET_ARM" +; "@ +; mov%D5\\t%0, %2%S4 +; mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4 +; mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4" +; [(set_attr "conds" "use") +; (set_attr "shift" "2") +; (set_attr "length" "4,8,8") +; (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") +; (const_string "alu_shift") +; (const_string "alu_shift_reg")))] +;) + +;(define_insn "*ifcompare_shift_shift" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (if_then_else:SI +; (match_operator 7 "arm_comparison_operator" +; [(match_operand:SI 5 "s_register_operand" "r") +; (match_operand:SI 6 "arm_add_operand" "rIL")]) +; (match_operator:SI 8 "shift_operator" +; [(match_operand:SI 1 "s_register_operand" "r") +; (match_operand:SI 2 "arm_rhs_operand" "rM")]) +; (match_operator:SI 9 "shift_operator" +; [(match_operand:SI 3 "s_register_operand" "r") +; (match_operand:SI 4 "arm_rhs_operand" "rM")]))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "#" +; [(set_attr "conds" "clob") +; (set_attr "length" "12")] +;) + +;(define_insn "*if_shift_shift" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (if_then_else:SI +; (match_operator 5 "arm_comparison_operator" +; [(match_operand 8 "cc_register" "") (const_int 0)]) +; (match_operator:SI 6 "shift_operator" +; [(match_operand:SI 1 "s_register_operand" "r") +; (match_operand:SI 2 "arm_rhs_operand" "rM")]) +; (match_operator:SI 7 "shift_operator" +; [(match_operand:SI 3 "s_register_operand" "r") +; (match_operand:SI 4 "arm_rhs_operand" "rM")])))] +; "TARGET_ARM" +; "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7" +; [(set_attr "conds" "use") +; (set_attr "shift" "1") +; (set_attr "length" "8") +; (set (attr "type") (if_then_else +; (and (match_operand 2 "const_int_operand" "") +; (match_operand 4 "const_int_operand" "")) +; (const_string "alu_shift") +; (const_string "alu_shift_reg")))] +;) + +;(define_insn "*ifcompare_not_arith" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (if_then_else:SI +; (match_operator 6 "arm_comparison_operator" +; [(match_operand:SI 4 "s_register_operand" "r") +; (match_operand:SI 5 "arm_add_operand" "rIL")]) +; (not:SI (match_operand:SI 1 "s_register_operand" "r")) +; (match_operator:SI 7 "shiftable_operator" +; [(match_operand:SI 2 "s_register_operand" "r") +; (match_operand:SI 3 "arm_rhs_operand" "rI")]))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "#" +; [(set_attr "conds" "clob") +; (set_attr "length" "12")] +;) + +;(define_insn "*if_not_arith" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (if_then_else:SI +; (match_operator 5 "arm_comparison_operator" +; [(match_operand 4 "cc_register" "") (const_int 0)]) +; (not:SI (match_operand:SI 1 "s_register_operand" "r")) +; (match_operator:SI 6 "shiftable_operator" +; [(match_operand:SI 2 "s_register_operand" "r") +; (match_operand:SI 3 "arm_rhs_operand" "rI")])))] +; "TARGET_ARM" +; "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3" +; [(set_attr "conds" "use") +; (set_attr "length" "8")] +;) + +;(define_insn "*ifcompare_arith_not" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (if_then_else:SI +; (match_operator 6 "arm_comparison_operator" +; [(match_operand:SI 4 "s_register_operand" "r") +; (match_operand:SI 5 "arm_add_operand" "rIL")]) +; (match_operator:SI 7 "shiftable_operator" +; [(match_operand:SI 2 "s_register_operand" "r") +; (match_operand:SI 3 "arm_rhs_operand" "rI")]) +; (not:SI (match_operand:SI 1 "s_register_operand" "r")))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "#" +; [(set_attr "conds" "clob") +; (set_attr "length" "12")] +;) + +;(define_insn "*if_arith_not" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (if_then_else:SI +; (match_operator 5 "arm_comparison_operator" +; [(match_operand 4 "cc_register" "") (const_int 0)]) +; (match_operator:SI 6 "shiftable_operator" +; [(match_operand:SI 2 "s_register_operand" "r") +; (match_operand:SI 3 "arm_rhs_operand" "rI")]) +; (not:SI (match_operand:SI 1 "s_register_operand" "r"))))] +; "TARGET_ARM" +; "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3" +; [(set_attr "conds" "use") +; (set_attr "length" "8")] +;) + +;(define_insn "*ifcompare_neg_move" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (if_then_else:SI +; (match_operator 5 "arm_comparison_operator" +; [(match_operand:SI 3 "s_register_operand" "r,r") +; (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) +; (neg:SI (match_operand:SI 2 "s_register_operand" "r,r")) +; (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "#" +; [(set_attr "conds" "clob") +; (set_attr "length" "8,12")] +;) + +;(define_insn "*if_neg_move" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") +; (if_then_else:SI +; (match_operator 4 "arm_comparison_operator" +; [(match_operand 3 "cc_register" "") (const_int 0)]) +; (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r")) +; (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] +; "TARGET_ARM" +; "@ +; rsb%d4\\t%0, %2, #0 +; mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0 +; mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0" +; [(set_attr "conds" "use") +; (set_attr "length" "4,8,8")] +;) + +;(define_insn "*ifcompare_move_neg" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (if_then_else:SI +; (match_operator 5 "arm_comparison_operator" +; [(match_operand:SI 3 "s_register_operand" "r,r") +; (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) +; (match_operand:SI 1 "arm_not_operand" "0,?rIK") +; (neg:SI (match_operand:SI 2 "s_register_operand" "r,r")))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "#" +; [(set_attr "conds" "clob") +; (set_attr "length" "8,12")] +;) + +;(define_insn "*if_move_neg" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") +; (if_then_else:SI +; (match_operator 4 "arm_comparison_operator" +; [(match_operand 3 "cc_register" "") (const_int 0)]) +; (match_operand:SI 1 "arm_not_operand" "0,?rI,K") +; (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))] +; "TARGET_ARM" +; "@ +; rsb%D4\\t%0, %2, #0 +; mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0 +; mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0" +; [(set_attr "conds" "use") +; (set_attr "length" "4,8,8")] +;) + +;(define_insn "*arith_adjacentmem" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (match_operator:SI 1 "shiftable_operator" +; [(match_operand:SI 2 "memory_operand" "m") +; (match_operand:SI 3 "memory_operand" "m")])) +; (clobber (match_scratch:SI 4 "=r"))] +; "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])" +; "* +; { +; rtx ldm[3]; +; rtx arith[4]; +; rtx base_reg; +; HOST_WIDE_INT val1 = 0, val2 = 0; +; +; if (REGNO (operands[0]) > REGNO (operands[4])) +; { +; ldm[1] = operands[4]; +; ldm[2] = operands[0]; +; } +; else +; { +; ldm[1] = operands[0]; +; ldm[2] = operands[4]; +; } +; +; base_reg = XEXP (operands[2], 0); +; +; if (!REG_P (base_reg)) +; { +; val1 = INTVAL (XEXP (base_reg, 1)); +; base_reg = XEXP (base_reg, 0); +; } +; +; if (!REG_P (XEXP (operands[3], 0))) +; val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1)); +; +; arith[0] = operands[0]; +; arith[3] = operands[1]; +; +; if (val1 < val2) +; { +; arith[1] = ldm[1]; +; arith[2] = ldm[2]; +; } +; else +; { +; arith[1] = ldm[2]; +; arith[2] = ldm[1]; +; } +; +; ldm[0] = base_reg; +; if (val1 !=0 && val2 != 0) +; { +; rtx ops[3]; +; +; if (val1 == 4 || val2 == 4) +; /* Other val must be 8, since we know they are adjacent and neither +; is zero. */ +; output_asm_insn (\"ldm%?ib\\t%0, {%1, %2}\", ldm); +; else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1)) +; { +; ldm[0] = ops[0] = operands[4]; +; ops[1] = base_reg; +; ops[2] = GEN_INT (val1); +; output_add_immediate (ops); +; if (val1 < val2) +; output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm); +; else +; output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm); +; } +; else +; { +; /* Offset is out of range for a single add, so use two ldr. */ +; ops[0] = ldm[1]; +; ops[1] = base_reg; +; ops[2] = GEN_INT (val1); +; output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops); +; ops[0] = ldm[2]; +; ops[2] = GEN_INT (val2); +; output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops); +; } +; } +; else if (val1 != 0) +; { +; if (val1 < val2) +; output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm); +; else +; output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm); +; } +; else +; { +; if (val1 < val2) +; output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm); +; else +; output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm); +; } +; output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith); +; return \"\"; +; }" +; [(set_attr "length" "12") +; (set_attr "predicable" "yes") +; (set_attr "type" "load1")] +;) ; This pattern is never tried by combine, so do it as a peephole -(define_peephole2 - [(set (match_operand:SI 0 "arm_general_register_operand" "") - (match_operand:SI 1 "arm_general_register_operand" "")) - (set (reg:CC CC_REGNUM) - (compare:CC (match_dup 1) (const_int 0)))] - "TARGET_ARM" - [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0))) - (set (match_dup 0) (match_dup 1))])] - "" -) +;(define_peephole2 +; [(set (match_operand:SI 0 "arm_general_register_operand" "") +; (match_operand:SI 1 "arm_general_register_operand" "")) +; (set (reg:CC CC_REGNUM) +; (compare:CC (match_dup 1) (const_int 0)))] +; "TARGET_ARM" +; [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0))) +; (set (match_dup 0) (match_dup 1))])] +; "" +;) ; Peepholes to spot possible load- and store-multiples, if the ordering is ; reversed, check that the memory references aren't volatile. @@ -9536,20 +9717,20 @@ " ) -(define_split - [(set (match_operand:SI 0 "s_register_operand" "") - (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "") - (const_int 0)) - (neg:SI (match_operator:SI 2 "arm_comparison_operator" - [(match_operand:SI 3 "s_register_operand" "") - (match_operand:SI 4 "arm_rhs_operand" "")])))) - (clobber (match_operand:SI 5 "s_register_operand" ""))] - "TARGET_ARM" - [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31)))) - (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) - (match_dup 5)))] - "" -) +;(define_split +; [(set (match_operand:SI 0 "s_register_operand" "") +; (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "") +; (const_int 0)) +; (neg:SI (match_operator:SI 2 "arm_comparison_operator" +; [(match_operand:SI 3 "s_register_operand" "") +; (match_operand:SI 4 "arm_rhs_operand" "")])))) +; (clobber (match_operand:SI 5 "s_register_operand" ""))] +; "TARGET_ARM" +; [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31)))) +; (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) +; (match_dup 5)))] +; "" +;) ;; This split can be used because CC_Z mode implies that the following ;; branch will be an equality, or an unsigned inequality, so the sign @@ -9619,7 +9800,7 @@ return arm_output_epilogue (next_nonnote_insn (insn)); " ;; Length is absolute worst case - [(set_attr "length" "44") + [(set_attr "length" "108") (set_attr "type" "block") ;; We don't clobber the conditions, but the potential length of this ;; operation is sufficient to make conditionalizing the sequence @@ -9637,7 +9818,7 @@ return thumb_unexpanded_epilogue (); " ; Length is absolute worst case - [(set_attr "length" "44") + [(set_attr "length" "108") (set_attr "type" "block") ;; We don't clobber the conditions, but the potential length of this ;; operation is sufficient to make conditionalizing the sequence @@ -9673,168 +9854,168 @@ ;; some extent with the conditional data operations, so we have to split them ;; up again here. -(define_split - [(set (match_operand:SI 0 "s_register_operand" "") - (if_then_else:SI (match_operator 1 "arm_comparison_operator" - [(match_operand 2 "" "") (match_operand 3 "" "")]) - (match_dup 0) - (match_operand 4 "" ""))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM && reload_completed" - [(set (match_dup 5) (match_dup 6)) - (cond_exec (match_dup 7) - (set (match_dup 0) (match_dup 4)))] - " - { - enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), - operands[2], operands[3]); - enum rtx_code rc = GET_CODE (operands[1]); - - operands[5] = gen_rtx_REG (mode, CC_REGNUM); - operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]); - if (mode == CCFPmode || mode == CCFPEmode) - rc = reverse_condition_maybe_unordered (rc); - else - rc = reverse_condition (rc); - - operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx); - }" -) - -(define_split - [(set (match_operand:SI 0 "s_register_operand" "") - (if_then_else:SI (match_operator 1 "arm_comparison_operator" - [(match_operand 2 "" "") (match_operand 3 "" "")]) - (match_operand 4 "" "") - (match_dup 0))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM && reload_completed" - [(set (match_dup 5) (match_dup 6)) - (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)]) - (set (match_dup 0) (match_dup 4)))] - " - { - enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), - operands[2], operands[3]); - - operands[5] = gen_rtx_REG (mode, CC_REGNUM); - operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]); - }" -) - -(define_split - [(set (match_operand:SI 0 "s_register_operand" "") - (if_then_else:SI (match_operator 1 "arm_comparison_operator" - [(match_operand 2 "" "") (match_operand 3 "" "")]) - (match_operand 4 "" "") - (match_operand 5 "" ""))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM && reload_completed" - [(set (match_dup 6) (match_dup 7)) - (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)]) - (set (match_dup 0) (match_dup 4))) - (cond_exec (match_dup 8) - (set (match_dup 0) (match_dup 5)))] - " - { - enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), - operands[2], operands[3]); - enum rtx_code rc = GET_CODE (operands[1]); - - operands[6] = gen_rtx_REG (mode, CC_REGNUM); - operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]); - if (mode == CCFPmode || mode == CCFPEmode) - rc = reverse_condition_maybe_unordered (rc); - else - rc = reverse_condition (rc); - - operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); - }" -) - -(define_split - [(set (match_operand:SI 0 "s_register_operand" "") - (if_then_else:SI (match_operator 1 "arm_comparison_operator" - [(match_operand:SI 2 "s_register_operand" "") - (match_operand:SI 3 "arm_add_operand" "")]) - (match_operand:SI 4 "arm_rhs_operand" "") - (not:SI - (match_operand:SI 5 "s_register_operand" "")))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM && reload_completed" - [(set (match_dup 6) (match_dup 7)) - (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)]) - (set (match_dup 0) (match_dup 4))) - (cond_exec (match_dup 8) - (set (match_dup 0) (not:SI (match_dup 5))))] - " - { - enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), - operands[2], operands[3]); - enum rtx_code rc = GET_CODE (operands[1]); - - operands[6] = gen_rtx_REG (mode, CC_REGNUM); - operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]); - if (mode == CCFPmode || mode == CCFPEmode) - rc = reverse_condition_maybe_unordered (rc); - else - rc = reverse_condition (rc); - - operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); - }" -) - -(define_insn "*cond_move_not" - [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (if_then_else:SI (match_operator 4 "arm_comparison_operator" - [(match_operand 3 "cc_register" "") (const_int 0)]) - (match_operand:SI 1 "arm_rhs_operand" "0,?rI") - (not:SI - (match_operand:SI 2 "s_register_operand" "r,r"))))] - "TARGET_ARM" - "@ - mvn%D4\\t%0, %2 - mov%d4\\t%0, %1\;mvn%D4\\t%0, %2" - [(set_attr "conds" "use") - (set_attr "length" "4,8")] -) +;(define_split +; [(set (match_operand:SI 0 "s_register_operand" "") +; (if_then_else:SI (match_operator 1 "arm_comparison_operator" +; [(match_operand 2 "" "") (match_operand 3 "" "")]) +; (match_dup 0) +; (match_operand 4 "" ""))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM && reload_completed" +; [(set (match_dup 5) (match_dup 6)) +; (cond_exec (match_dup 7) +; (set (match_dup 0) (match_dup 4)))] +; " +; { +; enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), +; operands[2], operands[3]); +; enum rtx_code rc = GET_CODE (operands[1]); +; +; operands[5] = gen_rtx_REG (mode, CC_REGNUM); +; operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]); +; if (mode == CCFPmode || mode == CCFPEmode) +; rc = reverse_condition_maybe_unordered (rc); +; else +; rc = reverse_condition (rc); +; +; operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx); +; }" +;) + +;(define_split +; [(set (match_operand:SI 0 "s_register_operand" "") +; (if_then_else:SI (match_operator 1 "arm_comparison_operator" +; [(match_operand 2 "" "") (match_operand 3 "" "")]) +; (match_operand 4 "" "") +; (match_dup 0))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM && reload_completed" +; [(set (match_dup 5) (match_dup 6)) +; (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)]) +; (set (match_dup 0) (match_dup 4)))] +; " +; { +; enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), +; operands[2], operands[3]); +; +; operands[5] = gen_rtx_REG (mode, CC_REGNUM); +; operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]); +; }" +;) + +;(define_split +; [(set (match_operand:SI 0 "s_register_operand" "") +; (if_then_else:SI (match_operator 1 "arm_comparison_operator" +; [(match_operand 2 "" "") (match_operand 3 "" "")]) +; (match_operand 4 "" "") +; (match_operand 5 "" ""))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM && reload_completed" +; [(set (match_dup 6) (match_dup 7)) +; (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)]) +; (set (match_dup 0) (match_dup 4))) +; (cond_exec (match_dup 8) +; (set (match_dup 0) (match_dup 5)))] +; " +; { +; enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), +; operands[2], operands[3]); +; enum rtx_code rc = GET_CODE (operands[1]); +; +; operands[6] = gen_rtx_REG (mode, CC_REGNUM); +; operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]); +; if (mode == CCFPmode || mode == CCFPEmode) +; rc = reverse_condition_maybe_unordered (rc); +; else +; rc = reverse_condition (rc); +; +; operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); +; }" +;) + +;(define_split +; [(set (match_operand:SI 0 "s_register_operand" "") +; (if_then_else:SI (match_operator 1 "arm_comparison_operator" +; [(match_operand:SI 2 "s_register_operand" "") +; (match_operand:SI 3 "arm_add_operand" "")]) +; (match_operand:SI 4 "arm_rhs_operand" "") +; (not:SI +; (match_operand:SI 5 "s_register_operand" "")))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM && reload_completed" +; [(set (match_dup 6) (match_dup 7)) +; (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)]) +; (set (match_dup 0) (match_dup 4))) +; (cond_exec (match_dup 8) +; (set (match_dup 0) (not:SI (match_dup 5))))] +; " +; { +; enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), +; operands[2], operands[3]); +; enum rtx_code rc = GET_CODE (operands[1]); +; +; operands[6] = gen_rtx_REG (mode, CC_REGNUM); +; operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]); +; if (mode == CCFPmode || mode == CCFPEmode) +; rc = reverse_condition_maybe_unordered (rc); +; else +; rc = reverse_condition (rc); +; +; operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); +; }" +;) + +;(define_insn "*cond_move_not" +; [(set (match_operand:SI 0 "s_register_operand" "=r,r") +; (if_then_else:SI (match_operator 4 "arm_comparison_operator" +; [(match_operand 3 "cc_register" "") (const_int 0)]) +; (match_operand:SI 1 "arm_rhs_operand" "0,?rI") +; (not:SI +; (match_operand:SI 2 "s_register_operand" "r,r"))))] +; "TARGET_ARM" +; "@ +; mvn%D4\\t%0, %2 +; mov%d4\\t%0, %1\;mvn%D4\\t%0, %2" +; [(set_attr "conds" "use") +; (set_attr "length" "4,8")] +;) ;; The next two patterns occur when an AND operation is followed by a ;; scc insn sequence -(define_insn "*sign_extract_onebit" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") - (const_int 1) - (match_operand:SI 2 "const_int_operand" "n"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "* - operands[2] = GEN_INT (1 << INTVAL (operands[2])); - output_asm_insn (\"ands\\t%0, %1, %2\", operands); - return \"mvnne\\t%0, #0\"; - " - [(set_attr "conds" "clob") - (set_attr "length" "8")] -) - -(define_insn "*not_signextract_onebit" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (not:SI - (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") - (const_int 1) - (match_operand:SI 2 "const_int_operand" "n")))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "* - operands[2] = GEN_INT (1 << INTVAL (operands[2])); - output_asm_insn (\"tst\\t%1, %2\", operands); - output_asm_insn (\"mvneq\\t%0, #0\", operands); - return \"movne\\t%0, #0\"; - " - [(set_attr "conds" "clob") - (set_attr "length" "12")] -) +;(define_insn "*sign_extract_onebit" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") +; (const_int 1) +; (match_operand:SI 2 "const_int_operand" "n"))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "* +; operands[2] = GEN_INT (1 << INTVAL (operands[2])); +; output_asm_insn (\"ands\\t%0, %1, %2\", operands); +; return \"mvnne\\t%0, #0\"; +; " +; [(set_attr "conds" "clob") +; (set_attr "length" "8")] +;) + +;(define_insn "*not_signextract_onebit" +; [(set (match_operand:SI 0 "s_register_operand" "=r") +; (not:SI +; (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") +; (const_int 1) +; (match_operand:SI 2 "const_int_operand" "n")))) +; (clobber (reg:CC CC_REGNUM))] +; "TARGET_ARM" +; "* +; operands[2] = GEN_INT (1 << INTVAL (operands[2])); +; output_asm_insn (\"tst\\t%1, %2\", operands); +; output_asm_insn (\"mvneq\\t%0, #0\", operands); +; return \"movne\\t%0, #0\"; +; " +; [(set_attr "conds" "clob") +; (set_attr "length" "12")] +;) ;; Push multiple registers to the stack. Registers are in parallel (use ...) ;; expressions. For simplicity, the first register is also in the unspec @@ -10091,13 +10272,153 @@ "TARGET_ARM && arm_arch5e" "pld\\t%a0") +;; Special predication pattern for Maverick Crunch floating-point + +;(define_cond_exec +; [(match_operator 0 "maverick_comparison_operator" +; [(match_operand:CCFP 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;; Special predication pattern for Maverick Crunch - !CCFP + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC_NOOV 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC_Z 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC_SWP 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC_DNE 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC_DEQ 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC_DLE 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC_DLT 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC_DGE 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC_DGT 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC_DLEU 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC_DLTU 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC_DGEU 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC_DGTU 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC_C 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC_N 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + +;(define_cond_exec +; [(match_operator 0 "arm_comparison_operator" +; [(match_operand:CC 1 "cc_register" "") +; (const_int 0)])] +; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" +; "" +;) + ;; General predication pattern (define_cond_exec [(match_operator 0 "arm_comparison_operator" [(match_operand 1 "cc_register" "") (const_int 0)])] - "TARGET_ARM" + "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)" "" ) @@ -10105,6 +10426,7 @@ [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_PROLOGUE_USE)] "" "%@ %0 needed for prologue" + [(set_attr "length" "0")] ) Only in gcc-4.1.2-futaris/gcc/config/arm: arm.md.orig diff -ru gcc-4.1.2/gcc/config/arm/arm.opt gcc-4.1.2-futaris/gcc/config/arm/arm.opt --- gcc-4.1.2/gcc/config/arm/arm.opt 2005-11-04 15:02:51.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/config/arm/arm.opt 2007-08-27 13:21:54.000000000 +0100 @@ -68,6 +68,14 @@ Target Report Mask(CIRRUS_FIX_INVALID_INSNS) Cirrus: Place NOPs to avoid invalid instruction combinations +fix-crunch-d0 +Target Report Mask(ARM_FLAG_CIRRUS_D0) +Cirrus: workarounds for Crunch coprocessor revision D0 + +fix-crunch-d1 +Target Report Mask(ARM_FLAG_CIRRUS_D1) +Cirrus: workarounds for Crunch coprocessor revision D1 + mcpu= Target RejectNegative Joined Specify the name of the target CPU diff -ru gcc-4.1.2/gcc/config/arm/bpabi.h gcc-4.1.2-futaris/gcc/config/arm/bpabi.h --- gcc-4.1.2/gcc/config/arm/bpabi.h 2005-12-13 01:35:37.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/config/arm/bpabi.h 2007-08-27 13:21:53.000000000 +0100 @@ -33,9 +33,19 @@ #undef FPUTYPE_DEFAULT #define FPUTYPE_DEFAULT FPUTYPE_VFP +/* + * 'config.gcc' defines TARGET_BIG_ENDIAN_DEFAULT as 1 for arm*b-* + * (big endian) configurations. + */ +#if TARGET_BIG_ENDIAN_DEFAULT +#define TARGET_ENDIAN_DEFAULT MASK_BIG_END +#else +#define TARGET_ENDIAN_DEFAULT 0 +#endif + /* EABI targets should enable interworking by default. */ #undef TARGET_DEFAULT -#define TARGET_DEFAULT MASK_INTERWORK +#define TARGET_DEFAULT (MASK_INTERWORK | TARGET_ENDIAN_DEFAULT) /* The ARM BPABI functions return a boolean; they use no special calling convention. */ diff -ru gcc-4.1.2/gcc/config/arm/cirrus.md gcc-4.1.2-futaris/gcc/config/arm/cirrus.md --- gcc-4.1.2/gcc/config/arm/cirrus.md 2005-06-25 02:22:41.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/config/arm/cirrus.md 2007-08-27 13:21:54.000000000 +0100 @@ -34,7 +34,7 @@ [(set (match_operand:DI 0 "cirrus_fp_register" "=v") (plus:DI (match_operand:DI 1 "cirrus_fp_register" "v") (match_operand:DI 2 "cirrus_fp_register" "v")))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cfadd64%?\\t%V0, %V1, %V2" [(set_attr "type" "mav_farith") (set_attr "cirrus" "normal")] @@ -74,7 +74,7 @@ [(set (match_operand:DI 0 "cirrus_fp_register" "=v") (minus:DI (match_operand:DI 1 "cirrus_fp_register" "v") (match_operand:DI 2 "cirrus_fp_register" "v")))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cfsub64%?\\t%V0, %V1, %V2" [(set_attr "type" "mav_farith") (set_attr "cirrus" "normal")] @@ -124,7 +124,7 @@ [(set (match_operand:DI 0 "cirrus_fp_register" "=v") (mult:DI (match_operand:DI 2 "cirrus_fp_register" "v") (match_operand:DI 1 "cirrus_fp_register" "v")))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cfmul64%?\\t%V0, %V1, %V2" [(set_attr "type" "mav_dmult") (set_attr "cirrus" "normal")] @@ -206,7 +206,7 @@ [(set (match_operand:DI 0 "cirrus_fp_register" "=v") (ashift:DI (match_operand:DI 1 "cirrus_fp_register" "v") (match_operand:SI 2 "register_operand" "r")))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cfrshl64%?\\t%V1, %V0, %s2" [(set_attr "cirrus" "normal")] ) @@ -215,7 +215,7 @@ [(set (match_operand:DI 0 "cirrus_fp_register" "=v") (ashift:DI (match_operand:DI 1 "cirrus_fp_register" "v") (match_operand:SI 2 "cirrus_shift_const" "")))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cfsh64%?\\t%V0, %V1, #%s2" [(set_attr "cirrus" "normal")] ) @@ -224,7 +224,7 @@ [(set (match_operand:DI 0 "cirrus_fp_register" "=v") (ashiftrt:DI (match_operand:DI 1 "cirrus_fp_register" "v") (match_operand:SI 2 "cirrus_shift_const" "")))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cfsh64%?\\t%V0, %V1, #-%s2" [(set_attr "cirrus" "normal")] ) @@ -232,17 +232,18 @@ (define_insn "*cirrus_absdi2" [(set (match_operand:DI 0 "cirrus_fp_register" "=v") (abs:DI (match_operand:DI 1 "cirrus_fp_register" "v")))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cfabs64%?\\t%V0, %V1" [(set_attr "cirrus" "normal")] ) ;; This doesn't really clobber ``cc''. Fixme: aldyh. +;; maybe buggy? (define_insn "*cirrus_negdi2" [(set (match_operand:DI 0 "cirrus_fp_register" "=v") (neg:DI (match_operand:DI 1 "cirrus_fp_register" "v"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cfneg64%?\\t%V0, %V1" [(set_attr "cirrus" "normal")] ) @@ -255,18 +256,20 @@ [(set_attr "cirrus" "normal")] ) +;; appears to be buggy: neg 0 != -0 (define_insn "*cirrus_negsf2" [(set (match_operand:SF 0 "cirrus_fp_register" "=v") (neg:SF (match_operand:SF 1 "cirrus_fp_register" "v")))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cfnegs%?\\t%V0, %V1" [(set_attr "cirrus" "normal")] ) +;; appears to be buggy: neg 0 != -0 (define_insn "*cirrus_negdf2" [(set (match_operand:DF 0 "cirrus_fp_register" "=v") (neg:DF (match_operand:DF 1 "cirrus_fp_register" "v")))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cfnegd%?\\t%V0, %V1" [(set_attr "cirrus" "normal")] ) @@ -298,21 +301,23 @@ ) ;; Convert Cirrus-SI to Cirrus-SF +; appears to be buggy (define_insn "cirrus_floatsisf2" [(set (match_operand:SF 0 "cirrus_fp_register" "=v") (float:SF (match_operand:SI 1 "s_register_operand" "r"))) (clobber (match_scratch:DF 2 "=v"))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cfmv64lr%?\\t%Z2, %1\;cfcvt32s%?\\t%V0, %Y2" [(set_attr "length" "8") (set_attr "cirrus" "move")] ) +;appears to be buggy (define_insn "cirrus_floatsidf2" [(set (match_operand:DF 0 "cirrus_fp_register" "=v") (float:DF (match_operand:SI 1 "s_register_operand" "r"))) (clobber (match_scratch:DF 2 "=v"))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cfmv64lr%?\\t%Z2, %1\;cfcvt32d%?\\t%V0, %Y2" [(set_attr "length" "8") (set_attr "cirrus" "move")] @@ -321,41 +326,45 @@ (define_insn "floatdisf2" [(set (match_operand:SF 0 "cirrus_fp_register" "=v") (float:SF (match_operand:DI 1 "cirrus_fp_register" "v")))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cfcvt64s%?\\t%V0, %V1" [(set_attr "cirrus" "normal")]) (define_insn "floatdidf2" [(set (match_operand:DF 0 "cirrus_fp_register" "=v") (float:DF (match_operand:DI 1 "cirrus_fp_register" "v")))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cfcvt64d%?\\t%V0, %V1" [(set_attr "cirrus" "normal")]) +; appears to be buggy (define_insn "cirrus_truncsfsi2" [(set (match_operand:SI 0 "s_register_operand" "=r") (fix:SI (fix:SF (match_operand:SF 1 "cirrus_fp_register" "v")))) (clobber (match_scratch:DF 2 "=v"))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cftruncs32%?\\t%Y2, %V1\;cfmvr64l%?\\t%0, %Z2" [(set_attr "length" "8") (set_attr "cirrus" "normal")] ) +; appears to be buggy (define_insn "cirrus_truncdfsi2" [(set (match_operand:SI 0 "s_register_operand" "=r") (fix:SI (fix:DF (match_operand:DF 1 "cirrus_fp_register" "v")))) (clobber (match_scratch:DF 2 "=v"))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cftruncd32%?\\t%Y2, %V1\;cfmvr64l%?\\t%0, %Z2" - [(set_attr "length" "8")] + [(set_attr "length" "8") + (set_attr "cirrus" "normal")] ) +; appears to be buggy - causes 20000320-1.c to fail in execute/ieee (define_insn "*cirrus_truncdfsf2" [(set (match_operand:SF 0 "cirrus_fp_register" "=v") (float_truncate:SF (match_operand:DF 1 "cirrus_fp_register" "v")))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "cfcvtds%?\\t%V0, %V1" [(set_attr "cirrus" "normal")] ) @@ -369,9 +378,9 @@ ) (define_insn "*cirrus_arm_movdi" - [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,o<>,v,r,v,m,v") - (match_operand:DI 1 "di_operand" "rIK,mi,r,r,v,mi,v,v"))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" + [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,o<>,v,r,v,Uy,v") + (match_operand:DI 1 "di_operand" "rIK,mi,r,r,v,Uyi,v,v"))] + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" "* { switch (which_alternative) @@ -427,8 +436,8 @@ ) (define_insn "*cirrus_movsf_hard_insn" - [(set (match_operand:SF 0 "nonimmediate_operand" "=v,v,v,r,m,r,r,m") - (match_operand:SF 1 "general_operand" "v,mE,r,v,v,r,mE,r"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=v,v,v,r,Uy,r,r,m") + (match_operand:SF 1 "general_operand" "v,UyE,r,v,v,r,mE,r"))] "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && (GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode))" @@ -449,8 +458,8 @@ ) (define_insn "*cirrus_movdf_hard_insn" - [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Q,r,m,r,v,v,v,r,m") - (match_operand:DF 1 "general_operand" "Q,r,r,r,mF,v,mF,r,v,v"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Q,r,m,r,v,v,v,r,Uy") + (match_operand:DF 1 "general_operand" "Q,r,r,r,UyF,v,mF,r,v,v"))] "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && (GET_CODE (operands[0]) != MEM Only in gcc-4.1.2-futaris/gcc/config/arm: cirrus.md.orig diff -ru gcc-4.1.2/gcc/config/arm/ieee754-df.S gcc-4.1.2-futaris/gcc/config/arm/ieee754-df.S --- gcc-4.1.2/gcc/config/arm/ieee754-df.S 2007-01-09 10:14:54.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/config/arm/ieee754-df.S 2007-08-27 13:21:53.000000000 +0100 @@ -42,8 +42,9 @@ @ For FPA, float words are always big-endian. +@ For MAVERICK, float words are always little-endian. @ For VFP, floats words follow the memory system mode. -#if defined(__VFP_FP__) && !defined(__ARMEB__) +#if ((defined(__VFP_FP__) && !defined(__ARMEB__)) || defined(__MAVERICK__)) #define xl r0 #define xh r1 #define yl r2 @@ -451,8 +452,13 @@ orrs r2, r0, r1 #if !defined (__VFP_FP__) && !defined(__SOFTFP__) +#if defined (__FPA_FP__) mvfeqd f0, #0.0 #endif +#if defined (__MAVERICK__) + cfstrd mvd0, #0.0 +#endif +#endif RETc(eq) #if !defined (__VFP_FP__) && !defined(__SOFTFP__) @@ -473,8 +479,13 @@ orrs r2, r0, r1 #if !defined (__VFP_FP__) && !defined(__SOFTFP__) +#if defined (__FPA_FP__) mvfeqd f0, #0.0 #endif +#if defined (__MAVERICK__) + cfstrd mvd0, #0.0 +#endif +#endif RETc(eq) #if !defined (__VFP_FP__) && !defined(__SOFTFP__) @@ -526,8 +537,14 @@ @ Legacy code expects the result to be returned in f0. Copy it @ there as well. LSYM(f0_ret): +#if defined (__FPA_FP__) stmfd sp!, {r0, r1} ldfd f0, [sp], #8 +#endif +#if defined (__MAVERICK__) + cfmvdlr mvd0, xl + cfmvdhr mvd0, xh +#endif RETLDM #endif @@ -700,6 +717,10 @@ cmn r4, #(53 + 1) movle xl, #0 bicle xh, xh, #0x7fffffff +#ifdef __MAVERICK__ + cfmvdlr mvd0, xl + cfmvdhr mvd0, xh +#endif RETLDM "r4, r5, r6" le @ Find out proper shift value. @@ -721,6 +742,10 @@ adc xh, r2, xh, lsr r4 orrs lr, lr, r3, lsl #1 biceq xl, xl, r3, lsr #31 +#ifdef __MAVERICK__ + cfmvdlr mvd0, xl + cfmvdhr mvd0, xh +#endif RETLDM "r4, r5, r6" @ shift result right of 21 to 31 bits, or left 11 to 1 bits after @@ -735,6 +760,10 @@ adc xh, xh, #0 orrs lr, lr, r3, lsl #1 biceq xl, xl, r3, lsr #31 +#ifdef __MAVERICK__ + cfmvdlr mvd0, xl + cfmvdhr mvd0, xh +#endif RETLDM "r4, r5, r6" @ Shift value right of 32 to 64 bits, or 0 to 32 bits after a switch @@ -749,6 +778,10 @@ add xl, xl, r3, lsr #31 orrs lr, lr, r3, lsl #1 biceq xl, xl, r3, lsr #31 +#ifdef __MAVERICK__ + cfmvdlr mvd0, xl + cfmvdhr mvd0, xh +#endif RETLDM "r4, r5, r6" @ One or both arguments are denormalized. @@ -791,6 +824,10 @@ eor xh, xh, yh bic xh, xh, #0x7fffffff mov xl, #0 +#ifdef __MAVERICK__ + cfmvdlr mvd0, xl + cfmvdhr mvd0, xh +#endif RETLDM "r4, r5, r6" 1: @ One or both args are INF or NAN. @@ -820,12 +857,20 @@ orr xh, xh, #0x7f000000 orr xh, xh, #0x00f00000 mov xl, #0 +#ifdef __MAVERICK__ + cfmvdlr mvd0, xl + cfmvdhr mvd0, xh +#endif RETLDM "r4, r5, r6" @ Return a quiet NAN. LSYM(Lml_n): orr xh, xh, #0x7f000000 orr xh, xh, #0x00f80000 +#ifdef __MAVERICK__ + cfmvdlr mvd0, xl + cfmvdhr mvd0, xh +#endif RETLDM "r4, r5, r6" FUNC_END aeabi_dmul diff -ru gcc-4.1.2/gcc/config/arm/ieee754-sf.S gcc-4.1.2-futaris/gcc/config/arm/ieee754-sf.S --- gcc-4.1.2/gcc/config/arm/ieee754-sf.S 2005-08-06 14:26:35.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/config/arm/ieee754-sf.S 2007-08-27 13:21:53.000000000 +0100 @@ -302,8 +302,13 @@ orrs r2, r0, r1 #if !defined (__VFP_FP__) && !defined(__SOFTFP__) +#if defined (__FPA_FP__) mvfeqs f0, #0.0 #endif +#if defined (__MAVERICK__) + cfmvsr mvf0, #0.0 +#endif +#endif RETc(eq) mov r3, #0 @@ -314,8 +319,13 @@ orrs r2, r0, r1 #if !defined (__VFP_FP__) && !defined(__SOFTFP__) +#if defined (__FPA_FP__) mvfeqs f0, #0.0 #endif +#if defined (__MAVERICK__) + cfmvsr mvf0, #0.0 +#endif +#endif RETc(eq) ands r3, ah, #0x80000000 @ sign bit in r3 @@ -387,8 +397,13 @@ #if !defined (__VFP_FP__) && !defined(__SOFTFP__) LSYM(f0_ret): +#if defined (__FPA_FP__) str r0, [sp, #-4]! ldfs f0, [sp], #4 +#endif +#if defined (__MAVERICK__) + cfmvsr mvf0, r0 +#endif RETLDM #endif @@ -503,6 +518,9 @@ @ Check if denormalized result is possible, otherwise return signed 0. cmn r2, #(24 + 1) bicle r0, r0, #0x7fffffff +#ifdef __MAVERICK__ + cfmvsr mvf0, r0 +#endif RETc(le) @ Shift value right, round, etc. @@ -515,6 +533,9 @@ adc r0, r0, #0 orrs r3, r3, ip, lsl #1 biceq r0, r0, ip, lsr #31 +#ifdef __MAVERICK__ + cfmvsr mvf0, r0 +#endif RET @ One or both arguments are denormalized. @@ -552,6 +573,9 @@ LSYM(Lml_z): eor r0, r0, r1 bic r0, r0, #0x7fffffff +#ifdef __MAVERICK__ + cfmvsr mvf0, r0 +#endif RET 1: @ One or both args are INF or NAN. @@ -580,12 +604,18 @@ and r0, r0, #0x80000000 orr r0, r0, #0x7f000000 orr r0, r0, #0x00800000 +#ifdef __MAVERICK__ + cfmvsr mvf0, r0 +#endif RET @ Return a quiet NAN. LSYM(Lml_n): orr r0, r0, #0x7f000000 orr r0, r0, #0x00c00000 +#ifdef __MAVERICK__ + cfmvsr mvf0, r0 +#endif RET FUNC_END aeabi_fmul @@ -662,6 +692,9 @@ adds r2, r2, #127 rsbgts r3, r2, #255 orrgt r0, r0, r2, lsl #23 +#ifdef __MAVERICK__ + cfmvsr mvf0, r0 +#endif RETc(gt) orr r0, r0, #0x00800000 diff -ru gcc-4.1.2/gcc/config/arm/lib1funcs.asm gcc-4.1.2-futaris/gcc/config/arm/lib1funcs.asm --- gcc-4.1.2/gcc/config/arm/lib1funcs.asm 2005-11-15 14:32:13.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/config/arm/lib1funcs.asm 2007-08-27 13:21:53.000000000 +0100 @@ -995,10 +995,24 @@ .code 32 FUNC_START div0 +#if ! defined __thumb__ stmfd sp!, {r1, lr} mov r0, #SIGFPE bl SYM(raise) __PLT__ RETLDM r1 +#else + push {r1, lr} + mov r0, #SIGFPE + bl SYM(raise) __PLT__ +#if __ARM_ARCH__ > 4 + pop {r1, pc} +#else + @ on 4T that won't work + pop {r1} + pop {r3} + bx r3 +#endif +#endif FUNC_END div0 @@ -1141,11 +1155,12 @@ code here switches to the correct mode before executing the function. */ .text - .align 0 + .align 1 .force_thumb .macro call_via register THUMB_FUNC_START _call_via_\register + .hidden SYM (_call_via_\register) bx \register nop @@ -1242,6 +1257,7 @@ .code 16 THUMB_FUNC_START _interwork_call_via_\register + .hidden SYM (_interwork_call_via_\register) bx pc nop diff -ru gcc-4.1.2/gcc/config/arm/linux-eabi.h gcc-4.1.2-futaris/gcc/config/arm/linux-eabi.h --- gcc-4.1.2/gcc/config/arm/linux-eabi.h 2005-11-15 14:32:13.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/config/arm/linux-eabi.h 2007-08-27 13:21:53.000000000 +0100 @@ -20,6 +20,17 @@ the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +/* + * 'config.gcc' defines TARGET_BIG_ENDIAN_DEFAULT as 1 for arm*b-* + * (big endian) configurations. + */ +#undef TARGET_LINKER_EMULATION +#if TARGET_BIG_ENDIAN_DEFAULT +#define TARGET_LINKER_EMULATION "armelfb_linux_eabi" +#else +#define TARGET_LINKER_EMULATION "armelf_linux_eabi" +#endif + /* On EABI GNU/Linux, we want both the BPABI builtins and the GNU/Linux builtins. */ #undef TARGET_OS_CPP_BUILTINS @@ -45,15 +56,19 @@ The ARM10TDMI core is the default for armv5t, so set SUBTARGET_CPU_DEFAULT to achieve this. */ #undef SUBTARGET_CPU_DEFAULT -#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm10tdmi +#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm9tdmi #undef SUBTARGET_EXTRA_LINK_SPEC -#define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux_eabi" +#define SUBTARGET_EXTRA_LINK_SPEC " -m " TARGET_LINKER_EMULATION /* Use ld-linux.so.3 so that it will be possible to run "classic" GNU/Linux binaries on an EABI system. */ #undef LINUX_TARGET_INTERPRETER +#ifdef USE_UCLIBC +#define LINUX_TARGET_INTERPRETER "/lib/ld-uClibc.so.0" +#else #define LINUX_TARGET_INTERPRETER "/lib/ld-linux.so.3" +#endif /* At this point, bpabi.h will have clobbered LINK_SPEC. We want to use the GNU/Linux version, not the generic BPABI version. */ Only in gcc-4.1.2-futaris/gcc/config/arm: linux-eabi.h.orig diff -ru gcc-4.1.2/gcc/config/arm/linux-elf.h gcc-4.1.2-futaris/gcc/config/arm/linux-elf.h --- gcc-4.1.2/gcc/config/arm/linux-elf.h 2005-10-10 02:04:31.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/config/arm/linux-elf.h 2007-08-27 13:21:53.000000000 +0100 @@ -28,19 +28,33 @@ #undef TARGET_VERSION #define TARGET_VERSION fputs (" (ARM GNU/Linux with ELF)", stderr); +/* + * 'config.gcc' defines TARGET_BIG_ENDIAN_DEFAULT as 1 for arm*b-* + * (big endian) configurations. + */ +#if TARGET_BIG_ENDIAN_DEFAULT +#define TARGET_ENDIAN_DEFAULT MASK_BIG_END +#define TARGET_ENDIAN_OPTION "mbig-endian" +#define TARGET_LINKER_EMULATION "armelfb_linux" +#else +#define TARGET_ENDIAN_DEFAULT 0 +#define TARGET_ENDIAN_OPTION "mlittle-endian" +#define TARGET_LINKER_EMULATION "armelf_linux" +#endif + #undef TARGET_DEFAULT_FLOAT_ABI #define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_HARD #undef TARGET_DEFAULT -#define TARGET_DEFAULT (0) +#define TARGET_DEFAULT (TARGET_ENDIAN_DEFAULT) #define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm6 -#define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux -p" +#define SUBTARGET_EXTRA_LINK_SPEC " -m " TARGET_LINKER_EMULATION " -p" #undef MULTILIB_DEFAULTS #define MULTILIB_DEFAULTS \ - { "marm", "mlittle-endian", "mhard-float", "mno-thumb-interwork" } + { "marm", TARGET_ENDIAN_OPTION, "mhard-float", "mno-thumb-interwork" } /* Now we define the strings used to build the spec file. */ #undef LIB_SPEC @@ -49,9 +63,13 @@ %{shared:-lc} \ %{!shared:%{profile:-lc_p}%{!profile:-lc}}" -#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc" +#define LIBGCC_SPEC "-lgcc" +#ifdef USE_UCLIBC +#define LINUX_TARGET_INTERPRETER "/lib/ld-uClibc.so.0" +#else #define LINUX_TARGET_INTERPRETER "/lib/ld-linux.so.2" +#endif #define LINUX_TARGET_LINK_SPEC "%{h*} %{version:-v} \ %{b} \ @@ -61,7 +79,7 @@ %{rdynamic:-export-dynamic} \ %{!dynamic-linker:-dynamic-linker " LINUX_TARGET_INTERPRETER "} \ -X \ - %{mbig-endian:-EB}" \ + %{mbig-endian:-EB} %{mlittle-endian:-EL}" \ SUBTARGET_EXTRA_LINK_SPEC #undef LINK_SPEC Only in gcc-4.1.2-futaris/gcc/config/arm: linux-elf.h.orig diff -ru gcc-4.1.2/gcc/config/arm/linux-gas.h gcc-4.1.2-futaris/gcc/config/arm/linux-gas.h --- gcc-4.1.2/gcc/config/arm/linux-gas.h 2005-06-25 02:22:41.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/config/arm/linux-gas.h 2007-08-27 13:21:53.000000000 +0100 @@ -44,6 +44,7 @@ /* Clear the instruction cache from `beg' to `end'. This makes an inline system call to SYS_cacheflush. */ +#if !defined(__thumb__) #define CLEAR_INSN_CACHE(BEG, END) \ { \ register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \ @@ -53,3 +54,18 @@ : "=r" (_beg) \ : "0" (_beg), "r" (_end), "r" (_flg)); \ } +#else +#define CLEAR_INSN_CACHE(BEG, END) \ +{ \ + register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \ + register unsigned long _end __asm ("a2") = (unsigned long) (END); \ + register unsigned long _flg __asm ("a3") = 0; \ + register unsigned long _swi __asm ("a4") = 0xf0002; \ + __asm __volatile ("push {r7}\n" \ + " mov r7,a4\n" \ + " swi 0 @ sys_cacheflush\n" \ + " pop {r7}\n" \ + : "=r" (_beg) \ + : "0" (_beg), "r" (_end), "r" (_flg), "r" (_swi)); \ +} +#endif diff -ru gcc-4.1.2/gcc/config/arm/predicates.md gcc-4.1.2-futaris/gcc/config/arm/predicates.md --- gcc-4.1.2/gcc/config/arm/predicates.md 2005-09-11 08:38:02.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/config/arm/predicates.md 2007-08-27 13:21:54.000000000 +0100 @@ -174,6 +174,10 @@ (define_special_predicate "arm_comparison_operator" (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt")) +;; True for comparisons other than GE, GEU, UNLT, UNORDERED or ORDERED - TODO add LTGT and UNEQ - needs extra support elsewhere +(define_special_predicate "maverick_comparison_operator" +(match_code "eq,ne,le,lt,gt,gtu,leu,ltu,unle,unge,ungt")) + (define_special_predicate "minmax_operator" (and (match_code "smin,smax,umin,umax") (match_test "mode == GET_MODE (op)"))) Only in gcc-4.1.2-futaris/gcc/config/arm: predicates.md.orig diff -ru gcc-4.1.2/gcc/config/arm/t-linux gcc-4.1.2-futaris/gcc/config/arm/t-linux --- gcc-4.1.2/gcc/config/arm/t-linux 2004-05-15 13:41:35.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/config/arm/t-linux 2007-08-27 13:21:53.000000000 +0100 @@ -4,7 +4,11 @@ LIBGCC2_DEBUG_CFLAGS = -g0 LIB1ASMSRC = arm/lib1funcs.asm -LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx +LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx \ + _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \ + _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \ + _call_via_rX \ + _fixsfsi _fixunssfsi _floatdidf _floatdisf # MULTILIB_OPTIONS = mhard-float/msoft-float # MULTILIB_DIRNAMES = hard-float soft-float diff -ru gcc-4.1.2/gcc/config/cris/linux.h gcc-4.1.2-futaris/gcc/config/cris/linux.h --- gcc-4.1.2/gcc/config/cris/linux.h 2005-06-25 02:22:41.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/config/cris/linux.h 2007-08-27 13:21:53.000000000 +0100 @@ -73,6 +73,25 @@ #undef CRIS_DEFAULT_CPU_VERSION #define CRIS_DEFAULT_CPU_VERSION CRIS_CPU_NG +#ifdef USE_UCLIBC + +#undef CRIS_SUBTARGET_VERSION +#define CRIS_SUBTARGET_VERSION " - cris-axis-linux-uclibc" + +#undef CRIS_LINK_SUBTARGET_SPEC +#define CRIS_LINK_SUBTARGET_SPEC \ + "-mcrislinux\ + -rpath-link include/asm/../..%s\ + %{shared} %{static}\ + %{symbolic:-Bdynamic} %{shlib:-Bdynamic} %{static:-Bstatic}\ + %{!shared: \ + %{!static: \ + %{rdynamic:-export-dynamic} \ + %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}}} \ + %{!r:%{O2|O3: --gc-sections}}" + +#else /* USE_UCLIBC */ + #undef CRIS_SUBTARGET_VERSION #define CRIS_SUBTARGET_VERSION " - cris-axis-linux-gnu" @@ -87,6 +106,8 @@ %{!shared:%{!static:%{rdynamic:-export-dynamic}}}\ %{!r:%{O2|O3: --gc-sections}}" +#endif /* USE_UCLIBC */ + /* Node: Run-time Target */ diff -ru gcc-4.1.2/gcc/config/i386/linux64.h gcc-4.1.2-futaris/gcc/config/i386/linux64.h --- gcc-4.1.2/gcc/config/i386/linux64.h 2005-08-10 18:53:01.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/config/i386/linux64.h 2007-08-27 13:21:53.000000000 +0100 @@ -54,14 +54,21 @@ When the -shared link option is used a final link is not being done. */ +#ifdef USE_UCLIBC +#define ELF32_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" +#define ELF64_DYNAMIC_LINKER "/lib/ld64-uClibc.so.0" +#else +#define ELF32_DYNAMIC_LINKER "/lib/ld-linux.so.2" +#define ELF64_DYNAMIC_LINKER "/lib64/ld-linux-x86-64.so.2" +#endif #undef LINK_SPEC #define LINK_SPEC "%{!m32:-m elf_x86_64} %{m32:-m elf_i386} \ %{shared:-shared} \ %{!shared: \ %{!static: \ %{rdynamic:-export-dynamic} \ - %{m32:%{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ - %{!m32:%{!dynamic-linker:-dynamic-linker /lib64/ld-linux-x86-64.so.2}}} \ + %{m32:%{!dynamic-linker:-dynamic-linker " ELF32_DYNAMIC_LINKER "}} \ + %{!m32:%{!dynamic-linker:-dynamic-linker " ELF64_DYNAMIC_LINKER "}}} \ %{static:-static}}" /* Similar to standard Linux, but adding -ffast-math support. */ diff -ru gcc-4.1.2/gcc/config/i386/linux.h gcc-4.1.2-futaris/gcc/config/i386/linux.h --- gcc-4.1.2/gcc/config/i386/linux.h 2005-08-10 18:53:01.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/config/i386/linux.h 2007-08-27 13:21:53.000000000 +0100 @@ -107,6 +107,11 @@ #define LINK_EMULATION "elf_i386" #define DYNAMIC_LINKER "/lib/ld-linux.so.2" +#if defined USE_UCLIBC +#undef DYNAMIC_LINKER +#define DYNAMIC_LINKER "/lib/ld-uClibc.so.0" +#endif + #undef SUBTARGET_EXTRA_SPECS #define SUBTARGET_EXTRA_SPECS \ { "link_emulation", LINK_EMULATION },\ diff -ru gcc-4.1.2/gcc/config/ia64/linux.h gcc-4.1.2-futaris/gcc/config/ia64/linux.h --- gcc-4.1.2/gcc/config/ia64/linux.h 2006-12-12 15:24:07.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/config/ia64/linux.h 2007-08-27 13:21:53.000000000 +0100 @@ -37,13 +37,18 @@ /* Define this for shared library support because it isn't in the main linux.h file. */ +#ifdef USE_UCLIBC +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" +#else +#define ELF_DYNAMIC_LINKER "/lib/ld-linux-ia64.so.2" +#endif #undef LINK_SPEC #define LINK_SPEC "\ %{shared:-shared} \ %{!shared: \ %{!static: \ %{rdynamic:-export-dynamic} \ - %{!dynamic-linker:-dynamic-linker /lib/ld-linux-ia64.so.2}} \ + %{!dynamic-linker:-dynamic-linker " ELF_DYNAMIC_LINKER "}} \ %{static:-static}}" #define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}" Only in gcc-4.1.2-futaris/gcc/config/ia64: linux.h.orig diff -ru gcc-4.1.2/gcc/config/m68k/linux.h gcc-4.1.2-futaris/gcc/config/m68k/linux.h --- gcc-4.1.2/gcc/config/m68k/linux.h 2005-06-25 02:22:41.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/config/m68k/linux.h 2007-08-27 13:21:53.000000000 +0100 @@ -123,12 +123,17 @@ /* If ELF is the default format, we should not use /lib/elf. */ +#ifdef USE_UCLIBC +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" +#else +#define ELF_DYNAMIC_LINKER "/lib/ld.so.1" +#endif #undef LINK_SPEC #define LINK_SPEC "-m m68kelf %{shared} \ %{!shared: \ %{!static: \ %{rdynamic:-export-dynamic} \ - %{!dynamic-linker*:-dynamic-linker /lib/ld.so.1}} \ + %{!dynamic-linker*:-dynamic-linker " ELF_DYNAMIC_LINKER "}} \ %{static}}" /* For compatibility with linux/a.out */ diff -ru gcc-4.1.2/gcc/config/mips/linux.h gcc-4.1.2-futaris/gcc/config/mips/linux.h --- gcc-4.1.2/gcc/config/mips/linux.h 2006-12-17 13:57:31.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/config/mips/linux.h 2007-08-27 13:21:53.000000000 +0100 @@ -105,6 +105,11 @@ /* Borrowed from sparc/linux.h */ #undef LINK_SPEC +#ifdef USE_UCLIBC +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" +#else +#define ELF_DYNAMIC_LINKER "/lib/ld.so.1" +#endif #define LINK_SPEC \ "%(endian_spec) \ %{shared:-shared} \ @@ -112,7 +117,7 @@ %{!ibcs: \ %{!static: \ %{rdynamic:-export-dynamic} \ - %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}} \ + %{!dynamic-linker:-dynamic-linker " ELF_DYNAMIC_LINKER "}} \ %{static:-static}}}" #undef SUBTARGET_ASM_SPEC diff -ru gcc-4.1.2/gcc/config/pa/pa-linux.h gcc-4.1.2-futaris/gcc/config/pa/pa-linux.h --- gcc-4.1.2/gcc/config/pa/pa-linux.h 2007-01-12 02:23:38.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/config/pa/pa-linux.h 2007-08-27 13:21:53.000000000 +0100 @@ -49,13 +49,18 @@ /* Define this for shared library support because it isn't in the main linux.h file. */ +#ifdef USE_UCLIBC +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" +#else +#define ELF_DYNAMIC_LINKER "/lib/ld.so.1" +#endif #undef LINK_SPEC #define LINK_SPEC "\ %{shared:-shared} \ %{!shared: \ %{!static: \ %{rdynamic:-export-dynamic} \ - %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}} \ + %{!dynamic-linker:-dynamic-linker " ELF_DYNAMIC_LINKER "}} \ %{static:-static}}" /* glibc's profiling functions don't need gcc to allocate counters. */ diff -ru gcc-4.1.2/gcc/config/rs6000/linux.h gcc-4.1.2-futaris/gcc/config/rs6000/linux.h --- gcc-4.1.2/gcc/config/rs6000/linux.h 2006-02-10 20:58:33.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/config/rs6000/linux.h 2007-08-27 13:21:53.000000000 +0100 @@ -72,7 +72,11 @@ #define LINK_START_DEFAULT_SPEC "%(link_start_linux)" #undef LINK_OS_DEFAULT_SPEC +#ifdef USE_UCLIBC +#define LINK_OS_DEFAULT_SPEC "%(link_os_linux_uclibc)" +#else #define LINK_OS_DEFAULT_SPEC "%(link_os_linux)" +#endif #define LINK_GCC_C_SEQUENCE_SPEC \ "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" diff -ru gcc-4.1.2/gcc/config/rs6000/sysv4.h gcc-4.1.2-futaris/gcc/config/rs6000/sysv4.h --- gcc-4.1.2/gcc/config/rs6000/sysv4.h 2006-02-10 20:58:33.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/config/rs6000/sysv4.h 2007-08-27 13:21:53.000000000 +0100 @@ -866,6 +866,7 @@ mcall-linux : %(link_os_linux) ; \ mcall-gnu : %(link_os_gnu) ; \ mcall-netbsd : %(link_os_netbsd) ; \ + mcall-linux-uclibc : %(link_os_linux_uclibc); \ mcall-openbsd: %(link_os_openbsd) ; \ : %(link_os_default) }" @@ -1043,6 +1044,10 @@ %{rdynamic:-export-dynamic} \ %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}}}" +#define LINK_OS_LINUX_UCLIBC_SPEC "-m elf32ppclinux %{!shared: %{!static: \ + %{rdynamic:-export-dynamic} \ + %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}}}" + #if defined(HAVE_LD_EH_FRAME_HDR) # define LINK_EH_SPEC "%{!static:--eh-frame-hdr} " #endif @@ -1209,6 +1214,7 @@ { "link_os_sim", LINK_OS_SIM_SPEC }, \ { "link_os_freebsd", LINK_OS_FREEBSD_SPEC }, \ { "link_os_linux", LINK_OS_LINUX_SPEC }, \ + { "link_os_linux_uclibc", LINK_OS_LINUX_UCLIBC_SPEC }, \ { "link_os_gnu", LINK_OS_GNU_SPEC }, \ { "link_os_netbsd", LINK_OS_NETBSD_SPEC }, \ { "link_os_openbsd", LINK_OS_OPENBSD_SPEC }, \ diff -ru gcc-4.1.2/gcc/config/s390/linux.h gcc-4.1.2-futaris/gcc/config/s390/linux.h --- gcc-4.1.2/gcc/config/s390/linux.h 2006-12-12 15:24:07.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/config/s390/linux.h 2007-08-27 13:21:53.000000000 +0100 @@ -77,6 +77,13 @@ #define MULTILIB_DEFAULTS { "m31" } #endif +#ifdef USE_UCLIBC +#define ELF31_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" +#define ELF64_DYNAMIC_LINKER "/lib/ld64-uClibc.so.0" +#else +#define ELF31_DYNAMIC_LINKER "/lib/ld.so.1" +#define ELF64_DYNAMIC_LINKER "/lib/ld64.so.1" +#endif #undef LINK_SPEC #define LINK_SPEC \ "%{m31:-m elf_s390}%{m64:-m elf64_s390} \ @@ -86,8 +93,8 @@ %{!static: \ %{rdynamic:-export-dynamic} \ %{!dynamic-linker: \ - %{m31:-dynamic-linker /lib/ld.so.1} \ - %{m64:-dynamic-linker /lib/ld64.so.1}}}}" + %{m31:-dynamic-linker " ELF31_DYNAMIC_LINKER "} \ + %{m64:-dynamic-linker " ELF64_DYNAMIC_LINKER "}}}}" #define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}" Only in gcc-4.1.2-futaris/gcc/config/s390: linux.h.orig diff -ru gcc-4.1.2/gcc/config/sh/linux.h gcc-4.1.2-futaris/gcc/config/sh/linux.h --- gcc-4.1.2/gcc/config/sh/linux.h 2005-06-25 02:22:41.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/config/sh/linux.h 2007-08-27 13:21:53.000000000 +0100 @@ -56,12 +56,21 @@ #undef SUBTARGET_LINK_EMUL_SUFFIX #define SUBTARGET_LINK_EMUL_SUFFIX "_linux" #undef SUBTARGET_LINK_SPEC +#ifdef USE_UCLIBC +#define SUBTARGET_LINK_SPEC \ + "%{shared:-shared} \ + %{!static: \ + %{rdynamic:-export-dynamic} \ + %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}} \ + %{static:-static}" +#else #define SUBTARGET_LINK_SPEC \ "%{shared:-shared} \ %{!static: \ %{rdynamic:-export-dynamic} \ %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ %{static:-static}" +#endif /* Output assembler code to STREAM to call the profiler. */ diff -ru gcc-4.1.2/gcc/config/sparc/linux64.h gcc-4.1.2-futaris/gcc/config/sparc/linux64.h --- gcc-4.1.2/gcc/config/sparc/linux64.h 2006-02-11 08:38:51.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/config/sparc/linux64.h 2007-08-27 13:21:53.000000000 +0100 @@ -162,12 +162,17 @@ { "link_arch_default", LINK_ARCH_DEFAULT_SPEC }, \ { "link_arch", LINK_ARCH_SPEC }, +#ifdef USE_UCLIBC +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" +#else +#define ELF_DYNAMIC_LINKER "/lib/ld-linux.so.2" +#endif #define LINK_ARCH32_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \ %{!shared: \ %{!ibcs: \ %{!static: \ %{rdynamic:-export-dynamic} \ - %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ + %{!dynamic-linker:-dynamic-linker " ELF_DYNAMIC_LINKER "}} \ %{static:-static}}} \ " diff -ru gcc-4.1.2/gcc/config/sparc/linux.h gcc-4.1.2-futaris/gcc/config/sparc/linux.h --- gcc-4.1.2/gcc/config/sparc/linux.h 2006-02-11 08:38:51.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/config/sparc/linux.h 2007-08-27 13:21:53.000000000 +0100 @@ -125,6 +125,11 @@ /* If ELF is the default format, we should not use /lib/elf. */ +#ifdef USE_UCLIBC +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" +#else +#define ELF_DYNAMIC_LINKER "/lib/ld-linux.so.2" +#endif #undef LINK_SPEC #define LINK_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \ %{!mno-relax:%{!r:-relax}} \ @@ -132,7 +137,7 @@ %{!ibcs: \ %{!static: \ %{rdynamic:-export-dynamic} \ - %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ + %{!dynamic-linker:-dynamic-linker " ELF_DYNAMIC_LINKER "}} \ %{static:-static}}}" /* The sun bundled assembler doesn't accept -Yd, (and neither does gas). Only in gcc-4.1.2-futaris/gcc/config: t-linux-uclibc diff -ru gcc-4.1.2/gcc/config.gcc gcc-4.1.2-futaris/gcc/config.gcc --- gcc-4.1.2/gcc/config.gcc 2006-10-16 00:12:23.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/config.gcc 2007-08-27 13:21:53.000000000 +0100 @@ -672,9 +672,14 @@ ;; arm*-*-linux*) # ARM GNU/Linux with ELF tm_file="dbxelf.h elfos.h linux.h arm/elf.h arm/linux-gas.h arm/linux-elf.h" + case $target in + arm*b-*) + tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1" + ;; + esac tmake_file="${tmake_file} t-linux arm/t-arm" case ${target} in - arm*-*-linux-gnueabi) + arm*-*-linux-gnueabi | arm*-*-linux-uclibcgnueabi) tm_file="$tm_file arm/bpabi.h arm/linux-eabi.h" tmake_file="$tmake_file arm/t-arm-elf arm/t-bpabi arm/t-linux-eabi" # The BPABI long long divmod functions return a 128-bit value in @@ -1884,7 +1889,7 @@ ;; sh-*-elf* | sh[12346l]*-*-elf* | sh*-*-kaos* | \ sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \ - sh-*-linux* | sh[346lbe]*-*-linux* | \ + sh*-*-linux* | sh[346lbe]*-*-linux* | \ sh-*-netbsdelf* | shl*-*-netbsdelf* | sh5-*-netbsd* | sh5l*-*-netbsd* | \ sh64-*-netbsd* | sh64l*-*-netbsd*) tmake_file="${tmake_file} sh/t-sh sh/t-elf" @@ -2338,6 +2343,12 @@ ;; esac +# Rather than hook into each target, just do it after all the linux +# targets have been processed +case ${target} in +*-linux-uclibc*) tm_defines="${tm_defines} USE_UCLIBC" ; tmake_file="${tmake_file} t-linux-uclibc" +esac + case ${target} in i[34567]86-*-linux*aout* | i[34567]86-*-linux*libc1) tmake_file="${tmake_file} i386/t-gmm_malloc" Only in gcc-4.1.2-futaris/gcc: config.gcc.orig diff -ru gcc-4.1.2/gcc/configure gcc-4.1.2-futaris/gcc/configure --- gcc-4.1.2/gcc/configure 2006-11-13 22:09:55.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/configure 2007-08-27 13:21:53.000000000 +0100 @@ -12272,7 +12272,7 @@ esac saved_CFLAGS="${CFLAGS}" CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" \ - ${realsrcdir}/configure \ + CONFIG_SITE= ${realsrcdir}/configure --cache-file=./other.cache \ --enable-languages=${enable_languages-all} \ --target=$target_alias --host=$build_alias --build=$build_alias CFLAGS="${saved_CFLAGS}" @@ -14762,7 +14762,7 @@ tls_first_minor=14 tls_as_opt="-m64 -Aesame --fatal-warnings" ;; - sh-*-* | sh[34]-*-*) + sh-*-* | sh[34]*-*-*) conftest_s=' .section ".tdata","awT",@progbits foo: .long 25 diff -ru gcc-4.1.2/gcc/configure.ac gcc-4.1.2-futaris/gcc/configure.ac --- gcc-4.1.2/gcc/configure.ac 2006-11-13 22:09:55.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/configure.ac 2007-08-27 13:21:53.000000000 +0100 @@ -2435,7 +2435,7 @@ tls_first_minor=14 tls_as_opt="-m64 -Aesame --fatal-warnings" ;; - sh-*-* | sh[34]-*-*) + sh-*-* | sh[34]*-*-*) conftest_s=' .section ".tdata","awT",@progbits foo: .long 25 Only in gcc-4.1.2-futaris/gcc: configure.ac.orig Only in gcc-4.1.2-futaris/gcc: configure.orig diff -ru gcc-4.1.2/gcc/doc/invoke.texi gcc-4.1.2-futaris/gcc/doc/invoke.texi --- gcc-4.1.2/gcc/doc/invoke.texi 2006-09-25 22:21:58.000000000 +0100 +++ gcc-4.1.2-futaris/gcc/doc/invoke.texi 2007-08-27 13:21:54.000000000 +0100 @@ -408,7 +408,7 @@ -msingle-pic-base -mno-single-pic-base @gol -mpic-register=@var{reg} @gol -mnop-fun-dllimport @gol --mcirrus-fix-invalid-insns -mno-cirrus-fix-invalid-insns @gol +-mfix-crunch-d0 -mfix-crunch-d1 @gol -mpoke-function-name @gol -mthumb -marm @gol -mtpcs-frame -mtpcs-leaf-frame @gol @@ -7435,17 +7435,12 @@ Specify the register to be used for PIC addressing. The default is R10 unless stack-checking is enabled, when R9 is used. -@item -mcirrus-fix-invalid-insns -@opindex mcirrus-fix-invalid-insns -@opindex mno-cirrus-fix-invalid-insns -Insert NOPs into the instruction stream to in order to work around -problems with invalid Maverick instruction combinations. This option -is only valid if the @option{-mcpu=ep9312} option has been used to -enable generation of instructions for the Cirrus Maverick floating -point co-processor. This option is not enabled by default, since the -problem is only present in older Maverick implementations. The default -can be re-enabled by use of the @option{-mno-cirrus-fix-invalid-insns} -switch. +@item -mfix-crunch-d0 +@itemx -mfix-crunch-d1 +@opindex mfix-crunch-d0 +@opindex mfix-crunch-d1 +Enable workarounds for the Cirrus MaverickCrunch coprocessor revisions +D0 and D1 respectively. @item -mpoke-function-name @opindex mpoke-function-name diff -ru gcc-4.1.2/gcc/testsuite/gcc.c-torture/execute/ieee/20000320-1.c gcc-4.1.2-futaris/gcc/testsuite/gcc.c-torture/execute/ieee/20000320-1.c --- gcc-4.1.2/gcc/testsuite/gcc.c-torture/execute/ieee/20000320-1.c 2003-02-03 10:15:15.000000000 +0000 +++ gcc-4.1.2-futaris/gcc/testsuite/gcc.c-torture/execute/ieee/20000320-1.c 2007-08-27 13:21:53.000000000 +0100 @@ -49,7 +49,7 @@ exit (0); c(0x3690000000000000ULL, 0x00000000U); -#if (defined __arm__ || defined __thumb__) && ! (defined __ARMEB__ || defined __VFP_FP__) +#if (defined __arm__ || defined __thumb__) && ! (defined __ARMEB__ || defined __VFP_FP__) && ! (defined __MAVERICK__) /* The ARM always stores FP numbers in big-wordian format, even when running in little-byteian mode. */ c(0x0000000136900000ULL, 0x00000001U); diff -ru gcc-4.1.2/libffi/configure gcc-4.1.2-futaris/libffi/configure --- gcc-4.1.2/libffi/configure 2007-02-14 05:17:22.000000000 +0000 +++ gcc-4.1.2-futaris/libffi/configure 2007-08-27 13:21:53.000000000 +0100 @@ -3457,6 +3457,11 @@ lt_cv_deplibs_check_method=pass_all ;; +linux-uclibc*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` + ;; + netbsd* | knetbsd*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' diff -ru gcc-4.1.2/libgfortran/configure gcc-4.1.2-futaris/libgfortran/configure --- gcc-4.1.2/libgfortran/configure 2006-12-06 10:55:37.000000000 +0000 +++ gcc-4.1.2-futaris/libgfortran/configure 2007-08-27 13:21:53.000000000 +0100 @@ -3699,6 +3699,11 @@ lt_cv_deplibs_check_method=pass_all ;; +linux-uclibc*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` + ;; + netbsd* | knetbsd*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' diff -ru gcc-4.1.2/libjava/configure gcc-4.1.2-futaris/libjava/configure --- gcc-4.1.2/libjava/configure 2007-02-14 05:17:22.000000000 +0000 +++ gcc-4.1.2-futaris/libjava/configure 2007-08-27 13:21:53.000000000 +0100 @@ -5137,6 +5137,11 @@ lt_cv_deplibs_check_method=pass_all ;; +linux-uclibc*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` + ;; + netbsd* | knetbsd*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' diff -ru gcc-4.1.2/libmudflap/configure gcc-4.1.2-futaris/libmudflap/configure --- gcc-4.1.2/libmudflap/configure 2005-10-05 00:54:38.000000000 +0100 +++ gcc-4.1.2-futaris/libmudflap/configure 2007-08-27 13:21:53.000000000 +0100 @@ -5382,6 +5382,11 @@ lt_cv_deplibs_check_method=pass_all ;; +linux-uclibc*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` + ;; + netbsd* | knetbsd*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' diff -ru gcc-4.1.2/libobjc/configure gcc-4.1.2-futaris/libobjc/configure --- gcc-4.1.2/libobjc/configure 2007-02-14 05:17:22.000000000 +0000 +++ gcc-4.1.2-futaris/libobjc/configure 2007-08-27 13:21:53.000000000 +0100 @@ -3312,6 +3312,11 @@ lt_cv_deplibs_check_method=pass_all ;; +linux-uclibc*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` + ;; + netbsd* | knetbsd*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' diff -ru gcc-4.1.2/libstdc++-v3/acinclude.m4 gcc-4.1.2-futaris/libstdc++-v3/acinclude.m4 --- gcc-4.1.2/libstdc++-v3/acinclude.m4 2007-01-29 10:51:01.000000000 +0000 +++ gcc-4.1.2-futaris/libstdc++-v3/acinclude.m4 2007-08-27 13:21:53.000000000 +0100 @@ -1003,7 +1003,7 @@ AC_MSG_CHECKING([for C locale to use]) GLIBCXX_ENABLE(clocale,auto,[@<:@=MODEL@:>@], [use MODEL for target locale package], - [permit generic|gnu|ieee_1003.1-2001|yes|no|auto]) + [permit generic|gnu|ieee_1003.1-2001|uclibc|yes|no|auto]) # If they didn't use this option switch, or if they specified --enable # with no specific model, we'll have to look for one. If they @@ -1019,6 +1019,9 @@ # Default to "generic". if test $enable_clocale_flag = auto; then case ${target_os} in + *-uclibc*) + enable_clocale_flag=uclibc + ;; linux* | gnu* | kfreebsd*-gnu | knetbsd*-gnu) AC_EGREP_CPP([_GLIBCXX_ok], [ #include @@ -1162,6 +1165,40 @@ CTIME_CC=config/locale/generic/time_members.cc CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h ;; + uclibc) + AC_MSG_RESULT(uclibc) + + # Declare intention to use gettext, and add support for specific + # languages. + # For some reason, ALL_LINGUAS has to be before AM-GNU-GETTEXT + ALL_LINGUAS="de fr" + + # Don't call AM-GNU-GETTEXT here. Instead, assume glibc. + AC_CHECK_PROG(check_msgfmt, msgfmt, yes, no) + if test x"$check_msgfmt" = x"yes" && test x"$enable_nls" = x"yes"; then + USE_NLS=yes + fi + # Export the build objects. + for ling in $ALL_LINGUAS; do \ + glibcxx_MOFILES="$glibcxx_MOFILES $ling.mo"; \ + glibcxx_POFILES="$glibcxx_POFILES $ling.po"; \ + done + AC_SUBST(glibcxx_MOFILES) + AC_SUBST(glibcxx_POFILES) + + CLOCALE_H=config/locale/uclibc/c_locale.h + CLOCALE_CC=config/locale/uclibc/c_locale.cc + CCODECVT_CC=config/locale/uclibc/codecvt_members.cc + CCOLLATE_CC=config/locale/uclibc/collate_members.cc + CCTYPE_CC=config/locale/uclibc/ctype_members.cc + CMESSAGES_H=config/locale/uclibc/messages_members.h + CMESSAGES_CC=config/locale/uclibc/messages_members.cc + CMONEY_CC=config/locale/uclibc/monetary_members.cc + CNUMERIC_CC=config/locale/uclibc/numeric_members.cc + CTIME_H=config/locale/uclibc/time_members.h + CTIME_CC=config/locale/uclibc/time_members.cc + CLOCALE_INTERNAL_H=config/locale/uclibc/c++locale_internal.h + ;; esac # This is where the testsuite looks for locale catalogs, using the Only in gcc-4.1.2-futaris/libstdc++-v3: acinclude.m4.orig Only in gcc-4.1.2-futaris/libstdc++-v3/config/locale: uclibc Only in gcc-4.1.2-futaris/libstdc++-v3/config/os: uclibc diff -ru gcc-4.1.2/libstdc++-v3/configure gcc-4.1.2-futaris/libstdc++-v3/configure --- gcc-4.1.2/libstdc++-v3/configure 2007-01-29 10:51:01.000000000 +0000 +++ gcc-4.1.2-futaris/libstdc++-v3/configure 2007-08-27 13:21:53.000000000 +0100 @@ -4005,6 +4005,11 @@ lt_cv_deplibs_check_method=pass_all ;; +linux-uclibc*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` + ;; + netbsd* | knetbsd*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' @@ -5740,7 +5745,7 @@ enableval="$enable_clocale" case "$enableval" in - generic|gnu|ieee_1003.1-2001|yes|no|auto) ;; + generic|gnu|ieee_1003.1-2001|uclibc|yes|no|auto) ;; *) { { echo "$as_me:$LINENO: error: Unknown argument to enable/disable clocale" >&5 echo "$as_me: error: Unknown argument to enable/disable clocale" >&2;} { (exit 1); exit 1; }; } ;; @@ -5765,6 +5770,9 @@ # Default to "generic". if test $enable_clocale_flag = auto; then case ${target_os} in + linux-uclibc*) + enable_clocale_flag=uclibc + ;; linux* | gnu* | kfreebsd*-gnu | knetbsd*-gnu) cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -5995,6 +6003,76 @@ CTIME_CC=config/locale/generic/time_members.cc CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h ;; + uclibc) + echo "$as_me:$LINENO: result: uclibc" >&5 +echo "${ECHO_T}uclibc" >&6 + + # Declare intention to use gettext, and add support for specific + # languages. + # For some reason, ALL_LINGUAS has to be before AM-GNU-GETTEXT + ALL_LINGUAS="de fr" + + # Don't call AM-GNU-GETTEXT here. Instead, assume glibc. + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_check_msgfmt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$check_msgfmt"; then + ac_cv_prog_check_msgfmt="$check_msgfmt" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_check_msgfmt="yes" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_check_msgfmt" && ac_cv_prog_check_msgfmt="no" +fi +fi +check_msgfmt=$ac_cv_prog_check_msgfmt +if test -n "$check_msgfmt"; then + echo "$as_me:$LINENO: result: $check_msgfmt" >&5 +echo "${ECHO_T}$check_msgfmt" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + if test x"$check_msgfmt" = x"yes" && test x"$enable_nls" = x"yes"; then + USE_NLS=yes + fi + # Export the build objects. + for ling in $ALL_LINGUAS; do \ + glibcxx_MOFILES="$glibcxx_MOFILES $ling.mo"; \ + glibcxx_POFILES="$glibcxx_POFILES $ling.po"; \ + done + + + + CLOCALE_H=config/locale/uclibc/c_locale.h + CLOCALE_CC=config/locale/uclibc/c_locale.cc + CCODECVT_CC=config/locale/uclibc/codecvt_members.cc + CCOLLATE_CC=config/locale/uclibc/collate_members.cc + CCTYPE_CC=config/locale/uclibc/ctype_members.cc + CMESSAGES_H=config/locale/uclibc/messages_members.h + CMESSAGES_CC=config/locale/uclibc/messages_members.cc + CMONEY_CC=config/locale/uclibc/monetary_members.cc + CNUMERIC_CC=config/locale/uclibc/numeric_members.cc + CTIME_H=config/locale/uclibc/time_members.h + CTIME_CC=config/locale/uclibc/time_members.cc + CLOCALE_INTERNAL_H=config/locale/uclibc/c++locale_internal.h + ;; esac # This is where the testsuite looks for locale catalogs, using the @@ -7246,6 +7324,9 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include +#ifdef __UCLIBC__ +#error ugly hack to make sure configure test fails here for cross until uClibc supports the complex funcs +#endif int main () { diff -ru gcc-4.1.2/libstdc++-v3/configure.host gcc-4.1.2-futaris/libstdc++-v3/configure.host --- gcc-4.1.2/libstdc++-v3/configure.host 2007-01-28 20:12:40.000000000 +0000 +++ gcc-4.1.2-futaris/libstdc++-v3/configure.host 2007-08-27 13:21:53.000000000 +0100 @@ -270,6 +270,12 @@ ;; esac +# Override for uClibc since linux-uclibc gets mishandled above. +case "${host_os}" in + *-uclibc*) + os_include_dir="os/uclibc" + ;; +esac # Set any OS-dependent and CPU-dependent bits. # THIS TABLE IS SORTED. KEEP IT THAT WAY. Only in gcc-4.1.2-futaris/libstdc++-v3: configure.host.orig Only in gcc-4.1.2-futaris/libstdc++-v3: configure.orig diff -ru gcc-4.1.2/libstdc++-v3/crossconfig.m4 gcc-4.1.2-futaris/libstdc++-v3/crossconfig.m4 --- gcc-4.1.2/libstdc++-v3/crossconfig.m4 2006-12-12 14:18:36.000000000 +0000 +++ gcc-4.1.2-futaris/libstdc++-v3/crossconfig.m4 2007-08-27 13:21:53.000000000 +0100 @@ -143,6 +143,99 @@ ;; esac ;; + *-uclibc*) +# Temporary hack until we implement the float versions of the libm funcs + AC_CHECK_HEADERS([nan.h ieeefp.h endian.h sys/isa_defs.h \ + machine/endian.h machine/param.h sys/machine.h sys/types.h \ + fp.h float.h endian.h inttypes.h locale.h float.h stdint.h]) + SECTION_FLAGS='-ffunction-sections -fdata-sections' + AC_SUBST(SECTION_FLAGS) + GLIBCXX_CHECK_LINKER_FEATURES + GLIBCXX_CHECK_COMPLEX_MATH_SUPPORT + GLIBCXX_CHECK_WCHAR_T_SUPPORT + + # For LFS. + AC_DEFINE(HAVE_INT64_T) + case "$target" in + *-uclinux*) + # Don't enable LFS with uClinux + ;; + *) + AC_DEFINE(_GLIBCXX_USE_LFS) + esac + + # For showmanyc_helper(). + AC_CHECK_HEADERS(sys/ioctl.h sys/filio.h) + GLIBCXX_CHECK_POLL + GLIBCXX_CHECK_S_ISREG_OR_S_IFREG + + # For xsputn_2(). + AC_CHECK_HEADERS(sys/uio.h) + GLIBCXX_CHECK_WRITEV + +# AC_DEFINE(HAVE_ACOSF) +# AC_DEFINE(HAVE_ASINF) +# AC_DEFINE(HAVE_ATANF) +# AC_DEFINE(HAVE_ATAN2F) + AC_DEFINE(HAVE_CEILF) + AC_DEFINE(HAVE_COPYSIGN) +# AC_DEFINE(HAVE_COPYSIGNF) +# AC_DEFINE(HAVE_COSF) +# AC_DEFINE(HAVE_COSHF) +# AC_DEFINE(HAVE_EXPF) +# AC_DEFINE(HAVE_FABSF) + AC_DEFINE(HAVE_FINITE) + AC_DEFINE(HAVE_FINITEF) + AC_DEFINE(HAVE_FLOORF) +# AC_DEFINE(HAVE_FMODF) +# AC_DEFINE(HAVE_FREXPF) + AC_DEFINE(HAVE_HYPOT) +# AC_DEFINE(HAVE_HYPOTF) + AC_DEFINE(HAVE_ISINF) + AC_DEFINE(HAVE_ISINFF) + AC_DEFINE(HAVE_ISNAN) + AC_DEFINE(HAVE_ISNANF) +# AC_DEFINE(HAVE_LOGF) +# AC_DEFINE(HAVE_LOG10F) +# AC_DEFINE(HAVE_MODFF) +# AC_DEFINE(HAVE_SINF) +# AC_DEFINE(HAVE_SINHF) +# AC_DEFINE(HAVE_SINCOS) +# AC_DEFINE(HAVE_SINCOSF) + AC_DEFINE(HAVE_SQRTF) +# AC_DEFINE(HAVE_TANF) +# AC_DEFINE(HAVE_TANHF) + if test x"long_double_math_on_this_cpu" = x"yes"; then + AC_MSG_ERROR([long_double_math_on_this_cpu is yes!]) +# AC_DEFINE(HAVE_ACOSL) +# AC_DEFINE(HAVE_ASINL) +# AC_DEFINE(HAVE_ATANL) +# AC_DEFINE(HAVE_ATAN2L) +# AC_DEFINE(HAVE_CEILL) +# AC_DEFINE(HAVE_COPYSIGNL) +# AC_DEFINE(HAVE_COSL) +# AC_DEFINE(HAVE_COSHL) +# AC_DEFINE(HAVE_EXPL) +# AC_DEFINE(HAVE_FABSL) +# AC_DEFINE(HAVE_FINITEL) +# AC_DEFINE(HAVE_FLOORL) +# AC_DEFINE(HAVE_FMODL) +# AC_DEFINE(HAVE_FREXPL) +# AC_DEFINE(HAVE_HYPOTL) +# AC_DEFINE(HAVE_ISINFL) +# AC_DEFINE(HAVE_ISNANL) +# AC_DEFINE(HAVE_LOGL) +# AC_DEFINE(HAVE_LOG10L) +# AC_DEFINE(HAVE_MODFL) +# AC_DEFINE(HAVE_POWL) +# AC_DEFINE(HAVE_SINL) +# AC_DEFINE(HAVE_SINHL) +# AC_DEFINE(HAVE_SINCOSL) +# AC_DEFINE(HAVE_SQRTL) +# AC_DEFINE(HAVE_TANL) +# AC_DEFINE(HAVE_TANHL) + fi + ;; *-linux* | *-uclinux* | *-gnu* | *-kfreebsd*-gnu | *-knetbsd*-gnu) AC_CHECK_HEADERS([nan.h ieeefp.h endian.h sys/isa_defs.h \ machine/endian.h machine/param.h sys/machine.h sys/types.h \ @@ -157,7 +250,7 @@ AC_DEFINE(HAVE_INT64_T) case "$target" in *-uclinux*) - # Don't enable LFS with uClibc + # Don't enable LFS with uClinux ;; *) AC_DEFINE(_GLIBCXX_USE_LFS) diff -ru gcc-4.1.2/libstdc++-v3/fragment.am gcc-4.1.2-futaris/libstdc++-v3/fragment.am --- gcc-4.1.2/libstdc++-v3/fragment.am 2005-03-21 17:40:24.000000000 +0000 +++ gcc-4.1.2-futaris/libstdc++-v3/fragment.am 2007-08-27 13:21:53.000000000 +0100 @@ -21,5 +21,5 @@ $(WARN_FLAGS) $(WERROR) -fdiagnostics-show-location=once # -I/-D flags to pass when compiling. -AM_CPPFLAGS = $(GLIBCXX_INCLUDES) +AM_CPPFLAGS = $(GLIBCXX_INCLUDES) -I$(toplevel_srcdir)/include diff -ru gcc-4.1.2/libstdc++-v3/include/c_compatibility/wchar.h gcc-4.1.2-futaris/libstdc++-v3/include/c_compatibility/wchar.h --- gcc-4.1.2/libstdc++-v3/include/c_compatibility/wchar.h 2005-08-17 03:28:44.000000000 +0100 +++ gcc-4.1.2-futaris/libstdc++-v3/include/c_compatibility/wchar.h 2007-08-27 13:21:53.000000000 +0100 @@ -101,7 +101,9 @@ using std::wmemcpy; using std::wmemmove; using std::wmemset; +#if _GLIBCXX_HAVE_WCSFTIME using std::wcsftime; +#endif #if _GLIBCXX_USE_C99 using std::wcstold; diff -ru gcc-4.1.2/libstdc++-v3/include/c_std/std_cstdio.h gcc-4.1.2-futaris/libstdc++-v3/include/c_std/std_cstdio.h --- gcc-4.1.2/libstdc++-v3/include/c_std/std_cstdio.h 2005-10-30 22:21:50.000000000 +0000 +++ gcc-4.1.2-futaris/libstdc++-v3/include/c_std/std_cstdio.h 2007-08-27 13:21:53.000000000 +0100 @@ -143,7 +143,7 @@ using ::vsprintf; } -#if _GLIBCXX_USE_C99 +#if _GLIBCXX_USE_C99 || defined(__UCLIBC__) #undef snprintf #undef vfscanf Only in gcc-4.1.2-futaris/libstdc++-v3/include/c_std: std_cstdio.h.orig diff -ru gcc-4.1.2/libstdc++-v3/include/c_std/std_cwchar.h gcc-4.1.2-futaris/libstdc++-v3/include/c_std/std_cwchar.h --- gcc-4.1.2/libstdc++-v3/include/c_std/std_cwchar.h 2005-10-30 22:21:50.000000000 +0000 +++ gcc-4.1.2-futaris/libstdc++-v3/include/c_std/std_cwchar.h 2007-08-27 13:21:53.000000000 +0100 @@ -180,7 +180,9 @@ using ::wcscoll; using ::wcscpy; using ::wcscspn; +#if _GLIBCXX_HAVE_WCSFTIME using ::wcsftime; +#endif using ::wcslen; using ::wcsncat; using ::wcsncmp; diff -ru gcc-4.1.2/libstdc++-v3/include/ext/rope gcc-4.1.2-futaris/libstdc++-v3/include/ext/rope --- gcc-4.1.2/libstdc++-v3/include/ext/rope 2005-08-17 03:28:44.000000000 +0100 +++ gcc-4.1.2-futaris/libstdc++-v3/include/ext/rope 2007-08-27 13:21:53.000000000 +0100 @@ -57,6 +57,9 @@ #include #include +/* cope w/ index defined as macro, SuSv3 proposal */ +#undef index + # ifdef __GC # define __GC_CONST const # else diff -ru gcc-4.1.2/libstdc++-v3/include/ext/ropeimpl.h gcc-4.1.2-futaris/libstdc++-v3/include/ext/ropeimpl.h --- gcc-4.1.2/libstdc++-v3/include/ext/ropeimpl.h 2005-08-17 03:28:44.000000000 +0100 +++ gcc-4.1.2-futaris/libstdc++-v3/include/ext/ropeimpl.h 2007-08-27 13:21:53.000000000 +0100 @@ -53,6 +53,9 @@ #include // For uninitialized_copy_n #include // For power +/* cope w/ index defined as macro, SuSv3 proposal */ +#undef index + namespace __gnu_cxx { using std::size_t; Only in gcc-4.1.2-futaris/libstdc++-v3/include/ext: rope.orig diff -ru gcc-4.1.2/libstdc++-v3/libmath/Makefile.am gcc-4.1.2-futaris/libstdc++-v3/libmath/Makefile.am --- gcc-4.1.2/libstdc++-v3/libmath/Makefile.am 2005-08-17 03:28:44.000000000 +0100 +++ gcc-4.1.2-futaris/libstdc++-v3/libmath/Makefile.am 2007-08-27 13:21:53.000000000 +0100 @@ -35,7 +35,7 @@ libmath_la_SOURCES = stubs.c -AM_CPPFLAGS = $(CANADIAN_INCLUDES) +AM_CPPFLAGS = $(CANADIAN_INCLUDES) -I$(toplevel_srcdir)/include # Only compiling "C" sources in this directory. LIBTOOL = @LIBTOOL@ --tag CC diff -ru gcc-4.1.2/libstdc++-v3/src/Makefile.am gcc-4.1.2-futaris/libstdc++-v3/src/Makefile.am --- gcc-4.1.2/libstdc++-v3/src/Makefile.am 2006-01-10 04:01:00.000000000 +0000 +++ gcc-4.1.2-futaris/libstdc++-v3/src/Makefile.am 2007-08-27 13:21:53.000000000 +0100 @@ -234,6 +234,10 @@ $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LDFLAGS) -o $@ +install-exec-local: + $(AR) cru libstdc++_pic.a .libs/*.o $(top_builddir)/libsupc++/*.o + $(INSTALL_DATA) libstdc++_pic.a $(DESTDIR)$(toolexeclibdir) + # Added bits to build debug library. if GLIBCXX_BUILD_DEBUG all-local: build_debug Only in gcc-4.1.2-futaris/libstdc++-v3/src: Makefile.am.orig diff -ru gcc-4.1.2/libstdc++-v3/src/Makefile.in gcc-4.1.2-futaris/libstdc++-v3/src/Makefile.in --- gcc-4.1.2/libstdc++-v3/src/Makefile.in 2006-01-10 17:14:00.000000000 +0000 +++ gcc-4.1.2-futaris/libstdc++-v3/src/Makefile.in 2007-08-27 13:21:53.000000000 +0100 @@ -627,7 +627,7 @@ install-data-am: install-data-local -install-exec-am: install-toolexeclibLTLIBRARIES +install-exec-am: install-toolexeclibLTLIBRARIES install-exec-local install-info: install-info-am @@ -660,6 +660,7 @@ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-data-local install-exec \ + install-exec-local \ install-exec-am install-info install-info-am install-man \ install-strip install-toolexeclibLTLIBRARIES installcheck \ installcheck-am installdirs maintainer-clean \ @@ -760,6 +761,11 @@ install_debug: (cd ${debugdir} && $(MAKE) \ toolexeclibdir=$(glibcxx_toolexeclibdir)/debug install) + +install-exec-local: + $(AR) cru libstdc++_pic.a .libs/*.o $(top_builddir)/libsupc++/*.o + $(INSTALL_DATA) libstdc++_pic.a $(DESTDIR)$(toolexeclibdir) + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: Only in gcc-4.1.2-futaris/libstdc++-v3/src: Makefile.in.orig diff -ru gcc-4.1.2/libtool.m4 gcc-4.1.2-futaris/libtool.m4 --- gcc-4.1.2/libtool.m4 2005-07-16 03:30:53.000000000 +0100 +++ gcc-4.1.2-futaris/libtool.m4 2007-08-27 13:21:53.000000000 +0100 @@ -743,6 +743,11 @@ lt_cv_deplibs_check_method=pass_all ;; +linux-uclibc*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` + ;; + netbsd* | knetbsd*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'] diff -ru gcc-4.1.2/ltconfig gcc-4.1.2-futaris/ltconfig --- gcc-4.1.2/ltconfig 2006-07-04 21:30:34.000000000 +0100 +++ gcc-4.1.2-futaris/ltconfig 2007-08-27 13:21:53.000000000 +0100 @@ -603,6 +603,7 @@ # Transform linux* to *-*-linux-gnu*, to support old configure scripts. case $host_os in +linux-uclibc*) ;; linux-gnu*) ;; linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` esac @@ -1274,6 +1275,23 @@ dynamic_linker='GNU/Linux ld.so' ;; +linux-uclibc*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + # Assume using the uClibc dynamic linker. + dynamic_linker="uClibc ld.so" + ;; + netbsd*) need_lib_prefix=no need_version=no diff -ru gcc-4.1.2/Makefile.in gcc-4.1.2-futaris/Makefile.in --- gcc-4.1.2/Makefile.in 2006-04-04 22:03:05.000000000 +0100 +++ gcc-4.1.2-futaris/Makefile.in 2007-08-27 13:21:53.000000000 +0100 @@ -194,6 +194,7 @@ AS="$(COMPILER_AS_FOR_TARGET)"; export AS; \ CC="$(CC_FOR_TARGET)"; export CC; \ CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \ + CPP="$(CC_FOR_TARGET) -E"; export CCP; \ CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \ CPPFLAGS="$(CPPFLAGS_FOR_TARGET)"; export CPPFLAGS; \ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \ @@ -334,7 +335,7 @@ CXXFLAGS_FOR_TARGET = $(CXXFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET) LIBCFLAGS_FOR_TARGET = $(CFLAGS_FOR_TARGET) LIBCXXFLAGS_FOR_TARGET = $(CXXFLAGS_FOR_TARGET) -fno-implicit-templates -LDFLAGS_FOR_TARGET = +LDFLAGS_FOR_TARGET = @LDFLAGS@ PICFLAG_FOR_TARGET = # ------------------------------------ diff -ru gcc-4.1.2/Makefile.tpl gcc-4.1.2-futaris/Makefile.tpl --- gcc-4.1.2/Makefile.tpl 2006-04-04 22:03:05.000000000 +0100 +++ gcc-4.1.2-futaris/Makefile.tpl 2007-08-27 13:21:53.000000000 +0100 @@ -337,7 +337,7 @@ CXXFLAGS_FOR_TARGET = $(CXXFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET) LIBCFLAGS_FOR_TARGET = $(CFLAGS_FOR_TARGET) LIBCXXFLAGS_FOR_TARGET = $(CXXFLAGS_FOR_TARGET) -fno-implicit-templates -LDFLAGS_FOR_TARGET = +LDFLAGS_FOR_TARGET = @LDFLAGS@ PICFLAG_FOR_TARGET = # ------------------------------------ diff -ru gcc-4.1.2/zlib/configure gcc-4.1.2-futaris/zlib/configure --- gcc-4.1.2/zlib/configure 2005-09-12 18:02:07.000000000 +0100 +++ gcc-4.1.2-futaris/zlib/configure 2007-08-27 13:21:53.000000000 +0100 @@ -3426,6 +3426,11 @@ lt_cv_deplibs_check_method=pass_all ;; +linux-uclibc*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` + ;; + netbsd* | knetbsd*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'