Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 29 additions & 8 deletions src/core/bitop.d
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ else version (X86)
* The bit number of the first bit set.
* The return value is undefined if v is zero.
*/
pragma(DigitalMars_intrinsic, "bsf")
int bsf(size_t v) pure;

///
Expand All @@ -46,6 +47,7 @@ unittest
* The bit number of the first bit set.
* The return value is undefined if v is zero.
*/
pragma(DigitalMars_intrinsic, "bsr")
int bsr(size_t v) pure;

///
Expand Down Expand Up @@ -84,12 +86,14 @@ int bt(in size_t* p, size_t bitnum) pure @system
/**
* Tests and complements the bit.
*/
pragma(DigitalMars_intrinsic, "btc")
int btc(size_t* p, size_t bitnum) pure @system;


/**
* Tests and resets (sets to 0) the bit.
*/
pragma(DigitalMars_intrinsic, "btr")
int btr(size_t* p, size_t bitnum) pure @system;


Expand All @@ -106,6 +110,7 @@ p[index / (size_t.sizeof*8)] & (1 << (index & ((size_t.sizeof*8) - 1)))
* A non-zero value if the bit was set, and a zero
* if it was clear.
*/
pragma(DigitalMars_intrinsic, "bts")
int bts(size_t* p, size_t bitnum) pure @system;

///
Expand Down Expand Up @@ -154,43 +159,50 @@ int bts(size_t* p, size_t bitnum) pure @system;
* byte 3, byte 1 becomes byte 2, byte 2 becomes byte 1, byte 3
* becomes byte 0.
*/
pragma(DigitalMars_intrinsic, "bswap")
uint bswap(uint v) pure;

version (DigitalMars) version (AnyX86) @system // not pure
{
/**
* Reads I/O port at port_address.
*/
pragma(DigitalMars_intrinsic, "inp")
ubyte inp(uint port_address);


/**
* ditto
*/
pragma(DigitalMars_intrinsic, "inp")
ushort inpw(uint port_address);


/**
* ditto
*/
pragma(DigitalMars_intrinsic, "inp")
uint inpl(uint port_address);


/**
* Writes and returns value to I/O port at port_address.
*/
pragma(DigitalMars_intrinsic, "outp")
ubyte outp(uint port_address, ubyte value);


/**
* ditto
*/
pragma(DigitalMars_intrinsic, "outp")
ushort outpw(uint port_address, ushort value);


/**
* ditto
*/
pragma(DigitalMars_intrinsic, "outp")
uint outpl(uint port_address, uint value);
}

Expand All @@ -201,12 +213,15 @@ version (AnyX86)
* using the X86 SSE4 POPCNT instruction.
* POPCNT is not available on all X86 CPUs.
*/
pragma(DigitalMars_intrinsic, "popcnt")
ushort _popcnt( ushort x ) pure;
Copy link
Member

Choose a reason for hiding this comment

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

Unrelated to this PR I guess, but why not mark popcnt as an intrinsic instead? Why this bizarrely named intrinsic here?

/// ditto
pragma(DigitalMars_intrinsic, "popcnt")
int _popcnt( uint x ) pure;
version (X86_64)
{
/// ditto
pragma(DigitalMars_intrinsic, "popcnt")
int _popcnt( ulong x ) pure;
}

Expand Down Expand Up @@ -276,15 +291,21 @@ version (AnyX86)
* They may be used to guarantee a write or read cycle occurs at a specified address.
*/

ubyte volatileLoad(ubyte * ptr);
ushort volatileLoad(ushort* ptr); /// ditto
uint volatileLoad(uint * ptr); /// ditto
ulong volatileLoad(ulong * ptr); /// ditto
pragma(DigitalMars_intrinsic, "ind")
Copy link
Member

Choose a reason for hiding this comment

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

Need a better name than "ind" ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are the dmd backend op names. Do you have any ideas on a good namespacing scheme for builtins? Does it make sense to have some common ones?

Something like digitalmars.* gcc.* llvm.* d.*?

Copy link
Member

Choose a reason for hiding this comment

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

Having a namespace for them could be a possibility. But I would consider volatileLoad and volatileStore common between all compilers - unlike y2lx or cmpxchg - and so will need a meaningful name.

