[a64] Implement OPCODE_CACHE_CONTROL store
This commit is contained in:
@@ -76,7 +76,7 @@ struct CACHE_CONTROL
|
|||||||
: Sequence<CACHE_CONTROL,
|
: Sequence<CACHE_CONTROL,
|
||||||
I<OPCODE_CACHE_CONTROL, VoidOp, I64Op, OffsetOp>> {
|
I<OPCODE_CACHE_CONTROL, VoidOp, I64Op, OffsetOp>> {
|
||||||
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
||||||
bool is_prefetch = false, is_prefetchw = false;
|
bool is_clflush = false, is_prefetch = false, is_prefetchw = false;
|
||||||
switch (CacheControlType(i.instr->flags)) {
|
switch (CacheControlType(i.instr->flags)) {
|
||||||
case CacheControlType::CACHE_CONTROL_TYPE_DATA_TOUCH:
|
case CacheControlType::CACHE_CONTROL_TYPE_DATA_TOUCH:
|
||||||
is_prefetch = true;
|
is_prefetch = true;
|
||||||
@@ -86,15 +86,18 @@ struct CACHE_CONTROL
|
|||||||
break;
|
break;
|
||||||
case CacheControlType::CACHE_CONTROL_TYPE_DATA_STORE:
|
case CacheControlType::CACHE_CONTROL_TYPE_DATA_STORE:
|
||||||
case CacheControlType::CACHE_CONTROL_TYPE_DATA_STORE_AND_FLUSH:
|
case CacheControlType::CACHE_CONTROL_TYPE_DATA_STORE_AND_FLUSH:
|
||||||
// ARM64 dc instructions aren't available in xbyak_aarch64.
|
is_clflush = true;
|
||||||
// These are mostly hints anyway; skip.
|
break;
|
||||||
return;
|
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto addr = ComputeMemoryAddress(e, i.src1);
|
auto addr = ComputeMemoryAddress(e, i.src1);
|
||||||
e.add(e.x0, e.GetMembaseReg(), addr);
|
e.add(e.x0, e.GetMembaseReg(), addr);
|
||||||
size_t cache_line_size = i.src2.value;
|
size_t cache_line_size = i.src2.value;
|
||||||
|
if (is_clflush) {
|
||||||
|
// dc civac, x0
|
||||||
|
e.sys(0b011, 0b0111, 0b1110, 0b001, e.x0);
|
||||||
|
}
|
||||||
if (is_prefetch) {
|
if (is_prefetch) {
|
||||||
e.prfm(Xbyak_aarch64::PLDL1KEEP, ptr(e.x0));
|
e.prfm(Xbyak_aarch64::PLDL1KEEP, ptr(e.x0));
|
||||||
} else if (is_prefetchw) {
|
} else if (is_prefetchw) {
|
||||||
@@ -102,6 +105,10 @@ struct CACHE_CONTROL
|
|||||||
}
|
}
|
||||||
if (cache_line_size >= 128) {
|
if (cache_line_size >= 128) {
|
||||||
e.eor(e.x0, e.x0, 64);
|
e.eor(e.x0, e.x0, 64);
|
||||||
|
if (is_clflush) {
|
||||||
|
// dc civac, x0
|
||||||
|
e.sys(0b011, 0b0111, 0b1110, 0b001, e.x0);
|
||||||
|
}
|
||||||
if (is_prefetch) {
|
if (is_prefetch) {
|
||||||
e.prfm(Xbyak_aarch64::PLDL1KEEP, ptr(e.x0));
|
e.prfm(Xbyak_aarch64::PLDL1KEEP, ptr(e.x0));
|
||||||
} else if (is_prefetchw) {
|
} else if (is_prefetchw) {
|
||||||
|
|||||||
Reference in New Issue
Block a user