access-softek / llvm-project

Other
0 stars 0 forks source link

GCC passes and returns complex numbers in registers #2

Closed chbessonova closed 11 months ago

chbessonova commented 5 years ago

I noticed that GCC passes and returns complex numbers (complex.h) in registers while user-defined structures, even contain 2 floats are still passed and returned by reference.

#include <complex.h>

struct s { float a[2]; };

void f1(struct s S); 
void f2(float complex C); 

extern struct s SS; 
extern float complex CC; 

int main() {
  f1(SS);
  f2(CC);
}
main:
    MOV.W   #SS, R12
    CALL    #f1
    MOV.W   &CC, R12
    MOV.W   &CC+2, R13
    MOV.W   &CC+4, R14
    MOV.W   &CC+6, R15
    CALL    #f2
    MOV.B   #0, R12

TI CCS passes everything by reference:

main:
        MOV.W     #SS+0,r12
        CALL      #f1 
        MOV.W     #CC+0,r12  
        CALL      #f2  
        MOV.W     #0,r12 
        RET      
atrosinenko commented 4 years ago

The 67422e4294754e08f277b1ba22820487eb76b918 commit is expected to make sure _Complex types are laid out identically by both gcc and clang.

Hmm, now for the test.c with -Os optimization level, clang generates (R1 == SP)

main: 
        sub     #8, r1
        mov     &SS+6, 6(r1)
        mov     &SS+4, 4(r1)
        mov     &SS+2, 2(r1)
        mov     &SS, 0(r1)
        call    #f1
        mov     &CC+6, r15
        mov     &CC+4, r14
        mov     &CC+2, r13
        mov     &CC, r12
        call    #f2
        clr     r12
        add     #8, r1
        ret

And gcc generates

main:
        MOV.W   #SS, R12
        CALL    #f1
        MOV.W   &CC, R12
        MOV.W   &CC+2, R13
        MOV.W   &CC+4, R14
        MOV.W   &CC+6, R15
        CALL    #f2
        MOV.B   #0, R12
        RET

So it seems there is no difference for f2 but something strange is generated for f1 and needs further investigation.