LinuxX86_64系统ARMv8-A交叉编译C程序
Cross-compilng C program for ARMv8-A in Linux X86_64 system
我是 ARM 架构的新手,我正在尝试清理 Arm 的缓存。
我正在关注“ARMv8-A 程序员指南”,因为 Gem-5 具有按照 (https://www.gem5.org/documentation/general_docs/architecture_support/arm_implementation/) ,
的实现
我正在尝试在 linux x86_64 系统中交叉编译以下代码
arm-linux-gnueabi-gcc test_arm.c -o 测试,
但我收到以下错误。
/tmp/ccTM2bcE.s: Assembler messages:
/tmp/ccTM2bcE.s:38: Error: selected processor does not support requested special purpose register -- `mrs r3,ctr_el0'
/tmp/ccTM2bcE.s:69: Error: bad instruction `dc cavu,r3'
/tmp/ccTM2bcE.s:150: Error: selected processor does not support `dsb ish' in ARM mode
/tmp/ccTM2bcE.s:159: Error: selected processor does not support `dsb ish' in ARM mode
代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <stdint.h>
void clean_invalidate(uint64_t addr){
uint64_t ctr_el0 = 0;
if(ctr_el0 == 0)
asm volatile("mrs %0, ctr_el0":"=r"(ctr_el0)::);
const size_t dcache_line_size = 4 << ((ctr_el0 >>16)&15);
addr = addr & ~(dcache_line_size - 1);
asm volatile("dc cvau, %0"::"r"(addr):);
}
int main(){
int a[1000];
int index = 0;
uint64_t addr = 0;
double time_spend = 0.0;
clock_t begin = clock();
for(int i=0;i<100;i++){
index = rand()%1000;
a[index] = index;
addr = (uint64_t)(&a[index]);
asm volatile("dsb ish");
clean_invalidate(addr);
asm volatile("dsb ish");
int b = a[index];
}
clock_t end = clock();
time_spend = (double)(end-begin)/CLOCKS_PER_SEC;
printf("Time:%f\n",time_spend);
return 0;
}
谁能帮我在 Linux X86 系统中为 ARMv8-A 编译这段代码。
PS: 您可以忽略从指针到不同大小整数的转换警告。
指令有问题:
asm volatile("mrs %0, ctr_el0":"=r"(ctr_el0)::);
它被翻译成汇编指令,它与你的 ARM 架构有关,为此你应该查看你对应的 arm 寄存器,看看它是否包含在那里,如果没有,那么你需要找到另一个以类似目的注册
我觉得mrs %0,ctr_el0
是ARMv8 aarch64指令,arm-linux-gnueabi-gcc
是armv7/aarch32编译器,你得用aarch64-linux-gnu-gcc
.
而且dc cavu
好像不存在,你说的是dc cvau
吗?
通过这两个更改,它可以编译。
说实话,ARMv7里面除了MRC还有MRS,只是一直没搞明白每一个应该在什么时候用到里面。 aarch64 只有 MRS,所以更简单。
对于CTR_EL0的具体情况,存在一个类似的aarch32寄存器CTR,但根据手册,该寄存器是通过MRC访问的,而不是MRS。
这里有大量可运行的示例,您可能也会感兴趣:
我是 ARM 架构的新手,我正在尝试清理 Arm 的缓存。
我正在关注“ARMv8-A 程序员指南”,因为 Gem-5 具有按照 (https://www.gem5.org/documentation/general_docs/architecture_support/arm_implementation/) ,
的实现我正在尝试在 linux x86_64 系统中交叉编译以下代码 arm-linux-gnueabi-gcc test_arm.c -o 测试, 但我收到以下错误。
/tmp/ccTM2bcE.s: Assembler messages:
/tmp/ccTM2bcE.s:38: Error: selected processor does not support requested special purpose register -- `mrs r3,ctr_el0'
/tmp/ccTM2bcE.s:69: Error: bad instruction `dc cavu,r3'
/tmp/ccTM2bcE.s:150: Error: selected processor does not support `dsb ish' in ARM mode
/tmp/ccTM2bcE.s:159: Error: selected processor does not support `dsb ish' in ARM mode
代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <stdint.h>
void clean_invalidate(uint64_t addr){
uint64_t ctr_el0 = 0;
if(ctr_el0 == 0)
asm volatile("mrs %0, ctr_el0":"=r"(ctr_el0)::);
const size_t dcache_line_size = 4 << ((ctr_el0 >>16)&15);
addr = addr & ~(dcache_line_size - 1);
asm volatile("dc cvau, %0"::"r"(addr):);
}
int main(){
int a[1000];
int index = 0;
uint64_t addr = 0;
double time_spend = 0.0;
clock_t begin = clock();
for(int i=0;i<100;i++){
index = rand()%1000;
a[index] = index;
addr = (uint64_t)(&a[index]);
asm volatile("dsb ish");
clean_invalidate(addr);
asm volatile("dsb ish");
int b = a[index];
}
clock_t end = clock();
time_spend = (double)(end-begin)/CLOCKS_PER_SEC;
printf("Time:%f\n",time_spend);
return 0;
}
谁能帮我在 Linux X86 系统中为 ARMv8-A 编译这段代码。
PS: 您可以忽略从指针到不同大小整数的转换警告。
指令有问题: asm volatile("mrs %0, ctr_el0":"=r"(ctr_el0)::);
它被翻译成汇编指令,它与你的 ARM 架构有关,为此你应该查看你对应的 arm 寄存器,看看它是否包含在那里,如果没有,那么你需要找到另一个以类似目的注册
我觉得mrs %0,ctr_el0
是ARMv8 aarch64指令,arm-linux-gnueabi-gcc
是armv7/aarch32编译器,你得用aarch64-linux-gnu-gcc
.
而且dc cavu
好像不存在,你说的是dc cvau
吗?
通过这两个更改,它可以编译。
说实话,ARMv7里面除了MRC还有MRS,只是一直没搞明白每一个应该在什么时候用到里面。 aarch64 只有 MRS,所以更简单。
对于CTR_EL0的具体情况,存在一个类似的aarch32寄存器CTR,但根据手册,该寄存器是通过MRC访问的,而不是MRS。
这里有大量可运行的示例,您可能也会感兴趣: