From 4df1190a74679ca430b7800123393625ffa0b6e0 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 25 Nov 2000 18:38:58 +0100 Subject: [PATCH] sparc.md (muldi3_v8plus): Remove H constraint. * config/sparc/sparc.md (muldi3_v8plus): Remove H constraint. Handle CONST_INT as second argument. * config/sparc/sparc.c (set_extends): Remove first argument. Properly handle AND, CONST_INT and CONST_DOUBLE, handle IOR, XOR and MOV. (sparc_check_64): Abort if first argument is not REG. If it is DImode REG, look at the lower register of the register pair. * config/sparc/sparc.c (load_pic_register, restore_regs, output_return, sparc_v8plus_shift, sparc_function_profiler, sparc_function_block_profiler, sparc_block_profiler): Fix output formatting. * gcc.dg/ultrasp3.c: New test. From-SVN: r37738 --- gcc/ChangeLog | 16 ++++ gcc/config/sparc/sparc.c | 133 ++++++++++++++++++-------------- gcc/config/sparc/sparc.md | 9 ++- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gcc.dg/ultrasp3.c | 36 +++++++++ 5 files changed, 141 insertions(+), 57 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ultrasp3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0bb9a521baf..724c75f46e3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2000-11-25 Jakub Jelinek + + * config/sparc/sparc.md (muldi3_v8plus): Remove H constraint. + Handle CONST_INT as second argument. + * config/sparc/sparc.c (set_extends): Remove first argument. + Properly handle AND, CONST_INT and CONST_DOUBLE, handle IOR, XOR and + MOV. + (sparc_check_64): Abort if first argument is not REG. + If it is DImode REG, look at the lower register of the register + pair. + + * config/sparc/sparc.c (load_pic_register, restore_regs, + output_return, sparc_v8plus_shift, sparc_function_profiler, + sparc_function_block_profiler, sparc_block_profiler): Fix output + formatting. + 2000-11-25 Alexandre Oliva * config/sh/sh.h (TARGET_NONE): New. diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 85707e4c31f..863b3eb3387 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -153,7 +153,7 @@ static rtx *ultra_find_type PARAMS ((int, rtx *, int)); static void ultra_build_types_avail PARAMS ((rtx *, int)); static void ultra_flush_pipeline PARAMS ((void)); static void ultra_rescan_pipeline_state PARAMS ((rtx *, int)); -static int set_extends PARAMS ((rtx, rtx)); +static int set_extends PARAMS ((rtx)); static void output_restore_regs PARAMS ((FILE *, int)); /* Option handling. */ @@ -2852,7 +2852,7 @@ load_pic_register () if (align > 0) ASM_OUTPUT_ALIGN (asm_out_file, align); ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LGETPC", 0); - fputs ("\tretl\n\tadd %o7,%l7,%l7\n", asm_out_file); + fputs ("\tretl\n\tadd\t%o7, %l7, %l7\n", asm_out_file); } /* Initialize every time through, since we can't easily @@ -3253,11 +3253,11 @@ restore_regs (file, low, high, base, offset, n_regs) base, offset + 4 * n_regs, reg_names[i]), n_regs += 2; else - fprintf (file, "\tld\t[%s+%d],%s\n", + fprintf (file, "\tld\t[%s+%d], %s\n", base, offset + 4 * n_regs, reg_names[i]), n_regs += 2; else if (regs_ever_live[i+1] && ! call_used_regs[i+1]) - fprintf (file, "\tld\t[%s+%d],%s\n", + fprintf (file, "\tld\t[%s+%d], %s\n", base, offset + 4 * n_regs + 4, reg_names[i+1]), n_regs += 2; } @@ -5417,9 +5417,9 @@ output_return (operands) else { if ((actual_fsize & 0x3ff) != 0) - return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp"; + return "sethi\t%%hi(%a0), %%g1\n\tor\t%%g1, %%lo(%a0), %%g1\n\tretl\n\tadd\t%%sp, %%g1, %%sp"; else - return "sethi %%hi(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp"; + return "sethi\t%%hi(%a0), %%g1\n\tretl\n\tadd\t%%sp, %%g1, %%sp"; } } else if (TARGET_V9) @@ -7978,8 +7978,8 @@ sparc_issue_rate () } static int -set_extends(x, insn) - rtx x, insn; +set_extends (insn) + rtx insn; { register rtx pat = PATTERN (insn); @@ -8003,27 +8003,40 @@ set_extends(x, insn) return 1; case AND: { + rtx op0 = XEXP (SET_SRC (pat), 0); rtx op1 = XEXP (SET_SRC (pat), 1); if (GET_CODE (op1) == CONST_INT) return INTVAL (op1) >= 0; - if (GET_CODE (XEXP (SET_SRC (pat), 0)) == REG - && sparc_check_64 (XEXP (SET_SRC (pat), 0), insn) == 1) - return 1; - if (GET_CODE (op1) == REG - && sparc_check_64 ((op1), insn) == 1) + if (GET_CODE (op0) != REG) + return 0; + if (sparc_check_64 (op0, insn) == 1) return 1; + return (GET_CODE (op1) == REG && sparc_check_64 (op1, insn) == 1); + } + case IOR: + case XOR: + { + rtx op0 = XEXP (SET_SRC (pat), 0); + rtx op1 = XEXP (SET_SRC (pat), 1); + if (GET_CODE (op0) != REG || sparc_check_64 (op0, insn) <= 0) + return 0; + if (GET_CODE (op1) == CONST_INT) + return INTVAL (op1) >= 0; + return (GET_CODE (op1) == REG && sparc_check_64 (op1, insn) == 1); } case ASHIFT: case LSHIFTRT: return GET_MODE (SET_SRC (pat)) == SImode; /* Positive integers leave the high bits zero. */ case CONST_DOUBLE: - return ! (CONST_DOUBLE_LOW (x) & 0x80000000); + return ! (CONST_DOUBLE_LOW (SET_SRC (pat)) & 0x80000000); case CONST_INT: - return ! (INTVAL (x) & 0x80000000); + return ! (INTVAL (SET_SRC (pat)) & 0x80000000); case ASHIFTRT: case SIGN_EXTEND: return - (GET_MODE (SET_SRC (pat)) == SImode); + case REG: + return sparc_check_64 (SET_SRC (pat), insn); default: return 0; } @@ -8145,10 +8158,16 @@ sparc_check_64 (x, insn) the single set and return the correct value or fail to recognize it and return 0. */ int set_once = 0; + rtx y = x; + + if (GET_CODE (x) != REG) + abort (); + + if (GET_MODE (x) == DImode) + y = gen_rtx_REG (SImode, REGNO (x) + WORDS_BIG_ENDIAN); - if (GET_CODE (x) == REG - && flag_expensive_optimizations - && REG_N_SETS (REGNO (x)) == 1) + if (flag_expensive_optimizations + && REG_N_SETS (REGNO (y)) == 1) set_once = 1; if (insn == 0) @@ -8178,8 +8197,10 @@ sparc_check_64 (x, insn) if (GET_CODE (pat) != SET) return 0; if (rtx_equal_p (x, SET_DEST (pat))) - return set_extends (x, insn); - if (reg_overlap_mentioned_p (SET_DEST (pat), x)) + return set_extends (insn); + if (y && rtx_equal_p (y, SET_DEST (pat))) + return set_extends (insn); + if (reg_overlap_mentioned_p (SET_DEST (pat), y)) return 0; } } @@ -8199,21 +8220,21 @@ sparc_v8plus_shift (operands, insn, opcode) operands[3] = operands[0]; if (GET_CODE (operands[1]) == CONST_INT) { - output_asm_insn ("mov %1,%3", operands); + output_asm_insn ("mov\t%1, %3", operands); } else { - output_asm_insn ("sllx %H1,32,%3", operands); + output_asm_insn ("sllx\t%H1, 32, %3", operands); if (sparc_check_64 (operands[1], insn) <= 0) - output_asm_insn ("srl %L1,0,%L1", operands); - output_asm_insn ("or %L1,%3,%3", operands); + output_asm_insn ("srl\t%L1, 0, %L1", operands); + output_asm_insn ("or\t%L1, %3, %3", operands); } strcpy(asm_code, opcode); if (which_alternative != 2) - return strcat (asm_code, " %0,%2,%L0\n\tsrlx %L0,32,%H0"); + return strcat (asm_code, "\t%0, %2, %L0\n\tsrlx\t%L0, 32, %H0"); else - return strcat (asm_code, " %3,%2,%3\n\tsrlx %3,32,%H0\n\tmov %3,%L0"); + return strcat (asm_code, "\t%3, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"); } @@ -8250,22 +8271,22 @@ sparc_function_profiler (file, labelno) ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); if (! TARGET_ARCH64) - fputs ("\tst\t%g2,[%fp-4]\n", file); + fputs ("\tst\t%g2, [%fp-4]\n", file); fputs ("\tsethi\t%hi(", file); assemble_name (file, buf); - fputs ("),%o0\n", file); + fputs ("), %o0\n", file); fputs ("\tcall\t", file); assemble_name (file, MCOUNT_FUNCTION); putc ('\n', file); - fputs ("\t or\t%o0,%lo(", file); + fputs ("\t or\t%o0, %lo(", file); assemble_name (file, buf); - fputs ("),%o0\n", file); + fputs ("), %o0\n", file); if (! TARGET_ARCH64) - fputs ("\tld\t[%fp-4],%g2\n", file); + fputs ("\tld\t[%fp-4], %g2\n", file); } @@ -8337,17 +8358,17 @@ sparc_function_block_profiler(file, block_or_label) { fputs ("\tsethi\t%hi(", file); assemble_name (file, LPBX); - fputs ("),%o0\n", file); + fputs ("), %o0\n", file); - fprintf (file, "\tsethi\t%%hi(%d),%%o1\n", block_or_label); + fprintf (file, "\tsethi\t%%hi(%d), %%o1\n", block_or_label); - fputs ("\tor\t%o0,%lo(", file); + fputs ("\tor\t%o0, %lo(", file); assemble_name (file, LPBX); - fputs ("),%o0\n", file); + fputs ("), %o0\n", file); fprintf (file, "\tcall\t%s__bb_init_trace_func\n", user_label_prefix); - fprintf (file, "\t or\t%%o1,%%lo(%d),%%o1\n", block_or_label); + fprintf (file, "\t or\t%%o1, %%lo(%d), %%o1\n", block_or_label); } else if (profile_block_flag != 0) { @@ -8356,11 +8377,11 @@ sparc_function_block_profiler(file, block_or_label) fputs ("\tsethi\t%hi(", file); assemble_name (file, LPBX); - fputs ("),%o0\n", file); + fputs ("), %o0\n", file); fputs ("\tld\t[%lo(", file); assemble_name (file, LPBX); - fputs (")+%o0],%o1\n", file); + fputs (")+%o0], %o1\n", file); fputs ("\ttst\t%o1\n", file); @@ -8377,9 +8398,9 @@ sparc_function_block_profiler(file, block_or_label) putc ('\n', file); } - fputs ("\t or\t%o0,%lo(", file); + fputs ("\t or\t%o0, %lo(", file); assemble_name (file, LPBX); - fputs ("),%o0\n", file); + fputs ("), %o0\n", file); fprintf (file, "\tcall\t%s__bb_init_func\n\t nop\n", user_label_prefix); @@ -8464,27 +8485,27 @@ sparc_block_profiler(file, blockno) { ASM_GENERATE_INTERNAL_LABEL (LPBX, "LPBX", 0); - fprintf (file, "\tsethi\t%%hi(%s__bb),%%g1\n", user_label_prefix); - fprintf (file, "\tsethi\t%%hi(%d),%%g%d\n", blockno, bbreg); - fprintf (file, "\tor\t%%g1,%%lo(%s__bb),%%g1\n", user_label_prefix); - fprintf (file, "\tor\t%%g%d,%%lo(%d),%%g%d\n", bbreg, blockno, bbreg); + fprintf (file, "\tsethi\t%%hi(%s__bb), %%g1\n", user_label_prefix); + fprintf (file, "\tsethi\t%%hi(%d), %%g%d\n", blockno, bbreg); + fprintf (file, "\tor\t%%g1, %%lo(%s__bb), %%g1\n", user_label_prefix); + fprintf (file, "\tor\t%%g%d, %%lo(%d), %%g%d\n", bbreg, blockno, bbreg); - fprintf (file, "\tst\t%%g%d,[%%g1]\n", bbreg); + fprintf (file, "\tst\t%%g%d, [%%g1]\n", bbreg); fputs ("\tsethi\t%hi(", file); assemble_name (file, LPBX); - fprintf (file, "),%%g%d\n", bbreg); + fprintf (file, "), %%g%d\n", bbreg); - fputs ("\tor\t%o2,%lo(", file); + fputs ("\tor\t%o2, %lo(", file); assemble_name (file, LPBX); - fprintf (file, "),%%g%d\n", bbreg); + fprintf (file, "), %%g%d\n", bbreg); - fprintf (file, "\tst\t%%g%d,[%%g1+4]\n", bbreg); - fprintf (file, "\tmov\t%%o7,%%g%d\n", bbreg); + fprintf (file, "\tst\t%%g%d, [%%g1 + 4]\n", bbreg); + fprintf (file, "\tmov\t%%o7, %%g%d\n", bbreg); fprintf (file, "\tcall\t%s__bb_trace_func\n\t nop\n", user_label_prefix); - fprintf (file, "\tmov\t%%g%d,%%o7\n", bbreg); + fprintf (file, "\tmov\t%%g%d, %%o7\n", bbreg); } else if (profile_block_flag != 0) { @@ -8492,18 +8513,18 @@ sparc_block_profiler(file, blockno) fputs ("\tsethi\t%hi(", file); assemble_name (file, LPBX); - fprintf (file, "+%d),%%g1\n", blockno*4); + fprintf (file, "+%d), %%g1\n", blockno*4); fputs ("\tld\t[%g1+%lo(", file); assemble_name (file, LPBX); if (TARGET_ARCH64 && USE_AS_OFFSETABLE_LO10) - fprintf (file, ")+%d],%%g%d\n", blockno*4, bbreg); + fprintf (file, ")+%d], %%g%d\n", blockno*4, bbreg); else - fprintf (file, "+%d)],%%g%d\n", blockno*4, bbreg); + fprintf (file, "+%d)], %%g%d\n", blockno*4, bbreg); - fprintf (file, "\tadd\t%%g%d,1,%%g%d\n", bbreg, bbreg); + fprintf (file, "\tadd\t%%g%d, 1, %%g%d\n", bbreg, bbreg); - fprintf (file, "\tst\t%%g%d,[%%g1+%%lo(", bbreg); + fprintf (file, "\tst\t%%g%d, [%%g1+%%lo(", bbreg); assemble_name (file, LPBX); if (TARGET_ARCH64 && USE_AS_OFFSETABLE_LO10) fprintf (file, ")+%d]\n", blockno*4); diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 861a9f32faf..21cf0a3bc8c 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -6088,7 +6088,7 @@ (define_insn "muldi3_v8plus" [(set (match_operand:DI 0 "register_operand" "=r,h") (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0") - (match_operand:DI 2 "arith_double_operand" "rHI,rHI"))) + (match_operand:DI 2 "arith_double_operand" "rI,rI"))) (clobber (match_scratch:SI 3 "=&h,X")) (clobber (match_scratch:SI 4 "=&h,X"))] "TARGET_V8PLUS" @@ -6098,6 +6098,13 @@ output_asm_insn (\"srl\\t%L1, 0, %L1\", operands); if (which_alternative == 1) output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands); + if (GET_CODE (operands[2]) == CONST_INT) + { + if (which_alternative == 1) + return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\"; + else + return \"sllx\\t%H1, 32, %3\\n\\tor\\t%L1, %3, %3\\n\\tmulx\\t%3, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\"; + } if (sparc_check_64 (operands[2], insn) <= 0) output_asm_insn (\"srl\\t%L2, 0, %L2\", operands); if (which_alternative == 1) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e7ca09720f5..b328ff34027 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2000-11-25 Jakub Jelinek + + * gcc.dg/ultrasp3.c: New test. + 2000-11-25 Neil Booth * gcc.dg/cpp/include2.c: Update test to be locale independent. diff --git a/gcc/testsuite/gcc.dg/ultrasp3.c b/gcc/testsuite/gcc.dg/ultrasp3.c new file mode 100644 index 00000000000..5156c17e822 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ultrasp3.c @@ -0,0 +1,36 @@ +/* { dg-options "" } */ +/* { dg-options "-mcpu=ultrasparc -mv8plus" { target sparc-*-* } } */ + +unsigned long long foo (unsigned long long x) +{ + return 0x73500000735LL * x; +} + +unsigned long long a, b; +unsigned long p; + +unsigned long long bar (void) +{ + unsigned long long c = a | b; + return 0x73500000735LL * c; +} + +unsigned long long baz (void) +{ + unsigned long long c = (p + 345) & -2; + return c * a; +} + +main () +{ + if (foo (0x56789LL) != 0x26f32e5d26f32e5dLL) + abort (); + a = 0x8000000080000000LL; + b = 0x0000000180000001LL; + if (bar () != 0x120480000735LL) + abort (); + p = 0xffffffff; + if (baz () != 0xac00000000LL) + abort (); + exit (0); +} -- 2.30.2