Moin guys, this little patch improves 16*8 multiplication to some degree.
The FSF did'n yet send the assignment papers, but maybe the stuff is still useful all the same.
cheers Georg-Johann
Index: avr.md =================================================================== --- avr.md (Revision 147721) +++ avr.md (Arbeitskopie) @@ -980,18 +980,31 @@ (define_expand "mulhi3" [(set (match_operand:HI 0 "register_operand" "") (mult:HI (match_operand:HI 1 "register_operand" "") - (match_operand:HI 2 "register_operand" "")))] + (match_operand:HI 2 "nonmemory_operand" "")))] "" " { if (!AVR_HAVE_MUL) { + if (!register_operand (operands[2], HImode)) + operands[2] = copy_to_mode_reg (HImode, operands[2]); emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2])); DONE; } + else if (immediate_operand (operands[2], HImode)) + { + enum machine_mode mode = (satisfies_constraint_M (operands[2])) ? QImode : HImode; + + operands[2] = force_reg (mode, operands[2]); + if (HImode == mode) + emit_insn (gen_mulhi3_enh (operands[0], operands[1], operands[2])); + else + emit_insn (gen_umulhi3_enh_zerox (operands[0], operands[2], operands[1])); + DONE; + } }") -(define_insn "*mulhi3_enh" +(define_insn "mulhi3_enh" [(set (match_operand:HI 0 "register_operand" "=&r") (mult:HI (match_operand:HI 1 "register_operand" "r") (match_operand:HI 2 "register_operand" "r")))] @@ -1006,6 +1019,19 @@ [(set_attr "length" "7") (set_attr "cc" "clobber")]) +(define_insn "umulhi3_enh_zerox" + [(set (match_operand:HI 0 "register_operand" "=&r") + (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) + (match_operand:HI 2 "register_operand" "r")))] + "AVR_HAVE_MUL" + "mul %A2,%1 + movw %0,r0 + mul %B2,%1 + add %B0,r0 + clr r1" + [(set_attr "length" "5") + (set_attr "cc" "clobber")]) + (define_expand "mulhi3_call" [(set (reg:HI 24) (match_operand:HI 1 "register_operand" "")) (set (reg:HI 22) (match_operand:HI 2 "register_operand" "")) Index: avr.c =================================================================== --- avr.c (Revision 147721) +++ avr.c (Arbeitskopie) @@ -45,6 +45,7 @@ #include "target-def.h" #include "params.h" #include "df.h" +#include "tm-constrs.h" /* Maximal allowed offset for an address in the LD command */ #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE)) @@ -5055,6 +5056,14 @@ avr_operand_rtx_cost (rtx x, enum machin case CONST_DOUBLE: return COSTS_N_INSNS (GET_MODE_SIZE (mode)); + case ZERO_EXTEND: + if (HImode == mode + && MULT == outer) + { + return 0; + } + break; + default: break; } @@ -5203,7 +5212,7 @@ avr_rtx_costs (rtx x, int code, int oute { case QImode: if (AVR_HAVE_MUL) - *total = COSTS_N_INSNS (!speed ? 3 : 4); + *total = COSTS_N_INSNS (!speed ? 3 : 4); else if (!speed) *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1); else @@ -5212,7 +5221,18 @@ avr_rtx_costs (rtx x, int code, int oute case HImode: if (AVR_HAVE_MUL) - *total = COSTS_N_INSNS (!speed ? 7 : 10); + { + if (ZERO_EXTEND == GET_CODE (XEXP (x, 0)) + && ZERO_EXTEND == GET_CODE (XEXP (x, 1))) + *total = COSTS_N_INSNS (!speed ? 3 : 4); + else if (satisfies_constraint_M (XEXP (x, 0)) + || satisfies_constraint_M (XEXP (x, 1)) + || ZERO_EXTEND == GET_CODE (XEXP (x, 0)) + || ZERO_EXTEND == GET_CODE (XEXP (x, 1))) + *total = COSTS_N_INSNS (!speed ? 5 : 6); + else + *total = COSTS_N_INSNS (!speed ? 7 : 10); + } else if (!speed) *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1); else @@ -5313,8 +5333,10 @@ avr_rtx_costs (rtx x, int code, int oute case 9: *total = COSTS_N_INSNS (3); break; - case 2: case 3: + *total = COSTS_N_INSNS (!speed ? 4 : 6); + break; + case 2: case 10: case 15: *total = COSTS_N_INSNS (4);
_______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list