From: Paul Koning Date: Thu, 30 Dec 2010 11:50:40 +0000 (-0500) Subject: pdp11.md (movmemhi, movmemhi1): Correct constraints. X-Git-Tag: upstream/12.2.0~87423 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dea44e569da296dab34c6f76b259c0844083a919;p=platform%2Fupstream%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 067ed75..a3e7fae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-12-30 Paul Koning + + * config/pdp11/pdp11.md (movmemhi, movmemhi1): Correct + constraints. + * config/pdp11/pdp11.c (output_block_move): Rewrite. + 2010-12-30 Jakub Jelinek PR tree-optimization/47060 diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c index 9c7b476..3a7f9d6 100644 --- a/gcc/config/pdp11/pdp11.c +++ b/gcc/config/pdp11/pdp11.c @@ -1167,236 +1167,157 @@ output_block_move(rtx *operands) { static int count = 0; char buf[200]; + int unroll; + int lastbyte = 0; - if (GET_CODE(operands[2]) == CONST_INT - && ! optimize_size) + /* Move of zero bytes is a NOP. */ + 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 - && INTVAL(operands[3]) == 1) + if (INTVAL (operands[2]) < 16 + && (!optimize_size || INTVAL (operands[2]) < 5) + && INTVAL (operands[3]) == 1) { 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); 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; - for (i = 1; i <= INTVAL(operands[2])/2; i++) - output_asm_insn("mov (%1)+, (%0)+", operands); + for (i = 1; i <= INTVAL (operands[2]) / 2; i++) + 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 ""; } - - - /* 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 */ - output_asm_insn("mov %2, %4", operands); + if (INTVAL (operands[3]) < 2) + 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 { - /* just clobber the register */ + /* Variable byte count; use the input register + as the scratch. */ operands[4] = operands[2]; - } - - /* switch over alignment */ - switch (INTVAL(operands[3])) - { - case 1: - - /* - x: - movb (%1)+, (%0)+ - - if (TARGET_45) - sob %4,x - else - dec %4 - bgt x + /* Decide whether to move by words, and check + the byte count for zero. */ + if (TARGET_40_PLUS && INTVAL (operands[3]) > 1) + { + unroll = 1; + output_asm_insn ("asr %4", operands); + } + else + { + unroll = 0; + output_asm_insn ("tst %4", operands); + } + sprintf (buf, "beq movestrhi%d", count + 1); + 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_asm_insn(buf, NULL); - - output_asm_insn("movb (%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); - } + /* Output the appropriate move instructions. */ + switch (unroll) + { + case 0: + output_asm_insn ("movb (%1)+, (%0)+", operands); + break; - count ++; + case 1: + output_asm_insn ("mov (%1)+, (%0)+", operands); break; case 2: - - /* - 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 ++; + output_asm_insn ("mov (%1)+, (%0)+", operands); + output_asm_insn ("mov (%1)+, (%0)+", operands); 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: - - /* - - asr %4 - 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 ++; + 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); 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 ""; } diff --git a/gcc/config/pdp11/pdp11.md b/gcc/config/pdp11/pdp11.md index 0566d9a..aa7512b 100644 --- a/gcc/config/pdp11/pdp11.md +++ b/gcc/config/pdp11/pdp11.md @@ -321,7 +321,7 @@ (define_expand "movmemhi" [(parallel [(set (match_operand:BLK 0 "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")) (clobber (match_scratch:HI 4 "=&r,X")) (clobber (match_dup 5)) @@ -342,10 +342,10 @@ }") -(define_insn "" ; "movmemhi" - [(set (mem:BLK (match_operand 0 "pmode_register_operand" "+r,r")) - (mem:BLK (match_operand 1 "pmode_register_operand" "+r,r"))) - (use (match_operand:HI 2 "general_operand" "+n,&r")) +(define_insn "movmemhi1" + [(set (mem:BLK (match_operand:HI 0 "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 3 "immediate_operand" "i,i")) (clobber (match_scratch:HI 4 "=&r,X")) (clobber (match_dup 0))