打印

再问几个M0的问题

[复制链接]
4409|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
David_ming|  楼主 | 2010-3-19 00:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请问1.CM0支持分支预测吗?2.执行PUSH R0要多少个时钟?3.执行PUSH[R0-R3]需要的时间是PUSH R0的四倍吗?4.在C中如何定义位操作寄存器?问的问题有点多,感谢芯唐的支持

相关帖子

沙发
a_ziliu| | 2010-3-19 11:35 | 只看该作者
cortex 沒有分支預測的機制。

而push {r0}與push{r0-r3}的時脤上面每家作的都不一樣,
因為把ram掛在AHB上,寫進資料到RAM到資料回應,要看每一家處理的機制。

BIT ADDRESS是用C的struct的方法去定義暫存器結構。後用結構指標指向暫存器的位址。

使用特权

评论回复
板凳
a_ziliu| | 2010-3-19 11:48 | 只看该作者
修正一下,

push {r0}需要一個cpu時脤。
push {r0-r3}需要4個cpu時脤。

使用特权

评论回复
地板
David_ming|  楼主 | 2010-3-19 13:47 | 只看该作者
非常感謝樓上兄台,CM0要是有分支預測就完美了

使用特权

评论回复
5
yoyowodeai| | 2010-3-28 11:38 | 只看该作者
哦。学习了,第3,4个问题呢?

使用特权

评论回复
6
6019赵文| | 2010-3-28 12:46 | 只看该作者
在C中有定义位操作器吗?

使用特权

评论回复
7
David_ming|  楼主 | 2010-3-29 18:13 | 只看该作者
2# a_ziliu

谢谢哈,问错了一个问题,我就是想让编译器直接操作M0的PORTA.0这个脚,即生成下面的指令:

      LDR R0,PORTA; @0x5000 4000
      BFC R0,#1,#1;

同样能达到这样效率的其他指令也可以。

使用特权

评论回复
8
hiux| | 2010-3-30 08:34 | 只看该作者
M0对IO操作似乎很麻烦

使用特权

评论回复
9
David_ming|  楼主 | 2010-3-30 14:51 | 只看该作者
NUC把IO定义在0x50004000上面了,不知怎样高效写bit位

使用特权

评论回复
10
X-Hawk| | 2010-3-30 22:11 | 只看该作者
NUC把IO定义在0x50004000上面了,不知怎样高效写bit位
David_ming 发表于 2010-3-30 14:51

很难想象一个应用,读写IO的效率需要从指令集的差异上节省出来。
果真需要这样,那读写IO之间必定没其他更多流程耽搁到效率了。
既然没更多流程,那必定可以先将0x50004000事先放在某个不常用的通用寄存器,
那0x50004000就必定不是问题了。

听着像狡辩:lol


或许讲讲实际的需求,大家再讨论讨论。

使用特权

评论回复
11
David_ming|  楼主 | 2010-3-31 10:12 | 只看该作者
10# X-Hawk

其实我是想用来刷TFT的,这位大仙讲的有点绕,M0内部没有控制器(也是好事,不占用带宽了)如果IO映射在位带区域的话就可以提高速度,TFT不会有闪的感觉

使用特权

评论回复
12
X-Hawk| | 2010-3-31 10:17 | 只看该作者
11# David_ming

不知道用什么组件连接到TFT的呢,硬件不太懂。
要不建议看看PDMA模块,可以用DMA直接读写IO或Memory, 应该比用CPU做来的划算。

文档上写:
PDMA (外设-到-存储器、存储器-到-外设) 模式, DMA 可以在 外设 APB IP (ex: UART, SPI, ADC….) 和
Memory 将传递数据. 每个外设的内部 IP 和 DMA 数据传递具有握手信号

使用特权

评论回复
13
nanjue881016| | 2010-3-31 12:23 | 只看该作者
路过!顶顶。。。

使用特权

