From 1a06f5fe3fe23768a0336c4a2dc97f42207a3b10 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Wed, 14 Mar 2001 16:38:55 +0100 Subject: [PATCH] expr.c (emit_move_insn_1): Split push of complex value when no suitable push instruction exist. * expr.c (emit_move_insn_1): Split push of complex value when no suitable push instruction exist. * i386.md (QImode move/add/shift patterns): Use ANY_QI_REG_P instead of QI_REG_P. From-SVN: r40454 --- gcc/ChangeLog | 8 ++++++++ gcc/config/i386/i386.h | 2 +- gcc/config/i386/i386.md | 22 ++++++++++---------- gcc/expr.c | 45 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 64 insertions(+), 13 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d723d45dc0c..54031ae237a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +Wed Mar 14 16:36:25 CET 2001 Jan Hubicka + + * expr.c (emit_move_insn_1): Split push of complex value when + no suitable push instruction exist. + + * i386.md (QImode move/add/shift patterns): Use ANY_QI_REG_P + instead of QI_REG_P. + Tue Mar 13 22:22:04 2001 Richard Kenner * alias.c (handled_component_p, can_address_p): New functions. diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 58f622bf8f4..df06a2f3378 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1138,7 +1138,7 @@ enum reg_class ((n) < 8 || REX_INT_REGNO_P (n)) #define GENERAL_REG_P(X) \ - (REG_P (X) && GENERAL_REG_REGNO_P (X)) + (REG_P (X) && GENERAL_REGNO_P (X)) #define ANY_QI_REG_P(X) (TARGET_64BIT ? GENERAL_REG_P(X) : QI_REG_P (X)) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 5f6cef686ca..c700f2317b0 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1911,7 +1911,7 @@ switch (get_attr_type (insn)) { case TYPE_IMOVX: - if (!QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM) + if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM) abort (); return \"movz{bl|x}\\t{%1, %k0|%k0, %1}\"; default: @@ -3077,7 +3077,7 @@ (clobber (reg:CC 17))] "reload_completed && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) - && (!REG_P (operands[1]) || QI_REG_P (operands[1]))" + && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" [(set (match_operand:HI 0 "register_operand" "") (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]) @@ -3088,7 +3088,7 @@ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) (clobber (reg:CC 17))] "reload_completed - && QI_REG_P (operands[0]) + && ANY_QI_REG_P (operands[0]) && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) && !reg_overlap_mentioned_p (operands[0], operands[1])" [(set (match_dup 0) (const_int 0)) @@ -3147,7 +3147,7 @@ (clobber (reg:CC 17))] "reload_completed && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) - && (!REG_P (operands[1]) || QI_REG_P (operands[1]))" + && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]) @@ -3158,8 +3158,8 @@ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) (clobber (reg:CC 17))] "reload_completed - && QI_REG_P (operands[0]) - && (QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM) + && ANY_QI_REG_P (operands[0]) + && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM) && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) && !reg_overlap_mentioned_p (operands[0], operands[1])" [(set (match_dup 0) (const_int 0)) @@ -8470,7 +8470,7 @@ case TYPE_ALU: if (operands[2] != const1_rtx) abort (); - if (NON_QI_REG_P (operands[1])) + if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) return \"add{l}\\t{%k0, %k0|%k0, %k0}\"; else return \"add{b}\\t{%0, %0|%0, %0}\"; @@ -8527,7 +8527,7 @@ case TYPE_ALU: if (operands[2] != const1_rtx) abort (); - if (NON_QI_REG_P (operands[1])) + if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) return \"add{l}\\t{%k0, %k0|%k0, %k0}\"; else return \"add{b}\\t{%0, %0|%0, %0}\"; @@ -8535,7 +8535,7 @@ default: if (REG_P (operands[2])) { - if (NON_QI_REG_P (operands[1])) + if (get_attr_mode (insn) == MODE_SI) return \"sal{l}\\t{%b2, %k0|%k0, %b2}\"; else return \"sal{b}\\t{%b2, %0|%0, %b2}\"; @@ -8544,14 +8544,14 @@ && INTVAL (operands[2]) == 1 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)) { - if (NON_QI_REG_P (operands[1])) + if (get_attr_mode (insn) == MODE_SI) return \"sal{l}\\t%0\"; else return \"sal{b}\\t%0\"; } else { - if (NON_QI_REG_P (operands[1])) + if (get_attr_mode (insn) == MODE_SI) return \"sal{l}\\t{%2, %k0|%k0, %2}\"; else return \"sal{b}\\t{%2, %0|%0, %2}\"; diff --git a/gcc/expr.c b/gcc/expr.c index 382bb234916..44900a61346 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -2786,12 +2786,55 @@ emit_move_insn_1 (x, y) /* Don't split destination if it is a stack push. */ int stack = push_operand (x, GET_MODE (x)); + /* In case we output to the stack, but the size is smaller machine can + push exactly, we need to use move instructions. */ + if (stack + && PUSH_ROUNDING (GET_MODE_SIZE (submode)) != GET_MODE_SIZE (submode)) + { + rtx temp; + int offset1, offset2; + + /* Do not use anti_adjust_stack, since we don't want to update + stack_pointer_delta. */ + temp = expand_binop (Pmode, +#ifdef STACK_GROWS_DOWNWARD + sub_optab, +#else + add_optab, +#endif + stack_pointer_rtx, + GEN_INT + (PUSH_ROUNDING (GET_MODE_SIZE (GET_MODE (x)))), + stack_pointer_rtx, + 0, + OPTAB_LIB_WIDEN); + if (temp != stack_pointer_rtx) + emit_move_insn (stack_pointer_rtx, temp); +#ifdef STACK_GROWS_DOWNWARD + offset1 = 0; + offset2 = GET_MODE_SIZE (submode); +#else + offset1 = -PUSH_ROUNDING (GET_MODE_SIZE (GET_MODE (x))); + offset2 = (-PUSH_ROUNDING (GET_MODE_SIZE (GET_MODE (x))) + + GET_MODE_SIZE (submode)); +#endif + emit_move_insn (change_address (x, submode, + gen_rtx_PLUS (Pmode, + stack_pointer_rtx, + GEN_INT (offset1))), + gen_realpart (submode, y)); + emit_move_insn (change_address (x, submode, + gen_rtx_PLUS (Pmode, + stack_pointer_rtx, + GEN_INT (offset2))), + gen_imagpart (submode, y)); + } /* If this is a stack, push the highpart first, so it will be in the argument order. In that case, change_address is used only to convert the mode, not to change the address. */ - if (stack) + else if (stack) { /* Note that the real part always precedes the imag part in memory regardless of machine's endianness. */ -- 2.30.2