global Reader
global Mixer

; Note:
; Unix ABI says integer param are put in these registers in this order:
;       rdi, rsi, rdx, rcx, r8, r9

section .text
;-----------------------------
;     AL/AH, CL/CH, DL/DH, BL/BH, SPL, BPL, SIL, DIL, R8B-R15B
;     AX, CX, DX, BX, SP, BP, SI, DI, R8W-R15W
;     EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, R8D-R15D
;     RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8-R15
;
;
;-----------------------------
;
;			[rdi] == data
;        data[0] = size
;        data[1] = loops
;        data[2..9] = 8 different offsets
;        data[10..26] = 8 high/high pairs  that's start/end
;		 data[27..43] = 8 low/low pairs    that's start/end
;		Registers %rbp, %rbx and
;		%r12 through %r15 "belong" to the calling function and the called function is
;		required to preserve their values. In other words, a called function must preserve
;		these registers' values for its caller. Remaining registers "belong" to the called
;		function.5 If a calling function wants to preserve such a register value across a
;		function call, it must save the value in its local stack frame.
;
;Mixer(data, 256*4, UINT32_MAX/2/256);
;
;
Mixer:
    push    r10

    add rsi, rdi    ; rsi now points to end.

.L1:
    mov r10, rdi

.L2:
    mov ax, word[ dword r10]
	add r10, 1
	cmp r10, rsi
	jb  .L2

	dec rdx
	jnz .L1

	pop r10
	ret

Reader:
	push r8
	push r9
	;push r10
	;push r11
	;push r12
	;push r13
	;push r14

	;mov r10, rdi     ; reset to first address

    cpuid
    rdtsc
	mov r8, rax
	mov r9, rdx
	mov rax, [dword rdi+96] ; read
;	mov rax, [dword rdi+196] ; read
;mov rax, [dword rdi+916] ; read
;mov rax, [dword rdi+964] ; read
;mov rax, [dword rdi+264] ; read
cpuid
	rdtsc
	mov [rdi+40], r8 ; high
	mov [rdi+104], r9 ; low
	mov r8, rax
	mov r9, rdx
	mov [rdi+44], r8 ; high
	mov [rdi+108], r9 ; low

	cpuid
	rdtsc
	mov r8, rax
	mov r9, rdx
	mov rax, [dword rdi+8] ; read
	rdtsc
	mov [rdi+48], r8 ; high
	mov [rdi+112], r9 ; low
	mov r8, rax
	mov r9, rdx
	mov [rdi+52], r8
	mov [rdi+116], r9

	cpuid
	rdtsc
	mov r8, rax
	mov r9, rdx
	mov ax, word[dword rdi+768] ; read
	rdtsc
	mov [rdi+56], r8 ; high
	mov [rdi+120], r9 ; low
	mov r8, rax
	mov r9, rdx
	mov [rdi+60], r8
	mov [rdi+124], r9

	cpuid
	rdtsc
	mov r8, rax
	mov r9, rdx
	mov ax, word[dword rdi+512] ; read
	rdtsc
	mov [rdi+64], r8 ; high
	mov [rdi+128], r9 ; low
	mov r8, rax
	mov r9, rdx
	mov [rdi+68], r8
	mov [rdi+132], r9


;    mov r10, [dword rdi+6]
;    mov r11, [dword rdi+7]
;    mov r12, [dword rdi+8]
;    mov r13, [dword rdi+9]

	cpuid
	rdtsc
	mov r8, rax
	mov r9, rdx
	mov ax, word[dword rdi+384] ; read
	rdtsc
	mov [rdi+72], r8 ; high
	mov [rdi+136], r9 ; low
	mov r8, rax
	mov r9, rdx
	mov [rdi+76], r8
	mov [rdi+140], r9

	cpuid
	rdtsc
	mov r8, rax
	mov r9, rdx
	mov ax, word[dword rdi+1016] ; read
	rdtsc
	mov [rdi+80], r8 ; high
	mov [rdi+144], r9 ; low
	mov r8, rax
	mov r9, rdx
	mov [rdi+84], r8
	mov [rdi+148], r9

	cpuid
	rdtsc
	mov r8, rax
	mov r9, rdx
	mov ax, word[dword rdi+128] ; read
	rdtsc
	mov [rdi+88], r8 ; high
	mov [rdi+152], r9 ; low
	mov r8, rax
	mov r9, rdx
	mov [rdi+92], r8
	mov [rdi+156], r9

	cpuid
	rdtsc
	mov r8, rax
	mov r9, rdx
	mov ax, word[dword rdi+435] ; read
	rdtsc
	mov [rdi+96], r8 ; high
	mov [rdi+160], r9 ; low
	mov r8, rax
	mov r9, rdx
	mov [rdi+100], r8
	mov [rdi+164], r9


	;mov [rdi], r9
	;mov [rdi+4], r10
	;mov [rdi+8], word 8
	;mov [rdi+12], word 7
	;mov [rdi+16], word 6
	;mov [rdi+20], word 5
	;mov [rdi+24], word 4
	;mov [rdi+28], word 3

	pop r8
	pop r9
	;pop r10
	;pop r11
	;pop r12
	;pop r13
	ret