评论回复
14
David_ming|  楼主 | 2010-3-31 14:01 | 只看该作者
#include "NUC.h"

#define GP_BA 0x50004000

typedef struct
{
        volatile unsigned GPIO_0  :1;
        volatile unsigned GPIO_1  :1;
        volatile unsigned GPIO_2  :1;
        volatile unsigned GPIO_3  :1;
        volatile unsigned GPIO_4  :1;
        volatile unsigned GPIO_5  :1;
        volatile unsigned GPIO_6  :1;
        volatile unsigned GPIO_7  :1;
        volatile unsigned GPIO_8  :1;
        volatile unsigned GPIO_9  :1;
        volatile unsigned GPIO_10 :1;
        volatile unsigned GPIO_11 :1;
        volatile unsigned GPIO_12 :1;
        volatile unsigned GPIO_13 :1;
        volatile unsigned GPIO_14 :1;
        volatile unsigned GPIO_15 :1;
}GPIO;

#define PORTA    *((ulong *)(GP_BA + 0x000))
#define PORTA_0  ((GPIO *)(GP_BA + 0x000))->GPIO_0
#define PORTA_1  ((GPIO *)(GP_BA + 0x000))->GPIO_1
#define PORTA_2  ((GPIO *)(GP_BA + 0x000))->GPIO_2
#define PORTA_3  ((GPIO *)(GP_BA + 0x000))->GPIO_3
#define PORTA_4  ((GPIO *)(GP_BA + 0x000))->GPIO_4
#define PORTA_5  ((GPIO *)(GP_BA + 0x000))->GPIO_5
#define PORTA_6  ((GPIO *)(GP_BA + 0x000))->GPIO_6
#define PORTA_7  ((GPIO *)(GP_BA + 0x000))->GPIO_7
#define PORTA_8  ((GPIO *)(GP_BA + 0x000))->GPIO_8
#define PORTA_9  ((GPIO *)(GP_BA + 0x000))->GPIO_9
#define PORTA_10 ((GPIO *)(GP_BA + 0x000))->GPIO_10
#define PORTA_11 ((GPIO *)(GP_BA + 0x000))->GPIO_11
#define PORTA_12 ((GPIO *)(GP_BA + 0x000))->GPIO_12
#define PORTA_13 ((GPIO *)(GP_BA + 0x000))->GPIO_13
#define PORTA_14 ((GPIO *)(GP_BA + 0x000))->GPIO_14
#define PORTA_15 ((GPIO *)(GP_BA + 0x000))->GPIO_15

int main(void)
{
        PORTA_PMD = 0x5555;               
        while(1)
        {       
                PORTA_0 = 1;
                PORTA_0 = 0;                
        }                 
}

