www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - templates and assembler

reply manu <manu_member pathlink.com> writes:
Hi there!
Im 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

Ive 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(Im using dmd)? 

I would be very thankful to everybody who helps me fixing that problem!
Mar 25 2006
parent reply James Dunne <james.jdunne gmail.com> writes:
manu wrote:
 Hi there!
 Im 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
 
 Ive 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(Im 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
Mar 25 2006
parent reply manu <manu_member pathlink.com> writes:
James Dunne says...
manu wrote:
 Hi there!
 Im 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
 
 Ive 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(Im 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 thanks 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 doesnt work(CAPITAL letters!) cause the compiler(dmd) cant handle template arguments in asm blocks. And sure using 'fld x' works but only if I dont use 'naked', as you said. Otherwise the compiler doesnt 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.)
Mar 26 2006
parent reply Don Clugston <dac nospam.com.au> writes:
manu wrote:
 James Dunne says...
 manu wrote:
 Hi there!
 Im 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

 Ive 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(Im using dmd)? 

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

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 thanks 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 doesnt work(CAPITAL letters!) cause the compiler(dmd) cant 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 dont use 'naked', as you
 said. Otherwise the compiler doesnt 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.)

Mar 27 2006
parent James Dunne <james.jdunne gmail.com> writes:
Don Clugston wrote:
 manu wrote:
 
 James Dunne says...

 manu wrote:

 Hi there!
 Im 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

 Ive 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(Im 
 using dmd)?
 I would be very thankful to everybody who helps me fixing that problem!

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 thanks 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 doesnt work(CAPITAL letters!) cause the compiler(dmd) cant 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
Mar 27 2006