emit_arm64_memory: Use LDAR and STLR instead of barriers
This commit is contained in:
parent
4bf4d6565e
commit
fae1d604e4
1 changed files with 99 additions and 51 deletions
|
@ -284,33 +284,59 @@ std::pair<oaknut::XReg, oaknut::XReg> InlinePageTableEmitVAddrLookup(oaknut::Cod
|
||||||
|
|
||||||
template<std::size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
CodePtr EmitMemoryLdr(oaknut::CodeGenerator& code, int value_idx, oaknut::XReg Xbase, oaknut::XReg Xoffset, bool ordered, bool extend32 = false) {
|
CodePtr EmitMemoryLdr(oaknut::CodeGenerator& code, int value_idx, oaknut::XReg Xbase, oaknut::XReg Xoffset, bool ordered, bool extend32 = false) {
|
||||||
const auto ext = extend32 ? oaknut::IndexExt::UXTW : oaknut::IndexExt::LSL;
|
const auto index_ext = extend32 ? oaknut::IndexExt::UXTW : oaknut::IndexExt::LSL;
|
||||||
|
const auto add_ext = extend32 ? oaknut::AddSubExt::UXTW : oaknut::AddSubExt::LSL;
|
||||||
const auto Roffset = extend32 ? oaknut::RReg{Xoffset.toW()} : oaknut::RReg{Xoffset};
|
const auto Roffset = extend32 ? oaknut::RReg{Xoffset.toW()} : oaknut::RReg{Xoffset};
|
||||||
|
|
||||||
const CodePtr fastmem_location = code.ptr<CodePtr>();
|
CodePtr fastmem_location = code.ptr<CodePtr>();
|
||||||
switch (bitsize) {
|
|
||||||
case 8:
|
|
||||||
code.LDRB(oaknut::WReg{value_idx}, Xbase, Roffset, ext);
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
code.LDRH(oaknut::WReg{value_idx}, Xbase, Roffset, ext);
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
code.LDR(oaknut::WReg{value_idx}, Xbase, Roffset, ext);
|
|
||||||
break;
|
|
||||||
case 64:
|
|
||||||
code.LDR(oaknut::XReg{value_idx}, Xbase, Roffset, ext);
|
|
||||||
break;
|
|
||||||
case 128:
|
|
||||||
code.LDR(oaknut::QReg{value_idx}, Xbase, Roffset, ext);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ASSERT_FALSE("Invalid bitsize");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ordered) {
|
if (ordered) {
|
||||||
// TODO: Use LDAR
|
code.ADD(Xscratch0, Xbase, Roffset, add_ext);
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
|
||||||
|
fastmem_location = code.ptr<CodePtr>();
|
||||||
|
|
||||||
|
switch (bitsize) {
|
||||||
|
case 8:
|
||||||
|
code.LDARB(oaknut::WReg{value_idx}, Xscratch0);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
code.LDARH(oaknut::WReg{value_idx}, Xscratch0);
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
code.LDAR(oaknut::WReg{value_idx}, Xscratch0);
|
||||||
|
break;
|
||||||
|
case 64:
|
||||||
|
code.LDAR(oaknut::XReg{value_idx}, Xscratch0);
|
||||||
|
break;
|
||||||
|
case 128:
|
||||||
|
code.LDR(oaknut::QReg{value_idx}, Xscratch0);
|
||||||
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT_FALSE("Invalid bitsize");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fastmem_location = code.ptr<CodePtr>();
|
||||||
|
|
||||||
|
switch (bitsize) {
|
||||||
|
case 8:
|
||||||
|
code.LDRB(oaknut::WReg{value_idx}, Xbase, Roffset, index_ext);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
code.LDRH(oaknut::WReg{value_idx}, Xbase, Roffset, index_ext);
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
code.LDR(oaknut::WReg{value_idx}, Xbase, Roffset, index_ext);
|
||||||
|
break;
|
||||||
|
case 64:
|
||||||
|
code.LDR(oaknut::XReg{value_idx}, Xbase, Roffset, index_ext);
|
||||||
|
break;
|
||||||
|
case 128:
|
||||||
|
code.LDR(oaknut::QReg{value_idx}, Xbase, Roffset, index_ext);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT_FALSE("Invalid bitsize");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fastmem_location;
|
return fastmem_location;
|
||||||
|
@ -318,38 +344,60 @@ CodePtr EmitMemoryLdr(oaknut::CodeGenerator& code, int value_idx, oaknut::XReg X
|
||||||
|
|
||||||
template<std::size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
CodePtr EmitMemoryStr(oaknut::CodeGenerator& code, int value_idx, oaknut::XReg Xbase, oaknut::XReg Xoffset, bool ordered, bool extend32 = false) {
|
CodePtr EmitMemoryStr(oaknut::CodeGenerator& code, int value_idx, oaknut::XReg Xbase, oaknut::XReg Xoffset, bool ordered, bool extend32 = false) {
|
||||||
const auto ext = extend32 ? oaknut::IndexExt::UXTW : oaknut::IndexExt::LSL;
|
const auto index_ext = extend32 ? oaknut::IndexExt::UXTW : oaknut::IndexExt::LSL;
|
||||||
|
const auto add_ext = extend32 ? oaknut::AddSubExt::UXTW : oaknut::AddSubExt::LSL;
|
||||||
const auto Roffset = extend32 ? oaknut::RReg{Xoffset.toW()} : oaknut::RReg{Xoffset};
|
const auto Roffset = extend32 ? oaknut::RReg{Xoffset.toW()} : oaknut::RReg{Xoffset};
|
||||||
|
|
||||||
if (ordered) {
|
CodePtr fastmem_location;
|
||||||
// TODO: Use STLR
|
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
|
||||||
}
|
|
||||||
|
|
||||||
const CodePtr fastmem_location = code.ptr<CodePtr>();
|
|
||||||
switch (bitsize) {
|
|
||||||
case 8:
|
|
||||||
code.STRB(oaknut::WReg{value_idx}, Xbase, Roffset, ext);
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
code.STRH(oaknut::WReg{value_idx}, Xbase, Roffset, ext);
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
code.STR(oaknut::WReg{value_idx}, Xbase, Roffset, ext);
|
|
||||||
break;
|
|
||||||
case 64:
|
|
||||||
code.STR(oaknut::XReg{value_idx}, Xbase, Roffset, ext);
|
|
||||||
break;
|
|
||||||
case 128:
|
|
||||||
code.STR(oaknut::QReg{value_idx}, Xbase, Roffset, ext);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ASSERT_FALSE("Invalid bitsize");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ordered) {
|
if (ordered) {
|
||||||
// TODO: Use STLR
|
code.ADD(Xscratch0, Xbase, Roffset, add_ext);
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
|
||||||
|
fastmem_location = code.ptr<CodePtr>();
|
||||||
|
|
||||||
|
switch (bitsize) {
|
||||||
|
case 8:
|
||||||
|
code.STLRB(oaknut::WReg{value_idx}, Xscratch0);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
code.STLRH(oaknut::WReg{value_idx}, Xscratch0);
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
code.STLR(oaknut::WReg{value_idx}, Xscratch0);
|
||||||
|
break;
|
||||||
|
case 64:
|
||||||
|
code.STLR(oaknut::XReg{value_idx}, Xscratch0);
|
||||||
|
break;
|
||||||
|
case 128:
|
||||||
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
|
code.STR(oaknut::QReg{value_idx}, Xscratch0);
|
||||||
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT_FALSE("Invalid bitsize");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fastmem_location = code.ptr<CodePtr>();
|
||||||
|
|
||||||
|
switch (bitsize) {
|
||||||
|
case 8:
|
||||||
|
code.STRB(oaknut::WReg{value_idx}, Xbase, Roffset, index_ext);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
code.STRH(oaknut::WReg{value_idx}, Xbase, Roffset, index_ext);
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
code.STR(oaknut::WReg{value_idx}, Xbase, Roffset, index_ext);
|
||||||
|
break;
|
||||||
|
case 64:
|
||||||
|
code.STR(oaknut::XReg{value_idx}, Xbase, Roffset, index_ext);
|
||||||
|
break;
|
||||||
|
case 128:
|
||||||
|
code.STR(oaknut::QReg{value_idx}, Xbase, Roffset, index_ext);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT_FALSE("Invalid bitsize");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fastmem_location;
|
return fastmem_location;
|
||||||
|
|
Loading…
Reference in a new issue