From mboxrd@z Thu Jan 1 00:00:00 1970 From: hjl@innovix.com (H.J. Lu) To: grahams@rcp.co.uk Cc: wilson@cygnus.com, egcs@cygnus.com Subject: A patch for PPro Date: Fri, 15 May 1998 01:48:00 -0000 Message-id: References: <199805131005.KAA00076@iron.rcp.co.uk> X-SW-Source: 1998-05/msg00533.html > I reported a couple of bugs concerning bootstraping > egcs-19980428 using "-O6 -march=pentiumpro > -mcpu=pentiumpro -fexpensive-optimizations". > > The bootstrap failed due to diffs in all the object files > between stage2 and stage3. > > I managed to identify that its the compilation of > init_reg_sets_1() in gcc/regclass.c that results in the > differences. > Hi, This patch seems to fix all the PPro bugs I have known. Please give a try and let me know what you get. Jim, can you take a look at it? Thanks. BTW, it is against egcs in CVS on 980509. I will send in some test cases tomorrow. H.J. --- Wed May 13 17:36:28 1998 H.J. Lu (hjl@gnu.org) * reg-stack.c (subst_stack_regs_pat): Make sure the top of stack is the destination for conditional move insn. * config/i386/i386.c (expand_fp_conditional_move): New function to expand fp conditional move. (expand_int_conditional_move): New function to expand integer conditional move. (output_fp_conditional_move): New function to output fp conditional move. (output_int_conditional_move): New function to output integer conditional move. * config/i386/i386.md (movsicc, movhicc): Call expand_int_conditional_move () to expand int conditional move. (movsicc_1, movhicc_1): Use "nonimmediate_operand" as predicate for input, call output_int_conditional_move () to output int conditional move. (movsfcc, movdfcc, movxfcc): Use "t" as constraint for output, use "register_operand" as predicate for input and call expand_fp_conditional_move () to expand fp conditional move. (movxfcc_1, movdfcc_1, movxfcc_1): Use "nonimmediate_operand" as predicate for input, use "register_operand" as predicate for output and call output_fp_conditional_move () to output fp conditional move. (movsicc, movhicc, movsicc_1, movhicc_1, movsfcc, movdfcc, movxfcc, movxfcc_1, movdfcc_1, movxfcc_1): Enable. Mon May 11 08:04:17 1998 H.J. Lu (hjl@gnu.org) * config/i386/i386.c (output_float_compare): Fix the unordered comparison for IEEE math and CC_FCOMI. Fri May 8 07:53:43 1998 H.J. Lu (hjl@gnu.org) * config/i386/i386.c (put_condition_code): In INT mode, check cc_prev_status.flags & CC_NO_OVERFLOW for GE and LT. (output_int_conditional_move): Likewise for GT and LE. Index: config/i386/i386.md =================================================================== RCS file: /home/work/cvs/gnu/egcs/gcc/config/i386/i386.md,v retrieving revision 1.1.1.15 diff -u -r1.1.1.15 i386.md --- i386.md 1998/05/09 20:34:36 1.1.1.15 +++ i386.md 1998/05/14 18:22:56 @@ -7225,260 +7226,120 @@ /* Conditional move define_insns. */ -;; These are all disabled, because they are buggy. They are all susceptible -;; to problems with input reloads clobbering the condition code registers. -;; It appears the only safe way to write a integer/FP conditional move pattern -;; is to write one which emits both the compare and the cmov, and which can be -;; split only after reload. - (define_expand "movsicc" [(match_dup 4) - (parallel [(set (match_operand 0 "register_operand" "") + (set (match_operand 0 "register_operand" "") (if_then_else:SI (match_operand 1 "comparison_operator" "") (match_operand:SI 2 "general_operand" "") - (match_operand:SI 3 "general_operand" ""))) - (clobber (match_scratch:SI 4 "=&r"))])] - "0 && TARGET_CMOVE" + (match_operand:SI 3 "general_operand" "")))] + "TARGET_CMOVE" " { - operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1); + expand_int_conditional_move (operands); }") (define_expand "movhicc" [(match_dup 4) - (parallel [(set (match_operand 0 "register_operand" "") + (set (match_operand 0 "register_operand" "") (if_then_else:HI (match_operand 1 "comparison_operator" "") (match_operand:HI 2 "general_operand" "") - (match_operand:HI 3 "general_operand" ""))) - (clobber (match_scratch:SI 4 "=&r"))])] - "0 && TARGET_CMOVE" + (match_operand:HI 3 "general_operand" "")))] + "TARGET_CMOVE" " { - operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1); + expand_int_conditional_move (operands); }") (define_insn "movsicc_1" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,&r,rm") + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,&r") (if_then_else:SI (match_operator 1 "comparison_operator" [(cc0) (const_int 0)]) - (match_operand:SI 2 "general_operand" "rm,0,rm,g") - (match_operand:SI 3 "general_operand" "0,rm,rm,g"))) - (clobber (match_scratch:SI 4 "X,X,X,=&r"))] - "0 && TARGET_CMOVE" - "* -{ - if (which_alternative == 0) - { - /* r <- cond ? arg : r */ - output_asm_insn (AS2 (cmov%C1,%2,%0), operands); - } - else if (which_alternative == 1) - { - /* r <- cond ? r : arg */ - output_asm_insn (AS2 (cmov%c1,%3,%0), operands); - } - else if (which_alternative == 2) - { - /* r <- cond ? arg1 : arg2 */ - output_asm_insn (AS2 (cmov%C1,%2,%0), operands); - output_asm_insn (AS2 (cmov%c1,%3,%0), operands); - } - else if (which_alternative == 3) - { - /* r <- cond ? arg1 : arg2 */ - rtx xops[3]; - - xops[0] = gen_label_rtx (); - xops[1] = gen_label_rtx (); - xops[2] = operands[1]; - - output_asm_insn (\"j%c2 %l0\", xops); - if (! rtx_equal_p (operands[0], operands[2])) - if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[2]) == MEM) - { - output_asm_insn (AS2 (mov%z2,%2,%4), operands); - output_asm_insn (AS2 (mov%z2,%4,%0), operands); - } - else - output_asm_insn (AS2 (mov%z0,%2,%0), operands); - output_asm_insn (\"jmp %l1\", xops); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[0])); - if (! rtx_equal_p (operands[0], operands[3])) - { - if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[3]) == MEM) - { - output_asm_insn (AS2 (mov%z3,%3,%4), operands); - output_asm_insn (AS2 (mov%z3,%4,%0), operands); - } - else - output_asm_insn (AS2 (mov%z0,%3,%0), operands); - } - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[1])); - } - RET; -}") + (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm") + (match_operand:SI 3 "nonimmediate_operand" "0,rm,rm")))] + "TARGET_CMOVE" + "* return output_int_conditional_move (which_alternative, operands);") (define_insn "movhicc_1" - [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,&r,rm") + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,&r") (if_then_else:HI (match_operator 1 "comparison_operator" [(cc0) (const_int 0)]) - (match_operand:HI 2 "general_operand" "rm,0,rm,g") - (match_operand:HI 3 "general_operand" "0,rm,rm,g"))) - (clobber (match_scratch:SI 4 "X,X,X,=&r"))] - "0 && TARGET_CMOVE" - "* -{ - if (which_alternative == 0) - { - /* r <- cond ? arg : r */ - output_asm_insn (AS2 (cmov%C1,%2,%0), operands); - } - else if (which_alternative == 1) - { - /* r <- cond ? r : arg */ - output_asm_insn (AS2 (cmov%c1,%3,%0), operands); - } - else if (which_alternative == 2) - { - /* r <- cond ? arg1 : arg2 */ - output_asm_insn (AS2 (cmov%C1,%2,%0), operands); - output_asm_insn (AS2 (cmov%c1,%3,%0), operands); - } - else if (which_alternative == 3) - { - /* r <- cond ? arg1 : arg2 */ - rtx xops[3]; - - xops[0] = gen_label_rtx (); - xops[1] = gen_label_rtx (); - xops[2] = operands[1]; - - output_asm_insn (\"j%c2 %l0\", xops); - if (! rtx_equal_p (operands[0], operands[2])) - if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[2]) == MEM) - { - output_asm_insn (AS2 (mov%z2,%2,%4), operands); - output_asm_insn (AS2 (mov%z2,%4,%0), operands); - } - else - output_asm_insn (AS2 (mov%z0,%2,%0), operands); - output_asm_insn (\"jmp %l1\", xops); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[0])); - if (! rtx_equal_p (operands[0], operands[3])) - { - if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[3]) == MEM) - { - output_asm_insn (AS2 (mov%z3,%3,%4), operands); - output_asm_insn (AS2 (mov%z3,%4,%0), operands); - } - else - output_asm_insn (AS2 (mov%z0,%3,%0), operands); - } - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[1])); - } - RET; -}") + (match_operand:HI 2 "nonimmediate_operand" "rm,0,rm") + (match_operand:HI 3 "nonimmediate_operand" "0,rm,rm")))] + "TARGET_CMOVE" + "* return output_int_conditional_move (which_alternative, operands);") + ;; We need to disable the FP forms of these since they do not support ;; memory as written, but no input reloads are permitted for insns ;; that use cc0. Also, movxfcc is not present. +;; These are all disabled, because they are buggy. They are all susceptible +;; to problems with input reloads clobbering the condition code registers. +;; It appears the only safe way to write a FP conditional move pattern +;; is to write one which emits both the compare and the cmov, and which can be +;; split only after reload. + (define_expand "movsfcc" [(match_dup 4) - (set (match_operand 0 "register_operand" "") + (set (match_operand 0 "register_operand" "t") (if_then_else:SF (match_operand 1 "comparison_operator" "") - (match_operand:SF 2 "register_operand" "") - (match_operand:SF 3 "register_operand" "")))] - "0 && TARGET_CMOVE" + (match_operand:SF 2 "general_operand" "") + (match_operand:SF 3 "general_operand" "")))] + "TARGET_CMOVE" " { - operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1); + expand_fp_conditional_move (operands); }") (define_expand "movdfcc" [(match_dup 4) (set (match_operand 0 "register_operand" "t") (if_then_else:DF (match_operand 1 "comparison_operator" "") - (match_operand:DF 2 "register_operand" "") - (match_operand:DF 3 "register_operand" "")))] - "0 && TARGET_CMOVE" + (match_operand:DF 2 "general_operand" "") + (match_operand:DF 3 "general_operand" "")))] + "TARGET_CMOVE" " { - operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1); + expand_fp_conditional_move (operands); }") (define_expand "movxfcc" [(match_dup 4) - (set (match_operand 0 "register_operand" "") + (set (match_operand 0 "register_operand" "t") (if_then_else:XF (match_operand 1 "comparison_operator" "") - (match_operand:XF 2 "register_operand" "") - (match_operand:XF 3 "register_operand" "")))] - "0 && TARGET_CMOVE" + (match_operand:XF 2 "general_operand" "") + (match_operand:XF 3 "general_operand" "")))] + "TARGET_CMOVE" " { - operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1); + expand_fp_conditional_move (operands); }") (define_insn "movsfcc_1" - [(set (match_operand:SF 0 "general_operand" "=f,f,&f") + [(set (match_operand:SF 0 "register_operand" "=f,=f,=f,=f") (if_then_else:SF (match_operator 1 "comparison_operator" [(cc0) (const_int 0)]) - (match_operand:SF 2 "register_operand" "0,f,f") - (match_operand:SF 3 "register_operand" "f,0,f")))] - "0 && TARGET_CMOVE" - "* -{ - switch (which_alternative) - { - case 0: - /* r <- cond ? arg : r */ - output_asm_insn (AS2 (fcmov%f1,%3,%0), operands); - break; - - case 1: - /* r <- cond ? r : arg */ - output_asm_insn (AS2 (fcmov%F1,%2,%0), operands); - break; - - case 2: - /* r <- cond ? r : arg */ - output_asm_insn (AS2 (fcmov%F1,%2,%0), operands); - output_asm_insn (AS2 (fcmov%f1,%3,%0), operands); - break; - } - - RET; -}") + (match_operand:SF 2 "nonimmediate_operand" "0,f,f,fFm") + (match_operand:SF 3 "nonimmediate_operand" "f,0,f,fFm")))] + "TARGET_CMOVE" + "* return output_fp_conditional_move (which_alternative, operands);") (define_insn "movdfcc_1" - [(set (match_operand:DF 0 "general_operand" "=f,f,&f") + [(set (match_operand:DF 0 "register_operand" "=f,=f,=f,=f") (if_then_else:DF (match_operator 1 "comparison_operator" [(cc0) (const_int 0)]) - (match_operand:DF 2 "register_operand" "0,f,f") - (match_operand:DF 3 "register_operand" "f,0,f")))] - "0 && TARGET_CMOVE" - "* -{ - switch (which_alternative) - { - case 0: - /* r <- cond ? arg : r */ - output_asm_insn (AS2 (fcmov%f1,%3,%0), operands); - break; - - case 1: - /* r <- cond ? r : arg */ - output_asm_insn (AS2 (fcmov%F1,%2,%0), operands); - break; - - case 2: - /* r <- cond ? r : arg */ - output_asm_insn (AS2 (fcmov%F1,%2,%0), operands); - output_asm_insn (AS2 (fcmov%f1,%3,%0), operands); - break; - } - - RET; -}") + (match_operand:DF 2 "nonimmediate_operand" "0,f,f,fFm") + (match_operand:DF 3 "nonimmediate_operand" "f,0,f,fFm")))] + "TARGET_CMOVE" + "* return output_fp_conditional_move (which_alternative, operands);") + +(define_insn "movxfcc_1" + [(set (match_operand:XF 0 "register_operand" "=f,=f,=f,=f") + (if_then_else:XF (match_operator 1 "comparison_operator" + [(cc0) (const_int 0)]) + (match_operand:XF 2 "nonimmediate_operand" "0,f,f,fFm") + (match_operand:XF 3 "nonimmediate_operand" "f,0,f,fFm")))] + "TARGET_CMOVE" + "* return output_fp_conditional_move (which_alternative, operands);") (define_insn "strlensi_unroll" [(set (match_operand:SI 0 "register_operand" "=&r,&r") Index: config/i386/i386.c =================================================================== RCS file: /home/work/cvs/gnu/egcs/gcc/config/i386/i386.c,v retrieving revision 1.1.1.15 diff -u -p -r1.1.1.15 i386.c --- i386.c 1998/05/07 15:46:40 1.1.1.15 +++ i386.c 1998/05/14 19:51:14 @@ -3089,7 +3098,10 @@ put_condition_code (code, reverse_cc, mo return; case GE: - fputs ("ge", file); + if (cc_prev_status.flags & CC_NO_OVERFLOW) + fputs ("ns", file); + else + fputs ("ge", file); return; case GT: @@ -3101,7 +3113,10 @@ put_condition_code (code, reverse_cc, mo return; case LT: - fputs ("l", file); + if (cc_prev_status.flags & CC_NO_OVERFLOW) + fputs ("s", file); + else + fputs ("l", file); return; case GEU: @@ -4047,6 +4062,18 @@ output_float_compare (insn, operands) { output_asm_insn (AS2 (fucomip,%y1,%0), operands); output_asm_insn (AS1 (fstp, %y0), operands); + + if (TARGET_IEEE_FP) + { + /* It is very tricky. We have to do it right. */ + rtx xops [1]; + + xops [0] = gen_rtx_REG (QImode, 0); + output_asm_insn (AS1 (setne,%b0), xops); + output_asm_insn (AS1 (setp,%h0), xops); + output_asm_insn (AS2 (or%B0,%h0,%b0), xops); + } + return ""; } else @@ -4088,6 +4115,17 @@ output_float_compare (insn, operands) else if (cc_status.flags & CC_FCOMI) { output_asm_insn (strcat (buf, AS2 (%z1,%y1,%0)), operands); + if (unordered_compare && TARGET_IEEE_FP) + { + /* It is very tricky. We have to do it right. */ + rtx xops [1]; + + xops [0] = gen_rtx_REG (QImode, 0); + output_asm_insn (AS1 (setne,%b0), xops); + output_asm_insn (AS1 (setp,%h0), xops); + output_asm_insn (AS2 (or%B0,%h0,%b0), xops); + } + return ""; } else @@ -5123,4 +5161,290 @@ output_strlen_unroll (operands) ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[12])); return ""; +} + +char * +output_fp_conditional_move (which_alternative, operands) + int which_alternative; + rtx operands[]; +{ + if (which_alternative == 0) + { + /* r <- cond ? arg : r */ + output_asm_insn (AS2 (fcmov%f1,%3,%0), operands); + } + else if (which_alternative == 1) + { + /* r <- cond ? r : arg */ + output_asm_insn (AS2 (fcmov%F1,%2,%0), operands); + } + else if (which_alternative == 2) + { + /* r <- cond ? r : arg */ + output_asm_insn (AS2 (fcmov%F1,%2,%0), operands); + output_asm_insn (AS2 (fcmov%f1,%3,%0), operands); + } + else if (which_alternative == 3) + { + /* r <- cond ? arg1 : arg2 */ + rtx xops[3]; + + xops[0] = gen_label_rtx (); + xops[1] = gen_label_rtx (); + xops[2] = operands[1]; + + output_asm_insn ("j%f2 %l0", xops); + if (STACK_REG_P (operands[2]) || GET_CODE (operands[2]) == MEM) + output_asm_insn (AS1 (fld%z2,%y2), operands); + else + { + int conval = standard_80387_constant_p (operands[2]); + + switch (conval) + { + case 1: + fprintf (asm_out_file, "\tfldz\n"); + break; + case 2: + fprintf (asm_out_file, "\tfld1\n"); + break; + default: +#if 1 + abort (); +#else + operands[2] = CONST_DOUBLE_MEM (operands[2]); + if (GET_CODE (operands[2]) != MEM) + abort (); + output_asm_insn (AS1 (fld%z2,%y2), operands); +#endif + break; + } + } + output_asm_insn ("jmp %l1", xops); + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[0])); + if (STACK_REG_P (operands[3]) || GET_CODE (operands[3]) == MEM) + output_asm_insn (AS1 (fld%z3,%y3), operands); + else + { + int conval = standard_80387_constant_p (operands[2]); + + switch (conval) + { + case 1: + fprintf (asm_out_file, "\tfldz\n"); + break; + case 2: + fprintf (asm_out_file, "\tfld1\n"); + break; + default: +#if 1 + abort (); +#else + operands[3] = CONST_DOUBLE_MEM (operands[3]); + if (GET_CODE (operands[3]) != MEM) + abort (); + output_asm_insn (AS1 (fld%z3,%y3), operands); +#endif + break; + } + } + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[1])); + } + + return ""; +} + +char * +output_int_conditional_move (which_alternative, operands) + int which_alternative; + rtx operands[]; +{ + int code = GET_CODE (operands[1]); + + if ((code == GT || code == LE) + && (cc_prev_status.flags & CC_NO_OVERFLOW)) + return NULL_PTR; + + if (which_alternative == 0) + { + /* r <- cond ? arg : r */ + output_asm_insn (AS2 (cmov%C1,%2,%0), operands); + } + else if (which_alternative == 1) + { + /* r <- cond ? r : arg */ + output_asm_insn (AS2 (cmov%c1,%3,%0), operands); + } + else if (which_alternative == 2) + { + /* r <- cond ? arg1 : arg2 */ + output_asm_insn (AS2 (cmov%C1,%2,%0), operands); + output_asm_insn (AS2 (cmov%c1,%3,%0), operands); + } + else if (which_alternative == 3) + { + /* r <- cond ? arg1 : arg2 */ + rtx xops[3]; + + xops[0] = gen_label_rtx (); + xops[1] = gen_label_rtx (); + xops[2] = operands[1]; + + output_asm_insn ("j%c2 %l0", xops); + if (! rtx_equal_p (operands[0], operands[2])) + { + if (GET_CODE (operands[0]) == MEM + && GET_CODE (operands[2]) == MEM) + { + output_asm_insn (AS2 (mov%z2,%2,%4), operands); + output_asm_insn (AS2 (mov%z2,%4,%0), operands); + } + else + output_asm_insn (AS2 (mov%z0,%2,%0), operands); + } + output_asm_insn ("jmp %l1", xops); + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[0])); + if (! rtx_equal_p (operands[0], operands[3])) + { + if (GET_CODE (operands[0]) == MEM + && GET_CODE (operands[3]) == MEM) + { + output_asm_insn (AS2 (mov%z3,%3,%4), operands); + output_asm_insn (AS2 (mov%z3,%4,%0), operands); + } + else + output_asm_insn (AS2 (mov%z0,%3,%0), operands); + } + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[1])); + } + + return ""; +} + +void +expand_fp_conditional_move (operands) + rtx operands[]; +{ +#undef CONSTANT_DOUBLE_P +#define CONSTANT_DOUBLE_P(X) (GET_CODE ((X)) == CONST_DOUBLE) + + /* We have 4 cases: + + 1. operand 2 is immediate and operand 3 is immediate. + 2. operand 2 is immediate and operand 3 is non-immediate. + 3. operand 3 is non-immediate and operand 3 is immediate. + 4. operand 3 is non-immediate and operand 3 is non-immediate. + */ + if ((reload_in_progress | reload_completed) == 0 + && ((CONSTANT_DOUBLE_P (operands [2]) + && CONSTANT_DOUBLE_P (operands [3])) + || (CONSTANT_DOUBLE_P (operands [2]) + && !CONSTANT_DOUBLE_P (operands [3])) + || (!CONSTANT_DOUBLE_P (operands [2]) + && CONSTANT_DOUBLE_P (operands [3])))) + { + /* Case 1, 2 and 3. */ + rtx fp_const, reg, insn, note; + int i, start, end; + enum machine_mode mode = GET_MODE (operands [0]); + + if (flag_pic) + current_function_uses_pic_offset_table = 1; + + /* Case 1. */ + if (CONSTANT_DOUBLE_P (operands [2]) + && CONSTANT_DOUBLE_P (operands [3])) + { + start = 2; + end = 3; + } + else + { + /* Case 2 and 3. */ + start = CONSTANT_DOUBLE_P (operands [2]) ? 2 : 3; + end = start; + } + + for (i = start; i <= end; i++) + { + fp_const = force_const_mem (mode, operands [i]); + reg = gen_reg_rtx (mode); + + insn = emit_insn (gen_rtx_SET (mode, reg, fp_const)); + note = find_reg_note (insn, REG_EQUAL, NULL_RTX); + if (note) + XEXP (note, 0) = operands[i]; + else + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, + operands[i], + REG_NOTES (insn)); + + operands[i] = reg; + } + } + operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1); +} + +void +expand_int_conditional_move (operands) + rtx operands[]; +{ +#undef CONSTANT_INT_P(X) +#define CONSTANT_INT_P(X) CONSTANT_P(X) + + /* We have 4 cases: + + 1. operand 2 is immediate and operand 3 is immediate. + 2. operand 2 is immediate and operand 3 is non-immediate. + 3. operand 3 is non-immediate and operand 3 is immediate. + 4. operand 3 is non-immediate and operand 3 is non-immediate. + */ + if ((reload_in_progress | reload_completed) == 0 + && ((CONSTANT_INT_P (operands [2]) + && CONSTANT_INT_P (operands [3])) + || (CONSTANT_INT_P (operands [2]) + && !CONSTANT_INT_P (operands [3])) + || (!CONSTANT_INT_P (operands [2]) + && CONSTANT_INT_P (operands [3])))) + { + /* Case 1, 2 and 3. */ + rtx int_const, reg, insn, note; + int i, start, end; + enum machine_mode mode = GET_MODE (operands [0]); + + if (flag_pic) + current_function_uses_pic_offset_table = 1; + + /* Case 1. */ + if (CONSTANT_INT_P (operands [2]) + && CONSTANT_INT_P (operands [3])) + { + start = 2; + end = 3; + } + else + { + /* Case 2 and 3. */ + start = CONSTANT_INT_P (operands [2]) ? 2 : 3; + end = start; + } + + for (i = start; i <= end; i++) + { + int_const = force_const_mem (mode, operands [i]); + reg = gen_reg_rtx (mode); + + insn = emit_insn (gen_rtx_SET (mode, reg, int_const)); + note = find_reg_note (insn, REG_EQUAL, NULL_RTX); + if (note) + XEXP (note, 0) = operands[i]; + else + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, + operands[i], + REG_NOTES (insn)); + + operands[i] = reg; + } + } + operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1); } Index: reg-stack.c =================================================================== RCS file: /home/work/cvs/gnu/egcs/gcc/reg-stack.c,v retrieving revision 1.1.1.15 diff -u -r1.1.1.15 reg-stack.c --- reg-stack.c 1998/05/06 20:59:12 1.1.1.15 +++ reg-stack.c 1998/05/14 00:34:48 @@ -2344,6 +2345,13 @@ case IF_THEN_ELSE: /* This insn requires the top of stack to be the destination. */ + /* The comparison operator may not be FP comparison operator, + which is handled correctly in compare_for_stack_reg (). + We do a sanity check here. */ + if (get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG + && REGNO (*dest) != regstack->reg[regstack->top]) + emit_swap_insn (insn, regstack, *dest); + src1 = get_true_reg (&XEXP (SET_SRC (pat), 1)); src2 = get_true_reg (&XEXP (SET_SRC (pat), 2));