智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 15676|回复: 2
打印 上一主题 下一主题

谈谈SH系列的Delay Slot 和 branch指令[转帖]

  [复制链接]

489

主题

1691

帖子

1

精华

管理员

网站创始人&站长

Rank: 11Rank: 11Rank: 11Rank: 11

积分
85927

特殊贡献奖章资源大师奖章论坛骨干奖章推广达人奖章优秀版主奖章热心会员奖章论坛元老奖章在线王奖章活跃会员奖章优秀会员奖章

QQ
威望
56985
贡献
17372
兑换币
13142
注册时间
2007-6-8
在线时间
5785 小时
跳转到指定楼层
1#
发表于 2009-9-18 16:56:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
作者: 快乐水牛
今天在调试SH2A时,CPU很意外的进入了delay slot中断。
对于Delay Slot这个概率,不是很清楚,于是网上搜索了一下资料。
我们可以将Delay Slot翻译为延迟槽。流水线结构的CPU在执行分支branch或者跳转jump指令时,由于此过程时间比较长,需要延迟一下,故可在此段时间内执行下一条指令,这就是branch delay slot的概念。
但如果在延迟槽的时间内执行一条未译码的指令时(也就是该指令来不及译码,延迟槽就结束了),会发生此类中断(SH2A为例)。所以常常可见编译器将高级语言翻译为汇编代码时,插入NOP指令来等待延迟。
-----------------------------------------------------
先看段代码:(取自 linux 2.6.17 for godson2)
801ea9d4:     02202021     move   a0,s1
801ea9d8:     27a50014     addiu   a1,sp,20
801ea9dc:     0c0ce551     jal   80339544 <pcibios_resource_to_bus>
801ea9e0:     02403021     move   a2,s2
801ea9e4:     8e240010     lw     a0,16(s1)
...
pcibios_resource_to_bus 的原型是:
void __devinit
pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, struct resource *res);
其中,在有HOTPLUG的情况下
__devinit <===> __init <===> __attribute__ ((__section__ (".init.text")))
表示把该 pcibios_resource_to_bus 生成的机器码置于初始化代码节(详细定义于include/linux/init.h)
jal (jump and link) 类似于x86 的 call
回到最上面的汇编码,很明显在调用 pcibios_resource_to_bus 前,先要向 a0, a1, a2 中置入3个参数, 可是我们看到第三个参数居然在 jal 后面!这就是 branch delay slot,从名字猜测应该是跳转延迟,也就是当执行到 jal 这条指令时,延迟一下,把下面的 move 指令执行完后再执行这条 jal 。
一直以来就这样理解,有点困惑,今天特意查了下:(取自维基百科)
Many of these early RISC designs also shared a not-so-nice feature, the branch delay slot. A branch delay slot is an instruction space immediately following a jump or branch. The instruction in this space is executed whether or not the branch is taken (in other words the effect of the branch is delayed). This instruction keeps the ALU of the CPU busy for the extra time normally needed to perform a branch. Nowadays the branch delay slot is considered an unfortunate side effect of a particular strategy for implementing some RISC designs, and modern RISC designs generally do away with it (such as PowerPC, more recent versions of SPARC, and MIPS).
可以看出,上面的 "move a2, s2" 是位于 branch delay slot 中的,应该是跳转类型的指令执行时间相对来说有点长,需要处于 branch delay slot 中的指令,占据 ALU 来赢去跳转类型指令相对多的执行时间。
如果把 "move a2, s2" 移到 jal 指令前,那处于branch delay slot 的就是 "lw a0,16(s1)", 很明显当CPU执行到"jal 80339544" 时,由于时间稍长,那 "lw a0, 16(s1)" 就会被执行,很明显这将导致传给 pcibios_resource_to_bus 的第一个参数被覆盖.显然这类指令顺序的调整是编译器干的.

转自http://www.renesas-mcu.com/read.php?tid=41

6

主题

309

帖子

0

精华

跨届大侠

Rank: 10Rank: 10Rank: 10

积分
9606

论坛元老奖章

QQ
威望
1453
贡献
7919
兑换币
155
注册时间
2010-4-2
在线时间
117 小时
2#
发表于 2012-9-17 09:50:48 | 只看该作者
说的好,一定回复~
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-12-26 04:50 , Processed in 0.094979 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表