Hi everybody.<br><br>I'm having (yet) another look at trying to get naked functions from D (1) working in our LLVM D Compiler - LDC (2).<br><br>I have this test case:<br><br>/// D CODE<br>///<br>extern(C) int printf(char*, ...);<br>
<br>ulong retval() {<br>    asm { naked; mov EAX, 0xff; mov EDX, 0xaa; ret; }<br>}<br><br>ulong retval2() {<br>    return (cast(ulong)0xaa << 32) | 0xff;<br>}<br><br>void main() {<br>    printf("%llu\n%llu\n", retval(), retval2());<br>
}<br>///<br>///<br><br>I've tried out a few things. This currently compiles to:<br><br>/// <br>///<br>target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"<br>
target triple = "i686-pc-linux-gnu"<br><br>@.str1 = internal constant [11 x i8] c"%llu\0A%llu\0A\00"               ; <[11 x i8]*> [#uses=1]<br><br>declare i32 @printf(i8*, ...)<br><br>define x86_stdcallcc i64 @_D3bar6retvalFZm() noinline {<br>
entry:<br>        call void asm sideeffect "movl $0, %eax ; movl $1, %edx ; ret ", "i,i,~{eax},~{edx}"(i32 255, i32 170)<br>        unreachable<br>}<br><br>define x86_stdcallcc i64 @_D3bar7retval2FZm() {<br>
entry:<br>        ret i64 730144440575<br>}<br><br>define x86_stdcallcc i32 @_Dmain({ i32, { i32, i8* }* } %unnamed) {<br>entry:<br>        %tmp = call x86_stdcallcc i64 @_D3bar6retvalFZm()               ; <i64> [#uses=1]<br>
        %tmp1 = call x86_stdcallcc i64 @_D3bar7retval2FZm()             ; <i64> [#uses=1]<br>        %tmp2 = call i32 (i8*, ...)* @printf(i8* getelementptr ([11 x i8]* @.str1, i32 0, i32 0), i64 %tmp, i64 %tmp1)           ; <i32> [#uses=0]<br>
        ret i32 0<br>}<br>///<br>///<br><br>When this is linked as an application, without being optimized, it works as expected.<br>But when optimized, _Dmain is reduced to:<br><br>///<br>///<br>define x86_stdcallcc i32 @_Dmain({ i32, { i32, i8* }* } %unnamed) noreturn nounwind {<br>
entry:<br>        %tmp = call x86_stdcallcc i64 @_D3bar6retvalFZm()               ; <i64> [#uses=0]<br>        unreachable<br>}<br>///<br>///<br><br>If the first impl is changed to:<br><br>///<br>///<br>define x86_stdcallcc i64 @_D3bar6retvalFZm() noinline {<br>

entry:<br>
        call void asm sideeffect "movl $0, %eax ; movl $1, %edx ; ret ", "i,i,~{eax},~{edx}"(i32 255, i32 170)<br>
        ret i64 undef ;<br>
}<br>///<br>///<br><br>It still works when not optimized. However, when optimized, then _Dmain becomes:<br><br>///<br>///<br>define x86_stdcallcc i32 @_Dmain({ i32, { i32, i8* }* } %unnamed) {<br>entry:<br>        %tmp = call x86_stdcallcc i64 @_D3bar6retvalFZm()               ; <i64> [#uses=0]<br>
        %tmp1 = call x86_stdcallcc i64 @_D3bar7retval2FZm()             ; <i64> [#uses=0]<br>        %tmp2 = call i32 (i8*, ...)* @printf(i8* getelementptr ([11 x i8]* @.str1, i32 0, i32 0), i64 undef, i64 730144440575)           ; <i32> [#uses=0]<br>
        ret i32 0<br>}<br>///<br>///<br><br><br>which (as expected) prints a bogus value.<br><br>I realize I'm entering some undefined/invalid territory here, but I'd really like to get some ideas for what I could do to make this D code work.<br>
Ideally I would like a naked attribute for a function which would mean that the entire function is composed of a single asm block.<br><br>Module level assembler could probably be used for this, but it would be nice if we could get away with using a single asm translator in the compiler.<br>
<br>Thanx in advance,<br>- Tomas Lindquist Olsen<br><br>----------------------<br><br>(1): <a href="http://digitalmars.com/d/1.0/index.html">http://digitalmars.com/d/1.0/index.html</a><br>(2): <a href="http://dsource.org/projects/ldc">http://dsource.org/projects/ldc</a><br>
<br>