[컴퓨터구조] Ch7-3. CA_Instruction(v6)

김규원·2024년 6월 7일

24-1: 컴퓨터구조(完)

목록 보기
10/15
post-thumbnail

Additional Instruction (Arm)

  • ARM 아키텍처 버전 6에는 총 81개의 새로운 명령어가 포함
  • 여러 가지 추가적인 명령어 클래스가 도입
  1. 패킹된 데이터
  2. 더 많은 포화 산술 연산
  3. SIMD(Single Instruction Multiple Data, 단일 명령어 다중 데이터) 지원
  4. 혼합 엔디안 지원
    : 데이터를 저장하거나 전송할 때 바이트 순서가 서로 다른 엔디안 형식을 혼합하여 사용하는 것을 의미
    : 혼합 엔디안 시스템은 데이터를 저장하거나 전송할 때 두 형식(빅엔디안/스몰엔디안)을 혼합하여 사용 가능
  5. "Sum Absolute Difference" 작업
  • 이전 명령어 집합 확장과는 달리 (예: BLX 오프셋), ARMv6 확장 명령어는 주로 조건부
    : 두 개의 벡터나 배열 사이의 절대 차이를 모두 더하는 작업을 수행하는 연산

요약

ARM 아키텍처 버전 6에서는 이전에 비해 다양한 새로운 명령어들과 명령어 클래스들이 도입되었으며, 대부분의 명령어들이 조건부로 사용

Arithmetic extensions(v6, 산술확장)

  • 기존의 MUL(곱셈) 및 MLA(곱셈 누산) 명령어에 대한 확장 존재
  • UMAAL, SMMUL, SMMLA, SMMLS와 같은 새로운 명령어 추가

혼합 길이 덧셈

UXTAH(Unsigned eXtract and Add Halfword)

  • 32비트 레지스터에 half word를 추출하고, 이를 부호 없는 정수로 간주하여 해당 값을 32비트 레지스터에 더함.
  • 즉, 32비트 레지스터에서 하위 16비트인 절반 워드를 추출하여 부호 없는 정수로 처리하고, 이를 32비트 레지스터에 더하는데 사용
; r0 = 0x12345678 가정.

UXTAH r1, r0
; r0의 하위 반워드(0x5678)를 추출하여 부호 없는 정수로 간주하고, r1에 더함.

; 실행 후 r1 레지스터에 저장되는 값
; r1 = 0x00005678

UXTAB(Unsigned eXtract and Add Byte)

: 32비트 레지스터에 바이트를 추출하여 더하는데 사용

; r0 = 0x12345678 가정.

UXTAB r1, r0
; r0의 하위 바이트(0x78)를 추출하여 부호 없는 정수로 간주하고, r1에 더함.

; 실행 후 r1 레지스터에 저장되는 값
; r1 = 0x00000078

UXTAB16(Unsigned eXtract and Add Byte to 16-bit halfword)

: 두 개의 바이트를 추출하여 각각 32비트 레지스터의 상위 및 하위 반워드에 병렬로 추가하는데 사용

r0 = 0001 0010 0011 0100 0101 0110 0111 1000
하위 16비트 = 0101 0110 0111 1000
추출된 16비트를 각각의 반워드에 병렬로 추가
r1 레지스터의 상위 반워드에는 상위 16비트가 추가되고, 하위 반워드에는 하위 16비트가 추가

포화 명령어

  • 명시된 비트 위치로 값을 포화시키는 명령어 존재(효과적으로 2의 제고벵 포화시킴)

DSP Instructions

  • DSP 명령어들은 SIMD(Single Instruction Multiple Data)
  • 이 명령어들은 word에 패킹된 8bit 혹은 16bit 크기의 데이터를 처리
  • 이 명령어들은 패킹된 구조체 타입에 더 효율적으로 접근할 수 있게 해줌.

명령어 그룹

  • Data Packing/Unpacking(데이터 패킹/언패킹)
  • Data Processing(데이터 처리)

