Jump to page: 1 25  
Page
Thread overview
Conditional compilation inside asm and enum declarations
Jul 13, 2009
Julian Salazar
Jul 13, 2009
Walter Bright
Jul 13, 2009
bearophile
Jul 13, 2009
Julian Salazar
Jul 14, 2009
Walter Bright
Jul 14, 2009
Bill Baxter
Jul 14, 2009
Walter Bright
Jul 14, 2009
Walter Bright
Jul 14, 2009
Walter Bright
Jul 14, 2009
Walter Bright
Jul 14, 2009
Bill Baxter
Jul 14, 2009
Walter Bright
Jul 14, 2009
Bill Baxter
Jul 14, 2009
Leandro Lucarella
Jul 14, 2009
Walter Bright
Jul 14, 2009
Bill Baxter
Jul 15, 2009
Walter Bright
Jul 15, 2009
Bill Baxter
Jul 14, 2009
Rainer Deyke
Jul 15, 2009
Walter Bright
Jul 15, 2009
Bill Baxter
Jul 15, 2009
Walter Bright
Jul 15, 2009
bearophile
Jul 15, 2009
grauzone
Jul 15, 2009
Walter Bright
Jul 15, 2009
grauzone
Jul 15, 2009
Walter Bright
Jul 15, 2009
Lutger
Jul 15, 2009
Walter Bright
Jul 15, 2009
Leandro Lucarella
Jul 14, 2009
Julian Salazar
Jul 14, 2009
Walter Bright
Jul 14, 2009
Don
Jul 15, 2009
Walter Bright
Jul 15, 2009
Trass3r
Jul 15, 2009
Walter Bright
Jul 15, 2009
Don
Jul 15, 2009
Daniel Keep
Jul 15, 2009
Walter Bright
Jul 15, 2009
Walter Bright
July 13, 2009
Hi, I'm new here to the community but I've been using D for a while now, and I have to say that it's a great programming language. I'd like to get involved in this community and help shape this language.

I'm just wondering about a minor issue: why are conditional blocks invalid within expressions such as enum and asm? I mean, in trivial cases it's fine, but in instances where code duplication is a big maintainability nightmare, making conditional compilation more flexible would have benefits for developers.

Something like (I know it's a trivial example, but you get the point):

asm {
   version(x86) mov EAX, 1;
   else version(x86_64) mov EAX, 2;
}

would trigger an error. Also, though I know enum qualifies as a constant/datatype cross, structs and classes are perfectly fine with conditional compilation. Couldn't the lexical stuff be changed to support it for enum and asm as well?

Also, I noticed that there is no formal specification page for x86-64 inline assembly. You define a predefined version identifier such as D_InlineAsm_X86_64, but you don't define registers and instructions pertaining to it. In GDC for example, using the RAX register in the D inline ASM syntax is invalid. Not sure what the case is in LDC (they probably do implement it for x86-64), and I know DMD does not have a 64-bit version, but the spec should at least have a definition for compilers that do implement 64-bit support.

Thanks for your time,
- Julian 

July 13, 2009
On Mon, Jul 13, 2009 at 11:15 AM, Julian Salazar<julian@ifeelrandom.com> wrote:
> Hi, I'm new here to the community but I've been using D for a while now, and I have to say that it's a great programming language. I'd like to get involved in this community and help shape this language.

Man, so would I ;)

