ARMv8 架構與指令集.學習筆記


 

目 錄

1章 ARMv8簡介3

1.1基礎認識3

1.2 相關專業名詞解釋3

2章 Execution State 4

2.1 提供兩種Execution State 4

2.2 決定Execution State的條件4

3章 Exception Level 5

3.1 Exception Level 與Security 5

3.1.1 EL3使用AArch64、AArch32的對比5

3.2 ELx 和 Execution State 組合6

3.3路由控制7

3.3.1 路由規則7

3.3.2 IRQ/FIQ/SError路由流程圖8

4章 ARMv8寄存器9

4.1 AArch32重要寄存器9

4.1.1 A32狀態下寄存器組織10

4.1.1 T32狀態下寄存器組織10

4.2 AArch64重要寄存器11

4.3 64、32位寄存器的映射關系11

5章 異常模型12

5.1 異常類型描述12

5.1.1 AArch32異常類型12

5.1.2 AArch64異常類型12

5.2異常處理邏輯13

5.2.1 寄存器操作13

5.2.2 路由控制14

5.3流程圖對比14

5.3.1 IRQ 流程圖15

5.3.2 Data Abort 流程圖18

5.4  源代碼異常入口20

5.4.1 C函數入口20

5.4.2 上報流程圖20

5.4.3 異常進入壓棧准備21

5.4.4 棧布局21

6章 ARMv8指令集22

6.1 概況22

6.1.1 指令基本格式22

6.1.2 指令分類22

6.2 A64指令集22

6.2.1 指令助記符23

6.2.2 指令條件碼23

6.2.3 跳轉指令24

6.2.4 異常產生和返回指令24

6.2.5 系統寄存器指令24

6.2.6 數據處理指令25

6.2.7 Load/Store指令27

6.2.8 屏障指令31

6.3 A32 & T32指令集31

6.3.1 跳轉指令31

6.3.2 異常產生、返回指令32

6.3.3 系統寄存器指令32

6.3.4 系統寄存器指令32

6.3.5 數據處理指令32

6.3.6 Load/Store指令32

6.3.7 IT(if then)指令34

6.3.8 協處理器指令34

6.4 指令編碼34

6.4.1 A32編碼34

6.4.2 T32-16bit編碼35

6.4.3 T32-32bit編碼35

6.4.4 A64編碼35

6.4 匯編代碼分析35

7章 流水線36

7.1 簡介36

7.1.1 簡單三級流水線36

7.1.2 經典五級流水線36

7.2 流水線沖突37

7.3 指令並行37


1章 ARMv8簡介

1.1基礎認識

ARMv8的架構繼承以往ARMv7與之前處理器技術的基礎,除了現有的16/32bit的Thumb2指令支持外,也向前兼容現有的A32(ARM 32bit)指令集,基於64bit的AArch64架構,除了新增A64(ARM 64bit)指令集外,也擴充了現有的A32(ARM 32bit)和T32(Thumb2 32bit)指令集,另外還新增加了CRYPTO(加密)模塊支持。

1.2 相關專業名詞解釋

AArch32

描述32bit Execution State

AArch64

描述64bit Execution State

A32、T32

AArch32 ISA (Instruction Architecture)

A64

AArch64 ISA (Instruction Architecture)

Interprocessing

描述AArch32和AArch64兩種執行狀態之間的切換

SIMD

Single-Instruction, Multiple-Data (單指令多數據)

(參考文檔:ARMv8-A Architecture reference manual-DDI0487A_g_armv8_arm.pdf)

 

2章 Execution State

2.1 提供兩種Execution State

• ARMv8 提供AArch32 state和 AArch64 state 兩種Execution State,下面是兩種Execution State對比.

Execution State

Note

 

 

 

AArch32

提供13個32bit通用寄存器R0-R12,一個32bit PC指針 (R15)、堆棧指針SP (R13)、鏈接寄存器LR (R14)

提供一個32bit異常鏈接寄存器ELR, 用於Hyp mode下的異常返回

提供32個64bit SIMD向量和標量floating-point支持

提供兩個指令集A32(32bit)、T32(16/32bit)

兼容ARMv7的異常模型

協處理器只支持CP10\CP11\CP14\CP15

 

 

 

 

AArch64

提供31個64bit通用寄存器X0-X30(W0-W30),其中X30是程序鏈接寄存器LR

提供一個64bit PC指針、堆棧指針SPx 、異常鏈接寄存器ELRx

提供32個128bit SIMD向量和標量floating-point支持

定義ARMv8異常等級ELx(x<4),x越大等級越高,權限越大

定義一組PE state寄存器PSTATE(NZCV/DAIF/CurrentEL/SPSel等),用於保存PE當前的狀態信息

沒有協處理器概念

 

2.2 決定Execution State的條件

 

SPSR_EL1.M[4] 決定EL0的執行狀態,為0 =>64bit ,否則=>32bit

HCR_EL2.RW 決定EL1的執行狀態,為1 =>64bit ,否則=>32bit

SCR_EL3.RW確定EL2 or EL1的執行狀態,為1 =>64bit ,否則=>32bit

AArch32和AArch64之間的切換只能通過發生異常或者系統Reset來實現.(A32 -> T32之間是通過BX指令切換的)


 

 

3章 Exception Level

• ARMv8定義EL0-EL3共 4個Exception Level來控制PE的行為.

ELx(x<4),x越大等級越高,執行特權越高

執行在EL0稱為非特權執行

EL2 沒有Secure state,只有Non-secure state

EL3 只有Secure state,實現EL0/EL1的Secure 和Non-secure之間的切換

EL0 & EL1 必須要實現,EL2/EL3則是可選實現

3.1 Exception Level 與Security

Exception Level

EL0

Application

EL1

Linux kernel- OS

EL2

Hypervisor (可以理解為上面跑多個虛擬OS)

EL3

Secure Monitor(ARM Trusted Firmware)

Security

Non-secure

EL0/EL1/EL2, 只能訪問Non-secure memory

Secure

EL0/EL1/EL3, 可以訪問Non-secure memory & Secure memory,可起到物理屏障安全隔離作用

 

3.1.1 EL3使用AArch64、AArch32的對比

 

Note

 

Common

User mode 只執行在Non- Secure EL0 or Secure ELO

SCR_EL3.NS決定的是low level EL的secure/non-secure狀態,不是絕對自身的

EL2只有Non-secure state

EL0 既有Non-secure state 也有Secure state

 

EL3

AArch64

