asm woes...

ZombineDev via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat May 28 03:10:19 PDT 2016


On Saturday, 28 May 2016 at 08:10:50 UTC, Era Scarecrow wrote:
> On Friday, 27 May 2016 at 09:22:49 UTC, Guillaume Piolat wrote:
>> You have to write your code three times, one for
>>
>> version(D_InlineAsm_X86)
>> version (D_InlineAsm_X86_64)
>> and a version without assembly.
>
>  Rather than make a new thread I wonder if struct inheritance 
> wouldn't solve this, as trying to manage specific versions, 
> lack of versions, checks for CTFE all became a headache. and 
> bloated a 4 line function (2 of which were the 
> opening/declaration) to something like 20 lines and looks like 
> a huge mess.
>
>  So...
>
>  Let's assume structs as they are don't (otherwise) change.
>  Let's assume structs can be inherited.
>  Let's assume inherited structs change _behavior_ only 
> (overridden functions as final), but don't add/expand any new 
> data (non-polymorphic, no vtables).
>
>  Then I could do something like this!
>
>   //contains plain portable version
>   struct base {}
>
>   version(X86) {
>     struct inherited : base {
>       //only adds or replaces functions, no data changes
>       //all asm injection is known to be 32bit x86
>     }
>   }
>   version(X86_64) {
>     ...
>   }
>
>  Truthfully going with my example, only a couple functions 
> would be considered, namely multiply and divide as they would 
> be the slowest ones, while everything else has very little to 
> improve on, at least based on how wideint.d was implemented.

The great thing about D's UFCS is that it allows exactly that:

void main()
{
     WideInt myInt;
     myInt.inc(); // looks like a member function
     myInt++; // can be hidden behind operator overloading
}

struct WideInt
{
     ulong[2] data;

     int opUnary(string s)()
     {
         static if (s == "++")
             this.inc();
     }
}

version(D_InlineAsm_X86_64)
{
     void inc(ref WideInt w) { /* 32-bit increment implementation 
*/ }
}
else version(D_InlineAsm_X86)
{
     void inc(ref WideInt w) { /* 64-bit increment implementation 
*/ }
}
else
{
     void inc(ref WideInt w) { /* generic increment implementation 
*/ }
}

Also, you can implement inc() in terms of ulong[2] - void inc(ref 
ulong[2] w), which makes it applicable for other types, with the 
same memory representation.
E.g. cent - (cast(ulong[2]*)&cent).inc(), arrays - ulong[] arr; 
arr[0..2].inc(), and so on.




More information about the Digitalmars-d-learn mailing list