Skip to the content.

SXTW / SXTL 명령어 — 부호 확장(Sign Extend) 계열

분류 안내: 두 명령어는 서로 다른 그룹임.


SXTW

Sign Extend Word — 스칼라

정의: 32비트 값을 부호를 유지하며 64비트로 확장하는 명령어. 하위 32비트(word)의 최상위 비트(부호 비트)를 상위 32비트 전체에 복제(replicate)함.

문법:

SXTW Xd, Wn

동작 원리:

Wn = 0x80000001 (32비트, signed로는 -2147483647)

SXTW 적용 후:
Xd = 0xFFFFFFFF80000001  (상위 32비트가 전부 1로 채워짐, 부호 유지)

예시:

mov w0, #-5              // w0 = 0xFFFFFFFB (32비트 -5)
sxtw x1, w0                 // x1 = 0xFFFFFFFFFFFFFFFB (64비트 -5로 정확히 확장)

대비 — UXTW(부호 없는 버전)와의 차이:

mov w0, #-5
sxtw x1, w0     // x1 = 0xFFFFFFFFFFFFFFFB  (signed 확장, -5 유지)
uxtw x1, w0     // x1 = 0x00000000FFFFFFFB  (unsigned 확장, 상위 0으로 채움 — 완전히 다른 값)

실전 등장 배경 — 왜 자주 보이는가: 32비트 int 타입을 64비트 포인터 연산(배열 인덱싱, 주소 계산)에 사용할 때 필수적으로 등장함.

// C 코드
int idx = -1;
array[idx]   // idx가 음수일 때, 64비트 주소 계산 시 부호 유지 필수
sxtw x1, w0            // idx(32비트 int)를 64비트로 부호 확장
add  x2, x3, x1, lsl #2  // base + (idx × 4), 배열 주소 계산

주의할 함정: 만약 SXTW 대신 UXTW를 잘못 사용하면, 음수 인덱스가 거대한 양수로 왜곡되어 배열 범위를 벗어난 메모리 접근(버그, 크래시, 보안 취약점)으로 이어질 수 있음. 32비트 int → 64비트 포인터 연산에서 부호 확장 방식 선택은 매우 중요한 포인트임.


SXTB_SXTH

SXTW의 형제 명령어

동일 계열: SXTW는 사실 “32비트 → 64비트” 확장이고, 더 작은 크기의 확장도 존재함.

니모닉 원본 크기 대상 크기 용도
SXTB 8비트 (byte) 32/64비트 signed char → int/long 확장
SXTH 16비트 (halfword) 32/64비트 signed short → int/long 확장
SXTW 32비트 (word) 64비트 signed int → long 확장
sxtb x0, w1     // 하위 8비트를 부호 확장하여 64비트로
sxth x0, w1     // 하위 16비트를 부호 확장하여 64비트로
sxtw x0, w1     // 하위 32비트를 부호 확장하여 64비트로

대응 unsigned 계열도 존재: UXTB, UXTH, UXTW (단, UXTW는 실제로는 MOV Wd, Wn의 별칭에 가까움 — 32비트 레지스터 쓰기 자체가 상위 32비트를 자동으로 0 클리어하는 ARM64 규칙 때문).


Extended Register 형태 — 단독보다 결합형이 더 자주 관찰됨

이전 ASR/LSL 문서에서 다룬 패턴과 동일: SXTW/UXTW 등도 다른 명령어의 extend operand로 결합되어 훨씬 자주 등장함.

