CSINC, CSINV, CSNEG
Example
- CSINC, CSINV, CSNEG는 모두 동일한 부모(CSEL)에게서 나온 자식들이라 맥락과 문법이 100% 일치합니다.
- 이 세 친구의 공통된 미션은 하나입니다.
- “조건이 맞으면 첫 번째 값을 고르고
- 조건이 틀리면 두 번째 값을 그냥 고르는 게 아니라 ‘살짝 양념(연산)’을 쳐서 가져와라!”
⚙️ 3대 형제 명령어의 공통 구조
세 명령어 모두 문법 구조가 쌍둥이처럼 똑같습니다.
CSxxx
- 참(True)일 때: 무조건 첫 번째 레지스터인
을 선택해 목적지( )에 넣습니다. - 거짓(False)일 때: 두 번째 레지스터인
을 그냥 가져오지 않고, 자기만의 특기(연산)를 발휘해서 가공한 뒤 목적지에 넣습니다.
CSINC
Conditional Select Increment (조건부 선택 후 1 증가)
- 거짓일 때 양념: 두 번째 값에 +1을 해서 가져옵니다.
- 동작: 조건이 참이면 Xd = Xn, 거짓이면 Xd = Xm + 1
💡 언제 쓰나요? (루프 카운터나 조건부 누적)
우리가 코딩할 때 “조건이 맞으면 카운트를 유지하고, 틀리면 카운트를 1 증가시켜라” 같은 로직을 짤 때 아주 유용합니다.
// C언어 예시if (is_valid) { status = baseline; } else { status = current_index + 1; }
; ARM64 어셈블리 최적화 CMP W0, #1 CSINC W2, W3, W4, EQ ; EQ(같다)가 참이면 W3을 W2에 넣고, 거짓이면 W4에 1을 더해서 W2에 넣어라!
- 비밀 하나 더! 지난번에 배운 CSET W0, EQ는 내부적으로 CSINC W0, WZR, WZR, EQ로 실행된다고 했었죠? 조건이 거짓일 때 항상 0인 WZR에 +1을 해서 1을 만들어내는 마법이 바로 이 CSINC 덕분이었습니다.
CSINV
Conditional Select Invert (조건부 선택 후 비트 반전)
- 거짓일 때 양념: 두 번째 값의 모든 비트를 뒤집어서(NOT 연산, ~) 가져옵니다.
- 동작: 조건이 참이면 Xd = Xn, 거짓이면 Xd = ~Xm
💡 언제 쓰나요? (비트 마스크 반전 및 보수 연산)
특정 조건에 따라 비트 패턴을 완전히 뒤집어 필터링 영역을 전환할 때 사용합니다.
// C언어 예시
if (flag == 0) {
mask = original_mask;
} else {
mask = ~original_mask; // 비트 뒤집기 (0은 1로, 1은 0으로)
}
// ARM64 어셈블리 최적화
CMP W0, #0
CSINV W1, W2, W2, EQ // EQ가 참이면 W2를 그대로 W1에 넣고, 거짓이면 W2를 NOT 비트 반전시켜 W1에 넣어라!
- 비밀 하나 더! 참일 때 마스크(0xFFFFFFFF)를 만들던 CSETM이 바로 이 CSINV를 빌려서 만들어진 별칭 명령어였습니다.
CSNEG
Conditional Select Negate (조건부 선택 후 부호 반전)
- 거짓일 때 양념: 두 번째 값에 마이너스 부호(-)를 붙여서 가져옵니다. (2의 보수 연산)
- 동작: 조건이 참이면 Xd = Xn, 거짓이면 Xd = -Xm
💡 언제 쓰나요? (조건에 따른 양수/음수 전환)
수학 연산에서 조건에 따라 방향성을 바꾸거나 부호를 결정해야 할 때 맹활약합니다.
// C언어 예시if (direction == UP) { step = velocity; } else { step = -velocity; // 반대 방향으로 전환 }
; ARM64 어셈블리 최적화 CMP W0, #1 ; UP 방향인지 비교 CSNEG W1, W2, W2, EQ ; 참이면 속도(W2) 그대로 W1에 저장, 거짓이면 마이너스 속도(-W2)로 만들어 W1에 저장!
🎨 한눈에 보는 CSEL 가문 3대 병기 요약 판넬
친구야, 한눈에 쏙 들어오게 표로 직관적으로 묶어 드릴게요! 다시 봐도 정말 아름다운 규칙성입니다.
| 니모닉 | 이름 | 조건이 참(True)일 때 | 조건이 거짓(False)일 때 (양념) | 파생된 짝꿍 명령어 |
|---|---|---|---|---|
| CSINC | Select Increment | Xn 그대로 선택 | Xm + 1 (1 더하기) | CSET (참이면 1, 거짓이면 0) |
| CSINV | Select Invert | Xn 그대로 선택 | ~Xm (비트 반전 NOT) | CSETM (참이면 -1, 거짓이면 0) |
| CSNEG | Select Negate | Xn 그대로 선택 | -Xm (부호 반전 Minus) | CNEG (조건부 부호 반전) |
하하하, 이제 CSEL 계열의 “참/거짓 양 갈래 길 최적화” 메커니즘은 그 누구보다 완벽하게 지도를 그리실 수 있게 되었습니다. 점프(Branch) 명령어 없이 하드웨어를 한 줄로 직진시키는 이 설계의 매력에 푹 빠지셨을 것 같네요! 어셈블리어 조건부 명령어의 거대한 산맥을 드디어 다 넘으셨습니다! 고생하셨어요 친구야. 하하하. 혹시 이 흐름을 이어서 컴퓨터가 덧셈/뺄셈을 할 때 플래그를 바꾸는 내부 원리(진법 연산)를 파헤쳐 볼까요, 아니면 완전히 새로운 메모리 읽고 쓰기(LDR, STR) 영역으로 넘어가 볼까요?