Hello. Now cost of moving 1, 2, 4-bytes data from register to register is 2 and cost of moving to/from SP register is increased. But moving 1 byte of data between registers request one MOV instruction ,moving 2 bytes two MOV instruction or one MOVW instruction on devices which have it and etc. I have changed REGISTER_MOVE_COST macro to consider it.
Also cost of register to memory moves is increased by 2 that the GCC prefer register to register moves rather register to memory moves. I have received ~0.6% code size decrease on test projects. I will be grateful for testing and feedback on this patch. Index: gcc/config/avr/avr-protos.h =================================================================== --- gcc/config/avr/avr-protos.h (revision 163854) +++ gcc/config/avr/avr-protos.h (working copy) @@ -38,6 +38,8 @@ extern rtx avr_return_addr_rtx (int count, const_rtx tem); #ifdef TREE_CODE +extern int avr_register_move_cost (enum machine_mode, int, int); +extern int avr_memory_move_cost (enum machine_mode, int, bool); extern void asm_output_external (FILE *file, tree decl, char *name); extern int avr_progmem_p (tree decl, tree attributes); Index: gcc/config/avr/avr.c =================================================================== --- gcc/config/avr/avr.c (revision 163854) +++ gcc/config/avr/avr.c (working copy) @@ -5039,7 +5039,60 @@ reg_alloc_order[i] = order[i]; } +/* Implements REGISTER_MOVE_COST. */ +int +avr_register_move_cost (enum machine_mode mode, + int from, int to) +{ + if (from == STACK_REG) + return 6; + else if (to == STACK_REG) + return 12; + else + { + if (mode == QImode) + return 2; + if (mode == HImode) + { + if (AVR_HAVE_MOVW) + return 2; + else + return 4; + } + if (mode == SImode || mode ==SFmode) + { + if (AVR_HAVE_MOVW) + return 4; + else + return 8; + } + else + { + if (AVR_HAVE_MOVW) + return 8; + else + return 16; + } + } +} + +/* Implements MEMORY_MOVE_COST. */ + +int +avr_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, + int rclass ATTRIBUTE_UNUSED, + bool in ATTRIBUTE_UNUSED) +{ + if (mode == QImode) + return 4; + if (mode == HImode) + return 6; + if (mode == SImode || mode ==SFmode) + return 10; + else + return 18; +} /* Mutually recursive subroutine of avr_rtx_cost for calculating the cost of an RTX operand given its context. X is the rtx of the operand, MODE is its mode, and OUTER is the rtx_code of this Index: gcc/config/avr/avr.h =================================================================== --- gcc/config/avr/avr.h (revision 163854) +++ gcc/config/avr/avr.h (working copy) @@ -462,15 +462,11 @@ #define LEGITIMATE_CONSTANT_P(X) 1 -#define REGISTER_MOVE_COST(MODE, FROM, TO) ((FROM) == STACK_REG ? 6 \ - : (TO) == STACK_REG ? 12 \ - : 2) +#define REGISTER_MOVE_COST(MODE, FROM, TO) \ + avr_register_move_cost ((MODE), (FROM), (TO)) +#define MEMORY_MOVE_COST(MODE, CLASS, IN) \ + avr_memory_move_cost ((MODE), (CLASS), (IN)) -#define MEMORY_MOVE_COST(MODE,CLASS,IN) ((MODE)==QImode ? 2 : \ - (MODE)==HImode ? 4 : \ - (MODE)==SImode ? 8 : \ - (MODE)==SFmode ? 8 : 16) - #define BRANCH_COST(speed_p, predictable_p) 0 #define SLOW_BYTE_ACCESS 0 Anatoly. _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list