Packed data types(패킹된 데이터 타입)

  • 바이트(8bit)나 하프워드(16bit)를 하나의 큰 데이터 단위(단어)로 묶어서 저장하는 방식
    ex1. 4개의 8비트 데이터를 하나의 32비트 단어에 저장
    ex2. 2개의 16비트 데이터를 하나의 32비트 단어에 저장
    ex3. 0x12, 0x34, 0x56, 0x78 → 0x12345678
  • 패킹된 구조체 타입에 더 효율적으로 접근
    : 패킹된 데이터는 메모리 사용을 최적화하고, 데이터 접근을 더 빠르게 할 수 있도록 도와줌.
    : 여러 픽셀 값을 하나의 단어로 저장하여 이미지 처리를 효율적으로 하기.
  • SIMD 명령어들은 패킹된 데이터에 대해 작동
    : SIMD 명령어들은 단일 명령어로 패킹된 데이터의 각 요소에 대해 동시에 연산을 수행 가능
    : 즉, 4개의 byte데이터를 동시 처리 가능
  • 데이터를 추출하고 패킹하는 명령어
  1. A, B로 구성된 32bit
    ex. 0x11112222
  2. UXTH r2, r1, ROR #16USTH r3, r1을 통해 r2와 r3에 각각 저장
  • 00001111
  • 00002222
  1. PKHBT r1, r3, r2, LSL #16을 통해 r2와 r3를 합침.

시나리오

1. 패킹된 데이터

r0 레지스터에 4개의 8bit 데이터 0x12, 0x34, 0x56, 0x78이 패킹되어 있음.
r0 = 0x12345678

2. 데이터 추출

UXTB r1, r0, #8
: r0의 두 번째 바이트를 r1에 추출
: r1에 0x34를 저장

3. 데이터 패킹

두 개의 16bit 데이터를 하나의 32bit 단어로 패킹
PKHBT r0, r1, r2
: r1의 하위 16비트와 r2의 상위 16비트를 결합하여 r0에 저장
: r1 = 0x1234r2 = 0x5678인 경우, r0=0x12345678

Example- Unpacking data

Extract halfwords from words(워드에서 halfword 추출)

Extract bytes from words(워드에서 byte 추출)

The GE Flags

  • SIMD 명령어는 GE 플래그를 사용
  1. 일반 데이터 처리 명령어는 하나의 값만 출력
  2. 그러나 덧셈/뺄셈 SIMD 명령어는 여러 값을 출력
  3. 그렇기에 PSR의 NZCVQ 플래그 사용 불가
    이유: 위 플래그는 단일 값에만 해당하기 때문
  4. 이를 보완하기 위해 PSR에 GE플래그 추가
  5. GE는 Greater than or Equal의 약자
  6. MSR/MRS 명령어를 사용하여 GE 플래그를 읽거나 쓰기 가능.

MSR/MRS

1. MSR (Move to Status Register)

  • 일반 레지스터의 값을 상태 레지스터(CPSR 또는 SPSR)로 이동시키는 명령어
    MSR CPSR, r0
    ; r0 레지스터의 값을 CPSR로 이동

