Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Win64 additions/corrections
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Sep 9, 2012
1 parent 8788a2b commit 83d15bb
Show file tree
Hide file tree
Showing 9 changed files with 262 additions and 41 deletions.
1 change: 1 addition & 0 deletions posix.mak
Expand Up @@ -46,6 +46,7 @@ MANIFEST= \
README.txt \
posix.mak \
win32.mak \
win64.mak \
\
src/object_.d \
src/object.di \
Expand Down
9 changes: 7 additions & 2 deletions src/core/sys/windows/dll.d
Expand Up @@ -320,6 +320,10 @@ public:
*/
bool dll_fixTLS( HINSTANCE hInstance, void* tlsstart, void* tlsend, void* tls_callbacks_a, int* tlsindex )
{
version (Win64)
return true; // fixed
else
{
/* If the OS has allocated a TLS slot for us, we don't have to do anything
* tls_index 0 means: the OS has not done anything, or it has allocated slot 0
* Vista and later Windows systems should do this correctly and not need
Expand Down Expand Up @@ -355,6 +359,7 @@ public:
ldrMod.LoadCount = -1; // prevent unloading of the DLL,
// since XP does not keep track of used TLS entries
return true;
}
}

// fixup TLS storage, initialize runtime and attach to threads
Expand All @@ -380,7 +385,7 @@ public:
{
thread_attachByAddr( id );
thread_moduleTlsCtor( id );
}
}
}
return true;
}, null );
Expand Down Expand Up @@ -421,7 +426,7 @@ public:
bool dll_thread_attach( bool attach_thread = true, bool initTls = true )
{
// if the OS has not prepared TLS for us, don't attach to the thread
// (happened when running under x64 OS)
// (happened when running under x64 OS)
if( !GetTlsDataAddress( GetCurrentThreadId() ) )
return false;
if( !thread_findByAddr( GetCurrentThreadId() ) )
Expand Down
7 changes: 6 additions & 1 deletion src/rt/aaA.d
Expand Up @@ -668,7 +668,12 @@ BB* _d_assocarrayliteralT(TypeInfo_AssociativeArray ti, size_t length, ...)
else
{
va_list q;
version(X86_64) va_start(q, __va_argsave); else va_start(q, length);
version (Win64)
va_start(q, length);
else version(X86_64)
va_start(q, __va_argsave);
else
va_start(q, length);

result = new BB();
result.keyti = keyti;
Expand Down
65 changes: 58 additions & 7 deletions src/rt/alloca.d
Expand Up @@ -138,11 +138,19 @@ extern (C) void* __alloca(int nbytes)
}
else version (D_InlineAsm_X86_64)
{
version (Win64)
{
asm
{
/* RCX nbytes
* RDX address of variable with # of bytes in locals
* Must save registers RBX,RDI,RSI,R12..R15
*/
naked ;
mov RDX,RCX ;
mov RAX,RDI ; // get nbytes
push RBX ;
push RDI ;
push RSI ;
mov RAX,RCX ; // get nbytes
add RAX,15 ;
and AL,0xF0 ; // round up to 16 byte boundary
test RAX,RAX ;
Expand All @@ -153,11 +161,7 @@ extern (C) void* __alloca(int nbytes)
neg RAX ;
add RAX,RSP ; // RAX is now what the new RSP will be.
jae Aoverflow ;
}
version (Win64)
{
asm
{

// We need to be careful about the guard page
// Thus, for every 4k page, touch it to cause the OS to load it in.
mov RCX,RAX ; // RCX is new location for stack
Expand All @@ -167,8 +171,54 @@ extern (C) void* __alloca(int nbytes)
sub RBX,0x1000 ; // next 4K page down
jae L1 ; // if more pages
test [RCX],RBX ; // bring in last page

// Copy down to [RSP] the temps on the stack.
// The number of temps is (RBP - RSP - locals).
mov RCX,RBP ;
sub RCX,RSP ;
sub RCX,[RDX] ; // RCX = number of temps (bytes) to move.
add [RDX],RSI ; // adjust locals by nbytes for next call to alloca()
mov RSP,RAX ; // Set up new stack pointer.
add RAX,RCX ; // Return value = RSP + temps.
mov RDI,RSP ; // Destination of copy of temps.
add RSI,RSP ; // Source of copy.
shr RCX,3 ; // RCX to count of qwords in temps
rep ;
movsq ;
jmp done ;

Aoverflow:
// Overflowed the stack. Return null
xor RAX,RAX ;

done:
pop RSI ;
pop RDI ;
pop RBX ;
ret ;
}
}
else
{
asm
{
/* Parameter is passed in RDI
* Must save registers RBX,R12..R15
*/
naked ;
mov RDX,RCX ;
mov RAX,RDI ; // get nbytes
add RAX,15 ;
and AL,0xF0 ; // round up to 16 byte boundary
test RAX,RAX ;
jnz Abegin ;
mov RAX,16 ; // allow zero bytes allocation
Abegin:
mov RSI,RAX ; // RSI = nbytes
neg RAX ;
add RAX,RSP ; // RAX is now what the new RSP will be.
jae Aoverflow ;
}
version (Unix)
{
asm
Expand Down Expand Up @@ -201,6 +251,7 @@ extern (C) void* __alloca(int nbytes)
done:
ret ;
}
}

This comment has been minimized.

Copy link
@alexrp

alexrp Sep 9, 2012

Member

Is some indentation off here?

This comment has been minimized.

Copy link
@jmdavis

jmdavis Sep 9, 2012

Member

It looks like there's no indenting for the version blocks for some reason.

}
else
static assert(0);
Expand Down
12 changes: 6 additions & 6 deletions src/rt/dmain2.d
Expand Up @@ -126,23 +126,23 @@ extern (C) void* rt_loadLibrary(in char[] name)
// Load a DLL at runtime
enum CP_UTF8 = 65001;
auto len = MultiByteToWideChar(
CP_UTF8, 0, name.ptr, name.length, null, 0);
CP_UTF8, 0, name.ptr, cast(int)name.length, null, 0);
if (len == 0)
return null;