EL1使用AArch32,那么Non- Secure {SYS/FIQ/IRQ/SVC/ABORT/UND} 模式執行在Non-secure EL1,Secure {SYS/FIQ/IRQ/SVC/ABORT/UND}模式執行在Secure EL1

 SCR_EL3.NS == 0,則切換到Secure EL0/EL1狀態,否則切換到Non-secure ELO/EL1狀態

Secure state 只有Secure EL0/EL1/EL3

 

EL3

AArch32

User mode 只執行在Non- Secure EL0 or Secure ELO

EL1使用AArch32,那么Non- Secure {SYS/FIQ/IRQ/SVC/ABORT/UND} 模式執行在Non-secure EL1,Secure {SYS/FIQ/IRQ/SVC/ABORT/UND}模式執行在EL3

Secure state只有Secure EL0/EL3,沒有Secure EL1,要注意和上面的情況不同

 

• 當EL3使用AArch64時,有如下結構組合:

 

 

• 當EL3使用AArch32時,有如下結構組合:

3.2 ELx  Execution State 組合

•假設EL0-EL3都已經實現,那么將會有如下組合

五類組合

EL0/EL1/EL2/EL3  => AArch64

此兩類組合不存在64bit –> 32bit之間的所謂 Interprocessing 切換

EL0/EL1/EL2/EL3  => AArch32

EL0 => AARCH32,EL1/EL2/EL3 => AArch64

此三類組合存在64bit –> 32bit之間的所謂 Interprocessing 切換

EL0/EL1 => AArch32,EL2/EL3 => AArch64

EL0/EL1/EL2 => AArch32,EL3 => AArch64

組合規則

字寬(ELx)<= 字寬(EL(x+1))  { x=0,1,2 }

原則:上層字寬不能大於底層字寬

 

• 五類經典組合圖示

3.3路由控制

• 如果EL3使用AArch64,則有如下異常路由控制

3.3.1 路由規則

• 路由規則如下圖所示(from ARMv8 Datasheet):

 

• 規則小結如下:

SPSR_EL1.M[4] == 0,則決定ELO使用AArch64,否則AArch32

SCR_EL3.RW == 1,則決定 EL2/EL1 是使用AArch64,否則AArch32

SCR_EL3.{EA, FIQ, IRQ} == 1,則所有相應的SError\FIQ\IRQ 中斷都被路由到EL3

HCR_EL2.RW == 1,則決定EL1使用AArch64,否則使用AArch32

HCR_EL2.{AMO, IMO, FMO} == 1,則EL1/EL0所有對應的SError\FIQ\IRQ中斷都被路由到EL2,同時使能對應的虛擬中斷VSE,VI,VF

HCR_EL2.TGE == 1,那么會忽略HCR_EL2.{AMO, IMO, FMO}的具體值,直接當成1處理,則EL1/EL0所有對應的SError\FIQ\IRQ中斷都被路由到EL2,同時禁止所有虛擬中斷

注意: SCR_EL3.{EA, FIQ, IRQ}bit的優先級高於HCR_EL2.{AMO, IMO, FMO} bit優先級,路由優先考慮SCR_EL3

 

3.3.2 IRQ/FIQ/SError路由流程圖

 

4章 ARMv8寄存器

寄存器名稱描述

位寬

分類

32-bit

Wn(通用)

WZR(0寄存器)

WSP(堆棧指針)

64-bit

Xn(通用)

XZR(0寄存器)

SP(堆棧指針)

 

4.1 AArch32重要寄存器

寄存器類型

Bit

描述

R0-R14

32bit

通用寄存器,但是ARM不建議使用有特殊功能的R13,R14,R15當做通用寄存器使用.

SP_x

32bit

通常稱R13為堆棧指針,除了User和Sys模式外,其他各種模式下都有對應的SP_x寄存器:x ={ und/svc/abt/irq/fiq/hyp/mon}

LR_x

32bit

R14為鏈接寄存器,除了User和Sys模式外,其他各種模式下都有對應的SP_x寄存器:x ={ und/svc/abt/svc/irq/fiq/mon},用於保存程序返回鏈接信息地址,AArch32環境下,也用於保存異常返回地址,也就說LR和ELR是公用一個,AArch64下是獨立的.

ELR_hyp

32bit

Hyp mode下特有的異常鏈接寄存器,保存異常進入Hyp mode時的異常地址

PC

32bit

通常稱R15為程序計算器PC指針,AArch32 中PC指向取指地址,是執行指令地址+8,AArch64中PC讀取時指向當前指令地址.

CPSR

32bit

記錄當前PE的運行狀態數據,CPSR.M[4:0]記錄運行模式,AArch64下使用PSTATE代替

APSR

32bit

應用程序狀態寄存器,EL0下可以使用APSR訪問部分PSTATE值

SPSR_x

32bit

CPSR的備份,除了User和Sys模式外,其他各種模式下都有對應的SPSR_x寄存器:x ={ und/svc/abt/irq/fiq/hpy/mon},注意:這些模式只適用於32bit運行環境

HCR

32bit

EL2特有,HCR.{TEG,AMO,IMO,FMO,RW}控制EL0/EL1的異常路由

SCR

32bit

EL3特有,SCR.{EA,IRQ,FIQ,RW}控制EL0/EL1/EL2的異常路由,注意EL3始終不會路由

VBAR

32bit

保存任意異常進入非Hyp mode & 非Monitor mode的跳轉向量基地址

HVBAR

32bit

保存任意異常進入Hyp mode的跳轉向量基地址

MVBAR

32bit

保存任意異常進入Monitor mode的跳轉向量基地址

ESR_ELx

32bit

保存異常進入ELx時的異常綜合信息,包含異常類型EC等,可以通過EC值判斷異常class

PSTATE

 

不是一個寄存器,是保存當前PE狀態的一組寄存器統稱,其中可訪問寄存器有:PSTATE.{NZCV,DAIF,CurrentEL,SPSel},屬於ARMv8新增內容,主要用於64bit環境下

 

4.1.1 A32狀態下寄存器組織

• 所謂的banked register 是指一個寄存器在不同模式下有對應不同的寄存器,比如SP,在abort模式下是SP_bat,在Und模式是SP_und,在iqr模式下是SP_irq等,進入各種模式后會自動切換映射到各個模式下對應的寄存器.

 R0-R7是所謂的非banked register,R8-R14是所謂的banked register

4.1.1 T32狀態下寄存器組織

A32使用

Rd/Rn編碼位寬4位

T32-32bit使用

Rd/Rn編碼位寬4位

T32-16bit使用

Rd/Rn編碼位寬3位

R0

R0

R0

R1

R1

R1

R2

R2

R2

R3

R3

R3

R4

R4

R4

R5

R5

R5

R6

R6

R6

R7

