Skip to content
  • Chris Lattner's avatar
    Implement an annoying part of the Darwin/X86 abi: the callee of a struct · 8be5be81
    Chris Lattner authored
    return argument pops the hidden struct pointer if present, not the caller.
    
    For example, in this testcase:
    
    struct X { int D, E, F, G; };
    struct X bar() {
      struct X a;
      a.D = 0;
      a.E = 1;
      a.F = 2;
      a.G = 3;
      return a;
    }
    void foo(struct X *P) {
      *P = bar();
    }
    
    We used to emit:
    
    _foo:
            subl $28, %esp
            movl 32(%esp), %eax
            movl %eax, (%esp)
            call _bar
            addl $28, %esp
            ret
    _bar:
            movl 4(%esp), %eax
            movl $0, (%eax)
            movl $1, 4(%eax)
            movl $2, 8(%eax)
            movl $3, 12(%eax)
            ret
    
    This is correct on Linux/X86 but not Darwin/X86.  With this patch, we now
    emit:
    
    _foo:
            subl $28, %esp
            movl 32(%esp), %eax
            movl %eax, (%esp)
            call _bar
    ***     addl $24, %esp
            ret
    _bar:
            movl 4(%esp), %eax
            movl $0, (%eax)
            movl $1, 4(%eax)
            movl $2, 8(%eax)
            movl $3, 12(%eax)
    ***     ret $4
    
    For the record, GCC emits (which is functionally equivalent to our new code):
    
    _bar:
            movl    4(%esp), %eax
            movl    $3, 12(%eax)
            movl    $2, 8(%eax)
            movl    $1, 4(%eax)
            movl    $0, (%eax)
            ret     $4
    _foo:
            pushl   %esi
            subl    $40, %esp
            movl    48(%esp), %esi
            leal    16(%esp), %eax
            movl    %eax, (%esp)
            call    _bar
            subl    $4, %esp
            movl    16(%esp), %eax
            movl    %eax, (%esi)
            movl    20(%esp), %eax
            movl    %eax, 4(%esi)
            movl    24(%esp), %eax
            movl    %eax, 8(%esi)
            movl    28(%esp), %eax
            movl    %eax, 12(%esi)
            addl    $40, %esp
            popl    %esi
            ret
    
    This fixes SingleSource/Benchmarks/CoyoteBench/fftbench with LLC and the
    JIT, and fixes the X86-backend portion of PR729.  The CBE still needs to
    be updated.
    
    llvm-svn: 28438
    8be5be81
Loading