Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement ctfe yl2x and yl2xp1 #4012

Merged
merged 3 commits into from
Sep 25, 2014
Merged

Conversation

IgorStepanov
Copy link
Contributor

This PR intriduces builtin compile-time yl2x and yl2xp1 for some platforms.
Supported platforms: DMC, VS (x86, x86_64), MinGW (x86 and x86_64), GCC (x86, x86_64), SunC(x86, x86_64).
If platform doesn't support this builtin, "cannot evaluate unimplemented builtin..." error will be raised as it was early.

@IgorStepanov
Copy link
Contributor Author

@ibuclaw Please, check my *nix inline assebler code. Is it ok?

@rainers
Copy link
Member

rainers commented Sep 21, 2014

VS (x86_64) doesn't support inline assembler, so I can't implement yl2x for it.

You can implement x64 asm for VC in vcbuild/ldfpu.asm.

@IgorStepanov
Copy link
Contributor Author

Ok

Expression *eval_yl2x(Loc loc, FuncDeclaration *fd, Expressions *arguments)
{
Expression *arg0 = (*arguments)[0];
assert(arg0->op == TOKfloat64);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why float64 instead of float80?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know. I did it similar examples like eval_sqrt

Expression *eval_sqrt(Loc loc, FuncDeclaration *fd, Expressions *arguments)
{
    Expression *arg0 = (*arguments)[0];
    assert(arg0->op == TOKfloat64);
    return new RealExp(loc, Port::sqrt(arg0->toReal()), arg0->type);
}

Maybe CTFE stores all floating numbers with op == TOKfloat64

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, you're right, the others do it too.

@ibuclaw
Copy link
Member

ibuclaw commented Sep 22, 2014

GDC can't use this, but this is not touching any shared code anyway.

import core.math : yl2x;
static x = yl2x(0, 0);
import std.math : rndtol;
static x = rndtol(1.2);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, rndtol may be CTFE-able in GDC - I'll have to check this in detail.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

> cat test.d 
import std.math : rndtol;
static x = rndtol(1.2);
pragma(msg, rndtol(1.2));

> gdc test.d -S
1L

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I should remove this test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed it.

@IgorStepanov
Copy link
Contributor Author

@ibuclaw Please comment the next code:

void Port::yl2x_impl(longdouble* x, longdouble* y, longdouble* res)
{
    __asm__ ("fyl2x": "=t" (*res): "u" (*y), "0" (*x) : "st(1)" );
}

Is it ok? It works, but I'm scared by unused assembler syntax. Do I need to add additional instructions like fwait or finit?

@IgorStepanov
Copy link
Contributor Author

Added solaris support: tested with Sun C 5.12 Linux_i386 in x86 and x86_64 mode.

@WalterBright
Copy link
Member

@IgorStepanov you don't need fwait with modern CPUs, and finit is only needed at program startup.

@WalterBright
Copy link
Member

Auto-merge toggled on

WalterBright added a commit that referenced this pull request Sep 25, 2014
@WalterBright WalterBright merged commit f2fcc13 into dlang:master Sep 25, 2014
@IgorStepanov
Copy link
Contributor Author

Thanks!

@IgorStepanov you don't need fwait with modern CPUs

It was needed only when x87 was implemented as separate chip?

and finit is only needed at program startup.

I thinked, finit should be called after using xmm indtructions.
Is it wrong?

@CyberShadow
Copy link
Member

This broke building DMD x64 with MSVC 2010.

root\port.c(296): error C2065: 'long_double' : undeclared identifier [C:\Projects\Extern\D\dmd\src\dmd_msc.vcxproj]

@CyberShadow
Copy link
Member

If I change long_double to longdouble I get a linking error.

Supported platforms: DMC, VS (x86, x86_64),

Does it work for you?

@CyberShadow
Copy link
Member

Fixed it, the functions were not declared as extern "C".

@CyberShadow
Copy link
Member

#4041

mov eax, y
mov ebx, x
mov ecx, res
finit
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I create PR, which fix it? I'll do it after 3-5 hours.

@MartinNowak
Copy link
Member

@IgorStepanov
Copy link
Contributor Author

Created #4052 Is it ok?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants