我有一个汇编程序,它具有以下代码。这段代码在英特尔处理器上可以很好地编译。但是,当我使用PPC(交叉)编译器时,我得到一个操作码无法识别的错误。我正试图找到PPC架构是否有等效的操作码。
.file "assembly.s"
.text
.globl func64
.type func64,@function
func64:
rdtsc
ret
.size func64,.Lfe1-func64
.globl func
.type func,@function
func:
rdtsc
ret
PowerPC包含一个定时递增的"时基"寄存器(尽管可能不是在每个时钟递增——它取决于实际的硬件和操作系统)。TB寄存器是一个64位的值,读取为两个32位的一半,其中mftb
(低一半)和mftbu
(高一半)。TB的四个最低有效位有点不可靠(它们单调递增,但不一定以固定速率递增)。
一些旧的PowerPC处理器没有TB寄存器(但是操作系统可能会模仿它,可能有问题的准确性);但是,603e已经有了它,所以可以肯定的是,大多数(如果不是全部的话)实际生产中的PowerPC系统都有它。还有一个"备用时基寄存器"。
详细信息,请参见power.org网站上提供的Power ISA规范。在写这个答案的时候,当前版本是2.06B, TB寄存器和操作码记录在第703到706页。
当您需要在32位架构上的64位值(不确定它在64位上如何工作)并且您读取TB寄存器时,您可能会遇到下半部分从0xffffffff到0的问题-虽然这种情况不经常发生,但您可以确定它会在造成最大损害的时候发生;)
我建议你先看上半部分,然后是下半部分,最后再看上半部分。比较两个鞋面,如果它们相等,没有问题。如果它们不相同(第一个应该比最后一个少一个),你必须看下一个,看看它应该与哪个上位配对:如果它的最高位被设置,它应该与第一个配对,否则与最后一个配对。
对于不同类型的代码,Apple有三个版本的mach_absolute_time():
- 32位
- 64位内核,32位应用
- 64位内核,64位应用
灵感来自Peter Cordes的评论和clang的__builtin_readcyclecounter
的拆卸:
mfspr 3, 268
blr
对于gcc,您可以执行以下操作:
unsigned long long rdtsc(){
unsigned long long rval;
__asm__ __volatile__("mfspr %%r3, 268": "=r" (rval));
return rval;
}
Or For clang:
unsigned long long readTSC() {
// _mm_lfence(); // optionally wait for earlier insns to retire before reading the clock
return __builtin_readcyclecounter();
}