32位RISC芯片ARM 系统结构支撑两种指令集:32位的ARM指令集履行功率高,对ARM系统架构一切功用的完好支撑;16位的Thumb指令集是ARM指令集的子集并以杰出的代码密度著称。假如抛开预取指令时刻不计,ARM指令相对Thumb指令将有更好的运转功用(预取指令时需求依据指令地址偏移量来取指, ARM支撑更大的地址偏移量而比较耗时)。最近ARM公司推出的的Thumb-2/Thumb2指令集据称是上述两种特性的归纳,是ARM指令集的功用和Thumb指令集的代码密度的折中。声称到达98%的ARM功用而又能下降代码密度达30%。在现在的大多数ARM运用中仍然选用ARM + Thumb代码的稠浊方式。ARM code对应的CPU(ARM处理器)作业状况称为ARM State,Thumb对应的称之为Thumb State,这两种状况的不同首要经过CPSR[bit 5]差异。CPSR(当时程序状况寄存器)保存了处理器的当时作业状况,[bit 5]也被称为T bit。关于一切带有J标志的处理器核,比方ARM926EJ-S和ARM1136J-S,J(Jazelle)代表ARM核中集成了Jazelle技 术。CPSR[bit24]则被成为J bit,假如这位为1,则代表当时CPU作业在Java State下而CPU的取指和解码都是直接操作Java操作数栈。当然要生成Jazelle支撑的字节码需求特别的Java编译器和JVM,一般由第三方 渠道软件厂商供给,比方日本的Aplix公司。在ARM处理器的运转过程中,汇编指令BX以及BLX可以完结ARM State和Thumb State之间的切换(BXJ和BLXJ完结ARM/Thumb State和Java State之间的切换)。但假如程序有一部分作业在ARM作业状况下,一部分作业在Thumb作业状况下,而这两段代码却有交互调用,则在编译C/C++和汇编源文件时要 加上 -apcs /interwork选项。ARM公司的ADS(ARM Developer Suite,-apcs /interwork)和RealView的RVDS(RealView Developer Suite,–apcs /interwork) 都支撑这样的编译选项,他们会在链接时主动检测函数之间的调用联系和作业状况供给粘合剂(Veneers)以便程序可以在不同的作业状况下切换。arm-linux-gcc编译器单个版别不支撑这个选项,所以在开发ARM + Linux渠道下运用的程序时应该留意到这个问题。最终比较了arm-linux-gcc编译器下ARM(armv7-a)、Thumb-1、Thumb-2指令集以及armv5te、Cortex-A9与Cortex-A8的tune选项功率功用和代码密度。
图1. ARM系统结构演进图
ARM指令集(A32)
ARM指令集为32位指令集,指令地址有必要对齐在4字节鸿沟,可以完结ARM架构下一切功用。大多数ARM数据处理指令选用的是3地址格局(除了64位乘法指令外),即两个源操作数和一个成果操作数。
ARM指令分为以下几种: 一、ARM 存储器拜访指令 二、ARM 数据处理指令 三、乘法指令 四、跳转指令 助记符 阐明 操作 条件码方位 五、ARM协处理器指令 五、ARM 杂项指令 |
|||||||||||
一切反常都会使微处理器回来到ARM方式状况,并在ARM的编程方式中处理。因为ARM微处理器字传送地址有必要可被4整除(即字对准),半字传送地址有必要可被2整除(即半字对准)。而Thumb指令是2个字节长,而不是4个字节,所以,由Thumb履行状况进入反常时其天然偏移与ARM不同。
Thumb指令集
关于ARM指令来说,一切的指令长度都是32位,而且履行周期大多为单周期,指令都是有条件履行的。每条Thumb指令有相同处理器模型所对应的32位ARM指令。而THUMB 指令的特色如下:
- 不会常常条件履行运用指令:除了跳转指令 B 有条件履行功用外,其它指令均为无条件履行
- 源寄存器与方针寄存器常常是相同的以削减操作数
- 可用寄存器数量少
- 常数的值比较小
- 不常常用内核中的桶式移位器(barrel shifter)
Thumb指令集是对32位ARM指令集的扩大,它的方针是为了完结更高的代码密度。Thumb指令集完结的功用仅仅32位ARM指令集的子集,它仅仅把常用的ARM指令紧缩成16位的指令编码方法。在指令的履行阶段,16位的指令被从头解码,完结对等的32位指令所完结的功用。与悉数用ARM指令集的方法比较,运用Thumb指令可以在代码密度方面改善大约30%。可是,这种改善是以代码的功率为价值的。虽然每个Thumb指令都有相对应的ARM指令,可是,相同的功用需求更多的Thumb指令才干完结。因此,当指令预取需求的时刻没有差异时,ARM指令相对Thumb指令具有更好的功用。与ARM指令集比较较,Thumb指令会集的数据处理指令的操作数仍然是32位,指令地址也为32位,但Thumb指令集为完结16位的指令长度,放弃了ARM指令集的一些特性,若运用32位的存储器,ARM代码比Thumb代码快约40%,若运用16位的存储器,Thumb代码比ARM代码快约40%~50%.明显,ARM指令集和Thumb指令集各有其长处,若对系统的功用有较高要求,应运用32位的存储系统和ARM指令集,若对系统的本钱及功耗有较高要求,则应运用16位的存储系统和Thumb指令集。当然,若两者结合运用,充分发挥其各自的长处,会获得更好的作用。 在编写Thumb指令时,先要运用伪指令CODE16声明,编写ARM指令时,则可运用CODE32伪指令声明。Thumb 指令集没有协处理器指令,信号量指令以及拜访 CPSR 或 SPSR 的指令,没有乘加指令及 64 位乘法指令等,且指令的第二操作数遭到约束;大多数 Thumb 数据处理指令选用2地址格局.Thumb指令集与 ARM 指令的差异一般有如下几点: |
|
|
Thumb-2指令集(T32)
THUMB-2指令集是介绍ARM CPU中的THUMB的扩展,新指令对功用和代码密度的改善,然后供给低功耗,高功用的最优设计,更好的平衡代码功用和系统本钱,Thumb-2是混合的16-bit和32-bit指令格局,其16位指令在运转时被转换为32-bit指令履行。Thumb-2指令集在Thumb指令的基础上做了如下的扩大:添加了一些新的16位Thumb指令来改善程序的履行流程,添加了一些新的32位Thumb指令以完结一些ARM指令的专有功用32位的ARM 指令也得到了扩大,添加了一些新的指令来改善代码功用和数据处理的功率给Thumb指令集添加32位指令就处理了之前Thumb指令集不能拜访协处理器、特权指令和特别功用指令的限制。新的Thumb指令集现在可以完结一切的功用,这样就不需求在ARM/Thumb状况之间重复切换了,代码密度和功用得到明显的进步。Thumb-2的呈现使开发者只运用一套指令集就享有高功用、高代码密度,不再需求在不同指令之间重复切换了。开发者只需求重视对全体功用影响最大的那部分代码,其他的部分可以运用缺省的编译装备就可以了。
新的Thumb-2技能可以带来许多优点:
可以完结ARM指令的一切功用
添加了12条新指令,可以改善代码功用和代码密度之间的平衡
代码功用到达了纯ARM代码功用的98%
相对ARM代码,Thumb-2代码的巨细仅有其74%
代码密度比现有的Thumb指令集更高:代码巨细均匀下降5%;代码速度均匀进步2-3%
为了进步处理紧缩数据结构的功率,新的ARM架构为Thumb-2指令集和ARM指令集添加了一些新的指令来完结比特位的刺进和抽取。为了添加处理常数的灵活性,新架构中为Thumb-2指令集和ARM指令集添加了两条新的指令。MOVW可以把一个16-bit常数加载到寄存器中,并用0填充高比特位;另一条指令MOVT可以把一个16-bit常数加载到寄存器高16比特中。这两条指令组合运用就可以把一个32-bit常数加载到寄存器中。通常在拜访外设寄存器之前会把外设的基址加载到寄存器中,这时就会需求把32-bit常数加载到寄存器中。在之前的架构中需求经过literal pools来完结这样的操作,对32位常量的拜访一般经过PC相对寻址来完结。Literal pools可以保存常量并简化拜访这些常量的代码,可是,在Harvard架构的处理器中会引起额定的开支。这些开支来自于需求额定的时钟周期来使数据端 口可以对指令流进行拜访;这种拜访可能是需求把指令流加载的数据缓存中,或许从数据端口直接拜访指令存储器。将32位常量分红16比特的两个部分保存在两条指令中,意味着数据直接在指令流中,不再需求经过数据端口来拜访了。相关于literal pool方法,这种处理方法可以消除经过数据端口拜访指令流的额定开支,然后进步功用,下降功耗。
ARM/Thumb状况切换
在依据ARM 处理器的嵌入式开发中,为了增强系统的灵活性以及进步系统的全体功用常常需求运用16 位的Thumb 指令,所以需求在ARM 和Thumb 状况之间来切换(Interworking)微处理器状况。只需遵从ATPCS调用规矩,Thumb子程序和ARM子程序就可以彼此调用。首要介绍切换(Interwoking)的基本概念及切换时的子函数调用。
ARM处理器总是从ARM状况开端履行。因此,假如要在调试器中运转Thumb程序,有必要为该Thumb程序添加一个ARM程序头,然后再切换到Thumb状况,调用该Thumb程序。
- Thumb状况 BX Rn
- ARM状况 BX
Rn
其间Rn可以是寄存器R0—R15中的恣意一个。指令可以经过将寄存器Rn的内容拷贝到程序计数器PC来完结在4Gbyte地址空间中的肯定跳转,而状况切换是由寄存器Rn的最低位来指定的,假如操作数寄存器的状况位Bit0=0,则进入ARM状况,假如Bit0=1,则进入Thumb状况。在非Interworking函数调用中,调用函数运用BL(Branch with Link)指令,行将回来地址保存在衔接寄存器LR中,一起跳转到被调用的子函数程序进口。从子函数回来时履行指令 MOV PC, LR(当然也可能是其他方式的指令,如出栈指令)将LR值直接放入PC中,然后回来到调用函数中的下一条指令的地址,然后持续履行程序。在Interworking函数的调用中,需求在编译时对此函数地点的源程序指定编译开关选项:-apcs / interwork ,即确保程序恪守ARM/Thumb程序混合运用的ATPCS规矩。一般来说,这时生成的方针代码会添加2%左右。这样在编译器(compiler)处理这个函数时就会用BX 指令替代MOV PC,LR指令,而且衔接器(linker)会主动的发生一小段代码(veneers)来改动处理器状况(ARM/Thumb),关于C/C++程序来说,当编译时假如添加 –apcs/interwork 选项,那便是奉告衔接器主动添加一小段代码(veneer)来完结函数调用时ARM/Thumb的状况切换。可是关于运用C程序中的Interwork选项,需求留意的是:
- 关于一个C /C++源程序中不能一起包括ARM/Thumb指令;
-
假如C/C++程序直接的调用另一种指令系统下的子程序,编译该程序时需求添加-apcs/interwork选项;
- 编译用于交互作业的ARM C代码: armcc -apcs/interwork
- 编译用于交互作业的Thumb C代码:tcc -apcs/interwork
- 假如调用程序和被调用程序是不同的指令,而被调用程序是Non-Interworking代码,这时不要运用函数指针来调用该被调用程序。
关于汇编程序来说,假如本代码是被调用的函数,则需依照以下过程处理:
- 编译时添加-apcs/interwork 选项;ARM汇编armasm -32 -apcs /interwork;Thumb汇编代码:armasm -16 -apcs /interwork;
- 在进口处维护回来地址(lr)以及寄存器(r0-r7,r8-r12(ARM))
- 回来前康复维护的寄存器
- 用BX来回来;
- EXPORT本函数名;
假如本代码是调用函数,那就只需求用BL指令来完结子函数的调用即可,也便是正常的处理。当然,用户也可以自己来编写这些状况切换程序,这样履行代码的功率会更高些。关于C/C++程序和汇编程序的彼此调用相同需求恪守以上的规矩。别的,在实践运用中,假如要在ARM/Thumb状况间来切换程序,最好的方法是一切的函数在编译时都添加 -apcs/interwork选项。关于汇编代码,也可在程序中运用CODE32或CODE16指令清晰奉告汇编程序下面的代码是ARM代码仍是Thumb代码,这样在汇编时则无需运用-32、-16选项;当然也可在单个汇编原文件中混合运用ARM以及Thumb代码,这是需求运用CODE32以及CODE16指令,而且需求留意状况的切换,运用BX Rn,依据Rn的Bit[0]来确认方针是ARM代码仍是Thumb代码。如AREA Init,CODE,READONLY CODE32;告诉编译器这以后的指令为32位的ARM指令。
前面所说到的内容是针对ARM微处理器内核为V4T架构时的切换状况,而关于V5TE架构的ARM内核,除了彻底支撑V4T架构的代码(具有veneers)外,代码在衔接时不再添加veneers,而是运用新的指令BLX(Branch and Link with Exchang)来完结状况切换。这条指令完结完结的使命是:在跳转时将回来的指令地址保存在LR寄存器中,一起将PC中的最低位的值拷贝到CPSR寄存器中的T位,然后改动处理器状况(Exchange)。一般来说,关于调用函数运用BLX指令即可,被调用函数则与V4T架构相同,也是运用BX指令来回来。
ARM/Thumb代码功用比较
前面说到Thumb代码所需的存储空间约为ARM代码的60%~70%;Thumb代码运用的指令数比ARM代码少约30%~40%;若运用32位的存储器,ARM代码比Thumb代码速约40%;若运用16位的存储器,Thumb代码比ARM代码速约40%~50%;与ARM代码比较,运用Thumb代码,存储器的过耗会下降约30%。下面是arm-linux-gcc编译器选用不同的编译挑选对armv7-a,、thumb-2 和thumb-1指令集编译CoreMark的测验成果,成果如下:
- 最好的编译选项:-O3 -funroll-loops -marm -march=armv5te -mtune=cortex-a8
- armv7-a指令集最好的编译选项:-O3 -funroll-loops -marm -march=armv7-a -mtune=cortex-a8 95.2%
- Thumb-2指令集最好的编译选项:-O3 -funroll-loops -mthumb -march=armv7-a -mtune=cortex-a888.7%
- Thumb-1指令集最好的编译选项:-O2 -mthumb -march=armv5te -mtune=cortex-a8 66.4%
- Cortex-A9是Cortex-A8的tune的99.5%
- 默许选项-O2 -mthumb -march=armv7-a 功用比为80.8%
Top of Form
Score |
Optimisation |
Unroll? |
ISA |
Arch |
Tune |
% of best |
5634.6 |
-O3 |
-funroll-loops |
-marm |
-march=armv5te |
-mtune=cortex-a8 |
100.0% |
5607.7 |
-O3 |
-funroll-loops |
-marm |
-march=armv5te |
-mtune=cortex-a9 |
99.5% |
5601.5 |
-O2 |
-funroll-loops |
-marm |
-march=armv5te |
-mtune=cortex-a9 |
99.4% |
5580.0 |
-O3 |
-marm |
-march=armv5te |
-mtune=cortex-a8 |
99.0% |
|
5548.6 |
-O3 |
-marm |
-march=armv5te |
-mtune=cortex-a9 |
98.5% |
|
5505.1 |
-O2 |
-marm |
-march=armv5te |
-mtune=cortex-a8 |
97.7% |
|
5427.4 |
-O2 |
-funroll-loops |
-marm |
-march=armv5te |
-mtune=cortex-a8 |
96.3% |
5386.5 |
-O3 |
-funroll-loops |
-marm |
-march=armv7-a |
-mtune=cortex-a9 |
95.6% |
5364.4 |
-O3 |
-funroll-loops |
-marm |
-march=armv7-a |
-mtune=cortex-a8 |
95.2% |
5332.3 |
-O2 |
-marm |
-march=armv5te |
-mtune=cortex-a9 |
94.6% |
|
5330.8 |
-O3 |
-marm |
-march=armv7-a |
-mtune=cortex-a8 |
94.6% |
|
5283.7 |
-O3 |
-marm |
-march=armv7-a |
-mtune=cortex-a9 |
93.8% |
|
5253.5 |
-O2 |
-funroll-loops |
-marm |
-march=armv7-a |
-mtune=cortex-a9 |
93.2% |
5066.5 |
-O2 |
-funroll-loops |
-marm |
-march=armv7-a |
-mtune=cortex-a8 |
89.9% |
4996.6 |
-O3 |
-funroll-loops |
-mthumb |
-march=armv7-a |
-mtune=cortex-a8 |
88.7% |
4995.6 |
-O3 |
-funroll-loops |
-mthumb |
-march=armv7-a |
-mtune=cortex-a9 |
88.7% |
4947.2 |
-O3 |
-mthumb |
-march=armv7-a |
-mtune=cortex-a8 |
87.8% |
|
4858.3 |
-O2 |
-funroll-loops |
-mthumb |
-march=armv7-a |
-mtune=cortex-a9 |
86.2% |
4774.8 |
-O2 |
-funroll-loops |
-mthumb |
-march=armv7-a |
-mtune=cortex-a8 |
84.7% |
4763.8 |
-O2 |
-marm |
-march=armv7-a |
-mtune=cortex-a9 |
84.5% |
|
4737.8 |
-Os |
-marm |
-march=armv5te |
-mtune=cortex-a8 |
84.1% |
|
4731.1 |
-O2 |
-marm |
-march=armv7-a |
-mtune=cortex-a8 |
84.0% |
|
4688.6 |
-O3 |
-mthumb |
-march=armv7-a |
-mtune=cortex-a9 |
83.2% |
|
4665.6 |
-Os |
-funroll-loops |
-marm |
-march=armv5te |
-mtune=cortex-a8 |
82.8% |
4630.7 |
-Os |
-marm |
-march=armv5te |
-mtune=cortex-a9 |
82.2% |
|
4595.6 |
-Os |
-funroll-loops |
-marm |
-march=armv5te |
-mtune=cortex-a9 |
81.6% |
4562.7 |
-Os |
-funroll-loops |
-marm |
-march=armv7-a |
-mtune=cortex-a8 |
81.0% |
4551.7 |
-O2 |
-mthumb |
-march=armv7-a |
-mtune=cortex-a8 |
80.8% |
|
4521.5 |
-Os |
-funroll-loops |
-marm |
-march=armv7-a |
-mtune=cortex-a9 |
80.2% |
4519.8 |
-Os |
-marm |
-march=armv7-a |
-mtune=cortex-a8 |
80.2% |
|
4500.8 |
-Os |
-marm |
-march=armv7-a |
-mtune=cortex-a9 |
79.9% |
|
4237.6 |
-O2 |
-mthumb |
-march=armv7-a |
-mtune=cortex-a9 |
75.2% |
|
3739.7 |
-O2 |
-funroll-loops |
-mthumb |
-march=armv5te |
-mtune=cortex-a8 |
66.4% |
3730.6 |
-O2 |
-funroll-loops |
-mthumb |
-march=armv5te |
-mtune=cortex-a9 |
66.2% |
3658.8 |
-Os |
-mthumb |
-march=armv7-a |
-mtune=cortex-a8 |
64.9% |
|
3657.0 |
-Os |
-funroll-loops |
-mthumb |
-march=armv7-a |
-mtune=cortex-a8 |
64.9% |
3629.3 |
-O2 |
-mthumb |
-march=armv5te |
-mtune=cortex-a8 |
64.4% |
|
3585.1 |
-Os |
-mthumb |
-march=armv7-a |
-mtune=cortex-a9 |
63.6% |
|
3580.8 |
-Os |
-funroll-loops |
-mthumb |
-march=armv7-a |
-mtune=cortex-a9 |
63.6% |
3522.2 |
-O3 |
-mthumb |
-march=armv5te |
-mtune=cortex-a8 |
62.5% |
|
3473.0 |
-O2 |
-mthumb |
-march=armv5te |
-mtune=cortex-a9 |
61.6% |
|
3338.9 |
-O3 |
-funroll-loops |
-mthumb |
-march=armv5te |
-mtune=cortex-a8 |
59.3% |
3219.1 |
-O3 |
-funroll-loops |
-mthumb |
-march=armv5te |
-mtune=cortex-a9 |
57.1% |
3170.6 |
-O3 |
-mthumb |
-march=armv5te |
-mtune=cortex-a9 |
56.3% |
|
2753.7 |
-Os |
-mthumb |
-march=armv5te |
-mtune=cortex-a8 |
48.9% |
|
2748.6 |
-Os |
-funroll-loops |
-mthumb |
-march=armv5te |
-mtune=cortex-a8 |
48.8% |
2747.4 |
-Os |
-mthumb |
-march=armv5te |
-mtune=cortex-a9 |
48.8% |
|
2743.7 |
-Os |
-funroll-loops |
-mthumb |
-march=armv5te |
-mtune=cortex-a9 |
48.7% |
Bottom of Form
http://lion3875.blog.51cto.com/2911026/532719
Compile with ARM Thumb2 to Reduce Memory Footprint and Improve Performance
https://wiki.linaro.org/MichaelHope/Sandbox/CoreMark1
http://blog.csdn.net/itismine/archive/2009/11/01/4753701.aspx
http://hi.baidu.com/yzx408/blog/item/a050741180944c1cb8127b79.html
http://houh-1984.blog.163.com/
32位RISC芯片ARM 系统结构支撑两种指令集:32位的ARM指令集履行功率高,对ARM系统架构一切功用的完好支撑;16位的Thumb指令集是ARM指令集的子集并以杰出的代码密度著称。假如抛开预取指令时刻不计,ARM指令相对Thumb指令将有更好的运转功用(预取指令时需求依据指令地址偏移量来取指, ARM支撑更大的地址偏移量而比较耗时)。最近ARM公司推出的的Thumb-2/Thumb2指令集据称是上述两种特性的归纳,是ARM指令集的功用和Thumb指令集的代码密度的折中。声称到达98%的ARM功用而又能下降代码密度达30%。在现在的大多数ARM运用中仍然选用ARM + Thumb代码的稠浊方式。ARM code对应的CPU(ARM处理器)作业状况称为ARM State,Thumb对应的称之为Thumb State,这两种状况的不同首要经过CPSR[bit 5]差异。CPSR(当时程序状况寄存器)保存了处理器的当时作业状况,[bit 5]也被称为T bit。关于一切带有J标志的处理器核,比方ARM926EJ-S和ARM1136J-S,J(Jazelle)代表ARM核中集成了Jazelle技 术。CPSR[bit24]则被成为J bit,假如这位为1,则代表当时CPU作业在Java State下而CPU的取指和解码都是直接操作Java操作数栈。当然要生成Jazelle支撑的字节码需求特别的Java编译器和JVM,一般由第三方 渠道软件厂商供给,比方日本的Aplix公司。在ARM处理器的运转过程中,汇编指令BX以及BLX可以完结ARM State和Thumb State之间的切换(BXJ和BLXJ完结ARM/Thumb State和Java State之间的切换)。但假如程序有一部分作业在ARM作业状况下,一部分作业在Thumb作业状况下,而这两段代码却有交互调用,则在编译C/C++和汇编源文件时要 加上 -apcs /interwork选项。ARM公司的ADS(ARM Developer Suite,-apcs /interwork)和RealView的RVDS(RealView Developer Suite,–apcs /interwork) 都支撑这样的编译选项,他们会在链接时主动检测函数之间的调用联系和作业状况供给粘合剂(Veneers)以便程序可以在不同的作业状况下切换。arm-linux-gcc编译器单个版别不支撑这个选项,所以在开发ARM + Linux渠道下运用的程序时应该留意到这个问题。最终比较了arm-linux-gcc编译器下ARM(armv7-a)、Thumb-1、Thumb-2指令集以及armv5te、Cortex-A9与Cortex-A8的tune选项功率功用和代码密度。