2. MRS (Move from Status Register)

  • 상태 레지스터(CPSR 또는 SPSR)의 값을 일반 레지스터로 이동시키는 명령어
    MRS r0, CPSR
    ; CPSR의 값을 r0 레지스터로 이동`

Packed addition & Subtraction(패킹된 덧셈&뺄셈)

UADD8 Rd, Ra, Rb

  • 병렬 덧셈 수행 명령어
  • 위 그림은 4개의 개별적인 8bit 덧셈을 보여줌
  • 4개의 개별적인 결과가 하나의 레지스터에 패킹
  • 각 덧셈의 오버플로우는 다음 덧셈에 영향을 미치지 않음
  • 오버플로우는 GE 비트를 설정하는 데 사용
  • 16bit 버전, 부호 있는 버전 및 포화 연산 버전도 사용 가능

예시 시나리오

UADD8 r0, r1, r2

; 초기 값
; r1 = 0x11223344
; r2 = 0x55667788
UADD8 r0, r1, r2
  • 위 명령어 실행 후, 각 8비트 덧셈의 결과
  1. 첫 번째 바이트 덧셈: 0x44 + 0x88 = 0xCC(오버플로우 없음)
  2. 두 번째 바이트 덧셈: 0x33 + 0x77 = 0xAA(오버플로우 없음)
  3. 세 번째 바이트 덧셈: 0x22 + 0x66 = 0x88(오버플로우 없음)
  4. 네 번째 바이트 덧셈: 0x11 + 0x55 = 0x66(오버플로우 없음)
  • 덧셈의 결과는 하나의 32비트 레지스터에 패킹
    r0 = 0x6688AACC
  • 오버플로우가 모두 발생하지 않았으므로, GE비트는 모두 0으로 설정
    GE[3:0] = 0000

예시 시나리오(오버플로우 발생)

첫 번째 바이트 덧셈: 0xFF + 0x01 = 0x00 (오버플로우 발생)
두 번째 바이트 덧셈: 0xFF + 0x01 = 0x00 (오버플로우 발생)
세 번째 바이트 덧셈: 0xFF + 0x01 = 0x00 (오버플로우 발생)
네 번째 바이트 덧셈: 0xFF + 0x01 = 0x00 (오버플로우 발생)
이 경우, 각 덧셈에서 오버플로우가 발생했으므로, GE 비트는 모두 1로 설정
GE[3:0] = 1111

Packed addition & Subtraction(2)

  • SIMD (Single Instruction Multiple Data) 명령어 집합의 일부인 서브워드(subword) 연산에 관한 것
  • 서브워드(subword) 연산은 각 레지스터의 서브워드(subword) 단위로 병렬로 수행
  • ADD(덧셈) 및 SUB(뺄셈) 명령어가 사용 가능
  • 8비트 또는 16비트 서브워드(subword) 양을 대상으로 수행가능(아래 그림은 16bit)
  • 다양한 타입이 있으며, 명령어에 접두사를 추가하여 지정 가능
    ex. QADD16 또는 UHADD8
  • 명령어와 해당 결과에 따라 GE 비트가 설정
  1. ADD8/SUB8 명령어는 각각의 GE 비트를 개별적으로 설정
  2. ADD16/SUB16 명령어는 GE 비트 [3:2]를 한 쌍으로, [1:0]를 한 쌍으로 설정
  • ASX/SAX도 사용 가능
  • 이는 Rm의 반워드(halfword)를 반전(reverse)하고, 병렬로 쌍(pair)을 형성하여 추가 또는 뺄셈을 수행

예시 시나리오

; ASX 명령어 예시
; 초기 값 설정
; r0 = 0x12345678
; r1 = 0x87654321
ASX r2, r0, r1 
; r0와 r1의 반워드를 반전하고 덧셈을 병렬로 수행하여 결과를 r2에 저장
  • r0의 반워드

    상위 반워드: 0x1234
    하위 반워드: 0x5678
  • r1의 반워드

    상위 반워드: 0x8765
    하위 반워드: 0x4321

각 반워드의 비트 순서를 반전시킨 후 덧셈을 수행

  • 상위 반워드의 덧셈
    : 0x4321 + 0x5678 = 0x9999
  • 하위 반워드의 덧셈
    : 0x8765 + 0x1234 = 0x9999
    결론적으로
    r2 레지스터: 0x99999999

Byte Selection

SEL

SEL Rd, Rn, Rm

  • 두 피연산자 간의 비교를 수행하고 결과의 각 바이트를 선택하여 원하는 데이터를 추출하는 데 사용
  • 이 선택은 GE[3:0] 비트의 값에 따라 첫 번째 또는 두 번째 피연산자 중 하나에서 이루어짐.
  1. 패킹된 데이터 산술 명령어 중 일부는 별도의 덧셈 또는 뺄셈의 결과에 대해 GE[3:0] 비트를 설정. (예: SADD8/16, SSUB8/16)
  2. 이런 명령어 뒤에 SEL을 사용하여 데이터의 특정 부분을 추출

USUB8 Rd, Ra, Rb

Unsigned Subtract 8-bit
: Ra 및 Rb 간의 바이트 차이에 기반하여 GE 플래그를 설정
: 각 바이트의 차이가 양수일 때 해당 GE 비트가 설정되며, 차이가 0이거나 음수이면 해당 비트가 설정되지 않음.

SEL Rd, Rb, Ra

: Ra 및 Rb의 해당 바이트 중 (부호 없는) 최솟값을 Rd의 해당 바이트에 설정
: 즉, 각 바이트의 값을 비교하여 Ra 및 Rb 중 더 작은 값을 Rd에 저장
: 이때 GE 플래그를 사용하여 각 바이트가 선택
: GE 플래그가 설정된 경우에만 해당 바이트가 선택
: 즉, GE[x]=1은 첫 번째 값이 두 번째 값보다 크거나 같음을 의미하므로, Rn을 Rd에 넣고.
: GE[x]=0은 두 번째 값이 첫 번째 값보다 크거나 같음을 의미하므로, Rm을 Rd에 넣음.

Sum Absolute Difference

  • 두 이미지나 이미지 영역 사이의 각 픽셀 값의 차이를 절댓값을 취한 후 모든 차이의 합을 계산하는 것
  • 이를 통해 두 이미지나 이미지 영역 간의 유사성을 측정하거나 비교
  • 일반적으로 8bit 픽셀 데이터 배열에서 수행

Example-Byte reversal

ARMv6 이전

PRE ARMv6
EOR r1, r0, r0, ROR #16
BIC r1, r1, #0xFF0000
MOV r0, r0, ROR #8
EOR r0, r0, r1, LSR #8

ARMv6

REV r0, r0

NOP32(Arm v6K only)

  • NOP32는 Arm v6K 아키텍처에서만 사용할 수 있는 명령어
  • 진정한 ARM No Operation이지만 멀티 프로세서 작업에 대한 힌트도 포함

NOP32 기능

NOP32 #hint
Hint = 0: 진정한 No Operation 수행
Hint = 1: 해당 프로세서가 아무런 중요한 작업을 수행하지 않고 있는 것

  • 예를 들어 세마포어를 폴링하는 등의 작업이 진행되지 않음을 다른 멀티 프로세서 시스템에 신호로 보냄
  • NOP32는 진정한 No Operation을 수행하면서도 멀티 프로세서 시스템에 대한 힌트를 전달하는 데 사용

Changing processor state(CPS)

CPS - 프로세서 상태 변경

CPS{IE|ID} <aif> {#mode}

  • "IE"가 지정된 경우 지정된 인터럽트를 활성화하고 그렇지 않으면 비활성화
  • 지정된 경우 모드를 설정
  • <aif>는 활성화/비활성화할 인터럽트(IRQ, FIQ, Imprecise abort)를 지정
  • CPS는 모드를 변경하고 인터럽트를 활성화/비활성화하는 데 사용
  • CPSR을 읽기-수정-쓰기할 필요성을 없애며, 단일 작업으로 이를 수행
  • CPS는 무조건적인(instruction) 명령어
; CPS 명령어를 사용하여 IRQ 인터럽트를 활성화하고
; 모드를 SYS 모드로 변경하는 경우

CPSIE if ; IRQ 인터럽트를 활성화하고
CPS #0x1F ; 모드를 SYS 모드로 변경합니다.

Byte Invariant Big Endian Configuration

바이트 순서가 변하지 않고, 데이터의 엔디안이 변경되는 상황

  • 명령 메모리 시스템은 고정된 리틀 앤디안 사용
    SETEND: 시스템 엔디안 설정
    SETEND {BE | LE}
    : 지정된 엔디안에 따라 cpsr의 E비트 설정

바이트 불변 Big Endian 설정

LDR r0, [r7], #4 ; Big endian
SETEND LE
LDR r1, [r7], #4 ; Little endian
SETEND BE
  • SETEND LE는 작은 엔디안으로 설정
  • SETEND BE는 다시 큰 엔디안으로 설정
  • 즉, 레지스터 r7이 가리키는 메모리 주소에서 4바이트를 읽어서 r0 레지스터에 저장. 이때, 데이터는 big endian으로 해석. 그리고 SETEND LE 명령어를 사용하여 시스템의 엔디안을 리틀 엔디안으로 변경함.
  • 즉, LDR r0, [r7], #4 에서는 시스템이 빅 엔디안이어서 빅 엔디안으로 읽었다가 이제 SETEND LE를 통해 시스템을 리틀 엔디안으로, 그 후에 읽히는 LDR r1, [r7], #4를 리틀 엔디안으로 읽고 그 후 SETEND BE를 이용해 시스템을 빅엔디안으로 바꿈.

Exclusive Load and Store(독점적 Load/Store)

  • 공유 메모리 시스템에서 메모리 액세스를 "독점적"으로 표시하는 명령어

LDREX - Load

LDREX Rd, [Rn]
: Rd = *Rn

STREX - Store Exclusive

STREX Rd, Rm, [Rn]
: *Rn = Rm
: 메모리가 업데이트되면 Rd = 0, 그렇지 않으면 1

CLREX - 독점 태그 지우기 (비공유 메모리) - ARM v6k

  • 이러한 명령어에는 색인된 주소 지원이 없음
  • STREX는 메모리를 업데이트하는데 성공했는지 여부를 나타내는 결과 코드를 반환
  • ARM v6K는 LDREX 및 STREX의 바이트, 하프워드 및 더블워드 버전을 지원

예시

LDREX r0, [r1]
; r1이 가리키는 메모리 주소에서 데이터를 독점적으로 로드하여 r0에 저장
STREX r2, r3, [r1]
; r3의 값을 r1이 가리키는 메모리 주소에 저장하고, 성공 여부를 r2에 반환

Example Multi processor semaphore

  • 다중 프로세서 시스템에서 독점적인 메모리 액세스를 구현하기 위해 LDREX/STREX 명령어를 사용 가능.
  • SWP 명령어는 로드와 스토어 사이에 처리가 필요하지 않을 때만 유용
  • 이러한 방법을 구현하려면 외부 하드웨어가 태그 관리를 지원해야 함.
MOV r1, #0x1  ; 'lock taken' 값을 로드
try_for_lock
LDREX r0, [LockAddr]  ; 락 값을 로드
CMP r0, #0  ; 락이 비어 있는지 확인
STREXEQ r0, r1, [LockAddr]  ; 비어 있다면 소유권을 요청해보기
CMPEQ r0, #0  ; 성공적으로 요청되었는지 확인
BNE try_for_lock  ; 요청이 실패했다면 다시 시도
...  ; 성공 - 이제 락을 보유함

Exception entry and exit

  • 예외 진입 및 종료를 가속화하기 위해 고안

SRS (Save Return State)

SRS<DA|DB|IA|IB> #mode{!}

  • 현재 상태의 r14와 spsr을 [r13_mode]에 저장
  • 선택적으로 Writeback을 수행

RFE (Return From Exception)

RFE<DA|DB|IA|IB> Rn{!}

  • [Rn]으로부터 pc와 cpsr을 로드
  • 선택적으로 Writeback을 수행
  • SRS와 RFE 명령어는 조건부가 아님

SRS 예시

SRS DB #0x1F0!
  • SRS 명령어는 r14와 spsr을 [r13_db] 메모리 주소에 저장
  • 느낌표(!)는 Writeback을 의미
  • 이는 r13_db 값을 감소시킴.

RFE 예시

RFE IA r2!
  • RFE 명령어는 [r2] 메모리 주소에서 pc와 cpsr을 로드
  • 느낌표(!)는 Writeback을 의미
  • 이는 r2 값을 증가

이러한 명령어들은 예외 처리를 위한 효율적인 진입 및 종료를 위해 사용

<DA|DB|IA|IB>

SRS와 RFE 명령어에서 사용되는 모드 지정자

  • 레지스터 r13 (일반적으로 스택 포인터)를 선택하는 데 사용

1. DA (Decreasing After)

: 스택 포인터 값을 저장한 후 값을 감소시킵니다.

2. DB (Decreasing Before)

: 스택 포인터 값을 감소시킨 후 값을 저장합니다.

3. IA (Increasing After)

: 스택 포인터 값을 저장한 후 값을 증가시킵니다.

4. IB (Increasing Before)

: 스택 포인터 값을 증가시킨 후 값을 저장합니다.

Writeback(!)

  • Writeback은 느낌표(!)와 함께 사용됨.
  • 이것은 레지스터 값을 업데이트하는 동작을 나타냄.
  • Writeback을 사용하면 메모리에 액세스한 후에 레지스터 값을 업데이트 가능
profile
행복한 하루 보내세요

0개의 댓글