Applied easy part from wilsonk's x86-64 patch in #107

This commit is contained in:
Christian Kamm
2008-10-30 11:08:34 +01:00
parent e625829f0f
commit 891d17e4b5
20 changed files with 253 additions and 75 deletions

View File

@@ -851,6 +851,9 @@ int main(int argc, char *argv[], char** envp)
global.params.isLE = true;
global.params.is64bit = true;
global.params.cpu = ARCHx86_64;
if (global.params.useInlineAsm) {
VersionCondition::addPredefinedGlobalIdent("LLVM_InlineAsm_X86_64");
}
}
else if (strcmp(global.params.llvmArch,"ppc32")==0) {
VersionCondition::addPredefinedGlobalIdent("PPC");

View File

@@ -1379,10 +1379,14 @@ void OutBuffer::mark()
void OutBuffer::reserve(unsigned nbytes)
{
//printf("OutBuffer::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes);
//printf("OutBuffer::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes);
if (size - offset < nbytes)
{
#if defined (__x86_64__)
size = (offset + nbytes) * 2+2;
#else
size = (offset + nbytes) * 2;
#endif
data = (unsigned char *)mem.realloc(data, size);
}
}

View File

@@ -30,7 +30,7 @@ const LLType* DtoComplexBaseType(Type* t)
return LLType::DoubleTy;
}
else if (ty == Tcomplex80) {
if (global.params.cpu == ARCHx86)
if ((global.params.cpu == ARCHx86) || (global.params.cpu == ARCHx86_64))
return LLType::X86_FP80Ty;
else
return LLType::DoubleTy;

View File

@@ -147,7 +147,7 @@ static void LLVM_D_BuildRuntimeModule()
const LLType* floatTy = LLType::FloatTy;
const LLType* doubleTy = LLType::DoubleTy;
const LLType* realTy;
if (global.params.cpu == ARCHx86)
if ((global.params.cpu == ARCHx86) || (global.params.cpu == ARCHx86_64))
realTy = LLType::X86_FP80Ty;
else
realTy = LLType::DoubleTy;

View File

@@ -88,7 +88,7 @@ const LLType* DtoType(Type* t)
return LLType::DoubleTy;
case Tfloat80:
case Timaginary80:
if (global.params.cpu == ARCHx86)
if (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64)
return LLType::X86_FP80Ty;
else
return LLType::DoubleTy;

View File

@@ -112,6 +112,12 @@ pragma(intrinsic, "llvm.sqrt.f80")
real llvm_sqrt_f80(real val);
}
version(X86_64)
{
pragma(intrinsic, "llvm.sqrt.f80")
real llvm_sqrt_f80(real val);
}
// The 'llvm.sin.*' intrinsics return the sine of the operand.
@@ -125,6 +131,12 @@ pragma(intrinsic, "llvm.sin.f80")
real llvm_sin_f80(real val);
}
version(X86_64)
{
pragma(intrinsic, "llvm.sin.f80")
real llvm_sin_f80(real val);
}
// The 'llvm.cos.*' intrinsics return the cosine of the operand.
@@ -138,6 +150,12 @@ pragma(intrinsic, "llvm.cos.f80")
real llvm_cos_f80(real val);
}
version(X86_64)
{
pragma(intrinsic, "llvm.cos.f80")
real llvm_cos_f80(real val);
}
// The 'llvm.powi.*' intrinsics return the first operand raised to the specified (positive or negative) power. The order of evaluation of multiplications is not defined. When a vector of floating point type is used, the second argument remains a scalar integer value.
@@ -152,6 +170,11 @@ pragma(intrinsic, "llvm.powi.f80")
real llvm_powi_f80(real val, int power);
}
version(X86_64)
{
pragma(intrinsic, "llvm.powi.f80")
real llvm_powi_f80(real val, int power);
}
// The 'llvm.pow.*' intrinsics return the first operand raised to the specified (positive or negative) power.
@@ -166,7 +189,11 @@ pragma(intrinsic, "llvm.pow.f80")
real llvm_pow_f80(real val, real power);
}
version(X86_64)
{
pragma(intrinsic, "llvm.pow.f80")
real llvm_pow_f80(real val, real power);
}
//

View File

