From: David Edelsohn Date: Tue, 6 Feb 1996 21:57:54 +0000 (+0000) Subject: movdi 64 bit constants, use HOST_WIDE_INT, update tablejump X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e6ca2c17dc359915ed37cbeea6da852873ff3b94;p=gcc.git movdi 64 bit constants, use HOST_WIDE_INT, update tablejump From-SVN: r11178 --- diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index aaa412b905d..4969fc83806 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -888,14 +888,14 @@ (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))] " { - int low = INTVAL (operands[2]) & 0xffff; - int high = (unsigned) INTVAL (operands[2]) >> 16; + HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff; + HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff); if (low & 0x8000) - high++, low |= 0xffff0000; + high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16; - operands[3] = gen_rtx (CONST_INT, VOIDmode, high << 16); - operands[4] = gen_rtx (CONST_INT, VOIDmode, low); + operands[3] = GEN_INT (high); + operands[4] = GEN_INT (low); }") (define_insn "one_cmplsi2" @@ -3944,14 +3944,14 @@ (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] " { - int low = INTVAL (operands[2]) & 0xffff; - int high = (unsigned) INTVAL (operands[2]) >> 16; + HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff; + HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff); if (low & 0x8000) - high++, low |= 0xffff0000; + high+=0x10000, low |= ((HOST_WIDE_INT) -1) << 16; - operands[3] = gen_rtx (CONST_INT, VOIDmode, high << 16); - operands[4] = gen_rtx (CONST_INT, VOIDmode, low); + operands[3] = GEN_INT (high); + operands[4] = GEN_INT (low); }") (define_insn "one_cmpldi2" @@ -4503,7 +4503,7 @@ " { operands[3] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xffff0000); + INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff)); operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff); }") @@ -5301,11 +5301,14 @@ ;; multiple insns. (define_expand "movdi" [(set (match_operand:DI 0 "general_operand" "") - (match_operand:DI 1 "general_operand" ""))] + (match_operand:DI 1 "any_operand" ""))] "" " { - if (GET_CODE (operands[0]) == MEM) + if (! TARGET_64BIT && ! general_operand (operands[1], DImode)) + FAIL; + + if (GET_CODE (operands[0]) != REG) operands[1] = force_reg (DImode, operands[1]); if (GET_CODE (operands[1]) == CONST_DOUBLE @@ -5319,18 +5322,50 @@ low = CONST_DOUBLE_LOW (operands[1]); high = CONST_DOUBLE_HIGH (operands[1]); } - else + else if (HOST_BITS_PER_WIDE_INT <= 32) { low = INTVAL (operands[1]); high = (low < 0) ? ~0 : 0; } + else + { + low = INTVAL (operands[1]) & 0xffffffff; + high = (unsigned long long) INTVAL (operands[1]) >> 32; + } - emit_move_insn (gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN), - GEN_INT (low)); + if (! TARGET_POWERPC64) + { + emit_move_insn (gen_rtx (SUBREG, SImode, operands[0], + WORDS_BIG_ENDIAN), GEN_INT (low)); - emit_move_insn (gen_rtx (SUBREG, SImode, operands[0], !WORDS_BIG_ENDIAN), - GEN_INT (high)); - DONE; + emit_move_insn (gen_rtx (SUBREG, SImode, operands[0], + ! WORDS_BIG_ENDIAN), GEN_INT (high)); + DONE; + } + else + { + if (high + 0x8000 >= 0x10000) + { + emit_move_insn (gen_rtx (SUBREG, SImode, operands[0], 1), + GEN_INT (high)); + emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT(32))); + if (low) + { + HOST_WIDE_INT low_low = low & 0xffff; + HOST_WIDE_INT low_high = low & (~ (HOST_WIDE_INT) 0xffff); + if (low_high) + emit_insn (gen_iordi3 (operands[0], operands[0], + GEN_INT (low_high))); + if (low_low) + emit_insn (gen_iordi3 (operands[0], operands[0], + GEN_INT (low_low))); + } + } + else if (low) + emit_move_insn (gen_rtx (SUBREG, SImode, operands[0], 1), + GEN_INT (low)); + DONE; + } } /* Stores between FPR and any non-FPR registers must go through a @@ -5391,8 +5426,8 @@ (set_attr "length" "8,8,8,*,*,*")]) (define_insn "" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,f,f,m,r,*h,*h") - (match_operand:DI 1 "input_operand" "r,m,r,I,J,R,f,m,f,*h,r,0"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,f,f,m,r,*h,*h") + (match_operand:DI 1 "input_operand" "r,m,r,I,J,n,R,f,m,f,*h,r,0"))] "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode) || gpc_reg_operand (operands[1], DImode))" "@ @@ -5401,6 +5436,7 @@ std%U0%X0 %1,%0 li %0,%1 lis %0,%u1 + # {cal|la} %0,%1(%*) fmr %0,%1 lfd%U1%X1 %0,%1 @@ -5408,7 +5444,61 @@ mf%1 %0 mt%0 %1 cror 0,0,0" - [(set_attr "type" "*,load,*,*,*,*,fp,fpload,*,*,mtjmpr,*")]) + [(set_attr "type" "*,load,*,*,*,*,*,fp,fpload,*,*,mtjmpr,*") + (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")]) + +;; Split a load of a large constant into the appropriate five-instruction +;; sequence. The expansion in movdi tries to perform the minimum number of +;; steps, but here we have to handle anything in a constant number of insns. + +(define_split + [(set (match_operand:DI 0 "gpc_reg_operand" "") + (match_operand:DI 1 "const_double_operand" ""))] + "TARGET_POWERPC64" + [(set (match_dup 0) + (match_dup 2)) + (set (match_dup 0) + (ior:DI (match_dup 0) + (match_dup 3))) + (set (match_dup 0) + (ashift:DI (match_dup 0) + (const_int 32))) + (set (match_dup 0) + (ior:DI (match_dup 0) + (match_dup 4))) + (set (match_dup 0) + (ior:DI (match_dup 0) + (match_dup 5)))] + " +{ + HOST_WIDE_INT low; + HOST_WIDE_INT high; + + if (GET_CODE (operands[1]) == CONST_DOUBLE) + { + low = CONST_DOUBLE_LOW (operands[1]); + high = CONST_DOUBLE_HIGH (operands[1]); + } + else if (HOST_BITS_PER_WIDE_INT <= 32) + { + low = INTVAL (operands[1]); + high = (low < 0) ? ~0 : 0; + } + else + { + low = INTVAL (operands[1]) & 0xffffffff; + high = (unsigned long long) INTVAL (operands[1]) >> 32; + } + + if ((high + 0x8000) < 0x10000 + && ((low & 0xffff) == 0 || (low & (~ (HOST_WIDE_INT) 0xffff)) == 0)) + FAIL; + + operands[2] = GEN_INT (high & (~ (HOST_WIDE_INT) 0xffff)); + operands[3] = GEN_INT (high & 0xffff); + operands[4] = GEN_INT (low & (~ (HOST_WIDE_INT) 0xffff)); + operands[5] = GEN_INT (low & 0xffff); +}") (define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x") @@ -6242,18 +6332,18 @@ || INTVAL (operands[0]) > 32768) { neg_op0 = gen_reg_rtx (Pmode); - if (TARGET_POWERPC64) - emit_insn (gen_negdi2 (neg_op0, operands[0])); - else + if (TARGET_32BIT) emit_insn (gen_negsi2 (neg_op0, operands[0])); + else + emit_insn (gen_negdi2 (neg_op0, operands[0])); } else neg_op0 = GEN_INT (- INTVAL (operands[0])); - if (TARGET_POWERPC64) - emit_insn (gen_movdi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain)); - else + if (TARGET_32BIT) emit_insn (gen_movsi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain)); + else + emit_insn (gen_movdi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain)); DONE; }") @@ -8432,6 +8522,19 @@ ;; Table jump for switch statements: (define_expand "tablejump" + [(use (match_operand 0 "" "")) + (use (label_ref (match_operand 1 "" "")))] + "" + " +{ + if (TARGET_32BIT) + emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); + else + emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); + DONE; +}") + +(define_expand "tablejumpsi" [(set (match_dup 3) (plus:SI (match_operand:SI 0 "" "") (match_dup 2))) @@ -8444,6 +8547,19 @@ operands[3] = gen_reg_rtx (SImode); }") +(define_expand "tablejumpdi" + [(set (match_dup 3) + (plus:DI (match_operand:DI 0 "" "") + (match_dup 2))) + (parallel [(set (pc) (match_dup 3)) + (use (label_ref (match_operand 1 "" "")))])] + "" + " +{ operands[0] = force_reg (DImode, operands[0]); + operands[2] = force_reg (DImode, gen_rtx (LABEL_REF, VOIDmode, operands[1])); + operands[3] = gen_reg_rtx (DImode); +}") + (define_insn "" [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))