R7

R7

R8

R8

並不是說T32-16bit下沒有R8~R12,而是有限的指令才能訪問到,16bit指令的Rd/Rn編碼位只有3位,所以Rx范圍是R0-R7

R9

R9

R10

R10

R11

R11

R12

R12

SP (R13)

SP (R13)

SP (R13)

LR (R14)

LR (R14) //M

LR (R14) //M

PC (R15)

PC (R15) //P

PC (R15) //P

CPSR

CPSR

CPSR

SPSR

SPSR

SPSR

 

4.2 AArch64重要寄存器

寄存器類型

Bit

描述

X0-X30

64bit

通用寄存器,如果有需要可以當做32bit使用:WO-W30

LR (X30)

64bit

通常稱X30為程序鏈接寄存器,保存跳轉返回信息地址

SP_ELx

64bit

PSTATE.M[0] ==1,則每個ELx選擇SP_ELx,否則選擇同一個SP_EL0

ELR_ELx

64bit

異常鏈接寄存器,保存異常進入ELx的異常地址(x={0,1,2,3})

PC

64bit

程序計數器,俗稱PC指針,總是指向即將要執行的下一條指令

SPSR_ELx

32bit

寄存器,保存進入ELx的PSTATE狀態信息

NZCV

32bit

允許訪問的符號標志位

DIAF

32bit

中斷使能位:D-Debug,I-IRQ,A-SError,F-FIQ ,邏輯0允許

CurrentEL

32bit

記錄當前處於哪個Exception level

SPSel

32bit

記錄當前使用SP_EL0還是SP_ELx,x= {1,2,3}

HCR_EL2

32bit

HCR_EL2.{TEG,AMO,IMO,FMO,RW}控制EL0/EL1的異常路由 邏輯1允許

SCR_EL3

32bit

SCR_EL3.{EA,IRQ,FIQ,RW}控制EL0/EL1/EL2的異常路由  邏輯1允許

ESR_ELx

32bit

保存異常進入ELx時的異常綜合信息,包含異常類型EC等.

VBAR_ELx

64bit

保存任意異常進入ELx的跳轉向量基地址 x={0,1,2,3}

PSTATE

 

不是一個寄存器,是保存當前PE狀態的一組寄存器統稱,其中可訪問寄存器有:PSTATE.{NZCV,DAIF,CurrentEL,SPSel},屬於ARMv8新增內容,64bit下代替CPSR

 

4.3 6432位寄存器的映射關系

64-bit

32-bit

 

 

 

 

 

 

 

 

 

64-bit OS

Runing

AArch32 App

64-bit

32-bit

X0

R0

X20

LR_adt

X1

R1

X21

SP_abt

X2

R2

X22

LR_und

X3

R3

X23

SP_und

X4

R4

X24

R8_fiq

X5

R5

X25

R9_fiq

X6

R6

X26

R10_fiq

X7

R7

X27

R11_fiq

X8

R8_usr

X28

R12_fiq

X9

R9_usr

X29

SP_fiq

X10

R10_usr

X30(LR)

LR_fiq

X11

R11_usr

SCR_EL3

SCR

X12

R12_usr

HCR_EL2

HCR

X13

SP_usr

VBAR_EL1

VBAR

X14

LR_usr

VBAR_EL2

HVBAR

X15

SP_hyp

VBAR_EL3

MVBAR

X16

LR_irq

ESR_EL1

DFSR

X17

SP_irq

ESR_EL2

HSR

X18

LR_svc

 
 

X19

SP_svc

 
 

 

5章 異常模型

5.1 異常類型描述

5.1.1 AArch32異常類型

異常類型

描述

默認捕獲模式

向量地址偏移

Undefined Instruction

未定義指令

Und mode

0x04

Supervisor Call

SVC調用

Svc mode

0x08

Hypervisor Call

HVC調用

Hyp mode

0x08

Secure Monitor Call

SMC調用

Mon mode

0x08

Prefetch abort

預取指令終止

Abt mode

0x0c

Data abort

數據終止

Abt mode

0x10

IRQ interrupt

IRQ中斷

IRQ mode

0x18

FIQ interrupt

FIQ中斷

FIQ mode

0x1c

Hyp Trap exception

Hyp捕獲異常

Hyp mode

0x14

Monitor Trap exception

Mon捕獲異常

Mon mode

0x04

 

5.1.2 AArch64異常類型

可分為同步異常 & 異步異常兩大類,如下表描述:

 

Synchronous(同步異常)

異常類型

描述

Undefined Instruction

未定義指令異常

Illegal Execution State

非常執行狀態異常

System Call

系統調用指令異常(SVC/HVC/SMC)

Misaligned PC/SP

PC/SP未對齊異常

Instruction Abort

指令終止異常

Data Abort

數據終止異常

Debug exception

軟件斷點指令/斷點/觀察點/向量捕獲/軟件單步 等Debug異常

 

Asynchronous(異步異常)

類型

描述

SError or vSError

系統錯誤類型,包括外部數據終止

IRQ or vIRQ

外部中斷 or 虛擬外部中斷

FIQ or vFIQ

快速中斷 or 虛擬快速中斷

 

 

異常進入滿足以下條件

向量地址偏移表

Synchronous

(同步異常)

IRQ

|| vIRQ

FIQ

|| vFIQ

SError

|| vSError

SP => SP_EL0

&& 從Current EL來

0x000

0x080

0x100

0x180

SP => SP_ELx

&& 從Current EL來

0x200

0x280

0x300

0x380

64bit => 64bit

&& 從Low level EL來

0x400

0x480

0x500

0x580

32bit => 64bit

&& 從Low level EL來

0x600

0x680

0x700

0x780

• SP => SP_EL0,表示使用SP_EL0堆棧指針,由PSTATE.SP == 0決定,PSTATE.SP == 1 則SP_ELx;

• 32bit => 64bit 是指發生異常時PE從AArch32切換到AArch64的情況;

 

5.2異常處理邏輯

5.2.1 寄存器操作

流程

Note

AArch32 State

  1. PE根據異常類型跳轉到對應的異常模式x,

x = {und/svc/abt/irq/fiq/hyp/mon}

PE跳轉到哪一種模式通常由路由關系決定

2、保存異常返回地址到LR_x,用於異常返回用

LR也是對應模式的R[14]_x寄存器,32位系統下LR和ELR是同一個寄存器,而64位是獨立的

3、備份PSTATE 數據到SPSR_x

異常返回時需要從SPSR_x恢復PSTATE

4、PSTATE 操作:

PSTATE.M[4:0]設置為異常模式x

PSTATE.{A,I,F} = 1

