From 2a01c939370303ea0fe7aabdcee592cc3d4ec446 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 11 Aug 1998 05:54:17 +0000 Subject: [PATCH] sparc.c (sparc_emit_set_const32): INTVAL is of type HOST_WIDE_INT. * config/sparc/sparc.c (sparc_emit_set_const32): INTVAL is of type HOST_WIDE_INT. (safe_constDI sparc_emit_set_const64_quick1, sparc_emit_set_const64_quick2, sparc_emit_set_const64_longway, analyze_64bit_constant, const64_is_2insns, create_simple_focus_bits): Fix some bugs when compiled on real 64-bit hosts. (function_arg_record_value_3, function_arg_record_value_2, function_arg_record_value): Add fully prototyped forward decls. * config/sparc/sparc.md (define_insn cmpsi_insn_sp32): Rename back to cmpsi_insn and use on both 64 and 32 bit targets. (define_insn cmpsi_insn_sp64): Remove. (define_expand zero_extendsidi2): Allow for 32-bit target too. (define_insn zero_extendsidi2_insn): Rename to zero_extendsidi2_insn_sp64. (define_insn zero_extendsidi2_insn_sp32): New pattern and assosciated forced split for it. From-SVN: r21662 --- gcc/ChangeLog | 20 +++++++++++ gcc/config/sparc/sparc.c | 85 ++++++++++++++++++++++++++++++++--------------- gcc/config/sparc/sparc.md | 59 ++++++++++++++++++++++++-------- 3 files changed, 125 insertions(+), 39 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 20e837b..dcd7128 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +Tue Aug 11 04:46:01 1998 David S. Miller + + * config/sparc/sparc.c (sparc_emit_set_const32): INTVAL is of + type HOST_WIDE_INT. + (safe_constDI sparc_emit_set_const64_quick1, + sparc_emit_set_const64_quick2, sparc_emit_set_const64_longway, + analyze_64bit_constant, const64_is_2insns, + create_simple_focus_bits): Fix some bugs when compiled on real + 64-bit hosts. + (function_arg_record_value_3, function_arg_record_value_2, + function_arg_record_value): Add fully prototyped forward decls. + * config/sparc/sparc.md (define_insn cmpsi_insn_sp32): Rename back + to cmpsi_insn and use on both 64 and 32 bit targets. + (define_insn cmpsi_insn_sp64): Remove. + (define_expand zero_extendsidi2): Allow for 32-bit target too. + (define_insn zero_extendsidi2_insn): Rename to + zero_extendsidi2_insn_sp64. + (define_insn zero_extendsidi2_insn_sp32): New pattern and + assosciated forced split for it. + Mon Aug 10 22:57:24 1998 John Carr * config/sparc/sparc.md (define_insn jump): Output ba,pt not b,pt diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 94e86fa..187cb7a 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -115,6 +115,7 @@ static void sparc_output_addr_vec PROTO((rtx)); static void sparc_output_addr_diff_vec PROTO((rtx)); static void sparc_output_deferred_case_vectors PROTO((void)); + #ifdef DWARF2_DEBUGGING_INFO extern char *dwarf2out_cfi_label (); #endif @@ -1040,7 +1041,7 @@ sparc_emit_set_const32 (op0, op1) if (GET_CODE (op1) == CONST_INT) { - int value = INTVAL (op1); + HOST_WIDE_INT value = INTVAL (op1); if (SPARC_SETHI_P (value) || SPARC_SIMM13_P (value)) @@ -1192,6 +1193,8 @@ sparc_emit_set_symbolic_const64 (op0, op1, temp1) } /* This avoids problems when cross compiling. */ +static rtx safe_constDI PROTO((HOST_WIDE_INT)); + static rtx safe_constDI(val) HOST_WIDE_INT val; @@ -1211,17 +1214,21 @@ safe_constDI(val) such values are similar to something required later on. Without doing this, the optimizer cannot see such opportunities. */ + +static void sparc_emit_set_const64_quick1 + PROTO((rtx, rtx, unsigned HOST_WIDE_INT, int)); + static void sparc_emit_set_const64_quick1 (op0, temp, low_bits, is_neg) rtx op0; rtx temp; - unsigned int low_bits; + unsigned HOST_WIDE_INT low_bits; int is_neg; { - unsigned int high_bits; + unsigned HOST_WIDE_INT high_bits; if (is_neg) - high_bits = ~low_bits; + high_bits = (~low_bits) & 0xffffffff; else high_bits = low_bits; @@ -1242,12 +1249,16 @@ sparc_emit_set_const64_quick1 (op0, temp, low_bits, is_neg) } } +static void sparc_emit_set_const64_quick2 + PROTO((rtx, rtx, unsigned HOST_WIDE_INT, + unsigned HOST_WIDE_INT, int)); + static void sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_immediate, shift_count) rtx op0; rtx temp; - unsigned int high_bits; - unsigned int low_immediate; + unsigned HOST_WIDE_INT high_bits; + unsigned HOST_WIDE_INT low_immediate; int shift_count; { rtx temp2 = op0; @@ -1283,14 +1294,17 @@ sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_immediate, shift_count) safe_constDI (low_immediate & 0x3ff)))); } +static void sparc_emit_set_const64_longway + PROTO((rtx, rtx, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT)); + /* Full 64-bit constant decomposition. Even though this is the 'worst' case, we still optimize a few things away. */ static void sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits) rtx op0; rtx temp; - unsigned int high_bits; - unsigned int low_bits; + unsigned HOST_WIDE_INT high_bits; + unsigned HOST_WIDE_INT low_bits; { rtx sub_temp; @@ -1356,7 +1370,7 @@ sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits) { emit_insn (gen_rtx_SET (DImode, op0, gen_rtx_ASHIFT (DImode, sub_temp, - GEN_INT(to_shift)))); + GEN_INT (to_shift)))); emit_insn (gen_rtx_SET (DImode, op0, gen_rtx_IOR (DImode, op0, low1))); sub_temp = op0; @@ -1391,9 +1405,14 @@ sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits) } /* Analyze a 64-bit constant for certain properties. */ +static void analyze_64bit_constant + PROTO((unsigned HOST_WIDE_INT, + unsigned HOST_WIDE_INT, + int *, int *, int *)); + static void analyze_64bit_constant (high_bits, low_bits, hbsp, lbsp, abbasp) - unsigned int high_bits, low_bits; + unsigned HOST_WIDE_INT high_bits, low_bits; int *hbsp, *lbsp, *abbasp; { int lowest_bit_set, highest_bit_set, all_bits_between_are_set; @@ -1455,14 +1474,17 @@ analyze_64bit_constant (high_bits, low_bits, hbsp, lbsp, abbasp) *abbasp = all_bits_between_are_set; } +static int const64_is_2insns + PROTO((unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT)); + static int const64_is_2insns (high_bits, low_bits) - unsigned int high_bits, low_bits; + unsigned HOST_WIDE_INT high_bits, low_bits; { int highest_bit_set, lowest_bit_set, all_bits_between_are_set; if (high_bits == 0 - || high_bits == -1) + || high_bits == 0xffffffff) return 1; analyze_64bit_constant (high_bits, low_bits, @@ -1479,12 +1501,16 @@ const64_is_2insns (high_bits, low_bits) return 0; } -static unsigned int +static unsigned HOST_WIDE_INT create_simple_focus_bits + PROTO((unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, + int, int, int)); + +static unsigned HOST_WIDE_INT create_simple_focus_bits (high_bits, low_bits, highest_bit_set, lowest_bit_set, shift) - unsigned int high_bits, low_bits; + unsigned HOST_WIDE_INT high_bits, low_bits; int highest_bit_set, lowest_bit_set, shift; { - unsigned int hi, lo; + int hi, lo; if (lowest_bit_set < 32) { @@ -1510,7 +1536,7 @@ sparc_emit_set_const64 (op0, op1) rtx op0; rtx op1; { - unsigned int high_bits, low_bits; + unsigned HOST_WIDE_INT high_bits, low_bits; int lowest_bit_set, highest_bit_set; int all_bits_between_are_set; int i; @@ -1536,7 +1562,7 @@ sparc_emit_set_const64 (op0, op1) if (GET_CODE (op1) == CONST_DOUBLE) { #if HOST_BITS_PER_WIDE_INT == 64 - high_bits = CONST_DOUBLE_LOW (op1) >> 32; + high_bits = (CONST_DOUBLE_LOW (op1) >> 32) & 0xffffffff; low_bits = CONST_DOUBLE_LOW (op1) & 0xffffffff; #else high_bits = CONST_DOUBLE_HIGH (op1); @@ -1546,7 +1572,7 @@ sparc_emit_set_const64 (op0, op1) else { #if HOST_BITS_PER_WIDE_INT == 64 - high_bits = (INTVAL (op1) >> 32); + high_bits = ((INTVAL (op1) >> 32) & 0xffffffff); low_bits = (INTVAL (op1) & 0xffffffff); #else high_bits = ((INTVAL (op1) < 0) ? @@ -1582,7 +1608,7 @@ sparc_emit_set_const64 (op0, op1) if (((highest_bit_set == 63 || lowest_bit_set == 0) && all_bits_between_are_set != 0) - || ((highest_bit_set - lowest_bit_set) < 13)) + || ((highest_bit_set - lowest_bit_set) < 12)) { rtx the_const = constm1_rtx; int shift = lowest_bit_set; @@ -1629,9 +1655,9 @@ sparc_emit_set_const64 (op0, op1) * 2) sethi %hi(focus_bits), %reg * srlx %reg, shift, %reg */ - if ((highest_bit_set - lowest_bit_set) < 22) + if ((highest_bit_set - lowest_bit_set) < 21) { - unsigned int focus_bits = + unsigned HOST_WIDE_INT focus_bits = create_simple_focus_bits (high_bits, low_bits, highest_bit_set, lowest_bit_set, 10); emit_insn (gen_rtx_SET (DImode, @@ -1659,9 +1685,9 @@ sparc_emit_set_const64 (op0, op1) * xor %reg, %lo(-0x400 | (low_bits & 0x3ff)), %reg */ if (high_bits == 0 - || high_bits == -1) + || high_bits == 0xffffffff) return sparc_emit_set_const64_quick1 (op0, temp, low_bits, - (high_bits == -1)); + (high_bits == 0xffffffff)); /* 1) sethi %hi(high_bits), %reg * or %reg, %lo(high_bits), %reg @@ -1669,7 +1695,7 @@ sparc_emit_set_const64 (op0, op1) */ if (low_bits == 0 || (SPARC_SIMM13_P(low_bits) - && ((int)low_bits > 0))) + && ((HOST_WIDE_INT)low_bits > 0))) return sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_bits, 32); /* Now, try 3-insn sequences. But first we may be able to do something @@ -1677,7 +1703,7 @@ sparc_emit_set_const64 (op0, op1) if (const64_is_2insns ((~high_bits) & 0xffffffff, (~low_bits) & 0xfffffc00)) { - unsigned int trailing_bits = (~low_bits) & 0x3ff; + unsigned HOST_WIDE_INT trailing_bits = (~low_bits) & 0x3ff; if ((((~high_bits) & 0xffffffff) == 0 && ((~low_bits) & 0x80000000) == 0) @@ -1718,7 +1744,7 @@ sparc_emit_set_const64 (op0, op1) */ if ((highest_bit_set - lowest_bit_set) < 32) { - unsigned int hi, lo, focus_bits; + unsigned HOST_WIDE_INT hi, lo, focus_bits; /* We can't get here in this state. */ if (highest_bit_set < 32 @@ -3373,6 +3399,13 @@ struct function_arg_record_value_parms int nregs, intoffset; }; +static void function_arg_record_value_3 + PROTO((int, struct function_arg_record_value_parms *)); +static void function_arg_record_value_2 + PROTO((tree, int, struct function_arg_record_value_parms *)); +static rtx function_arg_record_value + PROTO((tree, enum machine_mode, int, int, int)); + static void function_arg_record_value_1 (type, startbitpos, parms) tree type; diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 9fc5db6..719e697 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -562,19 +562,11 @@ ;; Now the compare DEFINE_INSNs. -(define_insn "*cmpsi_insn_sp32" +(define_insn "*cmpsi_insn" [(set (reg:CC 100) (compare:CC (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "arith_operand" "rI")))] - "TARGET_ARCH32" - "cmp\\t%0, %1" - [(set_attr "type" "compare")]) - -(define_insn "*cmpsi_insn_sp64" - [(set (reg:CC 100) - (compare:CC (match_operand:SI 0 "register_operand" "r") - (match_operand:SI 1 "arith_double_operand" "rHI")))] - "TARGET_ARCH64" + "" "cmp\\t%0, %1" [(set_attr "type" "compare")]) @@ -2662,7 +2654,7 @@ /* Now emit using the real source and destination we found, swapping the order if we detect overlap. */ - if (REGNO(dest1) == REGNO(src2)) + if (REGNO (dest1) == REGNO (src2)) { emit_insn (gen_movsi (dest2, src2)); emit_insn (gen_movsi (dest1, src1)); @@ -3809,10 +3801,10 @@ movtf_is_ok: (define_expand "zero_extendsidi2" [(set (match_operand:DI 0 "register_operand" "") (zero_extend:DI (match_operand:SI 1 "register_operand" "")))] - "TARGET_ARCH64" + "" "") -(define_insn "*zero_extendsidi2_insn" +(define_insn "*zero_extendsidi2_insn_sp64" [(set (match_operand:DI 0 "register_operand" "=r,r") (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))] "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT" @@ -3822,6 +3814,47 @@ movtf_is_ok: [(set_attr "type" "unary,load") (set_attr "length" "1")]) +(define_insn "*zero_extendsidi2_insn_sp32" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))] + "! TARGET_ARCH64" + "#" + [(set_attr "type" "unary") + (set_attr "length" "2")]) + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (zero_extend:DI (match_operand:SI 1 "register_operand" "")))] + "! TARGET_ARCH64 && reload_completed" + [(set (match_dup 2) (match_dup 3)) + (set (match_dup 4) (match_dup 5))] + " +{ + rtx dest1, dest2; + + if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + + dest1 = gen_highpart (SImode, operands[0]); + dest2 = gen_lowpart (SImode, operands[0]); + + /* Swap the order in case of overlap. */ + if (REGNO (dest1) == REGNO (operands[1])) + { + operands[2] = dest2; + operands[3] = operands[1]; + operands[4] = dest1; + operands[5] = const0_rtx; + } + else + { + operands[2] = dest1; + operands[3] = const0_rtx; + operands[4] = dest2; + operands[5] = operands[1]; + } +}") + ;; Simplify comparisons of extended values. (define_insn "*cmp_zero_extendqisi2" -- 2.7.4