> I'm just wondering about a minor issue: why are conditional blocks invalid within expressions such as enum and asm? I mean, in trivial cases it's fine, but in instances where code duplication is a big maintainability nightmare, making conditional compilation more flexible would have benefits for developers.
>
> Something like (I know it's a trivial example, but you get the point):
>
> asm {
>   version(x86) mov EAX, 1;
>   else version(x86_64) mov EAX, 2;
> }
>
> would trigger an error. Also, though I know enum qualifies as a constant/datatype cross, structs and classes are perfectly fine with conditional compilation. Couldn't the lexical stuff be changed to support it for enum and asm as well?

That'd be nice.  If you'd like, you could file an enhancement in D's bugzilla, at http://d.puremagic.com/issues/.

> Also, I noticed that there is no formal specification page for x86-64 inline assembly. You define a predefined version identifier such as D_InlineAsm_X86_64, but you don't define registers and instructions pertaining to it. In GDC for example, using the RAX register in the D inline ASM syntax is invalid. Not sure what the case is in LDC (they probably do implement it for x86-64), and I know DMD does not have a 64-bit version, but the spec should at least have a definition for compilers that do implement 64-bit support.

I'm pretty sure LDC does implement x64 inline assembly.  It doesn't seem to be documented yet.

GDC supports inline assembly for just about any platform but with a nonstandard GCC-based syntax; see the "Extended Assembler" section here: http://dgcc.sourceforge.net/gdc/manual.html  I've personally used it for x64 assembly with great success :)
July 13, 2009
Julian Salazar wrote:
> Hi, I'm new here to the community but I've been using D for a while now, and I have to say that it's a great programming language. I'd like to get involved in this community and help shape this language.
[snip]

Great! This is the place to effect that, and the improvement related to
allowing version inside asm blocks is a good start.

Andrei

July 13, 2009
Julian Salazar wrote:
> Hi, I'm new here to the community but I've been using D for a while now, and I have to say that it's a great programming language. I'd like to get involved in this community and help shape this language.

Welcome!


> I'm just wondering about a minor issue: why are conditional blocks invalid within expressions such as enum and asm? I mean, in trivial cases it's fine, but in instances where code duplication is a big maintainability nightmare, making conditional compilation more flexible would have benefits for developers.

The request to do it for enums has been thrashed about before. Essentially, version works at the declaration and statement level, not at the expression level or in between tokens, etc. The reason for this is to encourage a more modular approach to versioning than the typical C method of doing it at the lowest level.


> Something like (I know it's a trivial example, but you get the point):
> 
> asm {
>    version(x86) mov EAX, 1;
>    else version(x86_64) mov EAX, 2;
> }
> 
> would trigger an error. Also, though I know enum qualifies as a constant/datatype cross, structs and classes are perfectly fine with conditional compilation. Couldn't the lexical stuff be changed to support it for enum and asm as well?

Let me illustrate by a current example. The linker (optlink) is written 100% in assembler. This makes it rather intractable. It's also loaded up with line-by-line nested conditional assembly (and a lot of macros). It's so hard to see what is *actually* being compiled that I'll assemble it, run OBJ2ASM on the output, and work off of the disassembled code.

So, in essence, the idea is to push conditional compilation to higher levels, not lower levels. Ideally, versioning would be done by abstracting all the version differences into an interface implemented by different modules.


> Also, I noticed that there is no formal specification page for x86-64 inline assembly. You define a predefined version identifier such as D_InlineAsm_X86_64, but you don't define registers and instructions pertaining to it. In GDC for example, using the RAX register in the D inline ASM syntax is invalid. Not sure what the case is in LDC (they probably do implement it for x86-64), and I know DMD does not have a 64-bit version, but the spec should at least have a definition for compilers that do implement 64-bit support.

The first approximation to the definition is to use the Intel asm syntax as outlined in their processor data sheets. I haven't written a spec more detailed than that because it's a lot of work and I'm lazy, and such work is not terribly exciting. But if you'd like to help with that, I'd welcome it.
July 13, 2009
Walter Bright:
> The first approximation to the definition is to use the Intel asm syntax as outlined in their processor data sheets. I haven't written a spec more detailed than that because it's a lot of work and I'm lazy, and such work is not terribly exciting. But if you'd like to help with that, I'd welcome it.

That can be done keeping a close look at how LDC has done things.

Bye,
bearophile
July 13, 2009
"Walter Bright" <newshound1@digitalmars.com> wrote in message news:h3fu36$22hl$1@digitalmars.com...
> Welcome!

A welcome from the guy who actually created the D language - thanks!

> The request to do it for enums has been thrashed about before. Essentially, version works at the declaration and statement level, not at the expression level or in between tokens, etc. The reason for this is to encourage a more modular approach to versioning than the typical C method of doing it at the lowest level.

That makes sense. I realize that enums aren't structures of data per se, but simply integers with a range of defined values, which of course should defined and parsed as one expression. And the comma separator in a list doesn't lend itself well to being separated by different expressions (in fact, I recently filed issue 3063 where DSSS goes out-of-memory because of an extra comma in D2's std.dateparse - not your fault but it'd be nice to use DSSS again without editing the library source).

> Let me illustrate by a current example. The linker (optlink) is written 100% in assembler. This makes it rather intractable. It's also loaded up with line-by-line nested conditional assembly (and a lot of macros). It's so hard to see what is *actually* being compiled that I'll assemble it, run OBJ2ASM on the output, and work off of the disassembled code.

Maybe it's time for some maintenance? Or a rewrite in a certain higher-level language? ;)

> So, in essence, the idea is to push conditional compilation to higher levels, not lower levels. Ideally, versioning would be done by abstracting all the version differences into an interface implemented by different modules.

You make a valid point. However the issue still remains where two versions for example are inextricably linked. It's understandable that you would keep separate modules when compiling between architectures like x86 and SPARC64, or even Basic and Advanced versions (which usually just involve including functionality). However, when it involves situations such as the x86 & x86-64 which ARE very similar platforms and a full copy with minimal rewrite does not seem justified. Tell that to device driver writers with their C, inline assembly and #ifdefs.

(Side note: I've worked around the versioning with a slightly more cumbersome syntax.
   asm {
       ...code...
   } // But I can't assure that no code is compiled between the two asm statements =/
   version(x86) asm  {
       ...code...
   }
   else version(x86_64) asm  {
       ...code...
   }
)

> The first approximation to the definition is to use the Intel asm syntax as outlined in their processor data sheets. I haven't written a spec more detailed than that because it's a lot of work and I'm lazy, and such work is not terribly exciting. But if you'd like to help with that, I'd welcome it.

How would I go about doing that? It seems like all the work that remains to be done is just updating opcodes and the valid registers. Maybe a bit of tightening of the specification and syntax, but other than that the basic outline is there.

Thanks to everyone for the positive response! 

July 14, 2009
Julian Salazar wrote:
> Maybe it's time for some maintenance? Or a rewrite in a certain higher-level language? ;)

Yes, but to rewrite it requires understanding it, and that means obj2asm.

>> So, in essence, the idea is to push conditional compilation to higher levels, not lower levels. Ideally, versioning would be done by abstracting all the version differences into an interface implemented by different modules.
> 
> You make a valid point. However the issue still remains where two versions for example are inextricably linked. It's understandable that you would keep separate modules when compiling between architectures like x86 and SPARC64, or even Basic and Advanced versions (which usually just involve including functionality). However, when it involves situations such as the x86 & x86-64 which ARE very similar platforms and a full copy with minimal rewrite does not seem justified. Tell that to device driver writers with their C, inline assembly and #ifdefs.
> 
> (Side note: I've worked around the versioning with a slightly more cumbersome syntax.
>    asm {
>        ...code...
>    } // But I can't assure that no code is compiled between the two asm statements =/
>    version(x86) asm  {
>        ...code...
>    }
>    else version(x86_64) asm  {
>        ...code...
>    }
> )

It's been rehashed here several times (not to rag on you, just to point out that it isn't something that's been overlooked). To sum up, I've worked a lot with both styles - #ifdef, and separating dependencies into independent modules. The latter works a lot better. I know it's hard to believe if you're used to the #ifdef style. I've been doing some work to remove #ifdef's from the dmd compiler source, and the results so far have been very satisfactory.


>> The first approximation to the definition is to use the Intel asm syntax as outlined in their processor data sheets. I haven't written a spec more detailed than that because it's a lot of work and I'm lazy, and such work is not terribly exciting. But if you'd like to help with that, I'd welcome it.
> 
> How would I go about doing that? It seems like all the work that remains to be done is just updating opcodes and the valid registers. Maybe a bit of tightening of the specification and syntax, but other than that the basic outline is there.

For one thing, the valid registers for x86 mode do not include the 64 bit registers. There's also the grammar for the operands, which is not specified in the D spec.
July 14, 2009
Julian Salazar wrote:
> Hi, I'm new here to the community but I've been using D for a while now, and I have to say that it's a great programming language. I'd like to get involved in this community and help shape this language.

Welcome!

> I'm just wondering about a minor issue: why are conditional blocks invalid within expressions such as enum and asm? I mean, in trivial cases it's fine, but in instances where code duplication is a big maintainability nightmare, making conditional compilation more flexible would have benefits for developers.
> 
> Something like (I know it's a trivial example, but you get the point):
> 
> asm {
>    version(x86) mov EAX, 1;
>    else version(x86_64) mov EAX, 2;
> }
> 
> would trigger an error. 

A much more convincing example is with position-independent code for Linux shared libraries.
In this case you may have a long function, with only a single instruction right in the middle which needs to be changed.
This example is taken from my bigint library. In the middle of a 50-line function is this single PIC-dependent instruction:

asm {
    :
    :
    adc ECX, EDX;
version (D_PIC) {} else { // the next trick can't be done in PIC mode.
      mov storagenop, EDX; // make #uops in loop a multiple of 3
}
    mul int ptr [ESP + 8];
    :
}

But I'd class this as a minor annoyance rather than a significant problem.
July 14, 2009
On Mon, Jul 13, 2009 at 10:05 PM, Walter Bright<newshound1@digitalmars.com> wrote:
> Julian Salazar wrote:
> It's been rehashed here several times (not to rag on you, just to point out
> that it isn't something that's been overlooked). To sum up, I've worked a
> lot with both styles - #ifdef, and separating dependencies into independent
> modules. The latter works a lot better. I know it's hard to believe if
> you're used to the #ifdef style. I've been doing some work to remove
> #ifdef's from the dmd compiler source, and the results so far have been very
> satisfactory.

But from where I sit it looked like Walter didn't really convince anyone.  To me this seems like a point where D is overly patronizing, to use the phrase from a recent post.

--bb
July 14, 2009
On Mon, Jul 13, 2009 at 8:24 PM, Walter Bright<newshound1@digitalmars.com> wrote:
> Julian Salazar wrote:
>>
>> Hi, I'm new here to the community but I've been using D for a while now, and I have to say that it's a great programming language. I'd like to get involved in this community and help shape this language.
>
> Welcome!
>
>
>> I'm just wondering about a minor issue: why are conditional blocks invalid within expressions such as enum and asm? I mean, in trivial cases it's fine, but in instances where code duplication is a big maintainability nightmare, making conditional compilation more flexible would have benefits for developers.
>
> The request to do it for enums has been thrashed about before. Essentially, version works at the declaration and statement level, not at the expression level or in between tokens, etc. The reason for this is to encourage a more modular approach to versioning than the typical C method of doing it at the lowest level.
>
>
>> Something like (I know it's a trivial example, but you get the point):
>>
>> asm {
>>   version(x86) mov EAX, 1;
>>   else version(x86_64) mov EAX, 2;
>> }
>>
>> would trigger an error. Also, though I know enum qualifies as a constant/datatype cross, structs and classes are perfectly fine with conditional compilation. Couldn't the lexical stuff be changed to support it for enum and asm as well?
>
> Let me illustrate by a current example. The linker (optlink) is written 100% in assembler. This makes it rather intractable. It's also loaded up with line-by-line nested conditional assembly (and a lot of macros). It's so hard to see what is *actually* being compiled that I'll assemble it, run OBJ2ASM on the output, and work off of the disassembled code.
>
> So, in essence, the idea is to push conditional compilation to higher levels, not lower levels. Ideally, versioning would be done by abstracting all the version differences into an interface implemented by different modules.
>
>
>> Also, I noticed that there is no formal specification page for x86-64 inline assembly. You define a predefined version identifier such as D_InlineAsm_X86_64, but you don't define registers and instructions pertaining to it. In GDC for example, using the RAX register in the D inline ASM syntax is invalid. Not sure what the case is in LDC (they probably do implement it for x86-64), and I know DMD does not have a 64-bit version, but the spec should at least have a definition for compilers that do implement 64-bit support.
>
> The first approximation to the definition is to use the Intel asm syntax as outlined in their processor data sheets. I haven't written a spec more detailed than that because it's a lot of work and I'm lazy, and such work is not terribly exciting. But if you'd like to help with that, I'd welcome it.
>

LDC implements x86-64 inline asm just like x86-32 inline asm, that is
the syntax is the same, and the only real difference is the new 64bit
registers and opcodes.
Of course a spec would be nice, but they're really so similar that it
might well be a single page if you ask me.
« First   ‹ Prev
1 2 3 4 5