[patch] implement __clear_cache for arm32 & mips

Daniel Sanders Daniel.Sanders at imgtec.com
Fri Mar 7 07:08:52 PST 2014

That makes sense to me. I've put a ticket about the better implementation into the LLVM bugzilla (PR19076) so we don't forget it.

From: Narayan Kamath [mailto:narayan at google.com]
Sent: 07 March 2014 14:10
To: Daniel Sanders; Elliott Hughes
Cc: llvm-commits at cs.uiuc.edu; Jean-Luc Brouillet; JF Bastien; Renato Golin
Subject: Re: [patch] implement __clear_cache for arm32 & mips

Thanks - I was aware of the better MIPS implementation, but I
am very hesitant to implement it because I don't have any MIPS
hardware with me to test it.

Perhaps someone from mips / imgtec could contribute it once the
necessary LLVM infrastructure is in place ? I'm happy to help in any
limited way I can.

I'll upload a new patch shortly with a better ARM implementation (and
to address jfb's comments)

On Fri, Mar 7, 2014 at 2:03 PM, Daniel Sanders <Daniel.Sanders at imgtec.com<mailto:Daniel.Sanders at imgtec.com>> wrote:
Sorry for the delay in reviewing this. I had to learn the details before I could comment.

The ICACHE argument should be BCACHE so that any stale instruction data in the dcache is also flushed. Other than that the MIPS part of the patch LGTM.

There is a better implementation available on MIPS32r2 and MIPS64r2 that you could implement if you want to. However the necessary 'synci' and 'jr.hb' instructions aren't implemented in LLVM yet so you may prefer to leave it for now. The better implementation, uses a series of synci instructions to flush the cache, then a 'sync' followed by a jr.hb to create the necessary barriers.

Here is an untested version of the better implementation based on the assembly that gcc emits for __builtin_clear_cache():
void __clear_cache(void* start, void* end)
const uintptr_t start_int = (uintptr_t) start;
const uintptr_t end_int = (uintptr_t) end;
if (begin == end)

// Discover the step needed for the synci instructions
uintptr_t inc;
     asm volatile ("rdhwr %0, $1" : "=r"(inc));
     if (inc == 0)

     // Round the start address downwards
     start_int &= ~inc;

     // Flush the region
     while (start_int < end_int) {
           asm volatile ("synci %0", :: "r"(start_int) : "memory");
           start_int += inc;

     // Memory barrier
     asm volatile ("sync" ::: "memory");

     // Execution hazard and instruction hazard barrier
     // The jr.hb is the important instruction and could be used in place
     // of the jr instruction that returns from this function rather than
     // faking a return like this.
     asm volatile ("bal 1f\n\t"
                   "1: addiu $31, $31, 12\n\t"
                   "jr.hb $31\n\t"
                   "nop\n\t" ::: "$31", "memory");

From: llvm-commits-bounces at cs.uiuc.edu<mailto:llvm-commits-bounces at cs.uiuc.edu> [mailto:llvm-commits-bounces at cs.uiuc.edu<mailto:llvm-commits-bounces at cs.uiuc.edu>] On Behalf Of Narayan Kamath
Sent: 26 February 2014 16:36
To: llvm-commits at cs.uiuc.edu<mailto:llvm-commits at cs.uiuc.edu>
Cc: Jean-Luc Brouillet
Subject: [patch] implement __clear_cache for arm32 & mips

Note that both arm32 and mips flavours of this code generate
a syscall.

Save Rainforests

Save Rainforests
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140307/c4671955/attachment.html>

More information about the llvm-commits mailing list