Cortex-M 프로세서에서의 Floating Point Fun
핵심 내용
Cortex-M의 soft, softfp, hard ABI 차이와 Zephyr 설정을 설명한다.
자세히 보기
Arm Cortex-M에서 floating point ABI가 어떻게 다른지, 그리고 soft, softfp, hard가 링커 에러와 실행 코드에 어떤 영향을 주는지 정리한다.
soft는 FPU 없이 동작하며 floating-point 연산을 런타임 라이브러리로 에뮬레이션한다. 인자는 r0-r3 같은 GPR로 전달된다.
softfp는 FPU 명령은 사용할 수 있지만 호출 규약은 soft와 같아서, 인자는 여전히 GPR로 전달된다. 따라서 하드웨어 FPU를 쓰면서도 소프트 호출 규약과 호환된다.
hard는 FPU 레지스터를 인자 전달에도 사용한다. Armv7-M 계열에서는 s0-s15가 인자 전달에 활용되며, FPU 전용 calling convention을 사용한다.
이 차이 때문에 ld.bfd: error: X uses VFP register arguments, Y does not 같은 에러가 발생한다. 링커는 오브젝트 파일의 Arm attributes를 보고 ABI가 섞였는지 판단한다.
nRF52840 예시에서는 readelf로 확인한 attribute가 ABI별로 다르게 나타난다.
- hard:
Tag_ABI_VFP_args: VFP registers - softfp: floating point 명령은 허용되지만 인자 전달은 GPR 기반
- soft: FPU 호출 규약 없이 소프트웨어 연산 중심
간단한 float addf(float a, float b) 예제로도 차이가 분명하다.
- soft 빌드:
__addsf3를 호출해 소프트웨어로 덧셈 수행 - hard 빌드:
s0,s1에 인자를 받고vadd.f32를 사용 - softfp 빌드: GPR로 인자를 받지만 내부에서는
vadd.f32를 사용
Zephyr에서는 CONFIG_FPU=y로 FPU를 활성화하면 기본적으로 hard ABI가 사용된다. 반대로 CONFIG_FP_SOFTABI=y를 선택하면 softfp가 된다. west -v build로 실제 컴파일 플래그의 -mfloat-abi 값을 확인할 수 있다.
또한 CONFIG_FPU는 ABI 선택만이 아니라 부팅 시 FPU 활성화에도 관여한다. z_prep_c()에서 z_arm_floating_point_init()가 호출되고, 여기서 CPACR, FPCCR, FPSCR가 설정된다.
핵심은 다음과 같다.
- FPU가 있어도 기본 설정은 소프트 ABI일 수 있다
- 서로 다른 ABI의 오브젝트를 섞으면 링커가 거부한다
- Zephyr에서는 보드 설정과 Kconfig가 ABI와 FPU 활성화를 함께 결정한다
이 한국어 요약은 AI가 자동으로 만들었습니다. 원문의 주장과 맥락은 원문에서 확인해 주세요. 저작권은 원저작자에게 있습니다.