但是生成的汇编如下:

    48:         while(1)
    49:         {        
0x00000148 4806      LDR      r0,[pc,#24]  ; @0x00000164
0x0000014A 4905      LDR      r1,[pc,#20]  ; @0x00000160
0x0000014C 6001      STR      r1,[r0,#0x00]
    50:                 PORTA_0 = 1;
0x0000014E 2201      MOVS     r2,#0x01
0x00000150 6801      LDR      r1,[r0,#0x00]
0x00000152 4311      ORRS     r1,r1,r2
0x00000154 6001      STR      r1,[r0,#0x00]
    51:                 PORTA_0 = 0;        
0x00000156 6801      LDR      r1,[r0,#0x00]
0x00000158 0849      LSRS     r1,r1,#1
0x0000015A 0049      LSLS     r1,r1,#1
0x0000015C 6001      STR      r1,[r0,#0x00]
    48:         while(1)
0x0000015E E7F7      B        0x00000150


这样效率低了点,另外,别说我叫真啊~

使用特权

评论回复
15
X-Hawk| | 2010-4-1 00:08 | 只看该作者
本帖最后由 X-Hawk 于 2010-4-1 00:19 编辑

15# David_ming
注意看B跳转到0x150。于是循环内 PORTA_0 = 1; 也就等于3条指令
0x00000150 6801      LDR      r1,[r0,#0x00]
0x00000152 4311      ORRS     r1,r1,r2
0x00000154 6001      STR      r1,[r0,#0x00]



IO上使用了volatile, 一条读出、一条运算、一条写回,
3条指令一条都少不了的。用ARM指令也至少是这个结果。


所以Thumb也是很高效的。但这个场合,不用DMA显然太浪费了。您说是吧!
(我有点喜欢反驳,别介意啊:)


使用特权

评论回复
16
David_ming|  楼主 | 2010-4-1 08:38 | 只看该作者
上面生成的指令看似三条,但也应该把LOAD地址也算进去,因为我们要和位带操作的区域比较,所以还是多了一条

使用特权

评论回复
17
David_ming|  楼主 | 2010-4-8 15:52 | 只看该作者
本帖最后由 David_ming 于 2010-4-8 15:57 编辑

m0指令表

QQ截图未命名.jpg (221.28 KB )

QQ截图未命名.jpg

使用特权

评论回复
18
David_ming|  楼主 | 2010-4-8 16:06 | 只看该作者
选择M0编译后生成的指令:

    16:         PORTA_DOUT0 = 0;
0x00000166 4812      LDR      r0,[pc,#72]  ; @0x000001B0
0x00000168 6881      LDR      r1,[r0,#0x08]
0x0000016A 0849      LSRS     r1,r1,#1
0x0000016C 0049      LSLS     r1,r1,#1
0x0000016E 6081      STR       r1,[r0,#0x08]
    17:         PORTA_DOUT0 = 1;
    18:  
0x00000170 6881      LDR      r1,[r0,#0x08]
0x00000172 2201      MOVS     r2,#0x01
0x00000174 4311      ORRS     r1,r1,r2
0x00000176 6081      STR      r1,[r0,#0x08]

选择M3编译后生成的指令

    16:         PORTA_DOUT0 = 0;
0x0000015E 4812           LDR      r0,[pc,#72]  ; @0x000001A8
0x00000160 6881           LDR      r1,[r0,#0x08]
0x00000162 F0210101   BIC      r1,r1,#0x01
0x00000166 6081           STR      r1,[r0,#0x08]
    17:         PORTA_DOUT0 = 1;
    18:  
0x00000168 6881           LDR      r1,[r0,#0x08]
0x0000016A F0410101   ORR      r1,r1,#0x01
0x0000016E 6081           STR      r1,[r0,#0x08]

使用特权

评论回复
19
X-Hawk| | 2010-4-8 21:12 | 只看该作者
这条 F0210101   BIC      r1,r1,#0x01
M0貌似比较省指令长度,不支持4个字节格式的BIC.

使用特权

评论回复
20
X-Hawk| | 2010-4-9 10:52 | 只看该作者
ARM编译器脑子进水了呢:lol

发现最后一个bit, 它会用移位实现,造成多一条指令,少花费一个寄存器。
其他的bit, 就会用BIC实现,少一条指令,多花费一个寄存器。比如bit 1的情况:
    61:                 PORTA_1 = 1;
0x00000368 4804      LDR      r0,[pc,#16]  ; @0x0000037C
0x0000036A 2102      MOVS     r1,#0x02
0x0000036C 6802      LDR      r2,[r0,#0x00]
0x0000036E 430A      ORRS     r2,r2,r1
0x00000370 6002      STR      r2,[r0,#0x00]
    62:                 PORTA_1 = 0;                 
0x00000372 6802      LDR      r2,[r0,#0x00]
0x00000374 438A      BICS     r2,r2,r1
0x00000376 6002      STR      r2,[r0,#0x00]
0x00000378 E7F8      B        0x0000036C

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名::“哥洒脱如此”

22

主题

762

帖子

2

粉丝