Loading...
You are not logged-in Login/Register





  • Posts   Search Threads
  • gangtiJuly 1, 2009 8:18 PM PDT   
    x64/ia64 Assemly Instructions in Code Porting

    refer to:
    http://software.intel.com/en-us/articles/use-explicit-prototyping/#comment-26974

    May someone give an answer???

    Contents:
    file.c
    ==================================================
    #undef NULL
    #define NULL 0
    void main() {
    func(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
    }
    void func(char *arg1, char *arg2, char *arg3,
    char *arg4, char *arg5, char *arg6,
    char *arg7, char *arg8, char *arg9)
    {
    //
    }
    ==================================================

    When I port above code from x86 to x64/ia64, I found:
    A.
    In windows x64 platform, when compiled with cl
    (vs2005's x64 cross compiler)the first four param
    will be transferred to func with universal registers,
    using mov(same as movzx) assembly instructions, so
    the upper 32 bits will be zeroed.
    So in the above code, arg1~arg4 will be transferred
    correctly, although arg5~arg9 may have problem.

    But in linux x64 platform, when compiled with cc(gcc's
    component), I found the first sixth parm will be
    transferred with universal registers.
    So in the above code, arg1~arg6 will be transferred
    correctly, although arg7~arg9 may have problem.

    B.
    In windows ia64 platform, when compiled with cl
    (vs2005's ia64 cross compiler)the first eight param
    will be transferred to func with universal registers,
    using mov(upper bits will be signed extended)assembly
    instruction. In this case, that is 0 extended for the
    upper bits. The other params will be put in the stack
    memory, but they will be first put to registers, and
    then stack memory.
    So in the above code, all params will be transferred
    correctly.

    So the questions is, whether I am right or not?
    May I rely on the knowledge of intermediate assembly
    code, and just modify the code as follows for windows
    x64??????
    ==================================================
    #undef NULL
    #define NULL 0
    void main() {
    func(NULL,NULL,NULL,NULL,(char*)NULL,
    (char*)NULL,(char*)NULL,(char*)NULL,(char*)NULL);
    }
    void func(char *arg1, char *arg2, char *arg3,
    char *arg4, char *arg5, char *arg6,
    char *arg7, char *arg8, char *arg9)
    {
    //
    }
    ==================================================

    Another questions is that, why linux x64 put the first
    six params to registers while windows x64 put the first
    four params to registers????
    The hardware(cpu especially) is the same, so why shouldn't
    the calling conventions is the same????

    --the end--

    srimksJuly 2, 2009 11:03 AM PDT
    Rate
     
    Re: x64/ia64 Assemly Instructions in Code Porting

    Quoting - gangti
    refer to:
    http://software.intel.com/en-us/articles/use-explicit-prototyping/#comment-26974

    May someone give an answer???

    Contents:
    file.c
    ==================================================
    #undef NULL
    #define NULL 0
    void main() {
    func(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
    }
    void func(char *arg1, char *arg2, char *arg3,
    char *arg4, char *arg5, char *arg6,
    char *arg7, char *arg8, char *arg9)
    {
    //
    }
    ==================================================

    When I port above code from x86 to x64/ia64, I found:
    A.
    In windows x64 platform, when compiled with cl
    (vs2005's x64 cross compiler)the first four param
    will be transferred to func with universal registers,
    using mov(same as movzx) assembly instructions, so
    the upper 32 bits will be zeroed.
    So in the above code, arg1~arg4 will be transferred
    correctly, although arg5~arg9 may have problem.

    But in linux x64 platform, when compiled with cc(gcc's
    component), I found the first sixth parm will be
    transferred with universal registers.
    So in the above code, arg1~arg6 will be transferred
    correctly, although arg7~arg9 may have problem.

    B.
    In windows ia64 platform, when compiled with cl
    (vs2005's ia64 cross compiler)the first eight param
    will be transferred to func with universal registers,
    using mov(upper bits will be signed extended)assembly
    instruction. In this case, that is 0 extended for the
    upper bits. The other params will be put in the stack
    memory, but they will be first put to registers, and
    then stack memory.
    So in the above code, all params will be transferred
    correctly.

    So the questions is, whether I am right or not?
    May I rely on the knowledge of intermediate assembly
    code, and just modify the code as follows for windows
    x64??????
    ==================================================
    #undef NULL
    #define NULL 0
    void main() {
    func(NULL,NULL,NULL,NULL,(char*)NULL,
    (char*)NULL,(char*)NULL,(char*)NULL,(char*)NULL);
    }
    void func(char *arg1, char *arg2, char *arg3,
    char *arg4, char *arg5, char *arg6,
    char *arg7, char *arg8, char *arg9)
    {
    //
    }
    ==================================================

    Another questions is that, why linux x64 put the first
    six params to registers while windows x64 put the first
    four params to registers????
    The hardware(cpu especially) is the same, so why shouldn't
    the calling conventions is the same????

    --the end--

    Ans.[A]: The calling convention for 64-bit Windows is - the first parameter is transferred in RCX if it is an integer or in XMM0 if it is a float or double, second in RDX or XMM1, third in RB or XMM2 and fourth in R9 or in XMM9. No more than 4 parameters can be transferred in registers, ragardless of types. Any further parameters are transferred on the stack with the first parameter at the lowest address & aligned by 8.
                                                                           While in Linux, first six parameters are transferred in RDI, RSI, RDX, RCX, R8 & R9 resp.. The first 8 floating-point parameters are transferred in XMM0 - XMM7. All these registers can be used, so in maximum fourteen parameters can be transferred in registers. Any further parameters are transferred in stack with first parameter at the lowest address and aligned by 8.

    Note that 64-bit Linux does not use the same registers for parameters transfer as done by 64-bit Windows. Also, for 64-bit, the calling save status registers for Windows(SI, RDI, XMM6 - XMM15) are different form Linux which means that calling conventions are different for Windows and Linux for 64-bit.

    All compilers for 64-bit Windows use the COFF/PE32+ format, while compilers for Linux use ELF64 format.

    HIH.

    ~BR
    Mukkaysh Srivastav

    gangtiJuly 2, 2009 8:52 PM PDT
    Rate
     
    Re: x64/ia64 Assemly Instructions in Code Porting

    Quoting - srimks

    Ans.[A]: The calling convention for 64-bit Windows is - the first parameter is transferred in RCX if it is an integer or in XMM0 if it is a float or double, second in RDX or XMM1, third in RB or XMM2 and fourth in R9 or in XMM9. No more than 4 parameters can be transferred in registers, ragardless of types. Any further parameters are transferred on the stack with the first parameter at the lowest address & aligned by 8.
                                                                           While in Linux, first six parameters are transferred in RDI, RSI, RDX, RCX, R8 & R9 resp.. The first 8 floating-point parameters are transferred in XMM0 - XMM7. All these registers can be used, so in maximum fourteen parameters can be transferred in registers. Any further parameters are transferred in stack with first parameter at the lowest address and aligned by 8.

    Note that 64-bit Linux does not use the same registers for parameters transfer as done by 64-bit Windows. Also, for 64-bit, the calling save status registers for Windows(SI, RDI, XMM6 - XMM15) are different form Linux which means that calling conventions are different for Windows and Linux for 64-bit.

    All compilers for 64-bit Windows use the COFF/PE32+ format, while compilers for Linux use ELF64 format.

    HIH.

    ~BR
    Mukkaysh Srivastav

    I appreciate you answer of my question, and the whole knowledge of calling conventions.

    My problem is that I just want to modify the arguments from 5 to 9 as following
    code shows, for windows x64. Am I right or not?
    I want to get an official answer from intel to persuade my boss. So I am looking
    forward to you reply...
    ==================================================
    #undef NULL
    #define NULL 0
    void main() {
    func(NULL,NULL,NULL,NULL,(char*)NULL,
    (char*)NULL,(char*)NULL,(char*)NULL,(char*)NULL);
    }
    void func(char *arg1, char *arg2, char *arg3,
    char *arg4, char *arg5, char *arg6,
    char *arg7, char *arg8, char *arg9)
    {
    //
    }
    ==================================================

    Though another way to approach this is to give an explictit prototype, I give the
    above approach first. It's a pity that  I cannot change the approach now.

    jimdempseyatthecoveJuly 6, 2009 8:42 AM PDT
    Rate
     
    Re: x64/ia64 Assemly Instructions in Code Porting


    Use function prototype

    #undef NULL
    #define NULL 0
    // declare forward reference to function func
    void func(char *arg1, char *arg2, char *arg3, 
    char *arg4, char *arg5, char *arg6, 
    char *arg7, char *arg8, char *arg9);
    
    void main() {
      func(NULL,NULL,NULL,NULL,NULL,
      NULL,NULL,NULL,NULL);
    }
    
    void func(char *arg1, char *arg2, char *arg3, 
    char *arg4, char *arg5, char *arg6, 
    char *arg7, char *arg8, char *arg9)
    {
    //
    }
    


    Blog: The Parallel Void
    www.quickthreadprogramming.com

Forum jump:  

Intel Software Network Forums Statistics

17,025 users have contributed to 48,319 threads and 172,758 posts to date.

In the past 24 hours, we have 11 new thread(s) 54 new posts(s), and 47 new user(s).

In the past 3 days, the most popular thread for everyone has been Optimalization of sine function\'s taylor expansion The most posts were made to Most likely, the issue is that The post with the most views is Optimalization of sine function\'s taylor expansion

Please welcome our newest member redfruit83


For more complete information about compiler optimizations, see our Optimization Notice.