Thread overview
templates and assembler
Mar 25, 2006
manu
Mar 25, 2006
James Dunne
Mar 26, 2006
manu
Mar 27, 2006
Don Clugston
Mar 27, 2006
James Dunne
March 25, 2006
Hi there!
I´m new to D and quite surprised about all the nice features it provides. So I
started to write some test apps and also tried to write some templates. It all
worked perfect until I wanted to use template identifiers in asm blocks.

consider the following:

/* file - main.d **************************************/
01: template sine(REAL) // where REAL should be one of float,double,real
02: {
03:     float sine(REAL x)
04:	{
05:	    asm
06:	    {
07:	        naked		    ; // <- make it naked to get maximum speed
08:		fld REAL ptr[ESP+4] ; // <- critical opcode
09:		fsin		    ;
10:		ret		    ;
11:	    }
12:     }
13: }
14: alias sine!(float) sine_float; // instantiation
/ *****************************************************/
An error occurs when typing the last line, due to the instantiation. It says:

main.d(8): end of instruction

I´ve figured out that it comes because of the REAL in the asm block. I also tried this for line 08:

08:   fld x

Though this compiles there remains an error at runtime: the program assumes x to be at a different position on the stack and so just a dump of stack memory is loaded into the FPU. May this an unfixed bug of the compiler(I´m using dmd)?

I would be very thankful to everybody who helps me fixing that problem!


March 25, 2006
manu wrote:
> Hi there!
> I´m new to D and quite surprised about all the nice features it provides. So I
> started to write some test apps and also tried to write some templates. It all
> worked perfect until I wanted to use template identifiers in asm blocks.
> 
> consider the following:
> 
> /* file - main.d **************************************/
> 01: template sine(REAL) // where REAL should be one of float,double,real 02: {
> 03:     float sine(REAL x)
> 04:	{
> 05:	    asm 06:	    {
> 07:	        naked		    ; // <- make it naked to get maximum speed
> 08:		fld REAL ptr[ESP+4] ; // <- critical opcode
> 09:		fsin		    ;
> 10:		ret		    ;
> 11:	    }
> 12:     }
> 13: }
> 14: alias sine!(float) sine_float; // instantiation
> / *****************************************************/
> An error occurs when typing the last line, due to the instantiation. It says:
> 
> main.d(8): end of instruction
> 
> I´ve figured out that it comes because of the REAL in the asm block. I also
> tried this for line 08:
> 
> 08:   fld x
> 
> Though this compiles there remains an error at runtime: the program assumes x to
> be at a different position on the stack and so just a dump of stack memory is
> loaded into the FPU. May this an unfixed bug of the compiler(I´m using dmd)? 
> 
> I would be very thankful to everybody who helps me fixing that problem!
> 
> 

Removing 'naked' and 'ret' instructions fixes the problem.  'real ptr[ESP+4]' also didn't work, so use 'fld x' instead.  I think you were trying to load the pointer value into the floating point register, which doesn't quite work. :)

-- 
Regards,
James Dunne
March 26, 2006
James Dunne says...
>
>manu wrote:
>> Hi there!
>> I´m new to D and quite surprised about all the nice features it provides. So I
>> started to write some test apps and also tried to write some templates. It all
>> worked perfect until I wanted to use template identifiers in asm blocks.
>> 
>> consider the following:
>> 
>> /* file - main.d **************************************/
>> 01: template sine(REAL) // where REAL should be one of float,double,real
>> 02: {
>> 03:     float sine(REAL x)
>> 04:	{
>> 05:	    asm
>> 06:	    {
>> 07:	        naked		    ; // <- make it naked to get maximum speed
>> 08:		fld REAL ptr[ESP+4] ; // <- critical opcode
>> 09:		fsin		    ;
>> 10:		ret		    ;
>> 11:	    }
>> 12:     }
>> 13: }
>> 14: alias sine!(float) sine_float; // instantiation
>> / *****************************************************/
>> An error occurs when typing the last line, due to the instantiation. It says:
>> 
>> main.d(8): end of instruction
>> 
>> I´ve figured out that it comes because of the REAL in the asm block. I also tried this for line 08:
>> 
>> 08:   fld x
>> 
>> Though this compiles there remains an error at runtime: the program assumes x to be at a different position on the stack and so just a dump of stack memory is loaded into the FPU. May this an unfixed bug of the compiler(I´m using dmd)?
>> 
>> I would be very thankful to everybody who helps me fixing that problem!
>> 
>> 
>
>Removing 'naked' and 'ret' instructions fixes the problem.  'real ptr[ESP+4]' also didn't work, so use 'fld x' instead.  I think you were trying to load the pointer value into the floating point register, which doesn't quite work. :)
>
>-- 
>Regards,
>James Dunne

First thank´s for your help, but 'real ptr[ESP+4]' works, there is no pointer
value
loaded into the FPU. 'REAL ptr[ESP+4]' is the code that doesn´t work(CAPITAL
letters!)
cause the compiler(dmd) can´t handle template arguments in asm blocks.

And sure using 'fld x' works but only if I don´t use 'naked', as you
said. Otherwise the compiler doesn´t load 'x' from the proper location. Probably

a stack frame is assumed and so it sure fails.

So I think there should be two new features implemented:

1. compiler knows the parameters offsets even if 'naked' is used 2. template arguments can be used inside asm blocks

(Please correct me if one of them is already available.)


