blob: 0c3b3cd4ff95ae105b812e86cc393db9bb228541 [file] [log] [blame]
// Copyright 2009 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.
package runtime
#include "runtime.h"
#include "type.h"
#include "../../cmd/ld/textflag.h"
bool runtime·use_aeshash;
void
runtime·memprint(uintptr s, void *a)
{
uint64 v;
v = 0xbadb00b;
switch(s) {
case 1:
v = *(uint8*)a;
break;
case 2:
v = *(uint16*)a;
break;
case 4:
v = *(uint32*)a;
break;
case 8:
v = *(uint64*)a;
break;
}
runtime·printint(v);
}
void
runtime·memcopy(uintptr s, void *a, void *b)
{
if(b == nil) {
runtime·memclr(a, s);
return;
}
runtime·memmove(a, b, s);
}
void
runtime·memcopy0(uintptr s, void *a, void *b)
{
USED(s);
USED(a);
USED(b);
}
void
runtime·memcopy8(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
*(uint8*)a = 0;
return;
}
*(uint8*)a = *(uint8*)b;
}
void
runtime·memcopy16(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
*(uint16*)a = 0;
return;
}
*(uint16*)a = *(uint16*)b;
}
void
runtime·memcopy32(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
*(uint32*)a = 0;
return;
}
*(uint32*)a = *(uint32*)b;
}
void
runtime·memcopy64(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
*(uint64*)a = 0;
return;
}
*(uint64*)a = *(uint64*)b;
}
void
runtime·memcopy128(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
((uint64*)a)[0] = 0;
((uint64*)a)[1] = 0;
return;
}
((uint64*)a)[0] = ((uint64*)b)[0];
((uint64*)a)[1] = ((uint64*)b)[1];
}
void
runtime·algslicecopy(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
((Slice*)a)->array = 0;
((Slice*)a)->len = 0;
((Slice*)a)->cap = 0;
return;
}
((Slice*)a)->array = ((Slice*)b)->array;
((Slice*)a)->len = ((Slice*)b)->len;
((Slice*)a)->cap = ((Slice*)b)->cap;
}
void
runtime·strprint(uintptr s, void *a)
{
USED(s);
runtime·printstring(*(String*)a);
}
void
runtime·strcopy(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
((String*)a)->str = 0;
((String*)a)->len = 0;
return;
}
((String*)a)->str = ((String*)b)->str;
((String*)a)->len = ((String*)b)->len;
}
void
runtime·interprint(uintptr s, void *a)
{
USED(s);
runtime·printiface(*(Iface*)a);
}
void
runtime·intercopy(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
((Iface*)a)->tab = 0;
((Iface*)a)->data = 0;
return;
}
((Iface*)a)->tab = ((Iface*)b)->tab;
((Iface*)a)->data = ((Iface*)b)->data;
}
void
runtime·nilinterprint(uintptr s, void *a)
{
USED(s);
runtime·printeface(*(Eface*)a);
}
void
runtime·nilintercopy(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
((Eface*)a)->type = 0;
((Eface*)a)->data = 0;
return;
}
((Eface*)a)->type = ((Eface*)b)->type;
((Eface*)a)->data = ((Eface*)b)->data;
}
extern uintptr runtime·nohashcode;
extern uintptr runtime·noequalcode;
static FuncVal memhashfunc = {(void*)runtime·memhash};
static FuncVal nohashfunc = {(void*)runtime·nohash};
static FuncVal strhashfunc = {(void*)runtime·strhash};
static FuncVal interhashfunc = {(void*)runtime·interhash};
static FuncVal nilinterhashfunc = {(void*)runtime·nilinterhash};
static FuncVal f32hashfunc = {(void*)runtime·f32hash};
static FuncVal f64hashfunc = {(void*)runtime·f64hash};
static FuncVal c64hashfunc = {(void*)runtime·c64hash};
static FuncVal c128hashfunc = {(void*)runtime·c128hash};
static FuncVal aeshashfunc = {(void*)runtime·aeshash};
static FuncVal aeshash32func = {(void*)runtime·aeshash32};
static FuncVal aeshash64func = {(void*)runtime·aeshash64};
static FuncVal aeshashstrfunc = {(void*)runtime·aeshashstr};
static FuncVal memequalfunc = {(void*)runtime·memequal};
static FuncVal noequalfunc = {(void*)runtime·noequal};
static FuncVal strequalfunc = {(void*)runtime·strequal};
static FuncVal interequalfunc = {(void*)runtime·interequal};
static FuncVal nilinterequalfunc = {(void*)runtime·nilinterequal};
static FuncVal f32equalfunc = {(void*)runtime·f32equal};
static FuncVal f64equalfunc = {(void*)runtime·f64equal};
static FuncVal c64equalfunc = {(void*)runtime·c64equal};
static FuncVal c128equalfunc = {(void*)runtime·c128equal};
static FuncVal memequal0func = {(void*)runtime·memequal0};
static FuncVal memequal8func = {(void*)runtime·memequal8};
static FuncVal memequal16func = {(void*)runtime·memequal16};
static FuncVal memequal32func = {(void*)runtime·memequal32};
static FuncVal memequal64func = {(void*)runtime·memequal64};
static FuncVal memequal128func = {(void*)runtime·memequal128};
Alg
runtime·algarray[] =
{
[AMEM] { &memhashfunc, &memequalfunc, runtime·memprint, runtime·memcopy },
[ANOEQ] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·memcopy },
[ASTRING] { &strhashfunc, &strequalfunc, runtime·strprint, runtime·strcopy },
[AINTER] { &interhashfunc, &interequalfunc, runtime·interprint, runtime·intercopy },
[ANILINTER] { &nilinterhashfunc, &nilinterequalfunc, runtime·nilinterprint, runtime·nilintercopy },
[ASLICE] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·algslicecopy },
[AFLOAT32] { &f32hashfunc, &f32equalfunc, runtime·memprint, runtime·memcopy },
[AFLOAT64] { &f64hashfunc, &f64equalfunc, runtime·memprint, runtime·memcopy },
[ACPLX64] { &c64hashfunc, &c64equalfunc, runtime·memprint, runtime·memcopy },
[ACPLX128] { &c128hashfunc, &c128equalfunc, runtime·memprint, runtime·memcopy },
[AMEM0] { &memhashfunc, &memequal0func, runtime·memprint, runtime·memcopy0 },
[AMEM8] { &memhashfunc, &memequal8func, runtime·memprint, runtime·memcopy8 },
[AMEM16] { &memhashfunc, &memequal16func, runtime·memprint, runtime·memcopy16 },
[AMEM32] { &memhashfunc, &memequal32func, runtime·memprint, runtime·memcopy32 },
[AMEM64] { &memhashfunc, &memequal64func, runtime·memprint, runtime·memcopy64 },
[AMEM128] { &memhashfunc, &memequal128func, runtime·memprint, runtime·memcopy128 },
[ANOEQ0] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·memcopy0 },
[ANOEQ8] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·memcopy8 },
[ANOEQ16] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·memcopy16 },
[ANOEQ32] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·memcopy32 },
[ANOEQ64] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·memcopy64 },
[ANOEQ128] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·memcopy128 },
};
// Runtime helpers.
// used in asm_{386,amd64}.s
#pragma dataflag NOPTR
byte runtime·aeskeysched[HashRandomBytes];
void
runtime·hashinit(void)
{
runtime·nohashcode = (uintptr)runtime·nohash;
runtime·noequalcode = (uintptr)runtime·noequal;
if(NaCl)
return;
// Install aes hash algorithm if we have the instructions we need
if((runtime·cpuid_ecx & (1 << 25)) != 0 && // aes (aesenc)
(runtime·cpuid_ecx & (1 << 9)) != 0 && // sse3 (pshufb)
(runtime·cpuid_ecx & (1 << 19)) != 0) { // sse4.1 (pinsr{d,q})
byte *rnd;
int32 n;
runtime·use_aeshash = true;
runtime·algarray[AMEM].hash = &aeshashfunc;
runtime·algarray[AMEM8].hash = &aeshashfunc;
runtime·algarray[AMEM16].hash = &aeshashfunc;
runtime·algarray[AMEM32].hash = &aeshash32func;
runtime·algarray[AMEM64].hash = &aeshash64func;
runtime·algarray[AMEM128].hash = &aeshashfunc;
runtime·algarray[ASTRING].hash = &aeshashstrfunc;
// Initialize with random data so hash collisions will be hard to engineer.
runtime·get_random_data(&rnd, &n);
if(n > HashRandomBytes)
n = HashRandomBytes;
runtime·memmove(runtime·aeskeysched, rnd, n);
if(n < HashRandomBytes) {
// Not very random, but better than nothing.
int64 t = runtime·nanotime();
while (n < HashRandomBytes) {
runtime·aeskeysched[n++] = (int8)(t >> (8 * (n % 8)));
}
}
}
}