Copy link
Member

Choose a reason for hiding this comment

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

Has this been taken to the NG? I might need a few days to think it over, but maybe we should talk it out there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, so dmd.yl2x and d.volatileLoad or something...

With the current PR I have it's possible to do this:

version (GDC)
{
    pragma(intrinsic, "gdc.volatileLoad", ...);
}
else version (DMD)
{
    pragma(intrinsic, "dmd.volatileLoad", ...);
}

Copy link
Member

Choose a reason for hiding this comment

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

Yep. But we should only deviate when we strictly need to. :-)

Copy link
Member

Choose a reason for hiding this comment

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

How about d.* for intrinsics available on all compilers (e.g. d.volatileLoad) and dmd.*, gdc.*, ldc.*, etc. for the ones that are not portable across compilers?

{
ubyte volatileLoad(ubyte * ptr);
ushort volatileLoad(ushort* ptr); /// ditto
uint volatileLoad(uint * ptr); /// ditto
ulong volatileLoad(ulong * ptr); /// ditto
}

void volatileStore(ubyte * ptr, ubyte value); /// ditto
void volatileStore(ushort* ptr, ushort value); /// ditto
void volatileStore(uint * ptr, uint value); /// ditto
void volatileStore(ulong * ptr, ulong value); /// ditto
pragma(DigitalMars_intrinsic, "eq")
Copy link
Member

Choose a reason for hiding this comment

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

Likewise here with "eq"

{
void volatileStore(ubyte * ptr, ubyte value); /// ditto
void volatileStore(ushort* ptr, ushort value); /// ditto
void volatileStore(uint * ptr, uint value); /// ditto
void volatileStore(ulong * ptr, ulong value); /// ditto
}

@system unittest
{
Expand Down
9 changes: 9 additions & 0 deletions src/core/math.d
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public:
* Results are undefined if |x| >= $(POWER 2,64).
*/

pragma(DigitalMars_intrinsic, "cos")
real cos(real x) @safe pure nothrow; /* intrinsic */

/***********************************
Expand All @@ -55,6 +56,7 @@ real cos(real x) @safe pure nothrow; /* intrinsic */
* Results are undefined if |x| >= $(POWER 2,64).
*/

pragma(DigitalMars_intrinsic, "sin")
real sin(real x) @safe pure nothrow; /* intrinsic */

/*****************************************
Expand All @@ -63,6 +65,7 @@ real sin(real x) @safe pure nothrow; /* intrinsic */
* greater than long.max, the result is
* indeterminate.
*/
pragma(DigitalMars_intrinsic, "rndtol")
long rndtol(real x) @safe pure nothrow; /* intrinsic */


Expand All @@ -85,6 +88,7 @@ extern (C) real rndtonl(real x);
* )
*/

pragma(DigitalMars_intrinsic, "sqrt")
@safe pure nothrow
{
float sqrt(float x); /* intrinsic */
Expand All @@ -97,6 +101,7 @@ extern (C) real rndtonl(real x);
* References: frexp
*/

pragma(DigitalMars_intrinsic, "scale")
real ldexp(real n, int exp) @safe pure nothrow; /* intrinsic */

unittest {
Expand Down Expand Up @@ -124,6 +129,7 @@ unittest {
* $(TR $(TD $(PLUSMN)$(INFIN)) $(TD +$(INFIN)) )
* )
*/
pragma(DigitalMars_intrinsic, "abs")
real fabs(real x) @safe pure nothrow; /* intrinsic */

/**********************************
Expand All @@ -134,14 +140,17 @@ real fabs(real x) @safe pure nothrow; /* intrinsic */
* $(B nearbyint) performs
* the same operation, but does not set the FE_INEXACT exception.
*/
pragma(DigitalMars_intrinsic, "rint")
real rint(real x) @safe pure nothrow; /* intrinsic */

/***********************************
* Building block functions, they
* translate to a single x87 instruction.
*/

pragma(DigitalMars_intrinsic, "yl2x")
real yl2x(real x, real y) @safe pure nothrow; // y * log2(x)
pragma(DigitalMars_intrinsic, "yl2xp1")
real yl2xp1(real x, real y) @safe pure nothrow; // y * log2(x + 1)

unittest
Expand Down