Commit dea44e56 by Paul Koning Committed by Paul Koning

pdp11.md (movmemhi, movmemhi1): Correct constraints.

* config/pdp11/pdp11.md (movmemhi, movmemhi1): Correct
constraints. 
* config/pdp11/pdp11.c (output_block_move): Rewrite.

From-SVN: r168338
parent fd3ce292
2010-12-30 Paul Koning <ni1d@arrl.net>
* config/pdp11/pdp11.md (movmemhi, movmemhi1): Correct
constraints.
* config/pdp11/pdp11.c (output_block_move): Rewrite.
2010-12-30 Jakub Jelinek <jakub@redhat.com> 2010-12-30 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/47060 PR tree-optimization/47060
...@@ -1167,236 +1167,157 @@ output_block_move(rtx *operands) ...@@ -1167,236 +1167,157 @@ output_block_move(rtx *operands)
{ {
static int count = 0; static int count = 0;
char buf[200]; char buf[200];
int unroll;
int lastbyte = 0;
if (GET_CODE(operands[2]) == CONST_INT /* Move of zero bytes is a NOP. */
&& ! optimize_size) if (operands[2] == const0_rtx)
return "";
/* Look for moves by small constant byte counts, those we'll
expand to straight line code. */
if (CONSTANT_P (operands[2]))
{ {
if (INTVAL(operands[2]) < 16 if (INTVAL (operands[2]) < 16
&& INTVAL(operands[3]) == 1) && (!optimize_size || INTVAL (operands[2]) < 5)
&& INTVAL (operands[3]) == 1)
{ {
register int i; register int i;
for (i = 1; i <= INTVAL(operands[2]); i++) for (i = 1; i <= INTVAL (operands[2]); i++)
output_asm_insn("movb (%1)+, (%0)+", operands); output_asm_insn("movb (%1)+, (%0)+", operands);
return ""; return "";
} }
else if (INTVAL(operands[2]) < 32) else if (INTVAL(operands[2]) < 32
&& (!optimize_size || INTVAL (operands[2]) < 9)
&& INTVAL (operands[3]) >= 2)
{ {
register int i; register int i;
for (i = 1; i <= INTVAL(operands[2])/2; i++) for (i = 1; i <= INTVAL (operands[2]) / 2; i++)
output_asm_insn("mov (%1)+, (%0)+", operands); output_asm_insn ("mov (%1)+, (%0)+", operands);
if (INTVAL (operands[2]) & 1)
output_asm_insn ("movb (%1), (%0)", operands);
/* may I assume that moved quantity is
multiple of alignment ???
I HOPE SO !
*/
return ""; return "";
} }
/* can do other clever things, maybe... */
} }
if (CONSTANT_P(operands[2]) ) /* Ideally we'd look for moves that are multiples of 4 or 8
bytes and handle those by unrolling the move loop. That
makes for a lot of code if done at run time, but it's ok
for constant counts. Also, for variable counts we have
to worry about odd byte count with even aligned pointers.
On 11/40 and up we handle that case; on older machines
we don't and just use byte-wise moves all the time. */
if (CONSTANT_P (operands[2]) )
{ {
/* just move count to scratch */ if (INTVAL (operands[3]) < 2)
output_asm_insn("mov %2, %4", operands); unroll = 0;
else
{
lastbyte = INTVAL (operands[2]) & 1;
if (optimize_size || INTVAL (operands[2]) & 2)
unroll = 1;
else if (INTVAL (operands[2]) & 4)
unroll = 2;
else
unroll = 3;
}
/* Loop count is byte count scaled by unroll. */
operands[2] = GEN_INT (INTVAL (operands[2]) >> unroll);
output_asm_insn ("mov %2, %4", operands);
} }
else else
{ {
/* just clobber the register */ /* Variable byte count; use the input register
as the scratch. */
operands[4] = operands[2]; operands[4] = operands[2];
}
/* switch over alignment */ /* Decide whether to move by words, and check
switch (INTVAL(operands[3])) the byte count for zero. */
{ if (TARGET_40_PLUS && INTVAL (operands[3]) > 1)
case 1: {
unroll = 1;
/* output_asm_insn ("asr %4", operands);
x: }
movb (%1)+, (%0)+ else
{
if (TARGET_45) unroll = 0;
sob %4,x output_asm_insn ("tst %4", operands);
else }
dec %4 sprintf (buf, "beq movestrhi%d", count + 1);
bgt x output_asm_insn (buf, NULL);
}
*/ /* Output the loop label. */
sprintf (buf, "\nmovestrhi%d:", count);
output_asm_insn (buf, NULL);
sprintf(buf, "\nmovestrhi%d:", count); /* Output the appropriate move instructions. */
output_asm_insn(buf, NULL); switch (unroll)
{
output_asm_insn("movb (%1)+, (%0)+", operands); case 0:
output_asm_insn ("movb (%1)+, (%0)+", operands);
if (TARGET_45) break;
{
sprintf(buf, "sob %%4, movestrhi%d", count);
output_asm_insn(buf, operands);
}
else
{
output_asm_insn("dec %4", operands);
sprintf(buf, "bgt movestrhi%d", count);
output_asm_insn(buf, NULL);
}
count ++; case 1:
output_asm_insn ("mov (%1)+, (%0)+", operands);
break; break;
case 2: case 2:
output_asm_insn ("mov (%1)+, (%0)+", operands);
/* output_asm_insn ("mov (%1)+, (%0)+", operands);
asr %4
x:
mov (%1)+, (%0)+
if (TARGET_45)
sob %4, x
else
dec %4
bgt x
*/
generate_compact_code:
output_asm_insn("asr %4", operands);
sprintf(buf, "\nmovestrhi%d:", count);
output_asm_insn(buf, NULL);
output_asm_insn("mov (%1)+, (%0)+", operands);
if (TARGET_45)
{
sprintf(buf, "sob %%4, movestrhi%d", count);
output_asm_insn(buf, operands);
}
else
{
output_asm_insn("dec %4", operands);
sprintf(buf, "bgt movestrhi%d", count);
output_asm_insn(buf, NULL);
}
count ++;
break; break;
case 4:
/*
asr %4
asr %4
x:
mov (%1)+, (%0)+
mov (%1)+, (%0)+
if (TARGET_45)
sob %4, x
else
dec %4
bgt x
*/
if (optimize_size)
goto generate_compact_code;
output_asm_insn("asr %4", operands);
output_asm_insn("asr %4", operands);
sprintf(buf, "\nmovestrhi%d:", count);
output_asm_insn(buf, NULL);
output_asm_insn("mov (%1)+, (%0)+", operands);
output_asm_insn("mov (%1)+, (%0)+", operands);
if (TARGET_45)
{
sprintf(buf, "sob %%4, movestrhi%d", count);
output_asm_insn(buf, operands);
}
else
{
output_asm_insn("dec %4", operands);
sprintf(buf, "bgt movestrhi%d", count);
output_asm_insn(buf, NULL);
}
count ++;
break;
default: default:
output_asm_insn ("mov (%1)+, (%0)+", operands);
/* output_asm_insn ("mov (%1)+, (%0)+", operands);
output_asm_insn ("mov (%1)+, (%0)+", operands);
asr %4 output_asm_insn ("mov (%1)+, (%0)+", operands);
asr %4
asr %4
x:
mov (%1)+, (%0)+
mov (%1)+, (%0)+
mov (%1)+, (%0)+
mov (%1)+, (%0)+
if (TARGET_45)
sob %4, x
else
dec %4
bgt x
*/
if (optimize_size)
goto generate_compact_code;
output_asm_insn("asr %4", operands);
output_asm_insn("asr %4", operands);
output_asm_insn("asr %4", operands);
sprintf(buf, "\nmovestrhi%d:", count);
output_asm_insn(buf, NULL);
output_asm_insn("mov (%1)+, (%0)+", operands);
output_asm_insn("mov (%1)+, (%0)+", operands);
output_asm_insn("mov (%1)+, (%0)+", operands);
output_asm_insn("mov (%1)+, (%0)+", operands);
if (TARGET_45)
{
sprintf(buf, "sob %%4, movestrhi%d", count);
output_asm_insn(buf, operands);
}
else
{
output_asm_insn("dec %4", operands);
sprintf(buf, "bgt movestrhi%d", count);
output_asm_insn(buf, NULL);
}
count ++;
break; break;
;
} }
/* Output the decrement and test. */
if (TARGET_40_PLUS)
{
sprintf (buf, "sob %%4, movestrhi%d", count);
output_asm_insn (buf, operands);
}
else
{
output_asm_insn ("dec %4", operands);
sprintf (buf, "bgt movestrhi%d", count);
output_asm_insn (buf, NULL);
}
count ++;
/* If constant odd byte count, move the last byte. */
if (lastbyte)
output_asm_insn ("movb (%1), (%0)", operands);
else if (!CONSTANT_P (operands[2]))
{
/* Output the destination label for the zero byte count check. */
sprintf (buf, "\nmovestrhi%d:", count);
output_asm_insn (buf, NULL);
count++;
/* If we did word moves, check for trailing last byte. */
if (unroll)
{
sprintf (buf, "bcc movestrhi%d", count);
output_asm_insn (buf, NULL);
output_asm_insn ("movb (%1), (%0)", operands);
sprintf (buf, "\nmovestrhi%d:", count);
output_asm_insn (buf, NULL);
count++;
}
}
return ""; return "";
} }
......
...@@ -321,7 +321,7 @@ ...@@ -321,7 +321,7 @@
(define_expand "movmemhi" (define_expand "movmemhi"
[(parallel [(set (match_operand:BLK 0 "general_operand" "=g,g") [(parallel [(set (match_operand:BLK 0 "general_operand" "=g,g")
(match_operand:BLK 1 "general_operand" "g,g")) (match_operand:BLK 1 "general_operand" "g,g"))
(use (match_operand:HI 2 "general_operand" "n,&mr")) (use (match_operand:HI 2 "general_operand" "n,mr"))
(use (match_operand:HI 3 "immediate_operand" "i,i")) (use (match_operand:HI 3 "immediate_operand" "i,i"))
(clobber (match_scratch:HI 4 "=&r,X")) (clobber (match_scratch:HI 4 "=&r,X"))
(clobber (match_dup 5)) (clobber (match_dup 5))
...@@ -342,10 +342,10 @@ ...@@ -342,10 +342,10 @@
}") }")
(define_insn "" ; "movmemhi" (define_insn "movmemhi1"
[(set (mem:BLK (match_operand 0 "pmode_register_operand" "+r,r")) [(set (mem:BLK (match_operand:HI 0 "register_operand" "r,r"))
(mem:BLK (match_operand 1 "pmode_register_operand" "+r,r"))) (mem:BLK (match_operand:HI 1 "register_operand" "r,r")))
(use (match_operand:HI 2 "general_operand" "+n,&r")) (use (match_operand:HI 2 "general_operand" "n,r"))
(use (match_operand:HI 3 "immediate_operand" "i,i")) (use (match_operand:HI 3 "immediate_operand" "i,i"))
(clobber (match_scratch:HI 4 "=&r,X")) (clobber (match_scratch:HI 4 "=&r,X"))
(clobber (match_dup 0)) (clobber (match_dup 0))
......
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