I very grateful for your help and wisdom Testcase and MD Patch attached
unsigned long f (unsigned char *P) { unsigned long C; C = ((unsigned long)P[1] << 24) | ((unsigned long)P[2] << 16) | ((unsigned long)P[3] << 8) | ((unsigned long)P[4] << 0); return C; }
Index: avr.md =================================================================== --- avr.md (revision 132380) +++ avr.md (working copy) @@ -251,8 +251,8 @@ (set_attr "cc" "none")]) (define_insn "*movhi" - [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r") - (match_operand:HI 1 "general_operand" "r,m,rL,i,i,r,q"))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,Qm,d,*r,q,r") + (match_operand:HI 1 "general_operand" "r,Qm,rL,i,i,r,q"))] "(register_operand (operands[0],HImode) || register_operand (operands[1],HImode) || const0_rtx == operands[1])" "* return output_movhi (insn, operands, NULL);" @@ -1126,73 +1126,310 @@ [(set_attr "length" "1,1") (set_attr "cc" "set_zn,set_zn")]) -(define_insn "andhi3" - [(set (match_operand:HI 0 "register_operand" "=r,d,r") - (and:HI (match_operand:HI 1 "register_operand" "%0,0,0") - (match_operand:HI 2 "nonmemory_operand" "r,i,M"))) - (clobber (match_scratch:QI 3 "=X,X,&d"))] +(define_mode_iterator HIDI [(HI "") (SI "") (DI "")]) +(define_mode_iterator SIDI [(SI "") (DI "")]) +(define_mode_iterator DIDI [(DI "")]) + +(define_insn_and_split "and<mode>3" +[(set (match_operand:HIDI 0 "register_operand" "=r,d") + (and:HIDI (match_operand:HIDI 1 "register_operand" "%0,0") + (match_operand:HIDI 2 "nonmemory_operand" "r,i"))) + ] "" - "*{ - if (which_alternative==0) - return (AS2 (and,%A0,%A2) CR_TAB - AS2 (and,%B0,%B2)); - else if (which_alternative==1) + "#" + "" + [(const_int 0)] { + int i; + enum machine_mode mode; + mode = GET_MODE(operands[0]); + int size = GET_MODE_SIZE(mode); + if (GET_CODE (operands[2]) == CONST_INT) { - int mask = INTVAL (operands[2]); - if ((mask & 0xff) != 0xff) - output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands); - if ((mask & 0xff00) != 0xff00) - output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands); - return \"\"; + HOST_WIDE_INT x = INTVAL (operands[2]); + + for (i = 0; i < size; i++) + { + rtx dest = simplify_gen_subreg (QImode, operands[0], mode, i); + rtx src1 = simplify_gen_subreg (QImode, operands[1], mode, i); + int byte = (x & 0xff); + rtx src2 = gen_int_mode (byte, QImode); + if (byte == 0x00) + { + emit_move_insn (dest, const0_rtx); } - return (AS2 (andi,%A0,lo8(%2)) CR_TAB - AS2 (andi,%B0,hi8(%2))); + else if (byte == 0xff) + { + emit_move_insn (dest, src1); } - return (AS2 (ldi,%3,lo8(%2)) CR_TAB - AS2 (and,%A0,%3) CR_TAB - AS1 (clr,%B0)); -}" - [(set_attr "length" "2,2,3") - (set_attr "cc" "set_n,clobber,set_n")]) + else + { + emit_move_insn (dest, gen_rtx_AND (QImode, src1, src2)); + } + x= x >> 8; + } + } + else + { + for (i = 0; i < size; i++) + { + rtx dest = simplify_gen_subreg (QImode, operands[0], mode, i); + rtx src1 = simplify_gen_subreg (QImode, operands[1], mode, i); + rtx src2 = simplify_gen_subreg (QImode, operands[2], mode, i); + emit_move_insn (dest, gen_rtx_AND (QImode, src1, src2)); + } + } + DONE; + } + ) + +;(define_insn_and_split "ziorQI3" +;[(set (match_operand:QI 0 "nonimmediate_operand" "=rm") +; (ior:QI (match_operand:QI 1 "general_operand" "0") +; (const_int 0))) +; ] +; "0" +; "#" +; "" +; [(const_int 0)] +; "" +; ) -(define_insn "andsi3" - [(set (match_operand:SI 0 "register_operand" "=r,d") - (and:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "nonmemory_operand" "r,i")))] + +(define_insn_and_split "ior<mode>3" +[(set (match_operand:HIDI 0 "register_operand" "=r,d") + (ior:HIDI (match_operand:HIDI 1 "register_operand" "%0,0") + (match_operand:HIDI 2 "nonmemory_operand" "r,i"))) + ] "" - "*{ - if (which_alternative==0) - return (AS2 (and, %0,%2) CR_TAB - AS2 (and, %B0,%B2) CR_TAB - AS2 (and, %C0,%C2) CR_TAB - AS2 (and, %D0,%D2)); - else if (which_alternative==1) + "#" + "" + [(const_int 0)] { + int i; + enum machine_mode mode; + mode = GET_MODE(operands[0]); + int size = GET_MODE_SIZE(mode); + if (GET_CODE (operands[2]) == CONST_INT) { - HOST_WIDE_INT mask = INTVAL (operands[2]); - if ((mask & 0xff) != 0xff) - output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands); - if ((mask & 0xff00) != 0xff00) - output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands); - if ((mask & 0xff0000L) != 0xff0000L) - output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands); - if ((mask & 0xff000000L) != 0xff000000L) - output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands); - return \"\"; + HOST_WIDE_INT x = INTVAL (operands[2]); + + for (i = 0; i < size; i++) + { + rtx dest = simplify_gen_subreg (QImode, operands[0], mode, i); + rtx src1 = simplify_gen_subreg (QImode, operands[1], mode, i); + int byte = (x & 0xff); + rtx src2 = gen_int_mode (byte, QImode); + if (byte == 0x00) + { + emit_move_insn (dest, src1); } - return (AS2 (andi, %A0,lo8(%2)) CR_TAB - AS2 (andi, %B0,hi8(%2)) CR_TAB - AS2 (andi, %C0,hlo8(%2)) CR_TAB - AS2 (andi, %D0,hhi8(%2))); + else if (byte == 0xff) + { + emit_move_insn (dest, constm1_rtx); } - return \"bug\"; -}" - [(set_attr "length" "4,4") - (set_attr "cc" "set_n,set_n")]) + else + { + emit_move_insn (dest, gen_rtx_IOR (QImode, src1, src2)); + } + x= x >> 8; + } + } + else + { + for (i = 0; i < size; i++) + { + rtx dest = simplify_gen_subreg (QImode, operands[0], mode, i); + rtx src1 = simplify_gen_subreg (QImode, operands[1], mode, i); + rtx src2 = simplify_gen_subreg (QImode, operands[2], mode, i); + emit_move_insn (dest, gen_rtx_IOR (QImode, src1, src2)); + } + } + DONE; + } + ) + +;;need rtl peephole to find NOT patterns???? +;; NEED split for pop/push and fix post_inc bobo +;; +(define_insn_and_split "xor<mode>3" +[(set (match_operand:HIDI 0 "register_operand" "=r") + (xor:HIDI (match_operand:HIDI 1 "register_operand" "%0") + (match_operand:HIDI 2 "register_operand" "r"))) + ] + "" + "#" + "" + [(const_int 0)] + { + int i; + enum machine_mode mode; + mode = GET_MODE(operands[0]); + int size = GET_MODE_SIZE(mode); + + { + for (i = 0; i < size; i++) + { + rtx dest = simplify_gen_subreg (QImode, operands[0], mode, i); + rtx src1 = simplify_gen_subreg (QImode, operands[1], mode, i); + rtx src2 = simplify_gen_subreg (QImode, operands[2], mode, i); + emit_move_insn (dest, gen_rtx_XOR (QImode, src1, src2)); + } + } + DONE; + } + ) + + +(define_insn_and_split "one_cmpl<mode>2" +[(set (match_operand:HIDI 0 "register_operand" "=r") + (not:HIDI (match_operand:HIDI 1 "register_operand" "0")))] + "" + "#" + "" + [(const_int 0)] + { + int i; + enum machine_mode mode; + mode = GET_MODE(operands[0]); + int size = GET_MODE_SIZE(mode); + + { + for (i = 0; i < size; i++) + { + rtx dest = simplify_gen_subreg (QImode, operands[0], mode, i); + rtx src1 = simplify_gen_subreg (QImode, operands[1], mode, i); + emit_move_insn (dest, gen_rtx_NOT (QImode, src1)); + } + } + DONE; + } + ) + +;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x +;; zero extend + + +(define_insn_and_split "zero_extendqi<mode>2" + [(set (match_operand:HIDI 0 "nonimmediate_operand" "") + (zero_extend:HIDI (match_operand:QI 1 "nonimmediate_operand" "")))] + "" + "#" + "" + [(const_int 0)] + " + int i; + enum machine_mode dmode = GET_MODE (operands[0]); + int dsize = GET_MODE_SIZE (dmode); + enum machine_mode smode = GET_MODE (operands[1]); + int ssize = GET_MODE_SIZE (smode); + + rtx dword = simplify_gen_subreg (smode, operands[0], dmode, 0); + emit_move_insn (dword, operands[1]); + + for (i = ssize; i < dsize; i++) + { + rtx dbyte = simplify_gen_subreg (QImode, operands[0], dmode, i); + emit_move_insn (dbyte, const0_rtx); + } + DONE; + ") + +(define_insn_and_split "zero_extendhi<mode>2" + [(set (match_operand:SIDI 0 "nonimmediate_operand" "") + (zero_extend:SIDI (match_operand:HI 1 "nonimmediate_operand" "")))] + "" + "#" + "" + [(const_int 0)] + " + int i; + enum machine_mode dmode = GET_MODE (operands[0]); + int dsize = GET_MODE_SIZE (dmode); + enum machine_mode smode = GET_MODE (operands[1]); + int ssize = GET_MODE_SIZE (smode); + + rtx dword = simplify_gen_subreg (smode, operands[0], dmode, 0); + emit_move_insn (dword, operands[1]); + + for (i = ssize; i < dsize; i++) + { + rtx dbyte = simplify_gen_subreg (QImode, operands[0], dmode, i); + emit_move_insn (dbyte, const0_rtx); + } + DONE; + ") + (define_insn_and_split "zero_extendsi<mode>2" + [(set (match_operand:DIDI 0 "nonimmediate_operand" "") + (zero_extend:DIDI (match_operand:SI 1 "nonimmediate_operand" "")))] + "" + "#" + "" + [(const_int 0)] + " + int i; + enum machine_mode dmode = GET_MODE (operands[0]); + int dsize = GET_MODE_SIZE (dmode); + enum machine_mode smode = GET_MODE (operands[1]); + int ssize = GET_MODE_SIZE (smode); + + rtx dword = simplify_gen_subreg (smode, operands[0], dmode, 0); + emit_move_insn (dword, operands[1]); + + for (i = ssize; i < dsize; i++) + { + rtx dbyte = simplify_gen_subreg (QImode, operands[0], dmode, i); + emit_move_insn (dbyte, const0_rtx); + } + DONE; + ") +;byte shift is just a series of moves +;check src OR dest is in register, so the move will be ok + +(define_insn_and_split "ashl<mode>3_const2p" + [(set (match_operand:HIDI 0 "nonimmediate_operand" "") + + (ashift:HIDI (match_operand:HIDI 1 "register_operand" "") + (match_operand:HIDI 2 "const_int_operand" "i")) +) + ] + "((INTVAL (operands[2]) % 8) == 0) + " + "#" + "" + [(const_int 0)] + { + int i; + enum machine_mode mode; + mode = GET_MODE(operands[0]); + int size = GET_MODE_SIZE(mode); + + HOST_WIDE_INT x = INTVAL (operands[2]); + rtx dbytes[8], sbytes[8]; + for (i = 0; i < size; i++) + { + dbytes[i] = simplify_gen_subreg (QImode, operands[0], mode, i); + sbytes[i] = simplify_gen_subreg (QImode, operands[1], mode, i); + + } + int shift = x / 8; + if (shift > size) shift = size; + for (i = shift; i < size; i++) + { + emit_move_insn (dbytes[i], sbytes[i - shift]); + } + for (i = 0; i < shift; i++) + { + emit_move_insn (dbytes[i], const0_rtx); + } + + } +) + + ;;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ;; ior @@ -1207,88 +1444,10 @@ [(set_attr "length" "1,1") (set_attr "cc" "set_zn,set_zn")]) -(define_insn "iorhi3" - [(set (match_operand:HI 0 "register_operand" "=r,d") - (ior:HI (match_operand:HI 1 "register_operand" "%0,0") - (match_operand:HI 2 "nonmemory_operand" "r,i")))] - "" - "*{ - if (which_alternative==0) - return (AS2 (or,%A0,%A2) CR_TAB - AS2 (or,%B0,%B2)); - if (GET_CODE (operands[2]) == CONST_INT) - { - int mask = INTVAL (operands[2]); - if (mask & 0xff) - output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands); - if (mask & 0xff00) - output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands); - return \"\"; - } - return (AS2 (ori,%0,lo8(%2)) CR_TAB - AS2 (ori,%B0,hi8(%2))); -}" - [(set_attr "length" "2,2") - (set_attr "cc" "set_n,clobber")]) -(define_insn "*iorhi3_clobber" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (ior:HI (match_operand:HI 1 "register_operand" "%0,0") - (match_operand:HI 2 "immediate_operand" "M,i"))) - (clobber (match_scratch:QI 3 "=&d,&d"))] - "" - "@ - ldi %3,lo8(%2)\;or %A0,%3 - ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3" - [(set_attr "length" "2,4") - (set_attr "cc" "clobber,set_n")]) - -(define_insn "iorsi3" - [(set (match_operand:SI 0 "register_operand" "=r,d") - (ior:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "nonmemory_operand" "r,i")))] - "" - "*{ - if (which_alternative==0) - return (AS2 (or, %0,%2) CR_TAB - AS2 (or, %B0,%B2) CR_TAB - AS2 (or, %C0,%C2) CR_TAB - AS2 (or, %D0,%D2)); - if (GET_CODE (operands[2]) == CONST_INT) - { - HOST_WIDE_INT mask = INTVAL (operands[2]); - if (mask & 0xff) - output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands); - if (mask & 0xff00) - output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands); - if (mask & 0xff0000L) - output_asm_insn (AS2 (ori,%C0,hlo8(%2)), operands); - if (mask & 0xff000000L) - output_asm_insn (AS2 (ori,%D0,hhi8(%2)), operands); - return \"\"; - } - return (AS2 (ori, %A0,lo8(%2)) CR_TAB - AS2 (ori, %B0,hi8(%2)) CR_TAB - AS2 (ori, %C0,hlo8(%2)) CR_TAB - AS2 (ori, %D0,hhi8(%2))); -}" - [(set_attr "length" "4,4") - (set_attr "cc" "set_n,clobber")]) - -(define_insn "*iorsi3_clobber" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (ior:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "immediate_operand" "M,i"))) - (clobber (match_scratch:QI 3 "=&d,&d"))] - "" - "@ - ldi %3,lo8(%2)\;or %A0,%3 - ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3\;ldi %3,hlo8(%2)\;or %C0,%3\;ldi %3,hhi8(%2)\;or %D0,%3" - [(set_attr "length" "2,8") - (set_attr "cc" "clobber,set_n")]) - ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;; xor +;TODO cant we spec intger and force reload - thus dealing with 0xff and 0? (define_insn "xorqi3" [(set (match_operand:QI 0 "register_operand" "=r") @@ -1299,27 +1458,7 @@ [(set_attr "length" "1") (set_attr "cc" "set_zn")]) -(define_insn "xorhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (xor:HI (match_operand:HI 1 "register_operand" "%0") - (match_operand:HI 2 "register_operand" "r")))] - "" - "eor %0,%2 - eor %B0,%B2" - [(set_attr "length" "2") - (set_attr "cc" "set_n")]) -(define_insn "xorsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (xor:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "register_operand" "r")))] - "" - "eor %0,%2 - eor %B0,%B2 - eor %C0,%C2 - eor %D0,%D2" - [(set_attr "length" "4") - (set_attr "cc" "set_n")]) ;;<< << << << << << << << << << << << << << << << << << << << << << << << << << ;; arithmetic shift left @@ -1615,7 +1754,7 @@ (set_attr "cc" "set_n,set_n")]) ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -;; not +;; not TODO use expander (define_insn "one_cmplqi2" [(set (match_operand:QI 0 "register_operand" "=r") @@ -1625,26 +1764,7 @@ [(set_attr "length" "1") (set_attr "cc" "set_czn")]) -(define_insn "one_cmplhi2" - [(set (match_operand:HI 0 "register_operand" "=r") - (not:HI (match_operand:HI 1 "register_operand" "0")))] - "" - "com %0 - com %B0" - [(set_attr "length" "2") - (set_attr "cc" "set_n")]) -(define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (not:SI (match_operand:SI 1 "register_operand" "0")))] - "" - "com %0 - com %B0 - com %C0 - com %D0" - [(set_attr "length" "4") - (set_attr "cc" "set_n")]) - ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x ;; sign extend @@ -1682,99 +1802,8 @@ (const_int 6))]) (set_attr "cc" "set_n,set_n")]) -;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x -;; zero extend -(define_insn_and_split "zero_extendqihi2" - [(set (match_operand:HI 0 "register_operand" "=r") - (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))] - "" - "#" - "reload_completed" - [(set (match_dup 2) (match_dup 1)) - (set (match_dup 3) (const_int 0))] - "unsigned int low_off = subreg_lowpart_offset (QImode, HImode); - unsigned int high_off = subreg_highpart_offset (QImode, HImode); - - operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off); - operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off); - ") -(define_insn_and_split "zero_extendqisi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))] - "" - "#" - "reload_completed" - [(set (match_dup 2) (zero_extend:HI (match_dup 1))) - (set (match_dup 3) (const_int 0))] - "unsigned int low_off = subreg_lowpart_offset (HImode, SImode); - unsigned int high_off = subreg_highpart_offset (HImode, SImode); - - operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off); - operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off); - ") - -(define_insn_and_split "zero_extendhisi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))] - "" - "#" - "reload_completed" - [(set (match_dup 2) (match_dup 1)) - (set (match_dup 3) (const_int 0))] - "unsigned int low_off = subreg_lowpart_offset (HImode, SImode); - unsigned int high_off = subreg_highpart_offset (HImode, SImode); - - operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off); - operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off); - ") - -(define_insn_and_split "zero_extendqidi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))] - "" - "#" - "reload_completed" - [(set (match_dup 2) (zero_extend:SI (match_dup 1))) - (set (match_dup 3) (const_int 0))] - "unsigned int low_off = subreg_lowpart_offset (SImode, DImode); - unsigned int high_off = subreg_highpart_offset (SImode, DImode); - - operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off); - operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off); - ") - -(define_insn_and_split "zero_extendhidi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))] - "" - "#" - "reload_completed" - [(set (match_dup 2) (zero_extend:SI (match_dup 1))) - (set (match_dup 3) (const_int 0))] - "unsigned int low_off = subreg_lowpart_offset (SImode, DImode); - unsigned int high_off = subreg_highpart_offset (SImode, DImode); - - operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off); - operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off); - ") - -(define_insn_and_split "zero_extendsidi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))] - "" - "#" - "reload_completed" - [(set (match_dup 2) (match_dup 1)) - (set (match_dup 3) (const_int 0))] - "unsigned int low_off = subreg_lowpart_offset (SImode, DImode); - unsigned int high_off = subreg_highpart_offset (SImode, DImode); - - operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off); - operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off); - ") - ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=> ;; compare