# ARMv9 CPU 문서·Toolchain·Linux 실전

v6.18.37 / arch/arm64/kernel/cpufeature.c

컴파일 옵션은 어떤 명령을 만들어도 되는지를 정하지만 실제 실행 가능성을 대신 확인하지는 않습니다. 아래에서는 Linux v6.18.37가 HWCAP 비트를 보관하고 조회하는 경로를 읽습니다. 컴파일러 타깃 선택과 런타임 기능 분기를 서로 다른 단계로 설명하기 위한 예입니다.

## cpu_set_feature / cpu_have_feature / cpu_get_elf_hwcap

```c

void cpu_set_feature(unsigned int num)
{
	set_bit(num, elf_hwcap);
}

bool cpu_have_feature(unsigned int num)
{
	return test_bit(num, elf_hwcap);
}
EXPORT_SYMBOL_GPL(cpu_have_feature);

unsigned long cpu_get_elf_hwcap(void)
{
	/*
	 * We currently only populate the first 32 bits of AT_HWCAP. Please
	 * note that for userspace compatibility we guarantee that bits 62
	 * and 63 will always be returned as 0.
	 */
	return elf_hwcap[0];
}

```

### 3781행

```c

void cpu_set_feature(unsigned int num)

```

커널의 사용자 기능 비트 집합에 특정 기능 번호를 등록하는 함수입니다. 기능 판별 자체는 이 함수를 부르는 경로에서 이루어집니다.

### 3783행

```c

	set_bit(num, elf_hwcap);

```

elf_hwcap 비트 배열에서 num 위치를 1로 만듭니다. num을 하드웨어 시스템 레지스터 주소로 사용하는 것이 아닙니다.

### 3786행

```c

bool cpu_have_feature(unsigned int num)

```

이미 등록한 기능 비트를 조회하는 커널 내부 함수를 선언합니다.

### 3788행

```c

	return test_bit(num, elf_hwcap);

```

해당 비트의 참·거짓을 돌려줍니다. 이 조회는 실행 시마다 모든 CPU의 ID 레지스터를 새로 검사하는 동작이 아닙니다.

### 3790행

```c

EXPORT_SYMBOL_GPL(cpu_have_feature);

```

GPL 모듈에서 cpu_have_feature 기호를 사용할 수 있도록 내보냅니다. CPU가 수행하는 일반 함수 호출은 아닙니다.

### 3792행

```c

unsigned long cpu_get_elf_hwcap(void)

```

첫 번째 ELF HWCAP 묶음을 반환하는 함수입니다. 사용자 보조 벡터에 공개하는 경로와 연결됩니다.

### 3799행

```c

	return elf_hwcap[0];

```

내부 비트 배열의 첫 unsigned long 값을 반환합니다. 두 번째·세 번째 묶음은 별도의 helper가 담당합니다.

