2fbed0dc6c
Go requires that pointer moves are done 8 bytes at a time, but gccgo uses libc's memmove and memset which does not require that, and there are some cases where an 8 byte move might be done as 4+4. To enforce 8 byte moves for memmove and memset, this adds a C implementation in libgo/runtime for memmove and memset to be used on ppc64le and ppc64. Asm implementations were considered but discarded to avoid different implementations for different target ISAs. Fixes golang/go#41428 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/294931
61 lines
1.3 KiB
C
61 lines
1.3 KiB
C
/* go-memclr.c -- clear a memory buffer
|
|
|
|
Copyright 2016 The Go Authors. All rights reserved.
|
|
Use of this source code is governed by a BSD-style
|
|
license that can be found in the LICENSE file. */
|
|
|
|
#include "runtime.h"
|
|
|
|
void memclrNoHeapPointers(void *, uintptr)
|
|
__asm__ (GOSYM_PREFIX "runtime.memclrNoHeapPointers")
|
|
__attribute__ ((no_split_stack));
|
|
|
|
void
|
|
memclrNoHeapPointers (void *p1, uintptr len)
|
|
{
|
|
|
|
#if !defined(__PPC64__)
|
|
__builtin_memset(p1, 0, len);
|
|
#else
|
|
int64 rem,drem,i;
|
|
uint64 offset;
|
|
volatile uint64 *vp;
|
|
|
|
if (len == 0) {
|
|
return;
|
|
}
|
|
rem = len;
|
|
|
|
offset = (uint64)p1 % 8;
|
|
// This memset is OK since it can't contain
|
|
// an 8 byte aligned pointer.
|
|
if ((rem < 8) || (offset > 0 && offset+rem <= 16)) {
|
|
__builtin_memset(p1, 0, rem);
|
|
return;
|
|
}
|
|
// Move initial bytes to get to 8 byte boundary
|
|
if (offset > 0) {
|
|
__builtin_memset(p1, 0, 8-offset);
|
|
p1 = (void*)((char*)p1+8-offset);
|
|
rem -= 8-offset;
|
|
}
|
|
|
|
// If at least 8 bytes left, clear
|
|
drem = rem>>3;
|
|
|
|
vp = (volatile uint64*)(p1);
|
|
// Without the use of volatile here, the compiler
|
|
// might convert the loop into a memset.
|
|
for (i=0; i<drem; i++) {
|
|
*vp = 0;
|
|
vp++;
|
|
rem -= 8;
|
|
}
|
|
p1 = (void*)((char*)p1 + 8*drem);
|
|
// Clear any remaining
|
|
if (rem > 0) {
|
|
__builtin_memset (p1, 0, rem);
|
|
}
|
|
#endif
|
|
}
|