https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77308
--- Comment #13 from Bernd Edlinger <bernd.edlinger at hotmail dot de> --- I am still trying to understand why thumb1 seems to outperform thumb2. Obviously thumb1 does not have the shiftdi3 pattern, but even if I remove these from thumb2, the result is still not par with thumb2. Apparently other patterns still produce di values that are not enabled with thumb1, they are xordi3 and anddi3, these are often used. Then there is adddi3 that is enabled in thumb1 and thumb2, I also disabled this one, and now the sha512 gets down to inclredible 1152 bytes frame (-Os -march=armv7 -mthumb -float-abi=soft): I know this is a hack, but 1K stack is what we should expect... --- arm.md 2016-10-25 19:54:16.425736721 +0200 +++ arm.md.orig 2016-10-17 19:46:59.000000000 +0200 @@ -448,7 +448,7 @@ (plus:DI (match_operand:DI 1 "s_register_operand" "") (match_operand:DI 2 "arm_adddi_operand" ""))) (clobber (reg:CC CC_REGNUM))])] - "TARGET_EITHER && !TARGET_THUMB2" + "TARGET_EITHER" " if (TARGET_THUMB1) { @@ -465,7 +465,7 @@ (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r") (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT && !TARGET_NEON && !TARGET_THUMB2" + "TARGET_32BIT && !TARGET_NEON" "#" "TARGET_32BIT && reload_completed && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))" @@ -2256,7 +2256,7 @@ [(set (match_operand:DI 0 "s_register_operand" "") (and:DI (match_operand:DI 1 "s_register_operand" "") (match_operand:DI 2 "neon_inv_logic_op2" "")))] - "TARGET_32BIT && !TARGET_THUMB2" + "TARGET_32BIT" "" ) @@ -2264,7 +2264,7 @@ [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w") (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0") (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))] - "TARGET_32BIT && !TARGET_IWMMXT && !TARGET_THUMB2" + "TARGET_32BIT && !TARGET_IWMMXT" { switch (which_alternative) { @@ -3310,7 +3310,7 @@ [(set (match_operand:DI 0 "s_register_operand" "") (xor:DI (match_operand:DI 1 "s_register_operand" "") (match_operand:DI 2 "arm_xordi_operand" "")))] - "TARGET_32BIT && !TARGET_THUMB2" + "TARGET_32BIT" "" ) @@ -3318,7 +3318,7 @@ [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w") (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w") (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))] - "TARGET_32BIT && !TARGET_IWMMXT && !TARGET_THUMB2" + "TARGET_32BIT && !TARGET_IWMMXT" { switch (which_alternative) { @@ -3983,7 +3983,7 @@ [(set (match_operand:DI 0 "s_register_operand" "") (ashift:DI (match_operand:DI 1 "s_register_operand" "") (match_operand:SI 2 "general_operand" "")))] - "TARGET_32BIT && !TARGET_THUMB2" + "TARGET_32BIT" " if (TARGET_NEON) { @@ -4058,7 +4058,7 @@ [(set (match_operand:DI 0 "s_register_operand" "") (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "") (match_operand:SI 2 "reg_or_int_operand" "")))] - "TARGET_32BIT && !TARGET_THUMB2" + "TARGET_32BIT" " if (TARGET_NEON) { What do you think?