Arun Kp
Arun Kp

Reputation: 422

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.

Upvotes: 1

Views: 2231

Answers (2)

Ciro Santilli
Ciro Santilli

Reputation: 4073

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:

Upvotes: 2

NicoEagerLearner
NicoEagerLearner

Reputation: 1

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

Upvotes: 0

Related Questions