view tests/mini/asm8.d @ 1168:ab186e535e72

A different fix to #218 and DMD2682 that does not lead to constant folding regressions. Fixes run/const_15, run/c/const_16_B. The price is removing the lvalueness of struct literals. If it turns out too much code depends on this behavior or we don't want to break with DMD, we could keep struct literals as lvalues and instead convert struct literals used as expression initializers into struct initializers.
author Christian Kamm <kamm incasoftware de>
date Sun, 29 Mar 2009 11:43:45 +0200
parents e8c6dbcd33d1
children
line wrap: on
line source

const float  one_f = 1;
const double one_d = 1;
const real   one_r = 1;

int foo()
{
    version(X86)
    {
        asm { mov EAX, 42; }
    }
    else version (X86_64)
    {
        asm { mov EAX, 42; }
    }
    else static assert(0, "todo");
}

ulong bar()
{
    version(X86)
    {
        asm { mov EDX, 0xAA; mov EAX, 0xFF; }
    }
    else version (X86_64)
    {
        asm { movq RAX, 0xAA000000FF; }
    }
    else static assert(0, "todo");
}


float onef()
{
    version(X86)
    {
        asm { fld1; }
    }
    else version (X86_64)
    {
        asm { movss XMM0, [one_f]; }
    }
    else static assert(0, "todo");
}

double oned()
{
    version(X86)
    {
        asm { fld1; }
    }
    else version (X86_64)
    {
        asm { movsd XMM0, [one_d]; }
    }
    else static assert(0, "todo");
}

real oner()
{
    version(X86)
    {
        asm { fld1; }
    }
    else version (X86_64)
    {
        asm { fld1; }
    }
    else static assert(0, "todo");
}

ifloat oneif()
{
    version(X86)
    {
        asm { fld1; }
    }
    else version (X86_64)
    {
        asm { movss XMM0, [one_f]; }
    }
    else static assert(0, "todo");
}

idouble oneid()
{
    version(X86)
    {
        asm { fld1; }
    }
    else version (X86_64)
    {
        asm { movsd XMM0, [one_d]; }
    }
    else static assert(0, "todo");
}

ireal oneir()
{
    version(X86)
    {
        asm { fld1; }
    }
    else version (X86_64)
    {
        asm { fld1; }
    }
    else static assert(0, "todo");
}


const float two_f = 2;

cfloat cf()
{
    version(X86)
    {
        asm { fld1; fld two_f; }
    }
    else version (X86_64)
    {
        asm
        {
            movss XMM0, [one_f];
            movss XMM1, [two_f];
        }
    }
    else static assert(0, "todo");
}

extern(C) cfloat cf_C()
{
    version(X86)
    {
        asm {
            mov EAX, [one_f];
            mov EDX, [two_f];
        }
    }
    else version (X86_64)
    {
        asm {
            mov EAX, [one_f];
            mov ECX, [two_f];
            
            shl RCX, 32;
            or RAX, RCX;
            
            movd XMM0, RAX;
        }
    }
    else static assert(0, "todo");
}

cfloat cf2()
{
    version(X86)
    {
        asm
        {
            naked;
            fld1;
            fld two_f;
            ret;
        }
    }
    else version (X86_64)
    {
        asm
        {
            naked;
            movss XMM0, [one_f];
            movss XMM1, [two_f];
            ret;
        }
    }
    else static assert(0, "todo");
}

extern(C) cfloat cf2_C()
{
    version(X86)
    {
        asm
        {
            naked;
            mov EAX, [one_f];
            mov EDX, [two_f];
            ret;
        }
    }
    else version (X86_64)
    {
        asm {
            naked;
            mov EAX, [one_f];
            mov ECX, [two_f];
            
            shl RCX, 32;
            or RAX, RCX;
            
            movd XMM0, RAX;
            ret;
        }
    }
    else static assert(0, "todo");
}


const double two_d = 2;

cdouble cd()
{
    version(X86)
    {
        asm { fld1; fld two_d; }
    }
    else version (X86_64)
    {
        asm
        {
            leaq RAX, [one_d];
            leaq RCX, [two_d];
            movsd XMM0, [RAX];
            movsd XMM1, [RCX];
        }
    }
    else static assert(0, "todo");
}

cdouble cd2()
{
    version(X86)
    {
        asm
        {
            naked;
            fld1;
            fld two_d;
            ret;
        }
    }
    else version (X86_64)
    {
        asm
        {
            naked;
            movsd XMM0, [one_d];
            movsd XMM1, [two_d];
        }
    }
    else static assert(0, "todo");
}


const real two_r = 2.0;

creal cr()
{
    version(X86)
    {
        asm { fld1; fld two_r; }
    }
    else version (X86_64)
    {
        asm { fld two_r; fld1; }
    }
    else static assert(0, "todo");
}

creal cr2()
{
    version(X86)
    {
        asm
        {
            naked;
            fld1;
            fld two_r;
            ret;
        }
    }
    else version (X86_64)
    {
        asm
        {
            naked;
            fld two_r;
            fld1;
            ret;
        }
    }
    else static assert(0, "todo");
}

void* vp()
{
    version(X86)
    {
        asm { mov EAX, 0x80; }
    }
    else version (X86_64)
    {
        asm { movq RAX, 0x80; }
    }
    else static assert(0, "todo");
}

int[int] gaa;

int[int] aa()
{
    version(X86)
    {
        asm { mov EAX, gaa; }
    }
    else version (X86_64)
    {
        asm { movq RAX, gaa; }
    }
    else static assert(0, "todo");
}

Object gobj;

Object ob()
{
    version(X86)
    {
        asm { mov EAX, gobj; }
    }
    else version (X86_64)
    {
        asm { movq RAX, gobj; }
    }
    else static assert(0, "todo");
}

char[] ghello = "hello world";

char[] str()
{
    version(X86)
    {
        asm { lea ECX, ghello; mov EAX, [ECX]; mov EDX, [ECX+4]; }
    }
    else version (X86_64)
    {
        asm { movq RAX, [ghello]; movq RDX, [ghello]+8; }
    }
    else static assert(0, "todo");
}

char[] delegate() dg()
{
    version(X86)
    {
        asm { mov EAX, gobj; lea EDX, Object.toString; }
    }
    else version (X86_64)
    {
        asm { movq RAX, [gobj]; leaq RDX, Object.toString; }
    }
    else static assert(0, "todo");
}

void main()
{
    gaa[4] = 5;
    gobj = new Object;
    auto adg = &gobj.toString;

    assert(foo() == 42);
    assert(bar() == 0xAA000000FF);
    assert(onef() == 1);
    assert(oned() == 1);
    assert(oner() == 1);
    
    assert(oneif() == 1i);
    assert(oneid() == 1i);
    assert(oneir() == 1i);
    
    assert(cf() == 1+2i);
    assert(cf2() == 1+2i);
    
    assert(cf_C() == 1+2i);
    assert(cf2_C() == 1+2i);
    
    assert(cd() == 1+2i);
    assert(cd2() == 1+2i);
    
    assert(cr() == 1+2i);
    assert(cr2() == 1+2i);
    
    assert(vp() == cast(void*)0x80);
    assert(aa() is gaa);
    assert(ob() is gobj);
    assert(str() == "hello world");
    assert(dg()() == "object.Object");
}

extern(C) int printf(char*, ...);