auto buf = cast(wchar_t*)malloc((len+1) * wchar_t.sizeof);
if (buf is null)
return null;
scope (exit)
free(buf);

len = MultiByteToWideChar(
CP_UTF8, 0, name.ptr, name.length, buf, len);
CP_UTF8, 0, name.ptr, cast(int)name.length, buf, len);
if (len == 0)
return null;

buf[len] = '\0';

// BUG: LoadLibraryW() call calls rt_init(), which fails if proxy is not set!
auto mod = LoadLibraryW(buf);
if (mod is null)
Expand Down
66 changes: 58 additions & 8 deletions src/rt/lifetime.d
Expand Up @@ -2,16 +2,14 @@
* This module contains all functions related to an object's lifetime:
* allocation, resizing, deallocation, and finalization.
*
* Copyright: Copyright Digital Mars 2000 - 2010.
* License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
* Copyright: Copyright Digital Mars 2000 - 2012.
* License: Distributed under the
* $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
* (See accompanying file LICENSE)
* Authors: Walter Bright, Sean Kelly, Steven Schveighoffer
* Source: $(DRUNTIMESRC src/rt/_lifetime.d)
*/

/* Copyright Digital Mars 2000 - 2010.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
module rt.lifetime;

private
Expand Down Expand Up @@ -930,9 +928,17 @@ void[] _d_newarrayOpT(alias op)(const TypeInfo ti, size_t ndims, va_list q)
va_list ap2;
va_copy(ap2, ap);
}
else version(Win64)
{
va_list ap2;
va_copy(ap2, ap);
}
for (size_t i = 0; i < dim; i++)
{
version(X86_64)
version (Win64)
{
}
else version(X86_64)
{
__va_list argsave = *cast(__va_list*)ap;
va_list ap2 = &argsave;
Expand Down Expand Up @@ -977,6 +983,8 @@ extern (C) void[] _d_newarraymT(const TypeInfo ti, size_t ndims, ...)
va_list q;
version(X86)
va_start(q, ndims);
else version(Win64)
va_start(q, ndims);
else version(X86_64)
va_start(q, __va_argsave);
else
Expand All @@ -1000,6 +1008,8 @@ extern (C) void[] _d_newarraymiT(const TypeInfo ti, size_t ndims, ...)
va_list q;
version(X86)
va_start(q, ndims);
else version(Win64)
va_start(q, ndims);
else version(X86_64)
va_start(q, __va_argsave);
else
Expand Down Expand Up @@ -1762,6 +1772,11 @@ extern (C) void[] _d_arrayappendcT(const TypeInfo ti, ref byte[] x, ...)
byte *argp = cast(byte*)(&ti + 2);
return _d_arrayappendT(ti, x, argp[0..1]);
}
else version(Win64)
{
byte *argp = cast(byte*)(&ti + 2);
return _d_arrayappendT(ti, x, argp[0..1]);
}
else version(X86_64)
{
// This code copies the element twice, which is annoying
Expand Down Expand Up @@ -2052,6 +2067,16 @@ extern (C) void[] _d_arraycatnT(const TypeInfo ti, uint n, ...)
length += b.length;
}
}
else version(Win64)
{
byte[]* p = cast(byte[]*)(&n + 1);

for (auto i = 0; i < n; i++)
{
byte[] b = *p++;
length += b.length;
}
}
else
{
__va_list argsave = __va_argsave.va;
Expand Down Expand Up @@ -2089,6 +2114,21 @@ extern (C) void[] _d_arraycatnT(const TypeInfo ti, uint n, ...)
}
}
}
else version (Win64)
{
p = cast(byte[]*)(&n + 1);

size_t j = 0;
for (auto i = 0; i < n; i++)
{
byte[] b = *p++;
if (b.length)
{
memcpy(a + j, b.ptr, b.length * size);
j += b.length * size;
}
}
}
else
{
va_list ap2 = &argsave;
Expand Down Expand Up @@ -2177,6 +2217,16 @@ extern (C) void* _d_arrayliteralT(const TypeInfo ti, size_t length, ...)

va_end(q);
}
else version (Win64)
{
va_list q;
va_start(q, length);
for (size_t i = 0; i < length; i++)
{
va_arg(q, cast()ti.next, result + i * sizeelem);
}
va_end(q);
}
else
{
va_list q;
Expand Down

0 comments on commit 83d15bb

Please sign in to comment.