<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jack&#039;s Lab &#187; 指令集</title>
	<atom:link href="http://www.jackslab.org/?feed=rss2&#038;tag=%E6%8C%87%E4%BB%A4%E9%9B%86" rel="self" type="application/rss+xml" />
	<link>http://www.jackslab.org</link>
	<description>好奇之心，改变之力</description>
	<lastBuildDate>Sun, 02 Jul 2017 02:48:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>PowerPC 体系结构之指令集 (II)</title>
		<link>http://www.jackslab.org/?p=221</link>
		<comments>http://www.jackslab.org/?p=221#comments</comments>
		<pubDate>Tue, 22 Feb 2011 02:53:13 +0000</pubDate>
		<dc:creator>Jack Tan</dc:creator>
				<category><![CDATA[PowerPC]]></category>
		<category><![CDATA[体系结构]]></category>
		<category><![CDATA[ISA]]></category>
		<category><![CDATA[指令集]]></category>

		<guid isPermaLink="false">http://www.jackslab.org/?p=221</guid>
		<description><![CDATA[3.3 整数指令 这类指令大致分为如下几类： 整数访存指令 整数算术运算指令 整数逻辑运算指令 整数比较指令 整数陷阱指令 整数移位指令 XER 指令 其中以整数循环移位指令最为特别。 3.3.1 整数访存指令 3.3.1.1 Load Byte/Half-word/Word ...]]></description>
			<content:encoded><![CDATA[<p><span style="color: #3399ff;"><strong> 3.3 整数指令</strong></span></p>
<p>这类指令大致分为如下几类：</p>
<p>整数访存指令<br />
整数算术运算指令<br />
整数逻辑运算指令<br />
整数比较指令<br />
整数陷阱指令<br />
整数移位指令<br />
XER 指令</p>
<p>其中以整数循环移位指令最为特别。</p>
<p><strong> 3.3.1 整数访存指令</strong></p>
<p><strong>3.3.1.1</strong> Load Byte/Half-word/Word and Zero</p>
<p>该类指令从指定地址处读取 8 位、16 位、32 位数据，置入 RT，RT  高位置 0</p>
<p>lbz/lbzu                           RT, D(RA)<br />
lbzx/lbzux                  RT,  RA, RB</p>
<p>lhz/lhzu                           RT, D(RA)<br />
lhzx/lhzux                  RT,  RA, RB</p>
<p>lwz/lwzu                        RT, D(RA)<br />
lwzx/lwzux                  RT,  RA, RB</p>
<p>RT, RA, RB 皆为 GPR，D 为有符号立即数。则有效地址的计算分别为：RA[32:63] + D，RA[32:63] + RB[32:63]，有效地址高 32 位置 0。</p>
<p>后缀 u 表示 Update，即将有效地址更新到 RA 中<br />
后缀 x 表示 Indexed，即使用 RA + RB 的寻址方式</p>
<p>以上用于 32 位，对 64 位，上述指令皆加后缀 &#8216;e&#8217;。则有效地址的 0 ~ 31 位， 不再置 0，其计算方式如下：RA + D，RA + RB。</p>
<p>此外，用于 64 位的还有对双字操作的支持：</p>
<p>lde/ldue/ldxe/lduxe<br />
<em><span id="more-221"></span></p>
<p></em><strong>3.3.1.2</strong> Load Half-word Algebraic</p>
<p>lha/lhau                           RT, D(RA)<br />
lhax/lhaux                  RT,  RA, RB<em></p>
<p></em>与 lhz 不同的是，该指令将所读取的半字的最高位 (RT[48]) 填充到 RT[32:47]，实际上就是形成一个 16 位的补码有符号数。</p>
<p>有效地址计算与上同；后缀 u, x 与上同。</p>
<p>对 64 位情形，上述指令皆加后缀 &#8216;e&#8217;，有效地址计算与上小节同。<br />
<em></p>
<p></em><strong>3.3.1.3</strong> <span style="color: #808000;">Load Halfword/Word Byte-Reverse</span><strong></p>
<p></strong>从指定地址处读取 16 位/32 位数据，将字节反转后置入 RT，RT 高位置 0<br />
<strong><br />
</strong> lhbrx        RT, RA, RB<br />
lwbrx        RT, RA, RB</p>
<p>如： lwbrx        r3, r2, r1，若 r2 + r1 地址处的数据为 0x55aa66bb，则 r3 的结果为 0xbb66aa55</p>
<p>对 64 位情形，上述指令皆加后缀 &#8216;e&#8217;，有效地址计算与上小节同。</p>
<p><strong>3.3.1.4</strong> <span style="color: #99cc00;">Load Multiple Word</span></p>
<p>lmw        RT, D(RA)</p>
<p>该指令将 RA + D 开始处的数据，顺序置入 RT ~ R31 中，共读取 31 &#8211; T 个字</p>
<p>该指令无 64 位扩展。</p>
<p><strong>3.3.1.5</strong> <span style="color: #99cc00;">Load String Word</span></p>
<p>lswi         RT, RA, NB               （后缀 i，表示立即数 Immediate）<br />
lswx         RT, RA, RB          （后缀 x，表示 Indexed 寻址方式）</p>
<p>加载 n 个字节到 RT  开始的寄存器中；<br />
当 NB == 0 时 n = 32； NB != 0 时 n = NB，NB 取值范围为 0 ~ 31</p>
<p>如 r3 = 0&#215;1000 ：</p>
<p>lswi        r4, r3, 16</p>
<p>则将 0&#215;1000 处的 16 字节，依次写入 r4, r5, r6, r7</p>
<p>对于 lswx，要加载的字节数则位于 XER[57:63]</p>
<p>该指令无 64 位扩展。</p>
<p><strong>3.3.1.6</strong> <span style="color: #009900;">Load Word/Doubleword and Reserve</span></p>
<p>lwarx         RT, RA, RB</p>
<p>该指令与 lwzx 的差别在于，其还将处理器内部的 RESERVE 位置为 1，并将有效地址对应的物理地址放入 RESERVE_ADDR 中。</p>
<p>该指令的 64 位版本为： lwarxe        RT, RA, RB，差别还是在于有效地址的 0 ~ 31 不被置 0</p>
<p>此外还有一个 ldarxe        RT, RA, RB，与 lwarxe 的差别在于其加载 8 字节的数据。</p>
<p>这三条指令常分别与 stwcx./stwcxe./stdcxe. 联用，用于实现锁操作，类似 MIPS 之 ll/sc 指令。</p>
<p><strong>3.3.1.7 </strong>Store<strong> </strong></p>
<p>stb/stbu                           RS, D(RA)<br />
stbx/stbux                  RS,  RA, RB<br />
sth/sthu                           RS, D(RA)<br />
sthx/sthux                  RS,  RA, RB<br />
stw/stwu                           RS, D(RA)<br />
stwx/stwux                  RS,  RA, RB</p>
<p>该类指令将 RS 中的 8 位、16 位、32 位数据写入有效地址处。后缀 &#8216;u&#8217;, &#8216;x&#8217; 之含义与 3.3.1.1 同。</p>
<p>上述 12 条指令加后缀 &#8216;e&#8217; 则用于 64 位。有效地址计算与与 3.3.1.1 同。</p>
<p>另用于 64 位的还有对双字操作的支持：</p>
<p>stde/stdue/stdxe/stduxe</p>
<p><strong>3.3.1.8</strong> <span style="color: #ffcc00;">Store Halfword/Word Byte-Reverse</span></p>
<p>sthbrx    RS, RA, RB<br />
stwbrx    RS, RA, RB</p>
<p>将 RS 中的 16/32 bit 的数据字节反转后置入有效地址处。该指令用于支持在大端系统上以小端序存储数据，亦或在小端系统上以大端序存储数据。</p>
<p>对 64 位情形，上述指令皆加后缀 &#8216;e&#8217;，有效地址计算与上小节同。</p>
<p><strong>3.3.1.9</strong> <span style="color: #ff9900;">Store Multiple Word</span></p>
<p>smw       RS, D(RA)</p>
<p>该指令将 RS ~ R31 中的数据 （一个字），写入到 RA + D 处</p>
<p>该指令无 64 位扩展。</p>
<p><strong>3.3.1.10</strong> <span style="color: #ff9900;">Store  String Word</span></p>
<p>stswi              RS, RA, NB           （后缀 i，表示立即数 Immediate）<br />
stswx          RS, RA, RB           （后缀 x，表示 Indexed 寻址方式）</p>
<p>与 lswi/lswx 的操作相反，其将 RS 开始的寄存器组中的 n 个字节，写入到有效地址处（位于 RA）</p>
<p>当 NB == 0 时 n = 32； NB != 0 时 n = NB，NB 取值范围为 0 ~ 31</p>
<p>如 r3 = 0&#215;1000 ：</p>
<p>stswi        r4, r3, 16</p>
<p>则将 r4, r5, r6, r7  中的 16 字节数据依次写入 0&#215;1000 处</p>
<p>对于 stswx，要加载的字节数则位于 XER[57:63]</p>
<p>该指令无 64 位扩展。</p>
<p><strong>3.3.1.11</strong> <span style="color: #ff6600;">Store  Word/Doubleword Conditional</span></p>
<p>stwcx.                RS, RA, RB</p>
<p>如果 RESERVE 位为 1，且 RA + RB 对应的物理地址与 RESERVE_ADDR 一致，则将 RS[32:63] 的内容写入到 RA + RB 处，将 CR0[eq] 位置为 1 后，再将 RESERVE 位复位为 0。</p>
<p>若条件不满足，则仅将 CR0[eq] 位置为 0</p>
<p>可用该指令与 lwarx 联用，实现 spin_lock：</p>
<p>li       r0, 1<br />
loop:<br />
lwarx       r4, 0, r3<br />
cmpwi      r4, 0                     # r4[32:63] 与 0 比较<br />
bne loop<br />
stwcw.       r0, 0, r3<br />
bne       loop<br />
isync</p>
<p>解锁则为：</p>
<p>msync<br />
li       r0, 0<br />
stw       r0, 0(r3)</p>
<p>下面的指令用于 64 位：</p>
<p>stwcxe.            RS, RA, RB<br />
stdcxe.            RS, RA, RB</p>
<p>差别在于有效地址的高 32 位不再被置为 0。</p>
<p><strong> 3.3.2 整数算术运算指令</strong></p>
<p>加、减、乘、除、取负</p>
<p><strong> 3.3.3 整数逻辑运算指令</strong></p>
<p>与、或、非、异或<br />
<strong><br />
3.3.4 整数比较指令</strong></p>
<p>cmp                   BF, L, RA, RB<br />
cmpi                BF, L, RA, SI                     # RA 与有符号立即数 SI 比较<br />
cmpl                BF, L, RA, RB                     # RA, RB 逻辑比较。l &#8212;&gt; logical<br />
cmpli                BF, L, RA, UI                     # RA 与无符号立即数 UI 逻辑比较</p>
<p>BF 取值 0 ~ 7，用于指定使用的 CR 域<br />
L 为 0，则为 32 位比较；为 1，则为 64 位比较</p>
<p>如：</p>
<p>cmpi              0, 0, r3, 5</p>
<p>若 r3 &gt; 5，则 CR0[gt] = 1；若 r3 &lt; 5，则 CR0[lt] = 1</p>
<p><strong> 3.3.5 整数陷阱指令</strong></p>
<p>tw                    TO, RA, RB<br />
twi            TO, RA, SI</p>
<p>TO 为立即数，5 位，从左到右标号为 0 ~ 4，依次表示小于、大于、等于、无符号小于、无符号大于。用于指定 Trap 的条件。<br />
SI： Signed Immediate</p>
<p>如：</p>
<p>twi       0&#215;10, r3, 5</p>
<p>则如果 r3 &lt; 5，则陷入异常。</p>
<p>以上用于单字 (32 bit) 比较，双字比较则用：</p>
<p>td                    TO, RA, RB<br />
tdi            TO, RA, SI</p>
<p><strong><br />
3.3.6 整数移位指令</strong></p>
<p><strong> 3.3.6.1</strong> <span style="color: #99cc00;"><strong>Rotate</strong></span></p>
<p>rlwimi                RA, RS, SH, MB, ME                            # Rotate Left Word Immediate then Mask Insert<br />
rlwinm                RA, RS, SH, MB, ME                            # Rotate Left Word Immediate then AND with Mask<br />
rlwnm                 RA, RS, RB, MB, ME                            # Rotate Left Word then AND with Mask</p>
<p>以下是该指令的一些例子：</p>
<p>all r11 is: 0x55aa67bb</p>
<p>r0 = 0&#215;00000000<br />
rlwimi      r0, r11, 8, 0, 31<br />
r0 is: 0xaa67bb55</p>
<p>r0 = 0&#215;12345678<br />
rlwimi      r0, r11, 8, 0, 14<br />
r0 is: 0xaa665678</p>
<p>r0 = 0&#215;1<span style="color: #99cc00;">234567</span>8<br />
rlwimi      r0, r11, 8, 28, 3<br />
r0 is: 0xa<span style="color: #99cc00;">234567</span>5</p>
<p>即：取 RS 循环左移 SH 位后的 WB 到 WE 位，替换 RA 的 WB 到 WE 位。</p>
<p>r0 = 0&#215;00000000<br />
rlwinm      r0, r11, 8, 0, 31<br />
r0 is: 0xaa67bb55</p>
<p>r0 = 0&#215;12345678<br />
rlwinm      r0, r11, 8, 0, 14<br />
r0 is: 0xaa660000</p>
<p>即：取 RS 循环左移 SH 位后的 WB 到 WE 位，替换归零后的 RA</p>
<p>rldcl<br />
rldcr<br />
rldic<br />
rldicl<br />
rldicr<br />
rldimi</p>
<p><strong> 3.3.6.2</strong> Shift</p>
<p>slw<br />
srw<br />
sraw<br />
srawi</p>
<p>slw./srw./sraw./srawi.</p>
<p>sld<br />
srd<br />
srad<br />
sradi</p>
<p><strong> 3.3.7 XER 指令</strong></p>
<p>mcrxr              BF<br />
mcrxr64            BF</p>
<p><span style="color: #3399ff;"><strong> 3.4 浮点指令</strong></span></p>
<p>这类指令包括：</p>
<p>浮点数据加载与存储指令<br />
浮点运算指令<br />
浮点数近似和转化指令<br />
浮点比较指令<br />
浮点状态和控制寄存器指令</p>
<p>有关该指令的详情留待以后以《PowerPC 浮点结构》的形式讨论吧。</p>
<p><span style="color: #3399ff;"><strong> 3.5 处理器控制指令</strong></span></p>
<p>这类指令包括用于支持异常中断处理的：</p>
<p>sc                            System Call<br />
rfci                     Return From Critical Interrupt<br />
rfi                       Return From Interrup</p>
<p>用于处理器控制寄存器维护的：</p>
<p>mfspr              RT, SPRN                     Move From SPRN (Special Purpose Register) to RT<br />
mtspr              SPRN, RS                     Move RS To SPRN</p>
<p>mfdcr              RT, DCRN                     Move From DCRN (Device Control Register) to RT<br />
mtdcr              DCRN, RS                     Move RS To DCRN</p>
<p>mfmsr              RT                            Move From MSR to RT<br />
mtmsr              RS                            Move RS To MSR</p>
<p>wrtee              RA       Write MSR External Enable, MSR[EE] = RA[48]<br />
wrteei         E       Write MSR External Enable Immediate, MSR[EE] = E</p>
<p>以及用于指令同步的：</p>
<p>isync</p>
<p>其保证在其之前的所有指令皆提交，在其自己被提交前，其之后的指令不会进入流水线</p>
<p><span style="color: #3399ff;"><strong> 3.6 存储管理相关指令<br />
</strong></span><br />
这类指令包括用于 TLB 管理的：</p>
<p>tlbivax<br />
tlbre<br />
tlbwe<br />
tlbsx<br />
tlbsync</p>
<p>tlbivaxe<br />
tlbsxe</p>
<p>用于 Cache 管理的：</p>
<p>dcba/dcbf/dcbi/dcbst/dcbt/dcbtst/dctz/icbi/icbt<br />
dcbae/dcbfe/dcbie/dcbste/dcbte/dcbtste/dctze/icbie/icbte</p>
<p>用于存储同步的：</p>
<p>msync<br />
mbar</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jackslab.org/?feed=rss2&#038;p=221</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerPC 体系结构之指令集 (I)</title>
		<link>http://www.jackslab.org/?p=209</link>
		<comments>http://www.jackslab.org/?p=209#comments</comments>
		<pubDate>Mon, 21 Feb 2011 09:30:25 +0000</pubDate>
		<dc:creator>Jack Tan</dc:creator>
				<category><![CDATA[PowerPC]]></category>
		<category><![CDATA[体系结构]]></category>
		<category><![CDATA[ISA]]></category>
		<category><![CDATA[指令集]]></category>

		<guid isPermaLink="false">http://www.jackslab.org/?p=209</guid>
		<description><![CDATA[1. 概述 Book E 定义的 PowerPC 指令集的指令可分为以下几类： 分支跳转指令 CR 指令 整数指令 浮点指令 处理器控制指令 存储管理相关指令 CR 指令主要是对 CR ...]]></description>
			<content:encoded><![CDATA[<p><span style="color: #ff6600;"><strong>1. 概述</strong></span></p>
<p>Book E 定义的 PowerPC 指令集的指令可分为以下几类：</p>
<p>	分支跳转指令<br />
	CR 指令 整数指令<br />
	浮点指令<br />
	处理器控制指令<br />
	存储管理相关指令</p>
<p>CR 指令主要是对 CR 内部位运算支持的一些指令，如 crand, cror, crxor 等等。</p>
<p><span style="color: #009900;"><strong>2. 常用指令</strong></span></p>
<p>先看一个测试程序：</p>
<pre class="brush:cpp">int test_call(int a, int b, int c)
{
	a = b + c;
	return a;
}

int test_if(int s)
{
	int i;
	if(s &gt; 0)
		i = s;
	else if(s &lt; 0)
		i = -s;
	else
		i = s * 8;
	return i;
}

int test_cyc1(int c)
{
	int sum = 0;
	do {
		sum += c;
		c--;
	} while(c &gt; 0);
	return c;
}

int test_cyc2(int c)
{
	int sum = 0;
	for(; c &gt; 0; c--)
		sum += c;
	return c;
}

int main()
{
	int a, b, c, d;
	a = test_if(5);
	b = test_cyc1(10);
	c = test_cyc2(10);
	d = test_call(1, 2, 3);
	return a + b + c + d;
}</pre>
<p>引入的目的在于查看判断、循环和过程调用这些基本结构在 PowerPC 里怎么被支持。</p>
<p>-O2 参数编译后，objdump -S -d 反汇编，则：</p>
<p><span id="more-209"></span></p>
<pre class="brush:cpp">1000040c &lt;test_call&gt;:
int test_call(int a, int b, int c)
{
	a = b + c;
	return a;
}
1000040c:    7c 64 2a 14     add     r3,r4,r5
--&gt; 对应 a, b, c 三个参数，同时 r3 又置返回值
10000410:    4e 80 00 20     blr
--&gt; 跳转到 LR 所存放的地址处，即函数返回

10000414 &lt;test_if&gt;:
int test_if(int s)
{
	int i;
	if(s &gt; 0)
10000414:    7c 60 1b 79     mr.     r0,r3
--&gt; r3 移到 r0，若 r0 小于、大于、等于 0，则置 CR0 的相应位。指令后多一点，则说明该指令会据执行结果，设置 CR 的相应位
10000418:    7c 03 03 78     mr      r3,r0
--&gt; 此条指令多余
1000041c:    4d a1 00 20     bgtlr+
--&gt; 若 CR0[gt] 位为 1，则跳转到 LR 所存放的地址处，即直接函数返回了。此条指令等价于 bclr  13, 1
		i = s;
	else if(s &lt; 0)
10000420:    38 60 00 00     li      r3,0
10000424:    4d 82 00 20     beqlr
--&gt; 若 CR0[eq] 位为 1，则跳转到 LR 所存放的地址处，也直接函数返回了。此条指令等价于 bclr      12, 2
		i = -s;
10000428:    7c 60 00 d0     neg     r3,r0
--&gt; r0 取反，入 r3
	else
		i = s * 8;
	return i;
}
1000042c:    4e 80 00 20     blr
--&gt; 跳转到 LR 所存放的地址处，函数返回

10000430 &lt;test_cyc1&gt;:
int test_cyc1(int c)
{
10000430:    34 03 ff ff     addic. r0,r3,-1
10000434:    7c 69 03 a6     mtctr   r3
10000438:    41 80 00 10     blt-    10000448 &lt;test_cyc1+0x18&gt;
	int sum = 0;
	do {
		sum += c;
		c--;
1000043c:    38 63 ff ff     addi    r3,r3,-1
	} while(c &gt; 0);
10000440:    42 00 ff fc     bdnz+   1000043c &lt;test_cyc1+0xc&gt;
	return c;
}
10000444:    4e 80 00 20     blr
10000448:    38 00 00 01     li      r0,1
1000044c:    7c 09 03 a6     mtctr   r0
10000450:    4b ff ff ec     b       1000043c &lt;test_cyc1+0xc&gt;

10000454 &lt;test_cyc2&gt;:
int test_cyc2(int c)
{
10000454:    2c 03 00 00     cmpwi   r3,0
10000458:    39 20 00 00     li      r9,0
1000045c:    7d 23 48 1e     .long 0x7d23481e
	int sum = 0;
	for(; c &gt; 0; c--)
		sum += c;
	return c;
}
10000460:    7d 23 4b 78     mr      r3,r9
10000464:    4e 80 00 20     blr

int main()
{
10000468:   94 21 ff e0     stwu    r1,-32(r1)
1000046c:   7c 08 02 a6     mflr    r0
	int a, b, c, d;
	a = test_if(5);
10000470:   38 60 00 05     li      r3,5
10000474:   90 01 00 24     stw     r0,36(r1)
10000478:   93 61 00 0c     stw     r27,12(r1)
1000047c:   93 81 00 10     stw     r28,16(r1)
10000480:   93 a1 00 14     stw     r29,20(r1)
10000484:   4b ff ff 91     bl      10000414 &lt;test_if&gt;
10000488:   7c 7d 1b 78     mr      r29,r3
	b = test_cyc1(10);
1000048c:   38 60 00 0a     li      r3,10
10000490:   4b ff ff a1     bl      10000430 &lt;test_cyc1&gt;
10000494:   7c 7b 1b 78     mr      r27,r3
	c = test_cyc2(10);
10000498:   38 60 00 0a     li      r3,10
	d = test_call(1, 2, 3);
1000049c:   7f bd da 14     add     r29,r29,r27
100004a0:   4b ff ff b5     bl      10000454 &lt;test_cyc2&gt;
100004a4:   38 80 00 02     li      r4,2
100004a8:   7c 7c 1b 78     mr      r28,r3
100004ac:   38 a0 00 03     li      r5,3
100004b0:   38 60 00 01     li      r3,1
100004b4:   4b ff ff 59     bl      1000040c &lt;test_call&gt;
	return a + b + c + d;
}
100004b8:   80 01 00 24     lwz     r0,36(r1)
100004bc:   7f 9c 1a 14     add     r28,r28,r3
100004c0:   83 61 00 0c     lwz     r27,12(r1)
100004c4:   7c 7d e2 14     add     r3,r29,r28
100004c8:   83 81 00 10     lwz     r28,16(r1)
100004cc:   83 a1 00 14     lwz     r29,20(r1)
100004d0:   7c 08 03 a6     mtlr    r0
100004d4:   38 21 00 20     addi    r1,r1,32
100004d8:   4e 80 00 20     blr</pre>
<p><span style="color: #3399ff;"><strong>3. 分类概述</strong></span></p>
<p><strong> 3.1 分支跳转指令</strong></p>
<p>这类指令算是 PowerPC 里比较有特色的，也是稍显复杂的。这类指令与 CR, LR 和 CTR 紧密相联，建构起判断、循环和过程调用这些程序的基本结构。其大致可分为四类：</p>
<p>Branch<br />
Branch Conditional<br />
Branch Conditional to Count Register<br />
Branch Conditional to Link Register<br />
<strong> </strong></p>
<p><strong> 3.1.1 Branch</strong></p>
<p>这类指令与 CR 没有联系，即为非条件跳转，助记符后直接跟立即数地址。指令内为立即数地址预留 26 位，即可跳转 2^26 大小的空间，如：(CIA, Current Instruction Address)</p>
<p>b                                             0&#215;20                       &#8212;&#8211;&gt; 以当前指令地址为基点，往后跳转 0&#215;20 字节，即 PC = CIA + 0&#215;20<br />
ba                               0&#215;20                                                            &#8212;&#8211;&gt; 直接跳转到地址 0&#215;20 处。<strong>后缀为 a，则表示使用 Absolute Address，PC = 0&#215;20</strong>。<br />
bl                   0&#215;20                                                            &#8212;&#8211;&gt; 在 b 0&#215;20 的基础上，将 LR 更新为 CIA + 4<br />
bla                 0&#215;20                                                            &#8212;&#8211;&gt; 使用绝对地址，且更新 LR。<strong>后缀带 l，则表示更新 LR 为 CIA + 4</strong></p>
<p>以上针对 32 位的情形，对 64 位则使用指令 be, bea, bel, bela 功能与上同。</p>
<p><strong>3.1.2 Branch Conditional</strong></p>
<p>此类为条件跳转指令。皆以 bc 开头，带 3 个操作数，如：</p>
<p>bc                        BO, BI, BD<br />
bca               BO, BI, BD<br />
bcl                  BO, BI, BD<br />
bcla              BO, BI, BD</p>
<p>后缀 a, l 的含义与 branch 类指令同。BO 指定跳转的条件，5 位；BI 指定关联的 CR 位，也是 5 位；BD 为跳转的立即数地址，16 位。</p>
<p>其中以 BO 的编码最为复杂（BO 从左到右编号为 0 ~ 4）：</p>
<p>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</p>
<p>则常见的 BO 值：<br />
20 (0b10100) 则表示无条件跳转<br />
12 (0b01100) 则表示 CR 的某个位为 1 时跳转<br />
4 (0b00100) 则表示 CR 的某个位为 0 时跳转</p>
<p>至于静态预测的策略位，默认被置为<strong> 0</strong>，则其行为为：</p>
<p>b1. 目标地址小于当前指令地址，预测为<span style="color: #ff9900;">跳转</span><br />
b2. 目标地址大于当前指令地址，预测为<span style="color: #ff9900;">不跳转</span><br />
b3. 对于目标地址在 CTR/LR 中的条件跳转指令，一律预测为<span style="color: #ff9900;">不跳转</span></p>
<p>若该位被置 <strong>1</strong>，则上述 b1, b2, b3 的静态预测行为分别为：<span style="color: #99cc00;">不跳转</span>，<span style="color: #99cc00;">跳转</span>，<span style="color: #99cc00;">跳转</span>。</p>
<p>可以给分支指令加一个 +/- 的后缀，来简化。加 &#8216;+&#8217; 的指令，一律预测为跳转。加 &#8216;-&#8217; 的分支指令，一律预测为不跳转。</p>
<p>则对于 b1，后缀 &#8216;+&#8217; 会将 y 位置 0，&#8217;-&#8217; 则将 y 位置 1。<br />
对于 b2，后缀 &#8216;+&#8217; 会将 y 位置 1，&#8217;-&#8217; 则将 y 位置 0。<br />
对于 b3，后缀 &#8216;+&#8217; 会将 y 位置 1，&#8217;-&#8217; 则将 y 位置 0。</p>
<p>BI 与关联 CR 位的关系为：</p>
<p>32 + BI</p>
<p>即，若 BI 为 2，则对应于 CR[34]，即为 CR0[gt] 位。</p>
<p>以上针对 32 位的情形，对 64 位则使用指令 bce, bcea, bcel, bcela 功能与上同。</p>
<p><strong>3.1.3 Branch Conditional to Count Register</strong></p>
<p>bcctr                BO, BI<br />
bcctrl               BO, BI</p>
<p>后缀 l 的含义与 branch 类指令同。<br />
BO，BI 的编码与 Branch Conditional 类指令同。<br />
跳转目标地址位于 CTR 中。</p>
<p>以上针对 32 位的情形，对 64 位则使用指令 bcctre, bcctrel 功能与上同。</p>
<p><strong>3.1.4 Branch Conditional to Link Register</strong></p>
<p>bclr                BO, BI<br />
bclrl               BO, BI</p>
<p>后缀 l 的含义与 branch 类指令同。<br />
BO，BI 的编码与 Branch Conditional 类指令同。<br />
跳转目标地址位于 LR 中。</p>
<p>以上针对 32 位的情形，对 64 位则使用指令 bclre, bclrel 功能与上同。</p>
<p><span style="color: #3399ff;"><strong>3.2 CR 指令</strong></span></p>
<p>这类指令包括用来支持 CR 内部位运算的指令和 CR 与 GPR 之间的数据交换指令。</p>
<p><strong>3.2.1 CR 内</strong><strong>位运算指令</strong></p>
<p>这类指令的格式皆为：           crxxx            BT, BA, BB</p>
<p>BT, BA, BB 是 CR 内的位编号，取值范围为 0 ~ 31，如 crand    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]</p>
<p>crand:                                                CR[32+BA] &amp; CR[32+BB]<br />
crandc:                                      CR[32+BA] &amp; (~CR[32+BB])<br />
creqv:                                                ~(CR[32+BA] ^ CR[32+BB])，即位相等，则置 1；不等则置 0<br />
crnand:                        ~(CR[32+BA] &amp; CR[32+BB])<br />
crnor:                                       ~(CR[32+BA] | CR[32+BB])<br />
cror:                                       CR[32+BA] | CR[32+BB]<br />
crorc:                          CR[32+BA] | (~CR[32+BB])，先取反后再或<br />
crxor:                              CR[32+BA] ^ CR[32+BB]，位异或</p>
<p><strong>3.2.2  CR 与 GPR 间</strong><strong>数据交换指令</strong><br />
<strong><br />
3.2.2.1</strong> mcrf                                    BF, BFA          &#8212;          Move Condition Register Fields</p>
<p>将 CR 之 BFA 域复制到 BF 域。如 mcrf            0, 3 则将 CR3 拷入 CR0</p>
<p><strong><br />
3.2.2.2</strong> mtcrf                          FXM, RS          &#8212;          Move To Condition Register Fields</p>
<p>通用寄存器 RS 之 32 ~ 63 位以 4 位为单位，对应于 CR 的 8 个域，编号为 RS0 ~ RS7；<br />
FXM 为域掩码，8 位，从左到右编号为 0 ~ 7，对应于 RS、CR 的 8 个域。某位为 1，则将对应的 RS 域拷贝到对应的 CR 域中。<br />
若 FXM 为 0&#215;80，则只将 CR0 = RS0<br />
若 FXM 为 0xc8，则将 CR0 = RS0, CR1 = RS1, CR4 = RS4</p>
<p><strong> 3.2.2.3</strong> mfcr                          RT          &#8212;          Move From Condition Register</p>
<p>将 CR 的内容移入通用寄存器 RT 的 32 ~ 63 位。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jackslab.org/?feed=rss2&#038;p=209</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
