www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - templates and assembler

reply manu <manu_member pathlink.com> writes:
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!
Mar 25 2006
parent reply James Dunne <james.jdunne gmail.com> writes:
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
Mar 25 2006
parent reply manu <manu_member pathlink.com> writes:
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.)
Mar 26 2006
parent reply Don Clugston <dac nospam.com.au> writes:
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.)
Mar 27 2006
parent James Dunne <james.jdunne gmail.com> writes:
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
Mar 27 2006