Commit e6ca2c17 by David Edelsohn

movdi 64 bit constants, use HOST_WIDE_INT, update tablejump

From-SVN: r11178
parent fc69eca0
...@@ -888,14 +888,14 @@ ...@@ -888,14 +888,14 @@
(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))] (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
" "
{ {
int low = INTVAL (operands[2]) & 0xffff; HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
int high = (unsigned) INTVAL (operands[2]) >> 16; HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
if (low & 0x8000) if (low & 0x8000)
high++, low |= 0xffff0000; high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
operands[3] = gen_rtx (CONST_INT, VOIDmode, high << 16); operands[3] = GEN_INT (high);
operands[4] = gen_rtx (CONST_INT, VOIDmode, low); operands[4] = GEN_INT (low);
}") }")
(define_insn "one_cmplsi2" (define_insn "one_cmplsi2"
...@@ -3944,14 +3944,14 @@ ...@@ -3944,14 +3944,14 @@
(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
" "
{ {
int low = INTVAL (operands[2]) & 0xffff; HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
int high = (unsigned) INTVAL (operands[2]) >> 16; HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
if (low & 0x8000) if (low & 0x8000)
high++, low |= 0xffff0000; high+=0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
operands[3] = gen_rtx (CONST_INT, VOIDmode, high << 16); operands[3] = GEN_INT (high);
operands[4] = gen_rtx (CONST_INT, VOIDmode, low); operands[4] = GEN_INT (low);
}") }")
(define_insn "one_cmpldi2" (define_insn "one_cmpldi2"
...@@ -4503,7 +4503,7 @@ ...@@ -4503,7 +4503,7 @@
" "
{ {
operands[3] = gen_rtx (CONST_INT, VOIDmode, 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); operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
}") }")
...@@ -5301,11 +5301,14 @@ ...@@ -5301,11 +5301,14 @@
;; multiple insns. ;; multiple insns.
(define_expand "movdi" (define_expand "movdi"
[(set (match_operand:DI 0 "general_operand" "") [(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]); operands[1] = force_reg (DImode, operands[1]);
if (GET_CODE (operands[1]) == CONST_DOUBLE if (GET_CODE (operands[1]) == CONST_DOUBLE
...@@ -5319,19 +5322,51 @@ ...@@ -5319,19 +5322,51 @@
low = CONST_DOUBLE_LOW (operands[1]); low = CONST_DOUBLE_LOW (operands[1]);
high = CONST_DOUBLE_HIGH (operands[1]); high = CONST_DOUBLE_HIGH (operands[1]);
} }
else else if (HOST_BITS_PER_WIDE_INT <= 32)
{ {
low = INTVAL (operands[1]); low = INTVAL (operands[1]);
high = (low < 0) ? ~0 : 0; 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), if (! TARGET_POWERPC64)
GEN_INT (low)); {
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), 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)); 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; DONE;
} }
}
/* Stores between FPR and any non-FPR registers must go through a /* Stores between FPR and any non-FPR registers must go through a
temporary stack slot. */ temporary stack slot. */
...@@ -5391,8 +5426,8 @@ ...@@ -5391,8 +5426,8 @@
(set_attr "length" "8,8,8,*,*,*")]) (set_attr "length" "8,8,8,*,*,*")])
(define_insn "" (define_insn ""
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,f,f,m,r,*h,*h") [(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,R,f,m,f,*h,r,0"))] (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) "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode)
|| gpc_reg_operand (operands[1], DImode))" || gpc_reg_operand (operands[1], DImode))"
"@ "@
...@@ -5401,6 +5436,7 @@ ...@@ -5401,6 +5436,7 @@
std%U0%X0 %1,%0 std%U0%X0 %1,%0
li %0,%1 li %0,%1
lis %0,%u1 lis %0,%u1
#
{cal|la} %0,%1(%*) {cal|la} %0,%1(%*)
fmr %0,%1 fmr %0,%1
lfd%U1%X1 %0,%1 lfd%U1%X1 %0,%1
...@@ -5408,7 +5444,61 @@ ...@@ -5408,7 +5444,61 @@
mf%1 %0 mf%1 %0
mt%0 %1 mt%0 %1
cror 0,0,0" 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 "" (define_insn ""
[(set (match_operand:CC 2 "cc_reg_operand" "=x") [(set (match_operand:CC 2 "cc_reg_operand" "=x")
...@@ -6242,18 +6332,18 @@ ...@@ -6242,18 +6332,18 @@
|| INTVAL (operands[0]) > 32768) || INTVAL (operands[0]) > 32768)
{ {
neg_op0 = gen_reg_rtx (Pmode); neg_op0 = gen_reg_rtx (Pmode);
if (TARGET_POWERPC64) if (TARGET_32BIT)
emit_insn (gen_negdi2 (neg_op0, operands[0]));
else
emit_insn (gen_negsi2 (neg_op0, operands[0])); emit_insn (gen_negsi2 (neg_op0, operands[0]));
else
emit_insn (gen_negdi2 (neg_op0, operands[0]));
} }
else else
neg_op0 = GEN_INT (- INTVAL (operands[0])); neg_op0 = GEN_INT (- INTVAL (operands[0]));
if (TARGET_POWERPC64) if (TARGET_32BIT)
emit_insn (gen_movdi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
else
emit_insn (gen_movsi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain)); 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; DONE;
}") }")
...@@ -8432,6 +8522,19 @@ ...@@ -8432,6 +8522,19 @@
;; Table jump for switch statements: ;; Table jump for switch statements:
(define_expand "tablejump" (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) [(set (match_dup 3)
(plus:SI (match_operand:SI 0 "" "") (plus:SI (match_operand:SI 0 "" "")
(match_dup 2))) (match_dup 2)))
...@@ -8444,6 +8547,19 @@ ...@@ -8444,6 +8547,19 @@
operands[3] = gen_reg_rtx (SImode); 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 "" (define_insn ""
[(set (pc) [(set (pc)
(match_operand:SI 0 "register_operand" "c,l")) (match_operand:SI 0 "register_operand" "c,l"))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment