简体   繁体   中英

Cross-compilng C program for ARMv8-A in Linux X86_64 system

I am new to ARM architecture,I am experimenting with cache clean of Arm.

I am following "Programmer's Guide for ARMv8-A" since Gem-5 has this implementation as per ( https://www.gem5.org/documentation/general_docs/architecture_support/arm_implementation/ ),

I am trying to cross-compile below code in linux x86_64 system using arm-linux-gnueabi-gcc test_arm.c -o test , but I am getting following error.

/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

code

#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;
}

Can someone please help me to compile this code for ARMv8-A in Linux X86 system.

PS: You can ignore the cast from pointer to integer of different size warning.

I think mrs %0,ctr_el0 is an ARMv8 aarch64 instruction, and arm-linux-gnueabi-gcc is the armv7/aarch32 compiler, you have to use aarch64-linux-gnu-gcc .

And dc cavu does not seem to exist, did you mean dc cvau ?

With those two changes it compiles.

To be honest, there is also MRS in ARMv7 in addition to MRC, but I haven't fully understood when each one should be used in there. aarch64 has only MRS so it's simpler.

For the specific case of CTR_EL0, there exists an analogous aarch32 register CTR, but that one is accessed with MRC according to the manual, not MRS.

Here are a gazillion runnable examples that might be of interest as well:

The problem comes with the instruction: asm volatile("mrs %0, ctr_el0":"=r"(ctr_el0)::);

which is translated to an assembler instruction, it is tie to your ARM architecture, for this you should take a look into your correspondign arm registers and see if it is included there, If not, then you need to find another register with a similar purpose

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM