[질문] SuperH 함수 호출 규약 관련 질문입니다...

freemckang의 이미지

어쩌다가 sh4 core로 project를 진행하게 되었는데, sh4_abi를 살펴보니 함수 호출 규약이 다음과 같이 되어 있습니다. 컴파일러는 sh4-superh-elf-gcc를 사용하구요...

R0 to R3 : Return value, caller save
R2 : Larget struct return address, caller save
R4 to R7 : Parameter passing, caller save
R8 to R13 : Callee save
R12 : Global context pointer, GP, callee save
R13 : Callee save
R14 : Frame pointer, FP, callee save
R15 : Stack pointer, SP, callee save
...
GBR : Reserved

여기서 궁금한 것은

1. 함수 호출로 4개의 register를 써야 하는 일이 있는지??

음... ST40 core 문서를 보면, ST40 core에서 다루는 최대 크기의 자료형은 Quad-word (64bit)입니다. 그럼 끽해야 register를 2개 사용할텐데 4개나 할당한 이유는 무엇일까요?

간단한 예제로 테스트해봤습니다.

long long test_sum (int a, int b)
{
    long long ret;
 
    ret = a + b;
 
    return ret;
}
 
int main (void)
{
    int a, b;
    int ret;
 
    a = 1;
    b = 2;
    ret = test_sum (a, b);
 
    return ret;
}

이것의 ASM code를 살펴보니... 실컷 연산하고 다음과 같은 작업을 하게 됩니다

...
    mov   r1,r0
    mov   r2,r1
    add   #16,r14
    mov   r14,r15
    mov.l @r15+,r14
    rts
    nop
...

즉, long long을 return할 때 register 2개를 쓰는 것이 확인된 것으로 보입니다... 그런데.. 4개는 언제 써야 할지??? 그래서 좀 다른 방법으로 테스트를 해보았습니다.

typedef struct
{
    int a;
    int b;
    int c;
    int d;
} test_st;
 
test_st test_sum (test_st temp)
{
    temp.c = temp.a + temp.b;
    temp.d = temp.a - temp.b;
 
    return temp;
}
 
int main (void)
{
    test_st temp;
 
    temp.a = 1;
    temp.b = 2;
    temp = test_sum (temp);
 
    return 0;
}

structure 크기가 정확히 4개의 register에 들어가는 값이므로 인자 전달은 stack이 아니라 r4, r5, r6, r7로 전달이 됩니다.

...
    mov.l @r1,r4
    mov.l @(4,r1),r5
    mov.l @(8,r1),r6
    mov.l @(12,r1),r7
    mov.l .L5,r1
    jsr   @1
...

그런데 리턴하는 함수에서는 stack을 사용하더군요... -.-

...
    mov.l r1,@r0
    mov.l r2,@(4,r0)
    ...
    mov.l r1,@(8,r0)
    mov.l r2,@(12,r0)
    mov   r14,r15
    mov.l @r15+,r14
    rts
    nop
...

2. r2의 경우 Large struct return address라고 되어 있어서, 두번째 예제의 structure 에 멤버를 몇개 더해서 했는데 여전히 r0를 사용하더군요. r2는 도대체 언제 쓰게 되는 것인지??

3. GP (Global context pointer)가 가리키는 값은 무엇인지???

SuperH 경험자 분들의 조언 부탁드립니다...

새해 복 많이 받으세요 (--)(__)

freemckang의 이미지

sh4_abi를 좀 더 읽어보니 _Complex double이라는 16bytes짜리 data type에 대한 이야기가 나오고, FPU를 사용하면 FPU 전용 register (FRx)를 사용하지만 컴파일 옵션 시 nofpu가 들어가게 되면 r0~r3를 사용해서 표현하네요. 역시 정답은 매뉴얼이군요... -.-

句日新, 日新 日新 又日新.

句日新, 日新 日新 又日新.