<?xml version="1.0" encoding="gbk"?> <rss version="2.0"><channel> <title>定阅帖子更新</title> <link>http://www.broadkey.com.cn/XML.ASP</link><description>TEAM Board - 意得法电子</description> <copyright>TEAM 2.0.5 Release</copyright><generator>TEAM Board by TEAM5.Cn Studio</generator> <ttl>30</ttl><item><link>http://www.broadkey.com.cn/Thread.asp?tid=46 </link><title>PowerPC&amp;nbsp;体系结构之指令集</title><author>east</author><pubDate>2009-11-25 23:32:01</pubDate><description><![CDATA[<strong><font color="#ff6600">1. 概述<br />
<br />
</font></strong>Book E 定义的 PowerPC 指令集的指令可分为以下几类：<br />
<br />
分支跳转指令<br />
CR 指令<br />
整数指令<br />
浮点指令<br />
处理器控制指令<br />
存储管理相关指令<br />
<br />
CR 指令主要是对 CR 内部位运算支持的一些指令，如 crand, cror, crxor 等等。<br />
<br />
<br />
<font color="#009900"><strong>2. 常用指令</strong></font><br />
<br />
先看一个测试程序：<br />
<br />
------------------------------------------------------------------<br />
<br />
int test_call(int a, int b, int c)<br />
{<br />
a = b + c;<br />
return a;<br />
}<br />
<br />
int test_if(int s)<br />
{<br />
int i;<br />
if(s &gt; 0)<br />
i = s;<br />
else if(s &lt; 0)<br />
i = -s;<br />
else<br />
i = s * 8;<br />
return i;<br />
}<br />
<br />
int test_cyc1(int c)<br />
{<br />
int sum = 0;<br />
do {<br />
sum += c;<br />
c--;<br />
} while(c &gt; 0);<br />
return c;<br />
}<br />
<br />
int test_cyc2(int c)<br />
{<br />
int sum = 0;<br />
for(; c &gt; 0; c--)<br />
sum += c;<br />
<br />
return c;<br />
}<br />
<br />
int main()<br />
{<br />
int a, b, c, d;<br />
a = test_if(5);<br />
b = test_cyc1(10);<br />
c = test_cyc2(10);<br />
d = test_call(1, 2, 3);<br />
return a + b + c + d;<br />
}<br />
<br />
------------------------------------------------------------------<br />
<br />
引入的目的在于查看判断、循环和过程调用这些基本结构在 PowerPC 里怎么被支持。<br />
<br />
-O2 参数编译后，objdump -S -d 反汇编，则：<br />
<br />
------------------------------------------------------------------<br />
<br />
1000040c <font color="#ff6600"><strong>&lt;test_call&gt;</strong></font>:<br />
int test_call(int a, int b, int c)<br />
{<br />
a = b + c;<br />
return a;<br />
}<br />
1000040c:&nbsp;&nbsp;&nbsp; 7c 64 2a 14 &nbsp;&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp; r3,r4,r5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ----&gt; 对应 a, b, c 三个参数，同时 r3 又置返回值<br />
10000410:&nbsp;&nbsp;&nbsp; 4e 80 00 20 &nbsp;&nbsp;&nbsp; blr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ----&gt; 跳转到 LR 所存放的地址处，即函数返回<br />
<br />
10000414 <font color="#99cc00"><strong>&lt;test_if&gt;</strong></font>:<br />
int test_if(int s)<br />
{<br />
int i;<br />
if(s &gt; 0)<br />
10000414:&nbsp;&nbsp;&nbsp; 7c 60 1b 79 &nbsp;&nbsp;&nbsp; mr<font color="#ff0000"><strong>.</strong></font>&nbsp;&nbsp;&nbsp;&nbsp; r0,r3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -----&gt; r3 移到 r0，若 r0 小于、大于、等于 0，则置 CR0 的相应位。指令后多一点，则说明该指令会据执行结果，设置 CR 的相应位<br />
10000418:&nbsp;&nbsp;&nbsp; 7c 03 03 78 &nbsp;&nbsp;&nbsp; mr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r3,r0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -----&gt; 此条指令多余<br />
1000041c:&nbsp;&nbsp;&nbsp; 4d a1 00 20 &nbsp;&nbsp;&nbsp; bgtlr+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -----&gt; 若 CR0[gt] 位为 1，则跳转到 LR 所存放的地址处，即直接函数返回了。此条指令等价于 bclr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13, 1<br />
i = s;<br />
else if(s &lt; 0)<br />
10000420:&nbsp;&nbsp;&nbsp; 38 60 00 00 &nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r3,0<br />
10000424:&nbsp;&nbsp;&nbsp; 4d 82 00 20 &nbsp;&nbsp;&nbsp; beqlr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -----&gt; 若 CR0[eq] 位为 1，则跳转到 LR 所存放的地址处，也直接函数返回了。此条指令等价于 bclr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12, 2<br />
i = -s;<br />
10000428:&nbsp;&nbsp;&nbsp; 7c 60 00 d0 &nbsp;&nbsp;&nbsp; neg&nbsp;&nbsp;&nbsp;&nbsp; r3,r0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; -----&gt; r0 取反，入 r3<br />
else<br />
i = s * 8;<br />
return i;<br />
}<br />
1000042c:&nbsp;&nbsp;&nbsp; 4e 80 00 20 &nbsp;&nbsp;&nbsp; blr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; -----&gt; 跳转到 LR 所存放的地址处，函数返回<br />
<br />
10000430 <font color="#ff9900"><strong>&lt;test_cyc1&gt;</strong></font>:<br />
int test_cyc1(int c)<br />
{<br />
10000430:&nbsp;&nbsp;&nbsp; 34 03 ff ff &nbsp;&nbsp;&nbsp; addic. r0,r3,-1<br />
10000434:&nbsp;&nbsp;&nbsp; 7c 69 03 a6 &nbsp;&nbsp;&nbsp; mtctr&nbsp;&nbsp; r3<br />
10000438:&nbsp;&nbsp;&nbsp; 41 80 00 10 &nbsp;&nbsp;&nbsp; blt-&nbsp;&nbsp;&nbsp; 10000448 &lt;test_cyc1+0x18&gt;<br />
int sum = 0;<br />
do {<br />
sum += c;<br />
c--;<br />
1000043c:&nbsp;&nbsp;&nbsp; 38 63 ff ff &nbsp;&nbsp;&nbsp; addi&nbsp;&nbsp;&nbsp; r3,r3,-1<br />
} while(c &gt; 0);<br />
10000440:&nbsp;&nbsp;&nbsp; 42 00 ff fc &nbsp;&nbsp;&nbsp; bdnz+&nbsp;&nbsp; 1000043c &lt;test_cyc1+0xc&gt;<br />
return c;<br />
}<br />
10000444:&nbsp;&nbsp;&nbsp; 4e 80 00 20 &nbsp;&nbsp;&nbsp; blr<br />
10000448:&nbsp;&nbsp;&nbsp; 38 00 00 01 &nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r0,1<br />
1000044c:&nbsp;&nbsp;&nbsp; 7c 09 03 a6 &nbsp;&nbsp;&nbsp; mtctr&nbsp;&nbsp; r0<br />
10000450:&nbsp;&nbsp;&nbsp; 4b ff ff ec &nbsp;&nbsp;&nbsp; b&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1000043c &lt;test_cyc1+0xc&gt;<br />
<br />
10000454 <font color="#800080"><strong>&lt;test_cyc2&gt;</strong></font>:<br />
int test_cyc2(int c)<br />
{<br />
10000454:&nbsp;&nbsp;&nbsp; 2c 03 00 00 &nbsp;&nbsp;&nbsp; cmpwi&nbsp;&nbsp; r3,0<br />
10000458:&nbsp;&nbsp;&nbsp; 39 20 00 00 &nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r9,0<br />
1000045c:&nbsp;&nbsp;&nbsp; 7d 23 48 1e &nbsp;&nbsp;&nbsp; .long 0x7d23481e<br />
int sum = 0;<br />
for(; c &gt; 0; c--)<br />
sum += c;<br />
return c;<br />
}<br />
10000460:&nbsp;&nbsp;&nbsp; 7d 23 4b 78 &nbsp;&nbsp;&nbsp; mr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r3,r9<br />
10000464:&nbsp;&nbsp;&nbsp; 4e 80 00 20 &nbsp;&nbsp;&nbsp; blr<br />
<br />
<font color="#3366ff"><strong>int main()</strong></font><br />
{<br />
10000468:&nbsp;&nbsp; 94 21 ff e0&nbsp;&nbsp;&nbsp;&nbsp; stwu&nbsp;&nbsp;&nbsp; r1,-32(r1)<br />
1000046c:&nbsp;&nbsp; 7c 08 02 a6&nbsp;&nbsp;&nbsp;&nbsp; mflr&nbsp;&nbsp;&nbsp; r0<br />
int a, b, c, d;<br />
a = test_if(5);<br />
10000470:&nbsp;&nbsp; 38 60 00 05&nbsp;&nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r3,5<br />
10000474:&nbsp;&nbsp; 90 01 00 24&nbsp;&nbsp;&nbsp;&nbsp; stw&nbsp;&nbsp;&nbsp;&nbsp; r0,36(r1)<br />
10000478:&nbsp;&nbsp; 93 61 00 0c&nbsp;&nbsp;&nbsp;&nbsp; stw&nbsp;&nbsp;&nbsp;&nbsp; r27,12(r1)<br />
1000047c:&nbsp;&nbsp; 93 81 00 10&nbsp;&nbsp;&nbsp;&nbsp; stw&nbsp;&nbsp;&nbsp;&nbsp; r28,16(r1)<br />
10000480:&nbsp;&nbsp; 93 a1 00 14&nbsp;&nbsp;&nbsp;&nbsp; stw&nbsp;&nbsp;&nbsp;&nbsp; r29,20(r1)<br />
10000484:&nbsp;&nbsp; 4b ff ff 91&nbsp;&nbsp;&nbsp;&nbsp; bl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10000414 &lt;test_if&gt;<br />
10000488:&nbsp;&nbsp; 7c 7d 1b 78&nbsp;&nbsp;&nbsp;&nbsp; mr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r29,r3<br />
b = test_cyc1(10);<br />
1000048c:&nbsp;&nbsp; 38 60 00 0a&nbsp;&nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r3,10<br />
10000490:&nbsp;&nbsp; 4b ff ff a1&nbsp;&nbsp;&nbsp;&nbsp; bl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10000430 &lt;test_cyc1&gt;<br />
10000494:&nbsp;&nbsp; 7c 7b 1b 78&nbsp;&nbsp;&nbsp;&nbsp; mr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r27,r3<br />
c = test_cyc2(10);<br />
10000498:&nbsp;&nbsp; 38 60 00 0a&nbsp;&nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r3,10<br />
d = test_call(1, 2, 3);<br />
1000049c:&nbsp;&nbsp; 7f bd da 14&nbsp;&nbsp;&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp; r29,r29,r27<br />
100004a0:&nbsp;&nbsp; 4b ff ff b5&nbsp;&nbsp;&nbsp;&nbsp; bl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10000454 &lt;test_cyc2&gt;<br />
100004a4:&nbsp;&nbsp; 38 80 00 02&nbsp;&nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r4,2<br />
100004a8:&nbsp;&nbsp; 7c 7c 1b 78&nbsp;&nbsp;&nbsp;&nbsp; mr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r28,r3<br />
100004ac:&nbsp;&nbsp; 38 a0 00 03&nbsp;&nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r5,3<br />
100004b0:&nbsp;&nbsp; 38 60 00 01&nbsp;&nbsp;&nbsp;&nbsp; li&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r3,1<br />
100004b4:&nbsp;&nbsp; 4b ff ff 59&nbsp;&nbsp;&nbsp;&nbsp; bl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1000040c &lt;test_call&gt;<br />
return a + b + c + d;<br />
}<br />
100004b8:&nbsp;&nbsp; 80 01 00 24&nbsp;&nbsp;&nbsp;&nbsp; lwz&nbsp;&nbsp;&nbsp;&nbsp; r0,36(r1)<br />
100004bc:&nbsp;&nbsp; 7f 9c 1a 14&nbsp;&nbsp;&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp; r28,r28,r3<br />
100004c0:&nbsp;&nbsp; 83 61 00 0c&nbsp;&nbsp;&nbsp;&nbsp; lwz&nbsp;&nbsp;&nbsp;&nbsp; r27,12(r1)<br />
100004c4:&nbsp;&nbsp; 7c 7d e2 14&nbsp;&nbsp;&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp; r3,r29,r28<br />
100004c8:&nbsp;&nbsp; 83 81 00 10&nbsp;&nbsp;&nbsp;&nbsp; lwz&nbsp;&nbsp;&nbsp;&nbsp; r28,16(r1)<br />
100004cc:&nbsp;&nbsp; 83 a1 00 14&nbsp;&nbsp;&nbsp;&nbsp; lwz&nbsp;&nbsp;&nbsp;&nbsp; r29,20(r1)<br />
100004d0:&nbsp;&nbsp; 7c 08 03 a6&nbsp;&nbsp;&nbsp;&nbsp; mtlr&nbsp;&nbsp;&nbsp; r0<br />
100004d4:&nbsp;&nbsp; 38 21 00 20&nbsp;&nbsp;&nbsp;&nbsp; addi&nbsp;&nbsp;&nbsp; r1,r1,32<br />
100004d8:&nbsp;&nbsp; 4e 80 00 20&nbsp;&nbsp;&nbsp;&nbsp; blr<br />
<br />
------------------------------------------------------------------<br />
<br />
<br />
<font color="#3399ff"><strong>3. 分类概述<br />
<br />
3.1 分支跳转指令</strong></font><br />
<br />
这类指令算是 PowerPC 里比较有特色的，也是稍显复杂的。这类指令与 CR, LR 和 CTR 紧密相联，建构起判断、循环和过程调用这些程序的基本结构。其大致可分为四类：<br />
<br />
Branch<br />
Branch Conditional<br />
Branch Conditional to Count Register<br />
Branch Conditional to Link Register<br />
<strong><br />
<br />
3.1.1 Branch</strong><br />
<br />
这类指令与 CR 没有联系，即为非条件跳转，助记符后直接跟立即数地址。指令内为立即数地址预留 26 位，即可跳转 2^26 大小的空间，如：(CIA, Current Instruction Address)<br />
<br />
b&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; 0x20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -----&gt; 以当前指令地址为基点，往后跳转 0x20 字节，即 PC = CIA + 0x20<br />
ba&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 0x20&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; -----&gt; 直接跳转到地址 0x20 处。<strong>后缀为 a，则表示使用 Absolute Address，PC = 0x20</strong>。<br />
bl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x20&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; -----&gt; 在 b 0x20 的基础上，将 LR 更新为 CIA + 4<br />
bla&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x20&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; -----&gt; 使用绝对地址，且更新 LR。<strong>后缀带 l，则表示更新 LR 为 CIA + 4</strong><br />
<br />
以上针对 32 位的情形，对 64 位则使用指令 be, bea, bel, bela 功能与上同。<br />
<br />
<br />
<strong>3.1.2 Branch Conditional</strong><br />
<br />
此类为条件跳转指令。皆以 bc 开头，带 3 个操作数，如：<br />
<br />
bc &nbsp;&nbsp; BO, BI, BD<br />
bca&nbsp;&nbsp;&nbsp; BO, BI, BD<br />
bcl&nbsp;&nbsp;&nbsp; BO, BI, BD<br />
bcla&nbsp;&nbsp; BO, BI, BD<br />
<br />
后缀 a, l 的含义与 branch 类指令同。BO 指定跳转的条件，5 位；BI 指定关联的 CR 位，也是 5 位；BD 为跳转的立即数地址，16 位。<br />
<br />
其中以 BO 的编码最为复杂（BO 从左到右编号为 0 ~ 4）：<br />
<br />
BO[0]: 为 1，则直接跳转<br />
BO[1]: 为 1，则条件为真时，跳转。否则条件为假时，跳转<br />
BO[2]: 为 1，则 CTR 不自动减 1<br />
BO[3]: 为 1 时，则 CTR == 0 时跳转；为 0 时，则 CTR != 0 时跳转<br />
BO[4]: 静态预测位，1 表示 unlikely，0 表示 likely <br />
<br />
则常见的 BO 值：<br />
20 (0b10100) 则表示无条件跳转<br />
12 (0b01100) 则表示 CR 的某个位为 1 时跳转<br />
4 (0b00100) 则表示 CR 的某个位为 0 时跳转<br />
<br />
至于静态预测的策略位，默认被置为<strong> 0</strong>，则其行为为：<br />
<br />
b1. 目标地址小于当前指令地址，预测为<font color="#ff9900">跳转</font> <br />
b2. 目标地址大于当前指令地址，预测为<font color="#ff9900">不跳转</font><br />
b3. 对于目标地址在 CTR/LR 中的条件跳转指令，一律预测为<font color="#ff9900">不跳转</font><br />
<br />
若该位被置 <strong>1</strong>，则上述 b1, b2, b3 的静态预测行为分别为：<font color="#99cc00">不跳转</font>，<font color="#99cc00">跳转</font>，<font color="#99cc00">跳转</font>。<br />
<br />
可以给分支指令加一个 +/- 的后缀，来简化。加 '+' 的指令，一律预测为跳转。加 '-' 的分支指令，一律预测为不跳转。<br />
<br />
则对于 b1，后缀 '+' 会将 y 位置 0，'-' 则将 y 位置 1。<br />
对于 b2，后缀 '+' 会将 y 位置 1，'-' 则将 y 位置 0。<br />
对于 b3，后缀 '+' 会将 y 位置 1，'-' 则将 y 位置 0。<br />
<br />
<br />
BI 与关联 CR 位的关系为：<br />
<br />
32 + BI<br />
<br />
即，若 BI 为 2，则对应于 CR[34]，即为 CR0[gt] 位。<br />
<br />
以上针对 32 位的情形，对 64 位则使用指令 bce, bcea, bcel, bcela 功能与上同。<br />
<br />
<br />
<strong>3.1.3 Branch Conditional to Count Register</strong><br />
<br />
bcctr&nbsp;&nbsp;&nbsp;&nbsp; BO, BI<br />
bcctrl&nbsp;&nbsp;&nbsp; BO, BI<br />
<br />
后缀 l 的含义与 branch 类指令同。<br />
BO，BI 的编码与 Branch Conditional 类指令同。<br />
跳转目标地址位于 CTR 中。<br />
<br />
以上针对 32 位的情形，对 64 位则使用指令 bcctre, bcctrel 功能与上同。<br />
<br />
<br />
<strong>3.1.4 Branch Conditional to Link Register</strong><br />
<br />
bclr&nbsp;&nbsp;&nbsp;&nbsp; BO, BI<br />
bclrl&nbsp;&nbsp;&nbsp; BO, BI<br />
<br />
后缀 l 的含义与 branch 类指令同。<br />
BO，BI 的编码与 Branch Conditional 类指令同。<br />
跳转目标地址位于 LR 中。<br />
<br />
以上针对 32 位的情形，对 64 位则使用指令 bclre, bclrel 功能与上同。<br />
<br />
<font color="#3399ff"><strong><br />
3.2 CR 指令</strong></font><br />
<br />
这类指令包括用来支持 CR 内部位运算的指令和 CR 与 GPR 之间的数据交换指令。<br />
<br />
<strong>3.2.1 CR 内</strong><strong>位运算指令</strong><br />
<br />
这类指令的格式皆为：&nbsp;&nbsp; crxxx&nbsp;&nbsp;&nbsp; BT, BA, BB<br />
<br />
BT, BA, BB 是 CR 内的位编号，取值范围为 0 ~ 31，如 crand&nbsp;&nbsp;&nbsp; 0, 8, 12，则将 CR[32+8] (CR2[lt]) 与 CR[32+12] (CR3[lt]) 作与操作后，将结果置入 CR[32+0] (CR0[lt])，即 CR[32] = CR[40] &amp; CR[44]<br />
<br />
crand:&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; CR[32+BA] &amp; CR[32+BB]<br />
crandc:&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; CR[32+BA] &amp; (~CR[32+BB])<br />
creqv:&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; ~(CR[32+BA] ^ CR[32+BB])，即位相等，则置 1；不等则置 0<br />
crnand: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ~(CR[32+BA] &amp; CR[32+BB])<br />
crnor:&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ~(CR[32+BA] | CR[32+BB])<br />
cror:&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CR[32+BA] | CR[32+BB]<br />
crorc:&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CR[32+BA] | (~CR[32+BB])，先取反后再或<br />
crxor:&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CR[32+BA] ^ CR[32+BB]，位异或<br />
<br />
<br />
<strong>3.2.2 CR 与 GPR 间</strong><strong>数据交换指令</strong><br />
<strong><br />
3.2.2.1</strong> mcrf&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; BF, BFA&nbsp;&nbsp; ---&nbsp;&nbsp; Move Condition Register Fields<br />
<br />
将 CR 之 BFA 域复制到 BF 域。如 mcrf&nbsp;&nbsp;&nbsp; 0, 3 则将 CR3 拷入 CR0<br />
<br />
<strong><br />
3.2.2.2</strong> mtcrf&nbsp;&nbsp; &nbsp;&nbsp; FXM, RS&nbsp;&nbsp; ---&nbsp;&nbsp; Move To Condition Register Fields<br />
<br />
通用寄存器 RS 之 32 ~ 63 位以 4 位为单位，对应于 CR 的 8 个域，编号为 RS0 ~ RS7；<br />
FXM 为域掩码，8 位，从左到右编号为 0 ~ 7，对应于 RS、CR 的 8 个域。某位为 1，则将对应的 RS 域拷贝到对应的 CR 域中。<br />
若 FXM 为 0x80，则只将 CR0 = RS0<br />
若 FXM 为 0xc8，则将 CR0 = RS0, CR1 = RS1, CR4 = RS4<br />
<br />
<strong>3.2.2.3</strong> mfcr&nbsp;&nbsp; &nbsp;&nbsp; RT&nbsp;&nbsp; ---&nbsp;&nbsp; Move From Condition Register<br />
<br />
将 CR 的内容移入通用寄存器 RT 的 32 ~ 63 位。<br />
<br />
<br />
<font color="#3399ff"><strong>3.3 整数指令</strong></font><br />
<br />
这类指令大致分为如下几类：<br />
<br />
整数访存指令<br />
整数算术运算指令<br />
整数逻辑运算指令<br />
整数比较指令<br />
整数陷阱指令<br />
整数移位指令<br />
XER 指令<br />
<br />
其中以整数循环移位指令最为特别。<br />
<br />
<strong>3.3.1 整数访存指令</strong><br />
<br />
<strong>3.3.1.1</strong> Load Byte/Half-word/Word and Zero<br />
<br />
该类指令从指定地址处读取 8 位、16 位、32 位数据，置入 RT，RT 高位置 0<br />
<br />
lbz/lbzu&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RT, D(RA)<br />
lbzx/lbzux&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RT, RA, RB<br />
<br />
lhz/lhzu&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RT, D(RA)<br />
lhzx/lhzux&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RT, RA, RB<br />
<br />
lwz/lwzu&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RT, D(RA)<br />
lwzx/lwzux&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RT, RA, RB<br />
<br />
RT, RA, RB 皆为 GPR，D 为有符号立即数。则有效地址的计算分别为：RA[32:63] + D，RA[32:63] + RB[32:63]，有效地址高 32 位置 0。<br />
<br />
后缀 u 表示 Update，即将有效地址更新到 RA 中<br />
后缀 x 表示 Indexed，即使用 RA + RB 的寻址方式<br />
<br />
以上用于 32 位，对 64 位，上述指令皆加后缀 'e'。则有效地址的 0 ~ 31 位， 不再置 0，其计算方式如下：RA + D，RA + RB。<br />
<br />
此外，用于 64 位的还有对双字操作的支持：<br />
<br />
lde/ldue/ldxe/lduxe<br />
<em><br />
<br />
</em><strong>3.3.1.2</strong> Load Half-word Algebraic<br />
<br />
lha/lhau&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RT, D(RA)<br />
lhax/lhaux&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RT, RA, RB<em><br />
<br />
</em>与 lhz 不同的是，该指令将所读取的半字的最高位 (RT[48]) 填充到 RT[32:47]，实际上就是形成一个 16 位的补码有符号数。<br />
<br />
有效地址计算与上同；后缀 u, x 与上同。<br />
<br />
对 64 位情形，上述指令皆加后缀 'e'，有效地址计算与上小节同。<br />
<em><br />
<br />
</em><strong>3.3.1.3</strong> <font color="#808000">Load Halfword/Word Byte-Reverse</font><strong><br />
<br />
</strong>从指定地址处读取 16 位/32 位数据，将字节反转后置入 RT，RT 高位置 0<br />
<strong><br />
</strong>&nbsp;&nbsp;&nbsp; lhbrx&nbsp;&nbsp; RT, RA, RB<br />
lwbrx&nbsp;&nbsp; RT, RA, RB<br />
<br />
如： lwbrx&nbsp;&nbsp; r3, r2, r1，若 r2 + r1 地址处的数据为 0x55aa66bb，则 r3 的结果为 0xbb66aa55<br />
<br />
对 64 位情形，上述指令皆加后缀 'e'，有效地址计算与上小节同。<br />
<br />
<br />
<strong>3.3.1.4</strong> <font color="#99cc00">Load Multiple Word</font><br />
<br />
lmw&nbsp;&nbsp;&nbsp; RT, D(RA)<br />
<br />
该指令将 RA + D 开始处的数据，顺序置入 RT ~ R31 中，共读取 31 - T 个字<br />
<br />
该指令无 64 位扩展。<br />
<br />
<br />
<strong>3.3.1.5</strong> <font color="#99cc00">Load String Word</font><br />
<br />
lswi&nbsp;&nbsp;&nbsp; RT, RA, NB&nbsp;&nbsp; &nbsp;&nbsp; （后缀 i，表示立即数 Immediate）<br />
lswx&nbsp;&nbsp;&nbsp; RT, RA, RB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （后缀 x，表示 Indexed 寻址方式）<br />
<br />
加载 n 个字节到 RT 开始的寄存器中；<br />
当 NB == 0 时 n = 32； NB != 0 时 n = NB，NB 取值范围为 0 ~ 31<br />
<br />
如 r3 = 0x1000 ： <br />
<br />
lswi&nbsp;&nbsp; r4, r3, 16&nbsp;&nbsp; <br />
<br />
则将 0x1000 处的 16 字节，依次写入 r4, r5, r6, r7<br />
<br />
对于 lswx，要加载的字节数则位于 XER[57:63]<br />
<br />
该指令无 64 位扩展。<br />
<br />
<br />
<strong>3.3.1.6</strong> <font color="#009900">Load Word/Doubleword and Reserve</font><br />
<br />
lwarx&nbsp;&nbsp;&nbsp; RT, RA, RB<br />
<br />
该指令与 lwzx 的差别在于，其还将处理器内部的 RESERVE 位置为 1，并将有效地址对应的物理地址放入 RESERVE_ADDR 中。<br />
<br />
该指令的 64 位版本为： lwarxe&nbsp;&nbsp; RT, RA, RB，差别还是在于有效地址的 0 ~ 31 不被置 0<br />
<br />
此外还有一个 ldarxe&nbsp;&nbsp; RT, RA, RB，与 lwarxe 的差别在于其加载 8 字节的数据。<br />
<br />
这三条指令常分别与 stwcx./stwcxe./stdcxe. 联用，用于实现锁操作，类似 MIPS 之 ll/sc 指令。<br />
<br />
<br />
<strong>3.3.1.7 </strong>Store<strong> </strong><br />
<br />
stb/stbu&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RS, D(RA)<br />
stbx/stbux&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RS, RA, RB<br />
sth/sthu&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RS, D(RA)<br />
sthx/sthux&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RS, RA, RB<br />
stw/stwu&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RS, D(RA)<br />
stwx/stwux&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RS, RA, RB<br />
<br />
该类指令将 RS 中的 8 位、16 位、32 位数据写入有效地址处。后缀 'u', 'x' 之含义与 3.3.1.1 同。<br />
<br />
上述 12 条指令加后缀 'e' 则用于 64 位。有效地址计算与与 3.3.1.1 同。<br />
<br />
另用于 64 位的还有对双字操作的支持：<br />
<br />
stde/stdue/stdxe/stduxe<br />
<br />
<br />
<strong>3.3.1.8</strong> <font color="#ffcc00">Store Halfword/Word Byte-Reverse</font><br />
<br />
sthbrx RS, RA, RB<br />
stwbrx RS, RA, RB<br />
<br />
将 RS 中的 16/32 bit 的数据字节反转后置入有效地址处。该指令用于支持在大端系统上以小端序存储数据，亦或在小端系统上以大端序存储数据。<br />
<br />
对 64 位情形，上述指令皆加后缀 'e'，有效地址计算与上小节同。<br />
<br />
<br />
<strong>3.3.1.9</strong> <font color="#ff9900">Store Multiple Word</font><br />
<br />
smw&nbsp;&nbsp; RS, D(RA)<br />
<br />
该指令将 RS ~ R31 中的数据 （一个字），写入到 RA + D 处<br />
<br />
该指令无 64 位扩展。<br />
<br />
<br />
<strong>3.3.1.10</strong> <font color="#ff9900">Store String Word</font><br />
<br />
stswi&nbsp;&nbsp; &nbsp;&nbsp; RS, RA, NB &nbsp;&nbsp; （后缀 i，表示立即数 Immediate）<br />
stswx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RS, RA, RB &nbsp;&nbsp; （后缀 x，表示 Indexed 寻址方式）<br />
<br />
与 lswi/lswx 的操作相反，其将 RS 开始的寄存器组中的 n 个字节，写入到有效地址处（位于 RA）<br />
<br />
当 NB == 0 时 n = 32； NB != 0 时 n = NB，NB 取值范围为 0 ~ 31<br />
<br />
如 r3 = 0x1000 ： <br />
<br />
stswi&nbsp;&nbsp; r4, r3, 16&nbsp;&nbsp; <br />
<br />
则将 r4, r5, r6, r7 中的 16 字节数据依次写入 0x1000 处 <br />
<br />
对于 stswx，要加载的字节数则位于 XER[57:63]<br />
<br />
该指令无 64 位扩展。<br />
<br />
<br />
<strong>3.3.1.11</strong> <font color="#ff6600">Store Word/Doubleword Conditional</font><br />
<br />
stwcx.&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RS, RA, RB<br />
<br />
如果 RESERVE 位为 1，且 RA + RB 对应的物理地址与 RESERVE_ADDR 一致，则将 RS[32:63] 的内容写入到 RA + RB 处，将 CR0[eq] 位置为 1 后，再将 RESERVE 位复位为 0。<br />
<br />
若条件不满足，则仅将 CR0[eq] 位置为 0<br />
<br />
可用该指令与 lwarx 联用，实现 spin_lock：<br />
<br />
li&nbsp;&nbsp; r0, 1<br />
loop:<br />
lwarx&nbsp;&nbsp; r4, 0, r3<br />
cmpwi&nbsp;&nbsp; r4, 0&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; # r4[32:63] 与 0 比较<br />
bne loop<br />
stwcw.&nbsp;&nbsp; r0, 0, r3<br />
bne&nbsp;&nbsp; loop<br />
isync<br />
<br />
解锁则为：<br />
<br />
msync<br />
li&nbsp;&nbsp; r0, 0<br />
stw&nbsp;&nbsp; r0, 0(r3)<br />
<br />
<br />
下面的指令用于 64 位：<br />
<br />
stwcxe. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RS, RA, RB<br />
stdcxe. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RS, RA, RB<br />
<br />
差别在于有效地址的高 32 位不再被置为 0。<br />
<br />
<br />
<strong>3.3.2 整数算术运算指令</strong><br />
<br />
<br />
<br />
<strong>3.3.3 整数逻辑运算指令</strong><br />
<br />
<br />
<strong><br />
3.3.4 整数比较指令</strong><br />
<br />
cmp&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BF, L, RA, RB&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <br />
cmpi&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BF, L, RA, SI &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; # RA 与有符号立即数 SI 比较<br />
cmpl&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BF, L, RA, RB&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; # RA, RB 逻辑比较。l ---&gt; logical<br />
cmpli&nbsp;&nbsp; &nbsp;&nbsp; BF, L, RA, UI &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; # RA 与无符号立即数 UI 逻辑比较<br />
<br />
BF 取值 0 ~ 7，用于指定使用的 CR 域<br />
L 为 0，则为 32 位比较；为 1，则为 64 位比较<br />
<br />
如：<br />
<br />
cmpi&nbsp;&nbsp; &nbsp;&nbsp; 0, 0, r3, 5<br />
<br />
若 r3 &gt; 5，则 CR0[gt] = 1；若 r3 &lt; 5，则 CR0[lt] = 1<br />
<br />
<br />
<strong>3.3.5 整数陷阱指令</strong><br />
<br />
tw&nbsp;&nbsp; &nbsp;&nbsp; TO, RA, RB<br />
twi&nbsp;&nbsp; TO, RA, SI<br />
<br />
TO 为立即数，5 位，从左到右标号为 0 ~ 4，依次表示小于、大于、等于、无符号小于、无符号大于。用于指定 Trap 的条件。<br />
SI： Signed Immediate<br />
<br />
如：<br />
<br />
twi&nbsp;&nbsp; 0x10, r3, 5<br />
<br />
则如果 r3 &lt; 5，则陷入异常。<br />
<br />
以上用于单字 (32 bit) 比较，双字比较则用：<br />
<br />
td&nbsp;&nbsp; &nbsp;&nbsp; TO, RA, RB<br />
tdi&nbsp;&nbsp; TO, RA, SI<br />
<br />
<strong><br />
3.3.6 整数移位指令</strong><br />
<br />
<strong>3.3.6.1</strong> <font color="#99cc00"><strong>Rotate</strong></font><br />
<br />
rlwimi&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RA, RS, SH, MB, ME&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; # Rotate Left Word Immediate then Mask Insert<br />
rlwinm&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RA, RS, SH, MB, ME&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; # Rotate Left Word Immediate then AND with Mask<br />
rlwnm&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; RA, RS, RB, MB, ME&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; # Rotate Left Word then AND with Mask<br />
<br />
以下是该指令的一些例子：<br />
<br />
all r11 is: 0x55aa67bb<br />
<br />
r0 = 0x00000000<br />
rlwimi&nbsp;&nbsp;&nbsp; r0, r11, 8, 0, 31<br />
r0 is: 0xaa67bb55<br />
<br />
r0 = 0x12345678<br />
rlwimi&nbsp;&nbsp;&nbsp; r0, r11, 8, 0, 14<br />
r0 is: 0xaa665678<br />
<br />
r0 = 0x1<font color="#99cc00">234567</font>8<br />
rlwimi&nbsp;&nbsp;&nbsp; r0, r11, 8, 28, 3<br />
r0 is: 0xa<font color="#99cc00">234567</font>5<br />
<br />
即：取 RS 循环左移 SH 位后的 WB 到 WE 位，替换 RA 的 WB 到 WE 位。<br />
<br />
r0 = 0x00000000<br />
rlwinm&nbsp;&nbsp;&nbsp; r0, r11, 8, 0, 31<br />
r0 is: 0xaa67bb55<br />
<br />
r0 = 0x12345678<br />
rlwinm&nbsp;&nbsp;&nbsp; r0, r11, 8, 0, 14<br />
r0 is: 0xaa660000<br />
<br />
即：取 RS 循环左移 SH 位后的 WB 到 WE 位，替换归零后的 RA<br />
<br />
rldcl<br />
rldcr<br />
rldic<br />
rldicl<br />
rldicr<br />
rldimi<br />
<br />
<strong>3.3.6.2</strong> Shift<br />
<br />
slw<br />
srw<br />
sraw<br />
srawi<br />
<br />
slw./srw./sraw./srawi.<br />
<br />
sld<br />
srd<br />
srad<br />
sradi<br />
<br />
<br />
<strong>3.3.7 XER 指令</strong><br />
<br />
mcrxr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BF<br />
mcrxr64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BF<br />
<br />
<br />
<font color="#3399ff"><strong>3.4 浮点指令</strong></font><br />
<br />
这类指令包括：<br />
<br />
浮点数据加载与存储指令<br />
浮点运算指令<br />
浮点数近似和转化指令<br />
浮点比较指令<br />
浮点状态和控制寄存器指令<br />
<br />
有关该指令的详情留待以后以《PowerPC 浮点结构》的形式讨论吧。<br />
<br />
<font color="#3399ff"><strong>3.5 处理器控制指令</strong></font><br />
<br />
这类指令包括用于支持异常中断处理的：<br />
<br />
sc&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; System Call<br />
rfci&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Return From Critical Interrupt<br />
rfi&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; Return From Interrup<br />
<br />
用于处理器控制寄存器维护的：<br />
<br />
mfspr&nbsp;&nbsp; &nbsp;&nbsp; RT, SPRN&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; Move From SPRN (Special Purpose Register) to RT<br />
mtspr&nbsp;&nbsp; &nbsp;&nbsp; SPRN, RS&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; Move RS To SPRN<br />
<br />
mfdcr&nbsp;&nbsp; &nbsp;&nbsp; RT, DCRN&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; Move From DCRN (Device Control Register) to RT<br />
mtdcr&nbsp;&nbsp; &nbsp;&nbsp; DCRN, RS&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; Move RS To DCRN<br />
<br />
mfmsr&nbsp;&nbsp; &nbsp;&nbsp; RT&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; Move From MSR to RT<br />
mtmsr&nbsp;&nbsp; &nbsp;&nbsp; RS&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; Move RS To MSR<br />
<br />
wrtee&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; RA &nbsp;&nbsp; Write MSR External Enable, MSR[EE] = RA[48]<br />
wrteei&nbsp;&nbsp;&nbsp; E&nbsp;&nbsp; Write MSR External Enable Immediate, MSR[EE] = E<br />
<br />
以及用于指令同步的：<br />
<br />
isync<br />
<br />
其保证在其之前的所有指令皆提交，在其自己被提交前，其之后的指令不会进入流水线<br />
<br />
<br />
<font color="#3399ff"><strong>3.6 存储管理相关指令<br />
</strong></font><br />
这类指令包括用于 TLB 管理的：<br />
<br />
tlbivax <br />
tlbre <br />
tlbwe <br />
tlbsx <br />
tlbsync<br />
<br />
tlbivaxe <br />
tlbsxe<br />
<br />
用于 Cache 管理的：<br />
<br />
dcba/dcbf/dcbi/dcbst/dcbt/dcbtst/dctz/icbi/icbt<br />
dcbae/dcbfe/dcbie/dcbste/dcbte/dcbtste/dctze/icbie/icbte<br />
<br />
用于存储同步的：<br />
<br />
msync<br />
mbar<br />]]></description></item></channel></rss>