Hi all, I believe the decision to use UNSPEC_CMP and UNSPEC_CMPU for microblaze compare instructions stems from the conversation in this thread from 2009;
http://gcc.gnu.org/ml/gcc/2009-12/msg00283.html This makes sense, because if I use code attributes and iterators to extend the compare insn as so; (define_code_iterator any_cmp [gt ge lt le gtu geu ltu leu]) ;; <u> expands to an empty string when doing a signed operation and ;; "u" when doing an unsigned operation. (define_code_attr u [(gt "") (gtu "u") (ge "") (geu "u") (lt "") (ltu "u") (le "") (leu "u")]) (define_insn "cmp<u>_<code>" [(set (match_operand:SI 0 "register_operand" "=d") (any_cmp:SI (match_operand:SI 1 "register_operand") (match_operand:SI 2 "register_operand")))] "" "cmp<u>\t%0,%1,%2" [(set_attr "type" "arith") (set_attr "mode" "SI") (set_attr "length" "4")]) They look ok; (insn 29 27 30 5 (set (reg:SI 67) (gt:SI (reg/v:SI 55 [ N ]) (reg/v:SI 51 [ j ]))) ../core_matrix_min.c:6 63 {cmp_gt} (nil)) (jump_insn 30 29 31 5 (set (pc) (if_then_else (lt:SI (reg:SI 67) (const_int 0 [0])) (label_ref 28) (pc))) ../core_matrix_min.c:6 72 {branch_zero} (expr_list:REG_BR_PROB (const_int 9100 [0x238c]) (nil)) -> 28) and code generated at -O0 is correct. But then I see that during CSE optimization, the instructions are trashed; starting the processing of deferred insns deleting insn with uid = 16. deleting insn with uid = 17. deleting insn with uid = 28. deleting insn with uid = 29. deleting insn with uid = 30. Looking back at the gcc 4.1.2 implementation, we had a branch_compare which carried out the compare and branching in one instruction; (define_insn "branch_compare" [(set (pc) (if_then_else (match_operator:SI 0 "cmp_op" [(match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d") ]) (match_operand:SI 3 "pc_or_label_operand" "") (match_operand:SI 4 "pc_or_label_operand" ""))) (clobber(reg:SI R_TMP))] "" { if (operands[3] != pc_rtx) { /* normal jump */ switch (GET_CODE (operands[0])) { case GT: return "cmp\tr18,%z1,%z2\;blti%?\tr18,%3 #GT"; case LE: return "cmp\tr18,%z1,%z2\;bgei%?\tr18,%3"; case GE: return "cmp\tr18,%z2,%z1\;bgei%?\tr18,%3"; case LT: return "cmp\tr18,%z2,%z1\;blti%?\tr18,%3 #LT"; case GTU:return "cmpu\tr18,%z1,%z2\;blti%?\tr18,%3 #GTU"; case LEU:return "cmpu\tr18,%z1,%z2\;bgei%?\tr18,%3"; case GEU:return "cmpu\tr18,%z2,%z1\;bgei%?\tr18,%3"; case LTU:return "cmpu\tr18,%z2,%z1\;blti%?\tr18,%3 #LTU"; .... Is this method still valid and considered acceptable in a modern gcc? thanks, David On 8 January 2013 15:59, David Holsgrove <david.holsgr...@xilinx.com> wrote: > Loop unrolling (-funroll-loops) for microblaze is ineffectual on the gcc > 4.6/4.7/4.8 branches. > > This previously worked on an out of tree gcc 4.1.2, and I believe the relevant > diff to be the use of UNSPEC_CMP and UNSPEC_CMPU to create two unique > instructions for signed_compare and unsigned_compare in microblaze's machine > description, which means that the iv_analyze_expr in loop-iv.c of the compare > instruction is unable to understand the expression. > > Details follow below, > > thanks, > David >