[ABI] Added prfm instruction (AArch64)

This commit is contained in:
kobalicek
2023-12-26 19:05:05 +01:00
parent 073f6e85e4
commit 13bd440022
6 changed files with 605 additions and 500 deletions

View File

@@ -2241,6 +2241,86 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
break;
}
// ------------------------------------------------------------------------
// [Base - Prefetch]
// ------------------------------------------------------------------------
case InstDB::kEncodingBasePrfm: {
const InstDB::EncodingData::BasePrfm& opData = InstDB::EncodingData::basePrfm[encodingIndex];
if (isign4 == ENC_OPS2(Imm, Mem)) {
const Mem& m = o1.as<Mem>();
rmRel = &m;
uint32_t immShift = 3u;
if (o0.as<Imm>().valueAs<uint64_t>() > 0x1Fu)
goto InvalidImmediate;
if (!armCheckMemBaseIndexRel(m))
goto InvalidAddress;
int64_t offset = m.offset();
uint32_t prfop = o0.as<Imm>().valueAs<uint32_t>();
if (m.hasBaseReg()) {
// [Base {Offset | Index}]
if (m.hasIndex()) {
uint32_t opt = armShiftOpToLdStOptMap[m.predicate()];
if (opt == 0xFF)
goto InvalidAddress;
uint32_t shift = m.shift();
uint32_t s = shift != 0;
if (s && shift != immShift)
goto InvalidAddressScale;
opcode.reset(uint32_t(opData.registerOp) << 21);
opcode.addImm(opt, 13);
opcode.addImm(s, 12);
opcode |= B(11);
opcode.addImm(prfop, 0);
goto EmitOp_MemBaseIndex_Rn5_Rm16;
}
if (!Support::isInt32(offset))
goto InvalidDisplacement;
int32_t offset32 = int32_t(offset);
if (m.isPreOrPost())
goto InvalidAddress;
uint32_t imm12 = uint32_t(offset32) >> immShift;
if (Support::isUInt12(imm12) && (imm12 << immShift) == uint32_t(offset32)) {
opcode.reset(uint32_t(opData.sOffsetOp) << 22);
opcode.addImm(imm12, 10);
opcode.addImm(prfop, 0);
goto EmitOp_MemBase_Rn5;
}
if (Support::isInt9(offset32)) {
opcode.reset(uint32_t(opData.uOffsetOp) << 21);
opcode.addImm(uint32_t(offset32) & 0x1FFu, 12);
opcode.addImm(prfop, 0);
goto EmitOp_MemBase_Rn5;
}
goto InvalidAddress;
}
else {
opcode.reset(uint32_t(opData.literalOp) << 24);
opcode.addImm(prfop, 0);
offsetFormat.resetToImmValue(OffsetType::kSignedOffset, 4, 5, 19, 2);
goto EmitOp_Rel;
}
}
break;
}
// ------------------------------------------------------------------------
// [Base - Load / Store]
// ------------------------------------------------------------------------

View File

@@ -514,6 +514,8 @@ struct EmitterExplicitT {
ASMJIT_INST_2x(ldxrb, Ldxrb, Gp, Mem)
ASMJIT_INST_2x(ldxrh, Ldxrh, Gp, Mem)
ASMJIT_INST_2x(prfm, Prfm, Imm, Mem)
ASMJIT_INST_2x(stadd, Stadd, Gp, Mem)
ASMJIT_INST_2x(staddb, Staddb, Gp, Mem)
ASMJIT_INST_2x(staddh, Staddh, Gp, Mem)

View File

@@ -293,6 +293,7 @@ struct Inst {
kIdPacdza, //!< Instruction 'pacdza'.
kIdPacdzb, //!< Instruction 'pacdzb'.
kIdPacga, //!< Instruction 'pacga'.
kIdPrfm, //!< Instruction 'prfm'.
kIdPssbb, //!< Instruction 'pssbb'.
kIdRbit, //!< Instruction 'rbit'.
kIdRet, //!< Instruction 'ret'.

File diff suppressed because it is too large Load Diff

View File

@@ -192,6 +192,7 @@ enum EncodingId : uint32_t {
kEncodingBaseMvnNeg,
kEncodingBaseOp,
kEncodingBaseOpImm,
kEncodingBasePrfm,
kEncodingBaseR,
kEncodingBaseRM_NoImm,
kEncodingBaseRM_SImm10,
@@ -412,6 +413,13 @@ struct BaseRM_SImm10 {
uint32_t immShift : 4;
};
struct BasePrfm {
uint32_t registerOp : 11;
uint32_t sOffsetOp : 10;
uint32_t uOffsetOp : 11;
uint32_t literalOp;
};
struct BaseLdSt {
uint32_t uOffsetOp : 10;
uint32_t prePostOp : 11;
@@ -787,6 +795,7 @@ extern const BaseMovKNZ baseMovKNZ[3];
extern const BaseMvnNeg baseMvnNeg[3];
extern const BaseOp baseOp[23];
extern const BaseOpImm baseOpImm[14];
extern const BasePrfm basePrfm[1];
extern const BaseR baseR[10];
extern const BaseRM_NoImm baseRM_NoImm[21];
extern const BaseRM_SImm10 baseRM_SImm10[2];

View File

@@ -862,6 +862,13 @@ static void ASMJIT_NOINLINE testA64AssemblerBase(AssemblerTester<a64::Assembler>
TEST_INSTRUCTION("F42FC1DA", pacdzb(x20));
TEST_INSTRUCTION("4130C39A", pacga(x1, x2, x3));
TEST_INSTRUCTION("4130DF9A", pacga(x1, x2, sp));
TEST_INSTRUCTION("204080F9", prfm(Predicate::PRFOp::kPLDL1KEEP, ptr(x1, 128)));
TEST_INSTRUCTION("401098F8", prfm(Predicate::PRFOp::kPLDL1KEEP, ptr(x2, -127)));
TEST_INSTRUCTION("601088F8", prfm(Predicate::PRFOp::kPLDL1KEEP, ptr(x3, 129)));
TEST_INSTRUCTION("6068A4F8", prfm(Predicate::PRFOp::kPLDL1KEEP, ptr(x3, x4)));
TEST_INSTRUCTION("6078A4F8", prfm(Predicate::PRFOp::kPLDL1KEEP, ptr(x3, x4, lsl(3))));
TEST_INSTRUCTION("60C8A4F8", prfm(Predicate::PRFOp::kPLDL1KEEP, ptr(x3, x4, sxtw(0))));
TEST_INSTRUCTION("73D8A4F8", prfm(Predicate::PRFOp::kPSTL2STRM, ptr(x3, x4, sxtw(3))));
TEST_INSTRUCTION("9F3403D5", pssbb());
TEST_INSTRUCTION("4100C05A", rbit(w1, w2));
TEST_INSTRUCTION("4100C0DA", rbit(x1, x2));