PSTATE.T = 1,強制進入A32模式

PSTATE.IT[7:2] = “00000”

PSTATE.M[4]只是對32位系統有效,64為下是保留的,因為64位下沒有各種mode的概念.

異常處理都要切換到ARM下進行;

進入異常時需要暫時關閉A,I,F中斷;

5、據異常模式x的向量偏移跳轉到進入異常處理

各個mode有對應的Vector base addr + offset

AArch64 state

  1. 保存PSTATE 數據到SPSR_ELx,(x = 1,2,3)

異常返回時需要從SPSR_ELx中恢復PSTATE

2、保存異常進入地址到ELR_ELx,同步異常(und/abt等)是當前地址,而

異步異常(irq/fiq等)是下一條指令地址

64位架構LR和ELR是獨立分開的,這點和32位架構有所差別

3、保存異常原因信息到ESR_ELx

ESR_ELx.EC代表Exception Class,關注這個bit

4、PE根據目標EL的異常向量表中定義的異常地址強制跳轉到異常處理程序

跳轉到哪個EL使用哪個向量偏移地址又路由關系決定

5、堆棧指針SP的使用由目標EL決定

(SPSR_ELx.M[0] == 1) ? h(ELx): t(EL0)

 

5.2.2 路由控制

Execution State

異步異常(中斷)

路由控制位、優先級排列. 1允許 0禁止

 

 

 

AArch32

Asynchronous Data Abort

(異步數據終止)

SCR.EA

HCR.TGE

HCR.AMO

IRQ  or vIRQ

SCR.IRQ

HCR.TGE

HCR.IMO

FIQ  or vFIQ

SCR.FIQ

HCR.TGE

HCR.FMO

 

 

AArch64

SError or vSError

SCR_EL3.EA

HCR_EL2.TGE

HCR_EL2.AMO

IRQ  or vIRQ

SCR_EL3.IRQ

HCR_EL2.TGE

HCR_EL2.IMO

FIQ  or vFIQ

SCR_EL3.FIQ

HCR_EL2.TGE

HCR_EL2.FMO

• 若HCR_EL2.TGE ==1所有的虛擬中斷將被禁止,HCR.{AMO,IMO,FMO} HCR_EL2.{AMO,IMO,FMO}被當成1處理.

5.3流程圖對比

AArch32、AArch64架構下IRQ 和Data Abort 異常處理流程圖對比.

 

5.3.1 IRQ 流程圖

5.3.1.1 AArch32

5.3.1.2 AArch64

5.3.2 Data Abort 流程圖

5.3.2.1 AArch32

 

5.3.2.2 AArch64

 

5.4  源代碼異常入口

5.4.1 C函數入口

 

異常類型

AArch32 State

AArch64 State

所在文件

C 函數

所在文件

C 函數

Und

arm/kernel/traps.c

do_undefinstr

Arm64/kernel/traps.c

do_undefinstr

Data Abort

arm/mm/fault.c

do_DataAbort

arm64/mm/fault.c

do_mem_abort

IRQ

arm/kernel/irq.c

asm_do_IRQ

arm64/kernel/irq.c

handle_IRQ

FIQ

 
 
 
 

System Call

 
 
 
 
 
 
 
 
 

 

5.4.2 上報流程圖

例舉Data Abort 和 IRQ中斷的入口流程圖

5.4.2.1 Data Abort 上報

5.4.2.2 IRQ上報

5.4.3 異常進入壓棧准備

分析64位kernel_entry 壓棧代碼邏輯(代碼路徑:kernel/arch/arm64/kernel/entry.S)

 sp指向 #S_LR – #S_FRAME_SIZE 位置

#S_FRAME_SIZE是pt_regs結構圖的size

 依次把x28-x29 … x0-x1 成對壓入棧內

每壓入一對寄存器,sp指針就移動 -16 =((64/8)*2)字節長度,棧是向地址減少方向增長的.

 保存sp+#S_FRAME_SIZE數據到x21

add x21, sp, #SP_FRAME_SIZE

• 保存elr_el1到x22

mrs x22, elr_el1

• 保存spsr_el1到x23

mrs x23, spsr_el1

 把lr、x21寫入sp+#S_LR地址內存

保存lr和x21的數據到指定棧內存位置

• 把x22、x23寫入sp+#S_PC地址內存

保存elr,spsr數據到指定棧內存位置

 

5.4.4 棧布局

 

6章 ARMv8指令集

6.1 概況

 A64指令集

 A32 & T32指令集

• 指令編碼

6.1.1 指令基本格式

<Opcode>{<Cond>}<S>  <Rd>, <Rn> {,<Opcode2>}

 

• 其中尖括號是必須的,花括號是可選的

• A32: Rd => {R0–R14}  

• A64: Rd =>Xt => {X0–X30}

 

標識符

Note

Opcode

操作碼,也就是助記符,說明指令需要執行的操作類型

Cond

指令執行條件碼,在編碼中占4bit,0b0000 -0b1110

S

條件碼設置項,決定本次指令執行是否影響PSTATE寄存器響應狀態位值

Rd/Xt

目標寄存器,A32指令可以選擇R0-R14,T32指令大部分只能選擇RO-R7,A64指令可以選擇X0-X30 or W0-W30

Rn/Xn

第一個操作數的寄存器,和Rd一樣,不同指令有不同要求

Opcode2

