mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
Applied easy part from wilsonk's x86-64 patch in #107
This commit is contained in:
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
private import
|
||||
tango.core.Thread;
|
||||
private import tango.core.Thread;
|
||||
|
||||
extern(C) void printf(char*, ...);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
module constructors;
|
||||
|
||||
import tango.io.Console;
|
||||
|
||||
class C
|
||||
|
||||
Reference in New Issue
Block a user