redo JIT superscalar to include less custom assembly
This commit is contained in:
parent
a71d8f6a2e
commit
34cfab4176
5
cache.go
5
cache.go
|
@ -12,8 +12,7 @@ type MemoryBlock [128]uint64
|
|||
|
||||
func (m *MemoryBlock) GetLine(addr uint64) *RegisterLine {
|
||||
addr >>= 3
|
||||
//[addr : addr+8 : addr+8]
|
||||
return (*RegisterLine)(unsafe.Add(unsafe.Pointer(m), addr*8))
|
||||
return (*RegisterLine)(unsafe.Pointer(unsafe.SliceData(m[addr : addr+8 : addr+8])))
|
||||
}
|
||||
|
||||
type Randomx_Cache struct {
|
||||
|
@ -21,7 +20,7 @@ type Randomx_Cache struct {
|
|||
|
||||
Programs [RANDOMX_PROGRAM_COUNT]SuperScalarProgram
|
||||
|
||||
JitPrograms [RANDOMX_PROGRAM_COUNT]ProgramFunc
|
||||
JitPrograms [RANDOMX_PROGRAM_COUNT]SuperScalarProgramFunc
|
||||
|
||||
Flags uint64
|
||||
}
|
||||
|
|
2
exec.go
2
exec.go
|
@ -1,3 +1,3 @@
|
|||
package randomx
|
||||
|
||||
type ProgramFunc []byte
|
||||
type SuperScalarProgramFunc []byte
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
package randomx
|
||||
|
||||
func (f ProgramFunc) Execute(v uintptr) {
|
||||
|
||||
}
|
||||
|
||||
func (f ProgramFunc) Close() error {
|
||||
func (f SuperScalarProgramFunc) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -4,35 +4,13 @@ package randomx
|
|||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func (f ProgramFunc) Execute(v uintptr) {
|
||||
if f == nil {
|
||||
panic("program is nil")
|
||||
}
|
||||
|
||||
var reservedStackHack [8 * 8]byte
|
||||
for i := range reservedStackHack {
|
||||
reservedStackHack[i] = uint8(i)
|
||||
}
|
||||
|
||||
memoryPtr := &f
|
||||
fun := *(*func(v uintptr))(unsafe.Pointer(&memoryPtr))
|
||||
fun(v)
|
||||
|
||||
for i := range reservedStackHack {
|
||||
reservedStackHack[i] = uint8(-i)
|
||||
}
|
||||
runtime.KeepAlive(reservedStackHack)
|
||||
}
|
||||
|
||||
func (f ProgramFunc) Close() error {
|
||||
func (f SuperScalarProgramFunc) Close() error {
|
||||
return unix.Munmap(f)
|
||||
}
|
||||
|
||||
func mapProgram(program []byte) ProgramFunc {
|
||||
func mapProgram(program []byte) []byte {
|
||||
// Write only
|
||||
execFunc, err := unix.Mmap(-1, 0, len(program), unix.PROT_WRITE, unix.MAP_PRIVATE|unix.MAP_ANONYMOUS)
|
||||
if err != nil {
|
||||
|
|
54
jit_amd64.go
54
jit_amd64.go
|
@ -11,8 +11,8 @@ package randomx
|
|||
; rcx -> temporary
|
||||
; rdx -> temporary
|
||||
; rsi -> scratchpad pointer
|
||||
; rdi -> dataset pointer
|
||||
; rbp -> memory registers "ma" (high 32 bits), "mx" (low 32 bits)
|
||||
; rdi -> return address // dataset pointer
|
||||
; rbp -> (do not use, it's used by Golang sampling) jump target //todo: memory registers "ma" (high 32 bits), "mx" (low 32 bits)
|
||||
; rsp -> stack pointer
|
||||
; r8 -> "r0"
|
||||
; r9 -> "r1"
|
||||
|
@ -154,53 +154,3 @@ var NOP8 = []byte{0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}
|
|||
func genSIB(scale, index, base int) byte {
|
||||
return byte((scale << 6) | (index << 3) | base)
|
||||
}
|
||||
|
||||
/*
|
||||
push rbp
|
||||
push rbx
|
||||
push rsi
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
mov rbp,rsp
|
||||
sub rsp,(0x8*7)
|
||||
|
||||
mov rsi, rax; # register dataset
|
||||
|
||||
prefetchnta byte ptr [rsi]
|
||||
|
||||
mov r8, qword ptr [rsi+0]
|
||||
mov r9, qword ptr [rsi+8]
|
||||
mov r10, qword ptr [rsi+16]
|
||||
mov r11, qword ptr [rsi+24]
|
||||
mov r12, qword ptr [rsi+32]
|
||||
mov r13, qword ptr [rsi+40]
|
||||
mov r14, qword ptr [rsi+48]
|
||||
mov r15, qword ptr [rsi+56]
|
||||
*/
|
||||
var codeInitBlock = []byte{0x55, 0x53, 0x56, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x89, 0xE5, 0x48, 0x83, 0xEC, 0x38, 0x48, 0x89, 0xC6, 0x0F, 0x18, 0x06, 0x4C, 0x8B, 0x06, 0x4C, 0x8B, 0x4E, 0x08, 0x4C, 0x8B, 0x56, 0x10, 0x4C, 0x8B, 0x5E, 0x18, 0x4C, 0x8B, 0x66, 0x20, 0x4C, 0x8B, 0x6E, 0x28, 0x4C, 0x8B, 0x76, 0x30, 0x4C, 0x8B, 0x7E, 0x38}
|
||||
|
||||
/*
|
||||
prefetchw byte ptr [rsi]
|
||||
|
||||
mov qword ptr [rsi+0], r8
|
||||
mov qword ptr [rsi+8], r9
|
||||
mov qword ptr [rsi+16], r10
|
||||
mov qword ptr [rsi+24], r11
|
||||
mov qword ptr [rsi+32], r12
|
||||
mov qword ptr [rsi+40], r13
|
||||
mov qword ptr [rsi+48], r14
|
||||
mov qword ptr [rsi+56], r15
|
||||
|
||||
add rsp,(0x8*7)
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop rsi
|
||||
pop rbx
|
||||
pop rbp
|
||||
ret
|
||||
*/
|
||||
var codeRetBlock = []byte{0x0F, 0x0D, 0x0E, 0x4C, 0x89, 0x06, 0x4C, 0x89, 0x4E, 0x08, 0x4C, 0x89, 0x56, 0x10, 0x4C, 0x89, 0x5E, 0x18, 0x4C, 0x89, 0x66, 0x20, 0x4C, 0x89, 0x6E, 0x28, 0x4C, 0x89, 0x76, 0x30, 0x4C, 0x89, 0x7E, 0x38, 0x48, 0x83, 0xC4, 0x38, 0x41, 0x5F, 0x41, 0x5E, 0x41, 0x5D, 0x41, 0x5C, 0x5E, 0x5B, 0x5D, 0xC3}
|
||||
|
|
|
@ -4,15 +4,41 @@ package randomx
|
|||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//go:noescape
|
||||
func superscalar_run(rf, jmp uintptr)
|
||||
|
||||
func (f SuperScalarProgramFunc) Execute(rf uintptr) {
|
||||
if f == nil {
|
||||
panic("program is nil")
|
||||
}
|
||||
|
||||
superscalar_run(rf, uintptr(unsafe.Pointer(unsafe.SliceData(f))))
|
||||
return
|
||||
|
||||
var reservedStackHack [8 * 8]byte
|
||||
for i := range reservedStackHack {
|
||||
reservedStackHack[i] = uint8(i)
|
||||
}
|
||||
|
||||
memoryPtr := &f
|
||||
fun := *(*func(v uintptr))(unsafe.Pointer(&memoryPtr))
|
||||
fun(rf)
|
||||
|
||||
for i := range reservedStackHack {
|
||||
reservedStackHack[i] = uint8(-i)
|
||||
}
|
||||
runtime.KeepAlive(reservedStackHack)
|
||||
}
|
||||
|
||||
// generateSuperscalarCode
|
||||
func generateSuperscalarCode(scalarProgram SuperScalarProgram) ProgramFunc {
|
||||
func generateSuperscalarCode(scalarProgram SuperScalarProgram) SuperScalarProgramFunc {
|
||||
|
||||
var program []byte
|
||||
|
||||
program = append(program, codeInitBlock...)
|
||||
|
||||
p := scalarProgram.Program()
|
||||
for i := range p {
|
||||
instr := &p[i]
|
||||
|
@ -78,7 +104,7 @@ func generateSuperscalarCode(scalarProgram SuperScalarProgram) ProgramFunc {
|
|||
}
|
||||
}
|
||||
|
||||
program = append(program, codeRetBlock...)
|
||||
program = append(program, RET)
|
||||
|
||||
return mapProgram(program)
|
||||
}
|
||||
|
|
39
superscalar_jit_amd64.s
Normal file
39
superscalar_jit_amd64.s
Normal file
|
@ -0,0 +1,39 @@
|
|||
//go:build unix && amd64 && !disable_jit && !purego
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT ·superscalar_run(SB),$0-16
|
||||
|
||||
MOVQ rf+0(FP), SI
|
||||
|
||||
PREFETCHNTA 0(SI)
|
||||
|
||||
// move register line to registers
|
||||
MOVQ 0(SI), R8
|
||||
MOVQ 8(SI), R9
|
||||
MOVQ 16(SI), R10
|
||||
MOVQ 24(SI), R11
|
||||
MOVQ 32(SI), R12
|
||||
MOVQ 40(SI), R13
|
||||
MOVQ 48(SI), R14
|
||||
MOVQ 56(SI), R15
|
||||
|
||||
MOVQ jmp+8(FP), AX
|
||||
// jump to JIT code
|
||||
CALL AX
|
||||
|
||||
|
||||
// todo: not supported by golang
|
||||
// PREFETCHW 0(SI)
|
||||
|
||||
// move registers back to register line
|
||||
MOVQ R8, 0(SI)
|
||||
MOVQ R9, 8(SI)
|
||||
MOVQ R10, 16(SI)
|
||||
MOVQ R11, 24(SI)
|
||||
MOVQ R12, 32(SI)
|
||||
MOVQ R13, 40(SI)
|
||||
MOVQ R14, 48(SI)
|
||||
MOVQ R15, 56(SI)
|
||||
|
||||
RET
|
|
@ -2,7 +2,11 @@
|
|||
|
||||
package randomx
|
||||
|
||||
func (f SuperScalarProgramFunc) Execute(rf uintptr) {
|
||||
|
||||
}
|
||||
|
||||
// generateSuperscalarCode
|
||||
func generateSuperscalarCode(scalarProgram SuperScalarProgram) ProgramFunc {
|
||||
func generateSuperscalarCode(scalarProgram SuperScalarProgram) SuperScalarProgramFunc {
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue