X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/83cccb37e9c5a36b06bf0ad05df0b61ba7e75f34..6c70430aed386aefe7cf8a0e76af920190a9f3ff:/toolchain/gcc/patches/4.3.5/930-avr32_support.patch?ds=inline diff --git a/toolchain/gcc/patches/4.3.5/930-avr32_support.patch b/toolchain/gcc/patches/4.3.5/930-avr32_support.patch index e7b01769e..cb4c823af 100644 --- a/toolchain/gcc/patches/4.3.5/930-avr32_support.patch +++ b/toolchain/gcc/patches/4.3.5/930-avr32_support.patch @@ -1,6 +1,6 @@ --- a/gcc/builtins.c +++ b/gcc/builtins.c -@@ -10779,7 +10779,7 @@ +@@ -10779,7 +10779,7 @@ validate_arglist (const_tree callexpr, . do { @@ -11,7 +11,7 @@ case 0: --- a/gcc/calls.c +++ b/gcc/calls.c -@@ -3496,7 +3496,7 @@ +@@ -3496,7 +3496,7 @@ emit_library_call_value_1 (int retval, r for (; count < nargs; count++) { rtx val = va_arg (p, rtx); @@ -20,15 +20,12 @@ /* We cannot convert the arg value to the mode the library wants here; must do it earlier where we know the signedness of the arg. */ ---- a/gcc/config/avr32/avr32.c +--- /dev/null +++ b/gcc/config/avr32/avr32.c -@@ -0,0 +1,7858 @@ +@@ -0,0 +1,8018 @@ +/* + Target hooks and helper functions for AVR32. -+ Copyright 2003-2006 Atmel Corporation. -+ -+ Written by Ronny Pedersen, Atmel Norway, -+ Initial porting by Anders �dland. ++ Copyright 2003,2004,2005,2006,2007,2008,2009,2010 Atmel Corporation. + + This file is part of GCC. + @@ -81,7 +78,9 @@ + +#include + -+/* Forward definitions of types. */ ++ ++ ++/* Global variables. */ +typedef struct minipool_node Mnode; +typedef struct minipool_fixup Mfix; + @@ -93,7 +92,10 @@ +/* True if we are currently building a constant table. */ +int making_const_table; + -+/* Some forward function declarations */ ++tree fndecl_attribute_args = NULL_TREE; ++ ++ ++/* Function prototypes. */ +static unsigned long avr32_isr_value (tree); +static unsigned long avr32_compute_func_type (void); +static tree avr32_handle_isr_attribute (tree *, tree, tree, int, bool *); @@ -104,6 +106,9 @@ +bool avr32_return_in_msb (tree type); +bool avr32_vector_mode_supported (enum machine_mode mode); +static void avr32_init_libfuncs (void); ++static void avr32_file_end (void); ++static void flashvault_decl_list_add (unsigned int vector_num, const char *name); ++ + + +static void @@ -117,51 +122,60 @@ +/* List of all known AVR32 parts */ +static const struct part_type_s avr32_part_types[] = { + /* name, part_type, architecture type, macro */ -+ {"none", PART_TYPE_AVR32_NONE, ARCH_TYPE_AVR32_AP, "__AVR32__"}, -+ {"ap7000", PART_TYPE_AVR32_AP7000, ARCH_TYPE_AVR32_AP, "__AVR32_AP7000__"}, -+ {"ap7001", PART_TYPE_AVR32_AP7001, ARCH_TYPE_AVR32_AP, "__AVR32_AP7001__"}, -+ {"ap7002", PART_TYPE_AVR32_AP7002, ARCH_TYPE_AVR32_AP, "__AVR32_AP7002__"}, -+ {"ap7200", PART_TYPE_AVR32_AP7200, ARCH_TYPE_AVR32_AP, "__AVR32_AP7200__"}, -+ {"uc3a0128", PART_TYPE_AVR32_UC3A0128, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A0128__"}, -+ {"uc3a0256", PART_TYPE_AVR32_UC3A0256, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A0256__"}, -+ {"uc3a0512", PART_TYPE_AVR32_UC3A0512, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A0512__"}, -+ {"uc3a0512es", PART_TYPE_AVR32_UC3A0512ES, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3A0512ES__"}, -+ {"uc3a1128", PART_TYPE_AVR32_UC3A1128, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A1128__"}, -+ {"uc3a1256", PART_TYPE_AVR32_UC3A1256, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A1256__"}, -+ {"uc3a1512", PART_TYPE_AVR32_UC3A1512, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A1512__"}, -+ {"uc3a1512es", PART_TYPE_AVR32_UC3A1512ES, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3A1512ES__"}, -+ {"uc3a3revd", PART_TYPE_AVR32_UC3A3REVD, ARCH_TYPE_AVR32_UCR2NOMUL, "__AVR32_UC3A3256S__"}, -+ {"uc3a364", PART_TYPE_AVR32_UC3A364, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A364__"}, -+ {"uc3a364s", PART_TYPE_AVR32_UC3A364S, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A364S__"}, -+ {"uc3a3128", PART_TYPE_AVR32_UC3A3128, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A3128__"}, -+ {"uc3a3128s", PART_TYPE_AVR32_UC3A3128S, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A3128S__"}, -+ {"uc3a3256", PART_TYPE_AVR32_UC3A3256, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A3256__"}, -+ {"uc3a3256s", PART_TYPE_AVR32_UC3A3256S, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A3256S__"}, -+ {"uc3b064", PART_TYPE_AVR32_UC3B064, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B064__"}, -+ {"uc3b0128", PART_TYPE_AVR32_UC3B0128, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B0128__"}, -+ {"uc3b0256", PART_TYPE_AVR32_UC3B0256, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B0256__"}, -+ {"uc3b0256es", PART_TYPE_AVR32_UC3B0256ES, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B0256ES__"}, -+ {"uc3b0512revc", PART_TYPE_AVR32_UC3B0512REVC, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3B0512REVC__"}, -+ {"uc3b164", PART_TYPE_AVR32_UC3B164, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B164__"}, -+ {"uc3b1128", PART_TYPE_AVR32_UC3B1128, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B1128__"}, -+ {"uc3b1256", PART_TYPE_AVR32_UC3B1256, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B1256__"}, -+ {"uc3b1256es", PART_TYPE_AVR32_UC3B1256ES, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B1256ES__"}, -+ {"uc3b1512revc", PART_TYPE_AVR32_UC3B1512REVC, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3B1512REVC__"}, -+ {"uc3c0512c", PART_TYPE_AVR32_UC3C0512C, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C0512C__"}, -+ {"uc3c0256c", PART_TYPE_AVR32_UC3C0256C, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C0256C__"}, -+ {"uc3c0128c", PART_TYPE_AVR32_UC3C0128C, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C0128C__"}, -+ {"uc3c064c", PART_TYPE_AVR32_UC3C064C, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C064C__"}, -+ {"uc3c1512c", PART_TYPE_AVR32_UC3C1512C, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C1512C__"}, -+ {"uc3c1256c", PART_TYPE_AVR32_UC3C1256C, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C1256C__"}, -+ {"uc3c1128c", PART_TYPE_AVR32_UC3C1128C, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C1128C__"}, -+ {"uc3c164c", PART_TYPE_AVR32_UC3C164C, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C164C__"}, -+ {"uc3c2512c", PART_TYPE_AVR32_UC3C2512C, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C2512C__"}, -+ {"uc3c2256c", PART_TYPE_AVR32_UC3C2256C, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C2256C__"}, -+ {"uc3c2128c", PART_TYPE_AVR32_UC3C2128C, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C2128C__"}, -+ {"uc3c264c", PART_TYPE_AVR32_UC3C264C, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C264C__"}, -+ {"uc3l064", PART_TYPE_AVR32_UC3L064, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3L064__"}, -+ {"uc3l032", PART_TYPE_AVR32_UC3L032, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3L032__"}, -+ {"uc3l016", PART_TYPE_AVR32_UC3L016, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3L016__"}, ++ {"none", PART_TYPE_AVR32_NONE, ARCH_TYPE_AVR32_AP, "__AVR32__"}, ++ {"ap7000", PART_TYPE_AVR32_AP7000, ARCH_TYPE_AVR32_AP, "__AVR32_AP7000__"}, ++ {"ap7001", PART_TYPE_AVR32_AP7001, ARCH_TYPE_AVR32_AP, "__AVR32_AP7001__"}, ++ {"ap7002", PART_TYPE_AVR32_AP7002, ARCH_TYPE_AVR32_AP, "__AVR32_AP7002__"}, ++ {"ap7200", PART_TYPE_AVR32_AP7200, ARCH_TYPE_AVR32_AP, "__AVR32_AP7200__"}, ++ {"uc3a0128", PART_TYPE_AVR32_UC3A0128, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A0128__"}, ++ {"uc3a0256", PART_TYPE_AVR32_UC3A0256, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A0256__"}, ++ {"uc3a0512", PART_TYPE_AVR32_UC3A0512, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A0512__"}, ++ {"uc3a0512es", PART_TYPE_AVR32_UC3A0512ES, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3A0512ES__"}, ++ {"uc3a1128", PART_TYPE_AVR32_UC3A1128, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A1128__"}, ++ {"uc3a1256", PART_TYPE_AVR32_UC3A1256, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A1256__"}, ++ {"uc3a1512", PART_TYPE_AVR32_UC3A1512, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A1512__"}, ++ {"uc3a1512es", PART_TYPE_AVR32_UC3A1512ES, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3A1512ES__"}, ++ {"uc3a3revd", PART_TYPE_AVR32_UC3A3REVD, ARCH_TYPE_AVR32_UCR2NOMUL, "__AVR32_UC3A3256S__"}, ++ {"uc3a364", PART_TYPE_AVR32_UC3A364, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A364__"}, ++ {"uc3a364s", PART_TYPE_AVR32_UC3A364S, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A364S__"}, ++ {"uc3a3128", PART_TYPE_AVR32_UC3A3128, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A3128__"}, ++ {"uc3a3128s", PART_TYPE_AVR32_UC3A3128S, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A3128S__"}, ++ {"uc3a3256", PART_TYPE_AVR32_UC3A3256, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A3256__"}, ++ {"uc3a3256s", PART_TYPE_AVR32_UC3A3256S, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3A3256S__"}, ++ {"uc3b064", PART_TYPE_AVR32_UC3B064, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B064__"}, ++ {"uc3b0128", PART_TYPE_AVR32_UC3B0128, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B0128__"}, ++ {"uc3b0256", PART_TYPE_AVR32_UC3B0256, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B0256__"}, ++ {"uc3b0256es", PART_TYPE_AVR32_UC3B0256ES, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B0256ES__"}, ++ {"uc3b0512", PART_TYPE_AVR32_UC3B0512, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3B0512__"}, ++ {"uc3b0512revc", PART_TYPE_AVR32_UC3B0512REVC, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3B0512REVC__"}, ++ {"uc3b164", PART_TYPE_AVR32_UC3B164, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B164__"}, ++ {"uc3b1128", PART_TYPE_AVR32_UC3B1128, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B1128__"}, ++ {"uc3b1256", PART_TYPE_AVR32_UC3B1256, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B1256__"}, ++ {"uc3b1256es", PART_TYPE_AVR32_UC3B1256ES, ARCH_TYPE_AVR32_UCR1, "__AVR32_UC3B1256ES__"}, ++ {"uc3b1512", PART_TYPE_AVR32_UC3B1512, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3B1512__"}, ++ {"uc3b1512revc", PART_TYPE_AVR32_UC3B1512REVC, ARCH_TYPE_AVR32_UCR2, "__AVR32_UC3B1512REVC__"}, ++ {"uc3c0512crevc", PART_TYPE_AVR32_UC3C0512CREVC, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C0512CREVC__"}, ++ {"uc3c1512crevc", PART_TYPE_AVR32_UC3C1512CREVC, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C1512CREVC__"}, ++ {"uc3c2512crevc", PART_TYPE_AVR32_UC3C2512CREVC, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3C2512CREVC__"}, ++ {"uc3l0256", PART_TYPE_AVR32_UC3L0256, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3L0256__"}, ++ {"uc3l0128", PART_TYPE_AVR32_UC3L0128, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3L0128__"}, ++ {"uc3l064", PART_TYPE_AVR32_UC3L064, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3L064__"}, ++ {"uc3l032", PART_TYPE_AVR32_UC3L032, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3L032__"}, ++ {"uc3l016", PART_TYPE_AVR32_UC3L016, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3L016__"}, ++ {"uc3l064revb", PART_TYPE_AVR32_UC3L064, ARCH_TYPE_AVR32_UCR3, "__AVR32_UC3L064REVB__"}, ++ {"uc3c064c", PART_TYPE_AVR32_UC3C064C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C064C__"}, ++ {"uc3c0128c", PART_TYPE_AVR32_UC3C0128C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C0128C__"}, ++ {"uc3c0256c", PART_TYPE_AVR32_UC3C0256C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C0256C__"}, ++ {"uc3c0512c", PART_TYPE_AVR32_UC3C0512C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C0512C__"}, ++ {"uc3c164c", PART_TYPE_AVR32_UC3C164C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C164C__"}, ++ {"uc3c1128c", PART_TYPE_AVR32_UC3C1128C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C1128C__"}, ++ {"uc3c1256c", PART_TYPE_AVR32_UC3C1256C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C1256C__"}, ++ {"uc3c1512c", PART_TYPE_AVR32_UC3C1512C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C1512C__"}, ++ {"uc3c264c", PART_TYPE_AVR32_UC3C264C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C264C__"}, ++ {"uc3c2128c", PART_TYPE_AVR32_UC3C2128C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C2128C__"}, ++ {"uc3c2256c", PART_TYPE_AVR32_UC3C2256C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C2256C__"}, ++ {"uc3c2512c", PART_TYPE_AVR32_UC3C2512C, ARCH_TYPE_AVR32_UCR3FP, "__AVR32_UC3C2512C__"}, ++ {"mxt768e", PART_TYPE_AVR32_MXT768E, ARCH_TYPE_AVR32_UCR3, "__AVR32_MXT768E__"}, + {NULL, 0, 0, NULL} +}; + @@ -190,6 +204,10 @@ + (FLAG_AVR32_HAS_DSP | FLAG_AVR32_HAS_RMW + | FLAG_AVR32_HAS_V2_INSNS), + "__AVR32_UC__=3"}, ++ {"ucr3fp", ARCH_TYPE_AVR32_UCR3FP, UARCH_TYPE_AVR32A, ++ (FLAG_AVR32_HAS_DSP | FLAG_AVR32_HAS_RMW | FLAG_AVR32_HAS_FPU ++ | FLAG_AVR32_HAS_V2_INSNS), ++ "__AVR32_UC__=3"}, + {NULL, 0, 0, 0, NULL} +}; + @@ -201,14 +219,25 @@ +const struct arch_type_s *avr32_arch; + + ++/* FIXME: needs to use GC. */ ++struct flashvault_decl_list ++{ ++ struct flashvault_decl_list *next; ++ unsigned int vector_num; ++ const char *name; ++}; ++ ++static struct flashvault_decl_list *flashvault_decl_list_head = NULL; ++ ++ +/* Set default target_flags. */ +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS \ + (MASK_HAS_ASM_ADDR_PSEUDOS | MASK_MD_REORG_OPTIMIZATION | MASK_COND_EXEC_BEFORE_RELOAD) + +void -+avr32_optimization_options (int level, -+ int size){ ++avr32_optimization_options (int level, int size) ++{ + if (AVR32_ALWAYS_PIC) + flag_pic = 1; + @@ -217,6 +246,7 @@ + flag_section_anchors = 1; +} + ++ +/* Override command line options */ +void +avr32_override_options (void) @@ -301,7 +331,6 @@ + + if (TARGET_NO_PIC) + flag_pic = 0; -+ + avr32_add_gc_roots (); +} + @@ -352,6 +381,8 @@ +#undef TARGET_ASM_FUNCTION_PROLOGUE +#define TARGET_ASM_FUNCTION_PROLOGUE avr32_target_asm_function_prologue + ++#undef TARGET_ASM_FILE_END ++#define TARGET_ASM_FILE_END avr32_file_end + +#undef TARGET_DEFAULT_SHORT_ENUMS +#define TARGET_DEFAULT_SHORT_ENUMS hook_bool_void_false @@ -383,6 +414,9 @@ +#undef TARGET_RETURN_IN_MSB +#define TARGET_RETURN_IN_MSB avr32_return_in_msb + ++#undef TARGET_ENCODE_SECTION_INFO ++#define TARGET_ENCODE_SECTION_INFO avr32_encode_section_info ++ +#undef TARGET_ARG_PARTIAL_BYTES +#define TARGET_ARG_PARTIAL_BYTES avr32_arg_partial_bytes + @@ -418,8 +452,24 @@ + +#undef TARGET_MAX_ANCHOR_OFFSET +#define TARGET_MAX_ANCHOR_OFFSET ((1 << 15) - 1) ++#undef TARGET_SECONDARY_RELOAD ++#define TARGET_SECONDARY_RELOAD avr32_secondary_reload ++ ++enum reg_class ++avr32_secondary_reload (bool in_p, rtx x, enum reg_class class, ++ enum machine_mode mode, secondary_reload_info *sri) ++{ + ++ if ( avr32_rmw_memory_operand (x, mode) ) ++ { ++ if (!in_p) ++ sri->icode = CODE_FOR_reload_out_rmw_memory_operand; ++ else ++ sri->icode = CODE_FOR_reload_in_rmw_memory_operand; ++ } ++ return NO_REGS; + ++} +/* + * Switches to the appropriate section for output of constant pool + * entry x in mode. You can assume that x is some kind of constant in @@ -494,6 +544,7 @@ + return default_assemble_integer (x, size, aligned_p); +} + ++ +/* + * This target hook describes the relative costs of RTL expressions. + * @@ -632,6 +683,7 @@ + } +} + ++ +static bool +avr32_rtx_costs (rtx x, int code, int outer_code, int *total) +{ @@ -659,6 +711,9 @@ + {"interrupt", 0, 1, false, false, false, avr32_handle_isr_attribute}, + {"acall", 0, 1, false, true, true, avr32_handle_acall_attribute}, + {"naked", 0, 0, true, false, false, avr32_handle_fndecl_attribute}, ++ {"rmw_addressable", 0, 0, true, false, false, NULL}, ++ {"flashvault", 0, 1, true, false, false, avr32_handle_fndecl_attribute}, ++ {"flashvault_impl", 0, 1, true, false, false, avr32_handle_fndecl_attribute}, + {NULL, 0, 0, false, false, false, NULL} +}; + @@ -670,6 +725,7 @@ +} +isr_attribute_arg; + ++ +static const isr_attribute_arg isr_attribute_args[] = { + {"FULL", AVR32_FT_ISR_FULL}, + {"full", AVR32_FT_ISR_FULL}, @@ -684,9 +740,9 @@ + {NULL, AVR32_FT_ISR_NONE} +}; + ++ +/* Returns the (interrupt) function type of the current + function, or AVR32_FT_UNKNOWN if the type cannot be determined. */ -+ +static unsigned long +avr32_isr_value (tree argument) +{ @@ -714,7 +770,6 @@ +} + + -+ +/* +These hooks specify assembly directives for creating certain kinds +of integer object. The TARGET_ASM_BYTE_OP directive creates a @@ -751,6 +806,7 @@ +#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK +#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true + ++ +static void +avr32_output_mi_thunk (FILE * file, + tree thunk ATTRIBUTE_UNUSED, @@ -837,7 +893,7 @@ + +tree int_ftype_int, int_ftype_void, short_ftype_short, void_ftype_int_int, + void_ftype_ptr_int; -+tree void_ftype_int, void_ftype_void, int_ftype_ptr_int; ++tree void_ftype_int, void_ftype_ulong, void_ftype_void, int_ftype_ptr_int; +tree short_ftype_short, int_ftype_int_short, int_ftype_short_short, + short_ftype_short_short; +tree int_ftype_int_int, longlong_ftype_int_short, longlong_ftype_short_short; @@ -871,21 +927,22 @@ +}; + +static const struct builtin_description bdesc_2arg[] = { ++ +#define DSP_BUILTIN(code, builtin, ftype) \ + { 1, CODE_FOR_##code, "__builtin_" #code , \ -+ AVR32_BUILTIN_##builtin, 0, 0, ftype } ++ AVR32_BUILTIN_##builtin, 0, 0, ftype } + -+ DSP_BUILTIN (mulsathh_h, MULSATHH_H, &short_ftype_short_short), -+ DSP_BUILTIN (mulsathh_w, MULSATHH_W, &int_ftype_short_short), ++ DSP_BUILTIN (mulsathh_h, MULSATHH_H, &short_ftype_short_short), ++ DSP_BUILTIN (mulsathh_w, MULSATHH_W, &int_ftype_short_short), + DSP_BUILTIN (mulsatrndhh_h, MULSATRNDHH_H, &short_ftype_short_short), + DSP_BUILTIN (mulsatrndwh_w, MULSATRNDWH_W, &int_ftype_int_short), -+ DSP_BUILTIN (mulsatwh_w, MULSATWH_W, &int_ftype_int_short), -+ DSP_BUILTIN (satadd_h, SATADD_H, &short_ftype_short_short), -+ DSP_BUILTIN (satsub_h, SATSUB_H, &short_ftype_short_short), -+ DSP_BUILTIN (satadd_w, SATADD_W, &int_ftype_int_int), -+ DSP_BUILTIN (satsub_w, SATSUB_W, &int_ftype_int_int), -+ DSP_BUILTIN (mulwh_d, MULWH_D, &longlong_ftype_int_short), -+ DSP_BUILTIN (mulnwh_d, MULNWH_D, &longlong_ftype_int_short) ++ DSP_BUILTIN (mulsatwh_w, MULSATWH_W, &int_ftype_int_short), ++ DSP_BUILTIN (satadd_h, SATADD_H, &short_ftype_short_short), ++ DSP_BUILTIN (satsub_h, SATSUB_H, &short_ftype_short_short), ++ DSP_BUILTIN (satadd_w, SATADD_W, &int_ftype_int_int), ++ DSP_BUILTIN (satsub_w, SATSUB_W, &int_ftype_int_int), ++ DSP_BUILTIN (mulwh_d, MULWH_D, &longlong_ftype_int_short), ++ DSP_BUILTIN (mulnwh_d, MULNWH_D, &longlong_ftype_int_short) +}; + + @@ -1014,6 +1071,10 @@ + /* void func (int) */ + void_ftype_int = build_function_type (void_type_node, int_endlink); + ++ /* void func (ulong) */ ++ void_ftype_ulong = build_function_type_list (void_type_node, ++ long_unsigned_type_node, NULL_TREE); ++ + /* void func (void) */ + void_ftype_void = build_function_type (void_type_node, void_endlink); + @@ -1074,6 +1135,11 @@ + AVR32_BUILTIN_MACWH_D); + def_builtin ("__builtin_machh_d", longlong_ftype_longlong_short_short, + AVR32_BUILTIN_MACHH_D); ++ def_builtin ("__builtin_mems", void_ftype_ptr_int, AVR32_BUILTIN_MEMS); ++ def_builtin ("__builtin_memt", void_ftype_ptr_int, AVR32_BUILTIN_MEMT); ++ def_builtin ("__builtin_memc", void_ftype_ptr_int, AVR32_BUILTIN_MEMC); ++ def_builtin ("__builtin_sleep", void_ftype_int, AVR32_BUILTIN_SLEEP); ++ def_builtin ("__builtin_avr32_delay_cycles", void_ftype_int, AVR32_BUILTIN_DELAY_CYCLES); + + /* Add all builtins that are more or less simple operations on two + operands. */ @@ -1090,8 +1156,7 @@ +} + + -+/* Subroutine of avr32_expand_builtin to take care of binop insns. */ -+ ++/* Subroutine of avr32_expand_builtin to take care of binop insns. */ +static rtx +avr32_expand_binop_builtin (enum insn_code icode, tree exp, rtx target) +{ @@ -1134,12 +1199,12 @@ + return target; +} + ++ +/* Expand an expression EXP that calls a built-in function, + with result going to TARGET if that's convenient + (and in mode MODE if that's convenient). + SUBTARGET may be used as the target for computing one of EXP's operands. + IGNORE is nonzero if the value is to be ignored. */ -+ +rtx +avr32_expand_builtin (tree exp, + rtx target, @@ -1806,6 +1871,99 @@ + return target; + } + ++ case AVR32_BUILTIN_MEMS: ++ case AVR32_BUILTIN_MEMC: ++ case AVR32_BUILTIN_MEMT: ++ { ++ if (!TARGET_RMW) ++ error ("Trying to use __builtin_mem(s/c/t) when target does not support RMW insns."); ++ ++ switch (fcode) { ++ case AVR32_BUILTIN_MEMS: ++ icode = CODE_FOR_iorsi3; ++ break; ++ case AVR32_BUILTIN_MEMC: ++ icode = CODE_FOR_andsi3; ++ break; ++ case AVR32_BUILTIN_MEMT: ++ icode = CODE_FOR_xorsi3; ++ break; ++ } ++ arg0 = CALL_EXPR_ARG (exp,0); ++ arg1 = CALL_EXPR_ARG (exp,1); ++ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); ++ if ( GET_CODE (op0) == SYMBOL_REF ) ++ // This symbol must be RMW addressable ++ SYMBOL_REF_FLAGS (op0) |= (1 << SYMBOL_FLAG_RMW_ADDR_SHIFT); ++ op0 = gen_rtx_MEM(SImode, op0); ++ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); ++ mode0 = insn_data[icode].operand[1].mode; ++ ++ ++ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) ++ { ++ error ("Parameter 1 to __builtin_mem(s/c/t) must be a Ks15<<2 address or a rmw addressable symbol."); ++ } ++ ++ if ( !CONST_INT_P (op1) ++ || INTVAL (op1) > 31 ++ || INTVAL (op1) < 0 ) ++ error ("Parameter 2 to __builtin_mem(s/c/t) must be a constant between 0 and 31."); ++ ++ if ( fcode == AVR32_BUILTIN_MEMC ) ++ op1 = GEN_INT((~(1 << INTVAL(op1)))&0xffffffff); ++ else ++ op1 = GEN_INT((1 << INTVAL(op1))&0xffffffff); ++ pat = GEN_FCN (icode) (op0, op0, op1); ++ if (!pat) ++ return 0; ++ emit_insn (pat); ++ return op0; ++ } ++ ++ case AVR32_BUILTIN_SLEEP: ++ { ++ arg0 = CALL_EXPR_ARG (exp, 0); ++ op0 = expand_normal (arg0); ++ int intval = INTVAL(op0); ++ ++ /* Check if the argument if integer and if the value of integer ++ is greater than 0. */ ++ ++ if (!CONSTANT_P (op0)) ++ error ("Parameter 1 to __builtin_sleep() is not a valid integer."); ++ if (intval < 0 ) ++ error ("Parameter 1 to __builtin_sleep() should be an integer greater than 0."); ++ ++ int strncmpval = strncmp (avr32_part_name,"uc3l", 4); ++ ++ /* Check if op0 is less than 7 for uc3l* and less than 6 for other ++ devices. By this check we are avoiding if operand is less than ++ 256. For more devices, add more such checks. */ ++ ++ if ( strncmpval == 0 && intval >= 7) ++ error ("Parameter 1 to __builtin_sleep() should be less than or equal to 7."); ++ else if ( strncmp != 0 && intval >= 6) ++ error ("Parameter 1 to __builtin_sleep() should be less than or equal to 6."); ++ ++ emit_insn (gen_sleep(op0)); ++ return target; ++ ++ } ++ case AVR32_BUILTIN_DELAY_CYCLES: ++ { ++ arg0 = CALL_EXPR_ARG (exp, 0); ++ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); ++ ++ if (TARGET_ARCH_AP) ++ error (" __builtin_avr32_delay_cycles() not supported for \'%s\' architecture.", avr32_arch_name); ++ if (!CONSTANT_P (op0)) ++ error ("Parameter 1 to __builtin_avr32_delay_cycles() should be an integer."); ++ emit_insn (gen_delay_cycles (op0)); ++ return 0; ++ ++ } ++ + } + + for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++) @@ -1820,7 +1978,6 @@ + +/* Handle an "interrupt" or "isr" attribute; + arguments as in struct attribute_spec.handler. */ -+ +static tree +avr32_handle_isr_attribute (tree * node, tree name, tree args, + int flags, bool * no_add_attrs) @@ -1878,11 +2035,12 @@ + return NULL_TREE; +} + ++ +/* Handle an attribute requiring a FUNCTION_DECL; + arguments as in struct attribute_spec.handler. */ +static tree +avr32_handle_fndecl_attribute (tree * node, tree name, -+ tree args ATTRIBUTE_UNUSED, ++ tree args, + int flags ATTRIBUTE_UNUSED, + bool * no_add_attrs) +{ @@ -1891,6 +2049,20 @@ + warning (OPT_Wattributes,"%qs attribute only applies to functions", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; ++ return NULL_TREE; ++ } ++ ++ fndecl_attribute_args = args; ++ if (args == NULL_TREE) ++ return NULL_TREE; ++ ++ tree value = TREE_VALUE (args); ++ if (TREE_CODE (value) != INTEGER_CST) ++ { ++ warning (OPT_Wattributes, ++ "argument of %qs attribute is not an integer constant", ++ IDENTIFIER_POINTER (name)); ++ *no_add_attrs = true; + } + + return NULL_TREE; @@ -1920,14 +2092,62 @@ +} + + ++bool ++avr32_flashvault_call(tree decl) ++{ ++ tree attributes; ++ tree fv_attribute; ++ tree vector_tree; ++ unsigned int vector; ++ ++ if (decl && TREE_CODE (decl) == FUNCTION_DECL) ++ { ++ attributes = DECL_ATTRIBUTES(decl); ++ fv_attribute = lookup_attribute ("flashvault", attributes); ++ if (fv_attribute != NULL_TREE) ++ { ++ /* Get attribute parameter, for the function vector number. */ ++ /* ++ There is probably an easier, standard way to retrieve the ++ attribute parameter which needs to be done here. ++ */ ++ vector_tree = TREE_VALUE(fv_attribute); ++ if (vector_tree != NULL_TREE) ++ { ++ vector = (unsigned int)TREE_INT_CST_LOW(TREE_VALUE(vector_tree)); ++ fprintf (asm_out_file, ++ "\tmov\tr8, lo(%i)\t# Load vector number for sscall.\n", ++ vector); ++ } ++ ++ fprintf (asm_out_file, ++ "\tsscall\t# Secure system call.\n"); ++ ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++ ++static bool has_attribute_p (tree decl, const char *name) ++{ ++ if (decl && TREE_CODE (decl) == FUNCTION_DECL) ++ { ++ return (lookup_attribute (name, DECL_ATTRIBUTES(decl)) != NULL_TREE); ++ } ++ return NULL_TREE; ++} ++ ++ +/* Return 0 if the attributes for two types are incompatible, 1 if they + are compatible, and 2 if they are nearly compatible (which causes a + warning to be generated). */ -+ +static int +avr32_comp_type_attributes (tree type1, tree type2) +{ -+ int acall1, acall2, isr1, isr2, naked1, naked2; ++ bool acall1, acall2, isr1, isr2, naked1, naked2, fv1, fv2, fvimpl1, fvimpl2; + + /* Check for mismatch of non-default calling convention. */ + if (TREE_CODE (type1) != FUNCTION_TYPE) @@ -1938,6 +2158,10 @@ + acall2 = lookup_attribute ("acall", TYPE_ATTRIBUTES (type2)) != NULL; + naked1 = lookup_attribute ("naked", TYPE_ATTRIBUTES (type1)) != NULL; + naked2 = lookup_attribute ("naked", TYPE_ATTRIBUTES (type2)) != NULL; ++ fv1 = lookup_attribute ("flashvault", TYPE_ATTRIBUTES (type1)) != NULL; ++ fv2 = lookup_attribute ("flashvault", TYPE_ATTRIBUTES (type2)) != NULL; ++ fvimpl1 = lookup_attribute ("flashvault_impl", TYPE_ATTRIBUTES (type1)) != NULL; ++ fvimpl2 = lookup_attribute ("flashvault_impl", TYPE_ATTRIBUTES (type2)) != NULL; + isr1 = lookup_attribute ("isr", TYPE_ATTRIBUTES (type1)) != NULL; + if (!isr1) + isr1 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type1)) != NULL; @@ -1947,7 +2171,16 @@ + isr2 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type2)) != NULL; + + if ((acall1 && isr2) -+ || (acall2 && isr1) || (naked1 && isr2) || (naked2 && isr1)) ++ || (acall2 && isr1) ++ || (naked1 && isr2) ++ || (naked2 && isr1) ++ || (fv1 && isr2) ++ || (fv2 && isr1) ++ || (fvimpl1 && isr2) ++ || (fvimpl2 && isr1) ++ || (fv1 && fvimpl2) ++ || (fv2 && fvimpl1) ++ ) + return 0; + + return 1; @@ -1955,7 +2188,6 @@ + + +/* Computes the type of the current function. */ -+ +static unsigned long +avr32_compute_func_type (void) +{ @@ -1998,11 +2230,19 @@ + if (a != NULL_TREE) + type |= AVR32_FT_NAKED; + ++ a = lookup_attribute ("flashvault", attr); ++ if (a != NULL_TREE) ++ type |= AVR32_FT_FLASHVAULT; ++ ++ a = lookup_attribute ("flashvault_impl", attr); ++ if (a != NULL_TREE) ++ type |= AVR32_FT_FLASHVAULT_IMPL; ++ + return type; +} + -+/* Returns the type of the current function. */ + ++/* Returns the type of the current function. */ +static unsigned long +avr32_current_func_type (void) +{ @@ -2012,10 +2252,11 @@ + return cfun->machine->func_type; +} + ++ +/* -+ This target hook should return true if we should not pass type solely -+ in registers. The file expr.h defines a definition that is usually appropriate, -+ refer to expr.h for additional documentation. ++This target hook should return true if we should not pass type solely ++in registers. The file expr.h defines a definition that is usually appropriate, ++refer to expr.h for additional documentation. +*/ +bool +avr32_must_pass_in_stack (enum machine_mode mode ATTRIBUTE_UNUSED, tree type) @@ -2052,6 +2293,7 @@ + return true; +} + ++ +/* + This target hook should return true if an argument at the position indicated + by cum should be passed by reference. This predicate is queried after target @@ -2069,6 +2311,7 @@ + return (type && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)); +} + ++ +static int +avr32_arg_partial_bytes (CUMULATIVE_ARGS * pcum ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, @@ -2093,11 +2336,13 @@ + INTERNAL_REGNUM (8) +}; + ++ +rtx avr32_compare_op0 = NULL_RTX; +rtx avr32_compare_op1 = NULL_RTX; +rtx avr32_compare_operator = NULL_RTX; +rtx avr32_acc_cache = NULL_RTX; + ++ +/* + Returns nonzero if it is allowed to store a value of mode mode in hard + register number regno. @@ -2105,43 +2350,35 @@ +int +avr32_hard_regno_mode_ok (int regnr, enum machine_mode mode) +{ -+ /* We allow only float modes in the fp-registers */ -+ if (regnr >= FIRST_FP_REGNUM -+ && regnr <= LAST_FP_REGNUM && GET_MODE_CLASS (mode) != MODE_FLOAT) -+ { -+ return 0; -+ } -+ + switch (mode) + { -+ case DImode: /* long long */ -+ case DFmode: /* double */ -+ case SCmode: /* __complex__ float */ -+ case CSImode: /* __complex__ int */ -+ if (regnr < 4) -+ { /* long long int not supported in r12, sp, lr -+ or pc. */ -+ return 0; -+ } -+ else -+ { -+ if (regnr % 2) /* long long int has to be refered in even -+ registers. */ ++ case DImode: /* long long */ ++ case DFmode: /* double */ ++ case SCmode: /* __complex__ float */ ++ case CSImode: /* __complex__ int */ ++ if (regnr < 4) ++ { /* long long int not supported in r12, sp, lr or pc. */ + return 0; -+ else -+ return 1; -+ } -+ case CDImode: /* __complex__ long long */ -+ case DCmode: /* __complex__ double */ -+ case TImode: /* 16 bytes */ -+ if (regnr < 7) -+ return 0; -+ else if (regnr % 2) -+ return 0; -+ else -+ return 1; -+ default: -+ return 1; ++ } ++ else ++ { ++ /* long long int has to be referred in even registers. */ ++ if (regnr % 2) ++ return 0; ++ else ++ return 1; ++ } ++ case CDImode: /* __complex__ long long */ ++ case DCmode: /* __complex__ double */ ++ case TImode: /* 16 bytes */ ++ if (regnr < 7) ++ return 0; ++ else if (regnr % 2) ++ return 0; ++ else ++ return 1; ++ default: ++ return 1; + } +} + @@ -2160,7 +2397,6 @@ +} + + -+ +int +avr32_const_ok_for_constraint_p (HOST_WIDE_INT value, char c, const char *str) +{ @@ -2204,50 +2440,20 @@ + return avr32_mask_upper_bits_operand (GEN_INT (value), VOIDmode); + case 'J': + return avr32_hi16_immediate_operand (GEN_INT (value), VOIDmode); ++ case 'O': ++ return one_bit_set_operand (GEN_INT (value), VOIDmode); ++ case 'N': ++ return one_bit_cleared_operand (GEN_INT (value), VOIDmode); ++ case 'L': ++ /* The lower 16-bits are set. */ ++ return ((value & 0xffff) == 0xffff) ; + } + + return 0; +} + + -+/*Compute mask of which floating-point registers needs saving upon -+ entry to this function*/ -+static unsigned long -+avr32_compute_save_fp_reg_mask (void) -+{ -+ unsigned long func_type = avr32_current_func_type (); -+ unsigned int save_reg_mask = 0; -+ unsigned int reg; -+ unsigned int max_reg = 7; -+ int save_all_call_used_regs = FALSE; -+ -+ /* This only applies for hardware floating-point implementation. */ -+ if (!TARGET_HARD_FLOAT) -+ return 0; -+ -+ if (IS_INTERRUPT (func_type)) -+ { -+ -+ /* Interrupt functions must not corrupt any registers, even call -+ clobbered ones. If this is a leaf function we can just examine the -+ registers used by the RTL, but otherwise we have to assume that -+ whatever function is called might clobber anything, and so we have -+ to save all the call-clobbered registers as well. */ -+ max_reg = 13; -+ save_all_call_used_regs = !current_function_is_leaf; -+ } -+ -+ /* All used registers used must be saved */ -+ for (reg = 0; reg <= max_reg; reg++) -+ if (df_regs_ever_live_p (INTERNAL_FP_REGNUM (reg)) -+ || (save_all_call_used_regs -+ && call_used_regs[INTERNAL_FP_REGNUM (reg)])) -+ save_reg_mask |= (1 << reg); -+ -+ return save_reg_mask; -+} -+ -+/*Compute mask of registers which needs saving upon function entry */ ++/* Compute mask of registers which needs saving upon function entry. */ +static unsigned long +avr32_compute_save_reg_mask (int push) +{ @@ -2261,7 +2467,6 @@ + { + unsigned int max_reg = 12; + -+ + /* Get the banking scheme for the interrupt */ + switch (func_type) + { @@ -2291,7 +2496,7 @@ + func_type = AVR32_FT_ISR_NONE; + } + -+ /* All registers which are used and is not shadowed must be saved */ ++ /* All registers which are used and are not shadowed must be saved. */ + for (reg = 0; reg <= max_reg; reg++) + if (df_regs_ever_live_p (INTERNAL_REGNUM (reg)) + || (!current_function_is_leaf @@ -2328,7 +2533,7 @@ + + + /* If we optimize for size and do not have anonymous arguments: use -+ popm/pushm always */ ++ pushm/popm always. */ + if (use_pushm) + { + if ((save_reg_mask & (1 << 0)) @@ -2346,12 +2551,14 @@ + } + + -+ /* Check LR */ -+ if ((df_regs_ever_live_p (LR_REGNUM) -+ || !current_function_is_leaf -+ || (optimize_size -+ && save_reg_mask -+ && !current_function_calls_eh_return) || frame_pointer_needed)) ++ /* Check LR */ ++ if ((df_regs_ever_live_p (LR_REGNUM) ++ || !current_function_is_leaf ++ || (optimize_size ++ && save_reg_mask ++ && !current_function_calls_eh_return) ++ || frame_pointer_needed) ++ && !IS_FLASHVAULT (func_type)) + { + if (push + /* Never pop LR into PC for functions which @@ -2389,7 +2596,8 @@ + return save_reg_mask; +} + -+/*Compute total size in bytes of all saved registers */ ++ ++/* Compute total size in bytes of all saved registers. */ +static int +avr32_get_reg_mask_size (int reg_mask) +{ @@ -2403,9 +2611,9 @@ + return size; +} + -+/*Get a register from one of the registers which are saved onto the stack -+ upon function entry */ + ++/* Get a register from one of the registers which are saved onto the stack ++ upon function entry. */ +static int +avr32_get_saved_reg (int save_reg_mask) +{ @@ -2419,15 +2627,15 @@ + return -1; +} + -+/* Return 1 if it is possible to return using a single instruction. */ ++ ++/* Return 1 if it is possible to return using a single instruction. */ +int +avr32_use_return_insn (int iscond) +{ + unsigned int func_type = avr32_current_func_type (); + unsigned long saved_int_regs; -+ unsigned long saved_fp_regs; + -+ /* Never use a return instruction before reload has run. */ ++ /* Never use a return instruction before reload has run. */ + if (!reload_completed) + return 0; + @@ -2440,12 +2648,6 @@ + return 0; + + saved_int_regs = avr32_compute_save_reg_mask (TRUE); -+ saved_fp_regs = avr32_compute_save_fp_reg_mask (); -+ -+ /* Functions which have saved fp-regs on the stack can not be performed in -+ one instruction */ -+ if (saved_fp_regs) -+ return 0; + + /* Conditional returns can not be performed in one instruction if we need + to restore registers from the stack */ @@ -2471,44 +2673,76 @@ +} + + -+/*Generate some function prologue info in the assembly file*/ -+ ++/* Generate some function prologue info in the assembly file. */ +void +avr32_target_asm_function_prologue (FILE * f, HOST_WIDE_INT frame_size) +{ -+ if (IS_NAKED (avr32_current_func_type ())) ++ unsigned long func_type = avr32_current_func_type (); ++ ++ if (IS_NAKED (func_type)) + fprintf (f, -+ "\t# Function is naked: Prologue and epilogue provided by programmer\n"); ++ "\t# Function is naked: Prologue and epilogue provided by programmer\n"); ++ ++ if (IS_FLASHVAULT (func_type)) ++ { ++ fprintf(f, ++ "\t.ident \"flashvault\"\n\t# Function is defined with flashvault attribute.\n"); ++ } ++ ++ if (IS_FLASHVAULT_IMPL (func_type)) ++ { ++ fprintf(f, ++ "\t.ident \"flashvault\"\n\t# Function is defined with flashvault_impl attribute.\n"); ++ ++ /* Save information on flashvault function declaration. */ ++ tree fv_attribute = lookup_attribute ("flashvault_impl", DECL_ATTRIBUTES(current_function_decl)); ++ if (fv_attribute != NULL_TREE) ++ { ++ tree vector_tree = TREE_VALUE(fv_attribute); ++ if (vector_tree != NULL_TREE) ++ { ++ unsigned int vector_num; ++ const char * name; ++ ++ vector_num = (unsigned int) TREE_INT_CST_LOW (TREE_VALUE (vector_tree)); ++ ++ name = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); ++ ++ flashvault_decl_list_add (vector_num, name); ++ } ++ } ++ } + -+ if (IS_INTERRUPT (avr32_current_func_type ())) ++ if (IS_INTERRUPT (func_type)) + { -+ switch (avr32_current_func_type ()) -+ { -+ case AVR32_FT_ISR_FULL: -+ fprintf (f, -+ "\t# Interrupt Function: Fully shadowed register file\n"); -+ break; -+ case AVR32_FT_ISR_HALF: -+ fprintf (f, -+ "\t# Interrupt Function: Half shadowed register file\n"); -+ break; -+ default: -+ case AVR32_FT_ISR_NONE: -+ fprintf (f, "\t# Interrupt Function: No shadowed register file\n"); -+ break; -+ } ++ switch (func_type) ++ { ++ case AVR32_FT_ISR_FULL: ++ fprintf (f, ++ "\t# Interrupt Function: Fully shadowed register file\n"); ++ break; ++ case AVR32_FT_ISR_HALF: ++ fprintf (f, ++ "\t# Interrupt Function: Half shadowed register file\n"); ++ break; ++ default: ++ case AVR32_FT_ISR_NONE: ++ fprintf (f, "\t# Interrupt Function: No shadowed register file\n"); ++ break; ++ } + } + + + fprintf (f, "\t# args = %i, frame = %li, pretend = %i\n", -+ current_function_args_size, frame_size, -+ current_function_pretend_args_size); ++ current_function_args_size, frame_size, ++ current_function_pretend_args_size); + + fprintf (f, "\t# frame_needed = %i, leaf_function = %i\n", -+ frame_pointer_needed, current_function_is_leaf); ++ frame_pointer_needed, current_function_is_leaf); + + fprintf (f, "\t# uses_anonymous_args = %i\n", -+ current_function_args_info.uses_anonymous_args); ++ current_function_args_info.uses_anonymous_args); ++ + if (current_function_calls_eh_return) + fprintf (f, "\t# Calls __builtin_eh_return.\n"); + @@ -2574,51 +2808,6 @@ + return insn; +} + -+ -+static rtx -+emit_multi_fp_reg_push (int reglist) -+{ -+ rtx insn; -+ rtx dwarf; -+ rtx tmp; -+ rtx reg; -+ int i; -+ int nr_regs; -+ int index = 0; -+ -+ insn = emit_insn (gen_stm_fp (stack_pointer_rtx, -+ gen_rtx_CONST_INT (SImode, reglist), -+ gen_rtx_CONST_INT (SImode, 1))); -+ -+ nr_regs = avr32_get_reg_mask_size (reglist) / 4; -+ dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (nr_regs + 1)); -+ -+ for (i = 15; i >= 0; i--) -+ { -+ if (reglist & (1 << i)) -+ { -+ reg = gen_rtx_REG (SImode, INTERNAL_FP_REGNUM (i)); -+ tmp = gen_rtx_SET (VOIDmode, -+ gen_rtx_MEM (SImode, -+ plus_constant (stack_pointer_rtx, -+ 4 * index)), reg); -+ RTX_FRAME_RELATED_P (tmp) = 1; -+ XVECEXP (dwarf, 0, 1 + index++) = tmp; -+ } -+ } -+ -+ tmp = gen_rtx_SET (SImode, -+ stack_pointer_rtx, -+ gen_rtx_PLUS (SImode, -+ stack_pointer_rtx, -+ GEN_INT (-4 * nr_regs))); -+ RTX_FRAME_RELATED_P (tmp) = 1; -+ XVECEXP (dwarf, 0, 0) = tmp; -+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf, -+ REG_NOTES (insn)); -+ return insn; -+} -+ +rtx +avr32_gen_load_multiple (rtx * regs, int count, rtx from, + int write_back, int in_struct_p, int scalar_p) @@ -2681,7 +2870,6 @@ + +/* Move a block of memory if it is word aligned or we support unaligned + word memory accesses. The size must be maximum 64 bytes. */ -+ +int +avr32_gen_movmemsi (rtx * operands) +{ @@ -2773,16 +2961,15 @@ +} + + -+ -+/*Expand the prologue instruction*/ ++/* Expand the prologue instruction. */ +void +avr32_expand_prologue (void) +{ + rtx insn, dwarf; -+ unsigned long saved_reg_mask, saved_fp_reg_mask; ++ unsigned long saved_reg_mask; + int reglist8 = 0; + -+ /* Naked functions does not have a prologue */ ++ /* Naked functions do not have a prologue. */ + if (IS_NAKED (avr32_current_func_type ())) + return; + @@ -2790,7 +2977,7 @@ + + if (saved_reg_mask) + { -+ /* Must push used registers */ ++ /* Must push used registers. */ + + /* Should we use POPM or LDM? */ + int usePUSHM = TRUE; @@ -2799,12 +2986,12 @@ + (saved_reg_mask & (1 << 1)) || + (saved_reg_mask & (1 << 2)) || (saved_reg_mask & (1 << 3)))) + { -+ /* One of R0-R3 should at least be pushed */ ++ /* One of R0-R3 should at least be pushed. */ + if (((saved_reg_mask & (1 << 0)) && + (saved_reg_mask & (1 << 1)) && + (saved_reg_mask & (1 << 2)) && (saved_reg_mask & (1 << 3)))) + { -+ /* All should be pushed */ ++ /* All should be pushed. */ + reglist8 |= 0x01; + } + else @@ -2834,11 +3021,11 @@ + + if (((saved_reg_mask & (1 << 8)) || (saved_reg_mask & (1 << 9)))) + { -+ /* One of R8-R9 should at least be pushed */ ++ /* One of R8-R9 should at least be pushed. */ + if (((saved_reg_mask & (1 << 8)) && (saved_reg_mask & (1 << 9)))) + { + if (usePUSHM) -+ /* All should be pushed */ ++ /* All should be pushed. */ + reglist8 |= 0x04; + } + else @@ -2856,7 +3043,8 @@ + if (saved_reg_mask & (1 << 12)) + reglist8 |= 0x20; + -+ if (saved_reg_mask & (1 << ASM_REGNUM (LR_REGNUM))) ++ if ((saved_reg_mask & (1 << ASM_REGNUM (LR_REGNUM))) ++ && !IS_FLASHVAULT (avr32_current_func_type ())) + { + /* Push LR */ + reglist8 |= 0x40; @@ -2877,17 +3065,6 @@ + emit_insn (gen_blockage ()); + } + -+ saved_fp_reg_mask = avr32_compute_save_fp_reg_mask (); -+ if (saved_fp_reg_mask) -+ { -+ insn = emit_multi_fp_reg_push (saved_fp_reg_mask); -+ RTX_FRAME_RELATED_P (insn) = 1; -+ -+ /* Prevent this instruction from being scheduled after any other -+ instructions. */ -+ emit_insn (gen_blockage ()); -+ } -+ + /* Set frame pointer */ + if (frame_pointer_needed) + { @@ -2987,6 +3164,7 @@ + return; +} + ++ +void +avr32_set_return_address (rtx source, rtx scratch) +{ @@ -3016,10 +3194,8 @@ +} + + -+ +/* Return the length of INSN. LENGTH is the initial length computed by + attributes in the machine-description file. */ -+ +int +avr32_adjust_insn_length (rtx insn ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) @@ -3027,13 +3203,14 @@ + return length; +} + ++ +void +avr32_output_return_instruction (int single_ret_inst ATTRIBUTE_UNUSED, + int iscond ATTRIBUTE_UNUSED, + rtx cond ATTRIBUTE_UNUSED, rtx r12_imm) +{ + -+ unsigned long saved_reg_mask, saved_fp_reg_mask; ++ unsigned long saved_reg_mask; + int insert_ret = TRUE; + int reglist8 = 0; + int stack_adjustment = get_frame_size (); @@ -3044,8 +3221,6 @@ + if (IS_NAKED (func_type)) + return; + -+ saved_fp_reg_mask = avr32_compute_save_fp_reg_mask (); -+ + saved_reg_mask = avr32_compute_save_reg_mask (FALSE); + + /* Reset frame pointer */ @@ -3067,19 +3242,6 @@ + } + } + -+ if (saved_fp_reg_mask) -+ { -+ char reglist[64]; /* 64 bytes should be enough... */ -+ avr32_make_fp_reglist_w (saved_fp_reg_mask, (char *) reglist); -+ fprintf (f, "\tldcm.w\tcp0, sp++, %s\n", reglist); -+ if (saved_fp_reg_mask & ~0xff) -+ { -+ saved_fp_reg_mask &= ~0xff; -+ avr32_make_fp_reglist_d (saved_fp_reg_mask, (char *) reglist); -+ fprintf (f, "\tldcm.d\tcp0, sp++, %s\n", reglist); -+ } -+ } -+ + if (saved_reg_mask) + { + /* Must pop used registers */ @@ -3151,7 +3313,8 @@ + /* Pop LR */ + reglist8 |= 0x40; + -+ if (saved_reg_mask & (1 << ASM_REGNUM (PC_REGNUM))) ++ if ((saved_reg_mask & (1 << ASM_REGNUM (PC_REGNUM))) ++ && !IS_FLASHVAULT_IMPL (func_type)) + /* Pop LR into PC. */ + reglist8 |= 0x80; + @@ -3197,7 +3360,20 @@ + { + fprintf (f, "\trete\n"); + } -+ else if (insert_ret) ++ else if (IS_FLASHVAULT (func_type)) ++ { ++ /* Normal return from Secure System call, increment SS_RAR before ++ returning. Use R8 as scratch. */ ++ fprintf (f, ++ "\t# Normal return from sscall.\n" ++ "\t# Increment SS_RAR before returning.\n" ++ "\t# Use R8 as scratch.\n" ++ "\tmfsr\tr8, 440\n" ++ "\tsub\tr8, -2\n" ++ "\tmtsr\t440, r8\n" ++ "\tretss\n"); ++ } ++ else if (insert_ret) + { + if (r12_imm) + fprintf (f, "\tretal\t%li\n", INTVAL (r12_imm)); @@ -3206,69 +3382,20 @@ + } +} + -+/* Function for converting a fp-register mask to a -+ reglistCPD8 register list string. */ -+void -+avr32_make_fp_reglist_d (int reglist_mask, char *reglist_string) -+{ -+ int i; -+ -+ /* Make sure reglist_string is empty */ -+ reglist_string[0] = '\0'; -+ -+ for (i = 0; i < NUM_FP_REGS; i += 2) -+ { -+ if (reglist_mask & (1 << i)) -+ { -+ strlen (reglist_string) ? -+ sprintf (reglist_string, "%s, %s-%s", reglist_string, -+ reg_names[INTERNAL_FP_REGNUM (i)], -+ reg_names[INTERNAL_FP_REGNUM (i + 1)]) : -+ sprintf (reglist_string, "%s-%s", -+ reg_names[INTERNAL_FP_REGNUM (i)], -+ reg_names[INTERNAL_FP_REGNUM (i + 1)]); -+ } -+ } -+} -+ -+/* Function for converting a fp-register mask to a -+ reglistCP8 register list string. */ -+void -+avr32_make_fp_reglist_w (int reglist_mask, char *reglist_string) -+{ -+ int i; -+ -+ /* Make sure reglist_string is empty */ -+ reglist_string[0] = '\0'; -+ -+ for (i = 0; i < NUM_FP_REGS; ++i) -+ { -+ if (reglist_mask & (1 << i)) -+ { -+ strlen (reglist_string) ? -+ sprintf (reglist_string, "%s, %s", reglist_string, -+ reg_names[INTERNAL_FP_REGNUM (i)]) : -+ sprintf (reglist_string, "%s", reg_names[INTERNAL_FP_REGNUM (i)]); -+ } -+ } -+} -+ +void +avr32_make_reglist16 (int reglist16_vect, char *reglist16_string) +{ + int i; -+ -+ /* Make sure reglist16_string is empty */ ++ bool first_reg = true; ++ /* Make sure reglist16_string is empty. */ + reglist16_string[0] = '\0'; + + for (i = 0; i < 16; ++i) + { + if (reglist16_vect & (1 << i)) + { -+ strlen (reglist16_string) ? -+ sprintf (reglist16_string, "%s, %s", reglist16_string, -+ reg_names[INTERNAL_REGNUM (i)]) : -+ sprintf (reglist16_string, "%s", reg_names[INTERNAL_REGNUM (i)]); ++ first_reg == true ? first_reg = false : strcat(reglist16_string,", "); ++ strcat (reglist16_string, reg_names[INTERNAL_REGNUM (i)]); + } + } +} @@ -3300,41 +3427,35 @@ +void +avr32_make_reglist8 (int reglist8_vect, char *reglist8_string) +{ -+ /* Make sure reglist8_string is empty */ ++ /* Make sure reglist8_string is empty. */ + reglist8_string[0] = '\0'; + + if (reglist8_vect & 0x1) -+ sprintf (reglist8_string, "r0-r3"); ++ strcpy (reglist8_string, "r0-r3"); + if (reglist8_vect & 0x2) -+ strlen (reglist8_string) ? sprintf (reglist8_string, "%s, r4-r7", -+ reglist8_string) : -+ sprintf (reglist8_string, "r4-r7"); ++ strlen (reglist8_string) ? strcat (reglist8_string, ", r4-r7") : ++ strcpy (reglist8_string, "r4-r7"); + if (reglist8_vect & 0x4) -+ strlen (reglist8_string) ? sprintf (reglist8_string, "%s, r8-r9", -+ reglist8_string) : -+ sprintf (reglist8_string, "r8-r9"); ++ strlen (reglist8_string) ? strcat (reglist8_string, ", r8-r9") : ++ strcpy (reglist8_string, "r8-r9"); + if (reglist8_vect & 0x8) -+ strlen (reglist8_string) ? sprintf (reglist8_string, "%s, r10", -+ reglist8_string) : -+ sprintf (reglist8_string, "r10"); ++ strlen (reglist8_string) ? strcat (reglist8_string, ", r10") : ++ strcpy (reglist8_string, "r10"); + if (reglist8_vect & 0x10) -+ strlen (reglist8_string) ? sprintf (reglist8_string, "%s, r11", -+ reglist8_string) : -+ sprintf (reglist8_string, "r11"); ++ strlen (reglist8_string) ? strcat (reglist8_string, ", r11") : ++ strcpy (reglist8_string, "r11"); + if (reglist8_vect & 0x20) -+ strlen (reglist8_string) ? sprintf (reglist8_string, "%s, r12", -+ reglist8_string) : -+ sprintf (reglist8_string, "r12"); ++ strlen (reglist8_string) ? strcat (reglist8_string, ", r12") : ++ strcpy (reglist8_string, "r12"); + if (reglist8_vect & 0x40) -+ strlen (reglist8_string) ? sprintf (reglist8_string, "%s, lr", -+ reglist8_string) : -+ sprintf (reglist8_string, "lr"); ++ strlen (reglist8_string) ? strcat (reglist8_string, ", lr") : ++ strcpy (reglist8_string, "lr"); + if (reglist8_vect & 0x80) -+ strlen (reglist8_string) ? sprintf (reglist8_string, "%s, pc", -+ reglist8_string) : -+ sprintf (reglist8_string, "pc"); ++ strlen (reglist8_string) ? strcat (reglist8_string, ", pc") : ++ strcpy (reglist8_string, "pc"); +} + ++ +int +avr32_eh_return_data_regno (int n) +{ @@ -3344,6 +3465,7 @@ + return INVALID_REGNUM; +} + ++ +/* Compute the distance from register FROM to register TO. + These can be the arg pointer, the frame pointer or + the stack pointer. @@ -3382,18 +3504,15 @@ + The sign of the number returned reflects the direction of stack + growth, so the values are positive for all eliminations except + from the soft frame pointer to the hard frame pointer. */ -+ -+ +int +avr32_initial_elimination_offset (int from, int to) +{ + int i; + int call_saved_regs = 0; -+ unsigned long saved_reg_mask, saved_fp_reg_mask; ++ unsigned long saved_reg_mask; + unsigned int local_vars = get_frame_size (); + + saved_reg_mask = avr32_compute_save_reg_mask (TRUE); -+ saved_fp_reg_mask = avr32_compute_save_fp_reg_mask (); + + for (i = 0; i < 16; ++i) + { @@ -3401,12 +3520,6 @@ + call_saved_regs += 4; + } + -+ for (i = 0; i < NUM_FP_REGS; ++i) -+ { -+ if (saved_fp_reg_mask & (1 << i)) -+ call_saved_regs += 4; -+ } -+ + switch (from) + { + case ARG_POINTER_REGNUM: @@ -3435,7 +3548,7 @@ + +/* + Returns a rtx used when passing the next argument to a function. -+ avr32_init_cumulative_args() and avr32_function_arg_advance() sets witch ++ avr32_init_cumulative_args() and avr32_function_arg_advance() sets which + register to use. +*/ +rtx @@ -3443,6 +3556,9 @@ + tree type, int named) +{ + int index = -1; ++ //unsigned long func_type = avr32_current_func_type (); ++ //int last_reg_index = (IS_FLASHVAULT(func_type) || IS_FLASHVAULT_IMPL(func_type) || cum->flashvault_func ? LAST_CUM_REG_INDEX - 1 : LAST_CUM_REG_INDEX); ++ int last_reg_index = (cum->flashvault_func ? LAST_CUM_REG_INDEX - 1 : LAST_CUM_REG_INDEX); + + HOST_WIDE_INT arg_size, arg_rsize; + if (type) @@ -3474,7 +3590,8 @@ + /* use r11:r10 or r9:r8. */ + if (!(GET_USED_INDEX (cum, 1) || GET_USED_INDEX (cum, 2))) + index = 1; -+ else if (!(GET_USED_INDEX (cum, 3) || GET_USED_INDEX (cum, 4))) ++ else if ((last_reg_index == 4) && ++ !(GET_USED_INDEX (cum, 3) || GET_USED_INDEX (cum, 4))) + index = 3; + else + index = -1; @@ -3482,39 +3599,40 @@ + else if (arg_rsize == 4) + { /* Use first available register */ + index = 0; -+ while (index <= LAST_CUM_REG_INDEX && GET_USED_INDEX (cum, index)) ++ while (index <= last_reg_index && GET_USED_INDEX (cum, index)) + index++; -+ if (index > LAST_CUM_REG_INDEX) ++ if (index > last_reg_index) + index = -1; + } + + SET_REG_INDEX (cum, index); + + if (GET_REG_INDEX (cum) >= 0) -+ return gen_rtx_REG (mode, -+ avr32_function_arg_reglist[GET_REG_INDEX (cum)]); ++ return gen_rtx_REG (mode, avr32_function_arg_reglist[GET_REG_INDEX (cum)]); + + return NULL_RTX; +} + -+/* -+ Set the register used for passing the first argument to a function. -+*/ ++ ++/* Set the register used for passing the first argument to a function. */ +void +avr32_init_cumulative_args (CUMULATIVE_ARGS * cum, + tree fntype ATTRIBUTE_UNUSED, + rtx libname ATTRIBUTE_UNUSED, -+ tree fndecl ATTRIBUTE_UNUSED) -+ { -+ /* Set all registers as unused. */ -+ SET_INDEXES_UNUSED (cum); ++ tree fndecl) ++{ ++ /* Set all registers as unused. */ ++ SET_INDEXES_UNUSED (cum); + -+ /* Reset uses_anonymous_args */ -+ cum->uses_anonymous_args = 0; ++ /* Reset uses_anonymous_args */ ++ cum->uses_anonymous_args = 0; ++ ++ /* Reset size of stack pushed arguments */ ++ cum->stack_pushed_args_size = 0; ++ ++ cum->flashvault_func = (fndecl && (has_attribute_p (fndecl,"flashvault") || has_attribute_p (fndecl,"flashvault_impl"))); ++} + -+ /* Reset size of stack pushed arguments */ -+ cum->stack_pushed_args_size = 0; -+ } + +/* + Set register used for passing the next argument to a function. Only the @@ -3555,7 +3673,7 @@ + } + arg_rsize = PUSH_ROUNDING (arg_size); + -+ /* It the argument had to be passed in stack, no register is used. */ ++ /* If the argument had to be passed in stack, no register is used. */ + if ((*targetm.calls.must_pass_in_stack) (mode, type)) + { + cum->stack_pushed_args_size += PUSH_ROUNDING (int_size_in_bytes (type)); @@ -3578,6 +3696,7 @@ + } +} + ++ +/* + Defines witch direction to go to find the next register to use if the + argument is larger then one register or for arguments shorter than an @@ -3602,9 +3721,8 @@ + return downward; +} + -+/* -+ Return a rtx used for the return value from a function call. -+*/ ++ ++/* Return a rtx used for the return value from a function call. */ +rtx +avr32_function_value (tree type, tree func, bool outgoing ATTRIBUTE_UNUSED) +{ @@ -3624,9 +3742,8 @@ + return NULL_RTX; +} + -+/* -+ Return a rtx used for the return value from a library function call. -+*/ ++ ++/* Return a rtx used for the return value from a library function call. */ +rtx +avr32_libcall_value (enum machine_mode mode) +{ @@ -3639,6 +3756,7 @@ + return NULL_RTX; +} + ++ +/* Return TRUE if X references a SYMBOL_REF. */ +int +symbol_mentioned_p (rtx x) @@ -3668,6 +3786,7 @@ + return 0; +} + ++ +/* Return TRUE if X references a LABEL_REF. */ +int +label_mentioned_p (rtx x) @@ -3696,6 +3815,7 @@ + return 0; +} + ++ +/* Return TRUE if X contains a MEM expression. */ +int +mem_mentioned_p (rtx x) @@ -3724,6 +3844,7 @@ + return 0; +} + ++ +int +avr32_legitimate_pic_operand_p (rtx x) +{ @@ -3824,6 +3945,7 @@ + return orig; +} + ++ +/* Generate code to load the PIC register. */ +void +avr32_load_pic_register (void) @@ -3854,7 +3976,6 @@ +} + + -+ +/* This hook should return true if values of type type are returned at the most + significant end of a register (in other words, if they are padded at the + least significant end). You can assume that type is returned in a register; @@ -3923,9 +4044,7 @@ +} + + -+/* -+ Initialize the variable parts of a trampoline. -+*/ ++/* Initialize the variable parts of a trampoline. */ +void +avr32_initialize_trampoline (rtx addr, rtx fnaddr, rtx static_chain) +{ @@ -3943,6 +4062,7 @@ + AVR32_CACHE_INVALIDATE_ICACHE))); +} + ++ +/* Return nonzero if X is valid as an addressing register. */ +int +avr32_address_register_rtx_p (rtx x, int strict_p) @@ -3965,6 +4085,7 @@ + return (regno <= LAST_REGNUM || regno >= FIRST_PSEUDO_REGISTER); +} + ++ +/* Return nonzero if INDEX is valid for an address index operand. */ +int +avr32_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p) @@ -3977,10 +4098,6 @@ + /* Standard coprocessor addressing modes. */ + if (code == CONST_INT) + { -+ if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT) -+ /* Coprocessor mem insns has a smaller reach than ordinary mem insns */ -+ return CONST_OK_FOR_CONSTRAINT_P (INTVAL (index), 'K', "Ku14"); -+ else + return CONST_OK_FOR_CONSTRAINT_P (INTVAL (index), 'K', "Ks16"); + } + @@ -4010,6 +4127,7 @@ + return 0; +} + ++ +/* + Used in the GO_IF_LEGITIMATE_ADDRESS macro. Returns a nonzero value if + the RTX x is a legitimate memory address. @@ -4018,7 +4136,8 @@ + if it is. +*/ + -+/* Forward declaration*/ ++ ++/* Forward declaration */ +int is_minipool_label (rtx label); + +int @@ -4029,6 +4148,9 @@ + { + case REG: + return avr32_address_register_rtx_p (x, strict); ++ case CONST_INT: ++ return ((mode==SImode) && TARGET_RMW_ADDRESSABLE_DATA ++ && CONST_OK_FOR_CONSTRAINT_P(INTVAL(x), 'K', "Ks17")); + case CONST: + { + rtx label = avr32_find_symbol (x); @@ -4045,7 +4167,10 @@ + ||*/ + ((GET_CODE (label) == LABEL_REF) + && GET_CODE (XEXP (label, 0)) == CODE_LABEL -+ && is_minipool_label (XEXP (label, 0))))) ++ && is_minipool_label (XEXP (label, 0))) ++ /*|| ((GET_CODE (label) == SYMBOL_REF) ++ && mode == SImode ++ && SYMBOL_REF_RMW_ADDR(label))*/)) + { + return TRUE; + } @@ -4065,12 +4190,9 @@ + && (symbol_mentioned_p (get_pool_constant (x)) + || label_mentioned_p (get_pool_constant (x))))) + return TRUE; -+ /* -+ A symbol_ref is only legal if it is a function. If all of them are -+ legal, a pseudo reg that is a constant will be replaced by a -+ symbol_ref and make illegale code. SYMBOL_REF_FLAG is set by -+ ENCODE_SECTION_INFO. */ -+ else if (SYMBOL_REF_RCALL_FUNCTION_P (x)) ++ else if (SYMBOL_REF_RCALL_FUNCTION_P (x) ++ || (mode == SImode ++ && SYMBOL_REF_RMW_ADDR (x))) + return TRUE; + break; + } @@ -4106,6 +4228,7 @@ + return avr32_const_ok_for_constraint_p (c, 'K', "Ks21"); +} + ++ +int +avr32_const_double_immediate (rtx value) +{ @@ -4164,9 +4287,8 @@ + else + return 0; + case LABEL_REF: -+ return flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS; + case SYMBOL_REF: -+ return flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS; ++ return avr32_find_symbol (x) && (flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS); + case CONST: + case HIGH: + case CONST_VECTOR: @@ -4221,6 +4343,7 @@ + return machine; +} + ++ +void +avr32_init_expanders (void) +{ @@ -4231,7 +4354,6 @@ + +/* Return an RTX indicating where the return address to the + calling function can be found. */ -+ +rtx +avr32_return_addr (int count, rtx frame ATTRIBUTE_UNUSED) +{ @@ -4245,20 +4367,29 @@ +void +avr32_encode_section_info (tree decl, rtx rtl, int first) +{ -+ -+ if (first && DECL_P (decl)) -+ { -+ /* Set SYMBOL_REG_FLAG for local functions */ -+ if (!TREE_PUBLIC (decl) && TREE_CODE (decl) == FUNCTION_DECL) -+ { -+ if ((*targetm.binds_local_p) (decl)) -+ { -+ SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1; -+ } -+ } ++ default_encode_section_info(decl, rtl, first); ++ ++ if ( TREE_CODE (decl) == VAR_DECL ++ && (GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF) ++ && (lookup_attribute ("rmw_addressable", DECL_ATTRIBUTES (decl)) ++ || TARGET_RMW_ADDRESSABLE_DATA) ){ ++ if ( !TARGET_RMW || flag_pic ) ++ return; ++ // { ++ // warning ("Using RMW addressable data with an arch that does not support RMW instructions."); ++ // return; ++ // } ++ // ++ //if ( flag_pic ) ++ // { ++ // warning ("Using RMW addressable data with together with -fpic switch. Can not use RMW instruction when compiling with -fpic."); ++ // return; ++ // } ++ SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= (1 << SYMBOL_FLAG_RMW_ADDR_SHIFT); + } +} + ++ +void +avr32_asm_output_label (FILE * stream, const char *name) +{ @@ -4270,7 +4401,6 @@ +} + + -+ +void +avr32_asm_weaken_label (FILE * stream, const char *name) +{ @@ -4279,6 +4409,7 @@ + fprintf (stream, "\n"); +} + ++ +/* + Checks if a labelref is equal to a reserved word in the assembler. If it is, + insert a '_' before the label name. @@ -4314,7 +4445,6 @@ +} + + -+ +/* + Check if the comparison in compare_exp is redundant + for the condition given in next_cond given that the @@ -4393,6 +4523,7 @@ + return NULL_RTX; +} + ++ +/* Updates cc_status. */ +void +avr32_notice_update_cc (rtx exp, rtx insn) @@ -4411,7 +4542,6 @@ + { + case CC_CALL_SET: + CC_STATUS_INIT; -+ FPCC_STATUS_INIT; + /* Check if the function call returns a value in r12 */ + if (REG_P (recog_data.operand[0]) + && REGNO (recog_data.operand[0]) == RETVAL_REGNUM) @@ -4536,26 +4666,6 @@ + + } + break; -+ case CC_FPCOMPARE: -+ /* Check that floating-point compare will not be optimized away if so -+ nothing should be done */ -+ if (!rtx_equal_p (cc_prev_status.mdep.fpvalue, SET_SRC (exp))) -+ { -+ /* cc0 already contains the correct comparison -> delete cmp insn */ -+ /* Reset the nonstandard flag */ -+ cc_status.mdep.fpvalue = SET_SRC (exp); -+ cc_status.mdep.fpflags = CC_SET_CZ; -+ } -+ break; -+ case CC_FROM_FPCC: -+ /* Flags are updated with flags from Floating-point coprocessor, set -+ CC_NOT_SIGNED flag since the flags are set so that unsigned -+ condidion codes can be used directly. */ -+ CC_STATUS_INIT; -+ cc_status.flags = CC_NOT_SIGNED; -+ cc_status.mdep.value = cc_status.mdep.fpvalue; -+ cc_status.mdep.flags = cc_status.mdep.fpflags; -+ break; + case CC_BLD: + /* Bit load is kind of like an inverted testsi, because the Z flag is + inverted */ @@ -4837,6 +4947,19 @@ + value = bitpos; + } + break; ++ case 'z': ++ { ++ /* Set to bit position of first bit cleared in immediate */ ++ int i, bitpos = 32; ++ for (i = 0; i < 32; i++) ++ if (!(value & (1 << i))) ++ { ++ bitpos = i; ++ break; ++ } ++ value = bitpos; ++ } ++ break; + case 'r': + { + /* Reglist 8 */ @@ -4844,26 +4967,21 @@ + op[0] = '\0'; + + if (value & 0x01) -+ sprintf (op, "r0-r3"); ++ strcpy (op, "r0-r3"); + if (value & 0x02) -+ strlen (op) ? sprintf (op, "%s, r4-r7", op) : sprintf (op, -+ "r4-r7"); ++ strlen (op) ? strcat (op, ", r4-r7") : strcpy (op,"r4-r7"); + if (value & 0x04) -+ strlen (op) ? sprintf (op, "%s, r8-r9", op) : sprintf (op, -+ "r8-r9"); ++ strlen (op) ? strcat (op, ", r8-r9") : strcpy (op,"r8-r9"); + if (value & 0x08) -+ strlen (op) ? sprintf (op, "%s, r10", op) : sprintf (op, -+ "r10"); ++ strlen (op) ? strcat (op, ", r10") : strcpy (op,"r10"); + if (value & 0x10) -+ strlen (op) ? sprintf (op, "%s, r11", op) : sprintf (op, -+ "r11"); ++ strlen (op) ? strcat (op, ", r11") : strcpy (op,"r11"); + if (value & 0x20) -+ strlen (op) ? sprintf (op, "%s, r12", op) : sprintf (op, -+ "r12"); ++ strlen (op) ? strcat (op, ", r12") : strcpy (op,"r12"); + if (value & 0x40) -+ strlen (op) ? sprintf (op, "%s, lr", op) : sprintf (op, "lr"); ++ strlen (op) ? strcat (op, ", lr") : strcpy (op, "lr"); + if (value & 0x80) -+ strlen (op) ? sprintf (op, "%s, pc", op) : sprintf (op, "pc"); ++ strlen (op) ? strcat (op, ", pc") : strcpy (op, "pc"); + + fputs (op, stream); + return; @@ -4873,41 +4991,20 @@ + /* Reglist 16 */ + char reglist16_string[100]; + int i; ++ bool first_reg = true; + reglist16_string[0] = '\0'; + + for (i = 0; i < 16; ++i) + { + if (value & (1 << i)) + { -+ strlen (reglist16_string) ? sprintf (reglist16_string, -+ "%s, %s", -+ reglist16_string, -+ reg_names -+ [INTERNAL_REGNUM -+ (i)]) : -+ sprintf (reglist16_string, "%s", -+ reg_names[INTERNAL_REGNUM (i)]); ++ first_reg == true ? first_reg = false : strcat(reglist16_string,", "); ++ strcat(reglist16_string,reg_names[INTERNAL_REGNUM(i)]); + } + } + fputs (reglist16_string, stream); + return; + } -+ case 'C': -+ { -+ /* RegListCP8 */ -+ char reglist_string[100]; -+ avr32_make_fp_reglist_w (value, (char *) reglist_string); -+ fputs (reglist_string, stream); -+ return; -+ } -+ case 'D': -+ { -+ /* RegListCPD8 */ -+ char reglist_string[100]; -+ avr32_make_fp_reglist_d (value, (char *) reglist_string); -+ fputs (reglist_string, stream); -+ return; -+ } + case 'h': + /* Print halfword part of word */ + fputs (value ? "b" : "t", stream); @@ -5066,6 +5163,9 @@ + fprintf (stream, " + %ld", + INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))); + break; ++ case CONST_INT: ++ avr32_print_operand (stream, XEXP (x, 0), 0); ++ break; + default: + error = 1; + } @@ -5205,6 +5305,7 @@ + return NULL_RTX; +} + ++ +/* + Outputs to stdio stream stream the assembler syntax for an instruction + operand that is a memory reference whose address is x. x is an RTL @@ -5218,6 +5319,7 @@ + fprintf (stream, "(%d) /* address */", REGNO (x)); +} + ++ +/* Return true if _GLOBAL_OFFSET_TABLE_ symbol is mentioned. */ +bool +avr32_got_mentioned_p (rtx addr) @@ -5243,7 +5345,6 @@ + + +/* Find the symbol in an address expression. */ -+ +rtx +avr32_find_symbol (rtx addr) +{ @@ -5363,6 +5464,7 @@ + int fix_size; +}; + ++ +struct minipool_fixup +{ + Mfix *next; @@ -5396,6 +5498,7 @@ +/* The fix entry for the current minipool, once it has been placed. */ +Mfix *minipool_barrier; + ++ +/* Determines if INSN is the start of a jump table. Returns the end + of the TABLE or NULL_RTX. */ +static rtx @@ -5416,6 +5519,7 @@ + return NULL_RTX; +} + ++ +static HOST_WIDE_INT +get_jump_table_size (rtx insn) +{ @@ -5435,6 +5539,7 @@ + return 0; +} + ++ +/* Move a minipool fix MP from its current location to before MAX_MP. + If MAX_MP is NULL, then MP doesn't need moving, but the addressing + constraints may need updating. */ @@ -5493,6 +5598,7 @@ + return max_mp; +} + ++ +/* Add a constant to the minipool for a forward reference. Returns the + node added or NULL if the constant will not fit in this pool. */ +static Mnode * @@ -5595,6 +5701,7 @@ + return max_mp; +} + ++ +static Mnode * +move_minipool_fix_backward_ref (Mnode * mp, Mnode * min_mp, + HOST_WIDE_INT min_address) @@ -5650,6 +5757,7 @@ + return min_mp; +} + ++ +/* Add a constant to the minipool for a backward reference. Returns the + node added or NULL if the constant will not fit in this pool. + @@ -5780,6 +5888,7 @@ + return min_mp; +} + ++ +static void +assign_minipool_offsets (Mfix * barrier) +{ @@ -5797,6 +5906,7 @@ + } +} + ++ +/* Print a symbolic form of X to the debug file, F. */ +static void +avr32_print_value (FILE * f, rtx x) @@ -5858,6 +5968,7 @@ + } +} + ++ +int +is_minipool_label (rtx label) +{ @@ -5876,6 +5987,7 @@ + return FALSE; +} + ++ +static void +new_minipool_label (rtx label) +{ @@ -5901,6 +6013,7 @@ + } +} + ++ +/* Output the literal table */ +static void +dump_minipool (rtx scan) @@ -5971,6 +6084,7 @@ + scan = emit_barrier_after (scan); +} + ++ +/* Return the cost of forcibly inserting a barrier after INSN. */ +static int +avr32_barrier_cost (rtx insn) @@ -6003,6 +6117,7 @@ + } +} + ++ +/* Find the best place in the insn stream in the range + (FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier. + Create the barrier by inserting a jump and add a new fix entry for @@ -6087,6 +6202,7 @@ + return new_fix; +} + ++ +/* Record that there is a natural barrier in the insn stream at + ADDRESS. */ +static void @@ -6106,6 +6222,7 @@ + minipool_fix_tail = fix; +} + ++ +/* Record INSN, which will need fixing up to load a value from the + minipool. ADDRESS is the offset of the insn since the start of the + function; LOC is a pointer to the part of the insn which requires @@ -6134,16 +6251,6 @@ + else if (GET_CODE (body) == SET + && GET_MODE_SIZE (GET_MODE (SET_DEST (body))) == 4) + { -+ /* Word Load */ -+ if (TARGET_HARD_FLOAT -+ && GET_MODE_CLASS (GET_MODE (SET_DEST (body))) == MODE_FLOAT) -+ { -+ /* Ldc0.w : Ku12 << 2 */ -+ fix->forwards = ((1 << 12) - 1) << 2; -+ fix->backwards = 0; -+ } -+ else -+ { + if (optimize_size) + { + /* Lddpc : Ku7 << 2 */ @@ -6157,25 +6264,13 @@ + fix->backwards = (1 << 15); + } + } -+ } + else if (GET_CODE (body) == SET + && GET_MODE_SIZE (GET_MODE (SET_DEST (body))) == 8) + { -+ /* Double word load */ -+ if (TARGET_HARD_FLOAT -+ && GET_MODE_CLASS (GET_MODE (SET_DEST (body))) == MODE_FLOAT) -+ { -+ /* Ldc0.d : Ku12 << 2 */ -+ fix->forwards = ((1 << 12) - 1) << 2; -+ fix->backwards = 0; -+ } -+ else -+ { + /* Ld.d : Ks16 */ + fix->forwards = ((1 << 15) - 4); + fix->backwards = (1 << 15); + } -+ } + else if (GET_CODE (body) == UNSPEC_VOLATILE + && XINT (body, 1) == VUNSPEC_MVRC) + { @@ -6221,6 +6316,7 @@ + minipool_fix_tail = fix; +} + ++ +/* Scan INSN and note any of its operands that need fixing. + If DO_PUSHES is false we do not actually push any of the fixups + needed. The function returns TRUE is any fixups were needed/pushed. @@ -6317,9 +6413,8 @@ + return false; +} + -+/* -+ Replace all occurances of reg FROM with reg TO in X */ + ++/* Replace all occurances of reg FROM with reg TO in X. */ +rtx +avr32_replace_reg (rtx x, rtx from, rtx to) +{ @@ -6526,12 +6621,23 @@ + continue; + + set = single_set (scan); -+ if (set && rtx_equal_p (src_reg, SET_DEST (set))) -+ { -+ link = scan; -+ break; -+ } -+ ++ // Fix for bug #11763 : the following if condition ++ // has been modified and else part is included to ++ // set the link to NULL_RTX. ++ // if (set && rtx_equal_p (src_reg, SET_DEST (set))) ++ if (set && (REGNO(src_reg) == REGNO(SET_DEST(set)))) ++ { ++ if (rtx_equal_p (src_reg, SET_DEST (set))) ++ { ++ link = scan; ++ break; ++ } ++ else ++ { ++ link = NULL_RTX; ++ break; ++ } ++ } + } + + @@ -6842,11 +6948,11 @@ + +} + ++ +/* Exported to toplev.c. + + Do a final pass over the function, just before delayed branch + scheduling. */ -+ +static void +avr32_reorg (void) +{ @@ -6999,8 +7105,7 @@ +} + + -+/* -+ Hook for doing some final scanning of instructions. Does nothing yet...*/ ++/* Hook for doing some final scanning of instructions. Does nothing yet...*/ +void +avr32_final_prescan_insn (rtx insn ATTRIBUTE_UNUSED, + rtx * opvec ATTRIBUTE_UNUSED, @@ -7061,8 +7166,8 @@ + return FALSE; +} + -+/* Function for obtaining the condition for the next instruction -+ after cur_insn. ++ ++/* Function for obtaining the condition for the next instruction after cur_insn. +*/ +rtx +get_next_insn_cond (rtx cur_insn) @@ -7170,6 +7275,7 @@ + return cond; +} + ++ +int +avr32_load_multiple_operation (rtx op, + enum machine_mode mode ATTRIBUTE_UNUSED) @@ -7221,6 +7327,7 @@ + return 1; +} + ++ +int +avr32_store_multiple_operation (rtx op, + enum machine_mode mode ATTRIBUTE_UNUSED) @@ -7258,6 +7365,7 @@ + return 1; +} + ++ +int +avr32_valid_macmac_bypass (rtx insn_out, rtx insn_in) +{ @@ -7271,6 +7379,7 @@ + return FALSE; +} + ++ +int +avr32_valid_mulmac_bypass (rtx insn_out, rtx insn_in) +{ @@ -7285,6 +7394,7 @@ + return FALSE; +} + ++ +int +avr32_store_bypass (rtx insn_out, rtx insn_in) +{ @@ -7299,6 +7409,7 @@ + return FALSE; +} + ++ +int +avr32_mul_waw_bypass (rtx insn_out, rtx insn_in) +{ @@ -7313,6 +7424,7 @@ + return FALSE; +} + ++ +int +avr32_valid_load_double_bypass (rtx insn_out, rtx insn_in) +{ @@ -7366,10 +7478,9 @@ +} + + -+ +rtx -+avr32_ifcvt_modify_test (ce_if_block_t *ce_info, -+ rtx test ){ ++avr32_ifcvt_modify_test (ce_if_block_t *ce_info, rtx test ) ++{ + rtx branch_insn; + rtx cmp_test; + rtx compare_op0; @@ -7401,12 +7512,10 @@ +} + + -+ +rtx -+avr32_ifcvt_modify_insn (ce_if_block_t *ce_info, -+ rtx pattern, -+ rtx insn, -+ int *num_true_changes){ ++avr32_ifcvt_modify_insn (ce_if_block_t *ce_info, rtx pattern, rtx insn, ++ int *num_true_changes) ++{ + rtx test = COND_EXEC_TEST(pattern); + rtx op = COND_EXEC_CODE(pattern); + rtx cmp_insn; @@ -7647,8 +7756,7 @@ + + +void -+avr32_ifcvt_modify_cancel ( ce_if_block_t *ce_info, -+ int *num_true_changes) ++avr32_ifcvt_modify_cancel ( ce_if_block_t *ce_info, int *num_true_changes) +{ + int n; + @@ -7692,13 +7800,13 @@ + } +} + ++ +/* Function returning TRUE if INSN with OPERANDS is a splittable + conditional immediate clobber insn. We assume that the insn is + already a conditional immediate clobber insns and do not check + for that. */ +int -+avr32_cond_imm_clobber_splittable (rtx insn, -+ rtx operands[]) ++avr32_cond_imm_clobber_splittable (rtx insn, rtx operands[]) +{ + if ( REGNO (operands[0]) == REGNO (operands[1]) ) + { @@ -7718,6 +7826,7 @@ + return TRUE; +} + ++ +/* Function for getting an integer value from a const_int or const_double + expression regardless of the HOST_WIDE_INT size. Each target cpu word + will be put into the val array where the LSW will be stored at the lowest @@ -7726,9 +7835,7 @@ + of the word size. +*/ +void -+avr32_get_intval (enum machine_mode mode, -+ rtx const_expr, -+ HOST_WIDE_INT *val) ++avr32_get_intval (enum machine_mode mode, rtx const_expr, HOST_WIDE_INT *val) +{ + int words_in_mode = GET_MODE_SIZE (mode)/UNITS_PER_WORD; + const int words_in_const_int = HOST_BITS_PER_WIDE_INT / BITS_PER_WORD; @@ -7761,11 +7868,10 @@ + } +} + ++ +void -+avr32_split_const_expr (enum machine_mode mode, -+ enum machine_mode new_mode, -+ rtx expr, -+ rtx *split_expr) ++avr32_split_const_expr (enum machine_mode mode, enum machine_mode new_mode, ++ rtx expr, rtx *split_expr) +{ + int i, word; + int words_in_intval = GET_MODE_SIZE (mode)/UNITS_PER_WORD; @@ -7795,7 +7901,6 @@ + + +/* Set up library functions to comply to AVR32 ABI */ -+ +static void +avr32_init_libfuncs (void) +{ @@ -7881,14 +7986,67 @@ + set_optab_libfunc (sdiv_optab, SFmode, "__avr32_f32_div"); + } +} ---- a/gcc/config/avr32/avr32-elf.h ++ ++ ++/* Record a flashvault declaration. */ ++static void ++flashvault_decl_list_add (unsigned int vector_num, const char *name) ++{ ++ struct flashvault_decl_list *p; ++ ++ p = (struct flashvault_decl_list *) ++ xmalloc (sizeof (struct flashvault_decl_list)); ++ p->next = flashvault_decl_list_head; ++ p->name = name; ++ p->vector_num = vector_num; ++ flashvault_decl_list_head = p; ++} ++ ++ ++static void ++avr32_file_end (void) ++{ ++ struct flashvault_decl_list *p; ++ unsigned int num_entries = 0; ++ ++ /* Check if a list of flashvault declarations exists. */ ++ if (flashvault_decl_list_head != NULL) ++ { ++ /* Calculate the number of entries in the table. */ ++ for (p = flashvault_decl_list_head; p != NULL; p = p->next) ++ { ++ num_entries++; ++ } ++ ++ /* Generate the beginning of the flashvault data table. */ ++ fputs ("\t.global __fv_table\n" ++ "\t.data\n" ++ "\t.align 2\n" ++ "\t.set .LFVTABLE, . + 0\n" ++ "\t.type __fv_table, @object\n", asm_out_file); ++ /* Each table entry is 8 bytes. */ ++ fprintf (asm_out_file, "\t.size __fv_table, %u\n", (num_entries * 8)); ++ ++ fputs("__fv_table:\n", asm_out_file); ++ ++ for (p = flashvault_decl_list_head; p != NULL; p = p->next) ++ { ++ /* Output table entry. */ ++ fprintf (asm_out_file, ++ "\t.align 2\n" ++ "\t.int %u\n", p->vector_num); ++ fprintf (asm_out_file, ++ "\t.align 2\n" ++ "\t.int %s\n", p->name); ++ } ++ } ++} +--- /dev/null +++ b/gcc/config/avr32/avr32-elf.h -@@ -0,0 +1,86 @@ +@@ -0,0 +1,91 @@ +/* + Elf specific definitions. -+ Copyright 2003-2006 Atmel Corporation. -+ -+ Written by Ronny Pedersen, Atmel Norway, ++ Copyright 2003,2004,2005,2006,2007,2008,2009 Atmel Corporation. + + This file is part of GCC. + @@ -7908,7 +8066,7 @@ + + +/***************************************************************************** -+ * Controlling the Compilator Driver, 'gcc' ++ * Controlling the Compiler Driver, 'gcc' + *****************************************************************************/ + +/* Run-time Target Specification. */ @@ -7923,8 +8081,13 @@ +If this macro is not defined, a default is provided that loads the +standard C startup file from the usual place. See gcc.c. +*/ ++#if 0 +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "crt0%O%s crti%O%s crtbegin%O%s" ++#endif ++#undef STARTFILE_SPEC ++#define STARTFILE_SPEC "%{mflashvault: crtfv.o%s} %{!mflashvault: crt0.o%s} \ ++ crti.o%s crtbegin.o%s" + +#undef LINK_SPEC +#define LINK_SPEC "%{muse-oscall:--defsym __do_not_use_oscall_coproc__=0} %{mrelax|O*:%{mno-relax|O0|O1: ;:--relax}} %{mpart=uc3a3revd:-mavr32elf_uc3a3256s;:%{mpart=*:-mavr32elf_%*}} %{mcpu=*:-mavr32elf_%*}" @@ -7942,43 +8105,42 @@ + + +/* Target CPU builtins. */ -+#define TARGET_CPU_CPP_BUILTINS() \ -+ do \ -+ { \ -+ builtin_define ("__avr32__"); \ -+ builtin_define ("__AVR32__"); \ -+ builtin_define ("__AVR32_ELF__"); \ -+ builtin_define (avr32_part->macro); \ -+ builtin_define (avr32_arch->macro); \ -+ if (avr32_arch->uarch_type == UARCH_TYPE_AVR32A) \ -+ builtin_define ("__AVR32_AVR32A__"); \ -+ else \ -+ builtin_define ("__AVR32_AVR32B__"); \ -+ if (TARGET_UNALIGNED_WORD) \ -+ builtin_define ("__AVR32_HAS_UNALIGNED_WORD__"); \ -+ if (TARGET_SIMD) \ -+ builtin_define ("__AVR32_HAS_SIMD__"); \ -+ if (TARGET_DSP) \ -+ builtin_define ("__AVR32_HAS_DSP__"); \ -+ if (TARGET_RMW) \ -+ builtin_define ("__AVR32_HAS_RMW__"); \ -+ if (TARGET_BRANCH_PRED) \ -+ builtin_define ("__AVR32_HAS_BRANCH_PRED__"); \ ++#define TARGET_CPU_CPP_BUILTINS() \ ++ do \ ++ { \ ++ builtin_define ("__avr32__"); \ ++ builtin_define ("__AVR32__"); \ ++ builtin_define ("__AVR32_ELF__"); \ ++ builtin_define (avr32_part->macro); \ ++ builtin_define (avr32_arch->macro); \ ++ if (avr32_arch->uarch_type == UARCH_TYPE_AVR32A) \ ++ builtin_define ("__AVR32_AVR32A__"); \ ++ else \ ++ builtin_define ("__AVR32_AVR32B__"); \ ++ if (TARGET_UNALIGNED_WORD) \ ++ builtin_define ("__AVR32_HAS_UNALIGNED_WORD__"); \ ++ if (TARGET_SIMD) \ ++ builtin_define ("__AVR32_HAS_SIMD__"); \ ++ if (TARGET_DSP) \ ++ builtin_define ("__AVR32_HAS_DSP__"); \ ++ if (TARGET_RMW) \ ++ builtin_define ("__AVR32_HAS_RMW__"); \ ++ if (TARGET_BRANCH_PRED) \ ++ builtin_define ("__AVR32_HAS_BRANCH_PRED__"); \ + if (TARGET_FAST_FLOAT) \ + builtin_define ("__AVR32_FAST_FLOAT__"); \ ++ if (TARGET_FLASHVAULT) \ ++ builtin_define ("__AVR32_FLASHVAULT__"); \ + if (TARGET_NO_MUL_INSNS) \ + builtin_define ("__AVR32_NO_MUL__"); \ -+ } \ ++ } \ + while (0) ---- a/gcc/config/avr32/avr32.h +--- /dev/null +++ b/gcc/config/avr32/avr32.h -@@ -0,0 +1,3344 @@ +@@ -0,0 +1,3274 @@ +/* + Definitions of target machine for AVR32. -+ Copyright 2003-2006 Atmel Corporation. -+ -+ Written by Ronny Pedersen, Atmel Norway, -+ Initial porting by Anders �dland. ++ Copyright 2003,2004,2005,2006,2007,2008,2009,2010 Atmel Corporation. + + This file is part of GCC. + @@ -8022,44 +8184,48 @@ +/* cache instruction op5 codes */ +#define AVR32_CACHE_INVALIDATE_ICACHE 1 + -+/* These bits describe the different types of function supported -+ by the AVR32 backend. They are exclusive. ie a function cannot be both a -+ normal function and an interworked function, for example. Knowing the -+ type of a function is important for determining its prologue and -+ epilogue sequences. -+ Note value 7 is currently unassigned. Also note that the interrupt -+ function types all have bit 2 set, so that they can be tested for easily. -+ Note that 0 is deliberately chosen for AVR32_FT_UNKNOWN so that when the -+ machine_function structure is initialized (to zero) func_type will -+ default to unknown. This will force the first use of avr32_current_func_type -+ to call avr32_compute_func_type. */ -+#define AVR32_FT_UNKNOWN 0 /* Type has not yet been determined. -+ */ -+#define AVR32_FT_NORMAL 1 /* Your normal, straightforward -+ function. */ -+#define AVR32_FT_ACALL 2 /* An acall function. */ -+#define AVR32_FT_EXCEPTION_HANDLER 3 /* A C++ exception handler. */ -+#define AVR32_FT_ISR_FULL 4 /* A fully shadowed interrupt mode. */ -+#define AVR32_FT_ISR_HALF 5 /* A half shadowed interrupt mode. */ -+#define AVR32_FT_ISR_NONE 6 /* No shadow registers. */ ++/* ++These bits describe the different types of function supported by the AVR32 ++backend. They are exclusive, e.g. a function cannot be both a normal function ++and an interworked function. Knowing the type of a function is important for ++determining its prologue and epilogue sequences. Note value 7 is currently ++unassigned. Also note that the interrupt function types all have bit 2 set, ++so that they can be tested for easily. Note that 0 is deliberately chosen for ++AVR32_FT_UNKNOWN so that when the machine_function structure is initialized ++(to zero) func_type will default to unknown. This will force the first use of ++avr32_current_func_type to call avr32_compute_func_type. ++*/ ++#define AVR32_FT_UNKNOWN 0 /* Type has not yet been determined. */ ++#define AVR32_FT_NORMAL 1 /* Normal function. */ ++#define AVR32_FT_ACALL 2 /* An acall function. */ ++#define AVR32_FT_EXCEPTION_HANDLER 3 /* A C++ exception handler. */ ++#define AVR32_FT_ISR_FULL 4 /* A fully shadowed interrupt mode. */ ++#define AVR32_FT_ISR_HALF 5 /* A half shadowed interrupt mode. */ ++#define AVR32_FT_ISR_NONE 6 /* No shadow registers. */ + +#define AVR32_FT_TYPE_MASK ((1 << 3) - 1) + -+/* In addition functions can have several type modifiers, -+ outlined by these bit masks: */ -+#define AVR32_FT_INTERRUPT (1 << 2) /* Note overlap with FT_ISR -+ and above. */ -+#define AVR32_FT_NAKED (1 << 3) /* No prologue or epilogue. */ -+#define AVR32_FT_VOLATILE (1 << 4) /* Does not return. */ -+#define AVR32_FT_NESTED (1 << 5) /* Embedded inside another -+ func. */ ++/* In addition functions can have several type modifiers, outlined by these bit masks: */ ++#define AVR32_FT_INTERRUPT (1 << 2) /* Note overlap with FT_ISR and above. */ ++#define AVR32_FT_NAKED (1 << 3) /* No prologue or epilogue. */ ++#define AVR32_FT_VOLATILE (1 << 4) /* Does not return. */ ++#define AVR32_FT_NESTED (1 << 5) /* Embedded inside another func. */ ++#define AVR32_FT_FLASHVAULT (1 << 6) /* Flashvault function call. */ ++#define AVR32_FT_FLASHVAULT_IMPL (1 << 7) /* Function definition in FlashVault. */ ++ + +/* Some macros to test these flags. */ -+#define AVR32_FUNC_TYPE(t) (t & AVR32_FT_TYPE_MASK) -+#define IS_INTERRUPT(t) (t & AVR32_FT_INTERRUPT) -+#define IS_VOLATILE(t) (t & AVR32_FT_VOLATILE) -+#define IS_NAKED(t) (t & AVR32_FT_NAKED) -+#define IS_NESTED(t) (t & AVR32_FT_NESTED) ++#define AVR32_FUNC_TYPE(t) (t & AVR32_FT_TYPE_MASK) ++#define IS_INTERRUPT(t) (t & AVR32_FT_INTERRUPT) ++#define IS_NAKED(t) (t & AVR32_FT_NAKED) ++#define IS_VOLATILE(t) (t & AVR32_FT_VOLATILE) ++#define IS_NESTED(t) (t & AVR32_FT_NESTED) ++#define IS_FLASHVAULT(t) (t & AVR32_FT_FLASHVAULT) ++#define IS_FLASHVAULT_IMPL(t) (t & AVR32_FT_FLASHVAULT_IMPL) ++ ++#define SYMBOL_FLAG_RMW_ADDR_SHIFT SYMBOL_FLAG_MACH_DEP_SHIFT ++#define SYMBOL_REF_RMW_ADDR(RTX) \ ++ ((SYMBOL_REF_FLAGS (RTX) & (1 << SYMBOL_FLAG_RMW_ADDR_SHIFT)) != 0) + + +typedef struct minipool_labels @@ -8136,27 +8302,35 @@ + PART_TYPE_AVR32_UC3B0128, + PART_TYPE_AVR32_UC3B0256, + PART_TYPE_AVR32_UC3B0256ES, ++ PART_TYPE_AVR32_UC3B0512, + PART_TYPE_AVR32_UC3B0512REVC, + PART_TYPE_AVR32_UC3B164, + PART_TYPE_AVR32_UC3B1128, + PART_TYPE_AVR32_UC3B1256, + PART_TYPE_AVR32_UC3B1256ES, ++ PART_TYPE_AVR32_UC3B1512, + PART_TYPE_AVR32_UC3B1512REVC, -+ PART_TYPE_AVR32_UC3C0512C, -+ PART_TYPE_AVR32_UC3C0256C, -+ PART_TYPE_AVR32_UC3C0128C, ++ PART_TYPE_AVR32_UC3C0512CREVC, ++ PART_TYPE_AVR32_UC3C1512CREVC, ++ PART_TYPE_AVR32_UC3C2512CREVC, ++ PART_TYPE_AVR32_UC3L0256, ++ PART_TYPE_AVR32_UC3L0128, ++ PART_TYPE_AVR32_UC3L064, ++ PART_TYPE_AVR32_UC3L032, ++ PART_TYPE_AVR32_UC3L016, + PART_TYPE_AVR32_UC3C064C, -+ PART_TYPE_AVR32_UC3C1512C, -+ PART_TYPE_AVR32_UC3C1256C, -+ PART_TYPE_AVR32_UC3C1128C, ++ PART_TYPE_AVR32_UC3C0128C, ++ PART_TYPE_AVR32_UC3C0256C, ++ PART_TYPE_AVR32_UC3C0512C, + PART_TYPE_AVR32_UC3C164C, -+ PART_TYPE_AVR32_UC3C2512C, -+ PART_TYPE_AVR32_UC3C2256C, -+ PART_TYPE_AVR32_UC3C2128C, ++ PART_TYPE_AVR32_UC3C1128C, ++ PART_TYPE_AVR32_UC3C1256C, ++ PART_TYPE_AVR32_UC3C1512C, + PART_TYPE_AVR32_UC3C264C, -+ PART_TYPE_AVR32_UC3L064, -+ PART_TYPE_AVR32_UC3L032, -+ PART_TYPE_AVR32_UC3L016 ++ PART_TYPE_AVR32_UC3C2128C, ++ PART_TYPE_AVR32_UC3C2256C, ++ PART_TYPE_AVR32_UC3C2512C, ++ PART_TYPE_AVR32_MXT768E +}; + +/* Microarchitectures. */ @@ -8177,6 +8351,7 @@ + ARCH_TYPE_AVR32_UCR2, + ARCH_TYPE_AVR32_UCR2NOMUL, + ARCH_TYPE_AVR32_UCR3, ++ ARCH_TYPE_AVR32_UCR3FP, + ARCH_TYPE_AVR32_NONE +}; + @@ -8199,6 +8374,9 @@ +#define FLAG_AVR32_HAS_V2_INSNS (1 << 7) +/* Flag specifying that the cpu has buggy mul insns. */ +#define FLAG_AVR32_HAS_NO_MUL_INSNS (1 << 8) ++/* Flag specifying that the device has FPU instructions according ++ to AVR32002 specifications*/ ++#define FLAG_AVR32_HAS_FPU (1 << 9) + +/* Structure for holding information about different avr32 CPUs/parts */ +struct part_type_s @@ -8240,6 +8418,7 @@ +#define TARGET_ARCH_UC (TARGET_ARCH_UCR1 || TARGET_ARCH_UCR2) +#define TARGET_UARCH_AVR32A (avr32_arch->uarch_type == UARCH_TYPE_AVR32A) +#define TARGET_UARCH_AVR32B (avr32_arch->uarch_type == UARCH_TYPE_AVR32B) ++#define TARGET_ARCH_FPU (avr32_arch->feature_flags & FLAG_AVR32_HAS_FPU) + +#define CAN_DEBUG_WITHOUT_FP + @@ -8694,12 +8873,10 @@ +/* Convert from gcc internal register number to register number + used in assembly code */ +#define ASM_REGNUM(reg) (LAST_REGNUM - (reg)) -+#define ASM_FP_REGNUM(reg) (LAST_FP_REGNUM - (reg)) + +/* Convert between register number used in assembly to gcc + internal register number */ +#define INTERNAL_REGNUM(reg) (LAST_REGNUM - (reg)) -+#define INTERNAL_FP_REGNUM(reg) (LAST_FP_REGNUM - (reg)) + +/** Basic Characteristics of Registers **/ + @@ -8709,13 +8886,10 @@ +pseudo register's number really is assigned the number +FIRST_PSEUDO_REGISTER. +*/ -+#define FIRST_PSEUDO_REGISTER (LAST_FP_REGNUM + 1) ++#define FIRST_PSEUDO_REGISTER (LAST_REGNUM + 1) + +#define FIRST_REGNUM 0 +#define LAST_REGNUM 15 -+#define NUM_FP_REGS 16 -+#define FIRST_FP_REGNUM 16 -+#define LAST_FP_REGNUM (16+NUM_FP_REGS-1) + +/* +An initializer that says which registers are used for fixed purposes @@ -8762,22 +8936,6 @@ + 0, /* r2 */ \ + 0, /* r1 */ \ + 0, /* r0 */ \ -+ 0, /* f15 */ \ -+ 0, /* f14 */ \ -+ 0, /* f13 */ \ -+ 0, /* f12 */ \ -+ 0, /* f11 */ \ -+ 0, /* f10 */ \ -+ 0, /* f9 */ \ -+ 0, /* f8 */ \ -+ 0, /* f7 */ \ -+ 0, /* f6 */ \ -+ 0, /* f5 */ \ -+ 0, /* f4 */ \ -+ 0, /* f3 */ \ -+ 0, /* f2*/ \ -+ 0, /* f1 */ \ -+ 0 /* f0 */ \ +} + +/* @@ -8808,22 +8966,6 @@ + 0, /* r2 */ \ + 0, /* r1 */ \ + 0, /* r0 */ \ -+ 1, /* f15 */ \ -+ 1, /* f14 */ \ -+ 1, /* f13 */ \ -+ 1, /* f12 */ \ -+ 1, /* f11 */ \ -+ 1, /* f10 */ \ -+ 1, /* f9 */ \ -+ 1, /* f8 */ \ -+ 0, /* f7 */ \ -+ 0, /* f6 */ \ -+ 0, /* f5 */ \ -+ 0, /* f4 */ \ -+ 0, /* f3 */ \ -+ 0, /* f2*/ \ -+ 0, /* f1*/ \ -+ 0, /* f0 */ \ +} + +/* Interrupt functions can only use registers that have already been @@ -8867,14 +9009,6 @@ +#define CONDITIONAL_REGISTER_USAGE \ + do \ + { \ -+ int regno; \ -+ \ -+ if (TARGET_SOFT_FLOAT) \ -+ { \ -+ for (regno = FIRST_FP_REGNUM; \ -+ regno <= LAST_FP_REGNUM; ++regno) \ -+ fixed_regs[regno] = call_used_regs[regno] = 1; \ -+ } \ + if (flag_pic) \ + { \ + fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ @@ -8924,22 +9058,6 @@ + INTERNAL_REGNUM(2), \ + INTERNAL_REGNUM(1), \ + INTERNAL_REGNUM(0), \ -+ INTERNAL_FP_REGNUM(15), \ -+ INTERNAL_FP_REGNUM(14), \ -+ INTERNAL_FP_REGNUM(13), \ -+ INTERNAL_FP_REGNUM(12), \ -+ INTERNAL_FP_REGNUM(11), \ -+ INTERNAL_FP_REGNUM(10), \ -+ INTERNAL_FP_REGNUM(9), \ -+ INTERNAL_FP_REGNUM(8), \ -+ INTERNAL_FP_REGNUM(7), \ -+ INTERNAL_FP_REGNUM(6), \ -+ INTERNAL_FP_REGNUM(5), \ -+ INTERNAL_FP_REGNUM(4), \ -+ INTERNAL_FP_REGNUM(3), \ -+ INTERNAL_FP_REGNUM(2), \ -+ INTERNAL_FP_REGNUM(1), \ -+ INTERNAL_FP_REGNUM(0), \ + SP_REGNUM, \ + PC_REGNUM \ +} @@ -9060,7 +9178,6 @@ +{ + NO_REGS, + GENERAL_REGS, -+ FP_REGS, + ALL_REGS, + LIM_REG_CLASSES +}; @@ -9079,7 +9196,6 @@ +{ \ + "NO_REGS", \ + "GENERAL_REGS", \ -+ "FLOATING_POINT_REGS", \ + "ALL_REGS" \ +} + @@ -9100,7 +9216,6 @@ +#define REG_CLASS_CONTENTS { \ + {0x00000000}, /* NO_REGS */ \ + {0x0000FFFF}, /* GENERAL_REGS */ \ -+ {0xFFFF0000}, /* FP_REGS */ \ + {0x7FFFFFFF}, /* ALL_REGS */ \ +} + @@ -9111,7 +9226,7 @@ +which is minimal, meaning that no smaller class also contains the +register. +*/ -+#define REGNO_REG_CLASS(REGNO) ((REGNO < 16) ? GENERAL_REGS : FP_REGS) ++#define REGNO_REG_CLASS(REGNO) (GENERAL_REGS) + +/* +A macro whose definition is the name of the class to which a valid @@ -9144,8 +9259,7 @@ +corresponding to class GENERAL_REGS, will not be passed +to this macro; you do not need to handle it. +*/ -+#define REG_CLASS_FROM_LETTER(CHAR) ((CHAR) == 'f' ? FP_REGS : NO_REGS) -+ ++#define REG_CLASS_FROM_LETTER(CHAR) NO_REGS + +/* These assume that REGNO is a hard or pseudo reg number. + They give nonzero only if REGNO is a hard reg of the suitable class @@ -9235,8 +9349,7 @@ +#define CONSTRAINT_LEN(C, STR) \ + ( ((C) == 'K' || (C) == 'I') ? 4 : \ + ((C) == 'R') ? 5 : \ -+ ((C) == 'N' || (C) == 'O' || \ -+ (C) == 'P' || (C) == 'L') ? -1 : \ ++ ((C) == 'P') ? -1 : \ + DEFAULT_CONSTRAINT_LEN((C), (STR)) ) + +#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \ @@ -9290,11 +9403,15 @@ + (C) == 'T' ? avr32_const_pool_ref_operand(OP, GET_MODE(OP)) : \ + (C) == 'U' ? SYMBOL_REF_RCALL_FUNCTION_P(OP) : \ + (C) == 'Z' ? avr32_cop_memory_operand(OP, GET_MODE(OP)) : \ ++ (C) == 'Q' ? avr32_non_rmw_memory_operand(OP, GET_MODE(OP)) : \ ++ (C) == 'Y' ? avr32_rmw_memory_operand(OP, GET_MODE(OP)) : \ + 0) + + +#define EXTRA_MEMORY_CONSTRAINT(C, STR) ( ((C) == 'R') || \ ++ ((C) == 'Q') || \ + ((C) == 'S') || \ ++ ((C) == 'Y') || \ + ((C) == 'Z') ) + + @@ -9424,8 +9541,6 @@ +*/ +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LR_REGNUM) + -+ -+ +/* +A C expression whose value is an integer giving the offset, in bytes, +from the value of the stack pointer register to the top of the stack @@ -9550,8 +9665,6 @@ +/* Use r7 */ +#define FRAME_POINTER_REGNUM INTERNAL_REGNUM(7) + -+ -+ +/* +The register number of the arg pointer register, which is used to access +the function's argument list. On some machines, this is the same as the @@ -9582,7 +9695,6 @@ +/* Using r0 */ +#define STATIC_CHAIN_REGNUM INTERNAL_REGNUM(0) + -+ +/** Eliminating Frame Pointer and Arg Pointer **/ + +/* @@ -9686,7 +9798,6 @@ +*/ +#define PUSH_ARGS 1 + -+ +/* +A C expression that is the number of bytes actually pushed onto the +stack when an instruction attempts to push NPUSHED bytes. @@ -9715,9 +9826,6 @@ +*/ +#define ACCUMULATE_OUTGOING_ARGS 0 + -+ -+ -+ +/* +A C expression that should indicate the number of bytes of its own +arguments that a function pops on returning, or 0 if the @@ -9834,9 +9942,6 @@ +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ + avr32_function_arg(&(CUM), MODE, TYPE, NAMED) + -+ -+ -+ +/* +A C type for declaring a variable that is used as the first argument of +FUNCTION_ARG and other related values. For some target machines, @@ -9856,7 +9961,7 @@ + will occupy */ + int index; + /* A mask with bits representing the argument registers: if a bit is set -+ then this register is used for an arguemnt */ ++ then this register is used for an argument */ + int used_index; + /* TRUE if this function has anonymous arguments */ + int uses_anonymous_args; @@ -9864,6 +9969,8 @@ + int stack_pushed_args_size; + /* Set to true if this function needs a Return Value Pointer */ + int use_rvp; ++ /* Set to true if function is a flashvault function. */ ++ int flashvault_func; + +} CUMULATIVE_ARGS; + @@ -9882,7 +9989,6 @@ + while (0) +#define SET_INDEXES_UNUSED(CUM) ((CUM)->used_index = 0) + -+ +/* + A C statement (sans semicolon) for initializing the variable cum for the + state at the beginning of the argument list. The variable has type @@ -9904,7 +10010,6 @@ +#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \ + avr32_init_cumulative_args(&(CUM), FNTYPE, LIBNAME, FNDECL) + -+ +/* +A C statement (sans semicolon) to update the summarizer variable +CUM to advance past an argument in the argument list. The @@ -9959,7 +10064,6 @@ +#define PAD_VARARGS_DOWN \ + (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward) + -+ +/* +A C expression that is nonzero if REGNO is the number of a hard +register in which function arguments are sometimes passed. This does @@ -9990,7 +10094,6 @@ +/* AVR32 is using r12 as return register. */ +#define RET_REGISTER (15 - 12) + -+ +/* +A C expression to create an RTX representing the place where a library +function returns a value of mode MODE. If the precise function @@ -10349,8 +10452,6 @@ +{ + int flags; + rtx value; -+ int fpflags; -+ rtx fpvalue; + int cond_exec_cmp_clobbered; +} avr32_status_reg; + @@ -10369,9 +10470,6 @@ +#define CC_STATUS_MDEP_INIT \ + (cc_status.mdep.flags = CC_NONE , cc_status.mdep.cond_exec_cmp_clobbered = 0, cc_status.mdep.value = 0) + -+#define FPCC_STATUS_INIT \ -+ (cc_status.mdep.fpflags = CC_NONE , cc_status.mdep.fpvalue = 0) -+ +/* +A C compound statement to set the components of cc_status +appropriately for an insn INSN whose body is EXP. It is @@ -10836,7 +10934,7 @@ +itself; before and after that, output the additional assembler syntax +for making that name global, and a newline. +*/ -+#define GLOBAL_ASM_OP "\t.globl\t" ++#define GLOBAL_ASM_OP "\t.global\t" + + + @@ -10923,14 +11021,6 @@ + "r5", "r4", \ + "r3", "r2", \ + "r1", "r0", \ -+ "f15","f14", \ -+ "f13","f12", \ -+ "f11","f10", \ -+ "f9", "f8", \ -+ "f7", "f6", \ -+ "f5", "f4", \ -+ "f3", "f2", \ -+ "f1", "f0" \ +} + +/* @@ -11262,7 +11352,12 @@ + AVR32_BUILTIN_SATS, + AVR32_BUILTIN_SATU, + AVR32_BUILTIN_SATRNDS, -+ AVR32_BUILTIN_SATRNDU ++ AVR32_BUILTIN_SATRNDU, ++ AVR32_BUILTIN_MEMS, ++ AVR32_BUILTIN_MEMC, ++ AVR32_BUILTIN_MEMT, ++ AVR32_BUILTIN_SLEEP, ++ AVR32_BUILTIN_DELAY_CYCLES +}; + + @@ -11317,13 +11412,11 @@ +#endif + +#endif ---- a/gcc/config/avr32/avr32.md +--- /dev/null +++ b/gcc/config/avr32/avr32.md -@@ -0,0 +1,4926 @@ +@@ -0,0 +1,5025 @@ +;; AVR32 machine description file. -+;; Copyright 2003-2006 Atmel Corporation. -+;; -+;; Written by Ronny Pedersen, Atmel Norway, ++;; Copyright 2003,2004,2005,2006,2007,2008,2009 Atmel Corporation. +;; +;; This file is part of GCC. +;; @@ -11352,7 +11445,7 @@ + + +; NB! Keep this in sync with enum architecture_type in avr32.h -+(define_attr "pipeline" "ap,ucr1,ucr2,ucr2nomul,ucr3" ++(define_attr "pipeline" "ap,ucr1,ucr2,ucr2nomul,ucr3,ucr3fp" + (const (symbol_ref "avr32_arch->arch_type"))) + +; Insn length in bytes @@ -11378,7 +11471,7 @@ + (UNSPEC_PIC_BASE 11) + (UNSPEC_STORE_MULTIPLE 12) + (UNSPEC_STMFP 13) -+ (UNSPEC_FPCC_TO_REG 14) ++ (UNSPEC_FRCPA 14) + (UNSPEC_REG_TO_CC 15) + (UNSPEC_FORCE_MINIPOOL 16) + (UNSPEC_SATS 17) @@ -11418,6 +11511,12 @@ + (VUNSPEC_FRS 27) + (VUNSPEC_CSRF 28) + (VUNSPEC_SSRF 29) ++ (VUNSPEC_SLEEP 30) ++ (VUNSPEC_DELAY_CYCLES 31) ++ (VUNSPEC_DELAY_CYCLES_1 32) ++ (VUNSPEC_DELAY_CYCLES_2 33) ++ (VUNSPEC_NOP 34) ++ (VUNSPEC_NOP3 35) + ]) + +(define_constants @@ -11775,10 +11874,9 @@ + } +) + -+ +(define_expand "mov" -+ [(set (match_operand:MOVM 0 "register_operand" "") -+ (match_operand:MOVM 1 "general_operand" ""))] ++ [(set (match_operand:MOVM 0 "avr32_non_rmw_nonimmediate_operand" "") ++ (match_operand:MOVM 1 "avr32_non_rmw_general_operand" ""))] + "" + { + @@ -11786,7 +11884,6 @@ + if (GET_CODE (operands[0]) == MEM) + operands[1] = force_reg (mode, operands[1]); + -+ + /* Check for out of range immediate constants as these may + occur during reloading, since it seems like reload does + not check if the immediate is legitimate. Don't know if @@ -11797,7 +11894,19 @@ + && !avr32_const_ok_for_constraint_p(INTVAL(operands[1]), 'K', "Ks21") ){ + operands[1] = force_const_mem(SImode, operands[1]); + } ++ /* Check for RMW memory operands. They are not allowed for mov operations ++ only the atomic memc/s/t operations */ ++ if ( !reload_in_progress ++ && avr32_rmw_memory_operand (operands[0], mode) ){ ++ operands[0] = copy_rtx (operands[0]); ++ XEXP(operands[0], 0) = force_reg (mode, XEXP(operands[0], 0)); ++ } + ++ if ( !reload_in_progress ++ && avr32_rmw_memory_operand (operands[1], mode) ){ ++ operands[1] = copy_rtx (operands[1]); ++ XEXP(operands[1], 0) = force_reg (mode, XEXP(operands[1], 0)); ++ } + if ( (flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS) + && !avr32_legitimate_pic_operand_p(operands[1]) ) + operands[1] = legitimize_pic_address (operands[1], mode, @@ -11808,12 +11917,13 @@ + }) + + -+ +(define_insn "mov_internal" -+ [(set (match_operand:MOVM 0 "nonimmediate_operand" "=r, r, r,r,r,m,r") -+ (match_operand:MOVM 1 "general_operand" "rKs08,Ks21,J,n,m,r,W"))] -+ "register_operand (operands[0], mode) -+ || register_operand (operands[1], mode)" ++ [(set (match_operand:MOVM 0 "avr32_non_rmw_nonimmediate_operand" "=r, r, r,r,r,Q,r") ++ (match_operand:MOVM 1 "avr32_non_rmw_general_operand" "rKs08,Ks21,J,n,Q,r,W"))] ++ "(register_operand (operands[0], mode) ++ || register_operand (operands[1], mode)) ++ && !avr32_rmw_memory_operand (operands[0], mode) ++ && !avr32_rmw_memory_operand (operands[1], mode)" + { + switch (which_alternative) { + case 0: @@ -11862,6 +11972,27 @@ + (set_attr "cc" "none,none,set_z_if_not_v2,set_z,none,none,clobber")]) + + ++(define_expand "reload_out_rmw_memory_operand" ++ [(set (match_operand:SI 2 "register_operand" "=r") ++ (match_operand:SI 0 "address_operand" "")) ++ (set (mem:SI (match_dup 2)) ++ (match_operand:SI 1 "register_operand" ""))] ++ "" ++ { ++ operands[0] = XEXP(operands[0], 0); ++ } ++) ++ ++(define_expand "reload_in_rmw_memory_operand" ++ [(set (match_operand:SI 2 "register_operand" "=r") ++ (match_operand:SI 1 "address_operand" "")) ++ (set (match_operand:SI 0 "register_operand" "") ++ (mem:SI (match_dup 2)))] ++ "" ++ { ++ operands[1] = XEXP(operands[1], 0); ++ } ++) + + +;; These instructions are for loading constants which cannot be loaded @@ -12192,8 +12323,7 @@ +(define_insn_and_split "*movdf_internal" + [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r,r,m") + (match_operand:DF 1 "general_operand" " r,G,F,m,r"))] -+ "TARGET_SOFT_FLOAT -+ && (register_operand (operands[0], DFmode) ++ "(register_operand (operands[0], DFmode) + || register_operand (operands[1], DFmode))" + { + switch (which_alternative ){ @@ -12212,8 +12342,7 @@ + abort(); + } + } -+ "TARGET_SOFT_FLOAT -+ && reload_completed ++ "reload_completed + && (REG_P (operands[0]) + && (REG_P (operands[1]) + || GET_CODE (operands[1]) == CONST_DOUBLE))" @@ -12238,7 +12367,7 @@ +;;============================================================================= +(define_insn "ld_predicable" + [(set (match_operand:MOVCC 0 "register_operand" "=r") -+ (match_operand:MOVCC 1 "memory_operand" ""))] ++ (match_operand:MOVCC 1 "avr32_non_rmw_memory_operand" ""))] + "TARGET_V2_INSNS" + "ld%?\t%0, %1" + [(set_attr "length" "4") @@ -12249,7 +12378,7 @@ + + +(define_insn "st_predicable" -+ [(set (match_operand:MOVCC 0 "memory_operand" "=") ++ [(set (match_operand:MOVCC 0 "avr32_non_rmw_memory_operand" "=") + (match_operand:MOVCC 1 "register_operand" "r"))] + "TARGET_V2_INSNS" + "st%?\t%0, %1" @@ -12549,13 +12678,13 @@ + +(define_insn "adddi3" + [(set (match_operand:DI 0 "register_operand" "=r,r") -+ (plus:DI (match_operand:DI 1 "register_operand" "%r,0") ++ (plus:DI (match_operand:DI 1 "register_operand" "%0,r") + (match_operand:DI 2 "register_operand" "r,r")))] + "" + "@ -+ add %0, %1, %2\;adc %m0, %m1, %m2 -+ add %0, %2\;adc %m0, %m0, %m2" -+ [(set_attr "length" "8,6") ++ add %0, %2\;adc %m0, %m0, %m2 ++ add %0, %1, %2\;adc %m0, %m1, %m2" ++ [(set_attr "length" "6,8") + (set_attr "type" "alu2") + (set_attr "cc" "set_vncz")]) + @@ -12594,17 +12723,14 @@ + (set_attr "cc" "")]) + +(define_insn "*sub3_mul" -+ [(set (match_operand:INTM 0 "register_operand" "=r,r,r") -+ (minus:INTM (match_operand:INTM 1 "register_operand" "r,0,r") -+ (mult:INTM (match_operand:INTM 2 "register_operand" "r,r,0") -+ (match_operand:SI 3 "immediate_operand" "Ku04,Ku04,Ku04" ))))] ++ [(set (match_operand:INTM 0 "register_operand" "=r") ++ (minus:INTM (match_operand:INTM 1 "register_operand" "r") ++ (mult:INTM (match_operand:INTM 2 "register_operand" "r") ++ (match_operand:SI 3 "immediate_operand" "Ku04" ))))] + "(INTVAL(operands[3]) == 0) || (INTVAL(operands[3]) == 2) || + (INTVAL(operands[3]) == 4) || (INTVAL(operands[3]) == 8)" -+ "@ -+ sub %0, %1, %2 << %p3 -+ sub %0, %0, %2 << %p3 -+ sub %0, %1, %0 << %p3" -+ [(set_attr "length" "4,4,4") ++ "sub %0, %1, %2 << %p3" ++ [(set_attr "length" "4") + (set_attr "cc" "")]) + +(define_insn "*sub3_lsl" @@ -12620,13 +12746,13 @@ + +(define_insn "subdi3" + [(set (match_operand:DI 0 "register_operand" "=r,r") -+ (minus:DI (match_operand:DI 1 "register_operand" "%r,0") ++ (minus:DI (match_operand:DI 1 "register_operand" "%0,r") + (match_operand:DI 2 "register_operand" "r,r")))] + "" + "@ -+ sub %0, %1, %2\;sbc %m0, %m1, %m2 -+ sub %0, %2\;sbc %m0, %m0, %m2" -+ [(set_attr "length" "8,6") ++ sub %0, %2\;sbc %m0, %m0, %m2 ++ sub %0, %1, %2\;sbc %m0, %m1, %m2" ++ [(set_attr "length" "6,8") + (set_attr "type" "alu2") + (set_attr "cc" "set_vncz")]) + @@ -12794,7 +12920,7 @@ + (set_attr "length" "4") + (set_attr "cc" "none")]) + -+(define_insn "mulaccsidi3" ++(define_insn "*mulaccsidi3" + [(set (match_operand:DI 0 "register_operand" "+r") + (plus:DI (mult:DI + (sign_extend:DI (match_operand:SI 1 "register_operand" "%r")) @@ -12806,7 +12932,7 @@ + (set_attr "length" "4") + (set_attr "cc" "none")]) + -+(define_insn "umulaccsidi3" ++(define_insn "*umulaccsidi3" + [(set (match_operand:DI 0 "register_operand" "+r") + (plus:DI (mult:DI + (zero_extend:DI (match_operand:SI 1 "register_operand" "%r")) @@ -13178,56 +13304,24 @@ + + +(define_insn "andsi3" -+ [(set (match_operand:SI 0 "register_operand" "=r, r, r, r") -+ (and:SI (match_operand:SI 1 "register_operand" "%0, r, 0, r") -+ (match_operand:SI 2 "nonmemory_operand" "r, M, i, r")))] ++ [(set (match_operand:SI 0 "avr32_rmw_memory_or_register_operand" "=Y,r,r,r, r, r,r,r,r,r") ++ (and:SI (match_operand:SI 1 "avr32_rmw_memory_or_register_operand" "%0,r,0,0, 0, 0,0,0,0,r" ) ++ (match_operand:SI 2 "nonmemory_operand" " N,M,N,Ku16,Ks17,J,L,r,i,r")))] + "" -+ { -+ switch (which_alternative){ -+ case 0: -+ return "and\t%0, %2"; -+ case 1: -+ { -+ int i, first_set = -1; -+ /* Search for first bit set in mask */ -+ for ( i = 31; i >= 0; --i ) -+ if ( INTVAL(operands[2]) & (1 << i) ){ -+ first_set = i; -+ break; -+ } -+ operands[2] = gen_rtx_CONST_INT(SImode, first_set + 1); -+ return "bfextu\t%0, %1, 0, %2"; -+ } -+ case 2: -+ if ( one_bit_cleared_operand(operands[2], VOIDmode) ){ -+ int bitpos; -+ for ( bitpos = 0; bitpos < 32; bitpos++ ) -+ if ( !(INTVAL(operands[2]) & (1 << bitpos)) ) -+ break; -+ operands[2] = gen_rtx_CONST_INT(SImode, bitpos); -+ return "cbr\t%0, %2"; -+ } else if ( (INTVAL(operands[2]) >= 0) && -+ (INTVAL(operands[2]) <= 65535) ) -+ return "andl\t%0, %2, COH"; -+ else if ( (INTVAL(operands[2]) < 0) && -+ (INTVAL(operands[2]) >= -65536 ) ) -+ return "andl\t%0, lo(%2)"; -+ else if ( ((INTVAL(operands[2]) & 0xffff) == 0xffff) ) -+ return "andh\t%0, hi(%2)"; -+ else if ( ((INTVAL(operands[2]) & 0xffff) == 0x0) ) -+ return "andh\t%0, hi(%2), COH"; -+ else -+ return "andh\t%0, hi(%2)\;andl\t%0, lo(%2)"; -+ case 3: -+ return "and\t%0, %1, %2"; -+ default: -+ abort(); -+ } -+ } -+ -+ [(set_attr "length" "2,4,8,4") -+ (set_attr "cc" "set_z")]) -+ ++ "@ ++ memc\t%0, %z2 ++ bfextu\t%0, %1, 0, %z2 ++ cbr\t%0, %z2 ++ andl\t%0, %2, COH ++ andl\t%0, lo(%2) ++ andh\t%0, hi(%2), COH ++ andh\t%0, hi(%2) ++ and\t%0, %2 ++ andh\t%0, hi(%2)\;andl\t%0, lo(%2) ++ and\t%0, %1, %2" ++ ++ [(set_attr "length" "4,4,2,4,4,4,4,2,8,4") ++ (set_attr "cc" "none,set_z,set_z,set_z,set_z,set_z,set_z,set_z,set_z,set_z")]) + + + @@ -13248,37 +13342,21 @@ +;;============================================================================= + +(define_insn "iorsi3" -+ [(set (match_operand:SI 0 "register_operand" "=r,r,r") -+ (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r" ) -+ (match_operand:SI 2 "nonmemory_operand" "r ,i,r")))] ++ [(set (match_operand:SI 0 "avr32_rmw_memory_or_register_operand" "=Y,r,r, r,r,r,r") ++ (ior:SI (match_operand:SI 1 "avr32_rmw_memory_or_register_operand" "%0,0,0, 0,0,0,r" ) ++ (match_operand:SI 2 "nonmemory_operand" " O,O,Ku16,J,r,i,r")))] + "" -+ { -+ switch (which_alternative){ -+ case 0: -+ return "or\t%0, %2"; -+ case 1: -+ if ( one_bit_set_operand(operands[2], VOIDmode) ){ -+ int bitpos; -+ for (bitpos = 0; bitpos < 32; bitpos++) -+ if (INTVAL(operands[2]) & (1 << bitpos)) -+ break; -+ operands[2] = gen_rtx_CONST_INT( SImode, bitpos); -+ return "sbr\t%0, %2"; -+ } else if ( (INTVAL(operands[2]) >= 0) && -+ (INTVAL(operands[2]) <= 65535) ) -+ return "orl\t%0, %2"; -+ else if ( ((INTVAL(operands[2]) & 0xffff) == 0x0) ) -+ return "orh\t%0, hi(%2)"; -+ else -+ return "orh\t%0, hi(%2)\;orl\t%0, lo(%2)"; -+ case 2: -+ return "or\t%0, %1, %2"; -+ default: -+ abort(); -+ } -+ } -+ [(set_attr "length" "2,8,4") -+ (set_attr "cc" "set_z")]) ++ "@ ++ mems\t%0, %p2 ++ sbr\t%0, %p2 ++ orl\t%0, %2 ++ orh\t%0, hi(%2) ++ or\t%0, %2 ++ orh\t%0, hi(%2)\;orl\t%0, lo(%2) ++ or\t%0, %1, %2" ++ ++ [(set_attr "length" "4,2,4,4,2,8,4") ++ (set_attr "cc" "none,set_z,set_z,set_z,set_z,set_z,set_z")]) + + +(define_insn "iordi3" @@ -13298,32 +13376,20 @@ +;;============================================================================= + +(define_insn "xorsi3" -+ [(set (match_operand:SI 0 "register_operand" "=r,r,r") -+ (xor:SI (match_operand:SI 1 "register_operand" "0,0,r") -+ (match_operand:SI 2 "nonmemory_operand" "r,i,r")))] ++ [(set (match_operand:SI 0 "avr32_rmw_memory_or_register_operand" "=Y,r, r,r,r,r") ++ (xor:SI (match_operand:SI 1 "avr32_rmw_memory_or_register_operand" "%0,0, 0,0,0,r" ) ++ (match_operand:SI 2 "nonmemory_operand" " O,Ku16,J,r,i,r")))] + "" -+ { -+ switch (which_alternative){ -+ case 0: -+ return "eor %0, %2"; -+ case 1: -+ if ( (INTVAL(operands[2]) >= 0) && -+ (INTVAL(operands[2]) <= 65535) ) -+ return "eorl %0, %2"; -+ else if ( ((INTVAL(operands[2]) & 0xffff) == 0x0) ) -+ return "eorh %0, hi(%2)"; -+ else -+ return "eorh %0, hi(%2)\;eorl %0, lo(%2)"; -+ case 2: -+ return "eor %0, %1, %2"; -+ default: -+ abort(); -+ } -+ } -+ -+ [(set_attr "length" "2,8,4") -+ (set_attr "cc" "set_z")]) ++ "@ ++ memt\t%0, %p2 ++ eorl\t%0, %2 ++ eorh\t%0, hi(%2) ++ eor\t%0, %2 ++ eorh\t%0, hi(%2)\;eorl\t%0, lo(%2) ++ eor\t%0, %1, %2" + ++ [(set_attr "length" "4,4,4,2,8,4") ++ (set_attr "cc" "none,set_z,set_z,set_z,set_z,set_z")]) + +(define_insn "xordi3" + [(set (match_operand:DI 0 "register_operand" "=&r,&r") @@ -13503,6 +13569,7 @@ +;;----------------------------------------------------------------------------- +;; Signed division that produces both a quotient and a remainder. +;;============================================================================= ++ +(define_expand "divmodsi4" + [(parallel [ + (parallel [ @@ -13517,16 +13584,13 @@ + { + if (can_create_pseudo_p ()) { + operands[4] = gen_reg_rtx (DImode); -+ + emit_insn(gen_divmodsi4_internal(operands[4],operands[1],operands[2])); + emit_move_insn(operands[0], gen_rtx_SUBREG( SImode, operands[4], 4)); + emit_move_insn(operands[3], gen_rtx_SUBREG( SImode, operands[4], 0)); -+ + DONE; + } else { + FAIL; + } -+ + }) + + @@ -13683,12 +13747,12 @@ + +(define_insn "one_cmplsi2" + [(set (match_operand:SI 0 "register_operand" "=r,r") -+ (not:SI (match_operand:SI 1 "register_operand" "r,0")))] ++ (not:SI (match_operand:SI 1 "register_operand" "0,r")))] + "" + "@ -+ rsub\t%0, %1, -1 -+ com\t%0" -+ [(set_attr "length" "4,2") ++ com\t%0 ++ rsub\t%0, %1, -1" ++ [(set_attr "length" "2,4") + (set_attr "cc" "set_z")]) + + @@ -13752,6 +13816,26 @@ + [(set_attr "length" "4") + (set_attr "cc" "compare")]) + ++(define_expand "cmpsf" ++ [(set (cc0) ++ (compare:SF ++ (match_operand:SF 0 "general_operand" "") ++ (match_operand:SF 1 "general_operand" "")))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "{ ++ rtx tmpreg; ++ if ( !REG_P(operands[0]) ) ++ operands[0] = force_reg(SFmode, operands[0]); ++ ++ if ( !REG_P(operands[1]) ) ++ operands[1] = force_reg(SFmode, operands[1]); ++ ++ avr32_compare_op0 = operands[0]; ++ avr32_compare_op1 = operands[1]; ++ emit_insn(gen_cmpsf_internal_uc3fp(operands[0], operands[1])); ++ DONE; ++ }" ++) + +;;;============================================================================= +;; Test if zero @@ -14317,21 +14401,29 @@ + (clobber (reg:SI LR_REGNUM))])] + "" + { -+ switch (which_alternative){ -+ case 0: -+ return "icall\t%0"; -+ case 1: -+ return "rcall\t%0"; -+ case 2: -+ return "mcall\t%0"; -+ case 3: -+ if ( TARGET_HAS_ASM_ADDR_PSEUDOS ) -+ return "call\t%0"; -+ else -+ return "mcall\tr6[%0@got]"; -+ default: -+ abort(); -+ } ++ ++ /* Check for a flashvault call. */ ++ if (avr32_flashvault_call (SYMBOL_REF_DECL (operands[0]))) ++ { ++ /* Assembly is already emitted. */ ++ return ""; ++ } ++ ++ switch (which_alternative) { ++ case 0: ++ return "icall\t%0"; ++ case 1: ++ return "rcall\t%0"; ++ case 2: ++ return "mcall\t%0"; ++ case 3: ++ if (TARGET_HAS_ASM_ADDR_PSEUDOS) ++ return "call\t%0"; ++ else ++ return "mcall\tr6[%0@got]"; ++ default: ++ abort(); ++ } + } + [(set_attr "type" "call") + (set_attr "length" "2,4,4,10") @@ -14344,50 +14436,54 @@ + (clobber (reg:SI LR_REGNUM))])] + "" + { -+ rtx call_address; -+ if ( GET_CODE(operands[0]) != MEM ) ++ rtx call_address; ++ if ( GET_CODE(operands[0]) != MEM ) + FAIL; + -+ call_address = XEXP(operands[0], 0); -+ -+ /* If assembler supports call pseudo insn and the call -+ address is a symbol then nothing special needs to be done. */ -+ if ( TARGET_HAS_ASM_ADDR_PSEUDOS -+ && (GET_CODE(call_address) == SYMBOL_REF) ){ -+ /* We must however mark the function as using the GOT if -+ flag_pic is set, since the call insn might turn into -+ a mcall using the GOT ptr register. */ -+ if ( flag_pic ){ -+ current_function_uses_pic_offset_table = 1; -+ emit_call_insn(gen_call_internal(call_address, operands[1])); -+ DONE; -+ } -+ } else { -+ if ( flag_pic && -+ GET_CODE(call_address) == SYMBOL_REF ){ -+ current_function_uses_pic_offset_table = 1; -+ emit_call_insn(gen_call_internal(call_address, operands[1])); -+ DONE; -+ } ++ call_address = XEXP(operands[0], 0); + -+ if ( !SYMBOL_REF_RCALL_FUNCTION_P(operands[0]) ){ -+ if ( optimize_size && -+ GET_CODE(call_address) == SYMBOL_REF ){ -+ call_address = force_const_mem(SImode, call_address); -+ } else { -+ call_address = force_reg(SImode, call_address); ++ /* If assembler supports call pseudo insn and the call address is a symbol then nothing special needs to be done. */ ++ if (TARGET_HAS_ASM_ADDR_PSEUDOS && (GET_CODE(call_address) == SYMBOL_REF) ) ++ { ++ /* We must however mark the function as using the GOT if flag_pic is set, since the call insn might turn into a mcall using the GOT ptr register. */ ++ if (flag_pic) ++ { ++ current_function_uses_pic_offset_table = 1; ++ emit_call_insn(gen_call_internal(call_address, operands[1])); ++ DONE; + } -+ } -+ } -+ emit_call_insn(gen_call_internal(call_address, operands[1])); -+ DONE; ++ } ++ else ++ { ++ if (flag_pic && GET_CODE(call_address) == SYMBOL_REF ) ++ { ++ current_function_uses_pic_offset_table = 1; ++ emit_call_insn(gen_call_internal(call_address, operands[1])); ++ DONE; ++ } ++ ++ if (!SYMBOL_REF_RCALL_FUNCTION_P(operands[0]) ) ++ { ++ if (optimize_size && GET_CODE(call_address) == SYMBOL_REF ) ++ { ++ call_address = force_const_mem(SImode, call_address); ++ } ++ else ++ { ++ call_address = force_reg(SImode, call_address); ++ } ++ } ++ } ++ emit_call_insn(gen_call_internal(call_address, operands[1])); ++ DONE; ++ + } +) + +;;============================================================================= +;; call_value +;;----------------------------------------------------------------------------- -+;; Subrutine call instruction returning a value. ++;; Subroutine call instruction returning a value. +;;============================================================================= +(define_expand "call_value" + [(parallel [(set (match_operand:SI 0 "" "") @@ -14402,6 +14498,13 @@ + + call_address = XEXP(operands[1], 0); + ++ /* Check for a flashvault call. ++ if (GET_CODE (call_address) == SYMBOL_REF ++ && avr32_flashvault_call (SYMBOL_REF_DECL (call_address))) ++ DONE; ++ ++ */ ++ + /* If assembler supports call pseudo insn and the call + address is a symbol then nothing special needs to be done. */ + if ( TARGET_HAS_ASM_ADDR_PSEUDOS @@ -14445,21 +14548,29 @@ + ;; Operand 2 not used on the AVR32. + "" + { -+ switch (which_alternative){ -+ case 0: -+ return "icall\t%1"; -+ case 1: -+ return "rcall\t%1"; -+ case 2: -+ return "mcall\t%1"; -+ case 3: -+ if ( TARGET_HAS_ASM_ADDR_PSEUDOS ) -+ return "call\t%1"; -+ else -+ return "mcall\tr6[%1@got]"; -+ default: -+ abort(); -+ } ++ /* Check for a flashvault call. */ ++ if (avr32_flashvault_call (SYMBOL_REF_DECL (operands[1]))) ++ { ++ /* Assembly is already emitted. */ ++ return ""; ++ } ++ ++ ++ switch (which_alternative) { ++ case 0: ++ return "icall\t%1"; ++ case 1: ++ return "rcall\t%1"; ++ case 2: ++ return "mcall\t%1"; ++ case 3: ++ if ( TARGET_HAS_ASM_ADDR_PSEUDOS ) ++ return "call\t%1"; ++ else ++ return "mcall\tr6[%1@got]"; ++ default: ++ abort(); ++ } + } + [(set_attr "type" "call") + (set_attr "length" "2,4,4,10") @@ -14591,19 +14702,6 @@ + [(set_attr "type" "call")]) + +;;============================================================================= -+;; nop -+;;----------------------------------------------------------------------------- -+;; No-op instruction. -+;;============================================================================= -+(define_insn "nop" -+ [(const_int 0)] -+ "" -+ "nop" -+ [(set_attr "length" "2") -+ (set_attr "type" "alu") -+ (set_attr "cc" "none")]) -+ -+;;============================================================================= +;; nonlocal_goto_receiver +;;----------------------------------------------------------------------------- +;; For targets with a return stack we must make sure to flush the return stack @@ -14665,7 +14763,7 @@ + +(define_insn "indirect_jump_internal" + [(set (pc) -+ (match_operand:SI 0 "general_operand" "r,m,W"))] ++ (match_operand:SI 0 "avr32_non_rmw_general_operand" "r,m,W"))] + "" + { + switch( which_alternative ){ @@ -15195,6 +15293,101 @@ + (set_attr "length" "4")] + ) + ++(define_insn "sleep" ++ [(unspec_volatile [(const_int 0)] VUNSPEC_SLEEP) ++ (match_operand:SI 0 "const_int_operand" "")] ++ "" ++ "sleep %0" ++ [(set_attr "length" "1") ++ (set_attr "cc" "none") ++ ]) ++ ++(define_expand "delay_cycles" ++ [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")] ++ VUNSPEC_DELAY_CYCLES)] ++ "" ++ " ++ unsigned int cycles = UINTVAL (operands[0]); ++ if (IN_RANGE(cycles,0x10000 ,0xFFFFFFFF)) ++ { ++ unsigned int msb = (cycles & 0xFFFF0000); ++ unsigned int shift = 16; ++ msb = (msb >> shift); ++ unsigned int cycles_used = (msb*0x10000); ++ emit_insn (gen_delay_cycles_2 (gen_int_mode (msb, SImode))); ++ cycles -= cycles_used; ++ } ++ if (IN_RANGE(cycles, 4, 0xFFFF)) ++ { ++ unsigned int loop_count = (cycles/ 4); ++ unsigned int cycles_used = (loop_count*4); ++ emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, SImode))); ++ cycles -= cycles_used; ++ } ++ while (cycles >= 3) ++ { ++ emit_insn (gen_nop3 ()); ++ cycles -= 3; ++ } ++ if (cycles == 1 || cycles == 2) ++ { ++ while (cycles--) ++ emit_insn (gen_nop ()); ++ } ++ DONE; ++ ") ++ ++(define_insn "delay_cycles_1" ++[(unspec_volatile [(const_int 0)] VUNSPEC_DELAY_CYCLES_1) ++ (match_operand:SI 0 "immediate_operand" "") ++ (clobber (match_scratch:SI 1 "=&r"))] ++ "" ++ "mov\t%1, %0 ++ 1: sub\t%1, 1 ++ brne\t1b ++ nop" ++) ++ ++(define_insn "delay_cycles_2" ++[(unspec_volatile [(const_int 0)] VUNSPEC_DELAY_CYCLES_2) ++ (match_operand:SI 0 "immediate_operand" "") ++ (clobber (match_scratch:SI 1 "=&r")) ++ (clobber (match_scratch:SI 2 "=&r"))] ++ "" ++ "mov\t%1, %0 ++ 1: mov\t%2, 16383 ++ 2: sub\t%2, 1 ++ brne\t2b ++ nop ++ sub\t%1, 1 ++ brne\t1b ++ nop" ++) ++ ++;; CPU instructions ++ ++;;============================================================================= ++;; nop ++;;----------------------------------------------------------------------------- ++;; No-op instruction. ++;;============================================================================= ++(define_insn "nop" ++ [(unspec_volatile [(const_int 0)] VUNSPEC_NOP)] ++ "" ++ "nop" ++ [(set_attr "length" "1") ++ (set_attr "type" "alu") ++ (set_attr "cc" "none")]) ++ ++;; NOP3 ++(define_insn "nop3" ++ [(unspec_volatile [(const_int 0)] VUNSPEC_NOP3)] ++ "" ++ "rjmp\t2" ++ [(set_attr "length" "3") ++ (set_attr "type" "alu") ++ (set_attr "cc" "none")]) ++ +;; Special patterns for dealing with the constant pool + +(define_insn "align_4" @@ -15207,6 +15400,7 @@ + [(set_attr "length" "2")] +) + ++ +(define_insn "consttable_start" + [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_START)] + "" @@ -16244,15 +16438,15 @@ +;; Load the SIMD description +(include "simd.md") + -+;; Load the FP coprAocessor patterns -+(include "fpcp.md") ---- a/gcc/config/avr32/avr32-modes.def ++;; Include the FPU for uc3 ++(include "uc3fpu.md") +--- /dev/null +++ b/gcc/config/avr32/avr32-modes.def @@ -0,0 +1 @@ +VECTOR_MODES (INT, 4); /* V4QI V2HI */ ---- a/gcc/config/avr32/avr32.opt +--- /dev/null +++ b/gcc/config/avr32/avr32.opt -@@ -0,0 +1,81 @@ +@@ -0,0 +1,89 @@ +; Options for the ATMEL AVR32 port of the compiler. + +; Copyright 2007 Atmel Corporation. @@ -16279,12 +16473,12 @@ +Use section .rodata for read-only data instead of .text. + +mhard-float -+Target Report Undocumented Mask(HARD_FLOAT) -+Use floating point coprocessor instructions. ++Target Report Mask(HARD_FLOAT) ++Use FPU instructions instead of floating point emulation. + +msoft-float -+Target Report Undocumented InverseMask(HARD_FLOAT, SOFT_FLOAT) -+Use software floating-point library for floating-point operations. ++Target Report InverseMask(HARD_FLOAT, SOFT_FLOAT) ++Use floating point emulation for floating point operations. + +mforce-double-align +Target Report RejectNegative Mask(FORCE_DOUBLE_ALIGN) @@ -16334,15 +16528,20 @@ +Target Report Undocumented Mask(COND_EXEC_BEFORE_RELOAD) +Enable experimental conditional execution preparation before the reload stage. + ---- a/gcc/config/avr32/avr32-protos.h ++mrmw-addressable-data ++Target Report Mask(RMW_ADDRESSABLE_DATA) ++Signal that all data is in range for the Atomic Read-Modify-Write memory instructions, and that ++gcc can safely generate these whenever possible. ++ ++mflashvault ++Target Var(TARGET_FLASHVAULT) ++Generate code for flashvault +--- /dev/null +++ b/gcc/config/avr32/avr32-protos.h -@@ -0,0 +1,197 @@ +@@ -0,0 +1,196 @@ +/* + Prototypes for exported functions defined in avr32.c -+ Copyright 2003-2006 Atmel Corporation. -+ -+ Written by Ronny Pedersen, Atmel Norway, -+ Initial porting by Anders �dland. ++ Copyright 2003,2004,2005,2006,2007,2008,2009 Atmel Corporation. + + This file is part of GCC. + @@ -16532,9 +16731,11 @@ +int avr32_cond_imm_clobber_splittable (rtx insn, + rtx operands[]); + ++bool avr32_flashvault_call(tree decl); ++extern void avr32_emit_swdivsf (rtx, rtx, rtx); + +#endif /* AVR32_PROTOS_H */ ---- a/gcc/config/avr32/crti.asm +--- /dev/null +++ b/gcc/config/avr32/crti.asm @@ -0,0 +1,64 @@ +/* @@ -16584,627 +16785,73 @@ + rsub r6, pc + rjmp 2f + .align 2 -+1: .long 0b - _GLOBAL_OFFSET_TABLE_ -+2: -+ -+ .section ".fini" -+/* Just load the GOT */ -+ .align 2 -+ .global _fini -+_fini: -+ stm --sp, r6, lr -+ lddpc r6, 1f -+0: -+ rsub r6, pc -+ rjmp 2f -+ .align 2 -+1: .long 0b - _GLOBAL_OFFSET_TABLE_ -+2: -+ ---- a/gcc/config/avr32/crtn.asm -+++ b/gcc/config/avr32/crtn.asm -@@ -0,0 +1,44 @@ -+/* Copyright (C) 2001 Free Software Foundation, Inc. -+ Written By Nick Clifton -+ -+ This file is free software; you can redistribute it and/or modify it -+ under the terms of the GNU General Public License as published by the -+ Free Software Foundation; either version 2, or (at your option) any -+ later version. -+ -+ In addition to the permissions in the GNU General Public License, the -+ Free Software Foundation gives you unlimited permission to link the -+ compiled version of this file with other programs, and to distribute -+ those programs without any restriction coming from the use of this -+ file. (The General Public License restrictions do apply in other -+ respects; for example, they cover modification of the file, and -+ distribution when not linked into another program.) -+ -+ This file is distributed in the hope that it will be useful, but -+ WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; see the file COPYING. If not, write to -+ the Free Software Foundation, 59 Temple Place - Suite 330, -+ Boston, MA 02111-1307, USA. -+ -+ As a special exception, if you link this library with files -+ compiled with GCC to produce an executable, this does not cause -+ the resulting executable to be covered by the GNU General Public License. -+ This exception does not however invalidate any other reasons why -+ the executable file might be covered by the GNU General Public License. -+*/ -+ -+ -+ -+ -+ .file "crtn.asm" -+ -+ .section ".init" -+ ldm sp++, r6, pc -+ -+ .section ".fini" -+ ldm sp++, r6, pc -+ ---- a/gcc/config/avr32/fpcp.md -+++ b/gcc/config/avr32/fpcp.md -@@ -0,0 +1,551 @@ -+;; AVR32 machine description file for Floating-Point instructions. -+;; Copyright 2003-2006 Atmel Corporation. -+;; -+;; Written by Ronny Pedersen, Atmel Norway, -+;; -+;; This file is part of GCC. -+;; -+;; This program is free software; you can redistribute it and/or modify -+;; it under the terms of the GNU General Public License as published by -+;; the Free Software Foundation; either version 2 of the License, or -+;; (at your option) any later version. -+;; -+;; This program is distributed in the hope that it will be useful, -+;; but WITHOUT ANY WARRANTY; without even the implied warranty of -+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+;; GNU General Public License for more details. -+;; -+;; You should have received a copy of the GNU General Public License -+;; along with this program; if not, write to the Free Software -+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+;; -*- Mode: Scheme -*- -+ -+;;****************************************************************************** -+;; Automaton pipeline description for floating-point coprocessor insns -+;;****************************************************************************** -+(define_cpu_unit "fid,fm1,fm2,fm3,fm4,fwb,fcmp,fcast" "avr32_ap") -+ -+(define_insn_reservation "fmv_op" 1 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "fmv")) -+ "is,da,d,fid,fwb") -+ -+(define_insn_reservation "fmul_op" 5 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "fmul")) -+ "is,da,d,fid,fm1,fm2,fm3,fm4,fwb") -+ -+(define_insn_reservation "fcmps_op" 1 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "fcmps")) -+ "is,da,d,fid,fcmp") -+ -+(define_insn_reservation "fcmpd_op" 2 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "fcmpd")) -+ "is,da,d,fid*2,fcmp") -+ -+(define_insn_reservation "fcast_op" 3 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "fcast")) -+ "is,da,d,fid,fcmp,fcast,fwb") -+ -+(define_insn_reservation "fmvcpu_op" 2 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "fmvcpu")) -+ "is,da,d") -+ -+(define_insn_reservation "fldd_op" 1 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "fldd")) -+ "is,da,d,fwb") -+ -+(define_insn_reservation "flds_op" 1 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "flds")) -+ "is,da,d,fwb") -+ -+(define_insn_reservation "fsts_op" 0 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "fsts")) -+ "is,da*2,d") -+ -+(define_insn_reservation "fstd_op" 0 -+ (and (eq_attr "pipeline" "ap") -+ (eq_attr "type" "fstd")) -+ "is,da*2,d") -+ -+ -+(define_insn "*movsf_fpcp" -+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,r,f,m,r,r,r,m") -+ (match_operand:SF 1 "general_operand" " f,r,f,m,f,r,G,m,r"))] -+ "TARGET_HARD_FLOAT" -+ "@ -+ fmov.s\t%0, %1 -+ fmov.s\t%0, %1 -+ fmov.s\t%0, %1 -+ fld.s\t%0, %1 -+ fst.s\t%0, %1 -+ mov\t%0, %1 -+ mov\t%0, %1 -+ ld.w\t%0, %1 -+ st.w\t%0, %1" -+ [(set_attr "length" "4,4,4,4,4,2,4,4,4") -+ (set_attr "type" "fmv,flds,fmvcpu,flds,fsts,alu,alu,load,store")]) -+ -+(define_insn_and_split "*movdf_fpcp" -+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,r,f,m,r,r,m") -+ (match_operand:DF 1 "general_operand" " f,r,f,m,f,r,m,r"))] -+ "TARGET_HARD_FLOAT" -+ "@ -+ fmov.d\t%0, %1 -+ fmov.d\t%0, %1 -+ fmov.d\t%0, %1 -+ fld.d\t%0, %1 -+ fst.d\t%0, %1 -+ mov\t%0, %1\;mov\t%m0, %m1 -+ ld.d\t%0, %1 -+ st.d\t%0, %1" -+ -+ "TARGET_HARD_FLOAT -+ && reload_completed -+ && (REG_P(operands[0]) && (REGNO_REG_CLASS(REGNO(operands[0])) == GENERAL_REGS)) -+ && (REG_P(operands[1]) && (REGNO_REG_CLASS(REGNO(operands[1])) == GENERAL_REGS))" -+ [(set (match_dup 0) (match_dup 1)) -+ (set (match_dup 2) (match_dup 3))] -+ " -+ { -+ operands[2] = gen_highpart (SImode, operands[0]); -+ operands[0] = gen_lowpart (SImode, operands[0]); -+ operands[3] = gen_highpart(SImode, operands[1]); -+ operands[1] = gen_lowpart(SImode, operands[1]); -+ } -+ " -+ -+ [(set_attr "length" "4,4,4,4,4,4,4,4") -+ (set_attr "type" "fmv,fldd,fmvcpu,fldd,fstd,alu2,load2,store2")]) -+ -+ -+(define_insn "mulsf3" -+ [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") -+ (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") -+ (match_operand:SF 2 "avr32_fp_register_operand" "f")))] -+ "TARGET_HARD_FLOAT" -+ "fmul.s\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_insn "nmulsf3" -+ [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") -+ (neg:SF (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") -+ (match_operand:SF 2 "avr32_fp_register_operand" "f"))))] -+ "TARGET_HARD_FLOAT" -+ "fnmul.s\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_peephole2 -+ [(set (match_operand:SF 0 "avr32_fp_register_operand" "") -+ (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "") -+ (match_operand:SF 2 "avr32_fp_register_operand" ""))) -+ (set (match_operand:SF 3 "avr32_fp_register_operand" "") -+ (neg:SF (match_dup 0)))] -+ "TARGET_HARD_FLOAT && -+ (peep2_reg_dead_p(2, operands[0]) || (REGNO(operands[3]) == REGNO(operands[0])))" -+ [(set (match_dup 3) -+ (neg:SF (mult:SF (match_dup 1) -+ (match_dup 2))))] -+) -+ -+ -+(define_insn "macsf3" -+ [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") -+ (plus:SF (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") -+ (match_operand:SF 2 "avr32_fp_register_operand" "f")) -+ (match_operand:SF 3 "avr32_fp_register_operand" "0")))] -+ "TARGET_HARD_FLOAT" -+ "fmac.s\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_insn "nmacsf3" -+ [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") -+ (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") -+ (match_operand:SF 2 "avr32_fp_register_operand" "f"))) -+ (match_operand:SF 3 "avr32_fp_register_operand" "0")))] -+ "TARGET_HARD_FLOAT" -+ "fnmac.s\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_peephole2 -+ [(set (match_operand:SF 0 "avr32_fp_register_operand" "") -+ (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "") -+ (match_operand:SF 2 "avr32_fp_register_operand" ""))) -+ (set (match_operand:SF 3 "avr32_fp_register_operand" "") -+ (minus:SF -+ (match_dup 3) -+ (match_dup 0)))] -+ "TARGET_HARD_FLOAT && peep2_reg_dead_p(2, operands[0])" -+ [(set (match_dup 3) -+ (plus:SF (neg:SF (mult:SF (match_dup 1) -+ (match_dup 2))) -+ (match_dup 3)))] -+) -+ -+ -+(define_insn "msubacsf3" -+ [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") -+ (minus:SF (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") -+ (match_operand:SF 2 "avr32_fp_register_operand" "f")) -+ (match_operand:SF 3 "avr32_fp_register_operand" "0")))] -+ "TARGET_HARD_FLOAT" -+ "fmsc.s\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_peephole2 -+ [(set (match_operand:SF 0 "avr32_fp_register_operand" "") -+ (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "") -+ (match_operand:SF 2 "avr32_fp_register_operand" ""))) -+ (set (match_operand:SF 3 "avr32_fp_register_operand" "") -+ (minus:SF -+ (match_dup 0) -+ (match_dup 3)))] -+ "TARGET_HARD_FLOAT && peep2_reg_dead_p(2, operands[0])" -+ [(set (match_dup 3) -+ (minus:SF (mult:SF (match_dup 1) -+ (match_dup 2)) -+ (match_dup 3)))] -+) -+ -+(define_insn "nmsubacsf3" -+ [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") -+ (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") -+ (match_operand:SF 2 "avr32_fp_register_operand" "f"))) -+ (match_operand:SF 3 "avr32_fp_register_operand" "0")))] -+ "TARGET_HARD_FLOAT" -+ "fnmsc.s\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+ -+ -+(define_insn "addsf3" -+ [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") -+ (plus:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") -+ (match_operand:SF 2 "avr32_fp_register_operand" "f")))] -+ "TARGET_HARD_FLOAT" -+ "fadd.s\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_insn "subsf3" -+ [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") -+ (minus:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") -+ (match_operand:SF 2 "avr32_fp_register_operand" "f")))] -+ "TARGET_HARD_FLOAT" -+ "fsub.s\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+ -+(define_insn "negsf2" -+ [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") -+ (neg:SF (match_operand:SF 1 "avr32_fp_register_operand" "f")))] -+ "TARGET_HARD_FLOAT" -+ "fneg.s\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmv")]) -+ -+(define_insn "abssf2" -+ [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") -+ (abs:SF (match_operand:SF 1 "avr32_fp_register_operand" "f")))] -+ "TARGET_HARD_FLOAT" -+ "fabs.s\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmv")]) -+ -+(define_insn "truncdfsf2" -+ [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") -+ (float_truncate:SF -+ (match_operand:DF 1 "avr32_fp_register_operand" "f")))] -+ "TARGET_HARD_FLOAT" -+ "fcastd.s\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "type" "fcast")]) -+ -+(define_insn "extendsfdf2" -+ [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") -+ (float_extend:DF -+ (match_operand:SF 1 "avr32_fp_register_operand" "f")))] -+ "TARGET_HARD_FLOAT" -+ "fcasts.d\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "type" "fcast")]) -+ -+(define_insn "muldf3" -+ [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") -+ (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") -+ (match_operand:DF 2 "avr32_fp_register_operand" "f")))] -+ "TARGET_HARD_FLOAT" -+ "fmul.d\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_insn "nmuldf3" -+ [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") -+ (neg:DF (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") -+ (match_operand:DF 2 "avr32_fp_register_operand" "f"))))] -+ "TARGET_HARD_FLOAT" -+ "fnmul.d\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_peephole2 -+ [(set (match_operand:DF 0 "avr32_fp_register_operand" "") -+ (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "") -+ (match_operand:DF 2 "avr32_fp_register_operand" ""))) -+ (set (match_operand:DF 3 "avr32_fp_register_operand" "") -+ (neg:DF (match_dup 0)))] -+ "TARGET_HARD_FLOAT && -+ (peep2_reg_dead_p(2, operands[0]) || (REGNO(operands[3]) == REGNO(operands[0])))" -+ [(set (match_dup 3) -+ (neg:DF (mult:DF (match_dup 1) -+ (match_dup 2))))] -+) -+ -+(define_insn "macdf3" -+ [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") -+ (plus:DF (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") -+ (match_operand:DF 2 "avr32_fp_register_operand" "f")) -+ (match_operand:DF 3 "avr32_fp_register_operand" "0")))] -+ "TARGET_HARD_FLOAT" -+ "fmac.d\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_insn "msubacdf3" -+ [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") -+ (minus:DF (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") -+ (match_operand:DF 2 "avr32_fp_register_operand" "f")) -+ (match_operand:DF 3 "avr32_fp_register_operand" "0")))] -+ "TARGET_HARD_FLOAT" -+ "fmsc.d\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_peephole2 -+ [(set (match_operand:DF 0 "avr32_fp_register_operand" "") -+ (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "") -+ (match_operand:DF 2 "avr32_fp_register_operand" ""))) -+ (set (match_operand:DF 3 "avr32_fp_register_operand" "") -+ (minus:DF -+ (match_dup 0) -+ (match_dup 3)))] -+ "TARGET_HARD_FLOAT && peep2_reg_dead_p(2, operands[0])" -+ [(set (match_dup 3) -+ (minus:DF (mult:DF (match_dup 1) -+ (match_dup 2)) -+ (match_dup 3)))] -+ ) -+ -+(define_insn "nmsubacdf3" -+ [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") -+ (minus:DF (neg:DF (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") -+ (match_operand:DF 2 "avr32_fp_register_operand" "f"))) -+ (match_operand:DF 3 "avr32_fp_register_operand" "0")))] -+ "TARGET_HARD_FLOAT" -+ "fnmsc.d\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_insn "nmacdf3" -+ [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") -+ (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") -+ (match_operand:DF 2 "avr32_fp_register_operand" "f"))) -+ (match_operand:DF 3 "avr32_fp_register_operand" "0")))] -+ "TARGET_HARD_FLOAT" -+ "fnmac.d\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_peephole2 -+ [(set (match_operand:DF 0 "avr32_fp_register_operand" "") -+ (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "") -+ (match_operand:DF 2 "avr32_fp_register_operand" ""))) -+ (set (match_operand:DF 3 "avr32_fp_register_operand" "") -+ (minus:DF -+ (match_dup 3) -+ (match_dup 0)))] -+ "TARGET_HARD_FLOAT && peep2_reg_dead_p(2, operands[0])" -+ [(set (match_dup 3) -+ (plus:DF (neg:DF (mult:DF (match_dup 1) -+ (match_dup 2))) -+ (match_dup 3)))] -+) -+ -+(define_insn "adddf3" -+ [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") -+ (plus:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") -+ (match_operand:DF 2 "avr32_fp_register_operand" "f")))] -+ "TARGET_HARD_FLOAT" -+ "fadd.d\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_insn "subdf3" -+ [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") -+ (minus:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") -+ (match_operand:DF 2 "avr32_fp_register_operand" "f")))] -+ "TARGET_HARD_FLOAT" -+ "fsub.d\t%0, %1, %2" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmul")]) -+ -+(define_insn "negdf2" -+ [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") -+ (neg:DF (match_operand:DF 1 "avr32_fp_register_operand" "f")))] -+ "TARGET_HARD_FLOAT" -+ "fneg.d\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmv")]) -+ -+(define_insn "absdf2" -+ [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") -+ (abs:DF (match_operand:DF 1 "avr32_fp_register_operand" "f")))] -+ "TARGET_HARD_FLOAT" -+ "fabs.d\t%0, %1" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmv")]) -+ -+ -+(define_expand "cmpdf" -+ [(set (cc0) -+ (compare:DF -+ (match_operand:DF 0 "general_operand" "") -+ (match_operand:DF 1 "general_operand" "")))] -+ "TARGET_HARD_FLOAT" -+ "{ -+ rtx tmpreg; -+ if ( !REG_P(operands[0]) ) -+ operands[0] = force_reg(DFmode, operands[0]); -+ -+ if ( !REG_P(operands[1]) ) -+ operands[1] = force_reg(DFmode, operands[1]); -+ -+ avr32_compare_op0 = operands[0]; -+ avr32_compare_op1 = operands[1]; -+ -+ emit_insn(gen_cmpdf_internal(operands[0], operands[1])); -+ -+ tmpreg = gen_reg_rtx(SImode); -+ emit_insn(gen_fpcc_to_reg(tmpreg)); -+ emit_insn(gen_reg_to_cc(tmpreg)); -+ -+ DONE; -+ }" -+) -+ -+(define_insn "cmpdf_internal" -+ [(set (reg:CC FPCC_REGNUM) -+ (compare:CC -+ (match_operand:DF 0 "avr32_fp_register_operand" "f") -+ (match_operand:DF 1 "avr32_fp_register_operand" "f")))] -+ "TARGET_HARD_FLOAT" -+ { -+ if (!rtx_equal_p(cc_prev_status.mdep.fpvalue, SET_SRC(PATTERN (insn))) ) -+ return "fcmp.d\t%0, %1"; -+ return ""; -+ } -+ [(set_attr "length" "4") -+ (set_attr "type" "fcmpd") -+ (set_attr "cc" "fpcompare")]) -+ -+(define_expand "cmpsf" -+ [(set (cc0) -+ (compare:SF -+ (match_operand:SF 0 "general_operand" "") -+ (match_operand:SF 1 "general_operand" "")))] -+ "TARGET_HARD_FLOAT" -+ "{ -+ rtx tmpreg; -+ if ( !REG_P(operands[0]) ) -+ operands[0] = force_reg(SFmode, operands[0]); -+ -+ if ( !REG_P(operands[1]) ) -+ operands[1] = force_reg(SFmode, operands[1]); ++1: .long 0b - _GLOBAL_OFFSET_TABLE_ ++2: ++ ++ .section ".fini" ++/* Just load the GOT */ ++ .align 2 ++ .global _fini ++_fini: ++ stm --sp, r6, lr ++ lddpc r6, 1f ++0: ++ rsub r6, pc ++ rjmp 2f ++ .align 2 ++1: .long 0b - _GLOBAL_OFFSET_TABLE_ ++2: + -+ avr32_compare_op0 = operands[0]; -+ avr32_compare_op1 = operands[1]; +--- /dev/null ++++ b/gcc/config/avr32/crtn.asm +@@ -0,0 +1,44 @@ ++/* Copyright (C) 2001 Free Software Foundation, Inc. ++ Written By Nick Clifton + -+ emit_insn(gen_cmpsf_internal(operands[0], operands[1])); ++ This file is free software; you can redistribute it and/or modify it ++ under the terms of the GNU General Public License as published by the ++ Free Software Foundation; either version 2, or (at your option) any ++ later version. + -+ tmpreg = gen_reg_rtx(SImode); -+ emit_insn(gen_fpcc_to_reg(tmpreg)); -+ emit_insn(gen_reg_to_cc(tmpreg)); ++ In addition to the permissions in the GNU General Public License, the ++ Free Software Foundation gives you unlimited permission to link the ++ compiled version of this file with other programs, and to distribute ++ those programs without any restriction coming from the use of this ++ file. (The General Public License restrictions do apply in other ++ respects; for example, they cover modification of the file, and ++ distribution when not linked into another program.) + -+ DONE; -+ }" -+) ++ This file is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. + -+(define_insn "cmpsf_internal" -+ [(set (reg:CC FPCC_REGNUM) -+ (compare:CC -+ (match_operand:SF 0 "avr32_fp_register_operand" "f") -+ (match_operand:SF 1 "avr32_fp_register_operand" "f")))] -+ "TARGET_HARD_FLOAT" -+ { -+ if (!rtx_equal_p(cc_prev_status.mdep.fpvalue, SET_SRC(PATTERN (insn))) ) -+ return "fcmp.s\t%0, %1"; -+ return ""; -+ } -+ [(set_attr "length" "4") -+ (set_attr "type" "fcmps") -+ (set_attr "cc" "fpcompare")]) ++ You should have received a copy of the GNU General Public License ++ along with this program; see the file COPYING. If not, write to ++ the Free Software Foundation, 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. + -+(define_insn "fpcc_to_reg" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (unspec:SI [(reg:CC FPCC_REGNUM)] -+ UNSPEC_FPCC_TO_REG))] -+ "TARGET_HARD_FLOAT" -+ "fmov.s\t%0, fsr" -+ [(set_attr "length" "4") -+ (set_attr "type" "fmvcpu")]) ++ As a special exception, if you link this library with files ++ compiled with GCC to produce an executable, this does not cause ++ the resulting executable to be covered by the GNU General Public License. ++ This exception does not however invalidate any other reasons why ++ the executable file might be covered by the GNU General Public License. ++*/ + -+(define_insn "reg_to_cc" -+ [(set (cc0) -+ (unspec:SI [(match_operand:SI 0 "register_operand" "r")] -+ UNSPEC_REG_TO_CC))] -+ "TARGET_HARD_FLOAT" -+ "musfr\t%0" -+ [(set_attr "length" "2") -+ (set_attr "type" "alu") -+ (set_attr "cc" "from_fpcc")]) + -+(define_insn "stm_fp" -+ [(unspec [(match_operand 0 "register_operand" "r") -+ (match_operand 1 "const_int_operand" "") -+ (match_operand 2 "const_int_operand" "")] -+ UNSPEC_STMFP)] -+ "TARGET_HARD_FLOAT" -+ { -+ int cop_reglist = INTVAL(operands[1]); + -+ if (INTVAL(operands[2]) != 0) -+ return "stcm.w\tcp0, --%0, %C1"; -+ else -+ return "stcm.w\tcp0, %0, %C1"; ++ ++ .file "crtn.asm" + -+ if ( cop_reglist & ~0xff ){ -+ operands[1] = GEN_INT(cop_reglist & ~0xff); -+ if (INTVAL(operands[2]) != 0) -+ return "stcm.d\tcp0, --%0, %D1"; -+ else -+ return "stcm.d\tcp0, %0, %D1"; -+ } -+ } -+ [(set_attr "type" "fstm") -+ (set_attr "length" "4") -+ (set_attr "cc" "none")]) ---- a/gcc/config/avr32/lib1funcs.S ++ .section ".init" ++ ldm sp++, r6, pc ++ ++ .section ".fini" ++ ldm sp++, r6, pc ++ +--- /dev/null +++ b/gcc/config/avr32/lib1funcs.S -@@ -0,0 +1,2874 @@ +@@ -0,0 +1,2903 @@ +/* Macro for moving immediate value to register. */ +.macro mov_imm reg, imm +.if (((\imm & 0xfffff) == \imm) || ((\imm | 0xfff00000) == \imm)) @@ -18243,6 +17890,7 @@ + brne __avr32_f64_add_return_nan + mov r10, 0 /* Generate Inf in r11, r10 */ + mov_imm r11, 0x7ff00000 ++ or r11, r12 /* Put sign bit back */ + ldm sp++, r5, r6, r7, pc/* opL Inf, return Inf */ +__avr32_f64_add_return_nan: + mov r10, -1 /* Generate NaN in r11, r10 */ @@ -18595,25 +18243,30 @@ +#endif + + /* compare magnitude of op1 and op2 */ ++ st.w --sp, lr ++ st.w --sp, r7 + lsl r11,1 /* Remove sign bit of op1 */ + srcs r12 /* Sign op1 to lsb of r12*/ -+ subfeq r10, 0 -+ breq 3f /* op1 zero */ + lsl r9,1 /* Remove sign bit of op2 */ ++ srcs r7 + rol r12 /* Sign op2 to lsb of lr, sign bit op1 bit 1 of r12*/ + + + /* Check for Nan */ -+ pushm lr -+ mov_imm lr, 0xffe00000 ++ mov_imm lr, 0xffe00000 + cp.w r10,0 + cpc r11,lr + brhi 0f /* We have NaN */ + cp.w r8,0 + cpc r9,lr + brhi 0f /* We have NaN */ -+ popm lr -+ ++ ++ cp.w r11, 0 ++ subfeq r10, 0 ++ breq 3f /* op1 zero */ ++ ld.w r7, sp++ ++ ld.w lr, sp++ ++ + cp.w r12,3 /* both operands negative ?*/ + breq 1f + @@ -18659,18 +18312,22 @@ +#endif + +0: ++ ld.w r7, sp++ + popm pc, r12=0 +#endif + +3: -+ lsl r9,1 /* Remove sign bit of op1 */ ++ cp.w r7, 1 /* Check sign bit from r9 */ +#ifdef L_avr32_f64_cmp_ge -+ srcs r12 /* If op2 is negative then op1 >= op2. */ ++ sreq r12 /* If op2 is negative then op1 >= op2. */ +#endif +#ifdef L_avr32_f64_cmp_lt -+ srcc r12 /* If op2 is positve then op1 <= op2. */ ++ srne r12 /* If op2 is positve then op1 <= op2. */ +#endif -+ subfeq r8, 0 ++ cp.w r9, 0 ++ subfeq r8, 0 ++ ld.w r7, sp++ ++ ld.w lr, sp++ +#ifdef L_avr32_f64_cmp_ge + reteq 1 /* Both operands are zero. Return true. */ +#endif @@ -18930,7 +18587,7 @@ + brne 16f /* Return NaN if op1 is NaN */ + /* Op1 is inf check op2 */ + lsr r6, r9, 20 /* Extract exponent */ -+ cbr r6, 8 /* Clear sign bit */ ++ cbr r6, 11 /* Clear sign bit */ + cp r6, 0x7ff + brne 17f /* Inf/number gives inf, return inf */ + rjmp 16f /* The rest gives NaN*/ @@ -19046,10 +18703,14 @@ + +16: /* Return NaN. */ + mov r11, -1 -+ mov r10, -1 ++ mov r10, 0 + ldm sp++, r0, r1, r2, r3, r4, r5, r6, r7,pc + -+17: /* Return INF. */ ++17: ++ /* Check if op1 is zero. */ ++ or r4, r10, r11 ++ breq __avr32_f64_div_op1_zero ++ /* Return INF. */ + mov r11, lr /*Get correct sign*/ + andh r11, 0x8000, COH + orh r11, 0x7ff0 @@ -19463,10 +19124,13 @@ + + /* Unpack */ + lsl r12,1 -+ reteq 0 /* Return zero if op1 is zero */ + lsl r11,1 + breq 4f /* Check op2 for zero */ -+ ++ ++ tst r12, r12 ++ moveq r9, 0 ++ breq 12f ++ + /* Unpack op1*/ + /* exp: r9 */ + /* sf: r12 */ @@ -19485,9 +19149,14 @@ + breq 13f /*If number is subnormal*/ + cp r10, 0xff + brhs 3f /* Check op2 for NaN or Inf */ -+ + lsl r11,7 + sbr r11, 31 /*Implicit bit*/ ++ ++ cp.w r9, 0 ++ subfeq r12, 0 ++ reteq 0 /* op1 is zero and op2 is not zero */ ++ /* or NaN so return zero */ ++ +14: + + /* For UC3, store with predecrement is faster than stm */ @@ -19656,9 +19325,14 @@ + reteq 0 /* Return zero if number/inf*/ + ret -1 /* Return NaN*/ +4: -+ /* Op2 is zero ? */ ++ /* Op1 is zero ? */ + tst r12,r12 + reteq -1 /* 0.0/0.0 is NaN */ ++ /* Op1 is Nan? */ ++ lsr r9, r12, 24 ++ breq 11f /*If number is subnormal*/ ++ cp r9, 0xff ++ brhs 2b /* Check op1 for NaN or Inf */ + /* Nonzero/0.0 is Inf. Sign bit will be shifted in before returning*/ + mov_imm r12, 0xff000000 + rjmp __divsf_return_op1 @@ -19802,6 +19476,7 @@ + cbr r11, 31 + clz r9, r11 + retcs 0 /* op2 is zero. Return 0 */ ++ sub r9, 8 + lsl r11, r11, r9 + rsub r9, r9, 1 + @@ -20007,6 +19682,7 @@ + lsl r11,8 /* check mantissa */ + movne r11, -1 /* Return NaN */ + moveq r11, r10 /* Return inf */ ++ mov r10, 0 + rjmp __extendsfdf_return_op1 +#endif + @@ -20054,7 +19730,7 @@ + /* NaN or inf */ + cbr r12,31 /* clear implicit bit */ + retne -1 /* Return NaN if mantissa not zero */ -+ mov_imm r12, 0xff000000 ++ mov_imm r12, 0x7f800000 + ret r12 /* Return inf */ + +3: /* Result is subnormal. Adjust it.*/ @@ -20079,7 +19755,7 @@ +1: + ret r9 +#endif ---- a/gcc/config/avr32/lib2funcs.S +--- /dev/null +++ b/gcc/config/avr32/lib2funcs.S @@ -0,0 +1,21 @@ + .align 4 @@ -20103,7 +19779,7 @@ + + + ---- a/gcc/config/avr32/linux-elf.h +--- /dev/null +++ b/gcc/config/avr32/linux-elf.h @@ -0,0 +1,151 @@ +/* @@ -20257,9 +19933,9 @@ + +#define LINK_GCC_C_SEQUENCE_SPEC \ + "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" ---- a/gcc/config/avr32/predicates.md +--- /dev/null +++ b/gcc/config/avr32/predicates.md -@@ -0,0 +1,386 @@ +@@ -0,0 +1,422 @@ +;; AVR32 predicates file. +;; Copyright 2003-2006 Atmel Corporation. +;; @@ -20487,13 +20163,13 @@ + (ior (match_operand 0 "register_operand") + (match_operand 0 "const_double_operand"))) + -+;; True is this is an operand containing a label_ref ++;; True if this is an operand containing a label_ref. +(define_predicate "avr32_label_ref_operand" + (and (match_code "mem") + (match_test "avr32_find_symbol(op) + && (GET_CODE(avr32_find_symbol(op)) == LABEL_REF)"))) + -+;; True is this is a valid symbol pointing to the constant pool ++;; True if this is a valid symbol pointing to the constant pool. +(define_predicate "avr32_const_pool_operand" + (and (match_code "symbol_ref") + (match_test "CONSTANT_POOL_ADDRESS_P(op)")) @@ -20505,7 +20181,7 @@ + } +) + -+;; True is this is a memory reference to the constant or mini pool ++;; True if this is a memory reference to the constant or mini pool. +(define_predicate "avr32_const_pool_ref_operand" + (ior (match_operand 0 "avr32_label_ref_operand") + (and (match_code "mem") @@ -20526,7 +20202,7 @@ + (match_operand 0 "pre_dec_memory_operand"))) + + -+;; True is this is a k12 offseted memory operand ++;; True if this is a k12 offseted memory operand. +(define_predicate "avr32_k12_memory_operand" + (and (match_code "mem") + (ior (match_test "REG_P(XEXP(op, 0))") @@ -20536,19 +20212,19 @@ + && (CONST_OK_FOR_CONSTRAINT_P(INTVAL(XEXP(XEXP(op, 0), 0)), + 'K', (mode == SImode) ? \"Ks14\" : ((mode == HImode) ? \"Ks13\" : \"Ks12\")))")))) + -+;; True is this is a memory operand with an immediate displacement ++;; True if this is a memory operand with an immediate displacement. +(define_predicate "avr32_imm_disp_memory_operand" + (and (match_code "mem") + (match_test "GET_CODE(XEXP(op, 0)) == PLUS + && REG_P(XEXP(XEXP(op, 0), 0)) + && (GET_CODE(XEXP(XEXP(op, 0), 1)) == CONST_INT)"))) + -+;; True is this is a bswap operand ++;; True if this is a bswap operand. +(define_predicate "avr32_bswap_operand" + (ior (match_operand 0 "avr32_k12_memory_operand") + (match_operand 0 "register_operand"))) + -+;; True is this is a valid coprocessor insn memory operand ++;; True if this is a valid coprocessor insn memory operand. +(define_predicate "avr32_cop_memory_operand" + (and (match_operand 0 "memory_operand") + (not (match_test "GET_CODE(XEXP(op, 0)) == PLUS @@ -20556,34 +20232,29 @@ + && (GET_CODE(XEXP(XEXP(op, 0), 1)) == CONST_INT) + && !(CONST_OK_FOR_CONSTRAINT_P(INTVAL(XEXP(XEXP(op, 0), 0)), 'K', \"Ku10\"))")))) + -+;; True is this is a valid source/destination operand ++;; True if this is a valid source/destination operand. +;; for moving values to/from a coprocessor +(define_predicate "avr32_cop_move_operand" + (ior (match_operand 0 "register_operand") + (match_operand 0 "avr32_cop_memory_operand"))) + + -+;; True is this is a valid extract byte offset for use in -+;; load extracted index insns ++;; True if this is a valid extract byte offset for use in ++;; load extracted index insns. +(define_predicate "avr32_extract_shift_operand" + (and (match_operand 0 "const_int_operand") + (match_test "(INTVAL(op) == 0) || (INTVAL(op) == 8) + || (INTVAL(op) == 16) || (INTVAL(op) == 24)"))) + -+;; True is this is a floating-point register -+(define_predicate "avr32_fp_register_operand" -+ (and (match_operand 0 "register_operand") -+ (match_test "REGNO_REG_CLASS(REGNO(op)) == FP_REGS"))) -+ -+;; True is this is valid avr32 symbol operand ++;; True if this is a valid avr32 symbol operand. +(define_predicate "avr32_symbol_operand" -+ (ior (match_code "label_ref, symbol_ref") -+ (and (match_code "const") -+ (match_test "avr32_find_symbol(op)")))) ++ (and (match_code "label_ref, symbol_ref, const") ++ (match_test "avr32_find_symbol(op)"))) + -+;; True is this is valid operand for the lda.w and call pseudo insns ++;; True if this is a valid operand for the lda.w and call pseudo insns. +(define_predicate "avr32_address_operand" -+ (and (match_code "label_ref, symbol_ref") ++ (and (and (match_code "label_ref, symbol_ref") ++ (match_test "avr32_find_symbol(op)")) + (ior (match_test "TARGET_HAS_ASM_ADDR_PSEUDOS") + (match_test "flag_pic")) )) + @@ -20646,7 +20317,48 @@ +(define_predicate "avr32_mov_immediate_operand" + (and (match_operand 0 "immediate_operand") + (match_test "avr32_const_ok_for_move(INTVAL(op))"))) ---- a/gcc/config/avr32/simd.md ++ ++ ++(define_predicate "avr32_rmw_address_operand" ++ (ior (and (match_code "symbol_ref") ++ (match_test "({rtx symbol = avr32_find_symbol(op); \ ++ symbol && (GET_CODE (symbol) == SYMBOL_REF) && SYMBOL_REF_RMW_ADDR(symbol);})")) ++ (and (match_operand 0 "immediate_operand") ++ (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ks17\")"))) ++ { ++ return TARGET_RMW && !flag_pic; ++ } ++) ++ ++(define_predicate "avr32_rmw_memory_operand" ++ (and (match_code "mem") ++ (match_test "!volatile_refs_p(op) && (GET_MODE(op) == SImode) && ++ avr32_rmw_address_operand(XEXP(op, 0), GET_MODE(XEXP(op, 0)))"))) ++ ++(define_predicate "avr32_rmw_memory_or_register_operand" ++ (ior (match_operand 0 "avr32_rmw_memory_operand") ++ (match_operand 0 "register_operand"))) ++ ++(define_predicate "avr32_non_rmw_memory_operand" ++ (and (not (match_operand 0 "avr32_rmw_memory_operand")) ++ (match_operand 0 "memory_operand"))) ++ ++(define_predicate "avr32_non_rmw_general_operand" ++ (and (not (match_operand 0 "avr32_rmw_memory_operand")) ++ (match_operand 0 "general_operand"))) ++ ++(define_predicate "avr32_non_rmw_nonimmediate_operand" ++ (and (not (match_operand 0 "avr32_rmw_memory_operand")) ++ (match_operand 0 "nonimmediate_operand"))) ++ ++;; Return true if the operand is the 1.0f constant. ++ ++(define_predicate "const_1f_operand" ++ (match_code "const_int,const_double") ++{ ++ return (op == CONST1_RTX (SFmode)); ++}) +--- /dev/null +++ b/gcc/config/avr32/simd.md @@ -0,0 +1,145 @@ +;; AVR32 machine description file for SIMD instructions. @@ -20794,7 +20506,7 @@ + "psubadd.h\t%0, %1:b, %2:b" + [(set_attr "length" "4") + (set_attr "type" "alu")]) ---- a/gcc/config/avr32/sync.md +--- /dev/null +++ b/gcc/config/avr32/sync.md @@ -0,0 +1,244 @@ +;;================================================================= @@ -21041,13 +20753,12 @@ + "xchg\t%0, %p1, %2" + [(set_attr "length" "4")] + ) ---- a/gcc/config/avr32/t-avr32 +--- /dev/null +++ b/gcc/config/avr32/t-avr32 -@@ -0,0 +1,94 @@ +@@ -0,0 +1,102 @@ + +MD_INCLUDES= $(srcdir)/config/avr32/avr32.md \ + $(srcdir)/config/avr32/sync.md \ -+ $(srcdir)/config/avr32/fpcp.md \ + $(srcdir)/config/avr32/simd.md \ + $(srcdir)/config/avr32/predicates.md + @@ -21070,8 +20781,8 @@ + +#LIB2FUNCS_EXTRA += $(srcdir)/config/avr32/lib2funcs.S + -+MULTILIB_OPTIONS = march=ap/march=ucr1/march=ucr2/march=ucr2nomul/march=ucr3 -+MULTILIB_DIRNAMES = ap ucr1 ucr2 ucr2nomul ucr3 ++MULTILIB_OPTIONS = march=ap/march=ucr1/march=ucr2/march=ucr2nomul/march=ucr3/march=ucr3fp ++MULTILIB_DIRNAMES = ap ucr1 ucr2 ucr2nomul ucr3 ucr3fp +MULTILIB_EXCEPTIONS = +MULTILIB_MATCHES += march?ap=mpart?ap7000 +MULTILIB_MATCHES += march?ap=mpart?ap7001 @@ -21097,27 +20808,36 @@ +MULTILIB_MATCHES += march?ucr1=mpart?uc3b0128 +MULTILIB_MATCHES += march?ucr1=mpart?uc3b0256es +MULTILIB_MATCHES += march?ucr1=mpart?uc3b0256 ++MULTILIB_MATCHES += march?ucr2=mpart?uc3b0512 +MULTILIB_MATCHES += march?ucr2=mpart?uc3b0512revc +MULTILIB_MATCHES += march?ucr1=mpart?uc3b164 +MULTILIB_MATCHES += march?ucr1=mpart?uc3b1128 +MULTILIB_MATCHES += march?ucr1=mpart?uc3b1256es +MULTILIB_MATCHES += march?ucr1=mpart?uc3b1256 ++MULTILIB_MATCHES += march?ucr2=mpart?uc3b1512 +MULTILIB_MATCHES += march?ucr2=mpart?uc3b1512revc -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c0512c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c0256c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c0128c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c064c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c1512c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c1256c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c1128c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c164c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c2512c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c2256c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c2128c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c264c ++MULTILIB_MATCHES += march?ucr3=mpart?uc3c0512crevc ++MULTILIB_MATCHES += march?ucr3=mpart?uc3c1512crevc ++MULTILIB_MATCHES += march?ucr3=mpart?uc3c2512crevc ++MULTILIB_MATCHES += march?ucr3=mpart?uc3l0256 ++MULTILIB_MATCHES += march?ucr3=mpart?uc3l0128 +MULTILIB_MATCHES += march?ucr3=mpart?uc3l064 +MULTILIB_MATCHES += march?ucr3=mpart?uc3l032 +MULTILIB_MATCHES += march?ucr3=mpart?uc3l016 ++MULTILIB_MATCHES += march?ucr3=mpart?uc3l064revb ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c064c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c0128c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c0256c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c0512c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c164c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c1128c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c1256c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c1512c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c264c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c2128c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c2256c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c2512c ++MULTILIB_MATCHES += march?ucr3=mpart?mxt768e + + +EXTRA_MULTILIB_PARTS = crtbegin.o crtbeginS.o crtend.o crtendS.o crti.o crtn.o @@ -21138,13 +20858,12 @@ + + + ---- a/gcc/config/avr32/t-avr32-linux +--- /dev/null +++ b/gcc/config/avr32/t-avr32-linux -@@ -0,0 +1,94 @@ +@@ -0,0 +1,102 @@ + +MD_INCLUDES= $(srcdir)/config/avr32/avr32.md \ + $(srcdir)/config/avr32/sync.md \ -+ $(srcdir)/config/avr32/fpcp.md \ + $(srcdir)/config/avr32/simd.md \ + $(srcdir)/config/avr32/predicates.md + @@ -21167,8 +20886,8 @@ + +#LIB2FUNCS_EXTRA += $(srcdir)/config/avr32/lib2funcs.S + -+MULTILIB_OPTIONS = march=ap/march=ucr1/march=ucr2/march=ucr2nomul/march=ucr3 -+MULTILIB_DIRNAMES = ap ucr1 ucr2 ucr2nomul ucr3 ++MULTILIB_OPTIONS = march=ap/march=ucr1/march=ucr2/march=ucr2nomul/march=ucr3/march=ucr3fp ++MULTILIB_DIRNAMES = ap ucr1 ucr2 ucr2nomul ucr3 ucr3fp +MULTILIB_EXCEPTIONS = +MULTILIB_MATCHES += march?ap=mpart?ap7000 +MULTILIB_MATCHES += march?ap=mpart?ap7001 @@ -21194,27 +20913,36 @@ +MULTILIB_MATCHES += march?ucr1=mpart?uc3b0128 +MULTILIB_MATCHES += march?ucr1=mpart?uc3b0256es +MULTILIB_MATCHES += march?ucr1=mpart?uc3b0256 ++MULTILIB_MATCHES += march?ucr2=mpart?uc3b0512 +MULTILIB_MATCHES += march?ucr2=mpart?uc3b0512revc +MULTILIB_MATCHES += march?ucr1=mpart?uc3b164 +MULTILIB_MATCHES += march?ucr1=mpart?uc3b1128 +MULTILIB_MATCHES += march?ucr1=mpart?uc3b1256es +MULTILIB_MATCHES += march?ucr1=mpart?uc3b1256 ++MULTILIB_MATCHES += march?ucr2=mpart?uc3b1512 +MULTILIB_MATCHES += march?ucr2=mpart?uc3b1512revc -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c0512c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c0256c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c0128c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c064c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c1512c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c1256c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c1128c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c164c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c2512c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c2256c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c2128c -+MULTILIB_MATCHES += march?ucr3=mpart?uc3c264c ++MULTILIB_MATCHES += march?ucr3=mpart?uc3c0512crevc ++MULTILIB_MATCHES += march?ucr3=mpart?uc3c1512crevc ++MULTILIB_MATCHES += march?ucr3=mpart?uc3c2512crevc ++MULTILIB_MATCHES += march?ucr3=mpart?uc3l0256 ++MULTILIB_MATCHES += march?ucr3=mpart?uc3l0128 +MULTILIB_MATCHES += march?ucr3=mpart?uc3l064 +MULTILIB_MATCHES += march?ucr3=mpart?uc3l032 +MULTILIB_MATCHES += march?ucr3=mpart?uc3l016 ++MULTILIB_MATCHES += march?ucr3=mpart?uc3l064revb ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c064c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c0128c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c0256c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c0512c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c164c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c1128c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c1256c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c1512c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c264c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c2128c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c2256c ++MULTILIB_MATCHES += march?ucr3fp=mpart?uc3c2512c ++MULTILIB_MATCHES += march?ucr3=mpart?mxt768e + + +EXTRA_MULTILIB_PARTS = crtbegin.o crtbeginS.o crtend.o crtendS.o @@ -21235,7 +20963,7 @@ + + + ---- a/gcc/config/avr32/t-elf +--- /dev/null +++ b/gcc/config/avr32/t-elf @@ -0,0 +1,16 @@ + @@ -21254,7 +20982,208 @@ + +LIBGCC = stmp-multilib +INSTALL_LIBGCC = install-multilib ---- a/gcc/config/avr32/uclinux-elf.h +--- /dev/null ++++ b/gcc/config/avr32/uc3fpu.md +@@ -0,0 +1,198 @@ ++;; AVR32 machine description file for Floating-Point instructions. ++;; Copyright 2003-2006 Atmel Corporation. ++;; ++;; ++;; This file is part of GCC. ++;; ++;; This program is free software; you can redistribute it and/or modify ++;; it under the terms of the GNU General Public License as published by ++;; the Free Software Foundation; either version 2 of the License, or ++;; (at your option) any later version. ++;; ++;; This program is distributed in the hope that it will be useful, ++;; but WITHOUT ANY WARRANTY; without even the implied warranty of ++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++;; GNU General Public License for more details. ++;; ++;; You should have received a copy of the GNU General Public License ++;; along with this program; if not, write to the Free Software ++;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++(define_insn "*movsf_uc3fp" ++ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,m") ++ (match_operand:SF 1 "general_operand" "r,G,m,r"))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "@ ++ mov\t%0, %1 ++ mov\t%0, %1 ++ ld.w\t%0, %1 ++ st.w\t%0, %1" ++ [(set_attr "length" "2,4,4,4") ++ (set_attr "type" "alu,alu,load,store")]) ++ ++(define_insn "mulsf3" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (mult:SF (match_operand:SF 1 "register_operand" "r") ++ (match_operand:SF 2 "register_operand" "r")))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "fmul.s\t%0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "fmul")]) ++ ++(define_insn "nmulsf3" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%r") ++ (match_operand:SF 2 "register_operand" "r"))))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "fnmul.s\t%0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "fmul")]) ++ ++(define_insn "macsf3" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "r") ++ (match_operand:SF 2 "register_operand" "r")) ++ (match_operand:SF 3 "register_operand" "r")))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "fmac.s\t%0, %3, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "fmul")]) ++ ++;(define_insn "nmacsf3" ++; [(set (match_operand:SF 0 "register_operand" "=r") ++; (plus:SF (neg:SF (match_operand:SF 1 "register_operand" "r")) ++; (mult:SF(match_operand:SF 2 "register_operand" "r") ++; (match_operand:SF 3 "register_operand" "r"))))] ++; "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++; "fnmac.s\t%0, %1, %2, %3" ++; [(set_attr "length" "4") ++; (set_attr "type" "fmul")]) ++ ++(define_insn "nmacsf3" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (minus:SF (mult:SF (match_operand:SF 2 "register_operand" "r") ++ (match_operand:SF 3 "register_operand" "r")) ++ (match_operand:SF 1 "register_operand" "r")))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "fnmac.s\t%0, %1, %2, %3" ++ [(set_attr "length" "4") ++ (set_attr "type" "fmul")]) ++ ++(define_insn "msubacsf3" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (minus:SF (match_operand:SF 3 "register_operand" "r") ++ (mult:SF (match_operand:SF 1 "register_operand" "r") ++ (match_operand:SF 2 "register_operand" "r"))))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "fmsc.s\t%0, %3, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "fmul")]) ++ ++(define_insn "nmsubacsf3" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "r") ++ (match_operand:SF 2 "register_operand" "r"))) ++ (match_operand:SF 3 "register_operand" "r")))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "fnmsc.s\t%0, %3, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "fmul")]) ++ ++(define_insn "addsf3" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (plus:SF (match_operand:SF 1 "register_operand" "%r") ++ (match_operand:SF 2 "register_operand" "r")))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "fadd.s\t%0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "fmul")]) ++ ++(define_insn "subsf3" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (minus:SF (match_operand:SF 1 "register_operand" "r") ++ (match_operand:SF 2 "register_operand" "r")))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "fsub.s\t%0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "fmul")]) ++ ++(define_insn "fixuns_truncsfsi2" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "fcastrs.uw\t%0, %1" ++ [(set_attr "length" "4")]) ++ ++(define_insn "fix_truncsfsi2" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (fix:SI (match_operand:SF 1 "register_operand" "r")))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "fcastrs.sw\t%0, %1" ++ [(set_attr "length" "4")]) ++ ++(define_insn "floatunssisf2" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (unsigned_float:SF (match_operand:SI 1 "register_operand" "r")))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "fcastuw.s\t%0, %1" ++ [(set_attr "length" "4")]) ++ ++(define_insn "floatsisf2" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (float:SF (match_operand:SI 1 "register_operand" "r")))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "fcastsw.s\t%0, %1" ++ [(set_attr "length" "4")]) ++ ++(define_insn "cmpsf_internal_uc3fp" ++ [(set (cc0) ++ (compare:CC ++ (match_operand:SF 0 "register_operand" "r") ++ (match_operand:SF 1 "register_operand" "r")))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ { ++ if (!rtx_equal_p(cc_prev_status.mdep.value, SET_SRC(PATTERN (insn))) ) ++ return "fcmp.s\t%0, %1"; ++ return ""; ++ } ++ [(set_attr "length" "4") ++ (set_attr "cc" "compare")]) ++ ++(define_expand "divsf3" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (div:SF (match_operand:SF 1 "register_operand" "r") ++ (match_operand:SF 2 "register_operand" "r")))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations" ++ "{ ++ emit_insn(gen_frcpa_internal(operands[0],operands[2])); ++ emit_insn(gen_mulsf3(operands[0],operands[0],operands[1])); ++ DONE; ++ }" ++) ++ ++(define_insn "frcpa_internal" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (unspec:SF [(match_operand:SF 1 "register_operand" "r")] UNSPEC_FRCPA))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "frcpa.s %0,%1" ++ [(set_attr "length" "4")]) ++ ++(define_expand "sqrtsf2" ++ [(set (match_operand:SF 0 "register_operand" "") ++ (sqrt:SF (match_operand:SF 1 "register_operand" "")))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations" ++ " ++{ ++ rtx scratch = gen_reg_rtx (SFmode); ++ emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode))); ++ emit_insn (gen_divsf3(operands[0], force_reg (SFmode, CONST1_RTX (SFmode)), ++ scratch)); ++ DONE; ++}") ++ ++(define_insn "rsqrtsf2" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (div:SF (match_operand:SF 2 "const_1f_operand" "F") ++ (sqrt:SF (match_operand:SF 1 "register_operand" "?r"))))] ++ "TARGET_ARCH_FPU && TARGET_HARD_FLOAT" ++ "frsqrta.s %1, %0") +--- /dev/null +++ b/gcc/config/avr32/uclinux-elf.h @@ -0,0 +1,20 @@ + @@ -21291,13 +21220,13 @@ address of non-fixed mapped segments by a (relatively) small amount. --- a/gcc/config.gcc +++ b/gcc/config.gcc -@@ -834,6 +834,24 @@ +@@ -834,6 +834,24 @@ avr-*-*) tm_file="avr/avr.h dbxelf.h" use_fixproto=yes ;; +avr32*-*-linux*) + tm_file="dbxelf.h elfos.h linux.h avr32/linux-elf.h avr32/avr32.h " -+ tmake_file="t-linux avr32/t-avr32 avr32/t-elf" ++ tmake_file="t-linux avr32/t-avr32-linux" + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" + extra_modes=avr32/avr32-modes.def + gnu_ld=yes @@ -21316,7 +21245,7 @@ bfin*-elf*) tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h" tmake_file=bfin/t-bfin-elf -@@ -2950,6 +2968,32 @@ +@@ -2950,6 +2968,32 @@ case "${target}" in fi ;; @@ -21351,7 +21280,7 @@ case "$with_cpu" in --- a/gcc/configure.ac +++ b/gcc/configure.ac -@@ -2174,10 +2174,9 @@ +@@ -2174,10 +2174,9 @@ L2:], as_ver=`$gcc_cv_as --version 2>/dev/null | sed 1q` if echo "$as_ver" | grep GNU > /dev/null; then changequote(,)dnl @@ -21365,7 +21294,7 @@ changequote([,])dnl if test $as_major -eq 2 && test $as_minor -lt 11 then : -@@ -3077,7 +3076,7 @@ +@@ -3077,7 +3076,7 @@ esac case "$target" in i?86*-*-* | mips*-*-* | alpha*-*-* | powerpc*-*-* | sparc*-*-* | m68*-*-* \ | x86_64*-*-* | hppa*-*-* | arm*-*-* | strongarm*-*-* | xscale*-*-* \ @@ -21376,7 +21305,7 @@ ia64*-*-* | s390*-*-*) --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi -@@ -2336,7 +2336,7 @@ +@@ -2336,7 +2336,7 @@ This attribute is ignored for R8C target @item interrupt @cindex interrupt handler functions @@ -21385,7 +21314,7 @@ and Xstormy16 ports to indicate that the specified function is an interrupt handler. The compiler will generate function entry and exit sequences suitable for use in an interrupt handler when this attribute -@@ -2356,6 +2356,15 @@ +@@ -2356,6 +2356,15 @@ void f () __attribute__ ((interrupt ("IR Permissible values for this parameter are: IRQ, FIQ, SWI, ABORT and UNDEF@. @@ -21401,7 +21330,7 @@ On ARMv7-M the interrupt type is ignored, and the attribute means the function may be called with a word aligned stack pointer. -@@ -3925,6 +3934,23 @@ +@@ -3925,6 +3934,23 @@ placed in either the @code{.bss_below100 @end table @@ -21425,7 +21354,7 @@ @subsection AVR Variable Attributes @table @code -@@ -6708,6 +6734,7 @@ +@@ -6708,6 +6734,7 @@ instructions, but allow the compiler to * Alpha Built-in Functions:: * ARM iWMMXt Built-in Functions:: * ARM NEON Intrinsics:: @@ -21433,7 +21362,15 @@ * Blackfin Built-in Functions:: * FR-V Built-in Functions:: * X86 Built-in Functions:: -@@ -6955,6 +6982,74 @@ +@@ -6947,6 +6974,7 @@ long long __builtin_arm_wxor (long long, + long long __builtin_arm_wzero () + @end smallexample + ++ + @node ARM NEON Intrinsics + @subsection ARM NEON Intrinsics + +@@ -6955,6 +6983,74 @@ when the @option{-mfpu=neon} switch is u @include arm-neon-intrinsics.texi @@ -21510,7 +21447,7 @@ --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi -@@ -195,7 +195,7 @@ +@@ -195,7 +195,7 @@ in the following sections. -fvisibility-ms-compat @gol -Wabi -Wctor-dtor-privacy @gol -Wnon-virtual-dtor -Wreorder @gol @@ -21519,7 +21456,7 @@ -Wno-non-template-friend -Wold-style-cast @gol -Woverloaded-virtual -Wno-pmf-conversions @gol -Wsign-promo} -@@ -609,6 +609,12 @@ +@@ -609,6 +609,12 @@ Objective-C and Objective-C++ Dialects}. -mauto-incdec -minmax -mlong-calls -mshort @gol -msoft-reg-count=@var{count}} @@ -21532,7 +21469,7 @@ @emph{MCore Options} @gccoptlist{-mhardlit -mno-hardlit -mdiv -mno-div -mrelax-immediates @gol -mno-relax-immediates -mwide-bitfields -mno-wide-bitfields @gol -@@ -3163,13 +3169,11 @@ +@@ -3163,13 +3169,11 @@ requiring @option{-O}. If you want to warn about code which uses the uninitialized value of the variable in its own initializer, use the @option{-Winit-self} option. @@ -21551,7 +21488,7 @@ Note that there may be no warning about a variable that is used only to compute a value that itself is never used, because such -@@ -7034,10 +7038,6 @@ +@@ -7034,10 +7038,6 @@ If number of candidates in the set is sm we always try to remove unnecessary ivs from the set during its optimization when a new iv is added to the set. @@ -21562,7 +21499,7 @@ @item omega-max-vars The maximum number of variables in an Omega constraint system. The default value is 128. -@@ -8363,6 +8363,7 @@ +@@ -8363,6 +8363,7 @@ platform. * ARC Options:: * ARM Options:: * AVR Options:: @@ -21570,7 +21507,7 @@ * Blackfin Options:: * CRIS Options:: * CRX Options:: -@@ -8834,6 +8835,120 @@ +@@ -8834,6 +8835,129 @@ comply to the C standards, but it will p size. @end table @@ -21646,27 +21583,36 @@ +@samp{uc3b0128}, +@samp{uc3b0256}, +@samp{uc3b0256es}, ++@samp{uc3b0512}, +@samp{uc3b0512revc}, +@samp{uc3b164}, +@samp{uc3b1128}, +@samp{uc3b1256}, +@samp{uc3b1256es}, ++@samp{uc3b1512} +@samp{uc3b1512revc} -+@samp{uc3c0512c}, -+@samp{uc3c0256c}, -+@samp{uc3c0128c}, ++@samp{uc3c0512crevc}, ++@samp{uc3c1512crevc}, ++@samp{uc3c2512crevc}, ++@samp{uc3l0256}, ++@samp{uc3l0128}, ++@samp{uc3l064}, ++@samp{uc3l032}, ++@samp{uc3l016}, ++@samp{uc3l064revb}, +@samp{uc3c064c}, -+@samp{uc3c1512c}, -+@samp{uc3c1256c}, -+@samp{uc3c1128c}, ++@samp{uc3c0128c}, ++@samp{uc3c0256c}, ++@samp{uc3c0512c}, +@samp{uc3c164c}, -+@samp{uc3c2512c}, -+@samp{uc3c2256c}, -+@samp{uc3c2128c}, ++@samp{uc3c1128c}, ++@samp{uc3c1256c}, ++@samp{uc3c1512c}, +@samp{uc3c264c}, -+@samp{uc3l064}, -+@samp{uc3l032}, -+@samp{uc3l016}. ++@samp{uc3c2128c}, ++@samp{uc3c2256c}, ++@samp{uc3c2512c}, ++@samp{mxt768e}. + +@item -mcpu=@var{cpu-type} +@opindex mcpu @@ -21691,7 +21637,7 @@ @node Blackfin Options @subsection Blackfin Options @cindex Blackfin Options -@@ -8889,29 +9004,12 @@ +@@ -8889,29 +9013,12 @@ When enabled, the compiler will ensure t contain speculative loads after jump instructions. If this option is used, @code{__WORKAROUND_SPECULATIVE_LOADS} is defined. @@ -21721,7 +21667,7 @@ @item -mstack-check-l1 @opindex mstack-check-l1 -@@ -8925,11 +9023,6 @@ +@@ -8925,11 +9032,6 @@ This allows for execute in place and sha without virtual memory management. This option implies @option{-fPIC}. With a @samp{bfin-elf} target, this option implies @option{-msim}. @@ -21733,7 +21679,7 @@ @item -mleaf-id-shared-library @opindex mleaf-id-shared-library Generate code that supports shared libraries via the library ID method, -@@ -8971,11 +9064,6 @@ +@@ -8971,11 +9073,6 @@ call on this register. This switch is n will lie outside of the 24 bit addressing range of the offset based version of subroutine call instruction. @@ -21747,7 +21693,15 @@ Link with the fast floating-point library. This library relaxes some of --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi -@@ -1681,6 +1681,58 @@ +@@ -3,6 +3,7 @@ + @c This is part of the GCC manual. + @c For copying conditions, see the file gcc.texi. + ++ + @ifset INTERNALS + @node Machine Desc + @chapter Machine Descriptions +@@ -1681,6 +1682,58 @@ A memory reference suitable for iWMMXt l A memory reference suitable for the ARMv4 ldrsb instruction. @end table @@ -21808,7 +21762,7 @@ @item l --- a/gcc/expmed.c +++ b/gcc/expmed.c -@@ -463,9 +463,9 @@ +@@ -463,9 +463,9 @@ store_bit_field_1 (rtx str_rtx, unsigned ? ((GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD || GET_MODE_SIZE (GET_MODE (op0)) == GET_MODE_SIZE (fieldmode)) && byte_offset % GET_MODE_SIZE (fieldmode) == 0) @@ -21822,7 +21776,7 @@ op0 = adjust_address (op0, fieldmode, offset); --- a/gcc/expr.c +++ b/gcc/expr.c -@@ -52,6 +52,7 @@ +@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. #include "tree-flow.h" #include "target.h" #include "timevar.h" @@ -21830,7 +21784,7 @@ #include "df.h" #include "diagnostic.h" -@@ -3620,16 +3621,17 @@ +@@ -3620,16 +3621,17 @@ emit_single_push_insn (enum machine_mode } else { @@ -21855,7 +21809,7 @@ } dest = gen_rtx_MEM (mode, dest_addr); -@@ -5739,7 +5741,8 @@ +@@ -5739,7 +5741,8 @@ store_field (rtx target, HOST_WIDE_INT b is a bit field, we cannot use addressing to access it. Use bit-field techniques or SUBREG to store in it. */ @@ -21865,7 +21819,7 @@ || (mode != BLKmode && ! direct_store[(int) mode] && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT) -@@ -5896,7 +5899,19 @@ +@@ -5896,7 +5899,18 @@ get_inner_reference (tree exp, HOST_WIDE { tree field = TREE_OPERAND (exp, 1); size_tree = DECL_SIZE (field); @@ -21878,15 +21832,14 @@ + access operation. But for volatile bitfields we do + not allow this when targetm.narrow_volatile_bitfield () + is false. We can use DECL_C_BIT_FIELD to check if this -+ really is a c-bitfield. */ ++ really is a c-bitfield. */ + && !(TREE_THIS_VOLATILE (exp) + && !targetm.narrow_volatile_bitfield () + && DECL_C_BIT_FIELD (field)) ) -+ mode = DECL_MODE (field); else if (DECL_MODE (field) == BLKmode) blkmode_bitfield = true; -@@ -7889,7 +7904,8 @@ +@@ -7889,7 +7903,8 @@ expand_expr_real_1 (tree exp, rtx target by doing the extract into an object as wide as the field (which we know to be the width of a basic mode), then storing into memory, and changing the mode to BLKmode. */ @@ -21898,7 +21851,7 @@ && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT --- a/gcc/function.c +++ b/gcc/function.c -@@ -2715,7 +2715,11 @@ +@@ -2715,7 +2715,11 @@ assign_parm_setup_reg (struct assign_par SET_DECL_RTL (parm, parmreg); /* Copy the value into the register. */ @@ -21913,7 +21866,7 @@ int save_tree_used; --- a/gcc/genemit.c +++ b/gcc/genemit.c -@@ -121,6 +121,24 @@ +@@ -121,6 +121,24 @@ max_operand_vec (rtx insn, int arg) } static void @@ -21938,7 +21891,7 @@ print_code (RTX_CODE code) { const char *p1; -@@ -406,18 +424,16 @@ +@@ -406,18 +424,16 @@ gen_insn (rtx insn, int lineno) fatal ("match_dup operand number has no match_operand"); /* Output the function name and argument declarations. */ @@ -21963,7 +21916,7 @@ /* Output code to construct and return the rtl for the instruction body. */ if (XVECLEN (insn, 1) == 1) -@@ -461,16 +477,12 @@ +@@ -461,16 +477,12 @@ gen_expand (rtx expand) operands = max_operand_vec (expand, 1); /* Output the function name and argument declarations. */ @@ -21984,7 +21937,7 @@ printf ("{\n"); /* If we don't have any C code to write, only one insn is being written, -@@ -480,6 +492,8 @@ +@@ -480,6 +492,8 @@ gen_expand (rtx expand) && operands > max_dup_opno && XVECLEN (expand, 1) == 1) { @@ -21993,7 +21946,7 @@ printf (" return "); gen_exp (XVECEXP (expand, 1, 0), DEFINE_EXPAND, NULL); printf (";\n}\n\n"); -@@ -493,6 +507,7 @@ +@@ -493,6 +507,7 @@ gen_expand (rtx expand) for (; i <= max_scratch_opno; i++) printf (" rtx operand%d ATTRIBUTE_UNUSED;\n", i); printf (" rtx _val = 0;\n"); @@ -22003,7 +21956,7 @@ /* The fourth operand of DEFINE_EXPAND is some code to be executed --- a/gcc/genflags.c +++ b/gcc/genflags.c -@@ -127,7 +127,6 @@ +@@ -127,7 +127,6 @@ static void gen_proto (rtx insn) { int num = num_operands (insn); @@ -22011,7 +21964,7 @@ const char *name = XSTR (insn, 0); int truth = maybe_eval_c_test (XSTR (insn, 2)); -@@ -158,12 +157,7 @@ +@@ -158,12 +157,7 @@ gen_proto (rtx insn) if (num == 0) fputs ("void", stdout); else @@ -22025,7 +21978,7 @@ puts (");"); -@@ -173,12 +167,7 @@ +@@ -173,12 +167,7 @@ gen_proto (rtx insn) { printf ("static inline rtx\ngen_%s", name); if (num > 0) @@ -22041,7 +21994,7 @@ puts ("{\n return 0;\n}"); --- a/gcc/genoutput.c +++ b/gcc/genoutput.c -@@ -386,7 +386,7 @@ +@@ -386,7 +386,7 @@ output_insn_data (void) } if (d->name && d->name[0] != '*') @@ -22052,7 +22005,7 @@ --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c -@@ -81,7 +81,7 @@ +@@ -81,7 +81,7 @@ static int num_possible_if_blocks; static int num_updated_if_blocks; /* # of changes made. */ @@ -22061,7 +22014,7 @@ /* Whether conditional execution changes were made. */ static int cond_exec_changed_p; -@@ -286,6 +286,9 @@ +@@ -286,6 +286,9 @@ cond_exec_process_insns (ce_if_block_t * if (must_be_last) return FALSE; @@ -22071,7 +22024,7 @@ if (modified_in_p (test, insn)) { if (!mod_ok) -@@ -566,15 +569,18 @@ +@@ -566,15 +569,18 @@ cond_exec_process_if_block (ce_if_block_ IFCVT_MODIFY_FINAL (ce_info); #endif @@ -22091,7 +22044,7 @@ fail: #ifdef IFCVT_MODIFY_CANCEL -@@ -1080,7 +1086,11 @@ +@@ -1080,7 +1086,11 @@ noce_try_addcc (struct noce_if_info *if_ != UNKNOWN)) { rtx cond = if_info->cond; @@ -22104,7 +22057,7 @@ /* First try to use addcc pattern. */ if (general_operand (XEXP (cond, 0), VOIDmode) -@@ -3017,7 +3027,12 @@ +@@ -3017,7 +3027,12 @@ find_if_header (basic_block test_bb, int && noce_find_if_block (test_bb, then_edge, else_edge, pass)) goto success; @@ -22118,7 +22071,7 @@ && cond_exec_find_if_block (&ce_info)) goto success; -@@ -3132,7 +3147,11 @@ +@@ -3132,7 +3147,11 @@ cond_exec_find_if_block (struct ce_if_bl /* We only ever should get here after reload, and only if we have conditional execution. */ @@ -22130,7 +22083,7 @@ /* Discover if any fall through predecessors of the current test basic block were && tests (which jump to the else block) or || tests (which jump to -@@ -4226,6 +4245,14 @@ +@@ -4226,6 +4245,14 @@ gate_handle_if_after_reload (void) static unsigned int rest_of_handle_if_after_reload (void) { @@ -22147,7 +22100,7 @@ } --- a/gcc/longlong.h +++ b/gcc/longlong.h -@@ -239,6 +239,41 @@ +@@ -239,6 +239,41 @@ UDItype __umulsidi3 (USItype, USItype); #define UDIV_TIME 100 #endif /* __arm__ */ @@ -22191,7 +22144,7 @@ #if __CRIS_arch_version >= 8 --- a/gcc/optabs.h +++ b/gcc/optabs.h -@@ -586,7 +586,7 @@ +@@ -586,7 +586,7 @@ extern enum insn_code reload_out_optab[N extern optab code_to_optab[NUM_RTX_CODE + 1]; @@ -22200,9 +22153,80 @@ /* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...) gives the gen_function to make a branch to test that condition. */ +--- a/gcc/regrename.c ++++ b/gcc/regrename.c +@@ -1580,6 +1580,9 @@ copyprop_hardreg_forward_1 (basic_block + bool changed = false; + rtx insn; + ++ rtx prev_pred_test; ++ int prev_pred_insn_skipped = 0; ++ + for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn)) + { + int n_ops, i, alt, predicated; +@@ -1619,6 +1622,58 @@ copyprop_hardreg_forward_1 (basic_block + recog_data.operand_type[i] = OP_INOUT; + } + ++ ++ /* Added for targets (AVR32) which supports test operands to be modified ++ in cond_exec instruction. For these targets we cannot make a change to ++ the test operands if one of the test operands is an output operand This beacuse ++ changing the test operands might cause the need for inserting a new test ++ insns in the middle of a sequence of cond_exec insns and if the test operands ++ are modified these tests will fail. ++ */ ++ if ( IFCVT_ALLOW_MODIFY_TEST_IN_INSN ++ && predicated ) ++ { ++ int insn_skipped = 0; ++ rtx test = COND_EXEC_TEST (PATTERN (insn)); ++ ++ /* Check if the previous insn was a skipped predicated insn with the same ++ test as this predicated insns. If so we cannot do any modification to ++ this insn either since we cannot emit the test insn because the operands ++ are clobbered. */ ++ if ( prev_pred_insn_skipped ++ && (rtx_equal_p (test, prev_pred_test) ++ || rtx_equal_p (test, reversed_condition (prev_pred_test))) ) ++ { ++ insn_skipped = 1; ++ } ++ else ++ { ++ /* Check if the output operand is used in the test expression. */ ++ for (i = 0; i < n_ops; ++i) ++ if ( recog_data.operand_type[i] == OP_INOUT ++ && reg_mentioned_p (recog_data.operand[i], test) ) ++ { ++ insn_skipped = 1; ++ break; ++ } ++ ++ } ++ ++ prev_pred_test = test; ++ prev_pred_insn_skipped = insn_skipped; ++ if ( insn_skipped ) ++ { ++ if (insn == BB_END (bb)) ++ break; ++ else ++ continue; ++ } ++ } ++ else ++ { ++ prev_pred_insn_skipped = 0; ++ } ++ + /* For each earlyclobber operand, zap the value data. */ + for (i = 0; i < n_ops; i++) + if (recog_op_alt[i][alt].earlyclobber) --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c -@@ -1406,7 +1406,14 @@ +@@ -1406,7 +1406,14 @@ fixup_sched_groups (rtx insn) prev_nonnote = prev_nonnote_insn (insn); if (BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (prev_nonnote) @@ -22218,7 +22242,7 @@ add_dependence (insn, prev_nonnote, REG_DEP_ANTI); } -@@ -1905,8 +1912,29 @@ +@@ -1905,8 +1912,29 @@ sched_analyze_insn (struct deps *deps, r if (code == COND_EXEC) { @@ -22272,7 +22296,7 @@ /* { dg-options "-O2 -foptimize-sibling-calls" } */ --- a/gcc/testsuite/gcc.dg/trampoline-1.c +++ b/gcc/testsuite/gcc.dg/trampoline-1.c -@@ -46,6 +46,8 @@ +@@ -46,6 +46,8 @@ void foo (void) int main (void) { @@ -22294,10 +22318,15 @@ // different sentry variables for construction and destruction. --- a/libgcc/config.host +++ b/libgcc/config.host -@@ -240,6 +240,8 @@ +@@ -240,6 +240,13 @@ arm-*-pe*) ;; arm*-*-kaos*) ;; ++avr32-*-linux*) ++ # No need to build crtbeginT.o on uClibc systems. Should probably be ++ # moved to the OS specific section above. ++ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" ++ ;; +avr32-*-*) + ;; avr-*-rtems*) @@ -22314,7 +22343,7 @@ /** @file ctype_base.h * This is an internal header file, included by other library headers. -@@ -45,7 +47,11 @@ +@@ -45,7 +47,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) struct ctype_base { // Non-standard typedefs. @@ -22328,7 +22357,7 @@ // on the mask type. Because of this, we don't use an enum. --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in -@@ -36,6 +36,7 @@ +@@ -36,6 +36,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @@ -22338,7 +22367,7 @@ subdir = include --- a/libstdc++-v3/libmath/Makefile.in +++ b/libstdc++-v3/libmath/Makefile.in -@@ -37,6 +37,7 @@ +@@ -37,6 +37,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @@ -22348,7 +22377,7 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 --- a/libstdc++-v3/libsupc++/Makefile.in +++ b/libstdc++-v3/libsupc++/Makefile.in -@@ -38,6 +38,7 @@ +@@ -38,6 +38,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @@ -22358,7 +22387,7 @@ subdir = libsupc++ --- a/libstdc++-v3/Makefile.in +++ b/libstdc++-v3/Makefile.in -@@ -36,6 +36,7 @@ +@@ -36,6 +36,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @@ -22368,7 +22397,7 @@ $(srcdir)/Makefile.am $(top_srcdir)/configure \ --- a/libstdc++-v3/po/Makefile.in +++ b/libstdc++-v3/po/Makefile.in -@@ -36,6 +36,7 @@ +@@ -36,6 +36,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @@ -22378,7 +22407,7 @@ subdir = po --- a/libstdc++-v3/src/Makefile.in +++ b/libstdc++-v3/src/Makefile.in -@@ -37,6 +37,7 @@ +@@ -37,6 +37,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@