diff --git a/gcc/config/i960/i960.md b/gcc/config/i960/i960.md index 0befad2d0a3..01e18c5ac9c 100644 --- a/gcc/config/i960/i960.md +++ b/gcc/config/i960/i960.md @@ -821,41 +821,12 @@ switch (which_alternative) { case 0: - if ((REGNO (operands[0]) & 1) - || (REGNO (operands[1]) & 1)) - { - /* We normally copy the low-numbered register first. However, if - the second source register is the same as the first destination - register, we must copy in the opposite order. */ - if (REGNO (operands[1]) + 1 == REGNO (operands[0])) - return \"mov %D1,%D0\;mov %1,%0\"; - else - return \"mov %1,%0\;mov %D1,%D0\"; - } - else - return \"movl %1,%0\"; case 1: - if (REGNO (operands[0]) & 1) - return \"mov %1,%0\;mov 0,%D0\"; - else - return \"movl %1,%0\"; + case 3: + case 4: + return i960_output_move_double (operands[0], operands[1]); case 2: return i960_output_ldconst (operands[0], operands[1]); - case 3: - if (REGNO (operands[0]) & 1) - { - /* One can optimize a few cases here, but you have to be - careful of clobbering registers used in the address and - edge conditions. */ - operands[2] = gen_rtx (REG, Pmode, REGNO (operands[0]) + 1); - operands[3] = gen_rtx (MEM, word_mode, operands[2]); - operands[4] = adj_offsettable_operand (operands[3], UNITS_PER_WORD); - return \"lda %1,%2\;ld %3,%0\;ld %4,%D0\"; - } - else - return \"ldl %1,%0\"; - case 4: - return \"stl %1,%0\"; case 5: operands[1] = adj_offsettable_operand (operands[0], 4); return \"st g14,%0\;st g14,%1\"; @@ -878,45 +849,29 @@ switch (which_alternative) { case 0: - if ((REGNO (operands[0]) & 1) - || (REGNO (operands[1]) & 1)) - { - /* We normally copy the low-numbered register first. However, if - the second source register is the same as the first destination - register, we must copy in the opposite order. */ - if (REGNO (operands[1]) + 1 == REGNO (operands[0])) - return \"mov %D1,%D0\;mov %1,%0\"; - else - return \"mov %1,%0\;mov %D1,%D0\"; - } - else - return \"movl %1,%0\"; case 1: - if (REGNO (operands[0]) & 1) - return \"mov %1,%0\;mov 0,%D0\"; - else - return \"movl %1,%0\"; + case 3: + case 4: + return i960_output_move_double (operands[0], operands[1]); case 2: return i960_output_ldconst (operands[0], operands[1]); - case 3: - if (REGNO (operands[0]) & 1) - { - /* One can optimize a few cases here, but you have to be - careful of clobbering registers used in the address and - edge conditions. */ - operands[2] = gen_rtx (REG, Pmode, REGNO (operands[0]) + 1); - operands[3] = gen_rtx (MEM, word_mode, operands[2]); - operands[4] = adj_offsettable_operand (operands[3], UNITS_PER_WORD); - return \"lda %1,%2\;ld %3,%0\;ld %4,%D0\"; - } - else - return \"ldl %1,%0\"; - case 4: - return \"stl %1,%0\"; } }" [(set_attr "type" "move,move,load,load,store")]) +(define_insn "*store_unaligned_di_reg" + [(set (match_operand:DI 0 "memory_operand" "=m") + (match_operand:DI 1 "register_operand" "d")) + (clobber (match_scratch:SI 2 "=&d"))] + "" + "* +{ + operands[3] = gen_rtx (MEM, word_mode, operands[2]); + operands[4] = adj_offsettable_operand (operands[3], UNITS_PER_WORD); + return \"lda %0,%2\;st %1,%3\;st %D1,%4\"; +}" + [(set_attr "type" "store")]) + (define_expand "movti" [(set (match_operand:TI 0 "general_operand" "") (match_operand:TI 1 "general_operand" ""))] @@ -929,8 +884,8 @@ ;; The store case can not be separate. See comment above. (define_insn "" - [(set (match_operand:TI 0 "general_operand" "=d,d,d,m,o") - (match_operand:TI 1 "general_operand" "dI,i,m,d,J"))] + [(set (match_operand:TI 0 "general_operand" "=d,d,d,d,m,o") + (match_operand:TI 1 "general_operand" "d,I,i,m,d,J"))] "(current_function_args_size == 0 && current_function_varargs == 0 && current_function_stdarg == 0 @@ -943,26 +898,25 @@ switch (which_alternative) { case 0: - return \"movq %1,%0\"; case 1: - return i960_output_ldconst (operands[0], operands[1]); - case 2: - return \"ldq %1,%0\"; case 3: - return \"stq %1,%0\"; case 4: + return i960_output_move_quad (operands[0], operands[1]); + case 2: + return i960_output_ldconst (operands[0], operands[1]); + case 5: operands[1] = adj_offsettable_operand (operands[0], 4); operands[2] = adj_offsettable_operand (operands[0], 8); operands[3] = adj_offsettable_operand (operands[0], 12); return \"st g14,%0\;st g14,%1\;st g14,%2\;st g14,%3\"; } }" - [(set_attr "type" "move,load,load,store,store")]) + [(set_attr "type" "move,move,load,load,store,store")]) ;; The store case can not be separate. See comment above. (define_insn "" - [(set (match_operand:TI 0 "general_operand" "=d,d,d,m") - (match_operand:TI 1 "general_operand" "dI,i,m,d"))] + [(set (match_operand:TI 0 "general_operand" "=d,d,d,d,m") + (match_operand:TI 1 "general_operand" "d,I,i,m,d"))] "(current_function_args_size != 0 || current_function_varargs != 0 || current_function_stdarg != 0 @@ -974,16 +928,30 @@ switch (which_alternative) { case 0: - return \"movq %1,%0\"; case 1: - return i960_output_ldconst (operands[0], operands[1]); - case 2: - return \"ldq %1,%0\"; case 3: - return \"stq %1,%0\"; + case 4: + return i960_output_move_quad (operands[0], operands[1]); + case 2: + return i960_output_ldconst (operands[0], operands[1]); } }" - [(set_attr "type" "move,load,load,store")]) + [(set_attr "type" "move,move,load,load,store")]) + +(define_insn "*store_unaligned_ti_reg" + [(set (match_operand:TI 0 "memory_operand" "=m") + (match_operand:TI 1 "register_operand" "d")) + (clobber (match_scratch:SI 2 "=&d"))] + "" + "* +{ + operands[3] = gen_rtx (MEM, word_mode, operands[2]); + operands[4] = adj_offsettable_operand (operands[3], UNITS_PER_WORD); + operands[5] = adj_offsettable_operand (operands[4], UNITS_PER_WORD); + operands[6] = adj_offsettable_operand (operands[5], UNITS_PER_WORD); + return \"lda %0,%2\;st %1,%3\;st %D1,%4\;st %E1,%5\;st %F1,%6\"; +}" + [(set_attr "type" "store")]) (define_expand "store_multiple" [(set (match_operand:SI 0 "" "") ;;- dest