<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - [mips] Implementation of __cache_flush() should use synci where possible"
   href="http://llvm.org/bugs/show_bug.cgi?id=19076">19076</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[mips] Implementation of __cache_flush() should use synci where possible
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>compiler-rt
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>compiler-rt
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>daniel.sanders@imgtec.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>There is a better implementation of __cache_flush() available on MIPS32r2 and
MIPS64r2 that could be implemented. However the necessary 'synci' and 'jr.hb'
instructions aren't implemented in LLVM yet. 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)
     return;

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

     // 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"
                   "nop\n\t"
                   "1: addiu $31, $31, 12\n\t"
                   "jr.hb $31\n\t"
                   "nop\n\t" ::: "$31", "memory");
}</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>