diff --git a/dmd/mars.c b/dmd/mars.c index 86966189..60fc0c79 100644 --- a/dmd/mars.c +++ b/dmd/mars.c @@ -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"); diff --git a/dmd/root.c b/dmd/root.c index 185be9e8..352c75f2 100644 --- a/dmd/root.c +++ b/dmd/root.c @@ -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); } } diff --git a/gen/complex.cpp b/gen/complex.cpp index 3c4c9f5d..ea41d289 100644 --- a/gen/complex.cpp +++ b/gen/complex.cpp @@ -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; diff --git a/gen/runtime.cpp b/gen/runtime.cpp index 1dec712c..058e4a21 100644 --- a/gen/runtime.cpp +++ b/gen/runtime.cpp @@ -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; diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 446b79cf..f64eabe8 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -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; diff --git a/runtime/import/ldc/intrinsics.di b/runtime/import/ldc/intrinsics.di index 1414cb2f..fbdbc4f6 100644 --- a/runtime/import/ldc/intrinsics.di +++ b/runtime/import/ldc/intrinsics.di @@ -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); +} // diff --git a/runtime/internal/eh.d b/runtime/internal/eh.d index 83dc580e..18c3529c 100644 --- a/runtime/internal/eh.d +++ b/runtime/internal/eh.d @@ -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) { diff --git a/tests/mini/asm1.d b/tests/mini/asm1.d index c5d59920..412f0247 100644 --- a/tests/mini/asm1.d +++ b/tests/mini/asm1.d @@ -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); } diff --git a/tests/mini/asm1_1.d b/tests/mini/asm1_1.d index e4ff101c..8b6938dc 100644 --- a/tests/mini/asm1_1.d +++ b/tests/mini/asm1_1.d @@ -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); diff --git a/tests/mini/asm2.d b/tests/mini/asm2.d index fc135010..b854a03a 100644 --- a/tests/mini/asm2.d +++ b/tests/mini/asm2.d @@ -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); diff --git a/tests/mini/asm3.d b/tests/mini/asm3.d index 61ee17f5..7650e0d0 100644 --- a/tests/mini/asm3.d +++ b/tests/mini/asm3.d @@ -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; + } + } + } diff --git a/tests/mini/asm4.d b/tests/mini/asm4.d index 0649bebd..8fd122d1 100644 --- a/tests/mini/asm4.d +++ b/tests/mini/asm4.d @@ -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); } diff --git a/tests/mini/asm5.d b/tests/mini/asm5.d index 8501f843..4a6d6913 100644 --- a/tests/mini/asm5.d +++ b/tests/mini/asm5.d @@ -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; + } } } diff --git a/tests/mini/asm6.d b/tests/mini/asm6.d index e197e16d..692ee46e 100644 --- a/tests/mini/asm6.d +++ b/tests/mini/asm6.d @@ -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"); } diff --git a/tests/mini/asm7.d b/tests/mini/asm7.d index 9ea56339..f9fa9437 100644 --- a/tests/mini/asm7.d +++ b/tests/mini/asm7.d @@ -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; } diff --git a/tests/mini/callingconv1.d b/tests/mini/callingconv1.d index 48d1a99d..102c313b 100644 --- a/tests/mini/callingconv1.d +++ b/tests/mini/callingconv1.d @@ -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); } diff --git a/tests/mini/fiber.d b/tests/mini/fiber.d index 11b6bdb6..bc9d7dc8 100644 --- a/tests/mini/fiber.d +++ b/tests/mini/fiber.d @@ -1,5 +1,4 @@ -private import - tango.core.Thread; +private import tango.core.Thread; extern(C) void printf(char*, ...); diff --git a/tests/mini/intrinsics.d b/tests/mini/intrinsics.d index 5d05013f..8a3f3ab4 100644 --- a/tests/mini/intrinsics.d +++ b/tests/mini/intrinsics.d @@ -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); diff --git a/tests/mini/vararg2.d b/tests/mini/vararg2.d index b8e5be16..2878a49b 100644 --- a/tests/mini/vararg2.d +++ b/tests/mini/vararg2.d @@ -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; diff --git a/tests/minicomplex/constructors.d b/tests/minicomplex/constructors.d index fa7b05dc..4a55d6c7 100644 --- a/tests/minicomplex/constructors.d +++ b/tests/minicomplex/constructors.d @@ -1,3 +1,5 @@ +module constructors; + import tango.io.Console; class C