第二個操作數,可以是立即數,寄存器Rm和寄存器移位方式(Rm,#shit)

 

6.1.2 指令分類

類型

Note

• 跳轉指令

條件跳轉、無條件跳轉(#imm、register)指令

• 異常產生指令

系統調用類指令(SVC、HVC、SMC)

• 系統寄存器指令

讀寫系統寄存器,如 :MRS、MSR指令 可操作PSTATE的位段寄存器

• 數據處理指令

包括各種算數運算、邏輯運算、位操作、移位(shift)指令

• load/store

內存訪問指令

load/store {批量寄存器、單個寄存器、一對寄存器、非-暫存、非特權、獨占}以及load-Acquire、store-Release指令 (A64沒有LDM/STM指令)

• 協處理指令

A64沒有協處理器指令

 

6.2 A64指令集

 A64指令編碼寬度固定32bit

 31個(X0-X30)個64bit通用用途寄存器(用作32bit時是W0-W30),寄存器名使用5bit編碼

 PC指針不能作為數據處理指或load指令的目的寄存器,X30通常用作LR

• 移除了批量加載寄存器指令 LDM/STM, PUSH/POP, 使用STP/LDP 一對加載寄存器指令代替

• 增加支持未對齊的load/store指令立即數偏移尋址,提供非-暫存LDNP/STNP指令,不需要hold數據到cache中

 沒有提供訪問CPSR的單一寄存器,但是提供訪問PSTATE的狀態域寄存器

• 相比A32少了很多條件執行指令,只有條件跳轉和少數數據處理這類指令才有條件執行.

• 支持48bit虛擬尋址空間

• 大部分A64指令都有32/64位兩種形式

 A64沒有協處理器的概念

 

6.2.1 指令助記符

整型

W/R

32bit整數

X

64bit整數

加載/存儲、符號-0擴展

B

無符號8bit字節

SB

帶符號8bit字節

H

無符號16bit半字

SH

帶符號16bit半字

W

無符號32bit字

SW

帶符號32bit字

P

Pair(一對)

寄存器寬度改變

H

高位(dst gets top half)

N

有限位(dst < src)

L

Long (dst > src)

W

Wide (dst==src1,src1>src2) ?

 

6.2.2 指令條件碼

編碼

助記符

描述

標記

0000

EQ

運算結果相等為1

Z==1

0001

NE

運算結果不等為0

Z==0

0010

HS/CS

無符號高或者相同進位,發生進位為1

C==1

0011

LO/CC

無符號低清零,發生借位為0

C==0

0100

MI

負數為1

N==1

0101

PL

非負數0

N==0

0110

VS

有符號溢出為1

V==1

0111

VC

沒用溢出為0

V==0

1000

HI

無符號 >

C==1 && Z==0

1001

LS

無符號 <=

!(C==1 && Z==0)

1010

GE

帶符號 >=

N==V

1011

LT

帶符號 <

N!=V

1100

GT

帶符號 >

Z==0 && N==V

1101

LE

帶符號 <=

!( Z==0 && N==V)

1110

AL

 

無條件執行

 

Any

1111

NV

6.2.3 跳轉指令

6.2.3.1 條件跳轉

B.cond

cond為真跳轉

CBNZ

CBNZ X1,label     //如果X1!= 0則跳轉到label

CBZ

CBZ X1label      //如果X1== 0則跳轉到label

TBNZ

TBNZ X1,#3 label  //若X1[3]!=0,則跳轉到label

TBZ

TBZ X1#3 label   //若X1[3]==0,則跳轉到label

 

6.2.3.2 絕對跳轉

B

絕對跳轉

BL

絕對跳轉 #imm,返回地址保存到LR(X30)

BLR

絕對跳轉reg,返回地址保存到LR(X30)

BR

跳轉到reg內容地址,

RET

子程序返回指令,返回地址默認保存在LR(X30)

 

6.2.4 異常產生和返回指令

SVC

SVC系統調用,目標異常等級為EL1

HVC

HVC系統調用,目標異常等級為EL2

SMC

SMC系統調用,目標異常等級為EL3

ERET

異常返回,使用當前的SPSR_ELx和ELR_ELx

 

6.2.5 系統寄存器指令

MRS

R <- S: 通用寄存器 <= 系統寄存器

MSR

S <- R: 系統寄存器 <= 通用寄存器

 

6.2.6 數據處理指令

數據處理指令類型

算數運算

邏輯運算

數據傳輸

地址生成

位段移動

移位運算

ADDS

ANDS

MOV

ADRP

BFM

ASR

SUBS

EOR

MOVZ

ADR

SBFM

LSL

CMP

ORR

MOVK

 

UBFM

LSR

SBC

MOVI

 
 

BFI

ROR

RSB

TST

 
 

BFXIL

 

RSC

 
 
 

SBFIZ

 

CMN

 
 
 

SBFX

 

MADD

 
 
 

UBFIZ

 

MSUB

 
 
 
 
 

MUL

 
 
 
 
 

SMADDL

 
 
 
 
 

SDIV

 
 
 
 
 

UDIV

 
 
 
 
 

 

6.2.6.1 算術運算指令

ADDS

加法指令,S存在,則更新條件位flag

ADCS

帶進位的加法,若S存在,則更新條件位flag

SUBS

減法指令,若S存在,則更新條件位flag

SBC

將操作數 1          減去操作數 2,再減去 標志位C的取反值 ,結果送到目的寄存器Xt/Wt

RSB

逆向減法,操作數 2 –操作數 1,結果 Rd

RSC

帶借位的逆向減法指令,將操作數 2 減去操作數 1,再減去 標志位C的取反值 ,結果送目標寄存器Xt/Wt

CMP

比較相等指令

CMN

比較不等指令

NEG

取負數運算,NEG X1,X2 // X1 = X2按位取反+1(負數=正數補碼+1)

MADD

乘加運算

MSUB

乘減運算

MUL

乘法運算

SMADDL

有符號乘加運算

SDIV

有符號除法運算

UDIV

無符號除法運算

 

6.2.6.2 邏輯運算指令

ANDS

按位與運算,如果S存在,則更新條件位標記

EOR

按位異或運算

ORR

按位或運算

TST

例如:TST  W0,  #0X40 //指令用來測試W0[3]是否為1,相當於:ANDS WZR,W0,#0X40

 

6.2.6.3 數據傳輸指令

MOV

賦值運算指令

MOVZ

賦值#uimm16到目標寄存器Xd

MOVN

賦值#uimm16到目標寄存器Xd,再取反

MOVK

賦值#uimm16到目標寄存器Xd,保存其它bit不變

 

6.2.6.4 地址生成指令

ADRP

base = PC[11:0]=ZERO(12); Xd = base + label;

ADR

Xd = PC + label

 

6.2.6.5 位段移動指令

BFM

BFM Wd, Wn, #r, #s

if s>=r then Wd<s-r:0> = Wn<s:r>, else  Wd<32+s-r,32-r> = Wn<s:0>.

SBFM

UBFM

BFI

 

BFXIL

 

SBFIZ

 

SBFX

 

UBFX

 

UBFZ

 

 

6.2.6.6 移位運算指令

ASR

算術右移 >> (結果帶符號)

LSL

邏輯左移 <<

LSR

邏輯右移 >>

ROR

循環右移:頭尾相連

SXTB

字節、半字、字符號/0擴展移位運算

關於SXTB #imm和UXTB #imm 的用法可以使用以下圖解描述:

SXTH

SXTW

UXTB

UXTH

 

 

 

6.2.7 Load/Store指令

對齊

偏移

非對齊

偏移

PC-相對

尋址

訪問

一對

非暫存

非特權

獨占

Acquire

Release

LDR

LDUR

LDR

LDP

LDNP

LDTR

LDXR

LDAR

LDRB

LDURB

LDRSW

LDRSW

STNP

LDTRB

LDXRB

LDARB

LDRSB

LDURSB

 

STP

 

LDTRSB

LDXRH

LDARH

LDRH

LDURH

 
 
 

LDTRH

LDXP

STLR

LDRSH

LDURSH

 
 
 

LDTRSH

STXR

STLRB

LDRSW

LDURSW

 
 
 

LDTRSW

STXRB

STLRH

STR

STUR

 
 
 

STTR

STXRH

LDAXR

STRB

STURB

 
 
 

STTRB

STXP

LDAXRB

STRH

STURH

 
 
 

STTRH

 

LDAXRH

 
 
 
 
 
 
 

LDAXP

 
 
 
 
 
 
 

STLXR

 
 
 
 
 
 
 

STLXRB

 
 
 
 
 
 
 

STLXRH

 
 
 
 
 
 
 

STLXP

 

6.2.7.1 尋址方式

類型

立即數偏移

寄存器偏移

擴展寄存器偏移

基址寄存器(無偏移)

{ base{,#0 } }

 
 

基址寄存器

+ 偏移)

{ base{,#imm } }

{ base,Xm{,LSL #imm } }

[base,Wm,(S|U)XTW {#imm }]

Pre-indexed

(事先更新)

[ base,#imm ]!

 
 

Post-indexed

(事后更新)

[ base,#imm ]

{ base },Xm

 

PC-相對尋址

label

 
 

6.2.7.2 Load/Store (Scaled Offset)

支持的尋址方式

對齊的,無符號#imm12偏移,不支持pre-/post-index 操作

非對齊,帶符號#imm9偏移,支持pre-/post-index 操作

對齊or非對齊的64bit寄存器偏移

對齊or 非對齊的32bit寄存器偏移

 

Zero-Extend / Sign-Extend

0 擴展

Memory讀取一個無符號32位Wn數據寫到一個64位Xt寄存器中,Wn數據被存儲到Xt[31:0],Xt[63:32]使用0代替

符號擴展

Memory讀取一個有符號32位Wn數據寫到一個64位Xt寄存器中,Wn數據被存儲到Xt[31:0],Xt[63:32]使用Wn的符號位值(Wn[31])代替

 

LDR

Memory地址addr中讀取雙字/字節/半字/字數據到目標寄存器Xt/Wt中

帶”S”表示需要符號擴展.

LDRB

LDRSB

LDRH

LDRSH

LDRSW

STR

Xn/Wn中的雙字/字節/半字數據寫入到Memory地址addr中

STRB

STRH

 

6.2.7.3 Load/Store (Unscaled Offset)

• 所謂Scaled 和Unscaled其實就是可以見到理解為對齊和非對齊,本質就是是否乘以一個常量,因為scaled的總是可以乘以一個常量來達到對齊,而Unscaled就不需要,是多少就多少,更符合人類自然的理解

支持的尋址方式

 非對齊的,有符號#simm9偏移,不支持pre-/post-index 操作

 

LDUR

Memory地址addr中讀取雙字/字節/半字/字數據到目標寄存器Xt/Wt中

帶”S”表示需要符號擴展.

立即數偏移 #simm9 = { -256 ~ +256 } 的任意整數,不需要對齊規則.

LDURB

LDURSB

LDURH

LDURSH

LDURSW

STUR

Xn/Wn中的雙字/字節/半字數據寫入到Memory地址addr中

立即數偏移 #simm9 = { -256 ~ +256 } 的任意整數,不需要對齊規則.

STURB

STURH

 

6.2.7.4 Load/Store PC-relative(PC相對尋址)

支持的尋址方式

• 不支持pre-/post-index 操作

 

LDR

Memory地址addr中讀取雙字/字數據到目標寄存器Xt/Wt中

帶”S”表示需要符號擴展.

LDRSW

6.2.7.5 Load/Store Pair(一對)

支持的尋址方式

• 對齊的,有符號#simm7偏移,支持pre-/post-index 操作

 

LDP

Memory地址addr處讀取兩個雙字/字數據到目標寄存器Xt1,Xt2

帶”S”表示需要符號擴展.

LDRSW

STP

Xt1,Xt2兩個雙字/字數據寫到Memory地址addr中

 

6.2.7.6 Load/Store Non-temporal(非暫存) Pair

• 所謂Non-temporal就是就是用於你確定知道該地址只加載一次,不需要觸發緩存,避免數據被刷新,優化性能,其它指令都默認會寫Cache

支持的尋址方式

 對齊的,有符號#simm7偏移,不支持pre-/post-index 操作

 

LDNP

Memory地址addr處讀取兩個雙字/字數據到目標寄存器Xt1,Xt2, 標注非暫存訪問,不更新cache

帶”S”表示需要符號擴展.

STNP

Xt1,Xt2兩個雙字/字數據寫到Memory地址addr中,標注非暫存訪問,不更新cache

 

6.2.7.7 Load/Store Unprivileged(非特權)

• 所謂Unprivileged就是說EL0/EL1的內存有不同的權限控制,這條指令以EL0的權限存取,用於模擬EL0的行為,該指令應用於EL1和EL0之間的交互.

支持的尋址方式

• 非對齊的,有符號#simm9偏移,不支持pre-/post-index 操作

 

LDTR

Memory地址addr中讀取雙字/字節/半字/字數據到目標寄存器Xt/Wt中,

當執行在EL1的時候使用EL0的權限

帶”S”表示需要符號擴展

 

LDTRB

LDTRSB

LDTRH

LDTRSH

LDTRSW

STTR

Xn/Wn中的雙字/字節/半字數據寫入到Memory地址addr中,

當執行在EL1的時候使用EL0的權限

STTRB

STTRH

 

6.2.7.8 Load/Store Exclusive(獨占)

• 在多核CPU下,對一個地址的訪問可能引起沖突,這個指令解決了沖突,保證原子性(所謂原子操作簡單理解就是不能被中斷的操作),是解決多個CPU訪問同一內存地址導致沖突的一種機制。

比如2個CPU同時寫,其中一條的Ws就會返回失敗值。通常用於鎖,比如spinlock,可以參考代碼:arch/arm64/include/asm/spinlock.h

 

支持的尋址方式

• 無偏移基址寄存器,不支持pre-/post-index 操作

 

LDXR

Memory地址addr中讀取雙字/字節/半字數據到目標寄存器Xt/Wt中

標記物理地址是獨占訪問的

LDXRB

LDXRH

LDXP

Memory地址addr中讀取一對雙字數據到目標寄存器Xt1,Xt2中,標記物理地址是獨占訪問的

STXR

Xn/Wn中的雙字/字節/半字數據寫入到Memory地址addr中,

返回是否獨占訪問成功狀態Ws)

STXRB

STXRH

STXP

Xt1,Xt2一對雙字字數據寫入到Memory地址addr中,返回是否獨占訪問成功狀態

 

6.2.7.9 Load-Acquire/Store-Release

Load-Acquire

Acquire的語義是讀操作

相當於半個DMB指令,只管讀內存操作

Store-Release

Release的語義是寫操作

相當於半個DMB指令,只管寫內存操作

 

支持的尋址方式

• 無偏移基址寄存器,不支持pre-/post-index 操作

 

Non-exclusive(非獨占)

LDAR

Memory地址addr中讀取一個雙字/字節/半字數據到目標寄存器Xt/Wt中,

標記物理地址為非獨占訪問

LDARB

LDARH

STLR

把一個雙字/字節/半字數據Xt/Wt寫到Memory地址addr中,

返回是否獨占訪問成功狀態

 

STLRB

STLRH

Exclusive(獨占)

LDAXR

Memory地址addr中讀取一個雙字/字節/半字數據到目標寄存器Xt/Wt中,

標記物理地址為獨占訪問

 

LDAXP 是Pair 訪問

LDAXRB

LDAXRH

LDAXP

STLXR

把一個雙字/字節/半字數據Xt/Wt寫到Memory地址addr中,

返回是否獨占訪問成功狀態

 

STLXP 是Pair 訪問

STLXRB

STLXRH

STLXP

 

6.2.8 屏障指令

DMB

數據內存屏障指令

保證該指令前的所有內存訪問結束,而該指令之后引起的內存訪問只能在該指令執行結束后開始,其它數據處理指令等可以越過DMB屏障亂序執行

DSB

數據同步屏障指令

DSB比DMB管得更寬,DSB屏障之后的所有得指令不可越過屏障亂序執行

ISB

指令同步屏障指令

ISB比DSB管的更寬,ISB屏障之前的指令保證執行完,屏障之后的指令直接flush掉再重新從Memroy中取指

 

 以DMB指令為例介紹屏障指令原理.

ADD X1,X2,X3       ------(A)

LDR X4,addr         ------(B)

STR X6,addr2

DMB <option>        -----(DMB)

LDR X5,addr3        ------(C)

STR X7,addr4

SUB X8,X9,#2     ------(D)

左邊程序中,因為有(DMB)的屏障作用,(C)必須要等(B)執行完成后才可以執行,保證執行順序。而(A)、(D)不屬於Memory access指令,可以越過DMB屏障 亂序執行;

 

而結合到Load-Acquire/Store-Release,可以分別理解為半個DMB指令,Load-Acquire只管Memory read,而Store-Release只管Memroy write,組合使用可以增加代碼亂序執行的靈活性和執行效率.

 

6.3 A32 & T32指令集

6.3.1 跳轉指令

B

條件跳轉

BL

跳轉前會把當前指令的下一條指令保存到 R14 (lr)

BX

只能用於寄存器尋址,寄存器最低位值用於切換 ARM/Thumb 工作狀態,ARM/Thumb 的切

換只能通過跳轉實現,不能通過直接 write register 方式實現.

BLX

BL & BX 的並集

CBNZ

比較非 0 跳轉

CBZ

比較為 0 跳轉

TBNZ

測試位比較非 0 跳轉

TBZ

測試位比較 0 跳轉

BLR

帶返回的寄存器跳轉

BR

跳轉到寄存器

RET

返回到子程序

 

6.3.2 異常產生、返回指令

• 參考A64指令集.

6.3.3 系統寄存器指令

 參考A64指令集.

6.3.4 系統寄存器指令

 參考A64指令集.

6.3.5 數據處理指令

• 參考A64指令集.

6.3.6 Load/Store指令

6.3.6.1 尋址方式

Offset addressing

偏移尋址(reg or #imm)

[ <Rn>, <offset>]

Pre-indexed addressing

事先更新尋址,先變化后操作

[ <Rn>, <offset>]!

Post-indexed addressing

事后更新尋址,先操作后變化

[<Rn>], <offset>

 

6.3.6.2 Load /Store

Normal

非特權

獨占

Load

Acquire

Store

Release

獨占

Acquire

Release

LDR

STR

LDRT

STRT

LDREX

STREX

LDA

STL

LDAEX

STLEX

LDRH

STRH

LDRHT

STRHT

LDREXH

STREXH

LDAH

STLH

LDAEXH

STLEXH

LDRSH

 

LDRSHT

 
 
 
 
 
 
 

LDRB

STRB

LDRBT

STRBT

LDREXB

STREXB

LDAB

STLB

LDAEXB

STLEXB

LDRSB

 

LDRSBT

 
 
 
 
 
 
 

LDRD

STRD

 
 

LDREXD

SETEXD

 
 

LDAEXD

STLEXD

 

 LDRD/ STRD 和A64的LDP/STP 用法類似,表中的D(Dua)關鍵字和A64的P(Pair)關鍵字是一個意思,都是指操作一對寄存器.

 以上指令用法和A64類似.

6.3.6.3 Load /Store(批量)

LDM

LDM {Cond} {類型} 基址寄存器{!},寄存器列表{^}

從指定內存中加載批量數據到寄存器堆

STM

STM {Cond} {類型} 基址寄存器{!},寄存器列表{^}

把寄存器堆中批量數據存儲到指定內存地址

PUSH

批量壓入棧

POP

批量彈出棧

 

類型

助記符

指令

Note

地址

變化

方式

IA

LDMIA/STMIA

先操作,后遞增4字節

IB

LDMIB/STMIA

先遞增4字節,后操作

DA

LDMDA/STMDA

先操作,后遞減4字節

DB

LDMDB/STMDB

先遞減4字節,后操作

棧操作

FD

LDMFD/STMFD

滿遞減堆棧SP指向最后一個元素

FA

LDMFA/STMFA

滿遞增堆棧,SP指向最后一個元素

ED

LDMED/STMED

空遞減堆棧,SP指向將要壓入數據的空地址

EA

LDMEA/STMEA

空遞增堆棧,SP指向將要壓入數據的空地址

•關於數據棧類型

滿遞減

堆棧首部是高地址,堆棧向低地址增長。SP總是指向堆棧最后一個元素(最后一個元素是最后壓入的數據)

滿遞增

堆棧首部是低地址,堆棧向高地址增長。SP總是指向堆棧最后一個元素(最后一個元素是最后壓入的數據)

空遞減

堆棧首部是低地址,堆棧向高地址增長。SP總是指向下一個將要放入數據的空位置

空遞增

堆棧首部是高地址,堆棧向低地址增長。SP總是指向下一個將要放入數據的空位置

 

 LDM/STM可以實現一次在一片連續的存儲器單元和多個寄存器之間傳送數據,批量加載指令用於將一片連續的存儲器中的數據傳送到多個寄存器,批量存儲指令完成相反的操作

 {!}為可選后綴,若選用,則當數據傳送完畢之后,將最后的地址寫入基址寄存器,否則基址寄存器的內容不改變,基址寄存器不允許為R15(PC),寄存器列表可以為R0 ~ R15的任意組合

• {^}為可選后綴,當指令為LDM且寄存器列表中包含有R15,選用該后綴表示:除了正常的數據傳送之外,還將SPSR復制到CPSR,同時,該后綴還表示傳入或傳出的是用戶模式下的寄存器,而不是當前模式下的寄存器

LDMIA R0!, {R1-R4}     // R1<----[R0]

                               // R2<----[R0 + 4]

                               // R3<----[R0 + 8]

                               // R4<----[R0 + 12] 

LDMIA R0!, {R1-R4}      // R1<----[R0]

                                // R2<----[R0 + 4]

                                // R3<----[R0 + 8]

                                // R4<----[R0 + 12] 

STMFD  SP!,{R0-R3}   //[R0]<----[SP]

//[R1]<----[SP + 4]

//[R2]<----[SP + 8]

//[R3]<----[SP + 12]

LDMFD SP!, {R6-R8}      // R6<----[SP]

                                 // R7<----[SP + 4]

                                // R8<----[SP + 8]

 

6.3.7 IT(if then)指令

• 基本格式:IT{<x>{<y>{<z>}}}{<q>} <cond>

 T32中的IT指令用於根據特定條件來執行緊跟其后的1-4條指令,其中X,Y,Z分別是執行第二、三、四條指令的條件,可取的值為T(then)或E(else),<cond>條件的值控制指令的執行邏輯.

T表示<cond>條件為TRUE則執行對應指令,E 表示<cond>為FALSE執行對應指令,如下例子描述.

ITETT   EQ

EQ(N==1)的條件是否成立判斷,2、3、4執行邏輯分別是E、T、T

MOVEQ   R0, #1  // 1

EQ為真(N==1),則執行 1、3、4(T)的MOV操作,否則執行2(E)的MOV操作

E

T

T

MOVNE   R0, #0  // 2

MOVEQ   R1, #0  // 3

MOVEQ   R2, #0  // 4

 

6.3.8 協處理器指令

CDP

數據操作指令,用於ARM通知協處理器執行特定操作

LDC

數據加載指令,用於源寄存器所指向的Mem數據傳送到目標寄存器

STC

數據存儲指令,用於源寄存器所指向的數據傳送到目標寄存器所指向的Mem中

MCR

數據傳送指令,ARM寄存器 => 協處理器寄存器

MRC

數據傳送指令,ARM寄存器 <= 協處理器寄存器

 

6.4 指令編碼

 A32

 T32-16bit

 T32-32bit

 A64

6.4.1 A32編碼

 基本格式

固定32bit編碼,要求字對齊

位於[31:28] 的4bit寬條件碼

op1位段控制指令類型:數據處理、load/store、跳轉、協處理器指令…

Rd/Rn寬度為4bit,寄存器可訪問范圍R0-R15 ,R15(PC)通常不做通用寄出去用途.

 

6.4.2 T32-16bit編碼

• 基本格式

 

固定13bit編碼,要求半字對齊

位於[15:10] 的5bit決定指令類型,詳見Datasheet F3.4/P2475.

沒用cond條件碼位.

Rd/Rn寬度為3bit,寄存器可訪問范圍R0-R7

 

6.4.3 T32-32bit編碼

 基本格式

 

固定32bit寬編碼,由兩個連續16bit半字組合而成,要求半字對齊

第一個半字的高三位固定為111,Op2位段決定指令類型,

如果op1 == 00,那么表示會被編碼位16bit指令,否則是32bit指令

Rd/Rn寬度為4bit,寄存器可訪問范圍R0-R14

 

6.4.4 A64編碼

 ADD指令為例

固定32bit寬編碼,若sf == 0則表示32bit指令,否則表示64bit指令

Rd/Rn寬度為5bit,寄存器可訪問范圍X0-X30

對比A32指令很少cond位.

詳細參考Datasheet C4章節.

 

6.4 匯編代碼分析

• 以memcpy.S為例,分析筆記如下:

http://note.youdao.com/share/?id=f7976e6571ceae443da4e36d28842dcb&type=note

 

                                    7章 流水線

7.1 簡介

1、不能減少單指令的響應時間,和single-cycle指令的響應時間是相同的

2、多指令同時使用不同資源,可提升整體單cycle內的指令吞吐量,極大提高指令執行效率

3、指令執行速率被最慢的流水線級所限制,執行效率被依賴關系限制影響

7.1.1 簡單三級流水線

IF

Instruction fetch

取指

ID

Instruction decode & register file read

譯碼 & 讀取寄存器堆數據

EX

Execution or address calculation

執行 or 地址計算

 

圖示:

 

7.1.2 經典五級流水線

IF

Instruction fetch

取指

ID

Instruction decode & register file read

譯碼 & 讀取寄存器堆數據

EX

Execution or address calculation

執行 or 地址計算

MEM

Data memeory access

讀寫內存數據

WB

Write back

數據寫回到寄存器堆

 

圖示:

 

7.2 流水線沖突

類型

Note

解決方法

結構沖突

不同指令同時占用問儲器資源沖突,早期處理器程序、數據存儲器混合設計產生的問題。

分離程序、數據存儲器,現代處理器已不存在這種沖突

 

數據沖突

不同指令同時訪問同一寄存器導致,通常發生在寄存器 RAW(read after write)的情況下,

WAR(write after read) & WAW(write after write) 的情況再ARM不會發生.

• SW插入NOP,增加足夠的cycle等待,但是對CPU性能有大影響

• HW 使用forwarding(直通)解決,對性能影響小

 

控制沖突

B指令跳轉,導致其后面的指令的fetch等操作變成無用功,因此跳轉指令會極大影響CPU性能.

• SW插入NOP,增加足夠的cycle等待,同樣對CPU性能有大影響

 使用分支預測算法來減少跳轉帶來的性能損失

 

7.3 指令並行

• 指令並行提升方法

1、增加單條流水線深度,若是N級流水線,那么在single-cycle內有N條指令被執行.

2、Pipeline並行,若有M條流水線,每條流水線深度為N,那么single-cycle內有M*N條指令被執行,極大提升指令執行效率.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM