mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 04:24:37 +03:00
[ABI] Added prfm instruction (AArch64)
This commit is contained in:
@@ -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]
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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];
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user