@@ -15,6 +15,9 @@ version(X86) {
version(linux) version=X86_UNWIND;
version(darwin) version=X86_UNWIND;
}
version(X86_64) {
version(linux) version=X86_UNWIND;
}
private extern(C) void abort();
private extern(C) int printf(char*, ...);
@@ -168,7 +171,7 @@ char[8] _d_exception_class = "LLDCD1\0\0";
// x86 unwind specific implementation of personality function
// and helpers
//
version(X86_UNWIND)
version(X86_UNWIND)
{
// the personality routine gets called by the unwind handler and is responsible for
@@ -296,9 +299,15 @@ extern(C) _Unwind_Reason_Code _d_eh_personality(int ver, _Unwind_Action actions,
// These are the register numbers for SetGR that
// llvm's eh.exception and eh.selector intrinsics
// will pick up.
// Found by trial-and-error and probably platform dependent!
private int eh_exception_regno = 0;
private int eh_selector_regno = 2;
// Found by trial-and-error :/
version (X86_64)
{
private int eh_exception_regno = 3;
private int eh_selector_regno = 1;
} else {
private int eh_exception_regno = 0;
private int eh_selector_regno = 2;
}
private _Unwind_Reason_Code _d_eh_install_catch_context(_Unwind_Action actions, ptrdiff_t switchval, ulong landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context)
{

View File

@@ -14,13 +14,13 @@ void main()
}
printf("x = %d\n", x);
}
else version(D_InlineAsm_X86_64)
else version(LLVM_InlineAsm_X86_64)
{
long x;
asm
{
mov RAX, 42L;
mov x, RAX;
movq RAX, 42L;
movq x, RAX;
}
printf("x = %ld\n", x);
}

View File

@@ -7,13 +7,27 @@ int main()
int i = 12;
int* ip = &i;
printf("%d\n", i);
asm
version (LLVM_InlineAsm_X86)
{
mov EBX, ip;
mov EAX, [EBX];
add EAX, 8;
mul EAX, EAX;
mov [EBX], EAX;
asm
{
mov EBX, ip;
mov EAX, [EBX];
add EAX, 8;
mul EAX, EAX;
mov [EBX], EAX;
}
}
else version (LLVM_InlineAsm_X86_64)
{
asm
{
movq RCX, ip;
movq RAX, [RCX];
add RAX, 8;
imul RAX, RAX;
movq [RCX], RAX;
}
}
printf("%d\n", i);
assert(i == 400);

View File

@@ -6,12 +6,25 @@ int main()
{
int i = 40;
int j = 2;
asm
version(LLVM_InlineAsm_X86)
{
mov EAX, i;
mov EBX, j;
add EAX, EBX;
mov i, EAX;
asm
{
mov EAX, i;
mov EBX, j;
add EAX, EBX;
mov i, EAX;
}
}
else version(LLVM_InlineAsm_X86_64)
{
asm
{
mov EAX, i;
mov EBX, j;
add EAX, EBX;
mov i, EAX;
}
}
printf("42 = %d\n", i);
assert(i == 42);

View File

@@ -6,10 +6,23 @@ void main()
{
char* fmt = "Hello D World\n";
printf(fmt);
asm
version (LLVM_InlineAsm_X86)
{
push fmt;
call printf;
pop EAX;
asm
{
push fmt;
call printf;
pop AX;
}
}
else version(LLVM_InlineAsm_X86_64)
{
asm
{
movq RDI, fmt;
xor AL, AL;
call printf;
}
}
}

View File

@@ -4,17 +4,38 @@ extern(C) int printf(char*,...);
void main()
{
char* fmt = "yay!\n";
asm
char* stmt = "yay!\n";
char* fmt = "%s";
version (LLVM_InlineAsm_X86)
{
jmp L2;
L1:;
jmp L3;
L2:;
jmp L1;
L3:;
push fmt;
call printf;
pop EAX;
asm
{
jmp L2;
L1:;
jmp L3;
L2:;
jmp L1;
L3:;
push fmt;
call printf;
pop AX;
}
}
else version(LLVM_InlineAsm_X86_64)
{
asm
{
jmp L2;
L1:;
jmp L3;
L2:;
jmp L1;
L3:;
movq RDI, fmt;
movq RSI, stmt;
xor AL, AL;
call printf;
}
}
printf(fmt,stmt);
}

View File

@@ -11,10 +11,20 @@ void main()
int func()
{
asm
version (LLVM_InlineAsm_X86)
{
naked;
mov EAX, 42;
ret;
asm
{
naked;
mov EAX, 42;
ret;
}
}
else version(LLVM_InlineAsm_X86_64)
{
asm
{
movq RAX, 42;
}
}
}

View File

@@ -4,20 +4,36 @@ void main()
{
int a,b,c;
a = int.max-1;
b = 1;
asm
b = 5;
version (LLVM_InlineAsm_X86)
{
mov EAX, a;
mov ECX, b;
add EAX, ECX;
jo Loverflow;
mov c, EAX;
asm
{
mov EAX, a;
mov ECX, b;
add EAX, ECX;
jo Loverflow;
mov c, EAX;
}
}
else version (LLVM_InlineAsm_X86_64)
{
asm
{
movq RDX, a;
movq RAX, b;
add RDX, RAX;
jo Loverflow;
movq c, RDX;
}
}
printf("a == %d\n", a);
printf("b == %d\n", b);
printf("c == %d\n", c);
assert(c == a+b);
assert(c == c);
return;
Loverflow:
assert(0, "overflow");
int y=0;
//assert(0, "overflow");
}

View File

@@ -1,6 +1,7 @@
module tangotests.asm7;
// test massive label collisions (runtime uses Loverflow too)
extern(C) int printf(char*, ...);
void main()
{
@@ -13,13 +14,27 @@ void main()
int add(int a, int b)
{
int res;
asm
version (LLVM_InlineAsm_X86)
{
mov EAX, a;
add EAX, b;
jo Loverflow;
mov res, EAX;
asm
{
mov EAX, a;
add EAX, b;
jo Loverflow;
mov res, EAX;
}
}
else version (LLVM_InlineAsm_X86_64)
{
asm
{
mov EAX, a;
add EAX, b;
jo Loverflow;
mov res, EAX;
}
}
printf("%d\n",res);
return res;
Loverflow:
assert(0, "add overflow");
@@ -28,14 +43,29 @@ Loverflow:
int sub(int a, int b)
{
int res;
asm
version (LLVM_InlineAsm_X86)
{
mov EAX, a;
sub EAX, b;
jo Loverflow;
mov res, EAX;
asm
{
mov EAX, a;
sub EAX, b;
jo Loverflow;
mov res, EAX;
}
}
else version (LLVM_InlineAsm_X86_64)
{
asm
{
mov EAX, a;
sub EAX, b;
jo Loverflow;
mov res, EAX;
}
}
printf("%d\n",res);
return res;
Loverflow:
assert(0, "sub overflow");
int x;
}

View File

@@ -13,19 +13,31 @@ void main()
float b = 2.5;
float c;
asm
version(LLVM_InlineAsm_X86)
{
mov EAX, [a];
push EAX;
mov EAX, [b];
push EAX;
call foo;
fstp c;
asm
{
mov EAX, [a];
push EAX;
mov EAX, [b];
push EAX;
call foo;
fstp c;
}
}
else version(LLVM_InlineAsm_X86_64)
{
asm
{
movss XMM0, [a];
movss XMM1, [b];
call foo;
movss [c], XMM0;
}
}
printf("%f\n", c);
assert(c == 4.0);
printf("passed\n", c);
printf("passed %f\n", c);
}

View File

@@ -1,5 +1,4 @@
private import
tango.core.Thread;
private import tango.core.Thread;
extern(C) void printf(char*, ...);

View File

@@ -28,6 +28,11 @@ void main()
real sr = llvm_sqrt_f80(r);
printf("sqrt(%llf) = %llf\n", r, sr);
}
else version (X86_64)
{
real sr = llvm_sqrt_f80(r);
printf("sqrt(%llf) = %llf\n", r, sr);
}
else
{
real sr = llvm_sqrt_f64(r);

View File

@@ -5,7 +5,7 @@ void func(...)
assert(_arguments.length == 2);
assert(_arguments[0] is typeid(int));
int a = *cast(int*)_argptr;
_argptr += int.sizeof;
_argptr += size_t.sizeof;
assert(_arguments[1] is typeid(int));
a += *cast(int*)_argptr;
_argptr += int.sizeof;

View File

@@ -1,3 +1,5 @@
module constructors;
import tango.io.Console;
class C