예제 #1
0
def test_float():
    label = Label()
    prog = Program(
        push(ebp),
        mov(ebp, esp),
        fld(ebp.addr + 8),
        fld(ebp.addr + 12),
        fcomi(st(1)),
        fstp(st(0)),
        fstp(st(0)),
        ja(label),
        mov(eax, 1),
        pop(ebp),
        ret(),
        label,
        mov(eax, 2),
        pop(ebp),
        ret(),
    )
    fun = prog.compile(c_int, [c_float, c_float])
    assert fun(10, 20) == 2
    assert fun(20, 10) == 1
예제 #2
0
def test_float():
    label = Label()
    prog = Program(
        push(ebp),
        mov(ebp, esp),
        fld(ebp.addr+8),
        fld(ebp.addr+12),
        fcomi(st(1)),
        fstp(st(0)),
        fstp(st(0)),
        ja(label),
        mov(eax, 1),
        pop(ebp),
        ret(),
        label,
        mov(eax, 2),
        pop(ebp),
        ret(),
    )
    fun = prog.compile(c_int, [c_float, c_float])
    assert fun(10, 20) == 2
    assert fun(20, 10) == 1
예제 #3
0
def compile():
    outer_loop = Label()
    inner_loop = Label()
    distance_condition = Label()
    distance_else = Label()
    min_condition = Label()
    size_condition = Label()

    prog = Program(
        push(ebp),
        mov(ebp, esp),
        mov(eax, ebp.addr + 8),  #size
        cmp(eax, 2),
        jl(size_condition),
        mov(ecx, ebp.addr + 12),  #array pointer
        fld(ebp.addr + 16),  #force factor
        fld(ebp.addr + 20),  #minimum distance
        fld(ebp.addr + 24),  #maximum distance
        sub(eax, 1),
        mov(ebx, 4 * 4),
        mul(ebx),
        add(ecx, eax),
        mov(eax, ebp.addr + 12),  #array pointer
        outer_loop,
        mov(ebx, eax),
        add(ebx, 4 * 4),
        inner_loop,
        # x vector
        fld(eax.addr + 0 * 4),
        fsub(ebx.addr + 0 * 4),
        # y vector
        fld(eax.addr + 1 * 4),
        fsub(ebx.addr + 1 * 4),
        # distance
        fld(st(1)),
        fmul(st(0), st(0)),
        fld(st(1)),
        fmul(st(0), st(0)),
        faddp(),
        fsqrt(),
        #make sure the distance is bigger then 10
        fcomi(st(4)),
        fcmovb(st(4)),
        #only calculate if the distance is less then 200
        fcomi(st(3)),
        ja(distance_condition),
        #cube distance
        fld(st(0)),
        fmul(st(1), st(0)),
        fmulp(),
        #compute force vector
        fdiv(st(2), st(0)),
        fdivp(),
        fld(st(4)),
        fmul(st(2), st(0)),
        fmulp(),
        #accumulate y component
        fld(st(0)),
        fadd(eax.addr + 3 * 4),
        fstp(eax.addr + 3 * 4),
        fsubr(ebx.addr + 3 * 4),
        fstp(ebx.addr + 3 * 4),
        #accumulate x component
        fld(st(0)),
        fadd(eax.addr + 2 * 4),
        fstp(eax.addr + 2 * 4),
        fsubr(ebx.addr + 2 * 4),
        fstp(ebx.addr + 2 * 4),
        jmp(distance_else),
        distance_condition,
        fstp(st(0)),
        fstp(st(0)),
        fstp(st(0)),
        distance_else,
        add(ebx, 4 * 4),
        cmp(ebx, ecx),
        jbe(inner_loop),
        add(eax, 4 * 4),
        cmp(eax, ecx),
        jb(outer_loop),

        #restore the fpu
        fstp(st(0)),
        fstp(st(0)),
        fstp(st(0)),
        size_condition,
        pop(ebp),
        ret(),
    )

    fun = prog.compile(argtypes=[
        c_int,
        POINTER(c_float),
        c_float,
        c_float,
        c_float,
    ])

    return fun
예제 #4
0
def compile():
    outer_loop = Label()
    inner_loop = Label()
    distance_condition = Label()
    distance_else = Label()
    min_condition = Label()
    size_condition = Label()

    prog = Program(
        push(ebp),
        mov(ebp, esp),

        mov(eax, ebp.addr+8), #size
        cmp(eax, 2),
        jl(size_condition),

        mov(ecx, ebp.addr+12), #array pointer

        fld(ebp.addr+16), #force factor
        fld(ebp.addr+20), #minimum distance
        fld(ebp.addr+24), #maximum distance

        sub(eax, 1),
        mov(ebx, 4*4),
        mul(ebx),
        add(ecx, eax),

        mov(eax, ebp.addr+12), #array pointer

        outer_loop,
            mov(ebx, eax),
            add(ebx, 4*4),
            inner_loop,
                # x vector
                fld(eax.addr+0*4),
                fsub(ebx.addr+0*4),
                # y vector 
                fld(eax.addr+1*4),
                fsub(ebx.addr+1*4),
                # distance
                fld(st(1)), 
                fmul(st(0), st(0)),
                fld(st(1)), 
                fmul(st(0), st(0)),
                faddp(),
                fsqrt(),
                #make sure the distance is bigger then 10
                fcomi(st(4)),
                fcmovb(st(4)),
                #only calculate if the distance is less then 200
                fcomi(st(3)),
                ja(distance_condition),
                    #cube distance
                    fld(st(0)),
                    fmul(st(1), st(0)),
                    fmulp(),
                    #compute force vector
                    fdiv(st(2), st(0)),
                    fdivp(),
                    fld(st(4)),
                    fmul(st(2), st(0)),
                    fmulp(),
                    #accumulate y component
                    fld(st(0)),
                    fadd(eax.addr+3*4),
                    fstp(eax.addr+3*4),
                    fsubr(ebx.addr+3*4),
                    fstp(ebx.addr+3*4),
                    #accumulate x component
                    fld(st(0)),
                    fadd(eax.addr+2*4),
                    fstp(eax.addr+2*4),
                    fsubr(ebx.addr+2*4),
                    fstp(ebx.addr+2*4),
                jmp(distance_else),
                distance_condition,
                    fstp(st(0)),
                    fstp(st(0)),
                    fstp(st(0)),
                distance_else,
            add(ebx, 4*4),
            cmp(ebx, ecx),
            jbe(inner_loop),
        add(eax, 4*4),
        cmp(eax, ecx),
        jb(outer_loop),
        
        #restore the fpu
        fstp(st(0)),
        fstp(st(0)),
        fstp(st(0)),

        size_condition,
        
        pop(ebp),
        ret(),
    )

    fun = prog.compile(argtypes=[
        c_int,
        POINTER(c_float),
        c_float,
        c_float,
        c_float,
    ])

    return fun