From 2e41c392fac193dc5e363cd8e3493bc5ae5e0e7f Mon Sep 17 00:00:00 2001 From: George Koehler Date: Sat, 11 Feb 2017 19:30:12 -0500 Subject: [PATCH] Implement blm and bls using an inline loop. This replaces a call to memmove() in libc. That was working for me, but it can fail because EM programs don't always link to libc. blm and bls only need to copy aligned words. They don't need to copy bytes, and they don't need to copy between overlapping buffers, as memmove() does. So the new loop is simpler than memmove(). --- mach/powerpc/ncg/table | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/mach/powerpc/ncg/table b/mach/powerpc/ncg/table index 1ba20a85e..569f3dde4 100644 --- a/mach/powerpc/ncg/table +++ b/mach/powerpc/ncg/table @@ -289,6 +289,7 @@ INSTRUCTIONS andisX "andis." GPR:wo:cc, GPR:ro, CONST:ro. b LABEL:ro. bc CONST:ro, CONST:ro, LABEL:ro. + bdnz LABEL:ro. beq LABEL:ro. bne LABEL:ro. bgt LABEL:ro. @@ -362,6 +363,7 @@ INSTRUCTIONS rlwinm GPR:wo, GPR:ro, CONST:ro, CONST:ro, CONST:ro. extlwi GPR:wo, GPR:ro, CONST:ro, CONST:ro. extrwi GPR:wo, GPR:ro, CONST:ro, CONST:ro. + srwi GPR:wo, GPR:ro, CONST:ro. slw GPR:wo, GPR:ro, GPR:ro. subf GPR:wo, GPR:ro, GPR:ro. sraw GPR:wo, GPR:ro, GPR:ro cost(4, 2). @@ -1930,24 +1932,22 @@ PATTERNS b {LABEL, ".ret"} pat blm /* Block move constant length */ - with REG REG STACK - uses REG - gen - move {CONST, $1}, %a - stwu %a, {IND_RC_W, SP, 0-4} - stwu %2, {IND_RC_W, SP, 0-4} - stwu %1, {IND_RC_W, SP, 0-4} - bl {LABEL, "_memmove"} - addi SP, SP, {CONST, 12} + leaving + loc $1 + bls pat bls /* Block move variable length */ - with REG REG REG STACK + with REG REG REG + uses reusing %1, REG, REG={CONST_0000_7FFF, 0} gen - stwu %1, {IND_RC_W, SP, 0-4} - stwu %3, {IND_RC_W, SP, 0-4} - stwu %2, {IND_RC_W, SP, 0-4} - bl {LABEL, "_memmove"} - addi SP, SP, {CONST, 12} + /* Wrong if size is zero */ + srwi %1, %1, {CONST, 2} + mtspr CTR, %1 + 1: + lwzx %a, %3, %b + stwx %a, %2, %b + addi %b, %b, {CONST, 4} + bdnz {LABEL, "1b"} pat csa /* Array-lookup switch */ with STACK