1
0
forked from 0ad/0ad

AMD64 assembly modifications for linux

This was SVN commit r6142.
This commit is contained in:
Simon Brenner 2008-06-28 18:44:06 +00:00
parent 2118c3ccfe
commit f2129f70a5
5 changed files with 78 additions and 21 deletions

View File

@ -1,11 +1,20 @@
#include "precompiled.h"
#if ARCH_AMD64
#include "amd64.h"
#include "amd64_asm.h"
#include "lib/sysdep/cpu.h"
#if MSC_VERSION
#include <intrin.h>
#endif
void cpu_ConfigureFloatingPoint()
{
// 64-bit CPU:s apparently use SSE2 for all floating-point operations, so I
// *guess* we don't need to do anything...
}
void* cpu_memcpy(void* RESTRICT dst, const void* RESTRICT src, size_t size)
{
@ -25,4 +34,18 @@ void cpu_AtomicAdd(volatile intptr_t* location, intptr_t increment)
(void)_InterlockedExchangeAdd64(location, increment);
}
#elif GCC_VERSION
void cpu_AtomicAdd(volatile intptr_t* location, intptr_t increment)
{
amd64_AtomicAdd(location, increment);
}
bool cpu_CAS(volatile uintptr_t* location, uintptr_t expected, uintptr_t newValue)
{
return amd64_CAS(location, expected, newValue) ? true : false;
}
#endif
#endif // ARCH_AMD64

View File

@ -0,0 +1,12 @@
%ifdef OS_LINUX
%define arg0 rdi
%define arg1 rsi
%define arg2 rdx
%define arg3 rcx
%else
%define arg0 rcx
%define arg1 rdx
%define arg2 r8
%define arg3 r9
%endif

View File

@ -6,31 +6,44 @@
; license: GPL; see lib/license.txt
; For the sym() macro
%include "../ia32/ia32.inc"
; For arg0..3
%include "amd64_abi.inc"
BITS 64
; extern "C" void __cdecl amd64_asm_cpuid(Ia32CpuidRegs* reg);
; reference: http://softwarecommunity.intel.com/articles/eng/2669.htm
PUBLIC amd64_asm_cpuid
.CODE
ALIGN 8
amd64_asm_cpuid PROC FRAME
sub rsp, 32
.allocstack 32
push rbx
.pushreg rbx
.endprolog
global sym(amd64_asm_cpuid)
sym(amd64_asm_cpuid):
push rbx ; rbx is the only caller-save register we clobber
mov r8, rcx
mov eax, DWORD PTR [r8+0]
mov ecx, DWORD PTR [r8+8]
mov r8, arg0
mov eax, DWORD [r8+0]
mov ecx, DWORD [r8+8]
cpuid
mov DWORD PTR [r8+0], eax
mov DWORD PTR [r8+4], ebx
mov DWORD PTR [r8+8], ecx
mov DWORD PTR [r8+12], edx
mov DWORD [r8+0], eax
mov DWORD [r8+4], ebx
mov DWORD [r8+8], ecx
mov DWORD [r8+12], edx
pop rbx
add rsp, 32
ret
ALIGN 8
cpuid64 ENDP
_TEXT ENDS
; extern "C" intptr_t amd64_CAS(volatile uintptr_t *location, uintptr_t expected, uintptr_t newValue);
global sym(amd64_CAS)
sym(amd64_CAS):
mov rax, arg1 ; expected -> rax
lock cmpxchg [arg0], arg2
sete al
movzx rax, al
ret
; extern "C" void amd64_AtomicAdd(intptr_t *location, intptr_t increment);
global sym(amd64_AtomicAdd)
sym(amd64_AtomicAdd):
lock add [arg0], arg1
ret

View File

@ -15,8 +15,12 @@
extern "C" {
#endif
struct Ia32CpuidRegs;
extern void CALL_CONV amd64_asm_cpuid(Ia32CpuidRegs* reg);
struct x86_x64_CpuidRegs;
extern void CALL_CONV amd64_asm_cpuid(x86_x64_CpuidRegs* reg);
extern intptr_t CALL_CONV amd64_CAS(volatile uintptr_t *location, uintptr_t expected, uintptr_t newValue);
extern void CALL_CONV amd64_AtomicAdd(volatile intptr_t *location, intptr_t increment);
#ifdef __cplusplus
}

View File

@ -9,6 +9,9 @@
// license: GPL; see lib/license.txt
#include "precompiled.h"
#if ARCH_IA32
#include "ia32.h"
#include "lib/sysdep/cpu.h"
@ -111,3 +114,5 @@ void* cpu_memcpy(void* RESTRICT dst, const void* RESTRICT src, size_t size)
{
return ia32_memcpy(dst, src, size);
}
#endif // ARCH_IA32