[질문] SuperH 함수 호출 규약 관련 질문입니다...
어쩌다가 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 경험자 분들의 조언 부탁드립니다...
새해 복 많이 받으세요 (--)(__)
1번 자답입니다.
sh4_abi를 좀 더 읽어보니 _Complex double이라는 16bytes짜리 data type에 대한 이야기가 나오고, FPU를 사용하면 FPU 전용 register (FRx)를 사용하지만 컴파일 옵션 시 nofpu가 들어가게 되면 r0~r3를 사용해서 표현하네요. 역시 정답은 매뉴얼이군요... -.-
句日新, 日新 日新 又日新.
句日新, 日新 日新 又日新.
댓글 달기