March 27, 2006
manu wrote:
> James Dunne says...
>> manu wrote:
>>> Hi there!
>>> I´m new to D and quite surprised about all the nice features it provides. So I
>>> started to write some test apps and also tried to write some templates. It all
>>> worked perfect until I wanted to use template identifiers in asm blocks.
>>>
>>> consider the following:
>>>
>>> /* file - main.d **************************************/
>>> 01: template sine(REAL) // where REAL should be one of float,double,real 02: {
>>> 03:     float sine(REAL x)
>>> 04:	{
>>> 05:	    asm 06:	    {
>>> 07:	        naked		    ; // <- make it naked to get maximum speed
>>> 08:		fld REAL ptr[ESP+4] ; // <- critical opcode
>>> 09:		fsin		    ;
>>> 10:		ret		    ;
>>> 11:	    }
>>> 12:     }
>>> 13: }
>>> 14: alias sine!(float) sine_float; // instantiation
>>> / *****************************************************/
>>> An error occurs when typing the last line, due to the instantiation. It says:
>>>
>>> main.d(8): end of instruction
>>>
>>> I´ve figured out that it comes because of the REAL in the asm block. I also
>>> tried this for line 08:
>>>
>>> 08:   fld x
>>>
>>> Though this compiles there remains an error at runtime: the program assumes x to
>>> be at a different position on the stack and so just a dump of stack memory is
>>> loaded into the FPU. May this an unfixed bug of the compiler(I´m using dmd)? 
>>>
>>> I would be very thankful to everybody who helps me fixing that problem!
>>>
>>>
>> Removing 'naked' and 'ret' instructions fixes the problem.  'real ptr[ESP+4]' also didn't work, so use 'fld x' instead.  I think you were trying to load the pointer value into the floating point register, which doesn't quite work. :)
>>
>> -- 
>> Regards,
>> James Dunne
> 
> First thank´s for your help, but 'real ptr[ESP+4]' works, there is no pointer
> value
> loaded into the FPU. 'REAL ptr[ESP+4]' is the code that doesn´t work(CAPITAL
> letters!) cause the compiler(dmd) can´t handle template arguments in asm blocks.

Actually REAL is an undocumented reserved word in D assembler! It means the same as TBYTE in other assemblers. Use a different name!

Also, I don't think that 'ret' on its own works correctly.

Here's (untemplated) code that works.
real sin(real x)
{
    asm {
        naked;
        fld real ptr [ESP+4];
        fsin;
        ret x.sizeof + x.alignof;
    }
}


> 
> And sure using 'fld x' works but only if I don´t use 'naked', as you
> said. Otherwise the compiler doesn´t load 'x' from the proper location. Probably
> 
> a stack frame is assumed and so it sure fails.
> 
> So I think there should be two new features implemented:
> 
> 1. compiler knows the parameters offsets even if 'naked' is used
> 2. template arguments can be used inside asm blocks
> 
> (Please correct me if one of them is already available.)

March 27, 2006
Don Clugston wrote:
> manu wrote:
> 
>> James Dunne says...
>>
>>> manu wrote:
>>>
>>>> Hi there!
>>>> I´m new to D and quite surprised about all the nice features it provides. So I
>>>> started to write some test apps and also tried to write some templates. It all
>>>> worked perfect until I wanted to use template identifiers in asm blocks.
>>>>
>>>> consider the following:
>>>>
>>>> /* file - main.d **************************************/
>>>> 01: template sine(REAL) // where REAL should be one of float,double,real 02: {
>>>> 03:     float sine(REAL x)
>>>> 04:    {
>>>> 05:        asm 06:        {
>>>> 07:            naked            ; // <- make it naked to get maximum speed
>>>> 08:        fld REAL ptr[ESP+4] ; // <- critical opcode
>>>> 09:        fsin            ;
>>>> 10:        ret            ;
>>>> 11:        }
>>>> 12:     }
>>>> 13: }
>>>> 14: alias sine!(float) sine_float; // instantiation
>>>> / *****************************************************/
>>>> An error occurs when typing the last line, due to the instantiation. It says:
>>>>
>>>> main.d(8): end of instruction
>>>>
>>>> I´ve figured out that it comes because of the REAL in the asm block. I also
>>>> tried this for line 08:
>>>>
>>>> 08:   fld x
>>>>
>>>> Though this compiles there remains an error at runtime: the program assumes x to
>>>> be at a different position on the stack and so just a dump of stack memory is
>>>> loaded into the FPU. May this an unfixed bug of the compiler(I´m using dmd)?
>>>> I would be very thankful to everybody who helps me fixing that problem!
>>>>
>>>>
>>> Removing 'naked' and 'ret' instructions fixes the problem.  'real ptr[ESP+4]' also didn't work, so use 'fld x' instead.  I think you were trying to load the pointer value into the floating point register, which doesn't quite work. :)
>>>
>>> -- 
>>> Regards,
>>> James Dunne
>>
>>
>> First thank´s for your help, but 'real ptr[ESP+4]' works, there is no pointer
>> value
>> loaded into the FPU. 'REAL ptr[ESP+4]' is the code that doesn´t work(CAPITAL
>> letters!) cause the compiler(dmd) can´t handle template arguments in asm blocks.
> 
> 
> Actually REAL is an undocumented reserved word in D assembler! It means the same as TBYTE in other assemblers. Use a different name!
> 
> Also, I don't think that 'ret' on its own works correctly.
> 
> Here's (untemplated) code that works.
> real sin(real x)
> {
>     asm {
>         naked;
>         fld real ptr [ESP+4];
>         fsin;
>         ret x.sizeof + x.alignof;
>     }
> }
> 
> 

Yes, I discovered both those oddities when I was playing with the code.  I think his point was to make a templated function which took in either a float, double, or real, and performed the fsin operation on it, returning the value back, obviously.  I just couldn't figure out how the ret instruction worked in a naked call.  This sets me right though.

That said, I don't think that templates make sense for use with asm blocks; there's too much incompatibility.

-- 
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M--@ V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++
------END GEEK CODE BLOCK------

James Dunne