www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Asm and CTFE

reply bearophile <bearophileHUGS lycos.com> writes:
This code doesn't compile with the latest DMD 2.057head:

import std.math: poly;
enum p = poly(2.0, [-2, 3, 5]);
void main() {}


The error:
...\dmd2\src\phobos\std\math.d(3752): Error: asm statements cannot be
interpreted at compile time
test.d(2):        called from here: poly(2L,[-2L,3L,5L])


The code of poly is something like this:


real poly(real x, const real[] A) pure {
    version (D_InlineAsm_X86) {
        version (Windows) {
            asm { // assembler by W. Bright
                mov     ECX,A[EBP];
                dec     ECX;
                lea     EDX,[ECX][ECX*8];
                add     EDX,ECX;
                add     EDX,A+4[EBP];
                fld     real ptr [EDX];
                jecxz   return_ST;
                fld     x[EBP];
                fxch    ST(1);
                align   4;
        L2:     fmul    ST,ST(1);
                fld     real ptr -10[EDX];
                sub     EDX,10;
                faddp   ST(1),ST;
                dec     ECX;
                jne     L2;
                fxch    ST(1);
                fstp    ST(0);
                align   4;
        return_ST:;
            }
        } else
            static assert(0);
    } else {
        sizediff_t i = A.length - 1;
        real r = A[i];
        while (--i >= 0) {
            r *= x;
            r += A[i];
        }
        return r;
    }
}


So there is code able to run at compile time, but D_InlineAsm_X86 is set at
compile time too, despite CTFE is not able to run assembly code. In Phobos
there are other similar cases where not-assembly fallback code is available,
but it can't be used by CTFE.

Do you know how to improve this situation, avoiding messy code too?

Bye,
bearophile
Nov 12 2011
parent reply =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> writes:
On 12-11-2011 13:33, bearophile wrote:
 This code doesn't compile with the latest DMD 2.057head:

 import std.math: poly;
 enum p = poly(2.0, [-2, 3, 5]);
 void main() {}


 The error:
 ...\dmd2\src\phobos\std\math.d(3752): Error: asm statements cannot be
interpreted at compile time
 test.d(2):        called from here: poly(2L,[-2L,3L,5L])


 The code of poly is something like this:


 real poly(real x, const real[] A) pure {
      version (D_InlineAsm_X86) {
          version (Windows) {
              asm { // assembler by W. Bright
                  mov     ECX,A[EBP];
                  dec     ECX;
                  lea     EDX,[ECX][ECX*8];
                  add     EDX,ECX;
                  add     EDX,A+4[EBP];
                  fld     real ptr [EDX];
                  jecxz   return_ST;
                  fld     x[EBP];
                  fxch    ST(1);
                  align   4;
          L2:     fmul    ST,ST(1);
                  fld     real ptr -10[EDX];
                  sub     EDX,10;
                  faddp   ST(1),ST;
                  dec     ECX;
                  jne     L2;
                  fxch    ST(1);
                  fstp    ST(0);
                  align   4;
          return_ST:;
              }
          } else
              static assert(0);
      } else {
          sizediff_t i = A.length - 1;
          real r = A[i];
          while (--i>= 0) {
              r *= x;
              r += A[i];
          }
          return r;
      }
 }


 So there is code able to run at compile time, but D_InlineAsm_X86 is set at
compile time too, despite CTFE is not able to run assembly code. In Phobos
there are other similar cases where not-assembly fallback code is available,
but it can't be used by CTFE.

 Do you know how to improve this situation, avoiding messy code too?

 Bye,
 bearophile

The problem is that DMD defines *all* version identifiers regardless of whether CTFE is active. I guess it's just a matter of removing the inline assembly identifiers when doing CTFE. - Alex
Nov 12 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Alex Rønne Petersen:

 The problem is that DMD defines *all* version identifiers regardless of 
 whether CTFE is active. I guess it's just a matter of removing the 
 inline assembly identifiers when doing CTFE.

Do you remember why the __ctfe is a run-time variable instead of a more right compile-time constant/version? I remember that Walter was not able to define it as a compile-time constant. So I don't know if it is possible to remove the inline assembly identifiers when doing CTFE. Bye, bearophile
Nov 12 2011
parent reply =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> writes:
On 12-11-2011 23:51, bearophile wrote:
 Alex Rønne Petersen:

 The problem is that DMD defines *all* version identifiers regardless of
 whether CTFE is active. I guess it's just a matter of removing the
 inline assembly identifiers when doing CTFE.

Do you remember why the __ctfe is a run-time variable instead of a more right compile-time constant/version? I remember that Walter was not able to define it as a compile-time constant. So I don't know if it is possible to remove the inline assembly identifiers when doing CTFE. Bye, bearophile

Not sure. But removing version identifiers when entering CTFE should be trivial; see src/mars.c for how they are added. - Alex
Nov 12 2011
parent bearophile <bearophileHUGS lycos.com> writes:
Alex Rønne Petersen:

 Not sure. But removing version identifiers when entering CTFE should be 
 trivial; see src/mars.c for how they are added.

Thank you for your answers. I have started again this topic (in a bit more general way) in the main D newsgroup. And I think Martin Nowak doesn't agree with you. Bye, bearophile
Nov 12 2011