add x0, x1, w2, sxtw          // w2를 부호확장 후 x1에 더함
add x0, x1, w2, sxtw #2         // 부호확장 + 시프트(주소 계산) 결합
ldr x0, [x1, w2, sxtw #3]        // 배열 인덱싱: base + (int idx × 8), signed

실전 최다 활용 사례 — 64비트 배열/포인터 연산에서의 32비트 인덱스 처리:

// C 코드: long array[]; int i; array[i]
// x0 = base address, w1 = int index (32비트)
ldr x2, [x0, w1, sxtw #3]     // base + (i × 8), i의 부호를 유지하며 64비트로 확장 후 접근

이 패턴은 64비트 macOS/iOS 앱에서 int 인덱스로 long/포인터 배열에 접근하는 거의 모든 코드에서 컴파일러가 자동 생성하는 최다 빈출 패턴 중 하나임.


SXTL

Signed Extend Long — NEON 벡터 전용

정의: NEON 벡터 레지스터의 하위 절반 레인(lane)들을 부호 유지하며 두 배 크기로 확장하는 명령어. 스칼라의 SXTW와 개념은 같으나 벡터 전체 레인에 동시 적용된다는 점이 다름.

전제: SIMD/NEON 벡터 레지스터(V레지스터) 전용이며, 정수 벡터 연산에서 오버플로우 없이 정밀도를 확보하기 위해 사용됨.

문법:

SXTL Vd.8H, Vn.8B      // 8× 8비트 → 8× 16비트 확장
SXTL Vd.4S, Vn.4H      // 4× 16비트 → 4× 32비트 확장
SXTL Vd.2D, Vn.2S      // 2× 32비트 → 2× 64비트 확장

동작 원리: 소스 벡터의 하위 절반 레인만 사용하여, 각 레인을 부호 확장한 뒤 목적 벡터에 두 배 크기로 저장함.

예시:

// v0 = 8개의 8비트 signed 값 (예: -1, 2, -3, 4, ...)
sxtl v1.8h, v0.8b      // 각 8비트 값을 16비트로 부호 확장, v1에 저장

SXTL2 — 상위 절반 버전: 벡터가 128비트(16바이트) 전체를 활용하는 경우, 하위 절반은 SXTL, 상위 절반SXTL2로 처리함.

sxtl  v1.8h, v0.8b     // v0의 하위 8바이트 레인을 16비트로 확장
sxtl2 v2.8h, v0.16b     // v0의 상위 8바이트 레인을 16비트로 확장

실전 활용: 오디오/이미지 처리에서 8비트 픽셀 데이터를 16비트 연산으로 승격시켜 오버플로우 없이 필터링·블렌딩할 때, 또는 신호 처리 알고리즘에서 정밀도를 확보하기 위한 중간 단계로 사용됨. 일반 스칼라 애플리케이션 코드보다는 벡터화된 미디어 처리 라이브러리(Accelerate framework, vImage 등) 내부 구현에서 관찰됨.

대응 UXTL(unsigned 버전)도 동일 구조로 존재:

UXTL Vd.8H, Vn.8B     // unsigned 확장, 부호 무시하고 상위 0으로 채움

종합 정리표

명령어 분류 원본→대상 부호 처리 용도
SXTB 스칼라 8→32/64비트 부호 유지 signed char 확장
SXTH 스칼라 16→32/64비트 부호 유지 signed short 확장
SXTW 스칼라 32→64비트 부호 유지 signed int → 포인터 연산 (최다 빈출)
UXTW 스칼라 32→64비트 0으로 채움 unsigned int → 포인터 연산
SXTL NEON 벡터 N→2N비트 (하위 레인) 부호 유지 벡터 정밀도 확장 (신호/이미지 처리)
SXTL2 NEON 벡터 N→2N비트 (상위 레인) 부호 유지 SXTL의 상위 절반 버전
UXTL / UXTL2 NEON 벡터 N→2N비트 0으로 채움 unsigned 벡터 확장

핵심 요약

두 명령어의 본질적 구분: SXTW는 “스칼라 정수 하나를 부호 유지하며 넓히는” 매우 흔한 스칼라 명령어이고(특히 배열 인덱싱에서 최다 빈출), SXTL은 “벡터의 여러 레인을 동시에 부호 유지하며 넓히는” NEON 전용 명령어(미디어/신호 처리 라이브러리 내부에서 주로 관찰)임. AESE/AESD 와 마찬가지로, SXTL은 일반 애플리케이션 코드보다는 최적화된 SIMD 루틴 내부에서 마주치게 되는 명령어라는 공통점이 있음.